Files
EventHubBack/test/api/users/user_automod_tests.erl
aleksey 7368adfb37
CI / test (push) Successful in 6m45s
CI / deploy-ift (push) Successful in 3m42s
CI / e2e-ift (push) Successful in 1m26s
CI / deploy-stage (push) Successful in 2m13s
CI / e2e-stage (push) Successful in 1m10s
fix: automod CT seeds confirmed booking before calendar review. Refs EventHub/EventHubFront#8
2026-07-20 22:53:45 +03:00

162 lines
6.6 KiB
Erlang
Executable File

%%%-------------------------------------------------------------------
%%% @doc User-facing automod API: content reject + report threshold + review reports.
%%%-------------------------------------------------------------------
-module(user_automod_tests).
-include_lib("eunit/include/eunit.hrl").
-export([test/0]).
-spec test() -> ok.
test() ->
ct:pal("=== User Automod Tests ==="),
Admin = api_test_runner:get_admin_token(),
Unique = integer_to_binary(erlang:system_time()),
BadWord = <<"uam_bad_", Unique/binary>>,
_ = api_test_runner:admin_post(<<"/v1/admin/banned-words">>, Admin, #{<<"word">> => BadWord}),
test_reject_event_create(Admin, BadWord),
test_reject_calendar_create(Admin, BadWord),
test_report_threshold_freezes_event(Admin),
test_report_on_review(Admin),
test_dismissed_reports_do_not_freeze(Admin),
%% restore defaults
_ = api_test_runner:admin_put(<<"/v1/admin/automod/settings">>, Admin, #{
<<"keyword_action">> => <<"flag">>,
<<"match_mode">> => <<"word_boundary">>,
<<"report_threshold">> => 3
}),
ct:pal("=== All user automod tests passed ==="),
ok.
test_reject_event_create(Admin, BadWord) ->
ct:pal(" TEST: reject policy returns 400 on event create"),
_ = api_test_runner:admin_put(<<"/v1/admin/automod/settings">>, Admin, #{
<<"keyword_action">> => <<"reject">>
}),
User = api_test_runner:get_user_token(),
CalId = api_test_runner:create_calendar(User, #{title => <<"CleanCal">>}),
{ok, Status, _, Body} = api_test_runner:client_request(post,
<<"/v1/calendars/", CalId/binary, "/events">>, User,
jsx:encode(#{
title => <<"Has ", BadWord/binary>>,
start_time => api_test_runner:future_date_iso8601(),
duration => 30
})),
?assertEqual(400, Status),
?assert(binary:match(list_to_binary(Body), <<"banned">>) =/= nomatch),
ct:pal(" OK").
test_reject_calendar_create(Admin, BadWord) ->
ct:pal(" TEST: reject policy returns 400 on calendar create"),
_ = api_test_runner:admin_put(<<"/v1/admin/automod/settings">>, Admin, #{
<<"keyword_action">> => <<"reject">>
}),
User = api_test_runner:get_user_token(),
{ok, Status, _, _} = api_test_runner:client_request(post, <<"/v1/calendars">>, User,
jsx:encode(#{title => <<"Cal ", BadWord/binary>>, description => <<"x">>})),
?assertEqual(400, Status),
ct:pal(" OK").
test_report_threshold_freezes_event(Admin) ->
ct:pal(" TEST: 3 pending reports freeze event"),
_ = api_test_runner:admin_put(<<"/v1/admin/automod/settings">>, Admin, #{
<<"keyword_action">> => <<"flag">>,
<<"report_threshold">> => 3
}),
Owner = api_test_runner:get_user_token(),
CalId = api_test_runner:create_calendar(Owner, #{title => <<"RepThrCal">>}),
#{<<"id">> := EventId} = api_test_runner:client_post(
<<"/v1/calendars/", CalId/binary, "/events">>, Owner,
#{title => <<"Clean event">>,
start_time => api_test_runner:future_date_iso8601(),
duration => 60}),
lists:foreach(fun(_) ->
Tok = api_test_runner:get_user_token(),
{ok, 201, _, _} = api_test_runner:client_request(post, <<"/v1/reports">>, Tok,
jsx:encode(#{
target_type => <<"event">>,
target_id => EventId,
reason => <<"spam">>
}))
end, [1, 2, 3]),
Ev = api_test_runner:admin_get(<<"/v1/admin/events/", EventId/binary>>, Admin),
?assertEqual(<<"frozen">>, maps:get(<<"status">>, Ev)),
Hits = api_test_runner:admin_get(<<"/v1/admin/automod/hits?trigger=report_threshold">>, Admin),
?assert(lists:any(fun(H) -> maps:get(<<"entity_id">>, H) =:= EventId end, Hits)),
ct:pal(" OK").
test_report_on_review(Admin) ->
ct:pal(" TEST: report on review + threshold hides"),
_ = api_test_runner:admin_put(<<"/v1/admin/automod/settings">>, Admin, #{
<<"report_threshold">> => 3
}),
Owner = api_test_runner:get_user_token(),
CalId = api_test_runner:create_calendar(Owner, #{title => <<"RevRepCal">>}),
#{<<"id">> := EventId} = api_test_runner:client_post(
<<"/v1/calendars/", CalId/binary, "/events">>, Owner,
#{title => <<"Event for review report">>,
start_time => api_test_runner:future_date_iso8601(),
duration => 60}),
Reviewer = api_test_runner:get_user_token(),
#{<<"id">> := BookingId} = api_test_runner:client_post(
<<"/v1/events/", EventId/binary, "/bookings">>, Reviewer, #{}),
api_test_runner:client_put(<<"/v1/bookings/", BookingId/binary>>, Owner,
#{action => <<"confirm">>}),
{ok, 201, _, RevBody} = api_test_runner:client_request(post, <<"/v1/reviews">>, Reviewer,
jsx:encode(#{
target_type => <<"calendar">>,
target_id => CalId,
rating => 2,
comment => <<"meh">>
})),
#{<<"id">> := ReviewId} = jsx:decode(list_to_binary(RevBody), [return_maps]),
lists:foreach(fun(_) ->
Tok = api_test_runner:get_user_token(),
{ok, 201, _, _} = api_test_runner:client_request(post, <<"/v1/reports">>, Tok,
jsx:encode(#{
target_type => <<"review">>,
target_id => ReviewId,
reason => <<"abuse">>
}))
end, [1, 2, 3]),
Rev = api_test_runner:admin_get(<<"/v1/admin/reviews/", ReviewId/binary>>, Admin),
?assertEqual(<<"hidden">>, maps:get(<<"status">>, Rev)),
ct:pal(" OK").
test_dismissed_reports_do_not_freeze(Admin) ->
ct:pal(" TEST: dismissed reports do not freeze"),
_ = api_test_runner:admin_put(<<"/v1/admin/automod/settings">>, Admin, #{
<<"report_threshold">> => 3
}),
Owner = api_test_runner:get_user_token(),
CalId = api_test_runner:create_calendar(Owner, #{title => <<"DismissCal">>}),
#{<<"id">> := EventId} = api_test_runner:client_post(
<<"/v1/calendars/", CalId/binary, "/events">>, Owner,
#{title => <<"Still clean">>,
start_time => api_test_runner:future_date_iso8601(),
duration => 60}),
ReportIds = lists:map(fun(_) ->
Tok = api_test_runner:get_user_token(),
{ok, 201, _, B} = api_test_runner:client_request(post, <<"/v1/reports">>, Tok,
jsx:encode(#{
target_type => <<"event">>,
target_id => EventId,
reason => <<"noise">>
})),
maps:get(<<"id">>, jsx:decode(list_to_binary(B), [return_maps]))
end, [1, 2]),
lists:foreach(fun(Rid) ->
_ = api_test_runner:admin_put(<<"/v1/admin/reports/", Rid/binary>>, Admin,
#{<<"status">> => <<"dismissed">>})
end, ReportIds),
Tok3 = api_test_runner:get_user_token(),
{ok, 201, _, _} = api_test_runner:client_request(post, <<"/v1/reports">>, Tok3,
jsx:encode(#{
target_type => <<"event">>,
target_id => EventId,
reason => <<"one pending">>
})),
Ev = api_test_runner:admin_get(<<"/v1/admin/events/", EventId/binary>>, Admin),
?assertEqual(<<"active">>, maps:get(<<"status">>, Ev)),
ct:pal(" OK").