diff --git a/tests/unit/services/api-publisher.test.ts b/tests/unit/services/api-publisher.test.ts index 3446074..47a86e4 100644 --- a/tests/unit/services/api-publisher.test.ts +++ b/tests/unit/services/api-publisher.test.ts @@ -1682,6 +1682,62 @@ describe('api-publisher', () => { ); }); + it.each([ + ['OpenAPI 3', { openapi: '3.0.1' }, 'openapi+json'], + ['Swagger 2', { swagger: '2.0' }, 'swagger-json'], + ])('preserves nulls and 24-hour timestamps in sanitized %s examples', async (_label, version, format) => { + const client = createMockClient(); + const store = createMockStore([]); + const apiDescriptor: ResourceDescriptor = { + type: ResourceType.Api, + nameParts: ['observations'], + }; + const example = { + firstSeen: '2026-07-11T14:01:26.0000000+00:00', + lastSeen: '2026-07-11T14:58:54.0000000+00:00', + zone: null, + }; + const response = format === 'swagger-json' + ? { description: 'OK', examples: { 'application/json': example } } + : { description: 'OK', content: { 'application/json': { example } } }; + store.readContent.mockResolvedValue({ + format: 'json', + content: JSON.stringify({ + ...version, + info: { title: 'Observations', version: '1.0' }, + paths: { + '/observations/{id}': { + get: { operationId: 'get-observation', responses: { '200': response } }, + }, + }, + }), + }); + + const result = await publishApi(client, store, testContext, apiDescriptor, testConfig); + + expect(result.status).toBe('success'); + expect(client.putResource).toHaveBeenCalledWith( + testContext, + apiDescriptor, + expect.objectContaining({ + properties: expect.objectContaining({ format, value: expect.any(String) }), + }) + ); + const payload = client.putResource.mock.calls[0]?.[2] as { + properties: { value: string }; + }; + const publishedSpec = JSON.parse(payload.properties.value) as { + paths: Record } }>; + }; + const operation = publishedSpec.paths['/observations/{id}']!.get; + expect(operation.parameters).toEqual([ + format === 'swagger-json' + ? { name: 'id', in: 'path', required: true, type: 'string' } + : { name: 'id', in: 'path', required: true, schema: { type: 'string' } }, + ]); + expect(operation.responses['200']).toStrictEqual(response); + }); + it('should use swagger-json format for Swagger 2.0 JSON specs', async () => { const client = createMockClient(); const store = createMockStore([]); diff --git a/tests/unit/services/resource-publisher.test.ts b/tests/unit/services/resource-publisher.test.ts index 6add006..b98e724 100644 --- a/tests/unit/services/resource-publisher.test.ts +++ b/tests/unit/services/resource-publisher.test.ts @@ -79,6 +79,60 @@ function generatedSubscriptionId(fill: string): string { } describe('resource-publisher', () => { + it('preserves nulls and 24-hour timestamps in operation response examples', async () => { + const client = createMockClient(); + const store = createMockStore(); + const descriptor: ResourceDescriptor = { + type: ResourceType.ApiOperation, + nameParts: ['observations', 'get-observation'], + }; + const example = { + firstSeen: '2026-07-11T14:01:26.0000000+00:00', + lastSeen: '2026-07-11T14:58:54.0000000+00:00', + zone: null, + }; + const representations = [{ + contentType: 'application/json', + sample: JSON.stringify(example), + examples: { default: { value: example } }, + }]; + store.readResource.mockResolvedValue({ + properties: { + displayName: 'Get observation', + method: 'GET', + urlTemplate: '/', + responses: [{ statusCode: 200, representations }], + }, + }); + const expectedSample = '{"firstSeen":"2026-07-11T14:01:26.0000000+00:00","lastSeen":"2026-07-11T14:58:54.0000000+00:00","zone":null}'; + const expectedExample = { + firstSeen: '2026-07-11T14:01:26.0000000+00:00', + lastSeen: '2026-07-11T14:58:54.0000000+00:00', + zone: null, + }; + + const result = await publishResource(client, store, testContext, descriptor, testConfig); + + expect(result.status).toBe('success'); + expect(client.putResource).toHaveBeenCalledWith( + testContext, + descriptor, + expect.objectContaining({ + properties: expect.objectContaining({ + responses: [{ statusCode: 200, representations: [{ + contentType: 'application/json', + sample: expectedSample, + examples: { default: { value: expectedExample } }, + }] }], + }), + }) + ); + const payload = client.putResource.mock.calls[0]?.[2]; + const representation = payload.properties.responses[0].representations[0]; + expect(representation.sample).toBe(expectedSample); + expect(representation.examples.default.value).toStrictEqual(expectedExample); + }); + describe('resolveAssociationDeleteDescriptor', () => { it('resolves an opaque workspace API link name from its target ARM ID', async () => { const client = createMockClient();