cellular 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6797a5f2c6ccf1a9f71167bad98a54eeed77d729
4
- data.tar.gz: 03dd1fcc61fd35ab0bfebee9a40b181fe731dff5
3
+ metadata.gz: 4d69945358dbd5a90eda81aee664adfffe7a971a
4
+ data.tar.gz: d0cccde1eb19cc6d1eb8b54d2414ee21815f02f0
5
5
  SHA512:
6
- metadata.gz: 14a1c8bf8e47f83eaa088cecf5efc867b60b76c5578b7b8236ed3897821018b85dc8b726bb969556bd72648e44aab42ce12324954f0c5a260a96475eae8b192b
7
- data.tar.gz: 1554bbe7f7d214a02aa49c0de8d3c58c6155bc0738e9d79ab1d2ce088b4ae75873d51a3b992775e6cf877af96386e86f118efea8240e0022ba44d027f18ca119
6
+ metadata.gz: 1e752bde39f9752f58f4e5c09aa2eb73a431c19066324aeb69a45930b83393aa59e042e5afe8549c5c23c749bdf5d390880273b977cee25a8f0c959080cb255f
7
+ data.tar.gz: 87d001976dbefd1fc8b7bc76f6e01007ebe23e17f28ec74f0a2ac37c6d8b9fdab0de2cd5b7c623935bfb7487c11e928b4b17fe6e4c35a6d506e1f254201821b2
data/.gitignore CHANGED
@@ -1,2 +1,4 @@
1
1
  Gemfile.lock
2
+ coverage/
2
3
  pkg/
4
+ vendor/cache/
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --format documentation
2
+ --color
data/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.3
4
+ - 2.0.0
5
+ - 2.1.0
6
+ script: bundle exec rake spec
data/Guardfile ADDED
@@ -0,0 +1,6 @@
1
+ guard :rspec do
2
+ watch(%r{^spec/.+_spec\.rb$})
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+ watch(%r{^spec/support/(.+)\.rb$}) { 'spec' }
5
+ watch('spec/spec_helper.rb') { 'spec' }
6
+ end
data/README.md CHANGED
@@ -1,8 +1,14 @@
1
1
  # Cellular
2
2
 
