Skip to content

Commit

Permalink
fix: add userId to Word
Browse files Browse the repository at this point in the history
  • Loading branch information
marwfair committed Jun 27, 2024
1 parent 83f17a1 commit 944c0c1
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 8 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class CrosswordRepository {
/// solvedTimestamp attribute.
/// The second value returns true if the answer was previously answered.
Future<(bool, bool)> answerWord(
String userId,
String wordId,
Mascot mascot,
String userAnswer,
Expand Down Expand Up @@ -134,6 +135,13 @@ class CrosswordRepository {
);
}

if (word.userId == userId) {
throw CrosswordRepositoryException(
'Word with id $wordId was already solved by current user',
StackTrace.current,
);
}

// The word has been solved previously
if (word.solvedTimestamp != null) {
return (true, true);
Expand All @@ -143,6 +151,7 @@ class CrosswordRepository {
answer: correctAnswer.answer,
solvedTimestamp: clock.now().millisecondsSinceEpoch,
mascot: mascot,
userId: userId,
);
updatedSection = updatedSection.copyWith(
words: [...section.words..remove(word), solvedWord],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ void main() {
axis: WordAxis.horizontal,
answer: 'hap y',
clue: '',
userId: 'userId',
);

final word4 = Word(
Expand Down Expand Up @@ -296,7 +297,12 @@ void main() {
final time = DateTime.now();
final clock = Clock.fixed(time);
await withClock(clock, () async {
final valid = await repository.answerWord('4', Mascot.dino, 'solved');
final valid = await repository.answerWord(
'userId',
'4',
Mascot.dino,
'solved',
);
expect(valid, (true, true));
});
});
Expand All @@ -306,8 +312,12 @@ void main() {
final time = DateTime.now();
final clock = Clock.fixed(time);
await withClock(clock, () async {
final valid =
await repository.answerWord('1', Mascot.dino, 'flutter');
final valid = await repository.answerWord(
'userId',
'1',
Mascot.dino,
'flutter',
);
expect(valid, (true, false));

verify(
Expand Down Expand Up @@ -339,6 +349,7 @@ void main() {
solvedTimestamp: time.millisecondsSinceEpoch,
mascot: Mascot.dino,
answer: 'flutter',
userId: 'userId',
)
.toJson(),
word2.copyWith(answer: 'bl ').toJson(),
Expand All @@ -351,7 +362,12 @@ void main() {
});

test('returns (false, false) if answer is incorrect', () async {
final valid = await repository.answerWord('1', Mascot.dino, 'android');
final valid = await repository.answerWord(
'userId',
'1',
Mascot.dino,
'android',
);
expect(valid, (false, false));
});

Expand All @@ -362,7 +378,12 @@ void main() {
() => dbClient.getById(answersCollection, 'fake'),
).thenAnswer((_) async => null);
expect(
() => repository.answerWord('fake', Mascot.dino, 'flutter'),
() => repository.answerWord(
'userId',
'fake',
Mascot.dino,
'flutter',
),
throwsA(isA<CrosswordRepositoryException>()),
);
},
Expand Down Expand Up @@ -395,7 +416,12 @@ void main() {
).thenAnswer((_) async => answersRecord);

expect(
() => repository.answerWord('3', Mascot.sparky, 'happy'),
() => repository.answerWord(
'userId',
'3',
Mascot.sparky,
'happy',
),
throwsA(isA<CrosswordRepositoryException>()),
);
},
Expand All @@ -412,7 +438,12 @@ void main() {
).thenAnswer((_) async => []);

expect(
() => repository.answerWord('1', Mascot.dino, 'flutter'),
() => repository.answerWord(
'userId',
'1',
Mascot.dino,
'flutter',
),
throwsA(isA<CrosswordRepositoryException>()),
);
},
Expand All @@ -434,7 +465,52 @@ void main() {
() => dbClient.getById(answersCollection, 'fake'),
).thenAnswer((_) async => answersRecord);
expect(
() => repository.answerWord('fake', Mascot.dino, 'flutter'),
() => repository.answerWord(
'userId',
'fake',
Mascot.dino,
'flutter',
),
throwsA(isA<CrosswordRepositoryException>()),
);
},
);

test(
'throws $CrosswordRepositoryException if user has already solved word',
() async {
final answersRecord = _MockDbEntityRecord();
when(() => answersRecord.id).thenReturn('3');
when(() => answersRecord.data).thenReturn({
'userId': 'userId',
'answer': 'happy',
'sections': [
{'x': 1, 'y': 1},
],
'collidedWords': <Map<String, dynamic>>[
{
'wordId': '6',
'position': 1,
'character': 'l',
'sections': [
{'x': 1, 'y': 1},
{'x': 1, 'y': 2},
],
}
],
});

when(
() => dbClient.getById(answersCollection, '3'),
).thenAnswer((_) async => answersRecord);

expect(
() => repository.answerWord(
'userId',
'3',
Mascot.sparky,
'happy',
),
throwsA(isA<CrosswordRepositoryException>()),
);
},
Expand Down
8 changes: 8 additions & 0 deletions api/packages/game_domain/lib/src/models/word.dart
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ class Word extends Equatable {
required this.answer,
this.solvedTimestamp,
this.mascot,
this.userId,
});

/// {@macro word}
Expand Down Expand Up @@ -68,6 +69,10 @@ class Word extends Equatable {
@JsonKey()
final Mascot? mascot;

/// The user id that first solved the word.
@JsonKey()
final String? userId;

/// Returns the solved characters with the index position and character
/// solved.
Map<int, String> get solvedCharacters {
Expand Down Expand Up @@ -96,6 +101,7 @@ class Word extends Equatable {
String? answer,
int? solvedTimestamp,
Mascot? mascot,
String? userId,
}) {
return Word(
id: id ?? this.id,
Expand All @@ -105,6 +111,7 @@ class Word extends Equatable {
answer: answer ?? this.answer,
solvedTimestamp: solvedTimestamp ?? this.solvedTimestamp,
mascot: mascot ?? this.mascot,
userId: userId ?? this.userId,
);
}

Expand All @@ -117,6 +124,7 @@ class Word extends Equatable {
answer,
solvedTimestamp,
mascot,
userId,
];
}

Expand Down
2 changes: 2 additions & 0 deletions api/packages/game_domain/lib/src/models/word.g.dart

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

Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ void main() {
clue: 'clue',
solvedTimestamp: 1234,
mascot: Mascot.android,
userId: 'userId',
),
],
);
Expand All @@ -37,6 +38,7 @@ void main() {
'clue': 'clue',
'solvedTimestamp': 1234,
'mascot': 'android',
'userId': 'userId',
},
],
}),
Expand All @@ -56,6 +58,7 @@ void main() {
'clue': 'clue',
'solvedTimestamp': 1234,
'mascot': 'android',
'userId': 'userId',
},
],
};
Expand All @@ -75,6 +78,7 @@ void main() {
clue: 'clue',
solvedTimestamp: 1234,
mascot: Mascot.android,
userId: 'userId',
),
],
),
Expand Down
1 change: 1 addition & 0 deletions api/packages/game_domain/test/src/models/word_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ void main() {
'clue': 'clue',
'solvedTimestamp': 0,
'mascot': 'sparky',
'userId': null,
}),
);
});
Expand Down
1 change: 1 addition & 0 deletions api/routes/game/answer.dart
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ Future<Response> _onPost(RequestContext context) async {

try {
final (valid, preSolved) = await crosswordRepository.answerWord(
user.id,
wordId,
player.mascot,
answer,
Expand Down

0 comments on commit 944c0c1

Please sign in to comment.