import 'package:flutter_test/flutter_test.dart'; import 'package:farolero/modelos/sala_multijugador.dart'; import 'package:farolero/modelos/usuario.dart'; void main() { group('EstadoSalaMultijugador', () { late EstadoSalaMultijugador sala; setUp(() { sala = EstadoSalaMultijugador.crear( roomId: 'room-1', nombreSala: 'Ana - Farolero', hostClientId: 'host', hostNombre: 'Ana', ); }); test('registra al host como cliente conectado de la sala', () { expect(sala.hostClientId, 'host'); expect(sala.clientes['host']?.esHost, isTrue); expect(sala.clientes['host']?.conectado, isTrue); }); test('permite seleccionar varios usuarios para un mismo cliente', () { sala.crearUsuario(Usuario(id: 'ana', nombre: 'Ana')); sala.crearUsuario(Usuario(id: 'juan', nombre: 'Juan')); final seleccionAna = sala.seleccionarUsuario( usuarioId: 'ana', clienteId: 'host', ); final seleccionJuan = sala.seleccionarUsuario( usuarioId: 'juan', clienteId: 'host', ); expect(seleccionAna.exitoso, isTrue); expect(seleccionJuan.exitoso, isTrue); expect(sala.usuariosPorCliente('host').map((u) => u.nombre), [ 'Ana', 'Juan', ]); }); test('impide que dos clientes seleccionen el mismo usuario', () { sala.registrarCliente( const ClienteSala( clientId: 'cliente-jorge', endpointId: 'endpoint-1', nombre: 'Jorge', ), ); sala.crearUsuario(Usuario(id: 'sofia', nombre: 'Sofía')); final primeraSeleccion = sala.seleccionarUsuario( usuarioId: 'sofia', clienteId: 'host', ); final segundaSeleccion = sala.seleccionarUsuario( usuarioId: 'sofia', clienteId: 'cliente-jorge', ); expect(primeraSeleccion.exitoso, isTrue); expect(segundaSeleccion.exitoso, isFalse); expect(segundaSeleccion.codigo, 'usuario_ya_seleccionado'); expect(sala.usuarios['sofia']?.clienteIdSeleccionado, 'host'); }); test('solo permite eliminar usuarios no seleccionados y por el host', () { sala.registrarCliente( const ClienteSala( clientId: 'cliente-jorge', endpointId: 'endpoint-1', nombre: 'Jorge', ), ); sala.crearUsuario(Usuario(id: 'ana', nombre: 'Ana')); sala.crearUsuario(Usuario(id: 'javier', nombre: 'Javier')); sala.seleccionarUsuario(usuarioId: 'ana', clienteId: 'host'); final clienteElimina = sala.eliminarUsuario( usuarioId: 'javier', solicitanteClientId: 'cliente-jorge', ); final hostEliminaSeleccionado = sala.eliminarUsuario( usuarioId: 'ana', solicitanteClientId: 'host', ); final hostEliminaLibre = sala.eliminarUsuario( usuarioId: 'javier', solicitanteClientId: 'host', ); expect(clienteElimina.exitoso, isFalse); expect(clienteElimina.codigo, 'solo_host'); expect(hostEliminaSeleccionado.exitoso, isFalse); expect(hostEliminaSeleccionado.codigo, 'usuario_seleccionado'); expect(hostEliminaLibre.exitoso, isTrue); expect(sala.usuarios.containsKey('javier'), isFalse); }); test('valida inicio con minimo tres usuarios y host seleccionado', () { sala ..crearUsuario(Usuario(id: 'ana', nombre: 'Ana')) ..crearUsuario(Usuario(id: 'juan', nombre: 'Juan')) ..crearUsuario(Usuario(id: 'sofia', nombre: 'Sofía')); expect(sala.validarInicio().exitoso, isFalse); expect(sala.validarInicio().codigo, 'faltan_jugadores'); sala ..seleccionarUsuario(usuarioId: 'ana', clienteId: 'host') ..seleccionarUsuario(usuarioId: 'juan', clienteId: 'host') ..seleccionarUsuario(usuarioId: 'sofia', clienteId: 'host'); expect(sala.validarInicio().exitoso, isTrue); expect(sala.iniciarPartida().exitoso, isTrue); expect(sala.fase, FaseSalaMultijugador.enPartida); }); test('libera usuarios de un cliente desconectado durante lobby', () { sala.registrarCliente( const ClienteSala( clientId: 'cliente-sofia', endpointId: 'endpoint-2', nombre: 'Sofía', ), ); sala ..crearUsuario(Usuario(id: 'sofia', nombre: 'Sofía')) ..crearUsuario(Usuario(id: 'helena', nombre: 'Helena')) ..seleccionarUsuario(usuarioId: 'sofia', clienteId: 'cliente-sofia') ..seleccionarUsuario(usuarioId: 'helena', clienteId: 'cliente-sofia'); sala.desconectarCliente('cliente-sofia'); expect(sala.clientes['cliente-sofia']?.conectado, isFalse); expect(sala.usuarios['sofia']?.estaDisponible, isTrue); expect(sala.usuarios['helena']?.estaDisponible, isTrue); }); test('serializa y restaura clientes y usuarios seleccionados', () { sala ..crearUsuario(Usuario(id: 'ana', nombre: 'Ana')) ..seleccionarUsuario(usuarioId: 'ana', clienteId: 'host'); final restaurada = EstadoSalaMultijugador.fromJson(sala.toJson()); expect(restaurada.roomId, 'room-1'); expect(restaurada.clientes['host']?.esHost, isTrue); expect(restaurada.usuarios['ana']?.clienteIdSeleccionado, 'host'); expect(restaurada.usuariosSeleccionados.single.nombre, 'Ana'); }); }); }