mblox 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/README.md +3 -1
- data/lib/mblox/configuration.rb +3 -26
- data/lib/mblox/sms.rb +6 -42
- data/lib/mblox/sms_response.rb +2 -0
- data/lib/mblox/version.rb +1 -1
- data/mblox.gemspec +1 -0
- data/spec/sms_spec.rb +214 -149
- data/spec/spec_helper.rb +1 -1
- metadata +22 -7
- data/spec/configuration_spec.rb +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 7d2c1da153da2a5588a22d61cbcc07487c289863
|
4
|
+
data.tar.gz: b2ae4e5d1be782d8d72273dcf33c6379038b751b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8ed41e839424e5100dbb082a872dd965dd49bbfed67ad48984060616542ada987692eb6395f89ac686e24f1c7890b6caa5490b004ca30c532ee76928f1232d62
|
7
|
+
data.tar.gz: be52c74f37f65a1a2947481aca7bb287bf8aab149659bbd436dc6372b78d9773172895e962624055b03160f71f2578eaaff2b1572cd5551540b9511c026ba289
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
### 0.6.0 (3/11/2015)
|
2
|
+
|
3
|
+
* BREAKING CHANGES:
|
4
|
+
* Mblox::Sms#message will now raise an exception if the message was split. Use Mblox::Sms#messages in that case. If the message was not split, Mblox::Sms#message returns the message as a String directly instead of warpping it in an array.
|
5
|
+
* `on_message_too_long`, `logger`, and `log_at` are configured in SmsValidation, a dependency of this gem. See https://github.com/betesh/sms_validation/blob/master/README.md for details
|
data/README.md
CHANGED
@@ -29,8 +29,10 @@ Configuration
|
|
29
29
|
config.partner_name = ...
|
30
30
|
config.tariff = ...
|
31
31
|
config.service_id = ...
|
32
|
+
end
|
32
33
|
|
33
|
-
|
34
|
+
# You can also configure some logging options via SmsValidation, a dependency of this gem. See https://github.com/betesh/sms_validation/blob/master/README.md for details
|
35
|
+
SmsValidation.configure do |config|
|
34
36
|
# In a Rails environment, config.logger will default to Rails.logger and config.log_at will default to :debug
|
35
37
|
# config.log_at means the level at which Mblox will log.
|
36
38
|
# For instance, if config.log_at == :debug, Mblox will log only if the logger's log level is :debug
|
data/lib/mblox/configuration.rb
CHANGED
@@ -3,37 +3,14 @@ module Mblox
|
|
3
3
|
def config
|
4
4
|
@config ||= Configuration.new
|
5
5
|
end
|
6
|
-
end
|
7
6
|
|
8
|
-
|
9
|
-
|
7
|
+
def configure
|
8
|
+
yield config
|
9
|
+
end
|
10
10
|
end
|
11
11
|
|
12
12
|
class Configuration
|
13
13
|
attr_accessor :outbound_url, :profile_id, :sender_id, :password, :partner_name, :tariff, :service_id
|
14
14
|
attr_reader :logger, :log_level, :on_message_too_long
|
15
|
-
def initialize
|
16
|
-
@logger = Rails.logger if defined?(::Rails)
|
17
|
-
@log_level = :debug
|
18
|
-
@on_message_too_long = :raise_error
|
19
|
-
end
|
20
|
-
|
21
|
-
def on_message_too_long= action
|
22
|
-
raise ArgumentError, "Mblox.config.on_message_too_long must be either :truncate, :split or :raise_error" unless [:truncate, :raise_error, :split].include?(action)
|
23
|
-
@on_message_too_long = action
|
24
|
-
end
|
25
|
-
|
26
|
-
def log_at level
|
27
|
-
validate @logger, level
|
28
|
-
@log_level = level
|
29
|
-
end
|
30
|
-
def logger= logger
|
31
|
-
validate logger, @log_level
|
32
|
-
@logger = logger
|
33
|
-
end
|
34
|
-
private
|
35
|
-
def validate logger, level
|
36
|
-
raise ArgumentError, "Mblox log level must be set to :fatal, :error, :warn, :info or :debug" if (logger && !logger.respond_to?(level))
|
37
|
-
end
|
38
15
|
end
|
39
16
|
end
|
data/lib/mblox/sms.rb
CHANGED
@@ -4,37 +4,19 @@ require 'addressable/uri'
|
|
4
4
|
require 'builder'
|
5
5
|
require "net/https"
|
6
6
|
require 'mblox/sms_response'
|
7
|
+
require 'sms_validation'
|
7
8
|
|
8
9
|
module Mblox
|
9
|
-
class Sms
|
10
|
-
class InvalidPhoneNumberError < ::ArgumentError; end
|
11
|
-
class InvalidMessageError < ::ArgumentError; end
|
10
|
+
class Sms < SmsValidation::Sms
|
12
11
|
class BatchIdOutOfRangeError < ::ArgumentError; end
|
13
12
|
class InvalidSenderIdError < ::ArgumentError; end
|
14
|
-
class MessageTooLongError < ::ArgumentError; end
|
15
|
-
MAX_LENGTH = 160
|
16
|
-
MAX_SECTION_LENGTH = MAX_LENGTH - "(MSG XXX/XXX): ".size
|
17
13
|
LEGAL_CHARACTERS = "~\`!\"#\$\%&'\(\)*+,-.\/:;<=>?@_£¤¥§¿i¡ÄÅÃÆÇÉÑÖØÜßâáäåãæçèéìíñòöøóùüú\n\r\t ©"
|
18
14
|
ILLEGAL_CHARACTERS = /([^a-zA-Z0-9#{LEGAL_CHARACTERS}\\])/
|
19
15
|
|
20
|
-
attr_reader :phone, :message
|
21
|
-
|
22
|
-
ON_MESSAGE_TOO_LONG_HANDLER = {
|
23
|
-
:raise_error => Proc.new { raise MessageTooLongError, "Message cannot be longer than #{MAX_LENGTH} characters" },
|
24
|
-
:truncate => Proc.new { |message| Mblox.log "Truncating message due to length. Message was: \"#{message}\" but will now be \"#{message = message[0,MAX_LENGTH]}\""; [message] },
|
25
|
-
:split => Proc.new { |message| split_message(message) }
|
26
|
-
}
|
27
|
-
|
28
16
|
def initialize(phone, message, batch_id=nil)
|
29
|
-
phone
|
30
|
-
raise InvalidPhoneNumberError, "Phone number must be ten digits" unless /\A[0-9]{10}\z/.match(phone)
|
31
|
-
raise InvalidPhoneNumberError, "Phone number cannot begin with 0 or 1" if ['0','1'].include?(phone[0].to_s)
|
32
|
-
raise InvalidMessageError, "Message cannot be blank" if message.empty?
|
17
|
+
super(phone, message)
|
33
18
|
illegal_characters = ILLEGAL_CHARACTERS.match(message).to_a
|
34
19
|
raise InvalidMessageError, "Message cannot contain the following special characters: #{illegal_characters.uniq.join(', ')}" unless illegal_characters.size.zero?
|
35
|
-
Mblox.log "WARNING: Some characters may be lost because the message must be broken into at least 1000 sections" if message.size > (999 * MAX_SECTION_LENGTH)
|
36
|
-
@message = (message.size > MAX_LENGTH) ? ON_MESSAGE_TOO_LONG_HANDLER[Mblox.config.on_message_too_long].call(message) : [message.dup]
|
37
|
-
@phone = "1#{phone}"
|
38
20
|
raise BatchIdOutOfRangeError, "batch_id must be in the range 1 to #{MAX_BATCH_ID}. The batch_id specified (#{batch_id}) is out of range." if !batch_id.blank? && (MAX_BATCH_ID < batch_id.to_i)
|
39
21
|
@batch_id = batch_id.to_i unless batch_id.blank?
|
40
22
|
end
|
@@ -49,15 +31,15 @@ module Mblox
|
|
49
31
|
end
|
50
32
|
|
51
33
|
def send
|
52
|
-
|
34
|
+
messages.collect { |message| commit build(message) }
|
53
35
|
end
|
54
36
|
private
|
55
37
|
def commit(request_body)
|
56
|
-
|
38
|
+
SmsValidation.log "Sending SMS to Mblox:\n#{request_body}"
|
57
39
|
request = self.class.request
|
58
40
|
request.body = request_body
|
59
41
|
response = self.class.http.start{ |http| http.request(request) }.body
|
60
|
-
|
42
|
+
SmsValidation.log "Mblox responds with:\n#{response}"
|
61
43
|
SmsResponse.from_xml(response)
|
62
44
|
end
|
63
45
|
|
@@ -86,24 +68,6 @@ module Mblox
|
|
86
68
|
end
|
87
69
|
end
|
88
70
|
|
89
|
-
def self.section_counter(size)
|
90
|
-
size / MAX_SECTION_LENGTH + ((size % MAX_SECTION_LENGTH).zero? ? 0 : 1)
|
91
|
-
end
|
92
|
-
|
93
|
-
def self.split_message(message)
|
94
|
-
sections = section_counter(message.size)
|
95
|
-
Mblox.log "Splitting message into #{sections} messages due to length."
|
96
|
-
split_message = []
|
97
|
-
(sections - 1).times do |i|
|
98
|
-
first_char = i * MAX_SECTION_LENGTH
|
99
|
-
Mblox.log "Section ##{i + 1} of ##{sections} contains characters #{first_char + 1} thru #{first_char + MAX_SECTION_LENGTH} of #{message.size}"
|
100
|
-
split_message << "(MSG #{i+1}/#{sections}): #{message[first_char, MAX_SECTION_LENGTH]}"
|
101
|
-
end
|
102
|
-
first_char = (sections-1)*MAX_SECTION_LENGTH
|
103
|
-
Mblox.log "Section ##{sections} of ##{sections} contains characters #{first_char + 1} thru #{message.size} of #{message.size}"
|
104
|
-
split_message << "(MSG #{sections}/#{sections}): #{message[first_char..-1]}"
|
105
|
-
end
|
106
|
-
|
107
71
|
class << self
|
108
72
|
def url
|
109
73
|
@url ||= URI.parse(URI.escape(Mblox.config.outbound_url))
|
data/lib/mblox/sms_response.rb
CHANGED
@@ -1,7 +1,9 @@
|
|
1
|
+
require 'active_support/callbacks'
|
1
2
|
require 'active_model/callbacks'
|
2
3
|
require 'active_model/validator'
|
3
4
|
require 'active_model/naming'
|
4
5
|
require 'active_model/translation'
|
6
|
+
require 'active_support/concern'
|
5
7
|
require 'active_model/validations'
|
6
8
|
require 'active_model/errors'
|
7
9
|
|
data/lib/mblox/version.rb
CHANGED
data/mblox.gemspec
CHANGED
@@ -25,6 +25,7 @@ Gem::Specification.new do |spec|
|
|
25
25
|
spec.add_runtime_dependency 'activemodel'
|
26
26
|
spec.add_runtime_dependency 'activesupport'
|
27
27
|
spec.add_runtime_dependency 'addressable'
|
28
|
+
spec.add_runtime_dependency 'sms_validation'
|
28
29
|
spec.add_runtime_dependency 'builder'
|
29
30
|
spec.add_runtime_dependency "nokogiri", ">= 1.5.0"
|
30
31
|
end
|
data/spec/sms_spec.rb
CHANGED
@@ -1,256 +1,321 @@
|
|
1
1
|
# encoding: UTF-8
|
2
2
|
require "spec_helper"
|
3
3
|
|
4
|
-
module Mblox
|
5
|
-
class Sms
|
6
|
-
def build_for_test(message)
|
7
|
-
build(message)
|
8
|
-
end
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
4
|
describe Mblox::Sms do
|
13
|
-
|
14
|
-
|
15
|
-
|
5
|
+
TEN_CHARACTERS = "ABCDEFGHIJ"
|
6
|
+
ONE_HUNDRED_SIXTY_CHARACTERS = TEN_CHARACTERS * 16
|
7
|
+
let(:phone_number) { TEST_NUMBER }
|
8
|
+
let(:message) { "Mblox gem test sent at #{Time.now}" }
|
9
|
+
|
10
|
+
subject { described_class.new(phone_number, message) }
|
11
|
+
|
16
12
|
before(:all) do
|
17
13
|
Mblox.reset_configuration
|
18
14
|
set_configuration
|
19
15
|
end
|
16
|
+
|
20
17
|
describe "phone number" do
|
21
|
-
|
22
|
-
|
23
|
-
expect { Mblox::Sms.new("2"*10, the_message) }.to_not raise_error
|
24
|
-
expect { Mblox::Sms.new("2"*11, the_message) }.to raise_error(Mblox::Sms::InvalidPhoneNumberError, "Phone number must be ten digits")
|
25
|
-
end
|
18
|
+
describe "when 9 digits" do
|
19
|
+
let(:phone_number) { '2' * 9 }
|
26
20
|
|
27
|
-
|
28
|
-
|
29
|
-
|
21
|
+
it "should raise an error" do
|
22
|
+
expect {subject}.to raise_error(Mblox::Sms::InvalidPhoneNumberError, "Phone number must be ten digits")
|
23
|
+
end
|
30
24
|
end
|
31
25
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
26
|
+
describe "when 11 digits" do
|
27
|
+
let(:phone_number) { '2' * 11 }
|
28
|
+
|
29
|
+
it "should raise an error" do
|
30
|
+
expect {subject}.to raise_error(Mblox::Sms::InvalidPhoneNumberError, "Phone number must be ten digits")
|
31
|
+
end
|
37
32
|
end
|
38
|
-
end
|
39
33
|
|
40
|
-
|
41
|
-
|
42
|
-
|
34
|
+
describe "when 10 digits" do
|
35
|
+
let(:phone_number) { '2' * 10 }
|
36
|
+
|
37
|
+
it "should not raise an error" do
|
38
|
+
expect {subject}.not_to raise_error
|
39
|
+
end
|
43
40
|
end
|
44
41
|
|
45
|
-
|
46
|
-
|
42
|
+
describe "when it starts with a 0" do
|
43
|
+
let(:phone_number) { '0' + '2' * 9 }
|
44
|
+
|
45
|
+
it "should raise an error" do
|
46
|
+
expect {subject}.to raise_error(Mblox::Sms::InvalidPhoneNumberError, "Phone number cannot begin with a \"0\"")
|
47
|
+
end
|
47
48
|
end
|
48
49
|
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
describe "when it starts with a 1" do
|
51
|
+
let(:phone_number) { '1' + '2' * 9 }
|
52
|
+
|
53
|
+
it "should raise an error" do
|
54
|
+
expect {subject}.to raise_error(Mblox::Sms::InvalidPhoneNumberError, "Phone number cannot begin with a \"1\"")
|
55
|
+
end
|
54
56
|
end
|
55
57
|
|
56
|
-
|
57
|
-
|
58
|
-
|
58
|
+
describe "when phone_number changes after instantiation" do
|
59
|
+
let(:phone_number) { super().to_s }
|
60
|
+
it "should be safe from changing" do
|
61
|
+
expect{phone_number[1..3] = ''}.not_to change{subject.phone}
|
62
|
+
end
|
59
63
|
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "message" do
|
67
|
+
let(:on_message_too_long) { :raise_error }
|
60
68
|
|
61
|
-
|
62
|
-
|
63
|
-
Mblox.config.on_message_too_long = :split
|
64
|
-
expect { @mblox = Mblox::Sms.new(LANDLINE, message) }.to_not raise_error
|
65
|
-
expect(@mblox.message).to eq(["(MSG 1/4): #{message[0,145]}", "(MSG 2/4): #{message[145,145]}", "(MSG 3/4): #{message[290,145]}", "(MSG 4/4): #{message[435,145]}"])
|
66
|
-
response = @mblox.send
|
67
|
-
expect(response.count).to eq(4)
|
68
|
-
response.each { |r| expect(r).to be_unroutable }
|
69
|
+
before(:each) do
|
70
|
+
SmsValidation.configuration.on_message_too_long = on_message_too_long
|
69
71
|
end
|
70
72
|
|
71
|
-
|
72
|
-
message
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
expect(response.count).to eq(3)
|
78
|
-
response.each { |r| expect(r).to be_unroutable }
|
73
|
+
describe "when message is blank" do
|
74
|
+
let(:message) { "" }
|
75
|
+
|
76
|
+
it "should raise an error" do
|
77
|
+
expect{subject}.to raise_error(Mblox::Sms::InvalidMessageError, "Message cannot be blank")
|
78
|
+
end
|
79
79
|
end
|
80
80
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
81
|
+
describe "when 160 characters long" do
|
82
|
+
let(:message) { ONE_HUNDRED_SIXTY_CHARACTERS }
|
83
|
+
|
84
|
+
it "sohuld not raise an error" do
|
85
|
+
expect{subject}.to_not raise_error
|
86
|
+
end
|
86
87
|
end
|
87
88
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
89
|
+
describe "when message is longer than 160 characters" do
|
90
|
+
let(:message) { "A" + ONE_HUNDRED_SIXTY_CHARACTERS }
|
91
|
+
|
92
|
+
describe "when on_message_too_long = :truncate" do
|
93
|
+
let(:on_message_too_long) { :truncate }
|
94
|
+
|
95
|
+
it "will be truncated when the message is longer than 160 characters" do
|
96
|
+
expect(subject.message).to eq(message[0,160])
|
97
|
+
end
|
98
|
+
|
99
|
+
it "should be safe from changing when long" do
|
100
|
+
expect{message[1..3] = ''}.not_to change{subject.message}
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
describe "when on_message_too_long = :raise_error" do
|
105
|
+
let(:on_message_too_long) { :raise_error }
|
106
|
+
|
107
|
+
it "cannot be longer than 160 characters" do
|
108
|
+
expect{subject}.to raise_error(Mblox::Sms::MessageTooLongError, "Message cannot be longer than 160 characters")
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
describe "when on_message_too_long = :split" do
|
113
|
+
let(:on_message_too_long) { :split }
|
114
|
+
let(:phone_number) { LANDLINE }
|
115
|
+
|
116
|
+
describe "when split is even" do
|
117
|
+
let(:message) { TEN_CHARACTERS * 58 }
|
118
|
+
|
119
|
+
it "should be split into multiple messages when longer than 160 characters" do
|
120
|
+
expect(subject.messages).to eq(["(MSG 1/4): #{message[0,145]}", "(MSG 2/4): #{message[145,145]}", "(MSG 3/4): #{message[290,145]}", "(MSG 4/4): #{message[435,145]}"])
|
121
|
+
response = subject.send
|
122
|
+
expect(response.count).to eq(4)
|
123
|
+
response.each { |r| expect(r).to be_unroutable }
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
describe "when split is not even" do
|
128
|
+
let(:message) { TEN_CHARACTERS * 32 }
|
129
|
+
|
130
|
+
it "should be split into multiple messages when longer than 160 characters" do
|
131
|
+
expect(subject.messages).to eq(["(MSG 1/3): #{message[0,145]}", "(MSG 2/3): #{message[145,145]}", "(MSG 3/3): #{message[290..-1]}"])
|
132
|
+
response = subject.send
|
133
|
+
expect(response.count).to eq(3)
|
134
|
+
response.each { |r| expect(r).to be_unroutable }
|
135
|
+
end
|
136
|
+
|
137
|
+
it "should be safe from changing when long" do
|
138
|
+
expect{message[1..3] = ''}.not_to change{subject.messages}
|
139
|
+
end
|
140
|
+
end
|
141
|
+
end
|
94
142
|
end
|
95
143
|
|
96
|
-
it "should be safe from changing when long
|
97
|
-
|
98
|
-
msg = the_message * 10
|
99
|
-
mblox = Mblox::Sms.new(TEST_NUMBER,msg)
|
100
|
-
msg[1..3] = ''
|
101
|
-
expect(mblox.message[0][0, 20]).to eq(the_message[0,20])
|
144
|
+
it "should be safe from changing when long" do
|
145
|
+
expect{message[1..3] = ''}.not_to change{subject.message}
|
102
146
|
end
|
103
147
|
end
|
104
148
|
|
105
149
|
describe "SMS messages" do
|
106
|
-
|
107
|
-
expect(response).to be_ok
|
108
|
-
expect(response).not_to be_unroutable
|
109
|
-
end
|
150
|
+
let(:response) { subject.send }
|
110
151
|
|
111
|
-
|
112
|
-
response = Mblox::Sms.new(TEST_NUMBER.to_i,the_message).send
|
152
|
+
def should_have_ok_response
|
113
153
|
expect(response.size).to eq(1)
|
114
|
-
|
154
|
+
expect(response[0]).to be_ok
|
155
|
+
expect(response[0]).not_to be_unroutable
|
115
156
|
end
|
116
157
|
|
117
|
-
|
118
|
-
response = Mblox::Sms.new(TEST_NUMBER.to_s,the_message).send
|
158
|
+
def should_have_unroutable_response
|
119
159
|
expect(response.size).to eq(1)
|
120
|
-
|
160
|
+
expect(response[0]).not_to be_ok
|
161
|
+
expect(response[0]).to be_unroutable
|
121
162
|
end
|
122
163
|
|
123
|
-
it
|
124
|
-
|
125
|
-
|
126
|
-
|
164
|
+
it { should_have_ok_response }
|
165
|
+
|
166
|
+
describe "when phone_number is a String" do
|
167
|
+
let(:phone_number) { super().to_s }
|
168
|
+
|
169
|
+
it { should_have_ok_response }
|
127
170
|
end
|
128
171
|
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
expect(response.first).not_to be_ok
|
172
|
+
describe "when message is 160 characters" do
|
173
|
+
let(:message) { ONE_HUNDRED_SIXTY_CHARACTERS }
|
174
|
+
|
175
|
+
it { should_have_ok_response }
|
134
176
|
end
|
135
177
|
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
178
|
+
describe "when sent to a landline" do
|
179
|
+
let(:phone_number) { LANDLINE }
|
180
|
+
|
181
|
+
it { should_have_unroutable_response }
|
182
|
+
|
183
|
+
described_class::LEGAL_CHARACTERS.each_char do |i|
|
184
|
+
describe "when message contains legal character '#{i}'" do
|
185
|
+
let(:message) { "#{super()}#{i}#{super()}" }
|
186
|
+
|
187
|
+
it { should_have_unroutable_response }
|
188
|
+
end
|
142
189
|
end
|
143
190
|
end
|
144
191
|
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
192
|
+
describe "when message contains legal character '\'" do
|
193
|
+
let(:message) { "#{super()}\A#{super()}" }
|
194
|
+
|
195
|
+
it { should_have_ok_response }
|
149
196
|
end
|
150
197
|
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
expect(response.first).to be_ok
|
198
|
+
describe "when all legal characters are in message" do
|
199
|
+
let(:message) { described_class::LEGAL_CHARACTERS }
|
200
|
+
it { should_have_ok_response }
|
155
201
|
end
|
156
202
|
end
|
157
203
|
|
158
204
|
describe "batch_id" do
|
159
|
-
|
160
|
-
|
205
|
+
let(:phone_number) { LANDLINE }
|
206
|
+
|
207
|
+
subject { described_class.new(phone_number, message, batch_id) }
|
208
|
+
|
209
|
+
def should_set_the_batch_id_to(expected)
|
210
|
+
expect(subject).to receive(:commit) do |arg|
|
211
|
+
expect(arg).to match(/<NotificationList BatchID=\"#{expected}\">/)
|
212
|
+
end
|
213
|
+
subject.send
|
161
214
|
end
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
215
|
+
|
216
|
+
describe "when a Fixnum" do
|
217
|
+
let(:batch_id) { 12345 }
|
218
|
+
|
219
|
+
it { should_set_the_batch_id_to(batch_id) }
|
167
220
|
end
|
168
221
|
|
169
|
-
|
170
|
-
batch_id
|
171
|
-
|
172
|
-
|
173
|
-
expect(batch_id(content)).to eq("#{batch_id}")
|
222
|
+
describe "when a String" do
|
223
|
+
let(:batch_id) { 12345.to_s }
|
224
|
+
|
225
|
+
it { should_set_the_batch_id_to(batch_id) }
|
174
226
|
end
|
175
227
|
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
228
|
+
describe "when a Float" do
|
229
|
+
let(:batch_id) { 12345.0 }
|
230
|
+
|
231
|
+
it { should_set_the_batch_id_to(batch_id.to_i) }
|
180
232
|
end
|
181
233
|
|
182
|
-
|
183
|
-
|
234
|
+
describe "when default" do
|
235
|
+
subject { described_class.new(phone_number, message) }
|
236
|
+
|
237
|
+
it { should_set_the_batch_id_to(1) }
|
238
|
+
end
|
239
|
+
|
240
|
+
describe "when the maximum allowed" do
|
241
|
+
let(:batch_id) { 99999999 }
|
242
|
+
|
243
|
+
it { should_set_the_batch_id_to(batch_id) }
|
184
244
|
end
|
185
245
|
|
186
|
-
|
187
|
-
|
246
|
+
describe "when 1 more than the maximum allowed" do
|
247
|
+
let(:batch_id) { 100000000 }
|
248
|
+
|
249
|
+
it "should raise an error" do
|
250
|
+
expect{subject}.to raise_error(Mblox::Sms::BatchIdOutOfRangeError, 'batch_id must be in the range 1 to 99999999. The batch_id specified (100000000) is out of range.')
|
251
|
+
end
|
188
252
|
end
|
189
253
|
end
|
190
254
|
|
191
255
|
describe "send from" do
|
192
|
-
|
193
|
-
@sms = Mblox::Sms.new(TEST_NUMBER,'This message should come from shortcode 55555')
|
194
|
-
end
|
256
|
+
let(:message) { "This message should come from shortcode 55555" }
|
195
257
|
|
196
258
|
describe "sender_id" do
|
197
259
|
def raise_invalid_sender_id_error
|
198
260
|
raise_error(Mblox::Sms::InvalidSenderIdError, 'You can only send from a 5-digit shortcode')
|
199
261
|
end
|
262
|
+
|
200
263
|
it "cannot be a 4-digit number" do
|
201
|
-
expect{
|
264
|
+
expect{subject .send_from(1234)}.to raise_invalid_sender_id_error
|
202
265
|
end
|
203
266
|
it "cannot be a 6-digit number" do
|
204
|
-
expect{
|
267
|
+
expect{subject .send_from(123456)}.to raise_invalid_sender_id_error
|
205
268
|
end
|
206
269
|
it "cannot be a blank string" do
|
207
|
-
expect{
|
270
|
+
expect{subject .send_from('')}.to raise_invalid_sender_id_error
|
208
271
|
end
|
209
272
|
it "cannot be a float" do
|
210
|
-
expect{
|
273
|
+
expect{subject .send_from(12345.6)}.to raise_invalid_sender_id_error
|
211
274
|
end
|
212
275
|
it "cannot be nil" do
|
213
|
-
expect{
|
276
|
+
expect{subject .send_from(nil)}.to raise_invalid_sender_id_error
|
214
277
|
end
|
215
278
|
end
|
216
279
|
|
217
280
|
describe "service_id" do
|
281
|
+
let(:sender_id) { Mblox.config.sender_id }
|
282
|
+
|
218
283
|
def raise_invalid_service_id
|
219
284
|
raise_error(Mblox::Sms::InvalidSenderIdError, "You can only send using a 5-digit service ID. Leave out the 2nd argument of send_from to use the globally configured '#{Mblox.config.service_id}'")
|
220
285
|
end
|
286
|
+
|
221
287
|
it "cannot be a 4-digit number" do
|
222
|
-
expect{
|
288
|
+
expect{subject.send_from(sender_id, 1234)}.to raise_invalid_service_id
|
223
289
|
end
|
224
290
|
it "cannot be a 6-digit number" do
|
225
|
-
expect{
|
291
|
+
expect{subject.send_from(sender_id, 123456)}.to raise_invalid_service_id
|
226
292
|
end
|
227
293
|
it "cannot be a blank string" do
|
228
|
-
expect{
|
294
|
+
expect{subject.send_from(sender_id, '')}.to raise_invalid_service_id
|
229
295
|
end
|
230
296
|
it "cannot be a float" do
|
231
|
-
expect{
|
297
|
+
expect{subject.send_from(sender_id, 12345.6)}.to raise_invalid_service_id
|
232
298
|
end
|
233
299
|
it "can be nil" do
|
234
|
-
expect{
|
300
|
+
expect{subject.send_from(sender_id, nil)}.to_not raise_error
|
235
301
|
end
|
236
302
|
end
|
237
303
|
|
238
304
|
it "should send from the specified sender_id" do
|
239
|
-
|
240
|
-
expect
|
241
|
-
|
242
|
-
|
305
|
+
subject.send_from(55555)
|
306
|
+
expect(subject).to receive(:commit) do |arg|
|
307
|
+
expect(arg).to match(/<SenderID Type=\"Shortcode\">55555<\/SenderID>/)
|
308
|
+
end
|
309
|
+
subject.send
|
243
310
|
end
|
244
311
|
|
245
312
|
it "should send from the specified sender_id and service_id" do
|
246
|
-
|
247
|
-
expect
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
expect(response.subscriber_result).to eq(Mblox::SmsResponse::Result.new(10, "MsipRejectCode=63 Invalid ServiceId:2e Do not retry:2e"))
|
253
|
-
expect(@sms.instance_variable_get("@service_id")).to eq("44444")
|
313
|
+
subject.send_from(55555, 44444)
|
314
|
+
expect(subject).to receive(:commit) do |arg|
|
315
|
+
expect(arg).to match(/<ServiceId>44444<\/ServiceId>/)
|
316
|
+
expect(arg).to match(/<SenderID Type=\"Shortcode\">55555<\/SenderID>/)
|
317
|
+
end
|
318
|
+
subject.send
|
254
319
|
end
|
255
320
|
end
|
256
321
|
end
|
data/spec/spec_helper.rb
CHANGED
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.
|
4
|
+
version: 0.6.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:
|
11
|
+
date: 2015-03-11 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -94,6 +94,20 @@ dependencies:
|
|
94
94
|
- - ">="
|
95
95
|
- !ruby/object:Gem::Version
|
96
96
|
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: sms_validation
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :runtime
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
97
111
|
- !ruby/object:Gem::Dependency
|
98
112
|
name: builder
|
99
113
|
requirement: !ruby/object:Gem::Requirement
|
@@ -131,6 +145,7 @@ extra_rdoc_files: []
|
|
131
145
|
files:
|
132
146
|
- ".gitignore"
|
133
147
|
- ".rspec"
|
148
|
+
- CHANGELOG.md
|
134
149
|
- Gemfile
|
135
150
|
- LICENSE.txt
|
136
151
|
- README.md
|
@@ -144,7 +159,6 @@ files:
|
|
144
159
|
- lib/mblox/sms_response.rb
|
145
160
|
- lib/mblox/version.rb
|
146
161
|
- mblox.gemspec
|
147
|
-
- spec/configuration_spec.rb
|
148
162
|
- spec/sms_receipt_spec.rb
|
149
163
|
- spec/sms_response_result_spec.rb
|
150
164
|
- spec/sms_response_spec.rb
|
@@ -178,9 +192,11 @@ summary: '# Mblox This gem is for subscribers to Mblox to send SMS messages. #
|
|
178
192
|
then execute: $ bundle Or install it yourself as: $ gem install mblox ## Usage Configuration Mblox.configure
|
179
193
|
do |config| # Set all of these values, provided to you in your Mblox subscription
|
180
194
|
config.outbound_url = ... config.profile_id = ... config.sender_id = ... config.password
|
181
|
-
= ... config.partner_name = ... config.tariff = ... config.service_id = ... #
|
182
|
-
can also configure some logging options
|
183
|
-
|
195
|
+
= ... config.partner_name = ... config.tariff = ... config.service_id = ... end #
|
196
|
+
You can also configure some logging options via SmsValidation, a dependency of this
|
197
|
+
gem. See https://github.com/betesh/sms_validation/blob/master/README.md for details
|
198
|
+
SmsValidation.configure do |config| # In a Rails environment, config.logger will
|
199
|
+
default to Rails.logger and config.log_at will default to :debug # config.log_at
|
184
200
|
means the level at which Mblox will log. # For instance, if config.log_at == :debug,
|
185
201
|
Mblox will log only if the logger''s log level is :debug # Note that if config.log_at
|
186
202
|
== :debug and your logger''s log level is :info, # logging will be suppressed
|
@@ -198,7 +214,6 @@ summary: '# Mblox This gem is for subscribers to Mblox to send SMS messages. #
|
|
198
214
|
your changes (`git commit -am ''Add some feature''`) 4. Push to the branch (`git
|
199
215
|
push origin my-new-feature`) 5. Create new Pull Request'
|
200
216
|
test_files:
|
201
|
-
- spec/configuration_spec.rb
|
202
217
|
- spec/sms_receipt_spec.rb
|
203
218
|
- spec/sms_response_result_spec.rb
|
204
219
|
- spec/sms_response_spec.rb
|
data/spec/configuration_spec.rb
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
require "spec_helper"
|
2
|
-
|
3
|
-
describe Mblox::Configuration do
|
4
|
-
describe "logger" do
|
5
|
-
before(:each) do
|
6
|
-
Mblox.reset_configuration
|
7
|
-
end
|
8
|
-
|
9
|
-
after(:all) do
|
10
|
-
set_configuration
|
11
|
-
end
|
12
|
-
|
13
|
-
[:fatal, :error, :warn, :info, :debug].each do |val|
|
14
|
-
it "should allow log level ':#{val}'" do
|
15
|
-
Mblox.config.log_at val
|
16
|
-
Mblox.config.logger = ::Logger.new('/dev/null')
|
17
|
-
expect { Mblox.log "Some info" }.to_not raise_error
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
it "should default to log level debug" do
|
22
|
-
expect(Mblox.config.log_level).to eq(:debug)
|
23
|
-
expect { Mblox.log "Some debug info" }.to_not raise_error
|
24
|
-
end
|
25
|
-
|
26
|
-
it "should not allow log level news when the logger is created after log level is set" do
|
27
|
-
Mblox.config.log_at :news
|
28
|
-
expect { Mblox.config.logger = ::Logger.new(STDOUT)}.to raise_error(ArgumentError, "Mblox log level must be set to :fatal, :error, :warn, :info or :debug")
|
29
|
-
expect { Mblox.log "Some news" }.to_not raise_error
|
30
|
-
end
|
31
|
-
|
32
|
-
it "should not allow log level news when the logger is created before log level is set and should remain in a valid state" do
|
33
|
-
Mblox.config.logger = ::Logger.new("/dev/null")
|
34
|
-
expect { Mblox.config.log_at :news }.to raise_error(ArgumentError, "Mblox log level must be set to :fatal, :error, :warn, :info or :debug")
|
35
|
-
expect(Mblox.config.log_level).to eq(:debug)
|
36
|
-
expect { Mblox.log "Some news" }.to_not raise_error
|
37
|
-
end
|
38
|
-
end
|
39
|
-
|
40
|
-
describe "on_message_too_long" do
|
41
|
-
it "should default to :raise_error" do
|
42
|
-
Mblox.reset_configuration
|
43
|
-
expect(Mblox.config.on_message_too_long).to eq(:raise_error)
|
44
|
-
end
|
45
|
-
|
46
|
-
[:raise_error, :split, :truncate].each do |val|
|
47
|
-
it "should allow the value ':#{val}'" do
|
48
|
-
expect { Mblox.config.on_message_too_long = val }.to_not raise_error
|
49
|
-
expect(Mblox.config.on_message_too_long).to eq(val)
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
it "should not allow other values and should remain in a valid state" do
|
54
|
-
original = Mblox.config.on_message_too_long
|
55
|
-
expect { Mblox.config.on_message_too_long = :do_nothing }.to raise_error(ArgumentError, "Mblox.config.on_message_too_long must be either :truncate, :split or :raise_error")
|
56
|
-
expect(Mblox.config.on_message_too_long).to eq(original)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|