Files
EventHubBack/test/unit/admin_handler_automod_tests.erl
aleksey e9d1a13900
CI / test (push) Failing after 37m9s
CI / deploy-ift (push) Has been skipped
CI / e2e-ift (push) Has been skipped
CI / deploy-stage (push) Has been skipped
CI / e2e-stage (push) Has been skipped
Добавить автомодерацию: политики, порог жалоб, settings/hits API и тесты.
Refs EventHub/EventHubBack#37
Refs EventHub/EventHubBack#38
Refs EventHub/EventHubBack#39
Refs EventHub/EventHubBack#40
2026-07-17 18:09:31 +03:00

189 lines
7.2 KiB
Erlang
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-module(admin_handler_automod_tests).
-include_lib("eunit/include/eunit.hrl").
-include("records.hrl").
-define(TABLES, [admin, admin_audit, automod_settings, automod_hit, banned_word,
user, calendar, event]).
-define(ADMIN_ID, <<"adm_automod">>).
-define(MOD_ID, <<"mod_automod">>).
setup() ->
eh_test_support:start_mnesia(),
eh_test_support:ensure_tables(?TABLES),
eh_test_support:ensure_jwt(),
eh_test_support:seed_admin(#{id => ?ADMIN_ID, role => admin}),
eh_test_support:seed_admin(#{id => ?MOD_ID, role => moderator, email => <<"m@t.local">>}),
core_automod_settings:ensure_defaults(),
ok.
cleanup(_) ->
eh_test_support:unload_cowboy(),
eh_test_support:delete_tables(?TABLES),
eh_test_support:stop_mnesia(),
ok.
admin_handler_automod_test_() ->
{foreach, fun setup/0, fun cleanup/1, [
{"GET settings 200", fun test_get_settings/0},
{"GET settings 401", fun test_get_settings_unauth/0},
{"PUT settings admin ok", fun test_put_settings/0},
{"PUT settings moderator forbidden", fun test_put_settings_moderator/0},
{"PUT settings invalid threshold", fun test_put_settings_bad/0},
{"GET hits list and filter", fun test_list_hits/0},
{"PUT hit approve", fun test_approve_hit/0},
{"PUT hit reject", fun test_reject_hit/0},
{"PUT hit not found", fun test_hit_not_found/0},
{"PUT hit already resolved", fun test_hit_already_resolved/0},
{"moderator can list and resolve hits", fun test_moderator_hits/0}
]}.
test_get_settings() ->
{Status, _, Body} = eh_test_support:call(admin_handler_automod, #{
method => <<"GET">>,
path => <<"/v1/admin/automod/settings">>,
auth => ?ADMIN_ID
}),
?assertEqual(200, Status),
Map = jsx:decode(Body, [return_maps]),
?assertEqual(<<"flag">>, maps:get(<<"keyword_action">>, Map)),
?assertEqual(<<"word_boundary">>, maps:get(<<"match_mode">>, Map)),
?assertEqual(3, maps:get(<<"report_threshold">>, Map)).
test_get_settings_unauth() ->
{Status, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"GET">>,
path => <<"/v1/admin/automod/settings">>,
auth => none
}),
?assertEqual(401, Status).
test_put_settings() ->
{Status, _, Body} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/settings">>,
auth => ?ADMIN_ID,
body => jsx:encode(#{
<<"keyword_action">> => <<"reject">>,
<<"match_mode">> => <<"substring">>,
<<"report_threshold">> => 7
})
}),
?assertEqual(200, Status),
Map = jsx:decode(Body, [return_maps]),
?assertEqual(<<"reject">>, maps:get(<<"keyword_action">>, Map)),
?assertEqual(<<"substring">>, maps:get(<<"match_mode">>, Map)),
?assertEqual(7, maps:get(<<"report_threshold">>, Map)).
test_put_settings_moderator() ->
{Status, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/settings">>,
auth => ?MOD_ID,
body => jsx:encode(#{<<"report_threshold">> => 2})
}),
?assertEqual(403, Status).
test_put_settings_bad() ->
{Status, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/settings">>,
auth => ?ADMIN_ID,
body => jsx:encode(#{<<"report_threshold">> => 0})
}),
?assertEqual(400, Status).
test_list_hits() ->
{ok, H1} = core_automod_hit:create(event, <<"e1">>, keyword, [<<"a">>], flag),
{ok, _} = core_automod_hit:create(calendar, <<"c1">>, report_threshold, [], freeze),
{ok, _} = core_automod_hit:resolve(H1#automod_hit.id, approved, ?ADMIN_ID),
{Status, _, Body} = eh_test_support:call(admin_handler_automod, #{
method => <<"GET">>,
path => <<"/v1/admin/automod/hits">>,
auth => ?ADMIN_ID,
qs => [{<<"status">>, <<"open">>}]
}),
?assertEqual(200, Status),
List = jsx:decode(Body, [return_maps]),
?assertEqual(1, length(List)),
?assertEqual(<<"open">>, maps:get(<<"status">>, hd(List))).
test_approve_hit() ->
Owner = seed_user(),
{ok, Cal} = core_calendar:create(Owner, <<"C">>, <<>>, manual),
{ok, Ev} = core_event:create(Cal#calendar.id, <<"t">>, eh_test_support:future_start(), 60),
_ = core_event:freeze(Ev#event.id, <<"auto:keyword">>),
{ok, Hit} = core_automod_hit:create(event, Ev#event.id, keyword, [<<"x">>], flag),
{Status, _, Body} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/hits/", (Hit#automod_hit.id)/binary>>,
auth => ?ADMIN_ID,
bindings => #{id => Hit#automod_hit.id},
body => jsx:encode(#{<<"status">> => <<"approved">>})
}),
?assertEqual(200, Status),
Map = jsx:decode(Body, [return_maps]),
?assertEqual(<<"approved">>, maps:get(<<"status">>, Map)),
{ok, Active} = core_event:get_by_id(Ev#event.id),
?assertEqual(active, Active#event.status).
test_reject_hit() ->
Owner = seed_user(),
{ok, Cal} = core_calendar:create(Owner, <<"C">>, <<>>, manual),
{ok, Ev} = core_event:create(Cal#calendar.id, <<"t">>, eh_test_support:future_start(), 60),
{ok, Hit} = core_automod_hit:create(event, Ev#event.id, keyword, [<<"x">>], flag),
{Status, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/hits/", (Hit#automod_hit.id)/binary>>,
auth => ?ADMIN_ID,
bindings => #{id => Hit#automod_hit.id},
body => jsx:encode(#{<<"status">> => <<"rejected">>})
}),
?assertEqual(200, Status),
{ok, Frozen} = core_event:get_by_id(Ev#event.id),
?assertEqual(frozen, Frozen#event.status).
test_hit_not_found() ->
{Status, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/hits/missing">>,
auth => ?ADMIN_ID,
bindings => #{id => <<"missing">>},
body => jsx:encode(#{<<"status">> => <<"approved">>})
}),
?assertEqual(404, Status).
test_hit_already_resolved() ->
{ok, Hit} = core_automod_hit:create(event, <<"e">>, keyword, [], flag),
{ok, _} = core_automod_hit:resolve(Hit#automod_hit.id, approved, ?ADMIN_ID),
{Status, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/hits/", (Hit#automod_hit.id)/binary>>,
auth => ?ADMIN_ID,
bindings => #{id => Hit#automod_hit.id},
body => jsx:encode(#{<<"status">> => <<"rejected">>})
}),
?assertEqual(409, Status).
test_moderator_hits() ->
{ok, Hit} = core_automod_hit:create(event, <<"e2">>, keyword, [<<"z">>], flag),
{StatusList, _, _} = eh_test_support:call(admin_handler_automod, #{
method => <<"GET">>,
path => <<"/v1/admin/automod/hits">>,
auth => ?MOD_ID
}),
?assertEqual(200, StatusList),
{StatusPut, _, Body} = eh_test_support:call(admin_handler_automod, #{
method => <<"PUT">>,
path => <<"/v1/admin/automod/hits/", (Hit#automod_hit.id)/binary>>,
auth => ?MOD_ID,
bindings => #{id => Hit#automod_hit.id},
body => jsx:encode(#{<<"status">> => <<"approved">>})
}),
?assertEqual(200, StatusPut),
?assertEqual(<<"approved">>, maps:get(<<"status">>, jsx:decode(Body, [return_maps]))).
seed_user() ->
Id = base64:encode(crypto:strong_rand_bytes(10), #{mode => urlsafe, padding => false}),
mnesia:dirty_write(eh_test_support:make_user(#{id => Id, email => <<Id/binary, "@t.com">>})),
Id.