From 516e3ca1ba54f2b847435ad88d9f71dd83bdeb3e Mon Sep 17 00:00:00 2001 From: Jaime Sanchez Date: Mon, 1 Apr 2024 18:48:23 +0200 Subject: [PATCH] feat: save mascot when answering word --- .../lib/src/crossword_repository.dart | 14 ++++++++----- .../crossword_repository/pubspec.yaml | 1 + .../test/src/crossword_repository_test.dart | 21 +++++++++++++++---- api/pubspec.yaml | 1 + api/routes/game/answer.dart | 7 ++++++- api/test/routes/game/answer_test.dart | 15 +++++++------ 6 files changed, 43 insertions(+), 16 deletions(-) diff --git a/api/packages/crossword_repository/lib/src/crossword_repository.dart b/api/packages/crossword_repository/lib/src/crossword_repository.dart index 44002b606..12a10a0d9 100644 --- a/api/packages/crossword_repository/lib/src/crossword_repository.dart +++ b/api/packages/crossword_repository/lib/src/crossword_repository.dart @@ -1,4 +1,5 @@ import 'package:clock/clock.dart'; +import 'package:collection/collection.dart'; import 'package:db_client/db_client.dart'; import 'package:game_domain/game_domain.dart'; @@ -64,24 +65,27 @@ class CrosswordRepository { int sectionY, int wordX, int wordY, + Mascots mascot, String answer, ) async { - final section = await findSectionByPosition( - sectionX, - sectionY, - ); + final section = await findSectionByPosition(sectionX, sectionY); if (section == null) { return false; } - final word = section.words.firstWhere( + final word = section.words.firstWhereOrNull( (element) => element.position.x == wordX && element.position.y == wordY, ); + if (word == null) { + return false; + } + if (answer == word.answer) { final solvedWord = word.copyWith( solvedTimestamp: clock.now().millisecondsSinceEpoch, + mascot: mascot, ); final newSection = section.copyWith( words: [...section.words..remove(word), solvedWord], diff --git a/api/packages/crossword_repository/pubspec.yaml b/api/packages/crossword_repository/pubspec.yaml index 7ffa51a45..d3a4d2a7c 100644 --- a/api/packages/crossword_repository/pubspec.yaml +++ b/api/packages/crossword_repository/pubspec.yaml @@ -8,6 +8,7 @@ environment: dependencies: clock: ^1.1.1 + collection: ^1.18.0 db_client: path: ../db_client game_domain: diff --git a/api/packages/crossword_repository/test/src/crossword_repository_test.dart b/api/packages/crossword_repository/test/src/crossword_repository_test.dart index 66c28078f..7636619fc 100644 --- a/api/packages/crossword_repository/test/src/crossword_repository_test.dart +++ b/api/packages/crossword_repository/test/src/crossword_repository_test.dart @@ -149,6 +149,7 @@ void main() { hints: const [], solvedTimestamp: null, ); + setUp(() { final record = _MockDbEntityRecord(); when(() => record.id).thenReturn('id'); @@ -184,7 +185,8 @@ void main() { final time = DateTime.now(); final clock = Clock.fixed(time); await withClock(clock, () async { - final valid = await repository.answerWord(1, 1, 1, 1, 'flutter'); + final valid = + await repository.answerWord(1, 1, 1, 1, Mascots.dino, 'flutter'); expect(valid, isTrue); final captured = verify( () => dbClient.update( @@ -201,7 +203,10 @@ void main() { 'size': 300, 'words': [ word - .copyWith(solvedTimestamp: time.millisecondsSinceEpoch) + .copyWith( + solvedTimestamp: time.millisecondsSinceEpoch, + mascot: Mascots.dino, + ) .toJson(), ], 'borderWords': [], @@ -212,7 +217,8 @@ void main() { }); test('answerWord returns false if answer is incorrect', () async { - final valid = await repository.answerWord(1, 1, 1, 1, 'android'); + final valid = + await repository.answerWord(1, 1, 1, 1, Mascots.dino, 'android'); expect(valid, isFalse); }); @@ -227,7 +233,14 @@ void main() { ), ).thenAnswer((_) async => []); - final valid = await repository.answerWord(0, 0, 1, 1, 'flutter'); + final valid = + await repository.answerWord(0, 0, 1, 1, Mascots.dino, 'flutter'); + expect(valid, isFalse); + }); + + test('answerWord returns false if word is not in section', () async { + final valid = + await repository.answerWord(1, 1, -1, -1, Mascots.dino, 'flutter'); expect(valid, isFalse); }); }); diff --git a/api/pubspec.yaml b/api/pubspec.yaml index 4221055cd..41349dce5 100644 --- a/api/pubspec.yaml +++ b/api/pubspec.yaml @@ -10,6 +10,7 @@ dependencies: board_renderer: path: packages/board_renderer clock: ^1.1.1 + collection: ^1.18.0 crossword_repository: path: packages/crossword_repository dart_frog: ^1.1.0 diff --git a/api/routes/game/answer.dart b/api/routes/game/answer.dart index 81333724b..e6c236ea3 100644 --- a/api/routes/game/answer.dart +++ b/api/routes/game/answer.dart @@ -1,8 +1,10 @@ import 'dart:io'; import 'package:api/extensions/path_param_to_position.dart'; +import 'package:collection/collection.dart'; import 'package:crossword_repository/crossword_repository.dart'; import 'package:dart_frog/dart_frog.dart'; +import 'package:game_domain/game_domain.dart'; Future onRequest(RequestContext context) async { if (context.request.method == HttpMethod.post) { @@ -18,9 +20,11 @@ Future _onPost(RequestContext context) async { final json = await context.request.json() as Map; final sectionId = json['sectionId'] as String?; final wordPosition = json['wordPosition'] as String?; - final mascot = json['mascot'] as String?; + final mascotName = json['mascot'] as String?; final answer = json['answer'] as String?; + final mascot = Mascots.values.firstWhereOrNull((e) => e.name == mascotName); + if (sectionId == null || wordPosition == null || mascot == null || @@ -49,6 +53,7 @@ Future _onPost(RequestContext context) async { sectionY, wordX, wordY, + mascot, answer, ); diff --git a/api/test/routes/game/answer_test.dart b/api/test/routes/game/answer_test.dart index a92d91a16..edcfb8afb 100644 --- a/api/test/routes/game/answer_test.dart +++ b/api/test/routes/game/answer_test.dart @@ -5,6 +5,7 @@ import 'dart:io'; import 'package:crossword_repository/crossword_repository.dart'; import 'package:dart_frog/dart_frog.dart'; +import 'package:game_domain/game_domain.dart'; import 'package:mocktail/mocktail.dart'; import 'package:test/test.dart'; @@ -55,14 +56,15 @@ void main() { test('returns Response with valid to true if answer is correct', () async { - when(() => crosswordRepository.answerWord(1, 1, 1, 1, 'flutter')) - .thenAnswer((_) async => true); + when( + () => crosswordRepository.answerWord(1, 1, 1, 1, Mascots.dash, 'sun'), + ).thenAnswer((_) async => true); when(() => request.json()).thenAnswer( (_) async => { 'sectionId': '1,1', 'wordPosition': '1,1', 'mascot': 'dash', - 'answer': 'flutter', + 'answer': 'sun', }, ); @@ -74,14 +76,15 @@ void main() { test('returns Response with valid to false if answer is incorrect', () async { - when(() => crosswordRepository.answerWord(1, 1, 1, 1, 'android')) - .thenAnswer((_) async => false); + when( + () => crosswordRepository.answerWord(1, 1, 1, 1, Mascots.dash, 'sun'), + ).thenAnswer((_) async => false); when(() => request.json()).thenAnswer( (_) async => { 'sectionId': '1,1', 'wordPosition': '1,1', 'mascot': 'dash', - 'answer': 'android', + 'answer': 'sun', }, );