Scope support E2E job cleanup

This commit is contained in:
SimpleTest 2026-08-13 05:53:38 +03:00
parent 9a2270e3db
commit 67fd3feba7
2 changed files with 154 additions and 6 deletions

View File

@ -43,6 +43,12 @@ defmodule Mix.Tasks.Wnh.StagingFullE2e do
@confirmation "public-staging-full-e2e" @confirmation "public-staging-full-e2e"
@precreated_roles ~w(requester helper replacement-helper activity-organizer activity-participant admin) @precreated_roles ~w(requester helper replacement-helper activity-organizer activity-participant admin)
@registered_roles ~w(auth-user auth-user-changed) @registered_roles ~w(auth-user auth-user-changed)
@support_job_workers [
"WhoNeedHelp.Mail.SupportConfirmationWorker",
"WhoNeedHelp.Mail.SupportOperatorAlertWorker",
"WhoNeedHelp.Mail.SupportUpdateWorker"
]
@content_removal_job_workers ["WhoNeedHelp.Mail.ContentRemovalEmailWorker"]
@target_schemas %{ @target_schemas %{
users: User, users: User,
@ -309,7 +315,14 @@ defmodule Mix.Tasks.Wnh.StagingFullE2e do
content_removal_notices: content_removal_notice_ids content_removal_notices: content_removal_notice_ids
}) })
job_ids = fixture_job_ids(user_ids, request_ids, notification_ids) job_ids =
fixture_job_ids(
user_ids,
request_ids,
notification_ids,
support_request_ids,
content_removal_notice_ids
)
targets = %{ targets = %{
users: user_ids, users: user_ids,
@ -392,7 +405,15 @@ defmodule Mix.Tasks.Wnh.StagingFullE2e do
end end
assert_targets_absent!(targets) assert_targets_absent!(targets)
assert_no_late_fixture_jobs!(user_ids, request_ids, notification_ids)
assert_no_late_fixture_jobs!(
user_ids,
request_ids,
notification_ids,
support_request_ids,
content_removal_notice_ids
)
assert_prefix_unused!(context) assert_prefix_unused!(context)
manifest = manifest =
@ -583,7 +604,13 @@ defmodule Mix.Tasks.Wnh.StagingFullE2e do
end end
end end
defp fixture_job_ids(user_ids, request_ids, notification_ids) do defp fixture_job_ids(
user_ids,
request_ids,
notification_ids,
support_request_ids,
content_removal_notice_ids
) do
recipients = Enum.map(user_ids, &"user:#{&1}") recipients = Enum.map(user_ids, &"user:#{&1}")
Job Job
@ -591,7 +618,11 @@ defmodule Mix.Tasks.Wnh.StagingFullE2e do
[job], [job],
fragment("?->>'recipient' = ANY(?)", job.args, ^recipients) or fragment("?->>'recipient' = ANY(?)", job.args, ^recipients) or
fragment("?->>'request_id' = ANY(?)", job.args, ^request_ids) or fragment("?->>'request_id' = ANY(?)", job.args, ^request_ids) or
fragment("?->>'notification_id' = ANY(?)", job.args, ^notification_ids) fragment("?->>'notification_id' = ANY(?)", job.args, ^notification_ids) or
(job.worker in ^@support_job_workers and
fragment("?->>'request_id' = ANY(?)", job.args, ^support_request_ids)) or
(job.worker in ^@content_removal_job_workers and
fragment("?->>'notice_id' = ANY(?)", job.args, ^content_removal_notice_ids))
) )
|> select([job], job.id) |> select([job], job.id)
|> Repo.all() |> Repo.all()
@ -614,8 +645,20 @@ defmodule Mix.Tasks.Wnh.StagingFullE2e do
end end
end end
defp assert_no_late_fixture_jobs!(user_ids, request_ids, notification_ids) do defp assert_no_late_fixture_jobs!(
case fixture_job_ids(user_ids, request_ids, notification_ids) do user_ids,
request_ids,
notification_ids,
support_request_ids,
content_removal_notice_ids
) do
case fixture_job_ids(
user_ids,
request_ids,
notification_ids,
support_request_ids,
content_removal_notice_ids
) do
[] -> :ok [] -> :ok
ids -> Mix.raise("run-scoped Oban jobs appeared during cleanup: #{inspect(ids)}") ids -> Mix.raise("run-scoped Oban jobs appeared during cleanup: #{inspect(ids)}")
end end

