pling 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8,9 +8,9 @@ describe Pling::Gateway do
8
8
  let(:device) { Pling::Device.new(:identifier => 'DEVICEIDENTIFIER', :type => :android) }
9
9
 
10
10
  let(:gateway_class) do
11
- Class.new(Pling::Gateway::Base).tap do |klass|
11
+ Class.new(Pling::Gateway).tap do |klass|
12
12
  klass.instance_eval do
13
- handles :android
13
+ handles :android, :c2dm
14
14
  end
15
15
  end
16
16
  end
@@ -33,7 +33,7 @@ describe Pling::Gateway do
33
33
  end
34
34
 
35
35
  it 'should call #to_pling_device on the given argument' do
36
- device.should_receive(:to_pling_device).and_return(device)
36
+ device.should_receive(:to_pling_device).at_least(1).times.and_return(device)
37
37
  subject.discover(device)
38
38
  end
39
39
 
@@ -47,4 +47,66 @@ describe Pling::Gateway do
47
47
  end
48
48
  end
49
49
 
50
+ describe '#handles?' do
51
+ it 'should return true if the gateway supports the given device\'s type' do
52
+ device.type = :android
53
+ gateway.handles?(device).should be_true
54
+
55
+ device.type = :c2dm
56
+ gateway.handles?(device).should be_true
57
+ end
58
+
59
+ it 'should return false if the gateway does not support the given device\'s type' do
60
+ device.type = :random
61
+ gateway.handles?(device).should be_false
62
+ end
63
+ end
64
+
65
+ describe '#deliver' do
66
+
67
+ it 'should call each middleware in the given order' do
68
+ first_middleware = double(Pling::Middleware::Base)
69
+ first_middleware.should_receive(:deliver).
70
+ with(message, device).and_yield(message, device)
71
+
72
+ second_middleware = double(Pling::Middleware::Base)
73
+ second_middleware.should_receive(:deliver).
74
+ with(message, device)
75
+
76
+ gateway = gateway_class.new(:middlewares => [first_middleware, second_middleware])
77
+ gateway.stub(:deliver!)
78
+
79
+ gateway.deliver(message, device)
80
+ end
81
+
82
+ it 'should raise an error if #deliver! is not overwritten' do
83
+ expect { gateway.deliver(message, device) }.to raise_error(/Please implement/)
84
+ end
85
+
86
+ it 'should not modify the middleware configuration' do
87
+ middlewares = [Pling::Middleware::Base.new, Pling::Middleware::Base.new]
88
+
89
+ gateway = gateway_class.new(:middlewares => middlewares)
90
+ gateway.stub(:deliver!)
91
+
92
+ expect { gateway.deliver(message, device) }.to_not change(middlewares, :count)
93
+ end
94
+
95
+ it 'should raise an Pling::Errors if no on_exception callback is set' do
96
+ gateway.stub(:deliver!).and_raise(Pling::Error)
97
+ expect { gateway.deliver(message, device) }.to raise_error Pling::Error
98
+ end
99
+
100
+ it 'should not raise an Pling::Errors if an on_exception callback is set' do
101
+ gateway = gateway_class.new(:on_exception => lambda {})
102
+ gateway.stub(:deliver!).and_raise(Pling::Error)
103
+ expect { gateway.deliver(message, device) }.to_not raise_error Pling::Error
104
+ end
105
+
106
+ it 'should pass the exception to the callback' do
107
+ gateway = gateway_class.new(:on_exception => lambda { |error| error.should be_kind_of Pling::Error })
108
+ gateway.stub(:deliver!).and_raise(Pling::Error)
109
+ gateway.deliver(message, device)
110
+ end
111
+ end
50
112
  end
@@ -22,6 +22,31 @@ describe Pling::Message do
22
22
  it { should be_valid }
23
23
  end
24
24
 
