55
66import { describe , expect , it } from 'vitest'
77
8+ import { FILE_STATUS , SIGN_REQUEST_STATUS } from '../../constants.js'
89import {
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+
1434function 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