@jgardner04/ghost-mcp-server 1.1.5 → 1.1.6
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/package.json
CHANGED
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a mock Ghost Admin API instance with configurable behavior.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} options - Configuration options for the mock
|
|
7
|
+
* @param {Object} options.posts - Mock implementations for posts methods
|
|
8
|
+
* @param {Object} options.tags - Mock implementations for tags methods
|
|
9
|
+
* @param {Object} options.site - Mock implementations for site methods
|
|
10
|
+
* @param {Object} options.images - Mock implementations for images methods
|
|
11
|
+
* @returns {Object} Mock Ghost Admin API instance
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* import { createMockGhostApi } from '../helpers/mockGhostApi.js';
|
|
15
|
+
*
|
|
16
|
+
* const api = createMockGhostApi({
|
|
17
|
+
* posts: {
|
|
18
|
+
* add: vi.fn().mockResolvedValue({ id: '1', title: 'Test Post' }),
|
|
19
|
+
* },
|
|
20
|
+
* tags: {
|
|
21
|
+
* browse: vi.fn().mockResolvedValue([{ id: '1', name: 'Test Tag' }]),
|
|
22
|
+
* },
|
|
23
|
+
* });
|
|
24
|
+
*/
|
|
25
|
+
export function createMockGhostApi(options = {}) {
|
|
26
|
+
return {
|
|
27
|
+
posts: {
|
|
28
|
+
add: vi.fn(),
|
|
29
|
+
browse: vi.fn(),
|
|
30
|
+
read: vi.fn(),
|
|
31
|
+
edit: vi.fn(),
|
|
32
|
+
delete: vi.fn(),
|
|
33
|
+
...options.posts,
|
|
34
|
+
},
|
|
35
|
+
tags: {
|
|
36
|
+
add: vi.fn(),
|
|
37
|
+
browse: vi.fn(),
|
|
38
|
+
read: vi.fn(),
|
|
39
|
+
edit: vi.fn(),
|
|
40
|
+
delete: vi.fn(),
|
|
41
|
+
...options.tags,
|
|
42
|
+
},
|
|
43
|
+
site: {
|
|
44
|
+
read: vi.fn(),
|
|
45
|
+
...options.site,
|
|
46
|
+
},
|
|
47
|
+
images: {
|
|
48
|
+
upload: vi.fn(),
|
|
49
|
+
...options.images,
|
|
50
|
+
},
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Creates a mock Ghost Admin API constructor for use with vi.mock().
|
|
56
|
+
*
|
|
57
|
+
* @param {Object} defaultOptions - Default configuration for all instances
|
|
58
|
+
* @returns {Function} Mock constructor function
|
|
59
|
+
*
|
|
60
|
+
* @example
|
|
61
|
+
* import { createMockGhostApiConstructor } from '../helpers/mockGhostApi.js';
|
|
62
|
+
*
|
|
63
|
+
* vi.mock('@tryghost/admin-api', () => ({
|
|
64
|
+
* default: createMockGhostApiConstructor({
|
|
65
|
+
* posts: {
|
|
66
|
+
* add: vi.fn().mockResolvedValue({ id: '1', title: 'Test Post' }),
|
|
67
|
+
* },
|
|
68
|
+
* }),
|
|
69
|
+
* }));
|
|
70
|
+
*/
|
|
71
|
+
export function createMockGhostApiConstructor(defaultOptions = {}) {
|
|
72
|
+
return vi.fn(function () {
|
|
73
|
+
return createMockGhostApi(defaultOptions);
|
|
74
|
+
});
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* Creates a default mock Ghost Admin API module for vi.mock().
|
|
79
|
+
*
|
|
80
|
+
* @param {Object} options - Configuration options for the mock API
|
|
81
|
+
* @returns {Object} Mock module with default export
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* import { mockGhostApiModule } from '../helpers/mockGhostApi.js';
|
|
85
|
+
*
|
|
86
|
+
* vi.mock('@tryghost/admin-api', () => mockGhostApiModule());
|
|
87
|
+
*/
|
|
88
|
+
export function mockGhostApiModule(options = {}) {
|
|
89
|
+
return {
|
|
90
|
+
default: createMockGhostApiConstructor(options),
|
|
91
|
+
};
|
|
92
|
+
}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a mock logger instance with spy functions for testing.
|
|
5
|
+
*
|
|
6
|
+
* @returns {Object} Mock logger with common logging methods
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* import { createMockLogger } from '../helpers/mockLogger.js';
|
|
10
|
+
*
|
|
11
|
+
* const logger = createMockLogger();
|
|
12
|
+
* logger.info('test message');
|
|
13
|
+
* expect(logger.info).toHaveBeenCalledWith('test message');
|
|
14
|
+
*/
|
|
15
|
+
export function createMockLogger() {
|
|
16
|
+
return {
|
|
17
|
+
apiRequest: vi.fn(),
|
|
18
|
+
apiResponse: vi.fn(),
|
|
19
|
+
apiError: vi.fn(),
|
|
20
|
+
warn: vi.fn(),
|
|
21
|
+
error: vi.fn(),
|
|
22
|
+
info: vi.fn(),
|
|
23
|
+
debug: vi.fn(),
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* Creates a mock context logger factory that returns a mock logger.
|
|
29
|
+
*
|
|
30
|
+
* @returns {Function} Mock createContextLogger function
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* import { createMockContextLogger } from '../helpers/mockLogger.js';
|
|
34
|
+
*
|
|
35
|
+
* vi.mock('../../utils/logger.js', () => ({
|
|
36
|
+
* createContextLogger: createMockContextLogger(),
|
|
37
|
+
* }));
|
|
38
|
+
*/
|
|
39
|
+
export function createMockContextLogger() {
|
|
40
|
+
return vi.fn(() => createMockLogger());
|
|
41
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Creates a mock environment variable configuration.
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} env - Environment variables to set
|
|
7
|
+
* @returns {Object} Mock dotenv module
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* import { mockEnv } from '../helpers/testUtils.js';
|
|
11
|
+
*
|
|
12
|
+
* vi.mock('dotenv', () => mockEnv({
|
|
13
|
+
* GHOST_ADMIN_API_URL: 'https://test.ghost.io',
|
|
14
|
+
* GHOST_ADMIN_API_KEY: 'test-key',
|
|
15
|
+
* }));
|
|
16
|
+
*/
|
|
17
|
+
export function mockEnv(env = {}) {
|
|
18
|
+
// Set environment variables
|
|
19
|
+
Object.entries(env).forEach(([key, value]) => {
|
|
20
|
+
process.env[key] = value;
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
default: {
|
|
25
|
+
config: vi.fn(),
|
|
26
|
+
},
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Cleans up environment variables after tests.
|
|
32
|
+
*
|
|
33
|
+
* @param {string[]} keys - Array of environment variable keys to remove
|
|
34
|
+
*
|
|
35
|
+
* @example
|
|
36
|
+
* import { cleanupEnv } from '../helpers/testUtils.js';
|
|
37
|
+
*
|
|
38
|
+
* afterEach(() => {
|
|
39
|
+
* cleanupEnv(['GHOST_ADMIN_API_URL', 'GHOST_ADMIN_API_KEY']);
|
|
40
|
+
* });
|
|
41
|
+
*/
|
|
42
|
+
export function cleanupEnv(keys) {
|
|
43
|
+
keys.forEach((key) => {
|
|
44
|
+
delete process.env[key];
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Creates a mock dotenv module for use with vi.mock().
|
|
50
|
+
*
|
|
51
|
+
* @returns {Object} Mock dotenv module
|
|
52
|
+
*
|
|
53
|
+
* @example
|
|
54
|
+
* import { mockDotenv } from '../helpers/testUtils.js';
|
|
55
|
+
*
|
|
56
|
+
* vi.mock('dotenv', () => mockDotenv());
|
|
57
|
+
*/
|
|
58
|
+
export function mockDotenv() {
|
|
59
|
+
return {
|
|
60
|
+
default: {
|
|
61
|
+
config: vi.fn(),
|
|
62
|
+
},
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Waits for a condition to be true or times out.
|
|
68
|
+
*
|
|
69
|
+
* @param {Function} condition - Function that returns true when condition is met
|
|
70
|
+
* @param {number} timeout - Maximum time to wait in milliseconds
|
|
71
|
+
* @param {number} interval - Check interval in milliseconds
|
|
72
|
+
* @returns {Promise<boolean>} True if condition met, false if timeout
|
|
73
|
+
*
|
|
74
|
+
* @example
|
|
75
|
+
* import { waitFor } from '../helpers/testUtils.js';
|
|
76
|
+
*
|
|
77
|
+
* await waitFor(() => mockFn.mock.calls.length > 0, 1000, 100);
|
|
78
|
+
*/
|
|
79
|
+
export async function waitFor(condition, timeout = 5000, interval = 100) {
|
|
80
|
+
const startTime = Date.now();
|
|
81
|
+
|
|
82
|
+
while (Date.now() - startTime < timeout) {
|
|
83
|
+
if (condition()) {
|
|
84
|
+
return true;
|
|
85
|
+
}
|
|
86
|
+
await new Promise((resolve) => setTimeout(resolve, interval));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates a promise that resolves after a specified delay.
|
|
94
|
+
*
|
|
95
|
+
* @param {number} ms - Milliseconds to delay
|
|
96
|
+
* @returns {Promise<void>}
|
|
97
|
+
*
|
|
98
|
+
* @example
|
|
99
|
+
* import { delay } from '../helpers/testUtils.js';
|
|
100
|
+
*
|
|
101
|
+
* await delay(1000); // Wait 1 second
|
|
102
|
+
*/
|
|
103
|
+
export function delay(ms) {
|
|
104
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
105
|
+
}
|
|
@@ -1,46 +1,17 @@
|
|
|
1
1
|
import { describe, it, expect, vi } from 'vitest';
|
|
2
|
+
import { mockGhostApiModule } from '../../__tests__/helpers/mockGhostApi.js';
|
|
3
|
+
import { createMockContextLogger } from '../../__tests__/helpers/mockLogger.js';
|
|
4
|
+
import { mockDotenv } from '../../__tests__/helpers/testUtils.js';
|
|
2
5
|
|
|
3
6
|
// Mock the Ghost Admin API
|
|
4
|
-
vi.mock('@tryghost/admin-api', () =>
|
|
5
|
-
const GhostAdminAPI = vi.fn(function () {
|
|
6
|
-
return {
|
|
7
|
-
posts: {
|
|
8
|
-
add: vi.fn(),
|
|
9
|
-
},
|
|
10
|
-
tags: {
|
|
11
|
-
add: vi.fn(),
|
|
12
|
-
browse: vi.fn(),
|
|
13
|
-
},
|
|
14
|
-
site: {
|
|
15
|
-
read: vi.fn(),
|
|
16
|
-
},
|
|
17
|
-
images: {
|
|
18
|
-
upload: vi.fn(),
|
|
19
|
-
},
|
|
20
|
-
};
|
|
21
|
-
});
|
|
22
|
-
|
|
23
|
-
return {
|
|
24
|
-
default: GhostAdminAPI,
|
|
25
|
-
};
|
|
26
|
-
});
|
|
7
|
+
vi.mock('@tryghost/admin-api', () => mockGhostApiModule());
|
|
27
8
|
|
|
28
9
|
// Mock dotenv
|
|
29
|
-
vi.mock('dotenv', () => (
|
|
30
|
-
default: {
|
|
31
|
-
config: vi.fn(),
|
|
32
|
-
},
|
|
33
|
-
}));
|
|
10
|
+
vi.mock('dotenv', () => mockDotenv());
|
|
34
11
|
|
|
35
12
|
// Mock logger
|
|
36
13
|
vi.mock('../../utils/logger.js', () => ({
|
|
37
|
-
createContextLogger:
|
|
38
|
-
apiRequest: vi.fn(),
|
|
39
|
-
apiResponse: vi.fn(),
|
|
40
|
-
apiError: vi.fn(),
|
|
41
|
-
warn: vi.fn(),
|
|
42
|
-
error: vi.fn(),
|
|
43
|
-
})),
|
|
14
|
+
createContextLogger: createMockContextLogger(),
|
|
44
15
|
}));
|
|
45
16
|
|
|
46
17
|
// Import after setting up mocks and environment
|