Skip to content

Commit

Permalink
Reporting test case issues frontend (#208)
Browse files Browse the repository at this point in the history
* Fix expandable size changes when expanded

* Add test result details expandable

* Add dummy test case issues expandable

* Fetch test case reported issues

* Add test issues preloader

* Show test issues and support updating them

* Add form validation

* Add ability to create test case issues

* Support deleting test case issues

* Add issue deletion confirmation

* Move public methods up

* Remove trailing comma

* Show reported issues count on test result expandable

* Use VanillaTextInput in review comment

* Show more detailed message on deletion of issue
  • Loading branch information
omar-selo committed Sep 6, 2024
1 parent 5685c87 commit 4ee6e3f
Show file tree
Hide file tree
Showing 16 changed files with 598 additions and 25 deletions.
18 changes: 18 additions & 0 deletions frontend/lib/models/test_issue.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import 'package:freezed_annotation/freezed_annotation.dart';

part 'test_issue.freezed.dart';
part 'test_issue.g.dart';

@freezed
class TestIssue with _$TestIssue {
const factory TestIssue({
required int id,
@JsonKey(name: 'template_id') required String templateId,
@JsonKey(name: 'case_name') required String caseName,
required String description,
required String url,
}) = _TestIssue;

factory TestIssue.fromJson(Map<String, Object?> json) =>
_$TestIssueFromJson(json);
}
1 change: 1 addition & 0 deletions frontend/lib/models/test_result.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class TestResult with _$TestResult {
required TestResultStatus status,
@Default('') String category,
@Default('') String comment,
@JsonKey(name: 'template_id') @Default('') String templateId,
@JsonKey(name: 'io_log') @Default('') String ioLog,
@JsonKey(name: 'previous_results')
@Default([])
Expand Down
26 changes: 26 additions & 0 deletions frontend/lib/providers/test_result_issues.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import 'package:dartx/dartx.dart';
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../models/test_issue.dart';
import '../models/test_result.dart';
import 'tests_issues.dart';

part 'test_result_issues.g.dart';

@riverpod
Future<List<TestIssue>> testResultIssues(
TestResultIssuesRef ref,
TestResult testResult,
) {
return ref.watch(
testsIssuesProvider.selectAsync(
(issues) => issues
.filter(
(issue) =>
issue.caseName == testResult.name ||
issue.templateId == testResult.templateId,
)
.toList(),
),
);
}
48 changes: 48 additions & 0 deletions frontend/lib/providers/tests_issues.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import 'package:riverpod_annotation/riverpod_annotation.dart';

import '../models/test_issue.dart';
import 'api.dart';

part 'tests_issues.g.dart';

@riverpod
class TestsIssues extends _$TestsIssues {
@override
Future<List<TestIssue>> build() {
final api = ref.watch(apiProvider);
return api.getTestIssues();
}

void updateIssue(TestIssue issue) async {
final api = ref.read(apiProvider);
final updatedIssue = await api.updateTestIssue(issue);
final issues = await future;
state = AsyncData([
for (final issue in issues)
issue.id == updatedIssue.id ? updatedIssue : issue,
]);
}

void createIssue(
String url,
String description, {
String? caseName,
String? templateId,
}) async {
final api = ref.read(apiProvider);
final issue =
await api.createTestIssue(url, description, caseName, templateId);
final issues = await future;
state = AsyncData([...issues, issue]);
}

void deleteIssue(int issueId) async {
final api = ref.read(apiProvider);
await api.deleteTestIssue(issueId);
final issues = await future;
state = AsyncData([
for (final issue in issues)
if (issue.id != issueId) issue,
]);
}
}
37 changes: 37 additions & 0 deletions frontend/lib/repositories/api_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import '../models/artefact_build.dart';
import '../models/family_name.dart';
import '../models/rerun_request.dart';
import '../models/test_execution.dart';
import '../models/test_issue.dart';
import '../models/test_result.dart';
import '../models/test_event.dart';

Expand Down Expand Up @@ -88,4 +89,40 @@ class ApiRepository {
rerunsJson.map((json) => RerunRequest.fromJson(json)).toList();
return reruns;
}

Future<List<TestIssue>> getTestIssues() async {
final response = await dio.get('/v1/test-cases/reported-issues');
final List issuesJson = response.data;
return issuesJson.map((json) => TestIssue.fromJson(json)).toList();
}

Future<TestIssue> updateTestIssue(TestIssue issue) async {
final response = await dio.put(
'/v1/test-cases/reported-issues/${issue.id}',
data: issue.toJson(),
);
return TestIssue.fromJson(response.data);
}

Future<TestIssue> createTestIssue(
String url,
String description,
String? caseName,
String? templateId,
) async {
final response = await dio.post(
'/v1/test-cases/reported-issues',
data: {
'url': url,
'description': description,
if (caseName != null) 'case_name': caseName,
if (templateId != null) 'template_id': templateId,
},
);
return TestIssue.fromJson(response.data);
}

Future<void> deleteTestIssue(int issueId) async {
await dio.delete('/v1/test-cases/reported-issues/$issueId');
}
}
19 changes: 11 additions & 8 deletions frontend/lib/ui/artefact_page/artefact_page_body.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import '../../routing.dart';
import '../spacing.dart';
import 'rerun_filtered_environments_button.dart';
import 'test_execution_expandable/test_execution_expandable.dart';
import 'test_issues/test_issues_preloader.dart';

class ArtefactPageBody extends ConsumerWidget {
const ArtefactPageBody({super.key, required this.artefact});
Expand Down Expand Up @@ -42,14 +43,16 @@ class ArtefactPageBody extends ConsumerWidget {
const RerunFilteredEnvironmentsButton(),
],
),
Expanded(
child: ListView.builder(
itemCount: testExecutions.length,
itemBuilder: (_, i) => Padding(
// Padding is to avoid scroll bar covering trailing buttons
padding: const EdgeInsets.only(right: Spacing.level3),
child: TestExecutionExpandable(
testExecution: testExecutions[i],
TestIssuesPreloader(
child: Expanded(
child: ListView.builder(
itemCount: testExecutions.length,
itemBuilder: (_, i) => Padding(
// Padding is to avoid scroll bar covering trailing buttons
padding: const EdgeInsets.only(right: Spacing.level3),
child: TestExecutionExpandable(
testExecution: testExecutions[i],
),
),
),
),
Expand Down
18 changes: 6 additions & 12 deletions frontend/lib/ui/artefact_page/test_execution_pop_over.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import '../../models/family_name.dart';
import '../../models/test_execution.dart';
import '../../providers/review_test_execution.dart';
import '../spacing.dart';
import '../vanilla/vanilla_text_input.dart';

class TestExecutionPopOver extends ConsumerStatefulWidget {
const TestExecutionPopOver({
Expand Down Expand Up @@ -102,19 +103,12 @@ class TestExecutionPopOverState extends ConsumerState<TestExecutionPopOver> {
.toList(),
),
const SizedBox(height: Spacing.level4),
Text(
'Additional review comments:',
style: Theme.of(context).textTheme.titleLarge,
),
const SizedBox(height: Spacing.level3),
TextField(
decoration: const InputDecoration(
border: OutlineInputBorder(),
hintText: 'Insert review comment',
),
VanillaTextInput(
label: 'Additional review comments:',
labelStyle: Theme.of(context).textTheme.titleLarge,
controller: reviewCommentController,
keyboardType: TextInputType.multiline,
maxLines: null,
multiline: true,
hintText: 'Insert review comment',
),
const SizedBox(height: Spacing.level3),
ElevatedButton(
Expand Down
2 changes: 1 addition & 1 deletion frontend/lib/ui/artefact_page/test_execution_review.dart
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class TestExecutionReviewButton extends StatelessWidget {
),
direction: PopoverDirection.bottom,
width: 500,
height: 400,
height: 450,
arrowHeight: 15,
arrowWidth: 30,
);
Expand Down
Loading

0 comments on commit 4ee6e3f

Please sign in to comment.