OverviewFilesCommitsIssuesDocsReleasesPeers

pearbrowser-desktop / test / privacy-defaults.test.js

102 lines · javascript ref:
import test from 'node:test'
import assert from 'node:assert/strict'
import { createRequire } from 'node:module'
import { readFileSync } from 'node:fs'
import { fileURLToPath } from 'node:url'
import { dirname, join } from 'node:path'

const require = createRequire(import.meta.url)
const {
  DEFAULT_PRIVACY,
  mergeSettingsWithPrivacyDefaults,
  isHistoryEnabled,
  isSearchIndexEnabled,
  normalizePrivacySettings
} = require('../backend/privacy-policy.cjs')
const { ContentShield } = require('../backend/content-shield.cjs')

const root = join(dirname(fileURLToPath(import.meta.url)), '..')

test('privacy defaults: history off, search index off, telemetry never, shield on', () => {
  assert.equal(DEFAULT_PRIVACY.historyEnabled, false)
  assert.equal(DEFAULT_PRIVACY.searchIndexEnabled, false)
  assert.equal(DEFAULT_PRIVACY.telemetryEnabled, false)
  assert.equal(DEFAULT_PRIVACY.contentShield, true)

  const merged = mergeSettingsWithPrivacyDefaults({})
  assert.equal(merged.historyEnabled, false)
  assert.equal(merged.searchIndexEnabled, false)
  assert.equal(merged.telemetryEnabled, false)
  assert.equal(merged.contentShield, true)

  assert.equal(isHistoryEnabled({}), false)
  assert.equal(isHistoryEnabled({ historyEnabled: true }), true)
  assert.equal(isSearchIndexEnabled({}), false)
  assert.equal(isSearchIndexEnabled({ searchIndexEnabled: true }), true)

  // Telemetry can never be forced on via normalize
  assert.equal(normalizePrivacySettings({ telemetryEnabled: true }).telemetryEnabled, false)
})

test('unset contentShield stays on; explicit false disables', () => {
  assert.equal(mergeSettingsWithPrivacyDefaults({}).contentShield, true)
  assert.equal(mergeSettingsWithPrivacyDefaults({ contentShield: false }).contentShield, false)
})

test('builtin shield blocks expanded ad/tracker set and ships cosmetics', () => {
  const shield = new ContentShield()
  const cases = [
    'https://stats.doubleclick.net/pixel',
    'https://www.googletagmanager.com/gtm.js',
    'https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js',
    'https://connect.facebook.net/en_US/fbevents.js',
    'https://cdn.segment.com/analytics.js',
    'https://static.hotjar.com/c/hotjar.js',
    'https://bat.bing.com/bat.js',
    'https://ads.linkedin.com/li.lms',
    'https://trc.taboola.com/x',
    'https://cdn.taboola.com/libtrc.js',
    'https://sb.scorecardresearch.com/beacon.js',
    'https://cdn.mxpnl.com/libs/mixpanel.js',
    'https://bam.nr-data.net/1',
    'https://app.appsflyer.com/x',
    'https://aax.amazon-adsystem.com/e/dtb'
  ]
  for (const url of cases) {
    assert.equal(shield.shouldBlockUrl(url).blocked, true, `expected block: ${url}`)
  }
  assert.equal(shield.shouldBlockUrl('https://example.com/blog/post').blocked, false)
  assert.equal(shield.shouldBlockUrl('https://news.example/article').blocked, false)
  const css = shield.cosmeticCssFor('example.com')
  assert.match(css, /\.adsbygoogle/)
  assert.match(css, /\.OUTBRAIN|\.taboola-container|\.ad-banner/)
  const stats = shield.stats()
  assert.ok(stats.blockRules > 40, `expected broad seed list, got ${stats.blockRules}`)
})

test('shield stats never retain URLs (counters only)', () => {
  const shield = new ContentShield()
  shield.shouldBlockUrl('https://doubleclick.net/ad?secret=token')
  const stats = shield.stats()
  assert.ok(stats.blocked >= 1)
  const blob = JSON.stringify(stats)
  assert.doesNotMatch(blob, /secret=token/)
  assert.doesNotMatch(blob, /https:\/\/doubleclick/)
})

test('UI and backend wire history/search opt-in and zero-collection copy', () => {
  const shell = readFileSync(join(root, 'ui/shell.js'), 'utf8')
  const index = readFileSync(join(root, 'backend/index.js'), 'utf8')
  assert.match(shell, /historyEnabled/)
  assert.match(shell, /searchIndexEnabled/)
  assert.match(shell, /privacy-zero-collection/)
  assert.match(shell, /history-disabled-note/)
  assert.match(shell, /Telemetry: never/)
  assert.match(index, /isHistoryEnabled/)
  assert.match(index, /isSearchIndexEnabled/)
  assert.match(index, /history-disabled/)
  assert.match(index, /search-index-disabled/)
  assert.match(index, /telemetryEnabled: false/)
  assert.match(index, /dataCollection/)
})