Refactor app/index separately, tune response handling in tests, add trigger route for creating test users

This commit is contained in:
ShootingStar91
2024-08-28 17:11:16 +03:00
parent 10eec97616
commit 66f39ab322
4 changed files with 125 additions and 74 deletions
+47 -16
View File
@@ -1,35 +1,56 @@
import { describe, it } from 'node:test'
import assert from 'node:assert'
import { EditDataType, EditMetaData, LocalityDetailsType } from '../../../frontend/src/backendTypes'
import { describe, it, before } from 'node:test'
import assert from 'node:assert/strict'
import { EditDataType, EditMetaData, LocalityDetailsType, SpeciesDetailsType } from '../../../frontend/src/backendTypes'
const baseUrl = 'http://localhost:4000'
let token: string | null = null
const send = async (path: string, method: 'GET' | 'POST' | 'PUT' | 'DELETE', body?: object) => {
const send = async <T extends Record<string, unknown>>(
path: string,
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
body?: object
) => {
const headers = new Headers()
headers.append('Content-Type', 'application/json')
if (token) headers.append('authorization', `bearer ${token}`)
const options = method === 'GET' ? {} : { body: JSON.stringify(body), method, headers }
const options = { body: method !== 'GET' ? JSON.stringify(body) : undefined, method, headers }
const result = await fetch(`${baseUrl}/${path}`, options)
const resultBody = (await result.json()) as Record<string, unknown>
return { body: resultBody, status: result.status }
if (!result) return {}
const r = await result.text()
if (!r) return { body: {} as T, status: result.status }
return { body: JSON.parse(r) as T, status: result.status }
}
void describe('Locality editing works', () => {
void it('works', async () => {
const loginResponse = await send('user/login', 'POST', { username: 'testSu', password: 'test' })
if (loginResponse?.body?.token) token = loginResponse.body.token as string
void describe('Locality write works', () => {
before(async () => {
await send('test/create-test-users', 'GET')
})
void it('Edits name, synonyms and locality species correctly', async () => {
const loginResponse = await send<{ token: string }>('user/login', 'POST', { username: 'testSu', password: 'test' })
if (loginResponse?.body?.token) token = loginResponse.body.token
else throw Error('Login unsuccessful')
const locality: EditDataType<LocalityDetailsType> & EditMetaData = {
lid: 20920,
lid: 21050,
loc_name: 'new_test_name',
now_mus: [],
now_ls: [],
now_ls: [
{
rowState: 'new',
species_id: 21052,
lid: 21050,
com_species: { species_id: 21052 } as SpeciesDetailsType,
},
{
rowState: 'removed',
species_id: 85729,
lid: 21050,
com_species: { species_id: 85729 } as SpeciesDetailsType,
},
],
projects: [],
now_plr: [],
now_ss: [],
@@ -40,7 +61,17 @@ void describe('Locality editing works', () => {
references: [],
}
const result = await send('locality', 'PUT', { locality })
assert(result.body.id === 20920, 'Invalid result')
const writeResult = await send<{ id: number }>('locality', 'PUT', { locality })
assert(writeResult.body.id === locality.lid, `Invalid result returned on write: ${writeResult.body.id}`)
const { body: resultLocality } = await send<LocalityDetailsType>(`locality/${locality.lid}`, 'GET')
assert(resultLocality.loc_name === locality.loc_name, 'Name was not changed correctly')
assert(
resultLocality.now_ls.find(ls => ls.species_id === 21052 && ls.lid === 21050),
'Added locality species not found'
)
assert(resultLocality.now_ls.length === 2, `Unexpected now_ls length: ${resultLocality.now_ls.length}`)
})
})
+65
View File
@@ -0,0 +1,65 @@
import 'express-async-errors'
import express from 'express'
import cors from 'cors'
import localityRouter from './routes/locality'
import museumRouter from './routes/museum'
import referenceRouter from './routes/reference'
import sedimentaryStructureRouter from './routes/sedimentaryStructure'
import regionRouter from './routes/region'
import personRouter from './routes/person'
import projectRouter from './routes/project'
import speciesRouter from './routes/species'
import localitySpeciesRouter from './routes/localitySpecies'
import refreshTokenRouter from './routes/refresh'
import timeBoundRouter from './routes/timeBound'
import timeUnitRouter from './routes/timeUnit'
import userRouter from './routes/user'
import emailRouter from './routes/email'
import { responseLogger } from './middlewares/requestLogger'
import compression from 'compression'
import { ENABLE_WRITE, RUNNING_ENV } from './utils/config'
import { tokenExtractor, userExtractor } from './middlewares/authenticator'
import { errorHandler } from './middlewares/errorHandler'
import { requireOneOf } from './middlewares/authorizer'
import { Role } from './../../frontend/src/types'
import { blockWriteRequests } from './middlewares/misc'
import testRouter from './routes/test'
const app = express()
app.use(express.json({ limit: '50mb' }))
app.use(cors())
app.use(compression())
app.use(responseLogger)
if (!ENABLE_WRITE && RUNNING_ENV !== 'dev') {
app.use(blockWriteRequests)
}
app.use(refreshTokenRouter)
app.use(tokenExtractor)
app.use(userExtractor)
app.use('/user', userRouter)
app.use('/locality', localityRouter)
app.use('/locality-species', localitySpeciesRouter)
app.use('/species', speciesRouter)
app.use('/reference', referenceRouter)
app.use('/time-unit', timeUnitRouter)
app.use('/time-bound', requireOneOf([Role.Admin, Role.EditUnrestricted]), timeBoundRouter)
app.use('/region', requireOneOf([Role.Admin]), regionRouter)
app.use('/person', personRouter)
app.use('/project', projectRouter)
app.use('/museum', museumRouter)
app.use('/sedimentary-structure', sedimentaryStructureRouter)
app.use('/email', requireOneOf([Role.Admin]), emailRouter)
if (RUNNING_ENV === 'dev') {
app.use('/test', testRouter)
}
app.use(errorHandler)
export default app
+3 -58
View File
@@ -1,63 +1,8 @@
import 'express-async-errors'
import express from 'express'
import cors from 'cors'
import localityRouter from './routes/locality'
import museumRouter from './routes/museum'
import referenceRouter from './routes/reference'
import sedimentaryStructureRouter from './routes/sedimentaryStructure'
import regionRouter from './routes/region'
import personRouter from './routes/person'
import projectRouter from './routes/project'
import speciesRouter from './routes/species'
import localitySpeciesRouter from './routes/localitySpecies'
import refreshTokenRouter from './routes/refresh'
import timeBoundRouter from './routes/timeBound'
import timeUnitRouter from './routes/timeUnit'
import userRouter from './routes/user'
import emailRouter from './routes/email'
import { responseLogger } from './middlewares/requestLogger'
import compression from 'compression'
import { logger } from './utils/logger'
import { ENABLE_WRITE, PORT, RUNNING_ENV } from './utils/config'
import { tokenExtractor, userExtractor } from './middlewares/authenticator'
import { errorHandler } from './middlewares/errorHandler'
import app from './app'
import { createTestUsers } from './services/user'
import { PORT, RUNNING_ENV } from './utils/config'
import { testDbConnection } from './utils/db'
import { requireOneOf } from './middlewares/authorizer'
import { Role } from './../../frontend/src/types'
import { blockWriteRequests } from './middlewares/misc'
const app = express()
app.use(express.json({ limit: '50mb' }))
app.use(cors())
app.use(compression())
app.use(responseLogger)
if (!ENABLE_WRITE && RUNNING_ENV !== 'dev') {
app.use(blockWriteRequests)
}
app.use(refreshTokenRouter)
app.use(tokenExtractor)
app.use(userExtractor)
app.use('/user', userRouter)
app.use('/locality', localityRouter)
app.use('/locality-species', localitySpeciesRouter)
app.use('/species', speciesRouter)
app.use('/reference', referenceRouter)
app.use('/time-unit', timeUnitRouter)
app.use('/time-bound', requireOneOf([Role.Admin, Role.EditUnrestricted]), timeBoundRouter)
app.use('/region', requireOneOf([Role.Admin]), regionRouter)
app.use('/person', personRouter)
app.use('/project', projectRouter)
app.use('/museum', museumRouter)
app.use('/sedimentary-structure', sedimentaryStructureRouter)
app.use('/email', requireOneOf([Role.Admin]), emailRouter)
app.use(errorHandler)
import { logger } from './utils/logger'
app.listen(PORT, async () => {
logger.info(`Server running on port ${PORT} in "${RUNNING_ENV}"-mode.`)
+10
View File
@@ -0,0 +1,10 @@
import { Router } from 'express'
import { createTestUsers } from '../services/user'
const router = Router()
router.get('/create-test-users', async (_req, res) => {
await createTestUsers()
res.status(200).send()
})
export default router