fcm-rails-push-notifications 0.2.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +152 -0
- data/Rakefile +15 -0
- data/lib/generators/rails-push-notifications/USAGE +6 -0
- data/lib/generators/rails-push-notifications/migrations_generator.rb +29 -0
- data/lib/generators/rails-push-notifications/templates/migrations/create_rails_push_notifications_apps.rb +29 -0
- data/lib/generators/rails-push-notifications/templates/migrations/create_rails_push_notifications_notifications.rb +22 -0
- data/lib/rails-push-notifications.rb +4 -0
- data/lib/rails-push-notifications/apps.rb +5 -0
- data/lib/rails-push-notifications/apps/apns_app.rb +36 -0
- data/lib/rails-push-notifications/apps/base_app.rb +39 -0
- data/lib/rails-push-notifications/apps/fcm_app.rb +27 -0
- data/lib/rails-push-notifications/apps/gcm_app.rb +27 -0
- data/lib/rails-push-notifications/apps/mpns_app.rb +27 -0
- data/lib/rails-push-notifications/notification.rb +42 -0
- data/lib/rails-push-notifications/rails_push_notifications_railtie.rb +12 -0
- data/lib/rails-push-notifications/version.rb +3 -0
- data/spec/apps/apns_app_spec.rb +96 -0
- data/spec/apps/gcm_app_spec.rb +69 -0
- data/spec/apps/mpns_app_spec.rb +75 -0
- data/spec/factories/apps.rb +15 -0
- data/spec/factories/notifications.rb +20 -0
- data/spec/generators/migrations_generator_spec.rb +25 -0
- data/spec/notification_spec.rb +98 -0
- data/spec/rails_apps/rails3_2.rb +47 -0
- data/spec/rails_apps/rails4.rb +47 -0
- data/spec/spec_helper.rb +61 -0
- data/spec/support/factory_girl.rb +5 -0
- metadata +196 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 9598012750f8ccf4873ae6e5985bc978c9f504be
|
4
|
+
data.tar.gz: 7e12d994ea80a6ff257fd2c945ab6a4d51006cfe
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 9c8fa43b070c14df34d558812f2a7e2ce7c0232ae6e6bffee160dc058a518f62a879865ec54f651243143001908eb36dd731d8d3e8230ef43837708fa8ccd01b
|
7
|
+
data.tar.gz: 06953b99a1168dc985ee990c545bb185336f2e3d1e1c27b608240fb970bde432157292d11bb8bcbef5077109bf182d50f40e0bec8d212620d6e122e04f6331e2
|
data/MIT-LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright 2013 YOURNAME
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,152 @@
|
|
1
|
+
# Rails Push Notifications
|
2
|
+
[![Build Status](https://travis-ci.org/calonso/rails-push-notifications.svg)](https://travis-ci.org/calonso/rails-push-notifications) [![Code Climate](https://codeclimate.com/github/calonso/rails-push-notifications/badges/gpa.svg)](https://codeclimate.com/github/calonso/rails-push-notifications) [![Test Coverage](https://codeclimate.com/github/calonso/rails-push-notifications/badges/coverage.svg)](https://codeclimate.com/github/calonso/rails-push-notifications/coverage)
|
3
|
+
## Professional iOS, Android and Windows Phone push notifications for Ruby on Rails
|
4
|
+
|
5
|
+
RailsPushNotifications is an intuitive and easy to use gem that will allow you to easily add Push Notifications to your project.
|
6
|
+
|
7
|
+
RailsPushNotifications key features:
|
8
|
+
|
9
|
+
* Multiple Apple/Android/WinPhone applications/configurations
|
10
|
+
* Single and Bulk notifications
|
11
|
+
* Fully customizable notification's contents
|
12
|
+
* Detailed feedback on each individual notification's push results.
|
13
|
+
|
14
|
+
## Live example
|
15
|
+
|
16
|
+
Want to try this gem live?
|
17
|
+
|
18
|
+
Browse [https://rails-push-notifications-test.herokuapp.com](https://rails-push-notifications-test.herokuapp.com) and play with it!
|
19
|
+
The source code for that project is here: [https://github.com/calonso/rails_push_notifications_test](https://github.com/calonso/rails_push_notifications_test)
|
20
|
+
|
21
|
+
## Installation
|
22
|
+
To install the gem simply add this line to your Gemfile
|
23
|
+
|
24
|
+
gem 'rails-push-notifications', '~> 0.2.0'
|
25
|
+
|
26
|
+
and then install it by running
|
27
|
+
|
28
|
+
$ bundle install
|
29
|
+
|
30
|
+
Once you have it installed, you need to generate the database migrations in order to build the required database structure and then run the newly generated migrations. So do it by executing:
|
31
|
+
|
32
|
+
$ rails generate rails_push_notifications:migrations
|
33
|
+
$ rake db:migrate
|
34
|
+
|
35
|
+
## Applications setup
|
36
|
+
|
37
|
+
First step when using RailsPushNotifications is to setup Apple/Android/WinPhone applications to which the notifications will be associated to. Each platform has it's own details and process.
|
38
|
+
|
39
|
+
### Apple Applications setup
|
40
|
+
|
41
|
+
Once you have configured your app as Apple Push Notifications Service enabled and you have requested and downloaded both the development and production certificates, it's time to convert them to a readable format (.pem) to import them into Rpn afterwards.
|
42
|
+
|
43
|
+
To convert the certificates the first thing you need to do is to export them as .p12 files. To do this:
|
44
|
+
|
45
|
+
1. Open Keychain Application of your Macintosh computer
|
46
|
+
2. Find the recently generated certificates. Click the disclosure button on the left of your certificate and select both the certificate and the contained key
|
47
|
+
3. Right click and select 'Export 2 items...'. Then select the desired .p12 format and save it to your disk
|
48
|
+
|
49
|
+
Once exported, to convert it to the readable .pem format simply run:
|
50
|
+
|
51
|
+
$ openssl pkcs12 -in <your .p12 filename> -out <your output .pem filename>.pem -nodes -clcerts
|
52
|
+
|
53
|
+
Now it's time to create our applications
|
54
|
+
|
55
|
+
app = RailsPushNotifications::APNSApp.new
|
56
|
+
app.apns_dev_cert = File.read('path/to/your/development/certificate.pem')
|
57
|
+
app.apns_prod_cert = File.read('path/to/your/production/certificate.pem')
|
58
|
+
app.sandbox_mode = true
|
59
|
+
app.save
|
60
|
+
|
61
|
+
And that's it!! You can create as many different applications as you want. RailsPushNotifications gem allows it.
|
62
|
+
|
63
|
+
### Android Applications setup
|
64
|
+
|
65
|
+
The only thing you need is the API_KEY that you will get from the Google APIS Console > API Access
|
66
|
+
|
67
|
+
app = RailsPushNotifications::GCMApp.new
|
68
|
+
app.gcm_key = '<your app api key>'
|
69
|
+
app.save
|
70
|
+
|
71
|
+
That's all. You have your applications' configurations stored in RailsPushNotification.
|
72
|
+
|
73
|
+
### WindowsPhone Applications setup
|
74
|
+
|
75
|
+
This case is similar but even simpler than APNS Apps
|
76
|
+
|
77
|
+
app = RailsPushNotifications::MPNSApp.new
|
78
|
+
app.cert = File.read('path/to/your/certificate.pem')
|
79
|
+
app.save
|
80
|
+
|
81
|
+
## Creating notifications
|
82
|
+
|
83
|
+
The notifications interface is common to all kind of apps, but depending on the type of underlying app
|
84
|
+
the destinations and the data format will vary, so for example
|
85
|
+
|
86
|
+
### Apple notifications
|
87
|
+
|
88
|
+
app = <Your Apple app>
|
89
|
+
notification = app.notifications.create(
|
90
|
+
destinations: [
|
91
|
+
'Your first destination token',
|
92
|
+
'Your second destination token'
|
93
|
+
],
|
94
|
+
data: { aps: { alert: 'Hello APNS World!', sound: 'true', badge: 1 } }
|
95
|
+
)
|
96
|
+
|
97
|
+
### GCM Notifications
|
98
|
+
|
99
|
+
app = <Your GCM app>
|
100
|
+
notification = app.notifications.create(
|
101
|
+
destinations: [
|
102
|
+
'Your first destination token',
|
103
|
+
'Your second destination token'
|
104
|
+
],
|
105
|
+
data: { message: 'Hello GCM World!' }
|
106
|
+
)
|
107
|
+
|
108
|
+
### WindowsPhone Notifications
|
109
|
+
|
110
|
+
app = <Your WindowsPhone app>
|
111
|
+
notification = app.notifications.create(
|
112
|
+
destinations: [
|
113
|
+
'Your first destination url',
|
114
|
+
'Your second destination url'
|
115
|
+
],
|
116
|
+
data: { title: 'Title', message: 'Hello MPNS World!', type: :toast }
|
117
|
+
)
|
118
|
+
|
119
|
+
## Pushing notifications
|
120
|
+
|
121
|
+
Eventually we want to actually push our notifications. For that task all the different apps
|
122
|
+
have a `push_notifications` method which will find the associated and not yet pushed notifications
|
123
|
+
and actually push them.
|
124
|
+
|
125
|
+
app = <Your app>
|
126
|
+
# Create several notifications for your app
|
127
|
+
app.push_notifications
|
128
|
+
|
129
|
+
As this task can be potentially very time consuming you will probably want to invoke it in
|
130
|
+
a background worker
|
131
|
+
|
132
|
+
And that's all!! I hope you find this gem useful and please, feel free to contribute with
|
133
|
+
any improvement/bug you may find.
|
134
|
+
|
135
|
+
## Pending tasks
|
136
|
+
|
137
|
+
Please, feel free to contribute in building any of those or adding more stuff to this list!
|
138
|
+
|
139
|
+
* Better generation of the data for each kind of notification. Hiding the particulars
|
140
|
+
to avoid bugs.
|
141
|
+
* Rake task to push all notifications from all applications.
|
142
|
+
|
143
|
+
## Contributing
|
144
|
+
|
145
|
+
1. Fork it ( https://github.com/calonso/rails-push-notifications/fork )
|
146
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
147
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
148
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
149
|
+
5. Create a new Pull Request
|
150
|
+
|
151
|
+
Released under the MIT-LICENSE.
|
152
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "bundler/setup"
|
3
|
+
require 'bundler'
|
4
|
+
require 'appraisal'
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
|
8
|
+
RSpec::Core::RakeTask.new(:spec)
|
9
|
+
|
10
|
+
task :default => :spec
|
11
|
+
|
12
|
+
if !ENV["APPRAISAL_INITIALIZED"] && !ENV["TRAVIS"]
|
13
|
+
task :default => :appraisal
|
14
|
+
end
|
15
|
+
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'rails/generators'
|
2
|
+
require 'rails/generators/migration'
|
3
|
+
|
4
|
+
module RailsPushNotifications
|
5
|
+
module Generators
|
6
|
+
class MigrationsGenerator < Rails::Generators::Base
|
7
|
+
include Rails::Generators::Migration
|
8
|
+
|
9
|
+
source_root File.expand_path('../templates/migrations', __FILE__)
|
10
|
+
|
11
|
+
def create_migrations
|
12
|
+
templates = [
|
13
|
+
'create_rails_push_notifications_apps',
|
14
|
+
'create_rails_push_notifications_notifications'
|
15
|
+
]
|
16
|
+
|
17
|
+
templates.each do |file|
|
18
|
+
migration_template("#{file}.rb", "db/migrate/#{file}.rb")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.next_migration_number(path)
|
23
|
+
@count ||= 0
|
24
|
+
@count += 1
|
25
|
+
(Time.now.utc.strftime("%Y%m%d%H%M%S").to_i + @count).to_s
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
class CreateRailsPushNotificationsApps < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
create_table :rails_push_notifications_apns_apps do |t|
|
4
|
+
t.text :apns_dev_cert
|
5
|
+
t.text :apns_prod_cert
|
6
|
+
t.boolean :sandbox_mode, deafult: true
|
7
|
+
|
8
|
+
t.timestamps null: false
|
9
|
+
end
|
10
|
+
|
11
|
+
create_table :rails_push_notifications_gcm_apps do |t|
|
12
|
+
t.string :gcm_key
|
13
|
+
|
14
|
+
t.timestamps null: false
|
15
|
+
end
|
16
|
+
|
17
|
+
create_table :rails_push_notifications_mpns_apps do |t|
|
18
|
+
t.text :cert
|
19
|
+
|
20
|
+
t.timestamps null: false
|
21
|
+
end
|
22
|
+
|
23
|
+
create_table :rails_push_notifications_fcm_apps do |t|
|
24
|
+
t.string :fcm_key
|
25
|
+
|
26
|
+
t.timestamps null: false
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,22 @@
|
|
1
|
+
class CreateRailsPushNotificationsNotifications < ActiveRecord::Migration
|
2
|
+
def change
|
3
|
+
create_table :rails_push_notifications_notifications do |t|
|
4
|
+
t.text :destinations
|
5
|
+
t.integer :app_id
|
6
|
+
t.string :app_type
|
7
|
+
t.text :data
|
8
|
+
t.text :results
|
9
|
+
t.integer :success
|
10
|
+
t.integer :failed
|
11
|
+
t.boolean :sent, default: false
|
12
|
+
|
13
|
+
t.timestamps null: false
|
14
|
+
end
|
15
|
+
|
16
|
+
add_index(
|
17
|
+
:rails_push_notifications_notifications,
|
18
|
+
[:app_id, :app_type, :sent],
|
19
|
+
name: 'app_and_sent_index_on_rails_push_notifications'
|
20
|
+
)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# This class represents an Apple iOS application.
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class APNSApp < BaseApp
|
8
|
+
self.table_name = 'rails_push_notifications_apns_apps'
|
9
|
+
|
10
|
+
# Requires a development certificate
|
11
|
+
validates :apns_dev_cert, presence: true
|
12
|
+
# Requires a production certificate
|
13
|
+
validates :apns_prod_cert, presence: true
|
14
|
+
|
15
|
+
before_validation { |app| app.sandbox_mode = true if app.sandbox_mode.nil? }
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
# @return [String] the certificate(dev or prod) to use
|
20
|
+
def cert
|
21
|
+
sandbox_mode ? apns_dev_cert : apns_prod_cert
|
22
|
+
end
|
23
|
+
|
24
|
+
# @return [RubyPushNotifications::APNS::APNSPusher] configured and
|
25
|
+
# ready to push
|
26
|
+
def build_pusher
|
27
|
+
RubyPushNotifications::APNS::APNSPusher.new cert, sandbox_mode
|
28
|
+
end
|
29
|
+
|
30
|
+
# @return [RubyPushNotifications::APNS::APNSNotification]. The type of
|
31
|
+
# notifications this app manages
|
32
|
+
def notification_type
|
33
|
+
RubyPushNotifications::APNS::APNSNotification
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# Abstract. This class is the base of all application entity type.
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class BaseApp < ActiveRecord::Base
|
8
|
+
|
9
|
+
self.abstract_class = true
|
10
|
+
|
11
|
+
# has_many notifications
|
12
|
+
has_many :notifications, as: :app
|
13
|
+
|
14
|
+
#
|
15
|
+
# This method will find all notifications owned by this app and
|
16
|
+
# push them.
|
17
|
+
#
|
18
|
+
def push_notifications
|
19
|
+
pending = find_pending
|
20
|
+
to_send = pending.map do |notification|
|
21
|
+
notification_type.new notification.destinations, notification.data
|
22
|
+
end
|
23
|
+
pusher = build_pusher
|
24
|
+
pusher.push to_send
|
25
|
+
pending.each_with_index do |p, i|
|
26
|
+
p.update_attributes! results: to_send[i].results
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
#
|
33
|
+
# Method that searches the owned notifications for those not yet sent
|
34
|
+
#
|
35
|
+
def find_pending
|
36
|
+
notifications.where sent: false
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# This class represents an Android FCM application.
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class FCMApp < BaseApp
|
8
|
+
self.table_name = 'rails_push_notifications_fcm_apps'
|
9
|
+
|
10
|
+
# Requires a fcm_key
|
11
|
+
validates :fcm_key, presence: true
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# @return [RubyPushNotifications::FCM::FCMPusher] configured and
|
16
|
+
# ready to push
|
17
|
+
def build_pusher
|
18
|
+
RubyPushNotifications::FCM::FCMPusher.new fcm_key
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [RubyPushNotifications::FCM::FCMNotification]. The type of
|
22
|
+
# notifications this app manages
|
23
|
+
def notification_type
|
24
|
+
RubyPushNotifications::FCM::FCMNotification
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# This class represents an Android GCM application.
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class GCMApp < BaseApp
|
8
|
+
self.table_name = 'rails_push_notifications_gcm_apps'
|
9
|
+
|
10
|
+
# Requires a gcm_key
|
11
|
+
validates :gcm_key, presence: true
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# @return [RubyPushNotifications::GCM::GCMPusher] configured and
|
16
|
+
# ready to push
|
17
|
+
def build_pusher
|
18
|
+
RubyPushNotifications::GCM::GCMPusher.new gcm_key
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [RubyPushNotifications::GCM::GCMNotification]. The type of
|
22
|
+
# notifications this app manages
|
23
|
+
def notification_type
|
24
|
+
RubyPushNotifications::GCM::GCMNotification
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# This class represents an Windows Phone application.
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class MPNSApp < BaseApp
|
8
|
+
self.table_name = 'rails_push_notifications_mpns_apps'
|
9
|
+
|
10
|
+
# Requires the certificate
|
11
|
+
validates :cert, presence: true
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
# @return [RubyPushNotifications::MPNS::MPNSPusher] configured and
|
16
|
+
# ready to push
|
17
|
+
def build_pusher
|
18
|
+
RubyPushNotifications::MPNS::MPNSPusher.new cert
|
19
|
+
end
|
20
|
+
|
21
|
+
# @return [RubyPushNotifications::MPNS::MPNSNotification]. The type of
|
22
|
+
# notifications this app manages
|
23
|
+
def notification_type
|
24
|
+
RubyPushNotifications::MPNS::MPNSNotification
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,42 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# This class represents the Notification Entity.
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class Notification < ActiveRecord::Base
|
8
|
+
|
9
|
+
self.table_name = 'rails_push_notifications_notifications'
|
10
|
+
|
11
|
+
# belongs_to an app
|
12
|
+
belongs_to :app, polymorphic: true
|
13
|
+
|
14
|
+
# Requires an app
|
15
|
+
validates :app, presence: true
|
16
|
+
# Requires data
|
17
|
+
validates :data, presence: true
|
18
|
+
# Requires at least one destination
|
19
|
+
validates :destinations, presence: true, length: { minimum: 1 }
|
20
|
+
|
21
|
+
serialize :data, Hash
|
22
|
+
serialize :destinations, Array
|
23
|
+
serialize :results
|
24
|
+
|
25
|
+
# Automatically manages the sent flag, setting it to true as soon as
|
26
|
+
# it is assigned results.
|
27
|
+
before_save do |record|
|
28
|
+
record.sent = !record.results.nil?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
# Automatically manages the success and failed fields, setting them to the
|
33
|
+
# value specified by the results assigned.
|
34
|
+
before_save do |record|
|
35
|
+
if record.results_changed? && record.results
|
36
|
+
record.success = record.results.success
|
37
|
+
record.failed = record.results.failed
|
38
|
+
end
|
39
|
+
true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
#
|
3
|
+
# This class exports the migrations generator to Rails
|
4
|
+
#
|
5
|
+
# @author Carlos Alonso
|
6
|
+
#
|
7
|
+
class RailsPushNotificationsRailtie < Rails::Railtie
|
8
|
+
generators do
|
9
|
+
require 'generators/rails-push-notifications/migrations_generator'
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -0,0 +1,96 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
describe APNSApp, type: :model do
|
3
|
+
it 'creates an instance given valid attributes' do
|
4
|
+
APNSApp.create! attributes_for :apns_app
|
5
|
+
end
|
6
|
+
|
7
|
+
describe 'validations' do
|
8
|
+
|
9
|
+
let(:app) { build :apns_app }
|
10
|
+
|
11
|
+
it 'requires an apns dev cert' do
|
12
|
+
app.apns_dev_cert = nil
|
13
|
+
expect(app).to_not be_valid
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'requires an apns prod cert' do
|
17
|
+
app.apns_prod_cert = nil
|
18
|
+
expect(app).to_not be_valid
|
19
|
+
end
|
20
|
+
|
21
|
+
describe 'sandbox mode' do
|
22
|
+
it 'automatically sets sandbox mode if missing' do
|
23
|
+
app.sandbox_mode = nil
|
24
|
+
expect do
|
25
|
+
app.valid?
|
26
|
+
end.to change { app.sandbox_mode }.from(nil).to true
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'uses the value if given' do
|
30
|
+
app.sandbox_mode = false
|
31
|
+
expect do
|
32
|
+
app.valid?
|
33
|
+
end.to_not change { app.sandbox_mode }.from false
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
describe 'notifications relationship' do
|
39
|
+
let(:app) { create :apns_app }
|
40
|
+
|
41
|
+
it 'can create new notifications' do
|
42
|
+
expect do
|
43
|
+
app.notifications.create attributes_for :apns_notification
|
44
|
+
end.to change { app.reload.notifications.count }.from(0).to 1
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe '#push_notifications' do
|
49
|
+
let(:app) { create :apns_app }
|
50
|
+
let(:notifications) do
|
51
|
+
(1..10).map { create :apns_notification, app: app }
|
52
|
+
end
|
53
|
+
let(:single_notification) { create :apns_notification, app: app }
|
54
|
+
|
55
|
+
let(:connection) do
|
56
|
+
instance_double(RubyPushNotifications::APNS::APNSConnection).
|
57
|
+
as_null_object
|
58
|
+
end
|
59
|
+
|
60
|
+
before do
|
61
|
+
allow(RubyPushNotifications::APNS::APNSConnection).
|
62
|
+
to receive(:open).with(app.apns_dev_cert, app.sandbox_mode).
|
63
|
+
and_return connection
|
64
|
+
allow(IO).to receive(:select).and_return []
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'assigns results' do
|
68
|
+
expect do
|
69
|
+
app.push_notifications
|
70
|
+
end.to change {
|
71
|
+
notifications.map do |n|
|
72
|
+
n.reload.results && n.results.individual_results
|
73
|
+
end
|
74
|
+
}.from([nil] * 10).
|
75
|
+
to([[RubyPushNotifications::APNS::NO_ERROR_STATUS_CODE]] * 10)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'marks as sent' do
|
79
|
+
expect do
|
80
|
+
app.push_notifications
|
81
|
+
end.to change { single_notification.reload.sent }.from(false).to true
|
82
|
+
end
|
83
|
+
|
84
|
+
context 'with an already sent notification' do
|
85
|
+
let!(:sent_notification) { create :apns_notification, app: app }
|
86
|
+
|
87
|
+
before { app.push_notifications }
|
88
|
+
|
89
|
+
it "doesn't send already sent notifications" do
|
90
|
+
expect(connection).to_not receive(:write)
|
91
|
+
app.push_notifications
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
describe GCMApp, type: :model do
|
3
|
+
|
4
|
+
it 'creates an instance given valid attributes' do
|
5
|
+
GCMApp.create! attributes_for :gcm_app
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'validations' do
|
9
|
+
let(:app) { build :gcm_app }
|
10
|
+
|
11
|
+
it 'requires a gcm key' do
|
12
|
+
app.gcm_key = nil
|
13
|
+
expect(app).to_not be_valid
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
describe 'notifications relationship' do
|
18
|
+
let(:app) { create :gcm_app }
|
19
|
+
|
20
|
+
it 'can create new notifications' do
|
21
|
+
expect do
|
22
|
+
app.notifications.create attributes_for :gcm_notification
|
23
|
+
end.to change { app.reload.notifications.count }.from(0).to 1
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#push_notifications' do
|
28
|
+
let(:app) { create :gcm_app }
|
29
|
+
let(:notifications) do
|
30
|
+
(1..10).map { create :gcm_notification, app: app }
|
31
|
+
end
|
32
|
+
let(:single_notification) { create :gcm_notification, app: app }
|
33
|
+
|
34
|
+
let(:response) { JSON.dump a: 1 }
|
35
|
+
|
36
|
+
before do
|
37
|
+
stub_request(:post, 'https://android.googleapis.com/gcm/send').
|
38
|
+
to_return status: [200, 'OK'], body: response
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'assigns results' do
|
42
|
+
expect do
|
43
|
+
app.push_notifications
|
44
|
+
end.to change {
|
45
|
+
notifications.map { |n| n.reload.results }
|
46
|
+
}.from([nil] * 10).
|
47
|
+
to([RubyPushNotifications::GCM::GCMResponse.new(200, response)] * 10)
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'marks as sent' do
|
51
|
+
expect do
|
52
|
+
app.push_notifications
|
53
|
+
end.to change { single_notification.reload.sent }.from(false).to true
|
54
|
+
end
|
55
|
+
|
56
|
+
context 'with an already sent notification' do
|
57
|
+
let!(:sent_notification) { create :apns_notification, app: app }
|
58
|
+
|
59
|
+
before { app.push_notifications }
|
60
|
+
|
61
|
+
it "doesn't send already sent notifications" do
|
62
|
+
expect(RubyPushNotifications::GCM::GCMConnection).
|
63
|
+
to_not receive(:post)
|
64
|
+
app.push_notifications
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module RailsPushNotifications
|
2
|
+
describe MPNSApp, type: :model do
|
3
|
+
|
4
|
+
it 'creates an instance given valid attributes' do
|
5
|
+
MPNSApp.create! attributes_for :mpns_app
|
6
|
+
end
|
7
|
+
|
8
|
+
describe 'validations' do
|
9
|
+
|
10
|
+
let(:app) { build :mpns_app }
|
11
|
+
|
12
|
+
it 'requires the certificate' do
|
13
|
+
app.cert = nil
|
14
|
+
expect(app).to_not be_valid
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'notifications relationship' do
|
19
|
+
|
20
|
+
let(:app) { create :mpns_app }
|
21
|
+
|
22
|
+
it 'can create new notifications' do
|
23
|
+
expect do
|
24
|
+
app.notifications.create attributes_for :mpns_notification
|
25
|
+
end.to change { app.reload.notifications.count }.from(0).to 1
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe '#push_notifications' do
|
30
|
+
|
31
|
+
let(:app) { create :mpns_app }
|
32
|
+
let(:notifications) {
|
33
|
+
(1..10).map { create :mpns_notification, app: app }
|
34
|
+
}
|
35
|
+
let(:single_notification) { create :mpns_notification, app: app }
|
36
|
+
|
37
|
+
let(:headers) {
|
38
|
+
{
|
39
|
+
'x-notificationstatus' => 'Received',
|
40
|
+
'x-deviceconnectionstatus' => 'Connected',
|
41
|
+
'x-subscriptionstatus' => 'Active'
|
42
|
+
}
|
43
|
+
}
|
44
|
+
let(:response) { [ { device_url: 'http://s.notify.live.net/1', headers: headers, code: 200 } ]}
|
45
|
+
|
46
|
+
before do
|
47
|
+
stub_request(:post, %r{s.notify.live.net}).
|
48
|
+
to_return status: [200, 'OK'], headers: headers
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'assigns results' do
|
52
|
+
expect do
|
53
|
+
app.push_notifications
|
54
|
+
end.to change { notifications.map { |n| n.reload.results } }.from([nil] * 10).to([RubyPushNotifications::MPNS::MPNSResponse.new(response)] * 10)
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'marks as sent' do
|
58
|
+
expect do
|
59
|
+
app.push_notifications
|
60
|
+
end.to change { single_notification.reload.sent }.from(false).to true
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'with an already sent notification' do
|
64
|
+
let!(:sent_notification) { create :mpns_notification, app: app }
|
65
|
+
|
66
|
+
before { app.push_notifications }
|
67
|
+
|
68
|
+
it "doesn't send already sent notifications" do
|
69
|
+
expect(RubyPushNotifications::MPNS::MPNSConnection).to_not receive(:post)
|
70
|
+
app.push_notifications
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
FactoryGirl.define do
|
2
|
+
factory :apns_app, class: 'RailsPushNotifications::APNSApp' do
|
3
|
+
apns_dev_cert 'abc'
|
4
|
+
apns_prod_cert 'def'
|
5
|
+
sandbox_mode true
|
6
|
+
end
|
7
|
+
|
8
|
+
factory :gcm_app, class: 'RailsPushNotifications::GCMApp' do
|
9
|
+
gcm_key 'abc123def456'
|
10
|
+
end
|
11
|
+
|
12
|
+
factory :mpns_app, class: 'RailsPushNotifications::MPNSApp' do
|
13
|
+
cert 'abc'
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
FactoryGirl.define do
|
3
|
+
factory :apns_notification, class: 'RailsPushNotifications::Notification' do
|
4
|
+
association :app, factory: :apns_app, strategy: :create
|
5
|
+
data a: 1
|
6
|
+
destinations ['1']
|
7
|
+
end
|
8
|
+
|
9
|
+
factory :gcm_notification, class: 'RailsPushNotifications::Notification' do
|
10
|
+
association :app, factory: :gcm_app, strategy: :create
|
11
|
+
data a: 1
|
12
|
+
destinations ['1']
|
13
|
+
end
|
14
|
+
|
15
|
+
factory :mpns_notification, class: 'RailsPushNotifications::Notification' do
|
16
|
+
association :app, factory: :mpns_app, strategy: :create
|
17
|
+
data message: { value1: 'hello' }
|
18
|
+
destinations ['http://s.notify.live.net/1']
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'generators/rails-push-notifications/migrations_generator'
|
2
|
+
|
3
|
+
describe RailsPushNotifications::Generators::MigrationsGenerator, type: :generator do
|
4
|
+
destination File.expand_path("../tmp", __FILE__)
|
5
|
+
|
6
|
+
before do
|
7
|
+
prepare_destination
|
8
|
+
run_generator
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
rm_rf destination_root
|
13
|
+
end
|
14
|
+
|
15
|
+
it 'creates the migrations' do
|
16
|
+
expect(destination_root).to have_structure do
|
17
|
+
directory 'db' do
|
18
|
+
directory 'migrate' do
|
19
|
+
migration 'create_rails_push_notifications_apps'
|
20
|
+
migration 'create_rails_push_notifications_notifications'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,98 @@
|
|
1
|
+
|
2
|
+
module RailsPushNotifications
|
3
|
+
describe Notification, type: :model do
|
4
|
+
|
5
|
+
class FakeResults
|
6
|
+
attr_reader :value1, :success, :failed
|
7
|
+
|
8
|
+
def initialize(value1, success, failed)
|
9
|
+
@value1 = value1
|
10
|
+
@success = success
|
11
|
+
@failed = failed
|
12
|
+
end
|
13
|
+
|
14
|
+
def ==(other)
|
15
|
+
other != nil && other.is_a?(FakeResults) &&
|
16
|
+
@value1 == other.value1 && @success == other.success &&
|
17
|
+
@failed == failed || super(other)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:notification) { build :apns_notification }
|
22
|
+
|
23
|
+
describe 'app relationship' do
|
24
|
+
it 'requires an app' do
|
25
|
+
notification.app = nil
|
26
|
+
expect(notification).to_not be_valid
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'belongs to an app' do
|
30
|
+
expect(notification.app).to be_a APNSApp
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
describe 'data' do
|
35
|
+
it 'requires data' do
|
36
|
+
notification.data = nil
|
37
|
+
expect(notification).to_not be_valid
|
38
|
+
end
|
39
|
+
|
40
|
+
it 'has to be a Hash' do
|
41
|
+
expect do
|
42
|
+
notification.data = 'dummy text'
|
43
|
+
notification.save
|
44
|
+
end.to raise_error ActiveRecord::SerializationTypeMismatch
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
describe 'destinations' do
|
49
|
+
it 'requires destinations' do
|
50
|
+
notification.destinations = nil
|
51
|
+
expect(notification).to_not be_valid
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'has to be an array' do
|
55
|
+
expect do
|
56
|
+
notification.destinations = 'dummy destinations'
|
57
|
+
notification.save
|
58
|
+
end.to raise_error ActiveRecord::SerializationTypeMismatch
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'has to contain at least one destination' do
|
62
|
+
notification.destinations = []
|
63
|
+
expect(notification).to_not be_valid
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
describe 'sent' do
|
68
|
+
it 'is false by default' do
|
69
|
+
notification.save
|
70
|
+
expect(notification.sent).to eq false
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'is sent if results assigned' do
|
74
|
+
notification.save
|
75
|
+
expect do
|
76
|
+
notification.results = FakeResults.new(1, 2, 3)
|
77
|
+
notification.save
|
78
|
+
end.to change { notification.reload.sent }.from(false).to true
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
describe 'results' do
|
83
|
+
|
84
|
+
let(:success) { 1 }
|
85
|
+
let(:failed) { 3 }
|
86
|
+
let(:results) { FakeResults.new 'abc', success, failed }
|
87
|
+
|
88
|
+
it 'serializes any object' do
|
89
|
+
notification.results = results
|
90
|
+
notification.save
|
91
|
+
notification.reload
|
92
|
+
expect(notification.results).to eq results
|
93
|
+
expect(notification.success).to eq success
|
94
|
+
expect(notification.failed).to eq failed
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'rails/all'
|
3
|
+
require 'action_view/testing/resolvers'
|
4
|
+
require 'rails/test_help'
|
5
|
+
|
6
|
+
require 'rails-push-notifications'
|
7
|
+
|
8
|
+
class RailsPushNotificationsApp < Rails::Application
|
9
|
+
config.root = File.expand_path("../../..", __FILE__)
|
10
|
+
config.cache_classes = true
|
11
|
+
|
12
|
+
config.eager_load = false
|
13
|
+
config.serve_static_assets = true
|
14
|
+
config.static_cache_control = "public, max-age=3600"
|
15
|
+
|
16
|
+
config.consider_all_requests_local = true
|
17
|
+
config.action_controller.perform_caching = false
|
18
|
+
|
19
|
+
config.action_dispatch.show_exceptions = false
|
20
|
+
|
21
|
+
config.action_controller.allow_forgery_protection = false
|
22
|
+
|
23
|
+
config.active_support.deprecation = :stderr
|
24
|
+
|
25
|
+
config.middleware.delete "Rack::Lock"
|
26
|
+
config.middleware.delete "ActionDispatch::Flash"
|
27
|
+
config.middleware.delete "ActionDispatch::BestStandardsSupport"
|
28
|
+
config.secret_token = "49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk"
|
29
|
+
routes.append do
|
30
|
+
get "/" => "welcome#index"
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ApplicationController < ActionController::Base
|
35
|
+
include Rails.application.routes.url_helpers
|
36
|
+
layout 'application'
|
37
|
+
self.view_paths = [ActionView::FixtureResolver.new(
|
38
|
+
"layouts/application.html.erb" => '<%= yield %>',
|
39
|
+
"welcome/index.html.erb"=> 'Hello from index.html.erb',
|
40
|
+
)]
|
41
|
+
|
42
|
+
def index
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
RailsPushNotificationsApp.initialize!
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'rails'
|
2
|
+
require 'rails/all'
|
3
|
+
require 'action_view/testing/resolvers'
|
4
|
+
|
5
|
+
require 'rails-push-notifications'
|
6
|
+
|
7
|
+
module RailsPushNotificationsApp
|
8
|
+
class Application < Rails::Application
|
9
|
+
config.root = File.expand_path("../../..", __FILE__)
|
10
|
+
config.cache_classes = true
|
11
|
+
|
12
|
+
config.eager_load = false
|
13
|
+
config.static_cache_control = "public, max-age=3600"
|
14
|
+
|
15
|
+
config.consider_all_requests_local = true
|
16
|
+
config.action_controller.perform_caching = false
|
17
|
+
|
18
|
+
config.action_dispatch.show_exceptions = false
|
19
|
+
|
20
|
+
config.action_controller.allow_forgery_protection = false
|
21
|
+
|
22
|
+
config.active_support.deprecation = :stderr
|
23
|
+
|
24
|
+
config.middleware.delete "Rack::Lock"
|
25
|
+
config.middleware.delete "ActionDispatch::Flash"
|
26
|
+
config.middleware.delete "ActionDispatch::BestStandardsSupport"
|
27
|
+
config.secret_key_base = '49837489qkuweoiuoqwehisuakshdjksadhaisdy78o34y138974xyqp9rmye8yrpiokeuioqwzyoiuxftoyqiuxrhm3iou1hrzmjk'
|
28
|
+
routes.append do
|
29
|
+
get "/" => "application#index"
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class ApplicationController < ActionController::Base
|
35
|
+
include Rails.application.routes.url_helpers
|
36
|
+
layout 'application'
|
37
|
+
self.view_paths = [ActionView::FixtureResolver.new(
|
38
|
+
"layouts/application.html.erb" => '<%= yield %>',
|
39
|
+
"welcome/index.html.erb"=> 'Hello from index.html.erb',
|
40
|
+
)]
|
41
|
+
|
42
|
+
def index
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
RailsPushNotificationsApp::Application.initialize!
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
|
2
|
+
require 'codeclimate-test-reporter'
|
3
|
+
CodeClimate::TestReporter.start
|
4
|
+
|
5
|
+
Bundler.setup
|
6
|
+
|
7
|
+
require 'rails'
|
8
|
+
|
9
|
+
ENV['RAILS_ENV'] = 'test'
|
10
|
+
|
11
|
+
case "#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}"
|
12
|
+
when '3.2'
|
13
|
+
ENV['DATABASE_URL'] = 'sqlite3://localhost/:memory:'
|
14
|
+
require 'rails_apps/rails3_2'
|
15
|
+
require 'active_record/migration'
|
16
|
+
when '4.0'
|
17
|
+
ENV['DATABASE_URL'] = 'sqlite3://localhost/:memory:'
|
18
|
+
require 'rails_apps/rails4'
|
19
|
+
when '4.1', '4.2'
|
20
|
+
ENV['DATABASE_URL'] = 'sqlite3::memory:'
|
21
|
+
require 'rails_apps/rails4'
|
22
|
+
else
|
23
|
+
raise NotImplementedError.new "Rails Push Notifications gem doesn't support Rails #{Rails.version}"
|
24
|
+
end
|
25
|
+
|
26
|
+
Bundler.require :default
|
27
|
+
Bundler.require :development
|
28
|
+
|
29
|
+
require 'webmock/rspec'
|
30
|
+
require 'rspec/rails'
|
31
|
+
require 'ruby-push-notifications'
|
32
|
+
|
33
|
+
Dir["./spec/support/**/*.rb"].sort.each { |f| require f }
|
34
|
+
|
35
|
+
files = Dir.glob(File.join(File.dirname(__FILE__), '..', 'lib', 'generators', 'rails-push-notifications', 'templates', 'migrations', '*.rb'))
|
36
|
+
|
37
|
+
migrations = []
|
38
|
+
files.each_with_index do |file, version|
|
39
|
+
name, scope = file.scan(/([_a-z0-9]*)\.?([_a-z0-9]*)?\.rb\z/).first
|
40
|
+
|
41
|
+
name = name.camelize
|
42
|
+
|
43
|
+
migrations << ActiveRecord::MigrationProxy.new(name, version, file, scope)
|
44
|
+
end
|
45
|
+
|
46
|
+
migrations.sort_by(&:version)
|
47
|
+
|
48
|
+
migrator = ActiveRecord::Migrator.new(:up, migrations)
|
49
|
+
|
50
|
+
if Rails::VERSION::MAJOR == 3
|
51
|
+
migrator.instance_variable_set(:@migrations, migrations)
|
52
|
+
end
|
53
|
+
|
54
|
+
migrator.migrate
|
55
|
+
|
56
|
+
RSpec.configure do |config|
|
57
|
+
config.use_transactional_fixtures = true
|
58
|
+
config.order = :random
|
59
|
+
end
|
60
|
+
|
61
|
+
WebMock.disable_net_connect!(:allow => "codeclimate.com")
|
metadata
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: fcm-rails-push-notifications
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.2.4
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Santhu MS
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2018-07-25 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: rails
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '5.0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '5.0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: fcm-ruby-push-notifications
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: 1.2.1
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: 1.2.1
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: sqlite3
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '1.3'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '1.3'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rspec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '3.2'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '3.2'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec-rails
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '3.0'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '3.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: factory_girl
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '4.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '4.0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: generator_spec
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - "~>"
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0.9'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - "~>"
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0.9'
|
111
|
+
- !ruby/object:Gem::Dependency
|
112
|
+
name: webmock
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
114
|
+
requirements:
|
115
|
+
- - "~>"
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '1.20'
|
118
|
+
type: :development
|
119
|
+
prerelease: false
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
121
|
+
requirements:
|
122
|
+
- - "~>"
|
123
|
+
- !ruby/object:Gem::Version
|
124
|
+
version: '1.20'
|
125
|
+
description: Rails gem to push notifications for iOS, Android and Windows Phone devices
|
126
|
+
email:
|
127
|
+
- santhu.ms83@gmail.com
|
128
|
+
executables: []
|
129
|
+
extensions: []
|
130
|
+
extra_rdoc_files: []
|
131
|
+
files:
|
132
|
+
- MIT-LICENSE
|
133
|
+
- README.md
|
134
|
+
- Rakefile
|
135
|
+
- lib/generators/rails-push-notifications/USAGE
|
136
|
+
- lib/generators/rails-push-notifications/migrations_generator.rb
|
137
|
+
- lib/generators/rails-push-notifications/templates/migrations/create_rails_push_notifications_apps.rb
|
138
|
+
- lib/generators/rails-push-notifications/templates/migrations/create_rails_push_notifications_notifications.rb
|
139
|
+
- lib/rails-push-notifications.rb
|
140
|
+
- lib/rails-push-notifications/apps.rb
|
141
|
+
- lib/rails-push-notifications/apps/apns_app.rb
|
142
|
+
- lib/rails-push-notifications/apps/base_app.rb
|
143
|
+
- lib/rails-push-notifications/apps/fcm_app.rb
|
144
|
+
- lib/rails-push-notifications/apps/gcm_app.rb
|
145
|
+
- lib/rails-push-notifications/apps/mpns_app.rb
|
146
|
+
- lib/rails-push-notifications/notification.rb
|
147
|
+
- lib/rails-push-notifications/rails_push_notifications_railtie.rb
|
148
|
+
- lib/rails-push-notifications/version.rb
|
149
|
+
- spec/apps/apns_app_spec.rb
|
150
|
+
- spec/apps/gcm_app_spec.rb
|
151
|
+
- spec/apps/mpns_app_spec.rb
|
152
|
+
- spec/factories/apps.rb
|
153
|
+
- spec/factories/notifications.rb
|
154
|
+
- spec/generators/migrations_generator_spec.rb
|
155
|
+
- spec/notification_spec.rb
|
156
|
+
- spec/rails_apps/rails3_2.rb
|
157
|
+
- spec/rails_apps/rails4.rb
|
158
|
+
- spec/spec_helper.rb
|
159
|
+
- spec/support/factory_girl.rb
|
160
|
+
homepage: https://github.com/santhums/rails-push-notifications
|
161
|
+
licenses:
|
162
|
+
- MIT
|
163
|
+
metadata: {}
|
164
|
+
post_install_message:
|
165
|
+
rdoc_options: []
|
166
|
+
require_paths:
|
167
|
+
- lib
|
168
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
169
|
+
requirements:
|
170
|
+
- - ">="
|
171
|
+
- !ruby/object:Gem::Version
|
172
|
+
version: 2.3.1
|
173
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
174
|
+
requirements:
|
175
|
+
- - ">="
|
176
|
+
- !ruby/object:Gem::Version
|
177
|
+
version: '0'
|
178
|
+
requirements: []
|
179
|
+
rubyforge_project:
|
180
|
+
rubygems_version: 2.5.1
|
181
|
+
signing_key:
|
182
|
+
specification_version: 4
|
183
|
+
summary: Professional iOS, Android and Windows Phone push notifications for Ruby on
|
184
|
+
Rails
|
185
|
+
test_files:
|
186
|
+
- spec/apps/apns_app_spec.rb
|
187
|
+
- spec/apps/mpns_app_spec.rb
|
188
|
+
- spec/apps/gcm_app_spec.rb
|
189
|
+
- spec/support/factory_girl.rb
|
190
|
+
- spec/notification_spec.rb
|
191
|
+
- spec/spec_helper.rb
|
192
|
+
- spec/generators/migrations_generator_spec.rb
|
193
|
+
- spec/rails_apps/rails3_2.rb
|
194
|
+
- spec/rails_apps/rails4.rb
|
195
|
+
- spec/factories/apps.rb
|
196
|
+
- spec/factories/notifications.rb
|