import 'package:flutter_test/flutter_test.dart'; import 'package:uto_manager/domain/entities/doctrinal_branch.dart'; import 'package:uto_manager/domain/value_objects/duty_mos.dart'; void main() { group('DutyMos', () { group('constructor validation', () { test('accepts valid known MOS codes', () { expect(() => DutyMos('11B'), returnsNormally); expect(() => DutyMos('68W'), returnsNormally); expect(() => DutyMos('13F'), returnsNormally); expect(() => DutyMos('25H'), returnsNormally); expect(() => DutyMos('17E'), returnsNormally); expect(() => DutyMos('92Y'), returnsNormally); expect(() => DutyMos('12B'), returnsNormally); }); test('normalizes lowercase input to uppercase', () { final mos = DutyMos('11b'); expect(mos.code, equals('11B')); }); test('trims whitespace from input', () { final mos = DutyMos(' 11B '); expect(mos.code, equals('11B')); }); test('throws ArgumentError for invalid format — too short', () { expect(() => DutyMos('1B'), throwsArgumentError); }); test('throws ArgumentError for invalid format — too long', () { expect(() => DutyMos('11BB'), throwsArgumentError); }); test('throws ArgumentError for invalid format — all digits', () { expect(() => DutyMos('111'), throwsArgumentError); }); test('throws ArgumentError for invalid format — all letters', () { expect(() => DutyMos('AAA'), throwsArgumentError); }); test('throws ArgumentError for unknown but validly-formatted MOS', () { expect(() => DutyMos('99Z'), throwsArgumentError); }); test('throws ArgumentError for empty string', () { expect(() => DutyMos(''), throwsArgumentError); }); }); group('unvalidated constructor', () { test('accepts valid format without dictionary check', () { expect(() => DutyMos.unvalidated('99Z'), returnsNormally); }); test('still rejects invalid format', () { expect(() => DutyMos.unvalidated('1B'), throwsArgumentError); }); }); group('isKnown', () { test('returns true for known MOS codes', () { expect(DutyMos.isKnown('11B'), isTrue); expect(DutyMos.isKnown('68W'), isTrue); expect(DutyMos.isKnown('13F'), isTrue); expect(DutyMos.isKnown('25H'), isTrue); expect(DutyMos.isKnown('17E'), isTrue); expect(DutyMos.isKnown('92Y'), isTrue); expect(DutyMos.isKnown('12B'), isTrue); expect(DutyMos.isKnown('91B'), isTrue); expect(DutyMos.isKnown('15W'), isTrue); }); test('returns false for unknown MOS codes', () { expect(DutyMos.isKnown('99Z'), isFalse); expect(DutyMos.isKnown('00A'), isFalse); expect(DutyMos.isKnown('XYZ'), isFalse); }); test('is case-insensitive', () { expect(DutyMos.isKnown('11b'), isTrue); expect(DutyMos.isKnown('68w'), isTrue); }); }); group('codesForBranch', () { test('returns infantry MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.infantry); expect(codes, contains('11B')); expect(codes, contains('11A')); expect(codes, contains('15W')); }); test('returns medical MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.medical); expect(codes, contains('68W')); expect(codes, isNot(contains('11B'))); }); test('returns fires MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.fires); expect(codes, contains('13F')); expect(codes, contains('13D')); expect(codes, isNot(contains('68W'))); }); test('returns signal MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.signal); expect(codes, contains('25H')); expect(codes, contains('25B')); }); test('returns cyberEw MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.cyberEw); expect(codes, contains('17E')); expect(codes, contains('17C')); }); test('returns logistics MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.logistics); expect(codes, contains('92Y')); expect(codes, contains('92A')); expect(codes, contains('91B')); }); test('returns engineer MOS codes', () { final codes = DutyMos.codesForBranch(DoctrinalBranch.engineer); expect(codes, contains('12B')); expect(codes, contains('12A')); }); }); group('equality', () { test('two DutyMos with same code are equal', () { final mos1 = DutyMos('11B'); final mos2 = DutyMos('11B'); expect(mos1, equals(mos2)); }); test('two DutyMos with different codes are not equal', () { final mos1 = DutyMos('11B'); final mos2 = DutyMos('68W'); expect(mos1, isNot(equals(mos2))); }); test('hashCode is consistent with equality', () { final mos1 = DutyMos('11B'); final mos2 = DutyMos('11B'); expect(mos1.hashCode, equals(mos2.hashCode)); }); }); group('toString', () { test('returns the MOS code string', () { expect(DutyMos('11B').toString(), equals('11B')); expect(DutyMos('68W').toString(), equals('68W')); }); }); group('all defined specialties are accepted', () { // Infantry & Maneuver test('accepts all infantry MOS codes', () { for (final code in ['11A', '11B', '11C', '15W', '15A', '15T']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); // Medical test('accepts all medical MOS codes', () { for (final code in ['68W', '68A', '68D', '68J', '68K']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); // Field Artillery test('accepts all fires MOS codes', () { for (final code in ['13A', '13B', '13D', '13F', '13J', '13M']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); // Signal test('accepts all signal MOS codes', () { for (final code in ['25A', '25B', '25H', '25U', '25N']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); // Cyber/EW test('accepts all cyber/EW MOS codes', () { for (final code in ['17A', '17C', '17E', '17S']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); // Logistics test('accepts all logistics MOS codes', () { for (final code in ['91B', '91A', '92A', '92Y', '92F']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); // Engineer test('accepts all engineer MOS codes', () { for (final code in ['12A', '12B', '12C', '12N', '12Z']) { expect( () => DutyMos(code), returnsNormally, reason: '$code should be a valid MOS', ); } }); }); }); }