import { describe, it, expect } from 'vitest';
import {
classifyChannel,
extractReferrerHost,
normalizeHost,
sanitizeLandingPath,
sanitizeTag,
} from '@/lib/analytics/channel';
// Every expected value below is written by hand. Deriving them from the lookup
// tables in the module would mean deleting an entry from a table also deletes
// its own test case.
describe('sanitizeTag', () => {
it('lowercases and trims', () => {
expect(sanitizeTag(' GitHub ')).toBe('github');
});
it('rejects a tag carrying markup or control characters', () => {
expect(sanitizeTag('')).toBe('/');
expect(sanitizeLandingPath('/ok\nX-Injected: 1')).toBe('/');
expect(sanitizeLandingPath('/a b')).toBe('/');
});
});
describe('classifyChannel', () => {
it('is DIRECT with no tags and no referrer', () => {
expect(classifyChannel({})).toBe('DIRECT');
});
it('reads the referring host when there are no tags', () => {
expect(classifyChannel({ referrerHost: 'github.com' })).toBe('GITHUB');
expect(classifyChannel({ referrerHost: 'gist.github.com' })).toBe('GITHUB');
expect(classifyChannel({ referrerHost: 'youtu.be' })).toBe('YOUTUBE');
expect(classifyChannel({ referrerHost: 'www.producthunt.com' })).toBe('REVIEW_LINK');
expect(classifyChannel({ referrerHost: 'news.ycombinator.com' })).toBe('COMMUNITY');
});
it('treats every Google country domain as search', () => {
expect(classifyChannel({ referrerHost: 'google.com' })).toBe('GOOGLE');
expect(classifyChannel({ referrerHost: 'google.com.tr' })).toBe('GOOGLE');
expect(classifyChannel({ referrerHost: 'news.google.co.uk' })).toBe('GOOGLE');
});
it('does not mistake a lookalike domain for the real one', () => {
expect(classifyChannel({ referrerHost: 'notgithub.com' })).toBe('REFERRAL');
expect(classifyChannel({ referrerHost: 'google.com.evil.example' })).toBe('REFERRAL');
});
it('counts an unrecognised site that links to us as a referral', () => {
expect(classifyChannel({ referrerHost: 'someblog.example' })).toBe('REFERRAL');
});
it('prefers an explicit utm_source over the referring host', () => {
expect(classifyChannel({ utmSource: 'youtube', referrerHost: 'google.com' })).toBe('YOUTUBE');
});
it('reads a utm_source that was written as a domain', () => {
expect(classifyChannel({ utmSource: 'github.com' })).toBe('GITHUB');
});
it('files a tagged campaign we do not recognise as OTHER, not DIRECT', () => {
expect(classifyChannel({ utmSource: 'conference-flyer' })).toBe('OTHER');
});
it('lets the medium that names the motion win over the source that names the place', () => {
expect(classifyChannel({ utmSource: 'linkedin', utmMedium: 'outbound' })).toBe('OUTBOUND');
expect(classifyChannel({ utmSource: 'github', utmMedium: 'email' })).toBe('OUTBOUND');
expect(classifyChannel({ utmSource: 'someone', utmMedium: 'referral' })).toBe('REFERRAL');
});
it('ignores a source that fails sanitizing and falls back to the referrer', () => {
expect(classifyChannel({ utmSource: '