@mintlify/scraping
Version:
Scrape documentation frameworks to Mintlify docs
156 lines (121 loc) • 5.38 kB
text/typescript
import { AsyncAPISchema } from '@mintlify/common/asyncapi';
import fs from 'fs/promises';
import yaml from 'js-yaml';
import { describe, it, expect, beforeEach, vi } from 'vitest';
import { getAsyncApiDefinition } from '../src/asyncapi/getAsyncApiDefinition.js';
vi.mock('fs/promises');
vi.mock('node-fetch');
const mockAsyncApiDoc: AsyncAPISchema = {
asyncapi: '3.0.0',
info: {
title: 'Test API',
version: '1.0.0',
},
channels: {},
components: {},
};
describe('getAsyncApiDefinition', () => {
beforeEach(() => {
vi.resetAllMocks();
});
it('should load AsyncAPI doc from a local file path', async () => {
const mockYaml = yaml.dump(mockAsyncApiDoc);
vi.mocked(fs.readFile).mockResolvedValue(mockYaml);
const result = await getAsyncApiDefinition('test.yaml');
expect(fs.readFile).toHaveBeenCalledWith(expect.stringContaining('test.yaml'), 'utf-8');
expect(result).toEqual({ document: mockAsyncApiDoc, isUrl: false });
});
it('should accept AsyncAPI document directly', async () => {
const result = await getAsyncApiDefinition(mockAsyncApiDoc);
expect(result).toEqual({ document: mockAsyncApiDoc, isUrl: false });
});
it('should fetch yaml AsyncAPI doc from URL', async () => {
const mockYaml = yaml.dump(mockAsyncApiDoc);
global.fetch = vi.fn().mockResolvedValue({
ok: true,
text: () => Promise.resolve(mockYaml),
});
const url = new URL('https://example.com/asyncapi.yaml');
const result = await getAsyncApiDefinition(url);
expect(fetch).toHaveBeenCalledWith(url);
expect(result).toEqual({ document: mockAsyncApiDoc, isUrl: true });
});
it('should fetch and parse valid JSON AsyncAPI doc from URL', async () => {
const mockJson = JSON.stringify(mockAsyncApiDoc);
global.fetch = vi.fn().mockResolvedValue({
ok: true,
status: 200,
text: () => Promise.resolve(mockJson),
});
const url = new URL('https://example.com/asyncapi.yaml');
const result = await getAsyncApiDefinition(url);
expect(fetch).toHaveBeenCalledWith(url);
expect(result).toEqual({ document: mockAsyncApiDoc, isUrl: true });
});
it('should fetch AsyncAPI doc from URL string', async () => {
const mockYaml = yaml.dump(mockAsyncApiDoc);
global.fetch = vi.fn().mockResolvedValue({
ok: true,
status: 200,
text: () => Promise.resolve(mockYaml),
});
const urlString = 'https://example.com/asyncapi.yaml';
const result = await getAsyncApiDefinition(urlString);
expect(fetch).toHaveBeenCalledWith(new URL(urlString));
expect(result).toEqual({ document: mockAsyncApiDoc, isUrl: true });
});
it('should throw error when local file read fails', async () => {
vi.mocked(fs.readFile).mockRejectedValue(new Error('File read error'));
await expect(getAsyncApiDefinition('test.yaml')).rejects.toThrow('File read error');
});
it('should throw error with URL and status code when fetch fails', async () => {
global.fetch = vi.fn().mockResolvedValue({
ok: false,
status: 404,
statusText: 'Not Found',
});
const urlString = 'https://mycoolwebsocketschema/asyncapi.doesnotexist';
await expect(getAsyncApiDefinition(urlString)).rejects.toThrow(
`${urlString} - failed to retrieve AsyncAPI file from source - : 404 Not Found`
);
expect(fetch).toHaveBeenCalledWith(new URL(urlString));
});
it('should throw error when HTTP URL is provided', async () => {
const httpUrl = new URL('http://example.com/asyncapi.yaml');
await expect(getAsyncApiDefinition(httpUrl)).rejects.toThrow(
'Only HTTPS URLs are supported. Please provide an HTTPS URL'
);
});
it('should throw error when HTTP URL string is provided', async () => {
const httpUrlString = 'http://example.com/asyncapi.yaml';
await expect(getAsyncApiDefinition(httpUrlString)).rejects.toThrow(
'Only HTTPS URLs are supported. Please provide an HTTPS URL'
);
});
it('should throw error when non-HTTPS URL string is provided', async () => {
const httpUrlString = 'ftp://example.com/asyncapi.yaml';
await expect(getAsyncApiDefinition(httpUrlString)).rejects.toThrow(
'Only HTTPS URLs are supported. Please provide an HTTPS URL'
);
});
it('should throw error when URL response is invalid YAML', async () => {
global.fetch = vi.fn().mockResolvedValue({
text: () => Promise.resolve('invalid: yaml: content'),
});
await expect(getAsyncApiDefinition('https://example.com/asyncapi.yaml')).rejects.toThrow();
});
it('should throw error when URL response is invalid JSON', async () => {
global.fetch = vi.fn().mockResolvedValue({
text: () => Promise.resolve('{"invalid": "yaml", "invalid": "content"}'),
});
await expect(getAsyncApiDefinition('https://example.com/asyncapi.json')).rejects.toThrow();
});
it('should throw error when local file contains invalid YAML', async () => {
vi.mocked(fs.readFile).mockResolvedValue('invalid: yaml: content');
await expect(getAsyncApiDefinition('test.yaml')).rejects.toThrow();
});
it('should throw error when local file contains invalid JSON', async () => {
vi.mocked(fs.readFile).mockResolvedValue('{"invalid": "yaml", "invalid": "content"}');
await expect(getAsyncApiDefinition('test.json')).rejects.toThrow();
});
});