@aigne/doc-smith 0.8.12-beta.8 → 0.8.12

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.
Files changed (264) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/agents/publish/index.yaml +4 -0
  3. package/agents/publish/publish-docs.mjs +77 -5
  4. package/agents/publish/translate-meta.mjs +103 -0
  5. package/agents/update/generate-document.yaml +30 -28
  6. package/agents/update/update-document-detail.yaml +3 -1
  7. package/agents/utils/update-branding.mjs +69 -0
  8. package/package.json +16 -2
  9. package/prompts/common/document/role-and-personality.md +3 -1
  10. package/prompts/detail/d2-diagram/guide.md +7 -1
  11. package/prompts/detail/d2-diagram/user-prompt.md +3 -0
  12. package/prompts/detail/generate/system-prompt.md +6 -7
  13. package/prompts/detail/generate/user-prompt.md +12 -3
  14. package/prompts/detail/update/user-prompt.md +0 -2
  15. package/prompts/structure/update/user-prompt.md +0 -4
  16. package/utils/file-utils.mjs +69 -24
  17. package/utils/markdown-checker.mjs +0 -20
  18. package/utils/request.mjs +7 -0
  19. package/utils/upload-files.mjs +231 -0
  20. package/utils/utils.mjs +11 -1
  21. package/.aigne/doc-smith/config.yaml +0 -77
  22. package/.aigne/doc-smith/history.yaml +0 -37
  23. package/.aigne/doc-smith/media-description.yaml +0 -91
  24. package/.aigne/doc-smith/output/structure-plan.json +0 -162
  25. package/.aigne/doc-smith/preferences.yml +0 -97
  26. package/.aigne/doc-smith/upload-cache.yaml +0 -1830
  27. package/.github/PULL_REQUEST_TEMPLATE.md +0 -28
  28. package/.github/workflows/ci.yml +0 -54
  29. package/.github/workflows/create-release-pr.yaml +0 -21
  30. package/.github/workflows/publish-docs.yml +0 -65
  31. package/.github/workflows/release.yml +0 -49
  32. package/.github/workflows/reviewer.yml +0 -54
  33. package/.release-please-manifest.json +0 -3
  34. package/RELEASE.md +0 -9
  35. package/assets/screenshots/doc-complete-setup.png +0 -0
  36. package/assets/screenshots/doc-generate-docs.png +0 -0
  37. package/assets/screenshots/doc-generate.png +0 -0
  38. package/assets/screenshots/doc-generated-successfully.png +0 -0
  39. package/assets/screenshots/doc-publish.png +0 -0
  40. package/assets/screenshots/doc-regenerate.png +0 -0
  41. package/assets/screenshots/doc-translate-langs.png +0 -0
  42. package/assets/screenshots/doc-translate.png +0 -0
  43. package/assets/screenshots/doc-update.png +0 -0
  44. package/biome.json +0 -73
  45. package/codecov.yml +0 -15
  46. package/docs/_sidebar.md +0 -15
  47. package/docs/configuration-initial-setup.ja.md +0 -179
  48. package/docs/configuration-initial-setup.md +0 -198
  49. package/docs/configuration-initial-setup.zh-TW.md +0 -179
  50. package/docs/configuration-initial-setup.zh.md +0 -179
  51. package/docs/configuration-managing-preferences.ja.md +0 -100
  52. package/docs/configuration-managing-preferences.md +0 -100
  53. package/docs/configuration-managing-preferences.zh-TW.md +0 -100
  54. package/docs/configuration-managing-preferences.zh.md +0 -100
  55. package/docs/configuration.ja.md +0 -69
  56. package/docs/configuration.md +0 -69
  57. package/docs/configuration.zh-TW.md +0 -69
  58. package/docs/configuration.zh.md +0 -69
  59. package/docs/getting-started.ja.md +0 -107
  60. package/docs/getting-started.md +0 -107
  61. package/docs/getting-started.zh-TW.md +0 -107
  62. package/docs/getting-started.zh.md +0 -107
  63. package/docs/guides-cleaning-up.ja.md +0 -51
  64. package/docs/guides-cleaning-up.md +0 -52
  65. package/docs/guides-cleaning-up.zh-TW.md +0 -51
  66. package/docs/guides-cleaning-up.zh.md +0 -51
  67. package/docs/guides-evaluating-documents.ja.md +0 -66
  68. package/docs/guides-evaluating-documents.md +0 -107
  69. package/docs/guides-evaluating-documents.zh-TW.md +0 -66
  70. package/docs/guides-evaluating-documents.zh.md +0 -66
  71. package/docs/guides-generating-documentation.ja.md +0 -151
  72. package/docs/guides-generating-documentation.md +0 -89
  73. package/docs/guides-generating-documentation.zh-TW.md +0 -151
  74. package/docs/guides-generating-documentation.zh.md +0 -151
  75. package/docs/guides-interactive-chat.ja.md +0 -85
  76. package/docs/guides-interactive-chat.md +0 -93
  77. package/docs/guides-interactive-chat.zh-TW.md +0 -85
  78. package/docs/guides-interactive-chat.zh.md +0 -85
  79. package/docs/guides-managing-history.ja.md +0 -48
  80. package/docs/guides-managing-history.md +0 -53
  81. package/docs/guides-managing-history.zh-TW.md +0 -48
  82. package/docs/guides-managing-history.zh.md +0 -48
  83. package/docs/guides-publishing-your-docs.ja.md +0 -78
  84. package/docs/guides-publishing-your-docs.md +0 -83
  85. package/docs/guides-publishing-your-docs.zh-TW.md +0 -78
  86. package/docs/guides-publishing-your-docs.zh.md +0 -78
  87. package/docs/guides-translating-documentation.ja.md +0 -95
  88. package/docs/guides-translating-documentation.md +0 -100
  89. package/docs/guides-translating-documentation.zh-TW.md +0 -95
  90. package/docs/guides-translating-documentation.zh.md +0 -95
  91. package/docs/guides-updating-documentation.ja.md +0 -77
  92. package/docs/guides-updating-documentation.md +0 -79
  93. package/docs/guides-updating-documentation.zh-TW.md +0 -77
  94. package/docs/guides-updating-documentation.zh.md +0 -77
  95. package/docs/guides.ja.md +0 -32
  96. package/docs/guides.md +0 -32
  97. package/docs/guides.zh-TW.md +0 -32
  98. package/docs/guides.zh.md +0 -32
  99. package/docs/overview.ja.md +0 -61
  100. package/docs/overview.md +0 -61
  101. package/docs/overview.zh-TW.md +0 -61
  102. package/docs/overview.zh.md +0 -61
  103. package/docs/release-notes.ja.md +0 -255
  104. package/docs/release-notes.md +0 -288
  105. package/docs/release-notes.zh-TW.md +0 -255
  106. package/docs/release-notes.zh.md +0 -255
  107. package/prompts/common/afs/afs-tools-usage.md +0 -5
  108. package/prompts/common/afs/use-afs-instruction.md +0 -1
  109. package/release-please-config.json +0 -14
  110. package/tests/agents/chat/chat.test.mjs +0 -46
  111. package/tests/agents/clear/choose-contents.test.mjs +0 -284
  112. package/tests/agents/clear/clear-auth-tokens.test.mjs +0 -268
  113. package/tests/agents/clear/clear-document-config.test.mjs +0 -167
  114. package/tests/agents/clear/clear-document-structure.test.mjs +0 -380
  115. package/tests/agents/clear/clear-generated-docs.test.mjs +0 -222
  116. package/tests/agents/evaluate/code-snippet.test.mjs +0 -163
  117. package/tests/agents/evaluate/fixtures/api-services.md +0 -87
  118. package/tests/agents/evaluate/fixtures/js-sdk.md +0 -94
  119. package/tests/agents/evaluate/generate-report.test.mjs +0 -312
  120. package/tests/agents/generate/check-document-structure.test.mjs +0 -45
  121. package/tests/agents/generate/check-need-generate-structure.test.mjs +0 -279
  122. package/tests/agents/generate/document-structure-tools/add-document.test.mjs +0 -449
  123. package/tests/agents/generate/document-structure-tools/delete-document.test.mjs +0 -410
  124. package/tests/agents/generate/document-structure-tools/generate-sub-structure.test.mjs +0 -277
  125. package/tests/agents/generate/document-structure-tools/move-document.test.mjs +0 -476
  126. package/tests/agents/generate/document-structure-tools/update-document.test.mjs +0 -548
  127. package/tests/agents/generate/generate-structure.test.mjs +0 -45
  128. package/tests/agents/generate/user-review-document-structure.test.mjs +0 -319
  129. package/tests/agents/history/view.test.mjs +0 -97
  130. package/tests/agents/init/init.test.mjs +0 -1657
  131. package/tests/agents/prefs/prefs.test.mjs +0 -431
  132. package/tests/agents/publish/publish-docs.test.mjs +0 -787
  133. package/tests/agents/translate/choose-language.test.mjs +0 -311
  134. package/tests/agents/translate/translate-document.test.mjs +0 -51
  135. package/tests/agents/update/check-document.test.mjs +0 -463
  136. package/tests/agents/update/check-update-is-single.test.mjs +0 -300
  137. package/tests/agents/update/document-tools/update-document-content.test.mjs +0 -329
  138. package/tests/agents/update/generate-document.test.mjs +0 -51
  139. package/tests/agents/update/save-and-translate-document.test.mjs +0 -369
  140. package/tests/agents/update/user-review-document.test.mjs +0 -582
  141. package/tests/agents/utils/action-success.test.mjs +0 -54
  142. package/tests/agents/utils/check-detail-result.test.mjs +0 -743
  143. package/tests/agents/utils/check-feedback-refiner.test.mjs +0 -478
  144. package/tests/agents/utils/choose-docs.test.mjs +0 -406
  145. package/tests/agents/utils/exit.test.mjs +0 -70
  146. package/tests/agents/utils/feedback-refiner.test.mjs +0 -51
  147. package/tests/agents/utils/find-item-by-path.test.mjs +0 -517
  148. package/tests/agents/utils/find-user-preferences-by-path.test.mjs +0 -382
  149. package/tests/agents/utils/format-document-structure.test.mjs +0 -364
  150. package/tests/agents/utils/fs.test.mjs +0 -267
  151. package/tests/agents/utils/load-sources.test.mjs +0 -1470
  152. package/tests/agents/utils/save-docs.test.mjs +0 -109
  153. package/tests/agents/utils/save-output.test.mjs +0 -315
  154. package/tests/agents/utils/save-single-doc.test.mjs +0 -364
  155. package/tests/agents/utils/transform-detail-datasources.test.mjs +0 -320
  156. package/tests/utils/auth-utils.test.mjs +0 -596
  157. package/tests/utils/blocklet.test.mjs +0 -336
  158. package/tests/utils/conflict-detector.test.mjs +0 -355
  159. package/tests/utils/constants.test.mjs +0 -295
  160. package/tests/utils/d2-utils.test.mjs +0 -437
  161. package/tests/utils/deploy.test.mjs +0 -399
  162. package/tests/utils/docs-finder-utils.test.mjs +0 -650
  163. package/tests/utils/file-utils.test.mjs +0 -521
  164. package/tests/utils/history-utils.test.mjs +0 -206
  165. package/tests/utils/kroki-utils.test.mjs +0 -646
  166. package/tests/utils/linter/fixtures/css/keyword-error.css +0 -1
  167. package/tests/utils/linter/fixtures/css/missing-semicolon.css +0 -1
  168. package/tests/utils/linter/fixtures/css/syntax-error.css +0 -1
  169. package/tests/utils/linter/fixtures/css/undeclare-variable.css +0 -1
  170. package/tests/utils/linter/fixtures/css/unused-variable.css +0 -2
  171. package/tests/utils/linter/fixtures/css/valid-code.css +0 -1
  172. package/tests/utils/linter/fixtures/dockerfile/keyword-error.dockerfile +0 -1
  173. package/tests/utils/linter/fixtures/dockerfile/missing-semicolon.dockerfile +0 -2
  174. package/tests/utils/linter/fixtures/dockerfile/syntax-error.dockerfile +0 -2
  175. package/tests/utils/linter/fixtures/dockerfile/undeclare-variable.dockerfile +0 -1
  176. package/tests/utils/linter/fixtures/dockerfile/unused-variable.dockerfile +0 -1
  177. package/tests/utils/linter/fixtures/dockerfile/valid-code.dockerfile +0 -2
  178. package/tests/utils/linter/fixtures/go/keyword-error.go +0 -5
  179. package/tests/utils/linter/fixtures/go/missing-semicolon.go +0 -5
  180. package/tests/utils/linter/fixtures/go/syntax-error.go +0 -6
  181. package/tests/utils/linter/fixtures/go/undeclare-variable.go +0 -5
  182. package/tests/utils/linter/fixtures/go/unused-variable.go +0 -5
  183. package/tests/utils/linter/fixtures/go/valid-code.go +0 -7
  184. package/tests/utils/linter/fixtures/js/keyword-error.js +0 -3
  185. package/tests/utils/linter/fixtures/js/missing-semicolon.js +0 -6
  186. package/tests/utils/linter/fixtures/js/syntax-error.js +0 -4
  187. package/tests/utils/linter/fixtures/js/undeclare-variable.js +0 -3
  188. package/tests/utils/linter/fixtures/js/unused-variable.js +0 -7
  189. package/tests/utils/linter/fixtures/js/valid-code.js +0 -15
  190. package/tests/utils/linter/fixtures/json/keyword-error.json +0 -1
  191. package/tests/utils/linter/fixtures/json/missing-semicolon.json +0 -1
  192. package/tests/utils/linter/fixtures/json/syntax-error.json +0 -1
  193. package/tests/utils/linter/fixtures/json/undeclare-variable.json +0 -1
  194. package/tests/utils/linter/fixtures/json/unused-variable.json +0 -1
  195. package/tests/utils/linter/fixtures/json/valid-code.json +0 -1
  196. package/tests/utils/linter/fixtures/jsx/keyword-error.jsx +0 -5
  197. package/tests/utils/linter/fixtures/jsx/missing-semicolon.jsx +0 -5
  198. package/tests/utils/linter/fixtures/jsx/syntax-error.jsx +0 -5
  199. package/tests/utils/linter/fixtures/jsx/undeclare-variable.jsx +0 -5
  200. package/tests/utils/linter/fixtures/jsx/unused-variable.jsx +0 -4
  201. package/tests/utils/linter/fixtures/jsx/valid-code.jsx +0 -5
  202. package/tests/utils/linter/fixtures/python/keyword-error.py +0 -3
  203. package/tests/utils/linter/fixtures/python/missing-semicolon.py +0 -2
  204. package/tests/utils/linter/fixtures/python/syntax-error.py +0 -3
  205. package/tests/utils/linter/fixtures/python/undeclare-variable.py +0 -3
  206. package/tests/utils/linter/fixtures/python/unused-variable.py +0 -6
  207. package/tests/utils/linter/fixtures/python/valid-code.py +0 -12
  208. package/tests/utils/linter/fixtures/ruby/keyword-error.rb +0 -2
  209. package/tests/utils/linter/fixtures/ruby/missing-semicolon.rb +0 -1
  210. package/tests/utils/linter/fixtures/ruby/syntax-error.rb +0 -2
  211. package/tests/utils/linter/fixtures/ruby/undeclare-variable.rb +0 -1
  212. package/tests/utils/linter/fixtures/ruby/unused-variable.rb +0 -2
  213. package/tests/utils/linter/fixtures/ruby/valid-code.rb +0 -1
  214. package/tests/utils/linter/fixtures/sass/keyword-error.sass +0 -2
  215. package/tests/utils/linter/fixtures/sass/missing-semicolon.sass +0 -3
  216. package/tests/utils/linter/fixtures/sass/syntax-error.sass +0 -3
  217. package/tests/utils/linter/fixtures/sass/undeclare-variable.sass +0 -2
  218. package/tests/utils/linter/fixtures/sass/unused-variable.sass +0 -4
  219. package/tests/utils/linter/fixtures/sass/valid-code.sass +0 -2
  220. package/tests/utils/linter/fixtures/scss/keyword-error.scss +0 -1
  221. package/tests/utils/linter/fixtures/scss/missing-semicolon.scss +0 -1
  222. package/tests/utils/linter/fixtures/scss/syntax-error.scss +0 -1
  223. package/tests/utils/linter/fixtures/scss/undeclare-variable.scss +0 -1
  224. package/tests/utils/linter/fixtures/scss/unused-variable.scss +0 -2
  225. package/tests/utils/linter/fixtures/scss/valid-code.scss +0 -1
  226. package/tests/utils/linter/fixtures/shell/keyword-error.sh +0 -5
  227. package/tests/utils/linter/fixtures/shell/missing-semicolon.sh +0 -3
  228. package/tests/utils/linter/fixtures/shell/syntax-error.sh +0 -4
  229. package/tests/utils/linter/fixtures/shell/undeclare-variable.sh +0 -3
  230. package/tests/utils/linter/fixtures/shell/unused-variable.sh +0 -4
  231. package/tests/utils/linter/fixtures/shell/valid-code.sh +0 -3
  232. package/tests/utils/linter/fixtures/ts/keyword-error.ts +0 -1
  233. package/tests/utils/linter/fixtures/ts/missing-semicolon.ts +0 -1
  234. package/tests/utils/linter/fixtures/ts/syntax-error.ts +0 -1
  235. package/tests/utils/linter/fixtures/ts/undeclare-variable.ts +0 -1
  236. package/tests/utils/linter/fixtures/ts/unused-variable.ts +0 -3
  237. package/tests/utils/linter/fixtures/ts/valid-code.ts +0 -3
  238. package/tests/utils/linter/fixtures/tsx/keyword-error.tsx +0 -5
  239. package/tests/utils/linter/fixtures/tsx/missing-semicolon.tsx +0 -5
  240. package/tests/utils/linter/fixtures/tsx/syntax-error.tsx +0 -5
  241. package/tests/utils/linter/fixtures/tsx/undeclare-variable.tsx +0 -6
  242. package/tests/utils/linter/fixtures/tsx/unused-variable.tsx +0 -6
  243. package/tests/utils/linter/fixtures/tsx/valid-code.tsx +0 -5
  244. package/tests/utils/linter/fixtures/vue/keyword-error.vue +0 -6
  245. package/tests/utils/linter/fixtures/vue/missing-semicolon.vue +0 -6
  246. package/tests/utils/linter/fixtures/vue/syntax-error.vue +0 -6
  247. package/tests/utils/linter/fixtures/vue/undeclare-variable.vue +0 -6
  248. package/tests/utils/linter/fixtures/vue/unused-variable.vue +0 -7
  249. package/tests/utils/linter/fixtures/vue/valid-code.vue +0 -6
  250. package/tests/utils/linter/fixtures/yaml/keyword-error.yml +0 -1
  251. package/tests/utils/linter/fixtures/yaml/missing-semicolon.yml +0 -2
  252. package/tests/utils/linter/fixtures/yaml/syntax-error.yml +0 -1
  253. package/tests/utils/linter/fixtures/yaml/undeclare-variable.yml +0 -1
  254. package/tests/utils/linter/fixtures/yaml/unused-variable.yml +0 -2
  255. package/tests/utils/linter/fixtures/yaml/valid-code.yml +0 -3
  256. package/tests/utils/linter/index.test.mjs +0 -440
  257. package/tests/utils/linter/scan-results.mjs +0 -42
  258. package/tests/utils/load-config.test.mjs +0 -141
  259. package/tests/utils/markdown/index.test.mjs +0 -478
  260. package/tests/utils/mermaid-validator.test.mjs +0 -541
  261. package/tests/utils/mock-chat-model.mjs +0 -12
  262. package/tests/utils/preferences-utils.test.mjs +0 -465
  263. package/tests/utils/save-value-to-config.test.mjs +0 -483
  264. package/tests/utils/utils.test.mjs +0 -941
