mblox 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- NDhiNjUwZDE4N2YyOTU3MGI3NWQ2MjBmYmUxODYzOTAzZjdjOGNjMA==
4
+ NWJiZmZlZWIxMDViNmIxNGE3MzE2NWYzYzZlY2M1MWIyNDg0MzkxNQ==
5
5
  data.tar.gz: !binary |-
6
- MDc4NzYxYWE4MjhkZGJiNDE5OTZiNGUyODBhODNhMWZkZDZlOGQ4NA==
6
+ ZDY0YmNkNzdjYmNhNDZkMDBhYjMxZTliNDdkYmNkZmVkMDhhMjk2MQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- OGNhNjBjYjI0NWUxMGJmZGU3ODQxZTIyMDNiNjIwNjk1NzNkNDdkNzQ3Zjc3
10
- OTc1NWI5MDk3ZjU0OTAzZTE4YTE0YjY4YTAwZjEzOTM1YjJjZDllNWUyMDEz
11
- NmUxMzQ2YjJmZWVhZjgyZTVlODA4YmNkMjZjY2U3ZjZiYmVjN2I=
9
+ MjE3NDJkODAwNThiOTZhYTQ0Y2EwZmQ5YzYxYzU2ZTgwZTQwNWQwODQwYzM0
10
+ ODcwZWU1NDIwODE3NmJiMDA0OWM2Y2VjZjg4OWI2NDUxMjNkYWY5ZDA5ZjE2
11
+ M2VhY2U4NzlmNGRjYjMyYzQ0ZGZjZGFmY2IyZThmZjFjODEyOGM=
12
12
  data.tar.gz: !binary |-
13
- MTNiMThhMDMzZTRkZTJlZmIyNGQ0OWVjMzIxNTNkYzJiN2Y4YWY5NzdmYTdm
14
- MmIxNjE5NDI3NDZkYWY3MTlmMmUzODAwYzgwYzg4NTAwNTY5ZWNiNTBmODU1
15
- ZTJhYTRjNWRiOTkzZTk1ZWY0MTFiZTFmMWIwYjRhMGE0OGMzY2U=
13
+ MzllZTE0OGZiZTg0ZTg0NTEyYWM5NjllYjMzZDMxMzY4ZmI2YzcwYWU5YTBl
14
+ NTA0ZWIzYzEyYmFmYzhiZjFmOWY5NGFhODcyNTg1MGM1ODE3MTkxYTc4ZTNi
15
+ M2VjNzA5NDk1YWY3NzU3NzkyMWRlMDk5ZmM1ODkwZGE5OWFmNjY=
data/README.md CHANGED
@@ -48,7 +48,8 @@ Once your application is configured, send messages:
48
48
 
49
49
  # The number to sending to must be a 10-digit number, including the area code. Can be a String or Fixnum.
50
50
  phone_number = 2225555555 # or: phone_number = "2225555555"
51
- Mblox::Sms.new(phone_number, "your message").send
51
+ responses = Mblox::Sms.new(phone_number, "your message").send # Returns an array of `Mblox::SmsResponse`'s
52
+ responses.first.should be_ok # each Mblox::SmsResponse responds to #ok? and #unroutable?
52
53
 
53
54
  ## Testing
54
55
 
@@ -2,6 +2,8 @@ require 'nokogiri'
2
2
 
3
3
  module Mblox
4
4
  class MissingExpectedXmlContentError < StandardError; end
5
+ class ValidationError < StandardError; end
6
+
5
7
  class << self
6
8
  def from_xml(xml)
7
9
  Nokogiri::XML(xml) { |config| config.nonet }.tap do |_|
data/lib/mblox/sms.rb CHANGED
@@ -13,7 +13,7 @@ module Mblox
13
13
  class InvalidSenderIdError < ::ArgumentError; end
14
14
  MAX_LENGTH = 160
15
15
  MAX_SECTION_LENGTH = MAX_LENGTH - "(MSG XXX/XXX): ".size
