@@ -152,9 +152,17 @@ vi.mock('../../utils/fileStatus.js', () => ({
152152describe ( 'Validation.vue - Business Logic' , ( ) => {
153153 let wrapper ! : ReturnType < typeof shallowMount >
154154 let mockAddConfetti : ReturnType < typeof vi . fn >
155+ const setVmState = async ( patch : Record < string , unknown > ) => {
156+ Object . entries ( patch ) . forEach ( ( [ key , value ] ) => {
157+ ; ( wrapper . vm as Record < string , unknown > ) [ key ] = value
158+ } )
159+ await wrapper . vm . $nextTick ( )
160+ }
155161
156162 beforeEach ( ( ) => {
163+ history . replaceState ( { } , '' )
157164 mockAddConfetti = vi . fn ( )
165+ vi . mocked ( axios . get ) . mockResolvedValue ( { data : { ocs : { data : { } } } } )
158166 // Must use `function` syntax so vitest accepts it as a valid constructor mock
159167 vi . mocked ( JSConfetti ) . mockImplementation ( function ( ) {
160168 return { addConfetti : mockAddConfetti }
@@ -182,91 +190,93 @@ describe('Validation.vue - Business Logic', () => {
182190 } )
183191
184192 afterEach ( ( ) => {
193+ history . replaceState ( { } , '' )
194+ vi . mocked ( axios . get ) . mockReset ( )
185195 wrapper . unmount ( )
186196 } )
187197
188198 describe ( 'canValidate computed property' , ( ) => {
189199 it ( 'returns false when uuidToValidate is empty' , ( ) => {
190- wrapper . setData ( { uuidToValidate : '' } )
200+ wrapper . vm . uuidToValidate = ''
191201 expect ( wrapper . vm . canValidate ) . toBe ( false )
192202 } )
193203
194204 it ( 'accepts numeric IDs' , ( ) => {
195- wrapper . setData ( { uuidToValidate : '12345' } )
205+ wrapper . vm . uuidToValidate = '12345'
196206 expect ( wrapper . vm . canValidate ) . toBe ( true )
197207 } )
198208
199209 it ( 'accepts valid UUID format' , ( ) => {
200- wrapper . setData ( { uuidToValidate : '550e8400-e29b-41d4-a716-446655440000' } )
210+ wrapper . vm . uuidToValidate = '550e8400-e29b-41d4-a716-446655440000'
201211 expect ( wrapper . vm . canValidate ) . toBe ( true )
202212 } )
203213
204214 it ( 'rejects invalid UUID format' , ( ) => {
205- wrapper . setData ( { uuidToValidate : 'invalid-uuid-format' } )
215+ wrapper . vm . uuidToValidate = 'invalid-uuid-format'
206216 expect ( wrapper . vm . canValidate ) . toBe ( false )
207217 } )
208218
209219 it ( 'rejects UUID with wrong version (not v4)' , ( ) => {
210- wrapper . setData ( { uuidToValidate : '550e8400-e29b-31d4-a716-446655440000' } )
220+ wrapper . vm . uuidToValidate = '550e8400-e29b-31d4-a716-446655440000'
211221 expect ( wrapper . vm . canValidate ) . toBe ( false )
212222 } )
213223
214224 it ( 'rejects UUID with wrong variant' , ( ) => {
215- wrapper . setData ( { uuidToValidate : '550e8400-e29b-41d4-1716-446655440000' } )
225+ wrapper . vm . uuidToValidate = '550e8400-e29b-41d4-1716-446655440000'
216226 expect ( wrapper . vm . canValidate ) . toBe ( false )
217227 } )
218228 } )
219229
220230 describe ( 'helperTextValidation computed property' , ( ) => {
221231 it ( 'shows error message for invalid UUID' , ( ) => {
222- wrapper . setData ( { uuidToValidate : 'invalid' } )
232+ wrapper . vm . uuidToValidate = 'invalid'
223233 expect ( wrapper . vm . helperTextValidation ) . toBe ( 'Invalid UUID' )
224234 } )
225235
226236 it ( 'returns empty string for valid UUID' , ( ) => {
227- wrapper . setData ( { uuidToValidate : '550e8400-e29b-41d4-a716-446655440000' } )
237+ wrapper . vm . uuidToValidate = '550e8400-e29b-41d4-a716-446655440000'
228238 expect ( wrapper . vm . helperTextValidation ) . toBe ( '' )
229239 } )
230240
231241 it ( 'returns empty string when uuidToValidate is empty' , ( ) => {
232- wrapper . setData ( { uuidToValidate : '' } )
242+ wrapper . vm . uuidToValidate = ''
233243 expect ( wrapper . vm . helperTextValidation ) . toBe ( '' )
234244 } )
235245 } )
236246
237247 describe ( 'isEnvelope computed property' , ( ) => {
238248 it ( 'returns true when nodeType is envelope' , ( ) => {
239- wrapper . setData ( {
249+ wrapper . vm . document = {
240250 document : { nodeType : 'envelope' } ,
241- } )
251+ } . document
242252 expect ( wrapper . vm . isEnvelope ) . toBe ( true )
243253 } )
244254
245255 it ( 'returns true when document has files array' , ( ) => {
246- wrapper . setData ( {
256+ wrapper . vm . document = {
247257 document : { files : [ { id : 1 } ] } ,
248- } )
258+ } . document
249259 expect ( wrapper . vm . isEnvelope ) . toBe ( true )
250260 } )
251261
252262 it ( 'returns false when files array is empty' , ( ) => {
253- wrapper . setData ( {
263+ wrapper . vm . document = {
254264 document : { files : [ ] } ,
255- } )
265+ } . document
256266 expect ( wrapper . vm . isEnvelope ) . toBe ( false )
257267 } )
258268
259269 it ( 'returns false for regular document' , ( ) => {
260- wrapper . setData ( {
270+ wrapper . vm . document = {
261271 document : { nodeType : 'file' } ,
262- } )
272+ } . document
263273 expect ( wrapper . vm . isEnvelope ) . toBe ( false )
264274 } )
265275 } )
266276
267277 describe ( 'async signing rendering' , ( ) => {
268278 it ( 'does not render Promise text in async signing mode' , async ( ) => {
269- await wrapper . setData ( {
279+ await setVmState ( {
270280 isAsyncSigning : true ,
271281 } )
272282
@@ -528,7 +538,7 @@ describe('Validation.vue - Business Logic', () => {
528538
529539 it ( 'falls back to shouldFireAsyncConfetti when history.state has no isAfterSigned' , async ( ) => {
530540 history . pushState ( { } , '' )
531- await wrapper . setData ( { shouldFireAsyncConfetti : true } )
541+ await setVmState ( { shouldFireAsyncConfetti : true } )
532542 expect ( wrapper . vm . isAfterSigned ) . toBe ( true )
533543 } )
534544
@@ -595,21 +605,19 @@ describe('Validation.vue - Business Logic', () => {
595605 const SIGNED_STATUS = 3
596606
597607 it ( 'fires confetti when document is signed and isAfterSigned returns true' , ( ) => {
598- // Spy on the computed getter to simulate the route-param path
599- // (Vue 3 mocked $route.params lacks reactivity in test env — covered separately)
600- vi . spyOn ( wrapper . vm , 'isAfterSigned' , 'get' ) . mockReturnValue ( true )
608+ history . pushState ( { isAfterSigned : true } , '' )
601609 wrapper . vm . handleValidationSuccess ( { status : SIGNED_STATUS , signers : [ ] } )
602610 expect ( mockAddConfetti ) . toHaveBeenCalledOnce ( )
603611 } )
604612
605613 it ( 'fires confetti when document is signed and shouldFireAsyncConfetti is true' , async ( ) => {
606- await wrapper . setData ( { shouldFireAsyncConfetti : true } )
614+ await setVmState ( { shouldFireAsyncConfetti : true } )
607615 wrapper . vm . handleValidationSuccess ( { status : SIGNED_STATUS , signers : [ ] } )
608616 expect ( mockAddConfetti ) . toHaveBeenCalledOnce ( )
609617 } )
610618
611619 it ( 'fires confetti when all files in envelope are signed and shouldFireAsyncConfetti is true' , async ( ) => {
612- await wrapper . setData ( { shouldFireAsyncConfetti : true } )
620+ await setVmState ( { shouldFireAsyncConfetti : true } )
613621 wrapper . vm . handleValidationSuccess ( {
614622 status : 0 ,
615623 files : [
@@ -622,7 +630,7 @@ describe('Validation.vue - Business Logic', () => {
622630 } )
623631
624632 it ( 'fires confetti when current signer is signed and shouldFireAsyncConfetti is true' , async ( ) => {
625- await wrapper . setData ( { shouldFireAsyncConfetti : true } )
633+ await setVmState ( { shouldFireAsyncConfetti : true } )
626634 // SIGN_REQUEST_STATUS.SIGNED = 2
627635 wrapper . vm . handleValidationSuccess ( {
628636 status : 0 ,
@@ -649,20 +657,20 @@ describe('Validation.vue - Business Logic', () => {
649657 } )
650658
651659 it ( 'resets shouldFireAsyncConfetti to false after firing confetti' , async ( ) => {
652- await wrapper . setData ( { shouldFireAsyncConfetti : true } )
660+ await setVmState ( { shouldFireAsyncConfetti : true } )
653661 wrapper . vm . handleValidationSuccess ( { status : SIGNED_STATUS , signers : [ ] } )
654662 expect ( wrapper . vm . shouldFireAsyncConfetti ) . toBe ( false )
655663 } )
656664
657665 it ( 'does not reset shouldFireAsyncConfetti when confetti is not fired' , async ( ) => {
658- await wrapper . setData ( { shouldFireAsyncConfetti : true } )
666+ await setVmState ( { shouldFireAsyncConfetti : true } )
659667 // document not signed → confetti won't fire
660668 wrapper . vm . handleValidationSuccess ( { status : 1 , signers : [ ] } )
661669 expect ( wrapper . vm . shouldFireAsyncConfetti ) . toBe ( true )
662670 } )
663671
664672 it ( 'does not fire confetti when isActiveView is false' , async ( ) => {
665- await wrapper . setData ( { shouldFireAsyncConfetti : true , isActiveView : false } )
673+ await setVmState ( { shouldFireAsyncConfetti : true , isActiveView : false } )
666674 wrapper . vm . handleValidationSuccess ( { status : SIGNED_STATUS , signers : [ ] } )
667675 expect ( mockAddConfetti ) . not . toHaveBeenCalled ( )
668676 } )
@@ -675,7 +683,7 @@ describe('Validation.vue - Business Logic', () => {
675683 } ,
676684 } ,
677685 } as ReturnType < typeof getCapabilities > )
678- vi . spyOn ( wrapper . vm , ' isAfterSigned' , 'get' ) . mockReturnValue ( true )
686+ history . pushState ( { isAfterSigned : true } , '' )
679687 wrapper . vm . handleValidationSuccess ( { status : SIGNED_STATUS , signers : [ ] } )
680688 expect ( mockAddConfetti ) . not . toHaveBeenCalled ( )
681689 } )
@@ -688,7 +696,7 @@ describe('Validation.vue - Business Logic', () => {
688696 const SIGNER_SIGNED_STATUS = 2
689697
690698 it ( 'sets isAsyncSigning to false when called' , async ( ) => {
691- await wrapper . setData ( { isAsyncSigning : true } )
699+ await setVmState ( { isAsyncSigning : true } )
692700 vi . spyOn ( wrapper . vm , 'refreshAfterAsyncSigning' ) . mockResolvedValue ( undefined )
693701 wrapper . vm . handleSigningComplete ( null )
694702 expect ( wrapper . vm . isAsyncSigning ) . toBe ( false )
@@ -701,14 +709,15 @@ describe('Validation.vue - Business Logic', () => {
701709 } )
702710
703711 it ( 'does nothing when isActiveView is false' , async ( ) => {
704- await wrapper . setData ( { isAsyncSigning : true , isActiveView : false } )
712+ await setVmState ( { isAsyncSigning : true , isActiveView : false } )
705713 wrapper . vm . handleSigningComplete ( null )
706714 expect ( wrapper . vm . isAsyncSigning ) . toBe ( true )
707715 expect ( wrapper . vm . shouldFireAsyncConfetti ) . toBe ( false )
708716 } )
709717
710718 describe ( 'RULE: when a file is returned directly by SigningProgress' , ( ) => {
711719 it ( 'fires confetti when the file has signed status' , ( ) => {
720+ history . pushState ( { isAfterSigned : true } , '' )
712721 const signedFile = { status : SIGNED_STATUS , signers : [ ] }
713722 wrapper . vm . handleSigningComplete ( signedFile )
714723 expect ( mockAddConfetti ) . toHaveBeenCalledOnce ( )
@@ -734,12 +743,9 @@ describe('Validation.vue - Business Logic', () => {
734743
735744 describe ( 'RULE: when SigningProgress emits completed without a file (async polling path)' , ( ) => {
736745 it ( 'fires confetti after polling returns a signed document' , async ( ) => {
737- await wrapper . setData ( { uuidToValidate : '550e8400-e29b-41d4-a716-446655440000' } )
738-
739- // Simulate the validate call returning a signed document via handleValidationSuccess
740- vi . spyOn ( wrapper . vm , 'validate' ) . mockImplementation ( async ( ) => {
741- wrapper . vm . handleValidationSuccess ( { status : SIGNED_STATUS , signers : [ ] } )
742- } )
746+ await setVmState ( { uuidToValidate : '550e8400-e29b-41d4-a716-446655440000' } )
747+ history . pushState ( { isAfterSigned : true } , '' )
748+ vi . mocked ( axios . get ) . mockResolvedValueOnce ( { data : { ocs : { data : { status : SIGNED_STATUS , signers : [ ] } } } } )
743749
744750 wrapper . vm . handleSigningComplete ( null )
745751
@@ -750,13 +756,17 @@ describe('Validation.vue - Business Logic', () => {
750756 } )
751757
752758 it ( 'fires confetti after polling finds that the current signer is signed' , async ( ) => {
753- await wrapper . setData ( { uuidToValidate : '550e8400-e29b-41d4-a716-446655440000' } )
754-
755- vi . spyOn ( wrapper . vm , 'validate' ) . mockImplementation ( async ( ) => {
756- wrapper . vm . handleValidationSuccess ( {
757- status : 1 ,
758- signers : [ { me : true , status : SIGNER_SIGNED_STATUS , signed : '2025-01-01T00:00:00Z' } ] ,
759- } )
759+ await setVmState ( { uuidToValidate : '550e8400-e29b-41d4-a716-446655440000' } )
760+ history . pushState ( { isAfterSigned : true } , '' )
761+ vi . mocked ( axios . get ) . mockResolvedValueOnce ( {
762+ data : {
763+ ocs : {
764+ data : {
765+ status : 1 ,
766+ signers : [ { me : true , status : SIGNER_SIGNED_STATUS , signed : '2025-01-01T00:00:00Z' } ] ,
767+ } ,
768+ } ,
769+ } ,
760770 } )
761771
762772 wrapper . vm . handleSigningComplete ( null )
0 commit comments