Skip to content

Commit

Permalink
[Tests] Added a few donations test
Browse files Browse the repository at this point in the history
  • Loading branch information
Wolfteam committed Mar 1, 2022
1 parent 869bcdb commit 56d131e
Show file tree
Hide file tree
Showing 3 changed files with 274 additions and 61 deletions.
241 changes: 241 additions & 0 deletions test/application/donations/donations_bloc_test.dart
@@ -0,0 +1,241 @@
import 'package:bloc_test/bloc_test.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/mockito.dart';
import 'package:shiori/application/bloc.dart';
import 'package:shiori/domain/models/models.dart';

import '../../mocks.mocks.dart';

void main() {
const _validUserId = '12345_suffix';
const _packages = <PackageItemModel>[
PackageItemModel(identifier: '123', offeringIdentifier: 'xyz', productIdentifier: 'xxx', priceString: '2\$'),
PackageItemModel(identifier: '456', offeringIdentifier: 'xyz', productIdentifier: 'yyy', priceString: '5\$'),
PackageItemModel(identifier: '789', offeringIdentifier: 'xyz', productIdentifier: 'zzz', priceString: '10\$'),
];

setUpAll(() {
TestWidgetsFlutterBinding.ensureInitialized();
});

test('Initial state', () => expect(DonationsBloc(MockPurchaseService(), MockNetworkService()).state, const DonationsState.loading()));

group('init', () {
blocTest<DonationsBloc, DonationsState>(
'network is not available',
build: () {
final networkService = MockNetworkService();
final purchaseService = MockPurchaseService();
when(networkService.isInternetAvailable()).thenAnswer((_) => Future.value(false));
return DonationsBloc(purchaseService, networkService);
},
act: (bloc) => bloc.add(const DonationsEvent.init()),
expect: () => const [
DonationsState.loading(),
DonationsState.initial(
packages: [],
isInitialized: false,
noInternetConnection: true,
canMakePurchases: false,
)
],
);

blocTest<DonationsBloc, DonationsState>(
'platform is not supported',
build: () {
final networkService = MockNetworkService();
final purchaseService = MockPurchaseService();
when(networkService.isInternetAvailable()).thenAnswer((_) => Future.value(true));
when(purchaseService.isPlatformSupported()).thenAnswer((_) => Future.value(false));
return DonationsBloc(purchaseService, networkService);
},
act: (bloc) => bloc.add(const DonationsEvent.init()),
expect: () => const [
DonationsState.loading(),
DonationsState.initial(
packages: [],
isInitialized: false,
noInternetConnection: false,
canMakePurchases: false,
)
],
);

blocTest<DonationsBloc, DonationsState>(
'cannot make purchases',
build: () {
final networkService = MockNetworkService();
final purchaseService = MockPurchaseService();
when(networkService.isInternetAvailable()).thenAnswer((_) => Future.value(true));
when(purchaseService.isPlatformSupported()).thenAnswer((_) => Future.value(true));
when(purchaseService.isInitialized).thenReturn(true);
when(purchaseService.init()).thenAnswer((_) => Future.value(true));
when(purchaseService.canMakePurchases()).thenAnswer((_) => Future.value(false));
return DonationsBloc(purchaseService, networkService);
},
act: (bloc) => bloc.add(const DonationsEvent.init()),
expect: () => const [
DonationsState.loading(),
DonationsState.initial(
packages: [],
isInitialized: true,
noInternetConnection: false,
canMakePurchases: false,
),
],
);

blocTest<DonationsBloc, DonationsState>(
'purchases are loaded',
build: () {
final networkService = MockNetworkService();
final purchaseService = MockPurchaseService();
when(networkService.isInternetAvailable()).thenAnswer((_) => Future.value(true));
when(purchaseService.isPlatformSupported()).thenAnswer((_) => Future.value(true));
when(purchaseService.isInitialized).thenReturn(true);
when(purchaseService.init()).thenAnswer((_) => Future.value(true));
when(purchaseService.canMakePurchases()).thenAnswer((_) => Future.value(true));
when(purchaseService.getInAppPurchases()).thenAnswer((_) => Future.value(_packages));
return DonationsBloc(purchaseService, networkService);
},
act: (bloc) => bloc.add(const DonationsEvent.init()),
expect: () => const [
DonationsState.loading(),
DonationsState.initial(
packages: _packages,
isInitialized: true,
noInternetConnection: false,
canMakePurchases: true,
),
],
);
});

group('restore purchases', () {
DonationsBloc _getBloc({bool restoreSucceeds = true}) {
final networkService = MockNetworkService();
final purchaseService = MockPurchaseService();
when(networkService.isInternetAvailable()).thenAnswer((_) => Future.value(true));
when(purchaseService.isPlatformSupported()).thenAnswer((_) => Future.value(true));
when(purchaseService.isInitialized).thenReturn(true);
when(purchaseService.init()).thenAnswer((_) => Future.value(true));
when(purchaseService.canMakePurchases()).thenAnswer((_) => Future.value(true));
when(purchaseService.getInAppPurchases()).thenAnswer((_) => Future.value(_packages));
when(purchaseService.restorePurchases(_validUserId)).thenAnswer((_) => Future.value(restoreSucceeds));
return DonationsBloc(purchaseService, networkService);
}

blocTest<DonationsBloc, DonationsState>(
'invalid userid',
build: () => _getBloc(),
act: (bloc) => bloc..add(const DonationsEvent.restorePurchases(userId: 'xxxx_1234')),
errors: () => [isA<Exception>()],
expect: () => const [
DonationsState.loading(),
],
);

blocTest<DonationsBloc, DonationsState>(
'succeeds',
build: () => _getBloc(),
act: (bloc) => bloc..add(const DonationsEvent.restorePurchases(userId: _validUserId)),
expect: () => const [
DonationsState.loading(),
DonationsState.restoreCompleted(error: false),
],
);

blocTest<DonationsBloc, DonationsState>(
'fails',
build: () => _getBloc(restoreSucceeds: false),
act: (bloc) => bloc..add(const DonationsEvent.restorePurchases(userId: _validUserId)),
expect: () => const [
DonationsState.loading(),
DonationsState.restoreCompleted(error: true),
DonationsState.initial(packages: _packages, isInitialized: true, noInternetConnection: false, canMakePurchases: true),
],
);
});

group('purchase', () {
DonationsBloc _getBloc({bool purchaseSucceeds = true}) {
final networkService = MockNetworkService();
final purchaseService = MockPurchaseService();
when(networkService.isInternetAvailable()).thenAnswer((_) => Future.value(true));
when(purchaseService.isPlatformSupported()).thenAnswer((_) => Future.value(true));
when(purchaseService.isInitialized).thenReturn(true);
when(purchaseService.init()).thenAnswer((_) => Future.value(true));
when(purchaseService.canMakePurchases()).thenAnswer((_) => Future.value(true));
when(purchaseService.getInAppPurchases()).thenAnswer((_) => Future.value(_packages));
when(purchaseService.purchase(_validUserId, _packages.first.identifier, _packages.first.offeringIdentifier))
.thenAnswer((_) => Future.value(purchaseSucceeds));
return DonationsBloc(purchaseService, networkService);
}

blocTest<DonationsBloc, DonationsState>(
'invalid user id',
build: () => _getBloc(),
act: (bloc) => bloc..add(const DonationsEvent.purchase(userId: '123_xyz', identifier: '', offeringIdentifier: '')),
errors: () => [isA<Exception>()],
expect: () => const [
DonationsState.loading(),
],
);

blocTest<DonationsBloc, DonationsState>(
'invalid identifier',
build: () => _getBloc(),
act: (bloc) => bloc..add(const DonationsEvent.purchase(userId: _validUserId, identifier: '', offeringIdentifier: '')),
errors: () => [isA<Exception>()],
expect: () => const [
DonationsState.loading(),
],
);

blocTest<DonationsBloc, DonationsState>(
'invalid offering identifier',
build: () => _getBloc(),
act: (bloc) => bloc..add(DonationsEvent.purchase(userId: _validUserId, identifier: _packages.first.identifier, offeringIdentifier: '')),
errors: () => [isA<Exception>()],
expect: () => const [
DonationsState.loading(),
],
);

blocTest<DonationsBloc, DonationsState>(
'succeed',
build: () => _getBloc(),
act: (bloc) => bloc
..add(
DonationsEvent.purchase(
userId: _validUserId,
identifier: _packages.first.identifier,
offeringIdentifier: _packages.first.offeringIdentifier,
),
),
expect: () => const [
DonationsState.loading(),
DonationsState.purchaseCompleted(error: false),
],
);

blocTest<DonationsBloc, DonationsState>(
'succeeds',
build: () => _getBloc(purchaseSucceeds: false),
act: (bloc) => bloc
..add(
DonationsEvent.purchase(
userId: _validUserId,
identifier: _packages.first.identifier,
offeringIdentifier: _packages.first.offeringIdentifier,
),
),
expect: () => const [
DonationsState.loading(),
DonationsState.purchaseCompleted(error: true),
DonationsState.initial(packages: _packages, isInitialized: true, noInternetConnection: false, canMakePurchases: true),
],
);
});
}
77 changes: 20 additions & 57 deletions test/application/main/main_bloc_test.dart
Expand Up @@ -9,6 +9,7 @@ import 'package:shiori/domain/services/device_info_service.dart';
import 'package:shiori/domain/services/genshin_service.dart';
import 'package:shiori/domain/services/locale_service.dart';
import 'package:shiori/domain/services/logging_service.dart';
import 'package:shiori/domain/services/purchase_service.dart';
import 'package:shiori/domain/services/settings_service.dart';
import 'package:shiori/domain/services/telemetry_service.dart';
import 'package:shiori/infrastructure/infrastructure.dart';
Expand Down Expand Up @@ -70,6 +71,7 @@ void main() {
late final LocaleService _localeService;
late final TelemetryService _telemetryService;
late final DeviceInfoService _deviceInfoService;
late final PurchaseService _purchaseService;

late final CharactersBloc _charactersBloc;
late final WeaponsBloc _weaponsBloc;
Expand All @@ -94,6 +96,8 @@ void main() {
_deviceInfoService = MockDeviceInfoService();
_localeService = LocaleServiceImpl(_settingsService);
_genshinService = GenshinServiceImpl(_localeService);
_purchaseService = MockPurchaseService();
when(_purchaseService.getUnlockedFeatures()).thenAnswer((_) => Future.value(AppUnlockedFeature.values));

_charactersBloc = MockCharactersBloc();
_weaponsBloc = MockWeaponsBloc();
Expand All @@ -112,37 +116,29 @@ void main() {
when(_deviceInfoService.versionChanged).thenReturn(false);
});

test('Initial state', () {
final bloc = MainBloc(
_logger,
_genshinService,
_settingsService,
_localeService,
_telemetryService,
_deviceInfoService,
_charactersBloc,
_weaponsBloc,
_homeBloc,
_artifactsBloc,
);
expect(bloc.state, const MainState.loading());
});

group('Init', () {
blocTest<MainBloc, MainState>(
'emits init state',
build: () => MainBloc(
MainBloc _getBloc() => MainBloc(
_logger,
_genshinService,
_settingsService,
_localeService,
_telemetryService,
_deviceInfoService,
_purchaseService,
_charactersBloc,
_weaponsBloc,
_homeBloc,
_artifactsBloc,
),
);

test('Initial state', () {
final bloc = _getBloc();
expect(bloc.state, const MainState.loading());
});

group('Init', () {
blocTest<MainBloc, MainState>(
'emits init state',
build: () => _getBloc(),
act: (bloc) => bloc.add(const MainEvent.init()),
expect: () => [
MainState.loaded(
Expand All @@ -161,18 +157,7 @@ void main() {
group('Theme changed', () {
blocTest<MainBloc, MainState>(
'updates the theme in the state',
build: () => MainBloc(
_logger,
_genshinService,
_settingsService,
_localeService,
_telemetryService,
_deviceInfoService,
_charactersBloc,
_weaponsBloc,
_homeBloc,
_artifactsBloc,
),
build: () => _getBloc(),
act: (bloc) => bloc
..add(const MainEvent.init())
..add(const MainEvent.themeChanged(newValue: AppThemeType.light)),
Expand All @@ -192,18 +177,7 @@ void main() {

blocTest<MainBloc, MainState>(
'updates the accent color in the state',
build: () => MainBloc(
_logger,
_genshinService,
_settingsService,
_localeService,
_telemetryService,
_deviceInfoService,
_charactersBloc,
_weaponsBloc,
_homeBloc,
_artifactsBloc,
),
build: () => _getBloc(),
act: (bloc) => bloc
..add(const MainEvent.init())
..add(const MainEvent.accentColorChanged(newValue: AppAccentColorType.blueGrey)),
Expand All @@ -225,18 +199,7 @@ void main() {
group('Language changed', () {
blocTest<MainBloc, MainState>(
'updates the language in the state',
build: () => MainBloc(
_logger,
_genshinService,
_settingsService,
_localeService,
_telemetryService,
_deviceInfoService,
_charactersBloc,
_weaponsBloc,
_homeBloc,
_artifactsBloc,
),
build: () => _getBloc(),
setUp: () {
when(_settingsService.language).thenReturn(AppLanguageType.russian);
},
Expand Down

0 comments on commit 56d131e

Please sign in to comment.