@aigne/doc-smith 0.8.12-beta.8 → 0.8.12-beta.9
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/CHANGELOG.md +13 -0
- package/agents/publish/index.yaml +4 -0
- package/agents/publish/publish-docs.mjs +77 -5
- package/agents/publish/translate-meta.mjs +103 -0
- package/agents/update/generate-document.yaml +30 -28
- package/agents/update/update-document-detail.yaml +3 -1
- package/agents/utils/update-branding.mjs +69 -0
- package/package.json +16 -2
- package/prompts/common/document/role-and-personality.md +3 -1
- package/prompts/detail/d2-diagram/guide.md +7 -1
- package/prompts/detail/d2-diagram/user-prompt.md +3 -0
- package/prompts/detail/generate/system-prompt.md +6 -7
- package/prompts/detail/generate/user-prompt.md +12 -3
- package/prompts/detail/update/user-prompt.md +0 -2
- package/prompts/structure/update/user-prompt.md +0 -4
- package/utils/file-utils.mjs +69 -24
- package/utils/markdown-checker.mjs +0 -20
- package/utils/request.mjs +7 -0
- package/utils/upload-files.mjs +231 -0
- package/utils/utils.mjs +11 -1
- package/.aigne/doc-smith/config.yaml +0 -77
- package/.aigne/doc-smith/history.yaml +0 -37
- package/.aigne/doc-smith/media-description.yaml +0 -91
- package/.aigne/doc-smith/output/structure-plan.json +0 -162
- package/.aigne/doc-smith/preferences.yml +0 -97
- package/.aigne/doc-smith/upload-cache.yaml +0 -1830
- package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
- package/.github/workflows/ci.yml +0 -54
- package/.github/workflows/create-release-pr.yaml +0 -21
- package/.github/workflows/publish-docs.yml +0 -65
- package/.github/workflows/release.yml +0 -49
- package/.github/workflows/reviewer.yml +0 -54
- package/.release-please-manifest.json +0 -3
- package/RELEASE.md +0 -9
- package/assets/screenshots/doc-complete-setup.png +0 -0
- package/assets/screenshots/doc-generate-docs.png +0 -0
- package/assets/screenshots/doc-generate.png +0 -0
- package/assets/screenshots/doc-generated-successfully.png +0 -0
- package/assets/screenshots/doc-publish.png +0 -0
- package/assets/screenshots/doc-regenerate.png +0 -0
- package/assets/screenshots/doc-translate-langs.png +0 -0
- package/assets/screenshots/doc-translate.png +0 -0
- package/assets/screenshots/doc-update.png +0 -0
- package/biome.json +0 -73
- package/codecov.yml +0 -15
- package/docs/_sidebar.md +0 -15
- package/docs/configuration-initial-setup.ja.md +0 -179
- package/docs/configuration-initial-setup.md +0 -198
- package/docs/configuration-initial-setup.zh-TW.md +0 -179
- package/docs/configuration-initial-setup.zh.md +0 -179
- package/docs/configuration-managing-preferences.ja.md +0 -100
- package/docs/configuration-managing-preferences.md +0 -100
- package/docs/configuration-managing-preferences.zh-TW.md +0 -100
- package/docs/configuration-managing-preferences.zh.md +0 -100
- package/docs/configuration.ja.md +0 -69
- package/docs/configuration.md +0 -69
- package/docs/configuration.zh-TW.md +0 -69
- package/docs/configuration.zh.md +0 -69
- package/docs/getting-started.ja.md +0 -107
- package/docs/getting-started.md +0 -107
- package/docs/getting-started.zh-TW.md +0 -107
- package/docs/getting-started.zh.md +0 -107
- package/docs/guides-cleaning-up.ja.md +0 -51
- package/docs/guides-cleaning-up.md +0 -52
- package/docs/guides-cleaning-up.zh-TW.md +0 -51
- package/docs/guides-cleaning-up.zh.md +0 -51
- package/docs/guides-evaluating-documents.ja.md +0 -66
- package/docs/guides-evaluating-documents.md +0 -107
- package/docs/guides-evaluating-documents.zh-TW.md +0 -66
- package/docs/guides-evaluating-documents.zh.md +0 -66
- package/docs/guides-generating-documentation.ja.md +0 -151
- package/docs/guides-generating-documentation.md +0 -89
- package/docs/guides-generating-documentation.zh-TW.md +0 -151
- package/docs/guides-generating-documentation.zh.md +0 -151
- package/docs/guides-interactive-chat.ja.md +0 -85
- package/docs/guides-interactive-chat.md +0 -93
- package/docs/guides-interactive-chat.zh-TW.md +0 -85
- package/docs/guides-interactive-chat.zh.md +0 -85
- package/docs/guides-managing-history.ja.md +0 -48
- package/docs/guides-managing-history.md +0 -53
- package/docs/guides-managing-history.zh-TW.md +0 -48
- package/docs/guides-managing-history.zh.md +0 -48
- package/docs/guides-publishing-your-docs.ja.md +0 -78
- package/docs/guides-publishing-your-docs.md +0 -83
- package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
- package/docs/guides-publishing-your-docs.zh.md +0 -78
- package/docs/guides-translating-documentation.ja.md +0 -95
- package/docs/guides-translating-documentation.md +0 -100
- package/docs/guides-translating-documentation.zh-TW.md +0 -95
- package/docs/guides-translating-documentation.zh.md +0 -95
- package/docs/guides-updating-documentation.ja.md +0 -77
- package/docs/guides-updating-documentation.md +0 -79
- package/docs/guides-updating-documentation.zh-TW.md +0 -77
- package/docs/guides-updating-documentation.zh.md +0 -77
- package/docs/guides.ja.md +0 -32
- package/docs/guides.md +0 -32
- package/docs/guides.zh-TW.md +0 -32
- package/docs/guides.zh.md +0 -32
- package/docs/overview.ja.md +0 -61
- package/docs/overview.md +0 -61
- package/docs/overview.zh-TW.md +0 -61
- package/docs/overview.zh.md +0 -61
- package/docs/release-notes.ja.md +0 -255
- package/docs/release-notes.md +0 -288
- package/docs/release-notes.zh-TW.md +0 -255
- package/docs/release-notes.zh.md +0 -255
- package/prompts/common/afs/afs-tools-usage.md +0 -5
- package/prompts/common/afs/use-afs-instruction.md +0 -1
- package/release-please-config.json +0 -14
- package/tests/agents/chat/chat.test.mjs +0 -46
- package/tests/agents/clear/choose-contents.test.mjs +0 -284
- package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
- package/tests/agents/clear/clear-document-config.test.mjs +0 -167
- package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
- package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
- package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
- package/tests/agents/evaluate/fixtures/api-services.md +0 -87
- package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
- package/tests/agents/evaluate/generate-report.test.mjs +0 -312
- package/tests/agents/generate/check-document-structure.test.mjs +0 -45
- package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
- package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
- package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
- package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
- package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
- package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
- package/tests/agents/generate/generate-structure.test.mjs +0 -45
- package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
- package/tests/agents/history/view.test.mjs +0 -97
- package/tests/agents/init/init.test.mjs +0 -1657
- package/tests/agents/prefs/prefs.test.mjs +0 -431
- package/tests/agents/publish/publish-docs.test.mjs +0 -787
- package/tests/agents/translate/choose-language.test.mjs +0 -311
- package/tests/agents/translate/translate-document.test.mjs +0 -51
- package/tests/agents/update/check-document.test.mjs +0 -463
- package/tests/agents/update/check-update-is-single.test.mjs +0 -300
- package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
- package/tests/agents/update/generate-document.test.mjs +0 -51
- package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
- package/tests/agents/update/user-review-document.test.mjs +0 -582
- package/tests/agents/utils/action-success.test.mjs +0 -54
- package/tests/agents/utils/check-detail-result.test.mjs +0 -743
- package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
- package/tests/agents/utils/choose-docs.test.mjs +0 -406
- package/tests/agents/utils/exit.test.mjs +0 -70
- package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
- package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
- package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
- package/tests/agents/utils/format-document-structure.test.mjs +0 -364
- package/tests/agents/utils/fs.test.mjs +0 -267
- package/tests/agents/utils/load-sources.test.mjs +0 -1470
- package/tests/agents/utils/save-docs.test.mjs +0 -109
- package/tests/agents/utils/save-output.test.mjs +0 -315
- package/tests/agents/utils/save-single-doc.test.mjs +0 -364
- package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
- package/tests/utils/auth-utils.test.mjs +0 -596
- package/tests/utils/blocklet.test.mjs +0 -336
- package/tests/utils/conflict-detector.test.mjs +0 -355
- package/tests/utils/constants.test.mjs +0 -295
- package/tests/utils/d2-utils.test.mjs +0 -437
- package/tests/utils/deploy.test.mjs +0 -399
- package/tests/utils/docs-finder-utils.test.mjs +0 -650
- package/tests/utils/file-utils.test.mjs +0 -521
- package/tests/utils/history-utils.test.mjs +0 -206
- package/tests/utils/kroki-utils.test.mjs +0 -646
- package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
- package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
- package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
- package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
- package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
- package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
- package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
- package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
- package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
- package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
- package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
- package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
- package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
- package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
- package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
- package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
- package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
- package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
- package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
- package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
- package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
- package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
- package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
- package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
- package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
- package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
- package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
- package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
- package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
- package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
- package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
- package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
- package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
- package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
- package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
- package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
- package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
- package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
- package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
- package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
- package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
- package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
- package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
- package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
- package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
- package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
- package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
- package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
- package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
- package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
- package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
- package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
- package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
- package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
- package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
- package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
- package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
- package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
- package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
- package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
- package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
- package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
- package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
- package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
- package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
- package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
- package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
- package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
- package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
- package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
- package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
- package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
- package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
- package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
- package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
- package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
- package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
- package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
- package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
- package/tests/utils/linter/index.test.mjs +0 -440
- package/tests/utils/linter/scan-results.mjs +0 -42
- package/tests/utils/load-config.test.mjs +0 -141
- package/tests/utils/markdown/index.test.mjs +0 -478
- package/tests/utils/mermaid-validator.test.mjs +0 -541
- package/tests/utils/mock-chat-model.mjs +0 -12
- package/tests/utils/preferences-utils.test.mjs +0 -465
- package/tests/utils/save-value-to-config.test.mjs +0 -483
- package/tests/utils/utils.test.mjs +0 -941
|
@@ -1,268 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, mock, spyOn, test } from "bun:test";
|
|
2
|
-
import * as fs from "node:fs";
|
|
3
|
-
import * as fsPromises from "node:fs/promises";
|
|
4
|
-
import clearAuthTokens from "../../../agents/clear/clear-auth-tokens.mjs";
|
|
5
|
-
|
|
6
|
-
describe("clear-auth-tokens", () => {
|
|
7
|
-
let mockOptions;
|
|
8
|
-
let existsSyncSpy;
|
|
9
|
-
let readFileSpy;
|
|
10
|
-
let writeFileSpy;
|
|
11
|
-
|
|
12
|
-
beforeEach(() => {
|
|
13
|
-
mockOptions = {
|
|
14
|
-
prompts: {
|
|
15
|
-
checkbox: mock(async () => ["example.com"]),
|
|
16
|
-
},
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
// Mock file system operations
|
|
20
|
-
existsSyncSpy = spyOn(fs, "existsSync");
|
|
21
|
-
readFileSpy = spyOn(fsPromises, "readFile");
|
|
22
|
-
writeFileSpy = spyOn(fsPromises, "writeFile");
|
|
23
|
-
|
|
24
|
-
// Clear mock call history
|
|
25
|
-
mockOptions.prompts.checkbox.mockClear();
|
|
26
|
-
});
|
|
27
|
-
|
|
28
|
-
afterEach(() => {
|
|
29
|
-
// Restore all mocks
|
|
30
|
-
existsSyncSpy.mockRestore();
|
|
31
|
-
readFileSpy.mockRestore();
|
|
32
|
-
writeFileSpy.mockRestore();
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("should accept empty input", async () => {
|
|
36
|
-
// Mock file doesn't exist
|
|
37
|
-
existsSyncSpy.mockReturnValue(false);
|
|
38
|
-
|
|
39
|
-
const result = await clearAuthTokens({}, {});
|
|
40
|
-
expect(result).toBeDefined();
|
|
41
|
-
expect(result.message).toBeDefined();
|
|
42
|
-
expect(typeof result.message).toBe("string");
|
|
43
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
44
|
-
});
|
|
45
|
-
|
|
46
|
-
test("should handle missing prompts gracefully", async () => {
|
|
47
|
-
// Mock file exists with some data
|
|
48
|
-
existsSyncSpy.mockReturnValue(true);
|
|
49
|
-
readFileSpy.mockResolvedValue('example.com:\n token: "test-token"');
|
|
50
|
-
writeFileSpy.mockResolvedValue();
|
|
51
|
-
|
|
52
|
-
const result = await clearAuthTokens({}, {});
|
|
53
|
-
expect(result).toBeDefined();
|
|
54
|
-
expect(result.message).toBeDefined();
|
|
55
|
-
expect(result.clearedCount).toBe(1);
|
|
56
|
-
expect(result.clearedSites).toEqual(["example.com"]);
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
test("should handle empty options", async () => {
|
|
60
|
-
// Mock file doesn't exist
|
|
61
|
-
existsSyncSpy.mockReturnValue(false);
|
|
62
|
-
|
|
63
|
-
const result = await clearAuthTokens({});
|
|
64
|
-
expect(result).toBeDefined();
|
|
65
|
-
expect(result.message).toBeDefined();
|
|
66
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
67
|
-
});
|
|
68
|
-
|
|
69
|
-
test("should return consistent result structure", async () => {
|
|
70
|
-
// Mock file exists with multiple sites
|
|
71
|
-
existsSyncSpy.mockReturnValue(true);
|
|
72
|
-
readFileSpy.mockResolvedValue(
|
|
73
|
-
'example.com:\n token: "test-token"\ntest.com:\n token: "test-token2"',
|
|
74
|
-
);
|
|
75
|
-
writeFileSpy.mockResolvedValue();
|
|
76
|
-
|
|
77
|
-
const result = await clearAuthTokens({}, mockOptions);
|
|
78
|
-
expect(result).toBeDefined();
|
|
79
|
-
expect(result).toHaveProperty("message");
|
|
80
|
-
expect(typeof result.message).toBe("string");
|
|
81
|
-
|
|
82
|
-
// Result may have additional properties depending on file state
|
|
83
|
-
if (result.clearedCount !== undefined) {
|
|
84
|
-
expect(typeof result.clearedCount).toBe("number");
|
|
85
|
-
}
|
|
86
|
-
if (result.clearedSites !== undefined) {
|
|
87
|
-
expect(Array.isArray(result.clearedSites)).toBe(true);
|
|
88
|
-
}
|
|
89
|
-
if (result.error !== undefined) {
|
|
90
|
-
expect(typeof result.error).toBe("boolean");
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("should handle prompts correctly when file exists (integration test)", async () => {
|
|
95
|
-
// Mock file exists with data
|
|
96
|
-
existsSyncSpy.mockReturnValue(true);
|
|
97
|
-
readFileSpy.mockResolvedValue('example.com:\n token: "test-token"');
|
|
98
|
-
writeFileSpy.mockResolvedValue();
|
|
99
|
-
|
|
100
|
-
const result = await clearAuthTokens({}, mockOptions);
|
|
101
|
-
|
|
102
|
-
expect(result).toBeDefined();
|
|
103
|
-
expect(result.message).toBeDefined();
|
|
104
|
-
expect(result.clearedCount).toBe(1);
|
|
105
|
-
expect(result.clearedSites).toEqual(["example.com"]);
|
|
106
|
-
|
|
107
|
-
// Verify that prompts were called
|
|
108
|
-
expect(mockOptions.prompts.checkbox.mock.calls.length).toBeGreaterThan(0);
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
test("should provide meaningful error messages", async () => {
|
|
112
|
-
// Mock file doesn't exist
|
|
113
|
-
existsSyncSpy.mockReturnValue(false);
|
|
114
|
-
|
|
115
|
-
const result = await clearAuthTokens({}, {});
|
|
116
|
-
|
|
117
|
-
// Should return a user-friendly message regardless of internal state
|
|
118
|
-
expect(result.message).toBeDefined();
|
|
119
|
-
expect(result.message.length).toBeGreaterThan(0);
|
|
120
|
-
expect(typeof result.message).toBe("string");
|
|
121
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
122
|
-
});
|
|
123
|
-
|
|
124
|
-
test("should handle undefined input parameters", async () => {
|
|
125
|
-
// Mock file doesn't exist
|
|
126
|
-
existsSyncSpy.mockReturnValue(false);
|
|
127
|
-
|
|
128
|
-
const result = await clearAuthTokens(undefined, undefined);
|
|
129
|
-
expect(result).toBeDefined();
|
|
130
|
-
expect(result.message).toBeDefined();
|
|
131
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
test("should handle null input parameters", async () => {
|
|
135
|
-
// Mock file doesn't exist
|
|
136
|
-
existsSyncSpy.mockReturnValue(false);
|
|
137
|
-
|
|
138
|
-
const result = await clearAuthTokens(null, null);
|
|
139
|
-
expect(result).toBeDefined();
|
|
140
|
-
expect(result.message).toBeDefined();
|
|
141
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
test("should handle various option configurations", async () => {
|
|
145
|
-
// Mock file doesn't exist for all configurations
|
|
146
|
-
existsSyncSpy.mockReturnValue(false);
|
|
147
|
-
|
|
148
|
-
const configs = [
|
|
149
|
-
{},
|
|
150
|
-
{ prompts: {} },
|
|
151
|
-
{ prompts: { checkbox: undefined } },
|
|
152
|
-
{ prompts: { checkbox: null } },
|
|
153
|
-
];
|
|
154
|
-
|
|
155
|
-
for (const config of configs) {
|
|
156
|
-
const result = await clearAuthTokens({}, config);
|
|
157
|
-
expect(result).toBeDefined();
|
|
158
|
-
expect(result.message).toBeDefined();
|
|
159
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
160
|
-
}
|
|
161
|
-
});
|
|
162
|
-
|
|
163
|
-
test("should maintain consistent behavior across calls", async () => {
|
|
164
|
-
// Mock file doesn't exist for both calls
|
|
165
|
-
existsSyncSpy.mockReturnValue(false);
|
|
166
|
-
|
|
167
|
-
const result1 = await clearAuthTokens({}, {});
|
|
168
|
-
const result2 = await clearAuthTokens({}, {});
|
|
169
|
-
|
|
170
|
-
// Both calls should return the same type of result structure
|
|
171
|
-
expect(typeof result1.message).toBe(typeof result2.message);
|
|
172
|
-
expect(result1).toHaveProperty("message");
|
|
173
|
-
expect(result2).toHaveProperty("message");
|
|
174
|
-
expect(result1.message).toBe(result2.message);
|
|
175
|
-
});
|
|
176
|
-
|
|
177
|
-
test("should handle prompt validation function", async () => {
|
|
178
|
-
// Mock file exists with data to trigger prompts
|
|
179
|
-
existsSyncSpy.mockReturnValue(true);
|
|
180
|
-
readFileSpy.mockResolvedValue('example.com:\n token: "test-token"');
|
|
181
|
-
writeFileSpy.mockResolvedValue();
|
|
182
|
-
|
|
183
|
-
// Test that if prompts are called, they have proper validation
|
|
184
|
-
try {
|
|
185
|
-
await clearAuthTokens({}, mockOptions);
|
|
186
|
-
|
|
187
|
-
// If prompts were called, check the validation function exists
|
|
188
|
-
if (mockOptions.prompts.checkbox.mock.calls.length > 0) {
|
|
189
|
-
const callArgs = mockOptions.prompts.checkbox.mock.calls[0][0];
|
|
190
|
-
expect(callArgs).toHaveProperty("validate");
|
|
191
|
-
expect(typeof callArgs.validate).toBe("function");
|
|
192
|
-
|
|
193
|
-
// Test validation function behavior
|
|
194
|
-
const validateFn = callArgs.validate;
|
|
195
|
-
expect(validateFn([])).toBe("Please select at least one site.");
|
|
196
|
-
expect(validateFn(["site1"])).toBe(true);
|
|
197
|
-
expect(validateFn(["site1", "site2"])).toBe(true);
|
|
198
|
-
}
|
|
199
|
-
} catch (error) {
|
|
200
|
-
// If there's an error, ensure it's handled gracefully
|
|
201
|
-
expect(error).toBeDefined();
|
|
202
|
-
}
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
test("should handle file read errors gracefully", async () => {
|
|
206
|
-
// Mock file exists but reading fails
|
|
207
|
-
existsSyncSpy.mockReturnValue(true);
|
|
208
|
-
readFileSpy.mockRejectedValue(new Error("Permission denied"));
|
|
209
|
-
|
|
210
|
-
const result = await clearAuthTokens({}, {});
|
|
211
|
-
expect(result).toBeDefined();
|
|
212
|
-
expect(result.message).toBeDefined();
|
|
213
|
-
expect(result.error).toBe(true);
|
|
214
|
-
expect(result.message).toContain("Failed to clear site authorizations");
|
|
215
|
-
});
|
|
216
|
-
|
|
217
|
-
test("should handle file write errors gracefully", async () => {
|
|
218
|
-
// Mock file exists, reading succeeds, but writing fails
|
|
219
|
-
existsSyncSpy.mockReturnValue(true);
|
|
220
|
-
readFileSpy.mockResolvedValue('example.com:\n token: "test-token"');
|
|
221
|
-
writeFileSpy.mockRejectedValue(new Error("Disk full"));
|
|
222
|
-
|
|
223
|
-
const result = await clearAuthTokens({}, {});
|
|
224
|
-
expect(result).toBeDefined();
|
|
225
|
-
expect(result.message).toBeDefined();
|
|
226
|
-
expect(result.error).toBe(true);
|
|
227
|
-
expect(result.message).toContain("Failed to clear site authorizations");
|
|
228
|
-
});
|
|
229
|
-
|
|
230
|
-
test("should handle empty file content", async () => {
|
|
231
|
-
// Mock file exists but is empty
|
|
232
|
-
existsSyncSpy.mockReturnValue(true);
|
|
233
|
-
readFileSpy.mockResolvedValue("");
|
|
234
|
-
|
|
235
|
-
const result = await clearAuthTokens({}, {});
|
|
236
|
-
expect(result).toBeDefined();
|
|
237
|
-
expect(result.message).toBeDefined();
|
|
238
|
-
expect(result.message).toBe("No site authorizations found to clear");
|
|
239
|
-
});
|
|
240
|
-
|
|
241
|
-
test("should handle malformed YAML content", async () => {
|
|
242
|
-
// Mock file exists with invalid YAML
|
|
243
|
-
existsSyncSpy.mockReturnValue(true);
|
|
244
|
-
readFileSpy.mockResolvedValue("invalid: yaml: content: [");
|
|
245
|
-
|
|
246
|
-
const result = await clearAuthTokens({}, {});
|
|
247
|
-
expect(result).toBeDefined();
|
|
248
|
-
expect(result.message).toBeDefined();
|
|
249
|
-
expect(result.error).toBe(true);
|
|
250
|
-
expect(result.message).toContain("Failed to clear site authorizations");
|
|
251
|
-
});
|
|
252
|
-
|
|
253
|
-
test("should handle empty selection from prompts", async () => {
|
|
254
|
-
// Mock file exists with data but user selects nothing
|
|
255
|
-
existsSyncSpy.mockReturnValue(true);
|
|
256
|
-
readFileSpy.mockResolvedValue('example.com:\n token: "test-token"');
|
|
257
|
-
|
|
258
|
-
const emptySelectionOptions = {
|
|
259
|
-
prompts: {
|
|
260
|
-
checkbox: mock(async () => []), // User selects nothing
|
|
261
|
-
},
|
|
262
|
-
};
|
|
263
|
-
|
|
264
|
-
const result = await clearAuthTokens({}, emptySelectionOptions);
|
|
265
|
-
expect(result).toBeDefined();
|
|
266
|
-
expect(result.message).toBe("No sites selected for clearing authorization");
|
|
267
|
-
});
|
|
268
|
-
});
|
|
@@ -1,167 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
|
|
2
|
-
import * as fsPromises from "node:fs/promises";
|
|
3
|
-
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
4
|
-
import { dirname, join } from "node:path";
|
|
5
|
-
import { fileURLToPath } from "node:url";
|
|
6
|
-
import clearDocumentConfig from "../../../agents/clear/clear-document-config.mjs";
|
|
7
|
-
|
|
8
|
-
const __dirname = dirname(fileURLToPath(import.meta.url));
|
|
9
|
-
|
|
10
|
-
describe("clear-document-config", () => {
|
|
11
|
-
let testDir;
|
|
12
|
-
let configPath;
|
|
13
|
-
|
|
14
|
-
beforeEach(async () => {
|
|
15
|
-
// Create a temporary test directory
|
|
16
|
-
testDir = join(__dirname, "test-clear-config");
|
|
17
|
-
await mkdir(testDir, { recursive: true });
|
|
18
|
-
|
|
19
|
-
// Create .aigne/doc-smith directory structure
|
|
20
|
-
const aigneDir = join(testDir, ".aigne", "doc-smith");
|
|
21
|
-
await mkdir(aigneDir, { recursive: true });
|
|
22
|
-
|
|
23
|
-
configPath = join(aigneDir, "config.yaml");
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
afterEach(async () => {
|
|
27
|
-
// Clean up test directory
|
|
28
|
-
try {
|
|
29
|
-
await rm(testDir, { recursive: true, force: true });
|
|
30
|
-
} catch {
|
|
31
|
-
// Ignore cleanup errors since they don't affect test results
|
|
32
|
-
}
|
|
33
|
-
});
|
|
34
|
-
|
|
35
|
-
test("should clear existing document configuration successfully", async () => {
|
|
36
|
-
// Create a test config file
|
|
37
|
-
const configContent = `
|
|
38
|
-
projectName: "Test Project"
|
|
39
|
-
projectDesc: "Test Description"
|
|
40
|
-
locale: "en"
|
|
41
|
-
documentPurpose: ["API", "Tutorial"]
|
|
42
|
-
`;
|
|
43
|
-
await writeFile(configPath, configContent);
|
|
44
|
-
|
|
45
|
-
const result = await clearDocumentConfig({ workDir: testDir });
|
|
46
|
-
|
|
47
|
-
expect(result.cleared).toBe(true);
|
|
48
|
-
expect(result.message).toContain("Cleared document configuration");
|
|
49
|
-
expect(result.path).toBeDefined();
|
|
50
|
-
expect(result.suggestions).toEqual([
|
|
51
|
-
"Run `aigne doc init` to generate a fresh configuration file.",
|
|
52
|
-
]);
|
|
53
|
-
|
|
54
|
-
// Verify file is actually deleted
|
|
55
|
-
const { pathExists } = await import("../../../utils/file-utils.mjs");
|
|
56
|
-
const exists = await pathExists(configPath);
|
|
57
|
-
expect(exists).toBe(false);
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
test("should handle non-existent configuration file", async () => {
|
|
61
|
-
// Don't create the config file
|
|
62
|
-
const result = await clearDocumentConfig({ workDir: testDir });
|
|
63
|
-
|
|
64
|
-
expect(result.cleared).toBe(false);
|
|
65
|
-
expect(result.message).toContain("Document configuration already empty");
|
|
66
|
-
expect(result.path).toBeDefined();
|
|
67
|
-
expect(result.suggestions).toEqual([]);
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
test("should use current working directory when workDir not provided", async () => {
|
|
71
|
-
const originalCwd = process.cwd();
|
|
72
|
-
|
|
73
|
-
try {
|
|
74
|
-
// Change to test directory
|
|
75
|
-
process.chdir(testDir);
|
|
76
|
-
|
|
77
|
-
// Create config in current directory's .aigne structure
|
|
78
|
-
await writeFile(configPath, "test: content");
|
|
79
|
-
|
|
80
|
-
const result = await clearDocumentConfig({});
|
|
81
|
-
|
|
82
|
-
expect(result.cleared).toBe(true);
|
|
83
|
-
expect(result.message).toContain("Cleared document configuration");
|
|
84
|
-
} finally {
|
|
85
|
-
// Restore original working directory
|
|
86
|
-
process.chdir(originalCwd);
|
|
87
|
-
}
|
|
88
|
-
});
|
|
89
|
-
|
|
90
|
-
test("should provide correct return structure", async () => {
|
|
91
|
-
await writeFile(configPath, "test: content");
|
|
92
|
-
|
|
93
|
-
const result = await clearDocumentConfig({ workDir: testDir });
|
|
94
|
-
|
|
95
|
-
expect(result).toHaveProperty("message");
|
|
96
|
-
expect(result).toHaveProperty("cleared");
|
|
97
|
-
expect(result).toHaveProperty("path");
|
|
98
|
-
expect(result).toHaveProperty("suggestions");
|
|
99
|
-
expect(typeof result.message).toBe("string");
|
|
100
|
-
expect(typeof result.cleared).toBe("boolean");
|
|
101
|
-
expect(typeof result.path).toBe("string");
|
|
102
|
-
expect(Array.isArray(result.suggestions)).toBe(true);
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
test("should have correct task metadata", () => {
|
|
106
|
-
expect(clearDocumentConfig.taskTitle).toBe("Clear document configuration");
|
|
107
|
-
expect(clearDocumentConfig.description).toBe("Clear the document configuration file");
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test("should handle nested directory structures", async () => {
|
|
111
|
-
// Create nested test directory
|
|
112
|
-
const nestedDir = join(testDir, "nested", "project");
|
|
113
|
-
await mkdir(nestedDir, { recursive: true });
|
|
114
|
-
|
|
115
|
-
const nestedAigneDir = join(nestedDir, ".aigne", "doc-smith");
|
|
116
|
-
await mkdir(nestedAigneDir, { recursive: true });
|
|
117
|
-
|
|
118
|
-
const nestedConfigPath = join(nestedAigneDir, "config.yaml");
|
|
119
|
-
await writeFile(nestedConfigPath, "nested: config");
|
|
120
|
-
|
|
121
|
-
const result = await clearDocumentConfig({ workDir: nestedDir });
|
|
122
|
-
|
|
123
|
-
expect(result.cleared).toBe(true);
|
|
124
|
-
expect(result.message).toContain("Cleared document configuration");
|
|
125
|
-
|
|
126
|
-
// Verify nested file is deleted
|
|
127
|
-
const { pathExists } = await import("../../../utils/file-utils.mjs");
|
|
128
|
-
const exists = await pathExists(nestedConfigPath);
|
|
129
|
-
expect(exists).toBe(false);
|
|
130
|
-
});
|
|
131
|
-
|
|
132
|
-
test("should handle path with special characters", async () => {
|
|
133
|
-
// Create directory with spaces and special characters
|
|
134
|
-
const specialDir = join(testDir, "special dir-with_chars");
|
|
135
|
-
await mkdir(specialDir, { recursive: true });
|
|
136
|
-
|
|
137
|
-
const specialAigneDir = join(specialDir, ".aigne", "doc-smith");
|
|
138
|
-
await mkdir(specialAigneDir, { recursive: true });
|
|
139
|
-
|
|
140
|
-
const specialConfigPath = join(specialAigneDir, "config.yaml");
|
|
141
|
-
await writeFile(specialConfigPath, "special: config");
|
|
142
|
-
|
|
143
|
-
const result = await clearDocumentConfig({ workDir: specialDir });
|
|
144
|
-
|
|
145
|
-
expect(result.cleared).toBe(true);
|
|
146
|
-
expect(result.message).toContain("Cleared document configuration");
|
|
147
|
-
});
|
|
148
|
-
|
|
149
|
-
test("should handle file system errors gracefully", async () => {
|
|
150
|
-
// Create a spy on rm to simulate an error
|
|
151
|
-
const rmSpy = spyOn(fsPromises, "rm");
|
|
152
|
-
rmSpy.mockImplementation(() => {
|
|
153
|
-
throw new Error("Permission denied");
|
|
154
|
-
});
|
|
155
|
-
|
|
156
|
-
try {
|
|
157
|
-
const result = await clearDocumentConfig({ workDir: testDir });
|
|
158
|
-
|
|
159
|
-
expect(result.error).toBe(true);
|
|
160
|
-
expect(result.message).toContain("Failed to clear document configuration");
|
|
161
|
-
expect(result.message).toContain("Permission denied");
|
|
162
|
-
expect(result.path).toBeDefined();
|
|
163
|
-
} finally {
|
|
164
|
-
rmSpy.mockRestore();
|
|
165
|
-
}
|
|
166
|
-
});
|
|
167
|
-
});
|