locasms 0.1.7 → 0.5.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.
@@ -1,5 +1,6 @@
1
- module LocaSMS
1
+ # frozen_string_literal: true
2
2
 
3
+ module LocaSMS
3
4
  # Class that sanitizes and validates a list of mobile's numbers
4
5
  class Numbers
5
6
  attr_reader :good, :bad
@@ -9,15 +10,16 @@ module LocaSMS
9
10
  # @see #normalize
10
11
  # @see #evaluate
11
12
  def initialize(*numbers)
12
- evaluated = evaluate(numbers)
13
- @good, @bad = evaluated[:good], evaluated[:bad]
13
+ evaluated = evaluate(numbers)
14
+ @good = evaluated[:good]
15
+ @bad = evaluated[:bad]
14
16
  end
15
17
 
16
18
  # Checks if there are bad numbers
17
19
  # @return [TrueClass, FalseClass] true if there are bad numbers
18
20
  # @see #valid_number?
19
21
  def bad?
20
- not bad.empty?
22
+ !bad.empty?
21
23
  end
22
24
 
23
25
  # Clears all non digits from a mobile's number and converts into a normalized array
@@ -34,17 +36,19 @@ module LocaSMS
34
36
  # numbers.normalize '8888-9999', ['AA', '6666-9999', '7777-0000'], '3333-4444,555-9999'
35
37
  # # => ['88889999','AA','66669999','77770000','33334444','5559999']
36
38
  def normalize(*numbers)
37
- numbers = numbers.join(',')
39
+ numbers
40
+ .join(',')
38
41
  .split(',')
39
- .map{|number| number.gsub(/[^0-9a-zA-Z]/, '') }
40
- .delete_if{|number| number.empty? }
42
+ .map { |number| number.gsub(/[^0-9a-zA-Z]/, '') }
43
+ .delete_if(&:empty?)
41
44
  end
42
45
 
43
46
  # Validates if a mobile's number has only digits
44
47
  # @param [String] number given number to be validated
45
48
  # @return [TrueClass, FalseClass] true if the number is valid
46
49
  def valid_number?(number)
47
- return false if number.nil? or number =~ /[^0-9a-zA-Z]/
50
+ return false if number.nil? || number =~ (/[^0-9a-zA-Z]/)
51
+
48
52
  [10, 11].include? number.size
49
53
  end
50
54
 
@@ -63,10 +67,9 @@ module LocaSMS
63
67
  # Numbers.new.evaluate('4199998888','11777770000','5551212')
64
68
  # #=> {good: ['4199998888','11777770000'], bad: ['5551212']}
65
69
  def evaluate(*numbers)
66
- normalize(numbers).reduce({good: [], bad: []}) do |hash, number|
70
+ normalize(numbers).each_with_object({ good: [], bad: [] }) do |number, hash|
67
71
  bucket = valid_number?(number) ? :good : :bad
68
72
  hash[bucket] << number
69
- hash
70
73
  end
71
74
  end
72
75
 
@@ -76,5 +79,4 @@ module LocaSMS
76
79
  (good || []).join(',')
77
80
  end
78
81
  end
79
-
80
- end
82
+ end
@@ -1,16 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
4
+ require 'net/http'
2
5
 
3
6
  module LocaSMS
4
-
5
7
  # Class that handle http calls to LocaSMS api
6
- # @see https://github.com/mcorp/locasms/wiki/A-API-de-envio List of avaiable services
8
+ # @see https://github.com/mcorp/locasms/wiki/A-API-de-envio
9
+ # List of avaiable services
7
10
  class RestClient
8
11
  attr_accessor :base_url, :base_params
9
12
 
10
13
  # Creates a new instance of the RestClient class
11
14
  # @param [String] base_url a well formed url
12
15
  # @param [Hash] base_params base params to send on every call
13
- def initialize(base_url, base_params={})
16
+ def initialize(base_url, base_params = {})
14
17
  @base_url = base_url
15
18
  @base_params = base_params
16
19
  end
@@ -34,12 +37,17 @@ module LocaSMS
34
37
  # client.get :holdsms, id: 345678
35
38
  # # => {"status"=>1,"data"=>nil,"msg"=>"SUCESSO"}
36
39
  #
37
- # @see https://github.com/mcorp/locasms/wiki/A-API-de-envio#lista-das-a%C3%A7%C3%B5es-dispon%C3%ADveis List of avaiable actions
40
+ # @see https://github.com/mcorp/locasms/wiki/A-API-de-envio#lista-das-a%C3%A7%C3%B5es-dispon%C3%ADveis
41
+ # List of avaiable actions
38
42
  # @raise [LocaSMS::InvalidOperation] when asked for an invalid operation