16
- LEGAL_CHARACTERS = "~\`!\"#\$\%&'\(\)*+,-.\/:;<=>?@_£¤¥§¿i¡ÄÅÆÇÉÑÖØÜßáäåæèéìñòöøóùüú\n\r\tí "
16
+ LEGAL_CHARACTERS = "~\`!\"#\$\%&'\(\)*+,-.\/:;<=>?@_£¤¥§¿i¡ÄÅÆÇÉÑÖØÜßâáäåæèéìñòöøóùüú\n\r\tí "
17
17
  ILLEGAL_CHARACTERS = /([^a-zA-Z0-9#{LEGAL_CHARACTERS}\\])/
18
18
 
19
19
  attr_reader :phone, :message
@@ -53,7 +53,7 @@ module Mblox
53
53
  request.body = request_body
54
54
  response = self.class.http.start{ |http| http.request(request) }.body
55
55
  Mblox.log "Mblox responds with:\n#{response}"
56
- SmsResponse.new(response)
56
+ SmsResponse.from_xml(response)
57
57
  end
58
58
 
59
59
  def build(message)
@@ -1,50 +1,78 @@
1
+ require 'active_support/core_ext/hash/keys.rb'
1
2
  require 'mblox/from_xml'
2
3
 
3
4
  module Mblox
4
5
  class SmsReceipt
5
- attr_reader :batch_id, :subscriber_number, :timestamp, :msg_reference, :status, :reason, :operator
6
- def initialize(xml)
7
- data = Mblox.from_xml(xml).xpath '//NotificationService'
8
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' node, but was #{xml}" if data.blank?
9
-
10
- data = data.xpath '//NotificationList'
11
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' node, but was #{xml}" if data.blank?
12
-
13
- data = data.xpath '//Notification'
14
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' node, but was #{xml}" if data.blank?
15
- @batch_id = data.attribute('BatchID').value.to_i
16
-
17
- data = data.xpath '//Subscriber'
18
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' -> 'Subscriber' node, but was #{xml}" if data.blank?
19
-
20
- @subscriber_number = value_at(:SubscriberNumber, data)
21
- @subscriber_number = @subscriber_number[1..-1] if '1' == @subscriber_number[0]
22
-
23
- timestamp = value_at(:TimeStamp, data)
24
- unless timestamp.blank?
25
- @timestamp = begin
26
- Time.strptime("#{timestamp}+0000", '%Y%m%d%H%M%z')
27
- rescue ArgumentError
28
- nil
29
- end
30
- end
6
+ ATTRIBUTES = [:batch_id, :subscriber_number, :msg_reference, :status, :timestamp, :reason, :operator]
7
+ attr_reader *ATTRIBUTES
31
8
 
32
- @timestamp = @timestamp.to_datetime if @timestamp
33
- @msg_reference = value_at(:MsgReference, data)
34
- @status = value_at(:Status, data)
35
- reason = value_at(:Reason, data)
36
- @reason = reason.blank? ? nil : reason.to_i
37
- data = data.xpath('//Tags').xpath('//Tag')
38
- return if data.empty?
39
- data.each do |d|
40
- @operator = d.child.content.to_i if "Operator" == data.attribute('Name').content
41
- return if @operator
9
+ def initialize args
10
+ args = args.symbolize_keys
11
+ ATTRIBUTES.each do |attr|
12
+ __send__("#{attr}=", args[attr])
13
+ args.delete(attr)
42
14
  end
15
+ raise ::ArgumentError, "Unrecognized attributes: #{args.inspect}" unless args.empty?
16
+ missing_fields = ATTRIBUTES.reject { |attr| [:timestamp, :reason, :operator].include?(attr) || __send__(attr) }
17
+ if 1 == missing_fields.count
18
+ raise ValidationError, "#{missing_fields.first} cannot be blank"
19
+ elsif missing_fields.count > 1
20
+ raise ValidationError, "The following fields cannot be blank: #{missing_fields.join(', ')}"
21
+ end
22
+ raise ValidationError, "batch_id must be a Fixnum" unless batch_id.is_a?(Fixnum)
23
+ raise ValidationError, "reason must be a Fixnum" unless reason.nil? || reason.is_a?(Fixnum)
24
+ raise ValidationError, "timestamp must be a DateTime" unless timestamp.nil? || timestamp.is_a?(DateTime)
43
25
  end
44
26
  private
45
- def value_at(path, data)
46
- data = data.xpath("//#{path}")
47
- (data.empty? || data.children.empty?) ? nil : data.first.child.content
27
+ attr_writer *ATTRIBUTES
28
+
29
+ class << self
30
+ def from_xml(xml)
31
+ args = {}
32
+ data = Mblox.from_xml(xml).xpath '//NotificationService'
33
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' node, but was #{xml}" if data.blank?
34
+
35
+ data = data.xpath '//NotificationList'
36
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' node, but was #{xml}" if data.blank?
37
+
38
+ data = data.xpath '//Notification'
39
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' node, but was #{xml}" if data.blank?
40
+ args[:batch_id]= data.attribute('BatchID').value.to_i
41
+
42
+ data = data.xpath '//Subscriber'
43
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' -> 'Subscriber' node, but was #{xml}" if data.blank?
44
+
45
+ args[:subscriber_number] = value_at(:SubscriberNumber, data)
46
+ args[:subscriber_number] = args[:subscriber_number][1..-1] if '1' == args[:subscriber_number][0]
47
+
48
+ timestamp = value_at(:TimeStamp, data)
49
+ unless timestamp.blank?
50
+ args[:timestamp] = begin
51
+ Time.strptime("#{timestamp}+0000", '%Y%m%d%H%M%z')
52
+ rescue ArgumentError
53
+ nil
54
+ end
55
+ end
56
+
57
+ args[:timestamp] = args[:timestamp].to_datetime if args[:timestamp]
58
+ args[:msg_reference] = value_at(:MsgReference, data)
59
+ args[:status] = value_at(:Status, data)
60
+ reason = value_at(:Reason, data)
61
+ args[:reason] = reason.blank? ? nil : reason.to_i
62
+ data = data.xpath('//Tags').xpath('//Tag')
63
+ unless data.empty?
64
+ data.each do |d|
65
+ args[:operator] = d.child.content.to_i if "Operator" == data.attribute('Name').content
66
+ break if args[:operator]
67
+ end
68
+ end
69
+ new(args)
48
70
  end
71
+ private
72
+ def value_at(path, data)
73
+ data = data.xpath("//#{path}")
74
+ (data.empty? || data.children.empty?) ? nil : data.first.child.content
75
+ end
76
+ end
49
77
  end
50
78
  end
@@ -36,28 +36,28 @@ module Mblox
36
36
  UNROUTABLE = new(10, UNROUTABLE_TEXT)
37
37
  end
38
38
 
39
- attr_reader :request, :result, :subscriber_result
40
- def initialize(xml)
41
- data = Mblox.from_xml(xml).xpath '//NotificationRequestResult'
42
-
43
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' node, but was #{xml}" if data.blank?
44
- header = data.xpath '//NotificationResultHeader'
45
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultHeader' node, but was #{xml}" if header.blank?
46
- @request = Result.from_xml(header, :RequestResult)
47
- @request = nil unless @request.valid?
48
-
49
- result_list = data.xpath '//NotificationResultList'
50
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultList' node, but was #{xml}" if result_list.blank?
51
- result_list = result_list.xpath '//NotificationResult'
52
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultList' -> 'NotificationResult' node, but was #{xml}" if result_list.blank?
53
- @result = Result.from_xml(result_list, :NotificationResult)
54
- @result = nil unless @result.valid?
55
-
56
- if @result.ok?
57
- result_list = result_list.xpath '//SubscriberResult'
58
- raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultList' -> 'NotificationResult' -> 'SubscriberResult' node, but was #{xml}" if result_list.blank?
59
- @subscriber_result = Result.from_xml(result_list, :SubscriberResult)
60
- @subscriber_result = nil unless @subscriber_result.valid?
39
+
40
+ ATTRIBUTES = [:request, :result, :subscriber_result]
41
+ attr_reader *ATTRIBUTES
42
+
43
+ def initialize args
44
+ args = args.symbolize_keys
45
+ ATTRIBUTES.each do |attr|
46
+ __send__("#{attr}=", args[attr])
47
+ args.delete(attr)
48
+ end
49
+ raise ::ArgumentError, "Unrecognized attributes: #{args.inspect}" unless args.empty?
50
+ missing_fields = ATTRIBUTES.reject { |attr| __send__(attr) }
51
+ if 1 == missing_fields.count
52
+ raise ValidationError, "#{missing_fields.first} cannot be blank"
53
+ elsif missing_fields.count > 1
54
+ raise ValidationError, "The following fields cannot be blank: #{missing_fields.join(', ')}"
55
+ end
56
+ wrong_type_fields = ATTRIBUTES.reject { |attr| __send__(attr).is_a?(self.class::Result) }
57
+ if 1 == wrong_type_fields.count
58
+ raise ValidationError, "#{wrong_type_fields.first} must be of type Mblox::SmsResponse::Result"
59
+ elsif wrong_type_fields.count > 1
60
+ raise ValidationError, "The following fields must be of type Mblox::SmsResponse::Result: #{wrong_type_fields.join(', ')}"
61
61
  end
62
62
  end
63
63
 
@@ -68,5 +68,36 @@ module Mblox
68
68
  def unroutable?
69
69
  @request.ok? && @result.ok? && Result::UNROUTABLE == @subscriber_result
70
70
  end
71
+
72
+ private
73
+ attr_writer *ATTRIBUTES
74
+
75
+ class << self
76
+ def from_xml(xml)
77
+ args = {}
78
+ data = Mblox.from_xml(xml).xpath '//NotificationRequestResult'
79
+
80
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' node, but was #{xml}" if data.blank?
81
+ header = data.xpath '//NotificationResultHeader'
82
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultHeader' node, but was #{xml}" if header.blank?
83
+ args[:request] = Result.from_xml(header, :RequestResult)
84
+ args[:request] = nil unless args[:request].valid?
85
+
86
+ result_list = data.xpath '//NotificationResultList'
87
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultList' node, but was #{xml}" if result_list.blank?
88
+ result_list = result_list.xpath '//NotificationResult'
89
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultList' -> 'NotificationResult' node, but was #{xml}" if result_list.blank?
90
+ args[:result] = Result.from_xml(result_list, :NotificationResult)
91
+ args[:result] = nil unless args[:result].valid?
92
+
93
+ if args[:result].ok?
94
+ result_list = result_list.xpath '//SubscriberResult'
95
+ raise MissingExpectedXmlContentError, "Xml should have contained a 'NotificationRequestResult' -> 'NotificationResultList' -> 'NotificationResult' -> 'SubscriberResult' node, but was #{xml}" if result_list.blank?
96
+ args[:subscriber_result] = Result.from_xml(result_list, :SubscriberResult)
97
+ args[:subscriber_result] = nil unless args[:subscriber_result].valid?
98
+ end
99
+ new(args)
100
+ end
101
+ end
71
102
  end
72
103
  end
data/lib/mblox/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module Mblox
2
- VERSION = "0.3.0"
2
+ VERSION = "0.4.0"
3
3
  end
@@ -21,6 +21,7 @@ describe Mblox::SmsReceipt do
21
21
  3
22
22
  end
23
23
 
24
+ describe "from_xml" do
24
25
  def valid
25
26
  xml = Builder::XmlMarkup.new
26
27
  xml.instruct!(:xml, :version => 1.0, :encoding => "ISO-8859-1", :standalone => :yes)
@@ -92,6 +93,8 @@ describe Mblox::SmsReceipt do
92
93
  n.Subscriber do |s|
93
94
  s.SubscriberNumber("2#{subscriber_number}")
94
95
  s.TimeStamp('Abcdefg')
96
+ s.MsgReference(msg_reference)
97
+ s.Status(status)
95
98
  s.Reason
96
99
  end
97
100
  end
@@ -101,7 +104,7 @@ describe Mblox::SmsReceipt do
101
104
  end
102
105
 
103
106
  it "should access attributes for valid data" do
104
- target = described_class.new(valid)
107
+ target = described_class.from_xml(valid)
105
108
  target.batch_id.should == batch_id
106
109
  target.subscriber_number.should == subscriber_number
107
110
  target.timestamp.should == DateTime.new(2013,10,7,17,36)
@@ -112,43 +115,80 @@ describe Mblox::SmsReceipt do
112
115
  end
113
116
 
114
117
  it "should raise error when missing root node" do
115
- expect{described_class.new('Abcdefg')}.to raise_error(Mblox::MissingExpectedXmlContentError, "'Abcdefg' is not parseable as XML")
118
+ expect{described_class.from_xml('Abcdefg')}.to raise_error(Mblox::MissingExpectedXmlContentError, "'Abcdefg' is not parseable as XML")
116
119
  end
117
120
 
118
121
  it "should raise error when missing notification service node" do
119
- expect{described_class.new(missing_notification_service)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' node, but was #{missing_notification_service}")
122
+ expect{described_class.from_xml(missing_notification_service)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' node, but was #{missing_notification_service}")
120
123
  end
121
124
 
122
125
  it "should raise error when missing notification list node" do
123
- expect{described_class.new(missing_notification_list)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' node, but was #{missing_notification_list}")
126
+ expect{described_class.from_xml(missing_notification_list)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' node, but was #{missing_notification_list}")
124
127
  end
125
128
 
126
129
  it "should raise error when missing notification node" do
127
- expect{described_class.new(missing_notification)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' node, but was #{missing_notification}")
130
+ expect{described_class.from_xml(missing_notification)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' node, but was #{missing_notification}")
128
131
  end
129
132
 
130
133
  it "should raise error when missing subscriber node" do
131
- expect{described_class.new(missing_subscriber)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' -> 'Subscriber' node, but was #{missing_subscriber}")
134
+ expect{described_class.from_xml(missing_subscriber)}.to raise_error(Mblox::MissingExpectedXmlContentError, "Xml should have contained a 'NotificationService' -> 'NotificationList' -> 'Notification' -> 'Subscriber' node, but was #{missing_subscriber}")
132
135
  end
133
136
 
134
137
  describe "subscriber_number" do
135
138
  it "should not drop leading character unless it is '1'" do
136
- target = described_class.new(unexpected_nested_values)
139
+ target = described_class.from_xml(unexpected_nested_values)
137
140
  target.subscriber_number.should == "2#{subscriber_number}"
138
141
  end
139
142
  end
140
143
 
141
144
  describe "reason" do
142
145
  it "should leave reason blank if it is nil" do
143
- target = described_class.new(unexpected_nested_values)
146
+ target = described_class.from_xml(unexpected_nested_values)
144
147
  target.reason.should be_nil
145
148
  end
146
149
  end
147
150
 
148
151
  describe "timestamp" do
149
152
  it "should fail gracefully if it can't be converted into a DateTime" do
150
- target = described_class.new(unexpected_nested_values)
153
+ target = described_class.from_xml(unexpected_nested_values)
151
154
  target.timestamp.should be_nil
152
155
  end
153
156
  end
157
+ end
158
+
159
+ describe "initialize" do
160
+ let(:args) { { :batch_id => batch_id, :subscriber_number => subscriber_number, :msg_reference => msg_reference, :status => status, :timestamp => DateTime.new(2013,10,7,17,36), :reason => reason, :operator => 10487 } }
161
+
162
+ [:batch_id, :subscriber_number, :msg_reference, :status].each do |attr|
163
+ it "should raise an error if #{attr} is missing" do
164
+ expect{described_class.new(args.merge(attr => nil))}.to raise_error(Mblox::ValidationError, "#{attr} cannot be blank")
165
+ end
166
+ end
167
+
168
+ [:timestamp, :reason, :operator].each do |attr|
169
+ it "should not raise an error if #{attr} is missing" do
170
+ expect{described_class.new(args.merge(attr => nil))}.to_not raise_error
171
+ end
172
+ end
173
+
174
+ it "should raise an error if batch_id, subscriber_number, msg_reference and status are missing" do
175
+ expect{described_class.new(args.merge(:batch_id => nil, :subscriber_number => nil, :msg_reference => nil, :status => nil))}.to raise_error(Mblox::ValidationError, "The following fields cannot be blank: batch_id, subscriber_number, msg_reference, status")
176
+ end
177
+
178
+ it "should raise an error if batch_id is not a Fixnum" do
179
+ expect{described_class.new(args.merge(:batch_id => 'ABC'))}.to raise_error(Mblox::ValidationError, "batch_id must be a Fixnum")
180
+ end
181
+
182
+ it "should raise an error if reason is not a Fixnum" do
183
+ expect{described_class.new(args.merge(:reason => 'ABC'))}.to raise_error(Mblox::ValidationError, "reason must be a Fixnum")
184
+ end
185
+
186
+ it "should raise an error if timestamp is not a DateTime" do
187
+ expect{described_class.new(args.merge(:timestamp => Time.now))}.to raise_error(Mblox::ValidationError, "timestamp must be a DateTime")
188
+ end
189
+
190
+ it "should raise an error if an unrecognized attribute is present" do
191
+ expect{described_class.new(args.merge(:extra_attribute => 'ABC'))}.to raise_error(::ArgumentError, 'Unrecognized attributes: {:extra_attribute=>"ABC"}')
192
+ end
193
+ end
154
194
  end
@@ -0,0 +1,26 @@
1
+ require "spec_helper"
2
+
3
+ describe Mblox::SmsResponse do
4
+ let(:args) { { :request => Mblox::SmsResponse::Result.new(9, "SomeRequest"), :result => Mblox::SmsResponse::Result.new(10, "SomeResult") , :subscriber_result => Mblox::SmsResponse::Result.new(11, "SomeSubscriberResult") } }
5
+
6
+ [:request, :result, :subscriber_result].each do |attr|
7
+ describe attr do
8
+ it "cannot be blank" do
9
+ expect{described_class.new(args.merge(:"#{attr}" => nil))}.to raise_error(Mblox::ValidationError, "#{attr} cannot be blank")
10
+ end
11
+ it "must be a Result" do
12
+ expect{described_class.new(args.merge(:"#{attr}" => 123))}.to raise_error(Mblox::ValidationError, "#{attr} must be of type Mblox::SmsResponse::Result")
13
+ end
14
+ end
15
+ end
16
+
17
+ it "should raise an error if request, result and subscriber_result are missing" do
18
+ expect{described_class.new({})}.to raise_error(Mblox::ValidationError, "The following fields cannot be blank: request, result, subscriber_result")
19
+ end
20
+ it "should raise an error if request, result and subscriber_result are the wrong types" do
21
+ expect{described_class.new(:request => 'A', :result => Time.now, :subscriber_result => 32)}.to raise_error(Mblox::ValidationError, "The following fields must be of type Mblox::SmsResponse::Result: request, result, subscriber_result")
22
+ end
23
+ it "should raise an error if an unrecognized attribute is present" do
24
+ expect{described_class.new(args.merge(:extra_attribute => 'ABC'))}.to raise_error(::ArgumentError, 'Unrecognized attributes: {:extra_attribute=>"ABC"}')
25
+ end
26
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: mblox
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Isaac Betesh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-11-20 00:00:00.000000000 Z
11
+ date: 2014-01-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -147,6 +147,7 @@ files:
147
147
  - spec/configuration_spec.rb
148
148
  - spec/sms_receipt_spec.rb
149
149
  - spec/sms_response_result_spec.rb
150
+ - spec/sms_response_spec.rb
150
151
  - spec/sms_spec.rb
151
152
  - spec/spec_helper.rb
152
153
  homepage: ''
@@ -188,16 +189,18 @@ summary: ! '# Mblox This gem is for subscribers to Mblox to send SMS messages.
188
189
  is :raise_error # Other options are :truncate and :split config.on_message_too_long
189
190
  = :truncate end Once your application is configured, send messages: # The number
190
191
  to sending to must be a 10-digit number, including the area code. Can be a String
191
- or Fixnum. phone_number = 2225555555 # or: phone_number = "2225555555" Mblox::Sms.new(phone_number,
192
- "your message").send ## Testing Copy config.yml.example to config.yml and set
193
- all the values in that file. Run: rspec You should recieve 6 SMS messages to
194
- your phone within several seconds. ## Contributing 1. Fork it 2. Create your feature
195
- branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am
196
- ''Add some feature''`) 4. Push to the branch (`git push origin my-new-feature`)
197
- 5. Create new Pull Request'
192
+ or Fixnum. phone_number = 2225555555 # or: phone_number = "2225555555" responses
193
+ = Mblox::Sms.new(phone_number, "your message").send # Returns an array of `Mblox::SmsResponse`''s
194
+ responses.first.should be_ok # each Mblox::SmsResponse responds to #ok? and #unroutable? ##
195
+ Testing Copy config.yml.example to config.yml and set all the values in that file. Run: rspec You
196
+ should recieve 6 SMS messages to your phone within several seconds. ## Contributing 1.
197
+ Fork it 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit
198
+ your changes (`git commit -am ''Add some feature''`) 4. Push to the branch (`git
199
+ push origin my-new-feature`) 5. Create new Pull Request'
198
200
  test_files:
199
201
  - spec/configuration_spec.rb
200
202
  - spec/sms_receipt_spec.rb
201
203
  - spec/sms_response_result_spec.rb
204
+ - spec/sms_response_spec.rb
202
205
  - spec/sms_spec.rb
203
206
  - spec/spec_helper.rb