import importlib.util from pathlib import Path import subprocess import tempfile import unittest def module(name): spec=importlib.util.spec_from_file_location(name,Path(__file__).parents[1]/'tools'/f'{name}.py') m=importlib.util.module_from_spec(spec);spec.loader.exec_module(m);return m inv=module('inventory');verify=module('verify_inventory') class InventoryTests(unittest.TestCase): def test_scan_emits_reference_only_and_skips_sensitive_files(self): with tempfile.TemporaryDirectory() as d: p=Path(d) subprocess.run(['git','init','-q',d],check=True) (p/'values.yaml').write_text('image: https://user:do-not-emit@forgejo.example/coulomb/example:tag?token=also-private\n') (p/'.env').write_text('SECRET=coulomb/private-secret\n') (p/'link').symlink_to(p/'values.yaml') subprocess.run(['git','-C',d,'add','.'],check=True) subprocess.run(['git','-C',d,'-c','user.name=Test','-c','user.email=test@example.invalid','commit','-qm','fixture'],check=True) result=inv.scan(p) self.assertEqual([r['reference'] for r in result['references']],['coulomb/example']) self.assertNotIn('do-not-emit',str(result));self.assertNotIn('also-private',str(result)) self.assertNotIn('private-secret',str(result)) self.assertEqual({e['reason'] for e in result['exclusions']},{'sensitive-or-encrypted','symlink-not-followed'}) self.assertEqual(result,inv.scan(p)) def test_paginated_server_read_does_not_stop_at_first_page(self): original=inv.get try: inv.get=lambda url: [{'id':1}] if 'page=1' in url else [{'id':2}] if 'page=2' in url else [] self.assertEqual(inv.pages('/repos'),[{'id':1},{'id':2}]) inv.get=lambda url:[{'id':1}] with self.assertRaises(RuntimeError):inv.pages('/repos') finally:inv.get=original def test_empty_partial_inventory_cannot_pass(self): result=verify.check({'g1_complete':False,'local_repositories':[]},{'approved':False,'assignments':[]}) self.assertFalse(result['clean']) def test_retained_org_and_stale_moved_path(self): i={'g1_complete':True,'local_repositories':[{'name':'consumer','references':[{'reference':'coulomb/example','categories':['historical-or-planning']}]}]} m={'approved':True,'assignments':[{'repository':'example','proposed_org':'coulomb'}]} self.assertTrue(verify.check(i,m)['clean']) m['assignments'][0]['proposed_org']='railiance' self.assertFalse(verify.check(i,m)['clean']) if __name__=='__main__':unittest.main()