39
43
  # @raise [LocaSMS::InvalidLogin] when the given credentials are invalid
40
- def get(action, params={})
41
- params = params_for action, params
42
- response = ::RestClient.get base_url, params: params
44
+ def get(action, params = {})
45
+ params = params_for action, params
46
+
47
+ uri = URI.parse(base_url)
48
+ uri.query = URI.encode_www_form(params)
49
+ response = Net::HTTP.get_response(uri).body
50
+
43
51
  parse_response(action, response)
44
52
  end
45
53
 
@@ -54,9 +62,10 @@ module LocaSMS
54
62
  # client.params_for :ACTION, a: 1, b: 2
55
63
  # # => { action: :ACTION, lgn: 'LOGIN', pwd: 'PASSWORD', a: 1, b: 2 }
56
64
  #
57
- # @see https://github.com/mcorp/locasms/wiki/A-API-de-envio#lista-das-a%C3%A7%C3%B5es-dispon%C3%ADveis List of avaiable actions
58
- def params_for(action, params={})
59
- {action: action}.merge(base_params).merge(params)
65
+ # @see https://github.com/mcorp/locasms/wiki/A-API-de-envio#lista-das-a%C3%A7%C3%B5es-dispon%C3%ADveis
66
+ # List of avaiable actions
67
+ def params_for(action, params = {})
68
+ { action: action }.merge(base_params).merge(params).select { |_k, v| v }
60
69
  end
61
70
 
62
71
  # Parses a result trying to get it in json
@@ -68,13 +77,17 @@ module LocaSMS
68
77
  def parse_response(action, response)
69
78
  raise InvalidOperation.new(action: action) if response =~ /^0:OPERACAO INVALIDA$/i
70
79
 
71
- j = JSON.parse(response) rescue { 'status' => 1, 'data' => response, 'msg' => nil }
80
+ j = begin
81
+ MultiJson.load(response)
82
+ rescue StandardError
83
+ { 'status' => 1, 'data' => response, 'msg' => nil }
84
+ end
72
85
 
73
- return j if j['status'] == 1 or action == :getstatus
86
+ return j if (j['status'] == 1) || (action == :getstatus)
74
87
 
75
88
  raise InvalidLogin.new(action: action) if j['msg'] =~ /^falha ao realizar login$/i
76
- raise Exception.new(message: j['msg'], raw: response, action: action)
89
+
90
+ raise LocaSMS::Exception.new(message: j['msg'], raw: response, action: action)
77
91
  end
78
92
  end
79
-
80
- end
93
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module LocaSMS
2
- VERSION = '0.1.7'
4
+ VERSION = '0.5.0'
3
5
  end
@@ -1,42 +1,44 @@
1
- # coding: utf-8
2
- lib = File.expand_path('../lib', __FILE__)
1
+ # frozen_string_literal: true
2
+
3
+ lib = File.expand_path('lib', __dir__)
3
4
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
5
  require 'locasms/version'
5
6
 
6
7
  Gem::Specification.new do |spec|
7
- spec.name = "locasms"
8
+ spec.name = 'locasms'
8
9
  spec.version = LocaSMS::VERSION
9
- spec.authors = ["Adilson Carvalho", "Leonardo Saraiva", "Marco Carvalho"]
10
- spec.email = ["lc.adilson@gmail.com", "vyper@maneh.org", "marco.carvalho.swasthya@gmail.com"]
11
- spec.description = %q{Cliente para o serviço de disparo de SMS da LocaSMS}
12
- spec.summary = %q{Cliente para o serviço de disparo de SMS da LocaSMS}
13
- spec.homepage = "https://github.com/mcorp/locasms"
14
- spec.license = "MIT"
15
-
16
- spec.files = `git ls-files`.split($/)
10
+ spec.authors = ['Adilson Carvalho', 'Leonardo Saraiva', 'Marco Carvalho']
11
+ spec.email = ['lc.adilson@gmail.com', 'vyper@maneh.org', 'marco.carvalho.swasthya@gmail.com']
12
+ spec.description = 'Cliente para o serviço de disparo de SMS da LocaSMS e de sua
13
+ versão para Short Code SMS (SMS Plataforma)'
14
+ spec.summary = 'Cliente para disparo de SMS, regular e Short Code, através da LocaSMS/SMS Plataforma'
15
+ spec.homepage = 'https://github.com/mcorp/locasms'
16
+ spec.license = 'MIT'
17
+
18
+ spec.files = `git ls-files`.split($INPUT_RECORD_SEPARATOR)
17
19
  spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
