@esaio/esa-mcp-server 0.2.1 → 0.2.3

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 (78) hide show
  1. package/README.en.md +1 -1
  2. package/README.md +1 -1
  3. package/bin/index.js +1 -1
  4. package/package.json +20 -2
  5. package/.dockerignore +0 -36
  6. package/.github/dependabot.yml +0 -23
  7. package/.github/workflows/docker-publish.yml +0 -120
  8. package/.github/workflows/main.yml +0 -41
  9. package/CLAUDE.md +0 -94
  10. package/Dockerfile +0 -34
  11. package/biome.json +0 -57
  12. package/src/__tests__/fixtures/mock-comment.ts +0 -90
  13. package/src/__tests__/fixtures/mock-post.ts +0 -79
  14. package/src/__tests__/index.test.ts +0 -216
  15. package/src/api_client/__tests__/index.test.ts +0 -149
  16. package/src/api_client/__tests__/middleware.test.ts +0 -120
  17. package/src/api_client/__tests__/with-context.test.ts +0 -98
  18. package/src/api_client/index.ts +0 -29
  19. package/src/api_client/middleware.ts +0 -21
  20. package/src/api_client/with-context.ts +0 -26
  21. package/src/config/__tests__/index.test.ts +0 -65
  22. package/src/config/index.ts +0 -20
  23. package/src/context/mcp-context.ts +0 -1
  24. package/src/context/stdio-context.ts +0 -6
  25. package/src/errors/missing-team-name-error.ts +0 -8
  26. package/src/formatters/__tests__/mcp-response.test.ts +0 -106
  27. package/src/formatters/mcp-response.ts +0 -95
  28. package/src/generated/api-types.ts +0 -2968
  29. package/src/i18n/__tests__/index.test.ts +0 -53
  30. package/src/i18n/index.ts +0 -39
  31. package/src/index.ts +0 -47
  32. package/src/locales/en.json +0 -13
  33. package/src/locales/ja.json +0 -13
  34. package/src/prompts/__tests__/index.test.ts +0 -48
  35. package/src/prompts/__tests__/summarize-post.test.ts +0 -291
  36. package/src/prompts/index.ts +0 -21
  37. package/src/prompts/summarize-post.ts +0 -94
  38. package/src/resources/__tests__/index.test.ts +0 -50
  39. package/src/resources/__tests__/recent-posts-list.test.ts +0 -92
  40. package/src/resources/__tests__/recent-posts.test.ts +0 -270
  41. package/src/resources/index.ts +0 -33
  42. package/src/resources/recent-posts-list.ts +0 -22
  43. package/src/resources/recent-posts.ts +0 -45
  44. package/src/schemas/team-name-schema.ts +0 -19
  45. package/src/tools/__tests__/attachments.test.ts +0 -460
  46. package/src/tools/__tests__/categories.test.ts +0 -402
  47. package/src/tools/__tests__/comments.test.ts +0 -970
  48. package/src/tools/__tests__/helps.test.ts +0 -222
  49. package/src/tools/__tests__/index.test.ts +0 -48
  50. package/src/tools/__tests__/post-actions.test.ts +0 -445
  51. package/src/tools/__tests__/posts.test.ts +0 -917
  52. package/src/tools/__tests__/search.test.ts +0 -339
  53. package/src/tools/__tests__/teams.test.ts +0 -615
  54. package/src/tools/attachments.ts +0 -167
  55. package/src/tools/categories.ts +0 -153
  56. package/src/tools/comments.ts +0 -258
  57. package/src/tools/helps.ts +0 -50
  58. package/src/tools/index.ts +0 -351
  59. package/src/tools/post-actions.ts +0 -132
  60. package/src/tools/posts.ts +0 -179
  61. package/src/tools/search.ts +0 -98
  62. package/src/tools/teams.ts +0 -157
  63. package/src/transformers/__tests__/category-transformer.test.ts +0 -161
  64. package/src/transformers/__tests__/comment-transformer.test.ts +0 -129
  65. package/src/transformers/__tests__/post-name-normalizer.test.ts +0 -53
  66. package/src/transformers/__tests__/post-transformer.test.ts +0 -70
  67. package/src/transformers/__tests__/query-normalizer.test.ts +0 -98
  68. package/src/transformers/__tests__/team-name-normalizer.test.ts +0 -21
  69. package/src/transformers/category-transformer.ts +0 -36
  70. package/src/transformers/comment-transformer.ts +0 -34
  71. package/src/transformers/post-name-normalizer.ts +0 -30
  72. package/src/transformers/post-transformer.ts +0 -38
  73. package/src/transformers/query-normalizer.ts +0 -36
  74. package/src/transformers/team-name-normalizer.ts +0 -7
  75. package/tsconfig.build.json +0 -4
  76. package/tsconfig.json +0 -30
  77. package/tsdown.config.ts +0 -13
  78. package/vitest.config.ts +0 -24
