Complete tasks 4.1-4.2: Page management service and HTTP endpoints
- Implemented PageService with full CRUD operations - Added GetPages, CreatePage, UpdatePage, DeletePage, ReorderPages methods - Cascade deletion of widgets when page is deleted - Prevention of last page deletion - Created page HTTP endpoints (GET, POST, PUT, DELETE, reorder) - HTMX-friendly HTML fragment responses - Comprehensive unit tests for service and handlers - Updated dashboard to use PageService and create default pages
This commit is contained in:
@@ -6,10 +6,67 @@ import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"custom-start-page/internal/middleware"
|
||||
"custom-start-page/internal/models"
|
||||
)
|
||||
|
||||
// mockPageService is a mock implementation of PageService for testing
|
||||
type mockPageService struct {
|
||||
pages []*models.Page
|
||||
err error
|
||||
}
|
||||
|
||||
func (m *mockPageService) GetPages(ctx context.Context, userID string) ([]*models.Page, error) {
|
||||
if m.err != nil {
|
||||
return nil, m.err
|
||||
}
|
||||
return m.pages, nil
|
||||
}
|
||||
|
||||
func (m *mockPageService) CreatePage(ctx context.Context, userID, name string) (*models.Page, error) {
|
||||
if m.err != nil {
|
||||
return nil, m.err
|
||||
}
|
||||
page := &models.Page{
|
||||
ID: "new-page-id",
|
||||
UserID: userID,
|
||||
Name: name,
|
||||
Order: len(m.pages),
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
}
|
||||
m.pages = append(m.pages, page)
|
||||
return page, nil
|
||||
}
|
||||
|
||||
func (m *mockPageService) CreateDefaultPage(ctx context.Context, userID string) (*models.Page, error) {
|
||||
return m.CreatePage(ctx, userID, "Home")
|
||||
}
|
||||
|
||||
func (m *mockPageService) UpdatePage(ctx context.Context, userID, pageID, name string) (*models.Page, error) {
|
||||
if m.err != nil {
|
||||
return nil, m.err
|
||||
}
|
||||
for _, page := range m.pages {
|
||||
if page.ID == pageID && page.UserID == userID {
|
||||
page.Name = name
|
||||
page.UpdatedAt = time.Now()
|
||||
return page, nil
|
||||
}
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func (m *mockPageService) DeletePage(ctx context.Context, userID, pageID string) error {
|
||||
return m.err
|
||||
}
|
||||
|
||||
func (m *mockPageService) ReorderPages(ctx context.Context, userID string, pageOrder []string) error {
|
||||
return m.err
|
||||
}
|
||||
|
||||
// createMockDashboardTemplate creates a simple mock template for testing
|
||||
func createMockDashboardTemplate() *template.Template {
|
||||
tmpl := template.New("dashboard.html")
|
||||
@@ -21,8 +78,21 @@ func createMockDashboardTemplate() *template.Template {
|
||||
func TestHandleDashboard_WithAuthenticatedUser(t *testing.T) {
|
||||
// Setup
|
||||
mockTemplate := createMockDashboardTemplate()
|
||||
mockPages := []*models.Page{
|
||||
{
|
||||
ID: "page-1",
|
||||
UserID: "test-user-123",
|
||||
Name: "Home",
|
||||
Order: 0,
|
||||
CreatedAt: time.Now(),
|
||||
UpdatedAt: time.Now(),
|
||||
},
|
||||
}
|
||||
mockService := &mockPageService{pages: mockPages}
|
||||
|
||||
handler := &DashboardHandler{
|
||||
templates: mockTemplate,
|
||||
pageService: mockService,
|
||||
templates: mockTemplate,
|
||||
}
|
||||
|
||||
// Create request with user ID in context
|
||||
@@ -50,8 +120,11 @@ func TestHandleDashboard_WithAuthenticatedUser(t *testing.T) {
|
||||
func TestHandleDashboard_WithoutUserID(t *testing.T) {
|
||||
// Setup
|
||||
mockTemplate := createMockDashboardTemplate()
|
||||
mockService := &mockPageService{}
|
||||
|
||||
handler := &DashboardHandler{
|
||||
templates: mockTemplate,
|
||||
pageService: mockService,
|
||||
templates: mockTemplate,
|
||||
}
|
||||
|
||||
// Create request without user ID in context
|
||||
|
||||
Reference in New Issue
Block a user