Skip to content

Commit

Permalink
Adding more unit tests for endpoints (#46)
Browse files Browse the repository at this point in the history
Increase the coverage a little bit by testing endpoints
  • Loading branch information
matheusgomes28 authored Mar 12, 2024
1 parent 31d7cf6 commit b9d3e53
Show file tree
Hide file tree
Showing 10 changed files with 265 additions and 117 deletions.
2 changes: 1 addition & 1 deletion admin-app/post.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func postPostHandler(database database.Database) func(*gin.Context) {
err := decoder.Decode(&add_post_request)

if err != nil {
log.Warn().Msgf("could not get post from DB: %v", err)
log.Warn().Msgf("invalid post request: %v", err)
c.JSON(http.StatusBadRequest, gin.H{
"error": "invalid request body",
"msg": err.Error(),
Expand Down
10 changes: 8 additions & 2 deletions app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func SetupRoutes(app_settings common.AppSettings, database database.Database) *g
r.MaxMultipartMemory = 1

// All cache-able endpoints
cache := makeCache(4, time.Minute*10)
cache := MakeCache(4, time.Minute*10, &TimeValidator{})
addCachableHandler(r, "GET", "/", homeHandler, &cache, app_settings, database)
addCachableHandler(r, "GET", "/contact", contactHandler, &cache, app_settings, database)
addCachableHandler(r, "GET", "/post/:id", postHandler, &cache, app_settings, database)
Expand All @@ -39,14 +39,20 @@ func addCachableHandler(e *gin.Engine, method string, endpoint string, generator
// if the endpoint is cached
cached_endpoint, err := (*cache).Get(c.Request.RequestURI)
if err == nil {
c.Data(http.StatusOK, "text/html; charset=utf-8", cached_endpoint.contents)
c.Data(http.StatusOK, "text/html; charset=utf-8", cached_endpoint.Contents)
return
}

// Before handler call (retrieve from cache)
html_buffer, err := generator(c, app_settings, db)
if err != nil {
log.Error().Msgf("could not generate html: %v", err)
// TODO : Need a proper error page
c.JSON(http.StatusInternalServerError, gin.H{
"error": "could not render HTML",
"msg": err.Error(),
})
return
}

// After handler (add to cache)
Expand Down
18 changes: 9 additions & 9 deletions app/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@ import (
const MAX_CACHE_SIZE_MB = 10

type EndpointCache struct {
name string
contents []byte
validUntil time.Time
Name string
Contents []byte
ValidUntil time.Time
}

func emptyEndpointCache() EndpointCache {
Expand All @@ -36,7 +36,7 @@ type TimeValidator struct{}

func (validator *TimeValidator) IsValid(cache *EndpointCache) bool {
// We only return the cache if it's still valid
return cache.validUntil.After(time.Now())
return cache.ValidUntil.After(time.Now())
}

type TimedCache struct {
Expand All @@ -54,9 +54,9 @@ func (cache *TimedCache) Store(name string, buffer []byte) error {
}

var cache_entry interface{} = EndpointCache{
name: name,
contents: buffer,
validUntil: time.Now().Add(cache.cacheTimeout),
Name: name,
Contents: buffer,
ValidUntil: time.Now().Add(cache.cacheTimeout),
}
cache.cacheMap.Set(name, &cache_entry)
cache.estimatedSize.Add(uint64(len(buffer)))
Expand Down Expand Up @@ -85,11 +85,11 @@ func (cache *TimedCache) Size() uint64 {
return cache.estimatedSize.Load()
}

func makeCache(n_shards int, expiry_duration time.Duration) Cache {
func MakeCache(n_shards int, expiry_duration time.Duration, validator CacheValidator) Cache {
return &TimedCache{
cacheMap: shardedmap.NewShardMap(n_shards),
cacheTimeout: expiry_duration,
estimatedSize: atomic.Uint64{},
validator: &TimeValidator{},
validator: validator,
}
}
68 changes: 0 additions & 68 deletions cmd/urchin/index_test.go

This file was deleted.

68 changes: 68 additions & 0 deletions tests/admin_app_tests/endpoint_tests/endpoint_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
package endpoint_tests

import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"

admin_app "github.com/matheusgomes28/urchin/admin-app"
"github.com/matheusgomes28/urchin/common"
"github.com/matheusgomes28/urchin/tests/mocks"
"github.com/stretchr/testify/assert"
)

type postRequest struct {
Title string `json:"title"`
Excerpt string `json:"excerpt"`
Content string `json:"content"`
}

type postResponse struct {
Id int `json:"id"`
}

var app_settings = common.AppSettings{
DatabaseAddress: "localhost",
DatabasePort: 3006,
DatabaseUser: "root",
DatabasePassword: "root",
DatabaseName: "urchin",
WebserverPort: 8080,
}

func TestIndexPing(t *testing.T) {

database_mock := mocks.DatabaseMock{}
r := admin_app.SetupRoutes(app_settings, database_mock)
w := httptest.NewRecorder()

request := postRequest{
Title: "",
Excerpt: "",
Content: "",
}
request_body, err := json.Marshal(request)
assert.Nil(t, err)

req, _ := http.NewRequest("POST", "/posts", bytes.NewReader(request_body))
req.Header.Add("content-type", "application/json")
r.ServeHTTP(w, req)

assert.Equal(t, 200, w.Code)

var response postResponse
err = json.Unmarshal(w.Body.Bytes(), &response)
assert.Nil(t, err)

assert.Equal(t, response.Id, 0)
}

// TODO : Test request without excerpt

// TODO : Test request without content

// TODO : Test request without title

// TODO : Test request that fails to be added to database
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
package common
package app_settings_tests

import (
"errors"
"os"
"testing"

"github.com/matheusgomes28/urchin/common"
"github.com/pelletier/go-toml/v2"
"github.com/stretchr/testify/assert"
)
Expand All @@ -28,7 +29,7 @@ func writeToml(contents []byte) (s string, err error) {
}

func TestCorrectToml(t *testing.T) {
expected := AppSettings{
expected := common.AppSettings{
DatabaseAddress: "test_database_address",
DatabaseUser: "test_database_user",
DatabasePassword: "test_database_password",
Expand All @@ -42,7 +43,7 @@ func TestCorrectToml(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

actual, err := ReadConfigToml(filepath)
actual, err := common.ReadConfigToml(filepath)
assert.Nil(t, err)
assert.Equal(t, actual, expected)
}
Expand All @@ -69,7 +70,7 @@ func TestMissingDatabaseAddress(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -95,7 +96,7 @@ func TestMissingDatabaseUser(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -120,7 +121,7 @@ func TestMissingDatabasePassword(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -145,7 +146,7 @@ func TestMissingDatabaseName(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -170,7 +171,7 @@ func TestMissingWebserverPort(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -195,7 +196,7 @@ func TestMissingDatabasePort(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -222,7 +223,7 @@ func TestWrongDatabasePortValueType(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}

Expand All @@ -249,6 +250,6 @@ func TestWrongwebserverPortValueType(t *testing.T) {
filepath, err := writeToml(bytes)
assert.Nil(t, err)

_, err = ReadConfigToml(filepath)
_, err = common.ReadConfigToml(filepath)
assert.NotNil(t, err)
}
Loading

0 comments on commit b9d3e53

Please sign in to comment.