Skip to content

Commit

Permalink
Modify game (#36)
Browse files Browse the repository at this point in the history
This is a replacement for #34

---------

Co-authored-by: aetn23 <mikolajpirog@gmail.com>
  • Loading branch information
Kwasow and mikolaj-pirog authored Apr 29, 2023
1 parent ae27bf9 commit ec2d685
Show file tree
Hide file tree
Showing 3 changed files with 193 additions and 0 deletions.
3 changes: 3 additions & 0 deletions src/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { isCelebrateError } from 'celebrate'
import kickPlayer from './routes/kickPlayer'
import joinGame from './routes/joinGame'
import createGame from './routes/createGame'
import modifyGame from './routes/modifyGame'
import leaveGame from './routes/leaveGame'
import { rateLimiter } from './utils/rateLimiter'

Expand Down Expand Up @@ -48,6 +49,8 @@ app.use(joinGame)

app.use(createGame)

app.use(modifyGame)

app.use(kickPlayer)

app.use(leaveGame)
Expand Down
95 changes: 95 additions & 0 deletions src/routes/modifyGame.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { getClient } from '../utils/databaseConnection'
import { rateLimiter } from '../utils/rateLimiter'
import { celebrate, Joi, Segments } from 'celebrate'
import { sendFirebaseMessage, verifyFCMToken } from '../utils/firebase'

import express, { type Router } from 'express'
const router: Router = express.Router()

router.post(
'/modifyGame',
rateLimiter,
celebrate({
[Segments.QUERY]: Joi.object().keys({
creatorToken: Joi.string()
.required()
.min(1)
.max(250)
.label('creatorToken'),
smallBlind: Joi.number().required().min(1).label('smallBlind'),
startingFunds: Joi.number().required().min(1).label('startingFunds'),
}),
}),
async (req, res) => {
if (!(await verifyFCMToken(req.query.creatorToken))) {
return res.sendStatus(400)
}

const client = getClient()
client
.connect()
.then(async () => {
// Define queries
const getGameQuery = 'SELECT game_id FROM Games WHERE game_master=$1'
const getCurrentPlayerQuery =
'SELECT current_player FROM Games WHERE game_id=$1 AND current_player IS NOT NULL'
const setNewSmallBlindStartingFunds =
'UPDATE Games SET small_blind=$1, starting_funds=$2 WHERE game_id=$3'
const getPlayersQuery = 'SELECT token FROM Players WHERE game_id=$1'

// Check if games exist
const getGameResult = await client.query(getGameQuery, [
req.query.creatorToken,
])

if (getGameResult.rowCount === 0) {
return res.sendStatus(400)
}
const gameId = getGameResult.rows[0].game_id

// Check if the game has not started yet
const getCurrentPlayerResult = await client.query(
getCurrentPlayerQuery,
[gameId]
)
if (getCurrentPlayerResult.rowCount !== 0) {
return res.sendStatus(400)
}

// Update settings
await client.query(setNewSmallBlindStartingFunds, [
req.query.smallBlind,
req.query.startingFunds,
gameId,
])

// Notify players about the changes
const getPlayersResult = await client.query(getPlayersQuery, [gameId])

const message = {
data: {
type: 'settingsUpdated',
startingFunds: req.query.startingFunds,
smallBlind: req.query.smallBlind,
},
token: '',
}

getPlayersResult.rows.forEach(async (row) => {
message.token = row.token
await sendFirebaseMessage(message)
})

return res.sendStatus(200)
})
.catch(async (err) => {
console.log(err.stack)
return res.sendStatus(500)
})
.finally(async () => {
await client.end()
})
}
)

export default router
95 changes: 95 additions & 0 deletions src/tests/modifyGame.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
import { app } from '../app'
import request from 'supertest'
import { getClient } from '../utils/databaseConnection'

test('Modify game, wrong args', async () => {
const client = getClient()
const insertGameCreator =
'INSERT INTO Players (token, nickname, turn) VALUES ($1, $2, $3)'
const deletePlayerQuery = 'DELETE FROM Players WHERE token = $1'
await client
.connect()
.then(async () => {
await request(app).post('/modifyGame').expect(400)
await request(app).post('/modifyGame?creatorToken=2137').expect(400)

await client.query(insertGameCreator, [2137, '2137', 0])

await request(app).post('/modifyGame?creatorToken=2137').expect(400)
await request(app)
.post('/modifyGame?creatorToken=2137&smallBlind=asd')
.expect(400)
await request(app)
.post('/modifyGame?creatorToken=2137&startingFunnds=dasdasd')
.expect(400)
await request(app)
.post('/modifyGame?creatorToken=2137&startingFunds=1&smallBlind=220')
.expect(400)
})
.finally(async () => {
await client.query(deletePlayerQuery, [2137])
await client.end()
})
})

test('Modify game, correct arguments', async () => {
const gameMasterToken = 'TESTMODIFY'
const gameMasterNick = 'MODIFYNICK'
const newSmallBlind = 2137
const newStartingFunds = 1337
const findGameQuery = 'SELECT game_id FROM Games WHERE game_master=$1'
const deleteGameQuery = 'DELETE FROM Games WHERE game_id=$1'
const verifyGameWasModifiedQuery =
'SELECT game_id FROM Games WHERE game_id=$1 AND small_blind=$2 AND starting_funds=$3'
const deletePlayerQuery = 'DELETE FROM Players WHERE token = $1'
let gameId

const client = getClient()
await client.connect()

await request(app)
.get(
'/createGame?creatorToken='
.concat(gameMasterToken)
.concat('&nickname=')
.concat(gameMasterNick)
)
.expect(200)

await request(app)
.post(
'/modifyGame?creatorToken='
.concat(gameMasterToken)
.concat('&smallBlind=')
.concat(newSmallBlind.toString())
.concat('&startingFunds=')
.concat(newStartingFunds.toString())
)
.expect(200)

await client
.query(findGameQuery, [gameMasterToken])
.then(async (result) => {
gameId = result.rows[0].game_id.toString()

await client
.query(verifyGameWasModifiedQuery, [
gameId,
newSmallBlind,
newStartingFunds,
])
.then(async (modified) => {
expect(modified.rowCount).toEqual(1)
})
})

.finally(async () => {
await client.query(deleteGameQuery, [gameId]).catch((err) => {
console.log(err.stack)
})
await client.query(deletePlayerQuery, [gameMasterToken]).catch((err) => {
console.log(err.stack)
})
await client.end()
})
})

0 comments on commit ec2d685

Please sign in to comment.