From be27edda8898b583f774f39873fd3abb5495b46c Mon Sep 17 00:00:00 2001 From: arnaucube Date: Fri, 14 Jun 2019 20:00:11 +0200 Subject: [PATCH] add some User functions, move api tests from js to python --- constants/constants.go | 33 +++++++ models/planet.go | 19 +++- models/solarsystem.go | 9 +- models/user.go | 143 ++++++++++++++++++++++++++++--- models/user_test.go | 17 ++++ services/gamesrv/gamesrv.go | 14 +-- services/gamesrv/gamesrv_test.go | 21 +++++ services/usersrv/usersrv.go | 40 +++++---- test/.gitignore | 1 - test/package-lock.json | 56 ------------ test/package.json | 22 ----- test/test.js | 29 ------- test/test.py | 42 +++++++++ 13 files changed, 289 insertions(+), 157 deletions(-) create mode 100644 constants/constants.go create mode 100644 models/user_test.go create mode 100644 services/gamesrv/gamesrv_test.go delete mode 100644 test/.gitignore delete mode 100644 test/package-lock.json delete mode 100644 test/package.json delete mode 100644 test/test.js create mode 100644 test/test.py diff --git a/constants/constants.go b/constants/constants.go new file mode 100644 index 0000000..ef934f6 --- /dev/null +++ b/constants/constants.go @@ -0,0 +1,33 @@ +package constants + +// game constants + +const GALAXYSIZE = 50 +const SOLARSYSTEMSIZE = 15 + +// MetalMineLevels contains the constants of productivity for each level, sorted from 0 to X levels +var MetalMineLevels = []int64{ + 0, + 1, + 5, + 10, + // TODO this will be same strategy with all the buildings and research +} +var CrystalMineLevels = []int64{ + 0, + 1, + 5, + 10, +} +var DeuteriumMineLevels = []int64{ + 0, + 1, + 5, + 10, +} +var EnergyMineLevels = []int64{ + 0, + 1, + 5, + 10, +} diff --git a/models/planet.go b/models/planet.go index 2f604d8..1d3afcf 100644 --- a/models/planet.go +++ b/models/planet.go @@ -2,9 +2,20 @@ package models import "gopkg.in/mgo.v2/bson" +type BuildingsList struct { + MetalMine int64 + CrystalMine int64 + DeuteriumMine int64 + EnergyMine int64 + FusionReactor int64 + RoboticsFactory int64 + Shipyard int64 + RessearchLab int64 +} type Planet struct { - Id bson.ObjectId `json:"id", bson:"_id, omitempty"` - Size int64 // fields/slots - Name string - OwnerId bson.ObjectId + Id bson.ObjectId `json:"id" bson:"_id,omitempty"` + Size int64 // fields/slots + Name string + OwnerId bson.ObjectId + Buildings BuildingsList } diff --git a/models/solarsystem.go b/models/solarsystem.go index 3577bb4..7b7821c 100644 --- a/models/solarsystem.go +++ b/models/solarsystem.go @@ -2,11 +2,8 @@ package models import "gopkg.in/mgo.v2/bson" -const GALAXYSIZE = 50 -const SOLARSYSTEMSIZE = 15 - type SolarSystem struct { - Id bson.ObjectId `json:"id", bson:"_id, omitempty"` - Position int64 // position of the solar system in the galaxy, the maximum position is GALAXYSIZE-1 - Planets []bson.ObjectId // array with ids of the planets, if empty is equal to "" + Id bson.ObjectId `json:"id" bson:"_id,omitempty"` + Position int64 // position of the solar system in the galaxy, the maximum position is GALAXYSIZE-1 + Planets []string // array with ids of the planets, if empty is equal to "" } diff --git a/models/user.go b/models/user.go index bc2bb5c..a130ee4 100644 --- a/models/user.go +++ b/models/user.go @@ -1,21 +1,138 @@ package models -import "gopkg.in/mgo.v2/bson" +import ( + "fmt" + "time" -type Resource struct { - Value int64 - Max int64 + "github.com/arnaucube/gogame/database" + "gopkg.in/mgo.v2/bson" +) + +type Resources struct { + Metal int64 + Crystal int64 + Deuterium int64 + Energy int64 +} + +// UserDb is the data in DB +type UserDb struct { + Id bson.ObjectId `json:"id" bson:"_id,omitempty"` + Name string + Password string + Email string + LastUpdated time.Time + Resources Resources + Planets []bson.ObjectId } +// User is the data in memory, after getting it from DB type User struct { - Id bson.ObjectId `json:"id" bson:"_id,omitempty"` - Name string - Password string - Email string - Resources struct { - Metal Resource - Crystal Resource - Deuterium Resource - Energy Resource + Id bson.ObjectId `json:"id" bson:"_id,omitempty"` + Name string + LastUpdated time.Time + db *database.Db + Resources Resources +} + +func NewUser(db *database.Db, name, password, email string) (*User, error) { + newUser := UserDb{ + Id: bson.NewObjectId(), + Name: name, + Password: password, + Email: email, + LastUpdated: time.Now(), + } + err := db.Users.Insert(newUser) + if err != nil { + return nil, err } + user := UserDbToUser(db, newUser) + return user, nil +} + +func UserDbToUser(db *database.Db, u UserDb) *User { + return &User{ + Id: u.Id, + Name: u.Name, + LastUpdated: u.LastUpdated, + db: db, + Resources: u.Resources, + } +} + +func (u *User) StoreInDb() error { + userDb := UserDb{ + Id: u.Id, + Name: u.Name, + LastUpdated: u.LastUpdated, + Resources: u.Resources, + } + err := u.db.Users.Update(bson.M{"_id": u.Id}, userDb) + return err + +} + +func (u *User) GetFromDb() error { + var userDb UserDb + err := u.db.Users.Find(bson.M{"_id": u.Id}).One(&userDb) + if err != nil { + return err + } + u = UserDbToUser(u.db, userDb) + return nil +} + +func (u *User) GetPlanets() ([]Planet, error) { + var planets []Planet + err := u.db.Users.Find(bson.M{"OwnerId": u.Id}).All(&planets) + if err != nil { + return planets, err + } + return planets, nil +} + +// GetResources updates the values of resources and returns the value +// Resource types: metal, crystal, deuterium, energy +func (u *User) GetResources() (*User, error) { + // get current values + err := u.GetFromDb() + if err != nil { + return nil, err + } + // get u.LastUpdated + fmt.Println(u.LastUpdated) + // calculate Delta time = currentTime - u.LastUpdated + delta := time.Since(u.LastUpdated) + + // get planets + planets, err := u.GetPlanets() + if err != nil { + return nil, err + } + + // get Resource-Plant level in each planet + var metalGrowth, crystalGrowth, deuteriumGrowth, energyGrowth int64 + for _, planet := range planets { + // calculate growth = ResourcePlant.Level for each planet + // TODO find correct formulas + metalGrowth = metalGrowth + (planet.Buildings.MetalMine * int64(delta)) + crystalGrowth = crystalGrowth + (planet.Buildings.CrystalMine * int64(delta)) + deuteriumGrowth = deuteriumGrowth + (planet.Buildings.DeuteriumMine * int64(delta)) + energyGrowth = energyGrowth + (planet.Buildings.EnergyMine * int64(delta)) + } + // calculate newAmount = oldAmount + (growth & DeltaTime) + u.Resources.Metal = u.Resources.Metal + metalGrowth + u.Resources.Crystal = u.Resources.Crystal + crystalGrowth + u.Resources.Deuterium = u.Resources.Deuterium + deuteriumGrowth + u.Resources.Energy = u.Resources.Energy + energyGrowth + + // store new amount to user db + err = u.StoreInDb() + if err != nil { + return nil, err + } + + // return user + return u, nil } diff --git a/models/user_test.go b/models/user_test.go new file mode 100644 index 0000000..acc6b05 --- /dev/null +++ b/models/user_test.go @@ -0,0 +1,17 @@ +package models + +import ( + "testing" + + "github.com/arnaucube/gogame/database" + "github.com/stretchr/testify/assert" +) + +func TestCreateUser(t *testing.T) { + db, err := database.New("127.0.0.1:27017", "gogametests") + assert.Nil(t, err) + + user, err := NewUser(db, "user00", "password00", "user00@email.com") + assert.Nil(t, err) + assert.Equal(t, user.Name, "user00") +} diff --git a/services/gamesrv/gamesrv.go b/services/gamesrv/gamesrv.go index a41237b..03e6f65 100644 --- a/services/gamesrv/gamesrv.go +++ b/services/gamesrv/gamesrv.go @@ -3,6 +3,7 @@ package gamesrv import ( "fmt" + "github.com/arnaucube/gogame/constants" "github.com/arnaucube/gogame/database" "github.com/arnaucube/gogame/models" "github.com/arnaucube/gogame/utils" @@ -41,7 +42,7 @@ func (srv Service) CreatePlanet(userId bson.ObjectId) (*models.SolarSystem, *mod // now put the planet in a solar system // get random solar system - systemPosition := utils.RandInRange(0, models.GALAXYSIZE) + systemPosition := utils.RandInRange(0, constants.GALAXYSIZE) solarSystem, err := srv.PutPlanetInSolarSystem(systemPosition, planet) // TODO if error is returned because there is no empty slots for planets in the solar system in systemPosition, get another systemPosition and try again @@ -54,9 +55,9 @@ func (srv Service) PutPlanetInSolarSystem(position int64, planet *models.Planet) if err != nil { // solar system non existing yet // create a solarsystem with empty planets - var emptyPlanets []bson.ObjectId - for i := 0; i < models.SOLARSYSTEMSIZE; i++ { - emptyPlanets = append(emptyPlanets, "") + var emptyPlanets []string + for i := 0; i < constants.SOLARSYSTEMSIZE; i++ { + emptyPlanets = append(emptyPlanets, "empty") } newSolarSystem := models.SolarSystem{ Position: position, @@ -71,16 +72,15 @@ func (srv Service) PutPlanetInSolarSystem(position int64, planet *models.Planet) return &solarSystem, err } // get free slots in solarSystem - posInSolarSystem := utils.RandInRange(0, models.SOLARSYSTEMSIZE) + posInSolarSystem := utils.RandInRange(0, constants.SOLARSYSTEMSIZE) if solarSystem.Planets[posInSolarSystem] != "" { // not empty slot, take another one TODO // if there are no empty slots, return error fmt.Println("not empty slot") } // store planet in solar system - solarSystem.Planets[posInSolarSystem] = planet.Id + solarSystem.Planets[posInSolarSystem] = planet.Id.String() err = srv.db.SolarSystems.Update(bson.M{"position": position}, solarSystem) return &solarSystem, err - } diff --git a/services/gamesrv/gamesrv_test.go b/services/gamesrv/gamesrv_test.go new file mode 100644 index 0000000..ff1774a --- /dev/null +++ b/services/gamesrv/gamesrv_test.go @@ -0,0 +1,21 @@ +package gamesrv + +import ( + "fmt" + "testing" + + "github.com/arnaucube/gogame/database" + "github.com/stretchr/testify/assert" + "gopkg.in/mgo.v2/bson" +) + +func TestCreatePlanet(t *testing.T) { + db, err := database.New("127.0.0.1:27017", "gogametests") + assert.Nil(t, err) + srv := New(db) + + solarSystem, planet, err := srv.CreatePlanet(bson.ObjectIdHex("5d029a6ff18ba24f406168fe")) + assert.Nil(t, err) + fmt.Println(solarSystem) + fmt.Println(planet) +} diff --git a/services/usersrv/usersrv.go b/services/usersrv/usersrv.go index 2f0180b..dbcf28d 100644 --- a/services/usersrv/usersrv.go +++ b/services/usersrv/usersrv.go @@ -31,8 +31,8 @@ func checkPasswordHash(password, hash string) bool { } func (srv Service) Register(name, password, email string) (*models.User, error) { - var user models.User - err := srv.db.Users.Find(bson.M{"email": email}).One(&user) + var userDb models.User + err := srv.db.Users.Find(bson.M{"email": email}).One(&userDb) if err == nil { return nil, errors.New("user already exist") } @@ -41,32 +41,22 @@ func (srv Service) Register(name, password, email string) (*models.User, error) if err != nil { return nil, err } - newUser := models.User{ - Name: name, - Password: hashedPassword, - Email: email, - } - err = srv.db.Users.Insert(newUser) - if err != nil { - return nil, err - } - err = srv.db.Users.Find(bson.M{"email": email}).One(&user) - user.Password = "" - return &user, err + user, err := models.NewUser(srv.db, name, hashedPassword, email) + return user, err } var signingKey = []byte("TODO") // TODO func (srv Service) Login(email, password string) (*string, *models.User, error) { - var user models.User - err := srv.db.Users.Find(bson.M{"email": email}).One(&user) + var userDb models.UserDb + err := srv.db.Users.Find(bson.M{"email": email}).One(&userDb) if err != nil { return nil, nil, errors.New("user not exist") } - if !checkPasswordHash(password, user.Password) { + if !checkPasswordHash(password, userDb.Password) { return nil, nil, errors.New("error with password") } - user.Password = "" + user := models.UserDbToUser(srv.db, userDb) // create jwt token := jwt.New(jwt.SigningMethodHS256) @@ -80,5 +70,17 @@ func (srv Service) Login(email, password string) (*string, *models.User, error) return nil, nil, errors.New("error creating token") } - return &tokenString, &user, err + return &tokenString, user, err } + +// func (srv Service) GetUser(id bson.ObjectId) (*models.User, error) { +// // update user stats +// user := getUserFromDB +// user.GetStats() +// +// } +// +// func (srv Service) GetUser(id bson.ObjectId) (*models.User, error) { +// // update user stats +// +// } diff --git a/test/.gitignore b/test/.gitignore deleted file mode 100644 index 3c3629e..0000000 --- a/test/.gitignore +++ /dev/null @@ -1 +0,0 @@ -node_modules diff --git a/test/package-lock.json b/test/package-lock.json deleted file mode 100644 index 453f404..0000000 --- a/test/package-lock.json +++ /dev/null @@ -1,56 +0,0 @@ -{ - "name": "gogame-test", - "version": "0.0.1", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "axios": { - "version": "0.19.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.0.tgz", - "integrity": "sha512-1uvKqKQta3KBxIz14F2v06AEHZ/dIoeKfbTRkK1E5oqjDnuEerLmYTgJB5AiQZHJcljpg1TuRzdjDR06qNk0DQ==", - "requires": { - "follow-redirects": "1.5.10", - "is-buffer": "^2.0.2" - } - }, - "debug": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", - "requires": { - "ms": "2.0.0" - } - }, - "follow-redirects": { - "version": "1.5.10", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz", - "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==", - "requires": { - "debug": "=3.1.0" - } - }, - "is-buffer": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-2.0.3.tgz", - "integrity": "sha512-U15Q7MXTuZlrbymiz95PJpZxu8IlipAp4dtS3wOdgPXx3mqBnslrWU14kxfHB+Py/+2PVKSr37dMAgM2A4uArw==" - }, - "ms": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", - "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" - }, - "nan": { - "version": "2.14.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", - "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==" - }, - "sleep": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/sleep/-/sleep-6.1.0.tgz", - "integrity": "sha512-Z1x4JjJxsru75Tqn8F4tnOFeEu3HjtITTsumYUiuz54sGKdISgLCek9AUlXlVVrkhltRFhNUsJDJE76SFHTDIQ==", - "requires": { - "nan": "^2.13.2" - } - } - } -} diff --git a/test/package.json b/test/package.json deleted file mode 100644 index b031c85..0000000 --- a/test/package.json +++ /dev/null @@ -1,22 +0,0 @@ -{ - "name": "gogame-test", - "version": "0.0.1", - "description": "", - "main": "test.js", - "scripts": { - "test": "echo \"Error: no test specified\" && exit 1" - }, - "repository": { - "type": "git", - "url": "git+https://github.com/arnaucube/gogame.git" - }, - "author": "", - "license": "ISC", - "bugs": { - "url": "https://github.com/arnaucube/gogame/issues" - }, - "homepage": "https://github.com/arnaucube/gogame#readme", - "dependencies": { - "axios": "^0.19.0" - } -} diff --git a/test/test.js b/test/test.js deleted file mode 100644 index a2d8068..0000000 --- a/test/test.js +++ /dev/null @@ -1,29 +0,0 @@ -const axios = require('axios'); - -const url = 'http://127.0.0.1:5000'; - -// let newUser = { -// name: 'user00', -// password: 'user00password', -// email: 'user00@email.com' -// }; -// axios.post(url + '/register', newUser) -// .then(function (res) { -// console.log(res.data); -// }) -// .catch(function (error) { -// console.error(error.response.data); -// }); - - -let user = { - email: 'user00@email.com', - password: 'user00password' -}; -axios.post(url + '/login', user) - .then(function (res) { - console.log(res.data); - }) - .catch(function (error) { - console.error(error.response.data); - }); diff --git a/test/test.py b/test/test.py new file mode 100644 index 0000000..fc9a073 --- /dev/null +++ b/test/test.py @@ -0,0 +1,42 @@ +#!/usr/bin/env python3 +"""Test endpoints for gogame +""" + +import json +import requests +import provoj +import time + +import subprocess +subprocess.check_call(["mongo", "gogame", "--eval", "'db.dropDatabase()'"]) + +time.sleep(1) + +URL = "http://127.0.0.1:5000" + +t = provoj.NewTest("gogame") + +registerData = { + "name": "user00", + "password": "user00password", + "email": "user00@email.com", +} +r = requests.post(URL + "/register", json=registerData) +t.rStatus("post /register", r) +jsonR = r.json() +print(jsonR) + +time.sleep(1) + +loginData = { + "email": "user00@email.com", + "password": "user00password", +} +r = requests.post(URL + "/login", json=loginData) +t.rStatus("post /login", r) +jsonR = r.json() +print(jsonR) + + +t.printScores() +