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) } }