ops design and app

add more comments feature, more tags feature, and other frontend updates
This commit is contained in:
2026-06-09 18:27:59 -04:00
parent 1e939f307d
commit 04a1f2bb6d
33 changed files with 3276 additions and 113 deletions

View File

@@ -14,6 +14,7 @@ import (
"testing"
"time"
"github.com/tim/cairnquire/apps/server/internal/auth"
"github.com/tim/cairnquire/apps/server/internal/config"
"github.com/tim/cairnquire/apps/server/internal/database"
"github.com/tim/cairnquire/apps/server/internal/docs"
@@ -211,8 +212,13 @@ func TestHandleUploadPromotesReadableFilesToDocuments(t *testing.T) {
t.Fatalf("document path = %q, want %q", attachment.DocumentPath, tt.wantPath)
}
listRequest := httptest.NewRequest(http.MethodGet, "/api/attachments", nil)
listRequest = listRequest.WithContext(withPrincipal(listRequest.Context(), auth.Principal{
UserID: "user:test-admin",
Role: auth.RoleAdmin,
}))
listRecorder := httptest.NewRecorder()
server.handleAttachmentsList(listRecorder, httptest.NewRequest(http.MethodGet, "/api/attachments", nil))
server.handleAttachmentsList(listRecorder, listRequest)
var listPayload struct {
Attachments []struct {
Kind string `json:"kind"`
@@ -233,6 +239,17 @@ func TestHandleUploadPromotesReadableFilesToDocuments(t *testing.T) {
if !bytes.Contains([]byte(page.HTML), []byte(tt.wantHTML)) {
t.Fatalf("rendered HTML = %q, want to contain %q", page.HTML, tt.wantHTML)
}
grants, err := server.auth.ListResourcePermissions(context.Background(), auth.Principal{
UserID: "user:test-admin",
Role: auth.RoleAdmin,
}, auth.ResourceDocument, tt.wantPath)
if err != nil {
t.Fatalf("list promoted document permissions: %v", err)
}
if len(grants) != 1 || grants[0].UserID != "user:test-admin" || grants[0].Permission != auth.PermissionAdmin {
t.Fatalf("promoted document grants = %#v, want creator admin grant", grants)
}
})
}
}
@@ -376,11 +393,25 @@ func setupUploadTestServer(t *testing.T) (*Server, string) {
sourceDir := t.TempDir()
repository := docs.NewRepository(db)
documents := docs.NewService(sourceDir, contentStore, markdown.NewRenderer(), repository, slog.Default())
authRepo := auth.NewRepository(db)
authService, err := auth.NewService(authRepo, "http://localhost")
if err != nil {
t.Fatalf("create auth service: %v", err)
}
if _, err := authRepo.UpsertUser(context.Background(), auth.User{
ID: "user:test-admin",
Email: "test-admin@example.com",
DisplayName: "Test Admin",
Role: auth.RoleAdmin,
}); err != nil {
t.Fatalf("create test admin user: %v", err)
}
return &Server{
documents: documents,
repository: repository,
contentStore: contentStore,
auth: authService,
}, sourceDir
}
@@ -412,6 +443,10 @@ func multipartUploadRequest(t *testing.T, filename string, content []byte, folde
request := httptest.NewRequest(http.MethodPost, "/api/uploads", &body)
request.Header.Set("Content-Type", writer.FormDataContentType())
request = request.WithContext(withPrincipal(request.Context(), auth.Principal{
UserID: "user:test-admin",
Role: auth.RoleAdmin,
}))
return request
}