25
+ context 'when created with a hash that contains a :subject key' do
26
+ subject { Pling::Message.new(:subject => "Hello!")}
27
+ its(:subject) { should eq('Hello!')}
28
+ end
29
+
30
+ context 'when created with a hash that contains a :badge key' do
31
+ subject { Pling::Message.new(:badge => 1)}
32
+ its(:badge) { should eq('1') }
33
+ end
34
+
35
+ context 'when created with a hash that contains a :sound key' do
36
+ subject { Pling::Message.new(:sound => '*pling*')}
37
+ its(:sound) { should eq('*pling*') }
38
+ end
39
+
40
+ context 'when created with a hash that contains a :badge key' do
41
+ subject { Pling::Message.new(:badge => 1)}
42
+ its(:badge) { should eq('1') }
43
+ end
44
+
45
+ context 'when created with a hash that contains a :payload key' do
46
+ subject { Pling::Message.new(:payload => { :data => true })}
47
+ its(:payload) { should eq({ :data => true }) }
48
+ end
49
+
25
50
  context 'when created with an hash of invalid attributes' do
26
51
  it 'should ignore the invalid paramters' do
27
52
  expect { Pling::Message.new({ :random_param => true }) }.to_not raise_error
data/spec/pling_spec.rb CHANGED
@@ -110,6 +110,15 @@ end
110
110
 
111
111
  describe Pling::DeliveryFailed do
112
112
  it { should be_kind_of Pling::Error }
113
+ it { should respond_to :pling_message }
114
+ it { should respond_to :pling_device }
115
+
116
+ it 'should initialize #pling_message and #pling_device' do
117
+ error = Pling::DeliveryFailed.new('message', 'pling message', 'pling device')
118
+ error.message.should eq('message')
119
+ error.pling_message.should eq('pling message')
120
+ error.pling_device.should eq('pling device')
121
+ end
113
122
  end
114
123
 
115
124
  describe Pling::NoGatewayFound do
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: pling
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -11,11 +11,11 @@ authors:
11
11
  autorequire:
12
12
  bindir: bin
13
13
  cert_chain: []
14
- date: 2011-10-28 00:00:00.000000000Z
14
+ date: 2011-11-11 00:00:00.000000000Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: faraday
18
- requirement: &70095758683660 !ruby/object:Gem::Requirement
18
+ requirement: &70316014249500 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
21
  - - ~>
@@ -23,10 +23,10 @@ dependencies:
23
23
  version: '0.7'
24
24
  type: :runtime
25
25
  prerelease: false
26
- version_requirements: *70095758683660
26
+ version_requirements: *70316014249500
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: json
29
- requirement: &70095758682420 !ruby/object:Gem::Requirement
29
+ requirement: &70316014248240 !ruby/object:Gem::Requirement
30
30
  none: false
31
31
  requirements:
32
32
  - - ~>
@@ -34,10 +34,10 @@ dependencies:
34
34
  version: '1.4'
35
35
  type: :runtime
36
36
  prerelease: false
37
- version_requirements: *70095758682420
37
+ version_requirements: *70316014248240
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: rspec
40
- requirement: &70095758681540 !ruby/object:Gem::Requirement
40
+ requirement: &70316014247280 !ruby/object:Gem::Requirement
41
41
  none: false
42
42
  requirements:
43
43
  - - ~>
@@ -45,10 +45,10 @@ dependencies:
45
45
  version: '2.7'
46
46
  type: :development
47
47
  prerelease: false
48
- version_requirements: *70095758681540
48
+ version_requirements: *70316014247280
49
49
  - !ruby/object:Gem::Dependency
50
50
  name: yard
51
- requirement: &70095758680240 !ruby/object:Gem::Requirement
51
+ requirement: &70316014246260 !ruby/object:Gem::Requirement
52
52
  none: false
53
53
  requirements:
54
54
  - - ! '>='
@@ -56,10 +56,10 @@ dependencies:
56
56
  version: '0.7'
57
57
  type: :development
58
58
  prerelease: false
59
- version_requirements: *70095758680240
59
+ version_requirements: *70316014246260
60
60
  - !ruby/object:Gem::Dependency
61
61
  name: rake
62
- requirement: &70095758678900 !ruby/object:Gem::Requirement
62
+ requirement: &70316014245540 !ruby/object:Gem::Requirement
63
63
  none: false
64
64
  requirements:
65
65
  - - ! '>='
