Skip to content

Commit

Permalink
test: add client tests
Browse files Browse the repository at this point in the history
  • Loading branch information
jbrunton committed Jul 30, 2023
1 parent f85cbfc commit d1dbd60
Show file tree
Hide file tree
Showing 13 changed files with 6,762 additions and 516 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
directory: ["services/api", "pulumi"]
directory: ["services/api", "pulumi", "client"]
defaults:
run:
working-directory: ${{ matrix.directory }}
Expand Down
7,127 changes: 6,615 additions & 512 deletions client/package-lock.json

Large diffs are not rendered by default.

11 changes: 9 additions & 2 deletions client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"preview": "vite preview",
"lint": "eslint --max-warnings 0 'src/**/*.{ts,tsx}'",
"lint:fix": "eslint --max-warnings 0 --fix 'src/**/*.{ts,tsx}'",
"format": "prettier --write 'src/**/*.{ts,tsx,css,md}' --config ./.prettierrc"
"format": "prettier --write 'src/**/*.{ts,tsx,css,md}' --config ./.prettierrc",
"test": "vitest"
},
"dependencies": {
"@auth0/auth0-react": "1.12.0",
Expand All @@ -34,6 +35,9 @@
"react-router-dom": "6.6.1"
},
"devDependencies": {
"@testing-library/jest-dom": "5.17.0",
"@testing-library/react": "14.0.0",
"@testing-library/user-event": "14.4.3",
"@types/debug": "4.1.7",
"@types/dompurify": "2.4.0",
"@types/event-source-polyfill": "1.0.0",
Expand All @@ -49,8 +53,11 @@
"eslint-plugin-prettier": "4.2.1",
"eslint-plugin-react": "7.31.11",
"eslint-plugin-react-hooks": "4.6.0",
"jsdom": "22.1.0",
"msw": "1.2.3",
"prettier": "2.8.1",
"typescript": "^4.9.3",
"vite": "^4.0.0"
"vite": "^4.0.0",
"vitest": "0.33.0"
}
}
28 changes: 28 additions & 0 deletions client/src/features/room/pages/Room.spec.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react'
import { screen, waitFor } from '@testing-library/react'
import { RoomPage } from './Room'
import { render } from '../../../test/fixtures'

describe('RoomPage', () => {
it('loads messages for the room', async () => {
render(<RoomPage />, {
path: '/room/:roomId',
initialEntry: '/room/room:123-can-manage',
})

await waitFor(() => {
expect(screen.getByText('Hello, World!'))
})
})

it('shows a help message if the user can join the room', async () => {
render(<RoomPage />, {
path: '/room/:roomId',
initialEntry: '/room/room:456-can-join',
})

await waitFor(() => {
expect(screen.getByText('You do not have permissions to view messages in this room'))
})
})
})
23 changes: 23 additions & 0 deletions client/src/mocks/handlers.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { rest } from 'msw'
import { readFileSync } from 'fs'
import { resolve } from 'path'

export const handlers = [
rest.get('/rooms/:roomId', (req, res, ctx) => {
const roomId = req.params['roomId']
const response = loadResponse(`./rooms/get/${roomId}.json`)
return res(ctx.json(response))
}),

rest.get('/messages/:roomId', (req, res, ctx) => {
const roomId = req.params['roomId']
const response = loadResponse(`./messages/get/${roomId}.json`)
return res(ctx.json(response))
}),
]

const loadResponse = (relativePath: string): JSON => {
const path = resolve(__dirname, relativePath)
const contents = readFileSync(path, { encoding: 'utf-8' })
return JSON.parse(contents)
}
16 changes: 16 additions & 0 deletions client/src/mocks/messages/get/room:123-can-manage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
[
{
"id": "message:a1b2c3",
"roomId": "room:123",
"content": "Hello, World!",
"authorId": "system",
"time": 1690030739801
},
{
"id": "message:d4e5f6",
"roomId": "room:123",
"content": "Test message",
"authorId": "user:test-user",
"time": 1690551939302
}
]
10 changes: 10 additions & 0 deletions client/src/mocks/rooms/get/room:123-can-manage.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"room": {
"id": "room:123",
"name": "Test Room",
"ownerId": "user:test-user",
"contentPolicy": "private",
"joinPolicy": "anyone"
},
"roles": ["read", "write", "manage", "join"]
}
10 changes: 10 additions & 0 deletions client/src/mocks/rooms/get/room:456-can-join.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"room": {
"id": "room:456",
"name": "Test Room",
"ownerId": "user:test-user",
"contentPolicy": "private",
"joinPolicy": "anyone"
},
"roles": ["role"]
}
4 changes: 4 additions & 0 deletions client/src/mocks/server.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { setupServer } from 'msw/node'
import { handlers } from './handlers'

export const server = setupServer(...handlers)
30 changes: 30 additions & 0 deletions client/src/test/fixtures.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react'
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
import { render } from '@testing-library/react'
import { ReactElement } from 'react'
import { RouterProvider, createMemoryRouter } from 'react-router-dom'

export type RenderOptions = {
path: string
initialEntry: string
}

const customRender = (ui: ReactElement, opts: RenderOptions | undefined) => {
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
},
})
const router = opts
? createMemoryRouter([{ path: opts.path, element: ui }], {
initialEntries: [opts.initialEntry],
})
: undefined
render(
<QueryClientProvider client={queryClient}>{router ? <RouterProvider router={router} /> : ui}</QueryClientProvider>,
)
}

export { customRender as render }
7 changes: 7 additions & 0 deletions client/src/test/setup-mocks.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { server } from '../mocks/server'

beforeAll(() => server.listen())

afterAll(() => server.close())

afterEach(() => server.resetHandlers())
3 changes: 2 additions & 1 deletion client/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
"jsx": "react-jsx",
"types": ["vitest/globals"]
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
Expand Down
7 changes: 7 additions & 0 deletions client/vite.config.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/// <reference types="vitest" />
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
import dns from 'dns'
Expand All @@ -7,4 +8,10 @@ dns.setDefaultResultOrder('verbatim')
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
test: {
globals: true,
environment: 'jsdom',
mockReset: true,
setupFiles: ['./src/test/setup-mocks.ts'],
},
})

0 comments on commit d1dbd60

Please sign in to comment.