Skip to content

Commit

Permalink
test: add bots unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
Fog3211 committed Mar 1, 2024
1 parent bbcc852 commit ab173b1
Show file tree
Hide file tree
Showing 4 changed files with 257 additions and 14 deletions.
20 changes: 10 additions & 10 deletions handlers/bots.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func NewBotHandler(db db.Database) *botHandler {
}
}

func CreateOrEditBot(w http.ResponseWriter, r *http.Request) {
func (bt *botHandler) CreateOrEditBot(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
pubKeyFromAuth, _ := ctx.Value(auth.ContextKey).(string)

Expand All @@ -48,7 +48,7 @@ func CreateOrEditBot(w http.ResponseWriter, r *http.Request) {

now := time.Now()

extractedPubkey, err := auth.VerifyTribeUUID(bot.UUID, false)
extractedPubkey, err := bt.verifyTribeUUID(bot.UUID, false)
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusUnauthorized)
Expand All @@ -66,9 +66,9 @@ func CreateOrEditBot(w http.ResponseWriter, r *http.Request) {

bot.OwnerPubKey = extractedPubkey
bot.Updated = &now
bot.UniqueName, _ = BotUniqueNameFromName(bot.Name)
bot.UniqueName, _ = bt.BotUniqueNameFromName(bot.Name)

_, err = db.DB.CreateOrEditBot(bot)
_, err = bt.db.CreateOrEditBot(bot)
if err != nil {
fmt.Println("=> ERR createOrEditBot", err)
w.WriteHeader(http.StatusBadRequest)
Expand All @@ -79,15 +79,15 @@ func CreateOrEditBot(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(bot)
}

func GetListedBots(w http.ResponseWriter, r *http.Request) {
bots := db.DB.GetListedBots(r)
func (bt *botHandler) GetListedBots(w http.ResponseWriter, r *http.Request) {
bots := bt.db.GetListedBots(r)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(bots)
}

func GetBot(w http.ResponseWriter, r *http.Request) {
func (bt *botHandler) GetBot(w http.ResponseWriter, r *http.Request) {
uuid := chi.URLParam(r, "uuid")
bot := db.DB.GetBot(uuid)
bot := bt.db.GetBot(uuid)
w.WriteHeader(http.StatusOK)
json.NewEncoder(w).Encode(bot)
}
Expand Down Expand Up @@ -155,7 +155,7 @@ func (bt *botHandler) DeleteBot(w http.ResponseWriter, r *http.Request) {
json.NewEncoder(w).Encode(true)
}

func BotUniqueNameFromName(name string) (string, error) {
func (h *botHandler) BotUniqueNameFromName(name string) (string, error) {
pathOne := strings.ToLower(strings.Join(strings.Fields(name), ""))
reg, err := regexp.Compile("[^a-zA-Z0-9]+")
if err != nil {
Expand All @@ -168,7 +168,7 @@ func BotUniqueNameFromName(name string) (string, error) {
if n > 0 {
uniquepath = path + strconv.Itoa(n)
}
existing := db.DB.GetBotByUniqueName(uniquepath)
existing := h.db.GetBotByUniqueName(uniquepath)
if existing.UUID != "" {
n = n + 1
} else {
Expand Down
242 changes: 242 additions & 0 deletions handlers/bots_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package handlers

import (
"bytes"
"context"
"encoding/json"
"net/http"
Expand Down Expand Up @@ -245,3 +246,244 @@ func TestDeleteBot(t *testing.T) {
mockDb.AssertCalled(t, "UpdateBot", expectedUUID, map[string]interface{}{"deleted": true})
})
}
func TestCreateOrEditBot(t *testing.T) {
mockDb := dbMocks.NewDatabase(t)
bHandler := NewBotHandler(mockDb)

t.Run("should test that a 401 error is returned during bot creation if there is no bot uuid", func(t *testing.T) {
mockUUID := "valid_uuid"

requestBody := map[string]interface{}{
"UUID": mockUUID,
}

requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
t.Fatal(err)
}

req, err := http.NewRequest("POST", "/", bytes.NewBuffer(requestBodyBytes))
if err != nil {
t.Fatal(err)
}

rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBot)

handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusUnauthorized, rr.Code)
})

t.Run("should test that a 401 error is returned if the user public key can't be verified during bot creation", func(t *testing.T) {
ctx := context.WithValue(context.Background(), auth.ContextKey, "pubkey")
mockPubKey := "valid_pubkey"
mockUUID := "valid_uuid"

requestBody := map[string]interface{}{
"UUID": mockUUID,
}

requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
t.Fatal(err)
}

mockVerifyTribeUUID := func(uuid string, checkTimestamp bool) (string, error) {
return mockPubKey, nil
}

bHandler.verifyTribeUUID = mockVerifyTribeUUID

rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBot)

req, err := http.NewRequestWithContext(ctx, "POST", "/", bytes.NewBuffer(requestBodyBytes))
if err != nil {
t.Fatal(err)
}

chiCtx := chi.NewRouteContext()
chiCtx.URLParams.Add("uuid", mockUUID)

req = req.WithContext(context.WithValue(req.Context(), chi.RouteCtxKey, chiCtx))
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusUnauthorized, rr.Code)
})

t.Run("should test that a bot gets created successfully if an authenticated user sends the right data", func(t *testing.T) {
mockPubKey := "valid_pubkey"
mockUUID := "valid_uuid"
mockName := "Test Bot"
mockUniqueName := "unique test bot"

mockVerifyTribeUUID := func(uuid string, checkTimestamp bool) (string, error) {
return mockPubKey, nil
}

bHandler.verifyTribeUUID = mockVerifyTribeUUID

requestBody := map[string]interface{}{
"UUID": mockUUID,
"Name": mockName,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
t.Fatal(err)
}

mockDb.On("GetBotByUniqueName", mock.Anything).Return(db.Bot{
UniqueName: mockUniqueName,
}, nil)

mockDb.On("CreateOrEditBot", mock.Anything).Return(db.Bot{
UUID: mockUUID,
}, nil)

req, err := http.NewRequest("POST", "/", bytes.NewBuffer(requestBodyBytes))
if err != nil {
t.Fatal(err)
}

ctx := context.WithValue(req.Context(), auth.ContextKey, mockPubKey)
req = req.WithContext(ctx)

rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBot)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
var responseData map[string]interface{}
err = json.Unmarshal(rr.Body.Bytes(), &responseData)
if err != nil {
t.Fatalf("Error decoding JSON response: %s", err)
}
assert.Equal(t, mockUUID, responseData["uuid"])
})

t.Run("should test that an existing bot gets updated when passed to POST bots", func(t *testing.T) {
mockPubKey := "valid_pubkey"
mockUUID := "valid_uuid"
mockName := "Updated Test Bot"
mockUniqueName := "unique test bot"

mockVerifyTribeUUID := func(uuid string, checkTimestamp bool) (string, error) {
return mockPubKey, nil
}
bHandler.verifyTribeUUID = mockVerifyTribeUUID

requestBody := map[string]interface{}{
"UUID": mockUUID,
"Name": mockName,
}
requestBodyBytes, err := json.Marshal(requestBody)
if err != nil {
t.Fatal(err)
}

mockDb.On("GetBotByUniqueName", mock.Anything).Return(db.Bot{
UUID: mockUUID,
UniqueName: mockUniqueName,
Name: "Original Test Bot",
}, nil)

mockDb.On("CreateOrEditBot", mock.Anything).Return(db.Bot{
UUID: mockUUID,
Name: mockName,
}, nil)

req, err := http.NewRequest("POST", "/", bytes.NewBuffer(requestBodyBytes))
if err != nil {
t.Fatal(err)
}
ctx := context.WithValue(req.Context(), auth.ContextKey, mockPubKey)
req = req.WithContext(ctx)

rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.CreateOrEditBot)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
var responseData map[string]interface{}
err = json.Unmarshal(rr.Body.Bytes(), &responseData)
if err != nil {
t.Fatalf("Error decoding JSON response: %s", err)
}
assert.Equal(t, mockUUID, responseData["uuid"])
assert.Equal(t, mockName, responseData["name"])
})

}

func TestGetBot(t *testing.T) {
mockDb := dbMocks.NewDatabase(t)
bHandler := NewBotHandler(mockDb)

t.Run("should test that a bot can be fetched with its uuid", func(t *testing.T) {

mockUUID := "valid_uuid"
mockBot := db.Bot{UUID: mockUUID, Name: "Test Bot"}
mockDb.On("GetBot", mock.Anything).Return(mockBot).Once()

rr := httptest.NewRecorder()
rctx := chi.NewRouteContext()
rctx.URLParams.Add("uuid", mockUUID)
req, err := http.NewRequestWithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx), http.MethodGet, "/"+mockUUID, nil)

if err != nil {
t.Fatal(err)
}

handler := http.HandlerFunc(bHandler.GetBot)
handler.ServeHTTP(rr, req)

assert.Equal(t, http.StatusOK, rr.Code)
var returnedBot db.Bot
json.Unmarshal(rr.Body.Bytes(), &returnedBot)
assert.Equal(t, mockBot, returnedBot)
})
}

