add tests for config

This commit is contained in:
Cubicroot 2021-06-11 10:13:17 +02:00
parent d39e2ea9a4
commit e87f775b1d
11 changed files with 461 additions and 6 deletions

View file

@ -114,6 +114,7 @@ func (h *ApplicationHandler) CreateApplication(ctx *gin.Context) {
var createApplication model.CreateApplication
if err := ctx.Bind(&createApplication); err != nil {
log.Println(err)
return
}

View file

@ -0,0 +1,105 @@
package api
import (
"fmt"
"log"
"os"
"testing"
"github.com/gin-gonic/gin"
"github.com/pushbits/server/internal/configuration"
"github.com/pushbits/server/tests"
"github.com/pushbits/server/tests/mockups"
"github.com/stretchr/testify/assert"
)
var TestApplicationHandler *ApplicationHandler
var TestConfig *configuration.Configuration
func TestMain(m *testing.M) {
// Get main config and adapt
config, err := mockups.ReadConfig("../../config.yml", true)
if err != nil {
cleanUp()
log.Println("Can not read config: ", err)
os.Exit(1)
}
config.Database.Connection = "pushbits-test.db"
config.Database.Dialect = "sqlite3"
TestConfig = config
// Set up test environment
appHandler, err := getApplicationHandler(&TestConfig.Matrix)
if err != nil {
cleanUp()
log.Println("Can not set up application handler: ", err)
os.Exit(1)
}
TestApplicationHandler = appHandler
// Run
m.Run()
cleanUp()
}
func TestApi_RegisterApplicationWithoutUser(t *testing.T) {
assert := assert.New(t)
gin.SetMode(gin.TestMode)
reqWoUser := tests.Request{Name: "Invalid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test1", "strict_compatibility": true}`, Headers: map[string]string{"Content-Type": "application/json"}}
_, c, err := reqWoUser.GetRequest()
if err != nil {
t.Fatalf(err.Error())
}
assert.Panicsf(func() { TestApplicationHandler.CreateApplication(c) }, "CreateApplication did not panic altough user is not in context")
}
func TestApi_RgisterApplication(t *testing.T) {
assert := assert.New(t)
gin.SetMode(gin.TestMode)
testCases := make(map[int]tests.Request)
testCases[400] = tests.Request{Name: "Invalid Form Data", Method: "POST", Endpoint: "/application", Data: "k=1&v=abc"}
testCases[400] = tests.Request{Name: "Invalid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test1", "strict_compatibility": "oh yes"}`, Headers: map[string]string{"Content-Type": "application/json"}}
testCases[200] = tests.Request{Name: "Valid JSON Data", Method: "POST", Endpoint: "/application", Data: `{"name": "test2", "strict_compatibility": true}`, Headers: map[string]string{"Content-Type": "application/json"}}
user := mockups.GetAdminUser(TestConfig)
for statusCode, req := range testCases {
w, c, err := req.GetRequest()
if err != nil {
t.Fatalf(err.Error())
}
c.Set("user", user)
TestApplicationHandler.CreateApplication(c)
assert.Equalf(w.Code, statusCode, fmt.Sprintf("CreateApplication (Test case: \"%s\") should return status code %v but is %v.", req.Name, statusCode, w.Code))
}
}
// GetApplicationHandler creates and returns an application handler
func getApplicationHandler(c *configuration.Matrix) (*ApplicationHandler, error) {
db, err := mockups.GetEmptyDatabase()
if err != nil {
return nil, err
}
dispatcher, err := mockups.GetMatrixDispatcher(c.Homeserver, c.Username, c.Password)
if err != nil {
return nil, err
}
return &ApplicationHandler{
DB: db,
DP: dispatcher,
}, nil
}
func cleanUp() {
os.Remove("pushbits-test.db")
}

View file

