From 9abab01d8f9913deba4b56a7825d32dcff0e85e1 Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Sun, 26 Jan 2025 18:30:38 +0900 Subject: [PATCH 1/6] Refactor tests --- test/widgets/logs/logs_test.dart | 321 ++---- test/widgets/logs/logs_test.mocks.dart | 1238 ------------------------ 2 files changed, 76 insertions(+), 1483 deletions(-) delete mode 100644 test/widgets/logs/logs_test.mocks.dart diff --git a/test/widgets/logs/logs_test.dart b/test/widgets/logs/logs_test.dart index b3261b37..bcc4bd99 100644 --- a/test/widgets/logs/logs_test.dart +++ b/test/widgets/logs/logs_test.dart @@ -1,259 +1,90 @@ -import 'package:dynamic_color/dynamic_color.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_dotenv/flutter_dotenv.dart'; -import 'package:flutter_gen/gen_l10n/app_localizations.dart'; -import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/annotations.dart'; -import 'package:mockito/mockito.dart'; -import 'package:pi_hole_client/config/globals.dart'; -import 'package:pi_hole_client/config/theme.dart'; -import 'package:pi_hole_client/constants/query_types.dart'; -import 'package:pi_hole_client/gateways/v6/api_gateway_v6.dart'; -import 'package:pi_hole_client/models/api/v6/metrics/query.dart'; -import 'package:pi_hole_client/models/gateways.dart'; -import 'package:pi_hole_client/models/log.dart'; -import 'package:pi_hole_client/models/server.dart'; -import 'package:pi_hole_client/providers/app_config_provider.dart'; -import 'package:pi_hole_client/providers/filters_provider.dart'; -import 'package:pi_hole_client/providers/servers_provider.dart'; import 'package:pi_hole_client/screens/logs/logs.dart'; -import 'package:provider/provider.dart'; -import './logs_test.mocks.dart'; +import '../helpers.dart'; -@GenerateMocks( - [AppConfigProvider, FiltersProvider, ServersProvider, ApiGatewayV6], -) void main() async { -// For loading the .env file - TestWidgetsFlutterBinding.ensureInitialized(); - await dotenv.load(); + await initializeApp(); - final server = Server( - address: 'address', - alias: 'test', - defaultServer: false, - apiVersion: 'v6', - ); - - final data = { - 'queries': [ - { - 'id': 1, - 'time': DateTime.now().millisecondsSinceEpoch / 1000 - 600, - 'type': 'A', - 'domain': 'white.example.com', - 'cname': null, - 'status': 'FORWARDED', - 'client': {'ip': '192.168.100.2'}, - 'dnssec': 'INSECURE', - 'reply': {'type': 'IP', 'time': 19}, - 'list_id': null, - 'upstream': 'localhost#5353', - 'dbid': 112421354, - }, - ], - 'cursor': 175881, - 'recordsTotal': 1234, - 'recordsFiltered': 1234, - 'draw': 1, - 'took': 0.003, - }; - - final queries = Queries.fromJson(data); - - group('Query logs screen tests', () { - late MockApiGatewayV6 mockApiGatewayV6; - late MockAppConfigProvider mockConfigProvider; - late MockServersProvider mockServersProvider; - late MockFiltersProvider mockFiltersProvider; - - setUp(() async { - mockApiGatewayV6 = MockApiGatewayV6(); - mockConfigProvider = MockAppConfigProvider(); - mockServersProvider = MockServersProvider(); - mockFiltersProvider = MockFiltersProvider(); + group( + 'Query logs screen tests', + () { + late TestSetupHelper testSetup; - // mock Apigateway - when(mockApiGatewayV6.fetchLogs(any, any)).thenAnswer((_) async { - return FetchLogsResponse( - result: APiResponseType.success, - data: queries.queries.map(Log.fromV6).toList(), - ); + setUp(() async { + testSetup = TestSetupHelper(); + testSetup.initializeMock(useApiGatewayVersion: 'v6'); }); - when(mockApiGatewayV6.setWhiteBlacklist(any, any)).thenAnswer((_) async { - return SetWhiteBlacklistResponse( - result: APiResponseType.success, - data: DomainResult(success: true, message: 'Added white.example.com'), - ); - }); - - // mock AppConfigProvider - const showingSnackbar = false; - when(mockConfigProvider.showingSnackbar).thenReturn(showingSnackbar); - when(mockConfigProvider.setShowingSnackbar(any)).thenAnswer((_) {}); - when(mockConfigProvider.logsPerQuery).thenReturn(2); - when(mockServersProvider.colors).thenReturn(lightAppColors); - - // mock ServersProvider - when(mockServersProvider.selectedServer).thenReturn(server); - when(mockServersProvider.selectedApiGateway).thenReturn(mockApiGatewayV6); - when(mockServersProvider.numShown).thenReturn(14); - when(mockServersProvider.getQueryStatus(any)) - .thenReturn(queryStatusesV6[3 - 1]); - - // mock FiltersProvier - when(mockFiltersProvider.statusSelected) - .thenReturn([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]); - when(mockFiltersProvider.selectedClients).thenReturn(['192.168.100.2']); - when(mockFiltersProvider.selectedDomain).thenReturn('white.example.com'); - when(mockFiltersProvider.startTime).thenReturn(DateTime.now()); - when(mockFiltersProvider.endTime) - .thenReturn(DateTime.now().add(const Duration(hours: 2))); - when(mockFiltersProvider.resetFilters()).thenReturn(null); - when(mockFiltersProvider.totalClients) - .thenReturn(['localhost', '192.168.100.2']); - when(mockFiltersProvider.resetTime()).thenReturn(null); - when(mockFiltersProvider.resetStatus()).thenReturn(null); - when(mockFiltersProvider.resetClients()).thenReturn(null); - when(mockFiltersProvider.setSelectedDomain(null)).thenReturn(null); - when(mockFiltersProvider.statusAllowedAndRetried) - .thenReturn([3, 4, 13, 14, 15]); - }); - testWidgets( - 'should mobile screen layout', - (WidgetTester tester) async { - tester.view.physicalSize = const Size(800, 400); - tester.view.devicePixelRatio = 1.0; + testWidgets( + 'should show logs screen on mobile layout', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; - addTearDown(() { - tester.view.resetPhysicalSize(); - tester.view.resetDevicePixelRatio(); - }); + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); - await tester.pumpWidget( - MultiProvider( - providers: [ - ChangeNotifierProvider( - create: (context) => mockServersProvider, - ), - ChangeNotifierProxyProvider( - create: (context) => mockFiltersProvider, - update: (context, serverConfig, servers) => - servers!..update(serverConfig), - ), - ChangeNotifierProvider( - create: (context) => mockConfigProvider, - ), - ChangeNotifierProxyProvider( - create: (context) => mockServersProvider, - update: (context, appConfig, servers) => - servers!..update(appConfig), - ), - ], - child: MaterialApp( - home: const Scaffold( - body: Logs(), - ), - localizationsDelegates: const [ - GlobalMaterialLocalizations.delegate, - AppLocalizations.delegate, - ], - scaffoldMessengerKey: scaffoldMessengerKey, + await tester.pumpWidget( + testSetup.buildTestWidget( + const Logs(), ), - ), - ); - - // Show logs screen - expect(find.byType(Logs), findsOneWidget); - await tester.pumpAndSettle(); - expect(find.text('Query logs'), findsOneWidget); - expect( - find.text('Choose a query log to see its details.'), - findsNothing, - ); - }, - ); - - testWidgets( - 'should set blacklist domains', - (WidgetTester tester) async { - tester.view.physicalSize = const Size(1000, 400); - tester.view.devicePixelRatio = 1.0; - - addTearDown(() { - tester.view.resetPhysicalSize(); - tester.view.resetDevicePixelRatio(); - }); - - await tester.pumpWidget( - DynamicColorBuilder( - builder: (lightDynamic, darkDynamic) { - return MultiProvider( - providers: [ - ChangeNotifierProvider( - create: (context) => mockServersProvider, - ), - ChangeNotifierProxyProvider( - create: (context) => mockFiltersProvider, - update: (context, serverConfig, servers) => - servers!..update(serverConfig), - ), - ChangeNotifierProvider( - create: (context) => mockConfigProvider, - ), - ChangeNotifierProxyProvider( - create: (context) => mockServersProvider, - update: (context, appConfig, servers) => - servers!..update(appConfig), - ), - ], - child: MaterialApp( - theme: lightTheme(lightDynamic), - darkTheme: darkTheme(darkDynamic), - themeMode: ThemeMode.light, - home: const Scaffold( - body: Logs(), - ), - localizationsDelegates: const [ - GlobalMaterialLocalizations.delegate, - AppLocalizations.delegate, - ], - scaffoldMessengerKey: scaffoldMessengerKey, - ), - ); - }, - ), - ); - - // Show logs screen - expect(find.byType(Logs), findsOneWidget); - await tester.pumpAndSettle(); - expect(find.text('Query logs'), findsOneWidget); - // expect(find.text('white.example.com'), findsOneWidget); why two widgets? - expect(find.text('white.example.com'), findsWidgets); - expect( - find.text('Choose a query log to see its details.'), - findsOneWidget, - ); - - // Tap whitelist domain to open domain detail screen - await tester.tap(find.text('white.example.com').at(0)); - await tester.pumpAndSettle(); - expect(find.text('Log details'), findsOneWidget); - - // Tap blacklist button - expect(find.byIcon(Icons.gpp_bad_rounded), findsOneWidget); - await tester.tap(find.byIcon(Icons.gpp_bad_rounded)); - await tester.pump(const Duration(milliseconds: 1000)); - - // Return to logs screen (Not raise Exception) - expect(find.text('Domain added to blacklist.'), findsWidgets); - expect(find.byType(Logs), findsOneWidget); - }, - ); - }); + ); + + // Show logs screen + expect(find.byType(Logs), findsOneWidget); + await tester.pumpAndSettle(); + expect(find.text('Query logs'), findsOneWidget); + expect( + find.text('Choose a query log to see its details.'), + findsNothing, + ); + }, + ); + + testWidgets( + 'should set blacklist domains on tablet layout', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(2176, 1600); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget(const Logs()), + ); + + // Show logs screen + expect(find.byType(Logs), findsOneWidget); + await tester.pumpAndSettle(); + expect(find.text('Query logs'), findsOneWidget); + expect(find.text('white.example.com'), findsWidgets); + expect( + find.text('Choose a query log to see its details.'), + findsOneWidget, + ); + + // Tap whitelist domain to open domain detail screen + await tester.tap(find.text('white.example.com').at(0)); + await tester.pumpAndSettle(); + expect(find.text('Log details'), findsOneWidget); + + // Tap blacklist button + expect(find.byIcon(Icons.gpp_bad_rounded), findsOneWidget); + await tester.tap(find.byIcon(Icons.gpp_bad_rounded)); + await tester.pump(const Duration(milliseconds: 1000)); + + // Return to logs screen (Not raise Exception) + expect(find.text('Domain added to blacklist.'), findsWidgets); + expect(find.byType(Logs), findsOneWidget); + }, + ); + }, + ); } diff --git a/test/widgets/logs/logs_test.mocks.dart b/test/widgets/logs/logs_test.mocks.dart deleted file mode 100644 index 2286ceb4..00000000 --- a/test/widgets/logs/logs_test.mocks.dart +++ /dev/null @@ -1,1238 +0,0 @@ -// Mocks generated by Mockito 5.4.5 from annotations -// in pi_hole_client/test/widgets/logs/logs_test.dart. -// Do not manually edit this file. - -// ignore_for_file: no_leading_underscores_for_library_prefixes -import 'dart:async' as _i12; -import 'dart:ui' as _i14; - -import 'package:device_info_plus/device_info_plus.dart' as _i11; -import 'package:flutter/material.dart' as _i7; -import 'package:http/http.dart' as _i4; -import 'package:mockito/mockito.dart' as _i1; -import 'package:mockito/src/dummies.dart' as _i8; -import 'package:package_info_plus/package_info_plus.dart' as _i10; -import 'package:pi_hole_client/config/theme.dart' as _i2; -import 'package:pi_hole_client/gateways/api_gateway_interface.dart' as _i19; -import 'package:pi_hole_client/gateways/v6/api_gateway_v6.dart' as _i20; -import 'package:pi_hole_client/models/app_log.dart' as _i9; -import 'package:pi_hole_client/models/domain.dart' as _i21; -import 'package:pi_hole_client/models/gateways.dart' as _i5; -import 'package:pi_hole_client/models/query_status.dart' as _i18; -import 'package:pi_hole_client/models/repository/database.dart' as _i13; -import 'package:pi_hole_client/models/server.dart' as _i3; -import 'package:pi_hole_client/providers/app_config_provider.dart' as _i6; -import 'package:pi_hole_client/providers/filters_provider.dart' as _i15; -import 'package:pi_hole_client/providers/servers_provider.dart' as _i17; -import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart' as _i16; - -// ignore_for_file: type=lint -// ignore_for_file: avoid_redundant_argument_values -// ignore_for_file: avoid_setters_without_getters -// ignore_for_file: comment_references -// ignore_for_file: deprecated_member_use -// ignore_for_file: deprecated_member_use_from_same_package -// ignore_for_file: implementation_imports -// ignore_for_file: invalid_use_of_visible_for_testing_member -// ignore_for_file: must_be_immutable -// ignore_for_file: prefer_const_constructors -// ignore_for_file: unnecessary_parenthesis -// ignore_for_file: camel_case_types -// ignore_for_file: subtype_of_sealed_class - -class _FakeAppColors_0 extends _i1.SmartFake implements _i2.AppColors { - _FakeAppColors_0( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeServer_1 extends _i1.SmartFake implements _i3.Server { - _FakeServer_1( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeResponse_2 extends _i1.SmartFake implements _i4.Response { - _FakeResponse_2( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeLoginQueryResponse_3 extends _i1.SmartFake - implements _i5.LoginQueryResponse { - _FakeLoginQueryResponse_3( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeRealtimeStatusResponse_4 extends _i1.SmartFake - implements _i5.RealtimeStatusResponse { - _FakeRealtimeStatusResponse_4( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeDisableServerResponse_5 extends _i1.SmartFake - implements _i5.DisableServerResponse { - _FakeDisableServerResponse_5( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeEnableServerResponse_6 extends _i1.SmartFake - implements _i5.EnableServerResponse { - _FakeEnableServerResponse_6( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeFetchOverTimeDataResponse_7 extends _i1.SmartFake - implements _i5.FetchOverTimeDataResponse { - _FakeFetchOverTimeDataResponse_7( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeFetchLogsResponse_8 extends _i1.SmartFake - implements _i5.FetchLogsResponse { - _FakeFetchLogsResponse_8( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeSetWhiteBlacklistResponse_9 extends _i1.SmartFake - implements _i5.SetWhiteBlacklistResponse { - _FakeSetWhiteBlacklistResponse_9( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeGetDomainLists_10 extends _i1.SmartFake - implements _i5.GetDomainLists { - _FakeGetDomainLists_10( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeRemoveDomainFromListResponse_11 extends _i1.SmartFake - implements _i5.RemoveDomainFromListResponse { - _FakeRemoveDomainFromListResponse_11( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -class _FakeAddDomainToListResponse_12 extends _i1.SmartFake - implements _i5.AddDomainToListResponse { - _FakeAddDomainToListResponse_12( - Object parent, - Invocation parentInvocation, - ) : super( - parent, - parentInvocation, - ); -} - -/// A class which mocks [AppConfigProvider]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockAppConfigProvider extends _i1.Mock implements _i6.AppConfigProvider { - MockAppConfigProvider() { - _i1.throwOnMissingStub(this); - } - - @override - _i2.AppColors get colors => (super.noSuchMethod( - Invocation.getter(#colors), - returnValue: _FakeAppColors_0( - this, - Invocation.getter(#colors), - ), - ) as _i2.AppColors); - - @override - bool get showingSnackbar => (super.noSuchMethod( - Invocation.getter(#showingSnackbar), - returnValue: false, - ) as bool); - - @override - int get selectedTab => (super.noSuchMethod( - Invocation.getter(#selectedTab), - returnValue: 0, - ) as int); - - @override - _i7.ThemeMode get selectedTheme => (super.noSuchMethod( - Invocation.getter(#selectedTheme), - returnValue: _i7.ThemeMode.system, - ) as _i7.ThemeMode); - - @override - String get selectedLanguage => (super.noSuchMethod( - Invocation.getter(#selectedLanguage), - returnValue: _i8.dummyValue( - this, - Invocation.getter(#selectedLanguage), - ), - ) as String); - - @override - int get selectedThemeNumber => (super.noSuchMethod( - Invocation.getter(#selectedThemeNumber), - returnValue: 0, - ) as int); - - @override - int get selectedLanguageNumber => (super.noSuchMethod( - Invocation.getter(#selectedLanguageNumber), - returnValue: 0, - ) as int); - - @override - bool get overrideSslCheck => (super.noSuchMethod( - Invocation.getter(#overrideSslCheck), - returnValue: false, - ) as bool); - - @override - bool get reducedDataCharts => (super.noSuchMethod( - Invocation.getter(#reducedDataCharts), - returnValue: false, - ) as bool); - - @override - double get logsPerQuery => (super.noSuchMethod( - Invocation.getter(#logsPerQuery), - returnValue: 0.0, - ) as double); - - @override - bool get biometricsSupport => (super.noSuchMethod( - Invocation.getter(#biometricsSupport), - returnValue: false, - ) as bool); - - @override - bool get useBiometrics => (super.noSuchMethod( - Invocation.getter(#useBiometrics), - returnValue: false, - ) as bool); - - @override - bool get appUnlocked => (super.noSuchMethod( - Invocation.getter(#appUnlocked), - returnValue: false, - ) as bool); - - @override - bool get validVibrator => (super.noSuchMethod( - Invocation.getter(#validVibrator), - returnValue: false, - ) as bool); - - @override - bool get importantInfoReaden => (super.noSuchMethod( - Invocation.getter(#importantInfoReaden), - returnValue: false, - ) as bool); - - @override - bool get hideZeroValues => (super.noSuchMethod( - Invocation.getter(#hideZeroValues), - returnValue: false, - ) as bool); - - @override - int get statisticsVisualizationMode => (super.noSuchMethod( - Invocation.getter(#statisticsVisualizationMode), - returnValue: 0, - ) as int); - - @override - bool get sendCrashReports => (super.noSuchMethod( - Invocation.getter(#sendCrashReports), - returnValue: false, - ) as bool); - - @override - List<_i9.AppLog> get logs => (super.noSuchMethod( - Invocation.getter(#logs), - returnValue: <_i9.AppLog>[], - ) as List<_i9.AppLog>); - - @override - bool get hasListeners => (super.noSuchMethod( - Invocation.getter(#hasListeners), - returnValue: false, - ) as bool); - - @override - void setShowingSnackbar(bool? status) => super.noSuchMethod( - Invocation.method( - #setShowingSnackbar, - [status], - ), - returnValueForMissingStub: null, - ); - - @override - void setSelectedTab(int? selectedTab) => super.noSuchMethod( - Invocation.method( - #setSelectedTab, - [selectedTab], - ), - returnValueForMissingStub: null, - ); - - @override - void setAppInfo(_i10.PackageInfo? appInfo) => super.noSuchMethod( - Invocation.method( - #setAppInfo, - [appInfo], - ), - returnValueForMissingStub: null, - ); - - @override - void setAndroidInfo(_i11.AndroidDeviceInfo? deviceInfo) => super.noSuchMethod( - Invocation.method( - #setAndroidInfo, - [deviceInfo], - ), - returnValueForMissingStub: null, - ); - - @override - void setIosInfo(_i11.IosDeviceInfo? deviceInfo) => super.noSuchMethod( - Invocation.method( - #setIosInfo, - [deviceInfo], - ), - returnValueForMissingStub: null, - ); - - @override - void setBiometricsSupport(bool? isSupported) => super.noSuchMethod( - Invocation.method( - #setBiometricsSupport, - [isSupported], - ), - returnValueForMissingStub: null, - ); - - @override - void setAppUnlocked(bool? status) => super.noSuchMethod( - Invocation.method( - #setAppUnlocked, - [status], - ), - returnValueForMissingStub: null, - ); - - @override - void setValidVibrator(bool? valid) => super.noSuchMethod( - Invocation.method( - #setValidVibrator, - [valid], - ), - returnValueForMissingStub: null, - ); - - @override - void addLog(_i9.AppLog? log) => super.noSuchMethod( - Invocation.method( - #addLog, - [log], - ), - returnValueForMissingStub: null, - ); - - @override - void setSelectedSettingsScreen({ - required int? screen, - bool? notify, - }) => - super.noSuchMethod( - Invocation.method( - #setSelectedSettingsScreen, - [], - { - #screen: screen, - #notify: notify, - }, - ), - returnValueForMissingStub: null, - ); - - @override - _i12.Future setUseBiometrics(bool? biometrics) => (super.noSuchMethod( - Invocation.method( - #setUseBiometrics, - [biometrics], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setImportantInfoReaden(bool? status) => (super.noSuchMethod( - Invocation.method( - #setImportantInfoReaden, - [status], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setPassCode(String? code) => (super.noSuchMethod( - Invocation.method( - #setPassCode, - [code], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setAutoRefreshTime(int? seconds) => (super.noSuchMethod( - Invocation.method( - #setAutoRefreshTime, - [seconds], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setLogsPerQuery(double? time) => (super.noSuchMethod( - Invocation.method( - #setLogsPerQuery, - [time], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setSendCrashReports(bool? status) => (super.noSuchMethod( - Invocation.method( - #setSendCrashReports, - [status], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - void saveFromDb(_i13.AppDbData? dbData) => super.noSuchMethod( - Invocation.method( - #saveFromDb, - [dbData], - ), - returnValueForMissingStub: null, - ); - - @override - _i12.Future setOverrideSslCheck(bool? status) => (super.noSuchMethod( - Invocation.method( - #setOverrideSslCheck, - [status], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setReducedDataCharts(bool? status) => (super.noSuchMethod( - Invocation.method( - #setReducedDataCharts, - [status], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setHideZeroValues(bool? status) => (super.noSuchMethod( - Invocation.method( - #setHideZeroValues, - [status], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setSelectedTheme(int? value) => (super.noSuchMethod( - Invocation.method( - #setSelectedTheme, - [value], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setSelectedLanguage(String? value) => (super.noSuchMethod( - Invocation.method( - #setSelectedLanguage, - [value], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setStatisticsVisualizationMode(int? value) => - (super.noSuchMethod( - Invocation.method( - #setStatisticsVisualizationMode, - [value], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future restoreAppConfig() => (super.noSuchMethod( - Invocation.method( - #restoreAppConfig, - [], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #addListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #removeListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void dispose() => super.noSuchMethod( - Invocation.method( - #dispose, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void notifyListeners() => super.noSuchMethod( - Invocation.method( - #notifyListeners, - [], - ), - returnValueForMissingStub: null, - ); -} - -/// A class which mocks [FiltersProvider]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockFiltersProvider extends _i1.Mock implements _i15.FiltersProvider { - MockFiltersProvider() { - _i1.throwOnMissingStub(this); - } - - @override - List get statusAllowedAndRetried => (super.noSuchMethod( - Invocation.getter(#statusAllowedAndRetried), - returnValue: [], - ) as List); - - @override - List get defaultSelected => (super.noSuchMethod( - Invocation.getter(#defaultSelected), - returnValue: [], - ) as List); - - @override - List get statusSelected => (super.noSuchMethod( - Invocation.getter(#statusSelected), - returnValue: [], - ) as List); - - @override - String get statusSelectedString => (super.noSuchMethod( - Invocation.getter(#statusSelectedString), - returnValue: _i8.dummyValue( - this, - Invocation.getter(#statusSelectedString), - ), - ) as String); - - @override - List get totalClients => (super.noSuchMethod( - Invocation.getter(#totalClients), - returnValue: [], - ) as List); - - @override - List get selectedClients => (super.noSuchMethod( - Invocation.getter(#selectedClients), - returnValue: [], - ) as List); - - @override - _i16.RequestStatus get requestStatus => (super.noSuchMethod( - Invocation.getter(#requestStatus), - returnValue: _i16.RequestStatus.all, - ) as _i16.RequestStatus); - - @override - bool get hasListeners => (super.noSuchMethod( - Invocation.getter(#hasListeners), - returnValue: false, - ) as bool); - - @override - void update(_i17.ServersProvider? provider) => super.noSuchMethod( - Invocation.method( - #update, - [provider], - ), - returnValueForMissingStub: null, - ); - - @override - void setStatusSelected(List? values) => super.noSuchMethod( - Invocation.method( - #setStatusSelected, - [values], - ), - returnValueForMissingStub: null, - ); - - @override - void setStartTime(DateTime? value) => super.noSuchMethod( - Invocation.method( - #setStartTime, - [value], - ), - returnValueForMissingStub: null, - ); - - @override - void setEndTime(DateTime? value) => super.noSuchMethod( - Invocation.method( - #setEndTime, - [value], - ), - returnValueForMissingStub: null, - ); - - @override - void resetFilters() => super.noSuchMethod( - Invocation.method( - #resetFilters, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void resetTime() => super.noSuchMethod( - Invocation.method( - #resetTime, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void resetStatus() => super.noSuchMethod( - Invocation.method( - #resetStatus, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void setClients(List? clients) => super.noSuchMethod( - Invocation.method( - #setClients, - [clients], - ), - returnValueForMissingStub: null, - ); - - @override - void setSelectedClients(List? selectedClients) => super.noSuchMethod( - Invocation.method( - #setSelectedClients, - [selectedClients], - ), - returnValueForMissingStub: null, - ); - - @override - void setSelectedDomain(String? domain) => super.noSuchMethod( - Invocation.method( - #setSelectedDomain, - [domain], - ), - returnValueForMissingStub: null, - ); - - @override - void resetClients() => super.noSuchMethod( - Invocation.method( - #resetClients, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void setRequestStatus(_i16.RequestStatus? status) => super.noSuchMethod( - Invocation.method( - #setRequestStatus, - [status], - ), - returnValueForMissingStub: null, - ); - - @override - void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #addListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #removeListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void dispose() => super.noSuchMethod( - Invocation.method( - #dispose, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void notifyListeners() => super.noSuchMethod( - Invocation.method( - #notifyListeners, - [], - ), - returnValueForMissingStub: null, - ); -} - -/// A class which mocks [ServersProvider]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockServersProvider extends _i1.Mock implements _i17.ServersProvider { - MockServersProvider() { - _i1.throwOnMissingStub(this); - } - - @override - _i2.AppColors get colors => (super.noSuchMethod( - Invocation.getter(#colors), - returnValue: _FakeAppColors_0( - this, - Invocation.getter(#colors), - ), - ) as _i2.AppColors); - - @override - List<_i3.Server> get getServersList => (super.noSuchMethod( - Invocation.getter(#getServersList), - returnValue: <_i3.Server>[], - ) as List<_i3.Server>); - - @override - int get numShown => (super.noSuchMethod( - Invocation.getter(#numShown), - returnValue: 0, - ) as int); - - @override - List<_i18.QueryStatus> get queryStatuses => (super.noSuchMethod( - Invocation.getter(#queryStatuses), - returnValue: <_i18.QueryStatus>[], - ) as List<_i18.QueryStatus>); - - @override - bool get hasListeners => (super.noSuchMethod( - Invocation.getter(#hasListeners), - returnValue: false, - ) as bool); - - @override - void update(_i6.AppConfigProvider? provider) => super.noSuchMethod( - Invocation.method( - #update, - [provider], - ), - returnValueForMissingStub: null, - ); - - @override - _i19.ApiGateway? loadApiGateway(_i3.Server? server) => - (super.noSuchMethod(Invocation.method( - #loadApiGateway, - [server], - )) as _i19.ApiGateway?); - - @override - _i18.QueryStatus? getQueryStatus(String? key) => - (super.noSuchMethod(Invocation.method( - #getQueryStatus, - [key], - )) as _i18.QueryStatus?); - - @override - _i18.QueryStatus? findQueryStatus(String? key) => - (super.noSuchMethod(Invocation.method( - #findQueryStatus, - [key], - )) as _i18.QueryStatus?); - - @override - _i12.Future addServer(_i3.Server? server) => (super.noSuchMethod( - Invocation.method( - #addServer, - [server], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future editServer(_i3.Server? server) => (super.noSuchMethod( - Invocation.method( - #editServer, - [server], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future removeServer(String? serverAddress) => (super.noSuchMethod( - Invocation.method( - #removeServer, - [serverAddress], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future setDefaultServer(_i3.Server? server) => (super.noSuchMethod( - Invocation.method( - #setDefaultServer, - [server], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future saveFromDb(List<_i13.ServerDbData>? servers) => - (super.noSuchMethod( - Invocation.method( - #saveFromDb, - [servers], - ), - returnValue: _i12.Future.value(), - ) as _i12.Future); - - @override - _i12.FutureOr> checkUrlExists(String? url) => - (super.noSuchMethod( - Invocation.method( - #checkUrlExists, - [url], - ), - returnValue: - _i12.Future>.value({}), - ) as _i12.FutureOr>); - - @override - void setselectedServer({ - required _i3.Server? server, - bool? toHomeTab, - }) => - super.noSuchMethod( - Invocation.method( - #setselectedServer, - [], - { - #server: server, - #toHomeTab: toHomeTab, - }, - ), - returnValueForMissingStub: null, - ); - - @override - void updateselectedServerStatus(bool? enabled) => super.noSuchMethod( - Invocation.method( - #updateselectedServerStatus, - [enabled], - ), - returnValueForMissingStub: null, - ); - - @override - _i12.Future deleteDbData() => (super.noSuchMethod( - Invocation.method( - #deleteDbData, - [], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - _i12.Future resetSelectedServer() => (super.noSuchMethod( - Invocation.method( - #resetSelectedServer, - [], - ), - returnValue: _i12.Future.value(false), - ) as _i12.Future); - - @override - void addListener(_i14.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #addListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void removeListener(_i14.VoidCallback? listener) => super.noSuchMethod( - Invocation.method( - #removeListener, - [listener], - ), - returnValueForMissingStub: null, - ); - - @override - void dispose() => super.noSuchMethod( - Invocation.method( - #dispose, - [], - ), - returnValueForMissingStub: null, - ); - - @override - void notifyListeners() => super.noSuchMethod( - Invocation.method( - #notifyListeners, - [], - ), - returnValueForMissingStub: null, - ); -} - -/// A class which mocks [ApiGatewayV6]. -/// -/// See the documentation for Mockito's code generation for more information. -class MockApiGatewayV6 extends _i1.Mock implements _i20.ApiGatewayV6 { - MockApiGatewayV6() { - _i1.throwOnMissingStub(this); - } - - @override - _i3.Server get server => (super.noSuchMethod( - Invocation.getter(#server), - returnValue: _FakeServer_1( - this, - Invocation.getter(#server), - ), - ) as _i3.Server); - - @override - _i12.Future<_i4.Response> httpClient({ - required String? method, - required String? url, - Map? headers, - Map? body, - int? timeout = 10, - int? maxRetries = 1, - }) => - (super.noSuchMethod( - Invocation.method( - #httpClient, - [], - { - #method: method, - #url: url, - #headers: headers, - #body: body, - #timeout: timeout, - #maxRetries: maxRetries, - }, - ), - returnValue: _i12.Future<_i4.Response>.value(_FakeResponse_2( - this, - Invocation.method( - #httpClient, - [], - { - #method: method, - #url: url, - #headers: headers, - #body: body, - #timeout: timeout, - #maxRetries: maxRetries, - }, - ), - )), - ) as _i12.Future<_i4.Response>); - - @override - _i12.Future<_i5.LoginQueryResponse> loginQuery({bool? refresh = false}) => - (super.noSuchMethod( - Invocation.method( - #loginQuery, - [], - {#refresh: refresh}, - ), - returnValue: - _i12.Future<_i5.LoginQueryResponse>.value(_FakeLoginQueryResponse_3( - this, - Invocation.method( - #loginQuery, - [], - {#refresh: refresh}, - ), - )), - ) as _i12.Future<_i5.LoginQueryResponse>); - - @override - _i12.Future<_i5.RealtimeStatusResponse> realtimeStatus() => - (super.noSuchMethod( - Invocation.method( - #realtimeStatus, - [], - ), - returnValue: _i12.Future<_i5.RealtimeStatusResponse>.value( - _FakeRealtimeStatusResponse_4( - this, - Invocation.method( - #realtimeStatus, - [], - ), - )), - ) as _i12.Future<_i5.RealtimeStatusResponse>); - - @override - _i12.Future<_i5.DisableServerResponse> disableServerRequest(int? time) => - (super.noSuchMethod( - Invocation.method( - #disableServerRequest, - [time], - ), - returnValue: _i12.Future<_i5.DisableServerResponse>.value( - _FakeDisableServerResponse_5( - this, - Invocation.method( - #disableServerRequest, - [time], - ), - )), - ) as _i12.Future<_i5.DisableServerResponse>); - - @override - _i12.Future<_i5.EnableServerResponse> enableServerRequest() => - (super.noSuchMethod( - Invocation.method( - #enableServerRequest, - [], - ), - returnValue: _i12.Future<_i5.EnableServerResponse>.value( - _FakeEnableServerResponse_6( - this, - Invocation.method( - #enableServerRequest, - [], - ), - )), - ) as _i12.Future<_i5.EnableServerResponse>); - - @override - _i12.Future<_i5.FetchOverTimeDataResponse> fetchOverTimeData() => - (super.noSuchMethod( - Invocation.method( - #fetchOverTimeData, - [], - ), - returnValue: _i12.Future<_i5.FetchOverTimeDataResponse>.value( - _FakeFetchOverTimeDataResponse_7( - this, - Invocation.method( - #fetchOverTimeData, - [], - ), - )), - ) as _i12.Future<_i5.FetchOverTimeDataResponse>); - - @override - _i12.Future<_i5.FetchLogsResponse> fetchLogs( - DateTime? from, - DateTime? until, - ) => - (super.noSuchMethod( - Invocation.method( - #fetchLogs, - [ - from, - until, - ], - ), - returnValue: - _i12.Future<_i5.FetchLogsResponse>.value(_FakeFetchLogsResponse_8( - this, - Invocation.method( - #fetchLogs, - [ - from, - until, - ], - ), - )), - ) as _i12.Future<_i5.FetchLogsResponse>); - - @override - _i12.Future<_i5.SetWhiteBlacklistResponse> setWhiteBlacklist( - String? domain, - String? list, - ) => - (super.noSuchMethod( - Invocation.method( - #setWhiteBlacklist, - [ - domain, - list, - ], - ), - returnValue: _i12.Future<_i5.SetWhiteBlacklistResponse>.value( - _FakeSetWhiteBlacklistResponse_9( - this, - Invocation.method( - #setWhiteBlacklist, - [ - domain, - list, - ], - ), - )), - ) as _i12.Future<_i5.SetWhiteBlacklistResponse>); - - @override - _i12.Future<_i5.GetDomainLists> getDomainLists() => (super.noSuchMethod( - Invocation.method( - #getDomainLists, - [], - ), - returnValue: - _i12.Future<_i5.GetDomainLists>.value(_FakeGetDomainLists_10( - this, - Invocation.method( - #getDomainLists, - [], - ), - )), - ) as _i12.Future<_i5.GetDomainLists>); - - @override - _i12.Future<_i5.RemoveDomainFromListResponse> removeDomainFromList( - _i21.Domain? domain) => - (super.noSuchMethod( - Invocation.method( - #removeDomainFromList, - [domain], - ), - returnValue: _i12.Future<_i5.RemoveDomainFromListResponse>.value( - _FakeRemoveDomainFromListResponse_11( - this, - Invocation.method( - #removeDomainFromList, - [domain], - ), - )), - ) as _i12.Future<_i5.RemoveDomainFromListResponse>); - - @override - _i12.Future<_i5.AddDomainToListResponse> addDomainToList( - Map? domainData) => - (super.noSuchMethod( - Invocation.method( - #addDomainToList, - [domainData], - ), - returnValue: _i12.Future<_i5.AddDomainToListResponse>.value( - _FakeAddDomainToListResponse_12( - this, - Invocation.method( - #addDomainToList, - [domainData], - ), - )), - ) as _i12.Future<_i5.AddDomainToListResponse>); -} From 1c8da837ced145c2fce58099015a0d1e2f10d4bf Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Sun, 26 Jan 2025 18:55:48 +0900 Subject: [PATCH 2/6] Add logs tests --- test/widgets/helpers.dart | 2 + test/widgets/logs/logs_test.dart | 120 +++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) diff --git a/test/widgets/helpers.dart b/test/widgets/helpers.dart index 51cfe6e6..f3d463ff 100644 --- a/test/widgets/helpers.dart +++ b/test/widgets/helpers.dart @@ -28,6 +28,7 @@ import 'package:pi_hole_client/providers/domains_list_provider.dart'; import 'package:pi_hole_client/providers/filters_provider.dart'; import 'package:pi_hole_client/providers/servers_provider.dart'; import 'package:pi_hole_client/providers/status_provider.dart'; +import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart'; import 'package:provider/provider.dart'; import './helpers.mocks.dart'; @@ -918,6 +919,7 @@ class TestSetupHelper { when(mockFiltersProvider.statusAllowedAndRetried).thenReturn( useApiGatewayVersion == 'v5' ? [2, 3, 12, 13, 14] : [3, 4, 13, 14, 15], ); + when(mockFiltersProvider.requestStatus).thenReturn(RequestStatus.all); } void _initStatusProviderMock(String useApiGatewayVersion) { diff --git a/test/widgets/logs/logs_test.dart b/test/widgets/logs/logs_test.dart index bcc4bd99..29d64c0a 100644 --- a/test/widgets/logs/logs_test.dart +++ b/test/widgets/logs/logs_test.dart @@ -1,6 +1,8 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:mockito/mockito.dart'; import 'package:pi_hole_client/screens/logs/logs.dart'; +import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart'; import '../helpers.dart'; @@ -38,6 +40,7 @@ void main() async { expect(find.byType(Logs), findsOneWidget); await tester.pumpAndSettle(); expect(find.text('Query logs'), findsOneWidget); + expect(find.text('white.example.com'), findsWidgets); expect( find.text('Choose a query log to see its details.'), findsNothing, @@ -85,6 +88,123 @@ void main() async { expect(find.byType(Logs), findsOneWidget); }, ); + + testWidgets( + 'should search logs', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget( + const Logs(), + ), + ); + + expect(find.byType(Logs), findsOneWidget); + expect(find.text('Query logs'), findsOneWidget); + await tester.pumpAndSettle(); + expect(find.text('white.example.com'), findsWidgets); + + expect(find.byIcon(Icons.search_rounded), findsOneWidget); + await tester.tap(find.byIcon(Icons.search_rounded)); + await tester.pumpAndSettle(); + expect(find.text('Search by URL...'), findsOneWidget); + await tester.enterText(find.byType(TextField), 'not.com'); + await tester.pumpAndSettle(); + + expect(find.text('white.example.com'), findsNothing); + }, + ); + + // testWidgets( + // 'should filter logs', + // (WidgetTester tester) async { + // tester.view.physicalSize = const Size(1080, 2400); + // tester.view.devicePixelRatio = 2.0; + + // addTearDown(() { + // tester.view.resetPhysicalSize(); + // tester.view.resetDevicePixelRatio(); + // }); + + // await tester.pumpWidget( + // testSetup.buildTestWidget( + // const Logs(), + // ), + // ); + + // // show logs screen + // expect(find.byType(Logs), findsOneWidget); + // expect(find.text('Query logs'), findsOneWidget); + // await tester.pumpAndSettle(); + // expect(find.text('white.example.com'), findsWidgets); + + // // tap filter button + // expect(find.byIcon(Icons.filter_list_rounded), findsOneWidget); + // await tester.tap(find.byIcon(Icons.filter_list_rounded)); + // await tester.pumpAndSettle(); + + // // show filter modal + // expect(find.byType(LogsFiltersModal), findsOneWidget); + // expect(find.text('Filters'), findsOneWidget); + // expect(find.text('Blocked'), findsOneWidget); + // expect(find.text('Apply'), findsOneWidget); + + // // tap blocked filter + // await tester.tap(find.text('Blocked')); + // await tester.pumpAndSettle(); + + // // apply filter and close modal + // await tester.tap(find.text('Apply')); + // await tester.pumpAndSettle(); + // // when(testSetup.mockFiltersProvider.requestStatus) + // // .thenReturn(RequestStatus.blocked); + + // // expect(find.text('status selected'), findsOneWidget); + // // expect(find.text('white.example.com'), findsNothing); + // }, + // ); + + // testWidgets( + // 'should sort logs', + // (WidgetTester tester) async { + // tester.view.physicalSize = const Size(1080, 2400); + // tester.view.devicePixelRatio = 2.0; + + // addTearDown(() { + // tester.view.resetPhysicalSize(); + // tester.view.resetDevicePixelRatio(); + // }); + + // await tester.pumpWidget( + // testSetup.buildTestWidget( + // const Logs(), + // ), + // ); + + // expect(find.byType(Logs), findsOneWidget); + // expect(find.text('Query logs'), findsOneWidget); + // await tester.pumpAndSettle(); + // expect(find.text('white.example.com'), findsWidgets); + + // expect(find.byIcon(Icons.sort_rounded), findsOneWidget); + // await tester.tap(find.byIcon(Icons.sort_rounded)); + // await tester.pump(); + // await tester.pumpAndSettle(); + // expect(find.text('From Latest to oldest'), findsOneWidget); + // expect(find.text('From oldest to latest'), findsOneWidget); + // await tester.tap(find.text('From oldest to latest')); + // await tester.pumpAndSettle(); + + // expect(find.byType(Logs), findsOneWidget); + // }, + // ); }, ); } From 35a6909709cb6f8a4404fc88a6ab5dad0df6330b Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Sun, 26 Jan 2025 20:09:36 +0900 Subject: [PATCH 3/6] Add logs tests --- test/widgets/helpers.dart | 8 ++ .../logs/clients_filters_modal_test.dart | 92 +++++++++++++++ .../widgets/logs/logs_filters_modal_test.dart | 51 +++++++++ test/widgets/logs/logs_test.dart | 2 - .../logs/status_filters_modal_test.dart | 106 ++++++++++++++++++ 5 files changed, 257 insertions(+), 2 deletions(-) create mode 100644 test/widgets/logs/clients_filters_modal_test.dart create mode 100644 test/widgets/logs/logs_filters_modal_test.dart create mode 100644 test/widgets/logs/status_filters_modal_test.dart diff --git a/test/widgets/helpers.dart b/test/widgets/helpers.dart index f3d463ff..0854af4e 100644 --- a/test/widgets/helpers.dart +++ b/test/widgets/helpers.dart @@ -896,6 +896,9 @@ class TestSetupHelper { when(mockServersProvider.deleteDbData()).thenAnswer((_) async => true); when(mockServersProvider.getServersList).thenReturn([serverV6]); when(mockServersProvider.colors).thenReturn(lightAppColors); + when(mockServersProvider.queryStatuses).thenReturn( + useApiGatewayVersion == 'v5' ? queryStatusesV5 : queryStatusesV6, + ); } void _initFiltersProviderMock(String useApiGatewayVersion) { @@ -920,6 +923,11 @@ class TestSetupHelper { useApiGatewayVersion == 'v5' ? [2, 3, 12, 13, 14] : [3, 4, 13, 14, 15], ); when(mockFiltersProvider.requestStatus).thenReturn(RequestStatus.all); + when(mockFiltersProvider.defaultSelected).thenReturn( + useApiGatewayVersion == 'v5' + ? [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 14] + : [2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15], + ); } void _initStatusProviderMock(String useApiGatewayVersion) { diff --git a/test/widgets/logs/clients_filters_modal_test.dart b/test/widgets/logs/clients_filters_modal_test.dart new file mode 100644 index 00000000..71cc3809 --- /dev/null +++ b/test/widgets/logs/clients_filters_modal_test.dart @@ -0,0 +1,92 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pi_hole_client/screens/logs/clients_filters_modal.dart'; + +import '../helpers.dart'; +import '../utils.dart'; + +void main() async { + await initializeApp(); + + group( + 'Client filter modal tests', + () { + late TestSetupHelper testSetup; + + setUp(() async { + testSetup = TestSetupHelper(); + testSetup.initializeMock(useApiGatewayVersion: 'v6'); + }); + + testWidgets( + 'should uncheck all filter', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget( + const ClientsFiltersModal( + statusBarHeight: 24, + bottomNavBarHeight: 48, + selectedClients: ['192.168.100.2', 'localhost'], + window: false, + ), + ), + ); + + expect(find.byType(ClientsFiltersModal), findsOneWidget); + expect(find.text('Clients'), findsOneWidget); + expect(find.text('Uncheck all'), findsOneWidget); + expect(find.text('Close'), findsOneWidget); + expect(find.text('Apply'), findsOneWidget); + await tester.tap(find.text('Uncheck all')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('Apply')); + await tester.pumpAndSettle(); + }, + ); + + testWidgets( + 'should check all clients', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget( + const ClientsFiltersModal( + statusBarHeight: 24, + bottomNavBarHeight: 48, + selectedClients: [], + window: false, + ), + ), + ); + + expect(find.byType(ClientsFiltersModal), findsOneWidget); + expect(find.text('Clients'), findsOneWidget); + expect(find.text('Check all'), findsOneWidget); + expect(find.text('Close'), findsOneWidget); + expect(find.text('Apply'), findsOneWidget); + await tester.tap(find.text('Check all')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('Apply')); + await tester.pumpAndSettle(); + }, + ); + }, + ); +} diff --git a/test/widgets/logs/logs_filters_modal_test.dart b/test/widgets/logs/logs_filters_modal_test.dart new file mode 100644 index 00000000..ff3dcebe --- /dev/null +++ b/test/widgets/logs/logs_filters_modal_test.dart @@ -0,0 +1,51 @@ +// import 'package:flutter/material.dart'; +// import 'package:flutter_test/flutter_test.dart'; +// import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart'; + +// import '../helpers.dart'; + +// TODO: couse +// ═╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ +// The following assertion was thrown during layout: + +// void main() async { +// await initializeApp(); + +// group( +// 'Query logs screen tests', +// () { +// late TestSetupHelper testSetup; + +// setUp(() async { +// testSetup = TestSetupHelper(); +// testSetup.initializeMock(useApiGatewayVersion: 'v6'); +// }); + +// testWidgets( +// 'should show logs screen on mobile layout', +// (WidgetTester tester) async { +// tester.view.physicalSize = const Size(1080, 2400); +// tester.view.devicePixelRatio = 2.0; + +// addTearDown(() { +// tester.view.resetPhysicalSize(); +// tester.view.resetDevicePixelRatio(); +// }); + +// await tester.pumpWidget( +// testSetup.buildTestWidget( +// LogsFiltersModal( +// statusBarHeight: 24.0, +// bottomNavBarHeight: 48.0, +// filterLogs: () {}, +// window: true, +// ), +// ), +// ); + +// expect(find.byType(LogsFiltersModal), findsOneWidget); +// }, +// ); +// }, +// ); +// } diff --git a/test/widgets/logs/logs_test.dart b/test/widgets/logs/logs_test.dart index 29d64c0a..51e5f288 100644 --- a/test/widgets/logs/logs_test.dart +++ b/test/widgets/logs/logs_test.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:mockito/mockito.dart'; import 'package:pi_hole_client/screens/logs/logs.dart'; -import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart'; import '../helpers.dart'; diff --git a/test/widgets/logs/status_filters_modal_test.dart b/test/widgets/logs/status_filters_modal_test.dart new file mode 100644 index 00000000..1bc6a2a1 --- /dev/null +++ b/test/widgets/logs/status_filters_modal_test.dart @@ -0,0 +1,106 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pi_hole_client/screens/logs/status_filters_modal.dart'; + +import '../helpers.dart'; + +void main() async { + await initializeApp(); + + group( + 'Client filter modal tests', + () { + late TestSetupHelper testSetup; + + setUp(() async { + testSetup = TestSetupHelper(); + testSetup.initializeMock(useApiGatewayVersion: 'v6'); + }); + + testWidgets( + 'should uncheck all filter', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget( + const StatusFiltersModal( + statusBarHeight: 24, + bottomNavBarHeight: 48, + statusSelected: [ + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + ], + window: false, + ), + ), + ); + + expect(find.byType(StatusFiltersModal), findsOneWidget); + expect(find.text('Logs status'), findsOneWidget); + expect(find.text('Uncheck all'), findsOneWidget); + expect(find.text('Close'), findsOneWidget); + expect(find.text('Apply'), findsOneWidget); + await tester.tap(find.text('Uncheck all')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('Apply')); + await tester.pumpAndSettle(); + }, + ); + + testWidgets( + 'should check all clients', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget( + const StatusFiltersModal( + statusBarHeight: 24, + bottomNavBarHeight: 48, + statusSelected: [3, 4], + window: false, + ), + ), + ); + + expect(find.byType(StatusFiltersModal), findsOneWidget); + expect(find.text('Logs status'), findsOneWidget); + expect(find.text('Check all'), findsOneWidget); + expect(find.text('Close'), findsOneWidget); + expect(find.text('Apply'), findsOneWidget); + await tester.tap(find.text('Check all')); + await tester.pumpAndSettle(); + + await tester.tap(find.text('Apply')); + await tester.pumpAndSettle(); + }, + ); + }, + ); +} From 25274467ad42f1d6da67ebfdbf280d00763d4ae4 Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Sun, 26 Jan 2025 20:13:21 +0900 Subject: [PATCH 4/6] Update ignore patterns to exclude generated files --- codecov.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/codecov.yml b/codecov.yml index 6a8b6302..c77361d5 100644 --- a/codecov.yml +++ b/codecov.yml @@ -1,2 +1,3 @@ ignore: - "lib/screens/settings/about/about.dart" + - "lib/**/*.g.dart" From b31d709b1cde604ff3d873a1dcb3dee6a57647ac Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Sun, 26 Jan 2025 20:22:02 +0900 Subject: [PATCH 5/6] Skip test --- .../widgets/logs/logs_filters_modal_test.dart | 93 ++++++++++--------- 1 file changed, 47 insertions(+), 46 deletions(-) diff --git a/test/widgets/logs/logs_filters_modal_test.dart b/test/widgets/logs/logs_filters_modal_test.dart index ff3dcebe..d4848f6f 100644 --- a/test/widgets/logs/logs_filters_modal_test.dart +++ b/test/widgets/logs/logs_filters_modal_test.dart @@ -1,51 +1,52 @@ -// import 'package:flutter/material.dart'; -// import 'package:flutter_test/flutter_test.dart'; -// import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:pi_hole_client/screens/logs/logs_filters_modal.dart'; -// import '../helpers.dart'; +import '../helpers.dart'; -// TODO: couse +// TODO: Fix this test // ═╡ EXCEPTION CAUGHT BY RENDERING LIBRARY ╞═════════════════════════════════════════════════════════ // The following assertion was thrown during layout: -// void main() async { -// await initializeApp(); - -// group( -// 'Query logs screen tests', -// () { -// late TestSetupHelper testSetup; - -// setUp(() async { -// testSetup = TestSetupHelper(); -// testSetup.initializeMock(useApiGatewayVersion: 'v6'); -// }); - -// testWidgets( -// 'should show logs screen on mobile layout', -// (WidgetTester tester) async { -// tester.view.physicalSize = const Size(1080, 2400); -// tester.view.devicePixelRatio = 2.0; - -// addTearDown(() { -// tester.view.resetPhysicalSize(); -// tester.view.resetDevicePixelRatio(); -// }); - -// await tester.pumpWidget( -// testSetup.buildTestWidget( -// LogsFiltersModal( -// statusBarHeight: 24.0, -// bottomNavBarHeight: 48.0, -// filterLogs: () {}, -// window: true, -// ), -// ), -// ); - -// expect(find.byType(LogsFiltersModal), findsOneWidget); -// }, -// ); -// }, -// ); -// } +void main() async { + await initializeApp(); + + group( + 'Query logs screen tests', + () { + late TestSetupHelper testSetup; + + setUp(() async { + testSetup = TestSetupHelper(); + testSetup.initializeMock(useApiGatewayVersion: 'v6'); + }); + + testWidgets( + 'should show logs screen on mobile layout', + (WidgetTester tester) async { + tester.view.physicalSize = const Size(1080, 2400); + tester.view.devicePixelRatio = 2.0; + + addTearDown(() { + tester.view.resetPhysicalSize(); + tester.view.resetDevicePixelRatio(); + }); + + await tester.pumpWidget( + testSetup.buildTestWidget( + LogsFiltersModal( + statusBarHeight: 24.0, + bottomNavBarHeight: 48.0, + filterLogs: () {}, + window: true, + ), + ), + ); + + expect(find.byType(LogsFiltersModal), findsOneWidget); + }, + skip: true, + ); + }, + ); +} From d66245487814d8edc72838807946e80c272e1861 Mon Sep 17 00:00:00 2001 From: tsutsu3 Date: Sun, 26 Jan 2025 20:22:22 +0900 Subject: [PATCH 6/6] Remove unused import from clients_filters_modal_test.dart --- test/widgets/logs/clients_filters_modal_test.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/test/widgets/logs/clients_filters_modal_test.dart b/test/widgets/logs/clients_filters_modal_test.dart index 71cc3809..ecf8b516 100644 --- a/test/widgets/logs/clients_filters_modal_test.dart +++ b/test/widgets/logs/clients_filters_modal_test.dart @@ -3,7 +3,6 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:pi_hole_client/screens/logs/clients_filters_modal.dart'; import '../helpers.dart'; -import '../utils.dart'; void main() async { await initializeApp();