@@ -1,382 +0,0 @@
1
- import { afterEach, beforeEach, describe, expect, spyOn, test } from "bun:test";
2
- import findUserPreferencesByPath from "../../../agents/utils/find-user-preferences-by-path.mjs";
3
-
4
- import * as preferencesUtils from "../../../utils/preferences-utils.mjs";
5
-
6
- describe("find-user-preferences-by-path", () => {
7
- // Spies for internal utils
8
- let getActiveRulesForScopeSpy;
9
-
10
- beforeEach(() => {
11
- // Set up spies for internal utils
12
- getActiveRulesForScopeSpy = spyOn(preferencesUtils, "getActiveRulesForScope").mockReturnValue(
13
- [],
14
- );
15
-
16
- // Clear spy call history
17
- getActiveRulesForScopeSpy.mockClear();
18
- });
19
-
20
- afterEach(() => {
21
- // Restore all spies
22
- getActiveRulesForScopeSpy?.mockRestore();
23
- });
24
-
25
- // BASIC FUNCTIONALITY TESTS
26
- test("should return empty preferences when no rules found", async () => {
27
- const result = await findUserPreferencesByPath({
28
- path: "/api/users",
29
- scope: "document",
30
- });
31
-
32
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledTimes(2);
33
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
34
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", ["/api/users"]);
35
- expect(result).toEqual({
36
- userPreferences: "",
37
- });
38
- });
39
-
40
- test("should return global rules when only global rules exist", async () => {
41
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
42
- if (scope === "global") {
43
- return [
44
- { rule: "Always use clear and concise language" },
45
- { rule: "Include code examples when relevant" },
46
- ];
47
- }
48
- return [];
49
- });
50
-
51
- const result = await findUserPreferencesByPath({
52
- path: "/api/users",
53
- scope: "document",
54
- });
55
-
56
- expect(result).toEqual({
57
- userPreferences:
58
- "Always use clear and concise language\n\nInclude code examples when relevant",
59
- });
60
- });
61
-
62
- test("should return scope rules when only scope rules exist", async () => {
63
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
64
- if (scope === "document") {
65
- return [
66
- { rule: "Focus on API documentation standards" },
67
- { rule: "Include parameter details" },
68
- ];
69
- }
70
- return [];
71
- });
72
-
73
- const result = await findUserPreferencesByPath({
74
- path: "/api/users",
75
- scope: "document",
76
- });
77
-
78
- expect(result).toEqual({
79
- userPreferences: "Focus on API documentation standards\n\nInclude parameter details",
80
- });
81
- });
82
-
83
- test("should combine global and scope rules correctly", async () => {
84
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
85
- if (scope === "global") {
86
- return [{ rule: "Use consistent terminology" }, { rule: "Maintain professional tone" }];
87
- }
88
- if (scope === "document") {
89
- return [{ rule: "Include version information" }, { rule: "Add deprecation notices" }];
90
- }
91
- return [];
92
- });
93
-
94
- const result = await findUserPreferencesByPath({
95
- path: "/api/auth",
96
- scope: "document",
97
- });
98
-
99
- expect(result).toEqual({
100
- userPreferences:
101
- "Use consistent terminology\n\nMaintain professional tone\n\nInclude version information\n\nAdd deprecation notices",
102
- });
103
- });
104
-
105
- // SCOPE-SPECIFIC TESTS
106
- test("should handle document scope correctly", async () => {
107
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
108
- if (scope === "global") {
109
- return [{ rule: "Global rule" }];
110
- }
111
- if (scope === "document") {
112
- return [{ rule: "Document rule" }];
113
- }
114
- return [];
115
- });
116
-
117
- await findUserPreferencesByPath({
118
- path: "/docs/getting-started",
119
- scope: "document",
120
- });
121
-
122
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
123
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", ["/docs/getting-started"]);
124
- });
125
-
126
- test("should handle translation scope correctly", async () => {
127
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
128
- if (scope === "global") {
129
- return [{ rule: "Global rule" }];
130
- }
131
- if (scope === "translation") {
132
- return [{ rule: "Translation rule" }];
133
- }
134
- return [];
135
- });
136
-
137
- await findUserPreferencesByPath({
138
- path: "/docs/api-reference",
139
- scope: "translation",
140
- });
141
-
142
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
143
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("translation", ["/docs/api-reference"]);
144
- });
145
-
146
- test("should handle missing path parameter", async () => {
147
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
148
- if (scope === "global") {
149
- return [{ rule: "Global rule for all" }];
150
- }
151
- if (scope === "document") {
152
- return [{ rule: "Document rule for all" }];
153
- }
154
- return [];
155
- });
156
-
157
- const result = await findUserPreferencesByPath({
158
- scope: "document",
159
- });
160
-
161
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
162
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", []);
163
- expect(result).toEqual({
164
- userPreferences: "Global rule for all\n\nDocument rule for all",
165
- });
166
- });
167
-
168
- test("should handle null path parameter", async () => {
169
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
170
- if (scope === "global") {
171
- return [{ rule: "Global rule" }];
172
- }
173
- return [];
174
- });
175
-
176
- const result = await findUserPreferencesByPath({
177
- path: null,
178
- scope: "translation",
179
- });
180
-
181
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
182
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("translation", []);
183
- expect(result).toEqual({
184
- userPreferences: "Global rule",
185
- });
186
- });
187
-
188
- test("should handle empty path parameter", async () => {
189
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
190
- if (scope === "global") {
191
- return [{ rule: "Global rule" }];
192
- }
193
- return [];
194
- });
195
-
196
- const result = await findUserPreferencesByPath({
197
- path: "",
198
- scope: "document",
199
- });
200
-
201
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
202
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", []);
203
- expect(result).toEqual({
204
- userPreferences: "Global rule",
205
- });
206
- });
207
-
208
- // RULE COMBINATION TESTS
209
- test("should handle single rule correctly", async () => {
210
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
211
- if (scope === "global") {
212
- return [{ rule: "Single global rule" }];
213
- }
214
- return [];
215
- });
216
-
217
- const result = await findUserPreferencesByPath({
218
- path: "/test",
219
- scope: "document",
220
- });
221
-
222
- expect(result).toEqual({
223
- userPreferences: "Single global rule",
224
- });
225
- });
226
-
227
- test("should handle multiple rules with proper formatting", async () => {
228
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
229
- if (scope === "global") {
230
- return [{ rule: "First rule" }, { rule: "Second rule" }, { rule: "Third rule" }];
231
- }
232
- return [];
233
- });
234
-
235
- const result = await findUserPreferencesByPath({
236
- path: "/test",
237
- scope: "document",
238
- });
239
-
240
- expect(result).toEqual({
241
- userPreferences: "First rule\n\nSecond rule\n\nThird rule",
242
- });
243
- });
244
-
245
- test("should handle rules with complex text", async () => {
246
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
247
- if (scope === "global") {
248
- return [
249
- {
250
- rule: "When writing API documentation, always include:\n- Request parameters\n- Response examples\n- Error codes",
251
- },
252
- ];
253
- }
254
- if (scope === "document") {
255
- return [
256
- {
257
- rule: "For authentication endpoints:\n1. Mention security considerations\n2. Include rate limiting info",
258
- },
259
- ];
260
- }
261
- return [];
262
- });
263
-
264
- const result = await findUserPreferencesByPath({
265
- path: "/api/auth/login",
266
- scope: "document",
267
- });
268
-
269
- expect(result.userPreferences).toContain("When writing API documentation");
270
- expect(result.userPreferences).toContain("For authentication endpoints");
271
- expect(result.userPreferences).toContain("\n\n");
272
- });
273
-
274
- // EDGE CASES
275
- test("should handle undefined scope parameter gracefully", async () => {
276
- const result = await findUserPreferencesByPath({
277
- path: "/test",
278
- });
279
-
280
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("global", []);
281
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith(undefined, ["/test"]);
282
- expect(result).toEqual({
283
- userPreferences: "",
284
- });
285
- });
286
-
287
- test("should handle rules with empty rule text", async () => {
288
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
289
- if (scope === "global") {
290
- return [{ rule: "Valid rule" }, { rule: "" }, { rule: "Another valid rule" }];
291
- }
292
- return [];
293
- });
294
-
295
- const result = await findUserPreferencesByPath({
296
- path: "/test",
297
- scope: "document",
298
- });
299
-
300
- expect(result).toEqual({
301
- userPreferences: "Valid rule\n\n\n\nAnother valid rule",
302
- });
303
- });
304
-
305
- test("should preserve rule order (global first, then scope)", async () => {
306
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
307
- if (scope === "global") {
308
- return [{ rule: "Global rule 1" }, { rule: "Global rule 2" }];
309
- }
310
- if (scope === "document") {
311
- return [{ rule: "Document rule 1" }, { rule: "Document rule 2" }];
312
- }
313
- return [];
314
- });
315
-
316
- const result = await findUserPreferencesByPath({
317
- path: "/test",
318
- scope: "document",
319
- });
320
-
321
- expect(result).toEqual({
322
- userPreferences: "Global rule 1\n\nGlobal rule 2\n\nDocument rule 1\n\nDocument rule 2",
323
- });
324
- });
325
-
326
- // PERFORMANCE AND EFFICIENCY TESTS
327
- test("should call getActiveRulesForScope exactly twice", async () => {
328
- await findUserPreferencesByPath({
329
- path: "/performance/test",
330
- scope: "translation",
331
- });
332
-
333
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledTimes(2);
334
- });
335
-
336
- test("should handle large number of rules efficiently", async () => {
337
- const manyRules = Array.from({ length: 100 }, (_, i) => ({
338
- rule: `Rule number ${i + 1}`,
339
- }));
340
-
341
- getActiveRulesForScopeSpy.mockImplementation((scope) => {
342
- if (scope === "global") {
343
- return manyRules.slice(0, 50);
344
- }
345
- if (scope === "document") {
346
- return manyRules.slice(50);
347
- }
348
- return [];
349
- });
350
-
351
- const result = await findUserPreferencesByPath({
352
- path: "/large/test",
353
- scope: "document",
354
- });
355
-
356
- expect(result.userPreferences.split("\n\n")).toHaveLength(100);
357
- expect(result.userPreferences).toContain("Rule number 1");
358
- expect(result.userPreferences).toContain("Rule number 100");
359
- });
360
-
361
- // PARAMETER VALIDATION TESTS
362
- test("should work with various path formats", async () => {
363
- const testPaths = [
364
- "/simple",
365
- "/nested/path",
366
- "/deeply/nested/path/here",
367
- "/with-dashes",
368
- "/with_underscores",
369
- "/with.dots",
370
- "/api/v1/users/123",
371
- ];
372
-
373
- for (const path of testPaths) {
374
- await findUserPreferencesByPath({
375
- path,
376
- scope: "document",
377
- });
378
-
379
- expect(getActiveRulesForScopeSpy).toHaveBeenCalledWith("document", [path]);
380
- }
381
- });
382
- });