1
Fork 0

jest setup

This commit is contained in:
viktorstrate 2020-10-26 22:06:53 +01:00
parent d6d0b0688e
commit d2b2537346
13 changed files with 4222 additions and 151 deletions

View File

@ -1,13 +1,16 @@
{ {
"env": { "env": {
"browser": true, "browser": true,
"es6": true "es6": true,
"jest/globals": true
}, },
"extends": ["eslint:recommended", "plugin:react/recommended"], "extends": ["eslint:recommended", "plugin:react/recommended"],
"globals": { "globals": {
"Atomics": "readonly", "Atomics": "readonly",
"SharedArrayBuffer": "readonly", "SharedArrayBuffer": "readonly",
"process": "readonly" "process": "readonly",
"module": "readonly",
"require": "readonly"
}, },
"parserOptions": { "parserOptions": {
"ecmaFeatures": { "ecmaFeatures": {
@ -16,7 +19,7 @@
"ecmaVersion": 2018, "ecmaVersion": 2018,
"sourceType": "module" "sourceType": "module"
}, },
"plugins": ["react", "react-hooks"], "plugins": ["react", "react-hooks", "jest"],
"rules": { "rules": {
"no-unused-vars": "warn", "no-unused-vars": "warn",
"react/display-name": "off" "react/display-name": "off"

View File

@ -1,4 +0,0 @@
{
"tabWidth": 2,
"useTabs": false
}

16
ui/babel.config.js Normal file
View File

@ -0,0 +1,16 @@
module.exports = {
presets: ['@babel/preset-env', '@babel/preset-react'],
plugins: [
'styled-components',
'@babel/plugin-transform-runtime',
'@babel/plugin-transform-modules-commonjs',
'graphql-tag',
// [
// 'transform-semantic-ui-react-imports',
// {
// convertMemberImports: true,
// addCssImports: true,
// },
// ],
],
}

4190
ui/package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@ -35,23 +35,33 @@
"scripts": { "scripts": {
"start": "parcel start src/index.html", "start": "parcel start src/index.html",
"build": "parcel build src/index.html --no-source-maps", "build": "parcel build src/index.html --no-source-maps",
"test": "eslint ./src --max-warnings 0 --cache" "test": "npm run lint && npm run jest",
"lint": "eslint ./src --max-warnings 0 --cache",
"jest": "jest"
}, },
"devDependencies": { "devDependencies": {
"react-apollo": "^3.2.5",
"@babel/core": "^7.12.3", "@babel/core": "^7.12.3",
"@babel/plugin-transform-modules-commonjs": "^7.12.1",
"@babel/plugin-transform-runtime": "^7.12.1", "@babel/plugin-transform-runtime": "^7.12.1",
"@babel/preset-react": "^7.12.1",
"@testing-library/react": "^11.1.0",
"babel-eslint": "^10.1.0", "babel-eslint": "^10.1.0",
"babel-jest": "^26.6.1",
"babel-plugin-graphql-tag": "^3.1.0", "babel-plugin-graphql-tag": "^3.1.0",
"babel-plugin-transform-semantic-ui-react-imports": "^1.4.1", "babel-plugin-transform-semantic-ui-react-imports": "^1.4.1",
"eslint": "^7.12.0", "eslint": "^7.12.0",
"eslint-plugin-jest": "^24.1.0",
"eslint-plugin-react": "^7.21.5", "eslint-plugin-react": "^7.21.5",
"eslint-plugin-react-hooks": "^4.2.0", "eslint-plugin-react-hooks": "^4.2.0",
"husky": "^4.3.0", "husky": "^4.3.0",
"jest": "^26.6.1",
"lint-staged": "^10.5.0", "lint-staged": "^10.5.0",
"mapbox-gl": "^1.12.0", "mapbox-gl": "^1.12.0",
"parcel-plugin-sw-cache": "^0.3.1", "parcel-plugin-sw-cache": "^0.3.1",
"prettier": "^2.1.2", "prettier": "^2.1.2",
"react-router-prop-types": "^1.0.5" "react-router-prop-types": "^1.0.5",
"react-test-renderer": "^17.0.1"
}, },
"cache": { "cache": {
"swDest": "service-worker.js" "swDest": "service-worker.js"
@ -68,27 +78,14 @@
"singleQuote": true, "singleQuote": true,
"arrowParens": "avoid" "arrowParens": "avoid"
}, },
"babel": { "jest": {
"presets": [ "transformIgnorePatterns": [
[ "^.+\\.css$"
"@babel/preset-env",
{
"useBuiltIns": "entry"
}
]
], ],
"plugins": [ "transform": {
"styled-components", "^.+\\.js$": "babel-jest",
"@babel/plugin-transform-runtime", "^.+\\.svg$": "<rootDir>/testing/transform-svg.js"
"graphql-tag", }
[
"transform-semantic-ui-react-imports",
{
"convertMemberImports": true,
"addCssImports": true
}
]
]
}, },
"lint-staged": { "lint-staged": {
"*.{js,json,css,md,graphql}": "prettier --write", "*.{js,json,css,md,graphql}": "prettier --write",

View File

@ -1,7 +1,7 @@
import React, { Component } from 'react' import React, { Component } from 'react'
import { createGlobalStyle } from 'styled-components' import { createGlobalStyle } from 'styled-components'
import { Helmet } from 'react-helmet' import { Helmet } from 'react-helmet'
import Routes from './Routes' import Routes from './components/routes/Routes'
import Messages from './components/messages/Messages' import Messages from './components/messages/Messages'
const GlobalStyle = createGlobalStyle` const GlobalStyle = createGlobalStyle`
@ -21,12 +21,7 @@ const GlobalStyle = createGlobalStyle`
} }
` `
import 'semantic-ui-css/components/reset.css' import 'semantic-ui-css/semantic.min.css'
import 'semantic-ui-css/components/site.css'
import 'semantic-ui-css/components/transition.css'
import 'semantic-ui-css/components/menu.css'
import 'semantic-ui-css/components/dimmer.css'
import 'semantic-ui-css/components/label.css'
class App extends Component { class App extends Component {
render() { render() {

View File

@ -6,7 +6,7 @@ import { Icon } from 'semantic-ui-react'
import Sidebar from './components/sidebar/Sidebar' import Sidebar from './components/sidebar/Sidebar'
import { useQuery, useLazyQuery } from 'react-apollo' import { useQuery, useLazyQuery } from 'react-apollo'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { Authorized } from './AuthorizedRoute' import { Authorized } from './components/routes/AuthorizedRoute'
import { Helmet } from 'react-helmet' import { Helmet } from 'react-helmet'
import Header from './components/header/Header' import Header from './components/header/Header'
import { authToken } from './authentication' import { authToken } from './authentication'

View File

@ -10,7 +10,7 @@ import { getSharePassword, saveSharePassword } from '../../authentication'
import AlbumSharePage from './AlbumSharePage' import AlbumSharePage from './AlbumSharePage'
import MediaSharePage from './MediaSharePage' import MediaSharePage from './MediaSharePage'
const shareTokenQuery = gql` export const SHARE_TOKEN_QUERY = gql`
query SharePageToken($token: String!, $password: String) { query SharePageToken($token: String!, $password: String) {
shareToken(token: $token, password: $password) { shareToken(token: $token, password: $password) {
token token
@ -90,7 +90,7 @@ const validateTokenPasswordQuery = gql`
const AuthorizedTokenRoute = ({ match }) => { const AuthorizedTokenRoute = ({ match }) => {
const token = match.params.token const token = match.params.token
const { loading, error, data } = useQuery(shareTokenQuery, { const { loading, error, data } = useQuery(SHARE_TOKEN_QUERY, {
variables: { variables: {
token, token,
password: getSharePassword(token), password: getSharePassword(token),
@ -220,6 +220,8 @@ TokenRoute.propTypes = {
} }
const SharePage = ({ match }) => { const SharePage = ({ match }) => {
console.log(match)
return ( return (
<Switch> <Switch>
<Route path={`${match.url}/:token`}> <Route path={`${match.url}/:token`}>

View File

@ -0,0 +1,54 @@
import React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { MockedProvider } from 'react-apollo/testing'
import { create } from 'react-test-renderer'
import SharePage, { SHARE_TOKEN_QUERY } from './SharePage'
test('two plus two is four', () => {
const token = 'token_here'
const matchMock = {
url: `/share`,
params: {},
path: `/share`,
isExact: false,
}
const historyMock = [{ pathname: `/share/${token}` }]
const graphqlMocks = [
{
request: {
query: SHARE_TOKEN_QUERY,
variables: {
token,
password: null,
},
},
response: {
data: {
shareToken: {
token: token,
album: null,
media: {
id: 1,
title: 'shared_image.jpg',
type: 'photo',
},
},
},
},
},
]
const mediaSharePage = create(
<MockedProvider mocks={graphqlMocks} addTypename={false}>
<MemoryRouter initialEntries={historyMock}>
<SharePage match={matchMock} />
</MemoryRouter>
</MockedProvider>
)
console.log(mediaSharePage.toJSON())
})

View File

@ -3,7 +3,7 @@ import PropTypes from 'prop-types'
import { Route, Redirect } from 'react-router-dom' import { Route, Redirect } from 'react-router-dom'
import gql from 'graphql-tag' import gql from 'graphql-tag'
import { Query } from 'react-apollo' import { Query } from 'react-apollo'
import { authToken } from './authentication' import { authToken } from '../../authentication'
const adminQuery = gql` const adminQuery = gql`
query adminQuery { query adminQuery {

View File

@ -2,23 +2,26 @@ import React from 'react'
import { Route, Switch, Redirect } from 'react-router-dom' import { Route, Switch, Redirect } from 'react-router-dom'
import { Loader } from 'semantic-ui-react' import { Loader } from 'semantic-ui-react'
import Layout from './Layout' import Layout from '../../Layout'
import { clearTokenCookie } from './authentication' import { clearTokenCookie } from '../../authentication'
const AlbumsPage = React.lazy(() => import('./Pages/AllAlbumsPage/AlbumsPage'))
const AlbumPage = React.lazy(() => import('./Pages/AlbumPage/AlbumPage'))
const AuthorizedRoute = React.lazy(() => import('./AuthorizedRoute')) const AuthorizedRoute = React.lazy(() => import('./AuthorizedRoute'))
const PhotosPage = React.lazy(() => import('./Pages/PhotosPage/PhotosPage'))
const PlacesPage = React.lazy(() => import('./Pages/PlacesPage/PlacesPage'))
const SharePage = React.lazy(() => import('./Pages/SharePage/SharePage'))
const LoginPage = React.lazy(() => import('./Pages/LoginPage/LoginPage')) const AlbumsPage = React.lazy(() =>
import('../../Pages/AllAlbumsPage/AlbumsPage')
)
const AlbumPage = React.lazy(() => import('../../Pages/AlbumPage/AlbumPage'))
const PhotosPage = React.lazy(() => import('../../Pages/PhotosPage/PhotosPage'))
const PlacesPage = React.lazy(() => import('../../Pages/PlacesPage/PlacesPage'))
const SharePage = React.lazy(() => import('../../Pages/SharePage/SharePage'))
const LoginPage = React.lazy(() => import('../../Pages/LoginPage/LoginPage'))
const InitialSetupPage = React.lazy(() => const InitialSetupPage = React.lazy(() =>
import('./Pages/LoginPage/InitialSetupPage') import('../../Pages/LoginPage/InitialSetupPage')
) )
const SettingsPage = React.lazy(() => const SettingsPage = React.lazy(() =>
import('./Pages/SettingsPage/SettingsPage') import('../../Pages/SettingsPage/SettingsPage')
) )
class Routes extends React.Component { class Routes extends React.Component {

View File

@ -1,3 +1,5 @@
import 'regenerator-runtime/runtime'
import React from 'react' import React from 'react'
import ReactDOM from 'react-dom' import ReactDOM from 'react-dom'
import App from './App' import App from './App'

View File

@ -0,0 +1,15 @@
/**
* Mock .svg imports
*/
const path = require('path')
module.exports = {
process(_, filename) {
return 'module.exports = "' + path.basename(filename) + '.svg"'
},
getCacheKey(_, filename) {
// The output is based on path.
return path.basename(filename)
},
}