TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import meta from './meta.json' with { type: 'json' };3import { localMeta } from '../_lib/local-meta.js';4import { listFixtures, loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';5import createConnector, { barcodeIds, idFromApiUrl, parseCoverPrice, parseKeyDate, trimIssue, trimSeries } from './index.js';6import { publisherCategory } from '../_g6-comics-toys-games-lib/comics.js';78const connector = createConnector(localMeta(meta));910describe('gcd', () => {11 runFixtureSuite(connector, it, expect);1213 it('parses GCD key dates without inventing missing day/month', () => {14 expect(parseKeyDate('1988-05-00')).toEqual({ year: 1988, date: null });15 expect(parseKeyDate('1988-02-23')).toEqual({ year: 1988, date: new Date(Date.UTC(1988, 1, 23)) });16 expect(parseKeyDate('1867-00-00')).toEqual({ year: 1867, date: null });17 expect(parseKeyDate('')).toEqual({ year: null, date: null });18 expect(parseKeyDate(null)).toEqual({ year: null, date: null });19 });2021 it('parses cover prices only when an ISO currency is printed', () => {22 expect(parseCoverPrice('0.12 USD')).toEqual({ amount: 0.12, currency: 'USD' });23 expect(parseCoverPrice('1.95 USD; 2.60 CAD; 0.50 GBP')).toEqual({ amount: 1.95, currency: 'USD' });24 expect(parseCoverPrice('0.00 FREE')).toBeNull();25 expect(parseCoverPrice('[none]')).toBeNull();26 expect(parseCoverPrice('')).toBeNull();27 });2829 it('derives deterministic identifiers from api urls and barcodes', () => {30 expect(idFromApiUrl('https://www.comics.org/api/issue/127538/?format=json')).toBe('127538');31 expect(idFromApiUrl('https://www.comics.org/api/publisher/78/?format=json')).toBe('78');32 expect(idFromApiUrl(null)).toBeNull();33 expect(barcodeIds('759606024605')).toEqual({ upc: '759606024605' });34 expect(barcodeIds('75960602460500111')).toEqual({ upc: '759606024605', upc_supplement: '00111' });35 expect(barcodeIds('9781302900000')).toEqual({ isbn: '9781302900000', ean: '9781302900000' });36 expect(barcodeIds('')).toEqual({});37 });3839 it('maps publishers to taxonomy families', () => {40 expect(publisherCategory('Marvel')).toBe('marvel_comics');41 expect(publisherCategory('DC')).toBe('dc_comics');42 expect(publisherCategory('Harrier')).toBe('independent_comics');43 expect(publisherCategory('Shueisha', 'ja')).toBe('manga');44 expect(publisherCategory(null)).toBe('comics');45 });4647 it('trims live API shapes and normalises fixtures into catalog items with comics_org_id', async () => {48 const issue = trimIssue({ api_url: 'https://www.comics.org/api/issue/1/?format=json', number: '[nn]', key_date: '1867-00-00', price: '[none]', story_set: [{ type: 'cover', pencils: 'Gustave Doré' }] });49 expect(issue.id).toBe('1');50 expect(issue.cover_pencils).toBe('Gustave Doré');51 expect(issue.story_count).toBe(1);52 const series = trimSeries({ api_url: 'https://www.comics.org/api/series/10814/?format=json', name: '!Gag!', country: 'gb', language: 'en', year_began: 1987, year_ended: 1989, active_issues: ['a', 'b'] });53 expect(series).toMatchObject({ id: '10814', country: 'gb', issue_count: 2 });54 for (const name of listFixtures('gcd')) {55 const fx = loadFixture('gcd', name);56 const out = await connector.normalize(fx.raw);57 expect(out.length).toBeGreaterThan(0);58 for (const r of out) {59 expect(r.kind).toBe('catalog_item');60 if (r.kind !== 'catalog_item') continue;61 expect(r.attributes.identifiers.comics_org_id).toMatch(/^\d+$/);62 expect(r.sourceUrl).toBe(`https://www.comics.org/issue/${r.attributes.identifiers.comics_org_id}/`);63 expect(r.attributes.metadata.license).toContain('CC-BY-SA');64 expect(r.confidence).toBeLessThan(1);65 }66 }67 const gag = await connector.normalize(loadFixture('gcd', 'series-page1-0-10814').raw);68 const first = gag[0];69 if (first?.kind !== 'catalog_item') throw new Error('expected catalog item');70 expect(first.attributes).toMatchObject({ categorySlug: 'independent_comics', brand: 'Harrier', set: '!Gag!', number: '1', year: 1987, country: 'GB', originalMsrp: 1.95, originalMsrpCurrency: 'USD' });71 expect(first.releaseDate).toBeNull();72 });73});74