mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-21 09:08:43 +00:00
test: convert mocha this.timeout/this.skip to vitest in merged-from-develop admin specs
Three admin test files brought in by the develop merge (5afd466bb) still used mocha-shape this.timeout/this.skip. Converts them to vi.setConfig and ctx.skip per the pattern established in95f753c80.
This commit is contained in:
parent
5afd466bba
commit
d8eeee8321
3 changed files with 48 additions and 30 deletions
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import {strict as assert} from 'assert';
|
||||
import {vi} from 'vitest';
|
||||
import setCookieParser from 'set-cookie-parser';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
|
|
@ -81,7 +82,7 @@ const ask = (socket: any, evt: string, payload: any, replyEvt: string) =>
|
|||
socket.emit(evt, payload);
|
||||
});
|
||||
|
||||
describe(__filename, function () {
|
||||
describe(__filename, () => {
|
||||
let socket: any;
|
||||
let savedUsers: any;
|
||||
let savedRequireAuthentication: boolean;
|
||||
|
|
@ -92,9 +93,10 @@ describe(__filename, function () {
|
|||
let savedSettingsFilename: any;
|
||||
let tmpSettingsPath: string | null = null;
|
||||
let setupCompleted = false;
|
||||
let skipReason: string | null = null;
|
||||
|
||||
before(async function () {
|
||||
this.timeout(60000);
|
||||
before(async () => {
|
||||
vi.setConfig({hookTimeout: 60000});
|
||||
await common.init();
|
||||
|
||||
// The load handler bails with logger.error + early return if the
|
||||
|
|
@ -125,13 +127,13 @@ describe(__filename, function () {
|
|||
console.warn(
|
||||
`[adminSettingsResolved] admin socket probe failed (${probe.reason}); ` +
|
||||
'skipping suite — likely an authenticate-hook plugin rejecting test creds.');
|
||||
this.skip();
|
||||
skipReason = probe.reason;
|
||||
return;
|
||||
}
|
||||
socket = probe.socket;
|
||||
});
|
||||
|
||||
after(function () {
|
||||
after(() => {
|
||||
if (socket) socket.disconnect();
|
||||
if (!setupCompleted) return;
|
||||
if (savedDbPwd === undefined) delete settings.dbSettings.password;
|
||||
|
|
@ -148,7 +150,8 @@ describe(__filename, function () {
|
|||
settings.requireAuthentication = savedRequireAuthentication;
|
||||
});
|
||||
|
||||
it('emits {results, resolved, flags}', async function () {
|
||||
it('emits {results, resolved, flags}', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const reply: any = await ask(socket, 'load', null, 'settings');
|
||||
assert.ok(reply, 'reply present');
|
||||
assert.equal(typeof reply.results, 'string', 'raw file string');
|
||||
|
|
@ -156,19 +159,22 @@ describe(__filename, function () {
|
|||
assert.ok(reply.flags, 'flags present');
|
||||
});
|
||||
|
||||
it('resolved reflects live in-memory values, not the file on disk', async function () {
|
||||
it('resolved reflects live in-memory values, not the file on disk', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const reply: any = await ask(socket, 'load', null, 'settings');
|
||||
assert.equal(reply.resolved.trustProxy, true,
|
||||
'resolved should show the in-memory trustProxy');
|
||||
});
|
||||
|
||||
it('resolved redacts secrets', async function () {
|
||||
it('resolved redacts secrets', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const reply: any = await ask(socket, 'load', null, 'settings');
|
||||
assert.equal(reply.resolved.dbSettings.password, '[REDACTED]');
|
||||
assert.equal(reply.resolved.sessionKey, '[REDACTED]');
|
||||
});
|
||||
|
||||
it('resolved is omitted when showSettingsInAdminPage is false', async function () {
|
||||
it('resolved is omitted when showSettingsInAdminPage is false', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
settings.showSettingsInAdminPage = false;
|
||||
try {
|
||||
const reply: any = await ask(socket, 'load', null, 'settings');
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import {strict as assert} from 'assert';
|
||||
import {vi} from 'vitest';
|
||||
import setCookieParser from 'set-cookie-parser';
|
||||
import * as fs from 'fs';
|
||||
import * as os from 'os';
|
||||
|
|
@ -97,7 +98,7 @@ const save = (socket: any, payload: string) =>
|
|||
// disk byte-for-byte at settings.settingsFilename, and the subsequent
|
||||
// `load` reply reflects the new file contents. We do NOT exercise
|
||||
// runtime reload — that's reloadSettings()' job and is covered elsewhere.
|
||||
describe(__filename, function () {
|
||||
describe(__filename, () => {
|
||||
let socket: any;
|
||||
let savedUsers: any;
|
||||
let savedRequireAuthentication: boolean;
|
||||
|
|
@ -105,9 +106,10 @@ describe(__filename, function () {
|
|||
let tmpSettingsPath: string | null = null;
|
||||
let baselineContents: string;
|
||||
let setupCompleted = false;
|
||||
let skipReason: string | null = null;
|
||||
|
||||
before(async function () {
|
||||
this.timeout(60000);
|
||||
before(async () => {
|
||||
vi.setConfig({hookTimeout: 60000});
|
||||
await common.init();
|
||||
|
||||
savedSettingsFilename = settings.settingsFilename;
|
||||
|
|
@ -134,13 +136,13 @@ describe(__filename, function () {
|
|||
console.warn(
|
||||
`[adminSettingsSave] admin socket probe failed (${probe.reason}); ` +
|
||||
'skipping suite — likely an authenticate-hook plugin rejecting test creds.');
|
||||
this.skip();
|
||||
skipReason = probe.reason;
|
||||
return;
|
||||
}
|
||||
socket = probe.socket;
|
||||
});
|
||||
|
||||
after(function () {
|
||||
after(() => {
|
||||
if (socket) socket.disconnect();
|
||||
if (!setupCompleted) return;
|
||||
settings.settingsFilename = savedSettingsFilename;
|
||||
|
|
@ -153,14 +155,15 @@ describe(__filename, function () {
|
|||
});
|
||||
|
||||
// Reset to baseline between tests so each it() is independent — earlier
|
||||
// suites in the same mocha run can leave behind state via shared sockets.
|
||||
beforeEach(function () {
|
||||
if (!tmpSettingsPath) this.skip();
|
||||
// suites in the same run can leave behind state via shared sockets.
|
||||
beforeEach((ctx) => {
|
||||
if (!tmpSettingsPath) return ctx.skip();
|
||||
fs.writeFileSync(tmpSettingsPath!, baselineContents);
|
||||
});
|
||||
|
||||
it('saveSettings writes the payload byte-for-byte to settings.settingsFilename',
|
||||
async function () {
|
||||
async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const payload = JSON.stringify({title: 'EtherpadWrittenViaSocket'}, null, 2);
|
||||
const ack = await save(socket, payload);
|
||||
assert.equal(ack.status, 'saved', 'saveprogress should be "saved"');
|
||||
|
|
@ -173,7 +176,8 @@ describe(__filename, function () {
|
|||
// one new top-level block (a plugin config). The block must persist on
|
||||
// disk verbatim and reappear in the next `load` reply.
|
||||
it('augmenting existing JSON with a new top-level plugin block round-trips',
|
||||
async function () {
|
||||
async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const augmented = JSON.stringify({
|
||||
title: 'Etherpad',
|
||||
ip: '0.0.0.0',
|
||||
|
|
@ -207,7 +211,8 @@ describe(__filename, function () {
|
|||
// path must not normalize or strip them — the SPA test
|
||||
// 'preserves /* */ comments after save round-trip' covers the UI side;
|
||||
// this one covers the socket-level guarantee.
|
||||
it('preserves /* */ comments in the written file', async function () {
|
||||
it('preserves /* */ comments in the written file', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const withComment =
|
||||
'/* persisted-marker-7819 */\n' +
|
||||
JSON.stringify({title: 'Etherpad'}, null, 2);
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@
|
|||
// offset/limit slice, so `total` reflects the filtered universe.
|
||||
|
||||
import {strict as assert} from 'assert';
|
||||
import {vi} from 'vitest';
|
||||
import setCookieParser from 'set-cookie-parser';
|
||||
|
||||
const io = require('socket.io-client');
|
||||
|
|
@ -86,19 +87,20 @@ const adminSocketWithProbe = async (budgetMs: number): Promise<{
|
|||
return {ok: true, socket};
|
||||
};
|
||||
|
||||
describe(__filename, function () {
|
||||
describe(__filename, () => {
|
||||
let socket: any;
|
||||
let savedUsers: any;
|
||||
let savedRequireAuthentication: boolean;
|
||||
let setupCompleted = false;
|
||||
let skipReason: string | null = null;
|
||||
// Distinct per-suite tag so concurrent test runs / leftover pads from
|
||||
// earlier suites don't pollute the filter assertions.
|
||||
const tag = `padLoadFilter-${Date.now()}-${Math.floor(Math.random() * 1e6)}`;
|
||||
const emptyPadIds: string[] = [];
|
||||
const editedPadIds: string[] = [];
|
||||
|
||||
before(async function () {
|
||||
this.timeout(120000);
|
||||
before(async () => {
|
||||
vi.setConfig({hookTimeout: 120000});
|
||||
await common.init();
|
||||
|
||||
savedUsers = settings.users;
|
||||
|
|
@ -111,7 +113,7 @@ describe(__filename, function () {
|
|||
`[padLoadFilter] admin socket probe failed (${probe.reason}); ` +
|
||||
"skipping suite — likely an authenticate-hook plugin rejecting the test's " +
|
||||
'admin credentials.');
|
||||
this.skip();
|
||||
skipReason = probe.reason;
|
||||
return;
|
||||
}
|
||||
socket = probe.socket;
|
||||
|
|
@ -132,7 +134,7 @@ describe(__filename, function () {
|
|||
}
|
||||
});
|
||||
|
||||
after(async function () {
|
||||
after(async () => {
|
||||
if (socket) socket.disconnect();
|
||||
if (!setupCompleted) return;
|
||||
// `savedUsers` may point at the same object that adminSocket mutated,
|
||||
|
|
@ -150,7 +152,8 @@ describe(__filename, function () {
|
|||
}
|
||||
});
|
||||
|
||||
it('filter:"empty" returns only revisionNumber===0 pads from the full set', async function () {
|
||||
it('filter:"empty" returns only revisionNumber===0 pads from the full set', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const res = await ask(socket, 'padLoad', {
|
||||
pattern: tag, offset: 0, limit: 12, sortBy: 'padName',
|
||||
ascending: true, filter: 'empty',
|
||||
|
|
@ -162,7 +165,8 @@ describe(__filename, function () {
|
|||
}
|
||||
});
|
||||
|
||||
it('filter:"empty" with limit=2 still reports the correct total (regression: thm)', async function () {
|
||||
it('filter:"empty" with limit=2 still reports the correct total (regression: thm)', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
// The bug thm hit: clicking "empty" showed at most `limit` empties
|
||||
// because filtering happened on the client AFTER pagination. The
|
||||
// server now applies filter first, so total reflects the filtered
|
||||
|
|
@ -175,7 +179,8 @@ describe(__filename, function () {
|
|||
assert.equal(res.results.length, 2, `expected limit=2 page, got ${res.results.length} rows`);
|
||||
});
|
||||
|
||||
it('filter omitted (older client) falls back to "all"', async function () {
|
||||
it('filter omitted (older client) falls back to "all"', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const res = await ask(socket, 'padLoad', {
|
||||
pattern: tag, offset: 0, limit: 12, sortBy: 'padName',
|
||||
ascending: true,
|
||||
|
|
@ -184,7 +189,8 @@ describe(__filename, function () {
|
|||
`expected total=8 (5 empty + 3 edited), got ${JSON.stringify(res)}`);
|
||||
});
|
||||
|
||||
it('filter:"all" matches the no-filter behaviour', async function () {
|
||||
it('filter:"all" matches the no-filter behaviour', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
const res = await ask(socket, 'padLoad', {
|
||||
pattern: tag, offset: 0, limit: 12, sortBy: 'padName',
|
||||
ascending: true, filter: 'all',
|
||||
|
|
@ -192,7 +198,8 @@ describe(__filename, function () {
|
|||
assert.equal(res.total, 8);
|
||||
});
|
||||
|
||||
it('filter:"active" excludes pads with no active users', async function () {
|
||||
it('filter:"active" excludes pads with no active users', async (ctx) => {
|
||||
if (skipReason) return ctx.skip();
|
||||
// No connected clients in this test, so every test pad has
|
||||
// userCount === 0 → filter:"active" must return zero.
|
||||
const res = await ask(socket, 'padLoad', {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue