111 lines
4.6 KiB
JavaScript
111 lines
4.6 KiB
JavaScript
import { test, before, after } from 'node:test'
|
|
import assert from 'node:assert/strict'
|
|
import { startFakeGitea } from './helpers/fakeGitea.js'
|
|
import { startFakeAppwrite } from './helpers/fakeAppwrite.js'
|
|
|
|
let gitea
|
|
let aw
|
|
let config
|
|
let listAllAccessibleRepos
|
|
let importNewRepos
|
|
let syncReposToAppwrite
|
|
let isHostedProject
|
|
let ensureRepoPreviewConfig
|
|
|
|
before(async () => {
|
|
gitea = await startFakeGitea({
|
|
repos: [
|
|
{ full_name: 'knso/alt' },
|
|
{ full_name: 'JUSN/neu', description: 'Döner Nation' },
|
|
{ full_name: 'JUSN/archiv', archived: true },
|
|
{ full_name: 'knso/privat', private: true },
|
|
{ full_name: 'knso/synced-sub' },
|
|
{ full_name: 'knso/lead' },
|
|
],
|
|
})
|
|
|
|
aw = await startFakeAppwrite({
|
|
seed: {
|
|
websiteProjects: [
|
|
{ repoFullName: 'knso/alt', projectName: 'alt', subdomain: 'alt' },
|
|
{ repoFullName: 'knso/synced-sub', projectName: 'synced-sub', status: 'synced', subdomain: 'synced-sub' },
|
|
{ repoFullName: 'knso/lead', projectName: 'lead', status: 'deployed', subdomain: 'lead' },
|
|
],
|
|
},
|
|
})
|
|
|
|
Object.assign(process.env, {
|
|
GITEA_BASE_URL: gitea.baseUrl,
|
|
GITEA_API_TOKEN: 'test-token',
|
|
APPWRITE_ENDPOINT: aw.endpoint,
|
|
APPWRITE_API_KEY: 'test-key',
|
|
PREVIEW_DEPLOY_ROOT: '',
|
|
TRAEFIK_DYNAMIC_DIR: '',
|
|
})
|
|
// config.js liest die Umgebung beim Import
|
|
;({ config } = await import('../server/config.js'))
|
|
;({ listAllAccessibleRepos, importNewRepos, syncReposToAppwrite, isHostedProject, ensureRepoPreviewConfig } =
|
|
await import('../server/services/giteaAdmin.js'))
|
|
})
|
|
|
|
after(async () => {
|
|
await gitea.close()
|
|
await aw.close()
|
|
})
|
|
|
|
test('importNewRepos legt nur fehlende an', async () => {
|
|
assert.deepEqual(await importNewRepos(), { created: 2 })
|
|
const neu = aw.all('websiteProjects').find((d) => d.repoFullName === 'JUSN/neu')
|
|
assert.deepEqual([neu.projectName, neu.status, neu.subdomain || '', neu.previewUrl || ''], ['Döner Nation', 'synced', '', ''])
|
|
assert.ok(aw.all('websiteProjects').some((d) => d.repoFullName === 'knso/privat'))
|
|
assert.ok(!aw.all('websiteProjects').some((d) => d.repoFullName === 'JUSN/archiv'))
|
|
assert.equal(aw.calls.filter((c) => c.method === 'PATCH').length, 0)
|
|
})
|
|
test('importNewRepos läuft nie doppelt', async () => {
|
|
gitea.addRepo({ full_name: 'ANDJ/zweimal' })
|
|
await Promise.all([importNewRepos(), importNewRepos()])
|
|
assert.equal(aw.all('websiteProjects').filter((d) => d.repoFullName === 'ANDJ/zweimal').length, 1)
|
|
})
|
|
test('Abgleich vergibt keine Subdomain mehr', async () => {
|
|
gitea.addRepo({ full_name: 'ANDJ/sync-neu' })
|
|
await syncReposToAppwrite()
|
|
const d = aw.all('websiteProjects').find((x) => x.repoFullName === 'ANDJ/sync-neu')
|
|
assert.equal(d.subdomain || '', ''); assert.equal(d.previewUrl || '', '')
|
|
assert.equal(aw.all('websiteProjects').find((x) => x.repoFullName === 'knso/alt').subdomain, 'alt')
|
|
})
|
|
test('isHostedProject', () => {
|
|
for (const [doc, want] of [[{ projectType: 'preview' }, true], [{ projectType: 'website' }, true], [{ projectType: 'template' }, true],
|
|
[{ status: 'deployed' }, true], [{ status: 'pending' }, true], [{ status: 'synced', subdomain: 'x' }, false], [{}, false]]) {
|
|
assert.equal(isHostedProject(doc), want, JSON.stringify(doc))
|
|
}
|
|
})
|
|
test('Selbstheilung nur für gehostete Projekte', async () => {
|
|
assert.equal(await ensureRepoPreviewConfig('knso/synced-sub', 'main'), null)
|
|
assert.equal(gitea.calls.filter((c) => c.path.includes('synced-sub/contents')).length, 0)
|
|
const cfg = await ensureRepoPreviewConfig('knso/lead', 'main')
|
|
assert.equal(cfg.subdomain, 'lead')
|
|
assert.ok(gitea.calls.some((c) => c.method === 'POST' && c.path.includes('knso/lead/contents/.webklar-preview.json')))
|
|
})
|
|
test('Repo-Liste hat eine Obergrenze', async () => {
|
|
// R8: eigener Fake-Server + kurzzeitig umgebogene config.gitea.baseUrl (statt in `gitea` oben
|
|
// Tausende Repos zu seeden) - sonst wuerden importNewRepos/syncReposToAppwrite in den Tests
|
|
// darueber auf einmal Tausende zusaetzliche, unbenannte Repos mitverarbeiten.
|
|
const capRepos = []
|
|
for (let i = 0; i < 2005; i++) capRepos.push({ full_name: `cap/repo${i}` })
|
|
const capGitea = await startFakeGitea({ repos: capRepos })
|
|
const originalBaseUrl = config.gitea.baseUrl
|
|
const originalWarn = console.warn
|
|
console.warn = () => {}
|
|
config.gitea.baseUrl = capGitea.baseUrl
|
|
let repos
|
|
try {
|
|
repos = await listAllAccessibleRepos()
|
|
} finally {
|
|
config.gitea.baseUrl = originalBaseUrl
|
|
console.warn = originalWarn
|
|
await capGitea.close()
|
|
}
|
|
assert.equal(repos.length, 2000)
|
|
assert.equal(capGitea.calls.filter((c) => c.path === '/api/v1/repos/search').length, 40)
|
|
})
|