package handlers import ( "encoding/json" "testing" "github.com/stretchr/testify/assert" ) // The device pushes deletions as dedup-key arrays on the progress request. // Verify the wire shape the plugin sends (lua json.encode of // { deleted_highlights = { { dedup_key = "..." } } }) binds correctly. func TestKOReaderProgressRequest_DeletedAnnotationsBinding(t *testing.T) { payload := `{ "books": [{ "sha256": "d1b1c6123d6206017b40798744ed994f00803b97d22ce51bea32e95e1ce7a164", "title": "1984", "percentage": 0.42, "deleted_highlights": [ { "dedup_key": "abc123" }, { "dedup_key": "def456" } ], "deleted_bookmarks": [ { "dedup_key": "789xyz" } ] }] }` var req KOReaderProgressRequest err := json.Unmarshal([]byte(payload), &req) assert.NoError(t, err) assert.Len(t, req.Books, 1) book := req.Books[0] assert.Len(t, book.DeletedHighlights, 2) assert.Equal(t, "abc123", book.DeletedHighlights[0].DedupKey) assert.Equal(t, "def456", book.DeletedHighlights[1].DedupKey) assert.Len(t, book.DeletedBookmarks, 1) assert.Equal(t, "789xyz", book.DeletedBookmarks[0].DedupKey) } // A request without the arrays (older plugins) must bind with them empty — // deletion propagation is strictly opt-in per push. func TestKOReaderProgressRequest_DeletedAnnotationsOmitted(t *testing.T) { payload := `{"books": [{"sha256": "x", "title": "t", "percentage": 0.1}]}` var req KOReaderProgressRequest err := json.Unmarshal([]byte(payload), &req) assert.NoError(t, err) assert.Empty(t, req.Books[0].DeletedHighlights) assert.Empty(t, req.Books[0].DeletedBookmarks) }