/ tests / config / countries-gdp.test.js
countries-gdp.test.js
  1  /**
  2   * Tests for src/config/countries-gdp.js
  3   *
  4   * Covers all exported functions:
  5   * - COUNTRIES_BY_GDP: data shape validation
  6   * - getTopCountriesByGDP: default limit, custom limit, zero/edge cases
  7   * - getBudgetOptimizedCountries: returns array of strings
  8   * - getCountryGDP: found, not found
  9   * - shouldProcessRegions: top-18 included, outside top-18
 10   */
 11  
 12  import { test, describe } from 'node:test';
 13  import assert from 'node:assert/strict';
 14  import {
 15    COUNTRIES_BY_GDP,
 16    getTopCountriesByGDP,
 17    getBudgetOptimizedCountries,
 18    getCountryGDP,
 19    shouldProcessRegions,
 20  } from '../../src/config/countries-gdp.js';
 21  
 22  describe('countries-gdp', () => {
 23    describe('COUNTRIES_BY_GDP', () => {
 24      test('is a non-empty array', () => {
 25        assert.ok(Array.isArray(COUNTRIES_BY_GDP));
 26        assert.ok(COUNTRIES_BY_GDP.length > 0);
 27      });
 28  
 29      test('each entry has code, name, gdp, gdpFormatted', () => {
 30        for (const c of COUNTRIES_BY_GDP) {
 31          assert.ok(typeof c.code === 'string', `code should be string in ${c.code}`);
 32          assert.ok(typeof c.name === 'string', `name should be string in ${c.code}`);
 33          assert.ok(typeof c.gdp === 'number', `gdp should be number in ${c.code}`);
 34          assert.ok(typeof c.gdpFormatted === 'string', `gdpFormatted should be string in ${c.code}`);
 35        }
 36      });
 37  
 38      test('US is the first entry (largest GDP)', () => {
 39        assert.equal(COUNTRIES_BY_GDP[0].code, 'US');
 40      });
 41    });
 42  
 43    describe('getTopCountriesByGDP', () => {
 44      test('default limit returns 25 entries', () => {
 45        const result = getTopCountriesByGDP();
 46        assert.ok(Array.isArray(result));
 47        assert.ok(result.length <= 25);
 48      });
 49  
 50      test('custom limit returns correct count', () => {
 51        const result = getTopCountriesByGDP(5);
 52        assert.equal(result.length, 5);
 53      });
 54  
 55      test('returns country codes as strings', () => {
 56        const result = getTopCountriesByGDP(3);
 57        for (const code of result) {
 58          assert.ok(typeof code === 'string');
 59          assert.equal(code, code.toUpperCase());
 60        }
 61      });
 62  
 63      test('first result is US', () => {
 64        const result = getTopCountriesByGDP(1);
 65        assert.equal(result[0], 'US');
 66      });
 67  
 68      test('limit=0 returns empty array', () => {
 69        const result = getTopCountriesByGDP(0);
 70        assert.equal(result.length, 0);
 71      });
 72  
 73      test('limit larger than available countries returns all', () => {
 74        const result = getTopCountriesByGDP(1000);
 75        assert.equal(result.length, COUNTRIES_BY_GDP.length);
 76      });
 77    });
 78  
 79    describe('getBudgetOptimizedCountries', () => {
 80      test('returns an object with businesses and regions arrays', () => {
 81        const result = getBudgetOptimizedCountries();
 82        assert.ok(result !== null && typeof result === 'object');
 83        assert.ok(Array.isArray(result.businesses), 'businesses should be an array');
 84        assert.ok(Array.isArray(result.regions), 'regions should be an array');
 85      });
 86  
 87      test('businesses contains all country codes as strings', () => {
 88        const result = getBudgetOptimizedCountries();
 89        assert.ok(result.businesses.length > 0);
 90        for (const code of result.businesses) {
 91          assert.ok(typeof code === 'string');
 92        }
 93      });
 94  
 95      test('regions is a subset of businesses (top 18)', () => {
 96        const result = getBudgetOptimizedCountries();
 97        assert.ok(result.regions.length <= result.businesses.length);
 98        assert.equal(result.regions.length, 18);
 99      });
100    });
101  
102    describe('getCountryGDP', () => {
103      test('returns country data for known code', () => {
104        const result = getCountryGDP('AU');
105        assert.ok(result !== null);
106        assert.equal(result.code, 'AU');
107        assert.equal(result.name, 'Australia');
108        assert.ok(typeof result.gdp === 'number');
109      });
110  
111      test('case-insensitive lookup', () => {
112        const result = getCountryGDP('au');
113        assert.ok(result !== null);
114        assert.equal(result.code, 'AU');
115      });
116  
117      test('returns null for unknown country code', () => {
118        const result = getCountryGDP('XX');
119        assert.strictEqual(result, null);
120      });
121  
122      test('returns null for empty-ish code that does not exist', () => {
123        const result = getCountryGDP('ZZ');
124        assert.strictEqual(result, null);
125      });
126    });
127  
128    describe('shouldProcessRegions', () => {
129      test('returns true for top-18 GDP country (US)', () => {
130        assert.equal(shouldProcessRegions('US'), true);
131      });
132  
133      test('returns true for AU (within top 18)', () => {
134        // AU is in top 18 by GDP
135        assert.equal(shouldProcessRegions('AU'), true);
136      });
137  
138      test('is case-insensitive', () => {
139        assert.equal(shouldProcessRegions('us'), true);
140      });
141  
142      test('returns false for country outside top 18', () => {
143        // Use a country code clearly outside the top 18
144        const top18 = getTopCountriesByGDP(18);
145        // Find a country in COUNTRIES_BY_GDP but not in top18
146        const outside = COUNTRIES_BY_GDP.find(c => !top18.includes(c.code));
147        if (outside) {
148          assert.equal(shouldProcessRegions(outside.code), false);
149        }
150      });
151  
152      test('returns false for unknown country code', () => {
153        assert.equal(shouldProcessRegions('XX'), false);
154      });
155    });
156  });