From d1c4c4a5d9a763ef0f4a23a23d0b0c904d3b59ae Mon Sep 17 00:00:00 2001 From: Owais Jamil Date: Thu, 7 May 2026 23:01:05 -0500 Subject: [PATCH] feat: deleteRecord no-op on absent record --- lib/tempest/records.ex | 18 +++++++++++------- lib/tempest/repo_storage.ex | 10 ++++------ test/smoke/records.hurl | 15 +++++++++++++++ test/tempest_web/xrpc/records_test.exs | 14 ++++++++++++++ 4 files changed, 44 insertions(+), 13 deletions(-) diff --git a/lib/tempest/records.ex b/lib/tempest/records.ex index 5faa7c9..b17c629 100644 --- a/lib/tempest/records.ex +++ b/lib/tempest/records.ex @@ -83,13 +83,17 @@ defmodule Tempest.Records do swap_commit: input.swap_commit }), :ok <- maybe_insert_delete_event(account.did, stored) do - {:ok, - %{ - commit: %{ - cid: stored.commit_cid, - rev: stored.rev - } - }} + if stored.deleted? do + {:ok, + %{ + commit: %{ + cid: stored.commit_cid, + rev: stored.rev + } + }} + else + {:ok, %{}} + end end end diff --git a/lib/tempest/repo_storage.ex b/lib/tempest/repo_storage.ex index de9ae32..ddc04a8 100644 --- a/lib/tempest/repo_storage.ex +++ b/lib/tempest/repo_storage.ex @@ -170,21 +170,19 @@ defmodule Tempest.RepoStorage do {:ok, conn, _path} <- open_repo(config, account.did) do transact(conn, fn -> with {:ok, current} <- current_repo(conn), - :ok <- ensure_swap_commit(current, attrs.swap_commit), - {:ok, existing_record} <- current_record(conn, attrs.collection, attrs.rkey), - :ok <- ensure_swap_record(existing_record, attrs.swap_record) do + {:ok, existing_record} <- current_record(conn, attrs.collection, attrs.rkey) do case existing_record do nil -> {:ok, %{ uri: "at://" <> account.did <> "/" <> attrs.collection <> "/" <> attrs.rkey, - commit_cid: current.commit_cid, - rev: current.rev, deleted?: false }} _record -> - with {:ok, repo} <- build_delete_record_repo(account.did, private_key, current, attrs), + with :ok <- ensure_swap_commit(current, attrs.swap_commit), + :ok <- ensure_swap_record(existing_record, attrs.swap_record), + {:ok, repo} <- build_delete_record_repo(account.did, private_key, current, attrs), :ok <- insert_blocks(conn, repo.blocks, repo.inserted_at), :ok <- delete_record_row(conn, repo.collection, repo.rkey), :ok <- insert_commit(conn, repo), diff --git a/test/smoke/records.hurl b/test/smoke/records.hurl index 23aa0e5..60155ff 100644 --- a/test/smoke/records.hurl +++ b/test/smoke/records.hurl @@ -157,3 +157,18 @@ HTTP 200 [Asserts] header "content-type" contains "application/json" jsonpath "$.records[0]" not exists + +POST {{base_url}}/xrpc/com.atproto.repo.deleteRecord +Authorization: Bearer {{access_token}} +Content-Type: application/json +{ + "repo": "{{created_did}}", + "collection": "app.bsky.actor.profile", + "rkey": "self", + "swapRecord": "{{updated_cid}}", + "swapCommit": "{{updated_commit_cid}}" +} +HTTP 200 +[Asserts] +header "content-type" contains "application/json" +jsonpath "$.commit" not exists diff --git a/test/tempest_web/xrpc/records_test.exs b/test/tempest_web/xrpc/records_test.exs index fa5baa6..79baabb 100644 --- a/test/tempest_web/xrpc/records_test.exs +++ b/test/tempest_web/xrpc/records_test.exs @@ -238,6 +238,20 @@ defmodule TempestWeb.Xrpc.RecordsTest do assert json_response(list_conn, 200)["records"] == [] assert scalar(repo_db(account["did"]), "SELECT COUNT(*) FROM records") == 0 assert sequencer_event_count(account["did"], "repo.record.delete") == 1 + + absent_delete_conn = + conn + |> auth_json(account) + |> post(~p"/xrpc/com.atproto.repo.deleteRecord", %{ + "repo" => account["did"], + "collection" => "app.bsky.actor.profile", + "rkey" => "self", + "swapRecord" => created["cid"], + "swapCommit" => created["commit"]["cid"] + }) + + refute Map.has_key?(json_response(absent_delete_conn, 200), "commit") + assert sequencer_event_count(account["did"], "repo.record.delete") == 1 end test "listRecords paginates within a collection", %{conn: conn} do -- 2.51.2