Files
Webklar-Kundenbereich/test/repoMove.test.js
T
2026-09-30 10:21:34 +00:00

149 lines
5.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import { test, before, after } from 'node:test'
import assert from 'node:assert/strict'
import fs from 'node:fs/promises'
import os from 'node:os'
import path from 'node:path'
import { randomUUID } from 'node:crypto'
import { startFakeGitea } from './helpers/fakeGitea.js'
import { startFakeAppwrite } from './helpers/fakeAppwrite.js'
let gitea
let aw
let tmp
let originalCwd
let previewWorkDir
let moveRepoToOrg
let isOrgRepo
let isInternalRepo
let repoLockKey
let currentRepoFullName
// Schluessel: urspruenglich gesetzter repoFullName -> Appwrite-$id. Wird beim Seeden befuellt
// (siehe Controller-Ruling R2) - eine Live-Suche ueber repoFullName wuerde nach einem Umzug
// nichts mehr finden, weil sich das Feld dann geaendert hat.
const idByRepo = new Map()
/** Liefert das gespeicherte Dokument des Repos, ueber den zur Seed-Zeit gebauten Id-Index. */
function doc(name) {
return aw.get('websiteProjects', idByRepo.get(name))
}
before(async () => {
gitea = await startFakeGitea({
repos: [
{ full_name: 'JUSN/D-ner-Nation' },
{ full_name: 'knso/emmas-schatzkiste' },
{ full_name: 'ANDJ/Steuerungstechnik' },
{ full_name: 'knso/hytail-ark' },
{ full_name: 'WEBklar/schon-da' },
{ full_name: 'JUSN/schon-da' },
{ full_name: 'WEBklar/von-hand' },
{ full_name: 'ANDJ/unberuehrt' },
],
hooks: {
'knso/emmas-schatzkiste': [{ id: 110, url: 'https://project.webklar.com/webhook/gitea' }],
'knso/hytail-ark': [{ id: 7, url: 'https://webklar.com/webhook/hytail-ark/deploy' }],
},
// knso/von-hand wurde von Hand bereits nach WEBklar/von-hand verschoben (kein Transfer-Aufruf noetig).
redirects: {
'knso/von-hand': 'WEBklar/von-hand',
},
})
const repoNames = [
'JUSN/D-ner-Nation',
'knso/emmas-schatzkiste',
'ANDJ/Steuerungstechnik',
'knso/hytail-ark',
'WEBklar/schon-da',
'JUSN/schon-da',
'knso/von-hand', // Appwrite kennt noch den alten Namen (siehe Brief)
'ANDJ/unberuehrt',
]
const websiteProjects = repoNames.map((repoFullName) => {
const $id = randomUUID()
idByRepo.set(repoFullName, $id)
return { $id, repoFullName, projectName: repoFullName.split('/').pop() }
})
aw = await startFakeAppwrite({ seed: { websiteProjects } })
originalCwd = process.cwd()
tmp = await fs.mkdtemp(path.join(os.tmpdir(), 'repo-move-'))
process.chdir(tmp)
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
;({ previewWorkDir } = await import('../server/services/previewDeploy.js'))
;({ moveRepoToOrg, isOrgRepo, isInternalRepo, repoLockKey, currentRepoFullName } = await import(
'../server/services/repoMove.js'
))
})
after(async () => {
process.chdir(originalCwd)
await gitea.close()
await aw.close()
await fs.rm(tmp, { recursive: true, force: true })
})
test('verschiebt Repo aus eigenem Konto', async () => {
await fs.mkdir(previewWorkDir('JUSN/D-ner-Nation'), { recursive: true })
const r = await moveRepoToOrg(doc('JUSN/D-ner-Nation'))
assert.deepEqual(r, { moved: { from: 'JUSN/D-ner-Nation', to: 'WEBklar/D-ner-Nation' }, warnings: [] })
assert.deepEqual(gitea.calls.find((c) => c.path.endsWith('/transfer')).body, { new_owner: 'WEBklar' })
const d = aw.get('websiteProjects', doc('JUSN/D-ner-Nation').$id)
assert.equal(d.repoFullName, 'WEBklar/D-ner-Nation')
assert.equal(d.giteaRepoUrl, `${gitea.baseUrl}/WEBklar/D-ner-Nation`)
assert.equal(d.giteaRepoName, 'D-ner-Nation')
await assert.rejects(fs.access(previewWorkDir('JUSN/D-ner-Nation')))
})
test('löscht den alten Portal-Webhook', async () => {
await moveRepoToOrg(doc('knso/emmas-schatzkiste'))
assert.deepEqual(gitea.hooksOf('WEBklar/emmas-schatzkiste'), [])
})
test('schon in WEBklar: nichts passiert', async () => {
assert.deepEqual(await moveRepoToOrg(doc('WEBklar/schon-da')), { moved: null, warnings: [] })
})
test('internes Repo per Liste und per fremdem Webhook', async () => {
for (const name of ['ANDJ/Steuerungstechnik', 'knso/hytail-ark']) {
assert.deepEqual(await moveRepoToOrg(doc(name)), { moved: null, warnings: ['Internes Repo, bleibt wo es ist.'] })
}
assert.equal(gitea.calls.filter((c) => c.path.endsWith('/transfer') && /steuerung|hytail/i.test(c.path)).length, 0)
})
test('Name existiert in WEBklar', async () => {
const r = await moveRepoToOrg(doc('JUSN/schon-da'))
assert.deepEqual(r, { moved: null, warnings: ['In WEBklar gibt es schon ein Repo namens schon-da. Bitte in Gitea umbenennen und dann ‚Pushes nachtragen‘ klicken.'] })
})
test('Weiterleitung korrigiert Projektdaten', async () => {
const r = await moveRepoToOrg(doc('knso/von-hand'))
assert.deepEqual(r.moved, { from: 'knso/von-hand', to: 'WEBklar/von-hand' })
assert.equal(gitea.calls.filter((c) => c.path.endsWith('/transfer') && c.path.includes('von-hand')).length, 0)
assert.equal(aw.get('websiteProjects', doc('knso/von-hand').$id).repoFullName, 'WEBklar/von-hand')
})
test('Erkennung ohne Groß-/Kleinschreibung', async () => {
assert.equal(isOrgRepo('webklar/x'), true)
assert.equal(await isInternalRepo('andj/steuerungstechnik'), true)
})
test('repoLockKey', () => {
assert.equal(repoLockKey('JUSN/D-ner-Nation'), 'repo:jusn/d-ner-nation')
})
test('currentRepoFullName', async () => {
assert.equal(await currentRepoFullName('WEBklar/D-ner-Nation'), 'WEBklar/D-ner-Nation') // Eintrag vorhanden
assert.equal(await currentRepoFullName('JUSN/D-ner-Nation'), 'WEBklar/D-ner-Nation') // kein Eintrag, Weiterleitung
})
test('Gitea nicht erreichbar', async () => {
gitea.setDown(true)
const r = await moveRepoToOrg(doc('ANDJ/unberuehrt'))
gitea.setDown(false)
assert.equal(r.moved, null)
assert.match(r.warnings[0], /^Gitea ist gerade nicht erreichbar \(.+\)\. Bitte später ‚Pushes nachtragen‘ klicken\.$/)
})