Files
abawo-bt-app/test/service/dfu_preflight_test.dart

138 lines
4.6 KiB
Dart

import 'package:abawo_bt_app/controller/bluetooth.dart';
import 'package:abawo_bt_app/model/shifter_types.dart';
import 'package:abawo_bt_app/service/shifter_service.dart';
import 'package:anyhow/anyhow.dart';
import 'package:flutter_test/flutter_test.dart';
void main() {
group('ShifterService.runDfuPreflight', () {
test('fails when no active button connection exists', () async {
final adapter = _FakeDfuPreflightBluetoothAdapter(
currentConnectionState: (ConnectionStatus.disconnected, null),
mtuResult: Ok(128),
);
final service = ShifterService(
buttonDeviceId: 'target-device',
dfuPreflightBluetooth: adapter,
);
final result = await service.runDfuPreflight();
expect(result.isOk(), isTrue);
final preflight = result.unwrap();
expect(preflight.canStart, isFalse);
expect(preflight.failureReason,
DfuPreflightFailureReason.deviceNotConnected);
expect(adapter.requestMtuCallCount, 0);
});
test('fails when connected to a different button', () async {
final adapter = _FakeDfuPreflightBluetoothAdapter(
currentConnectionState: (ConnectionStatus.connected, 'wrong-device'),
mtuResult: Ok(128),
);
final service = ShifterService(
buttonDeviceId: 'target-device',
dfuPreflightBluetooth: adapter,
);
final result = await service.runDfuPreflight();
expect(result.isOk(), isTrue);
final preflight = result.unwrap();
expect(preflight.canStart, isFalse);
expect(preflight.failureReason,
DfuPreflightFailureReason.wrongConnectedDevice);
expect(adapter.requestMtuCallCount, 0);
});
test('fails when MTU negotiation fails', () async {
final adapter = _FakeDfuPreflightBluetoothAdapter(
currentConnectionState: (ConnectionStatus.connected, 'target-device'),
mtuResult: bail('adapter rejected mtu request'),
);
final service = ShifterService(
buttonDeviceId: 'target-device',
dfuPreflightBluetooth: adapter,
);
final result = await service.runDfuPreflight(requestedMtu: 247);
expect(result.isOk(), isTrue);
final preflight = result.unwrap();
expect(preflight.canStart, isFalse);
expect(
preflight.failureReason, DfuPreflightFailureReason.mtuRequestFailed);
expect(preflight.message, contains('adapter rejected mtu request'));
expect(adapter.requestedMtuValues, [247]);
});
test('fails when negotiated MTU is too low for 64-byte frame writes',
() async {
final adapter = _FakeDfuPreflightBluetoothAdapter(
currentConnectionState: (ConnectionStatus.connected, 'target-device'),
mtuResult: Ok(universalShifterDfuMinimumMtu - 1),
);
final service = ShifterService(
buttonDeviceId: 'target-device',
dfuPreflightBluetooth: adapter,
);
final result = await service.runDfuPreflight();
expect(result.isOk(), isTrue);
final preflight = result.unwrap();
expect(preflight.canStart, isFalse);
expect(preflight.failureReason, DfuPreflightFailureReason.mtuTooLow);
expect(preflight.negotiatedMtu, universalShifterDfuMinimumMtu - 1);
expect(preflight.requiredMtu, universalShifterDfuMinimumMtu);
});
test('passes when connected to target and MTU is sufficient', () async {
final adapter = _FakeDfuPreflightBluetoothAdapter(
currentConnectionState: (ConnectionStatus.connected, 'target-device'),
mtuResult: Ok(128),
);
final service = ShifterService(
buttonDeviceId: 'target-device',
dfuPreflightBluetooth: adapter,
);
final result = await service.runDfuPreflight();
expect(result.isOk(), isTrue);
final preflight = result.unwrap();
expect(preflight.canStart, isTrue);
expect(preflight.failureReason, isNull);
expect(preflight.negotiatedMtu, 128);
expect(preflight.requestedMtu, universalShifterDfuPreferredMtu);
});
});
}
class _FakeDfuPreflightBluetoothAdapter
implements DfuPreflightBluetoothAdapter {
_FakeDfuPreflightBluetoothAdapter({
required this.currentConnectionState,
required Result<int> mtuResult,
}) : _mtuResult = mtuResult;
@override
final (ConnectionStatus, String?) currentConnectionState;
final Result<int> _mtuResult;
int requestMtuCallCount = 0;
final List<int> requestedMtuValues = <int>[];
@override
Future<Result<int>> requestMtuAndGetValue(
String deviceId, {
required int mtu,
}) async {
requestMtuCallCount += 1;
requestedMtuValues.add(mtu);
return _mtuResult;
}
}