mirror of
https://github.com/nowcommunity/nowdatabase.git
synced 2026-10-12 19:13:52 +03:00
update types for occurrence backend routes, and update more unit tests
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { Request, Response } from 'express'
|
||||
import { EditDataType, EditMetaData, OccurrenceDetailsType } from '../../../frontend/src/shared/types'
|
||||
import { getOccurrenceByCompositeKey, parseOccurrenceRouteParams } from '../services/occurrenceService'
|
||||
import { fixBigInt } from '../utils/common'
|
||||
import { EditMetaData, EditableOccurrenceData } from '../../../frontend/src/shared/types'
|
||||
import { updateOccurrenceByCompositeKey } from '../services/write/occurrence'
|
||||
import { fixBigInt } from '../utils/common'
|
||||
|
||||
type OccurrenceRouteParams = {
|
||||
lid: string
|
||||
@@ -21,12 +21,12 @@ export const getOccurrenceDetail = async (req: Request<OccurrenceRouteParams>, r
|
||||
}
|
||||
|
||||
export const updateOccurrenceDetail = async (
|
||||
req: Request<OccurrenceRouteParams, object, { occurrence?: EditableOccurrenceData & EditMetaData }>,
|
||||
req: Request<OccurrenceRouteParams, object, { occurrence: EditDataType<OccurrenceDetailsType> & EditMetaData }>,
|
||||
res: Response
|
||||
) => {
|
||||
const { lid, speciesId } = parseOccurrenceRouteParams(req.params.lid, req.params.speciesId)
|
||||
|
||||
const occurrencePayload: EditableOccurrenceData & EditMetaData = req.body.occurrence ?? {}
|
||||
const occurrencePayload = req.body.occurrence ?? {}
|
||||
const updatedOccurrence = await updateOccurrenceByCompositeKey(lid, speciesId, occurrencePayload, req.user)
|
||||
|
||||
if (!updatedOccurrence) {
|
||||
|
||||
@@ -1,9 +1,16 @@
|
||||
import { AnyReference, EditableOccurrenceData, Role, User } from '../../../frontend/src/shared/types'
|
||||
import {
|
||||
AnyReference,
|
||||
EditableOccurrenceData,
|
||||
EditDataType,
|
||||
OccurrenceDetailsType,
|
||||
Role,
|
||||
User,
|
||||
} from '../../../frontend/src/shared/types'
|
||||
import { validateOccurrence } from '../../../frontend/src/shared/validators/occurrence'
|
||||
import { AccessError } from '../middlewares/authorizer'
|
||||
import { logDb, nowDb } from '../utils/db'
|
||||
import { buildPersonLookupByInitials, getPersonDisplayName, getPersonFromLookup } from './utils/person'
|
||||
import { generateOccurrenceDetailSql } from './queries/crossSearchQuery'
|
||||
import { buildPersonLookupByInitials, getPersonDisplayName, getPersonFromLookup } from './utils/person'
|
||||
import { addNullExactDateToReferenceJoins, referenceWithoutExactDateSelect } from './utils/referenceDate'
|
||||
|
||||
const getAllowedLocalities = async (user: User) => {
|
||||
@@ -47,7 +54,7 @@ export const ensureOccurrenceEditAccess = async (lid: number, user: User) => {
|
||||
throw new AccessError()
|
||||
}
|
||||
|
||||
export const validateOccurrencePayload = (payload: EditableOccurrenceData) => {
|
||||
export const validateOccurrencePayload = (payload: EditDataType<OccurrenceDetailsType>) => {
|
||||
const validationErrors = (Object.keys(payload) as Array<keyof EditableOccurrenceData>)
|
||||
.map(fieldName => validateOccurrence(payload, fieldName))
|
||||
.filter(validation => !!validation.error)
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
EditDataType,
|
||||
EditMetaData,
|
||||
EditableOccurrenceData,
|
||||
OccurrenceDetailsType,
|
||||
OccurrenceEditableField,
|
||||
Reference,
|
||||
Role,
|
||||
@@ -93,7 +95,7 @@ const buildOccurrenceUpdateData = (
|
||||
export const updateOccurrenceByCompositeKey = async (
|
||||
lid: number,
|
||||
speciesId: number,
|
||||
editedOccurrence: EditableOccurrenceData & EditMetaData,
|
||||
editedOccurrence: EditDataType<OccurrenceDetailsType> & EditMetaData,
|
||||
user?: User
|
||||
) => {
|
||||
if (!user || ![Role.Admin, Role.EditUnrestricted, Role.EditRestricted].includes(user.role)) {
|
||||
|
||||
@@ -1,17 +1,23 @@
|
||||
import { describe, expect, it } from '@jest/globals'
|
||||
import { validateOccurrence, occurrenceDropdownValues } from '../../../../frontend/src/shared/validators/occurrence'
|
||||
import { EditableOccurrenceData } from '../../../../frontend/src/shared/types'
|
||||
import { EditableOccurrenceData, EditDataType, OccurrenceDetailsType } from '../../../../frontend/src/shared/types'
|
||||
|
||||
const createOccurrencePayload = (values: EditableOccurrenceData) => {
|
||||
return {
|
||||
...values,
|
||||
} as EditDataType<OccurrenceDetailsType>
|
||||
}
|
||||
|
||||
describe('validateOccurrence', () => {
|
||||
it('accepts valid dropdown values', () => {
|
||||
const payload: EditableOccurrenceData = {
|
||||
const payload = createOccurrencePayload({
|
||||
id_status: occurrenceDropdownValues.idStatus[0],
|
||||
qua: occurrenceDropdownValues.quantity[0],
|
||||
mesowear: occurrenceDropdownValues.mesowear[0],
|
||||
microwear: occurrenceDropdownValues.microwear[0],
|
||||
}
|
||||
})
|
||||
|
||||
const errors = (Object.keys(payload) as Array<keyof EditableOccurrenceData>)
|
||||
const errors = (Object.keys(payload) as Array<keyof OccurrenceDetailsType>)
|
||||
.map(field => validateOccurrence(payload, field))
|
||||
.filter(validation => validation.error)
|
||||
|
||||
@@ -19,12 +25,12 @@ describe('validateOccurrence', () => {
|
||||
})
|
||||
|
||||
it('returns errors for invalid dropdown values', () => {
|
||||
const payload: EditableOccurrenceData = {
|
||||
const payload = createOccurrencePayload({
|
||||
id_status: 'invalid',
|
||||
qua: 'x',
|
||||
mesowear: 'foo',
|
||||
microwear: 'bar',
|
||||
}
|
||||
})
|
||||
|
||||
const errors = (Object.keys(payload) as Array<keyof EditableOccurrenceData>)
|
||||
.map(field => validateOccurrence(payload, field))
|
||||
@@ -35,11 +41,11 @@ describe('validateOccurrence', () => {
|
||||
})
|
||||
|
||||
it('enforces mesowear scale consistency', () => {
|
||||
const payload: EditableOccurrenceData = {
|
||||
const payload = createOccurrencePayload({
|
||||
mw_scale_min: 5,
|
||||
mw_scale_max: 3,
|
||||
mw_value: 1,
|
||||
}
|
||||
})
|
||||
|
||||
expect(validateOccurrence(payload, 'mw_scale_min').error).toBe(
|
||||
'Scale Minimum cannot be greater than Scale Maximum.'
|
||||
@@ -51,12 +57,12 @@ describe('validateOccurrence', () => {
|
||||
})
|
||||
|
||||
it('enforces isotope min/max ordering', () => {
|
||||
const payload: EditableOccurrenceData = {
|
||||
const payload = createOccurrencePayload({
|
||||
dc13_min: 5,
|
||||
dc13_max: 4,
|
||||
do18_min: 9,
|
||||
do18_max: 8,
|
||||
}
|
||||
})
|
||||
|
||||
expect(validateOccurrence(payload, 'dc13_min').error).toBe('δ13C min cannot be greater than δ13C max.')
|
||||
expect(validateOccurrence(payload, 'dc13_max').error).toBe('δ13C min cannot be greater than δ13C max.')
|
||||
@@ -65,13 +71,13 @@ describe('validateOccurrence', () => {
|
||||
})
|
||||
|
||||
it('requires positive decimals for requested fields', () => {
|
||||
const payload: EditableOccurrenceData = {
|
||||
const payload = createOccurrencePayload({
|
||||
mw_value: -1,
|
||||
dc13_mean: -0.1,
|
||||
dc13_stdev: 0,
|
||||
do18_mean: -2.5,
|
||||
do18_stdev: 0,
|
||||
}
|
||||
})
|
||||
|
||||
expect(validateOccurrence(payload, 'mw_value').error).toBe('MW value must be a positive decimal number.')
|
||||
expect(validateOccurrence(payload, 'dc13_mean').error).toBe('δ13C Mean must be a positive decimal number.')
|
||||
|
||||
@@ -44,6 +44,8 @@ describe('TableToolBar export menu', () => {
|
||||
<TableToolBar
|
||||
table={{} as MRT_TableInstance<MRT_RowData>}
|
||||
tableName="Localities"
|
||||
showContactButton={false}
|
||||
showNewButton={false}
|
||||
kmlExport={kmlExport}
|
||||
svgExport={svgExport}
|
||||
/>
|
||||
|
||||
Reference in New Issue
Block a user