• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

esl / MongooseIM / 5487101041

pending completion
5487101041

push

github

DenysGonchar
adding optional CT suite/group/testcase logging at MIM node

27764 of 33096 relevant lines covered (83.89%)

36741.0 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.1
/src/pubsub/node_push.erl
1
%%%-------------------------------------------------------------------
2
%%% @author Rafal Slota
3
%%% @copyright (C) 2017 Erlang Solutions Ltd.
4
%%% This software is released under the Apache License, Version 2.0
5
%%% cited in 'LICENSE.txt'.
6
%%% @end
7
%%%-------------------------------------------------------------------
8
%%% @doc
9
%%% Node implementation that proxies all published items to `push_notification' hook.
10
%%% @end
11
%%%-------------------------------------------------------------------
12
-module(node_push).
13
-author('rafal.slota@erlang-solutions.com').
14
-behaviour(gen_pubsub_node).
15

16
-include("mongoose.hrl").
17
-include("jlib.hrl").
18
-include("pubsub.hrl").
19

20
-export([based_on/0, init/3, terminate/2, options/0, features/0,
21
         publish_item/9, node_to_path/1, should_delete_when_owner_removed/0]).
22

23
based_on() ->  node_flat.
2,142✔
24

25
init(Host, ServerHost, Opts) ->
26
    node_flat:init(Host, ServerHost, Opts),
95✔
27
    ok.
95✔
28

29
terminate(Host, ServerHost) ->
30
    node_flat:terminate(Host, ServerHost),
95✔
31
    ok.
95✔
32

33
options() ->
34
    [{deliver_payloads, true},
330✔
35
     {notify_config, false},
36
     {notify_delete, false},
37
     {notify_retract, false},
38
     {purge_offline, false},
39
     {persist_items, false},
40
     {max_items, 1},
41
     {subscribe, true},
42
     {access_model, whitelist},
43
     {roster_groups_allowed, []},
44
     {publish_model, open},
45
     {notification_type, headline},
46
     {max_payload_size, ?MAX_PAYLOAD_SIZE},
47
     {send_last_published_item, on_sub_and_presence},
48
     {deliver_notifications, true},
49
     {presence_based_delivery, true}].
50

51
features() ->
52
    [
1,622✔
53
        <<"create-nodes">>,
54
        <<"delete-nodes">>,
55
        <<"modify-affiliations">>,
56
        <<"publish">>,
57
        <<"publish-options">>,
58
        <<"publish-only-affiliation">>,
59
        <<"purge-nodes">>,
60
        <<"retrieve-affiliations">>
61
    ].
62

63
publish_item(ServerHost, Nidx, Publisher, Model, _MaxItems, _ItemId, _ItemPublisher, Payload,
64
             PublishOptions) ->
65
    {ok, Affiliation} = mod_pubsub_db_backend:get_affiliation(Nidx, jid:to_lower(Publisher)),
403✔
66
    ElPayload = [El || #xmlel{} = El <- Payload],
403✔
67

68
    case is_allowed_to_publish(Model, Affiliation) of
403✔
69
        true ->
70
            do_publish_item(ServerHost, PublishOptions, ElPayload);
396✔
71
        false ->
72
            {error, mongoose_xmpp_errors:forbidden()}
7✔
73
    end.
74

75
do_publish_item(ServerHost, PublishOptions,
76
                [#xmlel{name = <<"notification">>} | _] = Notifications) ->
77
    case parse_form(PublishOptions) of
389✔
78
        #{<<"device_id">> := _, <<"service">> := _} = OptionMap ->
79
            NotificationForms = [parse_form(El) || El <- Notifications],
382✔
80
            Result = mongoose_hooks:push_notifications(ServerHost, ok,
382✔
81
                                                       NotificationForms, OptionMap),
82
            handle_push_hook_result(Result);
382✔
83
        _ ->
84
            {error, mod_pubsub:extended_error(mongoose_xmpp_errors:conflict(), <<"precondition-not-met">>)}
7✔
85
    end;
86
do_publish_item(_ServerHost, _PublishOptions, _Payload) ->
87
    {error, mongoose_xmpp_errors:bad_request()}.
7✔
88

89
handle_push_hook_result(ok) ->
90
    {result, default};
354✔
91
handle_push_hook_result({error, device_not_registered}) ->
92
    {error, mod_pubsub:extended_error(mongoose_xmpp_errors:not_acceptable_cancel(), <<"device-not-registered">>)};
7✔
93
handle_push_hook_result({error, _}) ->
94
    {error, mod_pubsub:extended_error(mongoose_xmpp_errors:bad_request(), <<"faild-to-submit-push-notification">>)}.
21✔
95

96
node_to_path(Node) ->
97
    node_flat:node_to_path(Node).
330✔
98

99
should_delete_when_owner_removed() -> true.
16✔
100

101
%%%
102
%%% Internal
103
%%%
104

105
is_allowed_to_publish(PublishModel, Affiliation) ->
106
    (PublishModel == open)
107
    or (PublishModel == publishers)
403✔
108
        and ((Affiliation == owner)
109
              or (Affiliation == publisher)
110
              or (Affiliation == publish_only)).
111

112
-spec parse_form(undefined | exml:element()) -> invalid_form | #{binary() => binary()}.
113
parse_form(undefined) ->
114
    #{};
7✔
115
parse_form(Parent) ->
116
    case mongoose_data_forms:find_and_parse_form(Parent) of
764✔
117
        #{type := <<"submit">>, kvs := KVs} ->
118
            maps:filtermap(fun(_, [V]) -> {true, V};
764✔
119
                              (_, _) -> false
×
120
                           end, KVs);
121
        _ ->
122
            invalid_form
×
123
    end.
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc