feat: finalize AI analyzer, sync endpoints, and stabilize builds

This commit is contained in:
2026-05-19 12:27:08 +07:00
parent f697ef16cd
commit 23d0cf6f66
23 changed files with 375 additions and 142 deletions
@@ -261,13 +261,13 @@ void main() {
testWidgets('password tersembunyi (obscureText=true) secara default', (tester) async {
await tester.pumpWidget(makeTestable(const _StubLoginScreen()));
final editableText = tester.widget<EditableText>(
find.descendant(
of: find.byKey(const Key('password_field')),
matching: find.byType(EditableText),
),
);
expect(editableText.obscureText, isTrue);
final editableText = tester.widget<EditableText>(
find.descendant(
of: find.byKey(const Key('password_field')),
matching: find.byType(EditableText),
),
);
expect(editableText.obscureText, isTrue);
});
testWidgets('tap toggle mengubah obscureText menjadi false', (tester) async {
@@ -282,7 +282,7 @@ void main() {
matching: find.byType(EditableText),
),
);
expect(editableText.obscureText, isTrue);
expect(editableText.obscureText, isFalse);
});
testWidgets('tap toggle dua kali mengembalikan obscureText ke true', (tester) async {
@@ -313,9 +313,10 @@ void main() {
await tester.enterText(find.byKey(const Key('password_field')), 'password123');
await tester.tap(find.byKey(const Key('login_button')));
await tester.pump(); // Trigger rebuild
expect(find.byKey(const Key('loading_indicator')), findsOneWidget);
});
expect(find.byKey(const Key('loading_indicator')), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('menyembunyikan tombol login saat loading', (tester) async {
await tester.pumpWidget(makeTestable(const _StubLoginScreen()));
@@ -324,9 +325,10 @@ void main() {
await tester.enterText(find.byKey(const Key('password_field')), 'password123');
await tester.tap(find.byKey(const Key('login_button')));
await tester.pump();
expect(find.byKey(const Key('login_button')), findsNothing);
});
expect(find.byKey(const Key('login_button')), findsNothing);
await tester.pumpAndSettle();
});
testWidgets('loading selesai setelah async operation', (tester) async {
await tester.pumpWidget(makeTestable(const _StubLoginScreen()));
@@ -363,11 +363,16 @@ class _StubManualScreenState extends State<_StubManualScreen> {
}
}
Widget makeTestable(Widget child) => MaterialApp(home: child);
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
Widget makeTestable(Widget child) => MaterialApp(home: child);
Finder _commandScrollable() => find.descendant(
of: find.byKey(const Key('command_list')),
matching: find.byType(Scrollable),
);
// ---------------------------------------------------------------------------
// Tests
// ---------------------------------------------------------------------------
void main() {
group('ManualScreen Widget Tests', () {
@@ -418,12 +423,13 @@ void main() {
group('Konten perintah suara', () {
testWidgets('menampilkan tile untuk perintah Open Walkguide',
(tester) async {
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(
find.byKey(const Key('cmd_tile_openWalkguide')),
200,
);
expect(find.byKey(const Key('cmd_tile_openWalkguide')), findsOneWidget);
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(
find.byKey(const Key('cmd_tile_openWalkguide')),
200,
scrollable: _commandScrollable(),
);
expect(find.byKey(const Key('cmd_tile_openWalkguide')), findsOneWidget);
});
testWidgets('menampilkan phrase perintah dalam tanda kutip',
@@ -449,25 +455,36 @@ void main() {
expect(find.text('"Call Guardian"'), findsOneWidget);
});
testWidgets('menampilkan perintah Send SOS', (tester) async {
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(find.text('"Send SOS"'), 200);
expect(find.text('"Send SOS"'), findsOneWidget);
});
testWidgets('menampilkan perintah Where Am I', (tester) async {
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(find.text('"Where Am I"'), 200);
expect(find.text('"Where Am I"'), findsOneWidget);
});
testWidgets('menampilkan perintah Send SOS', (tester) async {
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(
find.text('"Send SOS"'),
200,
scrollable: _commandScrollable(),
);
expect(find.text('"Send SOS"'), findsOneWidget);
});
testWidgets('menampilkan perintah Where Am I', (tester) async {
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(
find.text('"Where Am I"'),
200,
scrollable: _commandScrollable(),
);
expect(find.text('"Where Am I"'), findsOneWidget);
});
testWidgets('menampilkan kategori Darurat untuk Send SOS',
(tester) async {
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(
find.byKey(const Key('cmd_category_sendSos')), 200);
expect(find.byKey(const Key('cmd_category_sendSos')), findsOneWidget);
});
await tester.pumpWidget(makeTestable(const _StubManualScreen()));
await tester.scrollUntilVisible(
find.byKey(const Key('cmd_category_sendSos')),
200,
scrollable: _commandScrollable(),
);
expect(find.byKey(const Key('cmd_category_sendSos')), findsOneWidget);
});
});
// ── Dialog info ───────────────────────────────────────────────────────
@@ -103,15 +103,16 @@ class _StubNotificationScreenState extends State<_StubNotificationScreen> {
],
],
),
actions: [
if (_items.any((e) => !e.isRead))
TextButton(
key: const Key('mark_all_read_button'),
onPressed: _markingAll ? null : _markAllRead,
child: const Text('Tandai Semua Dibaca'),
),
],
),
actions: [
if (_items.any((e) => !e.isRead))
IconButton(
key: const Key('mark_all_read_button'),
onPressed: _markingAll ? null : _markAllRead,
tooltip: 'Tandai Semua Dibaca',
icon: const Icon(Icons.done_all),
),
],
),
body: widget.isLoading
? const Center(
child: CircularProgressIndicator(key: Key('loading_indicator')))
@@ -431,9 +431,10 @@ void main() {
await tester.tap(find.byKey(const Key('sos_button')));
await tester.pump();
expect(find.byKey(const Key('sending_indicator')), findsOneWidget);
});
expect(find.byKey(const Key('sending_indicator')), findsOneWidget);
await tester.pumpAndSettle();
});
testWidgets('setelah SOS terkirim, tampil success banner',
(tester) async {