Version 2.0.0 - update of everything

This commit is contained in:
raphix committed 2026-10-07 14:04:26 +02:00
1 parent 164a1da009
commit 6017e03eac
85 files changed
+13065 -2107

No files matched your search

+84
View File
@@ -0,0 +1,84 @@
// Tests des fonctions pures de backend/src/playlists/Google/Utils.js (aucune dépendance)
const assert = require("assert")
const U = require(require("path").resolve(__dirname, "../../src/playlists/Google/Utils.js"))
;(async () => {
// --- parseIsoDuration ---
const cases = [["PT1H2M3S", 3723], ["PT4M13S", 253], ["PT45S", 45], ["PT0S", 0], ["P0D", 0], ["P1DT2H", 93600],
["PT10M", 600], ["P1W", 604800], ["PT1.5S", 1], ["pt3m", 180], ["P", null], ["PT", null], ["", null],
["1:23", null], [null, null], [123, null], ["P1Y", null], ["PT1H2M3", null]]
for (const [input, expected] of cases) assert.strictEqual(U.parseIsoDuration(input), expected, "parseIsoDuration(" + input + ")")
// --- collectPages : pagination simulée (3 pages de 50 + 1 de 20 = 170) ---
const makeFetcher = (total, size, log) => async (token) => {
log.push(token)
const start = token ? Number(token) : 0
const items = Array.from({ length: Math.min(size, total - start) }, (_, i) => start + i)
const next = start + size < total ? String(start + size) : undefined
return { items, nextPageToken: next }
}
let log = []
let r = await U.collectPages(makeFetcher(170, 50, log), { maxItems: 500 })
assert.strictEqual(r.items.length, 170); assert.strictEqual(r.truncated, false); assert.strictEqual(r.pages, 4)
assert.deepStrictEqual(log, [undefined, "50", "100", "150"])
// limite atteinte au milieu d'une page
log = []
r = await U.collectPages(makeFetcher(1000, 50, log), { maxItems: 120 })
assert.strictEqual(r.items.length, 120); assert.strictEqual(r.truncated, true); assert.strictEqual(r.pages, 3)
assert.deepStrictEqual(r.items.slice(-1), [119])
// limite atteinte pile en fin de page alors que Google annonce encore une page
r = await U.collectPages(makeFetcher(1000, 50, []), { maxItems: 100 })
assert.strictEqual(r.items.length, 100); assert.strictEqual(r.truncated, true); assert.strictEqual(r.pages, 2)
// limite pile sur le total : pas tronqué
r = await U.collectPages(makeFetcher(100, 50, []), { maxItems: 100 })
assert.strictEqual(r.truncated, false); assert.strictEqual(r.items.length, 100)
// jeton répété : pas de boucle infinie
let calls = 0
r = await U.collectPages(async () => { calls++; return { items: [calls], nextPageToken: "SAME" } }, { maxItems: 500 })
assert.strictEqual(calls, 2); assert.strictEqual(r.items.length, 2)
// maxPages
r = await U.collectPages(makeFetcher(1000, 10, []), { maxItems: 500, maxPages: 3 })
assert.strictEqual(r.items.length, 30); assert.strictEqual(r.truncated, true)
// page vide / réponse inattendue
r = await U.collectPages(async () => null)
assert.deepStrictEqual(r.items, [])
// erreur propagée
await assert.rejects(U.collectPages(async () => { throw new Error("boom") }), /boom/)
// --- chunk ---
assert.deepStrictEqual(U.chunk([1, 2, 3, 4, 5], 2), [[1, 2], [3, 4], [5]])
assert.strictEqual(U.chunk(Array.from({ length: 120 }), 50).length, 3)
assert.deepStrictEqual(U.chunk([], 50), [])
// --- createStateStore (horloge simulée) ---
let now = 1_000_000
const store = U.createStateStore({ ttlMs: 10 * 60 * 1000, maxPerKey: 3, now: () => now })
const s1 = store.create("alice")
assert.match(s1, /^[0-9a-f]{48}$/)
assert.strictEqual(store.consume(s1, "bob"), false, "autre utilisateur refusé")
assert.strictEqual(store.consume(s1, "alice"), true, "propriétaire accepté")
assert.strictEqual(store.consume(s1, "alice"), false, "usage unique")
const s2 = store.create("alice")
now += 10 * 60 * 1000 + 1
assert.strictEqual(store.consume(s2, "alice"), false, "expiré après 10 min")
const s3 = store.create("alice")
now += 9 * 60 * 1000
assert.strictEqual(store.consume(s3, "alice"), true, "valide avant 10 min")
// maxPerKey : les plus anciens sont évincés
const olds = [store.create("carol"), store.create("carol"), store.create("carol"), store.create("carol")]
assert.strictEqual(store.consume(olds[0], "carol"), false, "plus ancien évincé")
assert.strictEqual(store.consume(olds[3], "carol"), true)
store.clear("carol")
assert.strictEqual(store.consume(olds[2], "carol"), false, "clear")
assert.strictEqual(store.consume(undefined, "carol"), false)
assert.strictEqual(store.consume(12, "carol"), false)
// --- pickTokens / bestThumbnail ---
assert.deepStrictEqual(U.pickTokens({ access_token: "a", refresh_token: null, expiry_date: 5, foo: 1 }), { access_token: "a", expiry_date: 5 })
assert.deepStrictEqual(U.pickTokens(null), {})
assert.strictEqual(U.bestThumbnail({ default: { url: "d" }, high: { url: "h" } }), "h")
assert.strictEqual(U.bestThumbnail({}), null)
assert.strictEqual(U.bestThumbnail(undefined), null)
console.log("google-utils.test.js : OK")
})().catch((e) => { console.error(e); process.exit(1) })