Skip to content

Commit e2d45a2

Browse files
committed
test: cover numeric temp ids in files store
Signed-off-by: Vitor Mattos <1079143+vitormattos@users.noreply.github.com> (cherry picked from commit fce5f7e)
1 parent ac04f2f commit e2d45a2

1 file changed

Lines changed: 103 additions & 13 deletions

File tree

src/tests/store/files.spec.ts

Lines changed: 103 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type TranslationParams = {
2424

2525
type Signer = {
2626
email: string
27-
identify?: string | number
27+
identifyMethods?: Array<{ method: string; value: string; mandatory: number }>
2828
localKey?: string
2929
signRequestId?: number
3030
}
@@ -654,10 +654,10 @@ describe('files store - critical business rules', () => {
654654
expect(store.isTemporaryId(-999)).toBe(true)
655655
})
656656

657-
it('identifies envelope_ prefix as temporary ID', () => {
657+
it('does not identify strings as temporary IDs', () => {
658658
const store = useFilesStore()
659-
expect(store.isTemporaryId('envelope_123')).toBe(true)
660-
expect(store.isTemporaryId('envelope_abc')).toBe(true)
659+
expect(store.isTemporaryId('envelope_123')).toBe(false)
660+
expect(store.isTemporaryId('envelope_abc')).toBe(false)
661661
})
662662

663663
it('does not identify positive numbers as temporary', () => {
@@ -867,6 +867,29 @@ describe('files store - critical business rules', () => {
867867
expect(signers[0].localKey).toBe('signer:10')
868868
expect(signers[2].localKey).toBe('signer:20')
869869
})
870+
871+
it('hydrates nested child signers and deep-clones metadata in editable draft', async () => {
872+
const store = useFilesStore()
873+
const sourceFile = {
874+
id: 1,
875+
signers: [{ email: 'parent@example.com', signRequestId: 10 }],
876+
files: [{
877+
id: 2,
878+
metadata: { d: [{ w: 100, h: 200 }] },
879+
signers: [{ email: 'child@example.com', signRequestId: 20 }],
880+
}],
881+
}
882+
await store.addFile(sourceFile, { detailsLoaded: true })
883+
884+
store.selectedFileId = 1
885+
const draft = store.getEditableFile()
886+
887+
expect(draft.files?.[0]?.signers?.[0]?.localKey).toBe('signer:20')
888+
if (draft.files?.[0]?.metadata?.d?.[0]) {
889+
draft.files[0].metadata.d[0].w = 300
890+
}
891+
expect(sourceFile.files[0].metadata.d[0].w).toBe(100)
892+
})
870893
})
871894

872895
describe('RULE: file lookup by nodeId', () => {
@@ -1035,7 +1058,12 @@ describe('files store - critical business rules', () => {
10351058
id: 1,
10361059
name: 'contract.pdf',
10371060
signatureFlow: 'parallel',
1038-
signers: [{ email: 'signer@example.com' }],
1061+
signers: [{
1062+
email: 'signer@example.com',
1063+
identifyMethods: [{ method: 'email', value: 'signer@example.com', mandatory: 0 }],
1064+
localKey: 'draft-signer:1',
1065+
statusText: 'Draft',
1066+
}],
10391067
}
10401068
axiosMock.mockResolvedValue({
10411069
data: { ocs: { data: { id: 1, nodeId: 99, signatureFlow: 'parallel', signers: [] } } },
@@ -1044,14 +1072,53 @@ describe('files store - critical business rules', () => {
10441072
await store.saveOrUpdateSignatureRequest({ status: 1 })
10451073

10461074
const config = axiosMock.mock.calls[0][0]
1047-
expect(config.data.signers).toEqual([{ email: 'signer@example.com' }])
1075+
expect(config.data.signers).toEqual([{
1076+
identifyMethods: [{ method: 'email', value: 'signer@example.com', mandatory: 0 }],
1077+
}])
1078+
})
1079+
1080+
it('removes UI-only signer fields and preserves backend-facing fields', async () => {
1081+
const store = useFilesStore()
1082+
store.selectedFileId = 1
1083+
store.files[1] = {
1084+
id: 1,
1085+
name: 'contract.pdf',
1086+
signatureFlow: 'parallel',
1087+
signers: [{
1088+
identifyMethods: [{ method: 'email', value: 'signer@example.com', mandatory: 1 }],
1089+
displayName: 'Signer',
1090+
description: 'Needs review',
1091+
notify: 0,
1092+
status: 1,
1093+
localKey: 'draft-signer:1',
1094+
statusText: 'Draft',
1095+
me: true,
1096+
signed: ['sig'],
1097+
visibleElements: [{ elementId: 10 }],
1098+
}],
1099+
}
1100+
axiosMock.mockResolvedValue({
1101+
data: { ocs: { data: { id: 1, nodeId: 99, signatureFlow: 'parallel', signers: [] } } },
1102+
})
1103+
1104+
await store.saveOrUpdateSignatureRequest({ status: 1 })
1105+
1106+
const config = axiosMock.mock.calls[0][0]
1107+
expect(config.data.signers).toEqual([{
1108+
identifyMethods: [{ method: 'email', value: 'signer@example.com', mandatory: 1 }],
1109+
displayName: 'Signer',
1110+
description: 'Needs review',
1111+
notify: 0,
1112+
status: 1,
1113+
}])
10481114
})
10491115

10501116
it('maps numeric signatureFlow to ordered_numeric', async () => {
10511117
const store = useFilesStore()
10521118
store.selectedFileId = 1
10531119
store.files[1] = {
10541120
id: 1,
1121+
nodeId: 99,
10551122
name: 'contract.pdf',
10561123
signatureFlow: 2,
10571124
signers: [],
@@ -1065,7 +1132,7 @@ describe('files store - critical business rules', () => {
10651132

10661133
const config = axiosMock.mock.calls[0][0]
10671134
expect(config.data.signatureFlow).toBe('ordered_numeric')
1068-
expect(config.data.file.fileId).toBe(1)
1135+
expect(config.data.file.nodeId).toBe(99)
10691136
expect(config.data.file.settings).toEqual({ path: '/files/contract.pdf' })
10701137
})
10711138

@@ -1105,7 +1172,7 @@ describe('files store - critical business rules', () => {
11051172
signatureFlow: 'parallel',
11061173
settings: { path: '/files/contract.pdf' },
11071174
visibleElements: [{ id: 77 }],
1108-
signers: [{ identify: 'signer01@libresign.coop', signRequestId: 10 }],
1175+
signers: [{ identifyMethods: [{ method: 'email', value: 'signer01@libresign.coop', mandatory: 0 }], signRequestId: 10 }],
11091176
}
11101177
axiosMock.mockResolvedValue({
11111178
data: {
@@ -1114,7 +1181,7 @@ describe('files store - critical business rules', () => {
11141181
id: 1,
11151182
uuid: 'file-uuid',
11161183
signatureFlow: 'parallel',
1117-
signers: [{ identify: 'signer01@libresign.coop', signRequestId: 10 }],
1184+
signers: [{ identifyMethods: [{ method: 'email', value: 'signer01@libresign.coop', mandatory: 0 }], signRequestId: 10 }],
11181185
},
11191186
},
11201187
},
@@ -1177,7 +1244,7 @@ describe('files store - critical business rules', () => {
11771244
id: tempId,
11781245
nodeId,
11791246
name: 'test.pdf',
1180-
signers: [{ email: 'signer@example.com', identify: 'signer@example.com' }],
1247+
signers: [{ email: 'signer@example.com', identifyMethods: [{ method: 'email', value: 'signer@example.com', mandatory: 0 }] }],
11811248
signatureFlow: 'parallel',
11821249
}
11831250
store.selectedFileId = tempId
@@ -1192,15 +1259,38 @@ describe('files store - critical business rules', () => {
11921259
expect(config.data.file).toEqual({ nodeId })
11931260
})
11941261

1195-
it('includes file.fileId when file has a real positive LibreSign id', async () => {
1262+
it('serializes envelope files with nodeId-based references for creation flows', async () => {
1263+
const store = useFilesStore()
1264+
store.selectedFileId = -1
1265+
store.files[-1] = {
1266+
id: -1,
1267+
name: 'Envelope',
1268+
files: [
1269+
{ id: 7, nodeId: 12345, name: 'first.pdf', signers: [{ email: 'ignored@example.com' }] },
1270+
{ id: -22, nodeId: 22, name: 'second.pdf', metadata: { d: [{ w: 100, h: 200 }] } },
1271+
],
1272+
signers: [{ email: 'signer@example.com' }],
1273+
signatureFlow: 'parallel',
1274+
}
1275+
axiosMock.mockResolvedValue({
1276+
data: { ocs: { data: { id: 12, nodeId: 'real-node', signatureFlow: 'parallel', signers: [] } } },
1277+
})
1278+
1279+
await store.saveOrUpdateSignatureRequest({})
1280+
1281+
const config = axiosMock.mock.calls[0][0]
1282+
expect(config.data.files).toEqual([{ nodeId: 12345 }, { nodeId: 22 }])
1283+
})
1284+
1285+
it('includes file.nodeId when a known file is turned into a new request', async () => {
11961286
const store = useFilesStore()
11971287
// Simulate the state when LibreSign already knows about the file
11981288
// (returned by getAllFiles after the /api/v1/file POST in init.ts).
11991289
store.files[7] = {
12001290
id: 7,
12011291
nodeId: 12345,
12021292
name: 'test.pdf',
1203-
signers: [{ email: 'signer@example.com', identify: 'signer@example.com' }],
1293+
signers: [{ email: 'signer@example.com', identifyMethods: [{ method: 'email', value: 'signer@example.com', mandatory: 0 }] }],
12041294
signatureFlow: 'parallel',
12051295
}
12061296
store.selectedFileId = 7
@@ -1212,7 +1302,7 @@ describe('files store - critical business rules', () => {
12121302
await store.saveOrUpdateSignatureRequest({})
12131303

12141304
const config = axiosMock.mock.calls[0][0]
1215-
expect(config.data.file).toEqual({ fileId: 7 })
1305+
expect(config.data.file).toEqual({ nodeId: 12345 })
12161306
})
12171307

12181308
it('does NOT mutate the shared emptyFile when no file is selected', () => {

0 commit comments

Comments
 (0)