From 43e9196dca225e96879453c02f609f9f4a36c351 Mon Sep 17 00:00:00 2001 From: Mathis Kirchner Date: Mon, 9 Mar 2026 16:24:04 +0100 Subject: [PATCH] made icon optional and default to empty string & adjust all game instances --- lib/data/dto/game.dart | 8 +- lib/data/dto/match.dart | 27 +- .../views/main_menu/home_view.dart | 57 ++++- .../game_view/create_game_view.dart | 1 - .../main_menu/match_view/match_view.dart | 1 - lib/services/data_transfer_service.dart | 101 +++++--- test/db_tests/aggregates/match_test.dart | 1 - test/db_tests/aggregates/team_test.dart | 52 ++-- test/db_tests/entities/game_test.dart | 18 +- .../relationships/player_match_test.dart | 240 +++++++++++------- test/db_tests/values/score_test.dart | 115 +++++---- 11 files changed, 367 insertions(+), 254 deletions(-) diff --git a/lib/data/dto/game.dart b/lib/data/dto/game.dart index 2eeee1e..af3ba27 100644 --- a/lib/data/dto/game.dart +++ b/lib/data/dto/game.dart @@ -1,6 +1,6 @@ import 'package:clock/clock.dart'; -import 'package:uuid/uuid.dart'; import 'package:tallee/core/enums.dart'; +import 'package:uuid/uuid.dart'; class Game { final String id; @@ -18,10 +18,11 @@ class Game { required this.ruleset, String? description, required this.color, - required this.icon, + String? icon, }) : id = id ?? const Uuid().v4(), createdAt = createdAt ?? clock.now(), - description = description ?? ''; + description = description ?? '', + icon = icon ?? ''; @override String toString() { @@ -49,4 +50,3 @@ class Game { 'icon': icon, }; } - diff --git a/lib/data/dto/match.dart b/lib/data/dto/match.dart index 3976d36..8f7b6f0 100644 --- a/lib/data/dto/match.dart +++ b/lib/data/dto/match.dart @@ -27,8 +27,8 @@ class Match { String? notes, this.winner, }) : id = id ?? const Uuid().v4(), - createdAt = createdAt ?? clock.now(), - notes = notes ?? ''; + createdAt = createdAt ?? clock.now(), + notes = notes ?? ''; @override String toString() { @@ -38,14 +38,21 @@ class Match { /// Creates a Match instance from a JSON object (ID references format). /// Related objects are reconstructed from IDs by the DataTransferService. Match.fromJson(Map json) - : id = json['id'], - createdAt = DateTime.parse(json['createdAt']), - endedAt = json['endedAt'] != null ? DateTime.parse(json['endedAt']) : null, - name = json['name'], - game = Game(name: '', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''), // Populated during import via DataTransferService - group = null, // Populated during import via DataTransferService - players = [], // Populated during import via DataTransferService - notes = json['notes'] ?? ''; + : id = json['id'], + createdAt = DateTime.parse(json['createdAt']), + endedAt = json['endedAt'] != null + ? DateTime.parse(json['endedAt']) + : null, + name = json['name'], + game = Game( + name: '', + ruleset: Ruleset.singleWinner, + description: '', + color: GameColor.blue, + ), // Populated during import via DataTransferService + group = null, // Populated during import via DataTransferService + players = [], // Populated during import via DataTransferService + notes = json['notes'] ?? ''; /// Converts the Match instance to a JSON object using normalized format (ID references only). Map toJson() => { diff --git a/lib/presentation/views/main_menu/home_view.dart b/lib/presentation/views/main_menu/home_view.dart index a7f5cfa..e68dc8f 100644 --- a/lib/presentation/views/main_menu/home_view.dart +++ b/lib/presentation/views/main_menu/home_view.dart @@ -42,7 +42,12 @@ class _HomeViewState extends State { 2, Match( name: 'Skeleton Match', - game: Game(name: '', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''), + game: Game( + name: '', + ruleset: Ruleset.singleWinner, + description: '', + color: GameColor.blue, + ), group: Group( name: 'Skeleton Group', description: '', @@ -104,7 +109,9 @@ class _HomeViewState extends State { if (recentMatches.isNotEmpty) for (Match match in recentMatches) Padding( - padding: const EdgeInsets.symmetric(vertical: 6.0), + padding: const EdgeInsets.symmetric( + vertical: 6.0, + ), child: MatchTile( compact: true, width: constraints.maxWidth * 0.9, @@ -113,7 +120,8 @@ class _HomeViewState extends State { await Navigator.of(context).push( adaptivePageRoute( fullscreenDialog: true, - builder: (context) => MatchResultView(match: match), + builder: (context) => + MatchResultView(match: match), ), ); await updatedWinnerInRecentMatches(match.id); @@ -121,7 +129,10 @@ class _HomeViewState extends State { ), ) else - Center(heightFactor: 5, child: Text(loc.no_recent_matches_available)), + Center( + heightFactor: 5, + child: Text(loc.no_recent_matches_available), + ), ], ), ), @@ -137,22 +148,40 @@ class _HomeViewState extends State { Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - QuickCreateButton(text: 'Category 1', onPressed: () {}), - QuickCreateButton(text: 'Category 2', onPressed: () {}), + QuickCreateButton( + text: 'Category 1', + onPressed: () {}, + ), + QuickCreateButton( + text: 'Category 2', + onPressed: () {}, + ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - QuickCreateButton(text: 'Category 3', onPressed: () {}), - QuickCreateButton(text: 'Category 4', onPressed: () {}), + QuickCreateButton( + text: 'Category 3', + onPressed: () {}, + ), + QuickCreateButton( + text: 'Category 4', + onPressed: () {}, + ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ - QuickCreateButton(text: 'Category 5', onPressed: () {}), - QuickCreateButton(text: 'Category 6', onPressed: () {}), + QuickCreateButton( + text: 'Category 5', + onPressed: () {}, + ), + QuickCreateButton( + text: 'Category 6', + onPressed: () {}, + ), ], ), ], @@ -181,9 +210,11 @@ class _HomeViewState extends State { matchCount = results[0] as int; groupCount = results[1] as int; loadedRecentMatches = results[2] as List; - recentMatches = (loadedRecentMatches..sort((a, b) => b.createdAt.compareTo(a.createdAt))) - .take(2) - .toList(); + recentMatches = + (loadedRecentMatches + ..sort((a, b) => b.createdAt.compareTo(a.createdAt))) + .take(2) + .toList(); if (mounted) { setState(() { isLoading = false; diff --git a/lib/presentation/views/main_menu/match_view/create_match/game_view/create_game_view.dart b/lib/presentation/views/main_menu/match_view/create_match/game_view/create_game_view.dart index 3d63b01..442b935 100644 --- a/lib/presentation/views/main_menu/match_view/create_match/game_view/create_game_view.dart +++ b/lib/presentation/views/main_menu/match_view/create_match/game_view/create_game_view.dart @@ -261,7 +261,6 @@ class _CreateGameViewState extends State { description: _descriptionController.text.trim(), ruleset: selectedRuleset!, color: selectedColor!, - icon: '', ); if (isEditing) { await handleGameUpdate(newGame); diff --git a/lib/presentation/views/main_menu/match_view/match_view.dart b/lib/presentation/views/main_menu/match_view/match_view.dart index 96a17b7..0b2d76e 100644 --- a/lib/presentation/views/main_menu/match_view/match_view.dart +++ b/lib/presentation/views/main_menu/match_view/match_view.dart @@ -44,7 +44,6 @@ class _MatchViewState extends State { ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, - icon: '', ), group: Group( name: 'Group name', diff --git a/lib/services/data_transfer_service.dart b/lib/services/data_transfer_service.dart index 526a459..0fe16b3 100644 --- a/lib/services/data_transfer_service.dart +++ b/lib/services/data_transfer_service.dart @@ -40,33 +40,39 @@ class DataTransferService { 'players': players.map((p) => p.toJson()).toList(), 'games': games.map((g) => g.toJson()).toList(), 'groups': groups - .map((g) => { - 'id': g.id, - 'name': g.name, - 'description': g.description, - 'createdAt': g.createdAt.toIso8601String(), - 'memberIds': (g.members).map((m) => m.id).toList(), - }) + .map( + (g) => { + 'id': g.id, + 'name': g.name, + 'description': g.description, + 'createdAt': g.createdAt.toIso8601String(), + 'memberIds': (g.members).map((m) => m.id).toList(), + }, + ) .toList(), 'teams': teams - .map((t) => { - 'id': t.id, - 'name': t.name, - 'createdAt': t.createdAt.toIso8601String(), - 'memberIds': (t.members).map((m) => m.id).toList(), - }) + .map( + (t) => { + 'id': t.id, + 'name': t.name, + 'createdAt': t.createdAt.toIso8601String(), + 'memberIds': (t.members).map((m) => m.id).toList(), + }, + ) .toList(), 'matches': matches - .map((m) => { - 'id': m.id, - 'name': m.name, - 'createdAt': m.createdAt.toIso8601String(), - 'endedAt': m.endedAt?.toIso8601String(), - 'gameId': m.game.id, - 'groupId': m.group?.id, - 'playerIds': m.players.map((p) => p.id).toList(), - 'notes': m.notes, - }) + .map( + (m) => { + 'id': m.id, + 'name': m.name, + 'createdAt': m.createdAt.toIso8601String(), + 'endedAt': m.endedAt?.toIso8601String(), + 'gameId': m.game.id, + 'groupId': m.group?.id, + 'playerIds': m.players.map((p) => p.id).toList(), + 'notes': m.notes, + }, + ) .toList(), }; @@ -79,9 +85,9 @@ class DataTransferService { /// [jsonString] The JSON string to be exported. /// [fileName] The desired name for the exported file (without extension). static Future exportData( - String jsonString, - String fileName - ) async { + String jsonString, + String fileName, + ) async { try { final bytes = Uint8List.fromList(utf8.encode(jsonString)); final path = await FilePicker.platform.saveFile( @@ -94,7 +100,6 @@ class DataTransferService { } else { return ExportResult.success; } - } catch (e, stack) { print('[exportData] $e'); print(stack); @@ -122,13 +127,19 @@ class DataTransferService { final isValid = await _validateJsonSchema(jsonString); if (!isValid) return ImportResult.invalidSchema; - final Map decoded = json.decode(jsonString) as Map; + final Map decoded = + json.decode(jsonString) as Map; - final List playersJson = (decoded['players'] as List?) ?? []; - final List gamesJson = (decoded['games'] as List?) ?? []; - final List groupsJson = (decoded['groups'] as List?) ?? []; - final List teamsJson = (decoded['teams'] as List?) ?? []; - final List matchesJson = (decoded['matches'] as List?) ?? []; + final List playersJson = + (decoded['players'] as List?) ?? []; + final List gamesJson = + (decoded['games'] as List?) ?? []; + final List groupsJson = + (decoded['groups'] as List?) ?? []; + final List teamsJson = + (decoded['teams'] as List?) ?? []; + final List matchesJson = + (decoded['matches'] as List?) ?? []; // Import Players final List importedPlayers = playersJson @@ -151,7 +162,8 @@ class DataTransferService { // Import Groups final List importedGroups = groupsJson.map((g) { final map = g as Map; - final memberIds = (map['memberIds'] as List? ?? []).cast(); + final memberIds = (map['memberIds'] as List? ?? []) + .cast(); final members = memberIds .map((id) => playerById[id]) @@ -174,7 +186,8 @@ class DataTransferService { // Import Teams final List importedTeams = teamsJson.map((t) { final map = t as Map; - final memberIds = (map['memberIds'] as List? ?? []).cast(); + final memberIds = (map['memberIds'] as List? ?? []) + .cast(); final members = memberIds .map((id) => playerById[id]) @@ -195,8 +208,11 @@ class DataTransferService { final String gameId = map['gameId'] as String; final String? groupId = map['groupId'] as String?; - final List playerIds = (map['playerIds'] as List? ?? []).cast(); - final DateTime? endedAt = map['endedAt'] != null ? DateTime.parse(map['endedAt'] as String) : null; + final List playerIds = + (map['playerIds'] as List? ?? []).cast(); + final DateTime? endedAt = map['endedAt'] != null + ? DateTime.parse(map['endedAt'] as String) + : null; final game = gameById[gameId]; final group = (groupId == null) ? null : groupById[groupId]; @@ -208,7 +224,14 @@ class DataTransferService { return Match( id: map['id'] as String, name: map['name'] as String, - game: game ?? Game(name: 'Unknown', ruleset: Ruleset.singleWinner, description: '', color: GameColor.blue, icon: ''), + game: + game ?? + Game( + name: 'Unknown', + ruleset: Ruleset.singleWinner, + description: '', + color: GameColor.blue, + ), group: group, players: players, createdAt: DateTime.parse(map['createdAt'] as String), @@ -266,4 +289,4 @@ class DataTransferService { return false; } } -} \ No newline at end of file +} diff --git a/test/db_tests/aggregates/match_test.dart b/test/db_tests/aggregates/match_test.dart index ea80369..db14763 100644 --- a/test/db_tests/aggregates/match_test.dart +++ b/test/db_tests/aggregates/match_test.dart @@ -56,7 +56,6 @@ void main() { ruleset: Ruleset.singleWinner, description: 'A test game', color: GameColor.blue, - icon: '', ); testMatch1 = Match( name: 'First Test Match', diff --git a/test/db_tests/aggregates/team_test.dart b/test/db_tests/aggregates/team_test.dart index 17ceff9..348ca07 100644 --- a/test/db_tests/aggregates/team_test.dart +++ b/test/db_tests/aggregates/team_test.dart @@ -2,12 +2,12 @@ import 'package:clock/clock.dart'; import 'package:drift/drift.dart'; import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:tallee/core/enums.dart'; import 'package:tallee/data/db/database.dart'; import 'package:tallee/data/dto/game.dart'; import 'package:tallee/data/dto/match.dart'; import 'package:tallee/data/dto/player.dart'; import 'package:tallee/data/dto/team.dart'; -import 'package:tallee/core/enums.dart'; void main() { late AppDatabase database; @@ -37,20 +37,21 @@ void main() { testPlayer2 = Player(name: 'Bob', description: ''); testPlayer3 = Player(name: 'Charlie', description: ''); testPlayer4 = Player(name: 'Diana', description: ''); - testTeam1 = Team( - name: 'Team Alpha', - members: [testPlayer1, testPlayer2], + testTeam1 = Team(name: 'Team Alpha', members: [testPlayer1, testPlayer2]); + testTeam2 = Team(name: 'Team Beta', members: [testPlayer3, testPlayer4]); + testTeam3 = Team(name: 'Team Gamma', members: [testPlayer1, testPlayer3]); + testGame1 = Game( + name: 'Game 1', + ruleset: Ruleset.singleWinner, + description: 'Test game 1', + color: GameColor.blue, ); - testTeam2 = Team( - name: 'Team Beta', - members: [testPlayer3, testPlayer4], + testGame2 = Game( + name: 'Game 2', + ruleset: Ruleset.highestScore, + description: 'Test game 2', + color: GameColor.red, ); - testTeam3 = Team( - name: 'Team Gamma', - members: [testPlayer1, testPlayer3], - ); - testGame1 = Game(name: 'Game 1', ruleset: Ruleset.singleWinner, description: 'Test game 1', color: GameColor.blue, icon: ''); - testGame2 = Game(name: 'Game 2', ruleset: Ruleset.highestScore, description: 'Test game 2', color: GameColor.red, icon: ''); }); await database.playerDao.addPlayersAsList( @@ -65,7 +66,6 @@ void main() { }); group('Team Tests', () { - // Verifies that a single team can be added and retrieved with all fields intact. test('Adding and fetching a single team works correctly', () async { final added = await database.teamDao.addTeam(team: testTeam1); @@ -285,10 +285,7 @@ void main() { test('Updating team name to empty string works', () async { await database.teamDao.addTeam(team: testTeam1); - await database.teamDao.updateTeamName( - teamId: testTeam1.id, - newName: '', - ); + await database.teamDao.updateTeamName(teamId: testTeam1.id, newName: ''); final updatedTeam = await database.teamDao.getTeamById( teamId: testTeam1.id, @@ -350,9 +347,7 @@ void main() { await database.matchDao.addMatch(match: match2); // Add teams to database - await database.teamDao.addTeamsAsList( - teams: [testTeam1, testTeam3], - ); + await database.teamDao.addTeamsAsList(teams: [testTeam1, testTeam3]); // Associate players with teams through match1 // testTeam1: player1, player2 @@ -420,10 +415,11 @@ void main() { final allTeams = await database.teamDao.getAllTeams(); expect(allTeams.length, 3); - expect( - allTeams.map((t) => t.id).toSet(), - {testTeam1.id, testTeam2.id, testTeam3.id}, - ); + expect(allTeams.map((t) => t.id).toSet(), { + testTeam1.id, + testTeam2.id, + testTeam3.id, + }); }); // Verifies that teamExists returns false for deleted teams. @@ -462,9 +458,7 @@ void main() { // Verifies that addTeam after deleteAllTeams works correctly. test('Adding team after deleteAllTeams works correctly', () async { - await database.teamDao.addTeamsAsList( - teams: [testTeam1, testTeam2], - ); + await database.teamDao.addTeamsAsList(teams: [testTeam1, testTeam2]); expect(await database.teamDao.getTeamCount(), 2); await database.teamDao.deleteAllTeams(); @@ -524,4 +518,4 @@ void main() { expect(fetchedTeam.createdAt, testTeam1.createdAt); }); }); -} \ No newline at end of file +} diff --git a/test/db_tests/entities/game_test.dart b/test/db_tests/entities/game_test.dart index 924a60b..c4a8b47 100644 --- a/test/db_tests/entities/game_test.dart +++ b/test/db_tests/entities/game_test.dart @@ -44,7 +44,6 @@ void main() { ruleset: Ruleset.highestScore, description: 'A board game about real estate', color: GameColor.orange, - icon: '', ); }); }); @@ -54,7 +53,6 @@ void main() { }); group('Game Tests', () { - // Verifies that getAllGames returns an empty list when the database has no games. test('getAllGames returns empty list when no games exist', () async { final allGames = await database.gameDao.getAllGames(); @@ -106,7 +104,7 @@ void main() { // Verifies that getGameById throws a StateError when the game doesn't exist. test('getGameById throws exception for non-existent game', () async { expect( - () => database.gameDao.getGameById(gameId: 'non-existent-id'), + () => database.gameDao.getGameById(gameId: 'non-existent-id'), throwsA(isA()), ); }); @@ -134,7 +132,12 @@ void main() { // Verifies that a game with empty optional fields can be added and retrieved. test('addGame handles game with null optional fields', () async { - final gameWithNulls = Game(name: 'Simple Game', ruleset: Ruleset.lowestScore, description: 'A simple game', color: GameColor.green, icon: ''); + final gameWithNulls = Game( + name: 'Simple Game', + ruleset: Ruleset.lowestScore, + description: 'A simple game', + color: GameColor.green, + ); final result = await database.gameDao.addGame(game: gameWithNulls); expect(result, true); @@ -419,9 +422,7 @@ void main() { // Verifies that getGameCount updates correctly after deleting a game. test('getGameCount updates correctly after deletion', () async { - await database.gameDao.addGamesAsList( - games: [testGame1, testGame2], - ); + await database.gameDao.addGamesAsList(games: [testGame1, testGame2]); final countBefore = await database.gameDao.getGameCount(); expect(countBefore, 2); @@ -461,7 +462,6 @@ void main() { ruleset: Ruleset.multipleWinners, description: 'Description with émojis 🎮🎲', color: GameColor.purple, - icon: '', ); await database.gameDao.addGame(game: specialGame); @@ -478,7 +478,6 @@ void main() { name: '', ruleset: Ruleset.singleWinner, description: '', - icon: '', color: GameColor.red, ); await database.gameDao.addGame(game: emptyGame); @@ -500,7 +499,6 @@ void main() { description: longString, ruleset: Ruleset.multipleWinners, color: GameColor.yellow, - icon: '', ); await database.gameDao.addGame(game: longGame); diff --git a/test/db_tests/relationships/player_match_test.dart b/test/db_tests/relationships/player_match_test.dart index 890e74e..f1ffeca 100644 --- a/test/db_tests/relationships/player_match_test.dart +++ b/test/db_tests/relationships/player_match_test.dart @@ -48,7 +48,12 @@ void main() { description: '', members: [testPlayer1, testPlayer2, testPlayer3], ); - testGame = Game(name: 'Test Game', ruleset: Ruleset.singleWinner, description: 'A test game', color: GameColor.blue, icon: ''); + testGame = Game( + name: 'Test Game', + ruleset: Ruleset.singleWinner, + description: 'A test game', + color: GameColor.blue, + ); testMatchOnlyGroup = Match( name: 'Test Match with Group', game: testGame, @@ -61,14 +66,8 @@ void main() { players: [testPlayer4, testPlayer5, testPlayer6], notes: '', ); - testTeam1 = Team( - name: 'Team Alpha', - members: [testPlayer1, testPlayer2], - ); - testTeam2 = Team( - name: 'Team Beta', - members: [testPlayer3, testPlayer4], - ); + testTeam1 = Team(name: 'Team Alpha', members: [testPlayer1, testPlayer2]); + testTeam2 = Team(name: 'Team Beta', members: [testPlayer3, testPlayer4]); }); await database.playerDao.addPlayersAsList( players: [ @@ -88,7 +87,6 @@ void main() { }); group('Player-Match Tests', () { - // Verifies that matchHasPlayers returns false initially and true after adding a player. test('Match has player works correctly', () async { await database.matchDao.addMatch(match: testMatchOnlyGroup); @@ -153,26 +151,23 @@ void main() { ); expect(result.players.length, testMatchOnlyPlayers.players.length - 1); - final playerExists = result.players.any( - (p) => p.id == playerToRemove.id, - ); + final playerExists = result.players.any((p) => p.id == playerToRemove.id); expect(playerExists, false); }); // Verifies that getPlayersOfMatch returns all players of a match with correct data. test('Retrieving players of a match works correctly', () async { await database.matchDao.addMatch(match: testMatchOnlyPlayers); - final players = await database.playerMatchDao.getPlayersOfMatch( - matchId: testMatchOnlyPlayers.id, - ) ?? []; + final players = + await database.playerMatchDao.getPlayersOfMatch( + matchId: testMatchOnlyPlayers.id, + ) ?? + []; for (int i = 0; i < players.length; i++) { expect(players[i].id, testMatchOnlyPlayers.players[i].id); expect(players[i].name, testMatchOnlyPlayers.players[i].name); - expect( - players[i].createdAt, - testMatchOnlyPlayers.players[i].createdAt, - ); + expect(players[i].createdAt, testMatchOnlyPlayers.players[i].createdAt); } }); @@ -223,10 +218,20 @@ void main() { // Verifies that the same player can be added to multiple different matches. test( 'Adding the same player to separate matches works correctly', - () async { + () async { final playersList = [testPlayer1, testPlayer2, testPlayer3]; - final match1 = Match(name: 'Match 1', game: testGame, players: playersList, notes: ''); - final match2 = Match(name: 'Match 2', game: testGame, players: playersList, notes: ''); + final match1 = Match( + name: 'Match 1', + game: testGame, + players: playersList, + notes: '', + ); + final match2 = Match( + name: 'Match 2', + game: testGame, + players: playersList, + notes: '', + ); await Future.wait([ database.matchDao.addMatch(match: match1), @@ -299,16 +304,19 @@ void main() { }); // Verifies that getPlayerScore returns null for non-existent player-match combination. - test('getPlayerScore returns null for non-existent player in match', () async { - await database.matchDao.addMatch(match: testMatchOnlyGroup); + test( + 'getPlayerScore returns null for non-existent player in match', + () async { + await database.matchDao.addMatch(match: testMatchOnlyGroup); - final score = await database.playerMatchDao.getPlayerScore( - matchId: testMatchOnlyGroup.id, - playerId: 'non-existent-player-id', - ); + final score = await database.playerMatchDao.getPlayerScore( + matchId: testMatchOnlyGroup.id, + playerId: 'non-existent-player-id', + ); - expect(score, isNull); - }); + expect(score, isNull); + }, + ); // Verifies that updatePlayerScore updates the score correctly. test('updatePlayerScore updates score correctly', () async { @@ -331,17 +339,20 @@ void main() { }); // Verifies that updatePlayerScore returns false for non-existent player-match. - test('updatePlayerScore returns false for non-existent player-match', () async { - await database.matchDao.addMatch(match: testMatchOnlyGroup); + test( + 'updatePlayerScore returns false for non-existent player-match', + () async { + await database.matchDao.addMatch(match: testMatchOnlyGroup); - final updated = await database.playerMatchDao.updatePlayerScore( - matchId: testMatchOnlyGroup.id, - playerId: 'non-existent-player-id', - newScore: 50, - ); + final updated = await database.playerMatchDao.updatePlayerScore( + matchId: testMatchOnlyGroup.id, + playerId: 'non-existent-player-id', + newScore: 50, + ); - expect(updated, false); - }); + expect(updated, false); + }, + ); // Verifies that adding a player with teamId works correctly. test('Adding player with teamId works correctly', () async { @@ -431,17 +442,20 @@ void main() { }); // Verifies that updatePlayerTeam returns false for non-existent player-match. - test('updatePlayerTeam returns false for non-existent player-match', () async { - await database.matchDao.addMatch(match: testMatchOnlyGroup); + test( + 'updatePlayerTeam returns false for non-existent player-match', + () async { + await database.matchDao.addMatch(match: testMatchOnlyGroup); - final updated = await database.playerMatchDao.updatePlayerTeam( - matchId: testMatchOnlyGroup.id, - playerId: 'non-existent-player-id', - teamId: testTeam1.id, - ); + final updated = await database.playerMatchDao.updatePlayerTeam( + matchId: testMatchOnlyGroup.id, + playerId: 'non-existent-player-id', + teamId: testTeam1.id, + ); - expect(updated, false); - }); + expect(updated, false); + }, + ); // Verifies that getPlayersInTeam returns empty list for non-existent team. test('getPlayersInTeam returns empty list for non-existent team', () async { @@ -483,16 +497,19 @@ void main() { }); // Verifies that removePlayerFromMatch returns false for non-existent player. - test('removePlayerFromMatch returns false for non-existent player', () async { - await database.matchDao.addMatch(match: testMatchOnlyPlayers); + test( + 'removePlayerFromMatch returns false for non-existent player', + () async { + await database.matchDao.addMatch(match: testMatchOnlyPlayers); - final removed = await database.playerMatchDao.removePlayerFromMatch( - playerId: 'non-existent-player-id', - matchId: testMatchOnlyPlayers.id, - ); + final removed = await database.playerMatchDao.removePlayerFromMatch( + playerId: 'non-existent-player-id', + matchId: testMatchOnlyPlayers.id, + ); - expect(removed, false); - }); + expect(removed, false); + }, + ); // Verifies that adding the same player twice to the same match is ignored. test('Adding same player twice to same match is ignored', () async { @@ -528,27 +545,30 @@ void main() { }); // Verifies that updatePlayersFromMatch with empty list removes all players. - test('updatePlayersFromMatch with empty list removes all players', () async { - await database.matchDao.addMatch(match: testMatchOnlyPlayers); + test( + 'updatePlayersFromMatch with empty list removes all players', + () async { + await database.matchDao.addMatch(match: testMatchOnlyPlayers); - // Verify players exist initially - var players = await database.playerMatchDao.getPlayersOfMatch( - matchId: testMatchOnlyPlayers.id, - ); - expect(players?.length, 3); + // Verify players exist initially + var players = await database.playerMatchDao.getPlayersOfMatch( + matchId: testMatchOnlyPlayers.id, + ); + expect(players?.length, 3); - // Update with empty list - await database.playerMatchDao.updatePlayersFromMatch( - matchId: testMatchOnlyPlayers.id, - newPlayer: [], - ); + // Update with empty list + await database.playerMatchDao.updatePlayersFromMatch( + matchId: testMatchOnlyPlayers.id, + newPlayer: [], + ); - // Verify all players are removed - players = await database.playerMatchDao.getPlayersOfMatch( - matchId: testMatchOnlyPlayers.id, - ); - expect(players, isNull); - }); + // Verify all players are removed + players = await database.playerMatchDao.getPlayersOfMatch( + matchId: testMatchOnlyPlayers.id, + ); + expect(players, isNull); + }, + ); // Verifies that updatePlayersFromMatch with same players makes no changes. test('updatePlayersFromMatch with same players makes no changes', () async { @@ -702,16 +722,19 @@ void main() { }); // Verifies that getPlayersInTeam returns empty list for non-existent match. - test('getPlayersInTeam returns empty list for non-existent match', () async { - await database.teamDao.addTeam(team: testTeam1); + test( + 'getPlayersInTeam returns empty list for non-existent match', + () async { + await database.teamDao.addTeam(team: testTeam1); - final players = await database.playerMatchDao.getPlayersInTeam( - matchId: 'non-existent-match-id', - teamId: testTeam1.id, - ); + final players = await database.playerMatchDao.getPlayersInTeam( + matchId: 'non-existent-match-id', + teamId: testTeam1.id, + ); - expect(players.isEmpty, true); - }); + expect(players.isEmpty, true); + }, + ); // Verifies that players in different teams within the same match are returned correctly. test('Players in different teams within same match are separate', () async { @@ -759,8 +782,18 @@ void main() { // Verifies that removePlayerFromMatch does not affect other matches. test('removePlayerFromMatch does not affect other matches', () async { final playersList = [testPlayer1, testPlayer2]; - final match1 = Match(name: 'Match 1', game: testGame, players: playersList, notes: ''); - final match2 = Match(name: 'Match 2', game: testGame, players: playersList, notes: ''); + final match1 = Match( + name: 'Match 1', + game: testGame, + players: playersList, + notes: '', + ); + final match2 = Match( + name: 'Match 2', + game: testGame, + players: playersList, + notes: '', + ); await Future.wait([ database.matchDao.addMatch(match: match1), @@ -792,8 +825,18 @@ void main() { // Verifies that updating scores for players in different matches are independent. test('Player scores are independent across matches', () async { final playersList = [testPlayer1]; - final match1 = Match(name: 'Match 1', game: testGame, players: playersList, notes: ''); - final match2 = Match(name: 'Match 2', game: testGame, players: playersList, notes: ''); + final match1 = Match( + name: 'Match 1', + game: testGame, + players: playersList, + notes: '', + ); + final match2 = Match( + name: 'Match 2', + game: testGame, + players: playersList, + notes: '', + ); await Future.wait([ database.matchDao.addMatch(match: match1), @@ -829,16 +872,19 @@ void main() { }); // Verifies that updatePlayersFromMatch on non-existent match fails with constraint error. - test('updatePlayersFromMatch on non-existent match fails with foreign key constraint', () async { - // Should throw due to foreign key constraint - match doesn't exist - await expectLater( - database.playerMatchDao.updatePlayersFromMatch( - matchId: 'non-existent-match-id', - newPlayer: [testPlayer1, testPlayer2], - ), - throwsA(anything), - ); - }); + test( + 'updatePlayersFromMatch on non-existent match fails with foreign key constraint', + () async { + // Should throw due to foreign key constraint - match doesn't exist + await expectLater( + database.playerMatchDao.updatePlayersFromMatch( + matchId: 'non-existent-match-id', + newPlayer: [testPlayer1, testPlayer2], + ), + throwsA(anything), + ); + }, + ); // Verifies that a player can be in a match without being assigned to a team. test('Player can exist in match without team assignment', () async { diff --git a/test/db_tests/values/score_test.dart b/test/db_tests/values/score_test.dart index 2ad4671..7dbbba0 100644 --- a/test/db_tests/values/score_test.dart +++ b/test/db_tests/values/score_test.dart @@ -2,11 +2,11 @@ import 'package:clock/clock.dart'; import 'package:drift/drift.dart' hide isNull, isNotNull; import 'package:drift/native.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:tallee/core/enums.dart'; import 'package:tallee/data/db/database.dart'; import 'package:tallee/data/dto/game.dart'; import 'package:tallee/data/dto/match.dart'; import 'package:tallee/data/dto/player.dart'; -import 'package:tallee/core/enums.dart'; void main() { late AppDatabase database; @@ -32,7 +32,12 @@ void main() { testPlayer1 = Player(name: 'Alice', description: ''); testPlayer2 = Player(name: 'Bob', description: ''); testPlayer3 = Player(name: 'Charlie', description: ''); - testGame = Game(name: 'Test Game', ruleset: Ruleset.singleWinner, description: 'A test game', color: GameColor.blue, icon: ''); + testGame = Game( + name: 'Test Game', + ruleset: Ruleset.singleWinner, + description: 'A test game', + color: GameColor.blue, + ); testMatch1 = Match( name: 'Test Match 1', game: testGame, @@ -60,7 +65,6 @@ void main() { }); group('Score Tests', () { - // Verifies that a score can be added and retrieved with all fields intact. test('Adding and fetching a score works correctly', () async { await database.scoreDao.addScore( @@ -431,13 +435,16 @@ void main() { }); // Verifies that getScoresForMatch returns empty list for match with no scores. - test('Getting scores for match with no scores returns empty list', () async { - final scores = await database.scoreDao.getScoresForMatch( - matchId: testMatch1.id, - ); + test( + 'Getting scores for match with no scores returns empty list', + () async { + final scores = await database.scoreDao.getScoresForMatch( + matchId: testMatch1.id, + ); - expect(scores.isEmpty, true); - }); + expect(scores.isEmpty, true); + }, + ); // Verifies that getPlayerScoresInMatch returns empty list when player has no scores. test('Getting player scores with no scores returns empty list', () async { @@ -666,46 +673,58 @@ void main() { }); // Verifies that updating one player's score doesn't affect another player's score in same round. - test('Updating one player score does not affect other players in same round', () async { - await database.scoreDao.addScore( - playerId: testPlayer1.id, - matchId: testMatch1.id, - roundNumber: 1, - score: 10, - change: 10, - ); - await database.scoreDao.addScore( - playerId: testPlayer2.id, - matchId: testMatch1.id, - roundNumber: 1, - score: 20, - change: 20, - ); - await database.scoreDao.addScore( - playerId: testPlayer3.id, - matchId: testMatch1.id, - roundNumber: 1, - score: 30, - change: 30, - ); + test( + 'Updating one player score does not affect other players in same round', + () async { + await database.scoreDao.addScore( + playerId: testPlayer1.id, + matchId: testMatch1.id, + roundNumber: 1, + score: 10, + change: 10, + ); + await database.scoreDao.addScore( + playerId: testPlayer2.id, + matchId: testMatch1.id, + roundNumber: 1, + score: 20, + change: 20, + ); + await database.scoreDao.addScore( + playerId: testPlayer3.id, + matchId: testMatch1.id, + roundNumber: 1, + score: 30, + change: 30, + ); - await database.scoreDao.updateScore( - playerId: testPlayer2.id, - matchId: testMatch1.id, - roundNumber: 1, - newScore: 99, - newChange: 89, - ); + await database.scoreDao.updateScore( + playerId: testPlayer2.id, + matchId: testMatch1.id, + roundNumber: 1, + newScore: 99, + newChange: 89, + ); - final scores = await database.scoreDao.getScoresForMatch( - matchId: testMatch1.id, - ); + final scores = await database.scoreDao.getScoresForMatch( + matchId: testMatch1.id, + ); - expect(scores.length, 3); - expect(scores.where((s) => s.playerId == testPlayer1.id).first.score, 10); - expect(scores.where((s) => s.playerId == testPlayer2.id).first.score, 99); - expect(scores.where((s) => s.playerId == testPlayer3.id).first.score, 30); - }); + expect(scores.length, 3); + expect( + scores.where((s) => s.playerId == testPlayer1.id).first.score, + 10, + ); + expect( + scores.where((s) => s.playerId == testPlayer2.id).first.score, + 99, + ); + expect( + scores.where((s) => s.playerId == testPlayer3.id).first.score, + 30, + ); + }, + ); // Verifies that deleting a player's scores only affects that specific player. test('Deleting player scores only affects target player', () async { @@ -724,9 +743,7 @@ void main() { change: 20, ); - await database.scoreDao.deleteScoresForPlayer( - playerId: testPlayer1.id, - ); + await database.scoreDao.deleteScoresForPlayer(playerId: testPlayer1.id); final match1Scores = await database.scoreDao.getScoresForMatch( matchId: testMatch1.id,