diff --git a/packages/neon/neon_dashboard/pubspec.yaml b/packages/neon/neon_dashboard/pubspec.yaml index 0c3e56652f0..be4bbcbb8c3 100644 --- a/packages/neon/neon_dashboard/pubspec.yaml +++ b/packages/neon/neon_dashboard/pubspec.yaml @@ -28,6 +28,7 @@ dev_dependencies: flutter_test: sdk: flutter go_router_builder: ^2.4.1 + http: ^1.2.0 mocktail: ^1.0.3 neon_lints: git: diff --git a/packages/neon/neon_dashboard/test/bloc_test.dart b/packages/neon/neon_dashboard/test/bloc_test.dart new file mode 100644 index 00000000000..d731f317b14 --- /dev/null +++ b/packages/neon/neon_dashboard/test/bloc_test.dart @@ -0,0 +1,172 @@ +import 'dart:convert'; + +import 'package:built_collection/built_collection.dart'; +import 'package:collection/collection.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:http/http.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:neon_dashboard/src/blocs/dashboard.dart'; +import 'package:neon_framework/blocs.dart'; +import 'package:neon_framework/models.dart'; +import 'package:neon_framework/testing.dart'; + +Account mockDashboardAccount() => mockServer({ + RegExp(r'/ocs/v2\.php/apps/dashboard/api/v1/widgets'): { + 'get': (match, queryParameters) => Response( + json.encode({ + 'ocs': { + 'meta': {'status': '', 'statuscode': 0}, + 'data': { + for (final entry in { + 'null': null, + 'empty': [], + 'v1': [1], + 'v2': [2], + 'v1v2': [1, 2], + }.entries) + entry.key: { + 'id': entry.key, + 'title': '', + 'order': 0, + 'icon_class': '', + 'icon_url': '', + 'item_icons_round': false, + 'item_api_versions': entry.value, + }, + }, + }, + }), + 200, + ), + }, + RegExp(r'/ocs/v2\.php/apps/dashboard/api/v1/widget-items'): { + 'get': (match, queryParameters) => Response( + json.encode({ + 'ocs': { + 'meta': {'status': '', 'statuscode': 0}, + 'data': { + for (final key in queryParameters['widgets[]']!) + key: [ + { + 'subtitle': '', + 'title': key, + 'link': '', + 'iconUrl': '', + 'sinceId': '', + }, + ], + 'tooMany1': [ + for (var i = 0; i < 8; i++) + { + 'subtitle': '', + 'title': '$i', + 'link': '', + 'iconUrl': '', + 'sinceId': '', + }, + ], + }, + }, + }), + 200, + ), + }, + RegExp(r'/ocs/v2\.php/apps/dashboard/api/v2/widget-items'): { + 'get': (match, queryParameters) => Response( + json.encode({ + 'ocs': { + 'meta': {'status': '', 'statuscode': 0}, + 'data': { + for (final key in queryParameters['widgets[]']!) + key: { + 'items': [ + { + 'subtitle': '', + 'title': key, + 'link': '', + 'iconUrl': '', + 'sinceId': '', + }, + ], + 'emptyContentMessage': '', + 'halfEmptyContentMessage': '', + }, + 'tooMany2': { + 'items': [ + for (var i = 0; i < 8; i++) + { + 'subtitle': '', + 'title': '$i', + 'link': '', + 'iconUrl': '', + 'sinceId': '', + }, + ], + 'emptyContentMessage': '', + 'halfEmptyContentMessage': '', + }, + }, + }, + }), + 200, + ), + }, + }); + +void main() { + late Account account; + late DashboardBloc bloc; + + setUpAll(() { + final storage = MockNeonStorage(); + when(() => storage.requestCache).thenReturn(null); + }); + + setUp(() { + account = mockDashboardAccount(); + bloc = DashboardBloc(account); + }); + + test('refresh', () async { + final widgets = BuiltList([ + 'null', + 'v1', + 'v2', + 'v1v2', + ]); + expect( + bloc.widgets.transformResult((e) => BuiltList(e.map((w) => w.id))), + emitsInOrder([ + Result>.loading(), + Result.success(widgets), + Result.success(widgets).asLoading(), + Result.success(widgets), + ]), + ); + + final items = BuiltList([ + 'null', + 'v1', + for (var i = 0; i < 7; i++) '$i', + 'v2', + 'v1v2', + for (var i = 0; i < 7; i++) '$i', + ]); + expect( + bloc.items + .transformResult( + (e) => BuiltList(e.values.map((items) => items.items.map((item) => item.title)).flattened), + ) + .distinct(), + emitsInOrder([ + Result(BuiltList(), null, isLoading: true, isCached: false), + Result.success(items), + Result.success(items).asLoading(), + Result.success(items), + ]), + ); + // The delay is necessary to avoid a race condition with loading twice at the same time + await Future.delayed(const Duration(milliseconds: 1)); + await bloc.refresh(); + }); +}