Files
EventHubBack/test/unit/logic_upload_tests.erl
T
aleksey 29111cd514 feat(upload): avatar and calendar cover via local disk storage.
POST /v1/user/me/avatar and /v1/calendars/:id/cover; GET /v1/media;
UPLOAD_DIR on eventhub-data volume; MIME/size limits.
Refs EventHub/EventHubBack#71
Refs EventHub/EventHubSpec#8
2026-08-14 21:27:34 +03:00

79 lines
2.7 KiB
Erlang

-module(logic_upload_tests).
-include_lib("eunit/include/eunit.hrl").
logic_upload_test_() ->
{foreach, fun setup/0, fun cleanup/1, [
{"png avatar saves and serves path", fun test_png_avatar/0},
{"jpeg ok", fun test_jpeg/0},
{"webp ok", fun test_webp/0},
{"too large", fun test_too_large/0},
{"unsupported media", fun test_bad_media/0},
{"path traversal rejected", fun test_bad_path/0},
{"cover + delete old url", fun test_cover_and_delete/0}
]}.
setup() ->
Dir = "/tmp/eh-upload-test-" ++ integer_to_list(erlang:unique_integer([positive])),
ok = filelib:ensure_dir(filename:join(Dir, "dummy")),
application:set_env(eventhub, upload_dir, Dir),
application:set_env(eventhub, upload_max_bytes, 1024),
Dir.
cleanup(Dir) ->
application:unset_env(eventhub, upload_dir),
application:unset_env(eventhub, upload_max_bytes),
_ = os:cmd("rm -rf " ++ Dir),
ok.
png() ->
<<137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 0>>.
jpeg() ->
<<16#FF, 16#D8, 16#FF, 16#E0, 0, 0>>.
webp() ->
<<"RIFF", 0, 0, 0, 0, "WEBP", 0, 0>>.
test_png_avatar() ->
UserId = <<"user1">>,
{ok, Url} = logic_upload:save_avatar(UserId, png()),
?assertMatch(<<"/v1/media/avatar/user1/", _/binary>>, Url),
<<"/v1/media/", Rest/binary>> = Url,
[<<"avatar">>, <<"user1">>, File] = binary:split(Rest, <<"/">>, [global]),
{ok, Path} = logic_upload:media_abs_path(avatar, UserId, File),
{ok, Bin} = file:read_file(Path),
?assertEqual(png(), Bin).
test_jpeg() ->
{ok, Url} = logic_upload:save_avatar(<<"u">>, jpeg()),
?assert(binary:match(Url, <<".jpg">>) =/= nomatch).
test_webp() ->
{ok, Url} = logic_upload:save_cover(<<"cal1">>, <<"owner">>, webp()),
?assert(binary:match(Url, <<".webp">>) =/= nomatch),
?assertMatch(<<"/v1/media/cover/cal1/", _/binary>>, Url).
test_too_large() ->
Big = list_to_binary(lists:duplicate(2000, $x)),
%% not a valid image either, but size checked first
?assertEqual({error, too_large}, logic_upload:save_avatar(<<"u">>, Big)).
test_bad_media() ->
?assertEqual({error, unsupported_media},
logic_upload:save_avatar(<<"u">>, <<"not-an-image">>)).
test_bad_path() ->
?assertEqual({error, invalid},
logic_upload:media_abs_path(avatar, <<"../x">>, <<"a.jpg">>)),
?assertEqual({error, invalid},
logic_upload:media_abs_path(avatar, <<"u">>, <<"../a.jpg">>)).
test_cover_and_delete() ->
{ok, Url1} = logic_upload:save_cover(<<"c">>, <<"o">>, png()),
<<"/v1/media/", Rest/binary>> = Url1,
[<<"cover">>, <<"c">>, File] = binary:split(Rest, <<"/">>, [global]),
{ok, Path} = logic_upload:media_abs_path(cover, <<"c">>, File),
?assert(filelib:is_regular(Path)),
ok = logic_upload:maybe_delete_url(Url1),
?assertNot(filelib:is_regular(Path)).