296 lines
9.0 KiB
Dart
296 lines
9.0 KiB
Dart
import 'dart:io';
|
|
import 'package:flutter_test/flutter_test.dart';
|
|
import 'package:motorcycle_dash/services/motorcycle_image_service.dart';
|
|
|
|
void main() {
|
|
TestWidgetsFlutterBinding.ensureInitialized();
|
|
|
|
group('Motorcycle Image Selection & Hierarchy Audit', () {
|
|
late MotorcycleImageService service;
|
|
|
|
setUp(() {
|
|
MotorcycleImageService.resetRegistry();
|
|
service = MotorcycleImageService.instance;
|
|
});
|
|
|
|
tearDown(() {
|
|
MotorcycleImageService.resetRegistry();
|
|
});
|
|
|
|
test('1. 2001 Yamaha YZF-R6 returns verified authentic photograph', () {
|
|
final ref = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 2001,
|
|
);
|
|
expect(ref.isPhoto, isTrue);
|
|
expect(ref.hasImage, isTrue);
|
|
expect(
|
|
ref.assetPath,
|
|
equals('assets/images/motorcycles/yamaha_yzf_r6_2001.jpg'),
|
|
);
|
|
expect(ref.caption, contains('2001 Yamaha YZF-R6'));
|
|
expect(ref.attribution, contains('James McCauley'));
|
|
expect(ref.attribution, contains('CC BY 2.0'));
|
|
expect(
|
|
service.hasPhotographicAsset(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 2001,
|
|
),
|
|
isTrue,
|
|
);
|
|
});
|
|
|
|
test('2. 1st Generation Yamaha YZF-R6 aliases resolve correctly', () {
|
|
final r6Alias = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'R6',
|
|
year: 2001,
|
|
);
|
|
expect(r6Alias.isPhoto, isTrue);
|
|
expect(
|
|
r6Alias.assetPath,
|
|
equals('assets/images/motorcycles/yamaha_yzf_r6_2001.jpg'),
|
|
);
|
|
|
|
final spaceAlias = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'YZF R6',
|
|
year: 2001,
|
|
);
|
|
expect(spaceAlias.isPhoto, isTrue);
|
|
|
|
final noSpaceAlias = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'YZFR6',
|
|
year: 2000,
|
|
);
|
|
expect(noSpaceAlias.isPhoto, isTrue);
|
|
});
|
|
|
|
test('3. Model-generation year matching works for 1999-2002 5EB', () {
|
|
final gen1999 = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 1999,
|
|
);
|
|
expect(gen1999.isPhoto, isTrue);
|
|
|
|
final gen2002 = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 2002,
|
|
);
|
|
expect(gen2002.isPhoto, isTrue);
|
|
|
|
final gen2008 = service.getReferenceImage(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 2008,
|
|
);
|
|
expect(gen2008.isPhoto, isFalse);
|
|
expect(gen2008.assetPath, isNull);
|
|
expect(gen2008.caption, equals('2008 Yamaha YZF-R6'));
|
|
expect(gen2008.attribution, equals('Technical Schematic'));
|
|
});
|
|
|
|
test(
|
|
'4. Motorcycle with no bundled photograph returns graceful technical schematic',
|
|
() {
|
|
final ref = service.getReferenceImage(
|
|
make: 'Honda',
|
|
model: 'CBR600RR',
|
|
year: 2018,
|
|
);
|
|
expect(ref.isPhoto, isFalse);
|
|
expect(ref.hasImage, isFalse);
|
|
expect(ref.assetPath, isNull);
|
|
expect(ref.caption, equals('2018 Honda CBR600RR'));
|
|
expect(ref.attribution, equals('Technical Schematic'));
|
|
expect(
|
|
service.hasPhotographicAsset(
|
|
make: 'Honda',
|
|
model: 'CBR600RR',
|
|
year: 2018,
|
|
),
|
|
isFalse,
|
|
);
|
|
},
|
|
);
|
|
|
|
test('5. Unknown make and model returns generic technical fallback', () {
|
|
final nullRef = service.getReferenceImage(
|
|
make: null,
|
|
model: null,
|
|
year: null,
|
|
);
|
|
expect(nullRef.isPhoto, isFalse);
|
|
expect(nullRef.assetPath, isNull);
|
|
expect(nullRef.caption, equals('Motorcycle Technical Reference'));
|
|
|
|
final emptyRef = service.getReferenceImage(
|
|
make: '',
|
|
model: '',
|
|
year: 2020,
|
|
);
|
|
expect(emptyRef.isPhoto, isFalse);
|
|
expect(emptyRef.assetPath, isNull);
|
|
|
|
final customRef = service.getReferenceImage(
|
|
make: 'Custom',
|
|
model: 'Cafe Racer',
|
|
year: 1982,
|
|
);
|
|
expect(customRef.isPhoto, isFalse);
|
|
expect(customRef.assetPath, isNull);
|
|
expect(customRef.caption, equals('1982 Custom Cafe Racer'));
|
|
expect(customRef.attribution, equals('Technical Schematic'));
|
|
});
|
|
|
|
test(
|
|
'6. Yamaha R6 photograph is NEVER returned for an unrelated motorcycle',
|
|
() {
|
|
final testCases = [
|
|
{'make': 'Honda', 'model': 'CBR600RR', 'year': 2001},
|
|
{'make': 'Honda', 'model': 'CBR1000RR-R', 'year': 2024},
|
|
{'make': 'Suzuki', 'model': 'GSX-R600', 'year': 2001},
|
|
{'make': 'Suzuki', 'model': 'Hayabusa GSX1300R', 'year': 2022},
|
|
{'make': 'Kawasaki', 'model': 'Ninja ZX-6R', 'year': 2001},
|
|
{'make': 'Kawasaki', 'model': 'Ninja H2', 'year': 2023},
|
|
{'make': 'Ducati', 'model': 'Panigale V4 S', 'year': 2023},
|
|
{'make': 'Ducati', 'model': 'Monster 821', 'year': 2019},
|
|
{'make': 'BMW', 'model': 'S1000RR', 'year': 2022},
|
|
{'make': 'BMW', 'model': 'R1250GS Adventure', 'year': 2021},
|
|
{'make': 'KTM', 'model': '390 Duke', 'year': 2020},
|
|
{'make': 'KTM', 'model': '1290 Super Duke R', 'year': 2022},
|
|
{'make': 'Triumph', 'model': 'Daytona 675', 'year': 2012},
|
|
{'make': 'Triumph', 'model': 'Street Triple 765 RS', 'year': 2023},
|
|
{'make': 'Harley-Davidson', 'model': 'Sportster S', 'year': 2022},
|
|
{'make': 'Aprilia', 'model': 'RSV4 1100 Factory', 'year': 2023},
|
|
];
|
|
|
|
for (final tc in testCases) {
|
|
final make = tc['make'] as String;
|
|
final model = tc['model'] as String;
|
|
final year = tc['year'] as int;
|
|
final ref = service.getReferenceImage(
|
|
make: make,
|
|
model: model,
|
|
year: year,
|
|
);
|
|
|
|
expect(
|
|
ref.assetPath,
|
|
isNot(equals('assets/images/motorcycles/yamaha_yzf_r6_2001.jpg')),
|
|
reason: 'Failed isolation: $make $model returned R6 asset!',
|
|
);
|
|
expect(
|
|
ref.isPhoto,
|
|
isFalse,
|
|
reason: 'Expected schematic fallback for unbundled $make $model',
|
|
);
|
|
expect(ref.caption, equals('$year $make $model'));
|
|
expect(ref.attribution, equals('Technical Schematic'));
|
|
}
|
|
},
|
|
);
|
|
|
|
test(
|
|
'7. Architecture is genuinely extensible via dynamic descriptor registration',
|
|
() {
|
|
final beforeReg = service.getReferenceImage(
|
|
make: 'Ducati',
|
|
model: 'Panigale V4',
|
|
year: 2024,
|
|
);
|
|
expect(beforeReg.isPhoto, isFalse);
|
|
|
|
MotorcycleImageService.registerDescriptor(
|
|
const MotorcycleImageDescriptor(
|
|
make: 'Ducati',
|
|
model: 'Panigale V4',
|
|
minYear: 2022,
|
|
maxYear: 2025,
|
|
modelAliases: ['PanigaleV4', 'Panigale V4 S'],
|
|
assetPath: 'assets/images/motorcycles/ducati_panigale_v4.png',
|
|
caption: 'Ducati Panigale V4 (Desmosedici Stradale)',
|
|
attribution: 'Factory Superbike Reference',
|
|
isPhoto: true,
|
|
),
|
|
);
|
|
|
|
final afterReg = service.getReferenceImage(
|
|
make: 'Ducati',
|
|
model: 'Panigale V4',
|
|
year: 2024,
|
|
);
|
|
expect(afterReg.isPhoto, isTrue);
|
|
expect(
|
|
afterReg.assetPath,
|
|
equals('assets/images/motorcycles/ducati_panigale_v4.png'),
|
|
);
|
|
expect(afterReg.caption, contains('Ducati Panigale V4'));
|
|
|
|
final aliasReg = service.getReferenceImage(
|
|
make: 'Ducati',
|
|
model: 'Panigale V4 S',
|
|
year: 2023,
|
|
);
|
|
expect(aliasReg.isPhoto, isTrue);
|
|
},
|
|
);
|
|
|
|
test('8. Bundled photographic assets physically exist on disk', () {
|
|
final bundledAssets = MotorcycleImageService.bundledPhotographicAssets;
|
|
expect(bundledAssets, isNotEmpty);
|
|
|
|
for (final assetPath in bundledAssets) {
|
|
final file = File(assetPath);
|
|
expect(
|
|
file.existsSync(),
|
|
isTrue,
|
|
reason: 'Bundled asset $assetPath does not exist on disk!',
|
|
);
|
|
expect(
|
|
file.lengthSync(),
|
|
greaterThan(100000),
|
|
reason:
|
|
'Bundled photographic asset $assetPath is an undersized render or corrupt',
|
|
);
|
|
}
|
|
});
|
|
|
|
test('9. getCachedOrCuratedImage synchronously provides curated photo', () {
|
|
final img = service.getCachedOrCuratedImage(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 2001,
|
|
);
|
|
expect(img, isNotNull);
|
|
expect(img!.isPhoto, isTrue);
|
|
expect(
|
|
img.assetPath,
|
|
equals('assets/images/motorcycles/yamaha_yzf_r6_2001.jpg'),
|
|
);
|
|
});
|
|
|
|
test(
|
|
'10. resolve returns curated photo directly without network',
|
|
() async {
|
|
final img = await service.resolve(
|
|
make: 'Yamaha',
|
|
model: 'YZF-R6',
|
|
year: 2001,
|
|
);
|
|
expect(img, isNotNull);
|
|
expect(img!.isPhoto, isTrue);
|
|
expect(
|
|
img.assetPath,
|
|
equals('assets/images/motorcycles/yamaha_yzf_r6_2001.jpg'),
|
|
);
|
|
},
|
|
);
|
|
});
|
|
}
|