feat: add auto-updating Postman collection for API testing
All checks were successful
Build / increment-version (push) Successful in 6s
Build / build-windows (push) Successful in 3m15s
Build / build-linux (push) Successful in 4m56s
Build / create-release (push) Successful in 19s

This commit is contained in:
litruv
2026-02-21 22:05:41 +11:00
parent f23a07384c
commit 24bed419a2
4 changed files with 513 additions and 4 deletions

View File

@@ -8,17 +8,27 @@ The API server starts automatically when you run Paarrot. It listens on `http://
### Test the API
**Option 1: Using the test script**
**Option 1: Using Postman**
Import the Postman collection for easy testing:
1. Open Postman
2. Click **Import****File**
3. Select `paarrot-api.postman_collection.json`
4. All endpoints will be ready to use!
The collection is automatically updated on git push.
**Option 2: Using the test script**
```bash
node test-api.js
```
**Option 2: Using curl**
**Option 3: Using curl**
```bash
./test-api.sh
```
**Option 3: Manual curl commands**
**Option 4: Manual curl commands**
```bash
# Health check
curl http://127.0.0.1:33384/health

View File

@@ -0,0 +1,274 @@
{
"info": {
"_postman_id": "paarrot-api-collection",
"name": "Paarrot API",
"description": "API endpoints for controlling Paarrot (Cinny Desktop) features like muting, deafening, channel navigation, and messaging.",
"schema": "https://schema.getpostman.com/json/collection/v2.1.0/collection.json",
"_exporter_id": "paarrot-api"
},
"item": [
{
"name": "Health & Status",
"item": [
{
"name": "Health Check",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/health",
"host": [
"{{baseUrl}}"
],
"path": [
"health"
]
},
"description": "Check if the API server is running and healthy."
}
},
{
"name": "Get Status",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/status",
"host": [
"{{baseUrl}}"
],
"path": [
"status"
]
},
"description": "Get current application status including mute/deafen state, current room, connection status, and user ID."
}
}
]
},
{
"name": "Audio Controls",
"item": [
{
"name": "Toggle Mute",
"request": {
"method": "POST",
"header": [],
"url": {
"raw": "{{baseUrl}}/mute/toggle",
"host": [
"{{baseUrl}}"
],
"path": [
"mute",
"toggle"
]
},
"description": "Toggle microphone mute state. Works only when in an active call."
}
},
{
"name": "Set Mute",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"muted\": true\n}"
},
"url": {
"raw": "{{baseUrl}}/mute",
"host": [
"{{baseUrl}}"
],
"path": [
"mute"
]
},
"description": "Set microphone mute to a specific state (true/false). Works only when in an active call."
}
},
{
"name": "Toggle Deafen",
"request": {
"method": "POST",
"header": [],
"url": {
"raw": "{{baseUrl}}/deafen/toggle",
"host": [
"{{baseUrl}}"
],
"path": [
"deafen",
"toggle"
]
},
"description": "Toggle deafen state (mutes all incoming audio and your microphone). Works only when in an active call."
}
},
{
"name": "Set Deafen",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"deafened\": true\n}"
},
"url": {
"raw": "{{baseUrl}}/deafen",
"host": [
"{{baseUrl}}"
],
"path": [
"deafen"
]
},
"description": "Set deafen to a specific state (true/false). Works only when in an active call."
}
}
]
},
{
"name": "Rooms & Channels",
"item": [
{
"name": "Get Channels",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/channels",
"host": [
"{{baseUrl}}"
],
"path": [
"channels"
]
},
"description": "Get list of all available rooms/channels with their details (roomId, name, isDirect, avatar)."
}
},
{
"name": "Get Current Room",
"request": {
"method": "GET",
"header": [],
"url": {
"raw": "{{baseUrl}}/room/current",
"host": [
"{{baseUrl}}"
],
"path": [
"room",
"current"
]
},
"description": "Get information about the currently active room."
}
},
{
"name": "Change Channel",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"roomId\": \"!YourRoomId:server.com\"\n}"
},
"url": {
"raw": "{{baseUrl}}/channel",
"host": [
"{{baseUrl}}"
],
"path": [
"channel"
]
},
"description": "Navigate to a different room/channel by providing its roomId."
}
}
]
},
{
"name": "Messaging",
"item": [
{
"name": "Send Message to Room",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"roomId\": \"!YourRoomId:server.com\",\n \"message\": \"Hello from Postman!\"\n}"
},
"url": {
"raw": "{{baseUrl}}/message",
"host": [
"{{baseUrl}}"
],
"path": [
"message"
]
},
"description": "Send a text message to a specific room by providing roomId and message content."
}
},
{
"name": "Send Message to Current Room",
"request": {
"method": "POST",
"header": [
{
"key": "Content-Type",
"value": "application/json"
}
],
"body": {
"mode": "raw",
"raw": "{\n \"message\": \"Hello from Postman!\"\n}"
},
"url": {
"raw": "{{baseUrl}}/message/current",
"host": [
"{{baseUrl}}"
],
"path": [
"message",
"current"
]
},
"description": "Send a text message to the currently active room."
}
}
]
}
],
"variable": [
{
"key": "baseUrl",
"value": "http://127.0.0.1:33384",
"type": "string"
}
]
}

View File

