Upload via GUI (85 Dateien)
This commit is contained in:
@@ -0,0 +1,146 @@
|
||||
const test = require('node:test');
|
||||
const assert = require('node:assert');
|
||||
const http = require('node:http');
|
||||
const fs = require('node:fs');
|
||||
const os = require('node:os');
|
||||
const path = require('node:path');
|
||||
const {
|
||||
uploadItemsViaGiteaApi,
|
||||
createUploadCancelledError,
|
||||
isUploadCancelledError,
|
||||
throwIfUploadCancelled
|
||||
} = require('../src/git/apiHandler.js');
|
||||
|
||||
test('Abbruchfehler: Erkennung und throwIfUploadCancelled', () => {
|
||||
assert.strictEqual(isUploadCancelledError(createUploadCancelledError()), true);
|
||||
assert.strictEqual(isUploadCancelledError(new Error('anderer Fehler')), false);
|
||||
assert.strictEqual(isUploadCancelledError(null), false);
|
||||
|
||||
assert.doesNotThrow(() => throwIfUploadCancelled(undefined));
|
||||
assert.doesNotThrow(() => throwIfUploadCancelled(new AbortController().signal));
|
||||
const c = new AbortController();
|
||||
c.abort();
|
||||
assert.throws(() => throwIfUploadCancelled(c.signal), (e) => isUploadCancelledError(e));
|
||||
});
|
||||
|
||||
function makeTempFile() {
|
||||
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'gm-cancel-'));
|
||||
const file = path.join(dir, 'a.txt');
|
||||
fs.writeFileSync(file, 'hallo');
|
||||
return { dir, file };
|
||||
}
|
||||
|
||||
test('API-Upload: bereits abgebrochenes Signal sendet nichts', async () => {
|
||||
const { dir, file } = makeTempFile();
|
||||
try {
|
||||
const c = new AbortController();
|
||||
c.abort();
|
||||
await assert.rejects(
|
||||
uploadItemsViaGiteaApi({
|
||||
token: 't', url: 'http://127.0.0.1:1', owner: 'o', repo: 'r', branch: 'main',
|
||||
items: [{ localFile: file, targetPath: 'a.txt' }], message: 'm', signal: c.signal
|
||||
}),
|
||||
(e) => isUploadCancelledError(e)
|
||||
);
|
||||
} finally { fs.rmSync(dir, { recursive: true, force: true }); }
|
||||
});
|
||||
|
||||
test('API-Upload: Abbruch während der Übertragung wirft Abbruchfehler und landet nicht in "failed"', async () => {
|
||||
const { dir, file } = makeTempFile();
|
||||
let postSeen = false;
|
||||
const server = http.createServer((req, res) => {
|
||||
if (req.method === 'POST') {
|
||||
postSeen = true;
|
||||
setTimeout(() => { res.writeHead(201, { 'content-type': 'application/json' }); res.end('{}'); }, 3000);
|
||||
return;
|
||||
}
|
||||
res.writeHead(200, { 'content-type': 'application/json' });
|
||||
res.end(JSON.stringify({ default_branch: 'main', tree: [], entries: [] }));
|
||||
});
|
||||
await new Promise(r => server.listen(0, '127.0.0.1', r));
|
||||
const { port } = server.address();
|
||||
try {
|
||||
const c = new AbortController();
|
||||
const started = Date.now();
|
||||
setTimeout(() => c.abort(), 400);
|
||||
await assert.rejects(
|
||||
uploadItemsViaGiteaApi({
|
||||
token: 't', url: `http://127.0.0.1:${port}`, owner: 'o', repo: 'r', branch: 'main',
|
||||
items: [{ localFile: file, targetPath: 'a.txt' }], message: 'm', signal: c.signal
|
||||
}),
|
||||
(e) => isUploadCancelledError(e)
|
||||
);
|
||||
assert.ok(postSeen, 'Der POST muss gestartet sein, sonst prüft der Test nichts');
|
||||
assert.ok(Date.now() - started < 2500, 'Abbruch muss sofort greifen, nicht erst nach der Serverantwort');
|
||||
} finally {
|
||||
server.closeAllConnections?.();
|
||||
await new Promise(r => server.close(r));
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
const { createPauseGate } = require('../src/features/pauseGate.js');
|
||||
|
||||
function gitea(onPost) {
|
||||
return http.createServer((req, res) => {
|
||||
if (req.method === 'POST') {
|
||||
onPost();
|
||||
res.writeHead(201, { 'content-type': 'application/json' });
|
||||
res.end('{}');
|
||||
return;
|
||||
}
|
||||
res.writeHead(200, { 'content-type': 'application/json' });
|
||||
res.end(JSON.stringify({ default_branch: 'main', tree: [], entries: [] }));
|
||||
});
|
||||
}
|
||||
|
||||
test('API-Upload: während der Pause wird nichts gesendet, nach resume() schon', async () => {
|
||||
const { dir, file } = makeTempFile();
|
||||
let posts = 0;
|
||||
const server = gitea(() => { posts++; });
|
||||
await new Promise(r => server.listen(0, '127.0.0.1', r));
|
||||
const { port } = server.address();
|
||||
const gate = createPauseGate();
|
||||
try {
|
||||
gate.pause();
|
||||
const upload = uploadItemsViaGiteaApi({
|
||||
token: 't', url: `http://127.0.0.1:${port}`, owner: 'o', repo: 'r', branch: 'main',
|
||||
items: [{ localFile: file, targetPath: 'a.txt' }], message: 'm',
|
||||
waitIfPaused: (s) => gate.wait(s)
|
||||
});
|
||||
await new Promise(r => setTimeout(r, 700));
|
||||
assert.strictEqual(posts, 0, 'Während der Pause darf kein Paket gesendet werden');
|
||||
gate.resume();
|
||||
const result = await upload;
|
||||
assert.strictEqual(posts, 1);
|
||||
assert.deepStrictEqual(result.uploaded, ['a.txt']);
|
||||
} finally {
|
||||
await new Promise(r => server.close(r));
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
|
||||
test('API-Upload: Abbruch während der Pause beendet den Upload sofort', async () => {
|
||||
const { dir, file } = makeTempFile();
|
||||
let posts = 0;
|
||||
const server = gitea(() => { posts++; });
|
||||
await new Promise(r => server.listen(0, '127.0.0.1', r));
|
||||
const { port } = server.address();
|
||||
const gate = createPauseGate();
|
||||
try {
|
||||
gate.pause();
|
||||
const c = new AbortController();
|
||||
const upload = uploadItemsViaGiteaApi({
|
||||
token: 't', url: `http://127.0.0.1:${port}`, owner: 'o', repo: 'r', branch: 'main',
|
||||
items: [{ localFile: file, targetPath: 'a.txt' }], message: 'm',
|
||||
signal: c.signal, waitIfPaused: (s) => gate.wait(s)
|
||||
});
|
||||
setTimeout(() => c.abort(), 400);
|
||||
await assert.rejects(upload, (e) => isUploadCancelledError(e));
|
||||
assert.strictEqual(posts, 0);
|
||||
assert.strictEqual(gate.waitingCount(), 0);
|
||||
} finally {
|
||||
await new Promise(r => server.close(r));
|
||||
fs.rmSync(dir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user