1
Fork 0

Add first UI test

This commit is contained in:
viktorstrate 2020-10-27 00:22:08 +01:00
parent db9d64d948
commit 82925396a3
14 changed files with 271 additions and 51 deletions

View File

@ -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"

162
ui/package-lock.json generated
View File

@ -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",

View File

@ -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",

View File

@ -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 (
<Container>
<Container {...otherProps}>
<Helmet>
<title>{title ? `${title} - Photoview` : `Photoview`}</title>
</Helmet>

View File

@ -67,7 +67,6 @@ const AddUserRow = ({ setShow, show, onUserAdded }) => {
toggle
checked={state.admin}
onChange={(e, data) => {
console.log(data)
setState({
...state,
admin: data.checked,

View File

@ -42,14 +42,12 @@ MediaView.propTypes = {
media: PropTypes.object.isRequired,
}
const MediaSharePage = ({ media }) => {
return (
<Layout>
<h1>{media.title}</h1>
<MediaView media={media} />
</Layout>
)
}
const MediaSharePage = ({ media }) => (
<Layout data-testid="MediaSharePage">
<h1>{media.title}</h1>
<MediaView media={media} />
</Layout>
)
MediaSharePage.propTypes = {
media: PropTypes.object.isRequired,

View File

@ -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 (
<Switch>
<Route path={`${match.url}/:token`}>
{({ match }) => <TokenRoute match={match} />}
</Route>
<Route path="/">Route not found</Route>
</Switch>
)
}
const SharePage = ({ match }) => (
<Switch>
<Route path={`${match.url}/:token`}>
{({ match }) => {
return <TokenRoute match={match} />
}}
</Route>
<Route path="/">Route not found</Route>
</Switch>
)
SharePage.propTypes = {
...RouterProps,

View File

@ -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(
<MockedProvider mocks={graphqlMocks} addTypename={false}>
<MemoryRouter initialEntries={historyMock}>
<SharePage match={matchMock} />
</MemoryRouter>
</MockedProvider>
)
test('load media page', async () => {
render(
<MockedProvider
mocks={graphqlMocks}
addTypename={false}
defaultOptions={{
// disable cache, required to make fragments work
watchQuery: { fetchPolicy: 'no-cache' },
query: { fetchPolicy: 'no-cache' },
}}
>
<MemoryRouter initialEntries={historyMock}>
<SharePage match={matchMock} />
</MemoryRouter>
</MockedProvider>
)
console.log(mediaSharePage.toJSON())
expect(screen.getByText('Loading...')).toBeInTheDocument()
await waitForElementToBeRemoved(() => screen.getByText('Loading...'))
expect(screen.getByTestId('MediaSharePage')).toBeInTheDocument()
})
})

View File

@ -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)

View File

@ -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)

View File

@ -74,7 +74,6 @@ const PresentNavigationOverlay = ({
const onMouseMove = useRef(null)
useEffect(() => {
console.log('Setup mouse move')
onMouseMove.current = debounce(
() => {
setHide(hide => !hide)

View File

@ -22,8 +22,6 @@ const AlbumSidebar = ({ albumId }) => {
if (loading) return <div>Loading...</div>
if (error) return <div>{error.message}</div>
console.log('ALBUM', data.album)
return (
<div>
<h1>{data.album.title}</h1>

View File

@ -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 } }],

View File

@ -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 = []