Diffdown is a real-time collaborative Markdown editor/previewer built on the AT Protocol diffdown.com
at main 107 lines 2.5 kB view raw
1package db_test 2 3import ( 4 "os" 5 "testing" 6 7 "github.com/limeleaf/diffdown/internal/db" 8) 9 10func openTestDB(t *testing.T) *db.DB { 11 t.Helper() 12 f, err := os.CreateTemp("", "diffdown-test-*.db") 13 if err != nil { 14 t.Fatal(err) 15 } 16 t.Cleanup(func() { os.Remove(f.Name()) }) 17 f.Close() 18 19 database, err := db.Open(f.Name()) 20 if err != nil { 21 t.Fatal(err) 22 } 23 db.SetMigrationsDir("../../migrations") 24 if err := database.Migrate(); err != nil { 25 t.Fatal(err) 26 } 27 return database 28} 29 30func TestGetDocVersion_Empty(t *testing.T) { 31 d := openTestDB(t) 32 v, err := d.GetDocVersion("rkey1") 33 if err != nil { 34 t.Fatal(err) 35 } 36 if v != 0 { 37 t.Errorf("expected version 0 for new doc, got %d", v) 38 } 39} 40 41func TestAppendSteps_IncreasesVersion(t *testing.T) { 42 d := openTestDB(t) 43 steps := []string{`{"stepType":"replace"}`, `{"stepType":"replace"}`} 44 newVersion, err := d.AppendSteps("rkey1", 0, steps, "client-a") 45 if err != nil { 46 t.Fatal(err) 47 } 48 if newVersion != 2 { 49 t.Errorf("expected version 2, got %d", newVersion) 50 } 51} 52 53func TestAppendSteps_VersionConflict(t *testing.T) { 54 d := openTestDB(t) 55 _, err := d.AppendSteps("rkey1", 0, []string{`{}`}, "client-a") 56 if err != nil { 57 t.Fatal(err) 58 } 59 // Submit again from clientVersion=0 (stale) — must fail. 60 _, err = d.AppendSteps("rkey1", 0, []string{`{}`}, "client-b") 61 if err == nil { 62 t.Fatal("expected conflict error, got nil") 63 } 64} 65 66func TestGetStepsSince(t *testing.T) { 67 d := openTestDB(t) 68 steps := []string{`{"a":1}`, `{"a":2}`, `{"a":3}`} 69 d.AppendSteps("rkey1", 0, steps, "client-a") 70 71 rows, err := d.GetStepsSince("rkey1", 1) 72 if err != nil { 73 t.Fatal(err) 74 } 75 if len(rows) != 2 { 76 t.Errorf("expected 2 steps since v1, got %d", len(rows)) 77 } 78 if rows[0].JSON != `{"a":2}` { 79 t.Errorf("unexpected step: %s", rows[0].JSON) 80 } 81} 82 83func TestCollaborations(t *testing.T) { 84 d := openTestDB(t) 85 const collabDID = "did:plc:collab" 86 const ownerDID = "did:plc:owner" 87 const rkey = "abc123" 88 89 if err := d.AddCollaboration(collabDID, ownerDID, rkey); err != nil { 90 t.Fatalf("AddCollaboration: %v", err) 91 } 92 // idempotent — should not error on duplicate 93 if err := d.AddCollaboration(collabDID, ownerDID, rkey); err != nil { 94 t.Fatalf("AddCollaboration (dup): %v", err) 95 } 96 97 rows, err := d.GetCollaborations(collabDID) 98 if err != nil { 99 t.Fatalf("GetCollaborations: %v", err) 100 } 101 if len(rows) != 1 { 102 t.Fatalf("want 1 row, got %d", len(rows)) 103 } 104 if rows[0].OwnerDID != ownerDID || rows[0].DocumentRKey != rkey { 105 t.Errorf("unexpected row: %+v", rows[0]) 106 } 107}