ruby-push-notifications 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 26d655780454310999a17dd8ff1665594bdcc8d9
4
+ data.tar.gz: e270d62ecb2b946f24919fefb21412f52500be57
5
+ SHA512:
6
+ metadata.gz: 20912ffb3a561c8a6bc790c3ccafde1e749e89aabbac17516e9f87cd175f5b212d4de73b301940064ff7c4bdbab82b0c1ff07fa745835df16ba496ff00df0be2
7
+ data.tar.gz: 92c44920810d644ffb9f2db27587091f437d68ccae8ee8893794f5114ba300d3a0166ae43163d1aee5116a6a39f5a5bb00094abc7439f2a7435bbe07cd98c70f
data/.gitignore CHANGED
@@ -33,3 +33,5 @@ build/
33
33
  # unless supporting rvm < 1.11.0 or doing something fancy, ignore this:
34
34
  .rvmrc
35
35
  .DS_Store
36
+
37
+ examples/*.bak
data/.travis.yml CHANGED
@@ -4,3 +4,4 @@ rvm:
4
4
  - "2.1.5"
5
5
  - "2.0.0"
6
6
  - "1.9.3"
7
+ env: CODECLIMATE_REPO_TOKEN=efdb12c380287a25b2b26362aa710a9b59020122cbe4edecf0d353bf50e0046a
data/Gemfile CHANGED
@@ -2,3 +2,5 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ruby-push-notifications.gemspec
4
4
  gemspec
5
+
6
+ gem "codeclimate-test-reporter", group: :test, require: nil
data/Gemfile.lock CHANGED
@@ -1,45 +1,54 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- ruby-push-notifications (0.0.1)
4
+ ruby-push-notifications (0.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
8
8
  specs:
9
- activesupport (4.2.0)
9
+ activesupport (4.2.1)
10
10
  i18n (~> 0.7)
11
11
  json (~> 1.7, >= 1.7.7)
12
12
  minitest (~> 5.1)
13
13
  thread_safe (~> 0.3, >= 0.3.4)
14
14
  tzinfo (~> 1.1)
15
- addressable (2.3.7)
15
+ addressable (2.3.8)
16
+ codeclimate-test-reporter (0.4.7)
17
+ simplecov (>= 0.7.1, < 1.0.0)
16
18
  crack (0.4.2)
17
19
  safe_yaml (~> 1.0.0)
18
20
  diff-lcs (1.2.5)
21
+ docile (1.1.5)
19
22
  factory_girl (4.5.0)
20
23
  activesupport (>= 3.0.0)
21
24
  i18n (0.7.0)
22
25
  json (1.8.2)
23
26
  minitest (5.5.1)
27
+ multi_json (1.11.0)
24
28
  rake (10.4.2)
25
29
  rspec (3.2.0)
26
30
  rspec-core (~> 3.2.0)
27
31
  rspec-expectations (~> 3.2.0)
28
32
  rspec-mocks (~> 3.2.0)
29
- rspec-core (3.2.0)
33
+ rspec-core (3.2.2)
30
34
  rspec-support (~> 3.2.0)
31
35
  rspec-expectations (3.2.0)
32
36
  diff-lcs (>= 1.2.0, < 2.0)
33
37
  rspec-support (~> 3.2.0)
34
- rspec-mocks (3.2.0)
38
+ rspec-mocks (3.2.1)
35
39
  diff-lcs (>= 1.2.0, < 2.0)
36
40
  rspec-support (~> 3.2.0)
37
- rspec-support (3.2.1)
41
+ rspec-support (3.2.2)
38
42
  safe_yaml (1.0.4)
39
- thread_safe (0.3.4)
43
+ simplecov (0.9.2)
44
+ docile (~> 1.1.0)
45
+ multi_json (~> 1.0)
46
+ simplecov-html (~> 0.9.0)
47
+ simplecov-html (0.9.0)
48
+ thread_safe (0.3.5)
40
49
  tzinfo (1.2.2)
41
50
  thread_safe (~> 0.1)
42
- webmock (1.20.4)
51
+ webmock (1.21.0)
43
52
  addressable (>= 2.3.6)
44
53
  crack (>= 0.3.2)
45
54
 
@@ -48,6 +57,7 @@ PLATFORMS
48
57
 
49
58
  DEPENDENCIES
50
59
  bundler (~> 1.6)
60
+ codeclimate-test-reporter
51
61
  factory_girl (~> 4.0)
52
62
  rake (~> 10.4)
53
63
  rspec (~> 3.2)
data/README.md CHANGED
@@ -1,4 +1,6 @@
1
- # Ruby::Push::Notifications [![Build Status](https://travis-ci.org/calonso/ruby-push-notifications.svg)](https://travis-ci.org/calonso/ruby-push-notifications) [![Dependency Status](https://gemnasium.com/calonso/ruby-push-notifications.svg)](https://gemnasium.com/calonso/ruby-push-notifications)
1
+ # Ruby Push Notifications
2
+
3
+ [![Build Status](https://travis-ci.org/calonso/ruby-push-notifications.svg)](https://travis-ci.org/calonso/ruby-push-notifications) [![Dependency Status](https://gemnasium.com/calonso/ruby-push-notifications.svg)](https://gemnasium.com/calonso/ruby-push-notifications) [![Code Climate](https://codeclimate.com/github/calonso/ruby-push-notifications/badges/gpa.svg)](https://codeclimate.com/github/calonso/ruby-push-notifications) [![Test Coverage](https://codeclimate.com/github/calonso/ruby-push-notifications/badges/coverage.svg)](https://codeclimate.com/github/calonso/ruby-push-notifications) [![Gem Version](https://badge.fury.io/rb/ruby-push-notifications.svg)](http://badge.fury.io/rb/ruby-push-notifications)
2
4
 
3
5
  ###iOS and Android Push Notifications made easy!
4
6
 
@@ -46,6 +48,7 @@ Feel free to contribute!!
46
48
  * Validate GCM registration ids format
47
49
  * Validate GCM notifications format and max size
48
50
  * Split GCM notifications in parts if more than 1000 destinations are given (currently raising exception)
51
+ * Integrate with APNS Feedback service
49
52
 
50
53
  ## Contributing
51
54
 
@@ -5,15 +5,28 @@ require 'forwardable'
5
5
 
6
6
  module RubyPushNotifications
7
7
  module APNS
8
+ # This class encapsulates a connection with APNS.
9
+ #
10
+ # @author Carlos Alonso
8
11
  class APNSConnection
9
12
  extend Forwardable
10
13
 
14
+ # @private URL of the APNS Sandbox environment
11
15
  APNS_SANDBOX_URL = 'gateway.sandbox.push.apple.com'
16
+
17
+ # @private URL of APNS production environment
12
18
  APNS_PRODUCTION_URL = 'gateway.push.apple.com'
19
+
20
+ # @private Port to connect to
13
21
  APNS_PORT = 2195
14
22
 
15
23
  def_delegators :@sslsock, :write, :flush, :to_io, :read
16
24
 
25
+ # Opens a connection with APNS
26
+ #
27
+ # @param cert [String]. Contents of the PEM encoded certificate
28
+ # @param sandbox [Boolean]. Whether to use the sandbox environment or not.
29
+ # @return [APNSConnection]. The recently stablished connection.
17
30
  def self.open(cert, sandbox)
18
31
  ctx = OpenSSL::SSL::SSLContext.new
19
32
  ctx.key = OpenSSL::PKey::RSA.new cert
@@ -27,15 +40,25 @@ module RubyPushNotifications
27
40
  new socket, ssl
28
41
  end
29
42
 
43
+ # Returns the URL to connect to.
44
+ #
45
+ # @param sandbox [Boolean]. Whether it is the sandbox or the production
46
+ # environment we're looking for.
47
+ # @return [String]. The URL for the APNS service.
30
48
  def self.host(sandbox)
31
49
  sandbox ? APNS_SANDBOX_URL : APNS_PRODUCTION_URL
32
50
  end
33
51
 
52
+ # Initializes the APNSConnection
53
+ #
54
+ # @param tcpsock [TCPSocket]. The used TCP Socket.
55
+ # @param sslsock [SSLSocket]. The connected SSL Socket.
34
56
  def initialize(tcpsock, sslsock)
35
57
  @tcpsock = tcpsock
36
58
  @sslsock = sslsock
37
59
  end
38
60
 
61
+ # Closes the APNSConnection
39
62
  def close
40
63
  @sslsock.close
41
64
  @tcpsock.close
@@ -3,42 +3,70 @@ require 'json'
3
3
 
4
4
  module RubyPushNotifications
5
5
  module APNS
6
+ # Represents a APNS Notification.
7
+ # Manages the conversion of the notification to APNS binary format for
8
+ # each of the destinations.
9
+ # By default sets maximum expiration date (4 weeks).
10
+ #
11
+ # @author Carlos Alonso
6
12
  class APNSNotification
7
13
 
8
- WEEKS_4 = 2419200 # 4 weeks
14
+ # @private. 4 weeks in seconds
15
+ WEEKS_4 = 2419200
9
16
 
17
+ # @return [Array]. Array with the results from sending this notification
10
18
  attr_accessor :results
11
19
 
20
+ # Initializes the APNS Notification
21
+ #
22
+ # @param [Array]. Array containing all destinations for the notification
23
+ # @param [Hash]. Hash with the data to use as payload.
12
24
  def initialize(tokens, data)
13
25
  @tokens = tokens
14
26
  @data = data
15
27
  end
16
28
 
29
+ # Method that yields the notification's binary for each of the receivers.
30
+ #
31
+ # @param starting_id [Integer]. Every notification encodes a unique ID for
32
+ # further reference. This parameter represents the first id the first
33
+ # notification of this group should use.
34
+ # @yieldparam [String]. APNS binary's representation of this notification.
35
+ # Consisting of:
36
+ # Notification = 2(1), FrameLength(4), items(FrameLength)
37
+ # Item = ItemID(1), ItemLength(2), data(ItemLength)
38
+ # Items:
39
+ # Device Token => Id: 1, length: 32, data: binary device token
40
+ # Payload => Id: 2, length: ??, data: json formatted payload
41
+ # Notification ID => Id: 3, length: 4, data: notif id as int
42
+ # Expiration Date => Id: 4, length: 4, data: Unix timestamp as int
43
+ # Priority => Id: 5, length: 1, data: 10 as 1 byte int
44
+ # (https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW4)
17
45
  def each_message(starting_id)
18
46
  @tokens.each_with_index do |token, i|
19
- # Notification = 2(1), FrameLength(4), items(FrameLength)
20
- # Item = ItemID(1), ItemLength(2), data(ItemLength)
21
- # Items:
22
- # Device Token => Id: 1, length: 32, data: binary device token
23
- # Payload => Id: 2, length: ??, data: json formatted payload
24
- # Notification ID => Id: 3, length: 4, data: notif id as int
25
- # Expiration Date => Id: 4, length: 4, data: Unix timestamp as int
26
- # Priority => Id: 5, length: 1, data: 10 as 1 byte int
27
47
  bytes = device_token(token) + payload + notification_id(starting_id + i) + expiration_date + priority
28
48
  yield [2, bytes.bytesize, bytes].pack 'cNa*'
29
49
  end
30
50
  end
31
51
 
52
+ # @return [Integer]. The number of binaries this notification will send.
53
+ # One for each receiver.
32
54
  def count
33
55
  @tokens.count
34
56
  end
35
57
 
36
58
  private
37
59
 
60
+ # @param [String]. The device token to encode.
61
+ # @return [String]. Binary representation of the device token field.
38
62
  def device_token(token)
39
63
  [1, 32, token].pack 'cnH64'
40
64
  end
41
65
 
66
+ # Generates the APNS's binary representation of the notification's payload.
67
+ # Caches the value in an instance variable.
68
+ #
69
+ # @return [String]. Binary representation of the notification's payload.
42
70
  def payload
43
71
  @encoded_payload ||= -> {
44
72
  json = JSON.dump(@data).force_encoding 'ascii-8bit'
@@ -46,14 +74,18 @@ module RubyPushNotifications
46
74
  }.call
47
75
  end
48
76
 
77
+ # @param [Integer]. The unique ID for this notification.
78
+ # @return [String]. Binary representation of the notification id field.
49
79
  def notification_id(id)
50
80
  [3, 4, id].pack 'cnN'
51
81
  end
52
82
 
83
+ # @return [String]. Binary representation of the expiration date field.
53
84
  def expiration_date
54
85
  [4, 4, (Time.now + WEEKS_4).to_i].pack 'cnN'
55
86
  end
56
87
 
88
+ # @return [String]. Binary representation of the priority field.
57
89
  def priority
58
90
  [5, 1, 10].pack 'cnc'
59
91
  end
@@ -1,13 +1,34 @@
1
1
 
2
2
  module RubyPushNotifications
3
3
  module APNS
4
+ # This class coordinates the process of sending notifications.
5
+ # It takes care of reopening closed APNSConnections and seeking back to
6
+ # the failed notification to keep writing.
7
+ #
8
+ # Remember that APNS doesn't confirm successful notification, it just
9
+ # notifies when one went wrong and closes the connection. Therefore, this
10
+ # APNSPusher reconnects and rewinds the array until the notification that
11
+ # Apple rejected.
12
+ #
13
+ # @author Carlos Alonso
4
14
  class APNSPusher
5
15
 
16
+ # @param certificate [String]. The PEM encoded APNS certificate.
17
+ # @param sandbox [Boolean]. Whether the certificate is an APNS sandbox or not.
6
18
  def initialize(certificate, sandbox)
7
19
  @certificate = certificate
8
20
  @sandbox = sandbox
9
21
  end
10
22
 
23
+ # Pushes the notifications.
24
+ # Builds an array with all the binaries (one for each notification and receiver)
25
+ # and pushes them sequentially to APNS monitoring the response.
26
+ # If an error is received, the connection is reopened and the process
27
+ # continues at the next notification after the failed one (pointed by the response error)
28
+ #
29
+ # For each notification assigns an array with the results of each submission.
30
+ #
31
+ # @param notifications [Array]. All the APNSNotifications to be sent.
11
32
  def push(notifications)
12
33
  conn = APNSConnection.open @certificate, @sandbox
13
34
 
@@ -1,15 +1,40 @@
1
-
1
+ #
2
+ # @author Carlos Alonso
3
+ #
2
4
  module RubyPushNotifications::APNS
5
+
6
+ # No Status Error Code. Represents a successfully sent notification
3
7
  NO_ERROR_STATUS_CODE = 0
8
+
9
+ # An error occurred while processing the notification
4
10
  PROCESSING_ERROR_STATUS_CODE = 1
11
+
12
+ # The notification contains no device token
5
13
  MISSING_DEVICE_TOKEN_STATUS_CODE = 2
6
- MISSING_TOPIC_STATUS_CODE = 3 # You're writing to the TCPSocket rather than the SSL one
14
+
15
+ # The notification is being sent through the plain TCPSocket,
16
+ # rather than the SSL one
17
+ MISSING_TOPIC_STATUS_CODE = 3
18
+
19
+ # The notification contains no payload
7
20
  MISSING_PAYLOAD_STATUS_CODE = 4
21
+
22
+ # The given token sice is invalid (!= 32)
8
23
  INVALID_TOKEN_SIZE_STATUS_CODE = 5
24
+
25
+ # The given topic size is invalid
9
26
  INVALID_TOPIC_SIZE_STATUS_CODE = 6
27
+
28
+ # Payload size is invalid (256 bytes if iOS < 8, 2Kb otherwise)
10
29
  INVALID_PAYLOAD_SIZE_STATUS_CODE = 7
11
- INVALID_TOKEN_STATUS_CODE = 8 # The token is for dev and the env is prod or viceversa, or simply wrong
30
+
31
+ # The token is for dev and the env is prod or viceversa, or simply wrong
32
+ INVALID_TOKEN_STATUS_CODE = 8
33
+
34
+ # Connection closed at Apple's end
12
35
  SHUTDOWN_STATUS_CODE = 10
36
+
37
+ # Unknown error
13
38
  UNKNOWN_ERROR_STATUS_CODE = 255
14
39
  end
15
40
 
@@ -3,14 +3,31 @@ require 'net/https'
3
3
 
4
4
  module RubyPushNotifications
5
5
  module GCM
6
+ # Encapsulates a connection to the GCM service
7
+ # Responsible for final connection with the service.
8
+ #
9
+ # @author Carlos Alonso
6
10
  class GCMConnection
7
11
 
12
+ # @private The URL of the Android GCM endpoint
8
13
  GCM_URL = 'https://android.googleapis.com/gcm/send'
9
14
 
15
+ # @private Content-Type HTTP Header string
10
16
  CONTENT_TYPE_HEADER = 'Content-Type'
17
+
18
+ # @private Application/JSON content type
11
19
  JSON_CONTENT_TYPE = 'application/json'
20
+
21
+ # @private Authorization HTTP Header String
12
22
  AUTHORIZATION_HEADER = 'Authorization'
13
23
 
24
+ # Issues a POST request to the GCM send endpoint to
25
+ # submit the given notifications.
26
+ #
27
+ # @param notification [String]. The text to POST
28
+ # @param key [String]. The GCM sender id to use
29
+ # (https://developer.android.com/google/gcm/gcm.html#senderid)
30
+ # @return [GCMResponse]. The GCMResponse that encapsulates the received response
14
31
  def self.post(notification, key)
15
32
  headers = {
16
33
  CONTENT_TYPE_HEADER => JSON_CONTENT_TYPE,
@@ -1,6 +1,9 @@
1
1
 
2
2
  module RubyPushNotifications
3
3
  module GCM
4
+ # Base class for all GCM related errors
5
+ #
6
+ # @author Carlos Alonso
4
7
  class GCMError < StandardError ; end
5
8
 
6
9
  class MalformedGCMJSONError < GCMError ; end
@@ -1,15 +1,27 @@
1
1
 
2
2
  module RubyPushNotifications
3
3
  module GCM
4
+ # Encapsulates a GCM Notification.
5
+ # By default only Required fields are set.
6
+ # (https://developer.android.com/google/gcm/server-ref.html#send-downstream)
7
+ #
8
+ # @author Carlos Alonso
4
9
  class GCMNotification
5
10
 
11
+ # @return [Array]. Array with the results from sending this notification
6
12
  attr_accessor :results
7
13
 
14
+ # Initializes the notification
15
+ #
16
+ # @param [Array]. Array with the receiver's GCM registration ids.
17
+ # @param [Hash]. Payload to send.
8
18
  def initialize(registration_ids, data)
9
19
  @registration_ids = registration_ids
10
20
  @data = data
11
21
  end
12
22
 
23
+ # @return [String]. The GCM's JSON format for the payload to send.
24
+ # (https://developer.android.com/google/gcm/server-ref.html#send-downstream)
13
25
  def as_gcm_json
14
26
  JSON.dump(
15
27
  registration_ids: @registration_ids,
@@ -1,12 +1,25 @@
1
1
 
2
2
  module RubyPushNotifications
3
3
  module GCM
4
+
5
+ # This class is responsible for sending notifications to the GCM service.
6
+ #
7
+ # @author Carlos Alonso
4
8
  class GCMPusher
5
9
 
10
+ # Initializes the GCMPusher
11
+ #
12
+ # @param key [String]. GCM sender id to use
13
+ # ((https://developer.android.com/google/gcm/gcm.html#senderid))
6
14
  def initialize(key)
7
15
  @key = key
8
16
  end
9
17
 
18
+ # Actually pushes the given notifications.
19
+ # Assigns every notification an array with the result of each
20
+ # individual notification.
21
+ #
22
+ # @param notifications [Array]. Array of GCMNotification to send.
10
23
  def push(notifications)
11
24
  notifications.each do |notif|
12
25
  notif.results = GCMConnection.post notif.as_gcm_json, @key
@@ -1,10 +1,35 @@
1
1
 
2
2
  module RubyPushNotifications
3
3
  module GCM
4
+
5
+ # This class encapsulates a response received from the GCM service
6
+ # and helps parsing and understanding the received meesages/codes.
7
+ #
8
+ # @author Carlos Alonso
4
9
  class GCMResponse
5
10
 
6
- attr_reader :success, :failed, :canonical_ids, :results
11
+ # @return [Integer] the number of successfully sent notifications
12
+ attr_reader :success
13
+
14
+ # @return [Integer] the number of failed notifications
15
+ attr_reader :failed
16
+
17
+ # @return [Integer] the number of received canonical IDS
18
+ # (https://developer.android.com/google/gcm/server-ref.html#table4)
19
+ attr_reader :canonical_ids
20
+
21
+ # @return [Array] Array of a GCMResult for every receiver of the notification
22
+ # sent indicating the result of the operation.
23
+ attr_reader :results
7
24
 
25
+ # Initializes the GCMResponse and runs response parsing
26
+ #
27
+ # @param code [Integer]. The HTTP status code received
28
+ # @param body [String]. The response body received.
29
+ # @raise MalformedGCMJsonError if code == 400 Bad Request
30
+ # @raise GCMAuthError if code == 401 Unauthorized
31
+ # @raise GCMInternalError if code == 5xx
32
+ # @raise UnexpectedGCMResponseError if code != 200
8
33
  def initialize(code, body)
9
34
  case code
10
35
  when 200
@@ -30,6 +55,12 @@ module RubyPushNotifications
30
55
 
31
56
  private
32
57
 
58
+ # Parses the response extracting counts for successful, failed and
59
+ # containing canonical ID messages.
60
+ # Also creates the results array assigning a GCMResult subclass for each
61
+ # registration ID the notification was sent to.
62
+ #
63
+ # @param body [String]. The response body
33
64
  def parse_response(body)
34
65
  json = JSON.parse body, symbolize_names: true
35
66
  @success = json[:success]
@@ -38,6 +69,11 @@ module RubyPushNotifications
38
69
  @results = (json[:results] || []).map { |result| gcm_result_for result }
39
70
  end
40
71
 
72
+ # Factory method that, for each GCM result object assigns a GCMResult
73
+ # subclass.
74
+ #
75
+ # @param result [Hash]. GCM Result parsed hash
76
+ # @return [GCMResult]. Corresponding GCMResult subclass
41
77
  def gcm_result_for(result)
42
78
  if canonical_id = result[:registration_id]
43
79
  GCMCanonicalIDResult.new canonical_id
@@ -1,8 +1,14 @@
1
1
 
2
2
  module RubyPushNotifications
3
3
  module GCM
4
+ # Class that encapsulates the result of a single sent notification to a single
5
+ # Registration ID
6
+ # (https://developer.android.com/google/gcm/server-ref.html#table4)
7
+ # @author Carlos Alonso
4
8
  class GCMResult ; end
5
9
 
10
+ # Indicates that the notification was successfully sent to the corresponding
11
+ # registration ID
6
12
  class GCMResultOK < GCMResult
7
13
 
8
14
  def ==(other)
@@ -10,7 +16,12 @@ module RubyPushNotifications
10
16
  end
11
17
  end
12
18
 
19
+ # Indicates that the notification was successfully sent to the corresponding
20
+ # registration ID but GCM sent a canonical ID for it, so the received canonical
21
+ # ID should be used as registration ID ASAP.
13
22
  class GCMCanonicalIDResult < GCMResult
23
+
24
+ # @return [String]. The suggested canonical ID from GCM
14
25
  attr_reader :canonical_id
15
26
 
16
27
  def initialize(canonical_id)
@@ -23,7 +34,10 @@ module RubyPushNotifications
23
34
  end
24
35
  end
25
36
 
37
+ # An error occurred sending the notification to the registration ID.
26
38
  class GCMResultError < GCMResult
39
+
40
+ # @return [String]. The error sent by GCM
27
41
  attr_accessor :error
28
42
 
29
43
  def initialize(error)
@@ -1,3 +1,3 @@
1
1
  module RubyPushNotifications
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
@@ -1,8 +1,3 @@
1
- require "ruby-push-notifications/version"
2
-
3
- module RubyPushNotifications
4
- # Your code goes here...
5
- end
6
-
1
+ require 'ruby-push-notifications/version'
7
2
  require 'ruby-push-notifications/apns'
8
3
  require 'ruby-push-notifications/gcm'
@@ -13,6 +13,8 @@ Gem::Specification.new do |spec|
13
13
  spec.homepage = 'https://github.com/calonso/ruby-push-notifications'
14
14
  spec.license = 'MIT'
15
15
 
16
+ spec.required_ruby_version = '>= 1.9.3'
17
+
16
18
  spec.files = `git ls-files -z`.split("\x0")
17
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
data/spec/spec_helper.rb CHANGED
@@ -1,4 +1,7 @@
1
1
 
2
+ require 'codeclimate-test-reporter'
3
+ CodeClimate::TestReporter.start
4
+
2
5
  Bundler.setup
3
6
  Bundler.require :defaults, :development
4
7
  require 'webmock/rspec'
@@ -108,3 +111,5 @@ def apns_binary(json, token, id)
108
111
  3, 4, id, 4, 4, (Time.now + RubyPushNotifications::APNS::APNSNotification::WEEKS_4).to_i, 5, 1, 10
109
112
  ].pack 'cNcnH64cna*cnNcnNcnc'
110
113
  end
114
+
115
+ WebMock.disable_net_connect!(:allow => "codeclimate.com")
metadata CHANGED
@@ -1,94 +1,83 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ruby-push-notifications
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
5
- prerelease:
4
+ version: 0.1.0
6
5
  platform: ruby
7
6
  authors:
8
7
  - Carlos Alonso
9
8
  autorequire:
10
9
  bindir: bin
11
10
  cert_chain: []
12
- date: 2015-03-29 00:00:00.000000000 Z
11
+ date: 2015-03-30 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: bundler
16
15
  requirement: !ruby/object:Gem::Requirement
17
- none: false
18
16
  requirements:
19
- - - ~>
17
+ - - "~>"
20
18
  - !ruby/object:Gem::Version
21
19
  version: '1.6'
22
20
  type: :development
23
21
  prerelease: false
24
22
  version_requirements: !ruby/object:Gem::Requirement
25
- none: false
26
23
  requirements:
27
- - - ~>
24
+ - - "~>"
28
25
  - !ruby/object:Gem::Version
29
26
  version: '1.6'
30
27
  - !ruby/object:Gem::Dependency
31
28
  name: rake
32
29
  requirement: !ruby/object:Gem::Requirement
33
- none: false
34
30
  requirements:
35
- - - ~>
31
+ - - "~>"
36
32
  - !ruby/object:Gem::Version
37
33
  version: '10.4'
38
34
  type: :development
39
35
  prerelease: false
40
36
  version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
37
  requirements:
43
- - - ~>
38
+ - - "~>"
44
39
  - !ruby/object:Gem::Version
45
40
  version: '10.4'
46
41
  - !ruby/object:Gem::Dependency
47
42
  name: rspec
48
43
  requirement: !ruby/object:Gem::Requirement
49
- none: false
50
44
  requirements:
51
- - - ~>
45
+ - - "~>"
52
46
  - !ruby/object:Gem::Version
53
47
  version: '3.2'
54
48
  type: :development
55
49
  prerelease: false
56
50
  version_requirements: !ruby/object:Gem::Requirement
57
- none: false
58
51
  requirements:
59
- - - ~>
52
+ - - "~>"
60
53
  - !ruby/object:Gem::Version
61
54
  version: '3.2'
62
55
  - !ruby/object:Gem::Dependency
63
56
  name: factory_girl
64
57
  requirement: !ruby/object:Gem::Requirement
65
- none: false
66
58
  requirements:
67
- - - ~>
59
+ - - "~>"
68
60
  - !ruby/object:Gem::Version
69
61
  version: '4.0'
70
62
  type: :development
71
63
  prerelease: false
72
64
  version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
65
  requirements:
75
- - - ~>
66
+ - - "~>"
76
67
  - !ruby/object:Gem::Version
77
68
  version: '4.0'
78
69
  - !ruby/object:Gem::Dependency
79
70
  name: webmock
80
71
  requirement: !ruby/object:Gem::Requirement
81
- none: false
82
72
  requirements:
83
- - - ~>
73
+ - - "~>"
84
74
  - !ruby/object:Gem::Version
85
75
  version: '1.20'
86
76
  type: :development
87
77
  prerelease: false
88
78
  version_requirements: !ruby/object:Gem::Requirement
89
- none: false
90
79
  requirements:
91
- - - ~>
80
+ - - "~>"
92
81
  - !ruby/object:Gem::Version
93
82
  version: '1.20'
94
83
  description: Easy to use gem to send iOS and Android Push notifications
@@ -98,17 +87,15 @@ executables: []
98
87
  extensions: []
99
88
  extra_rdoc_files: []
100
89
  files:
101
- - .gitignore
102
- - .rspec
103
- - .travis.yml
90
+ - ".gitignore"
91
+ - ".rspec"
92
+ - ".travis.yml"
104
93
  - Gemfile
105
94
  - Gemfile.lock
106
95
  - LICENSE
107
96
  - README.md
108
97
  - Rakefile
109
- - examples/apns copy.rb
110
98
  - examples/apns.rb
111
- - examples/gcm copy.rb
112
99
  - examples/gcm.rb
113
100
  - lib/ruby-push-notifications.rb
114
101
  - lib/ruby-push-notifications/apns.rb
@@ -139,27 +126,26 @@ files:
139
126
  homepage: https://github.com/calonso/ruby-push-notifications
140
127
  licenses:
141
128
  - MIT
129
+ metadata: {}
142
130
  post_install_message:
143
131
  rdoc_options: []
144
132
  require_paths:
145
133
  - lib
146
134
  required_ruby_version: !ruby/object:Gem::Requirement
147
- none: false
148
135
  requirements:
149
- - - ! '>='
136
+ - - ">="
150
137
  - !ruby/object:Gem::Version
151
- version: '0'
138
+ version: 1.9.3
152
139
  required_rubygems_version: !ruby/object:Gem::Requirement
153
- none: false
154
140
  requirements:
155
- - - ! '>='
141
+ - - ">="
156
142
  - !ruby/object:Gem::Version
157
143
  version: '0'
158
144
  requirements: []
159
145
  rubyforge_project:
160
- rubygems_version: 1.8.23.2
146
+ rubygems_version: 2.2.2
161
147
  signing_key:
162
- specification_version: 3
148
+ specification_version: 4
163
149
  summary: iOS and Android Push Notifications made easy!
164
150
  test_files:
165
151
  - spec/factories.rb
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
-
5
- require 'ruby-push-notifications'
6
-
7
- tokens = [
8
- '6400b2a275eacf035d22d285d0ffb58fde5b647e54c7da882703136ba4ecd7d6',
9
- '16400b2a275eacf035d22d285d0ffb58fde5b647e54c7da882703136ba4ecd7d6',
10
- '6400b2a275eacf035d22d285d0ffb58fde5b647e54c7da882703136ba4ecd7d6'
11
- ]
12
-
13
- notification = RubyPushNotifications::APNS::APNSNotification.new tokens, { aps: { alert: 'Hello APNS World!', sound: 'true', badge: 1 } }
14
-
15
- pusher = RubyPushNotifications::APNS::APNSPusher.new(File.read('/Users/calonso/Desktop/apns.pem'), true)
16
- pusher.push [notification]
17
- p notification.results
@@ -1,16 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- $:.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
4
-
5
- require 'ruby-push-notifications'
6
-
7
- registration_ids = [
8
- 'APA91bFrtpS1bEo4BtTjE3V-GvRTX6KATZmh3ZGZ-wrQVY5UvsuQ4F-UmShwwjiG4uY0qtXG0RS4Tq2ir6t7gN6ziU7fpb1HtuiUKpdkY6WpE38mCxTa7cNeotIGgaKXOdNTEV10GU6Txp-Oxakqavuga6SrYNoVyA',
9
- 'APA91bFwufZkwhPhhLlQyIbM3MUksfxSvXXmXRP9L8LrJ8RMvUbRExERKHAzDR_pXZryKYICuqdS18fiytmks0WmKTZFd9_5AR8nK_m-5djqzM7AfBOyyv7Hy1uWCunJ2FcAbapGfaFYOTaW3MQGxjUIav_8Wj1R0OYANVMvZNGSDcu_j5wA80Y'
10
- ]
11
-
12
- notification = RubyPushNotifications::GCM::GCMNotification.new registration_ids, { text: 'Hello GCM World!' }
13
-
14
- pusher = RubyPushNotifications::GCM::GCMPusher.new 'AIzaSyAEO2CE_ipX217WwWsbHvGr8fiVHDdKUIc'
15
- pusher.push [notification]
16
- p notification.results