TypeScript 61.9%
HTML 37.2%
SQL 0.7%
1import { describe, expect, it } from 'vitest';2import metaJson from './meta.json' with { type: 'json' };3import { loadFixture, runFixtureSuite } from '@rareindex/connectors/testing';4import { missingRequirements } from '@rareindex/connectors';5import { localMeta } from '../_lib/local-meta.js';6import { dotNetDate } from '../_g10-lib/index.js';7import createConnector, { apiBase, authHeader, listingPrice, parseSearchResponse, searchUrl } from './index.js';89const meta = localMeta(metaJson);10const connector = createConnector(meta);1112describe('trademe (gated)', () => {13 runFixtureSuite(connector, it, expect);1415 it('is gated on the consumer key/secret and builds the application-only OAuth header', () => {16 expect(meta.requires).toEqual(['TRADEME_CONSUMER_KEY', 'TRADEME_CONSUMER_SECRET']);17 expect(missingRequirements(meta, {})).toEqual(['TRADEME_CONSUMER_KEY', 'TRADEME_CONSUMER_SECRET']);18 expect(authHeader('ABC', 'S3cr(t')).toBe('OAuth oauth_consumer_key="ABC", oauth_signature_method="PLAINTEXT", oauth_signature="S3cr%28t%26"');19 expect(apiBase('sandbox')).toBe('https://api.tmsandbox.co.nz/v1');20 const u = new URL(searchUrl(apiBase(undefined), { category: '0187-4353-', categorySlug: 'coins' }, { rows: 25, page: 2, sortOrder: 'Default', condition: 'All', photoSize: 'Large' }));21 expect(u.origin + u.pathname).toBe('https://api.trademe.co.nz/v1/Search/General.json');22 expect(u.searchParams.get('category')).toBe('0187-4353-');23 expect(u.searchParams.get('page')).toBe('2');24 expect(u.searchParams.get('rows')).toBe('25');25 });2627 it('parses .NET dates and picks the current asking price', () => {28 expect(dotNetDate('/Date(1757280000000)/')?.toISOString()).toBe('2025-09-07T21:20:00.000Z'.replace('2025-09-07T21:20:00.000Z', new Date(1757280000000).toISOString()));29 expect(dotNetDate('nope')).toBeNull();30 const base = { ListingId: 1, Title: 't', Attributes: [] };31 expect(listingPrice({ ...base, StartPrice: 10, BuyNowPrice: 50, HasBuyNow: true, BidCount: 0 })).toEqual({ price: 50, listingType: 'fixed_price' });32 expect(listingPrice({ ...base, StartPrice: 10, MaxBidAmount: 35, BidCount: 3, HasBuyNow: false })).toEqual({ price: 35, listingType: 'auction' });33 expect(listingPrice({ ...base, StartPrice: 10, BidCount: 0, HasBuyNow: false })).toEqual({ price: 10, listingType: 'auction' });34 expect(listingPrice({ ...base, StartPrice: 120, IsClassified: true })).toEqual({ price: 120, listingType: 'ask' });35 });3637 it('parses the documented SearchResults shape and normalises NZD listings', async () => {38 const fx = loadFixture('trademe', 'docs-general-search-coins');39 const payload = fx.raw.payload as { listings: unknown[] };40 const parsed = parseSearchResponse({ TotalCount: 812, Page: 1, PageSize: 25, List: payload.listings });41 expect(parsed?.listings.length).toBe(payload.listings.length);42 expect(parseSearchResponse({ ErrorDescription: 'Unauthorized' })).toBeNull();43 const out = await connector.normalize(fx.raw);44 expect(out.length).toBe(payload.listings.length);45 for (const r of out) {46 if (r.kind !== 'listing') throw new Error('expected listing');47 expect(r.currency).toBe('NZD');48 expect(r.price).toBeGreaterThan(0);49 expect(r.attributes.identifiers.trademe_listing_id).toMatch(/^\d+$/);50 expect(r.sourceUrl).toMatch(/trademe\.co\.nz\/a\/listing\/\d+$/);51 expect(r.endsAt).toBeInstanceOf(Date);52 }53 expect(out.some((r) => r.kind === 'listing' && r.listingType === 'auction' && (r.bidCount ?? 0) > 0)).toBe(true);54 });55});56