import 'dart:core' hide Match; 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/models/game.dart'; import 'package:tallee/data/models/match.dart'; import 'package:tallee/data/models/player.dart'; import 'package:tallee/data/models/team.dart'; void main() { late AppDatabase database; late Player testPlayer1; late Player testPlayer2; late Player testPlayer3; late Player testPlayer4; late Team testTeam1; late Team testTeam2; late Team testTeam3; late Team testTeam4; late Game testGame; late Match testMatch1; late Match testMatch2; late Match matchWithNoTeams; final fixedDate = DateTime(2025, 11, 19, 00, 11, 23); final fakeClock = Clock(() => fixedDate); setUp(() async { database = AppDatabase( DatabaseConnection( NativeDatabase.memory(), // Recommended for widget tests to avoid test errors. closeStreamsSynchronously: true, ), ); withClock(fakeClock, () { testPlayer1 = Player(name: 'Alice'); testPlayer2 = Player(name: 'Bob'); testPlayer3 = Player(name: 'Charlie'); testPlayer4 = Player(name: 'Diana'); testTeam1 = Team(name: 'Team Alpha', members: [testPlayer1, testPlayer2]); testTeam2 = Team(name: 'Team Beta', members: [testPlayer3, testPlayer4]); testTeam3 = Team(name: 'Team Gamma', members: [testPlayer1, testPlayer3]); testTeam4 = Team(name: 'Team Omega', members: [testPlayer2, testPlayer4]); testGame = Game( name: 'Test Game', ruleset: Ruleset.highestScore, color: GameColor.blue, icon: '', ); testMatch1 = Match( name: 'Match 1', game: testGame, players: [], teams: [testTeam1, testTeam2], ); testMatch2 = Match( name: 'Match 2', game: testGame, players: [], teams: [testTeam3, testTeam4], ); matchWithNoTeams = Match( name: 'Match with no teams', game: testGame, players: [testPlayer1, testPlayer2, testPlayer3, testPlayer4], ); }); await database.gameDao.addGame(game: testGame); await database.playerDao.addPlayersAsList( players: [testPlayer1, testPlayer2, testPlayer3, testPlayer4], ); }); tearDown(() async { await database.close(); }); group('Team Tests', () { group('CREATE', () { test('Adding and fetching a single team works correctly', () async { await database.matchDao.addMatch(match: matchWithNoTeams); final added = await database.teamDao.addTeam( team: testTeam1, matchId: matchWithNoTeams.id, ); expect(added, isTrue); final fetchedTeam = await database.teamDao.getTeamById( teamId: testTeam1.id, ); expect(fetchedTeam.id, testTeam1.id); expect(fetchedTeam.name, testTeam1.name); expect(fetchedTeam.createdAt, testTeam1.createdAt); expect(fetchedTeam.members.length, testTeam1.members.length); for (int i = 0; i < fetchedTeam.members.length; i++) { expect(fetchedTeam.members[i].id, testTeam1.members[i].id); expect(fetchedTeam.members[i].name, testTeam1.members[i].name); } }); test('Adding and fetching multiple teams works correctly', () async { await database.matchDao.addMatch(match: matchWithNoTeams); await database.teamDao.addTeamsAsList( teams: [testTeam1, testTeam2, testTeam3], matchId: matchWithNoTeams.id, ); final allTeams = await database.teamDao.getAllTeams(); expect(allTeams.length, 3); final testTeams = { testTeam1.id: testTeam1, testTeam2.id: testTeam2, testTeam3.id: testTeam3, }; for (final team in allTeams) { final testTeam = testTeams[team.id]!; expect(team.id, testTeam.id); expect(team.name, testTeam.name); expect(team.createdAt, testTeam.createdAt); } }); test('addTeam() ignores duplicates', () async { await database.matchDao.addMatch(match: matchWithNoTeams); var added = await database.teamDao.addTeam( team: testTeam1, matchId: matchWithNoTeams.id, ); expect(added, isTrue); added = await database.teamDao.addTeam( team: testTeam1, matchId: matchWithNoTeams.id, ); expect(added, isFalse); final teamCount = await database.teamDao.getTeamCount(); expect(teamCount, 1); }); test('addTeamsAsList() with empty list returns isFalse', () async { final added = await database.teamDao.addTeamsAsList( teams: [], matchId: matchWithNoTeams.id, ); expect(added, isFalse); }); test('addTeamsAsList() ignores duplicates', () async { await database.matchDao.addMatch(match: matchWithNoTeams); final added = await database.teamDao.addTeamsAsList( teams: [testTeam1, testTeam2, testTeam1], matchId: matchWithNoTeams.id, ); expect(added, isTrue); final teamCount = await database.teamDao.getTeamCount(); expect(teamCount, 2); }); }); group('READ', () { test('getTeamCount works correctly', () async { var count = await database.teamDao.getTeamCount(); expect(count, 0); await database.matchDao.addMatch(match: testMatch1); count = await database.teamDao.getTeamCount(); expect(count, 2); await database.teamDao.addTeam( team: testTeam2, matchId: matchWithNoTeams.id, ); count = await database.teamDao.getTeamCount(); expect(count, 2); await database.teamDao.deleteTeam(teamId: testTeam1.id); count = await database.teamDao.getTeamCount(); expect(count, 1); await database.teamDao.deleteTeam(teamId: testTeam2.id); count = await database.teamDao.getTeamCount(); expect(count, 0); }); test('teamExists() works correctly', () async { var teamExists = await database.teamDao.teamExists( teamId: testTeam1.id, ); expect(teamExists, isFalse); await database.matchDao.addMatch(match: matchWithNoTeams); await database.teamDao.addTeam( team: testTeam1, matchId: matchWithNoTeams.id, ); teamExists = await database.teamDao.teamExists(teamId: testTeam1.id); expect(teamExists, isTrue); }); test('getAllTeams() with no teams returns empty list', () async { final allTeams = await database.teamDao.getAllTeams(); expect(allTeams, isA>()); expect(allTeams.isEmpty, isTrue); }); test('getAllTeams() works correctly', () async { await database.matchDao.addMatch(match: matchWithNoTeams); await database.teamDao.addTeamsAsList( teams: [testTeam1, testTeam2, testTeam3], matchId: matchWithNoTeams.id, ); final allTeams = await database.teamDao.getAllTeams(); expect(allTeams.length, 3); expect(allTeams.map((t) => t.id).toSet(), { testTeam1.id, testTeam2.id, testTeam3.id, }); }); test('Getting non-existent team throws exception', () async { expect( () => database.teamDao.getTeamById(teamId: 'non-existent-id'), throwsA(isA()), ); }); }); group('UPDATED', () { test('updateTeamName() works correctly', () async { await database.matchDao.addMatch(match: matchWithNoTeams); await database.teamDao.addTeam( team: testTeam1, matchId: matchWithNoTeams.id, ); var fetchedTeam = await database.teamDao.getTeamById( teamId: testTeam1.id, ); expect(fetchedTeam.name, testTeam1.name); const newName = 'New name'; await database.teamDao.updateTeamName( teamId: testTeam1.id, name: newName, ); fetchedTeam = await database.teamDao.getTeamById(teamId: testTeam1.id); expect(fetchedTeam.name, newName); }); test('updateTeamName() does nothing for non-existent team', () async { final updated = await database.teamDao.updateTeamName( teamId: 'non-existing-id', name: 'New Name', ); expect(updated, isFalse); final allTeams = await database.teamDao.getAllTeams(); expect(allTeams, isEmpty); }); }); group('DELETE', () { test('deleteTeam() works correctly', () async { await database.matchDao.addMatch(match: testMatch1); await database.matchDao.addMatch(match: matchWithNoTeams); await database.teamDao.addTeam( team: testTeam1, matchId: matchWithNoTeams.id, ); final deleted = await database.teamDao.deleteTeam(teamId: testTeam1.id); expect(deleted, isTrue); final teamExists = await database.teamDao.teamExists( teamId: testTeam1.id, ); expect(teamExists, isFalse); }); test('Deleting a non-existent team returns isFalse', () async { final deleted = await database.teamDao.deleteTeam( teamId: 'non-existent-id', ); expect(deleted, isFalse); }); test('deleteAllTeams() works correctly', () async { await database.matchDao.addMatchesAsList( matches: [testMatch1, testMatch2], ); var teamCount = await database.teamDao.getTeamCount(); expect(teamCount, 4); final deleted = await database.teamDao.deleteAllTeams(); expect(deleted, isTrue); teamCount = await database.teamDao.getTeamCount(); expect(teamCount, 0); }); test('deleteAllTeams() with empty list returns false', () async { final deleted = await database.teamDao.deleteAllTeams(); expect(deleted, isFalse); }); }); }); }