test(import): a hand-edited backup cannot raise the role or reach other accounts
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
3c23d094ce
commit
83bba8d20b
1 file changed
+50
@@ -125,6 +125,56 @@ func TestImportMindSiftJSONRoundTrip(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// A backup changed by hand cannot raise the importer's role or reach other accounts: the profile in it
|
||||||
|
// (role, id) is ignored, and notes and blocks get new IDs and no task links.
|
||||||
|
func TestImportIgnoresProfileAndForeignIDs(t *testing.T) {
|
||||||
|
store, anna, ben := newImportStore(t)
|
||||||
|
annaDoc, _ := store.CreateDocument(anna.ID, "", "Annas Notiz", "", "", []domain.DocumentBlock{{ID: "blk_anna", Type: "bullet", Content: "Original"}}, nil, false)
|
||||||
|
annaTask, _ := store.CreateThoughtWithDetails(anna.ID, "Annas Aufgabe", "normal", "manual", "", "", "todo", "")
|
||||||
|
|
||||||
|
exp := domain.FullExport{
|
||||||
|
ExportedAt: "2026-11-02T00:00:00Z",
|
||||||
|
Version: "manipuliert",
|
||||||
|
User: domain.User{ID: anna.ID, Email: anna.Email, Role: "admin", IsActive: true},
|
||||||
|
Documents: []domain.Document{{
|
||||||
|
ID: annaDoc.ID,
|
||||||
|
Title: "Übernommen?",
|
||||||
|
Blocks: []domain.DocumentBlock{
|
||||||
|
{ID: "blk_anna", Type: "bullet", Content: "Überschrieben?"},
|
||||||
|
{ID: "blk_x", Type: "todo", Content: "Verknüpft?", TaskID: annaTask.ID},
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
data, _ := json.Marshal(exp)
|
||||||
|
plan, err := PlanMindSiftJSONImport(data)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("plan: %v", err)
|
||||||
|
}
|
||||||
|
if _, err := store.ApplyImport(ben.ID, plan); err != nil {
|
||||||
|
t.Fatalf("apply: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if u, _ := store.GetUserByID(ben.ID); u.Role != "member" {
|
||||||
|
t.Errorf("import must not change the role, got %q", u.Role)
|
||||||
|
}
|
||||||
|
if u, _ := store.GetUserByID(anna.ID); u.Role != anna.Role {
|
||||||
|
t.Errorf("import must not touch the account named in the backup, role now %q", u.Role)
|
||||||
|
}
|
||||||
|
if d, err := store.GetDocumentByID(anna.ID, annaDoc.ID); err != nil || d.Title != "Annas Notiz" || d.Blocks[0].Content != "Original" {
|
||||||
|
t.Errorf("Anna's note must stay as it was: %+v %v", d, err)
|
||||||
|
}
|
||||||
|
docs, _ := store.GetDocuments(ben.ID)
|
||||||
|
if len(docs) != 1 || docs[0].ID == annaDoc.ID || docs[0].Title != "Übernommen?" {
|
||||||
|
t.Fatalf("the note should be Ben's own copy with a new ID: %+v", docs)
|
||||||
|
}
|
||||||
|
got, _ := store.GetDocumentByID(ben.ID, docs[0].ID)
|
||||||
|
for _, b := range got.Blocks {
|
||||||
|
if b.ID == "blk_anna" || b.ID == "blk_x" || b.TaskID != "" {
|
||||||
|
t.Errorf("imported blocks need new IDs and no task links: %+v", b)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func zipOf(t *testing.T, files map[string]string) []byte {
|
func zipOf(t *testing.T, files map[string]string) []byte {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
var buf bytes.Buffer
|
var buf bytes.Buffer
|
||||||
|
|||||||
Reference in new issue
Block a user