@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,336 +0,0 @@
|
|
|
1
|
-
import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
|
|
2
|
-
import {
|
|
3
|
-
ComponentNotFoundError,
|
|
4
|
-
getComponentMountPoint,
|
|
5
|
-
InvalidBlockletError,
|
|
6
|
-
} from "../../utils/blocklet.mjs";
|
|
7
|
-
|
|
8
|
-
describe("blocklet", () => {
|
|
9
|
-
let mockFetch;
|
|
10
|
-
beforeEach(() => {
|
|
11
|
-
// Mock global fetch
|
|
12
|
-
mockFetch = spyOn(global, "fetch").mockResolvedValue({
|
|
13
|
-
ok: true,
|
|
14
|
-
json: () => Promise.resolve({ name: "test-repo", description: "Test repo" }),
|
|
15
|
-
statusText: "OK",
|
|
16
|
-
});
|
|
17
|
-
});
|
|
18
|
-
|
|
19
|
-
afterEach(() => {
|
|
20
|
-
mockFetch?.mockRestore();
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
// ERROR CLASSES TESTS
|
|
24
|
-
describe("InvalidBlockletError", () => {
|
|
25
|
-
test("should create error with correct properties", () => {
|
|
26
|
-
const url = "https://example.com";
|
|
27
|
-
const status = 404;
|
|
28
|
-
const statusText = "Not Found";
|
|
29
|
-
|
|
30
|
-
const error = new InvalidBlockletError(url, status, statusText);
|
|
31
|
-
|
|
32
|
-
expect(error).toBeInstanceOf(Error);
|
|
33
|
-
expect(error.name).toBe("InvalidBlockletError");
|
|
34
|
-
expect(error.message).toBe(
|
|
35
|
-
'Invalid application URL: "https://example.com". Unable to fetch configuration.',
|
|
36
|
-
);
|
|
37
|
-
expect(error.url).toBe(url);
|
|
38
|
-
expect(error.status).toBe(status);
|
|
39
|
-
expect(error.statusText).toBe(statusText);
|
|
40
|
-
});
|
|
41
|
-
|
|
42
|
-
test("should handle null status and statusText", () => {
|
|
43
|
-
const url = "https://example.com";
|
|
44
|
-
|
|
45
|
-
const error = new InvalidBlockletError(url, null, "Network error");
|
|
46
|
-
|
|
47
|
-
expect(error.url).toBe(url);
|
|
48
|
-
expect(error.status).toBeNull();
|
|
49
|
-
expect(error.statusText).toBe("Network error");
|
|
50
|
-
});
|
|
51
|
-
|
|
52
|
-
test("should be instanceof Error", () => {
|
|
53
|
-
const error = new InvalidBlockletError("https://example.com");
|
|
54
|
-
expect(error instanceof Error).toBe(true);
|
|
55
|
-
expect(error instanceof InvalidBlockletError).toBe(true);
|
|
56
|
-
});
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
describe("ComponentNotFoundError", () => {
|
|
60
|
-
test("should create error with correct properties", () => {
|
|
61
|
-
const did = "z8ia28nJVd6UMcS4dcJf5NLhv3rLmrFCK";
|
|
62
|
-
const appUrl = "https://example.com";
|
|
63
|
-
|
|
64
|
-
const error = new ComponentNotFoundError(did, appUrl);
|
|
65
|
-
|
|
66
|
-
expect(error).toBeInstanceOf(Error);
|
|
67
|
-
expect(error.name).toBe("ComponentNotFoundError");
|
|
68
|
-
expect(error.message).toBe(
|
|
69
|
-
'Your website "https://example.com" missing required component to host your docs.',
|
|
70
|
-
);
|
|
71
|
-
expect(error.did).toBe(did);
|
|
72
|
-
expect(error.appUrl).toBe(appUrl);
|
|
73
|
-
});
|
|
74
|
-
|
|
75
|
-
test("should be instanceof Error", () => {
|
|
76
|
-
const error = new ComponentNotFoundError("test-did", "https://example.com");
|
|
77
|
-
expect(error instanceof Error).toBe(true);
|
|
78
|
-
expect(error instanceof ComponentNotFoundError).toBe(true);
|
|
79
|
-
});
|
|
80
|
-
});
|
|
81
|
-
|
|
82
|
-
// GETCOMPONENTMOUNTPOINT FUNCTION TESTS
|
|
83
|
-
describe("getComponentMountPoint", () => {
|
|
84
|
-
const testAppUrl = "https://example.com";
|
|
85
|
-
const testDid = "z8ia28nJVd6UMcS4dcJf5NLhv3rLmrFCK";
|
|
86
|
-
const expectedUrl = "https://example.com/__blocklet__.js?type=json";
|
|
87
|
-
|
|
88
|
-
test("should return mount point for existing component", async () => {
|
|
89
|
-
const mockConfig = {
|
|
90
|
-
componentMountPoints: [
|
|
91
|
-
{ did: "other-did", mountPoint: "/other" },
|
|
92
|
-
{ did: testDid, mountPoint: "/api/discuss" },
|
|
93
|
-
{ did: "another-did", mountPoint: "/another" },
|
|
94
|
-
],
|
|
95
|
-
};
|
|
96
|
-
|
|
97
|
-
mockFetch.mockResolvedValue({
|
|
98
|
-
ok: true,
|
|
99
|
-
json: () => Promise.resolve(mockConfig),
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
103
|
-
|
|
104
|
-
expect(result).toBe("/api/discuss");
|
|
105
|
-
expect(mockFetch).toHaveBeenCalledWith(expectedUrl, {
|
|
106
|
-
method: "GET",
|
|
107
|
-
headers: { Accept: "application/json" },
|
|
108
|
-
});
|
|
109
|
-
});
|
|
110
|
-
|
|
111
|
-
// NETWORK ERROR TESTS
|
|
112
|
-
test("should throw InvalidBlockletError when fetch fails", async () => {
|
|
113
|
-
mockFetch.mockRejectedValue(new Error("Network timeout"));
|
|
114
|
-
|
|
115
|
-
await expect(getComponentMountPoint(testAppUrl, testDid)).rejects.toThrow(
|
|
116
|
-
InvalidBlockletError,
|
|
117
|
-
);
|
|
118
|
-
|
|
119
|
-
try {
|
|
120
|
-
await getComponentMountPoint(testAppUrl, testDid);
|
|
121
|
-
} catch (error) {
|
|
122
|
-
expect(error.url).toBe(testAppUrl);
|
|
123
|
-
expect(error.status).toBeNull();
|
|
124
|
-
expect(error.statusText).toBe("Network timeout");
|
|
125
|
-
}
|
|
126
|
-
});
|
|
127
|
-
|
|
128
|
-
test("should throw InvalidBlockletError when response is not ok", async () => {
|
|
129
|
-
mockFetch.mockResolvedValue({
|
|
130
|
-
ok: false,
|
|
131
|
-
status: 404,
|
|
132
|
-
statusText: "Not Found",
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
await expect(getComponentMountPoint(testAppUrl, testDid)).rejects.toThrow(
|
|
136
|
-
InvalidBlockletError,
|
|
137
|
-
);
|
|
138
|
-
|
|
139
|
-
try {
|
|
140
|
-
await getComponentMountPoint(testAppUrl, testDid);
|
|
141
|
-
} catch (error) {
|
|
142
|
-
expect(error.url).toBe(testAppUrl);
|
|
143
|
-
expect(error.status).toBe(404);
|
|
144
|
-
expect(error.statusText).toBe("Not Found");
|
|
145
|
-
}
|
|
146
|
-
});
|
|
147
|
-
|
|
148
|
-
test("should throw InvalidBlockletError when JSON parsing fails", async () => {
|
|
149
|
-
mockFetch.mockResolvedValue({
|
|
150
|
-
ok: true,
|
|
151
|
-
json: () => Promise.reject(new Error("Invalid JSON")),
|
|
152
|
-
});
|
|
153
|
-
|
|
154
|
-
await expect(getComponentMountPoint(testAppUrl, testDid)).rejects.toThrow(
|
|
155
|
-
InvalidBlockletError,
|
|
156
|
-
);
|
|
157
|
-
|
|
158
|
-
try {
|
|
159
|
-
await getComponentMountPoint(testAppUrl, testDid);
|
|
160
|
-
} catch (error) {
|
|
161
|
-
expect(error.url).toBe(testAppUrl);
|
|
162
|
-
expect(error.status).toBeNull();
|
|
163
|
-
expect(error.statusText).toBe("Invalid JSON response");
|
|
164
|
-
}
|
|
165
|
-
});
|
|
166
|
-
|
|
167
|
-
// COMPONENT NOT FOUND TESTS
|
|
168
|
-
test("should throw ComponentNotFoundError when component is not found", async () => {
|
|
169
|
-
const mockConfig = {
|
|
170
|
-
componentMountPoints: [
|
|
171
|
-
{ did: "other-did", mountPoint: "/other" },
|
|
172
|
-
{ did: "another-did", mountPoint: "/another" },
|
|
173
|
-
],
|
|
174
|
-
};
|
|
175
|
-
|
|
176
|
-
mockFetch.mockResolvedValue({
|
|
177
|
-
ok: true,
|
|
178
|
-
json: () => Promise.resolve(mockConfig),
|
|
179
|
-
});
|
|
180
|
-
|
|
181
|
-
await expect(getComponentMountPoint(testAppUrl, testDid)).rejects.toThrow(
|
|
182
|
-
ComponentNotFoundError,
|
|
183
|
-
);
|
|
184
|
-
|
|
185
|
-
try {
|
|
186
|
-
await getComponentMountPoint(testAppUrl, testDid);
|
|
187
|
-
} catch (error) {
|
|
188
|
-
expect(error.did).toBe(testDid);
|
|
189
|
-
expect(error.appUrl).toBe(testAppUrl);
|
|
190
|
-
}
|
|
191
|
-
});
|
|
192
|
-
|
|
193
|
-
test("should throw ComponentNotFoundError when componentMountPoints is undefined", async () => {
|
|
194
|
-
const mockConfig = {};
|
|
195
|
-
|
|
196
|
-
mockFetch.mockResolvedValue({
|
|
197
|
-
ok: true,
|
|
198
|
-
json: () => Promise.resolve(mockConfig),
|
|
199
|
-
});
|
|
200
|
-
|
|
201
|
-
await expect(getComponentMountPoint(testAppUrl, testDid)).rejects.toThrow(
|
|
202
|
-
ComponentNotFoundError,
|
|
203
|
-
);
|
|
204
|
-
});
|
|
205
|
-
|
|
206
|
-
test("should throw ComponentNotFoundError when componentMountPoints is empty", async () => {
|
|
207
|
-
const mockConfig = {
|
|
208
|
-
componentMountPoints: [],
|
|
209
|
-
};
|
|
210
|
-
|
|
211
|
-
mockFetch.mockResolvedValue({
|
|
212
|
-
ok: true,
|
|
213
|
-
json: () => Promise.resolve(mockConfig),
|
|
214
|
-
});
|
|
215
|
-
|
|
216
|
-
await expect(getComponentMountPoint(testAppUrl, testDid)).rejects.toThrow(
|
|
217
|
-
ComponentNotFoundError,
|
|
218
|
-
);
|
|
219
|
-
});
|
|
220
|
-
|
|
221
|
-
// EDGE CASES
|
|
222
|
-
test("should handle component at the beginning of array", async () => {
|
|
223
|
-
const mockConfig = {
|
|
224
|
-
componentMountPoints: [
|
|
225
|
-
{ did: testDid, mountPoint: "/first" },
|
|
226
|
-
{ did: "other-did", mountPoint: "/other" },
|
|
227
|
-
],
|
|
228
|
-
};
|
|
229
|
-
|
|
230
|
-
mockFetch.mockResolvedValue({
|
|
231
|
-
ok: true,
|
|
232
|
-
json: () => Promise.resolve(mockConfig),
|
|
233
|
-
});
|
|
234
|
-
|
|
235
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
236
|
-
expect(result).toBe("/first");
|
|
237
|
-
});
|
|
238
|
-
|
|
239
|
-
test("should handle component at the end of array", async () => {
|
|
240
|
-
const mockConfig = {
|
|
241
|
-
componentMountPoints: [
|
|
242
|
-
{ did: "other-did", mountPoint: "/other" },
|
|
243
|
-
{ did: testDid, mountPoint: "/last" },
|
|
244
|
-
],
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
mockFetch.mockResolvedValue({
|
|
248
|
-
ok: true,
|
|
249
|
-
json: () => Promise.resolve(mockConfig),
|
|
250
|
-
});
|
|
251
|
-
|
|
252
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
253
|
-
expect(result).toBe("/last");
|
|
254
|
-
});
|
|
255
|
-
|
|
256
|
-
test("should handle single component", async () => {
|
|
257
|
-
const mockConfig = {
|
|
258
|
-
componentMountPoints: [{ did: testDid, mountPoint: "/single" }],
|
|
259
|
-
};
|
|
260
|
-
|
|
261
|
-
mockFetch.mockResolvedValue({
|
|
262
|
-
ok: true,
|
|
263
|
-
json: () => Promise.resolve(mockConfig),
|
|
264
|
-
});
|
|
265
|
-
|
|
266
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
267
|
-
expect(result).toBe("/single");
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
test("should handle complex mount points", async () => {
|
|
271
|
-
const mockConfig = {
|
|
272
|
-
componentMountPoints: [{ did: testDid, mountPoint: "/api/v1/discuss-kit/endpoint" }],
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
mockFetch.mockResolvedValue({
|
|
276
|
-
ok: true,
|
|
277
|
-
json: () => Promise.resolve(mockConfig),
|
|
278
|
-
});
|
|
279
|
-
|
|
280
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
281
|
-
expect(result).toBe("/api/v1/discuss-kit/endpoint");
|
|
282
|
-
});
|
|
283
|
-
|
|
284
|
-
test("should handle empty mount point", async () => {
|
|
285
|
-
const mockConfig = {
|
|
286
|
-
componentMountPoints: [{ did: testDid, mountPoint: "" }],
|
|
287
|
-
};
|
|
288
|
-
|
|
289
|
-
mockFetch.mockResolvedValue({
|
|
290
|
-
ok: true,
|
|
291
|
-
json: () => Promise.resolve(mockConfig),
|
|
292
|
-
});
|
|
293
|
-
|
|
294
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
295
|
-
expect(result).toBe("");
|
|
296
|
-
});
|
|
297
|
-
|
|
298
|
-
test("should handle null/undefined mount point", async () => {
|
|
299
|
-
const mockConfig = {
|
|
300
|
-
componentMountPoints: [{ did: testDid, mountPoint: null }],
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
mockFetch.mockResolvedValue({
|
|
304
|
-
ok: true,
|
|
305
|
-
json: () => Promise.resolve(mockConfig),
|
|
306
|
-
});
|
|
307
|
-
|
|
308
|
-
const result = await getComponentMountPoint(testAppUrl, testDid);
|
|
309
|
-
expect(result).toBeNull();
|
|
310
|
-
});
|
|
311
|
-
|
|
312
|
-
// NETWORK TIMEOUT AND RETRY SCENARIOS
|
|
313
|
-
test("should handle network errors with different error types", async () => {
|
|
314
|
-
const errorTypes = [
|
|
315
|
-
new TypeError("Failed to fetch"),
|
|
316
|
-
new Error("Connection refused"),
|
|
317
|
-
new Error("Timeout"),
|
|
318
|
-
new ReferenceError("Network error"),
|
|
319
|
-
];
|
|
320
|
-
|
|
321
|
-
for (const error of errorTypes) {
|
|
322
|
-
mockFetch.mockRejectedValueOnce(error);
|
|
323
|
-
|
|
324
|
-
try {
|
|
325
|
-
await getComponentMountPoint(testAppUrl, testDid);
|
|
326
|
-
expect(true).toBe(false); // Should not reach here
|
|
327
|
-
} catch (caughtError) {
|
|
328
|
-
expect(caughtError).toBeInstanceOf(InvalidBlockletError);
|
|
329
|
-
expect(caughtError.url).toBe(testAppUrl);
|
|
330
|
-
expect(caughtError.status).toBeNull();
|
|
331
|
-
expect(caughtError.statusText).toBe(error.message);
|
|
332
|
-
}
|
|
333
|
-
}
|
|
334
|
-
});
|
|
335
|
-
});
|
|
336
|
-
});
|
|
@@ -1,355 +0,0 @@
|
|
|
1
|
-
import { describe, expect, test } from "bun:test";
|
|
2
|
-
import {
|
|
3
|
-
detectResolvableConflicts,
|
|
4
|
-
generateConflictResolutionRules,
|
|
5
|
-
getFilteredOptions,
|
|
6
|
-
} from "../../utils/conflict-detector.mjs";
|
|
7
|
-
import { processConfigFields } from "../../utils/utils.mjs";
|
|
8
|
-
|
|
9
|
-
describe("conflict-detector", () => {
|
|
10
|
-
describe("getFilteredOptions", () => {
|
|
11
|
-
test("should filter experiencedUsers when documentPurpose is getStarted", () => {
|
|
12
|
-
const allOptions = {
|
|
13
|
-
completeBeginners: "Complete beginners",
|
|
14
|
-
domainFamiliar: "Domain familiar",
|
|
15
|
-
experiencedUsers: "Experienced users",
|
|
16
|
-
emergencyTroubleshooting: "Emergency troubleshooting",
|
|
17
|
-
};
|
|
18
|
-
|
|
19
|
-
const currentSelections = {
|
|
20
|
-
documentPurpose: ["getStarted"],
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const result = getFilteredOptions("readerKnowledgeLevel", currentSelections, allOptions);
|
|
24
|
-
|
|
25
|
-
expect(result.filteredOptions).not.toHaveProperty("experiencedUsers");
|
|
26
|
-
expect(result.appliedFilters).toHaveLength(1);
|
|
27
|
-
expect(result.appliedFilters[0].removedOption).toBe("experiencedUsers");
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
test("should filter completeBeginners when documentPurpose is findAnswers", () => {
|
|
31
|
-
const allOptions = {
|
|
32
|
-
completeBeginners: "Complete beginners",
|
|
33
|
-
domainFamiliar: "Domain familiar",
|
|
34
|
-
experiencedUsers: "Experienced users",
|
|
35
|
-
};
|
|
36
|
-
|
|
37
|
-
const currentSelections = {
|
|
38
|
-
documentPurpose: ["findAnswers"],
|
|
39
|
-
};
|
|
40
|
-
|
|
41
|
-
const result = getFilteredOptions("readerKnowledgeLevel", currentSelections, allOptions);
|
|
42
|
-
|
|
43
|
-
expect(result.filteredOptions).not.toHaveProperty("completeBeginners");
|
|
44
|
-
expect(result.appliedFilters).toHaveLength(1);
|
|
45
|
-
expect(result.appliedFilters[0].removedOption).toBe("completeBeginners");
|
|
46
|
-
});
|
|
47
|
-
|
|
48
|
-
test("should filter emergencyTroubleshooting when documentPurpose is understandSystem", () => {
|
|
49
|
-
const allOptions = {
|
|
50
|
-
completeBeginners: "Complete beginners",
|
|
51
|
-
emergencyTroubleshooting: "Emergency troubleshooting",
|
|
52
|
-
};
|
|
53
|
-
|
|
54
|
-
const currentSelections = {
|
|
55
|
-
documentPurpose: ["understandSystem"],
|
|
56
|
-
};
|
|
57
|
-
|
|
58
|
-
const result = getFilteredOptions("readerKnowledgeLevel", currentSelections, allOptions);
|
|
59
|
-
|
|
60
|
-
expect(result.filteredOptions).not.toHaveProperty("emergencyTroubleshooting");
|
|
61
|
-
expect(result.appliedFilters).toHaveLength(1);
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
test("should filter experiencedUsers when targetAudienceTypes includes endUsers", () => {
|
|
65
|
-
const allOptions = {
|
|
66
|
-
completeBeginners: "Complete beginners",
|
|
67
|
-
experiencedUsers: "Experienced users",
|
|
68
|
-
};
|
|
69
|
-
|
|
70
|
-
const currentSelections = {
|
|
71
|
-
targetAudienceTypes: ["endUsers"],
|
|
72
|
-
};
|
|
73
|
-
|
|
74
|
-
const result = getFilteredOptions("readerKnowledgeLevel", currentSelections, allOptions);
|
|
75
|
-
|
|
76
|
-
expect(result.filteredOptions).not.toHaveProperty("experiencedUsers");
|
|
77
|
-
expect(result.appliedFilters).toHaveLength(1);
|
|
78
|
-
});
|
|
79
|
-
|
|
80
|
-
test("should return original options when no conflicts", () => {
|
|
81
|
-
const allOptions = {
|
|
82
|
-
option1: "Option 1",
|
|
83
|
-
option2: "Option 2",
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const currentSelections = {};
|
|
87
|
-
|
|
88
|
-
const result = getFilteredOptions("unknownType", currentSelections, allOptions);
|
|
89
|
-
|
|
90
|
-
expect(result.filteredOptions).toEqual(allOptions);
|
|
91
|
-
expect(result.appliedFilters).toHaveLength(0);
|
|
92
|
-
});
|
|
93
|
-
|
|
94
|
-
test("should handle object selections with value property", () => {
|
|
95
|
-
const allOptions = {
|
|
96
|
-
experiencedUsers: "Experienced users",
|
|
97
|
-
domainFamiliar: "Domain familiar",
|
|
98
|
-
};
|
|
99
|
-
|
|
100
|
-
const currentSelections = {
|
|
101
|
-
documentPurpose: [{ value: "getStarted", label: "Get Started" }],
|
|
102
|
-
};
|
|
103
|
-
|
|
104
|
-
const result = getFilteredOptions("readerKnowledgeLevel", currentSelections, allOptions);
|
|
105
|
-
|
|
106
|
-
expect(result.filteredOptions).not.toHaveProperty("experiencedUsers");
|
|
107
|
-
expect(result.appliedFilters).toHaveLength(1);
|
|
108
|
-
});
|
|
109
|
-
|
|
110
|
-
test("should handle multiple conditions in cross-conflict rules", () => {
|
|
111
|
-
const allOptions = {
|
|
112
|
-
emergencyTroubleshooting: "Emergency troubleshooting",
|
|
113
|
-
domainFamiliar: "Domain familiar",
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
const currentSelections = {
|
|
117
|
-
targetAudienceTypes: ["decisionMakers"],
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const result = getFilteredOptions("readerKnowledgeLevel", currentSelections, allOptions);
|
|
121
|
-
|
|
122
|
-
expect(result.filteredOptions).not.toHaveProperty("emergencyTroubleshooting");
|
|
123
|
-
expect(result.appliedFilters).toHaveLength(1);
|
|
124
|
-
});
|
|
125
|
-
});
|
|
126
|
-
|
|
127
|
-
describe("detectResolvableConflicts", () => {
|
|
128
|
-
test("should detect document purpose conflicts", () => {
|
|
129
|
-
const config = {
|
|
130
|
-
documentPurpose: ["getStarted", "findAnswers"],
|
|
131
|
-
targetAudienceTypes: ["developers"],
|
|
132
|
-
};
|
|
133
|
-
|
|
134
|
-
const conflicts = detectResolvableConflicts(config);
|
|
135
|
-
|
|
136
|
-
expect(conflicts).toHaveLength(1);
|
|
137
|
-
expect(conflicts[0]).toMatchObject({
|
|
138
|
-
type: "documentPurpose",
|
|
139
|
-
items: ["getStarted", "findAnswers"],
|
|
140
|
-
strategy: "layered_structure",
|
|
141
|
-
description: "Quick start and API reference conflict, resolved through layered structure",
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
test("should detect target audience conflicts", () => {
|
|
146
|
-
const config = {
|
|
147
|
-
documentPurpose: ["completeTasks"],
|
|
148
|
-
targetAudienceTypes: ["endUsers", "developers"],
|
|
149
|
-
};
|
|
150
|
-
|
|
151
|
-
const conflicts = detectResolvableConflicts(config);
|
|
152
|
-
|
|
153
|
-
expect(conflicts).toHaveLength(1);
|
|
154
|
-
expect(conflicts[0]).toMatchObject({
|
|
155
|
-
type: "targetAudienceTypes",
|
|
156
|
-
items: ["endUsers", "developers"],
|
|
157
|
-
strategy: "separate_user_paths",
|
|
158
|
-
description: "End users and developers conflict, resolved through separate user paths",
|
|
159
|
-
});
|
|
160
|
-
});
|
|
161
|
-
|
|
162
|
-
test("should detect multiple conflicts", () => {
|
|
163
|
-
const config = {
|
|
164
|
-
documentPurpose: ["getStarted", "findAnswers", "understandSystem"],
|
|
165
|
-
targetAudienceTypes: ["endUsers", "developers"],
|
|
166
|
-
};
|
|
167
|
-
|
|
168
|
-
const conflicts = detectResolvableConflicts(config);
|
|
169
|
-
|
|
170
|
-
expect(conflicts).toHaveLength(3);
|
|
171
|
-
|
|
172
|
-
// Check for getStarted vs findAnswers conflict
|
|
173
|
-
expect(
|
|
174
|
-
conflicts.some(
|
|
175
|
-
(c) =>
|
|
176
|
-
c.type === "documentPurpose" &&
|
|
177
|
-
c.items.includes("getStarted") &&
|
|
178
|
-
c.items.includes("findAnswers"),
|
|
179
|
-
),
|
|
180
|
-
).toBe(true);
|
|
181
|
-
|
|
182
|
-
// Check for getStarted vs understandSystem conflict
|
|
183
|
-
expect(
|
|
184
|
-
conflicts.some(
|
|
185
|
-
(c) =>
|
|
186
|
-
c.type === "documentPurpose" &&
|
|
187
|
-
c.items.includes("getStarted") &&
|
|
188
|
-
c.items.includes("understandSystem"),
|
|
189
|
-
),
|
|
190
|
-
).toBe(true);
|
|
191
|
-
|
|
192
|
-
// Check for endUsers vs developers conflict
|
|
193
|
-
expect(
|
|
194
|
-
conflicts.some(
|
|
195
|
-
(c) =>
|
|
196
|
-
c.type === "targetAudienceTypes" &&
|
|
197
|
-
c.items.includes("endUsers") &&
|
|
198
|
-
c.items.includes("developers"),
|
|
199
|
-
),
|
|
200
|
-
).toBe(true);
|
|
201
|
-
});
|
|
202
|
-
|
|
203
|
-
test("should not detect conflicts with single selections", () => {
|
|
204
|
-
const config = {
|
|
205
|
-
documentPurpose: ["getStarted"],
|
|
206
|
-
targetAudienceTypes: ["developers"],
|
|
207
|
-
};
|
|
208
|
-
|
|
209
|
-
const conflicts = detectResolvableConflicts(config);
|
|
210
|
-
|
|
211
|
-
expect(conflicts).toHaveLength(0);
|
|
212
|
-
});
|
|
213
|
-
|
|
214
|
-
test("should not detect conflicts with non-conflicting combinations", () => {
|
|
215
|
-
const config = {
|
|
216
|
-
documentPurpose: ["completeTasks", "solveProblems"],
|
|
217
|
-
targetAudienceTypes: ["developers", "devops"],
|
|
218
|
-
};
|
|
219
|
-
|
|
220
|
-
const conflicts = detectResolvableConflicts(config);
|
|
221
|
-
|
|
222
|
-
expect(conflicts).toHaveLength(0);
|
|
223
|
-
});
|
|
224
|
-
|
|
225
|
-
test("should handle object arrays with value property", () => {
|
|
226
|
-
const config = {
|
|
227
|
-
documentPurpose: [
|
|
228
|
-
{ value: "getStarted", label: "Get Started" },
|
|
229
|
-
{ value: "findAnswers", label: "Find Answers" },
|
|
230
|
-
],
|
|
231
|
-
};
|
|
232
|
-
|
|
233
|
-
const conflicts = detectResolvableConflicts(config);
|
|
234
|
-
|
|
235
|
-
expect(conflicts).toHaveLength(1);
|
|
236
|
-
expect(conflicts[0].items).toEqual(["getStarted", "findAnswers"]);
|
|
237
|
-
});
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
describe("generateConflictResolutionRules", () => {
|
|
241
|
-
test("should generate resolution rules for conflicts", () => {
|
|
242
|
-
const conflicts = [
|
|
243
|
-
{
|
|
244
|
-
type: "documentPurpose",
|
|
245
|
-
items: ["getStarted", "findAnswers"],
|
|
246
|
-
strategy: "layered_structure",
|
|
247
|
-
description: "Quick start and API reference conflict, resolved through layered structure",
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
type: "targetAudienceTypes",
|
|
251
|
-
items: ["endUsers", "developers"],
|
|
252
|
-
strategy: "separate_user_paths",
|
|
253
|
-
description: "End users and developers conflict, resolved through separate user paths",
|
|
254
|
-
},
|
|
255
|
-
];
|
|
256
|
-
|
|
257
|
-
const rules = generateConflictResolutionRules(conflicts);
|
|
258
|
-
|
|
259
|
-
expect(rules).toContain("=== Conflict Resolution Guidelines ===");
|
|
260
|
-
expect(rules).toContain('Detected "getStarted" and "findAnswers" purpose conflict');
|
|
261
|
-
expect(rules).toContain('Detected "endUsers" and "developers" audience conflict');
|
|
262
|
-
expect(rules).toContain('Quick start section: Uses "get started" style');
|
|
263
|
-
expect(rules).toContain('User guide path: Uses "end users" style');
|
|
264
|
-
expect(rules).toContain("Conflict Resolution Principles:");
|
|
265
|
-
expect(rules).toContain(
|
|
266
|
-
"1. Meet diverse needs through intelligent structural design, not simple concatenation",
|
|
267
|
-
);
|
|
268
|
-
});
|
|
269
|
-
|
|
270
|
-
test("should return empty string for no conflicts", () => {
|
|
271
|
-
const conflicts = [];
|
|
272
|
-
const rules = generateConflictResolutionRules(conflicts);
|
|
273
|
-
expect(rules).toBe("");
|
|
274
|
-
});
|
|
275
|
-
|
|
276
|
-
test("should handle unknown strategies gracefully", () => {
|
|
277
|
-
const conflicts = [
|
|
278
|
-
{
|
|
279
|
-
type: "documentPurpose",
|
|
280
|
-
items: ["unknown1", "unknown2"],
|
|
281
|
-
strategy: "unknown_strategy",
|
|
282
|
-
description: "Unknown conflict",
|
|
283
|
-
},
|
|
284
|
-
];
|
|
285
|
-
|
|
286
|
-
const rules = generateConflictResolutionRules(conflicts);
|
|
287
|
-
|
|
288
|
-
expect(rules).toContain("=== Conflict Resolution Guidelines ===");
|
|
289
|
-
expect(rules).toContain("Conflict Resolution Principles:");
|
|
290
|
-
// Should not contain any strategy-specific text since strategy is unknown
|
|
291
|
-
expect(rules).not.toContain('Detected "unknown1" and "unknown2"');
|
|
292
|
-
});
|
|
293
|
-
});
|
|
294
|
-
|
|
295
|
-
describe("processConfigFields integration", () => {
|
|
296
|
-
test("should integrate conflict resolution into config processing", () => {
|
|
297
|
-
const config = {
|
|
298
|
-
documentPurpose: ["getStarted", "findAnswers"],
|
|
299
|
-
targetAudienceTypes: ["endUsers", "developers"],
|
|
300
|
-
readerKnowledgeLevel: "completeBeginners",
|
|
301
|
-
documentationDepth: "balancedCoverage",
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
const result = processConfigFields(config);
|
|
305
|
-
|
|
306
|
-
// Should detect conflicts
|
|
307
|
-
expect(result.detectedConflicts).toBeDefined();
|
|
308
|
-
expect(result.detectedConflicts).toHaveLength(2);
|
|
309
|
-
|
|
310
|
-
// Should include conflict resolution rules in final rules
|
|
311
|
-
expect(result.rules).toContain("=== Conflict Resolution Guidelines ===");
|
|
312
|
-
expect(result.rules).toContain("Create layered documentation structure");
|
|
313
|
-
expect(result.rules).toContain("Create separate user paths");
|
|
314
|
-
|
|
315
|
-
// Should also include regular configuration content with enhanced format
|
|
316
|
-
expect(result.rules).toContain("Document Purpose - Get started quickly:");
|
|
317
|
-
expect(result.rules).toContain("Target Audience - End users (non-technical):");
|
|
318
|
-
expect(result.rules).toContain("Target Audience - Developers integrating your product/API:");
|
|
319
|
-
expect(result.rules).toContain("Reader Knowledge Level:");
|
|
320
|
-
});
|
|
321
|
-
|
|
322
|
-
test("should work without conflicts", () => {
|
|
323
|
-
const config = {
|
|
324
|
-
documentPurpose: ["completeTasks"],
|
|
325
|
-
targetAudienceTypes: ["developers"],
|
|
326
|
-
readerKnowledgeLevel: "domainFamiliar",
|
|
327
|
-
};
|
|
328
|
-
|
|
329
|
-
const result = processConfigFields(config);
|
|
330
|
-
|
|
331
|
-
// Should not detect conflicts
|
|
332
|
-
expect(result.detectedConflicts).toBeUndefined();
|
|
333
|
-
|
|
334
|
-
// Should not include conflict resolution rules
|
|
335
|
-
expect(result.rules).not.toContain("=== Conflict Resolution Guidelines ===");
|
|
336
|
-
|
|
337
|
-
// Should still include regular configuration content with enhanced format
|
|
338
|
-
expect(result.rules).toContain("Document Purpose - Complete specific tasks:");
|
|
339
|
-
expect(result.rules).toContain("Target Audience - Developers integrating your product/API:");
|
|
340
|
-
});
|
|
341
|
-
|
|
342
|
-
test("should preserve target audience field processing", () => {
|
|
343
|
-
const config = {
|
|
344
|
-
targetAudienceTypes: ["developers", "devops"],
|
|
345
|
-
targetAudience: "Existing audience description",
|
|
346
|
-
};
|
|
347
|
-
|
|
348
|
-
const result = processConfigFields(config);
|
|
349
|
-
|
|
350
|
-
expect(result.targetAudience).toContain("Existing audience description");
|
|
351
|
-
expect(result.targetAudience).toContain("Developers integrating your product/API");
|
|
352
|
-
expect(result.targetAudience).toContain("DevOps / SRE / Infrastructure teams");
|
|
353
|
-
});
|
|
354
|
-
});
|
|
355
|
-
});
|