@opencx/mcp 1.15.2 → 1.15.4

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.
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=availability-statuses.spec.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"availability-statuses.spec.d.ts","sourceRoot":"","sources":["../src/availability-statuses.spec.ts"],"names":[],"mappings":""}
@@ -0,0 +1,154 @@
1
+ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
2
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
3
+ import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js';
4
+ import { createServer } from './server.js';
5
+ function mockResponse(body, status = 200, statusText = 'OK') {
6
+ return new Response(JSON.stringify(body), { status, statusText });
7
+ }
8
+ function getRequestUrl(call) {
9
+ const arg = call[0];
10
+ if (arg instanceof Request)
11
+ return arg.url;
12
+ return String(arg);
13
+ }
14
+ function getRequestMethod(call) {
15
+ const arg = call[0];
16
+ if (arg instanceof Request)
17
+ return arg.method;
18
+ const opts = call[1];
19
+ return opts.method ?? 'GET';
20
+ }
21
+ async function getRequestBody(call) {
22
+ const arg = call[0];
23
+ if (arg instanceof Request) {
24
+ const text = await arg.clone().text();
25
+ return text ? JSON.parse(text) : undefined;
26
+ }
27
+ const opts = call[1];
28
+ return opts.body ? JSON.parse(opts.body) : undefined;
29
+ }
30
+ function contentJson(content) {
31
+ const parsed = content;
32
+ return JSON.parse(parsed[0].text);
33
+ }
34
+ describe('availability status tools', () => {
35
+ let client;
36
+ let cleanup;
37
+ let fetchSpy;
38
+ beforeEach(async () => {
39
+ fetchSpy = vi.fn();
40
+ vi.stubGlobal('fetch', fetchSpy);
41
+ const server = createServer('test-api-key', 'https://api.test.com');
42
+ const [clientTransport, serverTransport] = InMemoryTransport.createLinkedPair();
43
+ await server.connect(serverTransport);
44
+ client = new Client({ name: 'test-client', version: '1.0.0' });
45
+ await client.connect(clientTransport);
46
+ cleanup = async () => {
47
+ await client.close();
48
+ await server.close();
49
+ };
50
+ });
51
+ afterEach(async () => {
52
+ await cleanup();
53
+ vi.restoreAllMocks();
54
+ });
55
+ it('registers all four availability status tools', async () => {
56
+ const { tools } = await client.listTools();
57
+ const toolNames = tools.map((t) => t.name);
58
+ expect(toolNames).toContain('list_availability_statuses');
59
+ expect(toolNames).toContain('get_user_availability_status');
60
+ expect(toolNames).toContain('get_users_availability_statuses');
61
+ expect(toolNames).toContain('apply_user_availability_status');
62
+ });
63
+ it('list_availability_statuses GETs /availability-statuses', async () => {
64
+ const statuses = [{ id: 's1', name: 'Email & Chat', group_ids: ['g1'], sort_order: 0 }];
65
+ fetchSpy.mockResolvedValueOnce(mockResponse(statuses));
66
+ const result = await client.callTool({ name: 'list_availability_statuses', arguments: {} });
67
+ expect(fetchSpy).toHaveBeenCalledOnce();
68
+ const call = fetchSpy.mock.calls[0];
69
+ expect(getRequestUrl(call)).toBe('https://api.test.com/availability-statuses');
70
+ expect(getRequestMethod(call)).toBe('GET');
71
+ expect(contentJson(result.content)).toEqual(statuses);
72
+ });
73
+ it('get_user_availability_status GETs the per-user route', async () => {
74
+ const payload = {
75
+ availability: { user_id: 7 },
76
+ resolved_status: { kind: 'online' },
77
+ teams: [],
78
+ };
79
+ fetchSpy.mockResolvedValueOnce(mockResponse(payload));
80
+ const result = await client.callTool({
81
+ name: 'get_user_availability_status',
82
+ arguments: { user_id: 7 },
83
+ });
84
+ expect(fetchSpy).toHaveBeenCalledOnce();
85
+ const call = fetchSpy.mock.calls[0];
86
+ expect(getRequestUrl(call)).toBe('https://api.test.com/availability-statuses/users/7');
87
+ expect(getRequestMethod(call)).toBe('GET');
88
+ expect(contentJson(result.content)).toEqual(payload);
89
+ });
90
+ it('get_users_availability_statuses GETs the bulk route with comma-joined ids', async () => {
91
+ const payload = [
92
+ { availability: { user_id: 7 }, resolved_status: { kind: 'offline' }, teams: [] },
93
+ { availability: { user_id: 9 }, resolved_status: { kind: 'online' }, teams: [] },
94
+ ];
95
+ fetchSpy.mockResolvedValueOnce(mockResponse(payload));
96
+ const result = await client.callTool({
97
+ name: 'get_users_availability_statuses',
98
+ arguments: { user_ids: [7, 9] },
99
+ });
100
+ expect(fetchSpy).toHaveBeenCalledOnce();
101
+ const call = fetchSpy.mock.calls[0];
102
+ const url = new URL(getRequestUrl(call));
103
+ expect(url.pathname).toBe('/availability-statuses/users');
104
+ expect(url.searchParams.get('user_ids')).toBe('7,9');
105
+ expect(getRequestMethod(call)).toBe('GET');
106
+ expect(contentJson(result.content)).toEqual(payload);
107
+ });
108
+ it('apply_user_availability_status PUTs a status_id body', async () => {
109
+ fetchSpy.mockResolvedValueOnce(mockResponse({ resolved_status: { kind: 'custom', status_id: 's1', name: 'Email & Chat' } }));
110
+ await client.callTool({
111
+ name: 'apply_user_availability_status',
112
+ arguments: { user_id: 7, status_id: 'f7b0c9a4-3b1a-4b2e-9f6d-2f9d1f6f2a10' },
113
+ });
114
+ expect(fetchSpy).toHaveBeenCalledOnce();
115
+ const call = fetchSpy.mock.calls[0];
116
+ expect(getRequestUrl(call)).toBe('https://api.test.com/availability-statuses/users/7');
117
+ expect(getRequestMethod(call)).toBe('PUT');
118
+ expect(await getRequestBody(call)).toEqual({
119
+ status_id: 'f7b0c9a4-3b1a-4b2e-9f6d-2f9d1f6f2a10',
120
+ });
121
+ });
122
+ it('apply_user_availability_status PUTs a special body', async () => {
123
+ fetchSpy.mockResolvedValueOnce(mockResponse({ resolved_status: { kind: 'offline' } }));
124
+ await client.callTool({
125
+ name: 'apply_user_availability_status',
126
+ arguments: { user_id: 7, special: 'offline' },
127
+ });
128
+ const call = fetchSpy.mock.calls[0];
129
+ expect(await getRequestBody(call)).toEqual({ special: 'offline' });
130
+ });
131
+ it('special wins over status_id when both are provided (mirrors the API priority)', async () => {
132
+ fetchSpy.mockResolvedValueOnce(mockResponse({ resolved_status: { kind: 'offline' } }));
133
+ await client.callTool({
134
+ name: 'apply_user_availability_status',
135
+ arguments: {
136
+ user_id: 7,
137
+ special: 'offline',
138
+ status_id: 'f7b0c9a4-3b1a-4b2e-9f6d-2f9d1f6f2a10',
139
+ },
140
+ });
141
+ const call = fetchSpy.mock.calls[0];
142
+ // status_id must be dropped, not merged.
143
+ expect(await getRequestBody(call)).toEqual({ special: 'offline' });
144
+ });
145
+ it('returns an error envelope without calling the API when neither field is provided', async () => {
146
+ const result = await client.callTool({
147
+ name: 'apply_user_availability_status',
148
+ arguments: { user_id: 7 },
149
+ });
150
+ expect(fetchSpy).not.toHaveBeenCalled();
151
+ expect(contentJson(result.content)).toEqual({ error: 'Provide status_id or special' });
152
+ });
153
+ });
154
+ //# sourceMappingURL=availability-statuses.spec.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"availability-statuses.spec.js","sourceRoot":"","sources":["../src/availability-statuses.spec.ts"],"names":[],"mappings":"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"}