test: ensure file formats

This commit is contained in:
Nicolas Meienberger 2025-04-25 07:08:58 +02:00
parent 65a5a418e8
commit f5d39e61d8
6 changed files with 105 additions and 8 deletions

View file

@ -22,11 +22,6 @@ jobs:
- name: Checkout - name: Checkout
uses: actions/checkout@v4 uses: actions/checkout@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version: 22
- name: Install bun - name: Install bun
uses: oven-sh/setup-bun@v2 uses: oven-sh/setup-bun@v2

23
.github/workflows/test.yml vendored Normal file
View file

@ -0,0 +1,23 @@
name: Test
on:
push:
branches: [ main ]
pull_request:
branches: [ main ]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Bun
uses: oven-sh/setup-bun@v2
- name: Install dependencies
run: bun install
- name: Run tests
run: bun test

71
__tests__/apps.test.ts Normal file
View file

@ -0,0 +1,71 @@
import { expect, test, describe } from "bun:test";
import { appInfoSchema, dynamicComposeSchema } from '@runtipi/common/schemas'
import { fromError } from 'zod-validation-error';
import fs from 'node:fs'
import path from 'node:path'
const getApps = async () => {
const appsDir = await fs.promises.readdir(path.join(process.cwd(), 'apps'))
return appsDir
};
const getFile = async (app: string, file: string) => {
const filePath = path.join(process.cwd(), 'apps', app, file)
try {
const file = await fs.promises.readFile(filePath, 'utf-8')
return file
} catch (err) {
return null
}
}
describe("each app should have the required files", async () => {
const apps = await getApps()
for (const app of apps) {
const files = ['config.json', 'docker-compose.json', 'metadata/logo.jpg', 'metadata/description.md']
for (const file of files) {
test(`app ${app} should have ${file}`, async () => {
const fileContent = await getFile(app, file)
expect(fileContent).not.toBeNull()
})
}
}
})
describe("each app should have a valid config.json", async () => {
const apps = await getApps()
for (const app of apps) {
test(`app ${app} should have a valid config.json`, async () => {
const fileContent = await getFile(app, 'config.json')
const parsed = appInfoSchema.omit({ urn: true }).safeParse(JSON.parse(fileContent || '{}'))
if (!parsed.success) {
const validationError = fromError(parsed.error);
console.error(`Error parsing config.json for app ${app}:`, validationError.toString());
}
expect(parsed.success).toBe(true)
})
}
})
describe("each app should have a valid docker-compose.json", async () => {
const apps = await getApps()
for (const app of apps) {
test(`app ${app} should have a valid docker-compose.json`, async () => {
const fileContent = await getFile(app, 'docker-compose.json')
const parsed = dynamicComposeSchema.safeParse(JSON.parse(fileContent || '{}'))
if (!parsed.success) {
const validationError = fromError(parsed.error);
console.error(`Error parsing docker-compose.json for app ${app}:`, validationError.toString());
}
expect(parsed.success).toBe(true)
})
}
});

BIN
bun.lockb

Binary file not shown.

View file

@ -5,13 +5,18 @@
"main": "index.js", "main": "index.js",
"type": "module", "type": "module",
"scripts": { "scripts": {
"test": "echo \"Error: no test specified\" && exit 1" "test": "bun test"
}, },
"keywords": [], "keywords": [],
"author": "", "author": "",
"license": "ISC", "license": "ISC",
"devDependencies": { "devDependencies": {
"@runtipi/common": "^0.8.0", "@types/bun": "^1.2.10",
"@types/node": "^22.14.1" "@types/node": "^22.14.1"
},
"dependencies": {
"@runtipi/common": "^0.8.0",
"bun": "^1.2.10",
"zod-validation-error": "^3.4.0"
} }
} }

View file

@ -17,5 +17,8 @@
"lib": [ "lib": [
"es2022" "es2022"
] ]
} },
"include": [
"**/*.ts",
],
} }