Skip to content

[28] [Test] Survey - Detail screen #72

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,754 changes: 1,235 additions & 519 deletions coverage/lcov.info

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions lib/modules/survey_detail/components/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class Content extends StatelessWidget {
StreamsSelector0<SurveyInfo>.value(
stream: state._survey,
builder: (_, survey, __) => Image(
key: SurveyDetailView.backgroundImageKey,
image: NetworkImage(survey.coverImageUrl!),
fit: BoxFit.fill,
),
Expand Down Expand Up @@ -74,6 +75,7 @@ class Content extends StatelessWidget {
minWidth: 140,
),
child: Button(
key: SurveyDetailView.startSurveyButtonKey,
onPressed: () =>
state.delegate?.startSurveyButtonDidTap.add(null),
title: AppLocalizations.of(context)!
Expand Down
3 changes: 3 additions & 0 deletions lib/modules/survey_detail/survey_detail_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@ abstract class SurveyDetailViewDelegate implements AlertViewMixinDelegate {

abstract class SurveyDetailView extends View<SurveyDetailViewDelegate>
with ProgressHUDViewMixin, AlertViewMixin {
static const backgroundImageKey = Key("background_image_");
static const startSurveyButtonKey = Key("start_survey_button");

void setSurvey(SurveyInfo survey);
}

Expand Down
77 changes: 77 additions & 0 deletions test/modules/survey_detail/survey_detail_interactor_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/models/detailed_survey_info.dart';
import 'package:survey/models/survey_info.dart';
import 'package:survey/modules/survey_detail/survey_detail_module.dart';
import 'package:survey/repositories/survey_repository.dart';
import 'package:survey/services/locator/locator_service.dart';
import '../../helpers/behavior_subject_generator.dart';
import 'survey_detail_interactor_test.mocks.dart';

@GenerateMocks([SurveyDetailInteractorDelegate, SurveyRepository])
void main() {
describe("a SurveyDetail interactor", () {
late SurveyDetailInteractor interactor;
late MockSurveyDetailInteractorDelegate delegate;
late BehaviorSubjectGenerator generator;
late MockSurveyRepository surveyRepository;

final survey = SurveyInfo();
survey.id = "id";

beforeEach(() {
generator = BehaviorSubjectGenerator();

surveyRepository = MockSurveyRepository();
locator.registerSingleton<SurveyRepository>(surveyRepository);

delegate = MockSurveyDetailInteractorDelegate();
when(delegate.detailedSurveyDidFetch)
.thenAnswer((realInvocation) => generator.make(0));
when(delegate.detailedSurveyDidFailToFetch)
.thenAnswer((realInvocation) => generator.make(1));

interactor = SurveyDetailInteractorImpl();
interactor.delegate = delegate;
interactor.arguments = SurveyDetailArguments(survey: survey);
});

describe("its survey is got", () {
it("returns correct survey", () {
expect(interactor.survey, survey);
});
});

describe("its fetchDetailedSurvey() is called", () {
context("when survey repository's fetchDetailedSurvey() return success",
() {
final detailedSurvey = DetailedSurveyInfo();
beforeEach(() {
when(surveyRepository.fetchDetailedSurvey(any))
.thenAnswer((realInvocation) => Future.value(detailedSurvey));
interactor.fetchDetailedSurvey();
});

it("triggers delegate's detailedSurveyDidFetch to emit", () {
expect(delegate.detailedSurveyDidFetch, emits(detailedSurvey));
});
});

context("when survey repository's fetchDetailedSurvey() return failure",
() {
final exception = Exception();
beforeEach(() {
when(surveyRepository.fetchDetailedSurvey(any))
.thenAnswer((realInvocation) => Future.error(exception));
interactor.fetchDetailedSurvey();
});

it("triggers delegate's detailedSurveyDidFailToFetch to emit", () {
expect(delegate.detailedSurveyDidFailToFetch, emits(exception));
});
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
// Mocks generated by Mockito 5.0.7 from annotations
// in survey/test/modules/survey_detail/survey_detail_interactor_test.dart.
// Do not manually edit this file.

import 'dart:async' as _i6;

import 'package:mockito/mockito.dart' as _i1;
import 'package:rxdart/src/subjects/behavior_subject.dart' as _i2;
import 'package:survey/models/detailed_survey_info.dart' as _i3;
import 'package:survey/models/survey_info.dart' as _i7;
import 'package:survey/modules/survey_detail/survey_detail_module.dart' as _i4;
import 'package:survey/repositories/survey_repository.dart' as _i5;

// ignore_for_file: comment_references
// ignore_for_file: unnecessary_parenthesis

// ignore_for_file: prefer_const_constructors

// ignore_for_file: avoid_redundant_argument_values

class _FakeBehaviorSubject<T> extends _i1.Fake
implements _i2.BehaviorSubject<T> {}

class _FakeDetailedSurveyInfo extends _i1.Fake
implements _i3.DetailedSurveyInfo {}

/// A class which mocks [SurveyDetailInteractorDelegate].
///
/// See the documentation for Mockito's code generation for more information.
class MockSurveyDetailInteractorDelegate extends _i1.Mock
implements _i4.SurveyDetailInteractorDelegate {
MockSurveyDetailInteractorDelegate() {
_i1.throwOnMissingStub(this);
}

@override
_i2.BehaviorSubject<_i3.DetailedSurveyInfo> get detailedSurveyDidFetch =>
(super.noSuchMethod(Invocation.getter(#detailedSurveyDidFetch),
returnValue: _FakeBehaviorSubject<_i3.DetailedSurveyInfo>())
as _i2.BehaviorSubject<_i3.DetailedSurveyInfo>);
@override
_i2.BehaviorSubject<Exception> get detailedSurveyDidFailToFetch =>
(super.noSuchMethod(Invocation.getter(#detailedSurveyDidFailToFetch),
returnValue: _FakeBehaviorSubject<Exception>())
as _i2.BehaviorSubject<Exception>);
}

/// A class which mocks [SurveyRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockSurveyRepository extends _i1.Mock implements _i5.SurveyRepository {
MockSurveyRepository() {
_i1.throwOnMissingStub(this);
}

@override
_i6.Future<bool> get isSurveysCached =>
(super.noSuchMethod(Invocation.getter(#isSurveysCached),
returnValue: Future<bool>.value(false)) as _i6.Future<bool>);
@override
_i6.Future<List<_i7.SurveyInfo>> fetchSurveys({bool? force}) =>
(super.noSuchMethod(Invocation.method(#fetchSurveys, [], {#force: force}),
returnValue:
Future<List<_i7.SurveyInfo>>.value(<_i7.SurveyInfo>[]))
as _i6.Future<List<_i7.SurveyInfo>>);
@override
_i6.Future<_i3.DetailedSurveyInfo> fetchDetailedSurvey(String? id) =>
(super.noSuchMethod(Invocation.method(#fetchDetailedSurvey, [id]),
returnValue: Future<_i3.DetailedSurveyInfo>.value(
_FakeDetailedSurveyInfo()))
as _i6.Future<_i3.DetailedSurveyInfo>);
}
27 changes: 27 additions & 0 deletions test/modules/survey_detail/survey_detail_module_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import 'package:flutter/widgets.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/modules/survey_detail/survey_detail_module.dart';

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

void main() {
describe("a SurveyDetail module", () {
late SurveyDetailModule module;
beforeEach(() {
module = SurveyDetailModule();
});

describe("its build is called", () {
late Widget widget;

beforeEach(() {
widget = module.build(MockBuildContext());
});

it("returns SurveyDetailViewImpl", () {
expect(widget, isA<SurveyDetailViewImpl>());
});
});
});
}
88 changes: 88 additions & 0 deletions test/modules/survey_detail/survey_detail_presenter_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import 'package:mockito/annotations.dart';
import 'package:mockito/mockito.dart';
import 'package:quick_test/quick_test.dart';
import 'package:survey/models/detailed_survey_info.dart';
import 'package:survey/models/survey_info.dart';
import 'package:survey/modules/survey_detail/survey_detail_module.dart';

import '../../mocks/build_context.dart';
import 'survey_detail_presenter_test.mocks.dart';

@GenerateMocks([SurveyDetailView, SurveyDetailRouter, SurveyDetailInteractor])
void main() {
describe("a SurveyDetail presenter", () {
late SurveyDetailPresenterImpl presenter;
late MockSurveyDetailView view;
late MockSurveyDetailRouter router;
late MockSurveyDetailInteractor interactor;
late MockBuildContext buildContext;
final survey = SurveyInfo();

beforeEach(() {
buildContext = MockBuildContext();

view = MockSurveyDetailView();
when(view.context).thenReturn(buildContext);

router = MockSurveyDetailRouter();

interactor = MockSurveyDetailInteractor();
when(interactor.survey).thenReturn(survey);

presenter = SurveyDetailPresenterImpl();
presenter.configure(view: view, interactor: interactor, router: router);
});

describe("its detailedSurveyDidFailToFetch to emit", () {
final exception = Exception();
beforeEach(() {
presenter.detailedSurveyDidFailToFetch.add(exception);
});

it("triggers view to dismiss progress hud and alert error", () {
verify(view.dismissProgressHUD()).called(1);
verify(view.alert(exception)).called(1);
});
});

describe("its detailedSurveyDidFetch emits", () {
final survey = DetailedSurveyInfo();
beforeEach(() {
presenter.detailedSurveyDidFetch.add(survey);
});

it("triggers view to dismiss progress hud", () {
verify(view.dismissProgressHUD()).called(1);
});

it("triggers router to push to Survey Questions screen", () {
verify(
router.pushToSurveyQuestionsScreen(buildContext, survey: survey));
});
});

describe("its stateDidInit emits", () {
beforeEach(() {
presenter.stateDidInit.add(null);
});

it("triggers view to set survey", () {
verify(view.setSurvey(survey)).called(1);
});
});

describe("its startSurveyButtonDidTap emits", () {
beforeEach(() {
presenter.startSurveyButtonDidTap.add(null);
});

it("triggers view to dismiss progress hud", () {
verify(view.showProgressHUD()).called(1);
});

it("triggers interactor to fetch detailed survey", () {
verify(interactor.fetchDetailedSurvey()).called(1);
});
});
});
}
Loading