📄 src/models/test/patchContext.test.ts
D-OPEN SOVEREIGN
1/*
2 * Copyright (c) 2026 DataPond D-Library Pty Ltd. ("The Sanctuary")
3 * Non-Profit Public Library — The World Library
4 * 
5 * D-SAFE Certification issued by POND Enterprise.
6 * Published under the D-Open Code Sovereign Licence v1.0 framework
7 * DataPond D-Library All exclusive Right reserved on modifiying the code - CC Attribution to data pond, Non modifiable, Non Commercial.
8 * https://registry.world.bibliotech.com/licence
9 * Source code donated to DataPond D-Library by it's author: data pond.
10 * 
11 * Technical Guardian ("The Shield"): Pond Enterprise Pty Ltd. (ACN 694 747 987)
12 * All liability claims about D-SAFE certification issues coming from the published D-Safe direction must be addressed with Pond Enterprise Pty Ltd.
13 * Code Modification automatically voids the certified liability protection provided by Pond Enterprise.
14 */
15import { describe, it, expect, vi, beforeEach } from 'vitest';
16import { applyPatchWithContext, type PatchContext } from '../patchContext.ts';
17import { PatchOperation } from '../binary.ts';
18import * as db from '../db.ts';
19
20describe('patchContext', () => {
21    let mockRecordTable: any;
22    let mockRemapStore: any;
23    let mockCtx: PatchContext;
24
25    beforeEach(() => {
26        mockRecordTable = { putIfAbsent: vi.fn().mockResolvedValue(undefined) };
27        mockRemapStore = { get: vi.fn().mockResolvedValue(undefined), put: vi.fn().mockResolvedValue(undefined) };
28        
29        mockCtx = {
30            localRecordTable: mockRecordTable,
31            creatorUsername: 'test_user',
32            blockTimestamp: 1000,
33            batchRemainder: [],
34            instanceRemapStore: mockRemapStore
35        };
36
37        vi.spyOn(console, 'warn').mockImplementation(() => {});
38        // Mock db methods
39        vi.spyOn(db, 'hasRecord').mockReturnValue(false);
40    });
41
42    it('gracefully skips Edit patches if target is absent from LRU', async () => {
43        const patch: any = {
44            operation: PatchOperation.EditPropertyString,
45            objectType: 1,
46            objectId: 100,
47            langId: 1,
48            propertyId: 1,
49            value: 'hello'
50        };
51
52        await applyPatchWithContext(patch, mockCtx);
53
54        // Should just skip and not throw
55        expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('Edit target absent; skipping'));
56    });
57
58    it('gracefully skips AddInstance patches if target is absent', async () => {
59        const patch: any = {
60            operation: PatchOperation.AddInstance,
61            objectType: 1,
62            objectId: 100,
63            langId: 1,
64            instanceIndex: 0
65        };
66
67        await applyPatchWithContext(patch, mockCtx);
68
69        expect(console.warn).toHaveBeenCalledWith(expect.stringContaining('AddInstance target absent; skipping'));
70    });
71
72    it('resolves instance index via instanceRemapStore for EditInstanceField patches', async () => {
73        // Mock that the record is in LRU
74        vi.spyOn(db, 'hasRecord').mockReturnValue(true);
75        const mockRecord = { patch: vi.fn() };
76        vi.spyOn(db, 'getRecord').mockReturnValue(mockRecord as any);
77
78        // Mock a remap exists
79        mockRemapStore.get.mockResolvedValue(5);
80
81        const patch: any = {
82            operation: PatchOperation.EditInstanceFieldString,
83            objectType: 1,
84            objectId: 100,
85            langId: 1,
86            instanceIndex: 0,
87            propertyId: 2,
88            value: 'remapped value'
89        };
90
91        await applyPatchWithContext(patch, mockCtx);
92
93        expect(mockRemapStore.get).toHaveBeenCalledWith(100, 1, 'test_user', 0);
94        // The patch instanceIndex should be mutated to 5 before patching the record
95        expect(patch.instanceIndex).toBe(5);
96        expect(mockRecord.patch).toHaveBeenCalledWith(patch);
97    });
98});
99