fixed image upload, patched up tests.bash
This commit is contained in:
		
							parent
							
								
									7d853c26f1
								
							
						
					
					
						commit
						94115067c4
					
				|  | @ -1,2 +1,3 @@ | ||||||
| 
 | 
 | ||||||
| data/boxes.db | data/boxes.db | ||||||
|  | images/* | ||||||
|  | @ -1,6 +1,6 @@ | ||||||
| database_path: "data/boxes.db" | database_path: "data/boxes.db" | ||||||
| test_database_path: "data/test_database.db" | test_database_path: "data/test_database.db" | ||||||
| jwt_secret: "super_secret_key" | jwt_secret: "super_secret_key" | ||||||
| image_storage_dir: "images/" | image_storage_dir: "./images/" | ||||||
| listening_port: 8080 | listening_port: 8080 | ||||||
| log_file: "boxes.log" | log_file: "boxes.log" | ||||||
							
								
								
									
										2
									
								
								db.go
								
								
								
								
							
							
						
						
									
										2
									
								
								db.go
								
								
								
								
							|  | @ -19,7 +19,7 @@ type Item struct { | ||||||
| 	Name        string `json:"name"` | 	Name        string `json:"name"` | ||||||
| 	Description string `json:"description"` | 	Description string `json:"description"` | ||||||
| 	BoxID       uint   `json:"box_id"` | 	BoxID       uint   `json:"box_id"` | ||||||
| 	ImagePath   *string `json:"image_path"` | 	ImagePath   string `json:"image_path"` | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| // Define the User model
 | // Define the User model
 | ||||||
|  |  | ||||||
							
								
								
									
										71
									
								
								handlers.go
								
								
								
								
							
							
						
						
									
										71
									
								
								handlers.go
								
								
								
								
							|  | @ -4,7 +4,9 @@ import ( | ||||||
| 	"context" | 	"context" | ||||||
| 	"encoding/json" | 	"encoding/json" | ||||||
| 	"fmt" | 	"fmt" | ||||||
|  | 	"io" | ||||||
| 	"net/http" | 	"net/http" | ||||||
|  | 	"os" | ||||||
| 	"strings" | 	"strings" | ||||||
| 	"time" | 	"time" | ||||||
| 
 | 
 | ||||||
|  | @ -149,6 +151,75 @@ func CreateItemHandler(w http.ResponseWriter, r *http.Request) { | ||||||
| 	json.NewEncoder(w).Encode(response) | 	json.NewEncoder(w).Encode(response) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | // UploadItemImageHandler handles the image upload for an item
 | ||||||
|  | func UploadItemImageHandler(w http.ResponseWriter, r *http.Request) { | ||||||
|  | 	// Extract the authenticated user from context (assuming this is how AuthMiddleware works)
 | ||||||
|  | 	user, ok := r.Context().Value(userKey).(string) | ||||||
|  | 	if !ok || user == "" { | ||||||
|  | 		http.Error(w, "Unauthorized", http.StatusUnauthorized) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Parse the form data, 10MB limit for file uploads
 | ||||||
|  | 	err := r.ParseMultipartForm(10 << 20) | ||||||
|  | 	if err != nil { | ||||||
|  | 		http.Error(w, "Unable to parse form", http.StatusBadRequest) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Get the file from the form data
 | ||||||
|  | 	file, handler, err := r.FormFile("image") | ||||||
|  | 	if err != nil { | ||||||
|  | 		http.Error(w, "Error retrieving the file", http.StatusBadRequest) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	defer file.Close() | ||||||
|  | 
 | ||||||
|  | 	// Get item ID from the URL
 | ||||||
|  | 	vars := mux.Vars(r) | ||||||
|  | 	itemID := vars["id"] | ||||||
|  | 
 | ||||||
|  | 	// Validate that the item exists (fetch from DB using itemID)
 | ||||||
|  | 	var item Item | ||||||
|  | 	if err := db.First(&item, itemID).Error; err != nil { | ||||||
|  | 		http.Error(w, "Item not found", http.StatusNotFound) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Save the uploaded file locally or to a storage service
 | ||||||
|  | 	// Ensure the directory exists
 | ||||||
|  | 	if err := os.MkdirAll(config.ImageStorageDir, 0755); err != nil { | ||||||
|  | 		http.Error(w, "Unable to create image storage directory", http.StatusInternalServerError) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	filePath := fmt.Sprintf("%s/%s", config.ImageStorageDir, handler.Filename) | ||||||
|  | 	outFile, err := os.Create(filePath) | ||||||
|  | 	if err != nil { | ||||||
|  | 		http.Error(w, "Unable to save the file", http.StatusInternalServerError) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 	defer outFile.Close() | ||||||
|  | 
 | ||||||
|  | 	// Copy the uploaded file to the destination
 | ||||||
|  | 	_, err = io.Copy(outFile, file) | ||||||
|  | 	if err != nil { | ||||||
|  | 		http.Error(w, "Unable to save the file", http.StatusInternalServerError) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Update the item record in the database with the image path
 | ||||||
|  | 	item.ImagePath = filePath | ||||||
|  | 	if err := db.Save(&item).Error; err != nil { | ||||||
|  | 		http.Error(w, "Unable to save image path in database", http.StatusInternalServerError) | ||||||
|  | 		return | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	// Return the image path in the response
 | ||||||
|  | 	w.WriteHeader(http.StatusOK) | ||||||
|  | 	json.NewEncoder(w).Encode(map[string]string{"imagePath": filePath}) | ||||||
|  | } | ||||||
|  | 
 | ||||||
| // getItemHandler handles the GET /items/{id} endpoint.
 | // getItemHandler handles the GET /items/{id} endpoint.
 | ||||||
| func GetItemHandler(w http.ResponseWriter, r *http.Request) { | func GetItemHandler(w http.ResponseWriter, r *http.Request) { | ||||||
| 	vars := mux.Vars(r) | 	vars := mux.Vars(r) | ||||||
|  |  | ||||||
							
								
								
									
										4
									
								
								main.go
								
								
								
								
							
							
						
						
									
										4
									
								
								main.go
								
								
								
								
							|  | @ -51,6 +51,10 @@ func main() { | ||||||
| 	router.Handle("/items/{id}/items", AuthMiddleware(http.HandlerFunc(GetItemsInBoxHandler))).Methods("GET", "OPTIONS") | 	router.Handle("/items/{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(UpdateItemHandler))).Methods("PUT", "OPTIONS") | ||||||
| 	router.Handle("/items/{id}", AuthMiddleware(http.HandlerFunc(DeleteItemHandler))).Methods("DELETE", "OPTIONS") | 	router.Handle("/items/{id}", AuthMiddleware(http.HandlerFunc(DeleteItemHandler))).Methods("DELETE", "OPTIONS") | ||||||
|  | 	// Add a new route for uploading an image with AuthMiddleware
 | ||||||
|  | 	router.HandleFunc("/items/{id}/upload", UploadItemImageHandler). | ||||||
|  | 		Methods("POST"). | ||||||
|  | 		Handler(AuthMiddleware(http.HandlerFunc(UploadItemImageHandler))) | ||||||
| 
 | 
 | ||||||
| 	// Apply CORS middleware
 | 	// Apply CORS middleware
 | ||||||
| 	c := cors.New(cors.Options{ | 	c := cors.New(cors.Options{ | ||||||
|  |  | ||||||
							
								
								
									
										44
									
								
								tests.bash
								
								
								
								
							
							
						
						
									
										44
									
								
								tests.bash
								
								
								
								
							|  | @ -110,6 +110,48 @@ else | ||||||
|   echo "$response" |   echo "$response" | ||||||
| fi | fi | ||||||
| 
 | 
 | ||||||
|  | # 11. Create Image and Assign to Item (Assuming an item with ID $ITEM_ID exists) | ||||||
|  | echo | ||||||
|  | echo | ||||||
|  | echo "Testing /items/$ITEM_ID/upload (POST)..." | ||||||
|  | 
 | ||||||
|  | # 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 a temporary image file | ||||||
|  | IMAGE_FILE=$(mktemp /tmp/test_image.XXXXXX) | ||||||
|  | echo "Test Image Content" > "$IMAGE_FILE" | ||||||
|  | 
 | ||||||
|  | echo "Token is $TOKEN" | ||||||
|  | 
 | ||||||
|  | # Make the request using curl to upload the image | ||||||
|  | response=$(curl -s -w "%{http_code}" -X POST \ | ||||||
|  |   -H "Authorization: Bearer $(echo "$TOKEN")" \ | ||||||
|  |   -F "image=@$IMAGE_FILE" \ | ||||||
|  |   "$API_BASE_URL/items/$ITEM_ID/upload") | ||||||
|  | 
 | ||||||
|  | echo $response  | ||||||
|  | 
 | ||||||
|  | # Separate the body and the HTTP status code | ||||||
|  | http_status=$(echo "$response" | tail -n1) | ||||||
|  | body=$(echo "$response" | sed '$d') | ||||||
|  | 
 | ||||||
|  | # Remove the temporary image file | ||||||
|  | rm "$IMAGE_FILE" | ||||||
|  | 
 | ||||||
|  | # Check if the HTTP status is 200 (OK) and the imagePath is returned | ||||||
|  | if [[ "$http_status" == "200" && $(echo "$body" | jq -r '.imagePath') != "null" ]]; then | ||||||
|  |   echo -e "\033[32m  /items/$ITEM_ID/upload (POST): PASS\033[0m" # Green PASS | ||||||
|  |   IMAGE_PATH=$(echo "$body" | jq -r '.imagePath') | ||||||
|  |   echo "Image Path: $IMAGE_PATH" | ||||||
|  | else | ||||||
|  |   echo -e "\033[31m  /items/$ITEM_ID/upload (POST): FAIL (Invalid response or no imagePath)\033[0m" # Red FAIL | ||||||
|  |   echo "Response: $response" | ||||||
|  | fi | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| # 6. Get Items | # 6. Get Items | ||||||
| echo | echo | ||||||
| echo "Testing /items (GET)..." | echo "Testing /items (GET)..." | ||||||
|  | @ -130,6 +172,8 @@ echo | ||||||
| echo "Testing /items/{id} (GET)..." | echo "Testing /items/{id} (GET)..." | ||||||
| response=$(authenticated_request "GET" "/items/$ITEM_ID" "") | response=$(authenticated_request "GET" "/items/$ITEM_ID" "") | ||||||
| 
 | 
 | ||||||
|  | echo $response | jq . | ||||||
|  | 
 | ||||||
| # Check if the request was successful AND if the response ID matches $ITEM_ID | # Check if the request was successful AND if the response ID matches $ITEM_ID | ||||||
| if [[ $? -eq 0 ]] && [[ $(echo "$response" | jq -r '.ID') == "$ITEM_ID" ]]; then | if [[ $? -eq 0 ]] && [[ $(echo "$response" | jq -r '.ID') == "$ITEM_ID" ]]; then | ||||||
|   echo -e "\033[32m  /items/{id} (GET): PASS\033[0m" # Green PASS |   echo -e "\033[32m  /items/{id} (GET): PASS\033[0m" # Green PASS | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue