Skip to content

Commit

Permalink
chore: write tests for survey questions screen (#64)
Browse files Browse the repository at this point in the history
  • Loading branch information
markgravity committed May 17, 2021
1 parent fac8ce9 commit 0626682
Show file tree
Hide file tree
Showing 25 changed files with 2,098 additions and 288 deletions.
1,024 changes: 763 additions & 261 deletions coverage/lcov.info

Large diffs are not rendered by default.

7 changes: 2 additions & 5 deletions lib/gen/assets.gen.dart

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 6 additions & 4 deletions lib/modules/survey_completed/survey_completed_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ class SurveyCompletedViewImpl extends StatefulWidget {
const SurveyCompletedViewImpl({Key? key}) : super(key: key);

@override
_SurveyCompletedViewImplState createState() => _SurveyCompletedViewImplState();
_SurveyCompletedViewImplState createState() =>
_SurveyCompletedViewImplState();
}

class _SurveyCompletedViewImplState
extends ViewState<SurveyCompletedViewImpl, SurveyCompletedModule, SurveyCompletedViewDelegate>
implements SurveyCompletedView {
class _SurveyCompletedViewImplState extends ViewState<
SurveyCompletedViewImpl,
SurveyCompletedModule,
SurveyCompletedViewDelegate> implements SurveyCompletedView {
@override
Widget build(BuildContext context) {
return const Screen(
Expand Down
24 changes: 18 additions & 6 deletions lib/modules/survey_questions/components/answers/nps_answer.dart
Original file line number Diff line number Diff line change
@@ -1,6 +1,14 @@
part of '../../survey_questions_module.dart';

class NPSAnswer extends StatefulWidget {
static const itemKey = Key("nps_answer_item");
static const itemTextKey = Key("nps_answer_item_text");
static const lowestScoreTextKey = Key("nps_answer_lowest_score_text_key");
static const highestScoreTextKey = Key("nps_answer_highest_score_text_key");

static const textNormalColor = Color.fromRGBO(255, 255, 255, 0.5);
static const textHighlightColor = Colors.white;

const NPSAnswer({
Key? key,
required this.items,
Expand Down Expand Up @@ -52,10 +60,11 @@ class _NPSAnswerState extends State<NPSAnswer> {
builder: (_, selected, __) => Text(
AppLocalizations.of(context)!
.surveyQuestionsScreenLowestScoreNPSText,
key: NPSAnswer.lowestScoreTextKey,
style: TextStyle(
color: selected == 0
? Colors.white
: Colors.white.withOpacity(0.5),
? NPSAnswer.textHighlightColor
: NPSAnswer.textNormalColor,
fontSize: 17,
fontWeight: FontWeight.w800,
),
Expand All @@ -66,10 +75,11 @@ class _NPSAnswerState extends State<NPSAnswer> {
builder: (_, selected, __) => Text(
AppLocalizations.of(context)!
.surveyQuestionsScreenHighestScoreNPSText,
key: NPSAnswer.highestScoreTextKey,
style: TextStyle(
color: selected == widget.items.length - 1
? Colors.white
: Colors.white.withOpacity(0.5),
? NPSAnswer.textHighlightColor
: NPSAnswer.textNormalColor,
fontSize: 17,
fontWeight: FontWeight.w800,
),
Expand All @@ -84,6 +94,7 @@ class _NPSAnswerState extends State<NPSAnswer> {

Widget _itemBuilder(BuildContext context, int i) {
return GestureDetector(
key: NPSAnswer.itemKey,
onTap: () {
selected.add(i);
if (widget.onSelect != null) widget.onSelect!(widget.items[i]);
Expand All @@ -103,11 +114,12 @@ class _NPSAnswerState extends State<NPSAnswer> {
stream: selected,
builder: (_, selected, __) => Text(
widget.items[i].content!,
key: NPSAnswer.itemTextKey,
textAlign: TextAlign.center,
style: TextStyle(
color: selected != null && i <= selected
? Colors.white
: Colors.white.withOpacity(0.5),
? NPSAnswer.textHighlightColor
: NPSAnswer.textNormalColor,
fontSize: 20,
fontWeight: FontWeight.w800,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
part of '../../survey_questions_module.dart';

class RatingAnswer extends StatefulWidget {
static const int numberOfItems = 5;
static const double normalOpacity = 0.5;
static const double highlightOpacity = 1;

const RatingAnswer({
Key? key,
required this.symbol,
Expand Down Expand Up @@ -28,7 +32,7 @@ class _RatingAnswerState extends State<RatingAnswer> {
shrinkWrap: true,
scrollDirection: Axis.horizontal,
itemBuilder: _itemBuilder,
itemCount: 5,
itemCount: RatingAnswer.numberOfItems,
),
);
}
Expand All @@ -38,7 +42,9 @@ class _RatingAnswerState extends State<RatingAnswer> {
stream: selected,
builder: (_, selected, child) {
return Opacity(
opacity: selected != null && i <= selected ? 1 : 0.5,
opacity: selected != null && i <= selected
? RatingAnswer.highlightOpacity
: RatingAnswer.normalOpacity,
child: child,
);
},
Expand Down
23 changes: 19 additions & 4 deletions lib/modules/survey_questions/components/answers/select_answer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,16 @@ part of '../../survey_questions_module.dart';

class SelectAnswer extends StatefulWidget {
static const itemHeight = 50.0;
static const itemKey = Key("select_answer_item");
static const itemTextKey = Key("select_answer_item_text");
static const checkboxKey = Key("select_answer_check_box");
static const checkboxSelectedImageKey =
Key("select_answer_checkbox_selected_image");
static const checkboxNormalImageKey =
Key("select_answer_checkbox_normal_image");

static const highlightFontWeight = FontWeight.w800;
static const normalFontWeight = FontWeight.normal;

const SelectAnswer({
Key? key,
Expand Down Expand Up @@ -74,6 +84,7 @@ class _SelectAnswerState extends State<SelectAnswer> {

Widget _itemBuilder(BuildContext context, int i) {
return SizedBox(
key: SelectAnswer.itemKey,
height: SelectAnswer.itemHeight,
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
Expand All @@ -84,13 +95,14 @@ class _SelectAnswerState extends State<SelectAnswer> {
builder: (_, selectedIndexes, __) {
return Text(
widget.options[i].content!,
key: SelectAnswer.itemTextKey,
textAlign: TextAlign.left,
overflow: TextOverflow.ellipsis,
style: TextStyle(
color: Colors.white,
fontWeight: selectedIndexes.contains(i)
? FontWeight.w800
: FontWeight.normal,
? SelectAnswer.highlightFontWeight
: SelectAnswer.normalFontWeight,
fontSize: 20,
),
);
Expand All @@ -99,12 +111,15 @@ class _SelectAnswerState extends State<SelectAnswer> {
),
if (widget.isMultiSelection)
GestureDetector(
key: SelectAnswer.checkboxKey,
onTap: () => _onCheckboxTap(i),
child: StreamsSelector0<List<int>>.value(
stream: selectedIndexes,
builder: (_, selectedIndexes, __) => selectedIndexes.contains(i)
? Assets.images.roundedCheckboxSelected.svg()
: Assets.images.roundedCheckboxNormal.svg(),
? Assets.images.roundedCheckboxSelected
.svg(key: SelectAnswer.checkboxSelectedImageKey)
: Assets.images.roundedCheckboxNormal
.svg(key: SelectAnswer.checkboxNormalImageKey),
),
),
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
part of '../../survey_questions_module.dart';

class TextFieldAnswer extends StatefulWidget {
static const textFieldKey = Key("text_field_answer_text_field");

const TextFieldAnswer({
Key? key,
this.isMultiLines = false,
Expand Down Expand Up @@ -30,6 +32,7 @@ class _TextFieldAnswerState extends State<TextFieldAnswer> {
@override
Widget build(BuildContext context) {
return PlatformTextField(
key: TextFieldAnswer.textFieldKey,
controller: textController,
maxLines: widget.isMultiLines ? null : 1,
minLines: widget.isMultiLines ? 10 : null,
Expand Down
8 changes: 6 additions & 2 deletions lib/modules/survey_questions/components/content.dart
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ class Content extends StatelessWidget {
stream: state._questions,
builder: (_, questions, __) => CarouselSlider.builder(
itemCount: questions.length,
itemBuilder: (_, i, __) =>
Slide(questions: questions, index: i),
itemBuilder: (_, i, __) => Slide(
key: SurveyQuestionsView.slideKey,
questions: questions,
index: i,
),
carouselController: state._carouselController,
options: CarouselOptions(
height: double.infinity,
Expand All @@ -38,6 +41,7 @@ class Content extends StatelessWidget {
isBackButtonHidden: true,
leftChildren: [
PlatformButton(
key: SurveyQuestionsView.closeButtonKey,
onPressed: () =>
state.delegate?.closeButtonDidTap.add(null),
child: Assets.images.navCloseButton.svg(),
Expand Down
1 change: 1 addition & 0 deletions lib/modules/survey_questions/components/slide.dart
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class Slide extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.end,
children: [
Button(
key: SurveyQuestionsView.submitButtonKey,
onPressed: () => state.delegate?.submitButtonDidTap
.add(_answers.value),
title: _isLast
Expand Down
4 changes: 4 additions & 0 deletions lib/modules/survey_questions/survey_questions_view.dart
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ abstract class SurveyQuestionsViewDelegate implements AlertViewMixinDelegate {

abstract class SurveyQuestionsView extends View<SurveyQuestionsViewDelegate>
with AlertViewMixin, ProgressHUDViewMixin {
static const slideKey = Key("slide");
static const closeButtonKey = Key("close_button");
static const submitButtonKey = Key("submit_button");

void setQuestions(List<SurveyQuestionInfo> questions);

void showCloseConfirmDialog();
Expand Down
13 changes: 11 additions & 2 deletions test/modules/home/home_interactor_test.mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,10 @@ 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 _i5;
import 'package:survey/models/survey_submit_question_info.dart' as _i9;
import 'package:survey/models/user_info.dart' as _i6;
import 'package:survey/modules/home/home_module.dart' as _i4;
import 'package:survey/repositories/auth_repository.dart' as _i9;
import 'package:survey/repositories/auth_repository.dart' as _i10;
import 'package:survey/repositories/survey_repository.dart' as _i7;

// ignore_for_file: comment_references
Expand Down Expand Up @@ -80,12 +81,20 @@ class MockSurveyRepository extends _i1.Mock implements _i7.SurveyRepository {
returnValue: Future<_i3.DetailedSurveyInfo>.value(
_FakeDetailedSurveyInfo()))
as _i8.Future<_i3.DetailedSurveyInfo>);
@override
_i8.Future<void> submit(
{String? surveyId, List<_i9.SurveySubmitQuestionInfo>? questions}) =>
(super.noSuchMethod(
Invocation.method(
#submit, [], {#surveyId: surveyId, #questions: questions}),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i8.Future<void>);
}

/// A class which mocks [AuthRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockAuthRepository extends _i1.Mock implements _i9.AuthRepository {
class MockAuthRepository extends _i1.Mock implements _i10.AuthRepository {
MockAuthRepository() {
_i1.throwOnMissingStub(this);
}
Expand Down
13 changes: 11 additions & 2 deletions test/modules/side_menu/side_menu_interactor_test.mocks.dart
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@ 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/models/survey_submit_question_info.dart' as _i8;
import 'package:survey/modules/side_menu/side_menu_module.dart' as _i4;
import 'package:survey/repositories/auth_repository.dart' as _i8;
import 'package:survey/repositories/auth_repository.dart' as _i9;
import 'package:survey/repositories/survey_repository.dart' as _i5;

// ignore_for_file: comment_references
Expand Down Expand Up @@ -64,12 +65,20 @@ class MockSurveyRepository extends _i1.Mock implements _i5.SurveyRepository {
returnValue: Future<_i3.DetailedSurveyInfo>.value(
_FakeDetailedSurveyInfo()))
as _i6.Future<_i3.DetailedSurveyInfo>);
@override
_i6.Future<void> submit(
{String? surveyId, List<_i8.SurveySubmitQuestionInfo>? questions}) =>
(super.noSuchMethod(
Invocation.method(
#submit, [], {#surveyId: surveyId, #questions: questions}),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i6.Future<void>);
}

/// A class which mocks [AuthRepository].
///
/// See the documentation for Mockito's code generation for more information.
class MockAuthRepository extends _i1.Mock implements _i8.AuthRepository {
class MockAuthRepository extends _i1.Mock implements _i9.AuthRepository {
MockAuthRepository() {
_i1.throwOnMissingStub(this);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ 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/models/survey_submit_question_info.dart' as _i8;
import 'package:survey/modules/survey_detail/survey_detail_module.dart' as _i4;
import 'package:survey/repositories/survey_repository.dart' as _i5;

Expand Down Expand Up @@ -69,4 +70,12 @@ class MockSurveyRepository extends _i1.Mock implements _i5.SurveyRepository {
returnValue: Future<_i3.DetailedSurveyInfo>.value(
_FakeDetailedSurveyInfo()))
as _i6.Future<_i3.DetailedSurveyInfo>);
@override
_i6.Future<void> submit(
{String? surveyId, List<_i8.SurveySubmitQuestionInfo>? questions}) =>
(super.noSuchMethod(
Invocation.method(
#submit, [], {#surveyId: surveyId, #questions: questions}),
returnValue: Future<void>.value(null),
returnValueForMissingStub: Future.value()) as _i6.Future<void>);
}
Loading

0 comments on commit 0626682

Please sign in to comment.