import { test } from 'node:test'; import assert from 'node:assert/strict'; import { OUTLIER_SELECTOR, SUBSCRIBERS_SELECTOR, outlierScoreFromHref, parseVidiqScore, readVidiqData, } from '../src/lib/vidiq.js'; const HREF = 'https://app.vidiq.com/outliers?utm_source=chrome&utm_medium=extension&utm_content=&filters=%7B%22mode%22%3A%22long%22%7D' + '&outlier_score=146.19205697700949&video_id=Tts9NHL8D8I'; test('selectors point at VidIQ data attributes, not generated classes', () => { assert.equal(OUTLIER_SELECTOR, '[data-hover-popover="OutlierPopover"]'); assert.equal(SUBSCRIBERS_SELECTOR, '[data-vidiq-subscriber-count]'); }); test('parseVidiqScore takes the first number in the text', () => { assert.equal(parseVidiqScore('>100x'), 100); assert.equal(parseVidiqScore('12.5x'), 12.5); assert.equal(parseVidiqScore('5,2x'), 5.2); assert.equal(parseVidiqScore('Outlier 8'), 8); for (const text of ['no digits', '', null, undefined]) assert.equal(parseVidiqScore(text), null, String(text)); }); test('outlierScoreFromHref reads and rounds the outlier_score parameter', () => { assert.equal(outlierScoreFromHref(HREF), 146.19); assert.equal(outlierScoreFromHref('https://app.vidiq.com/outliers?outlier_score=2'), 2); }); test('outlierScoreFromHref returns null without a usable parameter', () => { for (const href of [ 'https://app.vidiq.com/outliers?video_id=x', 'https://app.vidiq.com/outliers?outlier_score=', 'https://app.vidiq.com/outliers?outlier_score=abc', '', null, undefined, ]) { assert.equal(outlierScoreFromHref(href), null, String(href)); } }); // A card stub: querySelector answers only for the two VidIQ selectors. const cardWith = ({ outlier, subscribers }) => ({ querySelector: (selector) => selector === OUTLIER_SELECTOR ? outlier ?? null : selector === SUBSCRIBERS_SELECTOR ? subscribers ?? null : null, }); const outlierNode = (text, href) => ({ textContent: text, querySelector: (selector) => selector === 'a' && href !== undefined ? { getAttribute: (name) => (name === 'href' ? href : null) } : null, }); test('readVidiqData reads the exact score from the link and subscribers from the data attribute', () => { const card = cardWith({ outlier: outlierNode('>100x', HREF), subscribers: { textContent: '571 тыс.' } }); assert.deepEqual(readVidiqData(card), { outlierScore: 146.19, subscribers: 571000 }); }); test('readVidiqData falls back to the badge text when the link has no score', () => { const card = cardWith({ outlier: outlierNode('>100x', 'https://app.vidiq.com/outliers'), subscribers: null }); assert.deepEqual(readVidiqData(card), { outlierScore: 100, subscribers: null }); const noLink = cardWith({ outlier: outlierNode('7.5x'), subscribers: null }); assert.deepEqual(readVidiqData(noLink), { outlierScore: 7.5, subscribers: null }); }); test('readVidiqData returns nulls when VidIQ has not rendered its blocks', () => { assert.deepEqual(readVidiqData(cardWith({})), { outlierScore: null, subscribers: null }); });