Skip to content

Commit 10bee5e

Browse files
test: add unit tests for configuration and type parsing
1 parent 31267cf commit 10bee5e

2 files changed

Lines changed: 138 additions & 0 deletions

File tree

test/unit/config.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { loadConfig } from '../../src/config'
3+
4+
describe('Config', () => {
5+
it('should load default configuration', () => {
6+
const config = loadConfig()
7+
8+
expect(config).toBeDefined()
9+
expect(config.server.name).toBe('sufetch-mcp')
10+
expect(config.server.version).toBe('0.3.0')
11+
})
12+
13+
it('should have default cache settings', () => {
14+
const config = loadConfig()
15+
16+
expect(config.cache.exampleSize).toBe(100)
17+
expect(config.cache.exampleTTL).toBe(5 * 60 * 1000) // 5 minutes
18+
})
19+
20+
it('should have default HTTP settings', () => {
21+
const config = loadConfig()
22+
23+
expect(config.http.methods).toContain('get')
24+
expect(config.http.methods).toContain('post')
25+
expect(config.http.successCodes).toContain(200)
26+
expect(config.http.successCodes).toContain(201)
27+
})
28+
29+
it('should respect SUFETCH_DEBUG environment variable', () => {
30+
const originalValue = process.env.SUFETCH_DEBUG
31+
32+
process.env.SUFETCH_DEBUG = 'true'
33+
const configWithDebug = loadConfig()
34+
expect(configWithDebug.debug).toBe(true)
35+
36+
process.env.SUFETCH_DEBUG = 'false'
37+
const configWithoutDebug = loadConfig()
38+
expect(configWithoutDebug.debug).toBe(false)
39+
40+
// Restore original value
41+
if (originalValue === undefined) {
42+
delete process.env.SUFETCH_DEBUG
43+
}
44+
else {
45+
process.env.SUFETCH_DEBUG = originalValue
46+
}
47+
})
48+
49+
it('should have schema configuration', () => {
50+
const config = loadConfig()
51+
52+
expect(config.schemas.identifierFields).toContain('id')
53+
expect(config.schemas.identifierFields).toContain('uuid')
54+
expect(config.schemas.importantFieldPatterns).toContain('name')
55+
expect(config.schemas.importantFieldPatterns).toContain('title')
56+
})
57+
58+
it('should have example value defaults', () => {
59+
const config = loadConfig()
60+
61+
expect(config.exampleValues.defaultEmail).toBe('user@example.com')
62+
expect(config.exampleValues.defaultUrl).toBe('https://example.com')
63+
expect(config.exampleValues.defaultNumber).toBe(10)
64+
expect(config.exampleValues.defaultInteger).toBe(1)
65+
expect(config.exampleValues.defaultBoolean).toBe(true)
66+
expect(config.exampleValues.getCurrentTimestamp).toBeDefined()
67+
expect(typeof config.exampleValues.getCurrentTimestamp()).toBe('string')
68+
})
69+
})

test/unit/type-parser.test.ts

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { existsSync } from 'node:fs'
2+
import { join } from 'node:path'
3+
import { describe, expect, it } from 'vitest'
4+
import { parseApiSpec } from '../../src/type-parser'
5+
6+
describe('Type Parser', () => {
7+
it('should parse DigitalOcean API types', () => {
8+
const typesPath = join(process.cwd(), 'openapi-specs/digitalocean/types.d.ts')
9+
10+
if (!existsSync(typesPath)) {
11+
console.warn('DigitalOcean types.d.ts not found, skipping test')
12+
return
13+
}
14+
15+
const spec = parseApiSpec(typesPath, 'digitalocean')
16+
17+
expect(spec).toBeDefined()
18+
expect(spec.paths.size).toBeGreaterThan(0)
19+
})
20+
21+
it('should parse Hetzner API types', () => {
22+
const typesPath = join(process.cwd(), 'openapi-specs/hetzner/types.d.ts')
23+
24+
if (!existsSync(typesPath)) {
25+
console.warn('Hetzner types.d.ts not found, skipping test')
26+
return
27+
}
28+
29+
const spec = parseApiSpec(typesPath, 'hetzner')
30+
31+
expect(spec).toBeDefined()
32+
expect(spec.paths.size).toBeGreaterThan(0)
33+
})
34+
35+
it('should parse Ory Kratos API types', () => {
36+
const typesPath = join(process.cwd(), 'openapi-specs/ory/types.d.ts')
37+
38+
if (!existsSync(typesPath)) {
39+
console.warn('Ory types.d.ts not found, skipping test')
40+
return
41+
}
42+
43+
const spec = parseApiSpec(typesPath, 'ory')
44+
45+
expect(spec).toBeDefined()
46+
expect(spec.paths.size).toBeGreaterThan(0)
47+
})
48+
49+
it('should return valid spec structure', () => {
50+
const typesPath = join(process.cwd(), 'openapi-specs/digitalocean/types.d.ts')
51+
52+
if (!existsSync(typesPath)) {
53+
console.warn('DigitalOcean types.d.ts not found, skipping test')
54+
return
55+
}
56+
57+
const spec = parseApiSpec(typesPath, 'digitalocean')
58+
59+
// Verify spec has required structure
60+
expect(spec).toBeDefined()
61+
expect(spec).toHaveProperty('paths')
62+
expect(spec.paths).toBeInstanceOf(Map)
63+
expect(spec.paths.size).toBeGreaterThan(0)
64+
65+
// Verify at least one path exists with methods
66+
const firstPath = spec.paths.values().next().value
67+
expect(firstPath).toBeDefined()
68+
})
69+
})

0 commit comments

Comments
 (0)