From 82925396a34101cec0ef3201cf6ed983d2bd131a Mon Sep 17 00:00:00 2001 From: viktorstrate Date: Tue, 27 Oct 2020 00:22:08 +0100 Subject: [PATCH] Add first UI test --- ui/.eslintrc.json | 2 +- ui/package-lock.json | 162 ++++++++++++++++++ ui/package.json | 2 + ui/src/Layout.js | 6 +- ui/src/Pages/SettingsPage/AddUserRow.js | 1 - ui/src/Pages/SharePage/MediaSharePage.js | 14 +- ui/src/Pages/SharePage/SharePage.js | 26 ++- ui/src/Pages/SharePage/SharePage.test.js | 96 +++++++++-- .../components/albumGallery/AlbumGallery.js | 1 - ui/src/components/header/Searchbar.js | 1 - .../presentView/PresentNavigationOverlay.js | 1 - ui/src/components/sidebar/AlbumSidebar.js | 2 - ui/src/components/sidebar/Sharing.js | 1 - ui/src/components/sidebar/SidebarDownload.js | 7 +- 14 files changed, 271 insertions(+), 51 deletions(-) diff --git a/ui/.eslintrc.json b/ui/.eslintrc.json index 0d7b7b4e..c97ff178 100644 --- a/ui/.eslintrc.json +++ b/ui/.eslintrc.json @@ -19,7 +19,7 @@ "ecmaVersion": 2018, "sourceType": "module" }, - "plugins": ["react", "react-hooks", "jest"], + "plugins": ["react", "react-hooks", "jest", "jest-dom"], "rules": { "no-unused-vars": "warn", "react/display-name": "off" diff --git a/ui/package-lock.json b/ui/package-lock.json index 241df26a..f9bc05fe 100644 --- a/ui/package-lock.json +++ b/ui/package-lock.json @@ -3172,6 +3172,73 @@ } } }, + "@testing-library/jest-dom": { + "version": "5.11.5", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.11.5.tgz", + "integrity": "sha512-XI+ClHR864i6p2kRCEyhvpVejuer+ObVUF4cjCvRSF88eOMIfqw7RoS9+qoRhyigGswMfT64L6Nt0Ufotxbwtg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.2", + "@types/testing-library__jest-dom": "^5.9.1", + "aria-query": "^4.2.2", + "chalk": "^3.0.0", + "css": "^3.0.0", + "css.escape": "^1.5.1", + "lodash": "^4.17.15", + "redent": "^3.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "chalk": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-3.0.0.tgz", + "integrity": "sha512-4D3B6Wf41KOYRFdszmDqMCGq5VV/uMAB273JILmO+3jAlh8X4qDtdtgCR3fxtbLEMzSx22QdhnDcJvu2u1fVwg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, "@testing-library/react": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/@testing-library/react/-/react-11.1.0.tgz", @@ -3268,6 +3335,16 @@ "@types/istanbul-lib-report": "*" } }, + "@types/jest": { + "version": "26.0.15", + "resolved": "https://registry.npmjs.org/@types/jest/-/jest-26.0.15.tgz", + "integrity": "sha512-s2VMReFXRg9XXxV+CW9e5Nz8fH2K1aEhwgjUqPPbQd7g95T0laAcvLv032EhFHIa5GHsZ8W7iJEQVaJq6k3Gog==", + "dev": true, + "requires": { + "jest-diff": "^26.0.0", + "pretty-format": "^26.0.0" + } + }, "@types/json-schema": { "version": "7.0.6", "resolved": "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.6.tgz", @@ -3323,6 +3400,15 @@ "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, + "@types/testing-library__jest-dom": { + "version": "5.9.5", + "resolved": "https://registry.npmjs.org/@types/testing-library__jest-dom/-/testing-library__jest-dom-5.9.5.tgz", + "integrity": "sha512-ggn3ws+yRbOHog9GxnXiEZ/35Mow6YtPZpd7Z5mKDeZS/o7zx3yAle0ov/wjhVB5QT4N2Dt+GNoGCdqkBGCajQ==", + "dev": true, + "requires": { + "@types/jest": "*" + } + }, "@types/yargs": { "version": "15.0.9", "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-15.0.9.tgz", @@ -4914,6 +5000,35 @@ "randomfill": "^1.0.3" } }, + "css": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/css/-/css-3.0.0.tgz", + "integrity": "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ==", + "dev": true, + "requires": { + "inherits": "^2.0.4", + "source-map": "^0.6.1", + "source-map-resolve": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", + "dev": true + }, + "source-map-resolve": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.6.0.tgz", + "integrity": "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w==", + "dev": true, + "requires": { + "atob": "^2.1.2", + "decode-uri-component": "^0.2.0" + } + } + } + }, "css-color-keywords": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/css-color-keywords/-/css-color-keywords-1.0.0.tgz", @@ -5071,6 +5186,12 @@ "resolved": "https://registry.npmjs.org/css-what/-/css-what-3.3.0.tgz", "integrity": "sha512-pv9JPyatiPaQ6pf4OvD/dbfm0o5LviWmwxNWzblYf/1u9QZd0ihV+PMwy5jdQWQ3349kZmKEx9WXuSka2dM4cg==" }, + "css.escape": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/css.escape/-/css.escape-1.5.1.tgz", + "integrity": "sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s=", + "dev": true + }, "csscolorparser": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/csscolorparser/-/csscolorparser-1.0.3.tgz", @@ -5908,6 +6029,16 @@ "@typescript-eslint/experimental-utils": "^4.0.1" } }, + "eslint-plugin-jest-dom": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-3.2.4.tgz", + "integrity": "sha512-CRR5rMMJgLKjxHHuio/oy4tt5gnUohgGNMzLM0p0THoyRYewzV/PE+8qUUHSyTO+iexCvgnHukdRfckdyi+5tg==", + "dev": true, + "requires": { + "@babel/runtime": "^7.9.6", + "requireindex": "^1.2.0" + } + }, "eslint-plugin-react": { "version": "7.21.5", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.21.5.tgz", @@ -10081,6 +10212,12 @@ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==" }, + "min-indent": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", + "integrity": "sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==", + "dev": true + }, "mini-create-react-context": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/mini-create-react-context/-/mini-create-react-context-0.4.0.tgz", @@ -11915,6 +12052,16 @@ "readable-stream": "^2.0.2" } }, + "redent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", + "integrity": "sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==", + "dev": true, + "requires": { + "indent-string": "^4.0.0", + "strip-indent": "^3.0.0" + } + }, "regenerate": { "version": "1.4.1", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.1.tgz", @@ -12103,6 +12250,12 @@ "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==", "dev": true }, + "requireindex": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/requireindex/-/requireindex-1.2.0.tgz", + "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", + "dev": true + }, "resolve": { "version": "1.17.0", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.17.0.tgz", @@ -13116,6 +13269,15 @@ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", "dev": true }, + "strip-indent": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-indent/-/strip-indent-3.0.0.tgz", + "integrity": "sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==", + "dev": true, + "requires": { + "min-indent": "^1.0.0" + } + }, "strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", diff --git a/ui/package.json b/ui/package.json index 014dda52..c7d8316f 100644 --- a/ui/package.json +++ b/ui/package.json @@ -37,6 +37,7 @@ "@babel/plugin-transform-modules-commonjs": "^7.12.1", "@babel/plugin-transform-runtime": "^7.12.1", "@babel/preset-react": "^7.12.1", + "@testing-library/jest-dom": "^5.11.5", "@testing-library/react": "^11.1.0", "babel-eslint": "^10.1.0", "babel-jest": "^26.6.1", @@ -44,6 +45,7 @@ "babel-plugin-transform-semantic-ui-react-imports": "^1.4.1", "eslint": "^7.12.0", "eslint-plugin-jest": "^24.1.0", + "eslint-plugin-jest-dom": "^3.2.4", "eslint-plugin-react": "^7.21.5", "eslint-plugin-react-hooks": "^4.2.0", "husky": "^4.3.0", diff --git a/ui/src/Layout.js b/ui/src/Layout.js index 4cdcb258..bf49afdc 100644 --- a/ui/src/Layout.js +++ b/ui/src/Layout.js @@ -18,7 +18,7 @@ const ADMIN_QUERY = gql` } ` -const MAPBOX_QUERY = gql` +export const MAPBOX_QUERY = gql` query mapboxEnabledQuery { mapboxToken } @@ -94,7 +94,7 @@ const SideButtonLabel = styled.div` font-size: 16px; ` -const Layout = ({ children, title }) => { +const Layout = ({ children, title, ...otherProps }) => { const [loadAdminQuery, adminQuery] = useLazyQuery(ADMIN_QUERY) const mapboxQuery = useQuery(MAPBOX_QUERY) @@ -110,7 +110,7 @@ const Layout = ({ children, title }) => { const mapboxEnabled = mapboxQuery.data && mapboxQuery.data.mapboxToken != null return ( - + {title ? `${title} - Photoview` : `Photoview`} diff --git a/ui/src/Pages/SettingsPage/AddUserRow.js b/ui/src/Pages/SettingsPage/AddUserRow.js index 92776827..9a33be64 100644 --- a/ui/src/Pages/SettingsPage/AddUserRow.js +++ b/ui/src/Pages/SettingsPage/AddUserRow.js @@ -67,7 +67,6 @@ const AddUserRow = ({ setShow, show, onUserAdded }) => { toggle checked={state.admin} onChange={(e, data) => { - console.log(data) setState({ ...state, admin: data.checked, diff --git a/ui/src/Pages/SharePage/MediaSharePage.js b/ui/src/Pages/SharePage/MediaSharePage.js index cad90b63..3e1cfea1 100644 --- a/ui/src/Pages/SharePage/MediaSharePage.js +++ b/ui/src/Pages/SharePage/MediaSharePage.js @@ -42,14 +42,12 @@ MediaView.propTypes = { media: PropTypes.object.isRequired, } -const MediaSharePage = ({ media }) => { - return ( - -

{media.title}

- -
- ) -} +const MediaSharePage = ({ media }) => ( + +

{media.title}

+ +
+) MediaSharePage.propTypes = { media: PropTypes.object.isRequired, diff --git a/ui/src/Pages/SharePage/SharePage.js b/ui/src/Pages/SharePage/SharePage.js index d898440c..0fcf4044 100644 --- a/ui/src/Pages/SharePage/SharePage.js +++ b/ui/src/Pages/SharePage/SharePage.js @@ -80,7 +80,7 @@ export const SHARE_TOKEN_QUERY = gql` } ` -const validateTokenPasswordQuery = gql` +export const VALIDATE_TOKEN_PASSWORD_QUERY = gql` query ShareTokenValidatePassword($token: String!, $password: String) { shareTokenValidatePassword(token: $token, password: $password) } @@ -174,7 +174,7 @@ const TokenRoute = ({ match }) => { const token = match.params.token const { loading, error, data, refetch } = useQuery( - validateTokenPasswordQuery, + VALIDATE_TOKEN_PASSWORD_QUERY, { variables: { token: match.params.token, @@ -218,18 +218,16 @@ TokenRoute.propTypes = { match: PropTypes.object.isRequired, } -const SharePage = ({ match }) => { - console.log(match) - - return ( - - - {({ match }) => } - - Route not found - - ) -} +const SharePage = ({ match }) => ( + + + {({ match }) => { + return + }} + + Route not found + +) SharePage.propTypes = { ...RouterProps, diff --git a/ui/src/Pages/SharePage/SharePage.test.js b/ui/src/Pages/SharePage/SharePage.test.js index 53b7a556..998807d2 100644 --- a/ui/src/Pages/SharePage/SharePage.test.js +++ b/ui/src/Pages/SharePage/SharePage.test.js @@ -1,12 +1,25 @@ +import '@testing-library/jest-dom' + import React from 'react' import { MemoryRouter } from 'react-router-dom' import { MockedProvider } from '@apollo/client/testing' -import { create } from 'react-test-renderer' +// import { create } from 'react-test-renderer' +import { + render, + screen, + waitForElementToBeRemoved, +} from '@testing-library/react' -import SharePage, { SHARE_TOKEN_QUERY } from './SharePage' +import SharePage, { + SHARE_TOKEN_QUERY, + VALIDATE_TOKEN_PASSWORD_QUERY, +} from './SharePage' -test('two plus two is four', () => { - const token = 'token_here' +import { MAPBOX_QUERY } from '../../Layout' +import { SIDEBAR_DOWNLOAD_QUERY } from '../../components/sidebar/SidebarDownload' + +describe('load correct share page, based on graphql query', () => { + const token = 'TOKEN123' const matchMock = { url: `/share`, @@ -26,7 +39,7 @@ test('two plus two is four', () => { password: null, }, }, - response: { + result: { data: { shareToken: { token: token, @@ -35,20 +48,77 @@ test('two plus two is four', () => { id: 1, title: 'shared_image.jpg', type: 'photo', + highRes: { + url: 'https://example.com/shared_image.jpg', + }, }, }, }, }, }, + { + request: { + query: VALIDATE_TOKEN_PASSWORD_QUERY, + variables: { + token, + password: null, + }, + }, + result: { + data: { + shareTokenValidatePassword: true, + }, + }, + }, + { + request: { + query: MAPBOX_QUERY, + }, + result: { + data: { + mapboxToken: null, + }, + }, + }, + { + request: { + query: SIDEBAR_DOWNLOAD_QUERY, + variables: { + mediaId: 1, + }, + }, + result: { + data: { + media: { + id: 1, + downloads: [], + }, + }, + }, + }, ] - const mediaSharePage = create( - - - - - - ) + test('load media page', async () => { + render( + + + + + + ) - console.log(mediaSharePage.toJSON()) + expect(screen.getByText('Loading...')).toBeInTheDocument() + + await waitForElementToBeRemoved(() => screen.getByText('Loading...')) + + expect(screen.getByTestId('MediaSharePage')).toBeInTheDocument() + }) }) diff --git a/ui/src/components/albumGallery/AlbumGallery.js b/ui/src/components/albumGallery/AlbumGallery.js index bc2a346c..4bed3351 100644 --- a/ui/src/components/albumGallery/AlbumGallery.js +++ b/ui/src/components/albumGallery/AlbumGallery.js @@ -56,7 +56,6 @@ const AlbumGallery = ({ useEffect(() => { const updateImageState = event => { - // console.log('Getting status from history', event.state) setImageState(event.state.imageState) } window.addEventListener('popstate', updateImageState) diff --git a/ui/src/components/header/Searchbar.js b/ui/src/components/header/Searchbar.js index 72513a4b..9d809d09 100644 --- a/ui/src/components/header/Searchbar.js +++ b/ui/src/components/header/Searchbar.js @@ -84,7 +84,6 @@ const SearchBar = () => { let debouncedFetch = useRef(null) useEffect(() => { debouncedFetch.current = debounce(query => { - console.log('searching', query) fetchSearches({ variables: { query } }) setFetched(true) }, 250) diff --git a/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js b/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js index b3be2de0..42b882ab 100644 --- a/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js +++ b/ui/src/components/photoGallery/presentView/PresentNavigationOverlay.js @@ -74,7 +74,6 @@ const PresentNavigationOverlay = ({ const onMouseMove = useRef(null) useEffect(() => { - console.log('Setup mouse move') onMouseMove.current = debounce( () => { setHide(hide => !hide) diff --git a/ui/src/components/sidebar/AlbumSidebar.js b/ui/src/components/sidebar/AlbumSidebar.js index 3ea134a5..8ead9089 100644 --- a/ui/src/components/sidebar/AlbumSidebar.js +++ b/ui/src/components/sidebar/AlbumSidebar.js @@ -22,8 +22,6 @@ const AlbumSidebar = ({ albumId }) => { if (loading) return
Loading...
if (error) return
{error.message}
- console.log('ALBUM', data.album) - return (

{data.album.title}

diff --git a/ui/src/components/sidebar/Sharing.js b/ui/src/components/sidebar/Sharing.js index ef203759..b979d368 100644 --- a/ui/src/components/sidebar/Sharing.js +++ b/ui/src/components/sidebar/Sharing.js @@ -99,7 +99,6 @@ const ShareItemMoreDropdown = ({ id, share, isPhoto }) => { { refetchQueries: [{ query: query, variables: { id } }], onCompleted: data => { - console.log('data', data) hidePassword(data.protectShareToken.hasPassword) }, // refetchQueries: [{ query: query, variables: { id } }], diff --git a/ui/src/components/sidebar/SidebarDownload.js b/ui/src/components/sidebar/SidebarDownload.js index f4a0d78f..65f76acd 100644 --- a/ui/src/components/sidebar/SidebarDownload.js +++ b/ui/src/components/sidebar/SidebarDownload.js @@ -7,7 +7,7 @@ import { useLazyQuery, gql } from '@apollo/client' import download from 'downloadjs' import { authToken } from '../../authentication' -const downloadQuery = gql` +export const SIDEBAR_DOWNLOAD_QUERY = gql` query sidebarDownloadQuery($mediaId: Int!) { media(id: $mediaId) { id @@ -52,7 +52,6 @@ const downloadPhoto = async url => { }) const totalBytes = Number(response.headers.get('content-length')) - console.log(totalBytes) if (totalBytes == 0) { MessageState.add({ @@ -72,7 +71,6 @@ const downloadPhoto = async url => { let canceled = false const onDismiss = () => { - console.log('Canceling download') canceled = true reader.cancel('Download canceled by user') } @@ -115,7 +113,6 @@ const downloadPhoto = async url => { } while (!result.done) if (canceled) { - console.log('Download canceled returning') return } @@ -152,7 +149,7 @@ const SidebarDownload = ({ photo }) => { const [ loadPhotoDownloads, { called, loading, data }, - ] = useLazyQuery(downloadQuery, { variables: { mediaId: photo.id } }) + ] = useLazyQuery(SIDEBAR_DOWNLOAD_QUERY, { variables: { mediaId: photo.id } }) let downloads = []