'use strict'; const test = require('node:test'); const assert = require('node:assert/strict'); const { loadCatalog, findOwned, countsFor, scoreFor } = require('../greatest'); const { seriesLink, hosterLinks } = require('../greatest/hosters'); test('curated manga catalog has unique identities and ordered five-year periods', () => { const catalog = loadCatalog(); assert.equal(catalog.periods.length, 13); assert.equal(catalog.entries.length, 106); assert.ok(catalog.entries.every(entry => /^https:\/\//.test(entry.cover)), 'Every catalog title has cover artwork'); assert.ok(catalog.entries.every(entry => entry.note?.length >= 45 && /[.!?]$/.test(entry.note)), 'Every catalog title has a complete reason for inclusion'); for (const [index, period] of catalog.periods.entries()) { const entries = catalog.entries.filter(entry => entry.period === period); assert.ok(entries.length >= 5 && entries.length <= 10); assert.deepEqual(entries.map(entry => entry.rank), entries.map((_, rank) => rank + 1)); assert.ok(entries.every(entry => entry.periodOrder === index)); } assert.equal(catalog.entries.find(entry => entry.title === 'Phoenix').year, 1954); assert.equal(catalog.entries.find(entry => entry.title === 'JoJo\'s Bizarre Adventure').year, 1987); }); test('library matching and vote aggregation stay independent of scraper data', () => { const catalog = loadCatalog(); const berserk = catalog.entries.find(entry => entry.title === 'Berserk'); const manga = { id: 'local-Berserk', title: 'Berserk', meta: {} }; assert.equal(findOwned(berserk, [manga]), manga); assert.equal(findOwned(berserk, [{ id: 'different', title: 'Berserker', meta: {} }]), null); const votes = { ada: { [berserk.id]: 'flame' }, bob: { [berserk.id]: 'good' }, gone: { [berserk.id]: 'skip' } }; const counts = countsFor(berserk.id, votes, { ada: {}, bob: {} }); assert.deepEqual(counts, { flame: 1, good: 1, neutral: 0, skip: 0 }); assert.equal(scoreFor(counts), 4); }); test('hoster links use confirmed series URLs and do not mistake unrelated queue entries for matches', () => { const entry = { title: 'BLAME!', aliases: ['Blame'] }; const weeb = 'https://weebcentral.com/series/01J76XY8CJ2RJGWMHM69ZS0J3H'; const dex = 'https://mangadex.org/title/06a37094-b3ba-4f25-bf2b-54c9751e0e91/bleach'; const owned = { id: 'BLAME!', meta: { sources: [{ name: 'WeebCentral', url: weeb }] } }; const result = hosterLinks(entry, owned, [ { id: 'match', title: 'blame', url: weeb, status: 'complete', kind: 'download' }, { id: 'other', title: 'Bleach', url: dex, status: 'queued', kind: 'download' }, ]); assert.equal(result.links.length, 1); assert.equal(result.links[0].source, 'weebcentral'); assert.equal(result.jobs.length, 1); assert.equal(result.jobs[0].status, 'complete'); assert.equal(seriesLink('https://weebcentral.com/chapters/01J76XY8CJ2RJGWMHM69ZS0J3H'), null); assert.equal(seriesLink('http://weebcentral.com/series/01J76XY8CJ2RJGWMHM69ZS0J3H'), null); assert.equal(seriesLink(dex).seriesId, '06a37094-b3ba-4f25-bf2b-54c9751e0e91'); });