@aaronsb/google-workspace-mcp 2.7.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +201 -21
- package/LICENSE-MIT +21 -0
- package/NOTICE +24 -0
- package/README.md +87 -57
- package/build/accounts/auth.d.ts +1 -1
- package/build/accounts/auth.js +1 -1
- package/build/accounts/oauth.js +3 -3
- package/build/accounts/oauth.js.map +1 -1
- package/build/accounts/token-service.js +1 -1
- package/build/accounts/token-service.js.map +1 -1
- package/build/coverage/analyze.d.ts +1 -1
- package/build/coverage/analyze.js +6 -4
- package/build/coverage/analyze.js.map +1 -1
- package/build/coverage/baseline.js +37 -20
- package/build/coverage/baseline.js.map +1 -1
- package/build/coverage/compare.d.ts +1 -1
- package/build/coverage/compare.js +19 -10
- package/build/coverage/compare.js.map +1 -1
- package/build/coverage/discover.d.ts +5 -5
- package/build/coverage/discover.js +71 -155
- package/build/coverage/discover.js.map +1 -1
- package/build/coverage/report.js +3 -3
- package/build/coverage/report.js.map +1 -1
- package/build/coverage/types.d.ts +19 -4
- package/build/executor/index.d.ts +0 -3
- package/build/executor/index.js +1 -2
- package/build/executor/index.js.map +1 -1
- package/build/factory/defaults.js +30 -4
- package/build/factory/defaults.js.map +1 -1
- package/build/factory/generator.d.ts +10 -4
- package/build/factory/generator.js +86 -96
- package/build/factory/generator.js.map +1 -1
- package/build/factory/manifest/README.md +4 -3
- package/build/factory/manifest/calendar.yaml +1 -11
- package/build/factory/manifest/docs.yaml +15 -6
- package/build/factory/manifest/drive.yaml +1 -5
- package/build/factory/manifest/gmail.yaml +32 -25
- package/build/factory/manifest/meet.yaml +1 -1
- package/build/factory/manifest/sheets.yaml +2 -5
- package/build/factory/manifest/tasks.yaml +40 -2
- package/build/factory/patches.js +2 -0
- package/build/factory/patches.js.map +1 -1
- package/build/factory/registry.d.ts +2 -3
- package/build/factory/registry.js +3 -9
- package/build/factory/registry.js.map +1 -1
- package/build/factory/safety.js +4 -4
- package/build/factory/safety.js.map +1 -1
- package/build/factory/types.d.ts +16 -15
- package/build/google/client.d.ts +45 -0
- package/build/google/client.js +232 -0
- package/build/google/client.js.map +1 -0
- package/build/google/descriptor.d.ts +40 -0
- package/build/google/descriptor.js +37 -0
- package/build/google/descriptor.js.map +1 -0
- package/build/google/descriptor.json +5271 -0
- package/build/google/errors.d.ts +45 -0
- package/build/google/errors.js +44 -0
- package/build/google/errors.js.map +1 -0
- package/build/google/methods.d.ts +37 -0
- package/build/google/methods.js +13 -0
- package/build/google/methods.js.map +1 -0
- package/build/index.js +30 -4
- package/build/index.js.map +1 -1
- package/build/node-floor.d.ts +16 -0
- package/build/node-floor.js +73 -0
- package/build/node-floor.js.map +1 -0
- package/build/server/formatting/markdown.d.ts +1 -1
- package/build/server/formatting/markdown.js +1 -1
- package/build/server/formatting/next-steps.js +1 -1
- package/build/server/formatting/next-steps.js.map +1 -1
- package/build/server/handlers/accounts.js +2 -2
- package/build/server/handlers/accounts.js.map +1 -1
- package/build/server/scratchpad/adapters/import-doc.js +15 -13
- package/build/server/scratchpad/adapters/import-doc.js.map +1 -1
- package/build/server/scratchpad/adapters/import-drive.js +16 -11
- package/build/server/scratchpad/adapters/import-drive.js.map +1 -1
- package/build/server/scratchpad/adapters/import-email.js +3 -15
- package/build/server/scratchpad/adapters/import-email.js.map +1 -1
- package/build/server/scratchpad/adapters/import-meet.js +5 -17
- package/build/server/scratchpad/adapters/import-meet.js.map +1 -1
- package/build/server/scratchpad/adapters/import-sheet.js +5 -6
- package/build/server/scratchpad/adapters/import-sheet.js.map +1 -1
- package/build/server/scratchpad/adapters/send-calendar.js +18 -13
- package/build/server/scratchpad/adapters/send-calendar.js.map +1 -1
- package/build/server/scratchpad/adapters/send-doc.js +22 -17
- package/build/server/scratchpad/adapters/send-doc.js.map +1 -1
- package/build/server/scratchpad/adapters/send-email-draft.d.ts +1 -1
- package/build/server/scratchpad/adapters/send-email-draft.js +17 -25
- package/build/server/scratchpad/adapters/send-email-draft.js.map +1 -1
- package/build/server/scratchpad/adapters/send-email.d.ts +2 -2
- package/build/server/scratchpad/adapters/send-email.js +21 -25
- package/build/server/scratchpad/adapters/send-email.js.map +1 -1
- package/build/server/scratchpad/adapters/send-sheet.js +10 -10
- package/build/server/scratchpad/adapters/send-sheet.js.map +1 -1
- package/build/server/scratchpad/adapters/send-task.js +9 -8
- package/build/server/scratchpad/adapters/send-task.js.map +1 -1
- package/build/server/scratchpad/handler.js +22 -28
- package/build/server/scratchpad/handler.js.map +1 -1
- package/build/server/scratchpad/manager.d.ts +1 -1
- package/build/server/server.js +13 -10
- package/build/server/server.js.map +1 -1
- package/build/server/session/tracker.js +21 -25
- package/build/server/session/tracker.js.map +1 -1
- package/build/server/tools.d.ts +1 -1
- package/build/server/tools.js +3 -3
- package/build/server/tools.js.map +1 -1
- package/build/services/calendar/patch.js +178 -68
- package/build/services/calendar/patch.js.map +1 -1
- package/build/services/docs/patch.d.ts +5 -3
- package/build/services/docs/patch.js +89 -19
- package/build/services/docs/patch.js.map +1 -1
- package/build/services/drive/patch.d.ts +1 -1
- package/build/services/drive/patch.js +115 -143
- package/build/services/drive/patch.js.map +1 -1
- package/build/services/gmail/attachments.js +10 -15
- package/build/services/gmail/attachments.js.map +1 -1
- package/build/services/gmail/mail.d.ts +34 -0
- package/build/services/gmail/mail.js +245 -0
- package/build/services/gmail/mail.js.map +1 -0
- package/build/services/gmail/mime.d.ts +45 -4
- package/build/services/gmail/mime.js +138 -4
- package/build/services/gmail/mime.js.map +1 -1
- package/build/services/gmail/patch.js +103 -53
- package/build/services/gmail/patch.js.map +1 -1
- package/build/services/meet/patch.js +24 -31
- package/build/services/meet/patch.js.map +1 -1
- package/build/services/sheets/patch.js +30 -35
- package/build/services/sheets/patch.js.map +1 -1
- package/build/services/tasks/patch.d.ts +18 -0
- package/build/services/tasks/patch.js +37 -0
- package/build/services/tasks/patch.js.map +1 -0
- package/build/version.d.ts +1 -1
- package/build/version.js +2 -2
- package/build/version.js.map +1 -1
- package/package.json +23 -12
- package/build/__helpers__/testSetup.d.ts +0 -1
- package/build/__helpers__/testSetup.js +0 -6
- package/build/__helpers__/testSetup.js.map +0 -1
- package/build/__tests__/accounts/credentials.test.d.ts +0 -1
- package/build/__tests__/accounts/credentials.test.js +0 -127
- package/build/__tests__/accounts/credentials.test.js.map +0 -1
- package/build/__tests__/accounts/oauth.test.d.ts +0 -1
- package/build/__tests__/accounts/oauth.test.js +0 -71
- package/build/__tests__/accounts/oauth.test.js.map +0 -1
- package/build/__tests__/accounts/registry.test.d.ts +0 -1
- package/build/__tests__/accounts/registry.test.js +0 -74
- package/build/__tests__/accounts/registry.test.js.map +0 -1
- package/build/__tests__/accounts/token-service.test.d.ts +0 -1
- package/build/__tests__/accounts/token-service.test.js +0 -126
- package/build/__tests__/accounts/token-service.test.js.map +0 -1
- package/build/__tests__/executor/errors.test.d.ts +0 -1
- package/build/__tests__/executor/errors.test.js +0 -42
- package/build/__tests__/executor/errors.test.js.map +0 -1
- package/build/__tests__/executor/gws.test.d.ts +0 -1
- package/build/__tests__/executor/gws.test.js +0 -187
- package/build/__tests__/executor/gws.test.js.map +0 -1
- package/build/__tests__/executor/paths.test.d.ts +0 -1
- package/build/__tests__/executor/paths.test.js +0 -60
- package/build/__tests__/executor/paths.test.js.map +0 -1
- package/build/__tests__/executor/resolve-binary.test.d.ts +0 -1
- package/build/__tests__/executor/resolve-binary.test.js +0 -58
- package/build/__tests__/executor/resolve-binary.test.js.map +0 -1
- package/build/__tests__/executor/workspace.test.d.ts +0 -1
- package/build/__tests__/executor/workspace.test.js +0 -143
- package/build/__tests__/executor/workspace.test.js.map +0 -1
- package/build/__tests__/factory/calendar-patch.test.d.ts +0 -5
- package/build/__tests__/factory/calendar-patch.test.js +0 -269
- package/build/__tests__/factory/calendar-patch.test.js.map +0 -1
- package/build/__tests__/factory/drive-patch.test.d.ts +0 -5
- package/build/__tests__/factory/drive-patch.test.js +0 -344
- package/build/__tests__/factory/drive-patch.test.js.map +0 -1
- package/build/__tests__/factory/generator.test.d.ts +0 -1
- package/build/__tests__/factory/generator.test.js +0 -240
- package/build/__tests__/factory/generator.test.js.map +0 -1
- package/build/__tests__/factory/patch-coverage.test.d.ts +0 -10
- package/build/__tests__/factory/patch-coverage.test.js +0 -182
- package/build/__tests__/factory/patch-coverage.test.js.map +0 -1
- package/build/__tests__/factory/safety.test.d.ts +0 -1
- package/build/__tests__/factory/safety.test.js +0 -107
- package/build/__tests__/factory/safety.test.js.map +0 -1
- package/build/__tests__/factory/sheets-patch.test.d.ts +0 -6
- package/build/__tests__/factory/sheets-patch.test.js +0 -498
- package/build/__tests__/factory/sheets-patch.test.js.map +0 -1
- package/build/__tests__/integration/executor.test.d.ts +0 -5
- package/build/__tests__/integration/executor.test.js +0 -38
- package/build/__tests__/integration/executor.test.js.map +0 -1
- package/build/__tests__/integration/handlers.test.d.ts +0 -6
- package/build/__tests__/integration/handlers.test.js +0 -95
- package/build/__tests__/integration/handlers.test.js.map +0 -1
- package/build/__tests__/integration/setup.d.ts +0 -19
- package/build/__tests__/integration/setup.js +0 -61
- package/build/__tests__/integration/setup.js.map +0 -1
- package/build/__tests__/server/formatting/html-sanitize.test.d.ts +0 -7
- package/build/__tests__/server/formatting/html-sanitize.test.js +0 -174
- package/build/__tests__/server/formatting/html-sanitize.test.js.map +0 -1
- package/build/__tests__/server/formatting/markdown.test.d.ts +0 -1
- package/build/__tests__/server/formatting/markdown.test.js +0 -259
- package/build/__tests__/server/formatting/markdown.test.js.map +0 -1
- package/build/__tests__/server/formatting/next-steps.test.d.ts +0 -1
- package/build/__tests__/server/formatting/next-steps.test.js +0 -42
- package/build/__tests__/server/formatting/next-steps.test.js.map +0 -1
- package/build/__tests__/server/handler.test.d.ts +0 -1
- package/build/__tests__/server/handler.test.js +0 -97
- package/build/__tests__/server/handler.test.js.map +0 -1
- package/build/__tests__/server/handlers/__mocks__/executor.d.ts +0 -173
- package/build/__tests__/server/handlers/__mocks__/executor.js +0 -135
- package/build/__tests__/server/handlers/__mocks__/executor.js.map +0 -1
- package/build/__tests__/server/handlers/accounts.test.d.ts +0 -1
- package/build/__tests__/server/handlers/accounts.test.js +0 -129
- package/build/__tests__/server/handlers/accounts.test.js.map +0 -1
- package/build/__tests__/server/handlers/calendar.test.d.ts +0 -1
- package/build/__tests__/server/handlers/calendar.test.js +0 -96
- package/build/__tests__/server/handlers/calendar.test.js.map +0 -1
- package/build/__tests__/server/handlers/drive.test.d.ts +0 -1
- package/build/__tests__/server/handlers/drive.test.js +0 -68
- package/build/__tests__/server/handlers/drive.test.js.map +0 -1
- package/build/__tests__/server/handlers/email.test.d.ts +0 -1
- package/build/__tests__/server/handlers/email.test.js +0 -99
- package/build/__tests__/server/handlers/email.test.js.map +0 -1
- package/build/__tests__/server/handlers/validate.test.d.ts +0 -1
- package/build/__tests__/server/handlers/validate.test.js +0 -88
- package/build/__tests__/server/handlers/validate.test.js.map +0 -1
- package/build/__tests__/server/queue.test.d.ts +0 -1
- package/build/__tests__/server/queue.test.js +0 -199
- package/build/__tests__/server/queue.test.js.map +0 -1
- package/build/__tests__/server/server.test.d.ts +0 -7
- package/build/__tests__/server/server.test.js +0 -135
- package/build/__tests__/server/server.test.js.map +0 -1
- package/build/__tests__/server/session/context.test.d.ts +0 -1
- package/build/__tests__/server/session/context.test.js +0 -101
- package/build/__tests__/server/session/context.test.js.map +0 -1
- package/build/__tests__/server/session/tracker.test.d.ts +0 -1
- package/build/__tests__/server/session/tracker.test.js +0 -146
- package/build/__tests__/server/session/tracker.test.js.map +0 -1
- package/build/__tests__/server/tools.test.d.ts +0 -1
- package/build/__tests__/server/tools.test.js +0 -91
- package/build/__tests__/server/tools.test.js.map +0 -1
- package/build/__tests__/services/gmail/mime.test.d.ts +0 -1
- package/build/__tests__/services/gmail/mime.test.js +0 -23
- package/build/__tests__/services/gmail/mime.test.js.map +0 -1
- package/build/__tests__/services/meet/patch.test.d.ts +0 -4
- package/build/__tests__/services/meet/patch.test.js +0 -374
- package/build/__tests__/services/meet/patch.test.js.map +0 -1
- package/build/executor/errors.d.ts +0 -15
- package/build/executor/errors.js +0 -37
- package/build/executor/errors.js.map +0 -1
- package/build/executor/gws.d.ts +0 -26
- package/build/executor/gws.js +0 -197
- package/build/executor/gws.js.map +0 -1
- package/build/server/handlers/calendar.d.ts +0 -2
- package/build/server/handlers/calendar.js +0 -97
- package/build/server/handlers/calendar.js.map +0 -1
- package/build/server/handlers/drive.d.ts +0 -2
- package/build/server/handlers/drive.js +0 -58
- package/build/server/handlers/drive.js.map +0 -1
- package/build/server/handlers/email.d.ts +0 -2
- package/build/server/handlers/email.js +0 -119
- package/build/server/handlers/email.js.map +0 -1
- package/build/server/scratchpad/__tests__/docs-sync-integration.test.d.ts +0 -11
- package/build/server/scratchpad/__tests__/docs-sync-integration.test.js +0 -187
- package/build/server/scratchpad/__tests__/docs-sync-integration.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/docs-sync.test.d.ts +0 -16
- package/build/server/scratchpad/__tests__/docs-sync.test.js +0 -213
- package/build/server/scratchpad/__tests__/docs-sync.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/json-path.test.d.ts +0 -4
- package/build/server/scratchpad/__tests__/json-path.test.js +0 -121
- package/build/server/scratchpad/__tests__/json-path.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/manager.test.d.ts +0 -5
- package/build/server/scratchpad/__tests__/manager.test.js +0 -886
- package/build/server/scratchpad/__tests__/manager.test.js.map +0 -1
- package/build/server/scratchpad/__tests__/validate.test.d.ts +0 -4
- package/build/server/scratchpad/__tests__/validate.test.js +0 -112
- package/build/server/scratchpad/__tests__/validate.test.js.map +0 -1
|
@@ -1,187 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Integration-ish tests for the docs-bound mutation path through the
|
|
3
|
-
* scratchpad handler. Mocks `execute` from the gws executor; everything
|
|
4
|
-
* else is real (ScratchpadManager, the docs-sync translator).
|
|
5
|
-
*
|
|
6
|
-
* Covers the two test cases that the pure-translator tests can't:
|
|
7
|
-
* - API rejects → local buffer preserved, error response returned.
|
|
8
|
-
* - API succeeds → reloadDocsBuffer fires, sp.lines replaced from the
|
|
9
|
-
* fresh response, binding revisionId updated.
|
|
10
|
-
*/
|
|
11
|
-
jest.mock('../../../executor/gws.js');
|
|
12
|
-
jest.mock('../../handler.js', () => ({ getEpoch: () => 0 }));
|
|
13
|
-
import { execute } from '../../../executor/gws.js';
|
|
14
|
-
import { handleScratchpad } from '../handler.js';
|
|
15
|
-
import { getScratchpadManager } from '../handler.js';
|
|
16
|
-
const mockExecute = execute;
|
|
17
|
-
/** Seed a docs-bound JSON scratchpad with a one-paragraph doc and return its id. */
|
|
18
|
-
function seedDocsBoundScratchpad(opts) {
|
|
19
|
-
const manager = getScratchpadManager();
|
|
20
|
-
const id = manager.create({ format: 'json' });
|
|
21
|
-
const doc = {
|
|
22
|
-
documentId: 'doc-1',
|
|
23
|
-
revisionId: opts?.revisionId ?? 'rev-1',
|
|
24
|
-
body: {
|
|
25
|
-
content: [
|
|
26
|
-
{
|
|
27
|
-
startIndex: 1,
|
|
28
|
-
endIndex: 13,
|
|
29
|
-
paragraph: {
|
|
30
|
-
elements: [
|
|
31
|
-
{ startIndex: 1, endIndex: 13, textRun: { content: 'Hello world\n' } },
|
|
32
|
-
],
|
|
33
|
-
paragraphStyle: { namedStyleType: 'NORMAL_TEXT' },
|
|
34
|
-
},
|
|
35
|
-
},
|
|
36
|
-
],
|
|
37
|
-
},
|
|
38
|
-
};
|
|
39
|
-
const sp = manager.get(id);
|
|
40
|
-
sp.lines = JSON.stringify(doc, null, 2).split('\n');
|
|
41
|
-
manager.setBinding(id, {
|
|
42
|
-
service: 'docs', resourceId: 'doc-1', account: 'me@test.com',
|
|
43
|
-
revisionId: opts?.revisionId ?? 'rev-1',
|
|
44
|
-
});
|
|
45
|
-
return id;
|
|
46
|
-
}
|
|
47
|
-
describe('docs-bound json_set', () => {
|
|
48
|
-
beforeEach(() => {
|
|
49
|
-
mockExecute.mockReset();
|
|
50
|
-
});
|
|
51
|
-
it('rejects an unsupported path WITHOUT mutating the local buffer (pre-validation)', async () => {
|
|
52
|
-
const id = seedDocsBoundScratchpad();
|
|
53
|
-
const manager = getScratchpadManager();
|
|
54
|
-
const linesBefore = [...manager.get(id).lines];
|
|
55
|
-
const result = await handleScratchpad({
|
|
56
|
-
operation: 'json_set',
|
|
57
|
-
scratchpadId: id,
|
|
58
|
-
// textStyle.bold is structural in the supported-path sense — not in the allowlist.
|
|
59
|
-
path: '$.body.content[0].paragraph.elements[0].textStyle.bold',
|
|
60
|
-
value: true,
|
|
61
|
-
});
|
|
62
|
-
expect(result.text).toMatch(/rejected/);
|
|
63
|
-
expect(result.text).toMatch(/not supported/);
|
|
64
|
-
// Pre-validation contract: the buffer is untouched on rejection.
|
|
65
|
-
expect(manager.get(id).lines).toEqual(linesBefore);
|
|
66
|
-
expect(mockExecute).not.toHaveBeenCalled();
|
|
67
|
-
});
|
|
68
|
-
it('on API success, pushes batchUpdate and reloads the buffer from documents.get', async () => {
|
|
69
|
-
const id = seedDocsBoundScratchpad({ revisionId: 'rev-1' });
|
|
70
|
-
const manager = getScratchpadManager();
|
|
71
|
-
// First call: batchUpdate succeeds.
|
|
72
|
-
// Second call: documents.get returns the fresh doc (with bumped revisionId).
|
|
73
|
-
mockExecute
|
|
74
|
-
.mockResolvedValueOnce({ success: true, data: {}, stderr: '' })
|
|
75
|
-
.mockResolvedValueOnce({
|
|
76
|
-
success: true,
|
|
77
|
-
data: {
|
|
78
|
-
documentId: 'doc-1',
|
|
79
|
-
revisionId: 'rev-2',
|
|
80
|
-
body: {
|
|
81
|
-
content: [{
|
|
82
|
-
startIndex: 1,
|
|
83
|
-
endIndex: 9,
|
|
84
|
-
paragraph: {
|
|
85
|
-
elements: [{ startIndex: 1, endIndex: 9, textRun: { content: 'Goodbye\n' } }],
|
|
86
|
-
paragraphStyle: { namedStyleType: 'NORMAL_TEXT' },
|
|
87
|
-
},
|
|
88
|
-
}],
|
|
89
|
-
},
|
|
90
|
-
},
|
|
91
|
-
stderr: '',
|
|
92
|
-
});
|
|
93
|
-
const result = await handleScratchpad({
|
|
94
|
-
operation: 'json_set',
|
|
95
|
-
scratchpadId: id,
|
|
96
|
-
path: '$.body.content[0].paragraph.elements[0].textRun.content',
|
|
97
|
-
value: 'Goodbye',
|
|
98
|
-
});
|
|
99
|
-
expect(result.refs.synced).toBe(true);
|
|
100
|
-
expect(mockExecute).toHaveBeenCalledTimes(2);
|
|
101
|
-
// First call: batchUpdate with the translated request + writeControl.
|
|
102
|
-
const batchArgs = mockExecute.mock.calls[0][0];
|
|
103
|
-
expect(batchArgs.slice(0, 3)).toEqual(['docs', 'documents', 'batchUpdate']);
|
|
104
|
-
const body = JSON.parse(batchArgs[batchArgs.indexOf('--json') + 1]);
|
|
105
|
-
expect(body.requests[0]).toEqual({ deleteContentRange: { range: { startIndex: 1, endIndex: 12 } } });
|
|
106
|
-
expect(body.requests[1]).toEqual({ insertText: { text: 'Goodbye', location: { index: 1 } } });
|
|
107
|
-
expect(body.writeControl).toEqual({ requiredRevisionId: 'rev-1' });
|
|
108
|
-
// Second call: documents.get for the reload.
|
|
109
|
-
expect(mockExecute.mock.calls[1][0].slice(0, 3)).toEqual(['docs', 'documents', 'get']);
|
|
110
|
-
// Buffer reloaded from fresh response.
|
|
111
|
-
const reloaded = JSON.parse(manager.get(id).lines.join('\n'));
|
|
112
|
-
expect(reloaded.revisionId).toBe('rev-2');
|
|
113
|
-
expect(reloaded.body.content[0].paragraph.elements[0].textRun.content).toBe('Goodbye\n');
|
|
114
|
-
// Binding revisionId advanced for the NEXT sync.
|
|
115
|
-
expect(manager.getBinding(id)?.revisionId).toBe('rev-2');
|
|
116
|
-
});
|
|
117
|
-
it('on API rejection, preserves the local buffer change and returns an error', async () => {
|
|
118
|
-
const id = seedDocsBoundScratchpad({ revisionId: 'rev-1' });
|
|
119
|
-
const manager = getScratchpadManager();
|
|
120
|
-
// Simulate the API rejecting (e.g., stale requiredRevisionId).
|
|
121
|
-
mockExecute.mockRejectedValueOnce(new Error('precondition failed: revisionId mismatch'));
|
|
122
|
-
const result = await handleScratchpad({
|
|
123
|
-
operation: 'json_set',
|
|
124
|
-
scratchpadId: id,
|
|
125
|
-
path: '$.body.content[0].paragraph.elements[0].textRun.content',
|
|
126
|
-
value: 'Goodbye',
|
|
127
|
-
});
|
|
128
|
-
expect(result.refs.error).toBe(true);
|
|
129
|
-
expect(result.text).toMatch(/Sync failed/);
|
|
130
|
-
expect(result.text).toMatch(/Retry or use scratchpad reset to discard/);
|
|
131
|
-
// The batchUpdate was attempted; the reload (second call) was NOT.
|
|
132
|
-
expect(mockExecute).toHaveBeenCalledTimes(1);
|
|
133
|
-
// Local buffer holds the would-have-synced change — agent retries or discards.
|
|
134
|
-
const buffer = JSON.parse(manager.get(id).lines.join('\n'));
|
|
135
|
-
expect(buffer.body.content[0].paragraph.elements[0].textRun.content).toBe('Goodbye');
|
|
136
|
-
// Binding revisionId did NOT advance — still the original.
|
|
137
|
-
expect(manager.getBinding(id)?.revisionId).toBe('rev-1');
|
|
138
|
-
});
|
|
139
|
-
it('json_delete on a docs-bound scratchpad is rejected (structural)', async () => {
|
|
140
|
-
const id = seedDocsBoundScratchpad();
|
|
141
|
-
const manager = getScratchpadManager();
|
|
142
|
-
const linesBefore = [...manager.get(id).lines];
|
|
143
|
-
const result = await handleScratchpad({
|
|
144
|
-
operation: 'json_delete',
|
|
145
|
-
scratchpadId: id,
|
|
146
|
-
path: '$.body.content[0]',
|
|
147
|
-
});
|
|
148
|
-
expect(result.text).toMatch(/rejected/);
|
|
149
|
-
expect(result.text).toMatch(/structural/);
|
|
150
|
-
expect(manager.get(id).lines).toEqual(linesBefore);
|
|
151
|
-
expect(mockExecute).not.toHaveBeenCalled();
|
|
152
|
-
});
|
|
153
|
-
it('omits writeControl when the binding has no revisionId (legacy import)', async () => {
|
|
154
|
-
const id = seedDocsBoundScratchpad({ revisionId: undefined });
|
|
155
|
-
// Need to clear it explicitly — the seed helper defaults to 'rev-1'.
|
|
156
|
-
const manager = getScratchpadManager();
|
|
157
|
-
manager.setBinding(id, { service: 'docs', resourceId: 'doc-1', account: 'me@test.com' });
|
|
158
|
-
mockExecute
|
|
159
|
-
.mockResolvedValueOnce({ success: true, data: {}, stderr: '' })
|
|
160
|
-
.mockResolvedValueOnce({
|
|
161
|
-
success: true,
|
|
162
|
-
data: {
|
|
163
|
-
documentId: 'doc-1',
|
|
164
|
-
revisionId: 'rev-9',
|
|
165
|
-
body: { content: [{
|
|
166
|
-
startIndex: 1, endIndex: 13,
|
|
167
|
-
paragraph: {
|
|
168
|
-
elements: [{ startIndex: 1, endIndex: 13, textRun: { content: 'Hello world\n' } }],
|
|
169
|
-
paragraphStyle: {},
|
|
170
|
-
},
|
|
171
|
-
}] },
|
|
172
|
-
},
|
|
173
|
-
stderr: '',
|
|
174
|
-
});
|
|
175
|
-
await handleScratchpad({
|
|
176
|
-
operation: 'json_set',
|
|
177
|
-
scratchpadId: id,
|
|
178
|
-
path: '$.body.content[0].paragraph.elements[0].textRun.content',
|
|
179
|
-
value: 'X',
|
|
180
|
-
});
|
|
181
|
-
const body = JSON.parse(mockExecute.mock.calls[0][0][mockExecute.mock.calls[0][0].indexOf('--json') + 1]);
|
|
182
|
-
expect(body.writeControl).toBeUndefined();
|
|
183
|
-
// But the reload picks up a fresh revisionId for the next sync.
|
|
184
|
-
expect(manager.getBinding(id)?.revisionId).toBe('rev-9');
|
|
185
|
-
});
|
|
186
|
-
});
|
|
187
|
-
//# sourceMappingURL=docs-sync-integration.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docs-sync-integration.test.js","sourceRoot":"","sources":["../../../../src/server/scratchpad/__tests__/docs-sync-integration.test.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,IAAI,CAAC,IAAI,CAAC,0BAA0B,CAAC,CAAC;AACtC,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAE7D,OAAO,EAAE,OAAO,EAAE,MAAM,0BAA0B,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACjD,OAAO,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,WAAW,GAAG,OAA8C,CAAC;AAEnE,oFAAoF;AACpF,SAAS,uBAAuB,CAAC,IAA8B;IAC7D,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;IACvC,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG;QACV,UAAU,EAAE,OAAO;QACnB,UAAU,EAAE,IAAI,EAAE,UAAU,IAAI,OAAO;QACvC,IAAI,EAAE;YACJ,OAAO,EAAE;gBACP;oBACE,UAAU,EAAE,CAAC;oBACb,QAAQ,EAAE,EAAE;oBACZ,SAAS,EAAE;wBACT,QAAQ,EAAE;4BACR,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;yBACvE;wBACD,cAAc,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE;qBAClD;iBACF;aACF;SACF;KACF,CAAC;IACF,MAAM,EAAE,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;IAC5B,EAAE,CAAC,KAAK,GAAG,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACpD,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE;QACrB,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa;QAC5D,UAAU,EAAE,IAAI,EAAE,UAAU,IAAI,OAAO;KACxC,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,QAAQ,CAAC,qBAAqB,EAAE,GAAG,EAAE;IACnC,UAAU,CAAC,GAAG,EAAE;QACd,WAAW,CAAC,SAAS,EAAE,CAAC;IAC1B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gFAAgF,EAAE,KAAK,IAAI,EAAE;QAC9F,MAAM,EAAE,GAAG,uBAAuB,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACpC,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,EAAE;YAChB,mFAAmF;YACnF,IAAI,EAAE,wDAAwD;YAC9D,KAAK,EAAE,IAAI;SACZ,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;QAC7C,iEAAiE;QACjE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,8EAA8E,EAAE,KAAK,IAAI,EAAE;QAC5F,MAAM,EAAE,GAAG,uBAAuB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QAEvC,oCAAoC;QACpC,6EAA6E;QAC7E,WAAW;aACR,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;aAC9D,qBAAqB,CAAC;YACrB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,OAAO;gBACnB,IAAI,EAAE;oBACJ,OAAO,EAAE,CAAC;4BACR,UAAU,EAAE,CAAC;4BACb,QAAQ,EAAE,CAAC;4BACX,SAAS,EAAE;gCACT,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,WAAW,EAAE,EAAE,CAAC;gCAC7E,cAAc,EAAE,EAAE,cAAc,EAAE,aAAa,EAAE;6BAClD;yBACF,CAAC;iBACH;aACF;YACD,MAAM,EAAE,EAAE;SACX,CAAC,CAAC;QAEL,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACpC,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE,yDAAyD;YAC/D,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,CAAC,WAAW,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE7C,sEAAsE;QACtE,MAAM,SAAS,GAAG,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/C,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;QAC5E,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,SAAS,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QACpE,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,kBAAkB,EAAE,EAAE,KAAK,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,CAAC;QACrG,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;QAC9F,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,OAAO,CAAC,EAAE,kBAAkB,EAAE,OAAO,EAAE,CAAC,CAAC;QAEnE,6CAA6C;QAC7C,MAAM,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,EAAE,WAAW,EAAE,KAAK,CAAC,CAAC,CAAC;QAEvF,uCAAuC;QACvC,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC1C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACzF,iDAAiD;QACjD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,0EAA0E,EAAE,KAAK,IAAI,EAAE;QACxF,MAAM,EAAE,GAAG,uBAAuB,CAAC,EAAE,UAAU,EAAE,OAAO,EAAE,CAAC,CAAC;QAC5D,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QAEvC,+DAA+D;QAC/D,WAAW,CAAC,qBAAqB,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;QAEzF,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACpC,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE,yDAAyD;YAC/D,KAAK,EAAE,SAAS;SACjB,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC3C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,0CAA0C,CAAC,CAAC;QAExE,mEAAmE;QACnE,MAAM,CAAC,WAAW,CAAC,CAAC,qBAAqB,CAAC,CAAC,CAAC,CAAC;QAE7C,+EAA+E;QAC/E,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAC7D,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACrF,2DAA2D;QAC3D,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iEAAiE,EAAE,KAAK,IAAI,EAAE;QAC/E,MAAM,EAAE,GAAG,uBAAuB,EAAE,CAAC;QACrC,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QACvC,MAAM,WAAW,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,CAAC;QAEhD,MAAM,MAAM,GAAG,MAAM,gBAAgB,CAAC;YACpC,SAAS,EAAE,aAAa;YACxB,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE,mBAAmB;SAC1B,CAAC,CAAC;QAEH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QACxC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC,KAAK,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACpD,MAAM,CAAC,WAAW,CAAC,CAAC,GAAG,CAAC,gBAAgB,EAAE,CAAC;IAC7C,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uEAAuE,EAAE,KAAK,IAAI,EAAE;QACrF,MAAM,EAAE,GAAG,uBAAuB,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,CAAC,CAAC;QAC9D,qEAAqE;QACrE,MAAM,OAAO,GAAG,oBAAoB,EAAE,CAAC;QACvC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,CAAC,CAAC;QAEzF,WAAW;aACR,qBAAqB,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;aAC9D,qBAAqB,CAAC;YACrB,OAAO,EAAE,IAAI;YACb,IAAI,EAAE;gBACJ,UAAU,EAAE,OAAO;gBACnB,UAAU,EAAE,OAAO;gBACnB,IAAI,EAAE,EAAE,OAAO,EAAE,CAAC;4BAChB,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE;4BAC3B,SAAS,EAAE;gCACT,QAAQ,EAAE,CAAC,EAAE,UAAU,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,EAAE,OAAO,EAAE,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE,CAAC;gCAClF,cAAc,EAAE,EAAE;6BACnB;yBACF,CAAC,EAAE;aACL;YACD,MAAM,EAAE,EAAE;SACX,CAAC,CAAC;QAEL,MAAM,gBAAgB,CAAC;YACrB,SAAS,EAAE,UAAU;YACrB,YAAY,EAAE,EAAE;YAChB,IAAI,EAAE,yDAAyD;YAC/D,KAAK,EAAE,GAAG;SACX,CAAC,CAAC;QAEH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;QAC1G,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,aAAa,EAAE,CAAC;QAC1C,gEAAgE;QAChE,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,CAAC,EAAE,UAAU,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC3D,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for docs-sync — translating a scratchpad JSON-mode mutation into
|
|
3
|
-
* a Docs batchUpdate request. Pure translator; no API calls (mocked or
|
|
4
|
-
* otherwise) in this file. See issue #79.
|
|
5
|
-
*/
|
|
6
|
-
export {};
|
|
7
|
-
/**
|
|
8
|
-
* Suggested next pass — handler-level integration tests that mock `execute`
|
|
9
|
-
* to cover the API-error-preserves-buffer and success-reloads-buffer cases.
|
|
10
|
-
* Co-located with this file would be reasonable; a separate file under the
|
|
11
|
-
* same dir keeps the unit-vs-integration split clear.
|
|
12
|
-
*
|
|
13
|
-
* - API rejects (stale revisionId, structural error) → buffer preserved.
|
|
14
|
-
* - API succeeds → reloadDocsBuffer fires, sp.lines replaced, binding
|
|
15
|
-
* revisionId updated from the fresh response.
|
|
16
|
-
*/
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for docs-sync — translating a scratchpad JSON-mode mutation into
|
|
3
|
-
* a Docs batchUpdate request. Pure translator; no API calls (mocked or
|
|
4
|
-
* otherwise) in this file. See issue #79.
|
|
5
|
-
*/
|
|
6
|
-
import { translateMutation, isRejection } from '../docs-sync.js';
|
|
7
|
-
/** Minimal Docs-API-shaped JSON with one body content element. */
|
|
8
|
-
function docWith(element, revisionId = 'rev-1') {
|
|
9
|
-
return JSON.stringify({
|
|
10
|
-
documentId: 'doc-1',
|
|
11
|
-
revisionId,
|
|
12
|
-
body: { content: [element] },
|
|
13
|
-
});
|
|
14
|
-
}
|
|
15
|
-
/** Helper — a textRun element. content/startIndex/endIndex configurable. */
|
|
16
|
-
function textRunElement(content, startIndex) {
|
|
17
|
-
return {
|
|
18
|
-
startIndex,
|
|
19
|
-
endIndex: startIndex + content.length,
|
|
20
|
-
paragraph: {
|
|
21
|
-
elements: [
|
|
22
|
-
{ startIndex, endIndex: startIndex + content.length, textRun: { content } },
|
|
23
|
-
],
|
|
24
|
-
paragraphStyle: { namedStyleType: 'NORMAL_TEXT' },
|
|
25
|
-
},
|
|
26
|
-
};
|
|
27
|
-
}
|
|
28
|
-
const TEXT_PATH = '$.body.content[0].paragraph.elements[0].textRun.content';
|
|
29
|
-
const STYLE_PATH = '$.body.content[0].paragraph.paragraphStyle.namedStyleType';
|
|
30
|
-
describe('translateMutation — textRun.content path', () => {
|
|
31
|
-
it('builds deleteContentRange(start, end-1) + insertText when old content ends with \\n', () => {
|
|
32
|
-
// Trailing newline is the paragraph break — must not delete through it,
|
|
33
|
-
// or the paragraph itself disappears.
|
|
34
|
-
const beforeJson = docWith(textRunElement('Hello world\n', 1)); // endIndex = 13
|
|
35
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'Goodbye', beforeJson }, 'rev-1');
|
|
36
|
-
if (isRejection(result))
|
|
37
|
-
throw new Error(`unexpected rejection: ${result.reason}`);
|
|
38
|
-
expect(result.body.requests).toEqual([
|
|
39
|
-
{ deleteContentRange: { range: { startIndex: 1, endIndex: 12 } } }, // end - 1 = 13 - 1
|
|
40
|
-
{ insertText: { text: 'Goodbye', location: { index: 1 } } },
|
|
41
|
-
]);
|
|
42
|
-
expect(result.body.writeControl).toEqual({ requiredRevisionId: 'rev-1' });
|
|
43
|
-
});
|
|
44
|
-
it('builds deleteContentRange(start, end) when old content has no trailing newline', () => {
|
|
45
|
-
const beforeJson = docWith(textRunElement('inline', 5)); // endIndex = 11, no trailing \n
|
|
46
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'inlined', beforeJson }, 'rev-1');
|
|
47
|
-
if (isRejection(result))
|
|
48
|
-
throw new Error(`unexpected rejection: ${result.reason}`);
|
|
49
|
-
expect(result.body.requests).toEqual([
|
|
50
|
-
{ deleteContentRange: { range: { startIndex: 5, endIndex: 11 } } },
|
|
51
|
-
{ insertText: { text: 'inlined', location: { index: 5 } } },
|
|
52
|
-
]);
|
|
53
|
-
});
|
|
54
|
-
it('omits deleteContentRange when the run is just a paragraph-break newline', () => {
|
|
55
|
-
// oldContent='\n' → deleteEnd = endIndex - 1 = startIndex; nothing to delete.
|
|
56
|
-
const beforeJson = docWith(textRunElement('\n', 7));
|
|
57
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'X', beforeJson }, 'rev-1');
|
|
58
|
-
if (isRejection(result))
|
|
59
|
-
throw new Error(`unexpected rejection: ${result.reason}`);
|
|
60
|
-
expect(result.body.requests).toEqual([
|
|
61
|
-
{ insertText: { text: 'X', location: { index: 7 } } },
|
|
62
|
-
]);
|
|
63
|
-
});
|
|
64
|
-
it('rejects a newline in the new value (structural edit disguised as text)', () => {
|
|
65
|
-
const beforeJson = docWith(textRunElement('Hello\n', 1));
|
|
66
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'line1\nline2', beforeJson }, 'rev-1');
|
|
67
|
-
expect(isRejection(result)).toBe(true);
|
|
68
|
-
if (isRejection(result))
|
|
69
|
-
expect(result.reason).toMatch(/newline/);
|
|
70
|
-
});
|
|
71
|
-
it('rejects a non-string value', () => {
|
|
72
|
-
const beforeJson = docWith(textRunElement('x', 1));
|
|
73
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 42, beforeJson }, 'rev-1');
|
|
74
|
-
expect(isRejection(result)).toBe(true);
|
|
75
|
-
if (isRejection(result))
|
|
76
|
-
expect(result.reason).toMatch(/string/);
|
|
77
|
-
});
|
|
78
|
-
it('rejects when the element has no textRun (e.g. an inline image)', () => {
|
|
79
|
-
const beforeJson = docWith({
|
|
80
|
-
startIndex: 1,
|
|
81
|
-
endIndex: 2,
|
|
82
|
-
paragraph: {
|
|
83
|
-
elements: [{ startIndex: 1, endIndex: 2, inlineObjectElement: { objectId: 'img-1' } }],
|
|
84
|
-
},
|
|
85
|
-
});
|
|
86
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'x', beforeJson }, 'rev-1');
|
|
87
|
-
expect(isRejection(result)).toBe(true);
|
|
88
|
-
if (isRejection(result))
|
|
89
|
-
expect(result.reason).toMatch(/textRun/);
|
|
90
|
-
});
|
|
91
|
-
});
|
|
92
|
-
describe('translateMutation — paragraphStyle path', () => {
|
|
93
|
-
it('builds updateParagraphStyle with the element range and the leaf field mask', () => {
|
|
94
|
-
const beforeJson = docWith(textRunElement('Heading text\n', 1));
|
|
95
|
-
const result = translateMutation({ op: 'set', path: STYLE_PATH, value: 'HEADING_1', beforeJson }, 'rev-1');
|
|
96
|
-
if (isRejection(result))
|
|
97
|
-
throw new Error(`unexpected rejection: ${result.reason}`);
|
|
98
|
-
expect(result.body.requests).toEqual([{
|
|
99
|
-
updateParagraphStyle: {
|
|
100
|
-
range: { startIndex: 1, endIndex: 14 }, // 'Heading text\n'.length = 13
|
|
101
|
-
paragraphStyle: { namedStyleType: 'HEADING_1' },
|
|
102
|
-
fields: 'namedStyleType',
|
|
103
|
-
},
|
|
104
|
-
}]);
|
|
105
|
-
expect(result.body.writeControl).toEqual({ requiredRevisionId: 'rev-1' });
|
|
106
|
-
});
|
|
107
|
-
it('passes the leaf field name through unchanged (alignment, direction, etc.)', () => {
|
|
108
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
109
|
-
const result = translateMutation({ op: 'set', path: '$.body.content[0].paragraph.paragraphStyle.alignment', value: 'CENTER', beforeJson }, 'rev-1');
|
|
110
|
-
if (isRejection(result))
|
|
111
|
-
throw new Error(`unexpected rejection: ${result.reason}`);
|
|
112
|
-
const r = result.body.requests[0];
|
|
113
|
-
expect(r.updateParagraphStyle.fields).toBe('alignment');
|
|
114
|
-
expect(r.updateParagraphStyle.paragraphStyle).toEqual({ alignment: 'CENTER' });
|
|
115
|
-
});
|
|
116
|
-
it('rejects when the element is not a paragraph', () => {
|
|
117
|
-
const beforeJson = docWith({
|
|
118
|
-
startIndex: 1, endIndex: 5,
|
|
119
|
-
table: { rows: 1, columns: 1 },
|
|
120
|
-
});
|
|
121
|
-
const result = translateMutation({ op: 'set', path: STYLE_PATH, value: 'HEADING_1', beforeJson }, 'rev-1');
|
|
122
|
-
expect(isRejection(result)).toBe(true);
|
|
123
|
-
if (isRejection(result))
|
|
124
|
-
expect(result.reason).toMatch(/paragraph/);
|
|
125
|
-
});
|
|
126
|
-
});
|
|
127
|
-
describe('translateMutation — rejected paths and ops', () => {
|
|
128
|
-
it('rejects an unsupported path with a guidance message', () => {
|
|
129
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
130
|
-
const result = translateMutation({ op: 'set', path: '$.body.content[0].paragraph.elements[0].textStyle.bold', value: true, beforeJson }, 'rev-1');
|
|
131
|
-
expect(isRejection(result)).toBe(true);
|
|
132
|
-
if (isRejection(result)) {
|
|
133
|
-
expect(result.reason).toMatch(/not supported/);
|
|
134
|
-
expect(result.reason).toMatch(/markdown mode/);
|
|
135
|
-
}
|
|
136
|
-
});
|
|
137
|
-
it('rejects json_delete on a docs-bound scratchpad (structural)', () => {
|
|
138
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
139
|
-
const result = translateMutation({ op: 'delete', path: TEXT_PATH, beforeJson }, 'rev-1');
|
|
140
|
-
expect(isRejection(result)).toBe(true);
|
|
141
|
-
if (isRejection(result))
|
|
142
|
-
expect(result.reason).toMatch(/structural/);
|
|
143
|
-
});
|
|
144
|
-
it('rejects json_insert on a docs-bound scratchpad (structural)', () => {
|
|
145
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
146
|
-
const result = translateMutation({ op: 'insert', path: '$.body.content', value: { paragraph: {} }, beforeJson }, 'rev-1');
|
|
147
|
-
expect(isRejection(result)).toBe(true);
|
|
148
|
-
if (isRejection(result))
|
|
149
|
-
expect(result.reason).toMatch(/structural/);
|
|
150
|
-
});
|
|
151
|
-
it('rejects when the element index is out of range', () => {
|
|
152
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
153
|
-
const result = translateMutation({ op: 'set', path: '$.body.content[5].paragraph.elements[0].textRun.content', value: 'y', beforeJson }, 'rev-1');
|
|
154
|
-
expect(isRejection(result)).toBe(true);
|
|
155
|
-
if (isRejection(result))
|
|
156
|
-
expect(result.reason).toMatch(/not found/);
|
|
157
|
-
});
|
|
158
|
-
it('rejects on a malformed buffer JSON (caller surfaces "fix syntax first")', () => {
|
|
159
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'x', beforeJson: '{ this is not valid JSON' }, 'rev-1');
|
|
160
|
-
expect(isRejection(result)).toBe(true);
|
|
161
|
-
if (isRejection(result))
|
|
162
|
-
expect(result.reason).toMatch(/JSON/);
|
|
163
|
-
});
|
|
164
|
-
});
|
|
165
|
-
describe('translateMutation — writeControl.requiredRevisionId', () => {
|
|
166
|
-
it('omits writeControl when no revisionId is provided', () => {
|
|
167
|
-
// E.g. an older import that didn't capture a revisionId. The API still
|
|
168
|
-
// accepts the request, just without optimistic-concurrency protection.
|
|
169
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
170
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'y', beforeJson }, undefined);
|
|
171
|
-
if (isRejection(result))
|
|
172
|
-
throw new Error('unexpected rejection');
|
|
173
|
-
expect(result.body.writeControl).toBeUndefined();
|
|
174
|
-
});
|
|
175
|
-
it('includes writeControl for paragraphStyle changes as well as text', () => {
|
|
176
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
177
|
-
const text = translateMutation({ op: 'set', path: TEXT_PATH, value: 'y', beforeJson }, 'rev-42');
|
|
178
|
-
const style = translateMutation({ op: 'set', path: STYLE_PATH, value: 'HEADING_2', beforeJson }, 'rev-42');
|
|
179
|
-
if (isRejection(text) || isRejection(style))
|
|
180
|
-
throw new Error('unexpected rejection');
|
|
181
|
-
expect(text.body.writeControl).toEqual({ requiredRevisionId: 'rev-42' });
|
|
182
|
-
expect(style.body.writeControl).toEqual({ requiredRevisionId: 'rev-42' });
|
|
183
|
-
});
|
|
184
|
-
});
|
|
185
|
-
describe('translateMutation — summary', () => {
|
|
186
|
-
it('summary names the path and (for text) the length delta', () => {
|
|
187
|
-
const beforeJson = docWith(textRunElement('Hello\n', 1));
|
|
188
|
-
const result = translateMutation({ op: 'set', path: TEXT_PATH, value: 'Goodbye', beforeJson }, 'rev-1');
|
|
189
|
-
if (isRejection(result))
|
|
190
|
-
throw new Error('unexpected rejection');
|
|
191
|
-
expect(result.summary).toMatch(/content\[0\].elements\[0\]/);
|
|
192
|
-
// 'Hello\n'.length = 6, 'Goodbye'.length = 7
|
|
193
|
-
expect(result.summary).toMatch(/6 → 7/);
|
|
194
|
-
});
|
|
195
|
-
it('summary names the paragraphStyle field for style changes', () => {
|
|
196
|
-
const beforeJson = docWith(textRunElement('x\n', 1));
|
|
197
|
-
const result = translateMutation({ op: 'set', path: STYLE_PATH, value: 'HEADING_1', beforeJson }, 'rev-1');
|
|
198
|
-
if (isRejection(result))
|
|
199
|
-
throw new Error('unexpected rejection');
|
|
200
|
-
expect(result.summary).toMatch(/paragraphStyle\.namedStyleType/);
|
|
201
|
-
});
|
|
202
|
-
});
|
|
203
|
-
/**
|
|
204
|
-
* Suggested next pass — handler-level integration tests that mock `execute`
|
|
205
|
-
* to cover the API-error-preserves-buffer and success-reloads-buffer cases.
|
|
206
|
-
* Co-located with this file would be reasonable; a separate file under the
|
|
207
|
-
* same dir keeps the unit-vs-integration split clear.
|
|
208
|
-
*
|
|
209
|
-
* - API rejects (stale revisionId, structural error) → buffer preserved.
|
|
210
|
-
* - API succeeds → reloadDocsBuffer fires, sp.lines replaced, binding
|
|
211
|
-
* revisionId updated from the fresh response.
|
|
212
|
-
*/
|
|
213
|
-
//# sourceMappingURL=docs-sync.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"docs-sync.test.js","sourceRoot":"","sources":["../../../../src/server/scratchpad/__tests__/docs-sync.test.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Tests for json-path.ts — JSON path parsing and manipulation helpers.
|
|
3
|
-
*/
|
|
4
|
-
import { parsePath, getByPath, setByPath, deleteByPath } from '../json-path.js';
|
|
5
|
-
describe('parsePath', () => {
|
|
6
|
-
it('parses $.foo.bar into string segments', () => {
|
|
7
|
-
expect(parsePath('$.foo.bar')).toEqual(['foo', 'bar']);
|
|
8
|
-
});
|
|
9
|
-
it('parses $.items[0] into mixed segments', () => {
|
|
10
|
-
expect(parsePath('$.items[0]')).toEqual(['items', 0]);
|
|
11
|
-
});
|
|
12
|
-
it('returns empty array for bare $', () => {
|
|
13
|
-
expect(parsePath('$')).toEqual([]);
|
|
14
|
-
});
|
|
15
|
-
it('returns empty array for empty string', () => {
|
|
16
|
-
expect(parsePath('')).toEqual([]);
|
|
17
|
-
});
|
|
18
|
-
it('parses deeply nested path with mixed access', () => {
|
|
19
|
-
expect(parsePath('$.a[1].b[2].c')).toEqual(['a', 1, 'b', 2, 'c']);
|
|
20
|
-
});
|
|
21
|
-
it('parses path without $ prefix', () => {
|
|
22
|
-
expect(parsePath('foo.bar')).toEqual(['foo', 'bar']);
|
|
23
|
-
});
|
|
24
|
-
it('distinguishes numeric strings from indices', () => {
|
|
25
|
-
// "01" is not a pure integer representation so stays as string
|
|
26
|
-
expect(parsePath('$.items[01]')).toEqual(['items', '01']);
|
|
27
|
-
});
|
|
28
|
-
});
|
|
29
|
-
describe('getByPath', () => {
|
|
30
|
-
const obj = {
|
|
31
|
-
name: 'test',
|
|
32
|
-
nested: { deep: { value: 42 } },
|
|
33
|
-
items: ['a', 'b', 'c'],
|
|
34
|
-
matrix: [[1, 2], [3, 4]],
|
|
35
|
-
};
|
|
36
|
-
it('gets a top-level key', () => {
|
|
37
|
-
expect(getByPath(obj, '$.name')).toBe('test');
|
|
38
|
-
});
|
|
39
|
-
it('gets a nested value', () => {
|
|
40
|
-
expect(getByPath(obj, '$.nested.deep.value')).toBe(42);
|
|
41
|
-
});
|
|
42
|
-
it('gets an array element by index', () => {
|
|
43
|
-
expect(getByPath(obj, '$.items[1]')).toBe('b');
|
|
44
|
-
});
|
|
45
|
-
it('gets nested array element', () => {
|
|
46
|
-
expect(getByPath(obj, '$.matrix[0][1]')).toBe(2);
|
|
47
|
-
});
|
|
48
|
-
it('returns undefined for missing key', () => {
|
|
49
|
-
expect(getByPath(obj, '$.missing')).toBeUndefined();
|
|
50
|
-
});
|
|
51
|
-
it('returns the root object for bare $', () => {
|
|
52
|
-
expect(getByPath(obj, '$')).toBe(obj);
|
|
53
|
-
});
|
|
54
|
-
it('throws on non-object traversal', () => {
|
|
55
|
-
expect(() => getByPath(obj, '$.name.child')).toThrow('cannot traverse into string');
|
|
56
|
-
});
|
|
57
|
-
it('throws when traversing through null', () => {
|
|
58
|
-
const o = { a: null };
|
|
59
|
-
expect(() => getByPath(o, '$.a.b')).toThrow('cannot traverse');
|
|
60
|
-
});
|
|
61
|
-
});
|
|
62
|
-
describe('setByPath', () => {
|
|
63
|
-
it('sets a top-level key', () => {
|
|
64
|
-
const obj = { a: 1 };
|
|
65
|
-
setByPath(obj, '$.b', 2);
|
|
66
|
-
expect(obj.b).toBe(2);
|
|
67
|
-
});
|
|
68
|
-
it('sets a nested value', () => {
|
|
69
|
-
const obj = { nested: { deep: { value: 0 } } };
|
|
70
|
-
setByPath(obj, '$.nested.deep.value', 99);
|
|
71
|
-
expect(obj.nested.deep.value).toBe(99);
|
|
72
|
-
});
|
|
73
|
-
it('sets an array element', () => {
|
|
74
|
-
const obj = { items: ['a', 'b', 'c'] };
|
|
75
|
-
setByPath(obj, '$.items[1]', 'B');
|
|
76
|
-
expect(obj.items[1]).toBe('B');
|
|
77
|
-
});
|
|
78
|
-
it('creates a new key on existing object', () => {
|
|
79
|
-
const obj = { existing: {} };
|
|
80
|
-
setByPath(obj, '$.existing.newKey', 'hello');
|
|
81
|
-
expect(obj.existing.newKey).toBe('hello');
|
|
82
|
-
});
|
|
83
|
-
it('throws on root path', () => {
|
|
84
|
-
expect(() => setByPath({}, '$', 'nope')).toThrow('Cannot set at root path');
|
|
85
|
-
});
|
|
86
|
-
it('throws when traversing through non-object', () => {
|
|
87
|
-
const obj = { a: 'string' };
|
|
88
|
-
expect(() => setByPath(obj, '$.a.b', 1)).toThrow('parent is not an object');
|
|
89
|
-
});
|
|
90
|
-
});
|
|
91
|
-
describe('deleteByPath', () => {
|
|
92
|
-
it('deletes an object key', () => {
|
|
93
|
-
const obj = { a: 1, b: 2 };
|
|
94
|
-
deleteByPath(obj, '$.b');
|
|
95
|
-
expect(obj).toEqual({ a: 1 });
|
|
96
|
-
expect('b' in obj).toBe(false);
|
|
97
|
-
});
|
|
98
|
-
it('deletes an array element by index (splice)', () => {
|
|
99
|
-
const obj = { items: [10, 20, 30] };
|
|
100
|
-
deleteByPath(obj, '$.items[1]');
|
|
101
|
-
expect(obj.items).toEqual([10, 30]);
|
|
102
|
-
});
|
|
103
|
-
it('deletes a nested key', () => {
|
|
104
|
-
const obj = { nested: { x: 1, y: 2 } };
|
|
105
|
-
deleteByPath(obj, '$.nested.x');
|
|
106
|
-
expect(obj.nested).toEqual({ y: 2 });
|
|
107
|
-
});
|
|
108
|
-
it('throws on root path', () => {
|
|
109
|
-
expect(() => deleteByPath({}, '$')).toThrow('Cannot delete root');
|
|
110
|
-
});
|
|
111
|
-
it('throws when traversing through non-object', () => {
|
|
112
|
-
const obj = { a: 42 };
|
|
113
|
-
expect(() => deleteByPath(obj, '$.a.b')).toThrow('parent is not an object');
|
|
114
|
-
});
|
|
115
|
-
it('deletes first array element', () => {
|
|
116
|
-
const obj = { items: ['x', 'y', 'z'] };
|
|
117
|
-
deleteByPath(obj, '$.items[0]');
|
|
118
|
-
expect(obj.items).toEqual(['y', 'z']);
|
|
119
|
-
});
|
|
120
|
-
});
|
|
121
|
-
//# sourceMappingURL=json-path.test.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"json-path.test.js","sourceRoot":"","sources":["../../../../src/server/scratchpad/__tests__/json-path.test.ts"],"names":[],"mappings":"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"}
|