349 lines
10 KiB
Go
349 lines
10 KiB
Go
package main
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/gorilla/mux"
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestMain(m *testing.M) {
|
|
// Load the configuration
|
|
var err error
|
|
config, err = LoadConfig("config.yaml")
|
|
if err != nil {
|
|
log.Fatalf("Failed to load config: %v", err)
|
|
}
|
|
|
|
// Set the environment variable for the test database
|
|
os.Setenv("TEST_DATABASE_PATH", "data/my_test_database.db")
|
|
config.DatabasePath = os.Getenv("TEST_DATABASE_PATH")
|
|
|
|
// Connect to the database using the test database path
|
|
db, err = ConnectDB(config.DatabasePath)
|
|
if err != nil {
|
|
log.Fatalf("Failed to connect to test database: %v", err)
|
|
}
|
|
|
|
fmt.Println("DB is connected")
|
|
|
|
defer db.Close()
|
|
|
|
// Truncate tables before running tests
|
|
for _, table := range []string{"boxes", "items", "users"} { // Add all your table names here
|
|
if err := db.Exec(fmt.Sprintf("DELETE FROM %s", table)).Error; err != nil {
|
|
log.Fatalf("Failed to truncate table %s: %v", table, err)
|
|
}
|
|
}
|
|
|
|
db.LogMode(true)
|
|
|
|
// Run the tests
|
|
exitCode := m.Run()
|
|
|
|
os.Exit(exitCode)
|
|
}
|
|
func TestGetBoxes(t *testing.T) {
|
|
|
|
// 1. Create a request (no need for a real token in testing)
|
|
req := httptest.NewRequest("GET", "/boxes", nil)
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
|
|
// 2. Create a recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// 3. Initialize your router
|
|
router := mux.NewRouter()
|
|
router.Handle("/boxes", http.HandlerFunc(GetBoxesHandler)).Methods("GET")
|
|
|
|
// 4. Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// 5. Assert the response
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
// Add more assertions to check response body, headers, etc.
|
|
}
|
|
|
|
func TestCreateBox(t *testing.T) {
|
|
// 1. Create a request with a new box in the body
|
|
newBox := Box{Name: "Test Box"}
|
|
reqBody, _ := json.Marshal(newBox)
|
|
req := httptest.NewRequest("POST", "/boxes", bytes.NewBuffer(reqBody))
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// 2. Create a recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// 3. Initialize your router
|
|
router := mux.NewRouter()
|
|
router.Handle("/boxes", http.HandlerFunc(CreateBoxHandler)).Methods("POST")
|
|
|
|
// 4. Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// 5. Assert the response
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
// 6. Decode the response body
|
|
var createdBox Box
|
|
json.Unmarshal(rr.Body.Bytes(), &createdBox)
|
|
|
|
// 7. Assert the created box
|
|
assert.Equal(t, newBox.Name, createdBox.Name)
|
|
}
|
|
|
|
func TestGetItem(t *testing.T) {
|
|
// Create a test item in the database
|
|
testItem := Item{Name: "Test Item", Description: "Test Description", BoxID: 1}
|
|
db.Create(&testItem)
|
|
|
|
// Create a request to get the test item
|
|
req := httptest.NewRequest("GET", fmt.Sprintf("/items/%d", testItem.ID), nil)
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
|
|
// Create a response recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// Initialize the router
|
|
router := mux.NewRouter()
|
|
router.Handle("/items/{id}", http.HandlerFunc(GetItemHandler)).Methods("GET")
|
|
|
|
// Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// Check the response status code
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
// Decode the response body
|
|
var retrievedItem Item
|
|
err := json.Unmarshal(rr.Body.Bytes(), &retrievedItem)
|
|
assert.NoError(t, err)
|
|
|
|
// Check if the retrieved item matches the test item
|
|
assert.Equal(t, testItem.ID, retrievedItem.ID)
|
|
assert.Equal(t, testItem.Name, retrievedItem.Name)
|
|
assert.Equal(t, testItem.Description, retrievedItem.Description)
|
|
assert.Equal(t, testItem.BoxID, retrievedItem.BoxID)
|
|
|
|
fmt.Println("TestGetItem")
|
|
}
|
|
|
|
func TestGetItemsInBox(t *testing.T) {
|
|
// Create test items associated with a specific box
|
|
testBox := Box{Name: "Test Box for Items"}
|
|
fmt.Println("testBox.ID (before create):", testBox.ID) // Should be 0
|
|
|
|
if err := db.Create(&testBox).Error; err != nil { // Check for errors!
|
|
t.Fatalf("Failed to create test box: %v", err)
|
|
}
|
|
|
|
// temporarily disable callbacks
|
|
db.Callback().Create().Replace("gorm:create", nil)
|
|
|
|
fmt.Println("testBox.ID (after create):", testBox.ID) // Should be a non-zero value
|
|
|
|
defaultImagePath := "default.jpg"
|
|
|
|
testItems := []Item{
|
|
{Name: "Item 1", Description: "Description 1", BoxID: testBox.ID, ImagePath: &defaultImagePath}, // Use "" for empty string
|
|
{Name: "Item 2", Description: "Description 2", BoxID: testBox.ID, ImagePath: &defaultImagePath}, // Use "" for empty string
|
|
}
|
|
|
|
fmt.Println("Right before creating test items in database")
|
|
|
|
// Marshal the testItems slice to JSON
|
|
jsonData, err := json.MarshalIndent(testItems, "", " ") // Use " " for indentation
|
|
if err != nil {
|
|
t.Fatalf("Failed to marshal testItems to JSON: %v", err)
|
|
}
|
|
|
|
// Print the formatted JSON
|
|
fmt.Println("testItems:", string(jsonData))
|
|
|
|
if err := db.Create(&testItems).Error; err != nil { // Check for errors!
|
|
t.Fatalf("Failed to create test items: %v", err)
|
|
}
|
|
fmt.Println("Right AFTER creating test items in database")
|
|
|
|
// Create a request to get items in the test box
|
|
req := httptest.NewRequest("GET", fmt.Sprintf("/items/%d/items", testBox.ID), nil)
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
|
|
// Create a response recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// Initialize the router
|
|
router := mux.NewRouter()
|
|
router.Handle("/items/{id}/items", http.HandlerFunc(GetItemsInBoxHandler)).Methods("GET")
|
|
|
|
// Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// Check the response status code
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
// Decode the response body
|
|
var retrievedItems []Item
|
|
err = json.Unmarshal(rr.Body.Bytes(), &retrievedItems)
|
|
assert.NoError(t, err)
|
|
|
|
// Check if the correct number of items is retrieved
|
|
assert.Equal(t, len(testItems), len(retrievedItems))
|
|
|
|
// You can add more assertions to check the content of retrievedItems
|
|
}
|
|
|
|
func TestUpdateItem(t *testing.T) {
|
|
// Create a test item in the database
|
|
testItem := Item{Name: "Test Item", Description: "Test Description", BoxID: 1}
|
|
db.Create(&testItem)
|
|
|
|
// Create a request to update the test item
|
|
updatedItem := Item{Name: "Updated Item", Description: "Updated Description"}
|
|
reqBody, _ := json.Marshal(updatedItem)
|
|
req := httptest.NewRequest("PUT", fmt.Sprintf("/items/%d", testItem.ID), bytes.NewBuffer(reqBody))
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// Create a response recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// Initialize the router
|
|
router := mux.NewRouter()
|
|
router.Handle("/items/{id}", http.HandlerFunc(UpdateItemHandler)).Methods("PUT")
|
|
|
|
// Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// Check the response status code
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
// Retrieve the updated item from the database
|
|
var dbItem Item
|
|
db.First(&dbItem, testItem.ID)
|
|
|
|
// Check if the item is updated in the database
|
|
assert.Equal(t, updatedItem.Name, dbItem.Name)
|
|
assert.Equal(t, updatedItem.Description, dbItem.Description)
|
|
}
|
|
|
|
func TestDeleteItem(t *testing.T) {
|
|
// Create a test item in the database
|
|
testItem := Item{Name: "Test Item", Description: "Test Description", BoxID: 1}
|
|
db.Create(&testItem)
|
|
|
|
// Create a request to delete the test item
|
|
req := httptest.NewRequest("DELETE", fmt.Sprintf("/items/%d", testItem.ID), nil)
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
|
|
// Create a response recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// Initialize the router
|
|
router := mux.NewRouter()
|
|
router.Handle("/items/{id}", http.HandlerFunc(DeleteItemHandler)).Methods("DELETE")
|
|
|
|
// Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// Check the response status code
|
|
assert.Equal(t, http.StatusNoContent, rr.Code)
|
|
|
|
// Try to retrieve the deleted item from the database
|
|
var deletedItem Item
|
|
err := db.First(&deletedItem, testItem.ID).Error
|
|
assert.Error(t, err) // Expect an error because the item should be deleted
|
|
}
|
|
|
|
func TestCreateItem(t *testing.T) {
|
|
// 1. Create a request with a new item in the body
|
|
newItem := Item{Name: "Test Item", Description: "Test Description", BoxID: 1}
|
|
reqBody, _ := json.Marshal(newItem)
|
|
req := httptest.NewRequest("POST", "/items", bytes.NewBuffer(reqBody))
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// 2. Create a recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// 3. Initialize your router
|
|
router := mux.NewRouter()
|
|
router.Handle("/items", http.HandlerFunc(CreateItemHandler)).Methods("POST")
|
|
|
|
// 4. Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// 5. Assert the response
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
|
|
// 6. Decode the response body
|
|
var createdItem Item
|
|
json.Unmarshal(rr.Body.Bytes(), &createdItem)
|
|
|
|
// 7. Assert the created item
|
|
assert.Equal(t, newItem.Name, createdItem.Name)
|
|
assert.Equal(t, newItem.Description, createdItem.Description)
|
|
assert.Equal(t, newItem.BoxID, createdItem.BoxID)
|
|
}
|
|
|
|
func TestGetItems(t *testing.T) {
|
|
// 1. Create a request (no need for a real token in testing)
|
|
req := httptest.NewRequest("GET", "/items", nil)
|
|
req = req.WithContext(context.WithValue(req.Context(), userKey, "testuser")) // Simulate authenticated user
|
|
|
|
// 2. Create a recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// 3. Initialize your router
|
|
router := mux.NewRouter()
|
|
router.Handle("/items", http.HandlerFunc(GetItemsHandler)).Methods("GET")
|
|
|
|
// 4. Serve the request
|
|
router.ServeHTTP(rr, req)
|
|
|
|
// 5. Assert the response
|
|
assert.Equal(t, http.StatusOK, rr.Code)
|
|
// Add more assertions to check response body, headers, etc.
|
|
}
|
|
|
|
func ExampleLoginHandler() {
|
|
// Create a request with login credentials
|
|
loginReq := LoginRequest{
|
|
Username: "testuser",
|
|
Password: "testpassword",
|
|
}
|
|
reqBody, _ := json.Marshal(loginReq)
|
|
|
|
req := httptest.NewRequest("POST", "/login", bytes.NewBuffer(reqBody))
|
|
req.Header.Set("Content-Type", "application/json")
|
|
|
|
// Create a response recorder
|
|
rr := httptest.NewRecorder()
|
|
|
|
// Create a test handler (usually your LoginHandler)
|
|
handler := http.HandlerFunc(LoginHandler)
|
|
|
|
// Serve the request
|
|
handler.ServeHTTP(rr, req)
|
|
|
|
// Check the response status code
|
|
if rr.Code != http.StatusOK {
|
|
fmt.Printf("Login failed with status code: %d\n", rr.Code)
|
|
} else {
|
|
// Decode the response body to get the token
|
|
var loginResp LoginResponse
|
|
json.Unmarshal(rr.Body.Bytes(), &loginResp)
|
|
|
|
fmt.Println("Login successful! Token:", loginResp.Token)
|
|
}
|
|
}
|