locasms 0.1.7 → 0.5.0

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