View File

@ -0,0 +1,105 @@
defmodule WhoNeedHelp.StagingFullE2ECleanupTest do
use WhoNeedHelp.DataCase, async: false
use Oban.Testing, repo: WhoNeedHelp.Repo
import ExUnit.CaptureIO
alias Oban.Job
alias WhoNeedHelp.Accounts.{Scope, User}
alias WhoNeedHelp.{ContentRemoval, Repo, Support}
alias WhoNeedHelp.Mail.{ContentRemovalEmailWorker, SupportConfirmationWorker}
alias WhoNeedHelp.Push.NearbyMatchWorker
test "cleanup removes only run-owned support and legal mail jobs" do
run_id = "cleanup-#{System.unique_integer([:positive])}"
manifest_path = "/output/wnh-staging-full-e2e-#{run_id}.json"
password = "staging-cleanup-#{System.unique_integer([:positive])}"
%Postgrex.Result{rows: [[database]]} =
Repo.query!("SELECT current_database()", [], log: false)
env = %{
"WNH_STAGING_E2E_CONFIRM" => "public-staging-full-e2e",
"WNH_STAGING_E2E_EXPECTED_DATABASE" => database,
"WNH_STAGING_E2E_MANIFEST_PATH" => manifest_path,
"WNH_STAGING_E2E_PASSWORD" => password,
"WNH_STAGING_E2E_RUN_ID" => run_id
}
previous_env = Map.new(env, fn {name, _value} -> {name, System.get_env(name)} end)
Enum.each(env, fn {name, value} -> System.put_env(name, value) end)
on_exit(fn ->
File.rm(manifest_path)
Enum.each(previous_env, fn
{name, nil} -> System.delete_env(name)
{name, value} -> System.put_env(name, value)
end)
end)
run_task("prepare")
requester =
Repo.get_by!(User, email: "wnh-staging-e2e-#{run_id}-requester@example.invalid")
scope = Scope.for_user(requester)
assert {:ok, support_request} =
Support.create_request(scope, %{
"kind" => "technical_issue",
"subject" => "Run-scoped support cleanup",
"details" => "Verify that the exact support mail job is removed with its fixture."
})
support_job =
%{request_id: support_request.id}
|> SupportConfirmationWorker.new()
|> Repo.insert!()
assert {:ok, notice} =
ContentRemoval.create_notice(scope, :general, %{
"category" => "privacy_violation",
"submitter_name" => "Fixture requester",
"relationship" => "self",
"content_locations" => "https://example.test/requests/run-scoped-cleanup",
"explanation" =>
"Verify that the exact content-removal mail job is removed with its fixture.",
"electronic_signature" => "Fixture requester",
"good_faith" => "true",
"accurate_complete" => "true"
})
legal_job =
Repo.get_by!(Job,
worker: inspect(ContentRemovalEmailWorker),
args: %{"notice_id" => notice.id, "kind" => "received"}
)
unrelated_job =
%{request_id: support_request.id, event_key: "created"}
|> NearbyMatchWorker.new()
|> Repo.insert!()
run_task("cleanup")
manifest = manifest_path |> File.read!() |> Jason.decode!()
cleaned_job_ids = manifest["cleanup_targets"]["push_jobs"]
assert support_job.id in cleaned_job_ids
assert legal_job.id in cleaned_job_ids
refute unrelated_job.id in cleaned_job_ids
refute Repo.get(Job, support_job.id)
refute Repo.get(Job, legal_job.id)
assert Repo.get(Job, unrelated_job.id)
assert manifest["cleanup_verified"] == true
end
defp run_task(action) do
Mix.Task.reenable("wnh.staging_full_e2e")
capture_io(fn ->
Mix.Tasks.Wnh.StagingFullE2e.run([action])
end)
end
end