feat(dfu): add firmware file selection and validation
This commit is contained in:
132
test/service/firmware_file_selection_service_test.dart
Normal file
132
test/service/firmware_file_selection_service_test.dart
Normal file
@ -0,0 +1,132 @@
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:abawo_bt_app/model/firmware_file_selection.dart';
|
||||
import 'package:abawo_bt_app/model/shifter_types.dart';
|
||||
import 'package:abawo_bt_app/service/firmware_file_selection_service.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
void main() {
|
||||
group('FirmwareFileSelectionService', () {
|
||||
test('prepares v1 metadata for selected .bin firmware', () async {
|
||||
final service = FirmwareFileSelectionService(
|
||||
filePicker: _FakeFirmwareFilePicker(
|
||||
selection: FirmwarePickerSelection(
|
||||
fileName: 'firmware.BIN',
|
||||
filePath: '/tmp/firmware.BIN',
|
||||
fileBytes: Uint8List.fromList(<int>[1, 2, 3, 4]),
|
||||
),
|
||||
),
|
||||
sessionIdGenerator: () => 0x1AB,
|
||||
);
|
||||
|
||||
final result = await service.selectAndPrepareDfuV1();
|
||||
expect(result.isSuccess, isTrue);
|
||||
|
||||
final firmware = result.firmware!;
|
||||
expect(firmware.fileName, 'firmware.BIN');
|
||||
expect(firmware.filePath, '/tmp/firmware.BIN');
|
||||
expect(firmware.fileBytes, <int>[1, 2, 3, 4]);
|
||||
expect(firmware.metadata.totalLength, 4);
|
||||
expect(firmware.metadata.crc32, 0xB63CFBCD);
|
||||
expect(firmware.metadata.sessionId, 0xAB);
|
||||
expect(firmware.metadata.flags, universalShifterDfuFlagNone);
|
||||
});
|
||||
|
||||
test('returns canceled result when user dismisses picker', () async {
|
||||
final service = FirmwareFileSelectionService(
|
||||
filePicker: _FakeFirmwareFilePicker(selection: null),
|
||||
);
|
||||
|
||||
final result = await service.selectAndPrepareDfuV1();
|
||||
|
||||
expect(result.isSuccess, isFalse);
|
||||
expect(result.isCanceled, isTrue);
|
||||
expect(result.failure?.reason, FirmwareSelectionFailureReason.canceled);
|
||||
});
|
||||
|
||||
test('rejects unsupported extension', () async {
|
||||
final service = FirmwareFileSelectionService(
|
||||
filePicker: _FakeFirmwareFilePicker(
|
||||
selection: FirmwarePickerSelection(
|
||||
fileName: 'firmware.hex',
|
||||
fileBytes: Uint8List.fromList(<int>[1]),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final result = await service.selectAndPrepareDfuV1();
|
||||
|
||||
expect(result.isSuccess, isFalse);
|
||||
expect(result.failure?.reason,
|
||||
FirmwareSelectionFailureReason.unsupportedExtension);
|
||||
});
|
||||
|
||||
test('rejects empty payload', () async {
|
||||
final service = FirmwareFileSelectionService(
|
||||
filePicker: _FakeFirmwareFilePicker(
|
||||
selection: FirmwarePickerSelection(
|
||||
fileName: 'firmware.bin',
|
||||
fileBytes: Uint8List(0),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
final result = await service.selectAndPrepareDfuV1();
|
||||
|
||||
expect(result.isSuccess, isFalse);
|
||||
expect(result.failure?.reason, FirmwareSelectionFailureReason.emptyFile);
|
||||
});
|
||||
|
||||
test('generates session id per run', () async {
|
||||
var nextSession = 9;
|
||||
final service = FirmwareFileSelectionService(
|
||||
filePicker: _FakeFirmwareFilePicker(
|
||||
selection: FirmwarePickerSelection(
|
||||
fileName: 'firmware.bin',
|
||||
fileBytes: Uint8List.fromList(<int>[10]),
|
||||
),
|
||||
),
|
||||
sessionIdGenerator: () => nextSession++,
|
||||
);
|
||||
|
||||
final first = await service.selectAndPrepareDfuV1();
|
||||
final second = await service.selectAndPrepareDfuV1();
|
||||
|
||||
expect(first.firmware?.metadata.sessionId, 9);
|
||||
expect(second.firmware?.metadata.sessionId, 10);
|
||||
});
|
||||
|
||||
test('maps picker read failure to explicit validation error', () async {
|
||||
final service = FirmwareFileSelectionService(
|
||||
filePicker: _FakeFirmwareFilePicker(
|
||||
selection: null,
|
||||
error: const FormatException('broken pick payload'),
|
||||
),
|
||||
);
|
||||
|
||||
final result = await service.selectAndPrepareDfuV1();
|
||||
|
||||
expect(result.isSuccess, isFalse);
|
||||
expect(result.failure?.reason, FirmwareSelectionFailureReason.readFailed);
|
||||
expect(result.failure?.message, contains('broken pick payload'));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class _FakeFirmwareFilePicker implements FirmwareFilePicker {
|
||||
_FakeFirmwareFilePicker({
|
||||
required this.selection,
|
||||
this.error,
|
||||
});
|
||||
|
||||
final FirmwarePickerSelection? selection;
|
||||
final Object? error;
|
||||
|
||||
@override
|
||||
Future<FirmwarePickerSelection?> pickFirmwareFile() async {
|
||||
if (error != null) {
|
||||
throw error!;
|
||||
}
|
||||
return selection;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user