Merge remote-tracking branch 'origin/main'

This commit is contained in:
Weblate
2026-09-27 11:33:22 +00:00
2 changed files with 139 additions and 5 deletions
@@ -8,6 +8,9 @@
-export_type([context/0]).
-define(MAX_GUILD_FEATURES, 64).
-define(MESSAGE_TYPE_DEFAULT, 0).
-define(MESSAGE_TYPE_REPLY, 19).
-define(PUSHABLE_MESSAGE_TYPES, [?MESSAGE_TYPE_DEFAULT, ?MESSAGE_TYPE_REPLY]).
-type context() :: #{
message_data := map(),
@@ -110,7 +113,24 @@ validate(#{message_id := undefined}) ->
validate(#{guild_default_notifications := undefined}) ->
{error, invalid_guild_default_notifications};
validate(Context) ->
{ok, Context}.
validate_message_type(message_type(Context), Context).
-spec validate_message_type(integer(), context()) -> {ok, context()} | {error, term()}.
validate_message_type(Type, Context) ->
case lists:member(Type, ?PUSHABLE_MESSAGE_TYPES) of
true -> {ok, Context};
false -> {error, {unpushable_message_type, Type}}
end.
-spec message_type(context()) -> integer().
message_type(#{message_data := MessageData}) ->
normalize_message_type(maps:get(<<"type">>, MessageData, ?MESSAGE_TYPE_DEFAULT)).
-spec normalize_message_type(term()) -> integer().
normalize_message_type(Type) when is_integer(Type) ->
Type;
normalize_message_type(_Type) ->
?MESSAGE_TYPE_DEFAULT.
-spec owner_fallback_key(map()) -> term().
owner_fallback_key(Params) ->
@@ -163,3 +183,51 @@ markdown_context(MessageData, GuildId, RoleNames, _RawContext) when
push_notification_format:build_markdown_context(MessageData, GuildId, RoleNames, #{});
markdown_context(_MessageData, _GuildId, _RoleNames, RawContext) ->
optional_map(RawContext).
-ifdef(TEST).
-include_lib("eunit/include/eunit.hrl").
params_with_message_type(Type) ->
#{
message_data => #{
<<"channel_id">> => <<"1472201127385612376">>,
<<"id">> => <<"1472201127385612377">>,
<<"type">> => Type
},
user_ids => [<<"1474262819227156566">>],
guild_id => <<"1472200708085309475">>,
author_id => <<"1472583967301656587">>,
guild_default_notifications => 0
}.
context_allows_a_default_message_test() ->
?assertMatch({ok, _}, context(params_with_message_type(?MESSAGE_TYPE_DEFAULT))).
context_allows_a_reply_test() ->
?assertMatch({ok, _}, context(params_with_message_type(?MESSAGE_TYPE_REPLY))).
context_rejects_a_call_system_message_test() ->
?assertEqual(
{error, {unpushable_message_type, 3}}, context(params_with_message_type(3))
).
context_rejects_every_non_authored_message_type_test() ->
lists:foreach(
fun(Type) ->
?assertEqual(
{error, {unpushable_message_type, Type}},
context(params_with_message_type(Type))
)
end,
[1, 2, 3, 4, 5, 6, 7, 99]
).
context_treats_a_missing_message_type_as_pushable_test() ->
Params = params_with_message_type(?MESSAGE_TYPE_DEFAULT),
MessageData = maps:remove(<<"type">>, maps:get(message_data, Params)),
?assertMatch({ok, _}, context(Params#{message_data := MessageData})).
context_treats_a_malformed_message_type_as_pushable_test() ->
?assertMatch({ok, _}, context(params_with_message_type(<<"nonsense">>))).
-endif.
@@ -33,7 +33,7 @@ build_content_preview(MessageData, MarkdownContext) ->
Preview = push_markdown_plaintext:render_push_preview(Content, MarkdownContext),
case Preview of
<<>> ->
truncate_preview(build_content_fallback_preview(MessageData));
truncate_preview(build_content_fallback_preview(MessageData, MarkdownContext));
_ ->
truncate_preview(Preview)
end.
@@ -372,13 +372,37 @@ valid_utf8_prefix(Content) ->
{error, Valid, _Rest} -> Valid
end.
-spec build_content_fallback_preview(map()) -> binary().
build_content_fallback_preview(MessageData) ->
-spec build_content_fallback_preview(map(), map()) -> binary().
build_content_fallback_preview(MessageData, MarkdownContext) ->
case
first_nonempty_binary([
build_sticker_preview(maps:get(<<"stickers">>, MessageData, [])),
build_attachment_preview(maps:get(<<"attachments">>, MessageData, [])),
build_embed_preview(maps:get(<<"embeds">>, MessageData, []))
build_embed_preview(maps:get(<<"embeds">>, MessageData, [])),
build_snapshot_preview(
maps:get(<<"message_snapshots">>, MessageData, []), MarkdownContext
)
])
of
Preview when is_binary(Preview) -> Preview;
undefined -> <<>>
end.
-spec build_snapshot_preview(term(), map()) -> binary().
build_snapshot_preview([Snapshot | _Rest], MarkdownContext) when is_map(Snapshot) ->
snapshot_preview(Snapshot, MarkdownContext);
build_snapshot_preview(_Snapshots, _MarkdownContext) ->
<<>>.
-spec snapshot_preview(map(), map()) -> binary().
snapshot_preview(Snapshot, MarkdownContext) ->
Content = push_utils:normalize_binary(maps:get(<<"content">>, Snapshot, <<>>), <<>>),
case
first_nonempty_binary([
push_markdown_plaintext:render_push_preview(Content, MarkdownContext),
build_sticker_preview(maps:get(<<"stickers">>, Snapshot, [])),
build_attachment_preview(maps:get(<<"attachments">>, Snapshot, [])),
build_embed_preview(maps:get(<<"embeds">>, Snapshot, []))
])
of
Preview when is_binary(Preview) -> Preview;
@@ -639,6 +663,48 @@ truncate_preview_keeps_short_valid_content_identical_test() ->
Content = <<"hello \xC3\xA9 world">>,
?assertEqual(Content, truncate_preview(Content)).
a_forwarded_message_previews_its_snapshot_content_test() ->
MessageData = #{
<<"content">> => <<>>,
<<"message_snapshots">> => [#{<<"content">> => <<"forwarded text">>}]
},
?assertEqual(<<"forwarded text">>, build_content_preview(MessageData)).
a_forwarded_attachment_previews_its_filename_test() ->
MessageData = #{
<<"content">> => <<>>,
<<"message_snapshots">> => [
#{<<"content">> => null, <<"attachments">> => [#{<<"filename">> => <<"cat.png">>}]}
]
},
?assertEqual(<<"Attachment: cat.png">>, build_content_preview(MessageData)).
a_forwarded_sticker_previews_its_name_test() ->
MessageData = #{
<<"content">> => <<>>,
<<"message_snapshots">> => [
#{<<"content">> => null, <<"stickers">> => [#{<<"name">> => <<"Wave">>}]}
]
},
?assertEqual(<<"Sticker: Wave">>, build_content_preview(MessageData)).
own_content_wins_over_a_snapshot_test() ->
MessageData = #{
<<"content">> => <<"my words">>,
<<"message_snapshots">> => [#{<<"content">> => <<"forwarded text">>}]
},
?assertEqual(<<"my words">>, build_content_preview(MessageData)).
an_empty_snapshot_list_previews_nothing_test() ->
?assertEqual(
<<>>, build_content_preview(#{<<"content">> => <<>>, <<"message_snapshots">> => []})
).
a_null_snapshot_field_previews_nothing_test() ->
?assertEqual(
<<>>, build_content_preview(#{<<"content">> => <<>>, <<"message_snapshots">> => null})
).
build_url_dm_test() ->
?assertEqual(<<"/channels/@me/456/789">>, build_url(0, 456, 789)).