action_sms 0.0.3 → 0.1.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.
@@ -1,11 +1,46 @@
1
1
  require 'net/https'
2
2
 
3
- module ActionSms #:nodoc:
4
- module ConnectionAdapters #:nodoc:
3
+ module ActionSms
4
+ module ConnectionAdapters
5
5
  # All the concrete gateway adapters follow the interface laid down in this
6
- # class. You can use this interface directly by borrowing the gateway
6
+ # class. You can use this interface directly by borrowing the gateway
7
7
  # connection from the Base with Base.connection.
8
8
  class AbstractAdapter
9
+ require 'uri'
10
+
11
+ def initialize(config = {}) #:nodoc:
12
+ @config = config
13
+ end
14
+
15
+ def authenticate(params)
16
+ params["authentication_key"] == @config[:authentication_key] ?
17
+ params.delete("authentication_key") : nil
18
+ end
19
+
20
+ def authentication_key=(value)
21
+ @config[:authentication_key] = value
22
+ end
23
+
24
+ def authentication_key
25
+ @config[:authentication_key]
26
+ end
27
+
28
+ def configuration
29
+ @config
30
+ end
31
+
32
+ def configuration=(value)
33
+ @config = value
34
+ end
35
+
36
+ def use_ssl
37
+ @config[:use_ssl]
38
+ end
39
+
40
+ def use_ssl=(value)
41
+ @config[:use_ssl] = value
42
+ end
43
+
9
44
  protected
10
45
  # Helper method to send an HTTP POST request to +url+ with paramaters
11
46
  # specified by the +params+ hash.
@@ -16,11 +51,18 @@ module ActionSms #:nodoc:
16
51
 
17
52
  http = Net::HTTP.new(uri.host, uri.port)
18
53
  http.use_ssl = true if uri.scheme == 'https'
54
+ http.verify_mode = OpenSSL::SSL::VERIFY_NONE
19
55
  resp = http.start do
20
56
  http.request(req)
21
57
  end
22
58
  resp.body
23
59
  end
60
+
61
+ def service_url(service_uri)
62
+ service_uri = URI.parse(service_uri)
63
+ service_uri.scheme = @config[:use_ssl] ? "https" : "http"
64
+ service_uri.to_s
65
+ end
24
66
  end
25
67
  end
26
68
  end
@@ -0,0 +1,76 @@
1
+ require 'action_sms/connection_adapters/abstract_adapter'
2
+
3
+ module ActionSms
4
+ class Base
5
+ def self.sms_global_connection(config) #:nodoc:
6
+ if config[:environment].to_s == "test"
7
+ test_helper = File.expand_path(File.dirname(__FILE__) + '/test_helpers/sms_global')
8
+ if File.exists?("#{test_helper}.rb")
9
+ require test_helper
10
+ ConnectionAdapters::SMSGlobalAdapter.class_eval do
11
+ include ActionSms::ConnectionAdapters::TestHelpers::SMSGlobal
12
+ end
13
+ end
14
+ end
15
+ ConnectionAdapters::SMSGlobalAdapter.new(config)
16
+ end
17
+ end
18
+
19
+ module ConnectionAdapters
20
+ # All the concrete gateway adapters follow the interface laid down in this
21
+ # class. You can use this interface directly by borrowing the gateway
22
+ # connection from the Base with Base.connection.
23
+ class SMSGlobalAdapter < AbstractAdapter
24
+
25
+ SERVICE_URL = "http://smsglobal.com.au/http-api.php"
26
+
27
+ def deliver(sms, options = {})
28
+ params = {
29
+ :action => 'sendsms',
30
+ :user => @config[:user],
31
+ :password => @config[:password],
32
+ :maxsplit => @config[:maxsplit] || "19",
33
+ :from => sms.respond_to?(:from) ? sms.from : "reply2email",
34
+ :to => sms.recipient,
35
+ :text => (sms.body || "")
36
+ }
37
+ params.merge!(
38
+ :userfield => sms.userfield
39
+ ) if sms.respond_to?(:userfield)
40
+ send_http_request(service_url, params)
41
+ end
42
+
43
+ def delivery_request_successful?(gateway_response)
44
+ gateway_response =~ /^OK/
45
+ end
46
+
47
+ def message_id(data)
48
+ sms_global_message_id_prefix = "SMSGlobalMsgID:"
49
+ if data.is_a?(Hash)
50
+ message_id = data["msgid"]
51
+ sms_global_message_id_prefix + message_id if message_id
52
+ elsif data.is_a?(String)
53
+ match = /#{sms_global_message_id_prefix}\s*(\d+)/.match(data)
54
+ sms_global_message_id_prefix + $1 if $1
55
+ end
56
+ end
57
+
58
+ def message_text(params)
59
+ params["msg"]
60
+ end
61
+
62
+ def sender(params)
63
+ params["from"]
64
+ end
65
+
66
+ def service_url
67
+ super(SERVICE_URL)
68
+ end
69
+
70
+ def status(delivery_receipt)
71
+ delivery_receipt["dlrstatus"]
72
+ end
73
+ end
74
+ end
75
+ end
76
+
@@ -0,0 +1,68 @@
1
+ module ActionSms
2
+ module ConnectionAdapters
3
+ module TestHelpers
4
+ module SMSGlobal
5
+
6
+ def sample_configuration(options = {})
7
+ config = {
8
+ :adapter => "sms_global",
9
+ :user => "SMSGlobal Username",
10
+ :password => "SMSGlobal Password"
11
+ }
12
+ config.merge!(
13
+ :authentication_key => "My Unique Authentication Key"
14
+ ) if options[:authentication_key]
15
+ config
16
+ end
17
+
18
+ def sample_delivery_receipt(options = {})
19
+ options[:message_id] ||= "6942744494999745"
20
+ options[:message_id].gsub!("SMSGlobalMsgID:", "")
21
+ options[:status] ||= "DELIVRD"
22
+ options[:error] ||= "000"
23
+ options[:date] ||= "1005132312"
24
+ {
25
+ "msgid"=> options[:message_id],
26
+ "dlrstatus"=> options[:status],
27
+ "dlr_err"=> options[:error],
28
+ "donedate"=> options[:date]
29
+ }
30
+ end
31
+
32
+ def sample_delivery_response(options = {})
33
+ options[:failed] ||= false
34
+ options[:message_id] ||= "6942744494999745"
35
+ options[:failed] ? "ERROR: No action requested" : "OK: 0; Sent queued message ID: 86b1a945370734f4 #{sample_message_id(:message_id => options[:message_id])}"
36
+ end
37
+
38
+ def sample_delivery_response_with_message_id(message_id, options = {})
39
+ options.merge!(:message_id => message_id)
40
+ sample_delivery_response(options)
41
+ end
42
+
43
+ def sample_incoming_sms(options = {})
44
+ options[:message] ||= "Endia kasdf ofeao"
45
+ options[:to] ||= "61447100308"
46
+ options[:from] ||= "61447100399"
47
+ options[:date] ||= "2010-05-13 23:59:11"
48
+ sample = {
49
+ "to" => options[:to],
50
+ "from" => options[:from],
51
+ "msg"=> options[:message],
52
+ "date" => options[:date]
53
+ }
54
+ sample.merge!(
55
+ "authentication_key" => @config[:authentication_key]
56
+ ) if options[:authentic]
57
+ sample
58
+ end
59
+
60
+ def sample_message_id(options = {})
61
+ options[:message_id] ||= "6942744494999745"
62
+ "SMSGlobalMsgID:#{options[:message_id]}"
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
68
+
@@ -0,0 +1,67 @@
1
+ module ActionSms
2
+ module ConnectionAdapters
3
+ module TestHelpers
4
+ module Tropo
5
+
6
+ def sample_configuration(options = {})
7
+ config = {
8
+ :adapter => "tropo",
9
+ :outgoing_token => "Tropo Outgoing Token"
10
+ }
11
+ config.merge!(
12
+ :authentication_key => "My Unique Authentication Key"
13
+ ) if options[:authentication_key]
14
+ config
15
+ end
16
+
17
+ def sample_delivery_response(options = {})
18
+ options[:failed] ? "<session><success>false</success><token></token><reason>FAILED TO ROUTE TOKEN</reason></session>" : "<session><success>true</success></session>"
19
+ end
20
+
21
+ def sample_incoming_sms(options = {})
22
+ options[:message] ||= "Endia kasdf ofeao"
23
+ options[:to] ||= "61447100308"
24
+ options[:from] ||= "61447100399"
25
+ options[:date] ||= "Mon Oct 11 09:21:38 UTC 2010"
26
+ params = {
27
+ "session" => {
28
+ "id"=>"12349516546e59746d6a89a990466789",
29
+ "account_id"=>"12345",
30
+ "timestamp"=> options[:date],
31
+ "user_type"=>"HUMAN",
32
+ "initial_text"=> options[:message],
33
+ "call_id"=>"123e71195545ad204bdd99f2070a7d86",
34
+ "to"=>{
35
+ "id"=> options[:to],
36
+ "name"=>"unknown",
37
+ "channel"=>"TEXT",
38
+ "network"=>"SMS"
39
+ },
40
+ "from" => {
41
+ "id"=> options[:from],
42
+ "name"=>"unknown",
43
+ "channel"=>"TEXT",
44
+ "network"=>"SMS"
45
+ },
46
+ "headers" => {
47
+ "_max-_forwards"=>"70",
48
+ "_content-_length"=>"124",
49
+ "_contact"=>"<sip:11.8.93.101:5066;transport=udp>",
50
+ "_to"=>"<sip:1231454582@10.6.69.203:5061;to=#{options[:to]}>",
51
+ "_c_seq"=>"1 INVITE",
52
+ "_via"=>"SIP/2.0/UDP 11.8.93.101:5066;branch=h0hG4bKk5sy1e",
53
+ "_call-_i_d"=>"ieeg18",
54
+ "_content-_type"=>"application/sdp",
55
+
56
+ "_from"=>"<sip:15EB6BAB-99DF-44C2-871DFBA75C319776@11.8.93.201;channel=private;user=#{options[:to]};msg=#{options[:message]};network=SMS;step=1>;tag=zm13kt"
57
+ }
58
+ }
59
+ }
60
+ params.merge!("authentication_key" => @config[:authentication_key]) unless options[:authentic] == false
61
+ params
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
67
+
@@ -0,0 +1,73 @@
1
+ require 'action_sms/connection_adapters/abstract_adapter'
2
+
3
+ module ActionSms
4
+ class Base
5
+ def self.tropo_connection(config) #:nodoc:
6
+ if config[:environment].to_s == "test"
7
+ test_helper = File.expand_path(File.dirname(__FILE__) + '/test_helpers/tropo')
8
+ if File.exists?("#{test_helper}.rb")
9
+ require test_helper
10
+ ConnectionAdapters::TropoAdapter.class_eval do
11
+ include ActionSms::ConnectionAdapters::TestHelpers::Tropo
12
+ end
13
+ end
14
+ end
15
+ ConnectionAdapters::TropoAdapter.new(config)
16
+ end
17
+ end
18
+
19
+ module ConnectionAdapters
20
+ # All the concrete gateway adapters follow the interface laid down in this
21
+ # class. You can use this interface directly by borrowing the gateway
22
+ # connection from the Base with Base.connection.
23
+ class TropoAdapter < AbstractAdapter
24
+ require 'tropo_message'
25
+
26
+ SERVICE_URL = "http://api.tropo.com/1.0/sessions"
27
+
28
+ def deliver(sms, options = {})
29
+ tropo_message = Tropo::Message.new
30
+ tropo_message.to = sms.recipient
31
+ tropo_message.text = sms.body || ""
32
+ tropo_message.from = sms.from if sms.respond_to?(:from)
33
+ tropo_message.token = @config[:outgoing_token]
34
+ response = send_http_request(service_url, tropo_message.request_xml)
35
+ options[:filter_response] ? filter_response(response) : response
36
+ end
37
+
38
+ def delivery_request_successful?(gateway_response)
39
+ gateway_response =~ /\<success\>true\<\/success\>/
40
+ end
41
+
42
+ def message_id(data)
43
+ # this method is supposed to return nil
44
+ end
45
+
46
+ def message_text(params)
47
+ session(params)["initial_text"]
48
+ end
49
+
50
+ def sender(params)
51
+ session(params)["from"]["id"]
52
+ end
53
+
54
+ def service_url
55
+ super(SERVICE_URL)
56
+ end
57
+
58
+ def status(delivery_receipt)
59
+ # this method is supposed to return nil
60
+ end
61
+
62
+ private
63
+ def session(params)
64
+ params["session"]
65
+ end
66
+
67
+ def filter_response(raw_response)
68
+ raw_response.gsub(/\<token\>\w+\<\/token\>/, "")
69
+ end
70
+ end
71
+ end
72
+ end
73
+
@@ -0,0 +1,4 @@
1
+ module ActionSms
2
+ VERSION = "0.1.0"
3
+ end
4
+
@@ -5,8 +5,35 @@ module ActionSms
5
5
  @source_root ||= File.join(File.dirname(__FILE__), 'templates')
