fix: gespeicherte Fahrzeugauswahl gegen Server-Fahrzeuge prüfen

Die Tagesauswahl liegt lokal pro Fahrer und wurde ungeprüft
wiederhergestellt. Durch den alten Session-Fehler hatte 414 auf dem
Gerät das Fahrzeug von 423 gespeichert — das erschien weiter, obwohl
„Fahrzeug verwalten" (frisch vom Server) leer war.

CarSelectBloc lädt beim Wiederherstellen die Fahrzeuge des Accounts vom
Server und übernimmt die Auswahl nur, wenn das Fahrzeug dazugehört und
aktiv ist; sonst wird sie verworfen und neu abgefragt.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Dennis Nemec
2026-09-25 16:53:37 +02:00
parent dce4447fcc
commit a5215367fd
5 changed files with 115 additions and 18 deletions

View File

@ -0,0 +1,74 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:hl_lieferservice/domain/entity/car.dart';
import 'package:hl_lieferservice/domain/repository/cars_repository.dart';
import 'package:hl_lieferservice/feature/car_selection/bloc/bloc.dart';
import 'package:hl_lieferservice/feature/car_selection/bloc/events.dart';
import 'package:hl_lieferservice/feature/car_selection/bloc/state.dart';
import 'package:hl_lieferservice/feature/car_selection/repository/car_selection_repository.dart';
/// Fahrzeuge „laut Server" für den angemeldeten Account.
class _ServerCars implements CarsRepository {
_ServerCars(this.cars);
final List<Car> cars;
@override
Future<List<Car>> listMine({bool includeInactive = false}) async => cars;
@override
dynamic noSuchMethod(Invocation invocation) => super.noSuchMethod(invocation);
}
const _fremdesAuto = 'b918b721-0000-0000-0000-000000000423';
Map<String, Object> _gespeichert(String userId, String carId) => {
'flutter.car_selection_test_${userId}_date': DateTime.now().toIso8601String(),
'flutter.car_selection_test_${userId}_car_id': carId,
'flutter.car_selection_test_${userId}_car_plate': 'test',
};
Future<CarSelectState> _laden(String userId, List<Car> serverCars) async {
final bloc = CarSelectBloc(
repository: CarSelectionRepository(environmentId: 'test'),
carsRepository: _ServerCars(serverCars),
)..add(CarSelectLoad(userId: userId));
final state = await bloc.stream.firstWhere(
(s) => s is! CarSelectLoading,
);
await bloc.close();
return state;
}
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
test('gespeichertes Fahrzeug eines anderen Fahrers wird verworfen', () async {
// 414 hat auf diesem Gerät das Auto von 423 als Tagesfahrzeug gespeichert.
SharedPreferences.setMockInitialValues(_gespeichert('414', _fremdesAuto));
final state = await _laden('414', const []);
expect(state, isA<CarSelectRequired>());
final prefs = await SharedPreferences.getInstance();
expect(prefs.getString('car_selection_test_414_car_id'), isNull);
});
test('eigenes aktives Fahrzeug wird übernommen, mit Serverdaten', () async {
SharedPreferences.setMockInitialValues(_gespeichert('423', _fremdesAuto));
const auto = Car(id: _fremdesAuto, accountId: 423, plate: 'test', active: true);
final state = await _laden('423', const [auto]);
expect(state, isA<CarSelectComplete>());
expect((state as CarSelectComplete).selectedCar.accountId, 423);
});
test('deaktiviertes Fahrzeug gilt nicht mehr', () async {
SharedPreferences.setMockInitialValues(_gespeichert('423', _fremdesAuto));
const auto =
Car(id: _fremdesAuto, accountId: 423, plate: 'test', active: false);
expect(await _laden('423', const [auto]), isA<CarSelectRequired>());
});
}