This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

core / appview / models / entity_state_test.go
4.8 kB 146 lines
1package models 2 3import ( 4 "testing" 5 "time" 6 7 "github.com/bluesky-social/indigo/atproto/syntax" 8 "tangled.org/core/api/tangled" 9) 10 11const testIssueSubject = "at://did:plc:anemone/sh.tangled.repo.issue/i1" 12 13func TestIssueStateFromRecord(t *testing.T) { 14 const rkey = "3jzfcijpj2z2a" 15 16 if _, err := IssueStateFromRecord("did:plc:akshay", rkey, tangled.RepoIssueState{ 17 Issue: testIssueSubject, 18 State: "sh.tangled.repo.issue.state.reopened", 19 CreatedAt: "2026-06-01T00:00:00Z", 20 }); err == nil { 21 t.Fatal("unknown state variant must be rejected") 22 } 23 24 created := "2026-06-01T12:30:00Z" 25 rec, err := IssueStateFromRecord("did:plc:akshay", rkey, tangled.RepoIssueState{ 26 Issue: testIssueSubject, 27 State: tangled.RepoIssueStateClosed, 28 CreatedAt: created, 29 }) 30 if err != nil { 31 t.Fatalf("IssueStateFromRecord: %v", err) 32 } 33 want, _ := time.Parse(time.RFC3339, created) 34 if rec.Value != StateClosed || rec.SortMicros != want.UnixMicro() { 35 t.Fatalf("got value=%q micros=%d, want closed with createdAt as the sort key", rec.Value, rec.SortMicros) 36 } 37 38 tidRec, err := IssueStateFromRecord("did:plc:akshay", rkey, tangled.RepoIssueState{ 39 Issue: testIssueSubject, 40 State: tangled.RepoIssueStateOpen, 41 CreatedAt: "not-a-datetime", 42 }) 43 if err != nil { 44 t.Fatalf("IssueStateFromRecord tid fallback: %v", err) 45 } 46 tid, _ := syntax.ParseTID(rkey) 47 if tidRec.SortMicros != tid.Time().UnixMicro() { 48 t.Fatalf("SortMicros = %d, want TID micros %d when createdAt is unparseable", tidRec.SortMicros, tid.Time().UnixMicro()) 49 } 50} 51 52func TestPullStatusFromRecord_Variants(t *testing.T) { 53 subject := "at://did:plc:limpet/sh.tangled.repo.pull/p1" 54 cases := map[string]StateValue{ 55 tangled.RepoPullStatusOpen: StateOpen, 56 tangled.RepoPullStatusClosed: StateClosed, 57 tangled.RepoPullStatusMerged: StateMerged, 58 } 59 for wire, want := range cases { 60 rec, err := PullStatusFromRecord("did:plc:akshay", "3jzfcijpj2z2a", tangled.RepoPullStatus{ 61 Pull: subject, 62 Status: wire, 63 CreatedAt: "2026-06-01T00:00:00Z", 64 }) 65 if err != nil { 66 t.Fatalf("PullStatusFromRecord(%q): %v", wire, err) 67 } 68 if rec.Value != want { 69 t.Fatalf("PullStatusFromRecord(%q) value = %q, want %q", wire, rec.Value, want) 70 } 71 } 72 73 if _, err := PullStatusFromRecord("did:plc:akshay", "3jzfcijpj2z2a", tangled.RepoPullStatus{ 74 Pull: subject, 75 Status: "sh.tangled.repo.pull.status.draft", 76 CreatedAt: "2026-06-01T00:00:00Z", 77 }); err == nil { 78 t.Fatal("unknown pull status variant must be rejected") 79 } 80} 81 82func TestAsIssueStateRecord_RoundTrip(t *testing.T) { 83 const rkey = "3jzfcijpj2z2a" 84 subject := syntax.ATURI(testIssueSubject) 85 created := time.Date(2026, 6, 30, 12, 30, 15, int(123*time.Millisecond), time.UTC) 86 87 for _, value := range []StateValue{StateOpen, StateClosed} { 88 rec, err := AsIssueStateRecord(subject, value, created) 89 if err != nil { 90 t.Fatalf("AsIssueStateRecord(%q): %v", value, err) 91 } 92 if rec.Issue != testIssueSubject { 93 t.Fatalf("Issue = %q, want %q", rec.Issue, testIssueSubject) 94 } 95 96 back, err := IssueStateFromRecord("did:plc:akshay", rkey, rec) 97 if err != nil { 98 t.Fatalf("IssueStateFromRecord after AsIssueStateRecord(%q): %v", value, err) 99 } 100 if back.Value != value { 101 t.Fatalf("round-trip value = %q, want %q", back.Value, value) 102 } 103 if back.SortMicros != created.UnixMicro() { 104 t.Fatalf("round-trip SortMicros = %d, want %d", back.SortMicros, created.UnixMicro()) 105 } 106 } 107 108 if _, err := AsIssueStateRecord(subject, StateMerged, created); err == nil { 109 t.Fatal("merged is not a valid issue state and must be rejected") 110 } 111} 112 113func TestAsPullStatusRecords_RoundTrip(t *testing.T) { 114 const rkey = "3jzfcijpj2z2a" 115 subject := syntax.ATURI("at://did:plc:limpet/sh.tangled.repo.pull/p1") 116 created := time.Date(2026, 6, 30, 12, 30, 15, int(123*time.Millisecond), time.UTC) 117 118 for _, value := range []StateValue{StateOpen, StateClosed, StateMerged} { 119 recs, err := AsPullStatusRecords([]syntax.ATURI{subject}, value, created) 120 if err != nil { 121 t.Fatalf("AsPullStatusRecords(%q): %v", value, err) 122 } 123 if len(recs) != 1 { 124 t.Fatalf("AsPullStatusRecords(%q) returned %d records, want 1", value, len(recs)) 125 } 126 rec := recs[0] 127 if rec.Pull != subject.String() { 128 t.Fatalf("Pull = %q, want %q", rec.Pull, subject) 129 } 130 131 back, err := PullStatusFromRecord("did:plc:akshay", rkey, rec) 132 if err != nil { 133 t.Fatalf("PullStatusFromRecord after AsPullStatusRecords(%q): %v", value, err) 134 } 135 if back.Value != value { 136 t.Fatalf("round-trip value = %q, want %q", back.Value, value) 137 } 138 if back.SortMicros != created.UnixMicro() { 139 t.Fatalf("round-trip SortMicros = %d, want %d", back.SortMicros, created.UnixMicro()) 140 } 141 } 142 143 if _, err := AsPullStatusRecords([]syntax.ATURI{subject}, "bogus", created); err == nil { 144 t.Fatal("invalid pull status value must be rejected") 145 } 146}