6
6
  end
7
7
 
8
- def copy_conversation_file
9
- copy_file "action_sms.rb", "config/initializers/action_sms.rb"
8
+ def copy_initializer
9
+ template "action_sms.rb", "config/initializers/action_sms.rb"
10
+ end
11
+
12
+ private
13
+
14
+ def built_in_adapter_configurations
15
+ output = ""
16
+ adapters = ActionSms::Base.adapters(
17
+ :sample_configuration, :environment => "test"
18
+ )
19
+ adapters.each do |adapter|
20
+ config = adapter.sample_configuration
21
+ output << "## " << config[:adapter].titleize << "\n\n" <<
22
+ "# ActionSms::Base.establish_connection(" << "\n" <<
23
+ pretty_print_adapter_configuration(config) << "\n" <<
24
+ "# )"
25
+ output << "\n\n" unless adapters.last == adapter
26
+ end
27
+ output
28
+ end
29
+
30
+ def pretty_print_adapter_configuration(config)
31
+ output = ""
32
+ config.each do |key, value|
33
+ output << "# " << ":#{key}" << " => " << "\"#{value}\""
34
+ output << ",\n" unless config.keys.last == key
35
+ end
36
+ output
10
37
  end
11
38
  end
12
39
  end
@@ -1,11 +1,31 @@
1
- # see http://github.com/dwilkie/action_sms_gateways
2
- # for preconfigured sms gateways and more details on how to make your own adapter
1
+ # see also http://github.com/dwilkie/action_sms
2
+ # for more configuration options and details on how to make your own adapter
3
3
 
