Merge branch 'development' into feature/108-Möglichkeit-der-horizontalen-Nutzung-deaktivieren
This commit is contained in:
@@ -21,7 +21,7 @@ class GroupMatchDao extends DatabaseAccessor<AppDatabase>
|
|||||||
}
|
}
|
||||||
await into(groupMatchTable).insert(
|
await into(groupMatchTable).insert(
|
||||||
GroupMatchTableCompanion.insert(groupId: groupId, matchId: matchId),
|
GroupMatchTableCompanion.insert(groupId: groupId, matchId: matchId),
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrIgnore,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -65,8 +65,9 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Adds a new [Match] to the database.
|
/// Adds a new [Match] to the database. Also adds players and group
|
||||||
/// Also adds associated players and group if they exist.
|
/// associations. This method assumes that the players and groups added to
|
||||||
|
/// this match are already present in the database.
|
||||||
Future<void> addMatch({required Match match}) async {
|
Future<void> addMatch({required Match match}) async {
|
||||||
await db.transaction(() async {
|
await db.transaction(() async {
|
||||||
await into(matchTable).insert(
|
await into(matchTable).insert(
|
||||||
@@ -80,7 +81,6 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
);
|
);
|
||||||
|
|
||||||
if (match.players != null) {
|
if (match.players != null) {
|
||||||
await db.playerDao.addPlayersAsList(players: match.players!);
|
|
||||||
for (final p in match.players ?? []) {
|
for (final p in match.players ?? []) {
|
||||||
await db.playerMatchDao.addPlayerToMatch(
|
await db.playerMatchDao.addPlayerToMatch(
|
||||||
matchId: match.id,
|
matchId: match.id,
|
||||||
@@ -90,7 +90,6 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (match.group != null) {
|
if (match.group != null) {
|
||||||
await db.groupDao.addGroup(group: match.group!);
|
|
||||||
await db.groupMatchDao.addGroupToMatch(
|
await db.groupMatchDao.addGroupToMatch(
|
||||||
matchId: match.id,
|
matchId: match.id,
|
||||||
groupId: match.group!.id,
|
groupId: match.group!.id,
|
||||||
@@ -102,6 +101,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
/// Adds multiple [Match]s to the database in a batch operation.
|
/// Adds multiple [Match]s to the database in a batch operation.
|
||||||
/// Also adds associated players and groups if they exist.
|
/// Also adds associated players and groups if they exist.
|
||||||
/// If the [matches] list is empty, the method returns immediately.
|
/// If the [matches] list is empty, the method returns immediately.
|
||||||
|
/// This Method should only be used to import matches from a different device.
|
||||||
Future<void> addMatchAsList({required List<Match> matches}) async {
|
Future<void> addMatchAsList({required List<Match> matches}) async {
|
||||||
if (matches.isEmpty) return;
|
if (matches.isEmpty) return;
|
||||||
await db.transaction(() async {
|
await db.transaction(() async {
|
||||||
@@ -186,7 +186,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
matchId: match.id,
|
matchId: match.id,
|
||||||
playerId: p.id,
|
playerId: p.id,
|
||||||
),
|
),
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrIgnore,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -204,7 +204,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
playerId: m.id,
|
playerId: m.id,
|
||||||
groupId: match.group!.id,
|
groupId: match.group!.id,
|
||||||
),
|
),
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrIgnore,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -221,7 +221,7 @@ class MatchDao extends DatabaseAccessor<AppDatabase> with _$MatchDaoMixin {
|
|||||||
matchId: match.id,
|
matchId: match.id,
|
||||||
groupId: match.group!.id,
|
groupId: match.group!.id,
|
||||||
),
|
),
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrIgnore,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
|
|||||||
}) async {
|
}) async {
|
||||||
await into(playerMatchTable).insert(
|
await into(playerMatchTable).insert(
|
||||||
PlayerMatchTableCompanion.insert(playerId: playerId, matchId: matchId),
|
PlayerMatchTableCompanion.insert(playerId: playerId, matchId: matchId),
|
||||||
mode: InsertMode.insertOrReplace,
|
mode: InsertMode.insertOrIgnore,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ class PlayerMatchDao extends DatabaseAccessor<AppDatabase>
|
|||||||
inserts.map(
|
inserts.map(
|
||||||
(c) => into(
|
(c) => into(
|
||||||
playerMatchTable,
|
playerMatchTable,
|
||||||
).insert(c, mode: InsertMode.insertOrReplace),
|
).insert(c, mode: InsertMode.insertOrIgnore),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,10 +74,18 @@ class _ChooseGroupViewState extends State<ChooseGroupView> {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: Visibility(
|
child: Visibility(
|
||||||
visible: filteredGroups.isNotEmpty,
|
visible: filteredGroups.isNotEmpty,
|
||||||
replacement: const TopCenteredMessage(
|
replacement: Visibility(
|
||||||
icon: Icons.info,
|
visible: widget.groups.isNotEmpty,
|
||||||
title: 'Info',
|
replacement: const TopCenteredMessage(
|
||||||
message: 'There is no group matching your search',
|
icon: Icons.info,
|
||||||
|
title: 'Info',
|
||||||
|
message: 'You have no groups created yet',
|
||||||
|
),
|
||||||
|
child: const TopCenteredMessage(
|
||||||
|
icon: Icons.info,
|
||||||
|
title: 'Info',
|
||||||
|
message: 'There is no group matching your search',
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
padding: const EdgeInsets.only(bottom: 85),
|
padding: const EdgeInsets.only(bottom: 85),
|
||||||
|
|||||||
@@ -28,8 +28,8 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
/// Reference to the app database
|
/// Reference to the app database
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
|
|
||||||
/// Controller for the game name input field
|
/// Controller for the match name input field
|
||||||
final TextEditingController _gameNameController = TextEditingController();
|
final TextEditingController _matchNameController = TextEditingController();
|
||||||
|
|
||||||
/// List of all groups from the database
|
/// List of all groups from the database
|
||||||
List<Group> groupsList = [];
|
List<Group> groupsList = [];
|
||||||
@@ -95,7 +95,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_gameNameController.addListener(() {
|
_matchNameController.addListener(() {
|
||||||
setState(() {});
|
setState(() {});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -119,7 +119,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
backgroundColor: CustomTheme.backgroundColor,
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
title: const Text(
|
title: const Text(
|
||||||
'Create new game',
|
'Create new match',
|
||||||
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
centerTitle: true,
|
centerTitle: true,
|
||||||
@@ -131,8 +131,8 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
Container(
|
Container(
|
||||||
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
|
margin: const EdgeInsets.symmetric(horizontal: 12, vertical: 5),
|
||||||
child: TextInputField(
|
child: TextInputField(
|
||||||
controller: _gameNameController,
|
controller: _matchNameController,
|
||||||
hintText: 'Game name',
|
hintText: 'Match name',
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
ChooseTile(
|
ChooseTile(
|
||||||
@@ -222,13 +222,13 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
CustomWidthButton(
|
CustomWidthButton(
|
||||||
text: 'Create game',
|
text: 'Create match',
|
||||||
sizeRelativeToWidth: 0.95,
|
sizeRelativeToWidth: 0.95,
|
||||||
buttonType: ButtonType.primary,
|
buttonType: ButtonType.primary,
|
||||||
onPressed: _enableCreateGameButton()
|
onPressed: _enableCreateGameButton()
|
||||||
? () async {
|
? () async {
|
||||||
Match match = Match(
|
Match match = Match(
|
||||||
name: _gameNameController.text.trim(),
|
name: _matchNameController.text.trim(),
|
||||||
createdAt: DateTime.now(),
|
createdAt: DateTime.now(),
|
||||||
group: selectedGroup,
|
group: selectedGroup,
|
||||||
players: selectedPlayers,
|
players: selectedPlayers,
|
||||||
@@ -239,7 +239,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
context,
|
context,
|
||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
builder: (context) => GameResultView(
|
builder: (context) => MatchResultView(
|
||||||
match: match,
|
match: match,
|
||||||
onWinnerChanged: widget.onWinnerChanged,
|
onWinnerChanged: widget.onWinnerChanged,
|
||||||
),
|
),
|
||||||
@@ -258,7 +258,7 @@ class _CreateMatchViewState extends State<CreateMatchView> {
|
|||||||
/// Determines whether the "Create Game" button should be enabled based on
|
/// Determines whether the "Create Game" button should be enabled based on
|
||||||
/// the current state of the input fields.
|
/// the current state of the input fields.
|
||||||
bool _enableCreateGameButton() {
|
bool _enableCreateGameButton() {
|
||||||
return _gameNameController.text.isNotEmpty &&
|
return _matchNameController.text.isNotEmpty &&
|
||||||
(selectedGroup != null ||
|
(selectedGroup != null ||
|
||||||
(selectedPlayers != null && selectedPlayers!.length > 1)) &&
|
(selectedPlayers != null && selectedPlayers!.length > 1)) &&
|
||||||
selectedRuleset != null;
|
selectedRuleset != null;
|
||||||
|
|||||||
@@ -6,17 +6,17 @@ import 'package:game_tracker/data/dto/player.dart';
|
|||||||
import 'package:game_tracker/presentation/widgets/tiles/custom_radio_list_tile.dart';
|
import 'package:game_tracker/presentation/widgets/tiles/custom_radio_list_tile.dart';
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class GameResultView extends StatefulWidget {
|
class MatchResultView extends StatefulWidget {
|
||||||
final Match match;
|
final Match match;
|
||||||
|
|
||||||
final VoidCallback? onWinnerChanged;
|
final VoidCallback? onWinnerChanged;
|
||||||
|
|
||||||
const GameResultView({super.key, required this.match, this.onWinnerChanged});
|
const MatchResultView({super.key, required this.match, this.onWinnerChanged});
|
||||||
@override
|
@override
|
||||||
State<GameResultView> createState() => _GameResultViewState();
|
State<MatchResultView> createState() => _MatchResultViewState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _GameResultViewState extends State<GameResultView> {
|
class _MatchResultViewState extends State<MatchResultView> {
|
||||||
late final List<Player> allPlayers;
|
late final List<Player> allPlayers;
|
||||||
late final AppDatabase db;
|
late final AppDatabase db;
|
||||||
Player? _selectedPlayer;
|
Player? _selectedPlayer;
|
||||||
@@ -38,6 +38,13 @@ class _GameResultViewState extends State<GameResultView> {
|
|||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: CustomTheme.backgroundColor,
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
|
leading: IconButton(
|
||||||
|
icon: const Icon(Icons.close),
|
||||||
|
onPressed: () {
|
||||||
|
widget.onWinnerChanged?.call();
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
},
|
||||||
|
),
|
||||||
backgroundColor: CustomTheme.backgroundColor,
|
backgroundColor: CustomTheme.backgroundColor,
|
||||||
scrolledUnderElevation: 0,
|
scrolledUnderElevation: 0,
|
||||||
title: Text(
|
title: Text(
|
||||||
@@ -135,12 +142,12 @@ class _GameResultViewState extends State<GameResultView> {
|
|||||||
widget.onWinnerChanged?.call();
|
widget.onWinnerChanged?.call();
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Player> getAllPlayers(Match game) {
|
List<Player> getAllPlayers(Match match) {
|
||||||
if (game.group == null && game.players != null) {
|
if (match.group == null && match.players != null) {
|
||||||
return [...game.players!];
|
return [...match.players!];
|
||||||
} else if (game.group != null && game.players != null) {
|
} else if (match.group != null && match.players != null) {
|
||||||
return [...game.players!, ...game.group!.members];
|
return [...match.players!, ...match.group!.members];
|
||||||
}
|
}
|
||||||
return [...game.group!.members];
|
return [...match.group!.members];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ class _MatchViewState extends State<MatchView> {
|
|||||||
context,
|
context,
|
||||||
CupertinoPageRoute(
|
CupertinoPageRoute(
|
||||||
fullscreenDialog: true,
|
fullscreenDialog: true,
|
||||||
builder: (context) => GameResultView(
|
builder: (context) => MatchResultView(
|
||||||
match: matches[index],
|
match: matches[index],
|
||||||
onWinnerChanged: loadGames,
|
onWinnerChanged: loadGames,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -133,33 +133,42 @@ class _PlayerSelectionState extends State<PlayerSelection> {
|
|||||||
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
style: const TextStyle(fontSize: 16, fontWeight: FontWeight.bold),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
Wrap(
|
SizedBox(
|
||||||
alignment: WrapAlignment.start,
|
height: 50,
|
||||||
crossAxisAlignment: WrapCrossAlignment.start,
|
child: selectedPlayers.isEmpty
|
||||||
spacing: 8.0,
|
? const Center(child: Text('No players selected'))
|
||||||
runSpacing: 8.0,
|
: SingleChildScrollView(
|
||||||
children: <Widget>[
|
scrollDirection: Axis.horizontal,
|
||||||
// Generates a TextIconTile for each selected player.
|
child: Row(
|
||||||
for (var player in selectedPlayers)
|
children: [
|
||||||
TextIconTile(
|
for (var player in selectedPlayers)
|
||||||
text: player.name,
|
Padding(
|
||||||
onIconTap: () {
|
padding: const EdgeInsets.only(right: 8.0),
|
||||||
setState(() {
|
child: TextIconTile(
|
||||||
// Removes the player from the selection and notifies the parent.
|
text: player.name,
|
||||||
final currentSearch = _searchBarController.text
|
onIconTap: () {
|
||||||
.toLowerCase();
|
setState(() {
|
||||||
selectedPlayers.remove(player);
|
// Removes the player from the selection and notifies the parent.
|
||||||
widget.onChanged([...selectedPlayers]);
|
final currentSearch = _searchBarController
|
||||||
// If the player matches the current search query (or search is empty),
|
.text
|
||||||
// they are added back to the suggestions and the list is re-sorted.
|
.toLowerCase();
|
||||||
if (currentSearch.isEmpty ||
|
selectedPlayers.remove(player);
|
||||||
player.name.toLowerCase().contains(currentSearch)) {
|
widget.onChanged([...selectedPlayers]);
|
||||||
suggestedPlayers.add(player);
|
// If the player matches the current search query (or search is empty),
|
||||||
}
|
// they are added back to the suggestions and the list is re-sorted.
|
||||||
});
|
if (currentSearch.isEmpty ||
|
||||||
},
|
player.name.toLowerCase().contains(
|
||||||
),
|
currentSearch,
|
||||||
],
|
)) {
|
||||||
|
suggestedPlayers.add(player);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 10),
|
const SizedBox(height: 10),
|
||||||
const Text(
|
const Text(
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ void main() {
|
|||||||
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
||||||
final fakeClock = Clock(() => fixedDate);
|
final fakeClock = Clock(() => fixedDate);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() async {
|
||||||
database = AppDatabase(
|
database = AppDatabase(
|
||||||
DatabaseConnection(
|
DatabaseConnection(
|
||||||
NativeDatabase.memory(),
|
NativeDatabase.memory(),
|
||||||
@@ -68,6 +68,16 @@ void main() {
|
|||||||
group: testGroup2,
|
group: testGroup2,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
await database.playerDao.addPlayersAsList(
|
||||||
|
players: [
|
||||||
|
testPlayer1,
|
||||||
|
testPlayer2,
|
||||||
|
testPlayer3,
|
||||||
|
testPlayer4,
|
||||||
|
testPlayer5,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
await database.groupDao.addGroupsAsList(groups: [testGroup1, testGroup2]);
|
||||||
});
|
});
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await database.close();
|
await database.close();
|
||||||
@@ -253,7 +263,7 @@ void main() {
|
|||||||
expect(matchCount, 0);
|
expect(matchCount, 0);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('Checking if match has winner works correclty', () async {
|
test('Checking if match has winner works correctly', () async {
|
||||||
await database.matchDao.addMatch(match: testMatch1);
|
await database.matchDao.addMatch(match: testMatch1);
|
||||||
await database.matchDao.addMatch(match: testMatchOnlyGroup);
|
await database.matchDao.addMatch(match: testMatchOnlyGroup);
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:clock/clock.dart';
|
import 'package:clock/clock.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart' hide isNotNull;
|
||||||
import 'package:drift/native.dart';
|
import 'package:drift/native.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:game_tracker/data/db/database.dart';
|
import 'package:game_tracker/data/db/database.dart';
|
||||||
@@ -21,7 +21,7 @@ void main() {
|
|||||||
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
||||||
final fakeClock = Clock(() => fixedDate);
|
final fakeClock = Clock(() => fixedDate);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() async {
|
||||||
database = AppDatabase(
|
database = AppDatabase(
|
||||||
DatabaseConnection(
|
DatabaseConnection(
|
||||||
NativeDatabase.memory(),
|
NativeDatabase.memory(),
|
||||||
@@ -53,6 +53,16 @@ void main() {
|
|||||||
group: testGroup1,
|
group: testGroup1,
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
await database.playerDao.addPlayersAsList(
|
||||||
|
players: [
|
||||||
|
testPlayer1,
|
||||||
|
testPlayer2,
|
||||||
|
testPlayer3,
|
||||||
|
testPlayer4,
|
||||||
|
testPlayer5,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
await database.groupDao.addGroupsAsList(groups: [testGroup1, testGroup2]);
|
||||||
});
|
});
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await database.close();
|
await database.close();
|
||||||
@@ -179,5 +189,33 @@ void main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('Adding the same group to seperate matches works correctly', () async {
|
||||||
|
final match1 = Match(name: 'Match 1', group: testGroup1);
|
||||||
|
final match2 = Match(name: 'Match 2', group: testGroup1);
|
||||||
|
|
||||||
|
await Future.wait([
|
||||||
|
database.matchDao.addMatch(match: match1),
|
||||||
|
database.matchDao.addMatch(match: match2),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final group1 = await database.groupMatchDao.getGroupOfMatch(
|
||||||
|
matchId: match1.id,
|
||||||
|
);
|
||||||
|
final group2 = await database.groupMatchDao.getGroupOfMatch(
|
||||||
|
matchId: match2.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(group1, isNotNull);
|
||||||
|
expect(group2, isNotNull);
|
||||||
|
|
||||||
|
final groups = [group1!, group2!];
|
||||||
|
for (final group in groups) {
|
||||||
|
expect(group.members.length, testGroup1.members.length);
|
||||||
|
expect(group.id, testGroup1.id);
|
||||||
|
expect(group.name, testGroup1.name);
|
||||||
|
expect(group.createdAt, testGroup1.createdAt);
|
||||||
|
}
|
||||||
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import 'package:clock/clock.dart';
|
import 'package:clock/clock.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart' hide isNotNull;
|
||||||
import 'package:drift/native.dart';
|
import 'package:drift/native.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:game_tracker/data/db/database.dart';
|
import 'package:game_tracker/data/db/database.dart';
|
||||||
@@ -21,7 +21,7 @@ void main() {
|
|||||||
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
final fixedDate = DateTime(2025, 19, 11, 00, 11, 23);
|
||||||
final fakeClock = Clock(() => fixedDate);
|
final fakeClock = Clock(() => fixedDate);
|
||||||
|
|
||||||
setUp(() {
|
setUp(() async {
|
||||||
database = AppDatabase(
|
database = AppDatabase(
|
||||||
DatabaseConnection(
|
DatabaseConnection(
|
||||||
NativeDatabase.memory(),
|
NativeDatabase.memory(),
|
||||||
@@ -50,6 +50,17 @@ void main() {
|
|||||||
players: [testPlayer4, testPlayer5, testPlayer6],
|
players: [testPlayer4, testPlayer5, testPlayer6],
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
await database.playerDao.addPlayersAsList(
|
||||||
|
players: [
|
||||||
|
testPlayer1,
|
||||||
|
testPlayer2,
|
||||||
|
testPlayer3,
|
||||||
|
testPlayer4,
|
||||||
|
testPlayer5,
|
||||||
|
testPlayer6,
|
||||||
|
],
|
||||||
|
);
|
||||||
|
await database.groupDao.addGroup(group: testgroup);
|
||||||
});
|
});
|
||||||
tearDown(() async {
|
tearDown(() async {
|
||||||
await database.close();
|
await database.close();
|
||||||
@@ -185,5 +196,42 @@ void main() {
|
|||||||
expect(player.createdAt, testPlayer.createdAt);
|
expect(player.createdAt, testPlayer.createdAt);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test(
|
||||||
|
'Adding the same player to seperate matches works correctly',
|
||||||
|
() async {
|
||||||
|
final playersList = [testPlayer1, testPlayer2, testPlayer3];
|
||||||
|
final match1 = Match(name: 'Match 1', players: playersList);
|
||||||
|
final match2 = Match(name: 'Match 2', players: playersList);
|
||||||
|
|
||||||
|
await Future.wait([
|
||||||
|
database.matchDao.addMatch(match: match1),
|
||||||
|
database.matchDao.addMatch(match: match2),
|
||||||
|
]);
|
||||||
|
|
||||||
|
final players1 = await database.playerMatchDao.getPlayersOfMatch(
|
||||||
|
matchId: match1.id,
|
||||||
|
);
|
||||||
|
final players2 = await database.playerMatchDao.getPlayersOfMatch(
|
||||||
|
matchId: match2.id,
|
||||||
|
);
|
||||||
|
|
||||||
|
expect(players1, isNotNull);
|
||||||
|
expect(players2, isNotNull);
|
||||||
|
|
||||||
|
expect(
|
||||||
|
players1!.map((p) => p.id).toList(),
|
||||||
|
equals(players2!.map((p) => p.id).toList()),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
players1.map((p) => p.name).toList(),
|
||||||
|
equals(players2.map((p) => p.name).toList()),
|
||||||
|
);
|
||||||
|
expect(
|
||||||
|
players1.map((p) => p.createdAt).toList(),
|
||||||
|
equals(players2.map((p) => p.createdAt).toList()),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user