@ -23,6 +23,13 @@ type Formatting struct {
ColoredTitle bool `default:"false"`
}
// Matrix holds credentials for a matrix account
type Matrix struct {
Homeserver string `default:"https://matrix.org"`
Username string `required:"true"`
Password string `required:"true"`
}
// Configuration holds values that can be configured by the user.
type Configuration struct {
Debug bool `default:"false"`
@ -39,11 +46,7 @@ type Configuration struct {
Password string `default:"admin"`
MatrixID string `required:"true"`
}
Matrix struct {
Homeserver string `default:"https://matrix.org"`
Username string `required:"true"`
Password string `required:"true"`
}
Matrix Matrix
Security struct {
CheckHIBP bool `default:"false"`
}

View file

@ -0,0 +1,203 @@
package configuration
import (
"fmt"
"io/ioutil"
"os"
"strings"
"testing"
"github.com/jinzhu/configor"
"github.com/stretchr/testify/assert"
"gopkg.in/yaml.v2"
)
type Pair struct {
Is interface{}
Should interface{}
}
func TestMain(m *testing.M) {
m.Run()
cleanUp()
}
func TestConfiguration_GetMinimal(t *testing.T) {
err := writeMinimalConfig()
if err != nil {
fmt.Println("Could not write minimal config: ", err)
os.Exit(1)
}
validateConfig(t)
}
func TestConfiguration_GetValid(t *testing.T) {
assert := assert.New(t)
err := writeValidConfig()
if err != nil {
fmt.Println("Could not write valid config: ", err)
os.Exit(1)
}
validateConfig(t)
config := Get()
expectedValues := make(map[string]Pair)
expectedValues["config.Admin.MatrixID"] = Pair{config.Admin.MatrixID, "000000"}
expectedValues["config.Matrix.Username"] = Pair{config.Matrix.Username, "default-username"}
expectedValues["config.Matrix.Password"] = Pair{config.Matrix.Password, "default-password"}
for name, pair := range expectedValues {
assert.Equalf(pair.Is, pair.Should, fmt.Sprintf("%s should be %v but is %v", name, pair.Should, pair.Is))
}
}
func TestConfiguration_GetEmpty(t *testing.T) {
err := writeEmptyConfig()
if err != nil {
fmt.Println("Could not write empty config: ", err)
os.Exit(1)
}
assert.Panicsf(t, func() { Get() }, "Get() did not panic altough config is empty")
}
func TestConfiguration_GetInvalid(t *testing.T) {
err := writeInvalidConfig()
if err != nil {
fmt.Println("Could not write empty config: ", err)
os.Exit(1)
}
assert.Panicsf(t, func() { Get() }, "Get() did not panic altough config is empty")
}
func TestConfiguaration_ConfigFiles(t *testing.T) {
files := configFiles()
assert.Greater(t, len(files), 0)
for _, file := range files {
assert.Truef(t, strings.HasSuffix(file, ".yml"), "%s is no yaml file", file)
}
}
// Checks if the values in the configuration are plausible
func validateConfig(t *testing.T) {
assert := assert.New(t)
assert.NotPanicsf(func() { Get() }, "Get configuration should not panic")
config := Get()
asGreater := make(map[string]Pair)
asGreater["config.Crypto.Argon2.Memory"] = Pair{config.Crypto.Argon2.Memory, uint32(0)}
asGreater["config.Crypto.Argon2.Iterations"] = Pair{config.Crypto.Argon2.Iterations, uint32(0)}
asGreater["config.Crypto.Argon2.SaltLength"] = Pair{config.Crypto.Argon2.SaltLength, uint32(0)}
asGreater["config.Crypto.Argon2.KeyLength"] = Pair{config.Crypto.Argon2.KeyLength, uint32(0)}
asGreater["config.Crypto.Argon2.Parallelism"] = Pair{config.Crypto.Argon2.Parallelism, uint8(0)}
asGreater["config.HTTP.Port"] = Pair{config.HTTP.Port, 0}
for name, pair := range asGreater {
assert.Greaterf(pair.Is, pair.Should, fmt.Sprintf("%s should be > %v but is %v", name, pair.Should, pair.Is))
}
asFalse := make(map[string]bool)
asFalse["config.Formatting.ColoredTitle"] = config.Formatting.ColoredTitle
asFalse["config.Debug"] = config.Debug
asFalse["config.Security.CheckHIBP"] = config.Security.CheckHIBP
for name, value := range asFalse {
assert.Falsef(value, fmt.Sprintf("%s should be false but is %t", name, value))
}
}
type MinimalConfiguration struct {
Admin struct {
MatrixID string
}
Matrix struct {
Username string
Password string
}
}
type InvalidConfiguration struct {
Debug int
HTTP struct {
ListenAddress bool
}
Admin struct {
Name int
}
Formatting string
}
// Writes a minimal config to config.yml
func writeMinimalConfig() error {
cleanUp()
config := MinimalConfiguration{}
config.Admin.MatrixID = "000000"
config.Matrix.Username = "default-username"
config.Matrix.Password = "default-password"
configString, err := yaml.Marshal(&config)
if err != nil {
return err
}
return ioutil.WriteFile("config.yml", configString, 0644)
}
// Writes a config with default values to config.yml
func writeValidConfig() error {
cleanUp()
// Load minimal config to get default values
writeMinimalConfig()
config := &Configuration{}
err := configor.New(&configor.Config{
Environment: "production",
ENVPrefix: "PUSHBITS",
ErrorOnUnmatchedKeys: true,
}).Load(config, "config.yml")
if err != nil {
return err
}
config.Admin.MatrixID = "000000"
config.Matrix.Username = "default-username"
config.Matrix.Password = "default-password"
configString, err := yaml.Marshal(&config)
if err != nil {
return err
}
return ioutil.WriteFile("config.yml", configString, 0644)
}
// Writes a config that is empty
func writeEmptyConfig() error {
cleanUp()
return ioutil.WriteFile("config.yml", []byte(""), 0644)
}
// Writes a config with invalid entries
func writeInvalidConfig() error {
cleanUp()
config := InvalidConfiguration{}
config.Debug = 1337
config.HTTP.ListenAddress = true
config.Admin.Name = 23
config.Formatting = "Nice"
configString, err := yaml.Marshal(&config)
if err != nil {
return err
}
return ioutil.WriteFile("config.yml", configString, 0644)
}
func cleanUp() error {
return os.Remove("config.yml")
}