188 lines
5.3 KiB
Go
188 lines
5.3 KiB
Go
|
|
package handlers
|
||
|
|
|
||
|
|
import (
|
||
|
|
"context"
|
||
|
|
"net/http"
|
||
|
|
"net/http/httptest"
|
||
|
|
"strings"
|
||
|
|
"testing"
|
||
|
|
)
|
||
|
|
|
||
|
|
func TestGetTabloDetailPage_Returns200(t *testing.T) {
|
||
|
|
handler := newTestAuthHandler(t)
|
||
|
|
sessionCookie := loginTestUser(t, handler, "demo@xtablo.com", "xtablo-demo")
|
||
|
|
|
||
|
|
// Create a tablo owned by demo user
|
||
|
|
user, err := handler.repo.(interface {
|
||
|
|
GetAuthUserByEmail(ctx context.Context, email string) (AuthUser, error)
|
||
|
|
}).GetAuthUserByEmail(context.Background(), "demo@xtablo.com")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("get demo user: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
tablo, err := handler.repo.CreateTablo(context.Background(), CreateTabloInput{
|
||
|
|
OwnerID: user.ID,
|
||
|
|
Name: "Test Project",
|
||
|
|
Status: TabloStatusTodo,
|
||
|
|
Color: "#3B82F6",
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("create tablo: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/tablos/"+tablo.ID.String(), nil)
|
||
|
|
req.SetPathValue("tabloID", tablo.ID.String())
|
||
|
|
req.AddCookie(sessionCookie)
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
|
||
|
|
handler.GetTabloDetailPage().ServeHTTP(rec, req)
|
||
|
|
|
||
|
|
if rec.Code != http.StatusOK {
|
||
|
|
t.Fatalf("expected 200, got %d\nbody: %s", rec.Code, rec.Body.String())
|
||
|
|
}
|
||
|
|
|
||
|
|
body := rec.Body.String()
|
||
|
|
if !strings.Contains(body, "Test Project") {
|
||
|
|
t.Errorf("expected body to contain tablo name 'Test Project', got: %s", body[:min(len(body), 500)])
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetTabloDetailPage_Returns404(t *testing.T) {
|
||
|
|
handler := newTestAuthHandler(t)
|
||
|
|
sessionCookie := loginTestUser(t, handler, "demo@xtablo.com", "xtablo-demo")
|
||
|
|
|
||
|
|
// Use a random UUID that doesn't belong to the user
|
||
|
|
unknownID := "00000000-0000-0000-0000-000000000099"
|
||
|
|
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/tablos/"+unknownID, nil)
|
||
|
|
req.SetPathValue("tabloID", unknownID)
|
||
|
|
req.AddCookie(sessionCookie)
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
|
||
|
|
handler.GetTabloDetailPage().ServeHTTP(rec, req)
|
||
|
|
|
||
|
|
if rec.Code != http.StatusNotFound {
|
||
|
|
t.Fatalf("expected 404, got %d", rec.Code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetTabloDetailPage_Returns400(t *testing.T) {
|
||
|
|
handler := newTestAuthHandler(t)
|
||
|
|
sessionCookie := loginTestUser(t, handler, "demo@xtablo.com", "xtablo-demo")
|
||
|
|
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/tablos/not-a-uuid", nil)
|
||
|
|
req.SetPathValue("tabloID", "not-a-uuid")
|
||
|
|
req.AddCookie(sessionCookie)
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
|
||
|
|
handler.GetTabloDetailPage().ServeHTTP(rec, req)
|
||
|
|
|
||
|
|
if rec.Code != http.StatusBadRequest {
|
||
|
|
t.Fatalf("expected 400, got %d", rec.Code)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetTabloDetailPage_Unauthenticated(t *testing.T) {
|
||
|
|
handler := newTestAuthHandler(t)
|
||
|
|
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/tablos/00000000-0000-0000-0000-000000000001", nil)
|
||
|
|
req.SetPathValue("tabloID", "00000000-0000-0000-0000-000000000001")
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
|
||
|
|
handler.GetTabloDetailPage().ServeHTTP(rec, req)
|
||
|
|
|
||
|
|
if rec.Code != http.StatusSeeOther {
|
||
|
|
t.Fatalf("expected 302 redirect to /login, got %d", rec.Code)
|
||
|
|
}
|
||
|
|
|
||
|
|
location := rec.Header().Get("Location")
|
||
|
|
if location != "/login" {
|
||
|
|
t.Errorf("expected redirect to /login, got %q", location)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestTabloDetailKanbanColumns(t *testing.T) {
|
||
|
|
handler := newTestAuthHandler(t)
|
||
|
|
sessionCookie := loginTestUser(t, handler, "demo@xtablo.com", "xtablo-demo")
|
||
|
|
|
||
|
|
user, err := handler.repo.(interface {
|
||
|
|
GetAuthUserByEmail(ctx context.Context, email string) (AuthUser, error)
|
||
|
|
}).GetAuthUserByEmail(context.Background(), "demo@xtablo.com")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("get demo user: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
tablo, err := handler.repo.CreateTablo(context.Background(), CreateTabloInput{
|
||
|
|
OwnerID: user.ID,
|
||
|
|
Name: "Kanban Test",
|
||
|
|
Status: TabloStatusTodo,
|
||
|
|
Color: "#3B82F6",
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("create tablo: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/tablos/"+tablo.ID.String(), nil)
|
||
|
|
req.SetPathValue("tabloID", tablo.ID.String())
|
||
|
|
req.AddCookie(sessionCookie)
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
|
||
|
|
handler.GetTabloDetailPage().ServeHTTP(rec, req)
|
||
|
|
|
||
|
|
if rec.Code != http.StatusOK {
|
||
|
|
t.Fatalf("expected 200, got %d", rec.Code)
|
||
|
|
}
|
||
|
|
|
||
|
|
body := rec.Body.String()
|
||
|
|
for _, status := range []string{"todo", "in_progress", "in_review", "done"} {
|
||
|
|
if !strings.Contains(body, status) {
|
||
|
|
t.Errorf("expected body to contain kanban column status %q", status)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func TestGetTabloDetailPage_ContainsSortableScript(t *testing.T) {
|
||
|
|
handler := newTestAuthHandler(t)
|
||
|
|
sessionCookie := loginTestUser(t, handler, "demo@xtablo.com", "xtablo-demo")
|
||
|
|
|
||
|
|
user, err := handler.repo.(interface {
|
||
|
|
GetAuthUserByEmail(ctx context.Context, email string) (AuthUser, error)
|
||
|
|
}).GetAuthUserByEmail(context.Background(), "demo@xtablo.com")
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("get demo user: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
tablo, err := handler.repo.CreateTablo(context.Background(), CreateTabloInput{
|
||
|
|
OwnerID: user.ID,
|
||
|
|
Name: "Sortable Test",
|
||
|
|
Status: TabloStatusTodo,
|
||
|
|
Color: "#3B82F6",
|
||
|
|
})
|
||
|
|
if err != nil {
|
||
|
|
t.Fatalf("create tablo: %v", err)
|
||
|
|
}
|
||
|
|
|
||
|
|
req := httptest.NewRequest(http.MethodGet, "/tablos/"+tablo.ID.String(), nil)
|
||
|
|
req.SetPathValue("tabloID", tablo.ID.String())
|
||
|
|
req.AddCookie(sessionCookie)
|
||
|
|
rec := httptest.NewRecorder()
|
||
|
|
|
||
|
|
handler.GetTabloDetailPage().ServeHTTP(rec, req)
|
||
|
|
|
||
|
|
if rec.Code != http.StatusOK {
|
||
|
|
t.Fatalf("expected 200, got %d", rec.Code)
|
||
|
|
}
|
||
|
|
|
||
|
|
body := rec.Body.String()
|
||
|
|
if !strings.Contains(body, "initTabloDetailSortable") {
|
||
|
|
t.Errorf("expected body to contain 'initTabloDetailSortable', got body[:500]: %s", body[:min(len(body), 500)])
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
func min(a, b int) int {
|
||
|
|
if a < b {
|
||
|
|
return a
|
||
|
|
}
|
||
|
|
return b
|
||
|
|
}
|