From b39fffccf3a05d29bb69c928184a022df6ffdfce Mon Sep 17 00:00:00 2001 From: Hugo Walbecq Date: Tue, 5 Mar 2024 16:06:48 +0100 Subject: [PATCH 1/4] chore: missing doc --- .../lib/src/crossword_repository.dart | 23 ++++++---- .../board_section_from_snapshot.dart | 12 +++++ .../test/src/crossword_repository_test.dart | 41 ++++++++++------- .../board_section_from_snapshot_test.dart | 46 +++++++++++++++++++ 4 files changed, 97 insertions(+), 25 deletions(-) create mode 100644 packages/crossword_repository/lib/src/extensions/board_section_from_snapshot.dart create mode 100644 packages/crossword_repository/test/src/extensions/board_section_from_snapshot_test.dart diff --git a/packages/crossword_repository/lib/src/crossword_repository.dart b/packages/crossword_repository/lib/src/crossword_repository.dart index 13e35aa7b..86accffc7 100644 --- a/packages/crossword_repository/lib/src/crossword_repository.dart +++ b/packages/crossword_repository/lib/src/crossword_repository.dart @@ -1,4 +1,5 @@ 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'; /// {@template crossword_repository} @@ -33,16 +34,22 @@ class CrosswordRepository { Stream> watchSections() { final snapshot = sectionCollection.snapshots(); return snapshot.map( - (snapshot) => snapshot.docs.map((doc) { - final dataJson = doc.data(); - dataJson['id'] = doc.id; - return BoardSection.fromJson(dataJson); - }).toList(), + (snapshot) => snapshot.toBoardSectionList(), ); } - /// Adds a board section - Future addSection(BoardSection section) async { - await sectionCollection.doc(section.id).set(section.toJson()); + /// Watches all the sections of the crossword board + Stream> watchSectionsFromPositions( + List> positions, + ) { + final snapshot = sectionCollection + .where( + 'position', + whereIn: positions, + ) + .snapshots(); + return snapshot.map( + (snapshot) => snapshot.toBoardSectionList(), + ); } } 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..543a786cc 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,7 +47,7 @@ void main() { ); }); - group('getSections', () { + group('watchSections', () { test('returns all the sections', () { expect( crosswordRepository.watchSections(), @@ -65,21 +65,28 @@ 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 [], - ); - await crosswordRepository.addSection(section); + 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.watchSections(), - emits([boardSection1, section]), + crosswordRepository.watchSectionsFromPositions([Point(0, 1)]), + emits([section]), ); }); }); 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])); + }); + }); +} From 7b03a39b3101583c7a9bdd0130874fc04f015e11 Mon Sep 17 00:00:00 2001 From: Hugo Walbecq Date: Wed, 6 Mar 2024 09:57:05 +0100 Subject: [PATCH 2/4] feat: remove watch all sections and update watch from position --- .../lib/src/crossword_repository.dart | 22 ++++++++----------- .../test/src/crossword_repository_test.dart | 13 ++--------- 2 files changed, 11 insertions(+), 24 deletions(-) diff --git a/packages/crossword_repository/lib/src/crossword_repository.dart b/packages/crossword_repository/lib/src/crossword_repository.dart index 86accffc7..517f21b23 100644 --- a/packages/crossword_repository/lib/src/crossword_repository.dart +++ b/packages/crossword_repository/lib/src/crossword_repository.dart @@ -31,25 +31,21 @@ class CrosswordRepository { } /// Watches all the sections of the crossword board - Stream> watchSections() { - final snapshot = sectionCollection.snapshots(); - return snapshot.map( - (snapshot) => snapshot.toBoardSectionList(), - ); - } - - /// Watches all the sections of the crossword board - Stream> watchSectionsFromPositions( - List> positions, + Stream watchSectionFromPositions( + Point position, ) { final snapshot = sectionCollection .where( - 'position', - whereIn: positions, + 'position.x', + isEqualTo: position.x, + ) + .where( + 'position.y', + isEqualTo: position.y, ) .snapshots(); return snapshot.map( - (snapshot) => snapshot.toBoardSectionList(), + (snapshot) => snapshot.toBoardSectionList().first, ); } } diff --git a/packages/crossword_repository/test/src/crossword_repository_test.dart b/packages/crossword_repository/test/src/crossword_repository_test.dart index 543a786cc..f9f0e0d41 100644 --- a/packages/crossword_repository/test/src/crossword_repository_test.dart +++ b/packages/crossword_repository/test/src/crossword_repository_test.dart @@ -47,15 +47,6 @@ void main() { ); }); - group('watchSections', () { - test('returns all the sections', () { - expect( - crosswordRepository.watchSections(), - emits([boardSection1]), - ); - }); - }); - group('watchSection', () { test('returns the requested section', () async { expect( @@ -85,8 +76,8 @@ void main() { test('returns the requested sections depending on position', () { expect( - crosswordRepository.watchSectionsFromPositions([Point(0, 1)]), - emits([section]), + crosswordRepository.watchSectionFromPositions(Point(0, 1)), + emits(section), ); }); }); From 1e68253a52ab9d0a0e134902975fe2051487b042 Mon Sep 17 00:00:00 2001 From: Hugo Walbecq Date: Wed, 6 Mar 2024 10:08:40 +0100 Subject: [PATCH 3/4] chore: update name and description --- .../crossword_repository/lib/src/crossword_repository.dart | 4 ++-- .../test/src/crossword_repository_test.dart | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/crossword_repository/lib/src/crossword_repository.dart b/packages/crossword_repository/lib/src/crossword_repository.dart index 517f21b23..f05db0a40 100644 --- a/packages/crossword_repository/lib/src/crossword_repository.dart +++ b/packages/crossword_repository/lib/src/crossword_repository.dart @@ -30,8 +30,8 @@ class CrosswordRepository { }); } - /// Watches all the sections of the crossword board - Stream watchSectionFromPositions( + /// Watches the section having the corresponding [position] + Stream watchSectionFromPosition( Point position, ) { final snapshot = sectionCollection diff --git a/packages/crossword_repository/test/src/crossword_repository_test.dart b/packages/crossword_repository/test/src/crossword_repository_test.dart index f9f0e0d41..ea8086280 100644 --- a/packages/crossword_repository/test/src/crossword_repository_test.dart +++ b/packages/crossword_repository/test/src/crossword_repository_test.dart @@ -76,7 +76,7 @@ void main() { test('returns the requested sections depending on position', () { expect( - crosswordRepository.watchSectionFromPositions(Point(0, 1)), + crosswordRepository.watchSectionFromPosition(Point(0, 1)), emits(section), ); }); From 8f0a0cf6d63c672b0518cac7579922bbdd086a94 Mon Sep 17 00:00:00 2001 From: Hugo Walbecq Date: Wed, 6 Mar 2024 12:13:09 +0100 Subject: [PATCH 4/4] test: return null if no section with requested position --- .../lib/src/crossword_repository.dart | 13 ++++++++++--- .../test/src/crossword_repository_test.dart | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/packages/crossword_repository/lib/src/crossword_repository.dart b/packages/crossword_repository/lib/src/crossword_repository.dart index f05db0a40..2798e455f 100644 --- a/packages/crossword_repository/lib/src/crossword_repository.dart +++ b/packages/crossword_repository/lib/src/crossword_repository.dart @@ -1,5 +1,4 @@ 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'; /// {@template crossword_repository} @@ -31,7 +30,7 @@ class CrosswordRepository { } /// Watches the section having the corresponding [position] - Stream watchSectionFromPosition( + Stream watchSectionFromPosition( Point position, ) { final snapshot = sectionCollection @@ -45,7 +44,15 @@ class CrosswordRepository { ) .snapshots(); return snapshot.map( - (snapshot) => snapshot.toBoardSectionList().first, + (snapshot) { + final doc = snapshot.docs.firstOrNull; + if (doc != null) { + final dataJson = doc.data(); + dataJson['id'] = doc.id; + return BoardSection.fromJson(dataJson); + } + return null; + }, ); } } diff --git a/packages/crossword_repository/test/src/crossword_repository_test.dart b/packages/crossword_repository/test/src/crossword_repository_test.dart index ea8086280..daf97b930 100644 --- a/packages/crossword_repository/test/src/crossword_repository_test.dart +++ b/packages/crossword_repository/test/src/crossword_repository_test.dart @@ -80,6 +80,13 @@ void main() { emits(section), ); }); + + test('returns null if there is no section with the position', () { + expect( + crosswordRepository.watchSectionFromPosition(Point(2, 2)), + emits(null), + ); + }); }); }); }