Skip to content

Commit 0928daa

Browse files
authored
Merge pull request #559 from nowcommunity/validator-documentation
Validator documentation
2 parents f153212 + 8be4b67 commit 0928daa

3 files changed

Lines changed: 110 additions & 9 deletions

File tree

backend/src/api-tests/reference/create.test.ts

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { beforeEach, beforeAll, afterAll, describe, it, expect } from '@jest/globals'
22
import { ReferenceDetailsType } from '../../../../frontend/src/backendTypes'
33
//import { LogRow } from '../../services/write/writeOperations/types'
4-
import { newReferenceBasis } from './data'
4+
import { newReferenceBasis, emptyReferenceBasis } from './data'
55
import { login, logout, resetDatabase, send, /*testLogRows,*/ resetDatabaseTimeout, noPermError } from '../utils'
66
import { pool } from '../../utils/db'
77
import Prisma from '../../../prisma/generated/now_test_client'
@@ -43,14 +43,38 @@ describe('Creating new reference works', () => {
4343
expect(journal_id).toBeDefined()
4444
})
4545

46-
it.skip('Adding "removed" in rowstate of authors & journal deletes author and clear journal data from reference', async () => {
46+
it('Adding "removed" in rowstate of authors & journal deletes author and clear journal data from reference', async () => {
4747
const { status: getReqStatus } = await send<{ rid: number }>(`reference/`, 'PUT', {
4848
reference: {
4949
...createdRef,
50-
ref_authors: createdRef!.ref_authors.map(ref_author => ({
51-
...ref_author,
52-
rowState: 'removed',
53-
})),
50+
//changing type_id to 2 since journals are mandatory on type 1
51+
ref_type_id: 2,
52+
ref_authors: [
53+
{
54+
rid: undefined,
55+
au_num: 1,
56+
author_surname: 'testiauthor',
57+
author_initials: 'testi-initials',
58+
field_id: 2,
59+
rowState: 'removed',
60+
},
61+
{
62+
rid: undefined,
63+
au_num: 2,
64+
author_surname: 'testiauthor2',
65+
author_initials: 'testi-initials2',
66+
field_id: 2,
67+
rowState: 'removed',
68+
},
69+
{
70+
rid: undefined,
71+
au_num: 1,
72+
author_surname: 'testiauthor3',
73+
author_initials: 'testi-initials3',
74+
field_id: 12,
75+
rowState: 'new',
76+
},
77+
],
5478
ref_journal: {
5579
...createdRef!.ref_journal,
5680
rowState: 'removed',
@@ -62,7 +86,7 @@ describe('Creating new reference works', () => {
6286
const updatedRef = resultBody
6387
const { ref_authors, ref_journal, journal_id } = updatedRef
6488

65-
expect(ref_authors.length).toEqual(0) //authors have been removed from the reference
89+
expect(ref_authors.length).toEqual(1) //authors have been removed from the reference
6690
expect(journal_id).toBeNull() //journal id set to null
6791
expect(ref_journal).toBeNull() //no journal fetched
6892

@@ -74,13 +98,14 @@ describe('Creating new reference works', () => {
7498

7599
const { body, status: getReqStatus3 } = await send(`reference/authors/${createdRef?.rid}`, 'GET')
76100
expect(getReqStatus3).toEqual(200)
77-
expect(body.length).toEqual(0) // Authors should be deleted from db
101+
expect(body.length).toEqual(1) // Authors should be deleted from db
78102
})
79103

80-
it.skip('Removing author / journal data from reference should clear the data from db', async () => {
104+
it('Removing author / journal data from reference should clear the data from db', async () => {
81105
const { status: getReqStatus } = await send<{ rid: number }>(`reference/`, 'PUT', {
82106
reference: {
83107
...createdRef,
108+
ref_type_id: 2,
84109
ref_authors: [createdRef!.ref_authors[0]],
85110
ref_journal: null,
86111
},
@@ -107,6 +132,47 @@ describe('Creating new reference works', () => {
107132
expect(body.length).toEqual(1) //Unused authors should be deleted from db
108133
})
109134

135+
it('All validators fail with empty reference', async () => {
136+
const { body: resultBody, status: getReqStatus } = await send('reference/', 'PUT', {
137+
reference: { ...emptyReferenceBasis },
138+
})
139+
expect(getReqStatus).toEqual(403)
140+
expect(resultBody.length).toEqual(8) //There should be 8 validation errors
141+
})
142+
143+
it('All validators pass with correct data', async () => {
144+
const { body: resultBody, status: getReqStatus } = await send<{ rid: number }>('reference/', 'PUT', {
145+
reference: {
146+
...emptyReferenceBasis,
147+
title_primary: 'title_primary',
148+
date_primary: 2020,
149+
title_secondary: 'title_secondary',
150+
title_series: 'title_series',
151+
gen_notes: 'gen_notes',
152+
exact_date: '2024-11-18',
153+
ref_authors: [
154+
{
155+
rid: undefined,
156+
au_num: 1,
157+
author_surname: 'testiauthor',
158+
author_initials: 'testi-initials',
159+
field_id: 2,
160+
rowState: 'new',
161+
},
162+
],
163+
ref_journal: {
164+
journal_title: 'testijournal',
165+
short_title: 'shorttitle',
166+
alt_title: 'alttitle',
167+
ISSN: 'issn',
168+
rowState: 'new',
169+
},
170+
},
171+
})
172+
expect(getReqStatus).toEqual(200)
173+
expect(typeof resultBody.rid).toEqual('number')
174+
})
175+
110176
it('Creation fails without permissions', async () => {
111177
logout()
112178
const { body: resultBodyNoPerm, status: resultStatusNoPerm } = await send('reference/', 'PUT', {

backend/src/api-tests/reference/data.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,3 +79,31 @@ export const newReferenceBasis: EditDataType<ReferenceDetailsType> = {
7979
rowState: 'new',
8080
},
8181
}
82+
83+
export const emptyReferenceBasis: EditDataType<ReferenceDetailsType> = {
84+
ref_type_id: 14,
85+
title_primary: null,
86+
date_primary: null,
87+
volume: null,
88+
issue: null,
89+
start_page: null,
90+
end_page: null,
91+
publisher: null,
92+
pub_place: null,
93+
title_secondary: null,
94+
date_secondary: null,
95+
title_series: null,
96+
issn_isbn: null,
97+
ref_abstract: null,
98+
web_url: null,
99+
misc_1: null,
100+
misc_2: null,
101+
gen_notes: null,
102+
printed_language: null,
103+
exact_date: null,
104+
used_morph: null,
105+
used_now: null,
106+
used_gene: null,
107+
ref_authors: [],
108+
ref_journal: {},
109+
}

frontend/src/validators/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ Validators are created as objects with the following fields. Only `name` is requ
99
- `asString` Either "true" to just require a string, or a function which can do more complex validation for the string value
1010
- `asNumber` Same as asString but for numbers: Set to `true` to require a valid number, or set the function to both require a valid number (checked automatically if function is supplied) and apply more custom validations in the function body
1111
- `miscCheck` is used to simply run any check you want. Currently it's used to e.g. validate the low_bound and up_bound fields of a time unit in the timeUnit validator.
12+
- `miscArray` is used to run any check you want on arrays. Used for example in reference validators to check all authors are in correct format, author name is set etc.
13+
- `condition` used to set some condition for when a validator is run. Happens before the check for if a value is required. Used for example in references to only run validators for for certain fields since they are only mandatory on some reference types, not all. Although using 'required' instead may now be possible after changes to it.
14+
- `useEditData` A boolean for if you want to pass editData to the different checks of a validator instead of just the data of the field being validated. Used in references since some validators need to pass editData to a common function. Again, using 'required' instead may be possible after its changes
1215

1316
Example:
1417

@@ -27,6 +30,10 @@ To know if user is creating a new entry or editing existing one, check if the id
2730

2831
### Note!
2932

33+
At the moment you can only create validators for existing and defined fields of editData. This is limiting in some cases and creating validators that check multiple fields (as is necessary in references) requires some trickery. Similarly you cannot create multiple validators for the same field.
34+
35+
Validators are only run if the data is defined! If the value of a key of editData == undefined, the data is not checked even if it is set as required in the validator. Similarly if a key does not exist in editData, it will not be checked even if the data would be required. This is also the case in backend. This may lead to mistakes getting into the db if some data must be set but it is not defined at all.
36+
3037
The files in this folder, and also backendTypes.d.ts, cannot
3138

3239
- Use path aliases in imports

0 commit comments

Comments
 (0)