20
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
- spec.require_paths = ["lib"]
21
+ spec.require_paths = ['lib']
20
22
 
21
- spec.add_development_dependency 'bundler', '~> 1.3'
22
- spec.add_development_dependency 'rake', '~> 10.4.2'
23
+ spec.required_ruby_version = '~> 2.4'
23
24
 
24
- # test stuff
25
- spec.add_development_dependency 'rspec', '~> 3.2'
26
- spec.add_development_dependency 'fuubar', '~> 2.0.0'
27
- spec.add_development_dependency 'timecop', '~> 0.7.3'
25
+ spec.add_dependency 'multi_json', '~> 1.13'
28
26
 
29
- # run tests automatically
30
- spec.add_development_dependency 'guard'
31
- spec.add_development_dependency 'guard-rspec'
32
- spec.add_development_dependency 'growl'
27
+ spec.add_development_dependency 'bundler'
28
+ spec.add_development_dependency 'rake', '~> 13.0'
29
+
30
+ # test stuff
31
+ spec.add_development_dependency 'rspec', '~> 3.9'
32
+ spec.add_development_dependency 'timecop', '~> 0.9'
33
33
 
34
34
  # for documentation
35
- spec.add_development_dependency 'yard'
36
- spec.add_development_dependency 'redcarpet'
35
+ spec.add_development_dependency 'redcarpet', '~> 3.5'
36
+ spec.add_development_dependency 'yard', '~> 0.9'
37
37
 
38
38
  # for code coverage
39
- spec.add_development_dependency 'simplecov'
39
+ spec.add_development_dependency 'simplecov', '~> 0.18'
40
40
 
41
- spec.add_dependency 'rest-client', '~> 1.6'
41
+ # for code quality
42
+ spec.add_development_dependency 'rubocop', '~> 0.93'
43
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.43'
42
44
  end
@@ -1,140 +1,148 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'spec_helper'
2
4
 
3
- describe LocaSMS::Client do
4
- let(:rest_client) { 'rest_client mock' }
5
- subject { LocaSMS::Client.new :login, :password, rest_client: rest_client }
5
+ describe LocaSMS::Client do # rubocop:disable RSpec/FilePath
6
+ subject(:client) { described_class.new :login, :password, rest_client: rest_client, callback: nil }
6
7
 
7
- context '.ENDPOINT' do
8
- def test_when(moment_in_time)
9
- Timecop.freeze(Time.parse(moment_in_time)) do
10
- LocaSMS.send :remove_const, :Client
11
- load 'lib/locasms/client.rb'
12
- yield
13
- end
14
- end
8
+ let(:rest_client) { instance_double 'RestClient' }
9
+ let(:base_args) { { msg: 'given message', numbers: '11988889991,11988889992,11988889993' } }
10
+ let(:default_callback_args) { base_args.merge(url_callback: 'default') }
11
+ let(:some_callback_args) { base_args.merge(url_callback: 'something') }
15
12
 
16
- it 'prior to Jun 1st, 2015' do
17
- test_when('2015-05-31T23:59:59-0300') do
18
- expect(LocaSMS::Client::ENDPOINT).to(
19
- eq('http://173.44.33.18/painel/api.ashx')
20
- )
13
+ describe '::ENDPOINT' do
14
+ let(:domain) { described_class::DOMAIN }
15
+
16
+ context 'when default' do
17
+ it 'returns the default URL' do
18
+ endpoint = described_class::ENDPOINT[client.type]
19
+ expect(endpoint).to eq("http://#{domain}/painel/api.ashx")
21
20
  end
22
21
  end
23
22
 
24
- it 'is Jun 1st, 2015' do
25
- test_when('2015-06-01T00:00:00-0300') do
26
- expect(LocaSMS::Client::ENDPOINT).to(
27
- eq('http://209.133.196.250/painel/api.ashx')
28
- )
23
+ context 'when shortcode' do
24
+ subject(:client) { described_class.new :login, :password, type: :shortcode }
25
+
26
+ it 'returns the short code URL' do
27
+ endpoint = described_class::ENDPOINT[client.type]
28
+ expect(endpoint).to eq("http://#{domain}/shortcode/api.ashx")
29
29
  end
