bae705aa97
- 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
193 lines
6.9 KiB
Python
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)
|