← back to Rentv Adintel

test/types.test.js

100 lines

'use strict';
/**
 * Tests for the shared contract vocabulary (spec §2, §8, §14).
 * Pure functions + frozen constant lists — no DB, no network.
 */

const test = require('node:test');
const assert = require('node:assert');

const {
  RELATIONSHIP_STATUS,
  VERIFIED_STATUSES,
  STATUS_LABELS,
  ADVERTISER_CATEGORIES,
  CONTACT_ROLE_PRIORITY,
  LINKEDIN_BLOCKED_HOSTS,
  normalizeName,
  isVerified,
} = require('../lib/types');

test('normalizeName strips corporate suffixes and articles', () => {
  assert.strictEqual(normalizeName('The Rockefeller Group, Inc.'), 'rockefeller');
});

test('normalizeName is stable across punctuation/casing variants', () => {
  const a = normalizeName('Hanley Investment Group, LLC');
  const b = normalizeName('hanley investment');
  assert.strictEqual(a, b);
  assert.strictEqual(a, 'hanley investment');
});

test('normalizeName handles empty / null input safely', () => {
  assert.strictEqual(normalizeName(''), '');
  assert.strictEqual(normalizeName(null), '');
  assert.strictEqual(normalizeName(undefined), '');
});

test('isVerified is true only for VERIFIED_* relationship statuses', () => {
  assert.strictEqual(isVerified('VERIFIED_ADVERTISER'), true);
  assert.strictEqual(isVerified('VERIFIED_CONFERENCE_SPONSOR'), true);
  assert.strictEqual(isVerified('VERIFIED_EXHIBITOR'), true);
  assert.strictEqual(isVerified('VERIFIED_MEDIA_PARTNER'), true);
  assert.strictEqual(isVerified('VERIFIED_CONTENT_PARTNER'), true);
});

test('isVerified is false for panelist / prospect / research / disqualified', () => {
  assert.strictEqual(isVerified('SPEAKER_OR_PANELIST_ONLY'), false);
  assert.strictEqual(isVerified('PAST_ADVERTISER'), false);
  assert.strictEqual(isVerified('LIKELY_PROSPECT'), false);
  assert.strictEqual(isVerified('RESEARCH_NEEDED'), false);
  assert.strictEqual(isVerified('DISQUALIFIED'), false);
  assert.strictEqual(isVerified('NOT_A_STATUS'), false);
});

test('every VERIFIED_STATUS is a member of RELATIONSHIP_STATUS', () => {
  for (const s of VERIFIED_STATUSES) {
    assert.ok(RELATIONSHIP_STATUS.includes(s), `${s} not in RELATIONSHIP_STATUS`);
  }
});

test('STATUS_LABELS covers every RELATIONSHIP_STATUS', () => {
  for (const s of RELATIONSHIP_STATUS) {
    assert.ok(
      typeof STATUS_LABELS[s] === 'string' && STATUS_LABELS[s].length > 0,
      `missing plain-English label for ${s}`
    );
  }
  // no orphan labels for statuses that don't exist
  for (const k of Object.keys(STATUS_LABELS)) {
    assert.ok(RELATIONSHIP_STATUS.includes(k), `orphan label ${k}`);
  }
});

test('ADVERTISER_CATEGORIES has the full §8 taxonomy', () => {
  // §8 lists 24 controlled categories.
  assert.strictEqual(ADVERTISER_CATEGORIES.length, 24);
  assert.ok(ADVERTISER_CATEGORIES.includes('Brokerage and investment sales'));
  assert.ok(ADVERTISER_CATEGORIES.includes('Other CRE service'));
  // no duplicates
  assert.strictEqual(new Set(ADVERTISER_CATEGORIES).size, ADVERTISER_CATEGORIES.length);
});

test('CONTACT_ROLE_PRIORITY ranks marketing leadership highest (§14)', () => {
  assert.strictEqual(CONTACT_ROLE_PRIORITY[0], 'CHIEF_MARKETING_OFFICER');
  assert.strictEqual(CONTACT_ROLE_PRIORITY.length, 10);
  assert.strictEqual(new Set(CONTACT_ROLE_PRIORITY).size, CONTACT_ROLE_PRIORITY.length);
});

test('LINKEDIN_BLOCKED_HOSTS lists the LinkedIn hosts (§6.4)', () => {
  assert.ok(LINKEDIN_BLOCKED_HOSTS.includes('linkedin.com'));
  assert.ok(LINKEDIN_BLOCKED_HOSTS.includes('www.linkedin.com'));
  assert.ok(LINKEDIN_BLOCKED_HOSTS.includes('lnkd.in'));
});

test('the constant lists are frozen (single source of truth)', () => {
  assert.ok(Object.isFrozen(RELATIONSHIP_STATUS));
  assert.ok(Object.isFrozen(ADVERTISER_CATEGORIES));
  assert.ok(Object.isFrozen(CONTACT_ROLE_PRIORITY));
});