@@ -67,7 +67,7 @@ dependencies:
67
67
  version: '0.9'
68
68
  type: :development
69
69
  prerelease: false
70
- version_requirements: *70095758678900
70
+ version_requirements: *70316014245540
71
71
  description: Pling is a notification framework that supports multiple gateways. Currently
72
72
  supported are Android Push and SMS.
73
73
  email:
@@ -88,29 +88,35 @@ files:
88
88
  - lib/pling.rb
89
89
  - lib/pling/adapter.rb
90
90
  - lib/pling/adapter/base.rb
91
+ - lib/pling/apn.rb
92
+ - lib/pling/apn/connection.rb
93
+ - lib/pling/apn/feedback.rb
94
+ - lib/pling/apn/gateway.rb
95
+ - lib/pling/c2dm.rb
96
+ - lib/pling/c2dm/gateway.rb
91
97
  - lib/pling/configurable.rb
92
98
  - lib/pling/delayed_initializer.rb
93
99
  - lib/pling/device.rb
94
100
  - lib/pling/gateway.rb
95
- - lib/pling/gateway/apn.rb
96
- - lib/pling/gateway/base.rb
97
- - lib/pling/gateway/c2dm.rb
98
101
  - lib/pling/message.rb
99
102
  - lib/pling/middleware.rb
100
103
  - lib/pling/middleware/base.rb
101
104
  - lib/pling/version.rb
102
105
  - pling.gemspec
106
+ - spec/pling/.DS_Store
107
+ - spec/pling/adapter/.DS_Store
103
108
  - spec/pling/adapter/base_spec.rb
109
+ - spec/pling/apn/connection_spec.rb
110
+ - spec/pling/apn/feedback_spec.rb
111
+ - spec/pling/apn/gateway_spec.rb
112
+ - spec/pling/c2dm/gateway_spec.rb
104
113
  - spec/pling/delayed_initializer_spec.rb
105
114
  - spec/pling/device_spec.rb
106
- - spec/pling/gateway/apn_spec.rb
107
- - spec/pling/gateway/base_spec.rb
108
- - spec/pling/gateway/c2dm_spec.rb
109
115
  - spec/pling/gateway_spec.rb
110
116
  - spec/pling/message_spec.rb
111
117
  - spec/pling_spec.rb
112
118
  - spec/spec_helper.rb
113
- homepage: https://flinc.github.com/pling
119
+ homepage: http://flinc.github.com/pling
114
120
  licenses: []
115
121
  post_install_message:
116
122
  rdoc_options: []
@@ -135,12 +141,15 @@ signing_key:
135
141
  specification_version: 3
136
142
  summary: Pling is a notification framework that supports multiple gateways
137
143
  test_files:
144
+ - spec/pling/.DS_Store
145
+ - spec/pling/adapter/.DS_Store
138
146
  - spec/pling/adapter/base_spec.rb
147
+ - spec/pling/apn/connection_spec.rb
148
+ - spec/pling/apn/feedback_spec.rb
149
+ - spec/pling/apn/gateway_spec.rb
150
+ - spec/pling/c2dm/gateway_spec.rb
139
151
  - spec/pling/delayed_initializer_spec.rb
140
152
  - spec/pling/device_spec.rb
141
- - spec/pling/gateway/apn_spec.rb
142
- - spec/pling/gateway/base_spec.rb
143
- - spec/pling/gateway/c2dm_spec.rb
144
153
  - spec/pling/gateway_spec.rb
145
154
  - spec/pling/message_spec.rb
146
155
  - spec/pling_spec.rb
