Version 2.1.1 - modification d'une certaine UI

This commit is contained in:
raphix committed 2026-10-08 21:47:31 +02:00
1 parent dcc350241e
commit fc71b10294
10 files changed
+1208 -139

No files matched your search

+67 -1
View File
@@ -79,6 +79,39 @@ const fakePlayer = {
const AllPlayers = new Map([['222222', fakePlayer]]);
const removed = [];
// Stockage des médias simulé (MediaBase) : une entrée Opus valide, une ancienne entrée manquante sur Discord
const HOUR = 3600 * 1000;
const hexSec = (ms) => Math.floor(ms / 1000).toString(16);
const cdnLink = (name, expiresAt) => `https://cdn.discordapp.com/attachments/1/2/${name}?ex=${hexSec(expiresAt)}&is=${hexSec(expiresAt - 24 * HOUR)}&hm=abcdef&`;
let mediaConnected = true;
const mediaCalls = { refresh: [], all: 0, deleted: [] };
const mediaEntries = [
{ id: '900000001', name: 'a.mp3', title: 'Titre A', author: 'Artiste', duration: 200, size: 3000000, originalSize: 8000000, bitrate: 96000,
format: 'opus', createdAt: '2026-10-08T10:00:00.000Z', userId: '333333', channelId: '777', url: cdnLink('a.ogg', Date.now() + 3 * HOUR), thumbnail: null },
{ id: '900000002', name: 'b.mp3', size: 5000000, createdAt: '2026-01-01T10:00:00.000Z', userId: '555555', uploaderName: 'parti',
url: 'https://cdn.discordapp.com/attachments/1/3/b.mp3', missing: true }
];
const fakeMediaBase = {
isConnected: () => mediaConnected,
getStorageStatus: () => ({ configured: true, connected: mediaConnected, guildId: '1', channelId: '2', channelName: 'stockage', premiumTier: 0,
storageLimitBytes: 10 * 1024 * 1024, maxInputBytes: 250 * 1024 * 1024, maxDurationSec: 2411, preferredBitrate: 96000 }),
listEntries: () => mediaEntries.map(e => ({ ...e })),
async refreshMedia(id) {
mediaCalls.refresh.push(id);
const entry = mediaEntries.find(e => e.id === id);
if (!entry) return undefined;
entry.url = cdnLink('a.ogg', Date.now() + 23 * HOUR);
return { ...entry };
},
async refreshAllMedia() { mediaCalls.all++; return { checked: 1, refreshed: 1, missing: 0 }; },
async adminDeleteMedia(id) {
const index = mediaEntries.findIndex(e => e.id === id);
if (index === -1) return null;
mediaCalls.deleted.push(id);
return mediaEntries.splice(index, 1)[0];
}
};
const stubs = {
[norm(SRC + '/server/auth/User')]: {
getUserById: (id) => id === '111111' ? admin : id === '333333' ? owner : null,
@@ -91,7 +124,7 @@ const stubs = {
getChannel: () => null
},
[norm(SRC + '/discord/ServerSettings')]: {},
[norm(SRC + '/discord/MediaBase')]: {},
[norm(SRC + '/discord/MediaBase')]: fakeMediaBase,
[norm(SRC + '/playlists/PlaylistManager')]: {
removePlaylist(userId, playlistId) {
const list = getDatabase('Playlists').data[userId] || [];
@@ -343,6 +376,39 @@ process.on('PLAYLISTS_UPDATE', (userId) => playlistEvents.push(userId));
r = await call('/ADMIN/USERS/SET_GUILD_MOD', { userId: '111111', guildId: '222222', value: true });
check('SET_GUILD_MOD sur soi-même -> SELF_ACTION', !r.ok && r.error === 'SELF_ACTION', r);
console.log('# Médias');
// Un titre du fichier A dans une playlist : compté dans "playlists"
playlistsDb.data['333333'][0].songs.push({ id: '900000001', type: 'attachment' });
r = await call('/ADMIN/MEDIA/LIST', {});
const mediaA = r.ok ? r.data.items.find(i => i.id === '900000001') : null;
const mediaB = r.ok ? r.data.items.find(i => i.id === '900000002') : null;
check('LIST : état du stockage + 2 fichiers', r.ok && r.data.status?.channelName === 'stockage' && r.data.items.length === 2, r);
check('LIST : expiration lue depuis le lien', mediaA && Math.abs(Date.parse(mediaA.expiresAt) - (Date.now() + 3 * HOUR)) < 2000, mediaA?.expiresAt);
check('LIST : propriétaire résolu et référence en playlist', mediaA?.uploader?.username === 'proprio' && mediaA.playlists === 1 && mediaA.format === 'opus', mediaA);
check('LIST : ancien fichier manquant, sans signature, propriétaire supprimé', mediaB?.missing === true && mediaB.expiresAt === null && mediaB.format === 'legacy'
&& mediaB.uploader?.username === 'parti' && mediaB.playlists === 0, mediaB);
check('LIST : plus récent en premier', r.ok && r.data.items[0].id === '900000001');
r = await call('/ADMIN/MEDIA/REFRESH', { id: '900000001' });
check('REFRESH {id} : lien renouvelé', r.ok && mediaCalls.refresh.includes('900000001') && Date.parse(r.data.item.expiresAt) > Date.now() + 20 * HOUR, r);
r = await call('/ADMIN/MEDIA/REFRESH', { id: '123456789' });
check('REFRESH id inconnu -> NOT_FOUND', !r.ok && r.error === 'NOT_FOUND', r);
r = await call('/ADMIN/MEDIA/REFRESH', { id: '../x' });
check('REFRESH id invalide -> INVALID_PARAMS', !r.ok && r.error === 'INVALID_PARAMS', r);
r = await call('/ADMIN/MEDIA/REFRESH', {});
check('REFRESH global', r.ok && mediaCalls.all === 1 && r.data.refreshed === 1, r);
mediaConnected = false;
r = await call('/ADMIN/MEDIA/REFRESH', {});
check('REFRESH hors connexion -> UNAVAILABLE', !r.ok && r.error === 'UNAVAILABLE', r);
mediaConnected = true;
r = await call('/ADMIN/MEDIA/DELETE', { id: '900000002' });
check('DELETE : supprimé', r.ok && r.data.deleted === true && mediaCalls.deleted.includes('900000002') && mediaEntries.length === 1, r);
r = await call('/ADMIN/MEDIA/DELETE', { id: '900000002' });
check('DELETE déjà supprimé -> NOT_FOUND', !r.ok && r.error === 'NOT_FOUND', r);
r = await call('/ADMIN/MEDIA/DELETE', {});
check('DELETE sans id -> INVALID_PARAMS', !r.ok && r.error === 'INVALID_PARAMS', r);
r = await call('/ADMIN/OVERVIEW', {});
check('vue d\'ensemble : compteurs médias présents', r.ok && typeof r.data.media?.files === 'number' && typeof r.data.media?.missing === 'number', r.ok ? r.data.media : r);
console.log('# Journaux');
await sleep(300);
const logDir = path.join(__dirname, 'logs');