Skip to content

Commit 2b07733

Browse files
authored
Merge pull request #1072 from foss42/test-fixes
Test fixes
2 parents 334155e + 4462e93 commit 2b07733

File tree

6 files changed

+143
-118
lines changed

6 files changed

+143
-118
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,3 +64,4 @@ installers/*
6464

6565
# Testing Files & Folders
6666
test-hive-storage
67+
/logs

lib/terminal/widgets/terminal_level_filter_menu.dart

Lines changed: 90 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -11,111 +11,106 @@ class TerminalLevelFilterMenu extends StatelessWidget {
1111
final Set<TerminalLevel> selected;
1212
final ValueChanged<Set<TerminalLevel>> onChanged;
1313

14-
void _toggleLevel(TerminalLevel level) {
15-
final next = selected.contains(level)
16-
? (selected.toSet()..remove(level))
17-
: (selected.toSet()..add(level));
18-
onChanged(next);
14+
void _showFilterDialog(BuildContext context) {
15+
showDialog<Set<TerminalLevel>>(
16+
context: context,
17+
builder: (context) => _FilterDialog(selected: selected),
18+
).then((result) {
19+
if (result != null) {
20+
onChanged(result);
21+
}
22+
});
1923
}
2024

2125
@override
2226
Widget build(BuildContext context) {
23-
final all = TerminalLevel.values.toSet();
24-
return PopupMenuButton<_MenuAction>(
27+
return IconButton(
2528
tooltip: 'Filter',
2629
icon: const Icon(Icons.filter_alt),
27-
onSelected: (action) {
28-
switch (action) {
29-
case _MenuAction.toggleDebug:
30-
_toggleLevel(TerminalLevel.debug);
31-
break;
32-
case _MenuAction.toggleInfo:
33-
_toggleLevel(TerminalLevel.info);
34-
break;
35-
case _MenuAction.toggleWarn:
36-
_toggleLevel(TerminalLevel.warn);
37-
break;
38-
case _MenuAction.toggleError:
39-
_toggleLevel(TerminalLevel.error);
40-
break;
41-
case _MenuAction.selectAll:
42-
onChanged(all);
43-
break;
44-
case _MenuAction.clearAll:
45-
onChanged(<TerminalLevel>{});
46-
break;
47-
}
48-
},
49-
itemBuilder: (context) => [
50-
CheckedPopupMenuItem<_MenuAction>(
51-
value: _MenuAction.toggleError,
52-
checked: selected.contains(TerminalLevel.error),
53-
child: const ListTile(
54-
dense: true,
55-
contentPadding: EdgeInsets.zero,
56-
leading: Icon(Icons.error_outline_rounded, color: Colors.red),
57-
title: Text('Errors'),
58-
),
59-
),
60-
CheckedPopupMenuItem<_MenuAction>(
61-
value: _MenuAction.toggleWarn,
62-
checked: selected.contains(TerminalLevel.warn),
63-
child: const ListTile(
64-
dense: true,
65-
contentPadding: EdgeInsets.zero,
66-
leading: Icon(Icons.warning_amber_outlined, color: Colors.amber),
67-
title: Text('Warnings'),
68-
),
69-
),
70-
CheckedPopupMenuItem<_MenuAction>(
71-
value: _MenuAction.toggleInfo,
72-
checked: selected.contains(TerminalLevel.info),
73-
child: const ListTile(
74-
dense: true,
75-
contentPadding: EdgeInsets.zero,
76-
leading: Icon(Icons.info_outline, color: Colors.blue),
77-
title: Text('Info'),
78-
),
79-
),
80-
CheckedPopupMenuItem<_MenuAction>(
81-
value: _MenuAction.toggleDebug,
82-
checked: selected.contains(TerminalLevel.debug),
83-
child: const ListTile(
84-
dense: true,
85-
contentPadding: EdgeInsets.zero,
86-
leading: Icon(Icons.bug_report_outlined),
87-
title: Text('Debug'),
88-
),
89-
),
90-
const PopupMenuDivider(),
91-
PopupMenuItem<_MenuAction>(
92-
value: _MenuAction.selectAll,
93-
child: const ListTile(
94-
dense: true,
95-
contentPadding: EdgeInsets.zero,
96-
leading: Icon(Icons.select_all),
97-
title: Text('Select all'),
30+
onPressed: () => _showFilterDialog(context),
31+
);
32+
}
33+
}
34+
35+
const _levelMeta = <TerminalLevel, ({IconData icon, Color? color, String label})>{
36+
TerminalLevel.error: (icon: Icons.error_outline_rounded, color: Colors.red, label: 'Errors'),
37+
TerminalLevel.warn: (icon: Icons.warning_amber_outlined, color: Colors.amber, label: 'Warnings'),
38+
TerminalLevel.info: (icon: Icons.info_outline, color: Colors.blue, label: 'Info'),
39+
TerminalLevel.debug: (icon: Icons.bug_report_outlined, color: null, label: 'Debug'),
40+
};
41+
42+
class _FilterDialog extends StatefulWidget {
43+
const _FilterDialog({required this.selected});
44+
45+
final Set<TerminalLevel> selected;
46+
47+
@override
48+
State<_FilterDialog> createState() => _FilterDialogState();
49+
}
50+
51+
class _FilterDialogState extends State<_FilterDialog> {
52+
late Set<TerminalLevel> _selected;
53+
54+
@override
55+
void initState() {
56+
super.initState();
57+
_selected = widget.selected.toSet();
58+
}
59+
60+
void _toggle(TerminalLevel level) {
61+
setState(() {
62+
if (_selected.contains(level)) {
63+
_selected.remove(level);
64+
} else {
65+
_selected.add(level);
66+
}
67+
});
68+
}
69+
70+
@override
71+
Widget build(BuildContext context) {
72+
return AlertDialog(
73+
title: const Text('Filter Levels'),
74+
content: Column(
75+
mainAxisSize: MainAxisSize.min,
76+
children: [
77+
for (final entry in _levelMeta.entries)
78+
CheckboxListTile(
79+
value: _selected.contains(entry.key),
80+
onChanged: (_) => _toggle(entry.key),
81+
secondary: Icon(entry.value.icon, color: entry.value.color),
82+
title: Text(entry.value.label),
83+
),
84+
const Divider(),
85+
Row(
86+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
87+
children: [
88+
TextButton(
89+
onPressed: () => setState(() {
90+
_selected = TerminalLevel.values.toSet();
91+
}),
92+
child: const Text('Select all'),
93+
),
94+
TextButton(
95+
onPressed: () => setState(() {
96+
_selected.clear();
97+
}),
98+
child: const Text('Clear selection'),
99+
),
100+
],
98101
),
102+
],
103+
),
104+
actions: [
105+
TextButton(
106+
onPressed: () => Navigator.of(context).pop(),
107+
child: const Text('Cancel'),
99108
),
100-
PopupMenuItem<_MenuAction>(
101-
value: _MenuAction.clearAll,
102-
child: const ListTile(
103-
dense: true,
104-
contentPadding: EdgeInsets.zero,
105-
leading: Icon(Icons.clear_all),
106-
title: Text('Clear selection'),
107-
),
109+
FilledButton(
110+
onPressed: () => Navigator.of(context).pop(_selected),
111+
child: const Text('Apply'),
108112
),
109113
],
110114
);
111115
}
112116
}
113-
114-
enum _MenuAction {
115-
toggleDebug,
116-
toggleInfo,
117-
toggleWarn,
118-
toggleError,
119-
selectAll,
120-
clearAll,
121-
}

pubspec.lock

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -801,10 +801,10 @@ packages:
801801
dependency: transitive
802802
description:
803803
name: google_fonts
804-
sha256: ba03d03bcaa2f6cb7bd920e3b5027181db75ab524f8891c8bc3aa603885b8055
804+
sha256: c30eef5e7cd26eb89cc8065b4390ac86ce579f2fcdbe35220891c6278b5460da
805805
url: "https://pub.dev"
806806
source: hosted
807-
version: "6.3.3"
807+
version: "8.0.1"
808808
graphs:
809809
dependency: transitive
810810
description:

test/screens/common_widgets/auth/oauth2_fields_test.dart

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1237,6 +1237,8 @@ void main() {
12371237
: authFields.last,
12381238
matching: find.byType(ExtendedTextField),
12391239
);
1240+
await tester.ensureVisible(identityTokenField);
1241+
await tester.pumpAndSettle();
12401242
await tester.tap(identityTokenField);
12411243
tester.testTextInput.enterText('new_identity');
12421244
await tester.pumpAndSettle();
@@ -1248,6 +1250,8 @@ void main() {
12481250
of: authFields.last,
12491251
matching: find.byType(ExtendedTextField),
12501252
);
1253+
await tester.ensureVisible(accessTokenField);
1254+
await tester.pumpAndSettle();
12511255
await tester.tap(accessTokenField);
12521256
tester.testTextInput.enterText('new_access');
12531257
await tester.pumpAndSettle();

test/screens/terminal/terminal_page_test.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -99,8 +99,8 @@ void main() {
9999
await tester.pumpAndSettle();
100100
expect(networkTitle, findsNothing);
101101

102-
// Toggle timestamp checkbox
103-
await tester.tap(find.byType(Checkbox));
102+
// Toggle timestamp icon button
103+
await tester.tap(find.byIcon(Icons.access_time));
104104
await tester.pumpAndSettle();
105105

106106
// We won't parse time, but ensure list still renders with entries

test/terminal/terminal_level_filter_menu_test.dart

Lines changed: 44 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:apidash/terminal/enums.dart';
44
import 'package:apidash/terminal/widgets/terminal_level_filter_menu.dart';
55

66
void main() {
7-
testWidgets('TerminalLevelFilterMenu toggles and bulk selects',
7+
testWidgets('TerminalLevelFilterMenu toggles and bulk selects via dialog',
88
(tester) async {
99
Set<TerminalLevel> selected = TerminalLevel.values.toSet();
1010
late Set<TerminalLevel> last;
@@ -17,34 +17,59 @@ void main() {
1717
),
1818
));
1919

20-
// Open menu
20+
// Open dialog
2121
await tester.tap(find.byIcon(Icons.filter_alt));
22-
await tester.pump();
23-
await tester.pump(const Duration(seconds: 1));
22+
await tester.pumpAndSettle();
2423

25-
// Toggle Info by tapping text within popup
26-
await tester.tap(find.text('Info').last);
27-
await tester.pump();
28-
await tester.pump(const Duration(seconds: 1));
24+
// Toggle Info off by tapping its checkbox row, then apply
25+
await tester.tap(find.text('Info'));
26+
await tester.pumpAndSettle();
27+
await tester.tap(find.text('Apply'));
28+
await tester.pumpAndSettle();
2929
expect(last.contains(TerminalLevel.info), isFalse);
3030

3131
// Select all
32-
// Reopen menu after it closes
3332
await tester.tap(find.byIcon(Icons.filter_alt));
34-
await tester.pump();
35-
await tester.pump(const Duration(seconds: 1));
36-
await tester.tap(find.text('Select all').last);
37-
await tester.pump();
38-
await tester.pump(const Duration(seconds: 1));
33+
await tester.pumpAndSettle();
34+
await tester.tap(find.text('Select all'));
35+
await tester.pumpAndSettle();
36+
await tester.tap(find.text('Apply'));
37+
await tester.pumpAndSettle();
3938
expect(last.length, TerminalLevel.values.length);
4039

4140
// Clear selection
4241
await tester.tap(find.byIcon(Icons.filter_alt));
43-
await tester.pump();
44-
await tester.pump(const Duration(seconds: 1));
45-
await tester.tap(find.text('Clear selection').last);
46-
await tester.pump();
47-
await tester.pump(const Duration(seconds: 1));
42+
await tester.pumpAndSettle();
43+
await tester.tap(find.text('Clear selection'));
44+
await tester.pumpAndSettle();
45+
await tester.tap(find.text('Apply'));
46+
await tester.pumpAndSettle();
4847
expect(last, isEmpty);
4948
});
49+
50+
testWidgets('Cancel does not apply changes', (tester) async {
51+
Set<TerminalLevel> selected = TerminalLevel.values.toSet();
52+
bool called = false;
53+
await tester.pumpWidget(MaterialApp(
54+
home: Scaffold(
55+
body: TerminalLevelFilterMenu(
56+
selected: selected,
57+
onChanged: (_) => called = true,
58+
),
59+
),
60+
));
61+
62+
await tester.tap(find.byIcon(Icons.filter_alt));
63+
await tester.pumpAndSettle();
64+
65+
// Toggle something off
66+
await tester.tap(find.text('Info'));
67+
await tester.pumpAndSettle();
68+
69+
// Cancel instead of apply
70+
await tester.tap(find.text('Cancel'));
71+
await tester.pumpAndSettle();
72+
73+
expect(called, isFalse);
74+
});
5075
}

0 commit comments

Comments
 (0)