cellular 2.1.0 → 2.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.
- checksums.yaml +4 -4
- data/.travis.yml +0 -2
- data/cellular.gemspec +5 -5
- data/lib/cellular.rb +1 -1
- data/lib/cellular/backends.rb +5 -3
- data/lib/cellular/backends/backend.rb +3 -2
- data/lib/cellular/backends/cool_sms.rb +3 -4
- data/lib/cellular/backends/link_mobility.rb +72 -0
- data/lib/cellular/backends/log.rb +1 -0
- data/lib/cellular/backends/sendega.rb +12 -13
- data/lib/cellular/backends/test.rb +1 -0
- data/lib/cellular/backends/twilio.rb +4 -4
- data/lib/cellular/configuration.rb +3 -6
- data/lib/cellular/jobs.rb +2 -1
- data/lib/cellular/jobs/async_messenger.rb +1 -0
- data/lib/cellular/logger.rb +2 -5
- data/lib/cellular/models/sms.rb +7 -5
- data/lib/cellular/version.rb +1 -1
- data/spec/cellular/backends/backend_spec.rb +19 -0
- data/spec/cellular/backends/cool_sms_spec.rb +31 -27
- data/spec/cellular/backends/link_mobility_spec.rb +118 -0
- data/spec/cellular/backends/log_spec.rb +3 -5
- data/spec/cellular/backends/log_with_rails_spec.rb +5 -7
- data/spec/cellular/backends/sendega_spec.rb +35 -37
- data/spec/cellular/backends/test_spec.rb +1 -12
- data/spec/cellular/backends/twilio_spec.rb +47 -42
- data/spec/cellular/configuration_spec.rb +1 -3
- data/spec/cellular/jobs/async_messenger_spec.rb +4 -4
- data/spec/cellular/logger_spec.rb +0 -2
- data/spec/cellular/models/sms_spec.rb +15 -15
- data/spec/cellular_spec.rb +0 -2
- data/spec/fixtures/backends/link_mobility/failure.json +1 -0
- data/spec/fixtures/backends/link_mobility/success.json +1 -0
- data/spec/spec_helper.rb +0 -2
- metadata +17 -7
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Cellular::Backends::LinkMobility do
|
4
|
+
let(:recipient) { '+15005550004' }
|
5
|
+
let(:sender) { '+15005550006' }
|
6
|
+
let(:message) { 'This is an SMS message' }
|
7
|
+
let(:partner_id) { 1234 }
|
8
|
+
|
9
|
+
let(:options) do
|
10
|
+
{
|
11
|
+
recipient: recipient,
|
12
|
+
sender: sender,
|
13
|
+
message: message,
|
14
|
+
}
|
15
|
+
end
|
16
|
+
|
17
|
+
let(:payload) do
|
18
|
+
{
|
19
|
+
source: sender,
|
20
|
+
destination: recipient,
|
21
|
+
userData: message,
|
22
|
+
platformId: 'COMMON_API',
|
23
|
+
platformPartnerId: partner_id
|
24
|
+
}.to_json
|
25
|
+
end
|
26
|
+
|
27
|
+
before do
|
28
|
+
Cellular.config.username = 'username'
|
29
|
+
Cellular.config.password = 'password'
|
30
|
+
Cellular.config.backend = Cellular::Backends::LinkMobility
|
31
|
+
Cellular.config.partner_id = 1234
|
32
|
+
end
|
33
|
+
|
34
|
+
describe '::deliver' do
|
35
|
+
before do
|
36
|
+
stub_request(:post, 'https://username:password@wsx.sp247.net/sms/send')
|
37
|
+
.to_return(
|
38
|
+
status: [200, 'OK'],
|
39
|
+
body: fixture('backends/link_mobility/success.json'),
|
40
|
+
headers: { 'Content-Type' => 'application/json' }
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'uses HTTParty to deliver an SMS' do
|
45
|
+
expect(HTTParty).to receive(:post).with(
|
46
|
+
described_class.sms_url,
|
47
|
+
body: payload,
|
48
|
+
headers: described_class::HTTP_HEADERS,
|
49
|
+
basic_auth: described_class.link_mobility_config
|
50
|
+
).and_call_original
|
51
|
+
|
52
|
+
described_class.deliver(options)
|
53
|
+
end
|
54
|
+
|
55
|
+
context 'when successful' do
|
56
|
+
it 'returns a status code and message' do
|
57
|
+
expect(described_class.deliver(options)).to eq [
|
58
|
+
'Queued'
|
59
|
+
]
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
context 'when not successful' do
|
64
|
+
before do
|
65
|
+
stub_request(:post, 'https://username:password@wsx.sp247.net/sms/send')
|
66
|
+
.to_return(
|
67
|
+
status: [403, 'FORBIDDEN'],
|
68
|
+
body: fixture('backends/link_mobility/failure.json'),
|
69
|
+
headers: { 'Content-Type' => 'application/json' }
|
70
|
+
)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'returns a status code and message' do
|
74
|
+
expect(described_class.deliver(options)).to eq [
|
75
|
+
'Unable to access SMSC credentials'
|
76
|
+
]
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
describe '::link_mobility_config' do
|
82
|
+
it 'returns the config for twilio' do
|
83
|
+
expect(described_class.link_mobility_config).to eq(
|
84
|
+
username: 'username',
|
85
|
+
password: 'password'
|
86
|
+
)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
describe '::sms_url' do
|
91
|
+
it 'returns the full sms gateway url' do
|
92
|
+
expect(described_class.sms_url).to eq(
|
93
|
+
'https://wsx.sp247.net/sms/send'
|
94
|
+
)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe '::payload' do
|
99
|
+
it 'returns the request payload' do
|
100
|
+
options[:batch] = recipient
|
101
|
+
expect(described_class.payload(options)).to eq(payload)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
describe '::recipients_batch' do
|
106
|
+
it 'wraps recipient option into an array' do
|
107
|
+
result = described_class.recipients_batch(recipient: recipient)
|
108
|
+
expect(result).to eq [recipient]
|
109
|
+
end
|
110
|
+
|
111
|
+
it 'return recipients option as-is' do
|
112
|
+
result = described_class.recipients_batch(
|
113
|
+
recipients: [recipient, recipient]
|
114
|
+
)
|
115
|
+
expect(result).to eq [recipient, recipient]
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Cellular::Backends::Log do
|
4
|
-
|
5
4
|
let(:recipient) { '47xxxxxxxx' }
|
6
5
|
let(:sender) { 'Custom sender' }
|
7
6
|
let(:message) { 'This is an SMS message' }
|
8
7
|
let(:price) { 100 }
|
9
|
-
let(:country) { 'NO '}
|
8
|
+
let(:country) { 'NO ' }
|
10
9
|
|
11
|
-
let(:options)
|
10
|
+
let(:options) do
|
12
11
|
{
|
13
12
|
recipient: recipient,
|
14
13
|
sender: sender,
|
15
14
|
message: message,
|
16
15
|
price: price
|
17
16
|
}
|
18
|
-
|
17
|
+
end
|
19
18
|
|
20
19
|
before do
|
21
20
|
Cellular.config.username = 'username'
|
@@ -39,5 +38,4 @@ describe Cellular::Backends::Log do
|
|
39
38
|
end.to raise_error NotImplementedError
|
40
39
|
end
|
41
40
|
end
|
42
|
-
|
43
41
|
end
|
@@ -1,21 +1,20 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Cellular::Backends::Log do
|
4
|
-
|
5
4
|
let(:recipient) { '47xxxxxxxx' }
|
6
5
|
let(:sender) { 'Custom sender' }
|
7
6
|
let(:message) { 'This is an SMS message' }
|
8
7
|
let(:price) { 100 }
|
9
|
-
let(:country) { 'NO '}
|
8
|
+
let(:country) { 'NO ' }
|
10
9
|
|
11
|
-
let(:options)
|
10
|
+
let(:options) do
|
12
11
|
{
|
13
12
|
recipient: recipient,
|
14
13
|
sender: sender,
|
15
14
|
message: message,
|
16
15
|
price: price
|
17
16
|
}
|
18
|
-
|
17
|
+
end
|
19
18
|
|
20
19
|
before do
|
21
20
|
# mock rails, we're pretending we're in a rails env
|
@@ -24,13 +23,13 @@ describe Cellular::Backends::Log do
|
|
24
23
|
@logger ||= Cellular::Logger.new
|
25
24
|
end
|
26
25
|
Object.const_set(:Rails, rails)
|
27
|
-
|
26
|
+
|
28
27
|
Cellular.config.username = 'username'
|
29
28
|
Cellular.config.password = 'password'
|
30
29
|
Cellular.config.delivery_url = nil
|
31
30
|
Cellular.config.logger = nil # so it will autowire
|
32
31
|
end
|
33
|
-
|
32
|
+
|
34
33
|
after do
|
35
34
|
Object.send :remove_const, :Rails
|
36
35
|
end
|
@@ -43,5 +42,4 @@ describe Cellular::Backends::Log do
|
|
43
42
|
described_class.deliver(options)
|
44
43
|
end
|
45
44
|
end
|
46
|
-
|
47
45
|
end
|
@@ -1,28 +1,29 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Cellular::Backends::Sendega do
|
4
|
-
|
5
4
|
let(:recipient) { '47xxxxxxxx' }
|
6
5
|
let(:sender) { 'Custom sender' }
|
7
6
|
let(:message) { 'This is an SMS message' }
|
8
7
|
let(:price) { 100 }
|
9
|
-
let(:country) { 'NO '}
|
10
|
-
let(:recipients) { (1..300).to_a.map!{|n| "47xxxxxxx#{n}"} }
|
11
|
-
|
8
|
+
let(:country) { 'NO ' }
|
9
|
+
let(:recipients) { (1..300).to_a.map! { |n| "47xxxxxxx#{n}" } }
|
10
|
+
|
11
|
+
let(:options) do
|
12
12
|
{
|
13
13
|
recipient: recipient,
|
14
14
|
sender: sender,
|
15
15
|
message: message,
|
16
16
|
price: price
|
17
17
|
}
|
18
|
-
|
19
|
-
|
18
|
+
end
|
19
|
+
|
20
|
+
let(:savon_options) do
|
20
21
|
{
|
21
22
|
log: false
|
22
23
|
}
|
23
|
-
|
24
|
+
end
|
24
25
|
|
25
|
-
let(:payload)
|
26
|
+
let(:payload) do
|
26
27
|
{
|
27
28
|
username: Cellular.config.username,
|
28
29
|
password: Cellular.config.password,
|
@@ -42,11 +43,11 @@ describe Cellular::Backends::Sendega do
|
|
42
43
|
pid: 0,
|
43
44
|
dcs: 0
|
44
45
|
}
|
45
|
-
|
46
|
+
end
|
46
47
|
|
47
48
|
before do
|
48
|
-
stub_request(:get, described_class::GATEWAY_URL)
|
49
|
-
to_return body: fixture('backends/sendega/service.wsdl')
|
49
|
+
stub_request(:get, described_class::GATEWAY_URL)
|
50
|
+
.to_return body: fixture('backends/sendega/service.wsdl')
|
50
51
|
|
51
52
|
Cellular.config.username = 'username'
|
52
53
|
Cellular.config.password = 'password'
|
@@ -55,10 +56,10 @@ describe Cellular::Backends::Sendega do
|
|
55
56
|
|
56
57
|
describe '::deliver' do
|
57
58
|
it 'uses Savon to deliver an SMS' do
|
58
|
-
client = double
|
59
|
+
client = double
|
59
60
|
Savon.stub(:client).and_return client
|
60
61
|
|
61
|
-
result = double(body: {send_response: {send_result: {}}})
|
62
|
+
result = double(body: { send_response: { send_result: {} } })
|
62
63
|
|
63
64
|
expect(client).to receive(:call).with(:send, message:
|
64
65
|
payload).and_return result
|
@@ -68,8 +69,8 @@ describe Cellular::Backends::Sendega do
|
|
68
69
|
|
69
70
|
context 'when successful' do
|
70
71
|
before do
|
71
|
-
stub_request(:post, 'https://smsc.sendega.com/Content.asmx')
|
72
|
-
to_return body: fixture('backends/sendega/success.xml')
|
72
|
+
stub_request(:post, 'https://smsc.sendega.com/Content.asmx')
|
73
|
+
.to_return body: fixture('backends/sendega/success.xml')
|
73
74
|
end
|
74
75
|
|
75
76
|
it 'returns a success code and a message' do
|
@@ -82,8 +83,8 @@ describe Cellular::Backends::Sendega do
|
|
82
83
|
|
83
84
|
context 'when not successful' do
|
84
85
|
before do
|
85
|
-
stub_request(:post, 'https://smsc.sendega.com/Content.asmx')
|
86
|
-
to_return body: fixture('backends/sendega/failure.xml')
|
86
|
+
stub_request(:post, 'https://smsc.sendega.com/Content.asmx')
|
87
|
+
.to_return body: fixture('backends/sendega/failure.xml')
|
87
88
|
end
|
88
89
|
|
89
90
|
it 'returns an error code and a message' do
|
@@ -104,41 +105,38 @@ describe Cellular::Backends::Sendega do
|
|
104
105
|
end
|
105
106
|
|
106
107
|
describe '::success_message' do
|
107
|
-
it '
|
108
|
-
expect(
|
109
|
-
|
110
|
-
.to eq 'Message is received and is being processed.'
|
108
|
+
it 'returns this message' do
|
109
|
+
expect(described_class.success_message)
|
110
|
+
.to eq 'Message is received and is being processed.'
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
|
115
114
|
describe '::defaults_with' do
|
116
|
-
it '
|
115
|
+
it 'returns the whole payload' do
|
117
116
|
options[:batch] = recipient
|
118
117
|
expect(described_class.defaults_with(options)).to eq(payload)
|
119
|
-
|
118
|
+
end
|
120
119
|
end
|
121
120
|
|
122
121
|
describe '::savon_config' do
|
123
|
-
it '
|
124
|
-
expect(described_class.savon_config)
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
})
|
122
|
+
it 'returns a configuration hash' do
|
123
|
+
expect(described_class.savon_config).to eq(
|
124
|
+
username: Cellular.config.username,
|
125
|
+
password: Cellular.config.password,
|
126
|
+
dlrUrl: Cellular.config.delivery_url
|
127
|
+
)
|
130
128
|
end
|
131
129
|
end
|
132
130
|
|
133
131
|
describe '::recipients_batch' do
|
134
|
-
it '
|
135
|
-
|
136
|
-
expect(
|
132
|
+
it 'splits recipients into arrays of 100 joined with commas' do
|
133
|
+
result = described_class.recipients_batch(recipients: recipients)
|
134
|
+
expect(result.length).to eq 3
|
137
135
|
end
|
138
136
|
|
139
|
-
it '
|
140
|
-
|
141
|
-
expect(
|
137
|
+
it 'puts recipient into one array' do
|
138
|
+
result = described_class.recipients_batch(receipient: recipient)
|
139
|
+
expect(result.length).to eq 1
|
142
140
|
end
|
143
141
|
end
|
144
142
|
end
|
@@ -1,21 +1,11 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Cellular::Backends::Test do
|
4
|
-
|
5
4
|
let(:recipient) { '47xxxxxxxx' }
|
6
5
|
let(:sender) { 'Custom sender' }
|
7
6
|
let(:message) { 'This is an SMS message' }
|
8
7
|
let(:price) { 100 }
|
9
|
-
let(:country) { 'NO '}
|
10
|
-
|
11
|
-
let(:options) {
|
12
|
-
{
|
13
|
-
recipient: recipient,
|
14
|
-
sender: sender,
|
15
|
-
message: message,
|
16
|
-
price: price
|
17
|
-
}
|
18
|
-
}
|
8
|
+
let(:country) { 'NO ' }
|
19
9
|
|
20
10
|
before do
|
21
11
|
Cellular.config.username = 'username'
|
@@ -49,5 +39,4 @@ describe Cellular::Backends::Test do
|
|
49
39
|
end.to raise_error NotImplementedError
|
50
40
|
end
|
51
41
|
end
|
52
|
-
|
53
42
|
end
|
@@ -1,36 +1,28 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Cellular::Backends::Twilio do
|
4
|
-
|
5
4
|
let(:recipient) { '+15005550004' }
|
6
5
|
let(:sender) { '+15005550006' }
|
7
6
|
let(:message) { 'This is an SMS message' }
|
8
7
|
let(:price) { 0.001 }
|
9
8
|
|
10
|
-
let(:options)
|
9
|
+
let(:options) do
|
11
10
|
{
|
12
11
|
recipient: recipient,
|
13
12
|
sender: sender,
|
14
13
|
message: message,
|
15
14
|
price: price
|
16
15
|
}
|
17
|
-
|
18
|
-
|
19
|
-
let(:auth) {
|
20
|
-
{
|
21
|
-
username: 'account_sid',
|
22
|
-
password: 'auth_token'
|
23
|
-
}
|
24
|
-
}
|
16
|
+
end
|
25
17
|
|
26
|
-
let(:payload)
|
18
|
+
let(:payload) do
|
27
19
|
{
|
28
20
|
From: sender,
|
29
21
|
To: recipient,
|
30
22
|
Body: message,
|
31
23
|
MaxPrice: price
|
32
24
|
}
|
33
|
-
|
25
|
+
end
|
34
26
|
|
35
27
|
before do
|
36
28
|
Cellular.config.username = 'account_sid'
|
@@ -40,62 +32,72 @@ describe Cellular::Backends::Twilio do
|
|
40
32
|
|
41
33
|
describe '::deliver' do
|
42
34
|
before do
|
43
|
-
stub_request(:post,
|
44
|
-
|
35
|
+
stub_request(:post, 'https://account_sid:auth_token@api.twilio.com/2010-04-01/Accounts/account_sid/Messages')
|
36
|
+
.to_return(
|
37
|
+
status: [201, 'CREATED'],
|
38
|
+
body: fixture('backends/twilio/success.json'),
|
39
|
+
headers: { 'Content-Type' => 'application/json' }
|
40
|
+
)
|
45
41
|
end
|
46
42
|
|
47
|
-
it '
|
48
|
-
expect(HTTParty).to receive(:post).with(
|
49
|
-
|
43
|
+
it 'uses HTTParty to deliver an SMS' do
|
44
|
+
expect(HTTParty).to receive(:post).with(
|
45
|
+
described_class.sms_url,
|
46
|
+
body: payload,
|
47
|
+
headers: described_class::HTTP_HEADERS,
|
48
|
+
basic_auth: described_class.twilio_config
|
49
|
+
).and_call_original
|
50
50
|
|
51
51
|
described_class.deliver(options)
|
52
52
|
end
|
53
53
|
|
54
54
|
context 'when successful' do
|
55
|
-
it '
|
56
|
-
expect(described_class.deliver(options)).to eq
|
55
|
+
it 'returns a status code and message' do
|
56
|
+
expect(described_class.deliver(options)).to eq [
|
57
57
|
201,
|
58
58
|
'CREATED'
|
59
|
-
]
|
59
|
+
]
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
63
|
context 'when not successful' do
|
64
64
|
before do
|
65
|
-
stub_request(:post,
|
66
|
-
to_return(
|
65
|
+
stub_request(:post, 'https://account_sid:auth_token@api.twilio.com/2010-04-01/Accounts/account_sid/Messages')
|
66
|
+
.to_return(
|
67
|
+
status: [400, 'BAD REQUEST'],
|
68
|
+
body: fixture('backends/twilio/failure.json'),
|
69
|
+
headers: { 'Content-Type' => 'application/json' }
|
70
|
+
)
|
67
71
|
end
|
68
72
|
|
69
|
-
it '
|
70
|
-
expect(described_class.deliver(options)).to eq
|
73
|
+
it 'returns a status code and message' do
|
74
|
+
expect(described_class.deliver(options)).to eq [
|
71
75
|
400,
|
72
76
|
'BAD REQUEST'
|
73
|
-
]
|
77
|
+
]
|
74
78
|
end
|
75
79
|
end
|
76
|
-
|
77
80
|
end
|
78
81
|
|
79
82
|
describe '::twilio_config' do
|
80
|
-
it '
|
83
|
+
it 'returns the config for twilio' do
|
81
84
|
expect(described_class.twilio_config).to eq(
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
})
|
85
|
+
username: 'account_sid',
|
86
|
+
password: 'auth_token'
|
87
|
+
)
|
86
88
|
end
|
87
89
|
end
|
88
90
|
|
89
91
|
describe '::sms_url' do
|
90
|
-
it '
|
92
|
+
it 'returns the full sms gateway url' do
|
91
93
|
expect(described_class.sms_url).to eq(
|
92
|
-
|
94
|
+
'https://api.twilio.com/2010-04-01/Accounts/account_sid/Messages'
|
93
95
|
)
|
94
96
|
end
|
95
97
|
end
|
96
98
|
|
97
99
|
describe '::payload' do
|
98
|
-
it '
|
100
|
+
it 'returns the request payload' do
|
99
101
|
options[:batch] = recipient
|
100
102
|
expect(described_class.payload(options)).to eq(payload)
|
101
103
|
end
|
@@ -107,7 +109,7 @@ describe Cellular::Backends::Twilio do
|
|
107
109
|
end
|
108
110
|
|
109
111
|
context 'when not successful' do
|
110
|
-
it '
|
112
|
+
it 'returns the formatted success response' do
|
111
113
|
subject.stub(:code).and_return(201)
|
112
114
|
subject.stub(:message).and_return('CREATED')
|
113
115
|
|
@@ -121,7 +123,7 @@ describe Cellular::Backends::Twilio do
|
|
121
123
|
end
|
122
124
|
|
123
125
|
context 'when not successful' do
|
124
|
-
it '
|
126
|
+
it 'returns the formatted failed response' do
|
125
127
|
subject.stub(:code).and_return(400)
|
126
128
|
subject.stub(:message).and_return('BAD REQUEST')
|
127
129
|
|
@@ -136,13 +138,16 @@ describe Cellular::Backends::Twilio do
|
|
136
138
|
end
|
137
139
|
|
138
140
|
describe '::recipients_batch' do
|
139
|
-
it '
|
140
|
-
|
141
|
-
|
141
|
+
it 'wraps recipient option into an array' do
|
142
|
+
result = described_class.recipients_batch(recipient: recipient)
|
143
|
+
expect(result).to eq [recipient]
|
142
144
|
end
|
143
|
-
|
144
|
-
|
145
|
-
|
145
|
+
|
146
|
+
it 'return recipients option as-is' do
|
147
|
+
result = described_class.recipients_batch(
|
148
|
+
recipients: [recipient, recipient]
|
149
|
+
)
|
150
|
+
expect(result).to eq [recipient, recipient]
|
146
151
|
end
|
147
152
|
end
|
148
153
|
end
|