@@ -1,970 +0,0 @@
1
- import { beforeEach, describe, expect, it, vi } from "vitest";
2
- import {
3
- createExpectedTransformedComment,
4
- createMockComment,
5
- createMockCommentList,
6
- } from "../../__tests__/fixtures/mock-comment.js";
7
- import type { createEsaClient } from "../../api_client/index.js";
8
- import {
9
- createComment,
10
- deleteComment,
11
- getComment,
12
- getPostComments,
13
- getTeamComments,
14
- updateComment,
15
- } from "../comments.js";
16
-
17
- describe("getComment", () => {
18
- const mockClient = {
19
- GET: vi.fn(),
20
- } as unknown as ReturnType<typeof createEsaClient> & {
21
- GET: ReturnType<typeof vi.fn>;
22
- };
23
-
24
- beforeEach(() => {
25
- vi.clearAllMocks();
26
- });
27
-
28
- it("should get a comment successfully", async () => {
29
- const mockComment = createMockComment();
30
-
31
- mockClient.GET.mockResolvedValue({
32
- data: mockComment,
33
- error: undefined,
34
- response: {
35
- ok: true,
36
- status: 200,
37
- } as Response,
38
- });
39
-
40
- const result = await getComment(mockClient, {
41
- teamName: "test-team",
42
- commentId: 123,
43
- });
44
-
45
- expect(mockClient.GET).toHaveBeenCalledWith(
46
- "/v1/teams/{team_name}/comments/{comment_id}",
47
- {
48
- params: {
49
- path: { team_name: "test-team", comment_id: 123 },
50
- query: { include: undefined },
51
- },
52
- },
53
- );
54
-
55
- const expectedResponse = createExpectedTransformedComment(mockComment);
56
-
57
- expect(result).toEqual({
58
- content: [
59
- {
60
- type: "text",
61
- text: JSON.stringify(expectedResponse, null, 2),
62
- },
63
- ],
64
- });
65
- });
66
-
67
- it("should get a comment with stargazers when include parameter is specified", async () => {
68
- const mockComment = createMockComment({
69
- stargazers_count: 3,
70
- star: true,
71
- });
72
-
73
- mockClient.GET.mockResolvedValue({
74
- data: mockComment,
75
- error: undefined,
76
- response: {
77
- ok: true,
78
- status: 200,
79
- } as Response,
80
- });
81
-
82
- const result = await getComment(mockClient, {
83
- teamName: "test-team",
84
- commentId: 123,
85
- include: "stargazers",
86
- });
87
-
88
- expect(mockClient.GET).toHaveBeenCalledWith(
89
- "/v1/teams/{team_name}/comments/{comment_id}",
90
- {
91
- params: {
92
- path: { team_name: "test-team", comment_id: 123 },
93
- query: { include: "stargazers" },
94
- },
95
- },
96
- );
97
-
98
- const expectedResponse = createExpectedTransformedComment(mockComment);
99
-
100
- expect(result).toEqual({
101
- content: [
102
- {
103
- type: "text",
104
- text: JSON.stringify(expectedResponse, null, 2),
105
- },
106
- ],
107
- });
108
- });
109
-
110
- it("should handle API errors when getting a comment", async () => {
111
- const mockError = { error: "not_found", message: "Comment not found" };
112
-
113
- mockClient.GET.mockResolvedValue({
114
- data: undefined,
115
- error: mockError,
116
- response: {
117
- ok: false,
118
- status: 404,
119
- } as Response,
120
- });
121
-
122
- const result = await getComment(mockClient, {
123
- teamName: "test-team",
124
- commentId: 999,
125
- });
126
-
127
- expect(result).toEqual({
128
- content: [
129
- {
130
- type: "text",
131
- text: `Error: ${JSON.stringify(mockError, null, 2)}`,
132
- },
133
- ],
134
- });
135
- });
136
-
137
- it("should handle network errors when getting a comment", async () => {
138
- const networkError = new Error("Network connection failed");
139
-
140
- mockClient.GET.mockRejectedValue(networkError);
141
-
142
- const result = await getComment(mockClient, {
143
- teamName: "test-team",
144
- commentId: 123,
145
- });
146
-
147
- expect(result).toEqual({
148
- content: [
149
- {
150
- type: "text",
151
- text: "Error: Network connection failed",
152
- },
153
- ],
154
- });
155
- });
156
-
157
- it("should handle non-Error exceptions when getting a comment", async () => {
158
- mockClient.GET.mockRejectedValue("Unexpected error");
159
-
160
- const result = await getComment(mockClient, {
161
- teamName: "test-team",
162
- commentId: 123,
163
- });
164
-
165
- expect(result).toEqual({
166
- content: [
167
- {
168
- type: "text",
169
- text: "Error: Unexpected error",
170
- },
171
- ],
172
- });
173
- });
174
-
175
- it("should throw MissingTeamNameError when teamName is empty", async () => {
176
- const result = await getComment(mockClient, {
177
- teamName: "",
178
- commentId: 123,
179
- });
180
-
181
- expect(result).toEqual({
182
- content: [
183
- {
184
- type: "text",
185
- text: "Error: Missing required parameter 'teamName'. Use esa_get_teams to list available teams, then retry with teamName specified.",
186
- },
187
- ],
188
- });
189
-
190
- expect(mockClient.GET).not.toHaveBeenCalled();
191
- });
192
- });
193
-
194
- describe("createComment", () => {
195
- const mockClient = {
196
- POST: vi.fn(),
197
- } as unknown as ReturnType<typeof createEsaClient> & {
198
- POST: ReturnType<typeof vi.fn>;
199
- };
200
-
201
- beforeEach(() => {
202
- vi.clearAllMocks();
203
- });
204
-
205
- it("should create a comment successfully", async () => {
206
- const mockComment = {
207
- id: 123,
208
- post_number: 456,
209
- body_md: "This is a test comment",
210
- body_html: "<p>This is a test comment</p>",
211
- created_at: "2024-01-01T00:00:00+09:00",
212
- updated_at: "2024-01-01T00:00:00+09:00",
213
- url: "https://test-team.esa.example.com/posts/456#comment-123",
214
- created_by: {
215
- name: "Test User",
216
- screen_name: "testuser",
217
- icon: "https://example.com/icon.png",
218
- myself: true,
219
- },
220
- stargazers_count: 0,
221
- star: false,
222
- };
223
-
224
- mockClient.POST.mockResolvedValue({
225
- data: mockComment,
226
- error: undefined,
227
- response: {
228
- ok: true,
229
- status: 201,
230
- } as Response,
231
- });
232
-
233
- const result = await createComment(mockClient, {
234
- teamName: "test-team",
235
- postNumber: 456,
236
- bodyMd: "This is a test comment",
237
- });
238
-
239
- expect(mockClient.POST).toHaveBeenCalledWith(
240
- "/v1/teams/{team_name}/posts/{post_number}/comments",
241
- {
242
- params: {
243
- path: { team_name: "test-team", post_number: 456 },
244
- },
245
- body: {
246
- comment: {
247
- body_md: "This is a test comment",
248
- user: undefined,
249
- },
250
- },
251
- },
252
- );
253
-
254
- const expectedResponse = createExpectedTransformedComment(mockComment);
255
-
256
- expect(result).toEqual({
257
- content: [
258
- {
259
- type: "text",
260
- text: JSON.stringify(expectedResponse, null, 2),
261
- },
262
- ],
263
- });
264
- });
265
-
266
- it("should create a comment with user parameter", async () => {
267
- const mockComment = createMockComment({
268
- id: 124,
269
- body_md: "Comment by specific user",
270
- body_html: "<p>Comment by specific user</p>",
271
- url: "https://test-team.esa.example.com/posts/456#comment-124",
272
- created_by: {
273
- name: "Specific User",
274
- screen_name: "specificuser",
275
- icon: "https://example.com/icon2.png",
276
- myself: false,
277
- },
278
- stargazers_count: 0,
279
- star: false,
280
- });
281
-
282
- mockClient.POST.mockResolvedValue({
283
- data: mockComment,
284
- error: undefined,
285
- response: {
286
- ok: true,
287
- status: 201,
288
- } as Response,
289
- });
290
-
291
- const result = await createComment(mockClient, {
292
- teamName: "test-team",
293
- postNumber: 456,
294
- bodyMd: "Comment by specific user",
295
- user: "specificuser",
296
- });
297
-
298
- expect(mockClient.POST).toHaveBeenCalledWith(
299
- "/v1/teams/{team_name}/posts/{post_number}/comments",
300
- {
301
- params: {
302
- path: { team_name: "test-team", post_number: 456 },
303
- },
304
- body: {
305
- comment: {
306
- body_md: "Comment by specific user",
307
- user: "specificuser",
308
- },
309
- },
310
- },
311
- );
312
-
313
- const expectedResponse = createExpectedTransformedComment(mockComment);
314
-
315
- expect(result).toEqual({
316
- content: [
317
- {
318
- type: "text",
319
- text: JSON.stringify(expectedResponse, null, 2),
320
- },
321
- ],
322
- });
323
- });
324
-
325
- it("should handle API errors when creating a comment", async () => {
326
- const mockError = { error: "bad_request", message: "Invalid comment data" };
327
-
328
- mockClient.POST.mockResolvedValue({
329
- data: undefined,
330
- error: mockError,
331
- response: {
332
- ok: false,
333
- status: 400,
334
- } as Response,
335
- });
336
-
337
- const result = await createComment(mockClient, {
338
- teamName: "test-team",
339
- postNumber: 456,
340
- bodyMd: "",
341
- });
342
-
343
- expect(result).toEqual({
344
- content: [
345
- {
346
- type: "text",
347
- text: `Error: ${JSON.stringify(mockError, null, 2)}`,
348
- },
349
- ],
350
- });
351
- });
352
-
353
- it("should handle network errors when creating a comment", async () => {
354
- const networkError = new Error("Network connection failed");
355
-
356
- mockClient.POST.mockRejectedValue(networkError);
357
-
358
- const result = await createComment(mockClient, {
359
- teamName: "test-team",
360
- postNumber: 456,
361
- bodyMd: "Test comment",
362
- });
363
-
364
- expect(result).toEqual({
365
- content: [
366
- {
367
- type: "text",
368
- text: "Error: Network connection failed",
369
- },
370
- ],
371
- });
372
- });
373
-
374
- it("should handle non-Error exceptions when creating a comment", async () => {
375
- mockClient.POST.mockRejectedValue("Unexpected error");
376
-
377
- const result = await createComment(mockClient, {
378
- teamName: "test-team",
379
- postNumber: 456,
380
- bodyMd: "Test comment",
381
- });
382
-
383
- expect(result).toEqual({
384
- content: [
385
- {
386
- type: "text",
387
- text: "Error: Unexpected error",
388
- },
389
- ],
390
- });
391
- });
392
-
393
- it("should throw MissingTeamNameError when teamName is empty", async () => {
394
- const result = await createComment(mockClient, {
395
- teamName: "",
396
- postNumber: 456,
397
- bodyMd: "Test comment",
398
- });
399
-
400
- expect(result).toEqual({
401
- content: [
402
- {
403
- type: "text",
404
- text: "Error: Missing required parameter 'teamName'. Use esa_get_teams to list available teams, then retry with teamName specified.",
405
- },
406
- ],
407
- });
408
-
409
- expect(mockClient.POST).not.toHaveBeenCalled();
410
- });
411
- });
412
-
413
- describe("updateComment", () => {
414
- const mockClient = {
415
- PATCH: vi.fn(),
416
- } as unknown as ReturnType<typeof createEsaClient> & {
417
- PATCH: ReturnType<typeof vi.fn>;
418
- };
419
-
420
- beforeEach(() => {
421
- vi.clearAllMocks();
422
- });
423
-
424
- it("should update a comment successfully", async () => {
425
- const mockComment = createMockComment({
426
- body_md: "Updated comment content",
427
- body_html: "<p>Updated comment content</p>",
428
- updated_at: "2024-01-01T01:00:00+09:00",
429
- stargazers_count: 0,
430
- star: false,
431
- });
432
-
433
- mockClient.PATCH.mockResolvedValue({
434
- data: mockComment,
435
- error: undefined,
436
- response: {
437
- ok: true,
438
- status: 200,
439
- } as Response,
440
- });
441
-
442
- const result = await updateComment(mockClient, {
443
- teamName: "test-team",
444
- commentId: 123,
445
- bodyMd: "Updated comment content",
446
- });
447
-
448
- expect(mockClient.PATCH).toHaveBeenCalledWith(
449
- "/v1/teams/{team_name}/comments/{comment_id}",
450
- {
451
- params: {
452
- path: { team_name: "test-team", comment_id: 123 },
453
- },
454
- body: {
455
- comment: {
456
- body_md: "Updated comment content",
457
- user: undefined,
458
- },
459
- },
460
- },
461
- );
462
-
463
- const expectedResponse = createExpectedTransformedComment(mockComment);
464
-
465
- expect(result).toEqual({
466
- content: [
467
- {
468
- type: "text",
469
- text: JSON.stringify(expectedResponse, null, 2),
470
- },
471
- ],
472
- });
473
- });
474
-
475
- it("should handle API errors when updating a comment", async () => {
476
- const mockError = { error: "not_found", message: "Comment not found" };
477
-
478
- mockClient.PATCH.mockResolvedValue({
479
- data: undefined,
480
- error: mockError,
481
- response: {
482
- ok: false,
483
- status: 404,
484
- } as Response,
485
- });
486
-
487
- const result = await updateComment(mockClient, {
488
- teamName: "test-team",
489
- commentId: 999,
490
- bodyMd: "Updated content",
491
- });
492
-
493
- expect(result).toEqual({
494
- content: [
495
- {
496
- type: "text",
497
- text: `Error: ${JSON.stringify(mockError, null, 2)}`,
498
- },
499
- ],
500
- });
501
- });
502
-
503
- it("should handle network errors when updating a comment", async () => {
504
- const networkError = new Error("Network connection failed");
505
-
506
- mockClient.PATCH.mockRejectedValue(networkError);
507
-
508
- const result = await updateComment(mockClient, {
509
- teamName: "test-team",
510
- commentId: 123,
511
- bodyMd: "Updated content",
512
- });
513
-
514
- expect(result).toEqual({
515
- content: [
516
- {
517
- type: "text",
518
- text: "Error: Network connection failed",
519
- },
520
- ],
521
- });
522
- });
523
-
524
- it("should handle non-Error exceptions when updating a comment", async () => {
525
- mockClient.PATCH.mockRejectedValue("Unexpected error");
526
-
527
- const result = await updateComment(mockClient, {
528
- teamName: "test-team",
529
- commentId: 123,
530
- bodyMd: "Updated content",
531
- });
532
-
533
- expect(result).toEqual({
534
- content: [
535
- {
536
- type: "text",
537
- text: "Error: Unexpected error",
538
- },
539
- ],
540
- });
541
- });
542
-
543
- it("should throw MissingTeamNameError when teamName is empty", async () => {
544
- const result = await updateComment(mockClient, {
545
- teamName: "",
546
- commentId: 123,
547
- bodyMd: "Updated content",
548
- });
549
-
550
- expect(result).toEqual({
551
- content: [
552
- {
553
- type: "text",
554
- text: "Error: Missing required parameter 'teamName'. Use esa_get_teams to list available teams, then retry with teamName specified.",
555
- },
556
- ],
557
- });
558
-
559
- expect(mockClient.PATCH).not.toHaveBeenCalled();
560
- });
561
- });
562
-
563
- describe("deleteComment", () => {
564
- const mockClient = {
565
- DELETE: vi.fn(),
566
- } as unknown as ReturnType<typeof createEsaClient> & {
567
- DELETE: ReturnType<typeof vi.fn>;
568
- };
569
-
570
- beforeEach(() => {
571
- vi.clearAllMocks();
572
- });
573
-
574
- it("should delete a comment successfully", async () => {
575
- mockClient.DELETE.mockResolvedValue({
576
- error: undefined,
577
- response: {
578
- ok: true,
579
- status: 204,
580
- } as Response,
581
- });
582
-
583
- const result = await deleteComment(mockClient, {
584
- teamName: "test-team",
585
- commentId: 123,
586
- });
587
-
588
- expect(mockClient.DELETE).toHaveBeenCalledWith(
589
- "/v1/teams/{team_name}/comments/{comment_id}",
590
- {
591
- params: {
592
- path: { team_name: "test-team", comment_id: 123 },
593
- },
594
- },
595
- );
596
-
597
- expect(result).toEqual({
598
- content: [
599
- {
600
- type: "text",
601
- text: JSON.stringify(
602
- { success: true, message: "Comment deleted successfully" },
603
- null,
604
- 2,
605
- ),
606
- },
607
- ],
608
- });
609
- });
610
-
611
- it("should handle API errors when deleting a comment", async () => {
612
- const mockError = {
613
- error: "forbidden",
614
- message: "Insufficient permissions",
615
- };
616
-
617
- mockClient.DELETE.mockResolvedValue({
618
- error: mockError,
619
- response: {
620
- ok: false,
621
- status: 403,
622
- } as Response,
623
- });
624
-
625
- const result = await deleteComment(mockClient, {
626
- teamName: "test-team",
627
- commentId: 123,
628
- });
629
-
630
- expect(result).toEqual({
631
- content: [
632
- {
633
- type: "text",
634
- text: `Error: ${JSON.stringify(mockError, null, 2)}`,
635
- },
636
- ],
637
- });
638
- });
639
-
640
- it("should handle network errors when deleting a comment", async () => {
641
- const networkError = new Error("Network connection failed");
642
-
643
- mockClient.DELETE.mockRejectedValue(networkError);
644
-
645
- const result = await deleteComment(mockClient, {
646
- teamName: "test-team",
647
- commentId: 123,
648
- });
649
-
650
- expect(result).toEqual({
651
- content: [
652
- {
653
- type: "text",
654
- text: "Error: Network connection failed",
655
- },
656
- ],
657
- });
658
- });
659
-
660
- it("should handle non-Error exceptions when deleting a comment", async () => {
661
- mockClient.DELETE.mockRejectedValue("Unexpected error");
662
-
663
- const result = await deleteComment(mockClient, {
664
- teamName: "test-team",
665
- commentId: 123,
666
- });
667
-
668
- expect(result).toEqual({
669
- content: [
670
- {
671
- type: "text",
672
- text: "Error: Unexpected error",
673
- },
674
- ],
675
- });
676
- });
677
-
678
- it("should throw MissingTeamNameError when teamName is empty", async () => {
679
- const result = await deleteComment(mockClient, {
680
- teamName: "",
681
- commentId: 123,
682
- });
683
-
684
- expect(result).toEqual({
685
- content: [
686
- {
687
- type: "text",
688
- text: "Error: Missing required parameter 'teamName'. Use esa_get_teams to list available teams, then retry with teamName specified.",
689
- },
690
- ],
691
- });
692
-
693
- expect(mockClient.DELETE).not.toHaveBeenCalled();
694
- });
695
- });
696
-
697
- describe("getPostComments", () => {
698
- const mockClient = {
699
- GET: vi.fn(),
700
- } as unknown as ReturnType<typeof createEsaClient> & {
701
- GET: ReturnType<typeof vi.fn>;
702
- };
703
-
704
- beforeEach(() => {
705
- vi.clearAllMocks();
706
- });
707
-
708
- it("should get post comments successfully", async () => {
709
- const mockCommentList = createMockCommentList();
710
-
711
- mockClient.GET.mockResolvedValue({
712
- data: mockCommentList,
713
- error: undefined,
714
- response: {
715
- ok: true,
716
- status: 200,
717
- } as Response,
718
- });
719
-
720
- const result = await getPostComments(mockClient, {
721
- teamName: "test-team",
722
- postNumber: 123,
723
- });
724
-
725
- expect(mockClient.GET).toHaveBeenCalledWith(
726
- "/v1/teams/{team_name}/posts/{post_number}/comments",
727
- {
728
- params: {
729
- path: { team_name: "test-team", post_number: 123 },
730
- query: { page: undefined, per_page: undefined },
731
- },
732
- },
733
- );
734
-
735
- const transformedComments = mockCommentList.comments.map((comment) =>
736
- createExpectedTransformedComment(comment),
737
- );
738
-
739
- expect(result).toEqual({
740
- content: [
741
- {
742
- type: "text",
743
- text: JSON.stringify(
744
- { ...mockCommentList, comments: transformedComments },
745
- null,
746
- 2,
747
- ),
748
- },
749
- ],
750
- });
751
- });
752
-
753
- it("should handle API errors when getting post comments", async () => {
754
- const mockError = { error: "not_found", message: "Post not found" };
755
-
756
- mockClient.GET.mockResolvedValue({
757
- data: undefined,
758
- error: mockError,
759
- response: {
760
- ok: false,
761
- status: 404,
762
- } as Response,
763
- });
764
-
765
- const result = await getPostComments(mockClient, {
766
- teamName: "test-team",
767
- postNumber: 999,
768
- });
769
-
770
- expect(result).toEqual({
771
- content: [
772
- {
773
- type: "text",
774
- text: `Error: ${JSON.stringify(mockError, null, 2)}`,
775
- },
776
- ],
777
- });
778
- });
779
-
780
- it("should handle network errors when getting post comments", async () => {
781
- const networkError = new Error("Network connection failed");
782
-
783
- mockClient.GET.mockRejectedValue(networkError);
784
-
785
- const result = await getPostComments(mockClient, {
786
- teamName: "test-team",
787
- postNumber: 123,
788
- });
789
-
790
- expect(result).toEqual({
791
- content: [
792
- {
793
- type: "text",
794
- text: "Error: Network connection failed",
795
- },
796
- ],
797
- });
798
- });
799
-
800
- it("should handle non-Error exceptions when getting post comments", async () => {
801
- mockClient.GET.mockRejectedValue("Unexpected error");
802
-
803
- const result = await getPostComments(mockClient, {
804
- teamName: "test-team",
805
- postNumber: 123,
806
- });
807
-
808
- expect(result).toEqual({
809
- content: [
810
- {
811
- type: "text",
812
- text: "Error: Unexpected error",
813
- },
814
- ],
815
- });
816
- });
817
-
818
- it("should throw MissingTeamNameError when teamName is empty", async () => {
819
- const result = await getPostComments(mockClient, {
820
- teamName: "",
821
- postNumber: 123,
822
- });
823
-
824
- expect(result).toEqual({
825
- content: [
826
- {
827
- type: "text",
828
- text: "Error: Missing required parameter 'teamName'. Use esa_get_teams to list available teams, then retry with teamName specified.",
829
- },
830
- ],
831
- });
832
-
833
- expect(mockClient.GET).not.toHaveBeenCalled();
834
- });
835
- });
836
-
837
- describe("getTeamComments", () => {
838
- const mockClient = {
839
- GET: vi.fn(),
840
- } as unknown as ReturnType<typeof createEsaClient> & {
841
- GET: ReturnType<typeof vi.fn>;
842
- };
843
-
844
- beforeEach(() => {
845
- vi.clearAllMocks();
846
- });
847
-
848
- it("should get team comments successfully", async () => {
849
- const mockCommentList = createMockCommentList();
850
-
851
- mockClient.GET.mockResolvedValue({
852
- data: mockCommentList,
853
- error: undefined,
854
- response: {
855
- ok: true,
856
- status: 200,
857
- } as Response,
858
- });
859
-
860
- const result = await getTeamComments(mockClient, {
861
- teamName: "test-team",
862
- });
863
-
864
- expect(mockClient.GET).toHaveBeenCalledWith(
865
- "/v1/teams/{team_name}/comments",
866
- {
867
- params: {
868
- path: { team_name: "test-team" },
869
- query: { page: undefined, per_page: undefined },
870
- },
871
- },
872
- );
873
-
874
- const transformedComments = mockCommentList.comments.map((comment) =>
875
- createExpectedTransformedComment(comment),
876
- );
877
-
878
- expect(result).toEqual({
879
- content: [
880
- {
881
- type: "text",
882
- text: JSON.stringify(
883
- { ...mockCommentList, comments: transformedComments },
884
- null,
885
- 2,
886
- ),
887
- },
888
- ],
889
- });
890
- });
891
-
892
- it("should handle API errors when getting team comments", async () => {
893
- const mockError = { error: "forbidden", message: "Access denied" };
894
-
895
- mockClient.GET.mockResolvedValue({
896
- data: undefined,
897
- error: mockError,
898
- response: {
899
- ok: false,
900
- status: 403,
901
- } as Response,
902
- });
903
-
904
- const result = await getTeamComments(mockClient, {
905
- teamName: "private-team",
906
- });
907
-
908
- expect(result).toEqual({
909
- content: [
910
- {
911
- type: "text",
912
- text: `Error: ${JSON.stringify(mockError, null, 2)}`,
913
- },
914
- ],
915
- });
916
- });
917
-
918
- it("should handle network errors when getting team comments", async () => {
919
- const networkError = new Error("Network connection failed");
920
-
921
- mockClient.GET.mockRejectedValue(networkError);
922
-
923
- const result = await getTeamComments(mockClient, {
924
- teamName: "test-team",
925
- });
926
-
927
- expect(result).toEqual({
928
- content: [
929
- {
930
- type: "text",
931
- text: "Error: Network connection failed",
932
- },
933
- ],
934
- });
935
- });
936
-
937
- it("should handle non-Error exceptions when getting team comments", async () => {
938
- mockClient.GET.mockRejectedValue("Unexpected error");
939
-
940
- const result = await getTeamComments(mockClient, {
941
- teamName: "test-team",
942
- });
943
-
944
- expect(result).toEqual({
945
- content: [
946
- {
947
- type: "text",
948
- text: "Error: Unexpected error",
949
- },
950
- ],
951
- });
952
- });
953
-
954
- it("should throw MissingTeamNameError when teamName is empty", async () => {
955
- const result = await getTeamComments(mockClient, {
956
- teamName: "",
957
- });
958
-
959
- expect(result).toEqual({
960
- content: [
961
- {
962
- type: "text",
963
- text: "Error: Missing required parameter 'teamName'. Use esa_get_teams to list available teams, then retry with teamName specified.",
964
- },
965
- ],
966
- });
967
-
968
- expect(mockClient.GET).not.toHaveBeenCalled();
969
- });
970
- });