Skip to content

Commit 6c0d419

Browse files
test(validation): expand business rule coverage with data providers
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com>
1 parent 9462839 commit 6c0d419

1 file changed

Lines changed: 146 additions & 14 deletions

File tree

src/tests/services/validationDocument.spec.ts

Lines changed: 146 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,32 @@
55

66
import { describe, expect, it } from 'vitest'
77

8+
import { FILE_STATUS, SIGN_REQUEST_STATUS } from '../../constants.js'
89
import {
10+
MODIFICATION_ALLOWED,
11+
MODIFICATION_UNMODIFIED,
12+
MODIFICATION_VIOLATION,
913
isLoadedValidationEnvelopeDocument,
1014
isLoadedValidationFileDocument,
1115
toValidationDocument,
1216
} from '../../services/validationDocument'
1317

18+
function createSigner(patch: Record<string, unknown> = {}): Record<string, unknown> {
19+
return {
20+
signRequestId: 1,
21+
displayName: 'Signer',
22+
email: 'signer@example.com',
23+
signed: null,
24+
status: SIGN_REQUEST_STATUS.ABLE_TO_SIGN,
25+
statusText: 'Pending',
26+
description: null,
27+
request_sign_date: '2026-01-01T00:00:00Z',
28+
me: false,
29+
visibleElements: [],
30+
...patch,
31+
}
32+
}
33+
1434
function createValidationPayload(patch: Record<string, unknown> = {}): Record<string, unknown> {
1535
return {
1636
id: 100,
@@ -26,7 +46,7 @@ function createValidationPayload(patch: Record<string, unknown> = {}): Record<st
2646
id: 100,
2747
uuid: '550e8400-e29b-41d4-a716-446655440000',
2848
name: 'contract.pdf',
29-
status: 1,
49+
status: FILE_STATUS.ABLE_TO_SIGN,
3050
statusText: 'Pending',
3151
nodeId: 100,
3252
totalPages: 1,
@@ -41,7 +61,7 @@ function createValidationPayload(patch: Record<string, unknown> = {}): Record<st
4161
pdfVersion: '1.7',
4262
created_at: '2026-01-01T00:00:00Z',
4363
requested_by: { userId: 'creator-user', displayName: 'Creator User' },
44-
status: 1,
64+
status: FILE_STATUS.ABLE_TO_SIGN,
4565
signers: [],
4666
...patch,
4767
}
@@ -88,23 +108,133 @@ describe('validationDocument', () => {
88108

89109
it('rejects payload with invalid signer status', () => {
90110
const normalized = toValidationDocument(createValidationPayload({
91-
signers: [{
92-
signRequestId: 1,
93-
displayName: 'Signer',
94-
email: 'signer@example.com',
95-
signed: null,
96-
status: 99,
97-
statusText: 'Invalid',
98-
description: null,
99-
request_sign_date: '2026-01-01T00:00:00Z',
100-
me: false,
101-
visibleElements: [],
102-
}],
111+
signers: [createSigner({ status: 99, statusText: 'Invalid' })],
103112
}))
104113

105114
expect(normalized).toBeNull()
106115
})
107116

117+
it.each([
118+
['status null', { status: null }],
119+
['status outside allowed values', { status: 99 }],
120+
['invalid nodeType', { nodeType: 'folder' }],
121+
['invalid requested_by payload', { requested_by: { displayName: 'Creator User' } }],
122+
['files is not an array', { files: {} }],
123+
])('rejects payload with invalid top-level contract: %s', (_, patch) => {
124+
expect(toValidationDocument(createValidationPayload(patch))).toBeNull()
125+
})
126+
127+
it.each([
128+
['metadata explicitly undefined', { metadata: undefined }],
129+
['settings explicitly undefined', { settings: undefined }],
130+
['signers explicitly undefined', { signers: undefined }],
131+
])('rejects payload when optional field is present with invalid value: %s', (_, patch) => {
132+
expect(toValidationDocument(createValidationPayload(patch))).toBeNull()
133+
})
134+
135+
it('accepts metadata with optional extension fields when valid', () => {
136+
const normalized = toValidationDocument(createValidationPayload({
137+
metadata: {
138+
extension: 'pdf',
139+
p: 7,
140+
d: [{ w: 100, h: 200 }],
141+
original_file_deleted: false,
142+
pdfVersion: '1.7',
143+
status_changed_at: '2026-02-02T10:10:10Z',
144+
},
145+
}))
146+
147+
expect(normalized).not.toBeNull()
148+
expect(normalized?.metadata).toEqual({
149+
extension: 'pdf',
150+
p: 7,
151+
d: [{ w: 100, h: 200 }],
152+
original_file_deleted: false,
153+
pdfVersion: '1.7',
154+
status_changed_at: '2026-02-02T10:10:10Z',
155+
})
156+
})
157+
158+
it('rejects payload with malformed metadata dimensions', () => {
159+
expect(toValidationDocument(createValidationPayload({
160+
metadata: {
161+
extension: 'pdf',
162+
p: 1,
163+
d: [{ w: '100', h: 200 }],
164+
},
165+
}))).toBeNull()
166+
})
167+
168+
it('rejects payload with malformed child file metadata', () => {
169+
expect(toValidationDocument(createValidationPayload({
170+
files: [{
171+
id: 100,
172+
uuid: '550e8400-e29b-41d4-a716-446655440000',
173+
name: 'contract.pdf',
174+
status: FILE_STATUS.ABLE_TO_SIGN,
175+
statusText: 'Pending',
176+
nodeId: 100,
177+
totalPages: 1,
178+
size: 10,
179+
pdfVersion: '1.7',
180+
signers: [],
181+
file: '/apps/libresign/p/pdf/550e8400-e29b-41d4-a716-446655440000',
182+
metadata: { extension: 'pdf', p: '1' },
183+
}],
184+
}))).toBeNull()
185+
})
186+
187+
it('accepts settings when optional isApprover is boolean', () => {
188+
const normalized = toValidationDocument(createValidationPayload({
189+
settings: {
190+
canSign: true,
191+
canRequestSign: false,
192+
phoneNumber: '5551',
193+
hasSignatureFile: true,
194+
needIdentificationDocuments: false,
195+
identificationDocumentsWaitingApproval: false,
196+
isApprover: true,
197+
},
198+
}))
199+
200+
expect(normalized).not.toBeNull()
201+
expect(normalized?.settings).toEqual(expect.objectContaining({ isApprover: true }))
202+
})
203+
204+
it('rejects settings when isApprover has invalid type', () => {
205+
expect(toValidationDocument(createValidationPayload({
206+
settings: {
207+
canSign: true,
208+
canRequestSign: false,
209+
phoneNumber: '5551',
210+
hasSignatureFile: true,
211+
needIdentificationDocuments: false,
212+
identificationDocumentsWaitingApproval: false,
213+
isApprover: 'yes',
214+
},
215+
}))).toBeNull()
216+
})
217+
218+
it.each([
219+
MODIFICATION_UNMODIFIED,
220+
MODIFICATION_ALLOWED,
221+
MODIFICATION_VIOLATION,
222+
])('accepts signer modification validation with allowed status %s', (status) => {
223+
const normalized = toValidationDocument(createValidationPayload({
224+
signers: [createSigner({
225+
modification_validation: { status, valid: status !== MODIFICATION_VIOLATION },
226+
})],
227+
}))
228+
229+
expect(normalized).not.toBeNull()
230+
})
231+
232+
it('rejects signer modification validation with unknown status', () => {
233+
expect(toValidationDocument(createValidationPayload({
234+
signers: [createSigner({ modification_validation: { status: 42, valid: false } })],
235+
}))).toBeNull()
236+
})
237+
108238
it('narrows loaded document types by nodeType', () => {
109239
const envelope = toValidationDocument(createValidationPayload({ nodeType: 'envelope' }))
110240
const file = toValidationDocument(createValidationPayload({ nodeType: 'file' }))
@@ -113,5 +243,7 @@ describe('validationDocument', () => {
113243
expect(isLoadedValidationFileDocument(envelope)).toBe(false)
114244
expect(isLoadedValidationFileDocument(file)).toBe(true)
115245
expect(isLoadedValidationEnvelopeDocument(file)).toBe(false)
246+
expect(isLoadedValidationEnvelopeDocument(null)).toBe(false)
247+
expect(isLoadedValidationFileDocument(null)).toBe(false)
116248
})
117249
})

0 commit comments

Comments
 (0)