Skip to content

Commit

Permalink
Feat #1031 Usercontroller.relogin gamestate rework (#1140)
Browse files Browse the repository at this point in the history
* feat: added conditional logic based on gamestate for relogin

* test: removed skipper

* Update api/controllers/UserController.js

Co-authored-by: Ryan Emberling <[email protected]>

* Update api/controllers/UserController.js

Co-authored-by: Ryan Emberling <[email protected]>

* fix: removed .loggedIn

* fix: populating p0, p1

* chore: new line

* test: fixed previously bugged test

* fix: bugged test

* test: updated test fixture

* fix: set pnum if missed event

* feat: added logic for lobby reload

* fix: only add p1 if in game model

* Update api/helpers/game-states/create-socket-event.js

* feat: updated the way socket event is handled

* fix: unneeded changes

---------

Co-authored-by: Ryan Emberling <[email protected]>
Co-authored-by: Sean Kennedy <[email protected]>
  • Loading branch information
3 people authored Jan 7, 2025
1 parent 1074e34 commit 1cf66c9
Show file tree
Hide file tree
Showing 3 changed files with 37 additions and 36 deletions.
29 changes: 29 additions & 0 deletions api/controllers/UserController.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,34 @@ module.exports = {
}
// Query for game if user is in one
const gameId = (user.game ?? req.session.game) ?? null;

if (process.env.VITE_USE_GAMESTATE_API) {
const { unpackGamestate, createSocketEvent } = sails.helpers.gameStates;
const game = await Game.findOne(gameId)
.populate('gameStates')
.populate('p0')
.populate('p1');
const gameObject = game.gameStates.length ? await unpackGamestate(game.gameStates.at(-1)) : null;
const socketEvent = game.gameStates.length ?
await createSocketEvent(game, gameObject)
: { game: { ...game, players: game.p1 ? [ game.p0, game.p1 ] : [ game.p0 ] } };

Game.subscribe(req, [ game.id ]);
req.session.usr = user.id;
// FIXME: #965 - remove game and pNum
req.session.game = game.id;
req.session.pNum = user.pNum ?? undefined;
Game.publish([ game.id ],socketEvent);

const pNum = game.p0?.id === user.id ? 0 : 1;
return res.ok({
game: socketEvent.game,
username: user.username,
pNum
});
}
// FIXME: #965
// Remove everything between here and catch AFTER gamestate is deployed
const unpopulatedGame = gameId ? await gameService.findGame({ gameId }) : null;
const populatedGame =
unpopulatedGame?.status === GameStatus.STARTED
Expand Down Expand Up @@ -97,6 +125,7 @@ module.exports = {
username: user.username,
pNum: user.pNum,
});

} catch (err) {
return res.badRequest(err);
}
Expand Down
1 change: 1 addition & 0 deletions tests/e2e/specs/in-game/game-over/winConditions.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -401,6 +401,7 @@ describe('Stalemates', () => {
});

