cellular 1.0.0 → 1.1.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,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