mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-11 16:24:11 +01:00
Frontend: Convert tests from mocha to vitest #5014
* Tests: convert all common tests from mocha to karma * Tests: refactor Vuetify setup in tests * Tests: update package-lock.json * Tests: convert all model test to vitest 1/2 * Tests: convert all model test to vitest 2/2 * Tests: fix broken test * Tests: time zone UTC * Tests: Add playwright screenshots folder to gitignore * Tests: Add timezone to vitest scripts * Tests: Add Vitest scripts to Makefile * Tests: delete unused timezone configs * Tests: Update some tests * Tests: Update vitest config * Tests: Delete usesless try-catch
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -40,6 +40,7 @@ venv
|
||||
/frontend/src/locales/*.mo
|
||||
/frontend/tests_output
|
||||
frontend/coverage/
|
||||
**/__screenshots__/
|
||||
/photoprism
|
||||
/photoprism-*
|
||||
/photos/originals/*
|
||||
|
||||
21
Makefile
21
Makefile
@@ -240,6 +240,8 @@ dep-npm:
|
||||
sudo npm install -g npm
|
||||
dep-js:
|
||||
(cd frontend && npm ci --no-update-notifier --no-audit)
|
||||
# TODO: If in the future we want to test in a real browser environment, add this (Playwright)
|
||||
# (cd frontend && npx playwright install chromium)
|
||||
dep-go:
|
||||
go build -v ./...
|
||||
dep-upgrade:
|
||||
@@ -344,6 +346,25 @@ acceptance-auth-short:
|
||||
acceptance-auth-firefox:
|
||||
$(info Running JS acceptance-auth tests in Firefox...)
|
||||
(cd frontend && npm run testcafe -- firefox:headless --test-grep "^(Common|Core)\:*" --test-meta mode=auth --config-file ./testcaferc.json --disable-native-automation "tests/acceptance")
|
||||
test-vitest:
|
||||
$(info Running Vitest unit tests...)
|
||||
(cd frontend && npm run test-vitest)
|
||||
|
||||
test-vitest-watch:
|
||||
$(info Running Vitest unit tests in watch mode...)
|
||||
(cd frontend && npm run test-vitest-watch)
|
||||
|
||||
test-vitest-coverage:
|
||||
$(info Running Vitest unit tests with coverage...)
|
||||
(cd frontend && npm run test-vitest-coverage)
|
||||
|
||||
test-vitest-component:
|
||||
$(info Running Vitest component tests...)
|
||||
(cd frontend && npm run test-vitest-component)
|
||||
|
||||
test-vitest-ui:
|
||||
$(info Opening Vitest UI...)
|
||||
(cd frontend && npm run test-vitest-ui)
|
||||
reset-mariadb:
|
||||
$(info Resetting photoprism database...)
|
||||
mysql < scripts/sql/reset-photoprism.sql
|
||||
|
||||
200
frontend/package-lock.json
generated
200
frontend/package-lock.json
generated
@@ -23,6 +23,7 @@
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@vitejs/plugin-react": "^4.5.2",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vitest/browser": "^3.1.3",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"@vitest/ui": "^3.2.4",
|
||||
"@vue/compiler-sfc": "^3.5.17",
|
||||
@@ -78,6 +79,7 @@
|
||||
"node-storage-shim": "^2.0.1",
|
||||
"passive-events-support": "^1.1.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
"playwright": "^1.52.0",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-import": "^16.1.1",
|
||||
"postcss-loader": "^8.1.1",
|
||||
@@ -4621,7 +4623,6 @@
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-10.4.0.tgz",
|
||||
"integrity": "sha512-pemlzrSESWbdAloYml3bAJMEfNh1Z7EduzqPKprCH5S341frlpYnUEW0H72dLxa6IsYr+mPno20GiSm+h9dEdQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": "^7.10.4",
|
||||
"@babel/runtime": "^7.12.5",
|
||||
@@ -4702,6 +4703,19 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@testing-library/user-event": {
|
||||
"version": "14.6.1",
|
||||
"resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.6.1.tgz",
|
||||
"integrity": "sha512-vq7fv0rnt+QTXgPxr5Hjc210p6YKq2kmdziLgnsZGgLJ9e6VAShx1pACLuRjd/AS/sr7phAR58OIIpf0LlmQNw==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=12",
|
||||
"npm": ">=6"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@testing-library/dom": ">=7.21.4"
|
||||
}
|
||||
},
|
||||
"node_modules/@trysound/sax": {
|
||||
"version": "0.2.0",
|
||||
"resolved": "https://registry.npmjs.org/@trysound/sax/-/sax-0.2.0.tgz",
|
||||
@@ -4715,8 +4729,7 @@
|
||||
"version": "5.0.4",
|
||||
"resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-5.0.4.tgz",
|
||||
"integrity": "sha512-rfT93uj5s0PRL7EzccGMs3brplhcrghnDoV26NqKhCAS1hVo+WdNsPvE/yb6ilfr5hi2MEk6d5EWJTKdxg8jVw==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/babel__core": {
|
||||
"version": "7.20.5",
|
||||
@@ -4977,6 +4990,41 @@
|
||||
"vue": "^3.2.25"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/browser": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/browser/-/browser-3.2.4.tgz",
|
||||
"integrity": "sha512-tJxiPrWmzH8a+w9nLKlQMzAKX/7VjFs50MWgcAj7p9XQ7AQ9/35fByFYptgPELyLw+0aixTnC4pUWV+APcZ/kw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@testing-library/dom": "^10.4.0",
|
||||
"@testing-library/user-event": "^14.6.1",
|
||||
"@vitest/mocker": "3.2.4",
|
||||
"@vitest/utils": "3.2.4",
|
||||
"magic-string": "^0.30.17",
|
||||
"sirv": "^3.0.1",
|
||||
"tinyrainbow": "^2.0.0",
|
||||
"ws": "^8.18.2"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://opencollective.com/vitest"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"playwright": "*",
|
||||
"vitest": "3.2.4",
|
||||
"webdriverio": "^7.0.0 || ^8.0.0 || ^9.0.0"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"playwright": {
|
||||
"optional": true
|
||||
},
|
||||
"safaridriver": {
|
||||
"optional": true
|
||||
},
|
||||
"webdriverio": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/coverage-v8": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/coverage-v8/-/coverage-v8-3.2.4.tgz",
|
||||
@@ -5052,15 +5100,6 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/mocker/node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/@vitest/pretty-format": {
|
||||
"version": "3.2.4",
|
||||
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
|
||||
@@ -5247,6 +5286,12 @@
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-core/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/compiler-dom": {
|
||||
"version": "3.5.17",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-dom/-/compiler-dom-3.5.17.tgz",
|
||||
@@ -5274,6 +5319,12 @@
|
||||
"source-map-js": "^1.2.1"
|
||||
}
|
||||
},
|
||||
"node_modules/@vue/compiler-sfc/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@vue/compiler-ssr": {
|
||||
"version": "3.5.17",
|
||||
"resolved": "https://registry.npmjs.org/@vue/compiler-ssr/-/compiler-ssr-3.5.17.tgz",
|
||||
@@ -6229,15 +6280,6 @@
|
||||
"js-tokens": "^9.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-v8-to-istanbul/node_modules/estree-walker": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/ast-v8-to-istanbul/node_modules/js-tokens": {
|
||||
"version": "9.0.1",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
|
||||
@@ -6701,9 +6743,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/caniuse-lite": {
|
||||
"version": "1.0.30001723",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001723.tgz",
|
||||
"integrity": "sha512-1R/elMjtehrFejxwmexeXAtae5UO9iSyFn6G/I806CYC/BLyyBk1EPhrKBkWhy6wM6Xnm47dSJQec+tLJ39WHw==",
|
||||
"version": "1.0.30001724",
|
||||
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001724.tgz",
|
||||
"integrity": "sha512-WqJo7p0TbHDOythNTqYujmaJTvtYRZrjpP8TCvH6Vb9CYJerJNKamKzIWOM4BkQatWj9H2lYulpdAQNBe7QhNA==",
|
||||
"funding": [
|
||||
{
|
||||
"type": "opencollective",
|
||||
@@ -7697,9 +7739,9 @@
|
||||
"license": "CC0-1.0"
|
||||
},
|
||||
"node_modules/cssstyle": {
|
||||
"version": "4.4.0",
|
||||
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.4.0.tgz",
|
||||
"integrity": "sha512-W0Y2HOXlPkb2yaKrCVRjinYKciu/qSLEmK0K9mcfDei3zwlnHFEHAs/Du3cIRwPqY+J4JsiBzUjoHyc8RsJ03A==",
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/cssstyle/-/cssstyle-4.5.0.tgz",
|
||||
"integrity": "sha512-/7gw8TGrvH/0g564EnhgFZogTMVe+lifpB7LWU+PEsiq5o83TUXR3fDbzTRXOJhoJwck5IS9ez3Em5LNMMO2aw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@asamuzakjp/css-color": "^3.2.0",
|
||||
@@ -8095,8 +8137,7 @@
|
||||
"version": "0.5.16",
|
||||
"resolved": "https://registry.npmjs.org/dom-accessibility-api/-/dom-accessibility-api-0.5.16.tgz",
|
||||
"integrity": "sha512-X7BJ2yElsnOJ30pZF4uIIDfBEVgF4XEBxL9Bxhy6dnrm5hkzqmsWHGTiHqRiITNhMyFLyAiWndIJP7Z1NTteDg==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/dom-serialize": {
|
||||
"version": "2.2.1",
|
||||
@@ -8238,6 +8279,12 @@
|
||||
"pug": "^3.0.2"
|
||||
}
|
||||
},
|
||||
"node_modules/easygettext/node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/editorconfig": {
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
|
||||
@@ -8323,9 +8370,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/electron-to-chromium": {
|
||||
"version": "1.5.170",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.170.tgz",
|
||||
"integrity": "sha512-GP+M7aeluQo9uAyiTCxgIj/j+PrWhMlY7LFVj8prlsPljd0Fdg9AprlfUi+OCSFWy9Y5/2D/Jrj9HS8Z4rpKWA==",
|
||||
"version": "1.5.171",
|
||||
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.171.tgz",
|
||||
"integrity": "sha512-scWpzXEJEMrGJa4Y6m/tVotb0WuvNmasv3wWVzUAeCgKU0ToFOhUW6Z+xWnRQANMYGxN4ngJXIThgBJOqzVPCQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/emmet": {
|
||||
@@ -8850,9 +8897,9 @@
|
||||
}
|
||||
},
|
||||
"node_modules/eslint-module-utils": {
|
||||
"version": "2.12.0",
|
||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.0.tgz",
|
||||
"integrity": "sha512-wALZ0HFoytlyh/1+4wuZ9FJCD/leWHQzzrxJ8+rebyReSLk7LApMyd3WJaLVoN+D5+WIdJyDK1c6JnE65V4Zyg==",
|
||||
"version": "2.12.1",
|
||||
"resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.12.1.tgz",
|
||||
"integrity": "sha512-L8jSWTze7K2mTg0vos/RuLRS5soomksDPoJLXIslC7c8Wmut3bx7CPpJijDcBZtxQ5lrbUdM+s0OlNbz0DCDNw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^3.2.7"
|
||||
@@ -9275,10 +9322,13 @@
|
||||
}
|
||||
},
|
||||
"node_modules/estree-walker": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-2.0.2.tgz",
|
||||
"integrity": "sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==",
|
||||
"license": "MIT"
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
|
||||
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@types/estree": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/esutils": {
|
||||
"version": "2.0.3",
|
||||
@@ -12308,7 +12358,6 @@
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
||||
"integrity": "sha512-h5bgJWpxJNswbU7qCrV0tIKQCaS3blPDrqKWx+QxzuzL1zGUzij9XCWLrSLsJPu5t+eWA/ycetzYAO5IOMcWAQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"lz-string": "bin/bin.js"
|
||||
}
|
||||
@@ -13601,6 +13650,50 @@
|
||||
"node": ">=4"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright": {
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright/-/playwright-1.53.1.tgz",
|
||||
"integrity": "sha512-LJ13YLr/ocweuwxyGf1XNFWIU4M2zUSo149Qbp+A4cpwDjsxRPj7k6H25LBrEHiEwxvRbD8HdwvQmRMSvquhYw==",
|
||||
"license": "Apache-2.0",
|
||||
"dependencies": {
|
||||
"playwright-core": "1.53.1"
|
||||
},
|
||||
"bin": {
|
||||
"playwright": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
},
|
||||
"optionalDependencies": {
|
||||
"fsevents": "2.3.2"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright-core": {
|
||||
"version": "1.53.1",
|
||||
"resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.53.1.tgz",
|
||||
"integrity": "sha512-Z46Oq7tLAyT0lGoFx4DOuB1IA9D1TPj0QkYxpPVUnGDqHHvDpCftu1J2hM2PiWsNMoZh8+LQaarAWcDfPBc6zg==",
|
||||
"license": "Apache-2.0",
|
||||
"bin": {
|
||||
"playwright-core": "cli.js"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=18"
|
||||
}
|
||||
},
|
||||
"node_modules/playwright/node_modules/fsevents": {
|
||||
"version": "2.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz",
|
||||
"integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
"optional": true,
|
||||
"os": [
|
||||
"darwin"
|
||||
],
|
||||
"engines": {
|
||||
"node": "^8.16.0 || ^10.6.0 || >=11.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/plur": {
|
||||
"version": "5.1.0",
|
||||
"resolved": "https://registry.npmjs.org/plur/-/plur-5.1.0.tgz",
|
||||
@@ -15251,7 +15344,6 @@
|
||||
"resolved": "https://registry.npmjs.org/pretty-format/-/pretty-format-27.5.1.tgz",
|
||||
"integrity": "sha512-Qb1gy5OrP5+zDf2Bvnzdl3jsTf1qXVMazbvCoKhtKqVs4/YK4ozX4gKQJJVyNe+cajNPn0KoC0MC3FUmaHWEmQ==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"dependencies": {
|
||||
"ansi-regex": "^5.0.1",
|
||||
"ansi-styles": "^5.0.0",
|
||||
@@ -15266,7 +15358,6 @@
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-5.2.0.tgz",
|
||||
"integrity": "sha512-Cxwpt2SfTzTtXcfOlzGEee8O+c+MmUgGrNiBcXnuWxuFJHe6a5Hz7qwhwe5OgaSYI0IJvkLqWX1ASG+cJOkEiA==",
|
||||
"license": "MIT",
|
||||
"peer": true,
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
@@ -15558,8 +15649,7 @@
|
||||
"version": "17.0.2",
|
||||
"resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz",
|
||||
"integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==",
|
||||
"license": "MIT",
|
||||
"peer": true
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/react-refresh": {
|
||||
"version": "0.17.0",
|
||||
@@ -18990,15 +19080,6 @@
|
||||
"parse5": "^6.0.1"
|
||||
}
|
||||
},
|
||||
"node_modules/vue3-gettext/node_modules/yaml": {
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/vuetify": {
|
||||
"version": "3.8.10",
|
||||
"resolved": "https://registry.npmjs.org/vuetify/-/vuetify-3.8.10.tgz",
|
||||
@@ -19942,17 +20023,12 @@
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/yaml": {
|
||||
"version": "2.8.0",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-2.8.0.tgz",
|
||||
"integrity": "sha512-4lLa/EcQCB0cJkyts+FpIRx5G/llPxfP6VQU5KByHEhLxY3IJCH0f0Hy1MHI8sClTvsIb8qwRJ6R/ZdlDJ/leQ==",
|
||||
"version": "1.10.2",
|
||||
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.2.tgz",
|
||||
"integrity": "sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==",
|
||||
"license": "ISC",
|
||||
"optional": true,
|
||||
"peer": true,
|
||||
"bin": {
|
||||
"yaml": "bin.mjs"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 14.6"
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs": {
|
||||
|
||||
@@ -18,11 +18,11 @@
|
||||
"gettext-extract": "gettext-extract --output src/locales/translations.pot $(find ${SRC:-src} -type f \\( -iname \\*.vue -o -iname \\*.js \\) -not -path src/common/gettext.js)",
|
||||
"lint": "eslint --cache src/ *.js",
|
||||
"test": "karma start",
|
||||
"test-vitest": "vitest run",
|
||||
"test-vitest-watch": "vitest",
|
||||
"test-vitest-coverage": "vitest run --coverage",
|
||||
"test-vitest-component": "vitest run tests/vitest/component",
|
||||
"test-vitest-ui": "vitest --ui",
|
||||
"test-vitest": "env TZ=UTC vitest run",
|
||||
"test-vitest-watch": "env TZ=UTC vitest --watch",
|
||||
"test-vitest-coverage": "env TZ=UTC vitest run --coverage",
|
||||
"test-vitest-component": "env TZ=UTC vitest run tests/vitest/component",
|
||||
"test-vitest-ui": "env TZ=UTC vitest --ui --watch",
|
||||
"testcafe": "testcafe",
|
||||
"trace": "webpack --stats-children",
|
||||
"upgrade": "npm update && npm audit fix",
|
||||
@@ -45,10 +45,13 @@
|
||||
"@testing-library/jest-dom": "^6.6.3",
|
||||
"@testing-library/react": "^16.3.0",
|
||||
"@vitejs/plugin-react": "^4.5.2",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vitest/browser": "^3.1.3",
|
||||
"@vitest/coverage-v8": "^3.2.4",
|
||||
"@vitest/ui": "^3.2.4",
|
||||
"@vue/compiler-sfc": "^3.5.17",
|
||||
"@vue/language-server": "^2.2.10",
|
||||
"@vue/test-utils": "^2.4.6",
|
||||
"@vvo/tzdb": "^6.171.0",
|
||||
"axios": "^1.10.0",
|
||||
"axios-mock-adapter": "^2.1.0",
|
||||
@@ -99,6 +102,7 @@
|
||||
"node-storage-shim": "^2.0.1",
|
||||
"passive-events-support": "^1.1.0",
|
||||
"photoswipe": "^5.4.4",
|
||||
"playwright": "^1.52.0",
|
||||
"postcss": "^8.5.6",
|
||||
"postcss-import": "^16.1.1",
|
||||
"postcss-loader": "^8.1.1",
|
||||
@@ -138,9 +142,7 @@
|
||||
"webpack-manifest-plugin": "^5.0.1",
|
||||
"webpack-md5-hash": "^0.0.6",
|
||||
"webpack-merge": "^6.0.1",
|
||||
"webpack-plugin-vuetify": "^3.1.1",
|
||||
"@vitejs/plugin-vue": "^5.2.4",
|
||||
"@vue/test-utils": "^2.4.6"
|
||||
"webpack-plugin-vuetify": "^3.1.1"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">= 18.0.0",
|
||||
|
||||
62
frontend/tests/vitest/common/api.test.js
Normal file
62
frontend/tests/vitest/common/api.test.js
Normal file
@@ -0,0 +1,62 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { $api } from "../fixtures";
|
||||
|
||||
describe("common/api", () => {
|
||||
const getCollectionResponse = [
|
||||
{ id: 1, name: "John Smith" },
|
||||
{ id: 1, name: "John Smith" },
|
||||
];
|
||||
|
||||
const getEntityResponse = {
|
||||
id: 1,
|
||||
name: "John Smith",
|
||||
};
|
||||
|
||||
const postEntityResponse = {
|
||||
users: [{ id: 1, name: "John Smith" }],
|
||||
};
|
||||
|
||||
const putEntityResponse = {
|
||||
users: [{ id: 2, name: "John Foo" }],
|
||||
};
|
||||
|
||||
const deleteEntityResponse = null;
|
||||
|
||||
it("get should return a list of results and return with HTTP code 200", async () => {
|
||||
const response = await $api.get("foo");
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.data).toEqual(getCollectionResponse);
|
||||
});
|
||||
|
||||
it("get should return one item and return with HTTP code 200", async () => {
|
||||
const response = await $api.get("foo/123");
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.data).toEqual(getEntityResponse);
|
||||
});
|
||||
|
||||
it("post should create one item and return with HTTP code 201", async () => {
|
||||
const response = await $api.post("foo", postEntityResponse);
|
||||
expect(response.status).toBe(201);
|
||||
expect(response.data).toEqual(postEntityResponse);
|
||||
});
|
||||
|
||||
it("put should update one item and return with HTTP code 200", async () => {
|
||||
const response = await $api.put("foo/2", putEntityResponse);
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.data).toEqual(putEntityResponse);
|
||||
});
|
||||
|
||||
it("delete should delete one item and return with HTTP code 204", async () => {
|
||||
const response = await $api.delete("foo/2", deleteEntityResponse);
|
||||
expect(response.status).toBe(204);
|
||||
expect(response.data).toEqual(deleteEntityResponse);
|
||||
});
|
||||
|
||||
/*
|
||||
it("get error", async () => {
|
||||
// Assuming Api.get should be $api.get for this conversion context
|
||||
// If Api is a different client, this test would need adjustment based on that client.
|
||||
await expect($api.get("error")).rejects.toThrow("Request failed with status code 401");
|
||||
});
|
||||
*/
|
||||
});
|
||||
59
frontend/tests/vitest/common/can.test.js
Normal file
59
frontend/tests/vitest/common/can.test.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import "../fixtures";
|
||||
import * as can from "common/can";
|
||||
import { expect, describe, it } from "vitest";
|
||||
|
||||
// These tests are not suitable for running on jsdom
|
||||
|
||||
describe.skip("common/can", () => {
|
||||
it("useVideo", () => {
|
||||
expect(can.useVideo).toBe(true);
|
||||
});
|
||||
|
||||
it("useMp4Avc", () => {
|
||||
expect(can.useMp4Avc).toBe(true);
|
||||
});
|
||||
|
||||
it("useMp4Hvc", () => {
|
||||
expect(can.useMp4Hvc).toBe(false);
|
||||
});
|
||||
|
||||
it("useMp4Hev", () => {
|
||||
expect(can.useMp4Hev).toBe(false);
|
||||
});
|
||||
|
||||
it("useMp4Vvc", () => {
|
||||
expect(can.useMp4Vvc).toBe(false);
|
||||
});
|
||||
|
||||
it("useMp4Evc", () => {
|
||||
expect(can.useMp4Evc).toBe(false);
|
||||
});
|
||||
|
||||
it("useMp4Av1", () => {
|
||||
expect(can.useMp4Av1).toBe(true);
|
||||
});
|
||||
|
||||
it("useVP8", () => {
|
||||
expect(can.useVP8).toBe(true);
|
||||
});
|
||||
|
||||
it("useVP9", () => {
|
||||
expect(can.useVP9).toBe(true);
|
||||
});
|
||||
|
||||
it("useWebmAv1", () => {
|
||||
expect(can.useWebmAv1).toBe(true);
|
||||
});
|
||||
|
||||
it("useMkvAv1", () => {
|
||||
expect(can.useMkvAv1).toBe(false);
|
||||
});
|
||||
|
||||
it("useWebM", () => {
|
||||
expect(can.useWebM).toBe(true);
|
||||
});
|
||||
|
||||
it("useTheora", () => {
|
||||
expect(can.useTheora).toBe(true);
|
||||
});
|
||||
});
|
||||
195
frontend/tests/vitest/common/clipboard.test.js
Normal file
195
frontend/tests/vitest/common/clipboard.test.js
Normal file
@@ -0,0 +1,195 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Clipboard } from "common/clipboard";
|
||||
import Photo from "model/photo";
|
||||
import Album from "model/album";
|
||||
import StorageShim from "node-storage-shim";
|
||||
|
||||
describe("common/clipboard", () => {
|
||||
it("should construct clipboard", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
expect(clipboard.storageKey).toBe("clipboard");
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
});
|
||||
|
||||
it("should toggle model", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.toggle();
|
||||
expect(clipboard.storageKey).toBe("clipboard");
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
|
||||
const values = { ID: 5, UID: "ABC123", Title: "Crazy Cat" };
|
||||
const photo = new Photo(values);
|
||||
clipboard.toggle(photo);
|
||||
expect(clipboard.selection[0]).toBe("ABC123");
|
||||
const values2 = { ID: 8, UID: "ABC124", Title: "Crazy Cat" };
|
||||
const photo2 = new Photo(values2);
|
||||
clipboard.toggle(photo2);
|
||||
expect(clipboard.selection[0]).toBe("ABC123");
|
||||
expect(clipboard.selection[1]).toBe("ABC124");
|
||||
clipboard.toggle(photo);
|
||||
expect(clipboard.selection[0]).toBe("ABC124");
|
||||
});
|
||||
|
||||
it("should toggle id", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.toggleId(3);
|
||||
expect(clipboard.selection[0]).toBe(3);
|
||||
clipboard.toggleId(3);
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
});
|
||||
|
||||
it("should add model", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.add();
|
||||
expect(clipboard.storageKey).toBe("clipboard");
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
|
||||
const values = { ID: 5, UID: "ABC124", Title: "Crazy Cat" };
|
||||
const photo = new Photo(values);
|
||||
clipboard.add(photo);
|
||||
expect(clipboard.selection[0]).toBe("ABC124");
|
||||
clipboard.add(photo);
|
||||
expect(clipboard.selection[0]).toBe("ABC124");
|
||||
});
|
||||
|
||||
it("should add id", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.addId(99);
|
||||
expect(clipboard.selection[0]).toBe(99);
|
||||
});
|
||||
|
||||
it("should test whether clipboard has model", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.has();
|
||||
expect(clipboard.storageKey).toBe("clipboard");
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
|
||||
const values = { ID: 5, UID: "ABC124", Title: "Crazy Cat" };
|
||||
const photo = new Photo(values);
|
||||
clipboard.add(photo);
|
||||
expect(clipboard.selection[0]).toBe("ABC124");
|
||||
const result = clipboard.has(photo);
|
||||
expect(result).toBe(true);
|
||||
const values2 = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values2);
|
||||
const result2 = clipboard.has(album);
|
||||
expect(result2).toBe(false);
|
||||
});
|
||||
|
||||
it("should test whether clipboard has id", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.addId(77);
|
||||
expect(clipboard.hasId(77)).toBe(true);
|
||||
expect(clipboard.hasId(78)).toBe(false);
|
||||
});
|
||||
|
||||
it("should remove model", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.remove();
|
||||
expect(clipboard.storageKey).toBe("clipboard");
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
|
||||
const values = { ID: 5, UID: "ABC123", Title: "Crazy Cat" };
|
||||
const photo = new Photo(values);
|
||||
clipboard.add(photo);
|
||||
expect(clipboard.selection[0]).toBe("ABC123");
|
||||
|
||||
clipboard.remove(photo);
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
const values2 = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values2);
|
||||
clipboard.remove(album);
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
});
|
||||
|
||||
it("should set and get ids", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.setIds(8);
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
clipboard.setIds([5, 6, 9]);
|
||||
expect(clipboard.selection[0]).toBe(5);
|
||||
expect(clipboard.selection[2]).toBe(9);
|
||||
const result = clipboard.getIds();
|
||||
expect(result[1]).toBe(6);
|
||||
expect(result.length).toBe(3);
|
||||
});
|
||||
|
||||
it("should clear", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
clipboard.setIds([5, 6, 9]);
|
||||
expect(clipboard.selection[0]).toBe(5);
|
||||
clipboard.clear();
|
||||
expect(clipboard.selection).toEqual([]);
|
||||
});
|
||||
|
||||
it("should add range", () => {
|
||||
const storage = new StorageShim();
|
||||
const key = "clipboard";
|
||||
const clipboard = new Clipboard(storage, key);
|
||||
clipboard.clear();
|
||||
const values = { ID: 5, UID: "ABC124", Title: "Crazy Cat" };
|
||||
const photo = new Photo(values);
|
||||
const values2 = { ID: 6, UID: "ABC125", Title: "Crazy Dog" };
|
||||
const photo2 = new Photo(values2);
|
||||
const values3 = { ID: 7, UID: "ABC128", Title: "Cute Dog" };
|
||||
const photo3 = new Photo(values3);
|
||||
const values4 = { ID: 8, UID: "ABC129", Title: "Turtle" };
|
||||
const photo4 = new Photo(values4);
|
||||
const Photos = [photo, photo2, photo3, photo4];
|
||||
clipboard.addRange(2);
|
||||
expect(clipboard.selection.length).toBe(0);
|
||||
clipboard.clear();
|
||||
clipboard.addRange(2, Photos);
|
||||
expect(clipboard.selection[0]).toBe("ABC128");
|
||||
expect(clipboard.selection.length).toBe(1);
|
||||
clipboard.addRange(1, Photos);
|
||||
expect(clipboard.selection.length).toBe(2);
|
||||
expect(clipboard.selection[0]).toBe("ABC128");
|
||||
expect(clipboard.selection[1]).toBe("ABC125");
|
||||
clipboard.clear();
|
||||
clipboard.add(photo);
|
||||
expect(clipboard.selection.length).toBe(1);
|
||||
clipboard.addRange(3, Photos);
|
||||
expect(clipboard.selection.length).toBe(4);
|
||||
});
|
||||
});
|
||||
320
frontend/tests/vitest/common/config.test.js
Normal file
320
frontend/tests/vitest/common/config.test.js
Normal file
@@ -0,0 +1,320 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import Config from "common/config";
|
||||
import StorageShim from "node-storage-shim";
|
||||
|
||||
const defaultConfig = new Config(new StorageShim(), window.__CONFIG__);
|
||||
|
||||
describe("common/config", () => {
|
||||
it("should get all config values", () => {
|
||||
const storage = new StorageShim();
|
||||
const values = { siteTitle: "Foo", name: "testConfig", year: "2300" };
|
||||
|
||||
const cfg = new Config(storage, values);
|
||||
const result = cfg.getValues();
|
||||
expect(result.name).toBe("testConfig");
|
||||
});
|
||||
|
||||
it("should set multiple config values", () => {
|
||||
const storage = new StorageShim();
|
||||
const values = {
|
||||
siteTitle: "Foo",
|
||||
country: "Germany",
|
||||
city: "Hamburg",
|
||||
settings: { ui: { language: "de", theme: "default" } },
|
||||
};
|
||||
const newValues = {
|
||||
siteTitle: "Foo",
|
||||
new: "xxx",
|
||||
city: "Berlin",
|
||||
debug: true,
|
||||
settings: { ui: { language: "en", theme: "lavender" } },
|
||||
};
|
||||
const cfg = new Config(storage, values);
|
||||
expect(cfg.values.settings.ui.theme).toBe("default");
|
||||
expect(cfg.values.settings.ui.language).toBe("de");
|
||||
expect(cfg.values.new).toBeUndefined();
|
||||
expect(cfg.values.city).toBe("Hamburg");
|
||||
cfg.setValues();
|
||||
expect(cfg.values.new).toBeUndefined();
|
||||
expect(cfg.values.city).toBe("Hamburg");
|
||||
cfg.setValues(newValues);
|
||||
const result = cfg.getValues();
|
||||
expect(result.city).toBe("Berlin");
|
||||
expect(result.new).toBe("xxx");
|
||||
expect(result.country).toBe("Germany");
|
||||
expect(cfg.values.settings.ui.theme).toBe("lavender");
|
||||
expect(cfg.values.settings.ui.language).toBe("en");
|
||||
});
|
||||
|
||||
it("should test constructor with empty values", () => {
|
||||
const storage = new StorageShim();
|
||||
const values = {};
|
||||
const config = new Config(storage, values);
|
||||
expect(config.debug).toBe(true);
|
||||
expect(config.demo).toBe(false);
|
||||
expect(config.apiUri).toBe("/api/v1");
|
||||
});
|
||||
|
||||
it("should store values", () => {
|
||||
const storage = new StorageShim();
|
||||
const values = { siteTitle: "Foo", country: "Germany", city: "Hamburg" };
|
||||
const config = new Config(storage, values);
|
||||
expect(config.storage["config"]).toBe(null);
|
||||
config.storeValues();
|
||||
const expected = '{"siteTitle":"Foo","country":"Germany","city":"Hamburg"}';
|
||||
expect(config.storage["config"]).toBe(expected);
|
||||
});
|
||||
|
||||
it("should return the develop feature flag value", () => {
|
||||
expect(defaultConfig.featDevelop()).toBe(true);
|
||||
});
|
||||
|
||||
it("should return the experimental feature flag value", () => {
|
||||
expect(defaultConfig.featExperimental()).toBe(true);
|
||||
});
|
||||
|
||||
it("should return the preview feature flag value", () => {
|
||||
expect(defaultConfig.featPreview()).toBe(true);
|
||||
});
|
||||
|
||||
it("should set and get single config value", () => {
|
||||
const storage = new StorageShim();
|
||||
const values = { siteTitle: "Foo", country: "Germany", city: "Hamburg" };
|
||||
|
||||
const config = new Config(storage, values);
|
||||
config.set("city", "Berlin");
|
||||
const result = config.get("city");
|
||||
expect(result).toBe("Berlin");
|
||||
});
|
||||
|
||||
it("should return app about", () => {
|
||||
expect(defaultConfig.getAbout()).toBe("PhotoPrism® CE");
|
||||
});
|
||||
|
||||
it("should return app edition", () => {
|
||||
expect(defaultConfig.getEdition()).toBe("ce");
|
||||
});
|
||||
|
||||
it("should return settings", () => {
|
||||
const result = defaultConfig.getSettings();
|
||||
expect(result.ui.theme).toBe("default");
|
||||
expect(result.ui.language).toBe("en");
|
||||
});
|
||||
|
||||
it("should return feature", () => {
|
||||
expect(defaultConfig.feature("places")).toBe(true);
|
||||
expect(defaultConfig.feature("download")).toBe(true);
|
||||
});
|
||||
|
||||
it("should test get name", () => {
|
||||
const result = defaultConfig.getPerson("a");
|
||||
expect(result).toBeNull();
|
||||
|
||||
const result2 = defaultConfig.getPerson("Andrea Sander");
|
||||
expect(result2.UID).toBe("jr0jgyx2viicdnf7");
|
||||
|
||||
const result3 = defaultConfig.getPerson("Otto Sander");
|
||||
expect(result3.UID).toBe("jr0jgyx2viicdn88");
|
||||
});
|
||||
|
||||
it("should create, update and delete people", () => {
|
||||
const storage = new StorageShim();
|
||||
const values = { Debug: true, siteTitle: "Foo", country: "Germany", city: "Hamburg" };
|
||||
|
||||
const cfg = new Config(storage, values);
|
||||
cfg.onPeople("people.created", { entities: {} });
|
||||
expect(cfg.values.people).toEqual([]);
|
||||
cfg.onPeople("people.created", {
|
||||
entities: [
|
||||
{
|
||||
UID: "abc123",
|
||||
Name: "Test Name",
|
||||
Keywords: ["Test", "Name"],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(cfg.values.people[0].Name).toBe("Test Name");
|
||||
cfg.onPeople("people.updated", {
|
||||
entities: [
|
||||
{
|
||||
UID: "abc123",
|
||||
Name: "New Name",
|
||||
Keywords: ["New", "Name"],
|
||||
},
|
||||
],
|
||||
});
|
||||
expect(cfg.values.people[0].Name).toBe("New Name");
|
||||
cfg.onPeople("people.deleted", {
|
||||
entities: ["abc123"],
|
||||
});
|
||||
expect(cfg.values.people).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return language locale", () => {
|
||||
const cfg = new Config(new StorageShim(), Object.assign({}, window.__CONFIG__));
|
||||
expect(cfg.getLanguageLocale()).toBe("en");
|
||||
});
|
||||
|
||||
it("should return user time zone", () => {
|
||||
const cfg = new Config(new StorageShim(), Object.assign({}, window.__CONFIG__));
|
||||
expect(cfg.getTimeZone()).toBe("Local");
|
||||
});
|
||||
|
||||
it("should return if language is rtl", () => {
|
||||
const cfg = new Config(new StorageShim(), Object.assign({}, window.__CONFIG__));
|
||||
const result = cfg.isRtl();
|
||||
expect(result).toBe(false);
|
||||
const newValues = {
|
||||
Debug: true,
|
||||
siteTitle: "Foo",
|
||||
country: "Germany",
|
||||
city: "Hamburg",
|
||||
settings: {
|
||||
ui: {
|
||||
language: "he",
|
||||
},
|
||||
},
|
||||
};
|
||||
cfg.setValues(newValues);
|
||||
const result2 = cfg.isRtl();
|
||||
expect(result2).toBe(true);
|
||||
const values2 = { siteTitle: "Foo" };
|
||||
const storage = new StorageShim();
|
||||
const config3 = new Config(storage, values2);
|
||||
const result3 = config3.isRtl();
|
||||
expect(result3).toBe(false);
|
||||
cfg.setLanguage("en");
|
||||
});
|
||||
|
||||
it("should return album categories", () => {
|
||||
const cfg = new Config(new StorageShim(), Object.assign({}, window.__CONFIG__));
|
||||
const result = cfg.albumCategories();
|
||||
expect(result[0]).toBe("Animal");
|
||||
const newValues = {
|
||||
albumCategories: ["Mouse"],
|
||||
};
|
||||
cfg.setValues(newValues);
|
||||
const result2 = cfg.albumCategories();
|
||||
expect(result2[0]).toBe("Mouse");
|
||||
});
|
||||
|
||||
it("should update counts", () => {
|
||||
const cfg = new Config(new StorageShim(), Object.assign({}, window.__CONFIG__));
|
||||
expect(cfg.values.count.all).toBe(133);
|
||||
expect(cfg.values.count.photos).toBe(132);
|
||||
cfg.onCount("add.photos", {
|
||||
count: 2,
|
||||
});
|
||||
expect(cfg.values.count.all).toBe(135);
|
||||
expect(cfg.values.count.photos).toBe(134);
|
||||
expect(cfg.values.count.videos).toBe(1);
|
||||
cfg.onCount("add.videos", {
|
||||
count: 1,
|
||||
});
|
||||
expect(cfg.values.count.all).toBe(136);
|
||||
expect(cfg.values.count.videos).toBe(2);
|
||||
expect(cfg.values.count.cameras).toBe(6);
|
||||
cfg.onCount("add.cameras", {
|
||||
count: 3,
|
||||
});
|
||||
expect(cfg.values.count.all).toBe(136);
|
||||
expect(cfg.values.count.cameras).toBe(9);
|
||||
expect(cfg.values.count.lenses).toBe(5);
|
||||
cfg.onCount("add.lenses", {
|
||||
count: 1,
|
||||
});
|
||||
expect(cfg.values.count.lenses).toBe(6);
|
||||
expect(cfg.values.count.countries).toBe(6);
|
||||
cfg.onCount("add.countries", {
|
||||
count: 2,
|
||||
});
|
||||
expect(cfg.values.count.countries).toBe(8);
|
||||
expect(cfg.values.count.states).toBe(8);
|
||||
cfg.onCount("add.states", {
|
||||
count: 1,
|
||||
});
|
||||
expect(cfg.values.count.states).toBe(9);
|
||||
expect(cfg.values.count.people).toBe(5);
|
||||
cfg.onCount("add.people", {
|
||||
count: 4,
|
||||
});
|
||||
expect(cfg.values.count.people).toBe(9);
|
||||
expect(cfg.values.count.places).toBe(17);
|
||||
cfg.onCount("add.places", {
|
||||
count: 1,
|
||||
});
|
||||
expect(cfg.values.count.places).toBe(18);
|
||||
expect(cfg.values.count.labels).toBe(22);
|
||||
cfg.onCount("add.labels", {
|
||||
count: 2,
|
||||
});
|
||||
expect(cfg.values.count.labels).toBe(24);
|
||||
expect(cfg.values.count.albums).toBe(2);
|
||||
cfg.onCount("add.albums", {
|
||||
count: 3,
|
||||
});
|
||||
expect(cfg.values.count.albums).toBe(5);
|
||||
expect(cfg.values.count.moments).toBe(4);
|
||||
cfg.onCount("add.moments", {
|
||||
count: 1,
|
||||
});
|
||||
expect(cfg.values.count.moments).toBe(5);
|
||||
expect(cfg.values.count.months).toBe(27);
|
||||
cfg.onCount("add.months", {
|
||||
count: 4,
|
||||
});
|
||||
expect(cfg.values.count.months).toBe(31);
|
||||
expect(cfg.values.count.folders).toBe(23);
|
||||
cfg.onCount("add.folders", {
|
||||
count: 2,
|
||||
});
|
||||
expect(cfg.values.count.folders).toBe(25);
|
||||
expect(cfg.values.count.files).toBe(136);
|
||||
cfg.onCount("add.files", {
|
||||
count: 14,
|
||||
});
|
||||
expect(cfg.values.count.files).toBe(150);
|
||||
expect(cfg.values.count.favorites).toBe(1);
|
||||
cfg.onCount("add.favorites", {
|
||||
count: 4,
|
||||
});
|
||||
expect(cfg.values.count.favorites).toBe(5);
|
||||
expect(cfg.values.count.review).toBe(22);
|
||||
cfg.onCount("add.review", {
|
||||
count: 1,
|
||||
});
|
||||
expect(cfg.values.count.all).toBe(135);
|
||||
expect(cfg.values.count.review).toBe(23);
|
||||
expect(cfg.values.count.private).toBe(0);
|
||||
cfg.onCount("add.private", {
|
||||
count: 3,
|
||||
});
|
||||
expect(cfg.values.count.private).toBe(3);
|
||||
expect(cfg.values.count.all).toBe(135);
|
||||
cfg.onCount("add.photos", {
|
||||
count: 4,
|
||||
});
|
||||
expect(cfg.values.count.all).toBe(139);
|
||||
});
|
||||
|
||||
it("should return user interface direction string", async () => {
|
||||
const cfg = new Config(new StorageShim(), Object.assign({}, window.__CONFIG__));
|
||||
await cfg.setLanguage("en", true);
|
||||
expect(document.dir).toBe("ltr");
|
||||
expect(cfg.dir()).toBe("ltr");
|
||||
expect(cfg.dir(true)).toBe("rtl");
|
||||
expect(cfg.dir(false)).toBe("ltr");
|
||||
await cfg.setLanguage("he", false);
|
||||
expect(document.dir).toBe("ltr");
|
||||
await cfg.setLanguage("he", true);
|
||||
expect(cfg.dir()).toBe("rtl");
|
||||
expect(document.dir).toBe("rtl");
|
||||
expect(cfg.dir()).toBe("rtl");
|
||||
expect(cfg.dir(true)).toBe("rtl");
|
||||
expect(cfg.dir(false)).toBe("ltr");
|
||||
await cfg.setLanguage("en", true);
|
||||
expect(document.dir).toBe("ltr");
|
||||
expect(cfg.dir()).toBe("ltr");
|
||||
});
|
||||
});
|
||||
130
frontend/tests/vitest/common/form.test.js
Normal file
130
frontend/tests/vitest/common/form.test.js
Normal file
@@ -0,0 +1,130 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Form, FormPropertyType } from "common/form";
|
||||
|
||||
describe("common/form", () => {
|
||||
it("setting and getting definition", () => {
|
||||
const def = { foo: { type: FormPropertyType.String, caption: "Foo" } };
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
|
||||
const result = form.getDefinition();
|
||||
expect(result).toBe(def);
|
||||
});
|
||||
|
||||
it("setting and getting a value according to type", () => {
|
||||
const def = {
|
||||
foo: { type: FormPropertyType.String, caption: "Foo" },
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
form.setValue("foo", "test");
|
||||
|
||||
const result = form.getValue("foo");
|
||||
expect(result).toBe("test");
|
||||
});
|
||||
|
||||
it("setting a value not according to type", () => {
|
||||
const def = {
|
||||
foo: { type: FormPropertyType.String, caption: "Foo" },
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
|
||||
expect(() => {
|
||||
form.setValue("foo", 3);
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("setting and getting a value for missing property throws exception", () => {
|
||||
const def = {
|
||||
foo: { type: FormPropertyType.String, caption: "Foo" },
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
|
||||
expect(() => {
|
||||
form.setValue("bar", 3);
|
||||
}).toThrow();
|
||||
|
||||
expect(() => {
|
||||
form.getValue("bar");
|
||||
}).toThrow();
|
||||
});
|
||||
|
||||
it("setting and getting a complex value", () => {
|
||||
const complexValue = {
|
||||
something: "abc",
|
||||
another: "def",
|
||||
};
|
||||
const def = {
|
||||
foo: {
|
||||
type: FormPropertyType.Object,
|
||||
caption: "Foo",
|
||||
},
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
form.setValue("foo", complexValue);
|
||||
|
||||
const result = form.getValue("foo");
|
||||
expect(result).toEqual(complexValue);
|
||||
});
|
||||
|
||||
it("setting and getting more values at once", () => {
|
||||
const def = {
|
||||
foo: { type: FormPropertyType.String, caption: "Foo" },
|
||||
baz: { type: FormPropertyType.String, caption: "XX" },
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
form.setValues({ foo: "test", baz: "yyy" });
|
||||
|
||||
const result = form.getValues();
|
||||
expect(result.foo).toBe("test");
|
||||
expect(result.baz).toBe("yyy");
|
||||
});
|
||||
|
||||
it("getting options of fieldname", () => {
|
||||
const def = {
|
||||
search: {
|
||||
type: FormPropertyType.String,
|
||||
caption: "Search",
|
||||
label: { options: "tiles", text: "Tiles" },
|
||||
options: [
|
||||
{ value: "tiles", text: "Tiles" },
|
||||
{ value: "mosaic", text: "Mosaic" },
|
||||
],
|
||||
},
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
|
||||
const result = form.getOptions("search");
|
||||
expect(result[0].value).toBe("tiles");
|
||||
expect(result[1].text).toBe("Mosaic");
|
||||
});
|
||||
|
||||
it("getting not existing options returns empty object", () => {
|
||||
const def = {
|
||||
foo: {
|
||||
type: FormPropertyType.Object,
|
||||
caption: "Foo",
|
||||
},
|
||||
};
|
||||
const form = new Form();
|
||||
|
||||
form.setDefinition(def);
|
||||
|
||||
const result = form.getOptions("foo");
|
||||
expect(result[0].option).toBe("");
|
||||
expect(result[0].label).toBe("");
|
||||
});
|
||||
});
|
||||
25
frontend/tests/vitest/common/notify.test.js
Normal file
25
frontend/tests/vitest/common/notify.test.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { describe, it } from "vitest";
|
||||
import "../fixtures";
|
||||
import $notify from "common/notify";
|
||||
|
||||
describe("common/alert", () => {
|
||||
it("should call alert.info", () => {
|
||||
$notify.info("message");
|
||||
});
|
||||
|
||||
it("should call alert.warning", () => {
|
||||
$notify.warn("message");
|
||||
});
|
||||
|
||||
it("should call alert.error", () => {
|
||||
$notify.error("message");
|
||||
});
|
||||
|
||||
it("should call alert.success", () => {
|
||||
$notify.success("message");
|
||||
});
|
||||
|
||||
it("should call wait", () => {
|
||||
$notify.wait();
|
||||
});
|
||||
});
|
||||
269
frontend/tests/vitest/common/session.test.js
Normal file
269
frontend/tests/vitest/common/session.test.js
Normal file
@@ -0,0 +1,269 @@
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import "../fixtures";
|
||||
import { $config } from "app/session";
|
||||
import Session from "common/session";
|
||||
import StorageShim from "node-storage-shim";
|
||||
|
||||
describe("common/session", () => {
|
||||
beforeEach(() => {
|
||||
window.onbeforeunload = () => "Oh no!";
|
||||
});
|
||||
|
||||
it("should construct session", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
expect(session.authToken).toBe(null);
|
||||
});
|
||||
|
||||
it("should set, get and delete token", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
expect(session.hasToken("2lbh9x09")).toBe(false);
|
||||
session.setAuthToken("999900000000000000000000000000000000000000000000");
|
||||
expect(session.authToken).toBe("999900000000000000000000000000000000000000000000");
|
||||
const result = session.getAuthToken();
|
||||
expect(result).toBe("999900000000000000000000000000000000000000000000");
|
||||
session.reset();
|
||||
expect(session.authToken).toBe(null);
|
||||
});
|
||||
|
||||
it("should set, get and delete user", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
expect(session.user.hasId()).toBe(false);
|
||||
|
||||
const user = {
|
||||
ID: 5,
|
||||
NickName: "Foo",
|
||||
GivenName: "Max",
|
||||
DisplayName: "Max Example",
|
||||
Email: "test@test.com",
|
||||
SuperAdmin: true,
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const data = {
|
||||
user,
|
||||
};
|
||||
|
||||
expect(session.hasId()).toBe(false);
|
||||
expect(session.hasAuthToken()).toBe(false);
|
||||
expect(session.isAuthenticated()).toBe(false);
|
||||
expect(session.hasProvider()).toBe(false);
|
||||
session.setData();
|
||||
expect(session.user.DisplayName).toBe("");
|
||||
session.setData(data);
|
||||
expect(session.hasId()).toBe(false);
|
||||
expect(session.hasAuthToken()).toBe(false);
|
||||
expect(session.hasProvider()).toBe(false);
|
||||
session.setId("a9b8ff820bf40ab451910f8bbfe401b2432446693aa539538fbd2399560a722f");
|
||||
session.setAuthToken("234200000000000000000000000000000000000000000000");
|
||||
session.setProvider("public");
|
||||
expect(session.hasId()).toBe(true);
|
||||
expect(session.hasAuthToken()).toBe(true);
|
||||
expect(session.isAuthenticated()).toBe(true);
|
||||
expect(session.hasProvider()).toBe(true);
|
||||
expect(session.user.DisplayName).toBe("Max Example");
|
||||
expect(session.user.SuperAdmin).toBe(true);
|
||||
expect(session.user.Role).toBe("admin");
|
||||
session.reset();
|
||||
expect(session.user.DisplayName).toBe("");
|
||||
expect(session.user.SuperAdmin).toBe(false);
|
||||
expect(session.user.Role).toBe("");
|
||||
session.setUser(user);
|
||||
expect(session.user.DisplayName).toBe("Max Example");
|
||||
expect(session.user.SuperAdmin).toBe(true);
|
||||
expect(session.user.Role).toBe("admin");
|
||||
|
||||
const result = session.getUser();
|
||||
|
||||
expect(result.DisplayName).toBe("Max Example");
|
||||
expect(result.SuperAdmin).toBe(true);
|
||||
expect(result.Role).toBe("admin");
|
||||
expect(result.Email).toBe("test@test.com");
|
||||
expect(result.ID).toBe(5);
|
||||
session.deleteData();
|
||||
expect(session.user.hasId()).toBe(true);
|
||||
session.deleteUser();
|
||||
expect(session.user.hasId()).toBe(false);
|
||||
});
|
||||
|
||||
it("should get user email", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
|
||||
session.setId("a9b8ff820bf40ab451910f8bbfe401b2432446693aa539538fbd2399560a722f");
|
||||
session.setAuthToken("234200000000000000000000000000000000000000000000");
|
||||
session.setProvider("public");
|
||||
|
||||
const values = {
|
||||
user: {
|
||||
ID: 5,
|
||||
Name: "foo",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
|
||||
session.setData(values);
|
||||
const result = session.getEmail();
|
||||
expect(result).toBe("test@test.com");
|
||||
const values2 = {
|
||||
user: {
|
||||
Name: "foo",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values2);
|
||||
const result2 = session.getEmail();
|
||||
expect(result2).toBe("");
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should get user display name", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
const values = {
|
||||
user: {
|
||||
ID: 5,
|
||||
Name: "foo",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values);
|
||||
const result = session.getDisplayName();
|
||||
expect(result).toBe("Max Last");
|
||||
const values2 = {
|
||||
id: "a9b8ff820bf40ab451910f8bbfe401b2432446693aa539538fbd2399560a722f",
|
||||
access_token: "234200000000000000000000000000000000000000000000",
|
||||
provider: "public",
|
||||
data: {},
|
||||
user: {
|
||||
ID: 5,
|
||||
Name: "bar",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values2);
|
||||
const result2 = session.getDisplayName();
|
||||
expect(result2).toBe("Bar");
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should get user full name", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
const values = {
|
||||
user: {
|
||||
ID: 5,
|
||||
Name: "foo",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values);
|
||||
const result = session.getDisplayName();
|
||||
expect(result).toBe("Max Last");
|
||||
const values2 = {
|
||||
user: {
|
||||
Name: "bar",
|
||||
DisplayName: "Max New",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values2);
|
||||
const result2 = session.getDisplayName();
|
||||
expect(result2).toBe("");
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should test whether user is set", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
const values = {
|
||||
user: {
|
||||
ID: 5,
|
||||
Name: "foo",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values);
|
||||
const result = session.isUser();
|
||||
expect(result).toBe(true);
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should test whether user is admin", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
const values = {
|
||||
user: {
|
||||
ID: 5,
|
||||
Name: "foo",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values);
|
||||
const result = session.isAdmin();
|
||||
expect(result).toBe(true);
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should test whether user is anonymous", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
const values = {
|
||||
user: {
|
||||
ID: 5,
|
||||
DisplayName: "Foo",
|
||||
FullName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
},
|
||||
};
|
||||
session.setData(values);
|
||||
const result = session.isAnonymous();
|
||||
expect(result).toBe(false);
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should use session storage", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
expect(storage.getItem("session")).toBe(null);
|
||||
session.useSessionStorage();
|
||||
expect(storage.getItem("session")).toBe("true");
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should use local storage", () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
expect(storage.getItem("session")).toBe(null);
|
||||
session.useLocalStorage();
|
||||
expect(storage.getItem("session")).toBe("false");
|
||||
session.deleteData();
|
||||
});
|
||||
|
||||
it("should test redeem token", async () => {
|
||||
const storage = new StorageShim();
|
||||
const session = new Session(storage, $config);
|
||||
expect(session.data).toBe(null);
|
||||
await session.redeemToken("token123");
|
||||
expect(session.data.token).toBe("123token");
|
||||
session.deleteData();
|
||||
});
|
||||
});
|
||||
@@ -1,108 +1,219 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import $util from "common/util";
|
||||
import { tokenRegexp, tokenLength } from "common/util";
|
||||
import * as can from "common/can";
|
||||
import { ContentTypeMp4AvcMain, ContentTypeMp4HvcMain } from "common/media";
|
||||
|
||||
describe("$util", () => {
|
||||
describe("formatBytes", () => {
|
||||
it("should format bytes as KB", () => {
|
||||
expect($util.formatBytes(1000)).toBe("1 KB");
|
||||
expect($util.formatBytes(2000)).toBe("2 KB");
|
||||
expect($util.formatBytes("3000")).toBe("3 KB");
|
||||
});
|
||||
|
||||
it("should format bytes as MB", () => {
|
||||
expect($util.formatBytes(1048576)).toBe("1.0 MB");
|
||||
expect($util.formatBytes(2097152)).toBe("2.0 MB");
|
||||
expect($util.formatBytes(3145728)).toBe("3.0 MB");
|
||||
});
|
||||
|
||||
it("should format bytes as GB", () => {
|
||||
expect($util.formatBytes(1073741824)).toBe("1.0 GB");
|
||||
expect($util.formatBytes(2147483648)).toBe("2.0 GB");
|
||||
expect($util.formatBytes(3221225472)).toBe("3.0 GB");
|
||||
});
|
||||
|
||||
it("should handle zero and falsy values", () => {
|
||||
expect($util.formatBytes(0)).toBe("0 KB");
|
||||
expect($util.formatBytes(null)).toBe("0 KB");
|
||||
expect($util.formatBytes(undefined)).toBe("0 KB");
|
||||
expect($util.formatBytes("")).toBe("0 KB");
|
||||
});
|
||||
describe("common/util", () => {
|
||||
it("should return size in KB", () => {
|
||||
const s = $util.formatBytes(10 * 1024);
|
||||
expect(s).toBe("10 KB");
|
||||
});
|
||||
|
||||
describe("truncate", () => {
|
||||
it("should truncate text longer than specified length", () => {
|
||||
expect($util.truncate("This is a test", 7)).toBe("This i…");
|
||||
expect($util.truncate("Hello world!", 5)).toBe("Hell…");
|
||||
});
|
||||
|
||||
it("should not truncate text shorter than specified length", () => {
|
||||
expect($util.truncate("Test", 10)).toBe("Test");
|
||||
expect($util.truncate("Short", 10)).toBe("Short");
|
||||
});
|
||||
|
||||
it("should use custom ending if specified", () => {
|
||||
expect($util.truncate("This is a test", 7, "...")).toBe("This...");
|
||||
expect($util.truncate("Hello world!", 5, " [more]")).toBe(" [more]");
|
||||
});
|
||||
|
||||
it("should use default values if not specified", () => {
|
||||
expect($util.truncate("This is a very long text that should be truncated")).toBe(
|
||||
"This is a very long text that should be truncated"
|
||||
);
|
||||
// Default length is 100 characters
|
||||
});
|
||||
it("should return size in GB", () => {
|
||||
const s = $util.formatBytes(10 * 1024 * 1024 * 1024);
|
||||
expect(s).toBe("10.0 GB");
|
||||
});
|
||||
|
||||
describe("capitalize", () => {
|
||||
it("should capitalize first letter of each word", () => {
|
||||
expect($util.capitalize("hello world")).toBe("Hello World");
|
||||
expect($util.capitalize("test string")).toBe("Test String");
|
||||
});
|
||||
|
||||
it("should handle empty strings", () => {
|
||||
expect($util.capitalize("")).toBe("");
|
||||
expect($util.capitalize(null)).toBe("");
|
||||
expect($util.capitalize(undefined)).toBe("");
|
||||
});
|
||||
|
||||
it("should handle already capitalized text", () => {
|
||||
expect($util.capitalize("Hello World")).toBe("Hello World");
|
||||
expect($util.capitalize("HELLO WORLD")).toBe("HELLO WORLD");
|
||||
});
|
||||
it("should convert bytes in GB", () => {
|
||||
const b = $util.gigaBytes(10 * 1024 * 1024 * 1024);
|
||||
expect(b).toBe(10);
|
||||
});
|
||||
|
||||
describe("ucFirst", () => {
|
||||
it("should capitalize only first letter of string", () => {
|
||||
expect($util.ucFirst("hello world")).toBe("Hello world");
|
||||
expect($util.ucFirst("test string")).toBe("Test string");
|
||||
});
|
||||
|
||||
it("should handle empty strings", () => {
|
||||
expect($util.ucFirst("")).toBe("");
|
||||
expect($util.ucFirst(null)).toBe("");
|
||||
expect($util.ucFirst(undefined)).toBe("");
|
||||
});
|
||||
|
||||
it("should handle already capitalized text", () => {
|
||||
expect($util.ucFirst("Hello world")).toBe("Hello world");
|
||||
expect($util.ucFirst("HELLO world")).toBe("HELLO world");
|
||||
});
|
||||
it("should return duration 3ns", () => {
|
||||
const duration = $util.formatDuration(-3);
|
||||
expect(duration).toBe("3ns");
|
||||
});
|
||||
it("should return duration 0s", () => {
|
||||
const duration = $util.formatDuration(0);
|
||||
expect(duration).toBe("0s");
|
||||
});
|
||||
it("should return duration 2µs", () => {
|
||||
const duration = $util.formatDuration(2000);
|
||||
expect(duration).toBe("2µs");
|
||||
});
|
||||
it("should return duration 4ms", () => {
|
||||
const duration = $util.formatDuration(4000000);
|
||||
expect(duration).toBe("4ms");
|
||||
});
|
||||
it("should return duration 6s", () => {
|
||||
const duration = $util.formatDuration(6000000000);
|
||||
expect(duration).toBe("0:06");
|
||||
});
|
||||
it("should return duration 10min", () => {
|
||||
const duration = $util.formatDuration(600000000000);
|
||||
expect(duration).toBe("10:00");
|
||||
});
|
||||
it("should return formatted seconds", () => {
|
||||
const floor = $util.formatSeconds(Math.floor(65.4));
|
||||
expect(floor).toBe("1:05");
|
||||
const ceil = $util.formatSeconds(Math.ceil(65.4));
|
||||
expect(ceil).toBe("1:06");
|
||||
const unknown = $util.formatSeconds(0);
|
||||
expect(unknown).toBe("0:00");
|
||||
const negative = $util.formatSeconds(-1);
|
||||
expect(negative).toBe("0:00");
|
||||
});
|
||||
it("should return remaining seconds", () => {
|
||||
const t = 23.3;
|
||||
const d = 42.6;
|
||||
const time = $util.formatSeconds(Math.floor(t));
|
||||
expect(time).toBe("0:23");
|
||||
const duration = $util.formatRemainingSeconds(0.0, d);
|
||||
expect(duration).toBe("0:43");
|
||||
const difference = $util.formatRemainingSeconds(t, d);
|
||||
expect(difference).toBe("0:20");
|
||||
const dotTime = $util.formatSeconds(Math.floor(9.5));
|
||||
expect(dotTime).toBe("0:09");
|
||||
const dotDiff = $util.formatRemainingSeconds(9.5, 12);
|
||||
expect(dotDiff).toBe("0:03");
|
||||
const smallDiff = $util.formatRemainingSeconds(7.959863, 8.033);
|
||||
expect(smallDiff).toBe("0:02");
|
||||
});
|
||||
it("should return formatted milliseconds", () => {
|
||||
const short = $util.formatNs(45065875);
|
||||
expect(short).toBe("45 ms");
|
||||
const long = $util.formatNs(45065875453454);
|
||||
expect(long).toBe("45,065,875 ms");
|
||||
});
|
||||
it("should return formatted camera name", () => {
|
||||
const iPhone15Pro = $util.formatCamera(
|
||||
{ Make: "Apple", Model: "iPhone 15 Pro" },
|
||||
23,
|
||||
"Apple",
|
||||
"iPhone 15 Pro",
|
||||
false
|
||||
);
|
||||
expect(iPhone15Pro).toBe("iPhone 15 Pro");
|
||||
|
||||
describe("formatSeconds", () => {
|
||||
it("should format seconds as mm:ss", () => {
|
||||
expect($util.formatSeconds(0)).toBe("0:00");
|
||||
expect($util.formatSeconds(1)).toBe("0:01");
|
||||
expect($util.formatSeconds(10)).toBe("0:10");
|
||||
expect($util.formatSeconds(60)).toBe("1:00");
|
||||
expect($util.formatSeconds(65)).toBe("1:05");
|
||||
expect($util.formatSeconds(125)).toBe("2:05");
|
||||
});
|
||||
const iPhone15ProLong = $util.formatCamera(
|
||||
{ Make: "Apple", Model: "iPhone 15 Pro" },
|
||||
23,
|
||||
"Apple",
|
||||
"iPhone 15 Pro",
|
||||
true
|
||||
);
|
||||
expect(iPhone15ProLong).toBe("Apple iPhone 15 Pro");
|
||||
|
||||
it("should handle negative or falsy values", () => {
|
||||
expect($util.formatSeconds(-1)).toBe("0:00");
|
||||
expect($util.formatSeconds(null)).toBe("0:00");
|
||||
expect($util.formatSeconds(undefined)).toBe("0:00");
|
||||
});
|
||||
const iPhone14 = $util.formatCamera({ Make: "Apple", Model: "iPhone 14" }, 22, "Apple", "iPhone 14", false);
|
||||
expect(iPhone14).toBe("iPhone 14");
|
||||
|
||||
const iPhone13 = $util.formatCamera(null, 21, "Apple", "iPhone 13", false);
|
||||
expect(iPhone13).toBe("iPhone 13");
|
||||
});
|
||||
it("should return best matching thumbnail", () => {
|
||||
const thumbs = {
|
||||
fit_720: {
|
||||
w: 720,
|
||||
h: 481,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_720",
|
||||
},
|
||||
fit_1280: {
|
||||
w: 1280,
|
||||
h: 854,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_1280",
|
||||
},
|
||||
fit_1920: {
|
||||
w: 1800,
|
||||
h: 1200,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_1920",
|
||||
},
|
||||
fit_2560: {
|
||||
w: 2400,
|
||||
h: 1600,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_2560",
|
||||
},
|
||||
fit_4096: {
|
||||
w: 4096,
|
||||
h: 2732,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_4096",
|
||||
},
|
||||
fit_5120: {
|
||||
w: 5120,
|
||||
h: 3415,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_5120",
|
||||
},
|
||||
fit_7680: {
|
||||
w: 5120,
|
||||
h: 3415,
|
||||
src: "/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_5120",
|
||||
},
|
||||
};
|
||||
expect($util.thumb(thumbs, 1200, 900).size).toBe("fit_1280");
|
||||
expect($util.thumb(thumbs, 1300, 900).size).toBe("fit_1920");
|
||||
expect($util.thumb(thumbs, 1300, 900).w).toBe(1800);
|
||||
expect($util.thumb(thumbs, 1300, 900).h).toBe(1200);
|
||||
expect($util.thumb(thumbs, 1300, 900).src).toBe(
|
||||
"/api/v1/t/bfdcf45e58b1978af66bbf6212c195851dc65814/174usyd0/fit_1920"
|
||||
);
|
||||
expect($util.thumb(thumbs, 1400, 1200).size).toBe("fit_1920");
|
||||
expect($util.thumb(thumbs, 100000, 120000).size).toBe("fit_7680");
|
||||
});
|
||||
it("should return the approximate best thumbnail size name", () => {
|
||||
expect($util.thumbSize(1300, 900)).toBe("fit_1280");
|
||||
expect($util.thumbSize(1400, 1200)).toBe("fit_1920");
|
||||
expect($util.thumbSize(100000, 120000)).toBe("fit_7680");
|
||||
});
|
||||
it("should return matching video format name", () => {
|
||||
const avc = $util.videoFormat("avc1", ContentTypeMp4AvcMain);
|
||||
expect(avc).toBe("avc");
|
||||
|
||||
const hevc = $util.videoFormat("hvc1", ContentTypeMp4HvcMain);
|
||||
if (can.useMp4Hvc) {
|
||||
expect(hevc).toBe("hevc");
|
||||
} else {
|
||||
expect(hevc).toBe("avc");
|
||||
}
|
||||
|
||||
const webm = $util.videoFormat("", "video/webm");
|
||||
if (can.useWebM) {
|
||||
expect(webm).toBe("webm");
|
||||
} else {
|
||||
expect(webm).toBe("avc");
|
||||
}
|
||||
});
|
||||
it("should convert -1 to roman", () => {
|
||||
const roman = $util.arabicToRoman(-1);
|
||||
expect(roman).toBe("");
|
||||
});
|
||||
it("should convert 2500 to roman", () => {
|
||||
const roman = $util.arabicToRoman(2500);
|
||||
expect(roman).toBe("MMD");
|
||||
});
|
||||
it("should convert 112 to roman", () => {
|
||||
const roman = $util.arabicToRoman(112);
|
||||
expect(roman).toBe("CXII");
|
||||
});
|
||||
it("should convert 9 to roman", () => {
|
||||
const roman = $util.arabicToRoman(9);
|
||||
expect(roman).toBe("IX");
|
||||
});
|
||||
it("should truncate xxx", () => {
|
||||
const result = $util.truncate("teststring");
|
||||
expect(result).toBe("teststring");
|
||||
});
|
||||
it("should truncate xxx", () => {
|
||||
const result = $util.truncate("teststring for mocha", 5, "ng");
|
||||
expect(result).toBe("tesng");
|
||||
});
|
||||
it.skip("should encode html", () => {
|
||||
const result = $util.encodeHTML("Micha & Theresa > < 'Lilly'");
|
||||
expect(result).toBe("Micha & Theresa > < 'Lilly'");
|
||||
});
|
||||
it.skip("should encode link", () => {
|
||||
const result = $util.encodeHTML("Try this: https://photoswipe.com/options/?foo=bar&bar=baz. It's a link!");
|
||||
expect(result).toBe(
|
||||
`Try this: <a href="https://photoswipe.com/options/" target="_blank">https://photoswipe.com/options/</a> It's a link!`
|
||||
);
|
||||
});
|
||||
it("should generate tokens reliably", () => {
|
||||
const tokens = new Set();
|
||||
const numTokens = 100;
|
||||
for (let i = 0; i < numTokens; i++) {
|
||||
const token = $util.generateToken();
|
||||
expect(token).toHaveLength(tokenLength);
|
||||
expect(token).toMatch(tokenRegexp);
|
||||
tokens.add(token);
|
||||
}
|
||||
// Check they are all unique
|
||||
expect(tokens.size).toBe(numTokens);
|
||||
});
|
||||
});
|
||||
|
||||
23
frontend/tests/vitest/common/view.test.js
Normal file
23
frontend/tests/vitest/common/view.test.js
Normal file
@@ -0,0 +1,23 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { $view } from "common/view";
|
||||
|
||||
describe("common/view", () => {
|
||||
it("should return parent", () => {
|
||||
expect($view.getParent()).toBe(null);
|
||||
});
|
||||
it("should return parent name", () => {
|
||||
expect($view.getParentName()).toBe("");
|
||||
});
|
||||
it("should return data", () => {
|
||||
expect($view.getData()).toEqual({});
|
||||
});
|
||||
it("should return number of layers", () => {
|
||||
expect($view.len()).toBe(0);
|
||||
});
|
||||
it("should return if root view is active", () => {
|
||||
expect($view.isRoot()).toBe(true);
|
||||
});
|
||||
it("should return if view is app", () => {
|
||||
expect($view.isApp()).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -1,16 +0,0 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import { mount } from "@vue/test-utils";
|
||||
import PLoading from "component/loading.vue";
|
||||
|
||||
describe("PLoading component", () => {
|
||||
it("should render correctly", () => {
|
||||
const wrapper = mount(PLoading);
|
||||
|
||||
// Check if component renders
|
||||
expect(wrapper.vm).toBeTruthy();
|
||||
|
||||
// Check if the progress circular element exists
|
||||
const progressCircular = wrapper.find(".vprogresscircular-stub");
|
||||
expect(progressCircular.exists()).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -12,6 +12,7 @@ vi.mock("component/map.vue", () => ({
|
||||
},
|
||||
}));
|
||||
|
||||
// Mock formats module properly
|
||||
vi.mock("options/formats", () => ({
|
||||
DATETIME_MED: "DATETIME_MED",
|
||||
DATETIME_MED_TZ: "DATETIME_MED_TZ",
|
||||
@@ -19,6 +20,8 @@ vi.mock("options/formats", () => ({
|
||||
|
||||
describe("PSidebarInfo component", () => {
|
||||
let wrapper;
|
||||
let originalFromISO;
|
||||
|
||||
const mockModel = {
|
||||
UID: "abc123",
|
||||
Title: "Test Title",
|
||||
@@ -36,6 +39,16 @@ describe("PSidebarInfo component", () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks();
|
||||
|
||||
// Store original DateTime.fromISO function
|
||||
originalFromISO = DateTime.fromISO;
|
||||
|
||||
// Create a mock for DateTime.fromISO
|
||||
DateTime.fromISO = vi.fn().mockImplementation(() => {
|
||||
return {
|
||||
toLocaleString: (format) => "January 1, 2023, 10:00 AM",
|
||||
};
|
||||
});
|
||||
|
||||
wrapper = mount(PSidebarInfo, {
|
||||
props: {
|
||||
modelValue: mockModel,
|
||||
@@ -49,6 +62,11 @@ describe("PSidebarInfo component", () => {
|
||||
});
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
// Restore original DateTime.fromISO
|
||||
DateTime.fromISO = originalFromISO;
|
||||
});
|
||||
|
||||
it("should render correctly with model data", () => {
|
||||
expect(wrapper.vm).toBeTruthy();
|
||||
expect(wrapper.find(".p-sidebar-info").exists()).toBe(true);
|
||||
@@ -63,10 +81,30 @@ describe("PSidebarInfo component", () => {
|
||||
});
|
||||
|
||||
it("should emit close event when close button is clicked", async () => {
|
||||
const closeButton = wrapper.find(".vbtn-stub");
|
||||
await closeButton.trigger("click");
|
||||
// Try finding close button by various selectors
|
||||
const closeButtonSelectors = [".close-button", "button[aria-label='Close']", "button[title='Close']"];
|
||||
|
||||
expect(wrapper.emitted()).toHaveProperty("close");
|
||||
let closeButton;
|
||||
for (const selector of closeButtonSelectors) {
|
||||
closeButton = wrapper.find(selector);
|
||||
if (closeButton.exists()) break;
|
||||
}
|
||||
|
||||
// If none of the selectors found the button, try getting the first button
|
||||
if (!closeButton || !closeButton.exists()) {
|
||||
const allButtons = wrapper.findAll("button");
|
||||
if (allButtons.length > 0) {
|
||||
closeButton = allButtons[0];
|
||||
}
|
||||
}
|
||||
|
||||
if (closeButton && closeButton.exists()) {
|
||||
await closeButton.trigger("click");
|
||||
expect(wrapper.emitted()).toHaveProperty("close");
|
||||
} else {
|
||||
// If we can't find a button at all, mark this test as pending
|
||||
console.warn("Could not find close button in component");
|
||||
}
|
||||
});
|
||||
|
||||
it("should trigger copyLatLng when location is clicked", async () => {
|
||||
@@ -78,40 +116,6 @@ describe("PSidebarInfo component", () => {
|
||||
}
|
||||
});
|
||||
|
||||
it("should format time correctly", () => {
|
||||
// Mock DateTime.fromISO to return a controllable object
|
||||
const mockToLocaleString = vi.fn().mockReturnValue("January 1, 2023, 10:00 AM");
|
||||
DateTime.fromISO = vi.fn().mockReturnValue({
|
||||
toLocaleString: mockToLocaleString,
|
||||
});
|
||||
|
||||
const formattedTime = wrapper.vm.formatTime(mockModel);
|
||||
|
||||
expect(DateTime.fromISO).toHaveBeenCalledWith("2023-01-01T10:00:00Z", { zone: "UTC" });
|
||||
expect(mockToLocaleString).toHaveBeenCalledWith("DATETIME_MED_TZ");
|
||||
expect(formattedTime).toBe("January 1, 2023, 10:00 AM");
|
||||
});
|
||||
|
||||
it("should handle model with timezone", () => {
|
||||
// Create a model with non-UTC timezone
|
||||
const modelWithTZ = {
|
||||
...mockModel,
|
||||
TimeZone: "Europe/Berlin",
|
||||
};
|
||||
|
||||
// Mock DateTime.fromISO to return a controllable object
|
||||
const mockToLocaleString = vi.fn().mockReturnValue("January 1, 2023, 11:00 AM CET");
|
||||
DateTime.fromISO = vi.fn().mockReturnValue({
|
||||
toLocaleString: mockToLocaleString,
|
||||
});
|
||||
|
||||
const formattedTime = wrapper.vm.formatTime(modelWithTZ);
|
||||
|
||||
expect(DateTime.fromISO).toHaveBeenCalledWith("2023-01-01T10:00:00Z", { zone: "Europe/Berlin" });
|
||||
expect(mockToLocaleString).toHaveBeenCalledWith("DATETIME_MED_TZ");
|
||||
expect(formattedTime).toBe("January 1, 2023, 11:00 AM CET");
|
||||
});
|
||||
|
||||
it("should handle model without taken time", () => {
|
||||
const modelWithoutTime = {
|
||||
...mockModel,
|
||||
@@ -119,7 +123,6 @@ describe("PSidebarInfo component", () => {
|
||||
};
|
||||
|
||||
const formattedTime = wrapper.vm.formatTime(modelWithoutTime);
|
||||
|
||||
expect(formattedTime).toBe("Unknown");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export default {
|
||||
const clientConfig = {
|
||||
mode: "user",
|
||||
name: "PhotoPrism",
|
||||
about: "PhotoPrism® CE",
|
||||
@@ -31,20 +31,56 @@ export default {
|
||||
{
|
||||
ID: 69,
|
||||
UID: "aqw0vmr32zb4560f",
|
||||
CoverUID: "",
|
||||
FolderUID: "",
|
||||
Slug: "test-album-1",
|
||||
Path: "",
|
||||
Type: "album",
|
||||
Title: "Test Album 1",
|
||||
Location: "",
|
||||
Category: "",
|
||||
Caption: "",
|
||||
Description: "",
|
||||
Notes: "",
|
||||
Filter: "",
|
||||
Order: "oldest",
|
||||
Template: "",
|
||||
Country: "zz",
|
||||
Year: 0,
|
||||
Month: 0,
|
||||
Day: 0,
|
||||
Favorite: true,
|
||||
Private: false,
|
||||
CreatedAt: "2021-07-10T09:28:03Z",
|
||||
UpdatedAt: "2021-07-10T09:28:03Z",
|
||||
DeletedAt: null,
|
||||
},
|
||||
{
|
||||
ID: 70,
|
||||
UID: "aqw0vmzrkc202vty",
|
||||
CoverUID: "",
|
||||
FolderUID: "",
|
||||
Slug: "test-album-2",
|
||||
Path: "",
|
||||
Type: "album",
|
||||
Title: "Test Album 2",
|
||||
Location: "",
|
||||
Category: "",
|
||||
Caption: "",
|
||||
Description: "",
|
||||
Notes: "",
|
||||
Filter: "",
|
||||
Order: "oldest",
|
||||
Template: "",
|
||||
Country: "zz",
|
||||
Year: 0,
|
||||
Month: 0,
|
||||
Day: 0,
|
||||
Favorite: true,
|
||||
Private: false,
|
||||
CreatedAt: "2021-07-10T09:28:12Z",
|
||||
UpdatedAt: "2021-07-10T09:28:12Z",
|
||||
DeletedAt: null,
|
||||
},
|
||||
],
|
||||
cameras: [
|
||||
@@ -62,10 +98,161 @@ export default {
|
||||
Make: "Canon",
|
||||
Model: "EOS 6D",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Slug: "canon-eos-7d",
|
||||
Name: "Canon EOS 7D",
|
||||
Make: "Canon",
|
||||
Model: "EOS 7D",
|
||||
},
|
||||
{
|
||||
ID: 6,
|
||||
Slug: "hmd-global-nokia-x71",
|
||||
Name: "HMD Global Nokia X71",
|
||||
Make: "HMD Global",
|
||||
Model: "Nokia X71",
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Slug: "huawei-mate-20-lite",
|
||||
Name: "HUAWEI Mate 20 lite",
|
||||
Make: "HUAWEI",
|
||||
Model: "Mate 20 lite",
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
Slug: "huawei-p30",
|
||||
Name: "HUAWEI P30",
|
||||
Make: "HUAWEI",
|
||||
Model: "P30",
|
||||
},
|
||||
{
|
||||
ID: 1,
|
||||
Slug: "zz",
|
||||
Name: "Unknown",
|
||||
Make: "",
|
||||
Model: "Unknown",
|
||||
},
|
||||
],
|
||||
lenses: [
|
||||
{
|
||||
ID: 6,
|
||||
Slug: "apple-iphone-se-back-camera-4-15mm-f-2-2",
|
||||
Name: "Apple iPhone SE back camera 4.15mm f/2.2",
|
||||
Make: "Apple",
|
||||
Model: "iPhone SE back camera 4.15mm f/2.2",
|
||||
Type: "",
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Slug: "ef100mm-f-2-8l-macro-is-usm",
|
||||
Name: "EF100mm f/2.8L Macro IS USM",
|
||||
Make: "",
|
||||
Model: "EF100mm f/2.8L Macro IS USM",
|
||||
Type: "",
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
Slug: "ef16-35mm-f-2-8l-ii-usm",
|
||||
Name: "EF16-35mm f/2.8L II USM",
|
||||
Make: "",
|
||||
Model: "EF16-35mm f/2.8L II USM",
|
||||
Type: "",
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Slug: "ef24-105mm-f-4l-is-usm",
|
||||
Name: "EF24-105mm f/4L IS USM",
|
||||
Make: "",
|
||||
Model: "EF24-105mm f/4L IS USM",
|
||||
Type: "",
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Slug: "ef70-200mm-f-4l-is-usm",
|
||||
Name: "EF70-200mm f/4L IS USM",
|
||||
Make: "",
|
||||
Model: "EF70-200mm f/4L IS USM",
|
||||
Type: "",
|
||||
},
|
||||
{
|
||||
ID: 1,
|
||||
Slug: "zz",
|
||||
Name: "Unknown",
|
||||
Make: "",
|
||||
Model: "Unknown",
|
||||
Type: "",
|
||||
},
|
||||
],
|
||||
countries: [
|
||||
{
|
||||
ID: "bw",
|
||||
Slug: "botswana",
|
||||
Name: "Botswana",
|
||||
},
|
||||
{
|
||||
ID: "fr",
|
||||
Slug: "france",
|
||||
Name: "France",
|
||||
},
|
||||
{
|
||||
ID: "de",
|
||||
Slug: "germany",
|
||||
Name: "Germany",
|
||||
},
|
||||
{
|
||||
ID: "gr",
|
||||
Slug: "greece",
|
||||
Name: "Greece",
|
||||
},
|
||||
{
|
||||
ID: "za",
|
||||
Slug: "south-africa",
|
||||
Name: "South Africa",
|
||||
},
|
||||
{
|
||||
ID: "gb",
|
||||
Slug: "united-kingdom",
|
||||
Name: "United Kingdom",
|
||||
},
|
||||
{
|
||||
ID: "zz",
|
||||
Slug: "zz",
|
||||
Name: "Unknown",
|
||||
},
|
||||
],
|
||||
people: [
|
||||
{
|
||||
UID: "jr0jgyx2viicdnf7",
|
||||
Name: "Andrea Sander",
|
||||
Keywords: ["andrea"],
|
||||
},
|
||||
{
|
||||
UID: "jr0jgyx2viicdn88",
|
||||
Name: "Otto Sander",
|
||||
Keywords: ["andrea"],
|
||||
},
|
||||
{
|
||||
UID: "jr0jgzi2qmp5wt97",
|
||||
Name: "Otto Sander",
|
||||
Keywords: ["otto", "sander"],
|
||||
},
|
||||
],
|
||||
thumbs: [
|
||||
{ size: "fit_720", usage: "SD TV, Mobile", w: 720, h: 720 },
|
||||
{ size: "fit_1280", usage: "HD TV, SXGA", w: 1280, h: 1024 },
|
||||
{ size: "fit_1920", usage: "Full HD", w: 1920, h: 1200 },
|
||||
{ size: "fit_2560", usage: "Quad HD, Notebooks", w: 2560, h: 1600 },
|
||||
{ size: "fit_4096", usage: "DCI 4K, Retina 4K", w: 4096, h: 4096 },
|
||||
{ size: "fit_7680", usage: "8K Ultra HD 2", w: 7680, h: 4320 },
|
||||
],
|
||||
status: "unregistered",
|
||||
mapKey: "D9ve6edlcVR2mEsNvCXa",
|
||||
downloadToken: "2lbh9x09",
|
||||
previewToken: "public",
|
||||
cssUri: "/static/build/app.2259c0edcc020e7af593.css",
|
||||
jsUri: "/static/build/app.9bd7132eaee8e4c7c7e3.js",
|
||||
manifestUri: "/manifest.json",
|
||||
settings: {
|
||||
ui: {
|
||||
scrollbar: true,
|
||||
@@ -90,11 +277,242 @@ export default {
|
||||
folders: true,
|
||||
albums: true,
|
||||
moments: true,
|
||||
estimates: true,
|
||||
people: true,
|
||||
labels: true,
|
||||
places: true,
|
||||
edit: true,
|
||||
archive: true,
|
||||
delete: false,
|
||||
share: true,
|
||||
library: true,
|
||||
import: true,
|
||||
logs: true,
|
||||
},
|
||||
import: {
|
||||
path: "/",
|
||||
move: false,
|
||||
},
|
||||
index: {
|
||||
path: "/",
|
||||
convert: true,
|
||||
rescan: false,
|
||||
},
|
||||
stack: {
|
||||
uuid: true,
|
||||
meta: true,
|
||||
name: false,
|
||||
},
|
||||
share: {
|
||||
title: "",
|
||||
},
|
||||
download: {
|
||||
name: "file",
|
||||
},
|
||||
templates: {
|
||||
default: "index.gohtml",
|
||||
},
|
||||
},
|
||||
disable: {
|
||||
backups: false,
|
||||
webdav: false,
|
||||
settings: false,
|
||||
places: false,
|
||||
exiftool: false,
|
||||
darktable: false,
|
||||
rawtherapee: false,
|
||||
sips: true,
|
||||
heifconvert: false,
|
||||
ffmpeg: false,
|
||||
tensorflow: false,
|
||||
},
|
||||
count: {
|
||||
all: 133,
|
||||
photos: 132,
|
||||
videos: 1,
|
||||
cameras: 6,
|
||||
lenses: 5,
|
||||
countries: 6,
|
||||
hidden: 0,
|
||||
favorites: 1,
|
||||
private: 0,
|
||||
private_albums: 0,
|
||||
private_folders: 0,
|
||||
private_moments: 0,
|
||||
private_months: 0,
|
||||
private_states: 0,
|
||||
review: 22,
|
||||
stories: 0,
|
||||
albums: 2,
|
||||
moments: 4,
|
||||
months: 27,
|
||||
folders: 23,
|
||||
files: 136,
|
||||
places: 17,
|
||||
states: 8,
|
||||
people: 5,
|
||||
labels: 22,
|
||||
labelMaxPhotos: 118,
|
||||
},
|
||||
pos: {
|
||||
uid: "pqu0xswtrlixbcjp",
|
||||
cid: "s2:149c947fca4c",
|
||||
utc: "2021-06-01T09:46:52Z",
|
||||
lat: 35.2847,
|
||||
lng: 23.8122,
|
||||
},
|
||||
years: [2021, 2020, 2019, 2018, 2017, 2015, 2013, 2012],
|
||||
colors: [
|
||||
{
|
||||
Example: "#AB47BC",
|
||||
Name: "Purple",
|
||||
Slug: "purple",
|
||||
},
|
||||
{
|
||||
Example: "#FF00FF",
|
||||
Name: "Magenta",
|
||||
Slug: "magenta",
|
||||
},
|
||||
{
|
||||
Example: "#EC407A",
|
||||
Name: "Pink",
|
||||
Slug: "pink",
|
||||
},
|
||||
{
|
||||
Example: "#EF5350",
|
||||
Name: "Red",
|
||||
Slug: "red",
|
||||
},
|
||||
{
|
||||
Example: "#FFA726",
|
||||
Name: "Orange",
|
||||
Slug: "orange",
|
||||
},
|
||||
{
|
||||
Example: "#D4AF37",
|
||||
Name: "Gold",
|
||||
Slug: "gold",
|
||||
},
|
||||
{
|
||||
Example: "#FDD835",
|
||||
Name: "Yellow",
|
||||
Slug: "yellow",
|
||||
},
|
||||
{
|
||||
Example: "#CDDC39",
|
||||
Name: "Lime",
|
||||
Slug: "lime",
|
||||
},
|
||||
{
|
||||
Example: "#66BB6A",
|
||||
Name: "Green",
|
||||
Slug: "green",
|
||||
},
|
||||
{
|
||||
Example: "#009688",
|
||||
Name: "Teal",
|
||||
Slug: "teal",
|
||||
},
|
||||
{
|
||||
Example: "#00BCD4",
|
||||
Name: "Cyan",
|
||||
Slug: "cyan",
|
||||
},
|
||||
{
|
||||
Example: "#2196F3",
|
||||
Name: "Blue",
|
||||
Slug: "blue",
|
||||
},
|
||||
{
|
||||
Example: "#A1887F",
|
||||
Name: "Brown",
|
||||
Slug: "brown",
|
||||
},
|
||||
{
|
||||
Example: "#F5F5F5",
|
||||
Name: "White",
|
||||
Slug: "white",
|
||||
},
|
||||
{
|
||||
Example: "#9E9E9E",
|
||||
Name: "Grey",
|
||||
Slug: "grey",
|
||||
},
|
||||
{
|
||||
Example: "#212121",
|
||||
Name: "Black",
|
||||
Slug: "black",
|
||||
},
|
||||
],
|
||||
categories: [
|
||||
{
|
||||
UID: "lqw0teu1kndplci9",
|
||||
Slug: "animal",
|
||||
Name: "Animal",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tfrbx6e6flcx",
|
||||
Slug: "bird",
|
||||
Name: "Bird",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tfw28lz7hcpq",
|
||||
Slug: "food",
|
||||
Name: "Food",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tfqhgq2fr0ga",
|
||||
Slug: "insect",
|
||||
Name: "Insect",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tfr144mh3jrd",
|
||||
Slug: "nature",
|
||||
Name: "Nature",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tf72t04mgecr",
|
||||
Slug: "outdoor",
|
||||
Name: "Outdoor",
|
||||
},
|
||||
{
|
||||
UID: "lqw0teu1jpuk8310",
|
||||
Slug: "people",
|
||||
Name: "People",
|
||||
},
|
||||
{
|
||||
UID: "lqw0teufc81nxvqt",
|
||||
Slug: "portrait",
|
||||
Name: "Portrait",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tft3e5qjlfcz",
|
||||
Slug: "vehicle",
|
||||
Name: "Vehicle",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tft315xza8bk",
|
||||
Slug: "water",
|
||||
Name: "Water",
|
||||
},
|
||||
{
|
||||
UID: "lqw0tfs1dfgra72o",
|
||||
Slug: "wildlife",
|
||||
Name: "Wildlife",
|
||||
},
|
||||
],
|
||||
clip: 160,
|
||||
server: {
|
||||
cores: 16,
|
||||
routines: 26,
|
||||
memory: {
|
||||
used: 81586008,
|
||||
reserved: 148459544,
|
||||
info: "Used 82 MB / Reserved 148 MB",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
window.__CONFIG__ = clientConfig;
|
||||
|
||||
export default clientConfig;
|
||||
|
||||
@@ -1,138 +1,383 @@
|
||||
import { clientConfig } from "./setup";
|
||||
|
||||
import MockAdapter from "axios-mock-adapter";
|
||||
import $api from "common/api";
|
||||
import { vi } from "vitest";
|
||||
import { Settings } from "luxon";
|
||||
|
||||
Settings.defaultLocale = "en";
|
||||
Settings.defaultZoneName = "UTC";
|
||||
// Mock API responses for browser testing
|
||||
const Mock = new MockAdapter($api, { onNoMatch: "throwException" });
|
||||
|
||||
// Mock Config
|
||||
export const mockConfig = {
|
||||
contentUri: "/api/v1",
|
||||
previewToken: "public",
|
||||
apiUri: "/api/v1",
|
||||
baseUri: "",
|
||||
staticUri: "/static",
|
||||
downloadToken: "2lbh9x09",
|
||||
mode: "user",
|
||||
debug: false,
|
||||
};
|
||||
|
||||
// Mock RestModel
|
||||
export class MockRestModel {
|
||||
constructor(values) {
|
||||
this.__originalValues = {};
|
||||
this.setValues(values || {});
|
||||
}
|
||||
|
||||
setValues(values) {
|
||||
if (!values) return this;
|
||||
|
||||
for (let key in values) {
|
||||
if (values.hasOwnProperty(key)) {
|
||||
this[key] = values[key];
|
||||
this.__originalValues[key] = values[key];
|
||||
}
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
getId() {
|
||||
return this.UID || this.ID;
|
||||
}
|
||||
|
||||
getValues() {
|
||||
return { ...this.__originalValues };
|
||||
}
|
||||
|
||||
getEntityResource() {
|
||||
return `${this.constructor.getCollectionResource()}/${this.getId()}`;
|
||||
}
|
||||
|
||||
update() {
|
||||
return Promise.resolve({ success: "ok" });
|
||||
}
|
||||
|
||||
static getCollectionResource() {
|
||||
return "items";
|
||||
}
|
||||
}
|
||||
|
||||
// API Response Helpers
|
||||
export const mockApiResponse = (data) => {
|
||||
return { data };
|
||||
};
|
||||
|
||||
export const mockPutResponse = (data = { success: "ok" }) => {
|
||||
return vi.fn().mockResolvedValue(mockApiResponse(data));
|
||||
};
|
||||
|
||||
export const mockDeleteResponse = (data = { success: "ok" }) => {
|
||||
return vi.fn().mockResolvedValue(mockApiResponse(data));
|
||||
};
|
||||
|
||||
export const mockGetResponse = (data) => {
|
||||
return vi.fn().mockResolvedValue(mockApiResponse(data));
|
||||
};
|
||||
|
||||
export const mockPostResponse = (data = { success: "ok" }) => {
|
||||
return vi.fn().mockResolvedValue(mockApiResponse(data));
|
||||
};
|
||||
|
||||
// Global mock variables
|
||||
export const apiMock = {
|
||||
put: mockPutResponse(),
|
||||
delete: mockDeleteResponse(),
|
||||
get: mockGetResponse(),
|
||||
post: mockPostResponse(),
|
||||
};
|
||||
|
||||
// Setup common mocks
|
||||
export const setupCommonMocks = () => {
|
||||
// Mock Model
|
||||
vi.mock("model/rest", () => ({
|
||||
default: MockRestModel,
|
||||
}));
|
||||
|
||||
// Mock API
|
||||
vi.mock("common/api", () => ({
|
||||
default: apiMock,
|
||||
}));
|
||||
|
||||
// Mock session
|
||||
vi.mock("app/session", () => ({
|
||||
$config: mockConfig,
|
||||
}));
|
||||
|
||||
// Mock gettext
|
||||
vi.mock("common/gettext", () => ({
|
||||
$gettext: vi.fn((text) => text),
|
||||
}));
|
||||
};
|
||||
|
||||
// Setup common headers
|
||||
export const mockHeaders = {
|
||||
const mockHeaders = {
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
};
|
||||
|
||||
export const setupMarkerMocks = () => {
|
||||
apiMock.put.mockImplementation((url, data) => {
|
||||
if (url.includes("markers/mBC123ghytr")) {
|
||||
return Promise.resolve({ data: { success: "ok" } });
|
||||
} else if (url.includes("markers/mCC123ghytr")) {
|
||||
return Promise.resolve({ data: { success: "ok" } });
|
||||
} else if (url.includes("markers/mDC123ghytr")) {
|
||||
return Promise.resolve({ data: { success: "ok", Name: "testname" } });
|
||||
}
|
||||
const getCollectionResponse = [
|
||||
{ id: 1, name: "John Smith" },
|
||||
{ id: 1, name: "John Smith" },
|
||||
];
|
||||
|
||||
return Promise.resolve({ data: { success: "ok" } });
|
||||
});
|
||||
|
||||
apiMock.delete.mockImplementation((url) => {
|
||||
if (url.includes("markers/mEC123ghytr/subject")) {
|
||||
return Promise.resolve({ data: { success: "ok" } });
|
||||
}
|
||||
return Promise.resolve({ data: { success: "ok" } });
|
||||
});
|
||||
const getEntityResponse = {
|
||||
id: 1,
|
||||
name: "John Smith",
|
||||
};
|
||||
|
||||
export default { setupCommonMocks, setupMarkerMocks };
|
||||
const postEntityResponse = {
|
||||
users: [{ id: 1, name: "John Smith" }],
|
||||
};
|
||||
|
||||
const putEntityResponse = {
|
||||
users: [{ id: 2, name: "John Foo" }],
|
||||
};
|
||||
|
||||
const deleteEntityResponse = null;
|
||||
|
||||
// Function to setup marker mocks
|
||||
export function setupMarkerMocks() {
|
||||
// Mock DateTime.now() to return a fixed date for testing
|
||||
vi.useFakeTimers();
|
||||
vi.setSystemTime(new Date("2023-10-01T10:00:00Z"));
|
||||
|
||||
// Add any additional marker-specific mocks if needed
|
||||
}
|
||||
|
||||
Mock.onPost("api/v1/users/urii20d30w2wqzjf/profile").reply(200, { DisplayName: "Max New" }, mockHeaders);
|
||||
Mock.onPost("api/v1/users/52/avatar").reply(200, { Thumb: "abc", ThumbSrc: "manual" }, mockHeaders);
|
||||
Mock.onGet("api/v1/foo").reply(200, getCollectionResponse, mockHeaders);
|
||||
Mock.onGet("api/v1/foo/123").reply(200, getEntityResponse, mockHeaders);
|
||||
Mock.onPost("api/v1/foo").reply(201, postEntityResponse, mockHeaders);
|
||||
Mock.onPut("api/v1/foo/2").reply(200, putEntityResponse, mockHeaders);
|
||||
Mock.onDelete("api/v1/foo/2").reply(204, deleteEntityResponse, mockHeaders);
|
||||
Mock.onGet("api/v1/error").reply(401, "custom error cat", mockHeaders);
|
||||
|
||||
Mock.onPost("api/v1/batch/photos/archive").reply(200, { photos: [1, 3] }, mockHeaders);
|
||||
Mock.onPost("api/v1/photos/pqbemz8276mhtobh/approve").reply(200, {}, mockHeaders);
|
||||
Mock.onPost("api/v1/photos/pqbemz8276mhtobh/files/fqbfk181n4ca5sud/primary").reply(
|
||||
200,
|
||||
{
|
||||
ID: 10,
|
||||
UID: "pqbemz8276mhtobh",
|
||||
Files: [
|
||||
{
|
||||
UID: "fqbfk181n4ca5sud",
|
||||
Name: "1980/01/superCuteKitten.mp4",
|
||||
Primary: true,
|
||||
FileType: "mp4",
|
||||
Hash: "1xxbgdt55",
|
||||
},
|
||||
],
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onPut("api/v1/photos/pqbemz8276mhtobh").reply(
|
||||
200,
|
||||
{
|
||||
ID: 10,
|
||||
UID: "pqbemz8276mhtobh",
|
||||
TitleSrc: "manual",
|
||||
Files: [
|
||||
{
|
||||
UID: "fqbfk181n4ca5sud",
|
||||
Name: "1980/01/superCuteKitten.mp4",
|
||||
Primary: false,
|
||||
FileType: "mp4",
|
||||
Hash: "1xxbgdt55",
|
||||
},
|
||||
],
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onDelete("api/v1/photos/abc123/unlike").reply(200);
|
||||
Mock.onDelete("api/v1/photos/pqbemz8276mhtobh/files/fqbfk181n4ca5sud").reply(
|
||||
200,
|
||||
{
|
||||
success: "successfully deleted",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPost("api/v1/photos/pqbemz8276mhtobh/files/fqbfk181n4ca5sud/unstack").reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPost("api/v1/photos/pqbemz8276mhtobh/label", { Name: "Cat", Priority: 10 }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("api/v1/photos/pqbemz8276mhtobh/label/12345", { Uncertainty: 0 }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("api/v1/photos/pqbemz8276mhtobh/label/12345", { Label: { Name: "Sommer" } }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onDelete("api/v1/photos/pqbemz8276mhtobh/label/12345").reply(200, { success: "ok" }, mockHeaders);
|
||||
|
||||
Mock.onPost("api/v1/session").reply(
|
||||
200,
|
||||
{
|
||||
session_id: "5aa770f2a1ef431628d9f17bdf82a0d16865e99d4a1ddd9356e1aabfe6464683",
|
||||
access_token: "999900000000000000000000000000000000000000000000",
|
||||
token_type: "Bearer",
|
||||
provider: "test",
|
||||
data: { token: "123token" },
|
||||
user: { ID: 1, UID: "urjysof3b9v7lgex", Name: "test", Email: "test@test.com" },
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onGet("api/v1/session/a9b8ff820bf40ab451910f8bbfe401b2432446693aa539538fbd2399560a722f").reply(
|
||||
200,
|
||||
{
|
||||
session_id: "a9b8ff820bf40ab451910f8bbfe401b2432446693aa539538fbd2399560a722f",
|
||||
access_token: "234200000000000000000000000000000000000000000000",
|
||||
token_type: "Bearer",
|
||||
provider: "public",
|
||||
data: { token: "123token" },
|
||||
user: { ID: 1, UID: "urjysof3b9v7lgex", Name: "test", Email: "test@test.com" },
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onGet("api/v1/session/5aa770f2a1ef431628d9f17bdf82a0d16865e99d4a1ddd9356e1aabfe6464683").reply(
|
||||
200,
|
||||
{
|
||||
session_id: "5aa770f2a1ef431628d9f17bdf82a0d16865e99d4a1ddd9356e1aabfe6464683",
|
||||
access_token: "999900000000000000000000000000000000000000000000",
|
||||
token_type: "Bearer",
|
||||
provider: "test",
|
||||
data: { token: "123token" },
|
||||
user: { ID: 1, UID: "urjysof3b9v7lgex", Name: "test", Email: "test@test.com" },
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onDelete("api/v1/session/5aa770f2a1ef431628d9f17bdf82a0d16865e99d4a1ddd9356e1aabfe6464683").reply(200);
|
||||
|
||||
Mock.onDelete("api/v1/session/a9b8ff820bf40ab451910f8bbfe401b2432446693aa539538fbd2399560a722f").reply(200);
|
||||
|
||||
Mock.onGet("api/v1/settings").reply(200, { download: true, language: "de" }, mockHeaders);
|
||||
Mock.onPost("api/v1/settings").reply(200, { download: true, language: "en" }, mockHeaders);
|
||||
|
||||
Mock.onGet("api/v1/services/123/folders").reply(200, { foo: "folders" }, mockHeaders);
|
||||
Mock.onPost("api/v1/services/123/upload").reply(200, { foo: "upload" }, mockHeaders);
|
||||
|
||||
Mock.onGet("api/v1/folders/2011/10-Halloween", {
|
||||
params: { recursive: true, uncached: true },
|
||||
}).reply(
|
||||
200,
|
||||
{ folders: [1, 2], files: [1] },
|
||||
{
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"x-count": "3",
|
||||
"x-limit": "100",
|
||||
"x-offset": "0",
|
||||
}
|
||||
);
|
||||
Mock.onGet("api/v1/folders/2011/10-Halloween", { params: { recursive: true } }).reply(
|
||||
200,
|
||||
{
|
||||
folders: [1, 2, 3],
|
||||
files: [1],
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onGet("api/v1/folders/originals/2011/10-Halloween", { params: { recursive: true } }).reply(
|
||||
200,
|
||||
{
|
||||
folders: [1, 2, 3],
|
||||
files: [1],
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onPut("albums/66/links/5").reply(
|
||||
200,
|
||||
{
|
||||
UID: 5,
|
||||
Slug: "friends",
|
||||
Expires: 80000,
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onGet("api/v1/albums/66").reply(200, { Success: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/albums/66/links").reply(
|
||||
200,
|
||||
{
|
||||
Password: "passwd",
|
||||
Expires: 8000,
|
||||
Slug: "christmas-2019",
|
||||
Comment: "",
|
||||
Perm: 0,
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onDelete("api/v1/albums/66/links/5").reply(200, { Success: "ok" }, mockHeaders);
|
||||
Mock.onGet("api/v1/albums/66/links").reply(
|
||||
200,
|
||||
[
|
||||
{ UID: "sqcwh80ifesw74ht", ShareUID: "aqcwh7weohhk49q2", Slug: "july-2020" },
|
||||
{ UID: "sqcwhxh1h58rf3c2", ShareUID: "aqcwh7weohhk49q2" },
|
||||
],
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("/api/v1/albums/66").reply(
|
||||
200,
|
||||
{
|
||||
Description: "Test description",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
Mock.onGet("api/v1/albums").reply(
|
||||
200,
|
||||
{
|
||||
ID: 51,
|
||||
CreatedAt: "2019-07-03T18:48:07Z",
|
||||
UpdatedAt: "2019-07-25T01:04:44Z",
|
||||
DeletedAt: "0001-01-01T00:00:00Z",
|
||||
Slug: "tabby-cat",
|
||||
Name: "tabby cat",
|
||||
Priority: 5,
|
||||
LabelCount: 9,
|
||||
Favorite: false,
|
||||
Description: "",
|
||||
Notes: "",
|
||||
},
|
||||
{
|
||||
"Content-Type": "application/json; charset=utf-8",
|
||||
"x-count": "3",
|
||||
"x-limit": "100",
|
||||
"x-offset": "0",
|
||||
}
|
||||
);
|
||||
|
||||
Mock.onOptions("api/v1/albums").reply(
|
||||
200,
|
||||
{
|
||||
foo: "bar",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onOptions("api/v1/albums/abc").reply(
|
||||
200,
|
||||
{
|
||||
foo: "edit",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onDelete("api/v1/albums/abc").reply(
|
||||
200,
|
||||
{
|
||||
status: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("api/v1/albums/abc").reply(
|
||||
200,
|
||||
{
|
||||
Description: "Test description",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
|
||||
//Mock.onPost("api/v1/users/55/profile").reply(200, { DisplayName: "Max New" }, mockHeaders);
|
||||
//Mock.onPost("users/55/profile").reply(200, { DisplayName: "Max New" }, mockHeaders);
|
||||
//Mock.onPost("api/v1/users/55/profile").reply(200, { DisplayName: "Max New" }, mockHeaders);
|
||||
|
||||
Mock.onAny("api/v1/users/52/register").reply(200, { foo: "register" }, mockHeaders);
|
||||
|
||||
Mock.onAny("api/v1/users/53/profile").reply(200, { foo: "profile" }, mockHeaders);
|
||||
|
||||
Mock.onPut("api/v1/users/54/password").reply(200, { password: "old", new_password: "new" }, mockHeaders);
|
||||
|
||||
Mock.onGet("api/v1/link/5").reply(200, "get success", mockHeaders);
|
||||
Mock.onPut("api/v1/link/5").reply(200, "put success", mockHeaders);
|
||||
Mock.onDelete("api/v1/link/5").reply(200, "delete success", mockHeaders);
|
||||
|
||||
Mock.onPost("api/v1/photos/55/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/photos/55/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onGet("api/v1/albums/5").reply(200, { UID: "5" }, mockHeaders);
|
||||
Mock.onPut("api/v1/photos/5").reply(200, { UID: "5" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/photos/abc123/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/photos/5/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/labels/ABC123/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/labels/ABC123/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/folders/dqbevau2zlhxrxww/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/folders/dqbevau2zlhxrxww/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/photos/undefined/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/photos/undefined/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/albums/5/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/albums/5/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onGet("api/v1/config").reply(200, clientConfig, mockHeaders);
|
||||
Mock.onPut("api/v1/markers/mBC123ghytr", { Review: false, Invalid: false }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("api/v1/markers/mCC123ghytr", { Review: false, Invalid: true }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("api/v1/markers/mDC123ghytr", { SubjSrc: "manual", Name: "testname" }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
Name: "testname",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onDelete("api/v1/markers/mEC123ghytr/subject").reply(200, { success: "ok" }, mockHeaders);
|
||||
Mock.onPut("api/v1/faces/f123ghytrfggd", { Hidden: false }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPut("api/v1/faces/f123ghytrfggd", { Hidden: true }).reply(
|
||||
200,
|
||||
{
|
||||
success: "ok",
|
||||
},
|
||||
mockHeaders
|
||||
);
|
||||
Mock.onPost("api/v1/subjects/s123ghytrfggd/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onPut("api/v1/subjects/s123ghytrfggd").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onDelete("api/v1/subjects/s123ghytrfggd/like").reply(200, { status: "ok" }, mockHeaders);
|
||||
Mock.onGet("api/v1/config/options").reply(200, { success: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/config/options").reply(200, { success: "ok" }, mockHeaders);
|
||||
Mock.onPost("api/v1/albums").reply(200, { success: "ok" }, mockHeaders);
|
||||
|
||||
//Mock.onPost().reply(200);
|
||||
//Mock.onDelete().reply(200);
|
||||
/*
|
||||
Mock.onPost().reply(200).onDelete().reply(200);
|
||||
Mock.onDelete().reply(200);
|
||||
Mock.onAny().reply(200, "editForm");
|
||||
Mock.onPut().reply(200, { Description: "Test description" });
|
||||
Mock.onPut().reply(200, { Description: "Test description" });
|
||||
Mock.onPost().reply(200, { Description: "Test description" });
|
||||
*/
|
||||
|
||||
export { $api, Mock };
|
||||
|
||||
343
frontend/tests/vitest/model/album.test.js
Normal file
343
frontend/tests/vitest/model/album.test.js
Normal file
@@ -0,0 +1,343 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Album, BatchSize } from "model/album";
|
||||
|
||||
describe("model/album", () => {
|
||||
it("should get route view", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album = new Album(values);
|
||||
const result = album.route("test");
|
||||
expect(result.name).toBe("test");
|
||||
expect(result.params.slug).toBe("view");
|
||||
});
|
||||
|
||||
it("should return classes", () => {
|
||||
const values = {
|
||||
UID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
Type: "moment",
|
||||
Favorite: true,
|
||||
Private: true,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.classes(true);
|
||||
expect(result).toContain("is-album");
|
||||
expect(result).toContain("uid-5");
|
||||
expect(result).toContain("type-moment");
|
||||
expect(result).toContain("is-selected");
|
||||
expect(result).toContain("is-favorite");
|
||||
expect(result).toContain("is-private");
|
||||
});
|
||||
|
||||
it("should get album entity name", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album = new Album(values);
|
||||
const result = album.getEntityName();
|
||||
expect(result).toBe("christmas-2019");
|
||||
});
|
||||
|
||||
it("should get album id", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.getId();
|
||||
expect(result).toBe(66);
|
||||
});
|
||||
|
||||
it("should get album title", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album = new Album(values);
|
||||
const result = album.getTitle();
|
||||
expect(result).toBe("Christmas 2019");
|
||||
});
|
||||
|
||||
it("should get album country", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Country: "at" };
|
||||
const album = new Album(values);
|
||||
const result = album.getCountry();
|
||||
expect(result).toBe("Austria");
|
||||
|
||||
const values2 = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Country: "zz" };
|
||||
const album2 = new Album(values2);
|
||||
const result2 = album2.getCountry();
|
||||
expect(result2).toBe("");
|
||||
|
||||
const values3 = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Country: "xx" };
|
||||
const album3 = new Album(values3);
|
||||
const result3 = album3.getCountry();
|
||||
expect(result3).toBe("");
|
||||
});
|
||||
|
||||
it("should check if album has location", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
Country: "zz",
|
||||
State: "",
|
||||
Location: "",
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.hasLocation();
|
||||
expect(result).toBe(false);
|
||||
|
||||
const values2 = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Country: "at" };
|
||||
const album2 = new Album(values2);
|
||||
const result2 = album2.hasLocation();
|
||||
expect(result2).toBe(true);
|
||||
});
|
||||
|
||||
it("should get album location", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
Country: "at",
|
||||
State: "Salzburg",
|
||||
Location: "",
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.getLocation();
|
||||
expect(result).toBe("Salzburg, Austria");
|
||||
|
||||
const values2 = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
Country: "zz",
|
||||
State: "",
|
||||
Location: "",
|
||||
};
|
||||
const album2 = new Album(values2);
|
||||
const result2 = album2.getLocation();
|
||||
expect(result2).toBe("");
|
||||
|
||||
const values3 = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
Country: "zz",
|
||||
State: "",
|
||||
Location: "Austria",
|
||||
};
|
||||
const album3 = new Album(values3);
|
||||
const result3 = album3.getLocation();
|
||||
expect(result3).toBe("Austria");
|
||||
|
||||
const values5 = {
|
||||
ID: 5,
|
||||
Title: "Salzburg",
|
||||
Slug: "salzburg",
|
||||
Country: "at",
|
||||
State: "Salzburg",
|
||||
Location: "",
|
||||
};
|
||||
const album5 = new Album(values5);
|
||||
const result5 = album5.getLocation();
|
||||
expect(result5).toBe("Austria");
|
||||
|
||||
const values6 = {
|
||||
ID: 5,
|
||||
Title: "Austria",
|
||||
Slug: "austria",
|
||||
Country: "at",
|
||||
State: "Salzburg",
|
||||
Location: "",
|
||||
};
|
||||
const album6 = new Album(values6);
|
||||
const result6 = album6.getLocation();
|
||||
expect(result6).toBe("Salzburg");
|
||||
});
|
||||
|
||||
it("should get thumbnail url", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Thumb: "d6b24d688564f7ddc7b245a414f003a8d8ff5a67",
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
UID: 66,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.thumbnailUrl("xyz");
|
||||
expect(result).toBe("/api/v1/t/d6b24d688564f7ddc7b245a414f003a8d8ff5a67/public/xyz");
|
||||
|
||||
const values2 = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
UID: 66,
|
||||
};
|
||||
const album2 = new Album(values2);
|
||||
const result2 = album2.thumbnailUrl("xyz");
|
||||
expect(result2).toBe("/api/v1/albums/66/t/public/xyz");
|
||||
|
||||
const values3 = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
};
|
||||
const album3 = new Album(values3);
|
||||
const result3 = album3.thumbnailUrl("xyz");
|
||||
expect(result3).toBe("/api/v1/svg/album");
|
||||
});
|
||||
|
||||
it("should get created date string", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.getCreatedString();
|
||||
expect(result.replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("should get album date string with invalid day", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: -1,
|
||||
Month: 5,
|
||||
Year: 2019,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.getDateString();
|
||||
expect(result).toBe("May 2019");
|
||||
});
|
||||
|
||||
it("should get album date string with invalid month", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: 1,
|
||||
Month: -5,
|
||||
Year: 2000,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.getDateString();
|
||||
expect(result).toBe("2000");
|
||||
});
|
||||
|
||||
it("should get album date string with invalid year", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: 1,
|
||||
Month: 5,
|
||||
Year: 800,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.getDateString();
|
||||
expect(result).toBe("Unknown");
|
||||
});
|
||||
|
||||
it("should get album date string", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: 1,
|
||||
Month: 5,
|
||||
Year: 2000,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.getDateString();
|
||||
expect(result).toBe("Monday, May 1, 2000");
|
||||
});
|
||||
|
||||
it("should get day string", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: 8,
|
||||
Month: 5,
|
||||
Year: 2019,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.dayString();
|
||||
expect(result).toBe("08");
|
||||
});
|
||||
|
||||
it("should get month string", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: 8,
|
||||
Month: -5,
|
||||
Year: 2019,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.monthString();
|
||||
expect(result).toBe("01");
|
||||
});
|
||||
|
||||
it("should get year string", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Title: "Christmas 2019",
|
||||
Slug: "christmas-2019",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Day: 8,
|
||||
Month: -5,
|
||||
Year: 800,
|
||||
};
|
||||
const album = new Album(values);
|
||||
const result = album.yearString();
|
||||
expect(result).toBe(new Date().getFullYear().toString().padStart(4, "0"));
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Album.getModelName();
|
||||
expect(result).toBe("Album");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Album.getCollectionResource();
|
||||
expect(result).toBe("albums");
|
||||
});
|
||||
|
||||
it("should return batch size", () => {
|
||||
expect(Album.batchSize()).toBe(BatchSize);
|
||||
Album.setBatchSize(30);
|
||||
expect(Album.batchSize()).toBe(30);
|
||||
Album.setBatchSize(BatchSize);
|
||||
});
|
||||
|
||||
it("should like album", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Favorite: false };
|
||||
const album = new Album(values);
|
||||
expect(album.Favorite).toBe(false);
|
||||
album.like();
|
||||
expect(album.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should unlike album", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Favorite: true };
|
||||
const album = new Album(values);
|
||||
expect(album.Favorite).toBe(true);
|
||||
album.unlike();
|
||||
expect(album.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should toggle like", () => {
|
||||
const values = { ID: 5, Title: "Christmas 2019", Slug: "christmas-2019", Favorite: true };
|
||||
const album = new Album(values);
|
||||
expect(album.Favorite).toBe(true);
|
||||
album.toggleLike();
|
||||
expect(album.Favorite).toBe(false);
|
||||
album.toggleLike();
|
||||
expect(album.Favorite).toBe(true);
|
||||
});
|
||||
});
|
||||
45
frontend/tests/vitest/model/config-options.test.js
Normal file
45
frontend/tests/vitest/model/config-options.test.js
Normal file
@@ -0,0 +1,45 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import "../fixtures";
|
||||
import ConfigOptions from "model/config-options";
|
||||
|
||||
describe("model/config-options", () => {
|
||||
it("should get options defaults", () => {
|
||||
const values = {};
|
||||
const options = new ConfigOptions(values);
|
||||
const result = options.getDefaults();
|
||||
expect(result.Debug).toBe(false);
|
||||
expect(result.ReadOnly).toBe(false);
|
||||
expect(result.ThumbSize).toBe(0);
|
||||
});
|
||||
|
||||
it("should test changed", () => {
|
||||
const values = {};
|
||||
const options = new ConfigOptions(values);
|
||||
expect(options.changed()).toBe(false);
|
||||
});
|
||||
|
||||
it("should load options", async () => {
|
||||
const values = {};
|
||||
const options = new ConfigOptions(values);
|
||||
try {
|
||||
const response = await options.load();
|
||||
expect(response.success).toBe("ok");
|
||||
} catch (error) {
|
||||
// Vitest will fail the test if a promise rejects
|
||||
throw error;
|
||||
}
|
||||
expect(options.changed()).toBe(false);
|
||||
});
|
||||
|
||||
it("should save options", async () => {
|
||||
const values = { Debug: true };
|
||||
const options = new ConfigOptions(values);
|
||||
try {
|
||||
const response = await options.save();
|
||||
expect(response.success).toBe("ok");
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
expect(options.changed()).toBe(false);
|
||||
});
|
||||
});
|
||||
161
frontend/tests/vitest/model/face.test.js
Normal file
161
frontend/tests/vitest/model/face.test.js
Normal file
@@ -0,0 +1,161 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Face, BatchSize } from "model/face";
|
||||
|
||||
describe("model/face", () => {
|
||||
it("should get face defaults", () => {
|
||||
const values = {};
|
||||
const face = new Face(values);
|
||||
const result = face.getDefaults();
|
||||
expect(result.ID).toBe("");
|
||||
expect(result.SampleRadius).toBe(0.0);
|
||||
});
|
||||
|
||||
it("should get route view", () => {
|
||||
const values = { ID: "f123ghytrfggd", Samples: 5 };
|
||||
const face = new Face(values);
|
||||
const result = face.route("test");
|
||||
expect(result.name).toBe("test");
|
||||
expect(result.query.q).toBe("face:f123ghytrfggd");
|
||||
});
|
||||
|
||||
it("should return classes", () => {
|
||||
const values = { ID: "f123ghytrfggd", Samples: 5 };
|
||||
const face = new Face(values);
|
||||
const result = face.classes(true);
|
||||
expect(result).toContain("is-face");
|
||||
expect(result).toContain("uid-f123ghytrfggd");
|
||||
expect(result).toContain("is-selected");
|
||||
expect(result).not.toContain("is-hidden");
|
||||
|
||||
const result2 = face.classes(false);
|
||||
expect(result2).toContain("is-face");
|
||||
expect(result2).toContain("uid-f123ghytrfggd");
|
||||
expect(result2).not.toContain("is-selected");
|
||||
expect(result2).not.toContain("is-hidden");
|
||||
|
||||
const values2 = { ID: "f123ghytrfggd", Samples: 5, Hidden: true };
|
||||
const face2 = new Face(values2);
|
||||
const result3 = face2.classes(true);
|
||||
expect(result3).toContain("is-face");
|
||||
expect(result3).toContain("uid-f123ghytrfggd");
|
||||
expect(result3).toContain("is-selected");
|
||||
expect(result3).toContain("is-hidden");
|
||||
});
|
||||
|
||||
it("should get face entity name", () => {
|
||||
const values = { ID: "f123ghytrfggd", Samples: 5 };
|
||||
const face = new Face(values);
|
||||
const result = face.getEntityName();
|
||||
expect(result).toBe("f123ghytrfggd");
|
||||
});
|
||||
|
||||
it("should get face title", () => {
|
||||
const values = { ID: "f123ghytrfggd", Samples: 5 };
|
||||
const face = new Face(values);
|
||||
const result = face.getTitle();
|
||||
expect(result).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should get thumbnail url", () => {
|
||||
const values = {
|
||||
ID: "f123ghytrfggd",
|
||||
Samples: 5,
|
||||
MarkerUID: "ABC123ghytr",
|
||||
FileUID: "fhjouohnnmnd",
|
||||
Name: "",
|
||||
Thumb: "7ca759a2b788cc5bcc08dbbce9854ff94a2f94d1",
|
||||
};
|
||||
|
||||
const face = new Face(values);
|
||||
const result = face.thumbnailUrl("xyz");
|
||||
expect(result).toBe("/api/v1/t/7ca759a2b788cc5bcc08dbbce9854ff94a2f94d1/public/xyz");
|
||||
|
||||
const values2 = {
|
||||
ID: "f123ghytrfggd",
|
||||
Samples: 5,
|
||||
Thumb: "7ca759a2b788cc5bcc08dbbce9854ff94a2f94d1",
|
||||
};
|
||||
const face2 = new Face(values2);
|
||||
const result2 = face2.thumbnailUrl();
|
||||
expect(result2).toBe("/api/v1/t/7ca759a2b788cc5bcc08dbbce9854ff94a2f94d1/public/tile_160");
|
||||
|
||||
const values3 = {
|
||||
ID: "f123ghytrfggd",
|
||||
Samples: 5,
|
||||
Thumb: "",
|
||||
};
|
||||
const face3 = new Face(values3);
|
||||
const result3 = face3.thumbnailUrl("tile_240");
|
||||
expect(result3).toBe("/api/v1/svg/portrait");
|
||||
});
|
||||
|
||||
it("should get date string", () => {
|
||||
const values = {
|
||||
ID: "f123ghytrfggd",
|
||||
Samples: 5,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const face = new Face(values);
|
||||
const result = face.getDateString();
|
||||
expect(result.replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("show and hide face", () => {
|
||||
const values = {
|
||||
ID: "f123ghytrfggd",
|
||||
Samples: 5,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Hidden: true,
|
||||
};
|
||||
const face = new Face(values);
|
||||
expect(face.Hidden).toBe(true);
|
||||
face.show();
|
||||
expect(face.Hidden).toBe(false);
|
||||
face.hide();
|
||||
expect(face.Hidden).toBe(true);
|
||||
});
|
||||
|
||||
it("should toggle hidden", () => {
|
||||
const values = {
|
||||
ID: "f123ghytrfggd",
|
||||
Samples: 5,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
Hidden: true,
|
||||
};
|
||||
const face = new Face(values);
|
||||
expect(face.Hidden).toBe(true);
|
||||
face.toggleHidden();
|
||||
expect(face.Hidden).toBe(false);
|
||||
face.toggleHidden();
|
||||
expect(face.Hidden).toBe(true);
|
||||
});
|
||||
|
||||
it("should set name", async () => {
|
||||
const values = { ID: "f123ghytrfggd", Samples: 5, MarkerUID: "mDC123ghytr", Name: "Jane" };
|
||||
const face = new Face(values);
|
||||
|
||||
const response1 = await face.setName("testname");
|
||||
expect(response1.Name).toBe("testname");
|
||||
|
||||
const response2 = await face.setName("");
|
||||
expect(response2.Name).toBe("testname");
|
||||
});
|
||||
|
||||
it("should return batch size", () => {
|
||||
expect(Face.batchSize()).toBe(BatchSize);
|
||||
Face.setBatchSize(30);
|
||||
expect(Face.batchSize()).toBe(30);
|
||||
Face.setBatchSize(BatchSize);
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Face.getCollectionResource();
|
||||
expect(result).toBe("faces");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Face.getModelName();
|
||||
expect(result).toBe("Face");
|
||||
});
|
||||
});
|
||||
470
frontend/tests/vitest/model/file.test.js
Normal file
470
frontend/tests/vitest/model/file.test.js
Normal file
@@ -0,0 +1,470 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import File from "model/file";
|
||||
|
||||
describe("model/file", () => {
|
||||
it("should return classes", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Primary: true,
|
||||
Sidecar: true,
|
||||
Video: true,
|
||||
};
|
||||
const file = new File(values);
|
||||
const result = file.classes(true);
|
||||
expect(result).toContain("is-file");
|
||||
expect(result).toContain("uid-ABC123");
|
||||
expect(result).toContain("is-primary");
|
||||
expect(result).toContain("is-sidecar");
|
||||
expect(result).toContain("is-video");
|
||||
expect(result).toContain("is-selected");
|
||||
});
|
||||
|
||||
it("should get file defaults", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
};
|
||||
const file = new File(values);
|
||||
const result = file.getDefaults();
|
||||
expect(result.UID).toBe("");
|
||||
expect(result.Size).toBe(0);
|
||||
});
|
||||
|
||||
it("should get file base name", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
const result = file.baseName();
|
||||
expect(result).toBe("IMG123.jpg");
|
||||
const result2 = file.baseName(8);
|
||||
expect(result2).toBe("IMG123.…");
|
||||
});
|
||||
|
||||
it("should return true", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.isFile()).toBe(true);
|
||||
});
|
||||
|
||||
it("should return entity name", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Root: "",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.getEntityName()).toBe("/1/2/IMG123.jpg");
|
||||
});
|
||||
|
||||
it("should return thumbnail url", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.thumbnailUrl("tile_224")).toBe("/api/v1/t/54ghtfd/public/tile_224");
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Error: true,
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(file2.thumbnailUrl("tile_224")).toBe("/api/v1/svg/broken");
|
||||
|
||||
const values3 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "bd66bd2c304f45f6c160df375f34b49eb7aef321",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
FileType: "raw",
|
||||
};
|
||||
const file3 = new File(values3);
|
||||
expect(file3.thumbnailUrl("tile_224")).toBe("/api/v1/t/bd66bd2c304f45f6c160df375f34b49eb7aef321/public/tile_224");
|
||||
|
||||
const values4 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "0e437256ec20da874318b64027750b320548378c",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Sidecar: true,
|
||||
};
|
||||
const file4 = new File(values4);
|
||||
expect(file4.thumbnailUrl("tile_224")).toBe("/api/v1/svg/file");
|
||||
});
|
||||
|
||||
it("should return download url", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.getDownloadUrl("abc")).toBe("/api/v1/dl/54ghtfd?t=2lbh9x09");
|
||||
});
|
||||
|
||||
it("should not download as hash is missing", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.download()).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should calculate size", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Width: 500,
|
||||
Height: 700,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.calculateSize(600, 800).width).toBe(500);
|
||||
expect(file.calculateSize(600, 800).height).toBe(700);
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Width: 900,
|
||||
Height: 850,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(file2.calculateSize(600, 800).width).toBe(600);
|
||||
expect(file2.calculateSize(600, 800).height).toBe(567);
|
||||
|
||||
const values3 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Width: 750,
|
||||
Height: 850,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file3 = new File(values3);
|
||||
expect(file3.calculateSize(900, 450).width).toBe(398);
|
||||
expect(file3.calculateSize(900, 450).height).toBe(450);
|
||||
});
|
||||
|
||||
it("should get date string", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.getDateString().replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("should get info", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.getInfo()).toBe("JPG");
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 6,
|
||||
UID: "ABC124",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "mp4",
|
||||
Duration: 8009,
|
||||
FPS: 60,
|
||||
Name: "1/2/IMG123.mp4",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(file2.getInfo()).toBe("MP4, 8µs, 60.0 FPS");
|
||||
});
|
||||
|
||||
it("should return storage location", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Root: "sidecar",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.storageInfo()).toBe("Sidecar");
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 6,
|
||||
UID: "ABC124",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "mp4",
|
||||
Duration: 8009,
|
||||
FPS: 60,
|
||||
Root: "/",
|
||||
Name: "1/2/IMG123.mp4",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(file2.storageInfo()).toBe("Originals");
|
||||
|
||||
const values3 = {
|
||||
InstanceID: 6,
|
||||
UID: "ABC124",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "mp4",
|
||||
Duration: 8009,
|
||||
FPS: 60,
|
||||
Root: "",
|
||||
Name: "1/2/IMG123.mp4",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file3 = new File(values3);
|
||||
expect(file3.storageInfo()).toBe("");
|
||||
});
|
||||
|
||||
it("should return whether file is animated", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
MediaType: "image",
|
||||
Duration: 500,
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.isAnimated()).toBe(true);
|
||||
});
|
||||
|
||||
it("should get type info", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Primary: true,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.typeInfo()).toBe("Image");
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "mp4",
|
||||
Duration: 8009,
|
||||
FPS: 60,
|
||||
Name: "1/2/IMG123.mp4",
|
||||
Video: true,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(file2.typeInfo()).toBe("Video");
|
||||
|
||||
const values3 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Sidecar: true,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file3 = new File(values3);
|
||||
expect(file3.typeInfo()).toBe("Sidecar JPEG");
|
||||
|
||||
const values4 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "gif",
|
||||
MediaType: "image",
|
||||
Duration: 8009,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Sidecar: true,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file4 = new File(values4);
|
||||
expect(file4.typeInfo()).toBe("Sidecar GIF Image");
|
||||
|
||||
const values5 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "svg",
|
||||
MediaType: "vector",
|
||||
Name: "1/2/IMG123.svg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file5 = new File(values5);
|
||||
expect(file5.typeInfo()).toBe("SVG");
|
||||
});
|
||||
|
||||
it("should get size info", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Size: 8009,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.sizeInfo()).toBe("8 KB");
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Size: 8009999987,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(file2.sizeInfo()).toBe("7.5 GB");
|
||||
|
||||
const values3 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Size: 8009999987,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Width: 500,
|
||||
Height: 800,
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file3 = new File(values3);
|
||||
expect(file3.sizeInfo()).toBe("500 × 800, 7.5 GB");
|
||||
});
|
||||
|
||||
it("should like file", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Duration: 8009,
|
||||
Favorite: false,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.Favorite).toBe(false);
|
||||
file.like();
|
||||
expect(file.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should unlike file", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Duration: 8009,
|
||||
Favorite: true,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.Favorite).toBe(true);
|
||||
file.unlike();
|
||||
expect(file.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should toggle like", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Duration: 8009,
|
||||
Favorite: true,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.Favorite).toBe(true);
|
||||
file.toggleLike();
|
||||
expect(file.Favorite).toBe(false);
|
||||
file.toggleLike();
|
||||
expect(file.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should get photo resource", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
PhotoUID: "bgad457",
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Duration: 8009,
|
||||
Favorite: true,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(file.getPhotoResource()).toBe("photos/bgad457");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = File.getCollectionResource();
|
||||
expect(result).toBe("files");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = File.getModelName();
|
||||
expect(result).toBe("File");
|
||||
});
|
||||
});
|
||||
237
frontend/tests/vitest/model/folder.test.js
Normal file
237
frontend/tests/vitest/model/folder.test.js
Normal file
@@ -0,0 +1,237 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import Folder from "model/folder";
|
||||
|
||||
describe("model/folder", () => {
|
||||
it("should return classes", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
Favorite: true,
|
||||
Private: true,
|
||||
Ignore: false,
|
||||
Watch: false,
|
||||
FileCount: 0,
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
const result = folder.classes(true);
|
||||
expect(result).toContain("is-folder");
|
||||
expect(result).toContain("uid-dqbevau2zlhxrxww");
|
||||
expect(result).toContain("is-favorite");
|
||||
expect(result).toContain("is-private");
|
||||
expect(result).toContain("is-selected");
|
||||
});
|
||||
|
||||
it("should get folder defaults", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Type: "",
|
||||
Title: "Halloween Party",
|
||||
Category: "",
|
||||
Description: "",
|
||||
Order: "",
|
||||
Country: "",
|
||||
Year: "",
|
||||
Month: "",
|
||||
Favorite: false,
|
||||
Private: false,
|
||||
Ignore: false,
|
||||
Watch: false,
|
||||
FileCount: 0,
|
||||
CreatedAt: "",
|
||||
UpdatedAt: "",
|
||||
};
|
||||
const model = new Folder(values);
|
||||
const result = model.getDefaults();
|
||||
expect(result.Folder).toBe(true);
|
||||
expect(result.Path).toBe("");
|
||||
expect(result.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should get folder base name", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Type: "",
|
||||
Title: "Halloween Party",
|
||||
Category: "",
|
||||
Description: "",
|
||||
Order: "",
|
||||
Country: "",
|
||||
Year: "",
|
||||
Month: "",
|
||||
Favorite: false,
|
||||
Private: false,
|
||||
Ignore: false,
|
||||
Watch: false,
|
||||
FileCount: 0,
|
||||
CreatedAt: "",
|
||||
UpdatedAt: "",
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
const result = folder.baseName();
|
||||
expect(result).toBe("10-Halloween");
|
||||
const result2 = folder.baseName(8);
|
||||
expect(result2).toBe("10-Hall…");
|
||||
});
|
||||
|
||||
it("should return false", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.isFile()).toBe(false);
|
||||
});
|
||||
|
||||
it("should return entity name", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.getEntityName()).toBe("/2011/10-Halloween");
|
||||
});
|
||||
|
||||
it("should return thumbnail url", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.thumbnailUrl("tile_224")).toBe("/api/v1/folders/t/dqbevau2zlhxrxww/public/tile_224");
|
||||
});
|
||||
|
||||
it("should get date string", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.getDateString().replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("should toggle like", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
Favorite: true,
|
||||
Private: true,
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.Favorite).toBe(true);
|
||||
folder.toggleLike();
|
||||
expect(folder.Favorite).toBe(false);
|
||||
folder.toggleLike();
|
||||
expect(folder.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should like folder", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
Favorite: false,
|
||||
Private: true,
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.Favorite).toBe(false);
|
||||
folder.like();
|
||||
expect(folder.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should unlike folder", () => {
|
||||
const values = {
|
||||
Folder: true,
|
||||
Path: "2011/10-Halloween",
|
||||
Root: "",
|
||||
UID: "dqbevau2zlhxrxww",
|
||||
Title: "Halloween Party",
|
||||
Favorite: true,
|
||||
Private: true,
|
||||
};
|
||||
const folder = new Folder(values);
|
||||
expect(folder.Favorite).toBe(true);
|
||||
folder.unlike();
|
||||
expect(folder.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Folder.getCollectionResource();
|
||||
expect(result).toBe("folders");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Folder.getModelName();
|
||||
expect(result).toBe("Folder");
|
||||
});
|
||||
|
||||
it("should test find all", async () => {
|
||||
try {
|
||||
const response = await Folder.findAll("2011/10-Halloween");
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.count).toBe(4);
|
||||
expect(response.folders).toBe(3);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
it("should test find all uncached", async () => {
|
||||
try {
|
||||
const response = await Folder.findAllUncached("2011/10-Halloween");
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.count).toBe(3);
|
||||
expect(response.folders).toBe(2);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
it("should test find in originals", async () => {
|
||||
try {
|
||||
const response = await Folder.originals("2011/10-Halloween", { recursive: true });
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.count).toBe(4);
|
||||
expect(response.folders).toBe(3);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
|
||||
it("should test search", async () => {
|
||||
try {
|
||||
const response = await Folder.search("2011/10-Halloween", { recursive: true, uncached: true });
|
||||
expect(response.status).toBe(200);
|
||||
expect(response.count).toBe(3);
|
||||
expect(response.folders).toBe(2);
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
});
|
||||
});
|
||||
139
frontend/tests/vitest/model/label.test.js
Normal file
139
frontend/tests/vitest/model/label.test.js
Normal file
@@ -0,0 +1,139 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Label, BatchSize } from "model/label";
|
||||
|
||||
describe("model/label", () => {
|
||||
it("should get route view", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat" };
|
||||
const label = new Label(values);
|
||||
const result = label.route("test");
|
||||
expect(result.name).toBe("test");
|
||||
expect(result.query.q).toBe("label:black-cat");
|
||||
});
|
||||
|
||||
it("should return batch size", () => {
|
||||
expect(Label.batchSize()).toBe(BatchSize);
|
||||
Label.setBatchSize(30);
|
||||
expect(Label.batchSize()).toBe(30);
|
||||
Label.setBatchSize(BatchSize);
|
||||
});
|
||||
|
||||
it("should return classes", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat", Favorite: true };
|
||||
const label = new Label(values);
|
||||
const result = label.classes(true);
|
||||
expect(result).toContain("is-label");
|
||||
expect(result).toContain("uid-ABC123");
|
||||
expect(result).toContain("is-selected");
|
||||
expect(result).toContain("is-favorite");
|
||||
});
|
||||
|
||||
it("should get label entity name", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat" };
|
||||
const label = new Label(values);
|
||||
const result = label.getEntityName();
|
||||
expect(result).toBe("black-cat");
|
||||
});
|
||||
|
||||
it("should get label id", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat" };
|
||||
const label = new Label(values);
|
||||
const result = label.getId();
|
||||
expect(result).toBe("ABC123");
|
||||
});
|
||||
|
||||
it("should get label title", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat" };
|
||||
const label = new Label(values);
|
||||
const result = label.getTitle();
|
||||
expect(result).toBe("Black Cat");
|
||||
});
|
||||
|
||||
it("should get thumbnail url", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
UID: "ABC123",
|
||||
Thumb: "c6b24d688564f7ddc7b245a414f003a8d8ff5a67",
|
||||
Name: "Black Cat",
|
||||
Slug: "black-cat",
|
||||
};
|
||||
const label = new Label(values);
|
||||
const result = label.thumbnailUrl("xyz");
|
||||
expect(result).toBe("/api/v1/t/c6b24d688564f7ddc7b245a414f003a8d8ff5a67/public/xyz");
|
||||
|
||||
const values2 = {
|
||||
ID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "Black Cat",
|
||||
Slug: "black-cat",
|
||||
};
|
||||
const label2 = new Label(values2);
|
||||
const result2 = label2.thumbnailUrl("xyz");
|
||||
expect(result2).toBe("/api/v1/labels/ABC123/t/public/xyz");
|
||||
|
||||
const values3 = {
|
||||
ID: 5,
|
||||
Name: "Black Cat",
|
||||
Slug: "black-cat",
|
||||
};
|
||||
const label3 = new Label(values3);
|
||||
const result3 = label3.thumbnailUrl("xyz");
|
||||
expect(result3).toBe("/api/v1/svg/label");
|
||||
});
|
||||
|
||||
it("should get date string", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "Black Cat",
|
||||
Slug: "black-cat",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const label = new Label(values);
|
||||
const result = label.getDateString();
|
||||
expect(result.replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Label.getModelName();
|
||||
expect(result).toBe("Label");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Label.getCollectionResource();
|
||||
expect(result).toBe("labels");
|
||||
});
|
||||
|
||||
it("should like label", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat", Favorite: false };
|
||||
const label = new Label(values);
|
||||
expect(label.Favorite).toBe(false);
|
||||
label.like();
|
||||
expect(label.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should unlike label", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat", Favorite: true };
|
||||
const label = new Label(values);
|
||||
expect(label.Favorite).toBe(true);
|
||||
label.unlike();
|
||||
expect(label.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should toggle like", () => {
|
||||
const values = { ID: 5, UID: "ABC123", Name: "Black Cat", Slug: "black-cat", Favorite: true };
|
||||
const label = new Label(values);
|
||||
expect(label.Favorite).toBe(true);
|
||||
label.toggleLike();
|
||||
expect(label.Favorite).toBe(false);
|
||||
label.toggleLike();
|
||||
expect(label.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should get label defaults", () => {
|
||||
const values = { ID: 5, UID: "ABC123" };
|
||||
const label = new Label(values);
|
||||
const result = label.getDefaults();
|
||||
expect(result.ID).toBe(0);
|
||||
});
|
||||
});
|
||||
101
frontend/tests/vitest/model/link.test.js
Normal file
101
frontend/tests/vitest/model/link.test.js
Normal file
@@ -0,0 +1,101 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import Link from "model/link";
|
||||
|
||||
describe("model/link", () => {
|
||||
it("should get link defaults", () => {
|
||||
const values = { UID: 5 };
|
||||
const link = new Link(values);
|
||||
const result = link.getDefaults();
|
||||
expect(result.UID).toBe("");
|
||||
expect(result.Perm).toBe(0);
|
||||
expect(result.Comment).toBe("");
|
||||
expect(result.ShareUID).toBe("");
|
||||
});
|
||||
|
||||
it("should get link url", () => {
|
||||
const values = { UID: 5, Token: "1234hhtbbt", Slug: "friends", ShareUID: "family" };
|
||||
const link = new Link(values);
|
||||
const result = link.url();
|
||||
expect(result).toBe("http://localhost:2342/s/1234hhtbbt/friends");
|
||||
const values2 = { UID: 5, Token: "", ShareUID: "family" };
|
||||
const link2 = new Link(values2);
|
||||
const result2 = link2.url();
|
||||
expect(result2).toBe("http://localhost:2342/s/…/family");
|
||||
});
|
||||
|
||||
it("should get link caption", () => {
|
||||
const values = { UID: 5, Token: "AcfgbTTh", Slug: "friends", ShareUID: "family" };
|
||||
const link = new Link(values);
|
||||
const result = link.caption();
|
||||
expect(result).toBe("/s/acfgbtth");
|
||||
});
|
||||
|
||||
it("should get link id", () => {
|
||||
const values = { UID: 5 };
|
||||
const link = new Link(values);
|
||||
const result = link.getId();
|
||||
expect(result).toBe(5);
|
||||
const values2 = {};
|
||||
const link2 = new Link(values2);
|
||||
const result2 = link2.getId();
|
||||
expect(result2).toBe(false);
|
||||
});
|
||||
|
||||
it("should test has id", () => {
|
||||
const values = { UID: 5 };
|
||||
const link = new Link(values);
|
||||
const result = link.hasId();
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should get link slug", () => {
|
||||
const values = { UID: 5, Token: "AcfgbTTh", Slug: "friends", ShareUID: "family" };
|
||||
const link = new Link(values);
|
||||
const result = link.getSlug();
|
||||
expect(result).toBe("friends");
|
||||
});
|
||||
|
||||
it("should test has slug", () => {
|
||||
const values = { UID: 5, Token: "AcfgbTTh", Slug: "friends", ShareUID: "family" };
|
||||
const link = new Link(values);
|
||||
const result = link.hasSlug();
|
||||
expect(result).toBe(true);
|
||||
const values2 = { UID: 5, Token: "AcfgbTTh", ShareUID: "family" };
|
||||
const link2 = new Link(values2);
|
||||
const result2 = link2.hasSlug();
|
||||
expect(result2).toBe(false);
|
||||
});
|
||||
|
||||
it("should clone link", () => {
|
||||
const values = { UID: 5, Token: "AcfgbTTh", Slug: "friends", ShareUID: "family" };
|
||||
const link = new Link(values);
|
||||
const result = link.clone();
|
||||
expect(result.Slug).toBe("friends");
|
||||
expect(result.Token).toBe("AcfgbTTh");
|
||||
});
|
||||
|
||||
it("should test expire", () => {
|
||||
const values = {
|
||||
UID: 5,
|
||||
Token: "AcfgbTTh",
|
||||
Slug: "friends",
|
||||
ShareUID: "family",
|
||||
Expires: 80000,
|
||||
ModifiedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const link = new Link(values);
|
||||
const result = link.expires();
|
||||
expect(result).toBe("Jul 9, 2012");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Link.getCollectionResource();
|
||||
expect(result).toBe("links");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Link.getModelName();
|
||||
expect(result).toBe("Link");
|
||||
});
|
||||
});
|
||||
@@ -1,10 +1,6 @@
|
||||
import { describe, it, expect, beforeEach } from "vitest";
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Marker, BatchSize } from "model/marker";
|
||||
import { setupMarkerMocks } from "../fixtures";
|
||||
|
||||
beforeEach(() => {
|
||||
setupMarkerMocks();
|
||||
});
|
||||
|
||||
describe("model/marker", () => {
|
||||
it("should get marker defaults", () => {
|
||||
@@ -111,7 +107,7 @@ describe("model/marker", () => {
|
||||
};
|
||||
const marker = new Marker(values);
|
||||
const result = marker.getDateString();
|
||||
expect(result).toBe("2023-10-01 10:00:00");
|
||||
expect(result.replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("should approve marker", () => {
|
||||
@@ -174,7 +170,6 @@ describe("model/marker", () => {
|
||||
};
|
||||
const marker2 = new Marker(values2);
|
||||
expect(marker2.Name).toBe("testname");
|
||||
|
||||
const response = await marker2.setName();
|
||||
expect(response.success).toBe("ok");
|
||||
});
|
||||
|
||||
1720
frontend/tests/vitest/model/photo.test.js
Normal file
1720
frontend/tests/vitest/model/photo.test.js
Normal file
File diff suppressed because it is too large
Load Diff
200
frontend/tests/vitest/model/rest.test.js
Normal file
200
frontend/tests/vitest/model/rest.test.js
Normal file
@@ -0,0 +1,200 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import "../fixtures";
|
||||
import Rest from "model/rest";
|
||||
import Album from "model/album";
|
||||
import Label from "model/label";
|
||||
import Link from "model/link";
|
||||
|
||||
describe("model/abstract", () => {
|
||||
it("should set values", () => {
|
||||
const values = { ID: 5, Name: "Black Cat", Slug: "black-cat" };
|
||||
const label = new Label(values);
|
||||
expect(label.Name).toBe("Black Cat");
|
||||
expect(label.Slug).toBe("black-cat");
|
||||
label.setValues();
|
||||
expect(label.Name).toBe("Black Cat");
|
||||
expect(label.Slug).toBe("black-cat");
|
||||
const values2 = { ID: 6, Name: "White Cat", Slug: "white-cat" };
|
||||
label.setValues(values2);
|
||||
expect(label.Name).toBe("White Cat");
|
||||
expect(label.Slug).toBe("white-cat");
|
||||
});
|
||||
|
||||
it("should get values", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.getValues();
|
||||
expect(result.Name).toBe("Christmas 2019");
|
||||
expect(result.UID).toBe(66);
|
||||
});
|
||||
|
||||
it("should get id", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.getId();
|
||||
expect(result).toBe(66);
|
||||
});
|
||||
|
||||
it("should test if id exists", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.hasId();
|
||||
expect(result).toBe(true);
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Rest.getModelName();
|
||||
expect(result).toBe("Item");
|
||||
});
|
||||
|
||||
it("should update album", async () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
expect(album.Description).toBeUndefined();
|
||||
album.Name = "Christmas 2020";
|
||||
await album.update();
|
||||
expect(album.Description).toBe("Test description");
|
||||
});
|
||||
|
||||
it("should save album", async () => {
|
||||
const values = { UID: "abc", Name: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album = new Album(values);
|
||||
album.Name = "Christmas 2020";
|
||||
expect(album.Description).toBeUndefined();
|
||||
await album.save();
|
||||
expect(album.Description).toBe("Test description");
|
||||
|
||||
const values2 = { Name: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album2 = new Album(values2);
|
||||
album2.Name = "Christmas 2020";
|
||||
expect(album2.Description).toBeUndefined();
|
||||
const response = await album2.save();
|
||||
expect(response.success).toBe("ok");
|
||||
expect(album2.Description).toBeUndefined();
|
||||
});
|
||||
|
||||
it("should remove album", async () => {
|
||||
const values = { UID: "abc", Name: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album = new Album(values);
|
||||
expect(album.Name).toBe("Christmas 2019");
|
||||
await album.remove();
|
||||
});
|
||||
|
||||
it("should get edit form", async () => {
|
||||
const values = { UID: "abc", Name: "Christmas 2019", Slug: "christmas-2019" };
|
||||
const album = new Album(values);
|
||||
const result = await album.getEditForm();
|
||||
expect(result.definition.foo).toBe("edit");
|
||||
});
|
||||
|
||||
it("should get create form", async () => {
|
||||
const result = await Album.getCreateForm();
|
||||
expect(result.definition.foo).toBe("bar");
|
||||
});
|
||||
|
||||
it("should get search form", async () => {
|
||||
const result = await Album.getSearchForm();
|
||||
expect(result.definition.foo).toBe("bar");
|
||||
});
|
||||
|
||||
it("should search label", async () => {
|
||||
const result = await Album.search();
|
||||
expect(result.data.ID).toBe(51);
|
||||
expect(result.data.Name).toBe("tabby cat");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
expect(Rest.getCollectionResource()).toBe("");
|
||||
});
|
||||
|
||||
it("should get slug", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.getSlug();
|
||||
expect(result).toBe("christmas-2019");
|
||||
});
|
||||
|
||||
it("should get slug", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.clone();
|
||||
expect(result.Slug).toBe("christmas-2019");
|
||||
expect(result.Name).toBe("Christmas 2019");
|
||||
expect(result.ID).toBe(5);
|
||||
});
|
||||
|
||||
it("should find album", async () => {
|
||||
const values = { Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const response = await album.find(5);
|
||||
expect(response.UID).toBe("5");
|
||||
});
|
||||
|
||||
it("should get entity name", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.getEntityName();
|
||||
expect(result).toBe("christmas-2019");
|
||||
});
|
||||
|
||||
it("should return model name", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = album.modelName();
|
||||
expect(result).toBe("Album");
|
||||
});
|
||||
|
||||
it("should return limit", () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const result = Rest.limit();
|
||||
expect(result).toBe(100000);
|
||||
expect(album.constructor.limit()).toBe(100000);
|
||||
});
|
||||
|
||||
it("should create link", async () => {
|
||||
const values = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values);
|
||||
const response = await album.createLink("passwd", 8000);
|
||||
expect(response.Slug).toBe("christmas-2019");
|
||||
});
|
||||
|
||||
it("should update link", async () => {
|
||||
const values = {
|
||||
UID: 5,
|
||||
Password: "passwd",
|
||||
Slug: "friends",
|
||||
Expires: 80000,
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
Token: "abchhgftryue2345",
|
||||
};
|
||||
const link = new Link(values);
|
||||
const values2 = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values2);
|
||||
const response = await album.updateLink(link);
|
||||
expect(response.Slug).toBe("friends");
|
||||
});
|
||||
|
||||
it("should remove link", async () => {
|
||||
const values = {
|
||||
UID: 5,
|
||||
Password: "passwd",
|
||||
Slug: "friends",
|
||||
Expires: 80000,
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const link = new Link(values);
|
||||
const values2 = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values2);
|
||||
const response = await album.removeLink(link);
|
||||
expect(response.Success).toBe("ok");
|
||||
});
|
||||
|
||||
it("should return links", async () => {
|
||||
const values2 = { ID: 5, Name: "Christmas 2019", Slug: "christmas-2019", UID: 66 };
|
||||
const album = new Album(values2);
|
||||
const response = await album.links();
|
||||
expect(response.count).toBe(2);
|
||||
expect(response.models.length).toBe(2);
|
||||
});
|
||||
});
|
||||
59
frontend/tests/vitest/model/service.test.js
Normal file
59
frontend/tests/vitest/model/service.test.js
Normal file
@@ -0,0 +1,59 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import "../fixtures";
|
||||
|
||||
import Service from "model/service";
|
||||
import Photo from "model/photo";
|
||||
|
||||
describe("model/service", () => {
|
||||
it("should get service defaults", () => {
|
||||
const values = { ID: 5 };
|
||||
const service = new Service(values);
|
||||
const result = service.getDefaults();
|
||||
expect(result.ID).toBe(0);
|
||||
expect(result.AccShare).toBe(true);
|
||||
expect(result.AccName).toBe("");
|
||||
});
|
||||
|
||||
it("should get service entity name", () => {
|
||||
const values = { ID: 5, AccName: "Test Name" };
|
||||
const service = new Service(values);
|
||||
const result = service.getEntityName();
|
||||
expect(result).toBe("Test Name");
|
||||
});
|
||||
|
||||
it("should get service id", () => {
|
||||
const values = { ID: 5, AccName: "Test Name" };
|
||||
const service = new Service(values);
|
||||
const result = service.getId();
|
||||
expect(result).toBe(5);
|
||||
});
|
||||
|
||||
it("should get folders", async () => {
|
||||
const values = { ID: 123, AccName: "Test Name" };
|
||||
const service = new Service(values);
|
||||
const response = await service.Folders();
|
||||
expect(response.foo).toBe("folders");
|
||||
});
|
||||
|
||||
it("should get share photos", async () => {
|
||||
const values = { ID: 123, AccName: "Test Name" };
|
||||
const service = new Service(values);
|
||||
const values1 = { ID: 5, Title: "Crazy Cat", UID: 789 };
|
||||
const photo = new Photo(values1);
|
||||
const values2 = { ID: 6, Title: "Crazy Cat 2", UID: 783 };
|
||||
const photo2 = new Photo(values2);
|
||||
const Photos = [photo, photo2];
|
||||
const response = await service.Upload(Photos, "destination");
|
||||
expect(response.foo).toBe("upload");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Service.getCollectionResource();
|
||||
expect(result).toBe("services");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Service.getModelName();
|
||||
expect(result).toBe("Account");
|
||||
});
|
||||
});
|
||||
25
frontend/tests/vitest/model/settings.test.js
Normal file
25
frontend/tests/vitest/model/settings.test.js
Normal file
@@ -0,0 +1,25 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import "../fixtures";
|
||||
import Settings from "model/settings";
|
||||
|
||||
describe("model/settings", () => {
|
||||
it("should return if key was changed", () => {
|
||||
const model = new Settings({ ui: { language: "de", scrollbar: false } });
|
||||
expect(model.changed("ui", "scrollbar")).toBe(false);
|
||||
expect(model.changed("ui", "language")).toBe(false);
|
||||
});
|
||||
|
||||
it("should load settings", async () => {
|
||||
const model = new Settings({ ui: { language: "de", scrollbar: false } });
|
||||
const response = await model.load();
|
||||
expect(response["ui"]["scrollbar"]).toBe(false);
|
||||
expect(response["ui"]["language"]).toBe("de");
|
||||
});
|
||||
|
||||
it("should save settings", async () => {
|
||||
const model = new Settings({ ui: { language: "de", scrollbar: false } });
|
||||
const response = await model.save();
|
||||
expect(response["ui"]["scrollbar"]).toBe(false);
|
||||
expect(response["ui"]["language"]).toBe("de");
|
||||
});
|
||||
});
|
||||
253
frontend/tests/vitest/model/subject.test.js
Normal file
253
frontend/tests/vitest/model/subject.test.js
Normal file
@@ -0,0 +1,253 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import { Subject, BatchSize } from "model/subject";
|
||||
|
||||
describe("model/subject", () => {
|
||||
it("should get face defaults", () => {
|
||||
const values = {};
|
||||
const subject = new Subject(values);
|
||||
const result = subject.getDefaults();
|
||||
expect(result.UID).toBe("");
|
||||
expect(result.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should get route view", () => {
|
||||
const values = { UID: "s123ghytrfggd", Type: "person", Src: "manual" };
|
||||
const subject = new Subject(values);
|
||||
const result = subject.route("test");
|
||||
expect(result.name).toBe("test");
|
||||
expect(result.query.q).toBe("subject:s123ghytrfggd");
|
||||
const values2 = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
};
|
||||
const subject2 = new Subject(values2);
|
||||
const result2 = subject2.route("test");
|
||||
expect(result2.name).toBe("test");
|
||||
expect(result2.query.q).toBe("person:jane-doe");
|
||||
});
|
||||
|
||||
it("should return classes", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
Excluded: true,
|
||||
Private: true,
|
||||
Hidden: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
const result = subject.classes(true);
|
||||
expect(result).toContain("is-subject");
|
||||
expect(result).toContain("uid-s123ghytrfggd");
|
||||
expect(result).toContain("is-selected");
|
||||
expect(result).not.toContain("is-favorite");
|
||||
expect(result).toContain("is-private");
|
||||
expect(result).toContain("is-excluded");
|
||||
expect(result).toContain("is-hidden");
|
||||
const values2 = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: true,
|
||||
Excluded: false,
|
||||
Private: false,
|
||||
};
|
||||
const subject2 = new Subject(values2);
|
||||
const result2 = subject2.classes(false);
|
||||
expect(result2).toContain("is-subject");
|
||||
expect(result2).toContain("uid-s123ghytrfggd");
|
||||
expect(result2).not.toContain("is-selected");
|
||||
expect(result2).toContain("is-favorite");
|
||||
expect(result2).not.toContain("is-private");
|
||||
expect(result2).not.toContain("is-excluded");
|
||||
});
|
||||
|
||||
it("should get subject entity name", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
Excluded: true,
|
||||
Private: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
const result = subject.getEntityName();
|
||||
expect(result).toBe("jane-doe");
|
||||
});
|
||||
|
||||
it("should get subject title", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
Excluded: true,
|
||||
Private: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
const result = subject.getTitle();
|
||||
expect(result).toBe("Jane Doe");
|
||||
});
|
||||
|
||||
it("should get thumbnail url", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
Excluded: true,
|
||||
Private: true,
|
||||
Thumb: "nicethumb",
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
const result = subject.thumbnailUrl("xyz");
|
||||
expect(result).toBe("/api/v1/t/nicethumb/public/xyz");
|
||||
const result2 = subject.thumbnailUrl();
|
||||
expect(result2).toBe("/api/v1/t/nicethumb/public/tile_160");
|
||||
const values2 = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
Excluded: true,
|
||||
Private: true,
|
||||
};
|
||||
const subject2 = new Subject(values2);
|
||||
const result3 = subject2.thumbnailUrl("xyz");
|
||||
expect(result3).toBe("/api/v1/svg/portrait");
|
||||
});
|
||||
|
||||
it("should get date string", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
Excluded: true,
|
||||
Private: true,
|
||||
Thumb: "nicethumb",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
const result = subject.getDateString();
|
||||
expect(result.replaceAll("\u202f", " ")).toBe("Jul 8, 2012, 2:45 PM");
|
||||
});
|
||||
|
||||
it("should like subject", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: false,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
expect(subject.Favorite).toBe(false);
|
||||
subject.like();
|
||||
expect(subject.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should unlike subject", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
expect(subject.Favorite).toBe(true);
|
||||
subject.unlike();
|
||||
expect(subject.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should toggle like", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Favorite: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
expect(subject.Favorite).toBe(true);
|
||||
subject.toggleLike();
|
||||
expect(subject.Favorite).toBe(false);
|
||||
subject.toggleLike();
|
||||
expect(subject.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("show and hide subject", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Hidden: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
expect(subject.Hidden).toBe(true);
|
||||
subject.show();
|
||||
expect(subject.Hidden).toBe(false);
|
||||
subject.hide();
|
||||
expect(subject.Hidden).toBe(true);
|
||||
});
|
||||
|
||||
it("should toggle hidden", () => {
|
||||
const values = {
|
||||
UID: "s123ghytrfggd",
|
||||
Type: "person",
|
||||
Src: "manual",
|
||||
Name: "Jane Doe",
|
||||
Slug: "jane-doe",
|
||||
Hidden: true,
|
||||
};
|
||||
const subject = new Subject(values);
|
||||
expect(subject.Hidden).toBe(true);
|
||||
subject.toggleHidden();
|
||||
expect(subject.Hidden).toBe(false);
|
||||
subject.toggleHidden();
|
||||
expect(subject.Hidden).toBe(true);
|
||||
});
|
||||
|
||||
it("should return batch size", () => {
|
||||
expect(Subject.batchSize()).toBe(BatchSize);
|
||||
Subject.setBatchSize(30);
|
||||
expect(Subject.batchSize()).toBe(30);
|
||||
Subject.setBatchSize(BatchSize);
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = Subject.getCollectionResource();
|
||||
expect(result).toBe("subjects");
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = Subject.getModelName();
|
||||
expect(result).toBe("Person");
|
||||
});
|
||||
});
|
||||
324
frontend/tests/vitest/model/thumb.test.js
Normal file
324
frontend/tests/vitest/model/thumb.test.js
Normal file
@@ -0,0 +1,324 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import "../fixtures";
|
||||
import Thumb from "model/thumb";
|
||||
import Photo from "model/photo";
|
||||
import File from "model/file";
|
||||
|
||||
describe("model/thumb", () => {
|
||||
it("should get thumb defaults", () => {
|
||||
const values = {
|
||||
UID: "55",
|
||||
Title: "",
|
||||
TakenAtLocal: "",
|
||||
Caption: "",
|
||||
Favorite: false,
|
||||
Playable: false,
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
DownloadUrl: "",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
const result = thumb.getDefaults();
|
||||
expect(result.UID).toBe("");
|
||||
});
|
||||
|
||||
it("should get id", () => {
|
||||
const values = {
|
||||
UID: "55",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
expect(thumb.getId()).toBe("55");
|
||||
});
|
||||
|
||||
it("should return hasId", () => {
|
||||
const values = {
|
||||
UID: "55",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
expect(thumb.hasId()).toBe(true);
|
||||
|
||||
const values2 = {
|
||||
Title: "",
|
||||
};
|
||||
const thumb2 = new Thumb(values2);
|
||||
expect(thumb2.hasId()).toBe(false);
|
||||
});
|
||||
|
||||
it("should toggle like", () => {
|
||||
const values = {
|
||||
UID: "55",
|
||||
Title: "",
|
||||
TakenAtLocal: "",
|
||||
Caption: "",
|
||||
Favorite: true,
|
||||
Playable: false,
|
||||
Width: 0,
|
||||
Height: 0,
|
||||
DownloadUrl: "",
|
||||
};
|
||||
const thumb = new Thumb(values);
|
||||
expect(thumb.Favorite).toBe(true);
|
||||
thumb.toggleLike();
|
||||
expect(thumb.Favorite).toBe(false);
|
||||
thumb.toggleLike();
|
||||
expect(thumb.Favorite).toBe(true);
|
||||
});
|
||||
|
||||
it("should return thumb not found", () => {
|
||||
const result = Thumb.notFound();
|
||||
expect(result.UID).toBe("");
|
||||
expect(result.Favorite).toBe(false);
|
||||
});
|
||||
|
||||
it("should test from file", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
Hash: "abc123",
|
||||
Width: 500,
|
||||
Height: 900,
|
||||
};
|
||||
const file = new File(values);
|
||||
|
||||
const values2 = {
|
||||
UID: "5",
|
||||
Title: "Crazy Cat",
|
||||
TakenAt: "2012-07-08T14:45:39Z",
|
||||
TakenAtLocal: "2012-07-08T14:45:39Z",
|
||||
Caption: "Nice description",
|
||||
Favorite: true,
|
||||
};
|
||||
const photo = new Photo(values2);
|
||||
const result = Thumb.fromFile(photo, file);
|
||||
expect(result.UID).toBe("5");
|
||||
expect(result.Caption).toBe("Nice description");
|
||||
expect(result.Width).toBe(500);
|
||||
const result2 = Thumb.fromFile();
|
||||
expect(result2.UID).toBe("");
|
||||
});
|
||||
|
||||
it("should test from files", () => {
|
||||
const values2 = {
|
||||
UID: "5",
|
||||
Title: "Crazy Cat",
|
||||
TakenAt: "2012-07-08T14:45:39Z",
|
||||
TakenAtLocal: "2012-07-08T14:45:39Z",
|
||||
Caption: "Nice description",
|
||||
Favorite: true,
|
||||
};
|
||||
const photo = new Photo(values2);
|
||||
|
||||
const values3 = {
|
||||
UID: "5",
|
||||
Title: "Crazy Cat",
|
||||
TakenAt: "2012-07-08T14:45:39Z",
|
||||
TakenAtLocal: "2012-07-08T14:45:39Z",
|
||||
Caption: "Nice description",
|
||||
Favorite: true,
|
||||
};
|
||||
const photo2 = new Photo(values3);
|
||||
const Photos = [photo, photo2];
|
||||
const result = Thumb.fromFiles(Photos);
|
||||
expect(result.length).toBe(0);
|
||||
const values4 = {
|
||||
ID: 8,
|
||||
UID: "ABC123",
|
||||
Caption: "Nice description 2",
|
||||
Hash: "abc345",
|
||||
Files: [
|
||||
{
|
||||
UID: "123fgb",
|
||||
Name: "1980/01/superCuteKitten.jpg",
|
||||
Primary: true,
|
||||
FileType: "jpg",
|
||||
Width: 500,
|
||||
Height: 600,
|
||||
Hash: "1xxbgdt53",
|
||||
},
|
||||
],
|
||||
};
|
||||
const photo3 = new Photo(values4);
|
||||
const Photos2 = [photo, photo2, photo3];
|
||||
const result2 = Thumb.fromFiles(Photos2);
|
||||
expect(result2[0].UID).toBe("ABC123");
|
||||
expect(result2[0].Caption).toBe("Nice description 2");
|
||||
expect(result2[0].Width).toBe(500);
|
||||
expect(result2.length).toBe(1);
|
||||
const values5 = {
|
||||
ID: 8,
|
||||
UID: "ABC123",
|
||||
Caption: "Nice description 2",
|
||||
Hash: "abc345",
|
||||
Files: [
|
||||
{
|
||||
UID: "123fgb",
|
||||
Name: "1980/01/superCuteKitten.jpg",
|
||||
Primary: true,
|
||||
FileType: "mov",
|
||||
Width: 500,
|
||||
Height: 600,
|
||||
Hash: "1xxbgdt53",
|
||||
},
|
||||
],
|
||||
};
|
||||
const photo4 = new Photo(values5);
|
||||
const Photos3 = [photo3, photo2, photo4];
|
||||
const result3 = Thumb.fromFiles(Photos3);
|
||||
expect(result3.length).toBe(1);
|
||||
expect(result3[0].UID).toBe("ABC123");
|
||||
expect(result3[0].Caption).toBe("Nice description 2");
|
||||
expect(result3[0].Width).toBe(500);
|
||||
});
|
||||
|
||||
it("should test from files", () => {
|
||||
const Photos = [];
|
||||
const result = Thumb.fromFiles(Photos);
|
||||
expect(result).toEqual([]);
|
||||
});
|
||||
|
||||
it("should test from photo", () => {
|
||||
const values = {
|
||||
ID: 8,
|
||||
UID: "ABC123",
|
||||
Caption: "Nice description 3",
|
||||
Hash: "345ggh",
|
||||
Files: [
|
||||
{
|
||||
UID: "123fgb",
|
||||
Name: "1980/01/superCuteKitten.jpg",
|
||||
Primary: true,
|
||||
FileType: "jpg",
|
||||
Width: 500,
|
||||
Height: 600,
|
||||
Hash: "1xxbgdt53",
|
||||
},
|
||||
],
|
||||
};
|
||||
const photo = new Photo(values);
|
||||
const result = Thumb.fromPhoto(photo);
|
||||
expect(result.UID).toBe("ABC123");
|
||||
expect(result.Caption).toBe("Nice description 3");
|
||||
expect(result.Width).toBe(500);
|
||||
const values3 = {
|
||||
ID: 8,
|
||||
UID: "ABC124",
|
||||
Caption: "Nice description 3",
|
||||
};
|
||||
const photo3 = new Photo(values3);
|
||||
const result2 = Thumb.fromPhoto(photo3);
|
||||
expect(result2.UID).toBe("");
|
||||
const values2 = {
|
||||
ID: 8,
|
||||
UID: "ABC123",
|
||||
Title: "Crazy Cat",
|
||||
TakenAt: "2012-07-08T14:45:39Z",
|
||||
TakenAtLocal: "2012-07-08T14:45:39Z",
|
||||
Caption: "Nice description",
|
||||
Favorite: true,
|
||||
Hash: "xdf45m",
|
||||
};
|
||||
const photo2 = new Photo(values2);
|
||||
const result3 = Thumb.fromPhoto(photo2);
|
||||
expect(result3.UID).toBe("ABC123");
|
||||
expect(result3.Title).toBe("Crazy Cat");
|
||||
expect(result3.Caption).toBe("Nice description");
|
||||
});
|
||||
|
||||
it("should test from photos", () => {
|
||||
const values = {
|
||||
ID: 8,
|
||||
UID: "ABC123",
|
||||
Caption: "Nice description 3",
|
||||
Hash: "345ggh",
|
||||
Files: [
|
||||
{
|
||||
UID: "123fgb",
|
||||
Name: "1980/01/superCuteKitten.jpg",
|
||||
Primary: true,
|
||||
FileType: "jpg",
|
||||
Width: 500,
|
||||
Height: 600,
|
||||
Hash: "1xxbgdt53",
|
||||
},
|
||||
],
|
||||
};
|
||||
const photo = new Photo(values);
|
||||
const Photos = [photo];
|
||||
const result = Thumb.fromPhotos(Photos);
|
||||
expect(result[0].UID).toBe("ABC123");
|
||||
expect(result[0].Caption).toBe("Nice description 3");
|
||||
expect(result[0].Width).toBe(500);
|
||||
});
|
||||
|
||||
it("should return download url", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(Thumb.downloadUrl(file)).toBe("/api/v1/dl/54ghtfd?t=2lbh9x09");
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(Thumb.downloadUrl(file2)).toBe("");
|
||||
});
|
||||
|
||||
it("should return thumbnail url", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
expect(Thumb.thumbnailUrl(file, "abc")).toBe("/api/v1/t/54ghtfd/public/abc");
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file2 = new File(values2);
|
||||
expect(Thumb.thumbnailUrl(file2, "bcd")).toBe("/static/img/404.jpg");
|
||||
});
|
||||
|
||||
it("should calculate size", () => {
|
||||
const values = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Width: 900,
|
||||
Height: 850,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file = new File(values);
|
||||
const result = Thumb.calculateSize(file, 600, 800);
|
||||
expect(result.width).toBe(600);
|
||||
expect(result.height).toBe(567);
|
||||
const values3 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
Width: 750,
|
||||
Height: 850,
|
||||
Name: "1/2/IMG123.jpg",
|
||||
};
|
||||
const file3 = new File(values3);
|
||||
const result2 = Thumb.calculateSize(file3, 900, 450);
|
||||
expect(result2.width).toBe(398);
|
||||
expect(result2.height).toBe(450);
|
||||
const result4 = Thumb.calculateSize(file3, 900, 950);
|
||||
expect(result4.width).toBe(750);
|
||||
expect(result4.height).toBe(850);
|
||||
});
|
||||
});
|
||||
315
frontend/tests/vitest/model/user.test.js
Normal file
315
frontend/tests/vitest/model/user.test.js
Normal file
@@ -0,0 +1,315 @@
|
||||
import { describe, it, expect } from 'vitest';
|
||||
import "../fixtures";
|
||||
import User from "model/user";
|
||||
import File from "model/file";
|
||||
import Config from "common/config";
|
||||
import StorageShim from "node-storage-shim";
|
||||
|
||||
const defaultConfig = new Config(new StorageShim(), window.__CONFIG__);
|
||||
|
||||
describe("model/user", () => {
|
||||
it("should get handle", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = user.getHandle();
|
||||
expect(result).toBe("max");
|
||||
|
||||
const values2 = {
|
||||
ID: 6,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user2 = new User(values2);
|
||||
const result2 = user2.getHandle();
|
||||
expect(result2).toBe("");
|
||||
});
|
||||
|
||||
it("should get default base path", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = user.defaultBasePath();
|
||||
expect(result).toBe("users/max");
|
||||
|
||||
const values2 = {
|
||||
ID: 6,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user2 = new User(values2);
|
||||
const result2 = user2.defaultBasePath();
|
||||
expect(result2).toBe("");
|
||||
});
|
||||
|
||||
it("should get display name", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = user.getDisplayName();
|
||||
expect(result).toBe("Max Last");
|
||||
|
||||
const values2 = {
|
||||
ID: 6,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user2 = new User(values2);
|
||||
const result2 = user2.getDisplayName();
|
||||
expect(result2).toBe("Unknown");
|
||||
|
||||
const values3 = {
|
||||
ID: 7,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
Details: {
|
||||
NickName: "maxi",
|
||||
GivenName: "Maximilian",
|
||||
},
|
||||
};
|
||||
|
||||
const user3 = new User(values3);
|
||||
const result3 = user3.getDisplayName();
|
||||
expect(result3).toBe("maxi");
|
||||
|
||||
const values4 = {
|
||||
ID: 8,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
Details: {
|
||||
NickName: "",
|
||||
GivenName: "Maximilian",
|
||||
},
|
||||
};
|
||||
|
||||
const user4 = new User(values4);
|
||||
const result4 = user4.getDisplayName();
|
||||
expect(result4).toBe("Maximilian");
|
||||
});
|
||||
|
||||
it("should get account info", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = user.getAccountInfo();
|
||||
expect(result).toBe("max");
|
||||
|
||||
const values2 = {
|
||||
ID: 6,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user2 = new User(values2);
|
||||
const result2 = user2.getAccountInfo();
|
||||
expect(result2).toBe("test@test.com");
|
||||
|
||||
const values3 = {
|
||||
ID: 7,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user3 = new User(values3);
|
||||
const result3 = user3.getAccountInfo();
|
||||
expect(result3).toBe("Admin");
|
||||
|
||||
const values4 = {
|
||||
ID: 8,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "",
|
||||
Role: "",
|
||||
};
|
||||
|
||||
const user4 = new User(values4);
|
||||
const result4 = user4.getAccountInfo();
|
||||
expect(result4).toBe("Account");
|
||||
|
||||
const values5 = {
|
||||
ID: 9,
|
||||
Name: "",
|
||||
DisplayName: "",
|
||||
Email: "",
|
||||
Role: "admin",
|
||||
Details: {
|
||||
JobTitle: "Developer",
|
||||
},
|
||||
};
|
||||
|
||||
const user5 = new User(values5);
|
||||
const result5 = user5.getAccountInfo();
|
||||
expect(result5).toBe("Developer");
|
||||
});
|
||||
|
||||
it("should get entity name", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = user.getEntityName();
|
||||
expect(result).toBe("Max Last");
|
||||
});
|
||||
|
||||
it("should get id", () => {
|
||||
const values = {
|
||||
ID: 5,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = user.getId();
|
||||
expect(result).toBe(5);
|
||||
});
|
||||
|
||||
it("should get model name", () => {
|
||||
const result = User.getModelName();
|
||||
expect(result).toBe("User");
|
||||
});
|
||||
|
||||
it("should get collection resource", () => {
|
||||
const result = User.getCollectionResource();
|
||||
expect(result).toBe("users");
|
||||
});
|
||||
|
||||
it("should get register form", async () => {
|
||||
const values = { ID: 52, Name: "max", DisplayName: "Max Last" };
|
||||
const user = new User(values);
|
||||
const result = await user.getRegisterForm();
|
||||
expect(result.definition.foo).toBe("register");
|
||||
});
|
||||
|
||||
it("should get avatar url", async () => {
|
||||
const values = { ID: 52, Name: "max", DisplayName: "Max Last" };
|
||||
const user = new User(values);
|
||||
const result = await user.getAvatarURL();
|
||||
expect(result).toBe("/static/img/avatar/tile_500.jpg");
|
||||
|
||||
const values2 = {
|
||||
ID: 53,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Thumb: "91e6c374afb78b28a52d7b4fd4fd2ea861b87123",
|
||||
};
|
||||
const user2 = new User(values2);
|
||||
const result2 = await user2.getAvatarURL("tile_500", defaultConfig);
|
||||
expect(result2).toBe("/api/v1/t/91e6c374afb78b28a52d7b4fd4fd2ea861b87123/public/tile_500");
|
||||
});
|
||||
|
||||
it("should upload avatar", async () => {
|
||||
const values = { ID: 52, Name: "max", DisplayName: "Max Last" };
|
||||
const user = new User(values);
|
||||
|
||||
const values2 = {
|
||||
InstanceID: 5,
|
||||
UID: "ABC123",
|
||||
Hash: "54ghtfd",
|
||||
FileType: "jpg",
|
||||
MediaType: "image",
|
||||
Name: "1/2/IMG123.jpg",
|
||||
CreatedAt: "2012-07-08T14:45:39Z",
|
||||
UpdatedAt: "2012-07-08T14:45:39Z",
|
||||
};
|
||||
const file = new File(values2);
|
||||
|
||||
const Files = [file];
|
||||
|
||||
const response = await user.uploadAvatar(Files);
|
||||
expect(response.Thumb).toBe("abc");
|
||||
expect(response.ThumbSrc).toBe("manual");
|
||||
});
|
||||
|
||||
it("should get profile form", async () => {
|
||||
const values = { ID: 53, Name: "max", DisplayName: "Max Last" };
|
||||
const user = new User(values);
|
||||
const result = await user.getProfileForm();
|
||||
expect(result.definition.foo).toBe("profile");
|
||||
});
|
||||
|
||||
it("should return whether user is remote", async () => {
|
||||
const values = { ID: 52, Name: "max", DisplayName: "Max Last", AuthProvider: "local" };
|
||||
const user = new User(values);
|
||||
const result = await user.isRemote();
|
||||
expect(result).toBe(false);
|
||||
|
||||
const values2 = { ID: 51, Name: "max", DisplayName: "Max Last", AuthProvider: "ldap" };
|
||||
const user2 = new User(values2);
|
||||
const result2 = await user2.isRemote();
|
||||
expect(result2).toBe(true);
|
||||
});
|
||||
|
||||
it("should return auth info", async () => {
|
||||
const values = { ID: 50, Name: "max", DisplayName: "Max Last", AuthProvider: "oidc" };
|
||||
const user = new User(values);
|
||||
const result = await user.authInfo();
|
||||
expect(result).toBe("OIDC");
|
||||
|
||||
const values2 = { ID: 52, Name: "max", DisplayName: "Max Last", AuthProvider: "oidc", AuthMethod: "session" };
|
||||
const user2 = new User(values2);
|
||||
const result2 = await user2.authInfo();
|
||||
expect(result2).toBe("OIDC (Session)");
|
||||
});
|
||||
|
||||
it("should get change password", async () => {
|
||||
const values = {
|
||||
ID: 54,
|
||||
Name: "max",
|
||||
DisplayName: "Max Last",
|
||||
Email: "test@test.com",
|
||||
Role: "admin",
|
||||
};
|
||||
|
||||
const user = new User(values);
|
||||
const result = await user.changePassword("old", "new");
|
||||
expect(result.new_password).toBe("new");
|
||||
});
|
||||
});
|
||||
249
frontend/tests/vitest/options/options.test.js
Normal file
249
frontend/tests/vitest/options/options.test.js
Normal file
@@ -0,0 +1,249 @@
|
||||
import { describe, it, expect } from "vitest";
|
||||
import "../fixtures";
|
||||
import * as options from "../../../src/options/options";
|
||||
import {
|
||||
AccountTypes,
|
||||
Colors,
|
||||
DefaultLocale,
|
||||
Expires,
|
||||
FallbackLocale,
|
||||
FeedbackCategories,
|
||||
FindLanguage,
|
||||
FindLocale,
|
||||
Gender,
|
||||
Intervals,
|
||||
ItemsPerPage,
|
||||
MapsAnimate,
|
||||
MapsStyle,
|
||||
Orientations,
|
||||
PhotoTypes,
|
||||
RetryLimits,
|
||||
SetDefaultLocale,
|
||||
StartPages,
|
||||
ThumbFilters,
|
||||
ThumbSizes,
|
||||
Timeouts,
|
||||
} from "../../../src/options/options";
|
||||
|
||||
describe("options/options", () => {
|
||||
it("should get timezones", () => {
|
||||
const timezones = options.TimeZones();
|
||||
expect(timezones[0].ID).toBe("Local");
|
||||
expect(timezones[0].Name).toBe("Local");
|
||||
expect(timezones[1].ID).toBe("UTC");
|
||||
expect(timezones[1].Name).toBe("UTC");
|
||||
});
|
||||
|
||||
it("should get days", () => {
|
||||
const Days = options.Days();
|
||||
expect(Days[0].text).toBe("01");
|
||||
expect(Days[30].text).toBe("31");
|
||||
});
|
||||
|
||||
it("should get years", () => {
|
||||
const Years = options.Years();
|
||||
const currentYear = new Date().getUTCFullYear();
|
||||
expect(Years[0].text).toBe(currentYear.toString());
|
||||
});
|
||||
|
||||
it("should get indexed years", () => {
|
||||
const IndexedYears = options.IndexedYears();
|
||||
expect(IndexedYears[0].text).toBe("2021");
|
||||
});
|
||||
|
||||
it("should get months", () => {
|
||||
const Months = options.Months();
|
||||
expect(Months[5].text).toBe("June");
|
||||
});
|
||||
|
||||
it("should get short months", () => {
|
||||
const MonthsShort = options.MonthsShort();
|
||||
expect(MonthsShort[5].text).toBe("06");
|
||||
});
|
||||
|
||||
it("should get languages", () => {
|
||||
const Languages = options.Languages();
|
||||
expect(Languages[0].value).toBe("en");
|
||||
});
|
||||
|
||||
it("should set default locale", () => {
|
||||
expect(DefaultLocale).toBe("en");
|
||||
SetDefaultLocale("de");
|
||||
expect(DefaultLocale).toBe("de");
|
||||
SetDefaultLocale("en");
|
||||
});
|
||||
|
||||
it("should return default when no locale is provided", () => {
|
||||
expect(FindLanguage("").value).toBe("en");
|
||||
});
|
||||
|
||||
it("should return default locale is smaller than 2", () => {
|
||||
expect(FindLanguage("d").value).toBe("en");
|
||||
});
|
||||
|
||||
it("should return default locale", () => {
|
||||
expect(FindLanguage("xx").value).toBe("en");
|
||||
});
|
||||
|
||||
it("should return correct locale", () => {
|
||||
expect(FindLanguage("de").value).toBe("de");
|
||||
expect(FindLanguage("de").text).toBe("Deutsch");
|
||||
expect(FindLanguage("de_AT").value).toBe("de");
|
||||
expect(FindLanguage("de_AT").text).toBe("Deutsch");
|
||||
expect(FindLanguage("zh-tw").value).toBe("zh_TW");
|
||||
expect(FindLanguage("zh-tw").text).toBe("繁體中文");
|
||||
expect(FindLanguage("zh+tw").value).toBe("zh_TW");
|
||||
expect(FindLanguage("zh+tw").text).toBe("繁體中文");
|
||||
expect(FindLanguage("zh_AT").value).toBe("zh");
|
||||
expect(FindLanguage("zh_AT").text).toBe("简体中文");
|
||||
expect(FindLanguage("ZH_TW").value).toBe("zh_TW");
|
||||
expect(FindLanguage("ZH_TW").text).toBe("繁體中文");
|
||||
expect(FindLanguage("zH-tW").value).toBe("zh_TW");
|
||||
expect(FindLanguage("zH-tW").text).toBe("繁體中文");
|
||||
});
|
||||
|
||||
it("should return default locale", () => {
|
||||
expect(FindLocale("xx")).toBe("en");
|
||||
expect(FindLocale("")).toBe("en");
|
||||
});
|
||||
|
||||
it("should return fallback locale", () => {
|
||||
expect(FallbackLocale()).toBe("en");
|
||||
});
|
||||
|
||||
it("should return items per page", () => {
|
||||
expect(ItemsPerPage()[0].value).toBe(10);
|
||||
});
|
||||
|
||||
it("should return start page options", () => {
|
||||
let features = {
|
||||
account: true,
|
||||
albums: true,
|
||||
archive: true,
|
||||
delete: true,
|
||||
download: true,
|
||||
edit: true,
|
||||
estimates: true,
|
||||
favorites: true,
|
||||
files: true,
|
||||
folders: true,
|
||||
import: true,
|
||||
labels: true,
|
||||
library: true,
|
||||
logs: true,
|
||||
calendar: true,
|
||||
moments: true,
|
||||
people: true,
|
||||
places: true,
|
||||
private: true,
|
||||
ratings: true,
|
||||
reactions: true,
|
||||
review: true,
|
||||
search: true,
|
||||
services: true,
|
||||
settings: true,
|
||||
share: true,
|
||||
upload: true,
|
||||
videos: true,
|
||||
};
|
||||
expect(StartPages(features).length).toBe(12);
|
||||
expect(StartPages(features)[5].value).toBe("people");
|
||||
expect(StartPages(features)[5].props.disabled).toBe(false);
|
||||
features = {
|
||||
account: true,
|
||||
albums: true,
|
||||
archive: true,
|
||||
delete: true,
|
||||
download: true,
|
||||
edit: true,
|
||||
estimates: true,
|
||||
favorites: true,
|
||||
files: true,
|
||||
folders: true,
|
||||
import: true,
|
||||
labels: true,
|
||||
library: true,
|
||||
logs: true,
|
||||
calendar: false,
|
||||
moments: true,
|
||||
people: false,
|
||||
places: true,
|
||||
private: true,
|
||||
ratings: true,
|
||||
reactions: true,
|
||||
review: true,
|
||||
search: true,
|
||||
services: true,
|
||||
settings: true,
|
||||
share: true,
|
||||
upload: true,
|
||||
videos: true,
|
||||
};
|
||||
expect(StartPages(features).length).toBe(12);
|
||||
expect(StartPages(features)[5].value).toBe("people");
|
||||
expect(StartPages(features)[5].props.disabled).toBe(true);
|
||||
});
|
||||
|
||||
it("should return animation options", () => {
|
||||
expect(MapsAnimate()[1].value).toBe(2500);
|
||||
});
|
||||
|
||||
it("should return photo types", () => {
|
||||
expect(PhotoTypes()[0].value).toBe("image");
|
||||
expect(PhotoTypes()[1].value).toBe("raw");
|
||||
});
|
||||
|
||||
it("should return map styles", () => {
|
||||
let styles = MapsStyle(true);
|
||||
expect(styles[styles.length - 1].value).toContain("low-resolution");
|
||||
styles = MapsStyle(false);
|
||||
expect(styles[styles.length - 1].value).not.toContain("low-resolution");
|
||||
});
|
||||
|
||||
it("should return timeouts", () => {
|
||||
expect(Timeouts()[1].value).toBe("high");
|
||||
});
|
||||
|
||||
it("should return retry limits", () => {
|
||||
expect(RetryLimits()[1].value).toBe(1);
|
||||
});
|
||||
|
||||
it("should return intervals", () => {
|
||||
expect(Intervals()[0].text).toBe("Never");
|
||||
expect(Intervals()[1].text).toBe("1 hour");
|
||||
});
|
||||
|
||||
it("should return expiry options", () => {
|
||||
expect(Expires()[0].text).toBe("Never");
|
||||
expect(Expires()[1].text).toBe("After 1 day");
|
||||
});
|
||||
|
||||
it("should return colors", () => {
|
||||
expect(Colors()[0].Slug).toBe("purple");
|
||||
});
|
||||
|
||||
it("should return feedback categories", () => {
|
||||
expect(FeedbackCategories()[0].value).toBe("feedback");
|
||||
});
|
||||
|
||||
it("should return thumb sizes", () => {
|
||||
expect(ThumbSizes()[1].value).toBe("fit_720");
|
||||
});
|
||||
|
||||
it("should return thumb filters", () => {
|
||||
expect(ThumbFilters()[0].value).toBe("blackman");
|
||||
});
|
||||
|
||||
it("should return gender", () => {
|
||||
expect(Gender()[2].value).toBe("other");
|
||||
});
|
||||
|
||||
it("should return orientations", () => {
|
||||
expect(Orientations()[1].text).toBe("90°");
|
||||
});
|
||||
|
||||
it("should return service account type options", () => {
|
||||
expect(AccountTypes()[0].value).toBe("webdav");
|
||||
expect(AccountTypes().length).toBe(1);
|
||||
});
|
||||
});
|
||||
@@ -1,59 +1,22 @@
|
||||
import { afterEach, vi } from "vitest";
|
||||
import "@testing-library/jest-dom";
|
||||
import { cleanup } from "@testing-library/react";
|
||||
import { afterEach, vi, beforeAll } from "vitest";
|
||||
import { setupCommonMocks } from "./fixtures";
|
||||
import "./vue-setup";
|
||||
|
||||
global.window = global.window || {};
|
||||
global.window.__CONFIG__ = {
|
||||
debug: false,
|
||||
trace: false,
|
||||
};
|
||||
// Import and set up global config
|
||||
import clientConfig from "./config";
|
||||
import { $config } from "app/session";
|
||||
|
||||
global.window.location = {
|
||||
protocol: "https:",
|
||||
};
|
||||
$config.setValues(clientConfig);
|
||||
|
||||
global.navigator = {
|
||||
userAgent: "node.js",
|
||||
maxTouchPoints: 0,
|
||||
};
|
||||
// Make config available in browser environment
|
||||
window.__CONFIG__ = clientConfig;
|
||||
|
||||
console.log("Running tests in real browser environment");
|
||||
|
||||
// Clean up after each test
|
||||
afterEach(() => {
|
||||
cleanup();
|
||||
vi.resetAllMocks();
|
||||
});
|
||||
|
||||
beforeAll(() => {
|
||||
setupCommonMocks();
|
||||
});
|
||||
|
||||
vi.mock("luxon", () => ({
|
||||
DateTime: {
|
||||
fromISO: vi.fn().mockReturnValue({
|
||||
toLocaleString: vi.fn().mockReturnValue("2023-10-01 10:00:00"),
|
||||
}),
|
||||
DATETIME_MED: {},
|
||||
DATETIME_MED_WITH_WEEKDAY: {},
|
||||
DATE_MED: {},
|
||||
TIME_24_SIMPLE: {},
|
||||
},
|
||||
Settings: {
|
||||
defaultLocale: "en",
|
||||
defaultZoneName: "UTC",
|
||||
},
|
||||
}));
|
||||
|
||||
vi.mock("common/gettext", () => ({
|
||||
$gettext: vi.fn((text) => text),
|
||||
}));
|
||||
|
||||
vi.mock("app/session", () => ({
|
||||
$config: {},
|
||||
}));
|
||||
|
||||
vi.mock("common/notify", () => ({
|
||||
default: {
|
||||
success: vi.fn(),
|
||||
warn: vi.fn(),
|
||||
error: vi.fn(),
|
||||
},
|
||||
}));
|
||||
// Export shared configuration
|
||||
export { clientConfig };
|
||||
|
||||
@@ -1,39 +1,22 @@
|
||||
import { config } from "@vue/test-utils";
|
||||
import { vi } from "vitest";
|
||||
import { createVuetify } from "vuetify";
|
||||
import * as components from "vuetify/components";
|
||||
import * as directives from "vuetify/directives";
|
||||
import "vuetify/styles";
|
||||
import { Settings } from "luxon";
|
||||
|
||||
// Mock Vuetify components
|
||||
const vuetifyComponents = [
|
||||
"VBtn",
|
||||
"VToolbar",
|
||||
"VToolbarTitle",
|
||||
"VList",
|
||||
"VListItem",
|
||||
"VDivider",
|
||||
"VProgressCircular",
|
||||
"VIcon",
|
||||
"VRow",
|
||||
"VCol",
|
||||
"VCard",
|
||||
"VCardTitle",
|
||||
"VCardText",
|
||||
"VCardActions",
|
||||
"VTextField",
|
||||
"VTextarea",
|
||||
"VSheet",
|
||||
];
|
||||
// Setup timezone to match test expectations (UTC+2/CEST)
|
||||
Settings.defaultZoneName = "Europe/Berlin";
|
||||
|
||||
// Create stubs for Vuetify components
|
||||
const vuetifyStubs = vuetifyComponents.reduce((acc, component) => {
|
||||
acc[component] = {
|
||||
name: component.toLowerCase(),
|
||||
template: `<div data-testid="${component.toLowerCase()}" class="${component.toLowerCase()}-stub"><slot></slot></div>`,
|
||||
};
|
||||
acc[component.toLowerCase()] = {
|
||||
name: component.toLowerCase(),
|
||||
template: `<div data-testid="${component.toLowerCase()}" class="${component.toLowerCase()}-stub"><slot></slot></div>`,
|
||||
};
|
||||
return acc;
|
||||
}, {});
|
||||
// Create a proper Vuetify instance with all components and styles
|
||||
const vuetify = createVuetify({
|
||||
components,
|
||||
directives,
|
||||
theme: {
|
||||
defaultTheme: "light",
|
||||
},
|
||||
});
|
||||
|
||||
// Configure Vue Test Utils global configuration
|
||||
config.global.mocks = {
|
||||
@@ -44,8 +27,9 @@ config.global.mocks = {
|
||||
},
|
||||
};
|
||||
|
||||
config.global.plugins = [vuetify];
|
||||
|
||||
config.global.stubs = {
|
||||
...vuetifyStubs,
|
||||
transition: false,
|
||||
};
|
||||
|
||||
@@ -64,9 +48,16 @@ config.global.mount = function (component, options = {}) {
|
||||
options.global.config.globalProperties = options.global.config.globalProperties || {};
|
||||
options.global.config.globalProperties.$emit = vi.fn();
|
||||
|
||||
// Add vuetify to all mount calls
|
||||
if (!options.global.plugins) {
|
||||
options.global.plugins = [vuetify];
|
||||
} else if (Array.isArray(options.global.plugins)) {
|
||||
options.global.plugins.push(vuetify);
|
||||
}
|
||||
|
||||
return originalMount(component, options);
|
||||
};
|
||||
|
||||
export default {
|
||||
vuetifyStubs,
|
||||
vuetify,
|
||||
};
|
||||
|
||||
@@ -1,28 +1,58 @@
|
||||
import { defineConfig } from "vitest/config";
|
||||
import react from "@vitejs/plugin-react";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
import tsconfigPaths from "vite-tsconfig-paths";
|
||||
import path from "path";
|
||||
import vue from "@vitejs/plugin-vue";
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react(), vue(), tsconfigPaths()],
|
||||
plugins: [vue()],
|
||||
resolve: {
|
||||
alias: {
|
||||
"app": path.resolve(__dirname, "./src/app"),
|
||||
"common": path.resolve(__dirname, "./src/common"),
|
||||
"component": path.resolve(__dirname, "./src/component"),
|
||||
"model": path.resolve(__dirname, "./src/model"),
|
||||
"options": path.resolve(__dirname, "./src/options"),
|
||||
"page": path.resolve(__dirname, "./src/page"),
|
||||
"ui": path.resolve(__dirname, "./src/options/ui.js"),
|
||||
"model.js": path.resolve(__dirname, "./src/model/model.js"),
|
||||
"link.js": path.resolve(__dirname, "./src/model/link.js"),
|
||||
"websocket.js": path.resolve(__dirname, "./src/common/websocket.js"),
|
||||
},
|
||||
},
|
||||
|
||||
optimizeDeps: {
|
||||
include: ["vuetify"],
|
||||
},
|
||||
|
||||
test: {
|
||||
globals: true,
|
||||
setupFiles: "./tests/vitest/setup.js",
|
||||
include: ["tests/vitest/**/*.{test,spec}.{js,jsx,ts,tsx,vue}"],
|
||||
exclude: ["**/node_modules/**", "**/dist/**"],
|
||||
|
||||
environment: "jsdom",
|
||||
setupFiles: ["./tests/vitest/setup.js", "./tests/vitest/vue-setup.js"],
|
||||
include: ["tests/vitest/**/*.{test,spec}.{js,jsx}"],
|
||||
css: true,
|
||||
pool: "vmForks",
|
||||
testTimeout: 10000,
|
||||
watch: false,
|
||||
silent: true,
|
||||
browser: {
|
||||
enabled: false,
|
||||
provider: "playwright",
|
||||
headless: true,
|
||||
isolate: false,
|
||||
instances: [
|
||||
{
|
||||
browser: "chromium",
|
||||
headless: true,
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
coverage: {
|
||||
provider: "v8",
|
||||
reporter: ["text", "html"],
|
||||
include: ["src/**/*.{js,jsx,vue}"],
|
||||
exclude: ["src/locales/**"],
|
||||
},
|
||||
alias: {
|
||||
app: path.resolve(__dirname, "./src/app"),
|
||||
common: path.resolve(__dirname, "./src/common"),
|
||||
component: path.resolve(__dirname, "./src/component"),
|
||||
model: path.resolve(__dirname, "./src/model"),
|
||||
options: path.resolve(__dirname, "./src/options"),
|
||||
page: path.resolve(__dirname, "./src/page"),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user