it('Player requests stalemate, then reloads before opponent accepts', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.get('#game-menu-activator').click();
cy.get('#game-menu').should('be.visible')
Expand Down
43 changes: 7 additions & 36 deletions tests/e2e/specs/in-game/reconnecting.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import { Card } from '../../fixtures/cards';

describe('Reconnecting to a game', () => {
it('Refreshs Game from Game Menu', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.ACE_OF_CLUBS, Card.SEVEN_OF_DIAMONDS ],
Expand Down Expand Up @@ -44,7 +43,6 @@ describe('Reconnecting to a game', () => {
});

it('Persists session after refreshing the page', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP0();

cy.loadGameFixture(0, {
Expand Down Expand Up @@ -74,7 +72,6 @@ describe('Reconnecting to a game', () => {
});

it('Reconnects after refreshing the page', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP0();

cy.loadGameFixture(0, {
Expand Down Expand Up @@ -105,7 +102,6 @@ describe('Reconnecting to a game', () => {

describe('Reconnecting into Cannot Counter Dialog', () => {
it('oneOff - Reconnect into cannot counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();

cy.loadGameFixture(1, {
Expand Down Expand Up @@ -141,7 +137,6 @@ describe('Reconnecting to a game', () => {
});

it('targetedOneOff -- reconnect into cannot counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();

cy.loadGameFixture(1, {
Expand Down Expand Up @@ -177,7 +172,6 @@ describe('Reconnecting to a game', () => {
});

it('counter -- Reconnect into cannot counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP0();
cy.loadGameFixture(0, {
p0Hand: [ Card.ACE_OF_CLUBS ],
Expand Down Expand Up @@ -215,7 +209,6 @@ describe('Reconnecting to a game', () => {
});

it('sevenOneOff -- Reconnect into cannot counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
Expand Down Expand Up @@ -259,7 +252,6 @@ describe('Reconnecting to a game', () => {
});

it('sevenTargetedOneOff -- Reconnect into cannot counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
Expand Down Expand Up @@ -297,7 +289,6 @@ describe('Reconnecting to a game', () => {
});

it('Opponent reconnects while player is in cannot-counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();

cy.loadGameFixture(1, {
Expand Down Expand Up @@ -334,7 +325,6 @@ describe('Reconnecting to a game', () => {

describe('Reconnecting into Counter Dialog', () => {
it('oneOff -- Reconnect into Counter Dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.ACE_OF_CLUBS ],
Expand Down Expand Up @@ -374,7 +364,6 @@ describe('Reconnecting to a game', () => {
});

it('targetedOneOff -- reconnect into counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.TWO_OF_SPADES ],
Expand Down Expand Up @@ -417,7 +406,6 @@ describe('Reconnecting to a game', () => {
});

it('targetedOneOff -- reconnect into waiting for opponent to counter overlay', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.TWO_OF_SPADES ],
Expand Down Expand Up @@ -462,7 +450,6 @@ describe('Reconnecting to a game', () => {
});

it('counter -- Reconnect into counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP0();
cy.loadGameFixture(0, {
p0Hand: [ Card.ACE_OF_CLUBS, Card.TWO_OF_SPADES ],
Expand Down Expand Up @@ -518,7 +505,6 @@ describe('Reconnecting to a game', () => {
});

it('sevenOneOff -- Reconnect into counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
Expand Down Expand Up @@ -561,7 +547,6 @@ describe('Reconnecting to a game', () => {
});

it('sevenTargetedOneOff -- Reconnect into counter dialog', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
Expand Down Expand Up @@ -608,7 +593,6 @@ describe('Reconnecting to a game', () => {
describe('Reconnecting into One-Off resolutions', () => {
describe('Reconnecting into 3s', () => {
it('Resolve 3 after reconnect -- Player fetches card', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP0();
cy.loadGameFixture(0, {
p0Hand: [ Card.THREE_OF_CLUBS ],
Expand Down Expand Up @@ -647,7 +631,6 @@ describe('Reconnecting to a game', () => {
});

it('Resolve opponents three after reconnect', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.THREE_OF_CLUBS ],
Expand Down Expand Up @@ -687,7 +670,6 @@ describe('Reconnecting to a game', () => {
}); // End 3's reconnect

it('Resolve 4 after reconnect - Player discards', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP1();
cy.loadGameFixture(1, {
p0Hand: [ Card.FOUR_OF_CLUBS ],
Expand Down Expand Up @@ -727,7 +709,6 @@ describe('Reconnecting to a game', () => {
});

it('Resolve 7 after reconnect - Player', () => {
cy.skipOnGameStateApi();
cy.setupGameAsP0();
cy.loadGameFixture(0, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
Expand Down Expand Up @@ -815,7 +796,6 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by conceded and opponent request rematch', () => {
cy.skipOnGameStateApi();
cy.concedeOpponent();
cy.get('[data-cy=game-over-dialog]').should('be.visible');
cy.reload();
Expand All @@ -834,7 +814,6 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by conceded and player request rematch', () => {
cy.skipOnGameStateApi();
cy.concedeOpponent();
cy.get('[data-cy=game-over-dialog]').should('be.visible');
cy.reload();
Expand All @@ -849,6 +828,7 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by stalemate', () => {
cy.skipOnGameStateApi();
cy.get('#game-menu-activator').click();
cy.get('#game-menu').should('be.visible')
.get('[data-cy=stalemate-initiate]')
Expand All @@ -863,14 +843,15 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by passing', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
p0Points: [ Card.SEVEN_OF_DIAMONDS, Card.SEVEN_OF_HEARTS ],
p0FaceCards: [],
p1Hand: [],
p1Points: [],
p1FaceCards: [],
topCard: Card.TWO_OF_CLUBS,
secondCard: Card.ACE_OF_HEARTS,
deck: [],
});

Expand All @@ -891,7 +872,6 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by points', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.SEVEN_OF_CLUBS ],
p0Points: [ Card.SEVEN_OF_DIAMONDS, Card.SEVEN_OF_HEARTS ],
Expand All @@ -911,7 +891,6 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by points playing jack', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.JACK_OF_DIAMONDS ],
p0Points: [ Card.SEVEN_OF_DIAMONDS, Card.SEVEN_OF_HEARTS ],
Expand All @@ -932,7 +911,6 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by points playing king', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.KING_OF_DIAMONDS ],
p0Points: [ Card.SEVEN_OF_DIAMONDS, Card.SEVEN_OF_HEARTS ],
Expand All @@ -952,15 +930,13 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by resolving one-off', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.SIX_OF_DIAMONDS, Card.SEVEN_OF_SPADES ],
p0Points: [ Card.SEVEN_OF_DIAMONDS, Card.SEVEN_OF_HEARTS ],
p0FaceCards: [],
p1Hand: [ Card.JACK_OF_CLUBS ],
p1Points: [],
p1FaceCards: [],
deck: [],
});

cy.get('#deck').click();
Expand All @@ -979,7 +955,6 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by resolving one-off from a seven', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.SIX_OF_DIAMONDS, Card.SEVEN_OF_SPADES ],
p0Points: [ Card.SEVEN_OF_DIAMONDS, Card.SEVEN_OF_HEARTS ],
Expand Down Expand Up @@ -1009,13 +984,12 @@ describe('Reconnecting after game is over', () => {
});

it('Dialogs persist after refreshing when game is over by playing jack from a seven', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.SIX_OF_DIAMONDS, Card.SEVEN_OF_SPADES ],
p0Points: [ Card.SEVEN_OF_HEARTS, Card.SEVEN_OF_DIAMONDS ],
p0FaceCards: [],
p1Hand: [],
p1Points: [ Card.SEVEN_OF_SPADES ],
p1Points: [ Card.SEVEN_OF_CLUBS ],
p1FaceCards: [],
topCard: Card.JACK_OF_DIAMONDS,
deck: [],
Expand All @@ -1029,31 +1003,30 @@ describe('Reconnecting after game is over', () => {
.click();
cy.get('[data-move-choice=jack]').should('be.visible')
.click();
cy.get('[data-opponent-point-card=7-3]').should('be.visible')
cy.get('[data-opponent-point-card=7-0]').should('be.visible')
.click();
cy.get('[data-cy=game-over-dialog]').should('be.visible');
cy.reload();
cy.get('[data-cy=game-over-dialog]').should('be.visible');
});

it('Dialogs persist after refreshing when game is over by playing points from a seven', () => {
cy.skipOnGameStateApi();
cy.loadGameFixture(0, {
p0Hand: [ Card.SIX_OF_DIAMONDS, Card.SEVEN_OF_SPADES ],
p0Points: [ Card.SEVEN_OF_HEARTS, Card.SEVEN_OF_DIAMONDS ],
p0FaceCards: [],
p1Hand: [],
p1Points: [],
p1FaceCards: [],
topCard: Card.SEVEN_OF_SPADES,
topCard: Card.SEVEN_OF_CLUBS,
deck: [],
});

cy.get('[data-player-hand-card=7-3]').click();
cy.get('[data-move-choice=oneOff]').should('be.visible')
.click();
cy.resolveOpponent();
cy.get('[data-top-card=7-3]').click();
cy.get('[data-top-card=7-0]').click();
cy.get('[data-move-choice=points]').should('be.visible')
.click();
cy.get('[data-cy=game-over-dialog]').should('be.visible');
Expand All @@ -1062,7 +1035,6 @@ describe('Reconnecting after game is over', () => {
});

it('Brings player to the rematch game when player hits rematch, disconnects, then refreshes after opponent hit rematch and started game', () => {
cy.skipOnGameStateApi();
cy.concedeOpponent();

cy.get('[data-cy=gameover-rematch').should('not.be.disabled')
Expand Down Expand Up @@ -1115,7 +1087,6 @@ describe('Reconnecting after game is over', () => {
});

it('Brings player to the rematch game when player hits rematch, disconnects, then reconnects socket after opponent hit rematch and started game', () => {
cy.skipOnGameStateApi();
cy.concedeOpponent();

cy.get('[data-cy=gameover-rematch').should('not.be.disabled')
Expand Down

0 comments on commit 1cf66c9

Please sign in to comment.