mirror of
https://github.com/foss42/apidash.git
synced 2025-12-02 10:49:49 +08:00
tests: add tests for dashbot utils(cv: 100)
This commit is contained in:
30
test/dashbot/utils/dashbot_icons_test.dart
Normal file
30
test/dashbot/utils/dashbot_icons_test.dart
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
import 'package:apidash/dashbot/core/utils/dashbot_icons.dart';
|
||||||
|
import 'package:flutter/widgets.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
group('DashbotIcons', () {
|
||||||
|
test('path getters', () {
|
||||||
|
expect(DashbotIcons.dashbotIcon1, 'assets/dashbot/dashbot_icon_1.png');
|
||||||
|
expect(DashbotIcons.dashbotIcon2, 'assets/dashbot/dashbot_icon_2.png');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getDashbotIcon1 returns Image.asset with correct dimensions', () {
|
||||||
|
final img = DashbotIcons.getDashbotIcon1(width: 24, height: 24);
|
||||||
|
expect(img, isA<Image>());
|
||||||
|
expect(img.width, 24);
|
||||||
|
expect(img.height, 24);
|
||||||
|
final provider = img.image;
|
||||||
|
expect(provider, isA<AssetImage>());
|
||||||
|
expect((provider as AssetImage).assetName, DashbotIcons.dashbotIcon1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getDashbotIcon2 returns Image.asset', () {
|
||||||
|
final img = DashbotIcons.getDashbotIcon2();
|
||||||
|
expect(img.image, isA<AssetImage>());
|
||||||
|
expect((img.image as AssetImage).assetName, DashbotIcons.dashbotIcon2);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
37
test/dashbot/utils/safe_parse_json_message_test.dart
Normal file
37
test/dashbot/utils/safe_parse_json_message_test.dart
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import 'package:apidash/dashbot/core/utils/safe_parse_json_message.dart';
|
||||||
|
import 'package:test/test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
group('MessageJson.safeParse', () {
|
||||||
|
test('parses valid JSON object', () {
|
||||||
|
final m = MessageJson.safeParse('{"a":1,"b":"x"}');
|
||||||
|
expect(m, containsPair('a', 1));
|
||||||
|
expect(m['b'], 'x');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('returns empty map for non-object top-level JSON', () {
|
||||||
|
final m = MessageJson.safeParse('[1,2,3]');
|
||||||
|
expect(m, isEmpty);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('extracts object from markdown fenced code block', () {
|
||||||
|
const input =
|
||||||
|
'''Here is your result:\n```json\n{\n "ok": true,\n "count": 2\n}\n```\nThanks''';
|
||||||
|
final m = MessageJson.safeParse(input);
|
||||||
|
expect(m['ok'], true);
|
||||||
|
expect(m['count'], 2);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('throws FormatException on invalid JSON with no braces slice', () {
|
||||||
|
expect(() => MessageJson.safeParse('totally invalid'),
|
||||||
|
throwsFormatException);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('falls back to slice between first { and last }', () {
|
||||||
|
const input = 'prefix {"z":42, "k":"v"} suffix';
|
||||||
|
final m = MessageJson.safeParse(input);
|
||||||
|
expect(m['z'], 42);
|
||||||
|
expect(m['k'], 'v');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
92
test/dashbot/utils/show_dashbot_test.dart
Normal file
92
test/dashbot/utils/show_dashbot_test.dart
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import 'package:apidash/dashbot/core/providers/dashbot_window_notifier.dart';
|
||||||
|
import 'package:apidash/dashbot/core/utils/show_dashbot.dart';
|
||||||
|
import 'package:apidash/dashbot/dashbot_dashboard.dart';
|
||||||
|
import 'package:apidash/providers/collection_providers.dart';
|
||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
|
Future<(BuildContext, WidgetRef)> pumpHarness(
|
||||||
|
WidgetTester tester, {
|
||||||
|
List<Override>? overrides,
|
||||||
|
}) async {
|
||||||
|
late BuildContext ctx;
|
||||||
|
late WidgetRef wRef;
|
||||||
|
await tester.pumpWidget(ProviderScope(
|
||||||
|
overrides: [
|
||||||
|
// Empty current request (StateProvider override supplies initial value).
|
||||||
|
selectedRequestModelProvider.overrideWith((ref) => null),
|
||||||
|
if (overrides != null) ...overrides,
|
||||||
|
],
|
||||||
|
child: MaterialApp(
|
||||||
|
home: Scaffold(
|
||||||
|
body: Consumer(builder: (c, ref, _) {
|
||||||
|
ctx = c;
|
||||||
|
wRef = ref;
|
||||||
|
return const SizedBox();
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
));
|
||||||
|
// Enlarge window width to avoid Row overflow in header (actions + title)
|
||||||
|
final notifier = wRef.read(dashbotWindowNotifierProvider.notifier);
|
||||||
|
notifier.state = notifier.state.copyWith(width: 650);
|
||||||
|
return (ctx, wRef);
|
||||||
|
}
|
||||||
|
|
||||||
|
group('showDashbotWindow', () {
|
||||||
|
testWidgets('activates & inserts overlay when inactive & popped',
|
||||||
|
(tester) async {
|
||||||
|
final (ctx, ref) = await pumpHarness(tester);
|
||||||
|
expect(ref.read(dashbotWindowNotifierProvider).isActive, isFalse);
|
||||||
|
showDashbotWindow(ctx, ref);
|
||||||
|
await tester.pump();
|
||||||
|
// State toggled active
|
||||||
|
expect(ref.read(dashbotWindowNotifierProvider).isActive, isTrue);
|
||||||
|
// DashBot title text present (from DashbotWindow)
|
||||||
|
expect(find.text('DashBot'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('early return when already active', (tester) async {
|
||||||
|
final (ctx, ref) = await pumpHarness(tester);
|
||||||
|
// Manually set active before calling util to hit early return.
|
||||||
|
ref.read(dashbotWindowNotifierProvider.notifier).toggleActive();
|
||||||
|
final before = ref.read(dashbotWindowNotifierProvider);
|
||||||
|
showDashbotWindow(ctx, ref);
|
||||||
|
await tester.pump();
|
||||||
|
final after = ref.read(dashbotWindowNotifierProvider);
|
||||||
|
expect(after.isActive, isTrue);
|
||||||
|
// No duplicate activation toggling (remains same instance/state)
|
||||||
|
expect(after.isActive, before.isActive);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('early return when not popped', (tester) async {
|
||||||
|
final (ctx, ref) = await pumpHarness(tester);
|
||||||
|
// Toggle popped to false
|
||||||
|
ref.read(dashbotWindowNotifierProvider.notifier).togglePopped();
|
||||||
|
expect(ref.read(dashbotWindowNotifierProvider).isPopped, isFalse);
|
||||||
|
showDashbotWindow(ctx, ref);
|
||||||
|
await tester.pump();
|
||||||
|
// Still inactive because not popped
|
||||||
|
expect(ref.read(dashbotWindowNotifierProvider).isActive, isFalse);
|
||||||
|
expect(find.byType(DashbotWindow), findsNothing);
|
||||||
|
});
|
||||||
|
|
||||||
|
testWidgets('pressing close button removes overlay & deactivates',
|
||||||
|
(tester) async {
|
||||||
|
final (ctx, ref) = await pumpHarness(tester);
|
||||||
|
showDashbotWindow(ctx, ref);
|
||||||
|
await tester.pump();
|
||||||
|
expect(ref.read(dashbotWindowNotifierProvider).isActive, isTrue);
|
||||||
|
// Tap the close (Icons.close)
|
||||||
|
final closeFinder = find.byIcon(Icons.close);
|
||||||
|
expect(closeFinder, findsOneWidget);
|
||||||
|
await tester.tap(closeFinder);
|
||||||
|
await tester.pump();
|
||||||
|
expect(ref.read(dashbotWindowNotifierProvider).isActive, isFalse);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user