const test = require('node:test'); const assert = require('node:assert/strict'); const detection = require('../public/js/services/channelLanguageDetection.js'); const grouping = require('../public/js/services/channelVariantGrouping.js'); const channel = (id, name, extra = {}) => ({ id, streamId: id, sourceId: 1, name, groupTitle: 'Sports', ...extra }); test('scores explicit French prefixes with strong confidence', () => { for (const name of ['|FR| BEIN SPORTS 1 UHD', 'FR-CAR| bein sports 1']) { const result = detection.detectLanguage(channel(name, name)); assert.equal(result.language.code, 'fr'); assert.match(result.language.status, /medium|high/); assert.ok(result.languageScores.fr >= 75); assert.ok(result.languageEvidence.some(item => item.type === 'name-prefix')); } }); test('maps UK group evidence to English with medium confidence', () => { const result = detection.detectLanguage(channel('1', 'Sports One', { groupTitle: 'UK Sports' })); assert.equal(result.language.code, 'en'); assert.equal(result.language.status, 'medium'); }); test('uses a France source as weak French evidence', () => { const result = detection.detectLanguage(channel('1', 'Sports One'), { sourceName: 'France IPTV' }); assert.equal(result.language.code, 'fr'); assert.equal(result.language.status, 'low'); }); test('does not force multilingual BE to a language', () => { const result = detection.detectLanguage(channel('1', 'BE Sports 1')); assert.equal(result.language.code, 'unknown'); }); test('classifies contradictory close evidence as unknown', () => { const result = detection.detectLanguage(channel('1', 'French English Sports')); assert.equal(result.language.code, 'unknown'); assert.equal(result.language.status, 'unknown'); }); test('global and per-channel language preferences resolve tied variants', () => { const variants = [channel('fr', '|FR| Sports One HD'), channel('en', '|UK| Sports One HD')]; const globalEnglish = grouping.groupChannels(variants, { preferredLanguage: 'en' })[0]; assert.equal(globalEnglish.preferredVariant.id, 'en'); const perChannel = grouping.groupChannels(variants, { preferredLanguage: 'en', languagePreferences: new Map([['sports one', 'fr']]) })[0]; assert.equal(perChannel.preferredVariant.id, 'fr'); }); test('explicit language preference beats quality and hidden variants are ignored', () => { const frenchSd = channel('fr', '|FR| Sports One SD'); const english4k = channel('en', '|UK| Sports One 4K'); const preferredFrench = grouping.groupChannels([frenchSd, english4k], { preferredLanguage: 'fr' })[0]; assert.equal(preferredFrench.preferredVariant.id, 'fr'); const hiddenFrench = grouping.groupChannels([frenchSd, english4k], { preferredLanguage: 'fr', isHidden: variant => variant.id === 'fr' })[0]; assert.equal(hiddenFrench.preferredVariant.id, 'en'); });