Commit 2af5c910dac6e2d55503d8927e5b98af2ee0f084
1 parent
4b11b708
Exists in
staging
and in
32 other branches
Push Notification plugin
Enables push notification for mobile platforms using Google Cloud Message infrastructure. - Administrators can choose among all available notification - Users can activate notifications through API and GUI - Users devices MUST be registered through API to use push notifications - Other plugins can add users to be notified for each notification. - Available notifications can be found in the file "notification_settings.rb" Signed-off-by: Marcos Ramos <ms.ramos@outlook.com> Signed-off-by: Marcos Ronaldo <marcos.rpj2@gmail.com>
Showing
45 changed files
with
1579 additions
and
0 deletions
Show diff stats
app/models/article.rb
@@ -12,6 +12,7 @@ class Article < ActiveRecord::Base | @@ -12,6 +12,7 @@ class Article < ActiveRecord::Base | ||
12 | :author, :display_preview, :published_at, :person_followers | 12 | :author, :display_preview, :published_at, :person_followers |
13 | 13 | ||
14 | acts_as_having_image | 14 | acts_as_having_image |
15 | + include Noosfero::Plugin::HotSpot | ||
15 | 16 | ||
16 | SEARCHABLE_FIELDS = { | 17 | SEARCHABLE_FIELDS = { |
17 | :name => {:label => _('Name'), :weight => 10}, | 18 | :name => {:label => _('Name'), :weight => 10}, |
app/models/task.rb
@@ -31,6 +31,8 @@ class Task < ActiveRecord::Base | @@ -31,6 +31,8 @@ class Task < ActiveRecord::Base | ||
31 | end | 31 | end |
32 | end | 32 | end |
33 | 33 | ||
34 | + include Noosfero::Plugin::HotSpot | ||
35 | + | ||
34 | belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id | 36 | belongs_to :requestor, :class_name => 'Profile', :foreign_key => :requestor_id |
35 | belongs_to :target, :foreign_key => :target_id, :polymorphic => true | 37 | belongs_to :target, :foreign_key => :target_id, :polymorphic => true |
36 | belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id | 38 | belongs_to :responsible, :class_name => 'Person', :foreign_key => :responsible_id |
@@ -253,6 +255,7 @@ class Task < ActiveRecord::Base | @@ -253,6 +255,7 @@ class Task < ActiveRecord::Base | ||
253 | end | 255 | end |
254 | 256 | ||
255 | def environment | 257 | def environment |
258 | + return target if target.kind_of?(Environment) | ||
256 | self.target.environment unless self.target.nil? | 259 | self.target.environment unless self.target.nil? |
257 | end | 260 | end |
258 | 261 |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +gem "gcm" |
@@ -0,0 +1,140 @@ | @@ -0,0 +1,140 @@ | ||
1 | +README - GCM - Google Cloud Message Plugin | ||
2 | +========================================== | ||
3 | + | ||
4 | +This plugin enables push notifications for mobile platforms | ||
5 | +using Google Cloud Message infrastructure. | ||
6 | + | ||
7 | +INSTALL | ||
8 | +======= | ||
9 | + | ||
10 | +Enable Plugin | ||
11 | +------------- | ||
12 | + | ||
13 | +You need to enable GCM Plugin on your Noosfero: | ||
14 | + | ||
15 | +cd <your_noosfero_dir> | ||
16 | +./script/noosfero-plugins install gcm | ||
17 | +./script/noosfero-plugins enable gcm | ||
18 | + | ||
19 | +Activation and Plugin Configuration | ||
20 | +----------------------------------- | ||
21 | + | ||
22 | +As a Noosfero administrator user, go to administrator panel: | ||
23 | + | ||
24 | +- Click on "Enable/disable plugins" option | ||
25 | +- Click on "Google Cloud Message Plugin" check-box | ||
26 | +- Click on "Configurations" just below the previous step | ||
27 | +- *Fill in the form with your server API key registered for GCM | ||
28 | +- Select from the check-boxes the notifications you want GCM plugin to send. | ||
29 | + | ||
30 | +*API key can be obtained creating a project in the GCM console, needed when preparing the application to use push notification. | ||
31 | +Link below: | ||
32 | + | ||
33 | +- https://console.developers.google.com/start | ||
34 | + | ||
35 | +More information can be found in the following links: | ||
36 | +- https://developers.google.com/cloud-messaging/gcm | ||
37 | +- https://developers.google.com/cloud-messaging/server | ||
38 | +- https://developers.google.com/cloud-messaging/registration | ||
39 | +- https://developers.google.com/instance-id/ | ||
40 | + | ||
41 | +After that, the mobile application need to take care of device registration to GCM and send the device token | ||
42 | +to GCM plugin through noosfero API. There are endpoints to add, see and remove device tokens. | ||
43 | + | ||
44 | +- post request to /api/v1/push_notification_plugin/device_tokens with "tokens" parameter like token1,token2,token3 | ||
45 | +will register the tokens token1, token2 and token3 to the api current logged user, defined by noosfero's private token | ||
46 | +also passed as parameter | ||
47 | + | ||
48 | +- get request to /api/v1/push_notification_plugin/device_tokens | ||
49 | +will return a list with all the tokens for the current user logged in the api | ||
50 | + | ||
51 | +- delete request to /api/v1/push_notification_plugin/device_tokens with "tokens" parameter like token1,token2 | ||
52 | +will remove token1 and token2 from the list of tokens for the logged user | ||
53 | + | ||
54 | +- get request to /api/v1/possible_notifications | ||
55 | +will return a list with all possible notifications available for user to activate/deactivate | ||
56 | + | ||
57 | +- get request to /api/v1/notification_settings | ||
58 | +will return the notification settings for the logged user | ||
59 | + | ||
60 | +- post request to /api/v1/notification_settings | ||
61 | +will activate/deactivate each notification passed as parameter. For instance, when receiving "new comment" as a parameter with value 1, | ||
62 | +the notifications for "new comment" will be activated for the logged user | ||
63 | + | ||
64 | +- get request to /api/v1/active_notifications | ||
65 | +will return a list with all active notifications for the logged user | ||
66 | + | ||
67 | +- get request to /api/v1/inactive_notifications | ||
68 | +will return a list with all inactive notifications for the logged user | ||
69 | + | ||
70 | +In any endpoint, there is an option to pass target_id so you can add, see and delete tokens of other users. | ||
71 | +However, only the admin has permission to do so. Normal users can pass target_id option with it's own id, | ||
72 | +but the behavior is the same as passing no parameter. | ||
73 | + | ||
74 | +As a noosfero user, you can change what notifications you want to receive through web interface as well. In your profile control panel, | ||
75 | +go to "Notification" and activate/deactivate notifications from there. | ||
76 | + | ||
77 | + | ||
78 | +Add Users to be notificated from another plugin | ||
79 | +------------------------------------------------ | ||
80 | + | ||
81 | +As a noosfero plugin developer, you can have your plugin to add users to be notified in some notifications implemented here. | ||
82 | +The way to do it is following the steps: | ||
83 | + | ||
84 | + 1 - Create a class with a callback for the specific notification you want to add users to. For instance, add users to the | ||
85 | +new comment notification creating a class with a method named** "push_notification_new_comment_additional_users". This method needs to | ||
86 | +return an Array with the list of users to be notified. Don't worry, no user will be notified twice. | ||
87 | + 2 - Subscribe the class calling the method PushNotificationPlugin::subscribe(environment,notification,klass). For a class CommentCallBack, | ||
88 | +call "PushNotificationPlugin::subscribe(<environment>, "new_comment", CommentCallBack)", with the environment object instead of | ||
89 | +<environment>. | ||
90 | + | ||
91 | +- Unsubscribe at any time calling PushNotificationPlugin::unsubscribe(environment, notification, klass) | ||
92 | +- Check the list of subscribers for any notification calling PushNotificationPlugin::subscribers(environment,notification) | ||
93 | + | ||
94 | +**The method will always be called "push_notification_" + <notification_name> + "additional_users". The class name does not matter, but it's | ||
95 | +important to use the full class name, with namespace, so there is no future problem with the callback. The method need to be a class method, | ||
96 | +not an instance method. | ||
97 | + | ||
98 | +Some details about the subscription methods: | ||
99 | + - subscribe: | ||
100 | + -> return null if the klass passed do not implement the method for the notification passed | ||
101 | + -> return null if the notification is not implemented in PushNotificationPlugin | ||
102 | + -> return true/false otherwise with the return of the save method | ||
103 | + - unsubscribe: | ||
104 | + -> return null if the notification is not implemented in PushNotificationPlugin | ||
105 | + -> return true if the klass was sucessfully subscribed | ||
106 | + -> return false if the klass was not subscribed or the unsubscription fails by any means | ||
107 | + - subscribers: | ||
108 | + -> return null if the notification is not implemented in PushNotificationPlugin | ||
109 | + -> return empty array if there is no subscribers for that notification in that environment | ||
110 | + -> return an array with all the subscribers otherwise | ||
111 | + | ||
112 | +Translate Plugin | ||
113 | +------------------ | ||
114 | + | ||
115 | +To translate the strings used in the plugin, create a copy of the file "en-US.yml" with your locale and | ||
116 | +translate the strings in there for each key. These files are stored in the folder "locales". | ||
117 | + | ||
118 | +Get Involved | ||
119 | +============ | ||
120 | + | ||
121 | +If you find any bug and/or want to collaborate, please send an e-mail to marcos.rpj2@gmail.com | ||
122 | + | ||
123 | +LICENSE | ||
124 | +======= | ||
125 | + | ||
126 | +Copyright (c) The Author developers. | ||
127 | + | ||
128 | +See Noosfero license. | ||
129 | + | ||
130 | + | ||
131 | +AUTHORS | ||
132 | +======= | ||
133 | + | ||
134 | +Marcos Ronaldo Pereira Junior (marcos.rpj2 at gmail.com) | ||
135 | +Marcos da Silva Ramos (msramos at outlook.com) | ||
136 | + | ||
137 | +ACKNOWLEDGMENTS | ||
138 | +=============== | ||
139 | + | ||
140 | +The authors have been supported by SNJ (Secretaria Nacional da Juventude) |
plugins/push_notification/controllers/push_notification_plugin_admin_controller.rb
0 → 100644
@@ -0,0 +1,19 @@ | @@ -0,0 +1,19 @@ | ||
1 | +require_relative "../lib/notification_settings" | ||
2 | + | ||
3 | +class PushNotificationPluginAdminController < PluginAdminController | ||
4 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | ||
5 | + | ||
6 | + def index | ||
7 | + @server_settings = Noosfero::Plugin::Settings.new(environment, PushNotificationPlugin) | ||
8 | + @settings = @server_settings.notifications || PushNotificationPlugin::NotificationSettings.default_hash_flags | ||
9 | + end | ||
10 | + | ||
11 | + def update | ||
12 | + data = params[:server_settings] | ||
13 | + data[:notifications] = params[:settings] | ||
14 | + @server_settings = Noosfero::Plugin::Settings.new(environment, PushNotificationPlugin, data) | ||
15 | + @server_settings.save! | ||
16 | + redirect_to :action => "index" | ||
17 | + end | ||
18 | + | ||
19 | +end |
plugins/push_notification/controllers/push_notification_plugin_myprofile_controller.rb
0 → 100644
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +require_relative "../lib/notification_settings" | ||
2 | +require_relative "../lib/device_token" | ||
3 | + | ||
4 | +class PushNotificationPluginMyprofileController < MyProfileController | ||
5 | + | ||
6 | + append_view_path File.join(File.dirname(__FILE__) + '/../views') | ||
7 | + | ||
8 | + def index | ||
9 | + @devices = current_user.device_tokens | ||
10 | + @settings = filter_notifications current_user.notification_settings.hash_flags | ||
11 | + end | ||
12 | + | ||
13 | + def delete_device | ||
14 | + device = PushNotificationPlugin::DeviceToken.find(params["device"]) | ||
15 | + device.delete | ||
16 | + redirect_to :action => "index" | ||
17 | + end | ||
18 | + | ||
19 | + def update_settings | ||
20 | + current_user.notification_settings.set_notifications(params["settings"] || {}) | ||
21 | + current_user.save | ||
22 | + redirect_to :action => "index" | ||
23 | + end | ||
24 | + | ||
25 | + private | ||
26 | + | ||
27 | + def filter_notifications hash_flags | ||
28 | + server_settings = Noosfero::Plugin::Settings.new(environment, PushNotificationPlugin) | ||
29 | + server_notifications = server_settings.notifications || {} | ||
30 | + filtered_settings = {} | ||
31 | + hash_flags.each do |notification, enabled| | ||
32 | + filtered_settings[notification] = enabled if server_notifications[notification] == "1" | ||
33 | + end | ||
34 | + filtered_settings | ||
35 | + end | ||
36 | +end |
plugins/push_notification/db/migrate/20160109195305_create_device_tokens.rb
0 → 100644
@@ -0,0 +1,11 @@ | @@ -0,0 +1,11 @@ | ||
1 | +class CreateDeviceTokens < ActiveRecord::Migration | ||
2 | + def change | ||
3 | + create_table :push_notification_plugin_device_tokens do |t| | ||
4 | + t.integer :user_id, null: false | ||
5 | + t.string :device_name, null:false | ||
6 | + t.string :token, null: false, unique: true | ||
7 | + t.timestamps null: false | ||
8 | + t.index :user_id | ||
9 | + end | ||
10 | + end | ||
11 | +end |
plugins/push_notification/db/migrate/20160110125119_create_notification_settings.rb
0 → 100644
@@ -0,0 +1,10 @@ | @@ -0,0 +1,10 @@ | ||
1 | +class CreateNotificationSettings < ActiveRecord::Migration | ||
2 | + def change | ||
3 | + create_table :push_notification_plugin_notification_settings do |t| | ||
4 | + t.integer :user_id, null: false | ||
5 | + t.integer :notifications, null: false, :default => 0 | ||
6 | + t.timestamps null: false | ||
7 | + t.index :user_id | ||
8 | + end | ||
9 | + end | ||
10 | +end |
plugins/push_notification/db/migrate/20160118192037_create_notification_subscriptions.rb
0 → 100644
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +class CreateNotificationSubscriptions < ActiveRecord::Migration | ||
2 | + def change | ||
3 | + create_table :push_notification_plugin_notification_subscriptions do |t| | ||
4 | + t.string :notification, :unique => true | ||
5 | + t.integer :environment_id, null: false | ||
6 | + t.text :subscribers | ||
7 | + end | ||
8 | + end | ||
9 | +end |
@@ -0,0 +1 @@ | @@ -0,0 +1 @@ | ||
1 | +require 'gcm' |
plugins/push_notification/features/push_notification_admin.feature
0 → 100644
@@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
1 | +Feature: push notification administration | ||
2 | + As an administrator | ||
3 | + I want to configure the push notification plugin | ||
4 | + | ||
5 | + Background: | ||
6 | + Given plugin PushNotification is enabled on environment | ||
7 | + Given I am logged in as admin | ||
8 | + | ||
9 | + Scenario: configure the api key | ||
10 | + Given I go to /admin/plugin/push_notification | ||
11 | + And I fill in "Server API key" with "ABCDEFGH1234567890" | ||
12 | + When I press "Save" | ||
13 | + Then I should be on /admin/plugin/push_notification | ||
14 | + Then the "Server API key" field should contain "ABCDEFGH1234567890" | ||
15 | + | ||
16 | + Scenario: change the api key | ||
17 | + Given that "old_key" is the server api key | ||
18 | + Given I go to /admin/plugin/push_notification | ||
19 | + Then the "Server API key" field should contain "old_key" | ||
20 | + When I fill in "Server API key" with "new_key" | ||
21 | + And I press "Save" | ||
22 | + Then I should be on /admin/plugin/push_notification | ||
23 | + Then the "Server API key" field should contain "new_key" | ||
24 | + | ||
25 | + Scenario: enable notifications | ||
26 | + Given I go to /admin/plugin/push_notification | ||
27 | + And I check "settings_add_member" | ||
28 | + And I check "settings_new_article" | ||
29 | + When I press "Save" | ||
30 | + Then the "settings_add_member" checkbox should be checked | ||
31 | + Then the "settings_new_article" checkbox should be checked | ||
32 | + | ||
33 | + Scenario: disable notifications | ||
34 | + Given the following notifications | ||
35 | + |name| | ||
36 | + |add_friend| | ||
37 | + |add_member| | ||
38 | + And I go to /admin/plugin/push_notification | ||
39 | + Then the "settings_add_friend" checkbox should be checked | ||
40 | + Then the "settings_add_member" checkbox should be checked | ||
41 | + And I uncheck "settings_add_friend" | ||
42 | + And I uncheck "settings_add_member" | ||
43 | + When I press "Save" | ||
44 | + Then I should be on /admin/plugin/push_notification | ||
45 | + Then the "settings_add_friend" checkbox should not be checked | ||
46 | + Then the "settings_add_member" checkbox should not be checked |
plugins/push_notification/features/push_notification_user_config.feature
0 → 100644
@@ -0,0 +1,73 @@ | @@ -0,0 +1,73 @@ | ||
1 | +Feature: push notification user config | ||
2 | + As an user | ||
3 | + I want to configure the notification I want to receive | ||
4 | + | ||
5 | + Background: | ||
6 | + Given plugin PushNotification is enabled on environment | ||
7 | + Given the following users | ||
8 | + |login | name | | ||
9 | + |joaosilva| Joao Silva | | ||
10 | + | ||
11 | + Scenario: the user should see his devices | ||
12 | + Given that the user joaosilva has the following devices | ||
13 | + | token | name | | ||
14 | + | "token_1" | "Banana Phone" | | ||
15 | + | "token_2" | "Zamzung Phone" | | ||
16 | + Given I am logged in as "joaosilva" | ||
17 | + Given I go to joaosilva's control panel | ||
18 | + When I follow "Notifications" | ||
19 | + Then I should see "Banana Phone" | ||
20 | + And I should see "Zamzung Phone" | ||
21 | + | ||
22 | + Scenario: the user should delete his devices | ||
23 | + Given that the user joaosilva has the following devices | ||
24 | + | token | name | | ||
25 | + | "token_1" | "Zamzung Phone" | | ||
26 | + Given I am logged in as "joaosilva" | ||
27 | + Given I go to joaosilva's control panel | ||
28 | + When I follow "Notifications" | ||
29 | + When I follow "delete_device_1" | ||
30 | + Then I should be on /myprofile/joaosilva/plugin/push_notification | ||
31 | + And I should not see "Zamzung Phone" | ||
32 | + | ||
33 | + Scenario: the user should only see the notifications enabled in the environment | ||
34 | + Given the following notifications | ||
35 | + |name | | ||
36 | + |add_friend | | ||
37 | + |new_article | | ||
38 | + Given I am logged in as "joaosilva" | ||
39 | + Given I go to joaosilva's control panel | ||
40 | + When I follow "Notifications" | ||
41 | + Then I should see "Add Friend" | ||
42 | + And I should see "New Article" | ||
43 | + And I should not see "New Member" | ||
44 | + And I should not see "Approve Article" | ||
45 | + | ||
46 | + Scenario: the user should be able to enable notifications | ||
47 | + Given the following notifications | ||
48 | + |name | | ||
49 | + |add_friend | | ||
50 | + |new_article | | ||
51 | + Given I am logged in as "joaosilva" | ||
52 | + Given I go to joaosilva's control panel | ||
53 | + When I follow "Notifications" | ||
54 | + And I check "settings_add_friend" | ||
55 | + And I check "settings_new_article" | ||
56 | + When I press "Save" | ||
57 | + Then the "settings_add_friend" checkbox should be checked | ||
58 | + Then the "settings_new_article" checkbox should be checked | ||
59 | + | ||
60 | + Scenario: the user should be able to disable notifications | ||
61 | + Given the following notifications | ||
62 | + | name | | ||
63 | + | add_friend | | ||
64 | + | new_article | | ||
65 | + Given that the user joaosilva has the following notifications | ||
66 | + | name | | ||
67 | + | add_friend | | ||
68 | + Given I am logged in as "joaosilva" | ||
69 | + Given I go to joaosilva's control panel | ||
70 | + When I follow "Notifications" | ||
71 | + And I uncheck "settings_add_friend" | ||
72 | + When I press "Save" | ||
73 | + Then the "settings_add_friend" checkbox should not be checked |
plugins/push_notification/features/step_definitions/push_notification_steps.rb
0 → 100644
@@ -0,0 +1,30 @@ | @@ -0,0 +1,30 @@ | ||
1 | +Given /^the following notifications$/ do |table| | ||
2 | + settings = {} | ||
3 | + table.hashes.each do |item| | ||
4 | + settings[item[:name]] = "1" | ||
5 | + end | ||
6 | + data = {:notifications => settings} | ||
7 | + server_settings = Noosfero::Plugin::Settings.new(Environment.default, PushNotificationPlugin, data) | ||
8 | + server_settings.save! | ||
9 | +end | ||
10 | + | ||
11 | +Given /^that the user ([^\"]*) has the following devices$/ do |user_name,table| | ||
12 | + user = User.find_by(:login => user_name) | ||
13 | + table.hashes.each do |item| | ||
14 | + PushNotificationPlugin::DeviceToken.create(:user => user, :token => item[:token], :device_name => item[:name]) | ||
15 | + end | ||
16 | +end | ||
17 | + | ||
18 | +Given /^that the user ([^\"]*) has the following notifications$/ do |user_name,table| | ||
19 | + user = User.find_by(:login => user_name) | ||
20 | + table.hashes.each do |item| | ||
21 | + user.notification_settings.activate_notification item[:name] | ||
22 | + end | ||
23 | + user.save! | ||
24 | +end | ||
25 | + | ||
26 | +Given /^that "([^\"]*)" is the server api key$/ do |key| | ||
27 | + data = {:server_api_key => key} | ||
28 | + server_settings = Noosfero::Plugin::Settings.new(Environment.default, PushNotificationPlugin, data) | ||
29 | + server_settings.save! | ||
30 | +end |
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +class PushNotificationPlugin::DeviceToken < ActiveRecord::Base | ||
2 | + belongs_to :user | ||
3 | + attr_accessible :token, :device_name, :user | ||
4 | + | ||
5 | + after_save :check_notification_settings | ||
6 | + | ||
7 | + private | ||
8 | + | ||
9 | + def check_notification_settings | ||
10 | + if user.notification_settings.nil? | ||
11 | + user.notification_settings=PushNotificationPlugin::NotificationSettings.new | ||
12 | + user.save | ||
13 | + end | ||
14 | + end | ||
15 | + | ||
16 | +end |
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
1 | +require_dependency "user" | ||
2 | +require_relative "../notification_subscription" | ||
3 | +require_relative "../notification_settings" | ||
4 | +require_relative "../device_token" | ||
5 | + | ||
6 | +class User | ||
7 | + has_many :device_tokens, class_name: "PushNotificationPlugin::DeviceToken", :dependent => :destroy | ||
8 | + has_one :notification_settings, class_name: "PushNotificationPlugin::NotificationSettings", :dependent => :destroy, :autosave => true | ||
9 | + | ||
10 | + after_save :save_notification_settings | ||
11 | + after_initialize :setup_notification_settings | ||
12 | + | ||
13 | + def device_token_list | ||
14 | + device_tokens.map { |t| t.token } | ||
15 | + end | ||
16 | + | ||
17 | + def enabled_notifications | ||
18 | + notification_settings.notifications | ||
19 | + end | ||
20 | + | ||
21 | + def enabled_notifications=(notifications) | ||
22 | + notification_settings.notifications=notifications | ||
23 | + end | ||
24 | + | ||
25 | + private | ||
26 | + | ||
27 | + def save_notification_settings | ||
28 | + notification_settings.save if notification_settings | ||
29 | + end | ||
30 | + | ||
31 | + def setup_notification_settings | ||
32 | + self.notification_settings = PushNotificationPlugin::NotificationSettings.new(:user => self) if self.notification_settings.nil? | ||
33 | + end | ||
34 | + | ||
35 | +end |
@@ -0,0 +1,69 @@ | @@ -0,0 +1,69 @@ | ||
1 | +class PushNotificationPlugin::NotificationSettings < ActiveRecord::Base | ||
2 | + | ||
3 | + NOTIFICATIONS= { | ||
4 | + "add_friend" => 0x1, | ||
5 | + "new_comment" => 0x2, | ||
6 | + "add_member" => 0x4, | ||
7 | + "suggest_article" => 0x8, | ||
8 | + "new_article" => 0x10, | ||
9 | + "approve_article" => 0x20, | ||
10 | + "add_friend_result" => 0x40, | ||
11 | + "add_member_result" => 0x80, | ||
12 | + "approve_article_result" => 0x100, | ||
13 | + "suggest_article_result" => 0x200 | ||
14 | + } | ||
15 | + | ||
16 | + belongs_to :user | ||
17 | + attr_accessible :user, :notifications | ||
18 | + | ||
19 | + def self.default_hash_flags | ||
20 | + default_hash_flags = {} | ||
21 | + NOTIFICATIONS.keys.each do |event| | ||
22 | + default_hash_flags[event] = "0" | ||
23 | + end | ||
24 | + default_hash_flags | ||
25 | + end | ||
26 | + | ||
27 | + def hash_flags | ||
28 | + flags = {} | ||
29 | + NOTIFICATIONS.keys.each do |notification| | ||
30 | + flags[notification] = active? notification | ||
31 | + end | ||
32 | + flags | ||
33 | + end | ||
34 | + | ||
35 | + def active_notifications | ||
36 | + NOTIFICATIONS.keys.select{|notification| active?(notification)} | ||
37 | + end | ||
38 | + | ||
39 | + def inactive_notifications | ||
40 | + NOTIFICATIONS.keys.select{|notification| !active?(notification)} | ||
41 | + end | ||
42 | + | ||
43 | + def active? notification | ||
44 | + ((self.notifications & NOTIFICATIONS[notification])!=0) | ||
45 | + end | ||
46 | + | ||
47 | + def activate_notification notification | ||
48 | + self.notifications |= NOTIFICATIONS[notification] | ||
49 | + end | ||
50 | + | ||
51 | + def set_notifications notifications | ||
52 | + NOTIFICATIONS.keys.each do |event| | ||
53 | + set_notification_state event, notifications[event] | ||
54 | + end | ||
55 | + end | ||
56 | + | ||
57 | + def deactivate_notification notification | ||
58 | + self.notifications &= ~NOTIFICATIONS[notification] | ||
59 | + end | ||
60 | + | ||
61 | + def set_notification_state notification, state | ||
62 | + if state.blank? || (state == 0) || (state == "0") || state == false | ||
63 | + deactivate_notification notification | ||
64 | + else | ||
65 | + activate_notification notification | ||
66 | + end | ||
67 | + end | ||
68 | + | ||
69 | +end |
plugins/push_notification/lib/notification_subscription.rb
0 → 100644
plugins/push_notification/lib/push_notification_helper.rb
0 → 100644
@@ -0,0 +1,46 @@ | @@ -0,0 +1,46 @@ | ||
1 | +module PushNotificationHelper | ||
2 | + | ||
3 | + def gcm_instance | ||
4 | + api_key = settings[:server_api_key] | ||
5 | + gcm = GCM.new(api_key) | ||
6 | + gcm | ||
7 | + end | ||
8 | + | ||
9 | + def settings | ||
10 | + return Noosfero::Plugin::Settings.new(environment, PushNotificationPlugin.class) | ||
11 | + end | ||
12 | + | ||
13 | + #data should be a hash, like {some_info: 123123} | ||
14 | + def send_to_users(flag, users, data) | ||
15 | + return false unless users.present? | ||
16 | + users |= subscribers_additional_users(flag, users.first.environment) | ||
17 | + users = filter_users_for_flag(flag, users) | ||
18 | + return false unless users.present? | ||
19 | + tokens = tokens_for_users(users) | ||
20 | + gcm = gcm_instance | ||
21 | + response = gcm.send(tokens, data) | ||
22 | + response[:response] | ||
23 | + end | ||
24 | + | ||
25 | + def filter_users_for_flag(flag, users) | ||
26 | + users.select{|u| u.notification_settings.active?(flag)} | ||
27 | + end | ||
28 | + | ||
29 | + def tokens_for_users(users) | ||
30 | + tokens=[] | ||
31 | + users.each{|c| tokens+= c.device_token_list} | ||
32 | + return tokens | ||
33 | + end | ||
34 | + | ||
35 | + def subscribers_additional_users notification, environment | ||
36 | + subs = PushNotificationPlugin::subscribers(environment, notification) | ||
37 | + users=[] | ||
38 | + if subs.present? | ||
39 | + subs.each do |s| | ||
40 | + users+=s.send("push_notification_#{notification}_additional_users".to_sym) | ||
41 | + end | ||
42 | + end | ||
43 | + users | ||
44 | + end | ||
45 | + | ||
46 | +end |
plugins/push_notification/lib/push_notification_plugin.rb
0 → 100644
@@ -0,0 +1,62 @@ | @@ -0,0 +1,62 @@ | ||
1 | +class PushNotificationPlugin < Noosfero::Plugin | ||
2 | + | ||
3 | + include Noosfero::Plugin::HotSpot | ||
4 | + include PushNotificationPlugin::Observers | ||
5 | + | ||
6 | + def self.plugin_name | ||
7 | + I18n.t("push_notification_plugin.lib.plugin.name") | ||
8 | + end | ||
9 | + | ||
10 | + def self.subscribe environment, notification, klass | ||
11 | + return nil unless PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys.include?(notification) | ||
12 | + return nil unless klass.name.constantize.respond_to?("push_notification_#{notification}_additional_users".to_sym) | ||
13 | + | ||
14 | + notification_subscription = PushNotificationPlugin::NotificationSubscription.where(:notification => notification).first | ||
15 | + notification_subscription ||= PushNotificationPlugin::NotificationSubscription.new({:notification => notification, | ||
16 | + :environment => environment, :subscribers => [klass.name]}) | ||
17 | + | ||
18 | + notification_subscription.subscribers |= [klass.name] | ||
19 | + notification_subscription.save | ||
20 | + end | ||
21 | + | ||
22 | + def self.unsubscribe environment, notification, klass | ||
23 | + return nil unless PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys.include?(notification) | ||
24 | + notification_subscription = PushNotificationPlugin::NotificationSubscription.where(:notification => notification, :environment => environment).first | ||
25 | + unless notification_subscription.blank? | ||
26 | + if notification_subscription.subscribers.include?(klass.name) | ||
27 | + notification_subscription.subscribers -= [klass.name] | ||
28 | + return notification_subscription.save | ||
29 | + end | ||
30 | + end | ||
31 | + return false | ||
32 | + end | ||
33 | + | ||
34 | + def self.subscribers environment, notification | ||
35 | + return nil unless PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys.include?(notification) | ||
36 | + notification_subscription = PushNotificationPlugin::NotificationSubscription.where(:notification => notification, :environment => environment) | ||
37 | + return [] if notification_subscription.blank? | ||
38 | + notification_subscription.first.subscribers.map{|s| s.constantize} | ||
39 | + end | ||
40 | + | ||
41 | + def self.api_mount_points | ||
42 | + [PushNotificationPlugin::API] | ||
43 | + end | ||
44 | + | ||
45 | + def self.plugin_description | ||
46 | + I18n.t("push_notification_plugin.lib.plugin.description") | ||
47 | + end | ||
48 | + | ||
49 | + def stylesheet? | ||
50 | + true | ||
51 | + end | ||
52 | + | ||
53 | + def control_panel_buttons | ||
54 | + if context.profile.person? | ||
55 | + { | ||
56 | + title: I18n.t("push_notification_plugin.lib.plugin.panel_button"), | ||
57 | + icon: 'push-notifications', | ||
58 | + url: {controller: 'push_notification_plugin_myprofile', action: 'index'} | ||
59 | + } | ||
60 | + end | ||
61 | + end | ||
62 | +end |
plugins/push_notification/lib/push_notification_plugin/api.rb
0 → 100644
@@ -0,0 +1,96 @@ | @@ -0,0 +1,96 @@ | ||
1 | +require File.dirname(__FILE__) + '/../../../../../lib/noosfero/api/helpers' | ||
2 | +require_relative 'api_entities' | ||
3 | + | ||
4 | +class PushNotificationPlugin::API < Grape::API | ||
5 | + | ||
6 | + include Noosfero::API::APIHelpers | ||
7 | + | ||
8 | + resource :push_notification_plugin do | ||
9 | + | ||
10 | + helpers do | ||
11 | + def target | ||
12 | + if params.has_key?(:target_id) | ||
13 | + target_user = environment.users.detect{|u|u.id == params[:target_id].to_i} | ||
14 | + else | ||
15 | + target_user = current_user | ||
16 | + end | ||
17 | + | ||
18 | + if !current_person.is_admin? && (target_user.nil? || target_user!=current_user) | ||
19 | + render_api_error!(_('Unauthorized'), 401) | ||
20 | + end | ||
21 | + | ||
22 | + return target_user | ||
23 | + end | ||
24 | + end | ||
25 | + | ||
26 | + get 'device_tokens' do | ||
27 | + authenticate! | ||
28 | + target_user = target | ||
29 | + tokens = target_user.device_token_list || [] | ||
30 | + present tokens | ||
31 | + end | ||
32 | + | ||
33 | + post 'device_tokens' do | ||
34 | + authenticate! | ||
35 | + target_user = target | ||
36 | + | ||
37 | + bad_request!("device_name") unless params[:device_name] | ||
38 | + token = PushNotificationPlugin::DeviceToken.new({:device_name => params[:device_name], :token => params[:token], :user => target_user}) if !target_user.device_token_list.include?(params[:token]) | ||
39 | + | ||
40 | + target_user.device_tokens.push(token) | ||
41 | + | ||
42 | + | ||
43 | + unless target_user.save | ||
44 | + render_api_errors!(target_user.errors.full_messages) | ||
45 | + end | ||
46 | + present target_user, :with => PushNotificationPlugin::Entities::DeviceUser | ||
47 | + end | ||
48 | + | ||
49 | + delete 'device_tokens' do | ||
50 | + authenticate! | ||
51 | + target_user = target | ||
52 | + | ||
53 | + PushNotificationPlugin::DeviceToken.delete_all(["token = ? AND user_id = (?)", params[:token],target_user.id]) | ||
54 | + | ||
55 | + present target_user, :with => PushNotificationPlugin::Entities::DeviceUser | ||
56 | + end | ||
57 | + | ||
58 | + get 'notification_settings' do | ||
59 | + authenticate! | ||
60 | + target_user = target | ||
61 | + | ||
62 | + present target_user, with: PushNotificationPlugin::Entities::DeviceUser | ||
63 | + end | ||
64 | + | ||
65 | + get 'possible_notifications' do | ||
66 | + result = {:possible_notifications => PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys} | ||
67 | + present result, with: Grape::Presenters::Presenter | ||
68 | + end | ||
69 | + | ||
70 | + post 'notification_settings' do | ||
71 | + authenticate! | ||
72 | + target_user = target | ||
73 | + | ||
74 | + PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys.each do |notification| | ||
75 | + next unless params.keys.include?(notification) | ||
76 | + state = params[notification] | ||
77 | + target_user.notification_settings.set_notification_state notification, state | ||
78 | + end | ||
79 | + | ||
80 | + target_user.save! | ||
81 | + present target_user, with: PushNotificationPlugin::Entities::DeviceUser | ||
82 | + end | ||
83 | + | ||
84 | + get 'active_notifications' do | ||
85 | + authenticate! | ||
86 | + target_user = target | ||
87 | + present target_user.notification_settings.active_notifications, with: Grape::Presenters::Presenter | ||
88 | + end | ||
89 | + | ||
90 | + get 'inactive_notifications' do | ||
91 | + authenticate! | ||
92 | + target_user = target | ||
93 | + present target_user.notification_settings.inactive_notifications, with: Grape::Presenters::Presenter | ||
94 | + end | ||
95 | + end | ||
96 | +end |
plugins/push_notification/lib/push_notification_plugin/api_entities.rb
0 → 100644
@@ -0,0 +1,9 @@ | @@ -0,0 +1,9 @@ | ||
1 | +module PushNotificationPlugin::Entities | ||
2 | + class DeviceUser < Noosfero::API::Entities::User | ||
3 | + expose :device_token_list, :as => :device_tokens | ||
4 | + expose :notification_settings do |user, options| | ||
5 | + user.notification_settings.hash_flags | ||
6 | + end | ||
7 | + end | ||
8 | + | ||
9 | +end |
plugins/push_notification/lib/push_notification_plugin/observers.rb
0 → 100644
@@ -0,0 +1,6 @@ | @@ -0,0 +1,6 @@ | ||
1 | +require_relative '../device_token' | ||
2 | +Dir[File.dirname(__FILE__) + "/observers/*"].each {|file| require file} | ||
3 | +module PushNotificationPlugin::Observers | ||
4 | + include PushNotificationHelper | ||
5 | + constants.collect{|const_name| const_get(const_name)}.select {|const| const.class == Module}.each{|submodule| include submodule} | ||
6 | +end |
plugins/push_notification/lib/push_notification_plugin/observers/add_friend_observer.rb
0 → 100644
@@ -0,0 +1,35 @@ | @@ -0,0 +1,35 @@ | ||
1 | +module PushNotificationPlugin::Observers | ||
2 | + module AddFriendObserver | ||
3 | + def add_friend_after_create_callback(add_friend) | ||
4 | + requestor = add_friend.requestor | ||
5 | + target = add_friend.target | ||
6 | + | ||
7 | + send_to_users("add_friend", | ||
8 | + [target.user], | ||
9 | + {:event => "Add Friend", | ||
10 | + :requestor_id => requestor.id, | ||
11 | + :requestor_name => requestor.name, | ||
12 | + :task_id => add_friend.id} | ||
13 | + ) | ||
14 | + end | ||
15 | + | ||
16 | + #check when task is finished | ||
17 | + def add_friend_after_save_callback(add_friend) | ||
18 | + requestor = add_friend.requestor | ||
19 | + target = add_friend.target | ||
20 | + | ||
21 | + return false unless [Task::Status::FINISHED, Task::Status::CANCELLED].include?(add_friend.status) | ||
22 | + | ||
23 | + added = add_friend.status==Task::Status::FINISHED | ||
24 | + event= added ? "Friendship accepted" : "Friendship refused" | ||
25 | + | ||
26 | + send_to_users("add_friend_result", | ||
27 | + [requestor.user], | ||
28 | + {:event => event, | ||
29 | + :target_id => target.id, | ||
30 | + :target_name => target.name, | ||
31 | + :task_id => add_friend.id} | ||
32 | + ) | ||
33 | + end | ||
34 | + end | ||
35 | +end |
plugins/push_notification/lib/push_notification_plugin/observers/add_member_observer.rb
0 → 100644
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +module PushNotificationPlugin::Observers | ||
2 | + module AddMemberObserver | ||
3 | + def add_member_after_create_callback(add_member) | ||
4 | + requestor = add_member.requestor | ||
5 | + target = add_member.target | ||
6 | + | ||
7 | + users = target.admins.map{|person| person.user} | ||
8 | + | ||
9 | + send_to_users("add_member", | ||
10 | + users, | ||
11 | + {:event => "Add Member to Organization", | ||
12 | + :requestor_id => requestor.id, | ||
13 | + :requestor_name => requestor.name, | ||
14 | + :task_id => add_member.id} | ||
15 | + ) | ||
16 | + end | ||
17 | + | ||
18 | + def add_member_after_save_callback(add_member) | ||
19 | + requestor = add_member.requestor | ||
20 | + target = add_member.target | ||
21 | + | ||
22 | + return false unless [Task::Status::FINISHED, Task::Status::CANCELLED].include?(add_member.status) | ||
23 | + | ||
24 | + accepted = add_member.status==Task::Status::FINISHED | ||
25 | + event= accepted ? "Membership accepted" : "Membership rejected" | ||
26 | + | ||
27 | + send_to_users("add_member_result", | ||
28 | + [requestor], | ||
29 | + {:event => event, | ||
30 | + :target_id => target.id, | ||
31 | + :target_name => target.name, | ||
32 | + :task_id => add_member.id} | ||
33 | + ) | ||
34 | + end | ||
35 | + end | ||
36 | +end |
plugins/push_notification/lib/push_notification_plugin/observers/approve_article_observer.rb
0 → 100644
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +module PushNotificationPlugin::Observers | ||
2 | + module ApproveArticleObserver | ||
3 | + def approve_article_after_create_callback(approve_article) | ||
4 | + requestor = approve_article.requestor | ||
5 | + target = approve_article.target | ||
6 | + | ||
7 | + if target.person? | ||
8 | + users = [target.user] | ||
9 | + elsif target.organization? | ||
10 | + users = target.admins.map{|person| person.user} | ||
11 | + end | ||
12 | + | ||
13 | + send_to_users("approve_article", | ||
14 | + users, | ||
15 | + {:event => "Approve Article", | ||
16 | + :requestor_id => requestor.id, | ||
17 | + :requestor_name => requestor.name, | ||
18 | + :article => approve_article.article, | ||
19 | + :task_id => approve_article.id} | ||
20 | + ) | ||
21 | + end | ||
22 | + | ||
23 | + def approve_article_after_save_callback(approve_article) | ||
24 | + requestor = approve_article.requestor | ||
25 | + target = approve_article.target | ||
26 | + | ||
27 | + return false unless [Task::Status::FINISHED, Task::Status::CANCELLED].include?(approve_article.status) | ||
28 | + | ||
29 | + accepted = approve_article.status==Task::Status::FINISHED | ||
30 | + event= accepted ? "Article approved" : "Article rejected" | ||
31 | + | ||
32 | + send_to_users("approve_article_result", | ||
33 | + [requestor], | ||
34 | + {:event => event, | ||
35 | + :target_id => target.id, | ||
36 | + :target_name => target.name, | ||
37 | + :article => approve_article.article, | ||
38 | + :task_id => approve_article.id} | ||
39 | + ) | ||
40 | + end | ||
41 | + end | ||
42 | +end |
plugins/push_notification/lib/push_notification_plugin/observers/article_observer.rb
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +module PushNotificationPlugin::Observers | ||
2 | + module ArticleObserver | ||
3 | + def article_after_create_callback(article) | ||
4 | + users=[] | ||
5 | + | ||
6 | + if article.profile.organization? | ||
7 | + article.profile.members.each do |person| | ||
8 | + users |= [person.user] if person.user.present? | ||
9 | + end | ||
10 | + elsif article.profile.person? | ||
11 | + users |= [article.profile.user] if article.profile.user.present? | ||
12 | + end | ||
13 | + | ||
14 | + send_to_users("new_article", | ||
15 | + users, | ||
16 | + {:event => "New article", | ||
17 | + :article => article.id, | ||
18 | + :article_body => article.body, | ||
19 | + :article_title => article.title, | ||
20 | + :article_name => article.name, | ||
21 | + :author => article.author_name}) | ||
22 | + end | ||
23 | + end | ||
24 | +end |
plugins/push_notification/lib/push_notification_plugin/observers/comment_observer.rb
0 → 100644
@@ -0,0 +1,16 @@ | @@ -0,0 +1,16 @@ | ||
1 | +module PushNotificationPlugin::Observers | ||
2 | + module CommentObserver | ||
3 | + def comment_after_create_callback(comment) | ||
4 | + users = comment.source.person_followers.map{|p| p.user} | ||
5 | + | ||
6 | + send_to_users("new_comment", | ||
7 | + users, | ||
8 | + {:event => "New Comment", | ||
9 | + :article => comment.source.id, | ||
10 | + :comment_body => comment.body, | ||
11 | + :comment_title => comment.title, | ||
12 | + :comment_name => comment.name, | ||
13 | + :author => comment.author.name}) | ||
14 | + end | ||
15 | + end | ||
16 | +end |
plugins/push_notification/lib/push_notification_plugin/observers/suggest_article_observer.rb
0 → 100644
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +module PushNotificationPlugin::Observers | ||
2 | + module SuggestArticleObserver | ||
3 | + def suggest_article_after_create_callback(suggest_article) | ||
4 | + requestor = suggest_article.requestor | ||
5 | + target = suggest_article.target | ||
6 | + | ||
7 | + if target.person? | ||
8 | + users = [target.user] | ||
9 | + elsif target.organization? | ||
10 | + users = target.admins.map{|person| person.user} | ||
11 | + end | ||
12 | + | ||
13 | + send_to_users("suggest_article", | ||
14 | + users, | ||
15 | + {:event => "Add Member", | ||
16 | + :requestor_id => requestor.id, | ||
17 | + :requestor_name => requestor.name, | ||
18 | + :article => suggest_article.article, | ||
19 | + :task_id => suggest_article.id} | ||
20 | + ) | ||
21 | + end | ||
22 | + | ||
23 | + def suggest_article_after_save_callback(suggest_article) | ||
24 | + requestor = suggest_article.requestor | ||
25 | + target = suggest_article.target | ||
26 | + | ||
27 | + return false unless [Task::Status::FINISHED, Task::Status::CANCELLED].include?(suggest_article.status) | ||
28 | + | ||
29 | + accepted = suggest_article.status==Task::Status::FINISHED | ||
30 | + event= accepted ? "Article approved" : "Article rejected" | ||
31 | + | ||
32 | + send_to_users("suggest_article_result", | ||
33 | + [requestor], | ||
34 | + {:event => event, | ||
35 | + :target_id => target.id, | ||
36 | + :target_name => target.name, | ||
37 | + :article => suggest_article.article, | ||
38 | + :task_id => suggest_article.id} | ||
39 | + ) | ||
40 | + end | ||
41 | + end | ||
42 | +end |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +en-US: &en-US | ||
2 | + | ||
3 | + push_notification_plugin: | ||
4 | + events: | ||
5 | + add_friend: "Add Friend" | ||
6 | + new_comment: "New Comment" | ||
7 | + add_member: "New Member" | ||
8 | + suggest_article: "Suggest Article" | ||
9 | + new_article: "New Article" | ||
10 | + approve_article: "Approve Article" | ||
11 | + add_friend_result: "Friendship Request Result" | ||
12 | + add_member_result: "Membership Request Result" | ||
13 | + approve_article_result: "Article approval Result" | ||
14 | + suggest_article_result: "Article suggestion Result" | ||
15 | + | ||
16 | + lib: | ||
17 | + plugin: | ||
18 | + name: "Push Notifications" | ||
19 | + description: "Send push notifications to mobile devices using Google Cloud Message" | ||
20 | + panel_button: "Notifications" | ||
21 | + settings: "Push Notification Settings" | ||
22 | + notifications: "Notifications" | ||
23 | + enabled_notifications: "Enabled Notifications" | ||
24 | + device: "Device" | ||
25 | + actions: "Actions" | ||
26 | + | ||
27 | + controllers: | ||
28 | + myprofile: | ||
29 | + my_devices: "My Devices" | ||
30 | + no_devices: "No device connected to your account" | ||
31 | + delete_device: "Delete Device" | ||
32 | + event: "Event" | ||
33 | + enabled: "Enabled?" | ||
34 | + | ||
35 | + admin: | ||
36 | + server_api_key: "Server API key" | ||
37 | + | ||
38 | +en_US: | ||
39 | + <<: *en-US | ||
40 | +en: | ||
41 | + <<: *en-US |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +pt-BR: &pt-BR | ||
2 | + | ||
3 | + push_notification_plugin: | ||
4 | + events: | ||
5 | + add_friend: "Nova Amizade" | ||
6 | + new_comment: "Novo Comentário" | ||
7 | + add_member: "Novo Membro" | ||
8 | + suggest_article: "Artigo Sugerido" | ||
9 | + new_article: "Novo Artigo" | ||
10 | + approve_article: "Aprovar Artigo" | ||
11 | + add_friend_result: "Resultado de Solicitação de Amizade" | ||
12 | + add_member_result: "Resultado de Solicitação de participação de comunidade" | ||
13 | + approve_article_result: "Resultado de Aprovação de Artigo" | ||
14 | + suggest_article_result: "Resultado de Sugestão de Artigo" | ||
15 | + | ||
16 | + lib: | ||
17 | + plugin: | ||
18 | + name: "Notificações Push" | ||
19 | + description: "Envie notificações para dispositivos móveis usando o Google Cloud Message" | ||
20 | + panel_button: "Notificações" | ||
21 | + settings: "Configuração das Notificações Push" | ||
22 | + notifications: "Notificações" | ||
23 | + enabled_notifications: "Notificações Habilitadas" | ||
24 | + device: "Dispositivo" | ||
25 | + actions: "Ações" | ||
26 | + | ||
27 | + controllers: | ||
28 | + myprofile: | ||
29 | + my_devices: "Meus Dispositivos" | ||
30 | + no_devices: "Nenhum dispositivo conectado à sua conta." | ||
31 | + delete_device: "Apagar Dispositivo" | ||
32 | + event: "Evento" | ||
33 | + enabled: "Ativo?" | ||
34 | + | ||
35 | + admin: | ||
36 | + server_api_key: "Chave da API do Servidor" | ||
37 | + | ||
38 | +pt_BR: | ||
39 | + <<: *pt-BR | ||
40 | +pt: | ||
41 | + <<: *pt-BR |
plugins/push_notification/public/images/control-panel/push-notification-settings.jpg
0 → 100644
2.82 KB
plugins/push_notification/public/images/control-panel/push-notification-settings.png
0 → 100644
1.44 KB
@@ -0,0 +1,8 @@ | @@ -0,0 +1,8 @@ | ||
1 | +.controller-profile_editor a.control-panel-push-notifications { | ||
2 | + background-image: url("/plugins/push_notification/images/control-panel/push-notification-settings.png"); | ||
3 | +} | ||
4 | + | ||
5 | +.controller-profile_editor .msie6 a.control-panel-push-notifications { | ||
6 | + background-image: url("/plugins/push_notification/images/control-panel/push-notification-settings.jpg"); | ||
7 | +} | ||
8 | + |
plugins/push_notification/test/helpers/observers_test_helper.rb
0 → 100644
@@ -0,0 +1,33 @@ | @@ -0,0 +1,33 @@ | ||
1 | +module ObserversTestHelper | ||
2 | + | ||
3 | + def create_add_friend_task | ||
4 | + user1 = fast_create(User) | ||
5 | + person = fast_create(Person, :user_id => user1.id) | ||
6 | + user2 = fast_create(User) | ||
7 | + friend = fast_create(Person, :user_id => user2.id) | ||
8 | + return AddFriend.create!(:requestor => person, :target => friend) | ||
9 | + end | ||
10 | + | ||
11 | + def create_add_member_task | ||
12 | + person = fast_create(Person) | ||
13 | + community = fast_create(Community) | ||
14 | + return AddMember.create!(:requestor => person, :target => community) | ||
15 | + end | ||
16 | + | ||
17 | + def create_suggest_article_task | ||
18 | + person = fast_create(Person) | ||
19 | + community = fast_create(Community) | ||
20 | + return SuggestArticle.create!(:target => community, :article => {:name => 'Munchkin', :body => 'Kill monsters!! Get treasures!! Stab your friends!!'}, :requestor => person) | ||
21 | + end | ||
22 | + | ||
23 | + def create_approve_article_task | ||
24 | + user1 = fast_create(User) | ||
25 | + person = fast_create(Person, :user_id => user1.id) | ||
26 | + article = fast_create(Article, :profile_id => person.id) | ||
27 | + community = fast_create(Community) | ||
28 | + community.add_member(person) | ||
29 | + community.save! | ||
30 | + | ||
31 | + return ApproveArticle.create!(:article => article, :target => community, :requestor => person) | ||
32 | + end | ||
33 | +end |
@@ -0,0 +1,178 @@ | @@ -0,0 +1,178 @@ | ||
1 | +require_relative '../../../../test/unit/api/test_helper' | ||
2 | + | ||
3 | +class PushNotificationApiTest < ActiveSupport::TestCase | ||
4 | + | ||
5 | + def setup | ||
6 | + login_api | ||
7 | + environment = Environment.default | ||
8 | + environment.enable_plugin(PushNotificationPlugin) | ||
9 | + end | ||
10 | + | ||
11 | + should 'list all my device tokens' do | ||
12 | + logged_user = @user | ||
13 | + token1 = PushNotificationPlugin::DeviceToken.create!(:token => "firsttoken", device_name: "my device", :user => logged_user) | ||
14 | + token2 = PushNotificationPlugin::DeviceToken.create!(:token => "secondtoken", device_name: "my device", :user => logged_user) | ||
15 | + | ||
16 | + get "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
17 | + json = JSON.parse(last_response.body) | ||
18 | + assert_equivalent [token1.token, token2.token], json | ||
19 | + end | ||
20 | + | ||
21 | + should 'not list other people device tokens' do | ||
22 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
23 | + user.activate | ||
24 | + PushNotificationPlugin::DeviceToken.create!(:token => "firsttoken", device_name: "my device", :user => user) | ||
25 | + get "/api/v1/push_notification_plugin/device_tokens?#{params.merge(:target_id => user.id).to_query}" | ||
26 | + assert_equal 401, last_response.status | ||
27 | + end | ||
28 | + | ||
29 | + should 'admin see other user\'s device tokens' do | ||
30 | + logged_user = @user | ||
31 | + Environment.default.add_admin(logged_user.person) | ||
32 | + logged_user.reload | ||
33 | + | ||
34 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
35 | + user.activate | ||
36 | + | ||
37 | + token1 = PushNotificationPlugin::DeviceToken.create!(:token => "firsttoken", device_name: "my device", :user => user) | ||
38 | + | ||
39 | + get "/api/v1/push_notification_plugin/device_tokens?#{params.merge(:target_id => user.id).to_query}" | ||
40 | + json = JSON.parse(last_response.body) | ||
41 | + assert_equivalent [token1.token], json | ||
42 | + end | ||
43 | + | ||
44 | +#------------------------------------------------------------------------------------------------------ | ||
45 | + | ||
46 | + should 'add my device token' do | ||
47 | + params.merge!(:device_name => "my_device", :token => "token1") | ||
48 | + post "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
49 | + json = JSON.parse(last_response.body) | ||
50 | + assert_equivalent ["token1"], json["user"]["device_tokens"] | ||
51 | + end | ||
52 | + | ||
53 | + should 'not add device tokens for other people' do | ||
54 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
55 | + user.activate | ||
56 | + params.merge!(:device_name => "my_device", :token => "tokenX", :target_id => user.id) | ||
57 | + post "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
58 | + assert_equal 401, last_response.status | ||
59 | + end | ||
60 | + | ||
61 | + should 'admin add device tokens for other users' do | ||
62 | + logged_user = @user | ||
63 | + Environment.default.add_admin(logged_user.person) | ||
64 | + logged_user.reload | ||
65 | + | ||
66 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
67 | + user.activate | ||
68 | + | ||
69 | + params.merge!(:device_name => "my_device", :token=> "tokenY", :target_id => user.id) | ||
70 | + post "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
71 | + | ||
72 | + json = JSON.parse(last_response.body) | ||
73 | + assert_equivalent ["tokenY"], json["user"]["device_tokens"] | ||
74 | + end | ||
75 | + | ||
76 | +#------------------------------------------------------------------------------------------------------ | ||
77 | + | ||
78 | + should 'delete my device tokens' do | ||
79 | + logged_user = @user | ||
80 | + PushNotificationPlugin::DeviceToken.create!(:token => "firsttoken", device_name: "my device", :user => logged_user) | ||
81 | + PushNotificationPlugin::DeviceToken.create!(:token => "secondtoken", device_name: "my device", :user => logged_user) | ||
82 | + | ||
83 | + params.merge!(:token => "secondtoken") | ||
84 | + delete "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
85 | + json = JSON.parse(last_response.body) | ||
86 | + assert_equivalent ["firsttoken"], json["user"]["device_tokens"] | ||
87 | + end | ||
88 | + | ||
89 | + should 'not delete device tokens for other people' do | ||
90 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
91 | + user.activate | ||
92 | + | ||
93 | + PushNotificationPlugin::DeviceToken.create!(:token => "secondtoken", device_name: "my device", :user => user) | ||
94 | + user.reload | ||
95 | + | ||
96 | + params.merge!(:token => "secondtoken", :target_id => user.id) | ||
97 | + delete "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
98 | + assert_equal 401, last_response.status | ||
99 | + assert_equivalent user.device_token_list, ["secondtoken"] | ||
100 | + end | ||
101 | + | ||
102 | + should 'admin delete device tokens for other users' do | ||
103 | + logged_user = @user | ||
104 | + Environment.default.add_admin(logged_user.person) | ||
105 | + logged_user.reload | ||
106 | + | ||
107 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
108 | + user.activate | ||
109 | + | ||
110 | + PushNotificationPlugin::DeviceToken.create!(:token => "firsttoken", device_name: "my device", :user => user) | ||
111 | + PushNotificationPlugin::DeviceToken.create!(:token => "secondtoken", device_name: "my device", :user => user) | ||
112 | + user.reload | ||
113 | + | ||
114 | + params.merge!(:token=> "secondtoken", :target_id => user.id) | ||
115 | + delete "/api/v1/push_notification_plugin/device_tokens?#{params.to_query}" | ||
116 | + | ||
117 | + json = JSON.parse(last_response.body) | ||
118 | + assert_equivalent ["firsttoken"], json["user"]["device_tokens"] | ||
119 | + end | ||
120 | + | ||
121 | +#-------------------------------------------------------------------------------------------------------------------------------------------- | ||
122 | + | ||
123 | + should 'list all notifications disabled by default for new users' do | ||
124 | + get "/api/v1/push_notification_plugin/notification_settings?#{params.to_query}" | ||
125 | + json = JSON.parse(last_response.body) | ||
126 | + json["user"]["notification_settings"].each_pair do |notification, status| | ||
127 | + refute status | ||
128 | + end | ||
129 | + end | ||
130 | + | ||
131 | + should 'list device tokens notification options' do | ||
132 | + logged_user = @user | ||
133 | + logged_user.notification_settings.activate_notification "new_comment" | ||
134 | + logged_user.save! | ||
135 | + | ||
136 | + get "/api/v1/push_notification_plugin/notification_settings?#{params.to_query}" | ||
137 | + json = JSON.parse(last_response.body) | ||
138 | + assert_equal true, json["user"]["notification_settings"]["new_comment"] | ||
139 | + assert_equal false, json["user"]["notification_settings"]["add_friend"] | ||
140 | + end | ||
141 | + | ||
142 | + should 'get possible notifications' do | ||
143 | + get "/api/v1/push_notification_plugin/possible_notifications?#{params.to_query}" | ||
144 | + json = JSON.parse(last_response.body) | ||
145 | + assert_equivalent PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys, json["possible_notifications"] | ||
146 | + end | ||
147 | + | ||
148 | + should 'change device tokens notification options' do | ||
149 | + logged_user = @user | ||
150 | + params.merge!("new_comment"=> "true") | ||
151 | + | ||
152 | + post "/api/v1/push_notification_plugin/notification_settings?#{params.to_query}" | ||
153 | + logged_user.reload | ||
154 | + json = JSON.parse(last_response.body) | ||
155 | + assert_equal true, json["user"]["notification_settings"]["new_comment"] | ||
156 | + assert_equal true, logged_user.notification_settings.hash_flags["new_comment"] | ||
157 | + end | ||
158 | + | ||
159 | + should 'get active notifications list' do | ||
160 | + logged_user = @user | ||
161 | + logged_user.notification_settings.activate_notification "new_comment" | ||
162 | + logged_user.save! | ||
163 | + | ||
164 | + get "/api/v1/push_notification_plugin/active_notifications?#{params.to_query}" | ||
165 | + json = JSON.parse(last_response.body) | ||
166 | + assert_equivalent ["new_comment"], json | ||
167 | + end | ||
168 | + | ||
169 | + should 'get inactive notifications list' do | ||
170 | + logged_user = @user | ||
171 | + logged_user.notification_settings.activate_notification "new_comment" | ||
172 | + logged_user.save | ||
173 | + | ||
174 | + get "/api/v1/push_notification_plugin/inactive_notifications?#{params.to_query}" | ||
175 | + json = JSON.parse(last_response.body) | ||
176 | + assert_equivalent (PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys-["new_comment"]), json | ||
177 | + end | ||
178 | +end |
plugins/push_notification/test/unit/notification_settings_test.rb
0 → 100644
@@ -0,0 +1,102 @@ | @@ -0,0 +1,102 @@ | ||
1 | +require_relative '../../lib/push_notification_helper.rb' | ||
2 | +require 'test_helper' | ||
3 | + | ||
4 | +class NotificationSettingsTest < ActiveSupport::TestCase | ||
5 | + include PushNotificationHelper | ||
6 | + | ||
7 | + should 'list notifications options in a hash' do | ||
8 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
9 | + user.activate | ||
10 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
11 | + user.reload | ||
12 | + assert_equivalent PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys, settings.hash_flags.keys | ||
13 | + | ||
14 | + settings.hash_flags.each_pair do |notification, status| | ||
15 | + assert !!status == status | ||
16 | + end | ||
17 | + end | ||
18 | + | ||
19 | + should 'all notifications be disabled by default for new settingss' do | ||
20 | + user = User.create!(:login => 'outro', :email => 'outro@example.com', :password => 'outro', :password_confirmation => 'outro', :environment => Environment.default) | ||
21 | + user.activate | ||
22 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
23 | + settings.hash_flags.each_pair do |notification, status| | ||
24 | + refute status | ||
25 | + end | ||
26 | + end | ||
27 | + | ||
28 | + should 'activate a notification for a settings' do | ||
29 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
30 | + user.activate | ||
31 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
32 | + settings.activate_notification "new_comment" | ||
33 | + settings.save! | ||
34 | + | ||
35 | + assert_equal true, settings.hash_flags["new_comment"] | ||
36 | + end | ||
37 | + | ||
38 | + should 'deactivate a notification for a settings' do | ||
39 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
40 | + user.activate | ||
41 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
42 | + | ||
43 | + settings.activate_notification "new_comment" | ||
44 | + settings.save! | ||
45 | + assert_equal true, settings.hash_flags["new_comment"] | ||
46 | + | ||
47 | + settings.deactivate_notification "new_comment" | ||
48 | + settings.save! | ||
49 | + assert_equal false, settings.hash_flags["new_comment"] | ||
50 | + end | ||
51 | + | ||
52 | + should 'set notification to specific state' do | ||
53 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
54 | + user.activate | ||
55 | + settings = PushNotificationPlugin::NotificationSettings.new(:user => user) | ||
56 | + | ||
57 | + settings.set_notification_state "new_comment", 1 | ||
58 | + settings.save! | ||
59 | + assert_equal true, settings.hash_flags["new_comment"] | ||
60 | + | ||
61 | + settings.set_notification_state "new_comment", 0 | ||
62 | + settings.save! | ||
63 | + assert_equal false, settings.hash_flags["new_comment"] | ||
64 | + end | ||
65 | + | ||
66 | + should 'check if notification is active' do | ||
67 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
68 | + user.activate | ||
69 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
70 | + | ||
71 | + settings.activate_notification "new_comment" | ||
72 | + settings.save! | ||
73 | + | ||
74 | + assert_equal true, settings.active?("new_comment") | ||
75 | + end | ||
76 | + | ||
77 | + should 'list active notifications' do | ||
78 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
79 | + user.activate | ||
80 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
81 | + | ||
82 | + settings.activate_notification "new_comment" | ||
83 | + settings.save! | ||
84 | + assert_equivalent ["new_comment"], settings.active_notifications | ||
85 | + | ||
86 | + settings.activate_notification "add_friend" | ||
87 | + settings.save! | ||
88 | + assert_equivalent ["new_comment","add_friend"], settings.active_notifications | ||
89 | + end | ||
90 | + | ||
91 | + should 'list inactive notifications' do | ||
92 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
93 | + user.activate | ||
94 | + settings = PushNotificationPlugin::NotificationSettings.create!(:user => user) | ||
95 | + | ||
96 | + assert_equivalent PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys, settings.inactive_notifications | ||
97 | + | ||
98 | + settings.activate_notification "new_comment" | ||
99 | + settings.save! | ||
100 | + assert_equivalent (PushNotificationPlugin::NotificationSettings::NOTIFICATIONS.keys-["new_comment"]), settings.inactive_notifications | ||
101 | + end | ||
102 | +end |
@@ -0,0 +1,86 @@ | @@ -0,0 +1,86 @@ | ||
1 | +require 'test_helper' | ||
2 | +require_relative '../helpers/observers_test_helper' | ||
3 | + | ||
4 | +class ObserversTest < ActiveSupport::TestCase | ||
5 | + include ObserversTestHelper | ||
6 | + | ||
7 | + def setup | ||
8 | + environment = Environment.default | ||
9 | + environment.enable_plugin(PushNotificationPlugin) | ||
10 | + end | ||
11 | + | ||
12 | + should 'send notification when creating a comment' do | ||
13 | + PushNotificationPlugin.any_instance.expects(:send_to_users) | ||
14 | + person = fast_create(Person) | ||
15 | + article = fast_create(Article, :profile_id => person.id) | ||
16 | + Comment.create!(:author => person, :title => 'test comment', :body => 'body!', :source => article) | ||
17 | + end | ||
18 | + | ||
19 | + should 'send notification when adding a friend' do | ||
20 | + PushNotificationPlugin.any_instance.expects(:send_to_users) | ||
21 | + create_add_friend_task | ||
22 | + end | ||
23 | + | ||
24 | + should 'send notification when friendship is accepted' do | ||
25 | + PushNotificationPlugin.any_instance.expects(:send_to_users).twice | ||
26 | + create_add_friend_task.finish | ||
27 | + end | ||
28 | + | ||
29 | + should 'send notification when friendship is refused' do | ||
30 | + PushNotificationPlugin.any_instance.expects(:send_to_users).twice | ||
31 | + create_add_friend_task.cancel | ||
32 | + end | ||
33 | + | ||
34 | + should 'send notification when adding a member to a community' do | ||
35 | + PushNotificationPlugin.any_instance.expects(:send_to_users) | ||
36 | + create_add_member_task | ||
37 | + end | ||
38 | + | ||
39 | + should 'send notification when accepting a member in a community' do | ||
40 | + PushNotificationPlugin.any_instance.expects(:send_to_users).twice | ||
41 | + create_add_member_task.finish | ||
42 | + end | ||
43 | + | ||
44 | + should 'send notification when rejecting a member in a community' do | ||
45 | + PushNotificationPlugin.any_instance.expects(:send_to_users).twice | ||
46 | + create_add_member_task.cancel | ||
47 | + end | ||
48 | + | ||
49 | + should 'send notification when suggesting an article' do | ||
50 | + PushNotificationPlugin.any_instance.expects(:send_to_users).twice | ||
51 | + create_suggest_article_task | ||
52 | + end | ||
53 | + | ||
54 | + should 'send notification when accepting suggested article' do | ||
55 | + PushNotificationPlugin.any_instance.expects(:send_to_users).times(5) | ||
56 | + create_suggest_article_task.finish | ||
57 | + end | ||
58 | + | ||
59 | + should 'send notification when rejecting suggested article' do | ||
60 | + PushNotificationPlugin.any_instance.expects(:send_to_users).times(4) | ||
61 | + create_suggest_article_task.cancel | ||
62 | + end | ||
63 | + | ||
64 | + should 'send notification when an article needs to be approved' do | ||
65 | + PushNotificationPlugin.any_instance.expects(:send_to_users) | ||
66 | + create_approve_article_task | ||
67 | + end | ||
68 | + | ||
69 | + should 'send notification when an article is approved' do | ||
70 | + PushNotificationPlugin.any_instance.expects(:send_to_users).times(3) | ||
71 | + create_approve_article_task.finish | ||
72 | + end | ||
73 | + | ||
74 | + should 'send notification when an article is not approved' do | ||
75 | + PushNotificationPlugin.any_instance.expects(:send_to_users).times(2) | ||
76 | + create_approve_article_task.cancel | ||
77 | + end | ||
78 | + | ||
79 | + should 'send notification when an article is created' do | ||
80 | + PushNotificationPlugin.any_instance.expects(:send_to_users).twice | ||
81 | + community = fast_create(Community) | ||
82 | + person = fast_create(Person) | ||
83 | + Article.create!(:name => 'great article', :profile => community) | ||
84 | + Article.create!(:name => 'great article', :profile => person) | ||
85 | + end | ||
86 | +end |
plugins/push_notification/test/unit/push_notification_helper_test.rb
0 → 100644
@@ -0,0 +1,38 @@ | @@ -0,0 +1,38 @@ | ||
1 | +require_relative '../../lib/push_notification_helper.rb' | ||
2 | +require 'test_helper' | ||
3 | + | ||
4 | +class PushNotificationHelperTest < ActiveSupport::TestCase | ||
5 | + include PushNotificationHelper | ||
6 | + | ||
7 | + should 'get all tokens for a group of users' do | ||
8 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
9 | + user.activate | ||
10 | + PushNotificationPlugin::DeviceToken.create!(:token => "tokenHomer1", device_name: "my device", :user => user) | ||
11 | + PushNotificationPlugin::DeviceToken.create!(:token => "tokenHomer2", device_name: "my device", :user => user) | ||
12 | + | ||
13 | + user2 = User.create!(:login => 'bart', :email => 'bart@example.com', :password => 'fart', :password_confirmation => 'fart', :environment => Environment.default) | ||
14 | + user2.activate | ||
15 | + PushNotificationPlugin::DeviceToken.create!(:token => "tokenBart1", device_name: "my device", :user => user2) | ||
16 | + PushNotificationPlugin::DeviceToken.create!(:token => "tokenBart2", device_name: "my device", :user => user2) | ||
17 | + PushNotificationPlugin::DeviceToken.create!(:token => "tokenBart3", device_name: "my device", :user => user2) | ||
18 | + | ||
19 | + tokens = tokens_for_users([user,user2]) | ||
20 | + | ||
21 | + assert_equivalent ["tokenHomer1","tokenHomer2","tokenBart1","tokenBart2","tokenBart3"], tokens | ||
22 | + end | ||
23 | + | ||
24 | + should 'filter users registered for a notification' do | ||
25 | + user = User.create!(:login => 'homer', :email => 'homer@example.com', :password => 'beer', :password_confirmation => 'beer', :environment => Environment.default) | ||
26 | + user.activate | ||
27 | + user2 = User.create!(:login => 'bart', :email => 'bart@example.com', :password => 'fart', :password_confirmation => 'fart', :environment => Environment.default) | ||
28 | + user2.activate | ||
29 | + | ||
30 | + user.notification_settings.activate_notification "new_comment" | ||
31 | + user.save! | ||
32 | + | ||
33 | + users = filter_users_for_flag("new_comment",[user,user2]) | ||
34 | + | ||
35 | + assert_equivalent [user], users | ||
36 | + end | ||
37 | + | ||
38 | +end |
plugins/push_notification/test/unit/push_notification_plugin_test.rb
0 → 100644
@@ -0,0 +1,68 @@ | @@ -0,0 +1,68 @@ | ||
1 | +require_relative '../../lib/push_notification_helper.rb' | ||
2 | +require 'test_helper' | ||
3 | + | ||
4 | +class PushNotificationPluginTest < ActiveSupport::TestCase | ||
5 | + include PushNotificationHelper | ||
6 | + | ||
7 | + def setup | ||
8 | + environment = Environment.default | ||
9 | + environment.enable_plugin(PushNotificationPlugin) | ||
10 | + end | ||
11 | + | ||
12 | + should 'subscribe and unsubscribe to notification' do | ||
13 | + class AnyClass | ||
14 | + def self.push_notification_new_comment_additional_users | ||
15 | + ['YO'] | ||
16 | + end | ||
17 | + end | ||
18 | + | ||
19 | + assert PushNotificationPlugin::subscribe(Environment.default, "new_comment", AnyClass) | ||
20 | + assert_equivalent PushNotificationPlugin::subscribers(Environment.default, "new_comment"), [AnyClass.name.constantize] | ||
21 | + assert PushNotificationPlugin::unsubscribe(Environment.default, "new_comment", AnyClass) | ||
22 | + assert_empty PushNotificationPlugin::subscribers(Environment.default, "new_comment") | ||
23 | + end | ||
24 | + | ||
25 | + should 'get additional users from subscribers' do | ||
26 | + class AnyClass | ||
27 | + def self.push_notification_new_comment_additional_users | ||
28 | + ['YO'] | ||
29 | + end | ||
30 | + end | ||
31 | + | ||
32 | + PushNotificationPlugin::subscribe(Environment.default, "new_comment", AnyClass) | ||
33 | + AnyClass.expects(:push_notification_new_comment_additional_users).returns(['YO']) | ||
34 | + subscribers_additional_users("new_comment", Environment.default) | ||
35 | + end | ||
36 | + | ||
37 | + should 'return nill for unknown notification subscription methods' do | ||
38 | + class AnyEventCallbackClass | ||
39 | + def self.push_notification_any_event_additional_users | ||
40 | + ['YO'] | ||
41 | + end | ||
42 | + end | ||
43 | + | ||
44 | + assert_nil PushNotificationPlugin::subscribe(Environment.default, "any_event", AnyEventCallbackClass) | ||
45 | + assert_nil PushNotificationPlugin::unsubscribe(Environment.default, "any_event", AnyEventCallbackClass) | ||
46 | + assert_nil PushNotificationPlugin::subscribers(Environment.default, "any_event") | ||
47 | + end | ||
48 | + | ||
49 | + should 'return empty list for known notification without subscribers' do | ||
50 | + class CommentCallbackClass | ||
51 | + def self.push_notification_new_comment_additional_users | ||
52 | + ['YO'] | ||
53 | + end | ||
54 | + end | ||
55 | + | ||
56 | + refute PushNotificationPlugin::unsubscribe(Environment.default, "new_comment", CommentCallbackClass) | ||
57 | + assert_empty PushNotificationPlugin::subscribers(Environment.default, "new_comment") | ||
58 | + end | ||
59 | + | ||
60 | + should 'not subscribe to notification if correspondent method callback is not implemented' do | ||
61 | + class NoCallbackClass | ||
62 | + end | ||
63 | + | ||
64 | + assert_nil PushNotificationPlugin::subscribe(Environment.default, "new_comment", NoCallbackClass) | ||
65 | + assert_empty PushNotificationPlugin::subscribers(Environment.default, "new_comment") | ||
66 | + end | ||
67 | + | ||
68 | +end |
plugins/push_notification/views/_notification_events_form.html.erb
0 → 100644
@@ -0,0 +1,17 @@ | @@ -0,0 +1,17 @@ | ||
1 | +<table> | ||
2 | + <tr> | ||
3 | + <th><%= t("push_notification_plugin.controllers.myprofile.event") %> </th> | ||
4 | + <th><%= t("push_notification_plugin.controllers.myprofile.enabled") %> </th> | ||
5 | + </tr> | ||
6 | + | ||
7 | + <% settings.each do |event, checked|%> | ||
8 | + <tr> | ||
9 | + <td><%= t("push_notification_plugin.events.#{event}") %></td> | ||
10 | + <td> | ||
11 | + <%= hidden_field_tag "settings[#{event}]", "0" %> | ||
12 | + <%= check_box_tag "settings[#{event}]", "1", (checked == "1" || checked == true) %> | ||
13 | + </td> | ||
14 | + </tr> | ||
15 | + <% end %> | ||
16 | + | ||
17 | +</table> |
plugins/push_notification/views/push_notification_plugin_admin/_notification_events_form.html.erb
0 → 120000
plugins/push_notification/views/push_notification_plugin_admin/index.html.erb
0 → 100644
@@ -0,0 +1,14 @@ | @@ -0,0 +1,14 @@ | ||
1 | +<h1><%= t("push_notification_plugin.lib.plugin.settings")%></h1> | ||
2 | + | ||
3 | +<%= form_for(:server_settings, :url => {:action => 'update'}) do |f| %> | ||
4 | + | ||
5 | + <%= labelled_form_field t('push_notification_plugin.controllers.admin.server_api_key'), f.text_field(:server_api_key, :size => "80") %> | ||
6 | + | ||
7 | + <h3><%= t('push_notification_plugin.lib.plugin.enabled_notifications')%></h3> | ||
8 | + <%= render partial: "notification_events_form", locals:{f: f, settings: @settings} %> | ||
9 | + | ||
10 | + <% button_bar do %> | ||
11 | + <%= submit_button(:save, c_('Save'), :cancel => {:controller => 'plugins'}) %> | ||
12 | + <% end %> | ||
13 | + | ||
14 | +<% end %> |
plugins/push_notification/views/push_notification_plugin_myprofile/_notification_events_form.html.erb
0 → 120000
plugins/push_notification/views/push_notification_plugin_myprofile/index.html.erb
0 → 100644
@@ -0,0 +1,25 @@ | @@ -0,0 +1,25 @@ | ||
1 | +<h1><%= t("push_notification_plugin.controllers.myprofile.my_devices") %></h1> | ||
2 | + <% if @devices.blank? %> | ||
3 | + <div><%= t("push_notification_plugin.controllers.myprofile.no_devices")%></div> | ||
4 | + <% else %> | ||
5 | + <table> | ||
6 | + <tr> | ||
7 | + <th><%= t("push_notification_plugin.lib.plugin.device")%></th> | ||
8 | + <th><%= t("push_notification_plugin.lib.plugin.actions") %></th> | ||
9 | + </tr> | ||
10 | + <% @devices.each do |d| %> | ||
11 | + <tr> | ||
12 | + <td><%= d.device_name %></td> | ||
13 | + <td><%= button_without_text(:delete, t('push_notification_plugin.controllers.myprofile.delete_device'), {:controller => "push_notification_plugin_myprofile", :action => "delete_device", :params => {:device => d}}, method: :delete, id: "delete_device_#{d.id}") %></td> | ||
14 | + </tr> | ||
15 | + <% end %> | ||
16 | + </table> | ||
17 | + <% end %> | ||
18 | +<%= form_for(:settings, :url => {:controller => "push_notification_plugin_myprofile", :action => "update_settings"}) do |f| %> | ||
19 | + <h1><%= t('push_notification_plugin.lib.plugin.enabled_notifications') %></h1> | ||
20 | + <%= render partial: "notification_events_form", locals: {f: f, settings: @settings} %> | ||
21 | + <% button_bar do %> | ||
22 | + <%= submit_button(:save, _('Save')) %> | ||
23 | + <%= button(:back, _('Back to control panel'), :controller => (profile.nil? ? 'admin_panel': 'profile_editor')) %> | ||
24 | + <% end %> | ||
25 | +<% end %> |