From 68e6a56f38898cc7ad07a0e5812bf464e35cdc26 Mon Sep 17 00:00:00 2001 From: Florian Schade Date: Tue, 15 Jun 2021 19:08:36 +0200 Subject: [PATCH] add constants for most used image dimensions update test naming add avatarUrl unit tests add axios mock --- package.json | 3 +- packages/web-app-files/src/constants.ts | 4 ++ .../src/helpers/user/avatarUrl.ts | 4 +- .../web-app-files/src/views/Favorites.vue | 3 +- packages/web-app-files/src/views/Personal.vue | 3 +- .../web-app-files/src/views/PublicFiles.vue | 3 +- .../web-app-files/src/views/SharedViaLink.vue | 3 +- .../web-app-files/src/views/SharedWithMe.vue | 3 +- .../src/views/SharedWithOthers.vue | 3 +- .../web-app-files/tests/helpers/user.spec.ts | 36 ------------- .../tests/helpers/user/avatarUrl.spec.ts | 51 +++++++++++++++++++ packages/web-pkg/src/utils/debounce.spec.ts | 2 +- tests/unit/__mocks__/axios.js | 2 + tests/unit/config/jest.config.js | 2 +- tests/unit/{mocks/style.js => stubs/empty.js} | 0 yarn.lock | 12 +++++ 16 files changed, 87 insertions(+), 47 deletions(-) create mode 100644 packages/web-app-files/src/constants.ts delete mode 100644 packages/web-app-files/tests/helpers/user.spec.ts create mode 100644 packages/web-app-files/tests/helpers/user/avatarUrl.spec.ts create mode 100644 tests/unit/__mocks__/axios.js rename tests/unit/{mocks/style.js => stubs/empty.js} (100%) diff --git a/package.json b/package.json index 05074094b24..d817a37d086 100644 --- a/package.json +++ b/package.json @@ -39,9 +39,9 @@ "@rollup/plugin-commonjs": "^17.0.0", "@rollup/plugin-html": "^0.2.0", "@rollup/plugin-json": "^4.1.0", - "@types/jest-axe": "^3.5.1", "@rollup/plugin-typescript": "^8.2.1", "@types/jest": "^26.0.23", + "@types/jest-axe": "^3.5.1", "@typescript-eslint/eslint-plugin": "^4.26.0", "@typescript-eslint/parser": "^4.26.0", "@vue/test-utils": "^1.1.2", @@ -72,6 +72,7 @@ "jest": "^26.6.3", "jest-axe": "^4.1.0", "jest-fetch-mock": "^3.0.3", + "jest-mock-axios": "^4.4.0", "jest-serializer-vue": "^2.0.2", "jest-svg-transformer": "^1.0.0", "join-path": "^1.1.1", diff --git a/packages/web-app-files/src/constants.ts b/packages/web-app-files/src/constants.ts new file mode 100644 index 00000000000..20fb09b9d84 --- /dev/null +++ b/packages/web-app-files/src/constants.ts @@ -0,0 +1,4 @@ +export abstract class ImageDimension { + static readonly ThumbNail: [25, 25] + static readonly Avatar: 64 +} diff --git a/packages/web-app-files/src/helpers/user/avatarUrl.ts b/packages/web-app-files/src/helpers/user/avatarUrl.ts index 8f55493cf39..b5a6148690b 100644 --- a/packages/web-app-files/src/helpers/user/avatarUrl.ts +++ b/packages/web-app-files/src/helpers/user/avatarUrl.ts @@ -1,4 +1,5 @@ import { cacheService, clientService } from '../../services' +import { ImageDimension } from '../../constants' interface avatarUrlOptions { server: string @@ -8,7 +9,7 @@ interface avatarUrlOptions { } export const avatarUrl = async (options: avatarUrlOptions, cached = false): Promise => { - const size = options.size || 128 + const size = options.size || ImageDimension.Avatar if (cached) { return cacheFactory({ ...options, size }) @@ -23,7 +24,6 @@ export const avatarUrl = async (options: avatarUrlOptions, cached = false): Prom } const { owncloudSdk } = clientService - if (!owncloudSdk || typeof owncloudSdk.signUrl !== 'function') { return url } diff --git a/packages/web-app-files/src/views/Favorites.vue b/packages/web-app-files/src/views/Favorites.vue index 6e93ab495e8..2eb9fc673ae 100644 --- a/packages/web-app-files/src/views/Favorites.vue +++ b/packages/web-app-files/src/views/Favorites.vue @@ -63,6 +63,7 @@ import ListLoader from '../components/ListLoader.vue' import NoContentMessage from '../components/NoContentMessage.vue' import { debounce } from 'web-pkg/src/utils' import { VisibilityObserver } from 'web-pkg/src/observer' +import { ImageDimension } from '../constants' const visibilityObserver = new VisibilityObserver() @@ -151,7 +152,7 @@ export default { this.loadPreview({ resource, isPublic: false, - dimensions: [25, 25] + dimensions: ImageDimension.ThumbNail }) }) diff --git a/packages/web-app-files/src/views/Personal.vue b/packages/web-app-files/src/views/Personal.vue index 3c8ea183525..82551be317c 100644 --- a/packages/web-app-files/src/views/Personal.vue +++ b/packages/web-app-files/src/views/Personal.vue @@ -80,6 +80,7 @@ import NoContentMessage from '../components/NoContentMessage.vue' import NotFoundMessage from '../components/FilesLists/NotFoundMessage.vue' import { VisibilityObserver } from 'web-pkg/src/observer' import { debounce } from 'web-pkg/src/utils' +import { ImageDimension } from '../constants' const visibilityObserver = new VisibilityObserver() @@ -203,7 +204,7 @@ export default { this.loadPreview({ resource, isPublic: false, - dimensions: [25, 25] + dimensions: ImageDimension.ThumbNail }) }) diff --git a/packages/web-app-files/src/views/PublicFiles.vue b/packages/web-app-files/src/views/PublicFiles.vue index 46647912b2a..f5f546a11c9 100644 --- a/packages/web-app-files/src/views/PublicFiles.vue +++ b/packages/web-app-files/src/views/PublicFiles.vue @@ -69,6 +69,7 @@ import NoContentMessage from '../components/NoContentMessage.vue' import NotFoundMessage from '../components/FilesLists/NotFoundMessage.vue' import { VisibilityObserver } from 'web-pkg/src/observer' import { debounce } from 'web-pkg/src/utils' +import { ImageDimension } from '../constants' const visibilityObserver = new VisibilityObserver() export default { @@ -168,7 +169,7 @@ export default { this.loadPreview({ resource, isPublic: true, - dimensions: [25, 25] + dimensions: ImageDimension.ThumbNail }) }) diff --git a/packages/web-app-files/src/views/SharedViaLink.vue b/packages/web-app-files/src/views/SharedViaLink.vue index e479bcda0de..69d38a5c54b 100644 --- a/packages/web-app-files/src/views/SharedViaLink.vue +++ b/packages/web-app-files/src/views/SharedViaLink.vue @@ -60,6 +60,7 @@ import ListLoader from '../components/ListLoader.vue' import NoContentMessage from '../components/NoContentMessage.vue' import { VisibilityObserver } from 'web-pkg/src/observer' import { debounce } from 'web-pkg/src/utils' +import { ImageDimension } from '../constants' const visibilityObserver = new VisibilityObserver() @@ -148,7 +149,7 @@ export default { this.loadPreview({ resource, isPublic: false, - dimensions: [25, 25] + dimensions: ImageDimension.ThumbNail }) }) diff --git a/packages/web-app-files/src/views/SharedWithMe.vue b/packages/web-app-files/src/views/SharedWithMe.vue index 6e80b7b57ec..484392ac33c 100644 --- a/packages/web-app-files/src/views/SharedWithMe.vue +++ b/packages/web-app-files/src/views/SharedWithMe.vue @@ -88,6 +88,7 @@ import ListLoader from '../components/ListLoader.vue' import NoContentMessage from '../components/NoContentMessage.vue' import { VisibilityObserver } from 'web-pkg/src/observer' import { debounce } from 'web-pkg/src/utils' +import { ImageDimension } from '../constants' const visibilityObserver = new VisibilityObserver() @@ -185,7 +186,7 @@ export default { this.loadPreview({ resource, isPublic: false, - dimensions: [25, 25] + dimensions: ImageDimension.ThumbNail }) }) diff --git a/packages/web-app-files/src/views/SharedWithOthers.vue b/packages/web-app-files/src/views/SharedWithOthers.vue index 441658ec038..c54f7508867 100644 --- a/packages/web-app-files/src/views/SharedWithOthers.vue +++ b/packages/web-app-files/src/views/SharedWithOthers.vue @@ -62,6 +62,7 @@ import ListLoader from '../components/ListLoader.vue' import NoContentMessage from '../components/NoContentMessage.vue' import { VisibilityObserver } from 'web-pkg/src/observer' import { debounce } from 'web-pkg/src/utils' +import { ImageDimension } from '../constants' const visibilityObserver = new VisibilityObserver() @@ -157,7 +158,7 @@ export default { this.loadPreview({ resource, isPublic: false, - dimensions: [25, 25] + dimensions: ImageDimension.ThumbNail }) }) diff --git a/packages/web-app-files/tests/helpers/user.spec.ts b/packages/web-app-files/tests/helpers/user.spec.ts deleted file mode 100644 index ab05cca3014..00000000000 --- a/packages/web-app-files/tests/helpers/user.spec.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { avatarUrl } from '../../src/helpers/user' - -describe('avatarUrl', () => { - it('throws an error', async () => { - //fetch.mockResponse(new Error(), { status: 404 }) - //await expect(getAvatarSrc('userId', 'server', 'token')).rejects.toBeTruthy() - - expect('TBD').toBeTruthy() - }) - - it('returns a signed url', async () => { - //fetch.mockResponse('', { status: 200 }) - //const client = { signUrl: jest.fn() } - //await getAvatarSrc('userId', 'server', 'token', client) - //expect(client.signUrl.mock.calls.length).toBe(1) - - expect('TBD').toBeTruthy() - }) - - it('returns the url if no valid client is present', async () => { - //fetch.mockResponse('', { status: 200 }) - //const url = await getAvatarSrc('userId', 'server', 'token') - //expect(url).toBe('serverremote.php/dav/avatars/userId/128.png') - - expect('TBD').toBeTruthy() - }) - - it('fetches avatarSrc from cache if url exists there', async () => { - //fetch.mockResponse('', { status: 200 }) - //const client = { signUrl: jest.fn() } - //await getAvatarSrc('userId', 'server', 'token', client) - //expect(client.signUrl.mock.calls.length).toBe(0) - - expect('TBD').toBeTruthy() - }) -}) diff --git a/packages/web-app-files/tests/helpers/user/avatarUrl.spec.ts b/packages/web-app-files/tests/helpers/user/avatarUrl.spec.ts new file mode 100644 index 00000000000..1e4cf833db7 --- /dev/null +++ b/packages/web-app-files/tests/helpers/user/avatarUrl.spec.ts @@ -0,0 +1,51 @@ +import { avatarUrl } from '../../../src/helpers/user' +import mockAxios from 'jest-mock-axios' + +beforeEach(() => { + mockAxios.reset() +}) + +const mockClient = (signUrl: any) => { + const vue = jest.fn() + vue.prototype.$client = jest.fn() + vue.prototype.$client.signUrl = signUrl + ;(global as any).Vue = vue +} + +const defaultOptions = { + server: 'https://www.ocis.rules/', + username: 'ocis', + token: 'rules', + size: 64 +} + +const buildUrl = ({ server, username, size }: { server: string; username: string; size: number }) => + [server, 'remote.php/dav/avatars/', username, `/${size}.png`].join('') + +describe('avatarUrl', () => { + it('throws an error', async () => { + const avatarUrlPromise = avatarUrl(defaultOptions) + mockAxios.mockResponse({ status: 404, statusText: 'no', data: undefined }) + await expect(avatarUrlPromise).rejects.toBeTruthy() + expect(mockAxios.head).toHaveBeenCalledWith(buildUrl(defaultOptions), undefined) + }) + + it('returns a unsigned url', async () => { + mockClient(undefined) + const avatarUrlPromise = avatarUrl(defaultOptions) + mockAxios.mockResponse({ status: 200, data: undefined }) + await expect(avatarUrlPromise).resolves.toBe(buildUrl(defaultOptions)) + expect(mockAxios.head).toHaveBeenCalledWith(buildUrl(defaultOptions), undefined) + }) + + it('returns a signed url', async () => { + const signUrlMock = jest.fn().mockImplementation(url => { + return `${url}?signed=true` + }) + mockClient(signUrlMock) + const avatarUrlPromise = avatarUrl(defaultOptions) + mockAxios.mockResponse({ status: 200, data: undefined }) + await expect(avatarUrlPromise).resolves.toBe(`${buildUrl(defaultOptions)}?signed=true`) + expect(mockAxios.head).toHaveBeenCalledWith(buildUrl(defaultOptions), undefined) + }) +}) diff --git a/packages/web-pkg/src/utils/debounce.spec.ts b/packages/web-pkg/src/utils/debounce.spec.ts index f0e0d189029..66aff4f260d 100644 --- a/packages/web-pkg/src/utils/debounce.spec.ts +++ b/packages/web-pkg/src/utils/debounce.spec.ts @@ -1,7 +1,7 @@ import { debounce } from './debounce' describe('debounce', () => { - it('waits till callback gets executed', () => { + it('waits until callback gets executed', () => { const cb = jest.fn() const debounced = debounce(cb) debounced() diff --git a/tests/unit/__mocks__/axios.js b/tests/unit/__mocks__/axios.js new file mode 100644 index 00000000000..ef28bf2ceee --- /dev/null +++ b/tests/unit/__mocks__/axios.js @@ -0,0 +1,2 @@ +import mockAxios from 'jest-mock-axios' +export default mockAxios diff --git a/tests/unit/config/jest.config.js b/tests/unit/config/jest.config.js index e870f904d62..7ee6969a245 100644 --- a/tests/unit/config/jest.config.js +++ b/tests/unit/config/jest.config.js @@ -12,7 +12,7 @@ module.exports = { '^.+\\.svg$': 'jest-svg-transformer' }, moduleNameMapper: { - '\\.(css|less)$': '/tests/unit/mocks/style.js' + '\\.(css|less)$': '/tests/unit/stubs/empty.js' }, transformIgnorePatterns: ['/node_modules/(?!lodash-es)'], setupFiles: ['/tests/unit/config/jest.init.js', 'core-js'], diff --git a/tests/unit/mocks/style.js b/tests/unit/stubs/empty.js similarity index 100% rename from tests/unit/mocks/style.js rename to tests/unit/stubs/empty.js diff --git a/yarn.lock b/yarn.lock index 6b0f8d8ef6d..0f555ec3036 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6198,6 +6198,13 @@ jest-message-util@^26.6.2: slash "^3.0.0" stack-utils "^2.0.2" +jest-mock-axios@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/jest-mock-axios/-/jest-mock-axios-4.4.0.tgz#de0d7cd1219ab780472f774160f9e004245db0f1" + integrity sha512-MF5MbjIZcv2KCtO6oH/Fmy1sML1LxQoaGyIPRGArDdd9pcsfjWoCmFFUD12GgOTeJw8ChjuVYHN0s8QnhGriQA== + dependencies: + synchronous-promise "^2.0.15" + jest-mock@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-26.6.2.tgz#d6cb712b041ed47fe0d9b6fc3474bc6543feb302" @@ -10264,6 +10271,11 @@ symbol-tree@^3.2.4: resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2" integrity sha512-9QNk5KwDF+Bvz+PyObkmSYjI5ksVUYtjW7AU22r2NKcfLJcXp96hkDWU3+XndOsUb+AQ9QhfzfCT2O+CNWT5Tw== +synchronous-promise@^2.0.15: + version "2.0.15" + resolved "https://registry.yarnpkg.com/synchronous-promise/-/synchronous-promise-2.0.15.tgz#07ca1822b9de0001f5ff73595f3d08c4f720eb8e" + integrity sha512-k8uzYIkIVwmT+TcglpdN50pS2y1BDcUnBPK9iJeGu0Pl1lOI8pD6wtzgw91Pjpe+RxtTncw32tLxs/R0yNL2Mg== + tabbable@^5.2.0: version "5.2.0" resolved "https://registry.yarnpkg.com/tabbable/-/tabbable-5.2.0.tgz#4fba60991d8bb89d06e5d9455c92b453acf88fb2"