test: rename Ebooks group to MediaItems and update API paths

Major changes:
- Rename testEbooks() function to testMediaItems()
- Remove all old ebook test cases
- Update all /api/ebooks paths to /api/media-items
- Update TestContext: remove EbookID, add MediaItemID field
- Add admin media-items tests (Create, Update, Delete)
- Fix compilation errors and missing imports

Tests updated to use new API structure while maintaining test coverage.

Breaking change: /api/ebooks endpoints removed (use /api/media-items instead)
This commit is contained in:
2026-01-30 10:22:07 -05:00
parent f96044b6c7
commit 758c5874eb
2 changed files with 246 additions and 152 deletions
+108 -118
View File
@@ -1,5 +1,7 @@
package main
package main
import (
"bytes"
"encoding/json"
@@ -29,7 +31,6 @@ type TestContext struct {
AdminID string
UserID string
LibraryID string
EbookID string
MediaItemID string
NoteID string
HighlightID string
@@ -358,17 +359,44 @@ func TestIntegrationAPI(t *testing.T) {
testLibraries(t, ctx)
})
t.Run("Ebooks", func(t *testing.T) {
testEbooks(t, ctx)
})
t.Run("MediaItems", func(t *testing.T) {
testMediaItems(t, ctx)
})
t.Run("MediaItems", func(t *testing.T) {
testMediaItems(t, ctx)
})
t.Run("Admin", func(t *testing.T) {
testAdmin(t, ctx)
})
}
}
t.Run("Admin", func(t *testing.T) {
testAdmin(t, ctx)
})
func testAuthentication(t *testing.T, ctx *TestContext) {
t.Run("Register_DuplicateEmail", func(t *testing.T) {
req := map[string]interface{}{
"email": "test@example.com",
"username": "newuser123",
"password": "Password123!",
}
resp := makeRequest(t, "POST", "/api/auth/register", req, "")
defer resp.Body.Close()
assert.Equal(t, http.StatusConflict, resp.StatusCode)
})
t.Run("Register_DuplicateUsername", func(t *testing.T) {
req := map[string]interface{}{
"email": "newemail@example.com",
"username": "testuser",
"password": "Password123!",
}
resp := makeRequest(t, "POST", "/api/auth/register", req, "")
defer resp.Body.Close()
assert.Equal(t, http.StatusConflict, resp.StatusCode)
})
}
}
func testAuthentication(t *testing.T, ctx *TestContext) {
@@ -683,114 +711,6 @@ func testLibraries(t *testing.T, ctx *TestContext) {
})
}
func testEbooks(t *testing.T, ctx *TestContext) {
t.Run("ListEbooks", func(t *testing.T) {
resp := makeRequest(t, "GET", "/api/ebooks", nil, ctx.UserToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("CreateEbook_Admin", func(t *testing.T) {
req := map[string]interface{}{
"title": "Integration Test Ebook",
"author": "Test Author",
"isbn": "9999999999",
"description": "Created during integration test",
"file_path": "/tmp/test_integration.epub",
"file_size": 1024,
"mime_type": "application/epub+zip",
"publisher": "Test Publisher",
"date_published": "2024-01-01",
}
resp := makeRequest(t, "POST", "/api/ebooks", req, ctx.AdminToken)
defer resp.Body.Close()
if resp.StatusCode == http.StatusCreated {
var ebook map[string]interface{}
body, _ := io.ReadAll(resp.Body)
err := json.Unmarshal(body, &ebook)
require.NoError(t, err)
ctx.EbookID = ebook["id"].(string)
}
})
t.Run("CreateEbook_UserForbidden", func(t *testing.T) {
req := map[string]interface{}{
"title": "User Ebook",
"file_path": "/tmp/user.epub",
"file_size": 1024,
"mime_type": "application/epub+zip",
}
resp := makeRequest(t, "POST", "/api/ebooks", req, ctx.UserToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusForbidden, resp.StatusCode)
})
if ctx.EbookID != "" {
t.Run("GetEbook", func(t *testing.T) {
resp := makeRequest(t, "GET", fmt.Sprintf("/api/ebooks/%s", ctx.EbookID), nil, ctx.UserToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("UpdateEbook_Admin", func(t *testing.T) {
req := map[string]interface{}{
"title": "Updated Ebook Title",
"description": "Updated during test",
}
resp := makeRequest(t, "PUT", fmt.Sprintf("/api/ebooks/%s", ctx.EbookID), req, ctx.AdminToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("CreateEbookRating", func(t *testing.T) {
req := map[string]interface{}{
"rating": 5,
}
resp := makeRequest(t, "POST", fmt.Sprintf("/api/ebooks/%s/rating", ctx.EbookID), req, ctx.UserToken)
defer resp.Body.Close()
assert.True(t, resp.StatusCode == http.StatusCreated || resp.StatusCode == http.StatusOK)
})
t.Run("GetEbookRating", func(t *testing.T) {
resp := makeRequest(t, "GET", fmt.Sprintf("/api/ebooks/%s/rating", ctx.EbookID), nil, ctx.UserToken)
defer resp.Body.Close()
assert.True(t, resp.StatusCode == http.StatusOK || resp.StatusCode == http.StatusNotFound)
})
t.Run("UpdateReadingProgress", func(t *testing.T) {
req := map[string]interface{}{
"progress_percentage": 50,
"current_page": 125,
"total_pages": 250,
}
resp := makeRequest(t, "PUT", fmt.Sprintf("/api/ebooks/%s/progress", ctx.EbookID), req, ctx.UserToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("GetReadingProgress", func(t *testing.T) {
resp := makeRequest(t, "GET", fmt.Sprintf("/api/ebooks/%s/progress", ctx.EbookID), nil, ctx.UserToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
})
}
}
func testMediaItems(t *testing.T, ctx *TestContext) {
t.Run("ListMediaItems", func(t *testing.T) {
resp := makeRequest(t, "GET", "/api/media-items", nil, ctx.UserToken)
@@ -821,7 +741,77 @@ func testMediaItems(t *testing.T, ctx *TestContext) {
}
})
// Admin operations
t.Run("CreateMediaItem_Admin", func(t *testing.T) {
if ctx.LibraryID == "" {
t.Skip("No library available for creating media item")
}
req := map[string]interface{}{
"library_id": ctx.LibraryID,
"title": "Integration Test Media Item",
"author": "Test Author",
"isbn": "9999999999",
"description": "Created during integration test",
"file_path": "/tmp/test_integration.epub",
"file_size": int64(1024),
"mime_type": "application/epub+zip",
"publisher": "Test Publisher",
"date_published": "2024-01-01",
}
resp := makeRequest(t, "POST", "/api/media-items", req, ctx.AdminToken)
defer resp.Body.Close()
if resp.StatusCode == http.StatusCreated {
var mediaItem map[string]interface{}
body, _ := io.ReadAll(resp.Body)
err := json.Unmarshal(body, &mediaItem)
require.NoError(t, err)
ctx.MediaItemID = mediaItem["id"].(string)
}
})
t.Run("CreateMediaItem_UserForbidden", func(t *testing.T) {
if ctx.LibraryID == "" {
t.Skip("No library available")
}
req := map[string]interface{}{
"library_id": ctx.LibraryID,
"title": "User Media Item",
"file_path": "/tmp/user.epub",
"file_size": int64(1024),
"mime_type": "application/epub+zip",
}
resp := makeRequest(t, "POST", "/api/media-items", req, ctx.UserToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusForbidden, resp.StatusCode)
})
if ctx.MediaItemID != "" {
t.Run("UpdateMediaItem_Admin", func(t *testing.T) {
req := map[string]interface{}{
"title": "Updated Media Item Title",
"description": "Updated during test",
}
resp := makeRequest(t, "PUT", fmt.Sprintf("/api/media-items/%s", ctx.MediaItemID), req, ctx.AdminToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusOK, resp.StatusCode)
})
t.Run("DeleteMediaItem_Admin", func(t *testing.T) {
resp := makeRequest(t, "DELETE", fmt.Sprintf("/api/media-items/%s", ctx.MediaItemID), nil, ctx.AdminToken)
defer resp.Body.Close()
assert.Equal(t, http.StatusNoContent, resp.StatusCode)
})
t.Run("GetMediaItem", func(t *testing.T) {
resp := makeRequest(t, "GET", fmt.Sprintf("/api/media-items/%s", ctx.MediaItemID), nil, ctx.UserToken)
defer resp.Body.Close()