From 6a07b0b4ba924dbdf68991a4fbd061e620291d29 Mon Sep 17 00:00:00 2001 From: Benson Shen Date: Mon, 16 Dec 2024 17:41:38 -0500 Subject: [PATCH] test: add tests for generating release description --- .github/workflows/pr.yml | 23 ++++ .nvmrc | 2 +- .../fixtures/modified-component/current.json | 75 +++++++++++++ tests/fixtures/modified-component/expected.md | 4 + .../fixtures/modified-component/previous.json | 75 +++++++++++++ .../modified-route-and-method/current.json | 75 +++++++++++++ .../modified-route-and-method/expected.md | 4 + .../modified-route-and-method/previous.json | 75 +++++++++++++ .../new-route-and-method/current.json | 103 ++++++++++++++++++ .../fixtures/new-route-and-method/expected.md | 3 + .../new-route-and-method/previous.json | 75 +++++++++++++ tests/fixtures/removed-route/current.json | 75 +++++++++++++ tests/fixtures/removed-route/expected.md | 2 + tests/fixtures/removed-route/previous.json | 93 ++++++++++++++++ tests/generate-release.test.js | 54 +++++++++ 15 files changed, 737 insertions(+), 1 deletion(-) create mode 100644 .github/workflows/pr.yml create mode 100644 tests/fixtures/modified-component/current.json create mode 100644 tests/fixtures/modified-component/expected.md create mode 100644 tests/fixtures/modified-component/previous.json create mode 100644 tests/fixtures/modified-route-and-method/current.json create mode 100644 tests/fixtures/modified-route-and-method/expected.md create mode 100644 tests/fixtures/modified-route-and-method/previous.json create mode 100644 tests/fixtures/new-route-and-method/current.json create mode 100644 tests/fixtures/new-route-and-method/expected.md create mode 100644 tests/fixtures/new-route-and-method/previous.json create mode 100644 tests/fixtures/removed-route/current.json create mode 100644 tests/fixtures/removed-route/expected.md create mode 100644 tests/fixtures/removed-route/previous.json create mode 100644 tests/generate-release.test.js diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml new file mode 100644 index 0000000..fc70f47 --- /dev/null +++ b/.github/workflows/pr.yml @@ -0,0 +1,23 @@ +name: Pull Request + +on: + pull_request: + paths: + - scripts/api-diff.js + - tests/** + +jobs: + test-api-diff: + name: Run API Diff Tests + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Use Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.nvmrc' + + - name: Run tests + run: node --test diff --git a/.nvmrc b/.nvmrc index eb800ed..790e110 100644 --- a/.nvmrc +++ b/.nvmrc @@ -1 +1 @@ -v18.19.0 +v20.10.0 diff --git a/tests/fixtures/modified-component/current.json b/tests/fixtures/modified-component/current.json new file mode 100644 index 0000000..1239798 --- /dev/null +++ b/tests/fixtures/modified-component/current.json @@ -0,0 +1,75 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "username": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "username": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/modified-component/expected.md b/tests/fixtures/modified-component/expected.md new file mode 100644 index 0000000..33ef17f --- /dev/null +++ b/tests/fixtures/modified-component/expected.md @@ -0,0 +1,4 @@ +## Modified +- [POST] `/user` + - `NewUser` modified in requestBody + - `User` modified in requestBody, responses diff --git a/tests/fixtures/modified-component/previous.json b/tests/fixtures/modified-component/previous.json new file mode 100644 index 0000000..149a68d --- /dev/null +++ b/tests/fixtures/modified-component/previous.json @@ -0,0 +1,75 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/modified-route-and-method/current.json b/tests/fixtures/modified-route-and-method/current.json new file mode 100644 index 0000000..3747b39 --- /dev/null +++ b/tests/fixtures/modified-route-and-method/current.json @@ -0,0 +1,75 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "post": { + "summary": "Create a new user", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/modified-route-and-method/expected.md b/tests/fixtures/modified-route-and-method/expected.md new file mode 100644 index 0000000..5d37e55 --- /dev/null +++ b/tests/fixtures/modified-route-and-method/expected.md @@ -0,0 +1,4 @@ +## Modified +- [POST] `/user` + - responses + - summary diff --git a/tests/fixtures/modified-route-and-method/previous.json b/tests/fixtures/modified-route-and-method/previous.json new file mode 100644 index 0000000..149a68d --- /dev/null +++ b/tests/fixtures/modified-route-and-method/previous.json @@ -0,0 +1,75 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/new-route-and-method/current.json b/tests/fixtures/new-route-and-method/current.json new file mode 100644 index 0000000..d4a78cf --- /dev/null +++ b/tests/fixtures/new-route-and-method/current.json @@ -0,0 +1,103 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/test": { + "get": { + "summary": "Test endpoint", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/user": { + "get": { + "summary": "Get a list of users", + "responses": { + "200": { + "description": "A JSON array of user objects", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/new-route-and-method/expected.md b/tests/fixtures/new-route-and-method/expected.md new file mode 100644 index 0000000..f40bf91 --- /dev/null +++ b/tests/fixtures/new-route-and-method/expected.md @@ -0,0 +1,3 @@ +## Added +- [GET] `/test` +- [GET] `/user` diff --git a/tests/fixtures/new-route-and-method/previous.json b/tests/fixtures/new-route-and-method/previous.json new file mode 100644 index 0000000..149a68d --- /dev/null +++ b/tests/fixtures/new-route-and-method/previous.json @@ -0,0 +1,75 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/removed-route/current.json b/tests/fixtures/removed-route/current.json new file mode 100644 index 0000000..adfa29e --- /dev/null +++ b/tests/fixtures/removed-route/current.json @@ -0,0 +1,75 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "names": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/fixtures/removed-route/expected.md b/tests/fixtures/removed-route/expected.md new file mode 100644 index 0000000..a01ceca --- /dev/null +++ b/tests/fixtures/removed-route/expected.md @@ -0,0 +1,2 @@ +## Removed +- [GET] `/user` diff --git a/tests/fixtures/removed-route/previous.json b/tests/fixtures/removed-route/previous.json new file mode 100644 index 0000000..dc8a0ab --- /dev/null +++ b/tests/fixtures/removed-route/previous.json @@ -0,0 +1,93 @@ +{ + "openapi": "3.0.3", + "info": { + "title": "Test API", + "description": "A sample API to for testing", + "version": "1.0.0" + }, + "servers": [ + { + "url": "https://api.example.com/v1" + } + ], + "paths": { + "/user": { + "get": { + "summary": "Get a list of users", + "responses": { + "200": { + "description": "A JSON array of user objects", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + }, + "post": { + "summary": "Create a new user profile", + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/NewUser" + } + } + } + }, + "responses": { + "201": { + "description": "User created successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/User" + } + } + } + } + } + } + } + }, + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "email": { + "type": "string" + } + } + }, + "NewUser": { + "type": "object", + "required": [ + "name", + "email" + ], + "properties": { + "names": { + "type": "string" + }, + "email": { + "type": "string" + } + } + } + } + } +} diff --git a/tests/generate-release.test.js b/tests/generate-release.test.js new file mode 100644 index 0000000..5bf5c11 --- /dev/null +++ b/tests/generate-release.test.js @@ -0,0 +1,54 @@ +const fs = require('fs'); +const path = require('path'); +const { execSync } = require('child_process'); +const { describe, it, beforeEach, afterEach } = require('node:test'); +const assert = require('node:assert'); + +const FIXTURES_DIR = path.join(__dirname, 'fixtures'); + +describe('Generate Release Description', async () => { + const scenarios = fs.readdirSync(FIXTURES_DIR); + + beforeEach(() => { + // Clean up any existing output files + if (fs.existsSync('release-description.md')) { + fs.unlinkSync('release-description.md'); + } + }); + + scenarios.forEach(scenario => { + it(`handles ${scenario} correctly`, () => { + // Copy fixture files to working directory + const scenarioDir = path.join(FIXTURES_DIR, scenario); + fs.copyFileSync( + path.join(scenarioDir, 'previous.json'), + 'previous.json' + ); + fs.copyFileSync( + path.join(scenarioDir, 'current.json'), + 'current.json' + ); + + // Run the script + execSync('node scripts/api-diff.js'); + + // Compare output with expected + const actual = fs.readFileSync('release-description.md', 'utf8').trim(); + const expected = fs.readFileSync( + path.join(scenarioDir, 'expected.md'), + 'utf8' + ).trim(); + + assert.strictEqual(actual, expected); + }); + }); + + afterEach(() => { + // Clean up test files + ['previous.json', 'current.json', 'release-description.md'].forEach(file => { + if (fs.existsSync(file)) { + fs.unlinkSync(file); + } + }); + }); +});