notifiable-rails 0.7.2 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/generators/notifiable/install/install_generator.rb +1 -0
- data/lib/generators/notifiable/install/templates/create_notifiable_apps.rb +10 -0
- data/lib/generators/notifiable/install/templates/create_notifiable_device_tokens.rb +1 -0
- data/lib/generators/notifiable/install/templates/create_notifiable_notifications.rb +5 -0
- data/lib/notifiable.rb +4 -3
- data/lib/notifiable/app.rb +8 -0
- data/lib/notifiable/batch.rb +22 -6
- data/lib/notifiable/device_token.rb +2 -4
- data/lib/notifiable/notification.rb +3 -0
- data/lib/notifiable/version.rb +1 -1
- data/spec/batch_spec.rb +27 -14
- data/spec/controllers/device_tokens_controller_spec.rb +21 -7
- data/spec/notifiable_server_spec.rb +5 -3
- data/spec/notifiable_spec.rb +5 -2
- data/spec/notification_spec.rb +3 -3
- data/spec/support/factories.rb +9 -2
- data/spec/test_app/db/migrate/20131210115649_create_notifiable_apps.rb +10 -0
- data/spec/test_app/db/migrate/20131228225139_create_notifiable_device_tokens.rb +3 -2
- data/spec/test_app/db/migrate/20131228225140_create_notifiable_notifications.rb +14 -4
- data/spec/test_app/db/schema.rb +11 -4
- data/spec/test_app/db/test.sqlite3 +0 -0
- data/spec/test_app/log/test.log +34718 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8bb9073ea05a2f8fc69c60f6f6cfbf0dfe7fe777
|
4
|
+
data.tar.gz: 0eb9ab880e47f9f1c5821fa5c71c1113e6fcbb79
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 63de150bca8c6845719a322493b3470b2381cb5cff93be4690dcbd92924475a6501e2e12745634cf0a8b423119f07192a18615c4f2e41924237edfa5c1c0f221
|
7
|
+
data.tar.gz: cb2f7131af80e79151cd0b3ff50357be1c9f4b903a4f7d4d441dc5e6fe6c0871e4d63fd7b89d0a6995829cc48a23f76a1f1e63b234a89d9517bb21ed3c0f4238
|
@@ -21,6 +21,7 @@ module Notifiable
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def copy_migrations
|
24
|
+
migration_template "create_notifiable_apps.rb", "db/migrate/create_notifiable_apps.rb"
|
24
25
|
migration_template "create_notifiable_device_tokens.rb", "db/migrate/create_notifiable_device_tokens.rb"
|
25
26
|
migration_template "create_notifiable_notifications.rb", "db/migrate/create_notifiable_notifications.rb"
|
26
27
|
migration_template "create_notifiable_notification_device_tokens.rb", "db/migrate/create_notifiable_notification_device_tokens.rb"
|
@@ -4,6 +4,11 @@ class CreateNotifiableNotifications < ActiveRecord::Migration
|
|
4
4
|
create_table :notifiable_notifications do |t|
|
5
5
|
t.text :message
|
6
6
|
t.text :params
|
7
|
+
t.references :app
|
8
|
+
|
9
|
+
#stats
|
10
|
+
t.integer :sent_count
|
11
|
+
t.integer :gateway_accepted_count
|
7
12
|
|
8
13
|
# APNS - Optional
|
9
14
|
#t.integer :badge
|
data/lib/notifiable.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
require 'notifiable/active_record'
|
2
|
+
require 'notifiable/app'
|
2
3
|
require 'notifiable/notifiable_concern'
|
3
4
|
require 'notifiable/railtie' if defined?(Rails)
|
4
5
|
require 'notifiable/engine'
|
@@ -13,7 +14,7 @@ module Notifiable
|
|
13
14
|
mattr_accessor :api_controller_class
|
14
15
|
|
15
16
|
mattr_accessor :api_device_token_params
|
16
|
-
@@api_device_token_params = [:device_id, :token, :provider]
|
17
|
+
@@api_device_token_params = [:device_id, :token, :provider, :app_id]
|
17
18
|
|
18
19
|
mattr_accessor :user_class
|
19
20
|
|
@@ -27,8 +28,8 @@ module Notifiable
|
|
27
28
|
yield self
|
28
29
|
end
|
29
30
|
|
30
|
-
def self.batch(
|
31
|
-
b = Batch.new(
|
31
|
+
def self.batch(app = Notifiable::App.first)
|
32
|
+
b = Batch.new(app)
|
32
33
|
yield(b)
|
33
34
|
b.close
|
34
35
|
end
|
@@ -0,0 +1,8 @@
|
|
1
|
+
module Notifiable
|
2
|
+
class App < ActiveRecord::Base
|
3
|
+
has_many :device_tokens, :class_name => 'Notifiable::DeviceToken', :dependent => :destroy
|
4
|
+
has_many :notifications, :class_name => 'Notifiable::App', :dependent => :destroy
|
5
|
+
|
6
|
+
serialize :configuration
|
7
|
+
end
|
8
|
+
end
|
data/lib/notifiable/batch.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
1
|
module Notifiable
|
2
2
|
class Batch
|
3
|
-
attr_accessor :notifiers
|
4
3
|
|
5
|
-
def initialize(
|
4
|
+
def initialize(app)
|
5
|
+
raise "Must specify Notifiable::App" unless app
|
6
|
+
@app = app
|
6
7
|
@notifiers = {}
|
7
|
-
@
|
8
|
+
@notification_ids = []
|
8
9
|
end
|
9
10
|
|
10
11
|
def add_notifiable(notification, notifiable)
|
@@ -15,24 +16,39 @@ module Notifiable
|
|
15
16
|
|
16
17
|
def add_device_token(notification, d)
|
17
18
|
provider = d.provider.to_sym
|
18
|
-
|
19
|
+
|
19
20
|
unless @notifiers[provider]
|
20
21
|
clazz = Notifiable.notifier_classes[provider]
|
21
22
|
raise "Notifier #{provider} not configured" unless clazz
|
22
23
|
@notifiers[provider] = clazz.new
|
23
24
|
@notifiers[provider].env = Rails.env
|
24
|
-
|
25
|
+
|
26
|
+
if @app.configuration && @app.configuration[provider]
|
27
|
+
@app.configuration[provider].each_pair {|key, value| @notifiers[provider].send("#{key}=", value) if @notifiers[provider].methods.include?("#{key}=".to_sym) }
|
28
|
+
end
|
25
29
|
end
|
26
30
|
|
27
31
|
notifier = @notifiers[provider]
|
28
32
|
if d.is_valid? && !notifier.nil?
|
29
|
-
notifier.send_notification(notification, d)
|
33
|
+
notifier.send_notification(notification, d)
|
34
|
+
@notification_ids << notification.id
|
30
35
|
end
|
31
36
|
end
|
32
37
|
|
33
38
|
def close
|
34
39
|
@notifiers.each_value {|n| n.close}
|
35
40
|
@notifiers = nil
|
41
|
+
summarise
|
36
42
|
end
|
43
|
+
|
44
|
+
private
|
45
|
+
def summarise
|
46
|
+
notifications = Notification.where(:id => @notification_ids)
|
47
|
+
notifications.each do |n|
|
48
|
+
n.sent_count = n.notification_statuses.count
|
49
|
+
n.gateway_accepted_count = n.notification_statuses.where(:status => 0).count
|
50
|
+
n.save
|
51
|
+
end
|
52
|
+
end
|
37
53
|
end
|
38
54
|
end
|
@@ -1,11 +1,9 @@
|
|
1
1
|
module Notifiable
|
2
|
-
|
3
2
|
class DeviceToken < ActiveRecord::Base
|
3
|
+
belongs_to :app, :class_name => "Notifiable::App"
|
4
4
|
|
5
|
+
validates_presence_of :token, :provider, :app
|
5
6
|
validates_uniqueness_of :token
|
6
|
-
validates_presence_of :token
|
7
|
-
validates_presence_of :provider
|
8
|
-
|
9
7
|
|
10
8
|
def user
|
11
9
|
user_id.blank? ? nil : Notifiable.user_class.find(user_id)
|
data/lib/notifiable/version.rb
CHANGED
data/spec/batch_spec.rb
CHANGED
@@ -2,32 +2,39 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe Notifiable::Batch do
|
4
4
|
let(:user1) { FactoryGirl.create(:user) }
|
5
|
-
let(:notification) {
|
5
|
+
let(:notification) { FactoryGirl.create(:notification, :app => app) }
|
6
|
+
let(:app) { FactoryGirl.create(:app, :configuration => {:configurable_mock => {:use_sandbox => true}}) }
|
6
7
|
|
7
8
|
it "adds a notifiable object" do
|
8
|
-
FactoryGirl.create(:mock_token, :provider => :configurable_mock, :user_id => user1.id)
|
9
|
+
FactoryGirl.create(:mock_token, :provider => :configurable_mock, :user_id => user1.id, :app => app)
|
9
10
|
|
10
|
-
b = Notifiable::Batch.new
|
11
|
+
b = Notifiable::Batch.new(app)
|
11
12
|
b.add_notifiable(notification, user1)
|
13
|
+
b.close
|
12
14
|
|
13
|
-
Notifiable::NotificationStatus.count == 1
|
15
|
+
Notifiable::NotificationStatus.count.should == 1
|
16
|
+
saved_notification = Notifiable::Notification.first
|
17
|
+
saved_notification.sent_count.should == 1
|
18
|
+
saved_notification.gateway_accepted_count.should == 1
|
14
19
|
end
|
15
20
|
|
16
21
|
it "adds a device token" do
|
17
|
-
FactoryGirl.create(:mock_token, :provider => :configurable_mock, :user_id => user1.id)
|
22
|
+
token = FactoryGirl.create(:mock_token, :provider => :configurable_mock, :user_id => user1.id, :app => app)
|
18
23
|
|
19
|
-
b = Notifiable::Batch.new
|
20
|
-
b.add_device_token(notification,
|
24
|
+
b = Notifiable::Batch.new(app)
|
25
|
+
b.add_device_token(notification, token)
|
26
|
+
b.close
|
21
27
|
|
22
|
-
Notifiable::NotificationStatus.count == 1
|
28
|
+
Notifiable::NotificationStatus.count.should == 1
|
29
|
+
saved_notification = Notifiable::Notification.first
|
30
|
+
saved_notification.sent_count.should == 1
|
31
|
+
saved_notification.gateway_accepted_count.should == 1
|
23
32
|
end
|
24
33
|
|
25
|
-
it "configures the provider" do
|
26
|
-
FactoryGirl.create(:mock_token, :provider => :configurable_mock, :user_id => user1.id)
|
27
|
-
|
28
|
-
config = {:configurable_mock => {:use_sandbox => true}}
|
34
|
+
it "configures the provider via an App" do
|
35
|
+
FactoryGirl.create(:mock_token, :provider => :configurable_mock, :user_id => user1.id, :app => app)
|
29
36
|
|
30
|
-
b = Notifiable::Batch.new(
|
37
|
+
b = Notifiable::Batch.new(app)
|
31
38
|
b.add_notifiable(notification, user1)
|
32
39
|
|
33
40
|
b.notifiers[:configurable_mock].env.should eql Rails.env
|
@@ -36,11 +43,17 @@ describe Notifiable::Batch do
|
|
36
43
|
|
37
44
|
end
|
38
45
|
|
46
|
+
module Notifiable
|
47
|
+
class Batch
|
48
|
+
attr_accessor :notifiers
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
39
52
|
class ConfigurableMockNotifier < Notifiable::NotifierBase
|
40
53
|
attr_accessor :use_sandbox
|
41
54
|
|
42
55
|
def enqueue(notification, device_token)
|
43
|
-
processed(notification, device_token,
|
56
|
+
processed(notification, device_token, 0)
|
44
57
|
end
|
45
58
|
end
|
46
59
|
|
@@ -5,6 +5,7 @@ describe Notifiable::DeviceTokensController do
|
|
5
5
|
let(:user1) { FactoryGirl.create(:user) }
|
6
6
|
let(:user2) { FactoryGirl.create(:user_with_mock_token) }
|
7
7
|
let(:user2_device_token) { user2.device_tokens.first }
|
8
|
+
let(:app) { FactoryGirl.create(:app) }
|
8
9
|
|
9
10
|
before(:each) do
|
10
11
|
@request.env["HTTP_ACCEPT"] = "application/json"
|
@@ -12,29 +13,33 @@ describe Notifiable::DeviceTokensController do
|
|
12
13
|
end
|
13
14
|
|
14
15
|
it "creates a new device token for an existing user" do
|
15
|
-
post :create, :token => "ABC123", :user_email => user1.email, :provider => :apns
|
16
|
+
post :create, :token => "ABC123", :user_email => user1.email, :provider => :apns, :app_id => app.id
|
16
17
|
|
17
18
|
expect(response).to be_success
|
18
19
|
|
19
20
|
Notifiable::DeviceToken.count.should == 1
|
20
21
|
user1.device_tokens.count.should == 1
|
21
|
-
user1.device_tokens.first
|
22
|
-
|
22
|
+
dt = user1.device_tokens.first
|
23
|
+
dt.token.should.eql? "ABC123"
|
24
|
+
dt.provider.should.eql? :apns
|
25
|
+
dt.app.should.eql? app
|
23
26
|
end
|
24
27
|
|
25
28
|
it "creates a new device token for an anonymous user" do
|
26
|
-
post :create, :token => "ABC123", :provider => :apns
|
29
|
+
post :create, :token => "ABC123", :provider => :apns, :app_id => app.id
|
27
30
|
|
28
31
|
expect(response).to be_success
|
29
32
|
|
30
33
|
Notifiable::DeviceToken.count.should == 1
|
31
|
-
Notifiable::DeviceToken.first
|
32
|
-
|
34
|
+
dt = Notifiable::DeviceToken.first
|
35
|
+
dt.token.should.eql? "ABC123"
|
36
|
+
dt.provider.should.eql? :apns
|
37
|
+
dt.app.should.eql? app
|
33
38
|
User.count.should == 0
|
34
39
|
end
|
35
40
|
|
36
41
|
it "creates a new device token with a device_id" do
|
37
|
-
post :create, :token => "ABC123", :device_id => "DEF456", :user_email => user1.email, :provider => :mpns
|
42
|
+
post :create, :token => "ABC123", :device_id => "DEF456", :user_email => user1.email, :provider => :mpns, :app_id => app.id
|
38
43
|
|
39
44
|
expect(response).to be_success
|
40
45
|
|
@@ -43,6 +48,7 @@ describe Notifiable::DeviceTokensController do
|
|
43
48
|
dt = user1.device_tokens.first
|
44
49
|
dt.token.should eql 'ABC123'
|
45
50
|
dt.provider.should eql 'mpns'
|
51
|
+
dt.app.should.eql? app
|
46
52
|
dt.device_id.should eql "DEF456"
|
47
53
|
end
|
48
54
|
|
@@ -58,6 +64,7 @@ describe Notifiable::DeviceTokensController do
|
|
58
64
|
dt = user1.device_tokens.first
|
59
65
|
dt.token.should eql 'ABC123'
|
60
66
|
dt.provider.should eql 'mpns'
|
67
|
+
dt.app.should.eql? app
|
61
68
|
dt.device_id.should eql "DEF456"
|
62
69
|
end
|
63
70
|
|
@@ -82,6 +89,13 @@ describe Notifiable::DeviceTokensController do
|
|
82
89
|
Notifiable::DeviceToken.where(:token => user2_device_token.token).count.should == 1
|
83
90
|
end
|
84
91
|
|
92
|
+
it "doesn't create a token if no app is specified" do
|
93
|
+
post :create, :token => "ABC123", :device_id => "DEF456", :user_email => user1.email, :provider => :mpns
|
94
|
+
|
95
|
+
expect(response.status).to eq(422)
|
96
|
+
Notifiable::DeviceToken.count.should == 0
|
97
|
+
end
|
98
|
+
|
85
99
|
it "returns not found if the token doesnt exist" do
|
86
100
|
delete :destroy, :token => "ZXY987", :user_email => user1.email
|
87
101
|
|
@@ -3,8 +3,10 @@ require 'spec_helper'
|
|
3
3
|
describe Notifiable do
|
4
4
|
let(:user1) { FactoryGirl.create(:user_with_mock_token) }
|
5
5
|
let(:user2) { FactoryGirl.create(:user_with_mock_token) }
|
6
|
-
let(:notification1) {
|
7
|
-
let(:notification2) {
|
6
|
+
let(:notification1) { FactoryGirl.create(:notification, :message => "First test message")}
|
7
|
+
let(:notification2) { FactoryGirl.create(:notification, :message => "Second test message")}
|
8
|
+
|
9
|
+
before(:each) { FactoryGirl.create(:app) }
|
8
10
|
|
9
11
|
it "sends two identical push notifications" do
|
10
12
|
Notifiable.batch do |b|
|
@@ -46,7 +48,7 @@ describe Notifiable do
|
|
46
48
|
|
47
49
|
it "raises an error if it can't find the notification provider" do
|
48
50
|
user = FactoryGirl.create(:user)
|
49
|
-
|
51
|
+
device_token = FactoryGirl.create(:mock_token, :provider => :sms, :user_id => user.id)
|
50
52
|
|
51
53
|
expect { user.send_notification(notification1) }.to raise_error
|
52
54
|
end
|
data/spec/notifiable_spec.rb
CHANGED
@@ -4,8 +4,11 @@ describe Notifiable::Concern do
|
|
4
4
|
let(:user1) { FactoryGirl.create(:user_with_mock_token) }
|
5
5
|
let(:notification) { Notifiable::Notification.new(:message => "Test message")}
|
6
6
|
|
7
|
-
|
8
|
-
|
7
|
+
before(:each) { FactoryGirl.create(:app) }
|
8
|
+
|
9
|
+
it "sends a single push notification" do
|
10
|
+
FactoryGirl.create(:app)
|
11
|
+
|
9
12
|
user1.send_notification(notification)
|
10
13
|
|
11
14
|
Notifiable::NotificationStatus.count.should == 1
|
data/spec/notification_spec.rb
CHANGED
@@ -3,19 +3,19 @@ require 'spec_helper'
|
|
3
3
|
describe Notifiable::Notification do
|
4
4
|
|
5
5
|
it "stores a message" do
|
6
|
-
|
6
|
+
FactoryGirl.create(:notification, :message => "Test message")
|
7
7
|
|
8
8
|
Notifiable::Notification.first.message.should eql "Test message"
|
9
9
|
end
|
10
10
|
|
11
11
|
it "stores params" do
|
12
|
-
|
12
|
+
FactoryGirl.create(:notification, :params => {:custom_property => "A different message"})
|
13
13
|
|
14
14
|
Notifiable::Notification.first.params.should == {:custom_property => "A different message"}
|
15
15
|
end
|
16
16
|
|
17
17
|
it "destroys dependent NotificationStatuses" do
|
18
|
-
n =
|
18
|
+
n = FactoryGirl.create(:notification, :params => {:custom_property => "A different message"})
|
19
19
|
Notifiable::NotificationStatus.create :notification => n
|
20
20
|
|
21
21
|
n.destroy
|
data/spec/support/factories.rb
CHANGED
@@ -2,11 +2,18 @@ FactoryGirl.define do
|
|
2
2
|
|
3
3
|
factory :mock_token, :class => Notifiable::DeviceToken do
|
4
4
|
provider :mock
|
5
|
-
token
|
5
|
+
sequence(:token) {|n| "ABCD#{n}" }
|
6
|
+
app
|
7
|
+
end
|
8
|
+
|
9
|
+
factory :app, :class => Notifiable::App do
|
10
|
+
end
|
11
|
+
|
12
|
+
factory :notification, :class => Notifiable::Notification do
|
13
|
+
app
|
6
14
|
end
|
7
15
|
|
8
16
|
sequence(:email) {|n| "person-#{n}@example.com" }
|
9
|
-
sequence(:token) {|n| "ABCD#{n}" }
|
10
17
|
|
11
18
|
factory :user do
|
12
19
|
email
|
@@ -7,12 +7,13 @@ class CreateNotifiableDeviceTokens < ActiveRecord::Migration
|
|
7
7
|
t.string :device_id
|
8
8
|
t.boolean :is_valid, :default => true
|
9
9
|
t.integer :user_id
|
10
|
+
t.references :app
|
10
11
|
|
11
12
|
t.timestamps
|
12
13
|
end
|
13
|
-
|
14
|
+
|
14
15
|
add_index :notifiable_device_tokens, :device_id, :unique => true
|
15
|
-
add_index :notifiable_device_tokens, :token, :unique => true
|
16
|
+
add_index :notifiable_device_tokens, :token, :unique => true
|
16
17
|
add_index :notifiable_device_tokens, :user_id
|
17
18
|
end
|
18
19
|
|
@@ -2,12 +2,22 @@ class CreateNotifiableNotifications < ActiveRecord::Migration
|
|
2
2
|
|
3
3
|
def change
|
4
4
|
create_table :notifiable_notifications do |t|
|
5
|
-
t.text :title
|
6
5
|
t.text :message
|
7
6
|
t.text :params
|
8
|
-
t.
|
9
|
-
|
10
|
-
|
7
|
+
t.references :app
|
8
|
+
|
9
|
+
#stats
|
10
|
+
t.integer :sent_count
|
11
|
+
t.integer :gateway_accepted_count
|
12
|
+
|
13
|
+
# APNS - Optional
|
14
|
+
#t.integer :badge
|
15
|
+
#t.text :sound
|
16
|
+
#t.datetime :expiry
|
17
|
+
|
18
|
+
# MPNS - Optional
|
19
|
+
#t.text :title
|
20
|
+
|
11
21
|
t.timestamps
|
12
22
|
end
|
13
23
|
end
|