3
+ [![Gem Version](https://badge.fury.io/rb/cellular.png)](https://rubygems.org/gems/cellular)
4
+ [![Build Status](https://secure.travis-ci.org/hyperoslo/cellular.png?branch=master)](https://travis-ci.org/hyperoslo/cellular)
5
+ [![Dependency Status](https://gemnasium.com/hyperoslo/cellular.png)](https://gemnasium.com/hyperoslo/cellular)
6
+ [![Code Climate](https://codeclimate.com/github/hyperoslo/cellular.png)](https://codeclimate.com/github/hyperoslo/cellular)
7
+ [![Coverage Status](https://coveralls.io/repos/hyperoslo/cellular/badge.png?branch=master)](https://coveralls.io/r/hyperoslo/cellular)
8
+
3
9
  Sending and receiving SMSs with Ruby through pluggable backends.
4
10
 
5
- **Supported Ruby versions: 1.9 or higher**
11
+ **Supported Ruby versions: 1.9.3 or higher**
6
12
 
7
13
  Licensed under the **MIT** license, see LICENSE for more information.
8
14
 
@@ -24,7 +30,37 @@ Or install it yourself as:
24
30
 
25
31
  ## Usage
26
32
 
27
- Usage instructions to follow shortly.
33
+ ### Configuration
34
+
35
+ ```ruby
36
+ Cellular.configure do |config|
37
+ config.username = 'username'
38
+ config.password = 'password'
39
+ config.backend = Cellular::Backends::Sendega
40
+ end
41
+ ```
42
+
43
+
44
+ ### Available Backends
45
+
46
+ * CoolSMS (http://coolsms.com/)
47
+ * Sendega (http://sendega.com/)
48
+
49
+
50
+ ### Sending SMSs
51
+
52
+ The options supported may differ between backends.
53
+
54
+ ```ruby
55
+ sms = Cellular::SMS.new(
56
+ recipient: '47xxxxxxxx',
57
+ sender: 'Custom sender',
58
+ country: 'NO',
59
+ message: 'This is an SMS message'
60
+ )
61
+
62
+ sms.deliver
63
+ ```
28
64
 
29
65
 
30
66
  ## Contributing
@@ -33,4 +69,4 @@ Usage instructions to follow shortly.
33
69
  2. Create your feature branch (`git checkout -b my-new-feature`)
34
70
  3. Commit your changes (`git commit -am 'Add some feature'`)
35
71
  4. Push to the branch (`git push origin my-new-feature`)
36
- 5. Create pull Request
72
+ 5. Create pull request
data/Rakefile CHANGED
@@ -1 +1,9 @@
1
1
  require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec) do |spec|
5
+ spec.pattern = 'spec/**/*_spec.rb'
6
+ end
7
+
8
+ task test: :spec
9
+ task default: :spec
data/cellular.gemspec CHANGED
@@ -19,7 +19,16 @@ Gem::Specification.new do |gem|
19
19
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
20
20
  gem.require_paths = ['lib']
21
21
 
22
- gem.add_dependency 'savon'
22
+ gem.add_dependency 'httparty', '~> 0.13.0'
23
+ gem.add_dependency 'savon', '~> 2.0'
23
24
 
24
25
  gem.add_development_dependency 'pry'
26
+
27
+ gem.add_development_dependency 'guard'
28
+ gem.add_development_dependency 'guard-rspec'
29
+ gem.add_development_dependency 'rake'
30
+ gem.add_development_dependency 'webmock'
31
+
32
+ gem.add_development_dependency 'coveralls'
33
+ gem.add_development_dependency 'simplecov'
25
34
  end
@@ -1,5 +1,6 @@
1
1
  module Cellular
2
2
  module Backends
3
+ autoload :CoolSMS, 'cellular/backends/cool_sms'
3
4
  autoload :Sendega, 'cellular/backends/sendega'
4
5
  end
5
6
  end
@@ -0,0 +1,33 @@
1
+ require 'httparty'
2
+
3
+ module Cellular
4
+ module Backends
5
+ class CoolSMS
6
+
7
+ # Documentation: http://www.coolsms.com/support/dokumentation/http-gateway.sms
8
+ GATEWAY_URL = 'https://sms.coolsmsc.dk/'
9
+
10
+ def self.deliver(options = {})
11
+ query = {
12
+ username: Cellular.config.username,
13
+ password: Cellular.config.password,
14
+ from: options[:sender],
15
+ to: options[:recipient],
16
+ message: options[:message],
17
+ charset: 'utf-8',
18
+ resulttype: 'xml',
19
+ lang: 'en'
20
+ }
21
+
22
+ result = HTTParty.get(GATEWAY_URL, query: query)
23
+ response = result.parsed_response['smsc']
24
+
25
+ [
26
+ response['status'],
27
+ response['result'] || response['message']['result']
28
+ ]
29
+ end
30
+
31
+ end
32
+ end
33
+ end
@@ -6,7 +6,7 @@ module Cellular
6
6
 
7
7
  GATEWAY_URL = 'https://smsc.sendega.com/Content.asmx?WSDL'
8
8
 
9
- def self.deliver(options = {})
9
+ def self.deliver(options = {}, savon_options = {})
10
10
  # Send an SMS and return its initial delivery status code.
11
11
  #
12
12
  # Delivery status codes:
@@ -34,7 +34,9 @@ module Cellular
34
34
  # See Gate API Documentation:
35
35
  # http://www.sendega.no/downloads/Sendega%20API%20documentation%20v2.0.pdf
36
36
 
37
- client = Savon.client wsdl: GATEWAY_URL
37
+ savon_options[:wsdl] = GATEWAY_URL
38
+
39
+ client = Savon.client savon_options
38
40
 
39
41
  result = client.call(:send, message: {
40
42
  username: Cellular.config.username,
@@ -43,13 +45,13 @@ module Cellular
43
45
  destination: options[:recipient],
44
46
  pricegroup: options[:price] || 0, # default price to 0
45
47
  contentTypeID: 1,
46
- contentHeader: "",
48
+ contentHeader: '',
47
49
  content: options[:message],
48
50
  dlrUrl: Cellular.config.delivery_url,
49
51
  ageLimit: 0,
50
- extID: "",
51
- sendDate: "",
52
- refID: "",
52
+ extID: '',
53
+ sendDate: '',
54
+ refID: '',
53
55
  priority: 0,
54
56
  gwID: 0,
55
57
  pid: 0,
@@ -57,10 +59,18 @@ module Cellular
57
59
  }
58
60
  )
59
61
 
60
- if result.success?
61
- [ result.body[:error_number], 'Message is received and is being processed.' ]
62
+ body = result.body[:send_response][:send_result]
63
+
64
+ if body[:success]
65
+ [
66
+ body[:error_number].to_i,
67
+ 'Message is received and is being processed.'
68
+ ]
62
69
  else
63
- [ result.body[:error_number], result.body[:error_message] ]
70
+ [
71
+ body[:error_number].to_i,
72
+ body[:error_message]
73
+ ]
64
74
  end
65
75
  end
66
76
 
@@ -27,11 +27,11 @@ module Cellular
27
27
  @delivered = true
28
28
  end
29
29
 
30
- def save(options)
30
+ def save(options = {})
31
31
  raise NotImplementedError
32
32
  end
33
33
 
34
- def receive(options)
34
+ def receive(options = {})
35
35
  raise NotImplementedError
36
36
  end
37
37
 
@@ -1,3 +1,3 @@
1
1
  module Cellular
2
- VERSION = '1.0.0'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -0,0 +1,67 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cellular::Backends::CoolSMS do
4
+
5
+ let(:recipient) { '47xxxxxxxx' }
6
+ let(:sender) { 'Custom sender' }
7
+ let(:message) { 'This is an SMS message' }
8
+
9
+ let(:options) {
10
+ {
11
+ recipient: recipient,
12
+ sender: sender,
13
+ message: message
14
+ }
15
+ }
16
+
17
+ before do
18
+ Cellular.config.username = 'username'
19
+ Cellular.config.password = 'password'
20
+ end
21
+
22
+ describe '::deliver' do
23
+ before do
24
+ stub_request(:get, 'https://sms.coolsmsc.dk/?charset=utf-8&from=Custom%20sender&lang=en&message=This%20is%20an%20SMS%20message&password=password&resulttype=xml&to=47xxxxxxxx&username=username').
25
+ to_return headers: { 'Content-Type' => 'text/xml' }, body: fixture('backends/cool_sms/success.xml')
26
+ end
27
+
28
+ it 'uses HTTParty to deliver an SMS' do
29
+ expect(HTTParty).to receive(:get).with(described_class::GATEWAY_URL, query: {
30
+ username: 'username',
31
+ password: 'password',
32
+ from: sender,
33
+ to: recipient,
34
+ message: message,
35
+ charset: 'utf-8',
36
+ resulttype: 'xml',
37
+ lang: 'en'
38
+ }).and_call_original
39
+
40
+ described_class.deliver(options)
41
+ end
42
+
43
+ context 'when successful' do
44
+ it 'returns success and a message' do
45
+ expect(described_class.deliver(options)).to eq [
46
+ 'success',
47
+ 'The message was sent correctly.'
48
+ ]
49
+ end
50
+ end
51
+
52
+ context 'when not successful' do
53
+ before do
54
+ stub_request(:get, 'https://sms.coolsmsc.dk/?charset=utf-8&from=Custom%20sender&lang=en&message=This%20is%20an%20SMS%20message&password=password&resulttype=xml&to=47xxxxxxxx&username=username').
55
+ to_return headers: { 'Content-Type' => 'text/xml' }, body: fixture('backends/cool_sms/failure.xml')
56
+ end
57
+
58
+ it 'returns failure and a message' do
59
+ expect(described_class.deliver(options)).to eq [
60
+ 'failure',
61
+ 'Access denied.'
62
+ ]
63
+ end
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,101 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cellular::Backends::Sendega do
4
+
5
+ let(:recipient) { '47xxxxxxxx' }
6
+ let(:sender) { 'Custom sender' }
7
+ let(:message) { 'This is an SMS message' }
8
+ 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
+ }
19
+ let(:savon_options) {
20
+ {
21
+ log: false
22
+ }
23
+ }
24
+
25
+ before do
26
+ stub_request(:get, described_class::GATEWAY_URL).
27
+ to_return body: fixture('backends/sendega/service.wsdl')
28
+
29
+ Cellular.config.username = 'username'
30
+ Cellular.config.password = 'password'
31
+ Cellular.config.delivery_url = nil
32
+ end
33
+
34
+ describe '::deliver' do
35
+ it 'uses Savon to deliver an SMS' do
36
+ client = double()
37
+ Savon.stub(:client).and_return client
38
+
39
+ result = double(body: {send_response: {send_result: {}}})
40
+
41
+ expect(client).to receive(:call).with(:send, message: {
42
+ username: Cellular.config.username,
43
+ password: Cellular.config.password,
44
+ sender: sender,
45
+ destination: recipient,
46
+ pricegroup: price,
47
+ contentTypeID: 1,
48
+ contentHeader: '',
49
+ content: message,
50
+ dlrUrl: nil,
51
+ ageLimit: 0,
52
+ extID: '',
53
+ sendDate: '',
54
+ refID: '',
55
+ priority: 0,
56
+ gwID: 0,
57
+ pid: 0,
58
+ dcs: 0
59
+ }).and_return result
60
+
61
+ described_class.deliver(options, savon_options)
62
+ end
63
+
64
+ context 'when successful' do
65
+ before do
66
+ stub_request(:post, 'https://smsc.sendega.com/Content.asmx').
67
+ to_return body: fixture('backends/sendega/success.xml')
68
+ end
69
+
70
+ it 'returns a success code and a message' do
71
+ expect(described_class.deliver(options, savon_options)).to eq [
72
+ 0,
73
+ 'Message is received and is being processed.'
74
+ ]
75
+ end
76
+ end
77
+
78
+ context 'when not successful' do
79
+ before do
80
+ stub_request(:post, 'https://smsc.sendega.com/Content.asmx').
81
+ to_return body: fixture('backends/sendega/failure.xml')
82
+ end
83
+
84
+ it 'returns an error code and a message' do
85
+ expect(described_class.deliver(options, savon_options)).to eq [
86
+ 9001,
87
+ 'Not validated - Username and password does not match (e)'
88
+ ]
89
+ end
90
+ end
91
+ end
92
+
93
+ describe '::receive' do
94
+ it 'has not been implemented yet' do
95
+ expect do
96
+ described_class.receive ''
97
+ end.to raise_error NotImplementedError
98
+ end
99
+ end
100
+
101
+ end
@@ -0,0 +1,14 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cellular::Configuration do
4
+
5
+ it { should respond_to :username= }
6
+ it { should respond_to :username }
7
+ it { should respond_to :password= }
8
+ it { should respond_to :password }
9
+ it { should respond_to :delivery_url= }
10
+ it { should respond_to :delivery_url }
11
+ it { should respond_to :backend= }
12
+ it { should respond_to :backend }
13
+
14
+ end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ describe Cellular::SMS do
4
+
5
+ let(:recipient) { '47xxxxxxxx' }
6
+ let(:sender) { 'Custom sender' }
7
+ let(:message) { 'This is an SMS message' }
8
+ let(:price) { 100 }
9
+ let(:country) { 'NO '}
10
+
11
+ subject do
12
+ described_class.new(
13
+ recipient: recipient,
14
+ sender: sender,
15
+ message: message,
16
+ price: price,
17
+ country: country
18
+ )
19
+ end
20
+
21
+ before do
22
+ Cellular.config.backend = Cellular::Backends::Sendega
23
+ end
24
+
25
+ describe '#initialize' do
26
+ its(:recipient) { should eq recipient }
27
+ its(:sender) { should eq sender }
28
+ its(:message) { should eq message }
29
+ its(:price) { should eq price }
30
+ its(:country) { should eq country }
31
+
32
+ it { should_not be_delivered }
33
+ end
34
+
35
+ describe '#deliver' do
36
+ before do
37
+ expect(Cellular::Backends::Sendega).to receive(:deliver).with(
38
+ recipient: recipient,
39
+ sender: sender,
40
+ price: price,
41
+ country: country,
42
+ message: message
43
+ )
44
+ end
45
+
46
+ it 'uses configured backend and marks SMS as delivered' do
47
+ subject.deliver
48
+ expect(subject).to be_delivered
49
+ end
50
+ end
51
+
52
+ describe '#save' do
53
+ it 'has not been implemented yet' do
54
+ expect do
55
+ subject.save
56
+ end.to raise_error NotImplementedError
57
+ end
58
+ end
59
+
60
+ describe '#receive' do
61
+ it 'has not been implemented yet' do
62
+ expect do
63
+ subject.receive
64
+ end.to raise_error NotImplementedError
65
+ end
66
+ end
67
+
68
+ end