test: remove outdated ISBN normalization tests
- Deleted isbn_and_library_test.go (507 lines) - All tests used deprecated /api/ebooks endpoint - Tests were mock-based, not real API calls - Functionality will be replaced with modern tests This is part of legacy code cleanup Phase 3. Phase 3: Test Suite Cleanup
This commit is contained in:
@@ -1,506 +0,0 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// TestISBNNormalization tests ISBN normalization with various formats
|
||||
func TestISBNNormalization(t *testing.T) {
|
||||
t.Run("ISBN-13 with hyphens should be normalized", func(t *testing.T) {
|
||||
// Test cases for ISBN-13 with various hyphen placements
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "ISBN-13 with hyphens (978-0-12345-678-9)",
|
||||
input: "978-0-12345-678-9",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-13 with single hyphen (978-0123456789)",
|
||||
input: "978-0123456789",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-13 without hyphens",
|
||||
input: "9780123456789",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-13 with spaces",
|
||||
input: "978 0123456789",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-13 with mixed hyphens and spaces",
|
||||
input: "978-0 1234-56789",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-10 with hyphens",
|
||||
input: "0-12345-678-9",
|
||||
expected: "0123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-10 without hyphens",
|
||||
input: "0123456789",
|
||||
expected: "0123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN-10 with X",
|
||||
input: "0-12345-678-X",
|
||||
expected: "012345678X",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": tc.input,
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
req.Header.Set("X-User-Id", uuid.New().String())
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Simulate successful creation with normalized ISBN
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
response := map[string]interface{}{
|
||||
"id": uuid.New().String(),
|
||||
"title": "Test Ebook",
|
||||
"isbn": tc.expected,
|
||||
}
|
||||
json.NewEncoder(w).Encode(response)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
assert.Equal(t, tc.expected, response["isbn"])
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("Empty ISBN should be handled", func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
})
|
||||
|
||||
t.Run("Invalid ISBN format should still be stored as-is", func(t *testing.T) {
|
||||
// Test that very short or obviously invalid ISBNs are still accepted
|
||||
// The database function will normalize what it can
|
||||
testCases := []struct {
|
||||
name string
|
||||
isbn string
|
||||
valid bool
|
||||
}{
|
||||
{"Too short ISBN", "123", true},
|
||||
{"Valid ISBN-13", "9780123456789", true},
|
||||
{"Valid ISBN-10", "0123456789", true},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": tc.isbn,
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if tc.valid {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
if tc.valid {
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
} else {
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestEbookLibraryRequirement tests that ebooks require an existing library
|
||||
func TestEbookLibraryRequirement(t *testing.T) {
|
||||
t.Run("Create ebook without any libraries should fail gracefully", func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": "978-0123456789",
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
req.Header.Set("X-User-Id", uuid.New().String())
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Simulate no library found scenario
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
w.Write([]byte(`{"error":"no ebook library found. Please create an ebook library first"}`))
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
assert.Contains(t, rr.Body.String(), "no ebook library found")
|
||||
})
|
||||
|
||||
t.Run("Create ebook with existing library should succeed", func(t *testing.T) {
|
||||
libraryID := uuid.New()
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": "978-0123456789",
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
req.Header.Set("X-User-Id", uuid.New().String())
|
||||
req.Header.Set("X-Library-Id", libraryID.String())
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Simulate successful creation
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
response := map[string]interface{}{
|
||||
"id": uuid.New().String(),
|
||||
"title": "Test Ebook",
|
||||
"isbn": "9780123456789",
|
||||
"library_id": libraryID.String(),
|
||||
}
|
||||
json.NewEncoder(w).Encode(response)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
assert.Equal(t, "9780123456789", response["isbn"])
|
||||
assert.Equal(t, libraryID.String(), response["library_id"])
|
||||
})
|
||||
|
||||
t.Run("Update ebook with normalized ISBN", func(t *testing.T) {
|
||||
ebookID := uuid.New()
|
||||
payload := map[string]interface{}{
|
||||
"title": "Updated Ebook",
|
||||
"isbn": "978-987654321-0",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("PUT", "/api/ebooks/"+ebookID.String(), bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusOK)
|
||||
response := map[string]interface{}{
|
||||
"id": ebookID.String(),
|
||||
"title": "Updated Ebook",
|
||||
"isbn": "9789876543210",
|
||||
}
|
||||
json.NewEncoder(w).Encode(response)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusOK, rr.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
assert.Equal(t, "9789876543210", response["isbn"])
|
||||
})
|
||||
}
|
||||
|
||||
// TestISBNEdgeCases tests edge cases for ISBN handling
|
||||
func TestISBNEdgeCases(t *testing.T) {
|
||||
t.Run("ISBN with special characters should be normalized", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
input string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "ISBN with multiple hyphens",
|
||||
input: "978-0-123-45678-9",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN with trailing hyphen",
|
||||
input: "9780123456789-",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN with leading hyphen",
|
||||
input: "-9780123456789",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
{
|
||||
name: "ISBN with multiple spaces",
|
||||
input: "978 0123456789",
|
||||
expected: "9780123456789",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": tc.input,
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
response := map[string]interface{}{
|
||||
"id": uuid.New().String(),
|
||||
"title": "Test Ebook",
|
||||
"isbn": tc.expected,
|
||||
}
|
||||
json.NewEncoder(w).Encode(response)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
assert.Equal(t, tc.expected, response["isbn"])
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("ISBN length validation", func(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
isbn string
|
||||
shouldAccept bool
|
||||
}{
|
||||
{
|
||||
name: "Empty ISBN",
|
||||
isbn: "",
|
||||
shouldAccept: true,
|
||||
},
|
||||
{
|
||||
name: "Valid ISBN-10",
|
||||
isbn: "0123456789",
|
||||
shouldAccept: true,
|
||||
},
|
||||
{
|
||||
name: "Valid ISBN-13",
|
||||
isbn: "9780123456789",
|
||||
shouldAccept: true,
|
||||
},
|
||||
{
|
||||
name: "ISBN-13 with hyphens",
|
||||
isbn: "978-0-12345-678-9",
|
||||
shouldAccept: true,
|
||||
},
|
||||
{
|
||||
name: "Maximum length (17 chars with hyphens)",
|
||||
isbn: "978-0-12345-678-9",
|
||||
shouldAccept: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": tc.isbn,
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
if tc.shouldAccept {
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
} else {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
}
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
if tc.shouldAccept {
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
} else {
|
||||
assert.Equal(t, http.StatusBadRequest, rr.Code)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// TestLibraryAutoSelection tests automatic library selection by resource type
|
||||
func TestLibraryAutoSelection(t *testing.T) {
|
||||
t.Run("Auto-select first available ebook library", func(t *testing.T) {
|
||||
libraryID := uuid.New()
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": "9780123456789",
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
req.Header.Set("X-User-Id", uuid.New().String())
|
||||
req.Header.Set("X-Library-Id", libraryID.String())
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Simulate auto-selection of first ebook library
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
response := map[string]interface{}{
|
||||
"id": uuid.New().String(),
|
||||
"title": "Test Ebook",
|
||||
"isbn": "9780123456789",
|
||||
"library_id": libraryID.String(),
|
||||
}
|
||||
json.NewEncoder(w).Encode(response)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
assert.Equal(t, libraryID.String(), response["library_id"])
|
||||
})
|
||||
|
||||
t.Run("Multiple ebook libraries - should select first", func(t *testing.T) {
|
||||
firstLibraryID := uuid.New()
|
||||
secondLibraryID := uuid.New()
|
||||
|
||||
payload := map[string]interface{}{
|
||||
"title": "Test Ebook",
|
||||
"isbn": "9780123456789",
|
||||
"file_path": "/path/to/file.epub",
|
||||
"file_size": 1024,
|
||||
"mime_type": "application/epub+zip",
|
||||
}
|
||||
jsonData, _ := json.Marshal(payload)
|
||||
|
||||
req := httptest.NewRequest("POST", "/api/ebooks", bytes.NewBuffer(jsonData))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
req.Header.Set("Authorization", "Bearer admin-token")
|
||||
req.Header.Set("X-User-Role", "admin")
|
||||
req.Header.Set("X-User-Id", uuid.New().String())
|
||||
rr := httptest.NewRecorder()
|
||||
|
||||
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
// Simulate auto-selection of first ebook library
|
||||
w.WriteHeader(http.StatusCreated)
|
||||
response := map[string]interface{}{
|
||||
"id": uuid.New().String(),
|
||||
"title": "Test Ebook",
|
||||
"isbn": "9780123456789",
|
||||
"library_id": firstLibraryID.String(),
|
||||
}
|
||||
json.NewEncoder(w).Encode(response)
|
||||
})
|
||||
|
||||
handler.ServeHTTP(rr, req)
|
||||
|
||||
assert.Equal(t, http.StatusCreated, rr.Code)
|
||||
|
||||
var response map[string]interface{}
|
||||
json.Unmarshal(rr.Body.Bytes(), &response)
|
||||
// Should select first library, not second
|
||||
assert.Equal(t, firstLibraryID.String(), response["library_id"])
|
||||
assert.NotEqual(t, secondLibraryID.String(), response["library_id"])
|
||||
})
|
||||
}
|
||||
Reference in New Issue
Block a user