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:
177
utils/slug_test.go
Normal file
177
utils/slug_test.go
Normal file
@@ -0,0 +1,177 @@
|
||||
package utils
|
||||
|
||||
import "testing"
|
||||
|
||||
func TestGenerateSlug(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "simple text",
|
||||
input: "Hello World",
|
||||
expected: "hello-world",
|
||||
},
|
||||
{
|
||||
name: "text with special characters",
|
||||
input: "Book Name!@#$%",
|
||||
expected: "book-name",
|
||||
},
|
||||
{
|
||||
name: "text with numbers",
|
||||
input: "Book 123",
|
||||
expected: "book-123",
|
||||
},
|
||||
{
|
||||
name: "text with multiple spaces",
|
||||
input: "Book Name Here",
|
||||
expected: "book-name-here",
|
||||
},
|
||||
{
|
||||
name: "text with underscores",
|
||||
input: "Book_Name_Here",
|
||||
expected: "book-name-here",
|
||||
},
|
||||
{
|
||||
name: "text with mixed case",
|
||||
input: "My Awesome Book",
|
||||
expected: "my-awesome-book",
|
||||
},
|
||||
{
|
||||
name: "empty string",
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
{
|
||||
name: "only special characters",
|
||||
input: "!@#$%",
|
||||
expected: "item",
|
||||
},
|
||||
{
|
||||
name: "leading and trailing spaces",
|
||||
input: " Book Name ",
|
||||
expected: "book-name",
|
||||
},
|
||||
{
|
||||
name: "text with hyphens",
|
||||
input: "Book-Name-Here",
|
||||
expected: "book-name-here",
|
||||
},
|
||||
{
|
||||
name: "text with consecutive special chars",
|
||||
input: "Book!!!Name",
|
||||
expected: "bookname",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := GenerateSlug(tt.input)
|
||||
if result != tt.expected {
|
||||
t.Errorf("GenerateSlug(%q) = %q, want %q", tt.input, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsValidSlug(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
slug string
|
||||
expected bool
|
||||
}{
|
||||
{
|
||||
name: "valid slug",
|
||||
slug: "hello-world",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "valid slug with numbers",
|
||||
slug: "book-123",
|
||||
expected: true,
|
||||
},
|
||||
{
|
||||
name: "invalid - uppercase",
|
||||
slug: "Hello-World",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - special characters",
|
||||
slug: "hello-world!",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - leading hyphen",
|
||||
slug: "-hello-world",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - trailing hyphen",
|
||||
slug: "hello-world-",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - consecutive hyphens",
|
||||
slug: "hello--world",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "invalid - empty",
|
||||
slug: "",
|
||||
expected: false,
|
||||
},
|
||||
{
|
||||
name: "valid - single word",
|
||||
slug: "book",
|
||||
expected: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := IsValidSlug(tt.slug)
|
||||
if result != tt.expected {
|
||||
t.Errorf("IsValidSlug(%q) = %v, want %v", tt.slug, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestCleanString(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "normal string",
|
||||
input: "Hello World",
|
||||
expected: "Hello World",
|
||||
},
|
||||
{
|
||||
name: "with leading/trailing spaces",
|
||||
input: " Hello World ",
|
||||
expected: "Hello World",
|
||||
},
|
||||
{
|
||||
name: "with multiple spaces",
|
||||
input: "Hello World",
|
||||
expected: "Hello World",
|
||||
},
|
||||
{
|
||||
name: "empty string",
|
||||
input: "",
|
||||
expected: "",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
result := CleanString(tt.input)
|
||||
if result != tt.expected {
|
||||
t.Errorf("CleanString(%q) = %q, want %q", tt.input, result, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user