30
30
  end
31
+ end
31
32
 
32
- it 'after Jun 1st, 2015 and prior to March 29, 2016' do
33
- test_when('2016-03-28T00:00:00-0300') do
34
- expect(LocaSMS::Client::ENDPOINT).to(
35
- eq('http://209.133.196.250/painel/api.ashx')
36
- )
37
- end
33
+ describe '.initialize' do
34
+ it { expect(client.login).to be(:login) }
35
+ it { expect(client.password).to be(:password) }
36
+ end
37
+
38
+ describe '#deliver' do
39
+ it 'sends SMS' do
40
+ allow(rest_client).to receive(:get).and_return({})
41
+
42
+ client.deliver 'given message', '11988889991', '11988889992', '11988889993'
43
+
44
+ expect(rest_client).to have_received(:get).once.with(:sendsms, base_args.merge(url_callback: nil))
38
45
  end
39
46
 
40
- it 'is March 29, 2016' do
41
- test_when('2016-03-29T00:00:00-0300') do
42
- expect(LocaSMS::Client::ENDPOINT).to(
43
- eq('http://54.173.24.177/painel/api.ashx')
44
- )
47
+ context 'when receive an error' do
48
+ let(:wrong_deliver) { -> { client.deliver('given message', '1', '2', '3') } }
49
+
50
+ it { expect(wrong_deliver).to raise_error(LocaSMS::Exception) }
51
+
52
+ it 'does not send SMS' do
53
+ allow(rest_client).to receive(:get)
54
+
55
+ wrong_deliver
56
+
57
+ expect(rest_client).not_to have_received(:get)
45
58
  end
46
59
  end
47
60
 
48
- it 'after March 29, 2016' do
49
- test_when('2017-01-01T00:00:00-0300') do
50
- expect(LocaSMS::Client::ENDPOINT).to(
51
- eq('http://54.173.24.177/painel/api.ashx')
52
- )
61
+ context 'when callback given as arg to #deliver' do
62
+ it 'uses specific callback' do
63
+ allow(rest_client).to receive(:get).and_return({})
64
+
65
+ client.deliver 'given message', '11988889991', '11988889992', '11988889993', url_callback: 'something'
66
+
67
+ expect(rest_client).to have_received(:get).once.with(:sendsms, some_callback_args)
53
68
  end
54
69
  end
55
- end
56
70
 
57
- describe '.initialize' do
58
- it { expect(subject.login).to be(:login) }
59
- it { expect(subject.password).to be(:password) }
71
+ it 'uses default callback' do
72
+ client = described_class.new :login, :password, rest_client: rest_client, url_callback: 'default'
73
+
74
+ allow(rest_client).to receive(:get).and_return({})
75
+
76
+ client.deliver 'given message', '11988889991', '11988889992', '11988889993'
77
+
78
+ expect(rest_client).to have_received(:get).once.with(:sendsms, default_callback_args)
79
+ end
60
80
  end
61
81
 
62
- describe '#deliver' do
63
- it 'Should send SMS' do
64
- expect(subject).to receive(:numbers)
65
- .once
66
- .with([:a, :b, :c])
67
- .and_return('XXX')
68
-
69
- expect(rest_client).to receive(:get)
70
- .once
71
- .with(:sendsms, msg: 'given message', numbers:'XXX')
72
- .and_return({})
73
-
74
- subject.deliver 'given message', :a, :b, :c
82
+ describe '#deliver_at' do
83
+ let(:base_args) do
84
+ {
85
+ msg: 'given message',
86
+ numbers: '11988889991,11988889992,11988889993',
87
+ jobdate: '10/10/2020',
88
+ jobtime: '10:10'
89
+ }
75
90
  end
76
91
 
77
- it 'Should not send SMS' do
78
- expect(subject).to receive(:numbers)
79
- .once
80
- .with([:a, :b, :c])
81
- .and_raise(LocaSMS::Exception)
92
+ it 'sends SMS' do
93
+ allow(rest_client).to receive(:get).and_return({})
82
94
 
83
- expect(rest_client).to receive(:get).never
95
+ client.deliver_at 'given message', '2020-10-10 10:10', '11988889991', '11988889992', '11988889993'
84
96
 
85
- expect { subject.deliver('given message', :a, :b, :c) }.to raise_error(LocaSMS::Exception)
97
+ expect(rest_client).to have_received(:get).once.with(:sendsms, base_args.merge(url_callback: nil))
86
98
  end
87
- end
88
99
 
