- Register journal and journal:read via pact.HasTokenScopes - Switch API auth to cabana.ResolveBackend with golem15.journal.* cover - Map ErrTokenScope to PHP Insufficient permissions bodies - Add TestResolveErrorMapping and TestJournalTokenTracer Co-authored-by: Cursor <cursoragent@cursor.com>
69 lines
2.1 KiB
Go
69 lines
2.1 KiB
Go
package journal_test
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
"testing"
|
|
|
|
"git.golem15.com/golem15/sm-journal-plugin/controllers"
|
|
"git.golem15.com/golem15/sm-journal-plugin/models"
|
|
"git.golem15.com/golem15/summercms/modules/cabana"
|
|
)
|
|
|
|
// TestJournalTokenTracer mints a journal-scoped personal API token through the
|
|
// admin account API and creates a Journal post as that token's owner (16.3-03).
|
|
func TestJournalTokenTracer(t *testing.T) {
|
|
env := newPostsEnv(t)
|
|
jwt := env.admin(t, controllers.PermissionAccessPosts)
|
|
adminID := env.lastUserID(t)
|
|
|
|
create := env.call(t, http.MethodPost, adminAPI("/account/tokens"), jwt, map[string]any{
|
|
"name": "journal-agent",
|
|
"expires": "90d",
|
|
"scopes": []string{"journal"},
|
|
})
|
|
if create.Code != http.StatusCreated {
|
|
t.Fatalf("create token: %d %s", create.Code, create.Body.String())
|
|
}
|
|
var created struct {
|
|
Data cabana.AdminAPITokenCreated `json:"data"`
|
|
}
|
|
if err := json.Unmarshal(create.Body.Bytes(), &created); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
plain := created.Data.Token
|
|
if !strings.HasPrefix(plain, cabana.APITokenPrefix) || len(plain) != len(cabana.APITokenPrefix)+40 {
|
|
t.Fatalf("token shape %q", plain)
|
|
}
|
|
|
|
postRec := env.call(t, http.MethodPost, "/_journal/api/v1/posts", plain, map[string]any{
|
|
"title": "Token-authored post",
|
|
"content": "Written with a journal scope token",
|
|
})
|
|
if postRec.Code != http.StatusCreated {
|
|
t.Fatalf("POST /posts with journal token: %d %s", postRec.Code, postRec.Body.String())
|
|
}
|
|
var postBody struct {
|
|
Data struct {
|
|
ID uint `json:"id"`
|
|
UserID *uint `json:"user_id"`
|
|
Slug string `json:"slug"`
|
|
} `json:"data"`
|
|
}
|
|
if err := json.Unmarshal(postRec.Body.Bytes(), &postBody); err != nil {
|
|
t.Fatalf("post body: %s err=%v", postRec.Body.String(), err)
|
|
}
|
|
if postBody.Data.ID == 0 {
|
|
t.Fatalf("missing post id: %s", postRec.Body.String())
|
|
}
|
|
|
|
var row models.Post
|
|
if err := env.gdb.First(&row, postBody.Data.ID).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if row.UserID == nil || *row.UserID != adminID {
|
|
t.Fatalf("stored user_id = %v, want %d", row.UserID, adminID)
|
|
}
|
|
}
|