cellular 2.1.0 → 2.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|