/ tests / payments / country-pricing-supplement.test.js
country-pricing-supplement.test.js
  1  /**
  2   * Country Pricing Supplement Tests
  3   *
  4   * Covers additional untested paths in src/utils/country-pricing.js using pg-mock.
  5   */
  6  
  7  import { describe, test, mock, beforeEach } from 'node:test';
  8  import assert from 'node:assert/strict';
  9  import Database from 'better-sqlite3';
 10  import { createPgMock } from '../helpers/pg-mock.js';
 11  
 12  // Mock dotenv before importing module under test
 13  mock.module('dotenv', {
 14    defaultExport: { config: () => {} },
 15    namedExports: { config: () => {} },
 16  });
 17  
 18  // Shared test DB reference
 19  let testDb;
 20  
 21  // Full schema matching all columns used in country-pricing.js
 22  function initDb() {
 23    const db = new Database(':memory:');
 24    db.exec(`
 25      CREATE TABLE IF NOT EXISTS countries (
 26        id INTEGER PRIMARY KEY AUTOINCREMENT,
 27        country_code TEXT NOT NULL UNIQUE,
 28        country_name TEXT NOT NULL,
 29        is_active INTEGER DEFAULT 1,
 30        price_usd INTEGER DEFAULT 0,
 31        price_usd_base INTEGER DEFAULT 0,
 32        price_usd_ppp INTEGER DEFAULT 0,
 33        price_local INTEGER DEFAULT 0,
 34        price_local_formatted TEXT,
 35        currency_code TEXT,
 36        currency_symbol TEXT,
 37        exchange_rate REAL DEFAULT 1.0,
 38        pricing_tier TEXT DEFAULT 'Standard',
 39        pricing_variant TEXT DEFAULT 'charm',
 40        price_last_updated TEXT,
 41        market_notes TEXT,
 42        is_price_sensitive INTEGER DEFAULT 0,
 43        price_overridden INTEGER DEFAULT 0,
 44        override_reason TEXT,
 45        override_date TEXT,
 46        requires_gdpr_check INTEGER DEFAULT 0,
 47        google_domain TEXT,
 48        accept_language TEXT,
 49        common_cities TEXT,
 50        company_types TEXT,
 51        company_keywords TEXT,
 52        key_page_names TEXT,
 53        updated_at TEXT DEFAULT (datetime('now')),
 54        twilio_phone_number TEXT
 55      );
 56    `);
 57    return db;
 58  }
 59  
 60  function insertCountry(db, overrides = {}) {
 61    const defaults = {
 62      country_code: 'AU',
 63      country_name: 'Australia',
 64      is_active: 1,
 65      price_usd: 34700,
 66      price_usd_base: 30000,
 67      price_usd_ppp: 34700,
 68      price_local: 52900,
 69      price_local_formatted: '529',
 70      currency_code: 'AUD',
 71      currency_symbol: 'A$',
 72      exchange_rate: 1.52,
 73      pricing_tier: 'Premium',
 74      pricing_variant: 'charm',
 75      price_last_updated: '2025-01-15',
 76      market_notes: 'Strong market',
 77      is_price_sensitive: 0,
 78      price_overridden: 0,
 79      override_reason: null,
 80      requires_gdpr_check: 0,
 81      google_domain: 'google.com.au',
 82      accept_language: 'en-AU',
 83      common_cities: JSON.stringify(['Sydney', 'Melbourne', 'Brisbane']),
 84      company_types: JSON.stringify(['Pty Ltd', 'PTY LTD']),
 85      company_keywords: JSON.stringify(['plumber', 'electrician', 'builder']),
 86      key_page_names: JSON.stringify(['Contact Us', 'About Us', 'Services']),
 87    };
 88    const row = { ...defaults, ...overrides };
 89  
 90    db.prepare(
 91      `
 92      INSERT OR REPLACE INTO countries (
 93        country_code, country_name, is_active,
 94        price_usd, price_usd_base, price_usd_ppp, price_local, price_local_formatted,
 95        currency_code, currency_symbol, exchange_rate,
 96        pricing_tier, pricing_variant, price_last_updated, market_notes,
 97        is_price_sensitive, price_overridden, override_reason,
 98        requires_gdpr_check, google_domain, accept_language,
 99        common_cities, company_types, company_keywords, key_page_names
100      ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
101    `
102    ).run(
103      row.country_code,
104      row.country_name,
105      row.is_active,
106      row.price_usd,
107      row.price_usd_base,
108      row.price_usd_ppp,
109      row.price_local,
110      row.price_local_formatted,
111      row.currency_code,
112      row.currency_symbol,
113      row.exchange_rate,
114      row.pricing_tier,
115      row.pricing_variant,
116      row.price_last_updated,
117      row.market_notes,
118      row.is_price_sensitive,
119      row.price_overridden,
120      row.override_reason,
121      row.requires_gdpr_check,
122      row.google_domain,
123      row.accept_language,
124      row.common_cities,
125      row.company_types,
126      row.company_keywords,
127      row.key_page_names
128    );
129  }
130  
131  // Mock db.js BEFORE importing the module under test
132  testDb = initDb();
133  mock.module('../../src/utils/db.js', { namedExports: createPgMock(testDb) });
134  
135  const {
136    getCountry,
137    getPrice,
138    getAllCountries,
139    getCountriesByTier,
140    getPricingSummary,
141    overridePrice,
142    getAcceptLanguage,
143    getGoogleDomain,
144    requiresGDPR,
145  } = await import('../../src/utils/country-pricing.js?v=supp');
146  
147  // ── getCountry ──────────────────────────────────────────────────────────────
148  
149  describe('getCountry - supplement', () => {
150    beforeEach(() => {
151      testDb.exec('DELETE FROM countries');
152      insertCountry(testDb);
153    });
154  
155    test('returns priceUsd as dollars (cents/100)', async () => {
156      const c = await getCountry('AU');
157      assert.equal(c.priceUsd, 347);
158    });
159  
160    test('returns all three JSON-parsed array fields', async () => {
161      const c = await getCountry('AU');
162      assert.deepEqual(c.commonCities, ['Sydney', 'Melbourne', 'Brisbane']);
163      assert.deepEqual(c.companyTypes, ['Pty Ltd', 'PTY LTD']);
164      assert.deepEqual(c.companyKeywords, ['plumber', 'electrician', 'builder']);
165      assert.deepEqual(c.keyPageNames, ['Contact Us', 'About Us', 'Services']);
166    });
167  
168    test('country_code is returned on the object', async () => {
169      const c = await getCountry('AU');
170      assert.equal(c.country_code, 'AU');
171    });
172  
173    test('returns null for non-existent country code', async () => {
174      assert.ok((await getCountry('ZZ')) == null);
175    });
176  
177    test('case-insensitive lookup works for lowercase code', async () => {
178      const c = await getCountry('au');
179      assert.ok(c !== null);
180      assert.equal(c.country_code, 'AU');
181    });
182  
183    test('returns null for inactive country', async () => {
184      insertCountry(testDb, {
185        country_code: 'XX',
186        country_name: 'Inactive',
187        is_active: 0,
188        common_cities: null,
189        company_types: null,
190        company_keywords: null,
191        key_page_names: null,
192      });
193      assert.ok((await getCountry('XX')) == null);
194    });
195  
196    test('handles null common_cities gracefully', async () => {
197      insertCountry(testDb, {
198        country_code: 'NZ',
199        country_name: 'NZ',
200        common_cities: null,
201        company_types: null,
202        company_keywords: null,
203        key_page_names: null,
204      });
205      const c = await getCountry('NZ');
206      assert.deepEqual(c.commonCities, []);
207      assert.deepEqual(c.companyTypes, []);
208      assert.deepEqual(c.companyKeywords, []);
209      assert.deepEqual(c.keyPageNames, []);
210    });
211  
212    test('returns null on db error', async () => {
213      const saved = testDb.prepare.bind(testDb);
214      testDb.prepare = () => {
215        throw new Error('db error');
216      };
217      try {
218        assert.ok((await getCountry('AU')) == null);
219      } finally {
220        testDb.prepare = saved;
221      }
222    });
223  });
224  
225  // ── getPrice ────────────────────────────────────────────────────────────────
226  
227  describe('getPrice - supplement', () => {
228    beforeEach(() => {
229      testDb.exec('DELETE FROM countries');
230      insertCountry(testDb);
231    });
232  
233    test('returns complete pricing object', async () => {
234      const p = await getPrice('AU');
235      assert.ok(p !== null);
236      assert.equal(p.countryCode, 'AU');
237      assert.equal(p.countryName, 'Australia');
238      assert.equal(p.priceUsd, 347); // ppp / 100
239      assert.equal(p.priceLocal, 529); // local / 100
240      assert.equal(p.priceCents, 34700);
241      assert.equal(p.priceLocalCents, 52900);
242      assert.equal(p.currency, 'AUD');
243      assert.equal(p.currencySymbol, 'A$');
244      assert.equal(p.formattedPrice, 'A$529');
245      assert.equal(p.tier, 'Premium');
246      assert.equal(p.variant, 'charm');
247      assert.equal(p.exchangeRate, 1.52);
248      assert.equal(p.lastUpdated, '2025-01-15');
249      assert.equal(p.notes, 'Strong market');
250      assert.equal(p.isPriceSensitive, false);
251      assert.equal(p.overridden, false);
252      assert.equal(p.overrideReason, null);
253    });
254  
255    test('isPriceSensitive is true when is_price_sensitive=1', async () => {
256      insertCountry(testDb, {
257        country_code: 'IN',
258        country_name: 'India',
259        is_price_sensitive: 1,
260        common_cities: null,
261        company_types: null,
262        company_keywords: null,
263        key_page_names: null,
264      });
265      assert.equal((await getPrice('IN')).isPriceSensitive, true);
266    });
267  
268    test('overridden is true when price_overridden=1', async () => {
269      insertCountry(testDb, {
270        country_code: 'CA',
271        country_name: 'Canada',
272        price_overridden: 1,
273        override_reason: 'Manual override',
274        common_cities: null,
275        company_types: null,
276        company_keywords: null,
277        key_page_names: null,
278      });
279      const p = await getPrice('CA');
280      assert.equal(p.overridden, true);
281      assert.equal(p.overrideReason, 'Manual override');
282    });
283  
284    test('returns null for unknown country', async () => {
285      assert.ok((await getPrice('ZZ')) == null);
286    });
287  
288    test('returns null for inactive country', async () => {
289      insertCountry(testDb, {
290        country_code: 'BR',
291        country_name: 'Brazil',
292        is_active: 0,
293        common_cities: null,
294        company_types: null,
295        company_keywords: null,
296        key_page_names: null,
297      });
298      assert.ok((await getPrice('BR')) == null);
299    });
300  
301    test('returns null on db error', async () => {
302      const saved = testDb.prepare.bind(testDb);
303      testDb.prepare = () => {
304        throw new Error('db error');
305      };
306      try {
307        assert.ok((await getPrice('AU')) == null);
308      } finally {
309        testDb.prepare = saved;
310      }
311    });
312  
313    test('priceFormatted field is the price_local_formatted string', async () => {
314      const p = await getPrice('AU');
315      assert.equal(p.priceFormatted, '529');
316    });
317  });
318  
319  // ── getAllCountries ──────────────────────────────────────────────────────────
320  
321  describe('getAllCountries - supplement', () => {
322    beforeEach(() => {
323      testDb.exec('DELETE FROM countries');
324      insertCountry(testDb, {
325        country_code: 'AU',
326        country_name: 'Australia',
327        price_usd: 34700,
328        pricing_tier: 'Premium',
329      });
330      insertCountry(testDb, {
331        country_code: 'US',
332        country_name: 'United States',
333        price_usd: 49700,
334        pricing_tier: 'Premium',
335        common_cities: null,
336        company_types: null,
337        company_keywords: null,
338        key_page_names: null,
339      });
340      insertCountry(testDb, {
341        country_code: 'DE',
342        country_name: 'Germany',
343        price_usd: 24700,
344        pricing_tier: 'Standard',
345        common_cities: null,
346        company_types: null,
347        company_keywords: null,
348        key_page_names: null,
349      });
350      insertCountry(testDb, {
351        country_code: 'IN',
352        country_name: 'India',
353        price_usd: 9700,
354        pricing_tier: 'Value',
355        is_active: 0,
356        common_cities: null,
357        company_types: null,
358        company_keywords: null,
359        key_page_names: null,
360      });
361    });
362  
363    test('returns only active countries (excludes inactive India)', async () => {
364      const all = await getAllCountries();
365      assert.equal(all.length, 3);
366      assert.ok(!all.some(c => c.country_code === 'IN'));
367    });
368  
369    test('default order is price_usd DESC', async () => {
370      const all = await getAllCountries();
371      // US(49700) > AU(34700) > DE(24700)
372      assert.equal(all[0].country_code, 'US');
373      assert.equal(all[1].country_code, 'AU');
374      assert.equal(all[2].country_code, 'DE');
375    });
376  
377    test('limit=2 returns only 2 countries', async () => {
378      const all = await getAllCountries({ limit: 2 });
379      assert.equal(all.length, 2);
380    });
381  
382    test('orderBy ASC reverses order', async () => {
383      const all = await getAllCountries({ orderBy: 'price_usd ASC' });
384      assert.equal(all[0].country_code, 'DE'); // lowest price
385      assert.equal(all[2].country_code, 'US'); // highest price
386    });
387  
388    test('priceUsd is converted from cents to dollars', async () => {
389      const all = await getAllCountries();
390      const us = all.find(c => c.country_code === 'US');
391      assert.equal(us.priceUsd, 497);
392    });
393  
394    test('JSON fields are parsed for each country', async () => {
395      const all = await getAllCountries();
396      all.forEach(c => {
397        assert.ok(Array.isArray(c.commonCities));
398        assert.ok(Array.isArray(c.companyTypes));
399        assert.ok(Array.isArray(c.companyKeywords));
400        assert.ok(Array.isArray(c.keyPageNames));
401      });
402    });
403  
404    test('returns empty array on db error', async () => {
405      const saved = testDb.prepare.bind(testDb);
406      testDb.prepare = () => {
407        throw new Error('db error');
408      };
409      try {
410        assert.deepEqual(await getAllCountries(), []);
411      } finally {
412        testDb.prepare = saved;
413      }
414    });
415  });
416  
417  // ── getCountriesByTier ──────────────────────────────────────────────────────
418  
419  describe('getCountriesByTier - supplement', () => {
420    beforeEach(() => {
421      testDb.exec('DELETE FROM countries');
422      insertCountry(testDb, {
423        country_code: 'AU',
424        country_name: 'Australia',
425        pricing_tier: 'Premium',
426        price_usd: 34700,
427        common_cities: null,
428        company_types: null,
429        company_keywords: null,
430        key_page_names: null,
431      });
432      insertCountry(testDb, {
433        country_code: 'US',
434        country_name: 'United States',
435        pricing_tier: 'Premium',
436        price_usd: 49700,
437        common_cities: null,
438        company_types: null,
439        company_keywords: null,
440        key_page_names: null,
441      });
442      insertCountry(testDb, {
443        country_code: 'DE',
444        country_name: 'Germany',
445        pricing_tier: 'Standard',
446        price_usd: 24700,
447        common_cities: null,
448        company_types: null,
449        company_keywords: null,
450        key_page_names: null,
451      });
452      insertCountry(testDb, {
453        country_code: 'IN',
454        country_name: 'India',
455        pricing_tier: 'Value',
456        price_usd: 9700,
457        common_cities: null,
458        company_types: null,
459        company_keywords: null,
460        key_page_names: null,
461      });
462    });
463  
464    test('returns both Premium countries ordered by price DESC', async () => {
465      const premium = await getCountriesByTier('Premium');
466      assert.equal(premium.length, 2);
467      assert.equal(premium[0].country_code, 'US'); // 497 > 347
468      assert.equal(premium[1].country_code, 'AU');
469    });
470  
471    test('returns single Standard country', async () => {
472      const std = await getCountriesByTier('Standard');
473      assert.equal(std.length, 1);
474      assert.equal(std[0].country_code, 'DE');
475    });
476  
477    test('returns single Value country', async () => {
478      const val = await getCountriesByTier('Value');
479      assert.equal(val.length, 1);
480      assert.equal(val[0].priceUsd, 97);
481    });
482  
483    test('returns empty array for non-existent tier', async () => {
484      assert.deepEqual(await getCountriesByTier('NonExistent'), []);
485    });
486  
487    test('priceUsd is converted from cents to dollars', async () => {
488      const premium = await getCountriesByTier('Premium');
489      assert.equal(premium.find(c => c.country_code === 'AU').priceUsd, 347);
490    });
491  
492    test('returns empty array on db error', async () => {
493      const saved = testDb.prepare.bind(testDb);
494      testDb.prepare = () => {
495        throw new Error('db error');
496      };
497      try {
498        assert.deepEqual(await getCountriesByTier('Premium'), []);
499      } finally {
500        testDb.prepare = saved;
501      }
502    });
503  });
504  
505  // ── getPricingSummary ───────────────────────────────────────────────────────
506  
507  describe('getPricingSummary - supplement', () => {
508    beforeEach(() => {
509      testDb.exec('DELETE FROM countries');
510      insertCountry(testDb, {
511        country_code: 'AU',
512        price_usd: 30000,
513        pricing_tier: 'Premium',
514        is_price_sensitive: 0,
515        requires_gdpr_check: 0,
516        common_cities: null,
517        company_types: null,
518        company_keywords: null,
519        key_page_names: null,
520      });
521      insertCountry(testDb, {
522        country_code: 'DE',
523        country_name: 'Germany',
524        price_usd: 20000,
525        pricing_tier: 'Standard',
526        is_price_sensitive: 0,
527        requires_gdpr_check: 1,
528        common_cities: null,
529        company_types: null,
530        company_keywords: null,
531        key_page_names: null,
532      });
533      insertCountry(testDb, {
534        country_code: 'IN',
535        country_name: 'India',
536        price_usd: 10000,
537        pricing_tier: 'Value',
538        is_price_sensitive: 1,
539        requires_gdpr_check: 0,
540        common_cities: null,
541        company_types: null,
542        company_keywords: null,
543        key_page_names: null,
544      });
545    });
546  
547    test('totalCountries is 3', async () => {
548      assert.equal((await getPricingSummary()).totalCountries, 3);
549    });
550  
551    test('minPrice is correct in dollars', async () => {
552      assert.equal((await getPricingSummary()).minPrice, 100);
553    });
554  
555    test('maxPrice is correct in dollars', async () => {
556      assert.equal((await getPricingSummary()).maxPrice, 300);
557    });
558  
559    test('avgPrice is rounded to 2 decimal places', async () => {
560      // avg of 30000, 20000, 10000 = 20000 cents = 200 dollars
561      assert.equal((await getPricingSummary()).avgPrice, 200);
562    });
563  
564    test('tierCount is 3', async () => {
565      assert.equal((await getPricingSummary()).tierCount, 3);
566    });
567  
568    test('gdprCountries is 1 (only DE)', async () => {
569      assert.equal((await getPricingSummary()).gdprCountries, 1);
570    });
571  
572    test('priceSensitiveCountries is 1 (only IN)', async () => {
573      assert.equal((await getPricingSummary()).priceSensitiveCountries, 1);
574    });
575  
576    test('tierBreakdown is an array of objects with tier, count, avgPrice', async () => {
577      const summary = await getPricingSummary();
578      assert.ok(Array.isArray(summary.tierBreakdown));
579      summary.tierBreakdown.forEach(t => {
580        assert.ok(typeof t.tier === 'string');
581        assert.ok(typeof t.count === 'number');
582        assert.ok(typeof t.avgPrice === 'number');
583      });
584    });
585  
586    test('tierBreakdown contains all three tiers', async () => {
587      const tiers = (await getPricingSummary()).tierBreakdown.map(t => t.tier);
588      assert.ok(tiers.includes('Premium'));
589      assert.ok(tiers.includes('Standard'));
590      assert.ok(tiers.includes('Value'));
591    });
592  
593    test('returns null on db error', async () => {
594      const saved = testDb.prepare.bind(testDb);
595      testDb.prepare = () => {
596        throw new Error('db error');
597      };
598      try {
599        assert.ok((await getPricingSummary()) == null);
600      } finally {
601        testDb.prepare = saved;
602      }
603    });
604  });
605  
606  // ── overridePrice ───────────────────────────────────────────────────────────
607  
608  describe('overridePrice - supplement', () => {
609    beforeEach(() => {
610      testDb.exec('DELETE FROM countries');
611      insertCountry(testDb);
612    });
613  
614    test('successfully updates price and sets override_reason', async () => {
615      const ok = await overridePrice('AU', 500, 'Test override');
616      assert.equal(ok, true);
617  
618      const row = testDb
619        .prepare(
620          'SELECT price_usd, price_overridden, override_reason FROM countries WHERE country_code = ?'
621        )
622        .get('AU');
623      assert.equal(row.price_usd, 50000);
624      assert.equal(row.price_overridden, 1);
625      assert.equal(row.override_reason, 'Test override');
626    });
627  
628    test('rounds decimal dollar to nearest cent', async () => {
629      await overridePrice('AU', 4.999, 'Decimal test');
630      const row = testDb.prepare('SELECT price_usd FROM countries WHERE country_code = ?').get('AU');
631      assert.equal(row.price_usd, 500); // Math.round(4.999 * 100) = 500
632    });
633  
634    test('handles zero price override', async () => {
635      const ok = await overridePrice('AU', 0, 'Free tier');
636      assert.equal(ok, true);
637      const row = testDb.prepare('SELECT price_usd FROM countries WHERE country_code = ?').get('AU');
638      assert.equal(row.price_usd, 0);
639    });
640  
641    test('returns false for unknown country code', async () => {
642      assert.equal(await overridePrice('ZZ', 100, 'Test'), false);
643    });
644  
645    test('returns false for inactive country', async () => {
646      insertCountry(testDb, {
647        country_code: 'FR',
648        country_name: 'France',
649        is_active: 0,
650        common_cities: null,
651        company_types: null,
652        company_keywords: null,
653        key_page_names: null,
654      });
655      assert.equal(await overridePrice('FR', 200, 'Test'), false);
656    });
657  
658    test('is case-insensitive for country code', async () => {
659      assert.equal(await overridePrice('au', 300, 'lowercase'), true);
660    });
661  
662    test('returns false on db error', async () => {
663      const saved = testDb.prepare.bind(testDb);
664      testDb.prepare = () => {
665        throw new Error('db error');
666      };
667      try {
668        assert.equal(await overridePrice('AU', 100, 'Test'), false);
669      } finally {
670        testDb.prepare = saved;
671      }
672    });
673  });
674  
675  // ── getAcceptLanguage ───────────────────────────────────────────────────────
676  
677  describe('getAcceptLanguage - supplement', () => {
678    beforeEach(() => {
679      testDb.exec('DELETE FROM countries');
680      insertCountry(testDb);
681    });
682  
683    test('returns accept_language for AU', async () => {
684      assert.equal(await getAcceptLanguage('AU'), 'en-AU');
685    });
686  
687    test('returns null for unknown country', async () => {
688      assert.ok((await getAcceptLanguage('ZZ')) == null);
689    });
690  
691    test('returns null when accept_language field is null', async () => {
692      insertCountry(testDb, {
693        country_code: 'TH',
694        country_name: 'Thailand',
695        accept_language: null,
696        common_cities: null,
697        company_types: null,
698        company_keywords: null,
699        key_page_names: null,
700      });
701      assert.ok((await getAcceptLanguage('TH')) == null);
702    });
703  
704    test('works for mixed case country code', async () => {
705      const lang = await getAcceptLanguage('au');
706      assert.equal(lang, 'en-AU');
707    });
708  });
709  
710  // ── getGoogleDomain ─────────────────────────────────────────────────────────
711  
712  describe('getGoogleDomain - supplement', () => {
713    beforeEach(() => {
714      testDb.exec('DELETE FROM countries');
715      insertCountry(testDb);
716    });
717  
718    test('returns google_domain for AU', async () => {
719      assert.equal(await getGoogleDomain('AU'), 'google.com.au');
720    });
721  
722    test('returns null for unknown country', async () => {
723      assert.ok((await getGoogleDomain('ZZ')) == null);
724    });
725  
726    test('returns null when google_domain is null', async () => {
727      insertCountry(testDb, {
728        country_code: 'KP',
729        country_name: 'North Korea',
730        google_domain: null,
731        common_cities: null,
732        company_types: null,
733        company_keywords: null,
734        key_page_names: null,
735      });
736      assert.ok((await getGoogleDomain('KP')) == null);
737    });
738  });
739  
740  // ── requiresGDPR ────────────────────────────────────────────────────────────
741  
742  describe('requiresGDPR - supplement', () => {
743    beforeEach(() => {
744      testDb.exec('DELETE FROM countries');
745      insertCountry(testDb, { requires_gdpr_check: 0 });
746      insertCountry(testDb, {
747        country_code: 'DE',
748        country_name: 'Germany',
749        requires_gdpr_check: 1,
750        common_cities: null,
751        company_types: null,
752        company_keywords: null,
753        key_page_names: null,
754      });
755      insertCountry(testDb, {
756        country_code: 'FR',
757        country_name: 'France',
758        requires_gdpr_check: 1,
759        common_cities: null,
760        company_types: null,
761        company_keywords: null,
762        key_page_names: null,
763      });
764    });
765  
766    test('AU does not require GDPR', async () => {
767      assert.equal(await requiresGDPR('AU'), false);
768    });
769  
770    test('DE requires GDPR', async () => {
771      assert.equal(await requiresGDPR('DE'), true);
772    });
773  
774    test('FR requires GDPR', async () => {
775      assert.equal(await requiresGDPR('FR'), true);
776    });
777  
778    test('returns false for unknown country (country is null)', async () => {
779      assert.equal(await requiresGDPR('ZZ'), false);
780    });
781  
782    test('case-insensitive lookup', async () => {
783      assert.equal(await requiresGDPR('de'), true);
784      assert.equal(await requiresGDPR('au'), false);
785    });
786  });