CreateUser test
This commit is contained in:
parent
37e09d6532
commit
6d80638cf8
@ -60,7 +60,14 @@ clean:
|
||||
rm -rf .run-data/*
|
||||
git clean -fdx
|
||||
go clean
|
||||
go clean -testcache
|
||||
|
||||
fmt:
|
||||
go fmt ./...
|
||||
swag fmt
|
||||
|
||||
.PHONY: test
|
||||
test:
|
||||
go test ./test/...
|
||||
|
||||
|
||||
|
@ -38,19 +38,20 @@ func NewAPIHandler(app *logic.Application) APIHandler {
|
||||
//
|
||||
// @Param post_body body handler.CreateUser.body false " "
|
||||
//
|
||||
// @Success 200 {object} handler.sendMessageInternal.response
|
||||
// @Success 200 {object} models.UserJSONWithClients
|
||||
// @Failure 400 {object} ginresp.apiError
|
||||
// @Failure 500 {object} ginresp.apiError
|
||||
//
|
||||
// @Router /api/users/ [POST]
|
||||
// @Router /api/users [POST]
|
||||
func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
|
||||
type body struct {
|
||||
FCMToken string `json:"fcm_token" binding:"required"`
|
||||
FCMToken string `json:"fcm_token"`
|
||||
ProToken *string `json:"pro_token"`
|
||||
Username *string `json:"username"`
|
||||
AgentModel string `json:"agent_model" binding:"required"`
|
||||
AgentVersion string `json:"agent_version" binding:"required"`
|
||||
ClientType string `json:"client_type" binding:"required"`
|
||||
AgentModel string `json:"agent_model"`
|
||||
AgentVersion string `json:"agent_version"`
|
||||
ClientType string `json:"client_type"`
|
||||
NoClient bool `json:"no_client"`
|
||||
}
|
||||
|
||||
var b body
|
||||
@ -61,12 +62,23 @@ func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
|
||||
defer ctx.Cancel()
|
||||
|
||||
var clientType models.ClientType
|
||||
if !b.NoClient {
|
||||
if b.FCMToken == "" {
|
||||
return ginresp.APIError(g, 400, apierr.INVALID_CLIENTTYPE, "Missing FCMToken", nil)
|
||||
}
|
||||
if b.AgentVersion == "" {
|
||||
return ginresp.APIError(g, 400, apierr.INVALID_CLIENTTYPE, "Missing AgentVersion", nil)
|
||||
}
|
||||
if b.ClientType == "" {
|
||||
return ginresp.APIError(g, 400, apierr.INVALID_CLIENTTYPE, "Missing ClientType", nil)
|
||||
}
|
||||
if b.ClientType == string(models.ClientTypeAndroid) {
|
||||
clientType = models.ClientTypeAndroid
|
||||
} else if b.ClientType == string(models.ClientTypeIOS) {
|
||||
clientType = models.ClientTypeIOS
|
||||
} else {
|
||||
return ginresp.APIError(g, 400, apierr.INVALID_CLIENTTYPE, "Invalid ClientType", nil)
|
||||
return ginresp.APIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "Invalid ClientType", nil)
|
||||
}
|
||||
}
|
||||
|
||||
if b.ProToken != nil {
|
||||
@ -106,12 +118,17 @@ func (h APIHandler) CreateUser(g *gin.Context) ginresp.HTTPResponse {
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to create user in db", err)
|
||||
}
|
||||
|
||||
_, err = h.database.CreateClient(ctx, userobj.UserID, clientType, b.FCMToken, b.AgentModel, b.AgentVersion)
|
||||
if b.NoClient {
|
||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, userobj.JSONWithClients(make([]models.Client, 0))))
|
||||
} else {
|
||||
client, err := h.database.CreateClient(ctx, userobj.UserID, clientType, b.FCMToken, b.AgentModel, b.AgentVersion)
|
||||
if err != nil {
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to create user in db", err)
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to create client in db", err)
|
||||
}
|
||||
|
||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, userobj.JSONWithClients([]models.Client{client})))
|
||||
}
|
||||
|
||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, userobj.JSON()))
|
||||
}
|
||||
|
||||
// GetUser swaggerdoc
|
||||
@ -409,7 +426,7 @@ func (h APIHandler) AddClient(g *gin.Context) ginresp.HTTPResponse {
|
||||
|
||||
client, err := h.database.CreateClient(ctx, u.UserID, clientType, b.FCMToken, b.AgentModel, b.AgentVersion)
|
||||
if err != nil {
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to create user in db", err)
|
||||
return ginresp.APIError(g, 500, apierr.DATABASE_ERROR, "Failed to create client in db", err)
|
||||
}
|
||||
|
||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, client.JSON()))
|
||||
|
@ -5,9 +5,11 @@ import (
|
||||
"blackforestbytes.com/simplecloudnotifier/common/ginresp"
|
||||
"blackforestbytes.com/simplecloudnotifier/logic"
|
||||
"bytes"
|
||||
"context"
|
||||
"errors"
|
||||
"github.com/gin-gonic/gin"
|
||||
sqlite3 "github.com/mattn/go-sqlite3"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/timeext"
|
||||
"net/http"
|
||||
"time"
|
||||
@ -74,7 +76,7 @@ func (h CommonHandler) Ping(g *gin.Context) ginresp.HTTPResponse {
|
||||
// @Success 200 {object} handler.DatabaseTest.response
|
||||
// @Failure 500 {object} ginresp.apiError
|
||||
//
|
||||
// @Router /api/db-test [get]
|
||||
// @Router /api/db-test [post]
|
||||
func (h CommonHandler) DatabaseTest(g *gin.Context) ginresp.HTTPResponse {
|
||||
type response struct {
|
||||
Success bool `json:"success"`
|
||||
@ -113,6 +115,9 @@ func (h CommonHandler) Health(g *gin.Context) ginresp.HTTPResponse {
|
||||
Status string `json:"status"`
|
||||
}
|
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
|
||||
defer cancel()
|
||||
|
||||
_, libVersionNumber, _ := sqlite3.Version()
|
||||
|
||||
if libVersionNumber < 3039000 {
|
||||
@ -124,6 +129,28 @@ func (h CommonHandler) Health(g *gin.Context) ginresp.HTTPResponse {
|
||||
return ginresp.InternalError(err)
|
||||
}
|
||||
|
||||
uuidKey, _ := langext.NewHexUUID()
|
||||
uuidWrite, _ := langext.NewHexUUID()
|
||||
|
||||
err = h.app.Database.WriteMetaString(ctx, uuidKey, uuidWrite)
|
||||
if err != nil {
|
||||
return ginresp.InternalError(err)
|
||||
}
|
||||
|
||||
uuidRead, err := h.app.Database.ReadMetaString(ctx, uuidKey)
|
||||
if err != nil {
|
||||
return ginresp.InternalError(err)
|
||||
}
|
||||
|
||||
if uuidRead == nil || uuidWrite != *uuidRead {
|
||||
return ginresp.InternalError(errors.New("writing into DB was not consistent"))
|
||||
}
|
||||
|
||||
err = h.app.Database.DeleteMeta(ctx, uuidKey)
|
||||
if err != nil {
|
||||
return ginresp.InternalError(err)
|
||||
}
|
||||
|
||||
return ginresp.JSON(http.StatusOK, response{Status: "ok"})
|
||||
}
|
||||
|
||||
|
@ -118,7 +118,7 @@ func (h CompatHandler) Register(g *gin.Context) ginresp.HTTPResponse {
|
||||
|
||||
_, err = h.database.CreateClient(ctx, user.UserID, models.ClientTypeAndroid, *data.FCMToken, "compat", "compat")
|
||||
if err != nil {
|
||||
return ginresp.CompatAPIError(0, "Failed to create user in db")
|
||||
return ginresp.CompatAPIError(0, "Failed to create client in db")
|
||||
}
|
||||
|
||||
return ctx.FinishSuccess(ginresp.JSON(http.StatusOK, response{
|
||||
|
@ -35,6 +35,11 @@ func (db *Database) Migrate(ctx context.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
err = db.WriteMetaInt(ctx, "schema", 3)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
} else if currschema == 1 {
|
||||
@ -49,34 +54,6 @@ func (db *Database) Migrate(ctx context.Context) error {
|
||||
|
||||
}
|
||||
|
||||
func (db *Database) ReadSchema(ctx context.Context) (int, error) {
|
||||
|
||||
r1, err := db.db.QueryContext(ctx, "SELECT name FROM sqlite_master WHERE type='table' AND name='meta'")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !r1.Next() {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
r2, err := db.db.QueryContext(ctx, "SELECT value_int FROM meta WHERE meta_key='schema'")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !r2.Next() {
|
||||
return 0, errors.New("no schema entry in meta table")
|
||||
}
|
||||
|
||||
var dbschema int
|
||||
err = r2.Scan(&dbschema)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return dbschema, nil
|
||||
}
|
||||
|
||||
func (db *Database) Ping() error {
|
||||
return db.db.Ping()
|
||||
}
|
||||
|
159
server/db/meta.go
Normal file
159
server/db/meta.go
Normal file
@ -0,0 +1,159 @@
|
||||
package db
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
)
|
||||
|
||||
func (db *Database) ReadSchema(ctx context.Context) (int, error) {
|
||||
|
||||
r1, err := db.db.QueryContext(ctx, "SELECT name FROM sqlite_master WHERE type='table' AND name='meta'")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if !r1.Next() {
|
||||
return 0, nil
|
||||
}
|
||||
|
||||
r2, err := db.db.QueryContext(ctx, "SELECT value_int FROM meta WHERE meta_key='schema'")
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if !r2.Next() {
|
||||
return 0, errors.New("no schema entry in meta table")
|
||||
}
|
||||
|
||||
var dbschema int
|
||||
err = r2.Scan(&dbschema)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return dbschema, nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaString(ctx context.Context, key string, value string) error {
|
||||
_, err := db.db.ExecContext(ctx, "INSERT INTO meta (meta_key, value_txt) VALUES (?, ?) ON CONFLICT(meta_key) DO UPDATE SET value_txt = ?",
|
||||
key,
|
||||
value,
|
||||
value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaInt(ctx context.Context, key string, value int64) error {
|
||||
_, err := db.db.ExecContext(ctx, "INSERT INTO meta (meta_key, value_int) VALUES (?, ?) ON CONFLICT(meta_key) DO UPDATE SET value_int = ?",
|
||||
key,
|
||||
value,
|
||||
value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaReal(ctx context.Context, key string, value float64) error {
|
||||
_, err := db.db.ExecContext(ctx, "INSERT INTO meta (meta_key, value_real) VALUES (?, ?) ON CONFLICT(meta_key) DO UPDATE SET value_real = ?",
|
||||
key,
|
||||
value,
|
||||
value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) WriteMetaBlob(ctx context.Context, key string, value []byte) error {
|
||||
_, err := db.db.ExecContext(ctx, "INSERT INTO meta (meta_key, value_blob) VALUES (?, ?) ON CONFLICT(meta_key) DO UPDATE SET value_blob = ?",
|
||||
key,
|
||||
value,
|
||||
value)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaString(ctx context.Context, key string) (*string, error) {
|
||||
r2, err := db.db.QueryContext(ctx, "SELECT value_txt FROM meta WHERE meta_key=?", key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !r2.Next() {
|
||||
return nil, errors.New("no matching entry in meta table")
|
||||
}
|
||||
|
||||
var value string
|
||||
err = r2.Scan(&value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaInt(ctx context.Context, key string) (*int64, error) {
|
||||
r2, err := db.db.QueryContext(ctx, "SELECT value_int FROM meta WHERE meta_key=?", key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !r2.Next() {
|
||||
return nil, errors.New("no matching entry in meta table")
|
||||
}
|
||||
|
||||
var value int64
|
||||
err = r2.Scan(&value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaReal(ctx context.Context, key string) (*float64, error) {
|
||||
r2, err := db.db.QueryContext(ctx, "SELECT value_real FROM meta WHERE meta_key=?", key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !r2.Next() {
|
||||
return nil, errors.New("no matching entry in meta table")
|
||||
}
|
||||
|
||||
var value float64
|
||||
err = r2.Scan(&value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) ReadMetaBlob(ctx context.Context, key string) (*[]byte, error) {
|
||||
r2, err := db.db.QueryContext(ctx, "SELECT value_blob FROM meta WHERE meta_key=?", key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if !r2.Next() {
|
||||
return nil, errors.New("no matching entry in meta table")
|
||||
}
|
||||
|
||||
var value []byte
|
||||
err = r2.Scan(&value)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return langext.Ptr(value), nil
|
||||
}
|
||||
|
||||
func (db *Database) DeleteMeta(ctx context.Context, key string) error {
|
||||
_, err := db.db.ExecContext(ctx, "DELETE FROM meta WHERE meta_key = ?", key)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
@ -125,4 +125,6 @@ CREATE TABLE `meta`
|
||||
|
||||
PRIMARY KEY (meta_key)
|
||||
);
|
||||
|
||||
|
||||
INSERT INTO meta (meta_key, value_int) VALUES ('schema', 3)
|
@ -167,7 +167,7 @@ func (app *Application) StartRequest(g *gin.Context, uri any, query any, body an
|
||||
}
|
||||
}
|
||||
|
||||
if body != nil && g.Request.Header.Get("Content-Type") == "application/javascript" {
|
||||
if body != nil && g.Request.Header.Get("Content-Type") == "application/json" {
|
||||
if err := g.ShouldBindJSON(body); err != nil {
|
||||
return nil, langext.Ptr(ginresp.APIError(g, 400, apierr.BINDFAIL_BODY_PARAM, "Failed to read body", err))
|
||||
}
|
||||
|
@ -42,6 +42,13 @@ func (u User) JSON() UserJSON {
|
||||
}
|
||||
}
|
||||
|
||||
func (u User) JSONWithClients(clients []Client) UserJSONWithClients {
|
||||
return UserJSONWithClients{
|
||||
UserJSON: u.JSON(),
|
||||
Clients: langext.ArrMap(clients, func(v Client) ClientJSON { return v.JSON() }),
|
||||
}
|
||||
}
|
||||
|
||||
func (u User) MaxContentLength() int {
|
||||
if u.IsPro {
|
||||
return 16384
|
||||
@ -99,6 +106,11 @@ type UserJSON struct {
|
||||
DefaultChannel string `json:"default_channel"`
|
||||
}
|
||||
|
||||
type UserJSONWithClients struct {
|
||||
UserJSON
|
||||
Clients []ClientJSON `json:"clients"`
|
||||
}
|
||||
|
||||
type UserDB struct {
|
||||
UserID UserID `db:"user_id"`
|
||||
Username *string `db:"username"`
|
||||
|
@ -1034,7 +1034,7 @@
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"schema": {
|
||||
"$ref": "#/definitions/handler.sendMessageInternal.response"
|
||||
"$ref": "#/definitions/models.UserJSONWithClients"
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
@ -2945,6 +2945,56 @@
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
},
|
||||
"models.UserJSONWithClients": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"admin_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"clients": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"$ref": "#/definitions/models.ClientJSON"
|
||||
}
|
||||
},
|
||||
"default_channel": {
|
||||
"type": "string"
|
||||
},
|
||||
"is_pro": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"messages_sent": {
|
||||
"type": "integer"
|
||||
},
|
||||
"quota_used": {
|
||||
"type": "integer"
|
||||
},
|
||||
"quota_used_day": {
|
||||
"type": "string"
|
||||
},
|
||||
"read_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"send_key": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp_created": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp_last_read": {
|
||||
"type": "string"
|
||||
},
|
||||
"timestamp_last_sent": {
|
||||
"type": "string"
|
||||
},
|
||||
"user_id": {
|
||||
"type": "integer"
|
||||
},
|
||||
"username": {
|
||||
"type": "string"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"tags": [
|
||||
|
@ -442,6 +442,39 @@ definitions:
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
models.UserJSONWithClients:
|
||||
properties:
|
||||
admin_key:
|
||||
type: string
|
||||
clients:
|
||||
items:
|
||||
$ref: '#/definitions/models.ClientJSON'
|
||||
type: array
|
||||
default_channel:
|
||||
type: string
|
||||
is_pro:
|
||||
type: boolean
|
||||
messages_sent:
|
||||
type: integer
|
||||
quota_used:
|
||||
type: integer
|
||||
quota_used_day:
|
||||
type: string
|
||||
read_key:
|
||||
type: string
|
||||
send_key:
|
||||
type: string
|
||||
timestamp_created:
|
||||
type: string
|
||||
timestamp_last_read:
|
||||
type: string
|
||||
timestamp_last_sent:
|
||||
type: string
|
||||
user_id:
|
||||
type: integer
|
||||
username:
|
||||
type: string
|
||||
type: object
|
||||
host: scn.blackforestbytes.com
|
||||
info:
|
||||
contact: {}
|
||||
@ -1142,7 +1175,7 @@ paths:
|
||||
"200":
|
||||
description: OK
|
||||
schema:
|
||||
$ref: '#/definitions/handler.sendMessageInternal.response'
|
||||
$ref: '#/definitions/models.UserJSONWithClients'
|
||||
"400":
|
||||
description: Bad Request
|
||||
schema:
|
||||
|
@ -10,26 +10,65 @@ import (
|
||||
"blackforestbytes.com/simplecloudnotifier/push"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/rs/zerolog"
|
||||
"github.com/rs/zerolog/log"
|
||||
"gogs.mikescher.com/BlackForestBytes/goext/langext"
|
||||
"io"
|
||||
"net/http"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func NewSimpleWebserver(t *testing.T) *logic.Application {
|
||||
type Void = struct{}
|
||||
|
||||
uuid, err := langext.NewHexUUID()
|
||||
func NewSimpleWebserver() (*logic.Application, func()) {
|
||||
cw := zerolog.ConsoleWriter{
|
||||
Out: os.Stdout,
|
||||
TimeFormat: "2006-01-02 15:04:05 Z07:00",
|
||||
}
|
||||
|
||||
zerolog.TimeFieldFormat = zerolog.TimeFormatUnix
|
||||
multi := zerolog.MultiLevelWriter(cw)
|
||||
logger := zerolog.New(multi).With().
|
||||
Timestamp().
|
||||
Caller().
|
||||
Logger()
|
||||
|
||||
log.Logger = logger
|
||||
|
||||
gin.SetMode(gin.TestMode)
|
||||
zerolog.SetGlobalLevel(zerolog.DebugLevel)
|
||||
|
||||
uuid1, _ := langext.NewHexUUID()
|
||||
uuid2, _ := langext.NewHexUUID()
|
||||
dbdir := filepath.Join(os.TempDir(), uuid1)
|
||||
dbfile := filepath.Join(dbdir, uuid2+".sqlite3")
|
||||
|
||||
err := os.MkdirAll(dbdir, os.ModePerm)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
dbfile := filepath.Join(os.TempDir(), uuid+"sqlite3")
|
||||
defer func() {
|
||||
_ = os.Remove(dbfile)
|
||||
}()
|
||||
f, err := os.Create(dbfile)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
err = f.Close()
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
err = os.Chmod(dbfile, 0777)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
//dbfile := "/home/mike/Code/private/SimpleCloudNotifier/server/.run-data/db_test.sqlite3"
|
||||
|
||||
fmt.Println("DatabaseFile: " + dbfile)
|
||||
|
||||
conf := scn.Config{
|
||||
Namespace: "test",
|
||||
@ -64,39 +103,94 @@ func NewSimpleWebserver(t *testing.T) *logic.Application {
|
||||
|
||||
router.Init(ginengine)
|
||||
|
||||
return app
|
||||
return app, func() { app.Stop(); _ = os.Remove(dbfile) }
|
||||
}
|
||||
|
||||
func requestGet[T any](t *testing.T, baseURL string, prefix string) T {
|
||||
func requestGet[TResult any](baseURL string, prefix string) TResult {
|
||||
return requestAny[TResult]("", "GET", baseURL, prefix, nil)
|
||||
}
|
||||
|
||||
func requestAuthGet[TResult any](akey string, baseURL string, prefix string) TResult {
|
||||
return requestAny[TResult](akey, "GET", baseURL, prefix, nil)
|
||||
}
|
||||
|
||||
func requestPost[TResult any](baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult]("", "POST", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestAuthPost[TResult any](akey string, baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult](akey, "POST", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestPut[TResult any](baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult]("", "PUT", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestAuthPUT[TResult any](akey string, baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult](akey, "PUT", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestPatch[TResult any](baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult]("", "PATCH", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestAuthPatch[TResult any](akey string, baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult](akey, "PATCH", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestDelete[TResult any](baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult]("", "DELETE", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestAuthDelete[TResult any](akey string, baseURL string, prefix string, body any) TResult {
|
||||
return requestAny[TResult](akey, "DELETE", baseURL, prefix, body)
|
||||
}
|
||||
|
||||
func requestAny[TResult any](akey string, method string, baseURL string, prefix string, body any) TResult {
|
||||
client := http.Client{}
|
||||
|
||||
req, err := http.NewRequest("GET", baseURL+prefix, bytes.NewReader([]byte{}))
|
||||
bytesbody := make([]byte, 0)
|
||||
if body != nil {
|
||||
bjson, err := json.Marshal(body)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return *new(T)
|
||||
panic(err)
|
||||
}
|
||||
bytesbody = bjson
|
||||
}
|
||||
|
||||
req, err := http.NewRequest(method, baseURL+prefix, bytes.NewReader(bytesbody))
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if body != nil {
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
}
|
||||
|
||||
if akey != "" {
|
||||
req.Header.Set("Authorization", "SCN "+akey)
|
||||
}
|
||||
|
||||
resp, err := client.Do(req)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return *new(T)
|
||||
panic(err)
|
||||
}
|
||||
defer func() { _ = resp.Body.Close() }()
|
||||
|
||||
if resp.StatusCode != 200 {
|
||||
t.Error("Statuscode != 200")
|
||||
}
|
||||
|
||||
respBodyBin, err := io.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return *new(T)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
var data T
|
||||
if resp.StatusCode != 200 {
|
||||
fmt.Println("Request: " + method + " :: " + baseURL + prefix)
|
||||
fmt.Println(string(respBodyBin))
|
||||
panic("Statuscode != 200")
|
||||
}
|
||||
|
||||
var data TResult
|
||||
if err := json.Unmarshal(respBodyBin, &data); err != nil {
|
||||
t.Error(err)
|
||||
return *new(T)
|
||||
panic(err)
|
||||
}
|
||||
|
||||
return data
|
||||
|
29
server/test/user_test.go
Normal file
29
server/test/user_test.go
Normal file
@ -0,0 +1,29 @@
|
||||
package test
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
func TestCreateUserNoClient(t *testing.T) {
|
||||
ws, stop := NewSimpleWebserver()
|
||||
defer stop()
|
||||
go func() { ws.Run() }()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
res := requestPost[gin.H](baseUrl, "/api/users", gin.H{
|
||||
"no_client": true,
|
||||
})
|
||||
|
||||
uid := fmt.Sprintf("%v", res["user_id"])
|
||||
admintok := res["admin_key"].(string)
|
||||
|
||||
fmt.Printf("uid := %s\n", uid)
|
||||
fmt.Printf("admin_key := %s\n", admintok)
|
||||
|
||||
requestAuthGet[Void](admintok, baseUrl, "/api/users/"+uid)
|
||||
}
|
@ -6,20 +6,45 @@ import (
|
||||
)
|
||||
|
||||
func TestWebserver(t *testing.T) {
|
||||
ws := NewSimpleWebserver(t)
|
||||
defer ws.Stop()
|
||||
ws, stop := NewSimpleWebserver()
|
||||
defer stop()
|
||||
go func() { ws.Run() }()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
}
|
||||
|
||||
func TestPing(t *testing.T) {
|
||||
ws := NewSimpleWebserver(t)
|
||||
defer ws.Stop()
|
||||
ws, stop := NewSimpleWebserver()
|
||||
defer stop()
|
||||
go func() { ws.Run() }()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
_ = requestGet[struct{}](t, baseUrl, "/api/ping")
|
||||
|
||||
_ = requestGet[Void](baseUrl, "/api/ping")
|
||||
_ = requestPut[Void](baseUrl, "/api/ping", nil)
|
||||
_ = requestPost[Void](baseUrl, "/api/ping", nil)
|
||||
_ = requestPatch[Void](baseUrl, "/api/ping", nil)
|
||||
_ = requestDelete[Void](baseUrl, "/api/ping", nil)
|
||||
}
|
||||
|
||||
func TestMongo(t *testing.T) {
|
||||
ws, stop := NewSimpleWebserver()
|
||||
defer stop()
|
||||
go func() { ws.Run() }()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
_ = requestPost[Void](baseUrl, "/api/db-test", nil)
|
||||
}
|
||||
|
||||
func TestHealth(t *testing.T) {
|
||||
ws, stop := NewSimpleWebserver()
|
||||
defer stop()
|
||||
go func() { ws.Run() }()
|
||||
time.Sleep(100 * time.Millisecond)
|
||||
|
||||
baseUrl := "http://127.0.0.1:" + ws.Port
|
||||
|
||||
_ = requestGet[Void](baseUrl, "/api/health")
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user