carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package console
2
3import (
4 "context"
5 "encoding/json"
6 "testing"
7 "time"
8
9 "github.com/carlosframework/platform/internal/domains"
10 "github.com/carlosframework/platform/internal/release"
11)
12
13// An account minted with an owner in its manifest is materialized WITH that
14// owner as a member. This is the whole point of naming an owner at creation:
15// an account whose owner is written nowhere is an account nobody can open,
16// which is the failure this feature exists to end.
17func TestMaterializeHonoursTheManifestOwner(t *testing.T) {
18 ctx := context.Background()
19 rel := release.NewDirStore(t.TempDir())
20 st := openTestStore(t)
21 now := time.Now()
22
23 id, sqid, err := domains.MintAccount(ctx, rel, "Kass", "paul@keymail.dev", now)
24 if err != nil {
25 t.Fatal(err)
26 }
27 body, _, err := rel.Get(ctx, domains.AccountManifestKey(sqid))
28 if err != nil {
29 t.Fatal(err)
30 }
31 var m domains.AccountManifest
32 if err := json.Unmarshal(body, &m); err != nil {
33 t.Fatal(err)
34 }
35 if m.Owner != "paul@keymail.dev" {
36 t.Fatalf("manifest owner = %q, want paul@keymail.dev", m.Owner)
37 }
38
39 n, err := MaterializeAccounts(ctx, rel, st)
40 if err != nil || n != 1 {
41 t.Fatalf("MaterializeAccounts = %d %v, want 1", n, err)
42 }
43 role, err := st.Role(id, "paul@keymail.dev")
44 if err != nil || role != RoleOwner {
45 t.Fatalf("role after materializing = %q %v, want owner", role, err)
46 }
47
48 // Re-materializing changes nothing — no membership is re-created, no role
49 // is reset. This runs on every console start.
50 if err := st.AddMember(id, "paul@keymail.dev", RoleMember, now); err == nil {
51 t.Fatal("demoting the last owner should have been refused")
52 }
53 if n, err := MaterializeAccounts(ctx, rel, st); err != nil || n != 0 {
54 t.Fatalf("second MaterializeAccounts = %d %v, want 0", n, err)
55 }
56}
57
58// A manifest with no owner still materializes — every account minted before
59// this existed has none — and still creates no membership out of thin air.
60func TestMaterializeWithoutAnOwnerCreatesNoMembership(t *testing.T) {
61 ctx := context.Background()
62 rel := release.NewDirStore(t.TempDir())
63 st := openTestStore(t)
64 id, _, err := domains.MintAccount(ctx, rel, "Legacy", "", time.Now())
65 if err != nil {
66 t.Fatal(err)
67 }
68 if _, err := MaterializeAccounts(ctx, rel, st); err != nil {
69 t.Fatal(err)
70 }
71 members, err := st.Members(id)
72 if err != nil {
73 t.Fatal(err)
74 }
75 if len(members) != 0 {
76 t.Fatalf("members = %v, want none", members)
77 }
78}
79
80// A manifest owner that the sign-in form would refuse is not a membership
81// anybody could ever claim, so it is skipped rather than written.
82func TestMaterializeRefusesAnUnusableOwner(t *testing.T) {
83 ctx := context.Background()
84 rel := release.NewDirStore(t.TempDir())
85 st := openTestStore(t)
86 // MintAccount validates the owner, so a manifest this broken can only
87 // arrive by hand-editing or corruption — which is exactly the case
88 // materialization has to survive. Write it directly.
89 id, sqid, err := domains.MintAccount(ctx, rel, "Typo", "", time.Now())
90 if err != nil {
91 t.Fatal(err)
92 }
93 raw, err := json.Marshal(domains.AccountManifest{
94 ID: id, Sqid: sqid, Name: "Typo", Owner: "not-an-address", CreatedAt: time.Now(),
95 })
96 if err != nil {
97 t.Fatal(err)
98 }
99 body, etag, err := rel.Get(ctx, AccountManifestKey(sqid))
100 if err != nil {
101 t.Fatal(err)
102 }
103 _ = body
104 if _, err := rel.Put(ctx, AccountManifestKey(sqid), raw, etag); err != nil {
105 t.Fatal(err)
106 }
107 if _, err := MaterializeAccounts(ctx, rel, st); err != nil {
108 t.Fatal(err)
109 }
110 if members, err := st.Members(id); err != nil || len(members) != 0 {
111 t.Fatalf("members = %v %v, want none", members, err)
112 }
113}
114
115// The console's own mint stamps the owner into the bucket too, so a second
116// box materializing the same account knows who it belongs to.
117func TestConsoleMintStampsTheOwner(t *testing.T) {
118 fx := newConsoleFixture(t)
119 token := cliToken(t, fx, "paul@keymail.dev", "code-owner")
120 _, out := postJSON(t, fx.ts.URL+"/auth/cli/accounts", map[string]string{"name": "kass"}, token)
121 sqid := str(t, out, "sqid")
122 body, _, err := fx.rel.Get(context.Background(), AccountManifestKey(sqid))
123 if err != nil {
124 t.Fatal(err)
125 }
126 var m domains.AccountManifest
127 if err := json.Unmarshal(body, &m); err != nil {
128 t.Fatal(err)
129 }
130 if m.Owner != "paul@keymail.dev" {
131 t.Fatalf("manifest owner = %q, want paul@keymail.dev", m.Owner)
132 }
133}
134