DEVELOPMENT ENVIRONMENT

~liljamo/deck-builder

2d16028264d16c23fb4bf1569b81b673c3374d3d — Jonni Liljamo 1 year, 10 months ago 483b441
feat(sdbapi): endpoint for joining games
4 files changed, 95 insertions(+), 0 deletions(-)

M sdbapi/apierror/apierror.go
M sdbapi/db/user.go
A sdbapi/handlers/joingame.go
M sdbapi/main.go
M sdbapi/apierror/apierror.go => sdbapi/apierror/apierror.go +3 -0
@@ 25,4 25,7 @@ const (
	GetAllFormingFailed string = "something went wrong while fetching all forming games"
	GameStatePatchFailed string = "failed to patch game state"
	NoGamesForUser = "no games found for user"
	GameNotForming string = "game is not forming"
	CannotJoinOwnGame string = "can not join own game"
	GameFull string = "game is full"
)

M sdbapi/db/user.go => sdbapi/db/user.go +11 -0
@@ 15,6 15,17 @@ import (
	"errors"
)

// get a user with an ID
func GetUserByID(id string) (models.User, error) {
	var user models.User
	user_record := DbConn.Where("id = ?", id).First(&user)
	if user_record.Error != nil {
		return models.User{}, errors.New(apierror.UserNotFound)
	}

	return user, nil
}

// get a user with an email address
func GetUserByEmail(email string) (models.User, error) {
	var user models.User

A sdbapi/handlers/joingame.go => sdbapi/handlers/joingame.go +80 -0
@@ 0,0 1,80 @@
/*
 * This file is part of sdbapi
 * Copyright (C) 2022 Jonni Liljamo <jonni@liljamo.com>
 *
 * Licensed under GPL-3.0-only.
 * See LICENSE for licensing information.
 */

package handlers

import (
	"api/apierror"
	"api/db"
	"api/models"
	"net/http"

	"github.com/gin-gonic/gin"
)

func JoinGame(c *gin.Context) {
	id := c.Param("id")

	// fetch the game
	var game models.Game
	record := db.DbConn.Where("id = ?", id).First(&game)
	if record.Error != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": apierror.GameNotFound})
		c.Abort()
		return
	}

	// check if p2 is already filled
	if game.P2 != "" {
		c.JSON(http.StatusBadRequest, gin.H{"error": apierror.GameFull})
		c.Abort()
		return
	}

	// check if the game is forming
	if game.State != models.GAMESTATE_FORMING {
		c.JSON(http.StatusBadRequest, gin.H{"error": apierror.GameNotForming})
		c.Abort()
		return
	}

	// get p1 (game creator)
	p1, p1err := db.GetUserByID(game.P1)
	if p1err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": apierror.Placeholder})
		c.Abort()
		return
	}

	// get p2 (us)
	p2, p2err := db.GetUserByEmail(c.GetString("email"))
	if p2err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": apierror.Placeholder})
		c.Abort()
		return
	}

	// are we p1?
	if p1.ID == p2.ID {
		c.JSON(http.StatusBadRequest, gin.H{"error": apierror.CannotJoinOwnGame})
		c.Abort()
		return
	}

	// if we are not p1, set us as p2
	updatedGame := db.DbConn.Model(&game).Update("p2", p2.ID)
	if updatedGame.Error != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": apierror.Placeholder})
		c.Abort()
		return
	}

	// return a 20x code
	c.JSON(http.StatusNoContent, nil)
}


M sdbapi/main.go => sdbapi/main.go +1 -0
@@ 52,6 52,7 @@ func createRouter() *gin.Engine {
			game.POST("/create", handlers.CreateGame)
			game.PATCH("/:id/state", handlers.PatchGameState)
			game.GET("/my_games", handlers.MyGames)
			game.POST("/:id/join", handlers.JoinGame)
		}
	}
	return router