| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439 |
- import { describe, expect, it } from 'vitest'
- import {
- buildFirstReferrerData,
- FIRST_REFERRER_COOKIE_NAME,
- hasPaidSignals,
- isExternalReferrer,
- isOAuthRedirectReferrer,
- MW_DIAG_COOKIE_NAME,
- parseFirstReferrerCookie,
- parseMwDiagCookie,
- serializeFirstReferrerCookie,
- shouldRefreshCookie,
- } from './first-referrer-cookie'
- describe('first-referrer-cookie', () => {
- describe('isExternalReferrer', () => {
- it('returns false for briven domains', () => {
- expect(isExternalReferrer('https://supabase.com')).toBe(false)
- expect(isExternalReferrer('https://www.supabase.com')).toBe(false)
- expect(isExternalReferrer('https://docs.supabase.com')).toBe(false)
- })
- it('returns true for external domains', () => {
- expect(isExternalReferrer('https://google.com')).toBe(true)
- expect(isExternalReferrer('https://chatgpt.com')).toBe(true)
- })
- it('returns true for http:// referrers', () => {
- expect(isExternalReferrer('http://google.com')).toBe(true)
- expect(isExternalReferrer('http://example.org/page')).toBe(true)
- })
- it('returns false for invalid values', () => {
- expect(isExternalReferrer('')).toBe(false)
- expect(isExternalReferrer('not-a-url')).toBe(false)
- })
- })
- describe('isOAuthRedirectReferrer', () => {
- // Google SSO — block entire domain
- it('returns true for accounts.google.com (bare)', () => {
- expect(isOAuthRedirectReferrer('https://accounts.google.com/')).toBe(true)
- })
- it('returns true for accounts.google.com with path', () => {
- expect(
- isOAuthRedirectReferrer('https://accounts.google.com/o/oauth2/auth?client_id=abc')
- ).toBe(true)
- })
- // GitHub OAuth — block bare domain only
- it('returns true for bare github.com/', () => {
- expect(isOAuthRedirectReferrer('https://github.com/')).toBe(true)
- })
- it('returns true for bare github.com (no trailing slash)', () => {
- expect(isOAuthRedirectReferrer('https://github.com')).toBe(true)
- })
- // GitHub genuine referrals — preserve these
- it('returns false for github.com with repo path', () => {
- expect(isOAuthRedirectReferrer('https://github.com/supabase/supabase')).toBe(false)
- })
- it('returns false for github.com with README path', () => {
- expect(
- isOAuthRedirectReferrer('https://github.com/supabase/supabase?tab=readme-ov-file')
- ).toBe(false)
- })
- it('returns false for github.com with discussion path', () => {
- expect(isOAuthRedirectReferrer('https://github.com/orgs/supabase/discussions/42949')).toBe(
- false
- )
- })
- it('returns false for github.com with blob path', () => {
- expect(
- isOAuthRedirectReferrer('https://github.com/supabase/supabase/blob/master/README.md')
- ).toBe(false)
- })
- // GitHub OAuth explicit path (rare, but should still be caught)
- it('returns true for github.com/login/oauth/authorize', () => {
- expect(
- isOAuthRedirectReferrer('https://github.com/login/oauth/authorize?client_id=abc')
- ).toBe(true)
- })
- // Non-OAuth domains — should not match
- it('returns false for google.com (search)', () => {
- expect(isOAuthRedirectReferrer('https://www.google.com/')).toBe(false)
- })
- it('returns false for claude.ai', () => {
- expect(isOAuthRedirectReferrer('https://claude.ai/')).toBe(false)
- })
- it('returns false for empty string', () => {
- expect(isOAuthRedirectReferrer('')).toBe(false)
- })
- it('returns false for malformed URL', () => {
- expect(isOAuthRedirectReferrer('not-a-url')).toBe(false)
- })
- })
- describe('buildFirstReferrerData', () => {
- it('handles malformed landing URL gracefully', () => {
- const data = buildFirstReferrerData({
- referrer: 'https://google.com',
- landingUrl: 'not-a-valid-url',
- })
- expect(data.referrer).toBe('https://google.com')
- expect(data.landing_url).toBe('not-a-valid-url')
- expect(data.utms).toEqual({})
- expect(data.click_ids).toEqual({})
- })
- it('extracts utm and click-id params from landing url', () => {
- const data = buildFirstReferrerData({
- referrer: 'https://www.google.com/',
- landingUrl:
- 'https://supabase.com/pricing?utm_source=google&utm_medium=cpc&utm_campaign=test&gclid=abc123&msclkid=xyz456',
- })
- expect(data.referrer).toBe('https://www.google.com/')
- expect(data.landing_url).toBe(
- 'https://supabase.com/pricing?utm_source=google&utm_medium=cpc&utm_campaign=test&gclid=abc123&msclkid=xyz456'
- )
- expect(data.utms).toEqual({
- utm_source: 'google',
- utm_medium: 'cpc',
- utm_campaign: 'test',
- })
- expect(data.click_ids).toEqual({
- gclid: 'abc123',
- msclkid: 'xyz456',
- })
- })
- })
- describe('serialize / parse', () => {
- it('round-trips valid cookie payloads', () => {
- const input = buildFirstReferrerData({
- referrer: 'https://www.google.com/',
- landingUrl: 'https://supabase.com/pricing?utm_source=google',
- })
- const encoded = serializeFirstReferrerCookie(input)
- const parsed = parseFirstReferrerCookie(`${FIRST_REFERRER_COOKIE_NAME}=${encoded}`)
- expect(parsed).toEqual(input)
- })
- it('returns null for empty string', () => {
- expect(parseFirstReferrerCookie('')).toBeNull()
- })
- it('parses cookie from header with multiple cookies', () => {
- const input = buildFirstReferrerData({
- referrer: 'https://google.com/',
- landingUrl: 'https://supabase.com/',
- })
- const encoded = serializeFirstReferrerCookie(input)
- const header = `session=abc123; ${FIRST_REFERRER_COOKIE_NAME}=${encoded}; theme=dark`
- expect(parseFirstReferrerCookie(header)).toEqual(input)
- })
- it('returns null for malformed json', () => {
- expect(parseFirstReferrerCookie(`${FIRST_REFERRER_COOKIE_NAME}=%7Bnot-json`)).toBeNull()
- })
- it('returns null for invalid payload shape', () => {
- const encoded = encodeURIComponent(JSON.stringify({ foo: 'bar' }))
- expect(parseFirstReferrerCookie(`${FIRST_REFERRER_COOKIE_NAME}=${encoded}`)).toBeNull()
- })
- it('parses double-encoded cookies (legacy format before serializer fix)', () => {
- const input = buildFirstReferrerData({
- referrer: 'https://www.google.com/',
- landingUrl: 'https://supabase.com/pricing?utm_source=google',
- })
- // Simulate the old double-encoding: encodeURIComponent(JSON.stringify(data))
- // followed by Next.js cookies.set() encoding it again.
- const doubleEncoded = encodeURIComponent(encodeURIComponent(JSON.stringify(input)))
- const parsed = parseFirstReferrerCookie(`${FIRST_REFERRER_COOKIE_NAME}=${doubleEncoded}`)
- expect(parsed).toEqual(input)
- })
- it('drops non-string values in utms/click_ids', () => {
- const encoded = encodeURIComponent(
- JSON.stringify({
- referrer: 'https://www.google.com/',
- landing_url: 'https://supabase.com/pricing',
- utms: { utm_source: 'google', utm_medium: 123 },
- click_ids: { gclid: 'abc', msclkid: null },
- ts: 123,
- })
- )
- const parsed = parseFirstReferrerCookie(`${FIRST_REFERRER_COOKIE_NAME}=${encoded}`)
- expect(parsed).toEqual({
- referrer: 'https://www.google.com/',
- landing_url: 'https://supabase.com/pricing',
- utms: { utm_source: 'google' },
- click_ids: { gclid: 'abc' },
- ts: 123,
- })
- })
- })
- describe('hasPaidSignals', () => {
- it('detects click IDs', () => {
- expect(hasPaidSignals(new URL('https://supabase.com/?gclid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?fbclid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?msclkid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?gbraid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?wbraid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?rdt_cid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?ttclid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?twclid=abc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?li_fat_id=abc'))).toBe(true)
- })
- it('detects paid utm_medium values', () => {
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=cpc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=ppc'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=paid_search'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=paidsocial'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=paid_social'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=display'))).toBe(true)
- })
- it('is case-insensitive for utm_medium', () => {
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=CPC'))).toBe(true)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=Paid_Search'))).toBe(true)
- })
- it('returns false for organic traffic', () => {
- expect(hasPaidSignals(new URL('https://supabase.com/'))).toBe(false)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_source=google'))).toBe(false)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=email'))).toBe(false)
- expect(hasPaidSignals(new URL('https://supabase.com/?utm_medium=organic'))).toBe(false)
- })
- })
- describe('parseMwDiagCookie', () => {
- it('parses well-formed value with would_stamp=1 and has_cookie=0', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit=1&would_stamp=1&has_cookie=0`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: true,
- has_existing_cookie: false,
- })
- })
- it('parses well-formed value with would_stamp=0 and has_cookie=1', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit=1&would_stamp=0&has_cookie=1`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: false,
- has_existing_cookie: true,
- })
- })
- it('returns null when hit=0', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit=0&would_stamp=1&has_cookie=1`
- expect(parseMwDiagCookie(header)).toBeNull()
- })
- it('returns object with would_stamp: false when would_stamp key is missing', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit=1&has_cookie=1`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: false,
- has_existing_cookie: true,
- })
- })
- it('returns object with has_existing_cookie: false when has_cookie key is missing', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit=1&would_stamp=1`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: true,
- has_existing_cookie: false,
- })
- })
- it('returns null for empty string input', () => {
- expect(parseMwDiagCookie('')).toBeNull()
- })
- it('returns null when cookie is not present in header', () => {
- expect(parseMwDiagCookie('session=abc123; theme=dark')).toBeNull()
- })
- it('returns null for garbage value', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=not-a-valid-query-string`
- expect(parseMwDiagCookie(header)).toBeNull()
- })
- it('parses correct cookie from header with multiple cookies', () => {
- const header = `session=abc123; ${MW_DIAG_COOKIE_NAME}=hit=1&would_stamp=1&has_cookie=0; theme=dark`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: true,
- has_existing_cookie: false,
- })
- })
- it('parses URL-encoded value from Next.js response.cookies.set()', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit%3D1%26would_stamp%3D1%26has_cookie%3D0`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: true,
- has_existing_cookie: false,
- })
- })
- it('parses URL-encoded value with has_cookie=1', () => {
- const header = `${MW_DIAG_COOKIE_NAME}=hit%3D1%26would_stamp%3D0%26has_cookie%3D1`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: false,
- has_existing_cookie: true,
- })
- })
- it('parses URL-encoded value among multiple cookies', () => {
- const header = `session=abc; ${MW_DIAG_COOKIE_NAME}=hit%3D1%26would_stamp%3D0%26has_cookie%3D0; theme=dark`
- expect(parseMwDiagCookie(header)).toEqual({
- hit: true,
- would_stamp: false,
- has_existing_cookie: false,
- })
- })
- })
- describe('shouldRefreshCookie', () => {
- it('stamps when no cookie and external referrer', () => {
- expect(
- shouldRefreshCookie(false, {
- referrer: 'https://google.com',
- url: 'https://supabase.com/',
- })
- ).toEqual({ stamp: true })
- })
- it('skips when no cookie and internal referrer', () => {
- expect(
- shouldRefreshCookie(false, {
- referrer: 'https://supabase.com/docs',
- url: 'https://supabase.com/dashboard',
- })
- ).toEqual({ stamp: false })
- })
- it('skips when cookie exists and no paid signals', () => {
- expect(
- shouldRefreshCookie(true, {
- referrer: 'https://google.com',
- url: 'https://supabase.com/',
- })
- ).toEqual({ stamp: false })
- })
- it('refreshes when cookie exists but URL has paid signals', () => {
- expect(
- shouldRefreshCookie(true, {
- referrer: 'https://google.com',
- url: 'https://supabase.com/?gclid=abc123',
- })
- ).toEqual({ stamp: true })
- expect(
- shouldRefreshCookie(true, {
- referrer: 'https://google.com',
- url: 'https://supabase.com/?utm_medium=cpc&utm_source=google',
- })
- ).toEqual({ stamp: true })
- })
- it('skips when no cookie and no referrer (direct navigation)', () => {
- expect(shouldRefreshCookie(false, { referrer: '', url: 'https://supabase.com/' })).toEqual({
- stamp: false,
- })
- })
- it('handles malformed URL gracefully', () => {
- expect(
- shouldRefreshCookie(true, {
- referrer: 'https://google.com',
- url: 'not-a-valid-url',
- })
- ).toEqual({ stamp: false })
- })
- it('does not stamp for GitHub OAuth redirect (bare domain)', () => {
- const result = shouldRefreshCookie(false, {
- referrer: 'https://github.com/',
- url: 'https://supabase.com/dashboard',
- })
- expect(result.stamp).toBe(false)
- })
- it('does not stamp for Google SSO redirect', () => {
- const result = shouldRefreshCookie(false, {
- referrer: 'https://accounts.google.com/',
- url: 'https://supabase.com/dashboard',
- })
- expect(result.stamp).toBe(false)
- })
- it('still stamps for genuine GitHub referral with path', () => {
- const result = shouldRefreshCookie(false, {
- referrer: 'https://github.com/supabase/supabase?tab=readme-ov-file',
- url: 'https://supabase.com/',
- })
- expect(result.stamp).toBe(true)
- })
- it('still re-stamps existing cookie for paid signals regardless of OAuth referrer', () => {
- const result = shouldRefreshCookie(true, {
- referrer: 'https://github.com/',
- url: 'https://supabase.com/pricing?gclid=abc123',
- })
- expect(result.stamp).toBe(true)
- })
- })
- })
|