@@ -1,64 +0,0 @@
1
- module Pling
2
- module Gateway
3
- class Base
4
- include Pling::Configurable
5
-
6
- class << self
7
- def handles(*types)
8
- @handled_types = [types].flatten.map { |t| t.to_sym }
9
- end
10
-
11
- def handled_types
12
- @handled_types ||= []
13
- end
14
- end
15
-
16
- def initialize(config = {})
17
- setup_configuration(config)
18
- middlewares = configuration[:middlewares]
19
- configuration.merge!(:middlewares => Pling::DelayedInitializer.new)
20
- middlewares.each { |middleware| configuration[:middlewares] << middleware } if middlewares
21
- end
22
-
23
- def handles?(device)
24
- self.class.handled_types.include?(device.type)
25
- end
26
-
27
- ##
28
- # Delivers the given message to the given device using the given stack.
29
- #
30
- # @param message [#to_pling_message]
31
- # @param device [#to_pling_device]
32
- # @param stack [Array] The stack to use (Default: configuration[:middlewares])
33
- def deliver(message, device, stack = nil)
34
- message = Pling._convert(message, :message)
35
- device = Pling._convert(device, :device)
36
-
37
- stack ||= [] + configuration[:middlewares].initialize!
38
-
39
- return deliver!(message, device) if stack.empty?
40
-
41
- stack.shift.deliver(message, device) do |m, d|
42
- deliver(m, d, stack)
43
- end
44
- end
45
-
46
- ##
47
- # Delivers the given message to the given device without using the middleware.
48
- #
49
- # @param message [#to_pling_message]
50
- # @param device [#to_pling_device]
51
- def deliver!(message, device)
52
- raise NotImplementedError, "Please implement #{self.class}#deliver!(message, device)"
53
- end
54
-
55
- protected
56
-
57
- def default_configuration
58
- {
59
- :middlewares => Pling::DelayedInitializer.new
60
- }
61
- end
62
- end
63
- end
64
- end
@@ -1,103 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Pling::Gateway::APN do
4
-
5
- let(:valid_configuration) { { :certificate => '/path/to/certificate.pem' } }
6
-
7
- let(:message) { Pling::Message.new('Hello from Pling') }
8
- let(:device) { Pling::Device.new(:identifier => 'DEVICEIDENTIFIER', :type => :iphone) }
9
-
10
- let(:ssl_context) { double(OpenSSL::SSL::SSLContext).as_null_object }
11
- let(:x509_certificate) { double(OpenSSL::X509::Certificate).as_null_object }
12
- let(:pkey_rsa) { double(OpenSSL::PKey::RSA).as_null_object }
13
- let(:tcp_socket) { double(TCPSocket).as_null_object }
14
- let(:ssl_socket) { double(OpenSSL::SSL::SSLSocket).as_null_object }
15
-
16
- before do
17
- File.stub(:read).with('/path/to/certificate.pem').and_return('--- CERT CONTENT ---')
18
- OpenSSL::SSL::SSLContext.stub(:new).and_return(ssl_context)
19
- OpenSSL::X509::Certificate.stub(:new).and_return(x509_certificate)
20
- OpenSSL::PKey::RSA.stub(:new).and_return(pkey_rsa)
21
- TCPSocket.stub(:new).and_return(tcp_socket)
22
- OpenSSL::SSL::SSLSocket.stub(:new).and_return(ssl_socket)
23
- end
24
-
25
- it 'should handle various apn related device types' do
26
- Pling::Gateway::APN.handled_types.should =~ [:apple, :apn, :ios, :ipad, :iphone, :ipod]
27
- end
28
-
29
- context 'when created with an invalid configuration' do
30
- it "should raise an error when :certificate is missing" do
31
- expect { Pling::Gateway::APN.new({}) }.to raise_error(ArgumentError, /:certificate is missing/)
32
- end
33
- end
34
-
35
- context 'when created with a valid configuration' do
36
- it 'should allow configuration of the :certificate' do
37
- File.should_receive(:read).with('/some/path').and_return('--- SOME CERT CONTENT ---')
38
- gateway = Pling::Gateway::APN.new(valid_configuration.merge(:certificate => '/some/path'))
39
- gateway.deliver(message, device)
40
- end
41
-
42
- it 'should allow configuration of the :host' do
43
- TCPSocket.should_receive(:new).with('some-host', anything).and_return(tcp_socket)
44
- gateway = Pling::Gateway::APN.new(valid_configuration.merge(:host => 'some-host'))
45
- gateway.deliver(message, device)
46
- end
47
-
48
- it 'should allow configuration of the :port' do
49
- TCPSocket.should_receive(:new).with(anything, 1234).and_return(tcp_socket)
50
- gateway = Pling::Gateway::APN.new(valid_configuration.merge(:port => 1234))
51
- gateway.deliver(message, device)
52
- end
53
-
54
- it 'should establish a connection' do
55
- ssl_socket.should_receive(:connect)
56
- Pling::Gateway::APN.new(valid_configuration)
57
- end
58
- end
59
-
60
- describe '#deliver' do
61
- subject { Pling::Gateway::APN.new(valid_configuration) }
62
-
63
- it 'should raise an error if no message is given' do
64
- expect { subject.deliver(nil, device) }.to raise_error
65
- end
66
-
67
- it 'should raise an error the device is given' do
68
- expect { subject.deliver(message, nil) }.to raise_error
69
- end
70
-
71
- it 'should call #to_pling_message on the given message' do
72
- message.should_receive(:to_pling_message).and_return(message)
73
- subject.deliver(message, device)
74
- end
75
-
76
- it 'should call #to_pling_device on the given device' do
77
- device.should_receive(:to_pling_device).and_return(device)
78
- subject.deliver(message, device)
79
- end
80
-
81
- it 'should raise an exception when the payload exceeds 256 bytes' do
82
- message.body = "X" * 256
83
- expect { subject.deliver(message, device) }.to raise_error(Pling::DeliveryFailed, /Payload size of \d+ exceeds allowed size of 256 bytes/)
84
- end
85
-
86
- it 'should try to deliver the given message' do
87
- expected_header = "\x00\x00 \xDE\xF2\xCE-\xE7\xD2\xF2\xEB\x00"
88
- expected_payload = {
89
- 'aps' => {
90
- 'alert' => 'Hello from Pling'
91
- }
92
- }
93
-
94
- ssl_socket.stub(:write) do |packet|
95
- header, payload = packet.split('$')
96
- header.should eq(expected_header)
97
- JSON.parse(payload).should eq(expected_payload)
98
- end
99
-
100
- subject.deliver(message, device)
101
- end
102
- end
103
- end
@@ -1,61 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Pling::Gateway::Base do
4
-
5
- let(:gateway_class) do
6
- Class.new(Pling::Gateway::Base).tap do |klass|
7
- klass.handles :android, :c2dm
8
- end
9
- end
10
-
11
- let(:gateway) { gateway_class.new }
12
- let(:message) { Pling::Message.new }
13
- let(:device) { Pling::Device.new }
14
-
15
- describe '#handles?' do
16
- it 'should return true if the gateway supports the given device\'s type' do
17
- device.type = :android
18
- gateway.handles?(device).should be_true
19
-
20
- device.type = :c2dm
21
- gateway.handles?(device).should be_true
22
- end
23
-
24
- it 'should return false if the gateway does not support the given device\'s type' do
25
- device.type = :random
26
- gateway.handles?(device).should be_false
27
- end
28
- end
29
-
30
- describe '#deliver' do
31
-
32
- it 'should call each middleware in the given order' do
33
- first_middleware = double(Pling::Middleware::Base)
34
- first_middleware.should_receive(:deliver).
35
- with(message, device).and_yield(message, device)
36
-
37
- second_middleware = double(Pling::Middleware::Base)
38
- second_middleware.should_receive(:deliver).
39
- with(message, device)
40
-
41
- gateway = gateway_class.new(:middlewares => [first_middleware, second_middleware])
42
- gateway.stub(:deliver!)
43
-
44
- gateway.deliver(message, device)
45
- end
46
-
47
- it 'should raise an error if #deliver! is not overwritten' do
48
- expect { gateway.deliver(message, device) }.to raise_error(/Please implement/)
49
- end
50
-
51
- it 'should not modify the middleware configuration' do
52
- middlewares = [Pling::Middleware::Base.new, Pling::Middleware::Base.new]
53
-
54
- gateway = gateway_class.new(:middlewares => middlewares)
55
- gateway.stub(:deliver!)
56
-
57
- expect { gateway.deliver(message, device) }.to_not change(middlewares, :count)
58
- end
59
- end
60
-
61
- end