Skip to content

Commit aea0826

Browse files
authored
Merge pull request #373 from DevKor-github/codex/fix-preparation-order
[codex] Fix preparation step order
2 parents ca4e8e6 + c72839e commit aea0826

2 files changed

Lines changed: 98 additions & 1 deletion

File tree

lib/data/models/get_preparation_step_response_model.dart

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,38 @@ class GetPreparationStepResponseModel {
4848
extension PreparationResponseModelListExtension
4949
on List<GetPreparationStepResponseModel> {
5050
PreparationEntity toPreparationEntity() {
51-
final steps = map((model) => model.toEntity()).toList();
51+
if (isEmpty) {
52+
return PreparationEntity(preparationStepList: []);
53+
}
54+
55+
final modelsById = {
56+
for (final model in this) model.id: model,
57+
};
58+
final referencedIds = {
59+
for (final model in this)
60+
if (model.nextPreparationId != null) model.nextPreparationId!,
61+
};
62+
final firstModel = firstWhere(
63+
(model) => !referencedIds.contains(model.id),
64+
orElse: () => first,
65+
);
66+
67+
final orderedModels = <GetPreparationStepResponseModel>[];
68+
final visitedIds = <String>{};
69+
GetPreparationStepResponseModel? currentModel = firstModel;
70+
while (currentModel != null && visitedIds.add(currentModel.id)) {
71+
orderedModels.add(currentModel);
72+
final nextId = currentModel.nextPreparationId;
73+
currentModel = nextId == null ? null : modelsById[nextId];
74+
}
75+
76+
for (final model in this) {
77+
if (visitedIds.add(model.id)) {
78+
orderedModels.add(model);
79+
}
80+
}
81+
82+
final steps = orderedModels.map((model) => model.toEntity()).toList();
5283
return PreparationEntity(preparationStepList: steps);
5384
}
5485
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import 'package:flutter_test/flutter_test.dart';
2+
import 'package:on_time_front/data/models/get_preparation_step_response_model.dart';
3+
4+
void main() {
5+
group('PreparationResponseModelListExtension', () {
6+
test('orders preparation steps by nextPreparationId chain', () {
7+
final models = [
8+
GetPreparationStepResponseModel(
9+
id: 'third',
10+
preparationName: 'Put on shoes',
11+
preparationTime: 3,
12+
nextPreparationId: null,
13+
),
14+
GetPreparationStepResponseModel(
15+
id: 'first',
16+
preparationName: 'Shower',
17+
preparationTime: 10,
18+
nextPreparationId: 'second',
19+
),
20+
GetPreparationStepResponseModel(
21+
id: 'second',
22+
preparationName: 'Get dressed',
23+
preparationTime: 5,
24+
nextPreparationId: 'third',
25+
),
26+
];
27+
28+
final preparation = models.toPreparationEntity();
29+
30+
expect(
31+
preparation.preparationStepList.map((step) => step.id),
32+
['first', 'second', 'third'],
33+
);
34+
});
35+
36+
test('keeps unlinked steps instead of dropping them', () {
37+
final models = [
38+
GetPreparationStepResponseModel(
39+
id: 'first',
40+
preparationName: 'Shower',
41+
preparationTime: 10,
42+
nextPreparationId: 'second',
43+
),
44+
GetPreparationStepResponseModel(
45+
id: 'second',
46+
preparationName: 'Get dressed',
47+
preparationTime: 5,
48+
nextPreparationId: null,
49+
),
50+
GetPreparationStepResponseModel(
51+
id: 'unlinked',
52+
preparationName: 'Pack bag',
53+
preparationTime: 2,
54+
nextPreparationId: null,
55+
),
56+
];
57+
58+
final preparation = models.toPreparationEntity();
59+
60+
expect(
61+
preparation.preparationStepList.map((step) => step.id),
62+
['first', 'second', 'unlinked'],
63+
);
64+
});
65+
});
66+
}

0 commit comments

Comments
 (0)