Files
boc/iom/core/test_goid.py
T
Bernt bae705aa97 ARCHITECTURE: NFC roadmap, edge AI, audit logging
- Add NFC ePassport roadmap (ICAO 9303, eIDAS)
- Add TensorFlow.js edge face detection (BlazeFace)
- Add structured audit logger (GDPR-compliant)
- Risk scoring support

Part of KYC Apple Native UX v1.1.0
2026-06-29 16:24:48 +00:00

193 lines
6.9 KiB
Python

"""
Unit tests for GOID Generator
"""
import unittest
import sys
import os
# Add parent directory to path
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from goid_generator import GOIDGenerator, generate_goid, validate_goid, parse_goid
class TestGOIDGenerator(unittest.TestCase):
"""Test cases for GOID generation and validation"""
def setUp(self):
"""Set up test fixtures"""
self.gen = GOIDGenerator()
def test_generate_basic(self):
"""Test basic GOID generation"""
goid = self.gen.generate('BYG', 'FAC', 'WIN', 'GLA')
self.assertTrue(goid.startswith('BYG-FAC-WIN-GLA-'))
self.assertEqual(len(goid.split('-')), 5)
def test_generate_sequence(self):
"""Test sequence incrementing"""
goid1 = self.gen.generate('BYG', 'FAC', 'WIN', 'GLA')
goid2 = self.gen.generate('BYG', 'FAC', 'WIN', 'GLA')
seq1 = int(goid1.split('-')[-1])
seq2 = int(goid2.split('-')[-1])
self.assertEqual(seq2, seq1 + 1)
def test_generate_with_location(self):
"""Test GOID generation with location hash"""
goid = self.gen.generate('BYG', 'FAC', 'WIN', 'GLA', location_hash='59.3293,18.0686')
parts = goid.split('-')
self.assertEqual(len(parts), 6)
self.assertEqual(len(parts[5]), 4)
def test_validate_valid(self):
"""Test validation of valid GOIDs"""
valid_goids = [
'BYG-FAC-WIN-GLA-0001',
'BYG-FAC-WIN-GLA-9999',
'ENE-EVC-CHA-LED-0001-ABCD',
'TRN-BRG-ABT-CON-0001'
]
for goid in valid_goids:
is_valid, error = self.gen.validate(goid)
self.assertTrue(is_valid, f"Expected {goid} to be valid, got error: {error}")
def test_validate_invalid(self):
"""Test validation of invalid GOIDs"""
invalid_goids = [
('', "empty"),
('BYG', "too few parts"),
('BYG-FAC-WIN-GLA', "missing sequence"),
('BYG-FAC-WIN-GLA-0', "sequence too low"),
('byg-fac-win-gla-0001', "lowercase"),
('BYG-FAC-WIN-GLA-ABC', "non-numeric sequence"),
('BYG-FAC-WIN-GLA-0001-ABCDE', "hash too long"),
('BYG-FAC-WIN-GLA-0001-ABCD-EXTRA', "too many parts"),
]
for goid, description in invalid_goids:
is_valid, error = self.gen.validate(goid)
self.assertFalse(is_valid, f"Expected {description} ({goid}) to be invalid")
def test_parse_valid(self):
"""Test parsing valid GOID"""
goid = 'BYG-FAC-WIN-GLA-0001'
parsed = self.gen.parse(goid)
self.assertEqual(parsed['domain'], 'BYG')
self.assertEqual(parsed['system'], 'FAC')
self.assertEqual(parsed['subsystem'], 'WIN')
self.assertEqual(parsed['obj_type'], 'GLA')
self.assertEqual(parsed['sequence'], 1)
self.assertIsNone(parsed['location_hash'])
def test_parse_with_location(self):
"""Test parsing GOID with location hash"""
goid = 'BYG-FAC-WIN-GLA-0001-ABCD'
parsed = self.gen.parse(goid)
self.assertEqual(parsed['location_hash'], 'ABCD')
def test_parse_invalid(self):
"""Test parsing invalid GOID raises error"""
with self.assertRaises(ValueError):
self.gen.parse('INVALID')
def test_validate_codes(self):
"""Test that invalid codes raise errors"""
with self.assertRaises(ValueError):
self.gen.generate('XXX', 'FAC', 'WIN', 'GLA')
with self.assertRaises(ValueError):
self.gen.generate('BYG', 'XXX', 'WIN', 'GLA')
def test_list_domains(self):
"""Test listing domains"""
domains = self.gen.list_domains()
self.assertGreater(len(domains), 0)
domain_codes = [d['code'] for d in domains]
self.assertIn('BYG', domain_codes)
self.assertIn('ENE', domain_codes)
def test_list_systems(self):
"""Test listing systems"""
systems = self.gen.list_systems('BYG')
self.assertGreater(len(systems), 0)
system_codes = [s['code'] for s in systems]
self.assertIn('FAC', system_codes)
def test_list_objects(self):
"""Test listing objects"""
objects = self.gen.list_objects('BYG', 'FAC')
self.assertGreater(len(objects), 0)
object_codes = [o['code'] for o in objects]
self.assertIn('WIN', object_codes)
def test_convenience_functions(self):
"""Test convenience functions"""
goid = generate_goid('BYG', 'FAC', 'WIN', 'GLA')
self.assertTrue(goid.startswith('BYG-FAC-WIN-GLA-'))
is_valid, error = validate_goid(goid)
self.assertTrue(is_valid)
parsed = parse_goid(goid)
self.assertEqual(parsed['domain'], 'BYG')
class TestTaxonomyValidation(unittest.TestCase):
"""Test taxonomy-specific validation"""
def setUp(self):
self.gen = GOIDGenerator()
def test_all_domains(self):
"""Test that all domains can generate GOIDs"""
domains = self.gen.list_domains()
for domain in domains:
systems = self.gen.list_systems(domain['code'])
for system in systems:
objects = self.gen.list_objects(domain['code'], system['code'])
for obj in objects:
# Generate GOID for first component or object itself
obj_type = obj['components'][0] if obj['components'] else obj['code']
goid = self.gen.generate(domain['code'], system['code'], obj['code'], obj_type)
is_valid, error = self.gen.validate(goid)
self.assertTrue(is_valid, f"Failed for {domain['code']}-{system['code']}-{obj['code']}: {error}")
def test_component_types(self):
"""Test generating GOIDs for component types"""
# Window glass
goid = self.gen.generate('BYG', 'FAC', 'WIN', 'GLA')
self.assertTrue(goid.startswith('BYG-FAC-WIN-GLA-'))
# Window frame
goid = self.gen.generate('BYG', 'FAC', 'WIN', 'FRM')
self.assertTrue(goid.startswith('BYG-FAC-WIN-FRM-'))
def test_known_examples(self):
"""Test known examples from spec"""
examples = [
('BYG', 'FAC', 'WIN', 'GLA', 'BYG-FAC-WIN-GLA-0001'),
('ENE', 'EVC', 'CHA', 'FND', 'ENE-EVC-CHA-FND-0001'),
('TRN', 'BRG', 'ABT', 'FND', 'TRN-BRG-ABT-FND-0001'),
]
for domain, system, subsystem, obj_type, expected_prefix in examples:
goid = self.gen.generate(domain, system, subsystem, obj_type)
self.assertTrue(goid.startswith(expected_prefix.rsplit('-', 1)[0]))
if __name__ == '__main__':
# Run with verbose output
unittest.main(verbosity=2)