func TestGetListedBots(t *testing.T) {
mockDb := dbMocks.NewDatabase(t)
bHandler := NewBotHandler(mockDb)

t.Run("should test that all bots that are not unlisted or deleted get listed", func(t *testing.T) {
rr := httptest.NewRecorder()
handler := http.HandlerFunc(bHandler.GetListedBots)

allBots := []db.Bot{
{UUID: "uuid1", Name: "Bot1", Unlisted: false, Deleted: false},
{UUID: "uuid2", Name: "Bot2", Unlisted: false, Deleted: true},
{UUID: "uuid3", Name: "Bot3", Unlisted: true, Deleted: false},
{UUID: "uuid4", Name: "Bot4", Unlisted: true, Deleted: true},
}

expectedBots := []db.Bot{
{UUID: "uuid1", Name: "Bot1", Unlisted: false, Deleted: false},
}

rctx := chi.NewRouteContext()
req, err := http.NewRequestWithContext(context.WithValue(context.Background(), chi.RouteCtxKey, rctx), http.MethodGet, "/", nil)
assert.NoError(t, err)

mockDb.On("GetListedBots", mock.Anything).Return(allBots)
handler.ServeHTTP(rr, req)
var returnedBots []db.Bot
err = json.Unmarshal(rr.Body.Bytes(), &returnedBots)
assert.NoError(t, err)
assert.Equal(t, http.StatusOK, rr.Code)

var filteredBots []db.Bot
for _, bot := range returnedBots {
if !bot.Deleted && !bot.Unlisted {
filteredBots = append(filteredBots, bot)
}
}

assert.ElementsMatch(t, expectedBots, filteredBots)
mockDb.AssertExpectations(t)
})

}
2 changes: 1 addition & 1 deletion routes/bot.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ func BotRoutes() chi.Router {
r.Group(func(r chi.Router) {
r.Use(auth.PubKeyContext)

r.Put("/", handlers.CreateOrEditBot)
r.Delete("/{uuid}", botHandler.DeleteBot)
r.Put("/", botHandler.CreateOrEditBot)
})
return r
}
7 changes: 4 additions & 3 deletions routes/bots.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@ import (
func BotsRoutes() chi.Router {
r := chi.NewRouter()
botHandler := handlers.NewBotHandler(db.DB)

r.Group(func(r chi.Router) {
r.Post("/", handlers.CreateOrEditBot)
r.Get("/", handlers.GetListedBots)
r.Post("/", botHandler.CreateOrEditBot)
r.Get("/", botHandler.GetListedBots)
r.Get("/owner/{pubkey}", botHandler.GetBotsByOwner)
r.Get("/{uuid}", handlers.GetBot)
r.Get("/{uuid}", botHandler.GetBot)
})
return r
}

0 comments on commit ab173b1

Please sign in to comment.