diff --git a/packages/crossword_repository/lib/src/crossword_repository.dart b/packages/crossword_repository/lib/src/crossword_repository.dart index 13e35aa7b..2798e455f 100644 --- a/packages/crossword_repository/lib/src/crossword_repository.dart +++ b/packages/crossword_repository/lib/src/crossword_repository.dart @@ -29,20 +29,30 @@ class CrosswordRepository { }); } - /// Watches all the sections of the crossword board - Stream> watchSections() { - final snapshot = sectionCollection.snapshots(); + /// Watches the section having the corresponding [position] + Stream watchSectionFromPosition( + Point position, + ) { + final snapshot = sectionCollection + .where( + 'position.x', + isEqualTo: position.x, + ) + .where( + 'position.y', + isEqualTo: position.y, + ) + .snapshots(); return snapshot.map( - (snapshot) => snapshot.docs.map((doc) { - final dataJson = doc.data(); - dataJson['id'] = doc.id; - return BoardSection.fromJson(dataJson); - }).toList(), + (snapshot) { + final doc = snapshot.docs.firstOrNull; + if (doc != null) { + final dataJson = doc.data(); + dataJson['id'] = doc.id; + return BoardSection.fromJson(dataJson); + } + return null; + }, ); } - - /// Adds a board section - Future addSection(BoardSection section) async { - await sectionCollection.doc(section.id).set(section.toJson()); - } } diff --git a/packages/crossword_repository/lib/src/extensions/board_section_from_snapshot.dart b/packages/crossword_repository/lib/src/extensions/board_section_from_snapshot.dart new file mode 100644 index 000000000..0b061118f --- /dev/null +++ b/packages/crossword_repository/lib/src/extensions/board_section_from_snapshot.dart @@ -0,0 +1,12 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:game_domain/game_domain.dart'; + +/// Adds method to QuerySnapshot to convert to BoardSection list +extension BoardSectionFromSnapshot on QuerySnapshot> { + /// Returns data as [BoardSection] list + List toBoardSectionList() => docs.map((doc) { + final dataJson = doc.data(); + dataJson['id'] = doc.id; + return BoardSection.fromJson(dataJson); + }).toList(); +} diff --git a/packages/crossword_repository/test/src/crossword_repository_test.dart b/packages/crossword_repository/test/src/crossword_repository_test.dart index 847ebe174..daf97b930 100644 --- a/packages/crossword_repository/test/src/crossword_repository_test.dart +++ b/packages/crossword_repository/test/src/crossword_repository_test.dart @@ -8,7 +8,7 @@ import 'package:test/test.dart'; void main() { group('CrosswordRepository', () { final word = Word( - position: Point(1, 1), + position: Point(0, 1), axis: Axis.horizontal, answer: 'answer', clue: 'clue', @@ -19,7 +19,7 @@ void main() { final boardSection1 = BoardSection( id: 'id', position: Point(1, 1), - size: 10, + size: 9, words: [ word, ], @@ -47,15 +47,6 @@ void main() { ); }); - group('getSections', () { - test('returns all the sections', () { - expect( - crosswordRepository.watchSections(), - emits([boardSection1]), - ); - }); - }); - group('watchSection', () { test('returns the requested section', () async { expect( @@ -65,21 +56,35 @@ void main() { }); }); - group('addSection', () { - test('returns the requested section', () async { - final section = BoardSection( - id: 'id2', - position: Point(1, 1), - size: 10, - words: [ - word, - ], - borderWords: const [], + group('watchSectionsFromPositions', () { + final section = BoardSection( + id: 'id2', + position: Point(0, 1), + size: 10, + words: [ + word, + ], + borderWords: const [], + ); + + setUp(() async { + await firebaseFirestore + .collection(sectionsCollection) + .doc(section.id) + .set(section.toJson()); + }); + + test('returns the requested sections depending on position', () { + expect( + crosswordRepository.watchSectionFromPosition(Point(0, 1)), + emits(section), ); - await crosswordRepository.addSection(section); + }); + + test('returns null if there is no section with the position', () { expect( - crosswordRepository.watchSections(), - emits([boardSection1, section]), + crosswordRepository.watchSectionFromPosition(Point(2, 2)), + emits(null), ); }); }); diff --git a/packages/crossword_repository/test/src/extensions/board_section_from_snapshot_test.dart b/packages/crossword_repository/test/src/extensions/board_section_from_snapshot_test.dart new file mode 100644 index 000000000..5f5b3fedc --- /dev/null +++ b/packages/crossword_repository/test/src/extensions/board_section_from_snapshot_test.dart @@ -0,0 +1,46 @@ +// ignore_for_file: subtype_of_sealed_class + +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:crossword_repository/src/extensions/board_section_from_snapshot.dart'; +import 'package:game_domain/game_domain.dart'; +import 'package:mocktail/mocktail.dart'; +import 'package:test/test.dart'; + +class _MockQuerySnapshot extends Mock implements QuerySnapshot {} + +class _MockQueryDocumentSnapshot extends Mock + implements QueryDocumentSnapshot {} + +void main() { + final word = Word( + position: const Point(0, 1), + axis: Axis.horizontal, + answer: 'answer', + clue: 'clue', + hints: const ['hint'], + visible: true, + solvedTimestamp: null, + ); + final boardSection1 = BoardSection( + id: 'id', + position: const Point(1, 1), + size: 9, + words: [ + word, + ], + borderWords: const [], + ); + + group('BoardSectionFromSnapshot', () { + test('returns list of BoardSections from snapshot', () { + final doc = _MockQueryDocumentSnapshot>(); + final query = _MockQuerySnapshot>(); + + when(() => query.docs).thenReturn([doc]); + when(() => doc.id).thenReturn('id'); + when(doc.data).thenReturn(boardSection1.toJson()); + + expect(query.toBoardSectionList(), equals([boardSection1])); + }); + }); +}