added some individual scripts to test things
This commit is contained in:
parent
7ced1b9e8d
commit
f5a953763a
|
@ -1,30 +1,35 @@
|
|||
# Application Overview:
|
||||
|
||||
I want to build a back-end application using Go that provides an API for managing boxes and items stored in those boxes. The app should be hosted in a Docker container and use SQLite3 as the database. Additionally, I want a config.yaml file to manage configuration (database path, JWT secret, and image storage directory). It should also support JWT-based authentication with a default user of 'boxuser' and password 'boxuser'.
|
||||
|
||||
I would like it to log all logins, box creation/deletion, and item creation/deletion to a local log file, specified in config.yaml.
|
||||
|
||||
# Database Tables:
|
||||
## Database Tables
|
||||
|
||||
- `boxes`: A table containing an ID and a name.
|
||||
- `items`: A table containing an item name, description, the ID of the box it is stored in, and an optional path to an image of the item.
|
||||
- `users`: A table containing usernames and passwords (hashed) for authentication.
|
||||
|
||||
# API Endpoints:
|
||||
## API Endpoints
|
||||
|
||||
1. Authentication:
|
||||
- POST `/login`: Authenticates a user and returns a JWT.
|
||||
2. Boxes:
|
||||
- GET `/boxes`: Retrieves all boxes.
|
||||
- POST `/boxes`: Creates a new box.
|
||||
- DELETE :`/boxes/{id}`: Deletes a box by its ID.
|
||||
- GET `/boxes/{id}/items`: Retrieves all items in box with this id.
|
||||
|
||||
3. Items:
|
||||
- GET `/items`: Retrieves all items, optionally searchable by description.
|
||||
- POST `/items`: Adds a new item to a box.
|
||||
- GET `/items/{id}`: Retrieves an item by its ID.
|
||||
- PUT `/items/{id}`: Updates an existing item.
|
||||
- GET `/items/{id}/items`: Retrieves all items in box with this id.
|
||||
- DELETE `/items/{id}`: Deletes an item by its ID.
|
||||
- GET `/items/{id}/image`: Retrieves the image of an item.
|
||||
|
||||
# Additional Details:
|
||||
## Additional Details
|
||||
|
||||
- If the database doesn’t exist, it should be created automatically when the app starts.
|
||||
- Images should be stored locally, and their paths should be saved in the database.
|
||||
- The default user for the app should be 'boxuser' with a password of 'boxuser'.
|
||||
|
|
|
@ -0,0 +1,81 @@
|
|||
# Boxes API
|
||||
|
||||
## Overview
|
||||
|
||||
This is a back-end application written in Go that provides an API for managing boxes and items stored within those boxes. It uses SQLite3 as its database and supports JWT-based authentication.
|
||||
|
||||
## Features
|
||||
|
||||
- **Box Management:** Create, retrieve, and delete boxes.
|
||||
- **Item Management:** Add, retrieve, update, and delete items within boxes.
|
||||
- **Image Storage:** Store images associated with items.
|
||||
- **JWT Authentication:** Secure API access with JSON Web Tokens.
|
||||
- **Configuration:** Manage settings via a `config.yaml` file.
|
||||
- **Logging:** Logs user logins and box/item actions to a file.
|
||||
|
||||
## API Documentation
|
||||
|
||||
See the [API Specification](api_specification.md) for detailed information on endpoints, request/response formats, and authentication.
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. **Clone the repository:**
|
||||
|
||||
```bash
|
||||
|
||||
git clone https://github.com/your-username/boxes-api.git
|
||||
|
||||
```
|
||||
|
||||
2. Configuration:
|
||||
|
||||
- Create a config.yaml file in the project root directory.
|
||||
- Refer to the config.yaml.example file for available settings.
|
||||
|
||||
3. Database Setup:
|
||||
|
||||
- The database will be automatically created if it doesn't exist.
|
||||
- Configure the database path in the config.yaml file.
|
||||
|
||||
4. Running the Application:
|
||||
|
||||
- Build and run the Go application:
|
||||
|
||||
```bash
|
||||
|
||||
go run boxes-api .
|
||||
|
||||
```
|
||||
|
||||
5. Run the test script:
|
||||
|
||||
``` bash
|
||||
|
||||
./tests.bash
|
||||
|
||||
```
|
||||
|
||||
## Podman Support
|
||||
|
||||
Build the podman image:
|
||||
|
||||
```bash
|
||||
|
||||
podman build -t boxes-api .
|
||||
|
||||
```
|
||||
|
||||
Run the podman container:
|
||||
|
||||
```bash
|
||||
|
||||
podman run \
|
||||
-e CONFIG="/app/config/config.yaml" \
|
||||
-v /Users/stwhite/CODE/boxes/data:/app/data \
|
||||
-v /Users/stwhite/CODE/boxes/images:/app/images \
|
||||
-v /Users/stwhite/CODE/boxes/config:/app/config \
|
||||
-p 8080:8080 \
|
||||
--name boxes-api-container \
|
||||
localhost/boxes-api
|
||||
|
||||
```
|
|
@ -0,0 +1,29 @@
|
|||
#!/bin/bash
|
||||
|
||||
# API base URL
|
||||
API_BASE_URL="http://localhost:8080" # Replace with your actual API base URL
|
||||
|
||||
# Box ID
|
||||
BOX_ID=96 # Replace with the actual box ID
|
||||
|
||||
# Login credentials
|
||||
USERNAME="boxuser" # Replace with your actual username
|
||||
PASSWORD="boxuser" # Replace with your actual password
|
||||
|
||||
# Item data
|
||||
ITEM_NAME="New Item"
|
||||
ITEM_DESCRIPTION="This is a new item"
|
||||
|
||||
# Get a new JWT token
|
||||
TOKEN=$(curl -s -X POST -H "Content-Type: application/json" \
|
||||
-d "{\"username\":\"$USERNAME\", \"password\":\"$PASSWORD\"}" \
|
||||
"$API_BASE_URL/login" | jq -r '.token')
|
||||
|
||||
# Create the item data in JSON format
|
||||
ITEM_DATA=$(echo "{\"name\":\"$ITEM_NAME\",\"description\":\"$ITEM_DESCRIPTION\",\"box_id\":$BOX_ID}" | jq -r '.')
|
||||
|
||||
# Add the item to the box using the obtained token
|
||||
curl -s -X POST -H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d "$ITEM_DATA" \
|
||||
"$API_BASE_URL/items"
|
|
@ -0,0 +1,28 @@
|
|||
#!/bin/bash
|
||||
|
||||
# API base URL
|
||||
API_BASE_URL="http://localhost:8080" # Replace with your actual API base URL
|
||||
|
||||
# Box ID to delete items from
|
||||
BOX_ID=0 # Replace with the actual box ID
|
||||
|
||||
# Login credentials
|
||||
USERNAME="boxuser" # Replace with your actual username
|
||||
PASSWORD="boxuser" # Replace with your actual password
|
||||
|
||||
# Get a new JWT token
|
||||
TOKEN=$(curl -s -X POST -H "Content-Type: application/json" \
|
||||
-d "{\"username\":\"$USERNAME\", \"password\":\"$PASSWORD\"}" \
|
||||
"$API_BASE_URL/login" | jq -r '.token')
|
||||
|
||||
# Get a list of all item IDs associated with the specified box ID
|
||||
ITEM_IDS=$(curl -s -X GET -H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
"$API_BASE_URL/boxes/$BOX_ID/items" | jq -r '.[].ID')
|
||||
|
||||
# Loop through each item ID and send a DELETE request
|
||||
for ITEM_ID in $ITEM_IDS; do
|
||||
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
"$API_BASE_URL/items/$ITEM_ID"
|
||||
done
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
|
||||
# API base URL
|
||||
API_BASE_URL="http://localhost:8080"
|
||||
|
||||
# Login credentials
|
||||
USERNAME="boxuser"
|
||||
PASSWORD="boxuser"
|
||||
|
||||
# Get a new JWT token
|
||||
TOKEN=$(curl -s -X POST -H "Content-Type: application/json" \
|
||||
-d "{\"username\":\"$USERNAME\", \"password\":\"$PASSWORD\"}" \
|
||||
"$API_BASE_URL/login" | jq -r '.token')
|
||||
|
||||
# Request all items using the obtained token
|
||||
response=$(curl -s -X GET -H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
"$API_BASE_URL/items")
|
||||
|
||||
# Print the response
|
||||
echo "$response"
|
|
@ -0,0 +1,21 @@
|
|||
#!/bin/bash
|
||||
|
||||
# API base URL
|
||||
API_BASE_URL="http://localhost:8080" # Replace with your actual API base URL
|
||||
|
||||
# Box ID
|
||||
BOX_ID=0 # Replace with the actual box ID
|
||||
|
||||
# Login credentials
|
||||
USERNAME="boxuser" # Replace with your actual username
|
||||
PASSWORD="boxuser" # Replace with your actual password
|
||||
|
||||
# Get a new JWT token
|
||||
TOKEN=$(curl -s -X POST -H "Content-Type: application/json" \
|
||||
-d "{\"username\":\"$USERNAME\", \"password\":\"$PASSWORD\"}" \
|
||||
"$API_BASE_URL/login" | jq -r '.token')
|
||||
|
||||
# Request items in the specified box using the obtained token
|
||||
curl -s -X GET -H "Authorization: Bearer $TOKEN" \
|
||||
-H "Content-Type: application/json" \
|
||||
"$API_BASE_URL/boxes/$BOX_ID/items"
|
|
@ -68,6 +68,7 @@ func LoginHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
// getBoxesHandler handles the GET /boxes endpoint.
|
||||
func GetBoxesHandler(w http.ResponseWriter, r *http.Request) {
|
||||
fmt.Printf("Received %s request to %s\n", r.Method, r.URL)
|
||||
var boxes []Box
|
||||
db.Find(&boxes)
|
||||
json.NewEncoder(w).Encode(boxes)
|
||||
|
@ -129,11 +130,13 @@ func GetItemsHandler(w http.ResponseWriter, r *http.Request) {
|
|||
// createItemHandler handles the POST /items endpoint.
|
||||
func CreateItemHandler(w http.ResponseWriter, r *http.Request) {
|
||||
var item Item
|
||||
|
||||
err := json.NewDecoder(r.Body).Decode(&item)
|
||||
if err != nil {
|
||||
http.Error(w, "Invalid request body", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fmt.Println(item)
|
||||
|
||||
db.Create(&item)
|
||||
|
||||
|
@ -234,7 +237,7 @@ func GetItemHandler(w http.ResponseWriter, r *http.Request) {
|
|||
json.NewEncoder(w).Encode(item)
|
||||
}
|
||||
|
||||
// getItemsInBoxHandler handles the GET /items/{id}/items endpoint.
|
||||
// getItemsInBoxHandler handles the GET /boxes/{id}/items endpoint.
|
||||
func GetItemsInBoxHandler(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
id := vars["id"]
|
||||
|
|
2
main.go
2
main.go
|
@ -54,7 +54,7 @@ func main() {
|
|||
router.Handle("/items", AuthMiddleware(http.HandlerFunc(GetItemsHandler))).Methods("GET", "OPTIONS")
|
||||
router.Handle("/items", AuthMiddleware(http.HandlerFunc(CreateItemHandler))).Methods("POST", "OPTIONS")
|
||||
router.Handle("/items/{id}", AuthMiddleware(http.HandlerFunc(GetItemHandler))).Methods("GET", "OPTIONS")
|
||||
router.Handle("/items/{id}/items", AuthMiddleware(http.HandlerFunc(GetItemsInBoxHandler))).Methods("GET", "OPTIONS")
|
||||
router.Handle("/boxes/{id}/items", AuthMiddleware(http.HandlerFunc(GetItemsInBoxHandler))).Methods("GET", "OPTIONS")
|
||||
router.Handle("/items/{id}", AuthMiddleware(http.HandlerFunc(UpdateItemHandler))).Methods("PUT", "OPTIONS")
|
||||
router.Handle("/items/{id}", AuthMiddleware(http.HandlerFunc(DeleteItemHandler))).Methods("DELETE", "OPTIONS")
|
||||
// Add a new route for uploading an image with AuthMiddleware
|
||||
|
|
348
main_test.go
348
main_test.go
|
@ -1,348 +0,0 @@
|
|||
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)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue