mirror of
https://github.com/usebruno/bruno.git
synced 2026-07-07 14:08:38 +00:00
feat: add path based grouping for openapi (#5638)
* feat: add path based grouping for openapi
This commit is contained in:
212
tests/import/openapi/cli/fixtures/openapi.json
Normal file
212
tests/import/openapi/cli/fixtures/openapi.json
Normal file
@@ -0,0 +1,212 @@
|
||||
{
|
||||
"openapi": "3.0.0",
|
||||
"info": {
|
||||
"title": "Simple Test API",
|
||||
"version": "1.0.0",
|
||||
"description": "A simple API for testing groupBy functionality"
|
||||
},
|
||||
"servers": [
|
||||
{
|
||||
"url": "https://api.example.com",
|
||||
"description": "Example server"
|
||||
}
|
||||
],
|
||||
"paths": {
|
||||
"/users": {
|
||||
"get": {
|
||||
"summary": "Get all users",
|
||||
"operationId": "getUsers",
|
||||
"tags": ["users"],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of users",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"id": { "type": "integer" },
|
||||
"name": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"summary": "Create user",
|
||||
"operationId": "createUser",
|
||||
"tags": ["users"],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "User created"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/users/{id}": {
|
||||
"get": {
|
||||
"summary": "Get user by ID",
|
||||
"operationId": "getUserById",
|
||||
"tags": ["users"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "User details"
|
||||
}
|
||||
}
|
||||
},
|
||||
"put": {
|
||||
"summary": "Update user",
|
||||
"operationId": "updateUser",
|
||||
"tags": ["users"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": { "type": "string" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "User updated"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/products": {
|
||||
"get": {
|
||||
"summary": "Get all products",
|
||||
"operationId": "getProducts",
|
||||
"tags": ["products"],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of products"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/products/{id}": {
|
||||
"get": {
|
||||
"summary": "Get product by ID",
|
||||
"operationId": "getProductById",
|
||||
"tags": ["products"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Product details"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/orders": {
|
||||
"get": {
|
||||
"summary": "Get all orders",
|
||||
"operationId": "getOrders",
|
||||
"tags": ["orders"],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "List of orders"
|
||||
}
|
||||
}
|
||||
},
|
||||
"post": {
|
||||
"summary": "Create order",
|
||||
"operationId": "createOrder",
|
||||
"tags": ["orders"],
|
||||
"requestBody": {
|
||||
"required": true,
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"userId": { "type": "integer" },
|
||||
"productId": { "type": "integer" }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"201": {
|
||||
"description": "Order created"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/orders/{id}": {
|
||||
"get": {
|
||||
"summary": "Get order by ID",
|
||||
"operationId": "getOrderById",
|
||||
"tags": ["orders"],
|
||||
"parameters": [
|
||||
{
|
||||
"name": "id",
|
||||
"in": "path",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"type": "integer"
|
||||
}
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "Order details"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
78
tests/import/openapi/cli/group-by-import.spec.ts
Normal file
78
tests/import/openapi/cli/group-by-import.spec.ts
Normal file
@@ -0,0 +1,78 @@
|
||||
import { test, expect } from '../../../../playwright';
|
||||
import { execSync } from 'child_process';
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
test.describe('OpenAPI Import GroupBy Tests', () => {
|
||||
test('CLI: Import OpenAPI with tags grouping', async ({ createTmpDir }) => {
|
||||
const outputDir = await createTmpDir('openapi-tags');
|
||||
const jsonOutputPath = path.join(outputDir, 'petstore-tags.json');
|
||||
|
||||
// Run OpenAPI import with tags grouping using JSON output
|
||||
const cliPath = path.resolve(__dirname, '../../../../packages/bruno-cli/bin/bru.js');
|
||||
const specPath = path.resolve(__dirname, './fixtures/openapi.json');
|
||||
const command = `node "${cliPath}" import openapi --source "${specPath}" --output-file "${jsonOutputPath}" --collection-name "Simple API (Tags)" --group-by tags`;
|
||||
|
||||
try {
|
||||
execSync(command, { stdio: 'pipe' });
|
||||
} catch (error) {
|
||||
// Continue with test even if import fails
|
||||
}
|
||||
|
||||
// Verify JSON file was created
|
||||
expect(fs.existsSync(jsonOutputPath)).toBe(true);
|
||||
|
||||
// Read and verify collection structure
|
||||
const jsonCollection = JSON.parse(fs.readFileSync(jsonOutputPath, 'utf8'));
|
||||
expect(jsonCollection.name).toBe('Simple API (Tags)');
|
||||
|
||||
// Verify tags grouping creates folders by OpenAPI tags
|
||||
const folders = jsonCollection.items.filter((item) => item.type === 'folder');
|
||||
expect(folders.length).toBe(3);
|
||||
|
||||
const folderNames = folders.map((folder) => folder.name);
|
||||
expect(folderNames).toContain('users');
|
||||
expect(folderNames).toContain('products');
|
||||
expect(folderNames).toContain('orders');
|
||||
|
||||
// Verify tags grouping doesn't create {id} folders
|
||||
const hasIdFolders = folders.some((folder) => folder.items?.some((item) => item.name === '{id}'));
|
||||
expect(hasIdFolders).toBe(false);
|
||||
});
|
||||
|
||||
test('CLI: Import OpenAPI with path grouping', async ({ createTmpDir }) => {
|
||||
const outputDir = await createTmpDir('openapi-path');
|
||||
const jsonOutputPath = path.join(outputDir, 'petstore-path.json');
|
||||
|
||||
// Run OpenAPI import with path grouping using JSON output
|
||||
const cliPath = path.resolve(__dirname, '../../../../packages/bruno-cli/bin/bru.js');
|
||||
const specPath = path.resolve(__dirname, './fixtures/openapi.json');
|
||||
const command = `node "${cliPath}" import openapi --source "${specPath}" --output-file "${jsonOutputPath}" --collection-name "Simple API (Path)" --group-by path`;
|
||||
|
||||
try {
|
||||
execSync(command, { stdio: 'pipe' });
|
||||
} catch (error) {
|
||||
// Continue with test even if import fails
|
||||
}
|
||||
|
||||
// Verify JSON file was created
|
||||
expect(fs.existsSync(jsonOutputPath)).toBe(true);
|
||||
|
||||
// Read and verify collection structure
|
||||
const jsonCollection = JSON.parse(fs.readFileSync(jsonOutputPath, 'utf8'));
|
||||
expect(jsonCollection.name).toBe('Simple API (Path)');
|
||||
|
||||
// Verify path grouping creates folders by URL path structure
|
||||
const folders = jsonCollection.items.filter((item) => item.type === 'folder');
|
||||
expect(folders.length).toBe(3); // users, products, orders
|
||||
|
||||
const folderNames = folders.map((folder) => folder.name);
|
||||
expect(folderNames).toContain('users');
|
||||
expect(folderNames).toContain('products');
|
||||
expect(folderNames).toContain('orders');
|
||||
|
||||
// Verify path grouping creates {id} folders for parameterized paths
|
||||
const hasIdFolders = folders.some((folder) => folder.items?.some((item) => item.name === '{id}'));
|
||||
expect(hasIdFolders).toBe(true);
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user