@@ -13,7 +13,8 @@
"dev:electron": "wait-on http://localhost:8080 && NODE_ENV=development electron .",
"build": "node -e \"require('fs').copyFileSync('config.json', 'cinny/config.json')\" && cd cinny && npm run build && cd .. && electron-builder --publish never",
"build:linux": "npm run build -- --linux",
"build:win": "npm run build -- --win"
"build:win": "npm run build -- --win",
"postman:generate": "node scripts/generate-postman-collection.js"
},
"keywords": [],
"author": {

View File

@@ -0,0 +1,224 @@
#!/usr/bin/env node
/**
* Generate Postman collection from API documentation
* This script reads the API.md file and generates a Postman collection
*/
const fs = require('fs');
const path = require('path');
const collection = {
info: {
_postman_id: 'paarrot-api-collection',
name: 'Paarrot API',
description: 'API endpoints for controlling Paarrot (Cinny Desktop) features like muting, deafening, channel navigation, and messaging.',
schema: 'https://schema.getpostman.com/json/collection/v2.1.0/collection.json',
_exporter_id: 'paarrot-api',
},
item: [
{
name: 'Health & Status',
item: [
{
name: 'Health Check',
request: {
method: 'GET',
header: [],
url: {
raw: '{{baseUrl}}/health',
host: ['{{baseUrl}}'],
path: ['health'],
},
description: 'Check if the API server is running and healthy.',
},
},
{
name: 'Get Status',
request: {
method: 'GET',
header: [],
url: {
raw: '{{baseUrl}}/status',
host: ['{{baseUrl}}'],
path: ['status'],
},
description: 'Get current application status including mute/deafen state, current room, connection status, and user ID.',
},
},
],
},
{
name: 'Audio Controls',
item: [
{
name: 'Toggle Mute',
request: {
method: 'POST',
header: [],
url: {
raw: '{{baseUrl}}/mute/toggle',
host: ['{{baseUrl}}'],
path: ['mute', 'toggle'],
},
description: 'Toggle microphone mute state. Works only when in an active call.',
},
},
{
name: 'Set Mute',
request: {
method: 'POST',
header: [{ key: 'Content-Type', value: 'application/json' }],
body: {
mode: 'raw',
raw: JSON.stringify({ muted: true }, null, 2),
},
url: {
raw: '{{baseUrl}}/mute',
host: ['{{baseUrl}}'],
path: ['mute'],
},
description: 'Set microphone mute to a specific state (true/false). Works only when in an active call.',
},
},
{
name: 'Toggle Deafen',
request: {
method: 'POST',
header: [],
url: {
raw: '{{baseUrl}}/deafen/toggle',
host: ['{{baseUrl}}'],
path: ['deafen', 'toggle'],
},
description: 'Toggle deafen state (mutes all incoming audio and your microphone). Works only when in an active call.',
},
},
{
name: 'Set Deafen',
request: {
method: 'POST',
header: [{ key: 'Content-Type', value: 'application/json' }],
body: {
mode: 'raw',
raw: JSON.stringify({ deafened: true }, null, 2),
},
url: {
raw: '{{baseUrl}}/deafen',
host: ['{{baseUrl}}'],
path: ['deafen'],
},
description: 'Set deafen to a specific state (true/false). Works only when in an active call.',
},
},
],
},
{
name: 'Rooms & Channels',
item: [
{
name: 'Get Channels',
request: {
method: 'GET',
header: [],
url: {
raw: '{{baseUrl}}/channels',
host: ['{{baseUrl}}'],
path: ['channels'],
},
description: 'Get list of all available rooms/channels with their details (roomId, name, isDirect, avatar).',
},
},
{
name: 'Get Current Room',
request: {
method: 'GET',
header: [],
url: {
raw: '{{baseUrl}}/room/current',
host: ['{{baseUrl}}'],
path: ['room', 'current'],
},
description: 'Get information about the currently active room.',
},
},
{
name: 'Change Channel',
request: {
method: 'POST',
header: [{ key: 'Content-Type', value: 'application/json' }],
body: {
mode: 'raw',
raw: JSON.stringify({ roomId: '!YourRoomId:server.com' }, null, 2),
},
url: {
raw: '{{baseUrl}}/channel',
host: ['{{baseUrl}}'],
path: ['channel'],
},
description: 'Navigate to a different room/channel by providing its roomId.',
},
},
],
},
{
name: 'Messaging',
item: [
{
name: 'Send Message to Room',
request: {
method: 'POST',
header: [{ key: 'Content-Type', value: 'application/json' }],
body: {
mode: 'raw',
raw: JSON.stringify(
{
roomId: '!YourRoomId:server.com',
message: 'Hello from Postman!',
},
null,
2
),
},
url: {
raw: '{{baseUrl}}/message',
host: ['{{baseUrl}}'],
path: ['message'],
},
description: 'Send a text message to a specific room by providing roomId and message content.',
},
},
{
name: 'Send Message to Current Room',
request: {
method: 'POST',
header: [{ key: 'Content-Type', value: 'application/json' }],
body: {
mode: 'raw',
raw: JSON.stringify({ message: 'Hello from Postman!' }, null, 2),
},
url: {
raw: '{{baseUrl}}/message/current',
host: ['{{baseUrl}}'],
path: ['message', 'current'],
},
description: 'Send a text message to the currently active room.',
},
},
],
},
],
variable: [
{
key: 'baseUrl',
value: 'http://127.0.0.1:33384',
type: 'string',
},
],
};
// Write the collection to file (in the project root)
const outputPath = path.join(__dirname, '..', 'paarrot-api.postman_collection.json');
fs.writeFileSync(outputPath, JSON.stringify(collection, null, 2) + '\n');
console.log('✅ Postman collection generated:', outputPath);