Skip to content

Commit

Permalink
feat: ✅ Enable jest and react-testing-library for unit testing
Browse files Browse the repository at this point in the history
Added a simple test for the Tile component and auth utility function. Page testing is problematic due to the i18n configuration, its do-able, just was taking too much time.
  • Loading branch information
RyanHirsch committed Jan 9, 2022
1 parent d2cee28 commit f3260ff
Show file tree
Hide file tree
Showing 13 changed files with 1,937 additions and 51 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/develop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,5 @@ jobs:
yarn install --frozen-lockfile
yarn lint
yarn build
yarn test
yarn test:ci
2 changes: 1 addition & 1 deletion .github/workflows/stage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
yarn install --frozen-lockfile
yarn lint
yarn build
yarn test
yarn test:ci
e2e:
runs-on: ubuntu-latest
Expand Down
8 changes: 5 additions & 3 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,18 @@
"appleboy",
"browserstack",
"callout",
"Downey",
"dropdowns",
"FDROID",
"fontawesome",
"fortawesome",
"nightwatch",
"perrywinkle",
"PGPASSWORD",
"podverse",
"scrollbars",
"stylelint"
"stylelint",
"Creonopoulos",
"Downey",
"FOSS",
"Podverse"
]
}
23 changes: 23 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const nextJest = require('next/jest')

const createJestConfig = nextJest({
// Provide the path to your Next.js app to load next.config.js and .env files in your test environment
dir: './'
})

// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/jest.setup.js'],
moduleNameMapper: {
// Handle module aliases (this will be automatically configured for you soon)
'^@/components/(.*)$': '<rootDir>/src/components/$1',

'^@/pages/(.*)$': '<rootDir>/pages/$1',
'^~/(.*)$': '<rootDir>/src/$1'
},
testEnvironment: 'jest-environment-jsdom',
testPathIgnorePatterns: ['__tests__/e2e', '__tests__/old_tests']
}

// createJestConfig is exported this way to ensure that next/jest can load the Next.js config which is async
module.exports = createJestConfig(customJestConfig)
6 changes: 6 additions & 0 deletions jest.setup.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import '@testing-library/jest-dom/extend-expect'
import { setConfig } from 'next/config'
import config from './next.config'

// Make sure you can use "publicRuntimeConfig" within tests.
setConfig(config.publicRuntimeConfig)
5 changes: 1 addition & 4 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,7 @@ const { i18n } = require('./next-i18next.config')
const { withSentryConfig } = require('@sentry/nextjs')

const isDev = process.env.NODE_ENV === 'development' || !process.env.NODE_ENV
console.log({
env: process.env.NODE_ENV,
isDev
})

const envVars = {}
const sentryWebpackPluginOptions = {
// Additional config options for the Sentry Webpack plugin. Keep in mind that
Expand Down
8 changes: 7 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,8 @@
"lint:ts": "tsc --noEmit",
"lint:prettier": "npm run prettier:check",
"lint:stylelint": "stylelint '**/*.scss'",
"test": "exit 0;",
"test": "jest --watch",
"test:ci": "jest --ci",
"stylelint:fix": "stylelint --fix '**/*.scss'",
"prettier:base": "prettier",
"prettier:list": "npm run prettier:base -- --list-different \"styles/**/*.scss\" \"src/**/*.{ts,tsx,scss}\" \"pages/**/*.{ts,tsx,scss}\" \"__tests__/**/*.{ts,js,tsx}\"",
Expand Down Expand Up @@ -72,13 +73,18 @@
"striptags": "3.2.0"
},
"devDependencies": {
"@testing-library/jest-dom": "5.16.1",
"@testing-library/react": "12.1.2",
"@testing-library/user-event": "13.5.0",
"@types/node": "16.11.11",
"@types/react": "17.0.37",
"@typescript-eslint/eslint-plugin": "5.6.0",
"@typescript-eslint/parser": "5.5.0",
"babel-jest": "27.4.6",
"eslint": "7.32.0",
"eslint-config-next": "12.0.4",
"eslint-config-prettier": "8.3.0",
"jest": "27.4.7",
"lint-staged": "12.1.2",
"npm-run-all": "4.1.5",
"postcss": "8.4.5",
Expand Down
2 changes: 1 addition & 1 deletion pages/about.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function About(props: ServerProps) {
<li>Subscribe to playlists</li>
</ul>
<p>
All Podverse software is provided under a free and open source (FOSS) licence. Features that require
All Podverse software is provided under a free and open source (FOSS) license. Features that require
updating our servers are available only with a Premium membership. Sign up today and get 1 year of
Premium for free{' '}
<span role='img' aria-label='partying face emoji'>
Expand Down
15 changes: 15 additions & 0 deletions src/components/Tile/__tests__/Tile.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { render, screen } from '@testing-library/react'
import { noop } from '~/lib/test-helpers'
import { Tile } from '../Tile'

describe('Title', () => {
it('renders a heading', () => {
render(<Tile title='Some Text' onClick={noop} />)

const heading = screen.getByRole('heading', {
name: /Some Text/i
})

expect(heading).toBeInTheDocument()
})
})
3 changes: 3 additions & 0 deletions src/lib/test-helpers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// eslint-disable-next-line @typescript-eslint/no-empty-function
export const noop = () => {}
export const identity = <T>(t: T) => t
17 changes: 17 additions & 0 deletions src/lib/utility/__tests__/auth.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { getAuthCredentialsHeaders } from '../auth'

describe('auth', () => {
it('returns a headers authorization object when passed a token', () => {
const fakeToken = 'some-token-here'
const result = getAuthCredentialsHeaders(fakeToken)

expect(result).toHaveProperty('headers')
expect(result.headers).toHaveProperty('Authorization', fakeToken)
})

it('returns cookie auth when no token is provided', () => {
const result = getAuthCredentialsHeaders()

expect(result).toHaveProperty('withCredentials', true)
})
})
3 changes: 2 additions & 1 deletion src/resources/Config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import getConfig from 'next/config'
const { publicRuntimeConfig, serverRuntimeConfig } = getConfig()

const getServerOrPublicVariable = (envVarKey: string) =>
serverRuntimeConfig[envVarKey] || publicRuntimeConfig[envVarKey]
// optional chaining helps with the test environment
serverRuntimeConfig?.[envVarKey] || publicRuntimeConfig?.[envVarKey]

const API_PROTOCOL = getServerOrPublicVariable('API_PROTOCOL')
const API_DOMAIN = getServerOrPublicVariable('API_DOMAIN')
Expand Down
Loading

0 comments on commit f3260ff

Please sign in to comment.