initial commit (migrated)
This commit is contained in:
commit
b594facb51
143 changed files with 11057 additions and 0 deletions
|
|
@ -0,0 +1,90 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:in_app_update/in_app_update.dart';
|
||||
import 'package:kuwot/core/app_updater.dart';
|
||||
import 'package:kuwot/features/in_app_update/presentation/bloc/in_app_update_bloc.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockAppUpdater extends Mock implements AppUpdater {}
|
||||
|
||||
void main() {
|
||||
late MockAppUpdater mockAppUpdater;
|
||||
late InAppUpdateBloc bloc;
|
||||
|
||||
setUp(() {
|
||||
mockAppUpdater = MockAppUpdater();
|
||||
bloc = InAppUpdateBloc(appUpdater: mockAppUpdater);
|
||||
});
|
||||
|
||||
test('initial state should be InAppUpdateInitialState', () {
|
||||
// assert
|
||||
expect(bloc.state, const InAppUpdateInitialState());
|
||||
});
|
||||
|
||||
group('InAppUpdateCheck', () {
|
||||
test(
|
||||
'should emit [Check, UpdateAvailable] when update is available',
|
||||
() async {
|
||||
// arrange
|
||||
final tAppUpdateInfo = AppUpdateInfo(
|
||||
updateAvailability: UpdateAvailability.updateAvailable,
|
||||
immediateUpdateAllowed: true,
|
||||
immediateAllowedPreconditions: [],
|
||||
flexibleUpdateAllowed: true,
|
||||
flexibleAllowedPreconditions: [],
|
||||
availableVersionCode: 1,
|
||||
installStatus: InstallStatus.pending,
|
||||
packageName: 'com.example.app',
|
||||
clientVersionStalenessDays: 1,
|
||||
updatePriority: 1,
|
||||
);
|
||||
when(
|
||||
() => mockAppUpdater.checkForUpdate(),
|
||||
).thenAnswer((_) async => tAppUpdateInfo);
|
||||
|
||||
// expect later
|
||||
final expected = [
|
||||
const InAppUpdateCheckingState(),
|
||||
const InAppUpdateAvailableState(),
|
||||
];
|
||||
expectLater(bloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
bloc.add(const InAppUpdateCheckEvent());
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should emit [Check, UpdateUnavailable] when update is not available',
|
||||
() async {
|
||||
// arrange
|
||||
final tAppUpdateInfo = AppUpdateInfo(
|
||||
updateAvailability: UpdateAvailability.updateNotAvailable,
|
||||
immediateUpdateAllowed: true,
|
||||
immediateAllowedPreconditions: [],
|
||||
flexibleUpdateAllowed: true,
|
||||
flexibleAllowedPreconditions: [],
|
||||
availableVersionCode: 1,
|
||||
installStatus: InstallStatus.pending,
|
||||
packageName: 'com.example.app',
|
||||
clientVersionStalenessDays: 1,
|
||||
updatePriority: 1,
|
||||
);
|
||||
when(
|
||||
() => mockAppUpdater.checkForUpdate(),
|
||||
).thenAnswer((_) async => tAppUpdateInfo);
|
||||
|
||||
// expect later
|
||||
final expected = [
|
||||
const InAppUpdateCheckingState(),
|
||||
const InAppUpdateUnavailableState(),
|
||||
];
|
||||
expectLater(bloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
bloc.add(const InAppUpdateCheckEvent());
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('InAppUpdateStart', () {});
|
||||
}
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:kuwot/core/env.dart';
|
||||
import 'package:kuwot/core/network/network.dart';
|
||||
import 'package:kuwot/features/quote/data/data_sources/remote/kuwot_api_remote_data_source.dart';
|
||||
import 'package:kuwot/features/quote/data/models/image_model.dart';
|
||||
import 'package:kuwot/features/quote/data/models/quote_model.dart';
|
||||
import 'package:kuwot/features/quote/data/models/translation_model.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../../../../_responses/_response.dart';
|
||||
|
||||
class MockEnv extends Mock implements Env {}
|
||||
|
||||
class MockNetwork extends Mock implements Network {}
|
||||
|
||||
class FakeUri extends Fake implements Uri {}
|
||||
|
||||
void main() {
|
||||
late MockEnv mockEnv;
|
||||
late MockNetwork mockNetwork;
|
||||
late KuwotApiRemoteDataSource dataSource;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeUri());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockEnv = MockEnv();
|
||||
mockNetwork = MockNetwork();
|
||||
dataSource = KuwotApiRemoteApiImpl(env: mockEnv, network: mockNetwork);
|
||||
|
||||
// global stubs
|
||||
when(() => mockEnv.authPublicKey).thenReturn('test');
|
||||
when(() => mockEnv.quoteApiScheme).thenReturn('http');
|
||||
when(() => mockEnv.quoteApiHost).thenReturn('10.0.2.2');
|
||||
when(() => mockEnv.quoteApiPort).thenReturn(8080);
|
||||
});
|
||||
|
||||
group('getDailyQuote', () {
|
||||
test('should return random quote when response is successful', () async {
|
||||
// arrange
|
||||
final tResponse = readResponse('quote');
|
||||
when(
|
||||
() => mockNetwork.get(any(), headers: any(named: 'headers')),
|
||||
).thenAnswer((_) async => tResponse);
|
||||
// act
|
||||
final result = await dataSource.getQuote();
|
||||
// assert
|
||||
expect(result, isA<QuoteModel>());
|
||||
});
|
||||
|
||||
test(
|
||||
'should return translated quote when response is successful',
|
||||
() async {
|
||||
// arrange
|
||||
final tResponse = readResponse('quote');
|
||||
when(
|
||||
() => mockNetwork.get(any(), headers: any(named: 'headers')),
|
||||
).thenAnswer((_) async => tResponse);
|
||||
// act
|
||||
final result = await dataSource.getTranslatedQuote(1);
|
||||
// assert
|
||||
expect(result, isA<QuoteModel>());
|
||||
},
|
||||
);
|
||||
|
||||
test('should return random images when response is successful', () async {
|
||||
// arrange
|
||||
final tResponse = readResponse('random_images');
|
||||
when(
|
||||
() => mockNetwork.get(any(), headers: any(named: 'headers')),
|
||||
).thenAnswer((_) async => tResponse);
|
||||
// act
|
||||
final result = await dataSource.getRandomImages();
|
||||
// assert
|
||||
expect(result, isA<List<ImageModel>>());
|
||||
});
|
||||
|
||||
test('should return translations when response is successful', () async {
|
||||
// arrange
|
||||
final tResponse = readResponse('translations');
|
||||
when(
|
||||
() => mockNetwork.get(any(), headers: any(named: 'headers')),
|
||||
).thenAnswer((_) async => tResponse);
|
||||
// act
|
||||
final result = await dataSource.getTranslations();
|
||||
// assert
|
||||
expect(result, isA<List<TranslationModel>>());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,347 @@
|
|||
import 'dart:convert';
|
||||
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:http/http.dart';
|
||||
import 'package:kuwot/core/data/local/translation_target_config.dart';
|
||||
import 'package:kuwot/core/error/failure.dart';
|
||||
import 'package:kuwot/features/quote/data/data_sources/remote/kuwot_api_remote_data_source.dart';
|
||||
import 'package:kuwot/features/quote/data/models/image_model.dart';
|
||||
import 'package:kuwot/features/quote/data/models/quote_model.dart';
|
||||
import 'package:kuwot/features/quote/data/models/translation_model.dart';
|
||||
import 'package:kuwot/features/quote/data/repositories/quote_repository_impl.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/background_image.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/quote.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/translation.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
import '../../../../_responses/_response.dart';
|
||||
|
||||
class MockKuwotApiRemoteDataSource extends Mock
|
||||
implements KuwotApiRemoteDataSource {}
|
||||
|
||||
void main() {
|
||||
late QuoteRepositoryImpl quoteRepository;
|
||||
late MockKuwotApiRemoteDataSource mockKuwotApiRemoteDataSource;
|
||||
|
||||
setUp(() {
|
||||
mockKuwotApiRemoteDataSource = MockKuwotApiRemoteDataSource();
|
||||
|
||||
quoteRepository = QuoteRepositoryImpl(
|
||||
quoteDataSource: mockKuwotApiRemoteDataSource,
|
||||
);
|
||||
});
|
||||
|
||||
const tQuoteModel = QuoteModel(id: 1, author: 'author', text: 'text');
|
||||
const tExpectedQuote = Quote(id: 1, author: 'author', body: 'text');
|
||||
const tTranslationTarget = TranslationTarget(id: 'en', name: 'English');
|
||||
|
||||
group('getQuote', () {
|
||||
test('should return a Quote entity', () async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getQuote(query: any(named: 'query')),
|
||||
).thenAnswer((_) async => tQuoteModel);
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getQuote(tTranslationTarget);
|
||||
|
||||
// assert
|
||||
verify(
|
||||
() => mockKuwotApiRemoteDataSource.getQuote(query: any(named: 'query')),
|
||||
);
|
||||
result.fold(
|
||||
(failure) => fail('Expected Quote, but got $failure'),
|
||||
(quote) => expect(quote, tExpectedQuote),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
|
||||
test(
|
||||
'should return ClientFailure when a client exception is thrown',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() =>
|
||||
mockKuwotApiRemoteDataSource.getQuote(query: any(named: 'query')),
|
||||
).thenThrow(ClientException('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getQuote(null);
|
||||
|
||||
// assert
|
||||
verify(
|
||||
() =>
|
||||
mockKuwotApiRemoteDataSource.getQuote(query: any(named: 'query')),
|
||||
);
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ClientFailure>()),
|
||||
(quote) => fail('Expected ClientFailure, but got $quote'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
},
|
||||
);
|
||||
|
||||
test('should return UnknownFailure when an exception is thrown', () async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getQuote(query: any(named: 'query')),
|
||||
).thenThrow(Exception('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getQuote(null);
|
||||
|
||||
// assert
|
||||
verify(
|
||||
() => mockKuwotApiRemoteDataSource.getQuote(query: any(named: 'query')),
|
||||
);
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<UnknownFailure>()),
|
||||
(quote) => fail('Expected UnknownFailure, but got $quote'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
});
|
||||
|
||||
group('getTranslatedQuote', () {
|
||||
const tQuoteId = 1;
|
||||
|
||||
test('should return a Quote entity', () async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslatedQuote(
|
||||
any(),
|
||||
query: any(named: 'query'),
|
||||
),
|
||||
).thenAnswer((_) async => tQuoteModel);
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getTranslatedQuote(
|
||||
tQuoteId,
|
||||
tTranslationTarget,
|
||||
);
|
||||
|
||||
// assert
|
||||
verify(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslatedQuote(
|
||||
any(),
|
||||
query: any(named: 'query'),
|
||||
),
|
||||
);
|
||||
result.fold(
|
||||
(failure) => fail('Expected Quote, but got $failure'),
|
||||
(quote) => expect(quote, tExpectedQuote),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
|
||||
test(
|
||||
'should return ClientFailure when a client exception is thrown',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslatedQuote(
|
||||
any(),
|
||||
query: any(named: 'query'),
|
||||
),
|
||||
).thenThrow(ClientException('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getTranslatedQuote(
|
||||
tQuoteId,
|
||||
tTranslationTarget,
|
||||
);
|
||||
|
||||
// assert
|
||||
verify(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslatedQuote(
|
||||
any(),
|
||||
query: any(named: 'query'),
|
||||
),
|
||||
);
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ClientFailure>()),
|
||||
(quote) => fail('Expected ClientFailure, but got $quote'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
},
|
||||
);
|
||||
|
||||
test('should return UnknownFailure when an exception is thrown', () async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslatedQuote(
|
||||
any(),
|
||||
query: any(named: 'query'),
|
||||
),
|
||||
).thenThrow(Exception('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getTranslatedQuote(
|
||||
tQuoteId,
|
||||
tTranslationTarget,
|
||||
);
|
||||
|
||||
// assert
|
||||
verify(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslatedQuote(
|
||||
any(),
|
||||
query: any(named: 'query'),
|
||||
),
|
||||
);
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<UnknownFailure>()),
|
||||
(quote) => fail('Expected UnknownFailure, but got $quote'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
});
|
||||
|
||||
group('getTranslations', () {
|
||||
test('should return a List of Translation entity', () async {
|
||||
// arrange
|
||||
final tTranslationListModel =
|
||||
(jsonDecode(readResponse('translations')) as List)
|
||||
.map((e) => TranslationModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
final tExpectedTranslations = tTranslationListModel
|
||||
.map((e) => Translation(id: e.id, language: e.lang))
|
||||
.toList();
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslations(),
|
||||
).thenAnswer((_) async => tTranslationListModel);
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getTranslations();
|
||||
|
||||
// assert
|
||||
verify(() => mockKuwotApiRemoteDataSource.getTranslations());
|
||||
result.fold(
|
||||
(failure) => fail('Expected Translations, but got $failure'),
|
||||
(translations) => expect(translations, tExpectedTranslations),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
|
||||
test(
|
||||
'should return ClientFailure when a client exception is thrown',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslations(),
|
||||
).thenThrow(ClientException('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getTranslations();
|
||||
|
||||
// assert
|
||||
verify(() => mockKuwotApiRemoteDataSource.getTranslations());
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ClientFailure>()),
|
||||
(translations) =>
|
||||
fail('Expected ClientFailure, but got $translations'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
},
|
||||
);
|
||||
|
||||
test('should return UnknownFailure when an exception is thrown', () async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getTranslations(),
|
||||
).thenThrow(Exception('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getTranslations();
|
||||
|
||||
// assert
|
||||
verify(() => mockKuwotApiRemoteDataSource.getTranslations());
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<UnknownFailure>()),
|
||||
(translations) =>
|
||||
fail('Expected UnknownFailure, but got $translations'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
});
|
||||
|
||||
group('getBackgroundImages', () {
|
||||
test('should return a List of BackgroundImage entity', () async {
|
||||
// arrange
|
||||
final tImageListModel =
|
||||
(jsonDecode(readResponse('random_images')) as List)
|
||||
.map((e) => ImageModel.fromJson(e as Map<String, dynamic>))
|
||||
.toList();
|
||||
final tExpectedImages = tImageListModel.map(
|
||||
(e) => BackgroundImage(
|
||||
id: e.id,
|
||||
description: e.description,
|
||||
color: e.color,
|
||||
blurHash: e.blurHash,
|
||||
url: e.url,
|
||||
originUrl: e.originUrl,
|
||||
authorName: e.authorName,
|
||||
authorProfileImageUrl: e.authorProfileImageUrl,
|
||||
authorUrl: e.authorUrl,
|
||||
authorBio: e.authorBio,
|
||||
authorLocation: e.authorLocation,
|
||||
authorTotalLikes: e.authorTotalLikes,
|
||||
authorTotalPhotos: e.authorTotalPhotos,
|
||||
authorIsForHire: e.authorIsForHire,
|
||||
),
|
||||
);
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getRandomImages(),
|
||||
).thenAnswer((_) async => tImageListModel);
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getBackgroundImages();
|
||||
|
||||
// assert
|
||||
verify(() => mockKuwotApiRemoteDataSource.getRandomImages());
|
||||
result.fold(
|
||||
(failure) => fail('Expected BackgroundImages, but got $failure'),
|
||||
(photos) => expect(photos, tExpectedImages),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
|
||||
test(
|
||||
'should return ClientFailure when a client exception is thrown',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getRandomImages(),
|
||||
).thenThrow(ClientException('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getBackgroundImages();
|
||||
|
||||
// assert
|
||||
verify(() => mockKuwotApiRemoteDataSource.getRandomImages());
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<ClientFailure>()),
|
||||
(images) => fail('Expected ClientFailure, but got $images'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
},
|
||||
);
|
||||
|
||||
test('should return UnknownFailure when an exception is thrown', () async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockKuwotApiRemoteDataSource.getRandomImages(),
|
||||
).thenThrow(Exception('test'));
|
||||
|
||||
// act
|
||||
final result = await quoteRepository.getBackgroundImages();
|
||||
|
||||
// assert
|
||||
verify(() => mockKuwotApiRemoteDataSource.getRandomImages());
|
||||
result.fold(
|
||||
(failure) => expect(failure, isA<UnknownFailure>()),
|
||||
(images) => fail('Expected UnknownFailure, but got $images'),
|
||||
);
|
||||
verifyNoMoreInteractions(mockKuwotApiRemoteDataSource);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/core/domain/no_params.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/background_image.dart';
|
||||
import 'package:kuwot/features/quote/domain/repositories/quote_repository.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_background_images.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockQuoteRepository extends Mock implements QuoteRepository {}
|
||||
|
||||
void main() {
|
||||
late MockQuoteRepository mockQuoteRepository;
|
||||
late GetBackgroundImages useCase;
|
||||
|
||||
setUp(() {
|
||||
mockQuoteRepository = MockQuoteRepository();
|
||||
useCase = GetBackgroundImages(mockQuoteRepository);
|
||||
});
|
||||
|
||||
test('should get background photos', () async {
|
||||
// arrange
|
||||
const tImages = <BackgroundImage>[];
|
||||
when(
|
||||
() => mockQuoteRepository.getBackgroundImages(),
|
||||
).thenAnswer((_) async => right(tImages));
|
||||
|
||||
// act
|
||||
final result = await useCase(const NoParams());
|
||||
|
||||
// assert
|
||||
expect(result, right(tImages));
|
||||
verify(() => mockQuoteRepository.getBackgroundImages());
|
||||
verifyNoMoreInteractions(mockQuoteRepository);
|
||||
});
|
||||
}
|
||||
34
test/features/quote/domain/use_cases/get_quote_test.dart
Normal file
34
test/features/quote/domain/use_cases/get_quote_test.dart
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/quote.dart';
|
||||
import 'package:kuwot/features/quote/domain/repositories/quote_repository.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_quote.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockQuoteRepository extends Mock implements QuoteRepository {}
|
||||
|
||||
void main() {
|
||||
late MockQuoteRepository mockQuoteRepository;
|
||||
late GetQuote useCase;
|
||||
|
||||
setUp(() {
|
||||
mockQuoteRepository = MockQuoteRepository();
|
||||
useCase = GetQuote(mockQuoteRepository);
|
||||
});
|
||||
|
||||
test('should get quote', () async {
|
||||
// arrange
|
||||
const tQuote = Quote(id: 1, author: 'author', body: 'text');
|
||||
when(
|
||||
() => mockQuoteRepository.getQuote(any()),
|
||||
).thenAnswer((_) async => right(tQuote));
|
||||
|
||||
// act
|
||||
final result = await useCase(const GetQuoteParams(null));
|
||||
|
||||
// assert
|
||||
expect(result, right(tQuote));
|
||||
verify(() => mockQuoteRepository.getQuote(any()));
|
||||
verifyNoMoreInteractions(mockQuoteRepository);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/core/data/local/translation_target_config.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/quote.dart';
|
||||
import 'package:kuwot/features/quote/domain/repositories/quote_repository.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_translated_quote.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockQuoteRepository extends Mock implements QuoteRepository {}
|
||||
|
||||
class FakeTranslationTarget extends Fake implements TranslationTarget {}
|
||||
|
||||
void main() {
|
||||
late MockQuoteRepository mockQuoteRepository;
|
||||
late GetTranslatedQuote useCase;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeTranslationTarget());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockQuoteRepository = MockQuoteRepository();
|
||||
useCase = GetTranslatedQuote(mockQuoteRepository);
|
||||
});
|
||||
|
||||
test('should get translated quote', () async {
|
||||
// arrange
|
||||
const tQuote = Quote(id: 1, author: 'author', body: 'text');
|
||||
const tTarget = TranslationTarget(id: 'en', name: 'English');
|
||||
when(
|
||||
() => mockQuoteRepository.getTranslatedQuote(any(), any()),
|
||||
).thenAnswer((_) async => right(tQuote));
|
||||
|
||||
// act
|
||||
final result = await useCase(
|
||||
const GetTranslatedQuoteParams(id: 1, translationTarget: tTarget),
|
||||
);
|
||||
|
||||
// assert
|
||||
expect(result, right(tQuote));
|
||||
verify(() => mockQuoteRepository.getTranslatedQuote(tQuote.id, tTarget));
|
||||
verifyNoMoreInteractions(mockQuoteRepository);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/core/domain/no_params.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/translation.dart';
|
||||
import 'package:kuwot/features/quote/domain/repositories/quote_repository.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_translations.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockQuoteRepository extends Mock implements QuoteRepository {}
|
||||
|
||||
void main() {
|
||||
late MockQuoteRepository mockQuoteRepository;
|
||||
late GetTranslations useCase;
|
||||
|
||||
setUp(() {
|
||||
mockQuoteRepository = MockQuoteRepository();
|
||||
useCase = GetTranslations(mockQuoteRepository);
|
||||
});
|
||||
|
||||
test('should get translations', () async {
|
||||
// arrange
|
||||
final tExpected = <Translation>[];
|
||||
when(
|
||||
() => mockQuoteRepository.getTranslations(),
|
||||
).thenAnswer((_) async => right(tExpected));
|
||||
|
||||
// act
|
||||
final result = await useCase(const NoParams());
|
||||
|
||||
// assert
|
||||
expect(result, right(tExpected));
|
||||
verify(() => mockQuoteRepository.getTranslations());
|
||||
verifyNoMoreInteractions(mockQuoteRepository);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/core/domain/no_params.dart';
|
||||
import 'package:kuwot/core/error/failure.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/background_image.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_background_images.dart';
|
||||
import 'package:kuwot/features/quote/presentation/bloc/background_images_bloc.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockGetBackgroundImages extends Mock implements GetBackgroundImages {}
|
||||
|
||||
class FakeNoParams extends Fake implements NoParams {}
|
||||
|
||||
void main() {
|
||||
late MockGetBackgroundImages mockGetBackgroundImages;
|
||||
late BackgroundImagesBloc backgroundImagesBloc;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeNoParams());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockGetBackgroundImages = MockGetBackgroundImages();
|
||||
backgroundImagesBloc = BackgroundImagesBloc(
|
||||
getBackgroundImages: mockGetBackgroundImages,
|
||||
);
|
||||
});
|
||||
|
||||
test('initial state is BackgroundImagesInitial', () {
|
||||
// assert
|
||||
expect(backgroundImagesBloc.state, const BackgroundImagesInitialState());
|
||||
});
|
||||
|
||||
group('GetBackgroundImages', () {
|
||||
test(
|
||||
'should get background photos from GetBackgroundImages use case',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockGetBackgroundImages(any()),
|
||||
).thenAnswer((_) async => right(const <BackgroundImage>[]));
|
||||
|
||||
// act
|
||||
backgroundImagesBloc.add(const GetBackgroundImagesEvent());
|
||||
await untilCalled(() => mockGetBackgroundImages(any()));
|
||||
|
||||
// assert
|
||||
verify(() => mockGetBackgroundImages(any())).called(1);
|
||||
verifyNoMoreInteractions(mockGetBackgroundImages);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should emit [BackgroundImagesLoading, BackgroundImagesLoaded] when data is gotten successfully',
|
||||
() async {
|
||||
// arrange
|
||||
const tBackgroundImages = <BackgroundImage>[];
|
||||
when(
|
||||
() => mockGetBackgroundImages(any()),
|
||||
).thenAnswer((_) async => right(tBackgroundImages));
|
||||
|
||||
// assert later
|
||||
final expected = [
|
||||
const BackgroundImagesLoadingState(),
|
||||
const BackgroundImagesLoadedState(tBackgroundImages),
|
||||
];
|
||||
expectLater(backgroundImagesBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
backgroundImagesBloc.add(const GetBackgroundImagesEvent());
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should emit [BackgroundImagesLoading, BackgroundImagesError] when getting data fails',
|
||||
() async {
|
||||
// arrange
|
||||
const tFailure = UnknownFailure(message: 'Unknown Failure');
|
||||
when(
|
||||
() => mockGetBackgroundImages(any()),
|
||||
).thenAnswer((_) async => left(tFailure));
|
||||
|
||||
// assert later
|
||||
final expected = [
|
||||
const BackgroundImagesLoadingState(),
|
||||
BackgroundImagesErrorState(message: tFailure.message),
|
||||
];
|
||||
expectLater(backgroundImagesBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
backgroundImagesBloc.add(const GetBackgroundImagesEvent());
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
180
test/features/quote/presentation/bloc/quote_bloc_test.dart
Normal file
180
test/features/quote/presentation/bloc/quote_bloc_test.dart
Normal file
|
|
@ -0,0 +1,180 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/core/data/local/config.dart';
|
||||
import 'package:kuwot/core/data/local/translation_target_config.dart';
|
||||
import 'package:kuwot/core/error/failure.dart';
|
||||
import 'package:kuwot/features/quote/domain/entities/quote.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_quote.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_translated_quote.dart';
|
||||
import 'package:kuwot/features/quote/presentation/bloc/quote_bloc.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockGetQuote extends Mock implements GetQuote {}
|
||||
|
||||
class MockGetTranslatedQuote extends Mock implements GetTranslatedQuote {}
|
||||
|
||||
class MockTranslationTargetConfig extends Mock
|
||||
implements Config<TranslationTarget> {}
|
||||
|
||||
class FakeQuoteParams extends Fake implements GetQuoteParams {}
|
||||
|
||||
class FakeTranslatedQuoteParams extends Fake
|
||||
implements GetTranslatedQuoteParams {}
|
||||
|
||||
void main() {
|
||||
late MockGetQuote mockGetQuote;
|
||||
late MockGetTranslatedQuote mockGetTranslatedQuote;
|
||||
late MockTranslationTargetConfig mockTranslationTargetConfig;
|
||||
late QuoteBloc quoteBloc;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeQuoteParams());
|
||||
registerFallbackValue(FakeTranslatedQuoteParams());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockGetQuote = MockGetQuote();
|
||||
mockGetTranslatedQuote = MockGetTranslatedQuote();
|
||||
mockTranslationTargetConfig = MockTranslationTargetConfig();
|
||||
|
||||
quoteBloc = QuoteBloc(
|
||||
getQuote: mockGetQuote,
|
||||
getTranslatedQuote: mockGetTranslatedQuote,
|
||||
translationTargetConfig: mockTranslationTargetConfig,
|
||||
);
|
||||
});
|
||||
|
||||
const tTranslationTarget = TranslationTarget(id: 'en', name: 'English');
|
||||
const tQuote = Quote(id: 1, author: 'author', body: 'text');
|
||||
const tFailure = UnknownFailure(message: 'Unknown Failure');
|
||||
|
||||
test('initial state is QuoteInitial', () {
|
||||
// assert
|
||||
expect(quoteBloc.state, const QuoteInitialState());
|
||||
});
|
||||
|
||||
group('GetQuote', () {
|
||||
test('should get quote from GetQuote use case', () async {
|
||||
// arrange
|
||||
when(() => mockGetQuote(any())).thenAnswer((_) async => right(tQuote));
|
||||
when(
|
||||
() => mockTranslationTargetConfig.get(),
|
||||
).thenAnswer((_) async => tTranslationTarget);
|
||||
|
||||
// act
|
||||
quoteBloc.add(const GetQuoteEvent());
|
||||
await untilCalled(() => mockTranslationTargetConfig.get());
|
||||
await untilCalled(() => mockGetQuote(any()));
|
||||
|
||||
// assert
|
||||
verify(() => mockGetQuote(any()));
|
||||
verifyNoMoreInteractions(mockGetQuote);
|
||||
});
|
||||
|
||||
test(
|
||||
'should emit [QuoteLoading, QuoteLoaded] when data is gotten successfully',
|
||||
() async {
|
||||
// arrange
|
||||
when(() => mockGetQuote(any())).thenAnswer((_) async => right(tQuote));
|
||||
when(
|
||||
() => mockTranslationTargetConfig.get(),
|
||||
).thenAnswer((_) async => tTranslationTarget);
|
||||
|
||||
// assert later
|
||||
const expected = [QuoteLoadingState(), QuoteLoadedState(quote: tQuote)];
|
||||
expectLater(quoteBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
quoteBloc.add(const GetQuoteEvent());
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should emit [QuoteLoading, QuoteError] when getting data fails',
|
||||
() async {
|
||||
// arrange
|
||||
when(() => mockGetQuote(any())).thenAnswer((_) async => left(tFailure));
|
||||
when(
|
||||
() => mockTranslationTargetConfig.get(),
|
||||
).thenAnswer((_) async => tTranslationTarget);
|
||||
|
||||
// assert later
|
||||
final expected = [
|
||||
const QuoteLoadingState(),
|
||||
QuoteErrorState(message: tFailure.message),
|
||||
];
|
||||
expectLater(quoteBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
quoteBloc.add(const GetQuoteEvent());
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
group('GetTranslatedQuote', () {
|
||||
test(
|
||||
'should get translated quote from GetTranslatedQuote use case',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockGetTranslatedQuote(any()),
|
||||
).thenAnswer((_) async => right(tQuote));
|
||||
when(
|
||||
() => mockTranslationTargetConfig.get(),
|
||||
).thenAnswer((_) async => tTranslationTarget);
|
||||
|
||||
// act
|
||||
quoteBloc.add(const GetTranslatedQuoteEvent(tTranslationTarget));
|
||||
await untilCalled(() => mockTranslationTargetConfig.get());
|
||||
await untilCalled(() => mockGetTranslatedQuote(any()));
|
||||
|
||||
// assert
|
||||
verify(() => mockGetTranslatedQuote(any()));
|
||||
verifyNoMoreInteractions(mockGetTranslatedQuote);
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should emit [QuoteLoading, QuoteLoaded] when data is gotten successfully',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockGetTranslatedQuote(any()),
|
||||
).thenAnswer((_) async => right(tQuote));
|
||||
when(
|
||||
() => mockTranslationTargetConfig.get(),
|
||||
).thenAnswer((_) async => tTranslationTarget);
|
||||
|
||||
// assert later
|
||||
const expected = [QuoteLoadingState(), QuoteLoadedState(quote: tQuote)];
|
||||
expectLater(quoteBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
quoteBloc.add(const GetTranslatedQuoteEvent(tTranslationTarget));
|
||||
},
|
||||
);
|
||||
|
||||
test(
|
||||
'should emit [QuoteLoading, QuoteError] when getting data fails',
|
||||
() async {
|
||||
// arrange
|
||||
when(
|
||||
() => mockGetTranslatedQuote(any()),
|
||||
).thenAnswer((_) async => left(tFailure));
|
||||
when(
|
||||
() => mockTranslationTargetConfig.get(),
|
||||
).thenAnswer((_) async => tTranslationTarget);
|
||||
|
||||
// assert later
|
||||
final expected = [
|
||||
const QuoteLoadingState(),
|
||||
QuoteErrorState(message: tFailure.message),
|
||||
];
|
||||
expectLater(quoteBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
quoteBloc.add(const GetTranslatedQuoteEvent(tTranslationTarget));
|
||||
},
|
||||
);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:fpdart/fpdart.dart';
|
||||
import 'package:kuwot/core/domain/no_params.dart';
|
||||
import 'package:kuwot/core/error/failure.dart';
|
||||
import 'package:kuwot/features/quote/domain/use_cases/get_translations.dart';
|
||||
import 'package:kuwot/features/quote/presentation/bloc/translations_bloc.dart';
|
||||
import 'package:mocktail/mocktail.dart';
|
||||
|
||||
class MockGetTranslations extends Mock implements GetTranslations {}
|
||||
|
||||
class FakeNoParams extends Fake implements NoParams {}
|
||||
|
||||
void main() {
|
||||
late MockGetTranslations mockGetTranslations;
|
||||
late TranslationsBloc translationsBloc;
|
||||
|
||||
setUpAll(() {
|
||||
registerFallbackValue(FakeNoParams());
|
||||
});
|
||||
|
||||
setUp(() {
|
||||
mockGetTranslations = MockGetTranslations();
|
||||
translationsBloc = TranslationsBloc(getTranslations: mockGetTranslations);
|
||||
});
|
||||
|
||||
group('GetTranslations', () {
|
||||
test('should get translations from GetTranslations use case', () async {
|
||||
// arrange
|
||||
when(() => mockGetTranslations(any())).thenAnswer((_) async => right([]));
|
||||
|
||||
// act
|
||||
translationsBloc.add(const GetTranslationsEvent());
|
||||
await untilCalled(() => mockGetTranslations(any()));
|
||||
|
||||
// assert
|
||||
verify(() => mockGetTranslations(any()));
|
||||
verifyNoMoreInteractions(mockGetTranslations);
|
||||
});
|
||||
|
||||
test('should emit [Loading, Loaded] when successful', () async {
|
||||
// arrange
|
||||
when(() => mockGetTranslations(any())).thenAnswer((_) async => right([]));
|
||||
|
||||
// assert later
|
||||
final expected = [
|
||||
const TranslationsLoadingState(),
|
||||
const TranslationsLoadedState(translations: []),
|
||||
];
|
||||
expectLater(translationsBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
translationsBloc.add(const GetTranslationsEvent());
|
||||
});
|
||||
|
||||
test('should emit [Loading, Error] when unsuccessful', () async {
|
||||
// arrange
|
||||
when(() => mockGetTranslations(any())).thenAnswer(
|
||||
(_) async => left(const UnknownFailure(message: 'Unknown Failure')),
|
||||
);
|
||||
|
||||
// assert later
|
||||
final expected = [
|
||||
const TranslationsLoadingState(),
|
||||
const TranslationsErrorState(message: 'Unknown Failure'),
|
||||
];
|
||||
expectLater(translationsBloc.stream, emitsInOrder(expected));
|
||||
|
||||
// act
|
||||
translationsBloc.add(const GetTranslationsEvent());
|
||||
});
|
||||
});
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue