Skip to content

Commit

Permalink
fix: avoid random updates of hints readable response (#393)
Browse files Browse the repository at this point in the history
* feat: update hint model to store the readable response

* feat: save readable hint response to database

* feat: update ui

* fix: hint response test
  • Loading branch information
jsgalarraga authored Apr 25, 2024
1 parent 53bfcb3 commit b3f466e
Show file tree
Hide file tree
Showing 17 changed files with 238 additions and 48 deletions.
12 changes: 10 additions & 2 deletions api/packages/game_domain/lib/src/models/hint.dart
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,11 @@ part 'hint.g.dart';
@JsonSerializable(ignoreUnannotated: true)
class Hint extends Equatable {
/// {@macro hint}
const Hint({required this.question, required this.response});
const Hint({
required this.question,
required this.response,
required this.readableResponse,
});

/// {@macro hint}
factory Hint.fromJson(Map<String, dynamic> json) => _$HintFromJson(json);
Expand All @@ -22,11 +26,15 @@ class Hint extends Equatable {
@JsonKey()
final HintResponse response;

/// Readable `response`.
@JsonKey()
final String readableResponse;

/// Returns a json representation from this instance.
Map<String, dynamic> toJson() => _$HintToJson(this);

@override
List<Object?> get props => [question, response];
List<Object?> get props => [question, response, readableResponse];
}

/// Enum representing the possible responses to a hint question.
Expand Down
2 changes: 2 additions & 0 deletions api/packages/game_domain/lib/src/models/hint.g.dart

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

11 changes: 10 additions & 1 deletion api/packages/game_domain/test/src/models/hint_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,19 @@ import 'package:test/test.dart';
void main() {
group('Hint', () {
test('creates correct json object from Hint object', () {
final hint = Hint(question: 'to be?', response: HintResponse.yes);
final hint = Hint(
question: 'to be?',
response: HintResponse.yes,
readableResponse: 'Yes, that is correct!',
);
final json = hint.toJson();

expect(
json,
equals({
'question': 'to be?',
'response': 'yes',
'readableResponse': 'Yes, that is correct!',
}),
);
});
Expand All @@ -22,6 +27,7 @@ void main() {
final json = {
'question': 'or not to be?',
'response': 'notApplicable',
'readableResponse': "I can't answer that.",
};
final hint = Hint.fromJson(json);
expect(
Expand All @@ -30,6 +36,7 @@ void main() {
Hint(
question: 'or not to be?',
response: HintResponse.notApplicable,
readableResponse: "I can't answer that.",
),
),
);
Expand All @@ -39,10 +46,12 @@ void main() {
final firstHint = Hint(
question: 'to be?',
response: HintResponse.no,
readableResponse: 'Nope!',
);
final secondHint = Hint(
question: 'to be?',
response: HintResponse.no,
readableResponse: 'Nope!',
);
expect(firstHint, equals(secondHint));
});
Expand Down
2 changes: 2 additions & 0 deletions api/packages/hint_repository/lib/src/hint_repository.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import 'package:db_client/db_client.dart';
import 'package:dio/dio.dart';
import 'package:game_domain/game_domain.dart';
import 'package:hint_repository/hint_repository.dart';
import 'package:hint_repository/src/hint_response_extension.dart';

/// {@template hint_repository}
/// A repository to handle the hints.
Expand Down Expand Up @@ -102,6 +103,7 @@ class HintRepository {
final hint = Hint(
question: question,
response: hintResponse,
readableResponse: hintResponse.readable,
);
return hint;
} catch (e, stackTrace) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import 'dart:math';

import 'package:flutter/foundation.dart';
import 'package:game_domain/game_domain.dart';
import 'package:meta/meta.dart';

/// An extension on [HintResponse] to provide readable responses.
extension HintResponseExtension on HintResponse {
/// Returns a readable response for the hint.
String get readable {
final random = Random();

Expand All @@ -19,6 +21,7 @@ extension HintResponseExtension on HintResponse {
}
}

/// Response alternatives to [HintResponse.yes].
@visibleForTesting
const yesResponses = [
'Yes, that is correct!',
Expand All @@ -33,6 +36,7 @@ const yesResponses = [
'Yes!',
];

/// Response alternatives to [HintResponse.no].
@visibleForTesting
const noResponses = [
'No, unfortunately.',
Expand All @@ -47,6 +51,7 @@ const noResponses = [
'Sorry, but no!',
];

/// Response alternatives to [HintResponse.notApplicable].
@visibleForTesting
const notApplicableResponses = [
"I can't answer that.",
Expand Down
1 change: 1 addition & 0 deletions api/packages/hint_repository/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ dependencies:
game_domain:
path: ../game_domain
http: ^1.2.1
meta: ^1.14.0

dev_dependencies:
mocktail: ^1.0.3
Expand Down
55 changes: 46 additions & 9 deletions api/packages/hint_repository/test/src/hint_repository_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -118,13 +118,34 @@ void main() {
final hint = await hintRepository.generateHint(
wordAnswer: 'answer',
question: 'question',
previousHints: [Hint(question: 'is it?', response: HintResponse.no)],
previousHints: [
Hint(
question: 'is it?',
response: HintResponse.no,
readableResponse: 'Nope!',
),
],
userToken: 'token',
);

expect(
hint,
equals(Hint(question: 'question', response: HintResponse.yes)),
isA<Hint>()
.having(
(hint) => hint.question,
'the question field',
'question',
)
.having(
(hint) => hint.response,
'the response field',
HintResponse.yes,
)
.having(
(hint) => hint.readableResponse,
'the readableResponse field',
isA<String>(),
),
);
});

Expand Down Expand Up @@ -155,12 +176,22 @@ void main() {

expect(
hint,
equals(
Hint(
question: 'question',
response: HintResponse.notApplicable,
),
),
isA<Hint>()
.having(
(hint) => hint.question,
'the question field',
'question',
)
.having(
(hint) => hint.response,
'the response field',
HintResponse.notApplicable,
)
.having(
(hint) => hint.readableResponse,
'the readableResponse field',
isA<String>(),
),
);
},
);
Expand Down Expand Up @@ -244,7 +275,11 @@ void main() {
userId: 'userId',
wordId: 'wordId',
hints: [
Hint(question: 'question', response: HintResponse.yes),
Hint(
question: 'question',
response: HintResponse.yes,
readableResponse: 'Yeah!',
),
],
);

Expand All @@ -258,6 +293,7 @@ void main() {
{
'question': 'question',
'response': 'yes',
'readableResponse': 'Yeah!',
},
],
},
Expand All @@ -277,6 +313,7 @@ void main() {
Hint(
question: 'question',
response: HintResponse.yes,
readableResponse: 'Yeah!',
),
],
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:game_domain/game_domain.dart';
import 'package:io_crossword/hint/hint.dart';
import 'package:hint_repository/src/hint_response_extension.dart';
import 'package:test/test.dart';

void main() {
group('HintResponseExtension', () {
Expand Down
65 changes: 55 additions & 10 deletions api/test/routes/game/hint_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -107,13 +107,23 @@ void main() {
userToken: 'token',
),
).thenAnswer(
(_) async => Hint(question: 'question', response: HintResponse.no),
(_) async => Hint(
question: 'question',
response: HintResponse.no,
readableResponse: 'Nope!',
),
);
when(
() => hintRepository.saveHints(
userId: 'userId',
wordId: 'wordId',
hints: [Hint(question: 'question', response: HintResponse.no)],
hints: [
Hint(
question: 'question',
response: HintResponse.no,
readableResponse: 'Nope!',
),
],
),
).thenAnswer((_) async {});

Expand All @@ -126,6 +136,7 @@ void main() {
'hint': {
'question': 'question',
'response': 'no',
'readableResponse': 'Nope!',
},
'maxHints': 10,
}),
Expand All @@ -134,7 +145,13 @@ void main() {
() => hintRepository.saveHints(
userId: 'userId',
wordId: 'wordId',
hints: [Hint(question: 'question', response: HintResponse.no)],
hints: [
Hint(
question: 'question',
response: HintResponse.no,
readableResponse: 'Nope!',
),
],
),
).called(1);
},
Expand Down Expand Up @@ -201,7 +218,11 @@ void main() {
);
},
);
final hint = Hint(question: 'question', response: HintResponse.yes);
final hint = Hint(
question: 'question',
response: HintResponse.yes,
readableResponse: 'Yes, that is correct!',
);
when(
() => hintRepository.getPreviousHints(
userId: 'userId',
Expand Down Expand Up @@ -298,9 +319,21 @@ void main() {
'returns Response with a list of hints',
() async {
final hintList = [
Hint(question: 'question1', response: HintResponse.yes),
Hint(question: 'question2', response: HintResponse.notApplicable),
Hint(question: 'question3', response: HintResponse.no),
Hint(
question: 'question1',
response: HintResponse.yes,
readableResponse: 'yes',
),
Hint(
question: 'question2',
response: HintResponse.notApplicable,
readableResponse: 'nah',
),
Hint(
question: 'question3',
response: HintResponse.no,
readableResponse: 'nope',
),
];
when(() => uri.queryParameters).thenReturn({'wordId': 'wordId'});
when(() => hintRepository.isHintsEnabled())
Expand All @@ -320,9 +353,21 @@ void main() {
await response.json(),
equals({
'hints': [
{'question': 'question1', 'response': 'yes'},
{'question': 'question2', 'response': 'notApplicable'},
{'question': 'question3', 'response': 'no'},
{
'question': 'question1',
'response': 'yes',
'readableResponse': 'yes',
},
{
'question': 'question2',
'response': 'notApplicable',
'readableResponse': 'nah',
},
{
'question': 'question3',
'response': 'no',
'readableResponse': 'nope',
},
],
'maxHints': 10,
}),
Expand Down
1 change: 0 additions & 1 deletion lib/hint/extensions/extensions.dart

This file was deleted.

1 change: 0 additions & 1 deletion lib/hint/hint.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
export 'bloc/hint_bloc.dart';
export 'extensions/extensions.dart';
export 'widgets/widgets.dart';
2 changes: 1 addition & 1 deletion lib/hint/widgets/hints_section.dart
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ class HintQuestionResponse extends StatelessWidget {
textAlign: TextAlign.center,
),
const SizedBox(height: 8),
HintText(text: hint.response.readable),
HintText(text: hint.readableResponse),
const SizedBox(height: 8),
],
);
Expand Down
Loading

0 comments on commit b3f466e

Please sign in to comment.