177 lines
8.2 KiB
Erlang
177 lines
8.2 KiB
Erlang
%%%-------------------------------------------------------------------
|
||
%%% @doc Тесты административного API для управления бан-словами.
|
||
%%%
|
||
%%% Покрывает эндпоинты:
|
||
%%% GET /v1/admin/banned-words
|
||
%%% POST /v1/admin/banned-words
|
||
%%% PUT /v1/admin/banned-words/:word
|
||
%%% DELETE /v1/admin/banned-words/:word
|
||
%%% POST /v1/admin/banned-words/batch
|
||
%%%
|
||
%%% Проверяет:
|
||
%%% - получение списка слов
|
||
%%% - добавление нового слова
|
||
%%% - редактирование существующего слова
|
||
%%% - удаление слова
|
||
%%% - массовую загрузку списком
|
||
%%% - пагинацию
|
||
%%% @end
|
||
%%%-------------------------------------------------------------------
|
||
-module(admin_banned_words_tests).
|
||
-include_lib("eunit/include/eunit.hrl").
|
||
-export([test/0]).
|
||
|
||
%%%===================================================================
|
||
%%% Главная тестовая функция
|
||
%%%===================================================================
|
||
-spec test() -> ok.
|
||
test() ->
|
||
ct:pal("=== Admin Banned Words Tests ==="),
|
||
Token = api_test_runner:get_admin_token(),
|
||
|
||
% Добавляем два исходных слова
|
||
Unique = integer_to_binary(erlang:system_time()),
|
||
Word1 = <<"badword1_", Unique/binary>>,
|
||
Word2 = <<"badword2_", Unique/binary>>,
|
||
api_test_runner:admin_post(<<"/v1/admin/banned-words">>, Token, #{<<"word">> => Word1}),
|
||
api_test_runner:admin_post(<<"/v1/admin/banned-words">>, Token, #{<<"word">> => Word2}),
|
||
|
||
test_list_words(Token, Word1, Word2),
|
||
test_add_word(Token),
|
||
test_update_word(Token, Word1),
|
||
test_batch_add_words(Token),
|
||
test_words_pagination(Token),
|
||
test_delete_word(Token, Word2),
|
||
test_update_word_conflict(Token),
|
||
test_batch_add_invalid(Token),
|
||
test_batch_add_duplicates(Token),
|
||
|
||
ct:pal("=== All admin banned words tests passed ==="),
|
||
ok.
|
||
|
||
%%%===================================================================
|
||
%%% Тестовые функции
|
||
%%%===================================================================
|
||
|
||
%% @doc GET /v1/admin/banned-words – список всех слов.
|
||
-spec test_list_words(binary(), binary(), binary()) -> ok.
|
||
test_list_words(Token, Word1, Word2) ->
|
||
ct:pal(" TEST: List all banned words"),
|
||
Words = api_test_runner:admin_get(<<"/v1/admin/banned-words">>, Token),
|
||
?assert(is_list(Words)),
|
||
?assert(length(Words) >= 2),
|
||
?assert(lists:any(fun(W) -> maps:get(<<"word">>, W) =:= Word1 orelse maps:get(<<"word">>, W) =:= Word2 end, Words)),
|
||
ct:pal(" OK: ~p words", [length(Words)]).
|
||
|
||
%% @doc POST /v1/admin/banned-words – добавление нового слова.
|
||
-spec test_add_word(binary()) -> ok.
|
||
test_add_word(Token) ->
|
||
ct:pal(" TEST: Add a new banned word"),
|
||
Unique = integer_to_binary(erlang:system_time()),
|
||
NewWord = <<"newbadword", Unique/binary>>,
|
||
Result = api_test_runner:admin_post(<<"/v1/admin/banned-words">>, Token, #{<<"word">> => NewWord}),
|
||
?assertEqual(<<"added">>, maps:get(<<"status">>, Result)),
|
||
Words = api_test_runner:admin_get(<<"/v1/admin/banned-words">>, Token),
|
||
?assert(lists:any(fun(W) -> maps:get(<<"word">>, W) =:= NewWord end, Words)),
|
||
ct:pal(" OK").
|
||
|
||
%% @doc PUT /v1/admin/banned-words/:word – редактирование слова.
|
||
-spec test_update_word(binary(), binary()) -> ok.
|
||
test_update_word(Token, Word) ->
|
||
ct:pal(" TEST: Update a banned word"),
|
||
NewWord = <<Word/binary, "_updated">>,
|
||
Result = api_test_runner:admin_put(<<"/v1/admin/banned-words/", Word/binary>>, Token, #{<<"word">> => NewWord}),
|
||
?assertEqual(<<"updated">>, maps:get(<<"status">>, Result)),
|
||
% Проверяем, что старое слово отсутствует, а новое присутствует
|
||
Words = api_test_runner:admin_get(<<"/v1/admin/banned-words">>, Token),
|
||
?assertNot(lists:any(fun(W) -> maps:get(<<"word">>, W) =:= Word end, Words)),
|
||
?assert(lists:any(fun(W) -> maps:get(<<"word">>, W) =:= NewWord end, Words)),
|
||
ct:pal(" OK").
|
||
|
||
%% @doc POST /v1/admin/banned-words/batch – массовая загрузка.
|
||
-spec test_batch_add_words(binary()) -> ok.
|
||
test_batch_add_words(Token) ->
|
||
ct:pal(" TEST: Batch add banned words"),
|
||
Unique = integer_to_binary(erlang:system_time()),
|
||
Words = [
|
||
<<"batch1_", Unique/binary>>,
|
||
<<"batch2_", Unique/binary>>,
|
||
<<"batch3_", Unique/binary>>
|
||
],
|
||
Body = jsx:encode(#{<<"words">> => Words}),
|
||
{ok, 200, _, RespBody} = api_test_runner:admin_request(post, <<"/v1/admin/banned-words/batch">>, Token, Body),
|
||
Result = jsx:decode(list_to_binary(RespBody), [return_maps]),
|
||
?assertEqual(3, maps:get(<<"added">>, Result)),
|
||
?assertEqual(0, maps:get(<<"skipped">>, Result)),
|
||
% Проверяем наличие всех слов
|
||
AllWords = api_test_runner:admin_get(<<"/v1/admin/banned-words">>, Token),
|
||
[?assert(lists:any(fun(W) -> maps:get(<<"word">>, W) =:= Word end, AllWords)) || Word <- Words],
|
||
ct:pal(" OK").
|
||
|
||
%% @doc DELETE /v1/admin/banned-words/:word – удаление слова.
|
||
-spec test_delete_word(binary(), binary()) -> ok.
|
||
test_delete_word(Token, Word) ->
|
||
ct:pal(" TEST: Delete a banned word"),
|
||
Path = <<"/v1/admin/banned-words/", Word/binary>>,
|
||
Result = api_test_runner:admin_delete(Path, Token),
|
||
?assertEqual(<<"deleted">>, maps:get(<<"status">>, Result)),
|
||
Words = api_test_runner:admin_get(<<"/v1/admin/banned-words">>, Token),
|
||
?assertNot(lists:any(fun(W) -> maps:get(<<"word">>, W) =:= Word end, Words)),
|
||
ct:pal(" OK").
|
||
|
||
%% @doc GET /v1/admin/banned-words?limit=...&offset=... – пагинация.
|
||
-spec test_words_pagination(binary()) -> ok.
|
||
test_words_pagination(Token) ->
|
||
ct:pal(" TEST: Banned words pagination"),
|
||
Page1 = api_test_runner:admin_get(<<"/v1/admin/banned-words?limit=1&offset=0">>, Token),
|
||
?assert(length(Page1) >= 1),
|
||
Page2 = api_test_runner:admin_get(<<"/v1/admin/banned-words?limit=1&offset=1">>, Token),
|
||
?assert(length(Page2) >= 1),
|
||
Id1 = maps:get(<<"id">>, hd(Page1)),
|
||
Id2 = maps:get(<<"id">>, hd(Page2)),
|
||
?assertNotEqual(Id1, Id2),
|
||
ct:pal(" OK").
|
||
|
||
%% @doc PUT /v1/admin/banned-words/:word – попытка переименовать в уже существующее слово.
|
||
test_update_word_conflict(Token) ->
|
||
ct:pal(" TEST: Update banned word to existing word"),
|
||
Unique = integer_to_binary(erlang:system_time()),
|
||
WordA = <<"conflictA_", Unique/binary>>,
|
||
WordB = <<"conflictB_", Unique/binary>>,
|
||
api_test_runner:admin_post(<<"/v1/admin/banned-words">>, Token, #{<<"word">> => WordA}),
|
||
api_test_runner:admin_post(<<"/v1/admin/banned-words">>, Token, #{<<"word">> => WordB}),
|
||
Path = <<"/v1/admin/banned-words/", WordA/binary>>,
|
||
{ok, 409, _, _} = api_test_runner:admin_request(put, Path, Token, jsx:encode(#{<<"word">> => WordB})),
|
||
ct:pal(" OK: got 409 conflict").
|
||
|
||
%% @doc POST /v1/admin/banned-words/batch – с невалидными элементами.
|
||
test_batch_add_invalid(Token) ->
|
||
ct:pal(" TEST: Batch add with invalid items"),
|
||
Unique = integer_to_binary(erlang:system_time()),
|
||
Words = [
|
||
<<"valid_", Unique/binary>>,
|
||
null,
|
||
12345,
|
||
<<"valid2_", Unique/binary>>
|
||
],
|
||
Body = jsx:encode(#{<<"words">> => Words}),
|
||
{ok, 200, _, RespBody} = api_test_runner:admin_request(post, <<"/v1/admin/banned-words/batch">>, Token, Body),
|
||
Result = jsx:decode(list_to_binary(RespBody), [return_maps]),
|
||
?assertEqual(2, maps:get(<<"added">>, Result)),
|
||
?assertEqual(0, maps:get(<<"skipped">>, Result)),
|
||
?assertEqual(2, maps:get(<<"invalid_count">>, Result)),
|
||
ct:pal(" OK: invalid items filtered").
|
||
|
||
%% @doc POST /v1/admin/banned-words/batch – с дубликатами.
|
||
test_batch_add_duplicates(Token) ->
|
||
ct:pal(" TEST: Batch add with duplicates"),
|
||
Unique = integer_to_binary(erlang:system_time()),
|
||
Word1 = <<"dup1_", Unique/binary>>,
|
||
Word2 = <<"dup2_", Unique/binary>>,
|
||
Words = [Word1, Word2, Word1, Word2],
|
||
Body = jsx:encode(#{<<"words">> => Words}),
|
||
{ok, 200, _, RespBody} = api_test_runner:admin_request(post, <<"/v1/admin/banned-words/batch">>, Token, Body),
|
||
Result = jsx:decode(list_to_binary(RespBody), [return_maps]),
|
||
?assertEqual(2, maps:get(<<"added">>, Result)),
|
||
?assertEqual(2, maps:get(<<"skipped">>, Result)),
|
||
ct:pal(" OK: duplicates handled"). |