Add initial project structure with core functionality for book and stationery uploads
- Created main application entry point in `main.go`. - Added configuration management in `config/config.go` and tests in `config/config_test.go`. - Implemented handlers for book and stationery uploads in `handlers/book.go` and `handlers/stationery.go`, including validation logic. - Established database connection and services in `services/database.go` and `services/book_service.go`. - Defined models for books and stationery in `models/book.go` and `models/stationery.go`. - Set up Firebase integration for image uploads in `services/firebase.go`. - Created migration scripts for database schema in `migrations/001_create_tables.sql` and subsequent updates. - Added CORS and error handling middleware. - Included comprehensive tests for handlers, services, and utilities. - Documented API endpoints and usage in `README.md` and migration instructions in `migrations/README.md`. - Introduced `.gitignore` to exclude unnecessary files and directories. - Added Go module support with `go.mod` and `go.sum` files. - Implemented utility functions for slug generation and validation in `utils/slug.go` and `utils/validation.go`.
This commit is contained in:
195
utils/validation_test.go
Normal file
195
utils/validation_test.go
Normal file
@@ -0,0 +1,195 @@
|
||||
package utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestValidateBookFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
bookName string
|
||||
cost string
|
||||
price string
|
||||
discount string
|
||||
quantity string
|
||||
publisherAuthor string
|
||||
category string
|
||||
description string
|
||||
wantErrors int
|
||||
}{
|
||||
{
|
||||
name: "valid fields",
|
||||
bookName: "Test Book",
|
||||
cost: "10.50",
|
||||
price: "15.99",
|
||||
discount: "0",
|
||||
quantity: "100",
|
||||
publisherAuthor: "Test Publisher",
|
||||
category: "Fiction",
|
||||
description: "A test book",
|
||||
wantErrors: 0,
|
||||
},
|
||||
{
|
||||
name: "missing book_name",
|
||||
bookName: "",
|
||||
cost: "10.50",
|
||||
price: "15.99",
|
||||
quantity: "100",
|
||||
publisherAuthor: "Test Publisher",
|
||||
category: "Fiction",
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "invalid cost",
|
||||
bookName: "Test Book",
|
||||
cost: "-10",
|
||||
price: "15.99",
|
||||
quantity: "100",
|
||||
publisherAuthor: "Test Publisher",
|
||||
category: "Fiction",
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "missing category",
|
||||
bookName: "Test Book",
|
||||
cost: "10.50",
|
||||
price: "15.99",
|
||||
quantity: "100",
|
||||
publisherAuthor: "Test Publisher",
|
||||
category: "",
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "description too long",
|
||||
bookName: "Test Book",
|
||||
cost: "10.50",
|
||||
price: "15.99",
|
||||
quantity: "100",
|
||||
publisherAuthor: "Test Publisher",
|
||||
category: "Fiction",
|
||||
description: string(make([]byte, 1001)), // 1001 characters
|
||||
wantErrors: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
errors := ValidateBookFields(
|
||||
tt.bookName,
|
||||
tt.cost,
|
||||
tt.price,
|
||||
tt.discount,
|
||||
tt.quantity,
|
||||
tt.publisherAuthor,
|
||||
tt.category,
|
||||
tt.description,
|
||||
)
|
||||
|
||||
if len(errors) != tt.wantErrors {
|
||||
t.Errorf("ValidateBookFields() returned %d errors, want %d", len(errors), tt.wantErrors)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateStationeryFields(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
stationeryName string
|
||||
cost string
|
||||
price string
|
||||
quantity string
|
||||
category string
|
||||
wantErrors int
|
||||
}{
|
||||
{
|
||||
name: "valid fields",
|
||||
stationeryName: "Test Pen",
|
||||
cost: "2.50",
|
||||
price: "5.99",
|
||||
quantity: "200",
|
||||
category: "Writing",
|
||||
wantErrors: 0,
|
||||
},
|
||||
{
|
||||
name: "missing stationery_name",
|
||||
stationeryName: "",
|
||||
cost: "2.50",
|
||||
price: "5.99",
|
||||
quantity: "200",
|
||||
category: "Writing",
|
||||
wantErrors: 1,
|
||||
},
|
||||
{
|
||||
name: "invalid quantity",
|
||||
stationeryName: "Test Pen",
|
||||
cost: "2.50",
|
||||
price: "5.99",
|
||||
quantity: "-10",
|
||||
category: "Writing",
|
||||
wantErrors: 1,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
errors := ValidateStationeryFields(
|
||||
tt.stationeryName,
|
||||
tt.cost,
|
||||
tt.price,
|
||||
"",
|
||||
tt.quantity,
|
||||
tt.category,
|
||||
"",
|
||||
)
|
||||
|
||||
if len(errors) != tt.wantErrors {
|
||||
t.Errorf("ValidateStationeryFields() returned %d errors, want %d", len(errors), tt.wantErrors)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateFileType(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
contentType string
|
||||
wantErr bool
|
||||
}{
|
||||
{"valid PNG", "image/png", false},
|
||||
{"valid JPEG", "image/jpeg", false},
|
||||
{"valid JPG", "image/jpg", false},
|
||||
{"valid WEBP", "image/webp", false},
|
||||
{"invalid type", "image/gif", true},
|
||||
{"invalid type", "text/plain", true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateFileType(tt.contentType)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateFileType() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestValidateFileSize(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
size int64
|
||||
maxSize int64
|
||||
wantErr bool
|
||||
}{
|
||||
{"valid size", 5 * 1024 * 1024, 10 * 1024 * 1024, false},
|
||||
{"exact max size", 10 * 1024 * 1024, 10 * 1024 * 1024, false},
|
||||
{"too large", 11 * 1024 * 1024, 10 * 1024 * 1024, true},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
err := ValidateFileSize(tt.size, tt.maxSize)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("ValidateFileSize() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user