138 lines
4.6 KiB
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;
|
|
}
|
|
}
|