4
- # Then uncomment the following code and replace :adapter with your adapter
4
+ # Built In Adapters
5
5
 
6
- #ActionSms::Base.establish_connection(
7
- # :adapter => 'your_adapter',
8
- # :username => '[username]',
9
- # :password => '[password]'
10
- #)
6
+ <%= built_in_adapter_configurations %>
7
+
8
+ # Custom Adapters
9
+
10
+ # ActionSms::Base.establish_connection(
11
+ # :adapter => "your_adapter"
12
+ # # adapter specific configuration...
13
+ # )
14
+
15
+ # Incoming Message Authentication
16
+
17
+ # Using an authentication key in conjunction with a secure connection helps protect you against someone faking incoming messages to your server.
18
+
19
+ # ActionSms::Base.establish_connection(
20
+ # :use_ssl => true,
21
+ # :authentication_key => "my_secret"
22
+ # )
23
+
24
+ # Testing
25
+
26
+ # Setting: `:environment => "test"` gives you get some additional test helpers useful for testing
27
+
28
+ # ActionSms::Base.establish_connection(
29
+ # :environment => "test"
30
+ # )
11
31
 
data/spec/base_spec.rb ADDED
@@ -0,0 +1,649 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActionSms::Base do
4
+
5
+ describe "#adapters" do
6
+ let(:adapter) {mock "gateway_adapter"}
7
+ before do
8
+ ActionSms::Base.stub!(:methods).and_return(
9
+ [:gateway_adapter_connection]
10
+ )
11
+ ActionSms::Base.stub!(:gateway_adapter_connection).and_return(adapter)
12
+ end
13
+ context "an adapter responds to 'adapter_method'" do
14
+ before do
15
+ adapter.stub!(:adapter_method)
16
+ end
17
+ it "should include the adapter" do
18
+ ActionSms::Base.adapters(
19
+ :adapter_method
20
+ ).should include(adapter)
21
+ end
22
+ context "config = {}" do
23
+ context "and there's a current connection" do
24
+ before do
25
+ ActionSms::Base.stub!(:connected?).and_return(true)
26
+ end
27
+ let(:active_adapter_config) { {:adapter_name => "some_adapter"} }
28
+ before do
29
+ ActionSms::Base.stub!(:connection).and_return(mock(
30
+ "active_adapter",
31
+ :configuration => active_adapter_config
32
+ ))
33
+ end
34
+ it "should set the adapter's config to that of the current connection's" do
35
+ ActionSms::Base.should_receive(
36
+ :gateway_adapter_connection
37
+ ).with(active_adapter_config)
38
+ ActionSms::Base.adapters(:adapter_method)
39
+ end
40
+ end
41
+ context "but there's no current connection" do
42
+ it "should set the adapter's config to: '{}'" do
43
+ ActionSms::Base.should_receive(
44
+ :gateway_adapter_connection
45
+ ).with({})
46
+ ActionSms::Base.adapters(:adapter_method)
47
+ end
48
+ end
49
+ end
50
+ context "config = {:some_config => 'something'}" do
51
+ let(:config) { {:some_config => 'something'} }
52
+ it "should set the adapter's config to the passed in config" do
53
+ ActionSms::Base.should_receive(
54
+ :gateway_adapter_connection
55
+ ).with(config)
56
+ ActionSms::Base.adapters(:adapter_method, config)
57
+ end
58
+ end
59
+ end
60
+ context "an adapter does not respond to 'adapter_method'" do
61
+ it "should not include the adapter" do
62
+ ActionSms::Base.adapters(
63
+ :adapter_method
64
+ ).should_not include(:adapter)
65
+ end
66
+ end
67
+ end
68
+
69
+ describe "#connection" do
70
+ it "should set the connection" do
71
+ adapter = mock("adapter")
72
+ ActionSms::Base.connection = adapter
73
+ ActionSms::Base.connection.should == adapter
74
+ ActionSms::Base.should be_connected
75
+ end
76
+ end
77
+
78
+ describe "#establish_connection" do
79
+ context "adapter is specified in the configuration" do
80
+ let (:adapter_name) { "my_adapter" }
81
+ let (:adapter_connection) { adapter_name + "_connection" }
82
+ context "and is defined" do
83
+ let (:adapter) { mock("adapter") }
84
+ before do
85
+ ActionSms::Base.stub!(:respond_to?).with(
86
+ adapter_connection
87
+ ).and_return(true)
88
+ ActionSms::Base.stub!(
89
+ adapter_connection
90
+ ).and_return(adapter)
91
+ end
92
+ it "should be connected" do
93
+ ActionSms::Base.establish_connection(:adapter => adapter_name)
94
+ ActionSms::Base.should be_connected
95
+ end
96
+ end
97
+ context "but is not defined" do
98
+ before do
99
+ ActionSms::Base.stub!(:respond_to?).with(
100
+ adapter_connection
101
+ ).and_return(false)
102
+ end
103
+ it "should raise and 'AdapterNotFound' error" do
104
+ expect {
105
+ ActionSms::Base.establish_connection(:adapter => adapter_name)
106
+ }.to raise_error(ActionSms::AdapterNotFound)
107
+ end
108
+ end
109
+ end
110
+ context "adapter is not specified in the configuration" do
111
+ it "should raise an 'AdapterNotSpecified' error" do
112
+ expect {
113
+ ActionSms::Base.establish_connection({})
114
+ }.to raise_error(ActionSms::AdapterNotSpecified)
115
+ end
116
+ end
117
+ end
118
+
119
+ context "adapter helper methods" do
120
+ let(:active_adapter) {
121
+ mock("active_adapter")
122
+ }
123
+
124
+ let(:another_adapter) {
125
+ mock("another_adapter")
126
+ }
127
+
128
+ before do
129
+ ActionSms::Base.stub!(
130
+ :connection
131
+ ).and_return(active_adapter)
132
+
133
+ ActionSms::Base.stub!(
134
+ :methods
135
+ ).and_return([:another_adapter_connection])
136
+
137
+ ActionSms::Base.stub!(
138
+ :another_adapter_connection
139
+ ).and_return(another_adapter)
140
+
141
+ active_adapter.stub!(:configuration)
142
+ end
143
+
144
+ describe "#authenticate" do
145
+ before do
146
+ active_adapter.stub!(:respond_to?).with(
147
+ :authenticate
148
+ ).and_return(true)
149
+ end
150
+ context "active connection authenticates the message" do
151
+ before do
152
+ active_adapter.stub!(
153
+ :authenticate
154
+ ).and_return("something")
155
+ end
156
+ it "should return the active connection's response" do
157
+ ActionSms::Base.authenticate("anything").should == "something"
158
+ end
159
+ end
160
+ context "active connection does not authenticate the message" do
161
+ before do
162
+ active_adapter.stub!(:authenticate)
163
+ end
164
+ context "another adapter authenticates the message" do
165
+ before do
166
+ another_adapter.stub!(
167
+ :authenticate
168
+ ).and_return("something else")
169
+ end
170
+ it "should return the other adapter's response" do
171
+ ActionSms::Base.authenticate("anything").should == "something else"
172
+ end
173
+ end
174
+ context "no other adapter authenticates the message" do
175
+ it "should return nil" do
176
+ ActionSms::Base.authenticate("anything").should be_nil
177
+ end
178
+ end
179
+ end
180
+ end
181
+
182
+ describe "#authentication_key" do
183
+ it "should call 'authentication_key' on the connection" do
184
+ active_adapter.should_receive(:authentication_key)
185
+ ActionSms::Base.authentication_key
186
+ end
187
+ end
188
+
189
+ describe "#authentication_key=" do
190
+ it "should call 'authentication_key=' on the connection" do
191
+ active_adapter.should_receive(
192
+ :authentication_key=
193
+ ).with("something")
194
+ ActionSms::Base.authentication_key = "something"
195
+ end
196
+ end
197
+
198
+ describe "#deliver" do
199
+ it "should call 'deliver' on the connection" do
200
+ sms = mock("sms")
201
+ options = {:my_options => "something"}
202
+ active_adapter.should_receive(:deliver).with(sms, options)
203
+ ActionSms::Base.deliver(sms, options)
204
+ end
205
+ end
206
+
207
+ describe "#delivery_request_successful?" do
208
+ it "should call 'delivery_request_successful?' on the connection" do
209
+ gateway_response = mock("gateway_response")
210
+ active_adapter.should_receive(
211
+ :delivery_request_successful?
212
+ ).with(gateway_response)
213
+ ActionSms::Base.delivery_request_successful?(gateway_response)
214
+ end
215
+ end
216
+
217
+ describe "#message_id" do
218
+ before do
219
+ active_adapter.stub!(:respond_to?).with(
220
+ :message_id
221
+ ).and_return(true)
222
+ end
223
+ context "active connection returns the message id" do
224
+ before do
225
+ active_adapter.stub!(
226
+ :message_id
227
+ ).and_return("something")
228
+ end
229
+ it "should return the active connection's response" do
230
+ ActionSms::Base.message_id("anything").should == "something"
231
+ end
232
+ end
233
+ context "active connection does not return the message id" do
234
+ before do
235
+ active_adapter.stub!(:message_id)
236
+ end
237
+ context "another adapter returns the message id" do
238
+ before do
239
+ another_adapter.stub!(
240
+ :message_id
241
+ ).and_return("something else")
242
+ end
243
+
244
+ it "should return the other adapter's response" do
245
+ ActionSms::Base.message_id("anything").should == "something else"
246
+ end
247
+ end
248
+
249
+ context "no other adapter returns the message id" do
250
+ it "should return nil" do
251
+ ActionSms::Base.message_id("anything").should be_nil
252
+ end
253
+ end
254
+ end
255
+ end
256
+
257
+ describe "#message_text" do
258
+ before do
259
+ active_adapter.stub!(:respond_to?).with(
260
+ :message_text
261
+ ).and_return(true)
262
+ end
263
+ context "active connection returns the message text" do
264
+ before do
265
+ active_adapter.stub!(
266
+ :message_text
267
+ ).and_return("something")
268
+ end
269
+ it "should return the active connection's response" do
270
+ ActionSms::Base.message_text("anything").should == "something"
271
+ end
272
+ end
273
+ context "active connection does not return the message text" do
274
+ before do
275
+ active_adapter.stub!(:message_text)
276
+ end
277
+ context "another adapter returns the message text" do
278
+ before do
279
+ another_adapter.stub!(
280
+ :message_text
281
+ ).and_return("something else")
282
+ end
283
+
284
+ it "should return the other adapter's response" do
285
+ ActionSms::Base.message_text("anything").should == "something else"
286
+ end
287
+ end
288
+
289
+ context "no other adapter returns the message text" do
290
+ it "should return nil" do
291
+ ActionSms::Base.message_text("anything").should be_nil
292
+ end
293
+ end
294
+ end
295
+ end
296
+
297
+ describe "#sender" do
298
+ before do
299
+ active_adapter.stub!(:respond_to?).with(
300
+ :sender
301
+ ).and_return(true)
302
+ end
303
+ context "active connection returns the sender" do
304
+ before do
305
+ active_adapter.stub!(
306
+ :sender
307
+ ).and_return("something")
308
+ end
309
+ it "should return the active connection's response" do
310
+ ActionSms::Base.sender("anything").should == "something"
311
+ end
312
+ end
313
+ context "active connection does not return the sender" do
314
+ before do
315
+ active_adapter.stub!(:sender)
316
+ end
317
+ context "another adapter returns the sender" do
318
+ before do
319
+ another_adapter.stub!(
320
+ :sender
321
+ ).and_return("something else")
322
+ end
323
+
324
+ it "should return the other adapter's response" do
325
+ ActionSms::Base.sender("anything").should == "something else"
326
+ end
327
+ end
328
+
329
+ context "no other adapter return the sender" do
330
+ it "should return nil" do
331
+ ActionSms::Base.sender("anything").should be_nil
332
+ end
333
+ end
334
+ end
335
+ end
336
+
337
+ describe "#service_url" do
338
+ it "should call 'service_url' on the connection" do
339
+ active_adapter.should_receive(:service_url)
340
+ ActionSms::Base.service_url
341
+ end
342
+ end
343
+
344
+ describe "#status" do
345
+ before do
346
+ active_adapter.stub!(:respond_to?).with(
347
+ :status
348
+ ).and_return(true)
349
+ end
350
+ context "active connection returns the status" do
351
+ before do
352
+ active_adapter.stub!(
353
+ :status
354
+ ).and_return("something")
355
+ end
356
+ it "should return the active connection's response" do
357
+ ActionSms::Base.status("anything").should == "something"
358
+ end
359
+ end
360
+ context "active connection does not return the status" do
361
+ before do
362
+ active_adapter.stub!(:status)
363
+ end
364
+ context "another adapter returns the status" do
365
+ before do
366
+ another_adapter.stub!(
367
+ :status
368
+ ).and_return("something else")
369
+ end
370
+ it "should return the other adapter's response" do
371
+ ActionSms::Base.status("anything").should == "something else"
372
+ end
373
+ end
374
+ context "no adapters return the status" do
375
+ it "should return nil" do
376
+ ActionSms::Base.status("anything").should be_nil
377
+ end
378
+ end
379
+ end
380
+ end
381
+
382
+ describe "#use_ssl" do
383
+ it "should call 'use_ssl' on the connection" do
384
+ active_adapter.should_receive(:use_ssl)
385
+ ActionSms::Base.use_ssl
386
+ end
387
+ end
388
+
389
+ describe "#use_ssl=" do
390
+ it "should call 'use_ssl=' on the connection" do
391
+ active_adapter.should_receive(
392
+ :use_ssl=
393
+ ).with("something")
394
+ ActionSms::Base.use_ssl = "something"
395
+ end
396
+ end
397
+
398
+ # Test Helper Methods
399
+
400
+ describe "#sample_configuration" do
401
+ it "should call 'sample_configuration' on the connection" do
402
+ active_adapter.should_receive(:sample_configuration)
403
+ ActionSms::Base.sample_configuration
404
+ end
405
+ context "with options" do
406
+ it "should pass on the options" do
407
+ options = {:my_option => "12345"}
408
+ active_adapter.should_receive(
409
+ :sample_configuration
410
+ ).with(options)
411
+ ActionSms::Base.sample_configuration(options)
412
+ end
413
+ end
414
+ end
415
+
416
+ describe "#sample_delivery_receipt" do
417
+ shared_examples_for "another adapter's sample_delivery_receipt" do
418
+ context "but another adapter responds to 'sample_delivery_receipt'" do
419
+ before do
420
+ another_adapter.stub!(:sample_delivery_receipt)
421
+ end
422
+ context "and returns one" do
423
+ before do
424
+ another_adapter.stub!(
425
+ :sample_delivery_receipt
426
+ ).and_return("something else")
427
+ end
428
+ it "should return the other adapter's response" do
429
+ ActionSms::Base.sample_delivery_receipt.should == "something else"
430
+ end
431
+ end
432
+ context "but also returns nil" do
433
+ it "should return nil" do
434
+ ActionSms::Base.sample_delivery_receipt.should be_nil
435
+ end
436
+ end
437
+ end
438
+ context "and no other adapter responds to 'sample_delivery_receipt'" do
439
+ it "should return nil" do
440
+ ActionSms::Base.sample_delivery_receipt.should be_nil
441
+ end
442
+ end
443
+ end
444
+ context "active connection responds to 'sample_delivery_receipt'" do
445
+ before do
446
+ active_adapter.stub!(:sample_delivery_receipt)
447
+ end
448
+ context "and returns a sample delivery receipt" do
449
+ before do
450
+ active_adapter.stub!(
451
+ :sample_delivery_receipt
452
+ ).and_return("something")
453
+ end
454
+ it "should return the active connection's response" do
455
+ ActionSms::Base.sample_delivery_receipt.should == "something"
456
+ end
457
+ end
458
+ context "but returns nil" do
459
+ before do
460
+ active_adapter.stub!(:sample_delivery_receipt)
461
+ end
462
+ it_behaves_like "another adapter's sample_delivery_receipt"
463
+ end
464
+ end
465
+ context "active connection does not respond to 'sample_delivery_receipt'" do
466
+ it_behaves_like "another adapter's sample_delivery_receipt"
467
+ end
468
+ end
469
+
470
+ describe "#sample_delivery_response" do
471
+ it "should call 'sample_delivery_response' on the connection" do
472
+ active_adapter.should_receive(:sample_delivery_response)
473
+ ActionSms::Base.sample_delivery_response
474
+ end
475
+ context "with options" do
476
+ it "should pass on the options" do
477
+ options = {:my_option => "12345"}
478
+ active_adapter.should_receive(
479
+ :sample_delivery_response
480
+ ).with(options)
481
+ ActionSms::Base.sample_delivery_response(options)
482
+ end
483
+ end
484
+ end
485
+
486
+ describe "#sample_delivery_response_with_message_id" do
487
+ shared_examples_for "another adapter's sample_delivery_response_with_message_id" do
488
+ context "but another adapter responds to 'sample_delivery_response_with_message_id'" do
489
+ before do
490
+ another_adapter.stub!(:sample_delivery_response_with_message_id)
491
+ end
492
+ context "and returns one" do
493
+ before do
494
+ another_adapter.stub!(
495
+ :sample_delivery_response_with_message_id
496
+ ).and_return("something else")
497
+ end
498
+ it "should return the other adapter's response" do
499
+ ActionSms::Base.sample_delivery_response_with_message_id("12345") == "something else"
500
+ end
501
+ end
502
+ context "but also returns nil" do
503
+ it "should return nil" do
504
+ ActionSms::Base.sample_delivery_response_with_message_id("12345").should be_nil
505
+ end
506
+ end
507
+ end
508
+ context "and no other adapter responds to 'sample_delivery_response_with_message_id'" do
509
+ it "should return nil" do
510
+ ActionSms::Base.sample_delivery_response_with_message_id("12345").should be_nil
511
+ end
512
+ end
513
+ end
514
+ context "active connection responds to 'sample_delivery_response_with_message_id'" do
515
+ before do
516
+ active_adapter.stub!(:sample_delivery_response_with_message_id)
517
+ end
518
+ context "and returns a sample delivery response with message id" do
519
+ before do
520
+ active_adapter.stub!(
521
+ :sample_delivery_response_with_message_id
522
+ ).and_return("something")
523
+ end
524
+ it "should return the active connection's response" do
525
+ ActionSms::Base.sample_delivery_response_with_message_id("12345").should == "something"
526
+ end
527
+ end
528
+ context "but returns nil" do
529
+ before do
530
+ active_adapter.stub!(:sample_delivery_response_with_message_id)
531
+ end
532
+ it_behaves_like "another adapter's sample_delivery_response_with_message_id"
533
+ end
534
+ end
535
+ context "active connection does not respond to 'sample_delivery_response_with_message_id'" do
536
+ it_behaves_like "another adapter's sample_delivery_response_with_message_id"
537
+ end
538
+ end
539
+
540
+ describe "#sample_incoming_sms" do
541
+ shared_examples_for "another adapter's sample_incoming_sms" do
542
+ context "but another adapter responds to 'sample_incoming_sms'" do
543
+ before do
544
+ another_adapter.stub!(:sample_incoming_sms)
545
+ end
546
+ context "and returns one" do
547
+ before do
548
+ another_adapter.stub!(
549
+ :sample_incoming_sms
550
+ ).and_return("something else")
551
+ end
552
+ it "should return the other adapter's response" do
553
+ ActionSms::Base.sample_incoming_sms.should == "something else"
554
+ end
555
+ end
556
+ context "but also returns nil" do
557
+ it "should return nil" do
558
+ ActionSms::Base.sample_incoming_sms.should be_nil
559
+ end
560
+ end
561
+ end
562
+ context "and no other adapter responds to 'sample_incoming_sms'" do
563
+ it "should return nil" do
564
+ ActionSms::Base.sample_incoming_sms.should be_nil
565
+ end
566
+ end
567
+ end
568
+ context "active connection responds to 'sample_incoming_sms'" do
569
+ before do
570
+ active_adapter.stub!(:sample_incoming_sms)
571
+ end
572
+ context "and returns a sample incoming sms" do
573
+ before do
574
+ active_adapter.stub!(
575
+ :sample_incoming_sms
576
+ ).and_return("something")
577
+ end
578
+ it "should return the active connection's response" do
579
+ ActionSms::Base.sample_incoming_sms.should == "something"
580
+ end
581
+ end
582
+ context "but returns nil" do
583
+ before do
584
+ active_adapter.stub!(:sample_incoming_sms)
585
+ end
586
+ it_behaves_like "another adapter's sample_incoming_sms"
587
+ end
588
+ end
589
+ context "active connection does not respond to 'sample_incoming_sms'" do
590
+ it_behaves_like "another adapter's sample_incoming_sms"
591
+ end
592
+ end
593
+
594
+ describe "#sample_message_id" do
595
+ shared_examples_for "another adapter's sample_message_id" do
596
+ context "but another adapter responds to 'sample_message_id'" do
597
+ before do
598
+ another_adapter.stub!(:sample_message_id)
599
+ end
600
+ context "and returns one" do
601
+ before do
602
+ another_adapter.stub!(
603
+ :sample_message_id
604
+ ).and_return("something else")
605
+ end
606
+ it "should return the other adapter's response" do
607
+ ActionSms::Base.sample_message_id.should == "something else"
608
+ end
609
+ end
610
+ context "but also returns nil" do
611
+ it "should return nil" do
612
+ ActionSms::Base.sample_message_id.should be_nil
613
+ end
614
+ end
615
+ end
616
+ context "and no other adapter responds to 'sample_message_id'" do
617
+ it "should return nil" do
618
+ ActionSms::Base.sample_message_id.should be_nil
619
+ end
620
+ end
621
+ end
622
+ context "active connection responds to 'sample_message_id'" do
623
+ before do
624
+ active_adapter.stub!(:sample_message_id)
625
+ end
626
+ context "and returns a sample message id" do
627
+ before do
628
+ active_adapter.stub!(
629
+ :sample_message_id
630
+ ).and_return("something")
631
+ end
632
+ it "should return the active connection's response" do
633
+ ActionSms::Base.sample_message_id.should == "something"
634
+ end
635
+ end
636
+ context "but returns nil" do
637
+ before do
638
+ active_adapter.stub!(:sample_message_id)
639
+ end
640
+ it_behaves_like "another adapter's sample_message_id"
641
+ end
642
+ end
643
+ context "active connection does not respond to 'sample_message_id'" do
644
+ it_behaves_like "another adapter's sample_message_id"
645
+ end
646
+ end
647
+ end
648
+ end
649
+