89
- describe '#deliver_at' do
90
- it 'Should send SMS' do
91
- expect(subject).to receive(:numbers)
92
- .once
93
- .with([:a, :b, :c])
94
- .and_return('XXX')
95
-
96
- expect(LocaSMS::Helpers::DateTimeHelper).to receive(:split)
97
- .once
98
- .with(:datetime)
99
- .and_return(%w[date time])
100
-
101
- expect(rest_client).to receive(:get)
102
- .once
103
- .with(:sendsms, msg: 'given message', numbers:'XXX', jobdate: 'date', jobtime: 'time')
104
- .and_return({})
105
-
106
- subject.deliver_at 'given message', :datetime, :a, :b, :c
100
+ context 'when receive an error' do
101
+ let(:wrong_deliver_at) { -> { client.deliver_at('given message', '2020-10-10 10:10', '1', '2', '3') } }
102
+
103
+ it { expect(wrong_deliver_at).to raise_error(LocaSMS::Exception) }
104
+
105
+ it 'does not send SMS' do
106
+ allow(rest_client).to receive(:get)
107
+
108
+ wrong_deliver_at
109
+
110
+ expect(rest_client).not_to have_received(:get)
111
+ end
107
112
  end
108
113
 
109
- it 'Should not send SMS' do
110
- expect(subject).to receive(:numbers)
111
- .once
112
- .with([:a, :b, :c])
113
- .and_raise(LocaSMS::Exception)
114
+ context 'with callback option' do
115
+ it 'when callback given as arg to #deliver' do
116
+ allow(rest_client).to receive(:get).and_return({})
117
+
118
+ client.deliver_at 'given message', '2020-10-10 10:10', '11988889991', '11988889992', '11988889993', url_callback: 'something'
119
+
120
+ expect(rest_client).to have_received(:get).once.with(:sendsms, some_callback_args)
121
+ end
122
+
123
+ it 'uses default callback' do
124
+ client = described_class.new :login, :password, rest_client: rest_client, url_callback: 'default'
114
125
 
115
- expect(LocaSMS::Helpers::DateTimeHelper).to receive(:split)
116
- .once
117
- .with(:datetime)
118
- .and_return(%w[date time])
126
+ allow(rest_client).to receive(:get).and_return({})
119
127
 
120
- expect(rest_client).to receive(:get).never
128
+ client.deliver_at 'given message', '2020-10-10 10:10', '11988889991', '11988889992', '11988889993'
121
129
 
122
- expect { subject.deliver_at('given message', :datetime, :a, :b, :c) }.to raise_error(LocaSMS::Exception)
130
+ expect(rest_client).to have_received(:get).once.with(:sendsms, default_callback_args)
131
+ end
123
132
  end
124
133
  end
125
134
 
126
135
  describe '#balance' do
127
- it 'Should check param assignment' do
128
- expect(rest_client).to receive(:get)
129
- .once
130
- .with(:getbalance)
131
- .and_return({})
136
+ it 'checks param assignment' do
137
+ allow(rest_client).to receive(:get).and_return({})
138
+
139
+ client.balance
132
140
 
133
- subject.balance
141
+ expect(rest_client).to have_received(:get).once.with(:getbalance)
134
142
  end
135
143
  end
136
144
 
137
- context 'Testing all campaign based methods' do
145
+ context 'when receive all campaign based methods' do
138
146
  def check_for(method)
139
147
  rest_method = {
140
148
  campaign_status: :getstatus,
@@ -142,19 +150,17 @@ describe LocaSMS::Client do
142
150
  campaign_release: :releasesms
143
151
  }[method]
144
152
 
145
- expect(rest_client).to receive(:get)
146
- .once
147
- .with(rest_method, id: '12345')
148
- .and_return({})
153
+ allow(rest_client).to receive(:get).and_return({})
149
154
 
150
- subject.send method, '12345'
155
+ client.send method, '12345'
156
+
157
+ expect(rest_client).to have_received(:get).once.with(rest_method, id: '12345')
151
158
  end
152
159
 
153
- it{ check_for :campaign_status }
154
- it{ check_for :campaign_hold }
155
- it{ check_for :campaign_release }
160
+ it { check_for :campaign_status }
161
+ it { check_for :campaign_hold }
162
+ it { check_for :campaign_release }
156
163
 
157
- it 'Should have tests to cover campaign_status csv result'
164
+ it 'has tests to cover campaign_status csv result'
158
165
  end
159
-
160
166
  end