sms77 0.2.0 → 0.3.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
  SHA256:
3
- metadata.gz: 36eb3f4cd708334c2bda49e4c94c7eef521de326a94231cdfe0c53e76bdee13f
4
- data.tar.gz: 4ab1e7ec064ee7b3fc3bb8415fe1f8b1b23721bdb786647e88bee187bcc620ac
3
+ metadata.gz: 7c6d1a2a65499394f749f079241498d3a7170c67f9951aac9e8f5c73e5eeb405
4
+ data.tar.gz: a9e06cabf74bcb72716f429b6e0915b195bb537cd8e0aeb82abd3c7e0c411359
5
5
  SHA512:
6
- metadata.gz: 0a1cfa14204af7aa47452dedbd5971f1f6d5e839651ef77fcabf94c6ebfc7995d4d78b2a5e77fa73d491bf3adf246fc32afe499919e5d9eddecc4817de6309f4
7
- data.tar.gz: c7c7631464d9bdc25b84e227d00c6271d46d2ee16e710759e445e457f84e3e212de819401abfbb74d4e5f6cd1cdef338a407e857887a212d9e06923826bc6d1b
6
+ metadata.gz: d35e191be7c6f4cf0a5066f69cbc2cb050c382cafc039d2ecae2b39c80987380dbc100b43c2398d78897f22ded6b7304bde5063b4665385ab027df06cd784ae1
7
+ data.tar.gz: 2297d5c22a861bc9be2168ffb045ad448d48b2af8caedd6ef1613f95eff163117d8da20828a91623e2b762d49f603115a9b825a5b3dbe155adbabb9347aa4d17
data/README.md CHANGED
@@ -3,18 +3,21 @@
3
3
  # Ruby Client for the Sms77.io SMS Gateway API
4
4
 
5
5
  ## Installation
6
+
6
7
  ```gem install sms77```
7
8
 
8
9
  ### Usage
10
+
9
11
  ```ruby
10
12
  require 'sms77'
11
13
 
12
- client = Sms77::Client.new(ENV['SMS77_API_KEY'])
13
-
14
- puts "Balance: #{client.balance}"
14
+ puts Sms77::Client.new(Sms77::Resource(ENV['SMS77_API_KEY'])).Balance.retrieve
15
+ # or
16
+ puts Sms77::Resources::Balance.new(ENV['SMS77_API_KEY']).retrieve
15
17
  ```
16
18
 
17
19
  #### Testing
20
+
18
21
  ```shell
19
22
  SMS77_API_KEY=MySms77ApiKey bundle exec rspec
20
23
  ```
@@ -26,4 +29,5 @@ Setting ```SMS77_DEBUG=1``` prints details to stdout.
26
29
  Setting ```SMS77_TEST_HTTP=1``` enables live testing with actual API requests.
27
30
 
28
31
  ##### Support
32
+
29
33
  Need help? Feel free to send us an <a href='mailto: support@sms77.io'>email</a>.
@@ -1,7 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'sms77/version'
4
- require 'sms77/client'
5
4
 
6
5
  module Sms77
7
6
  end
@@ -1,64 +1,29 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require 'cgi'
4
- require 'json'
5
- require 'faraday'
6
- require 'sms77/endpoint'
7
- require 'sms77/contacts'
8
- require 'sms77/base'
3
+ require 'sms77/resources/analytics'
4
+ require 'sms77/resources/balance'
5
+ require 'sms77/resources/contacts'
6
+ require 'sms77/resources/hooks'
7
+ require 'sms77/resources/journal'
8
+ require 'sms77/resources/lookup'
9
+ require 'sms77/resources/pricing'
10
+ require 'sms77/resources/sms'
11
+ require 'sms77/resources/status'
12
+ require 'sms77/resources/validate_for_voice'
13
+ require 'sms77/resources/voice'
14
+ require 'sms77/util'
9
15
 
10
16
  module Sms77
11
- class Client < Sms77::Base
12
- def analytics(params = {})
13
- get(Sms77::Endpoint::ANALYTICS, params)
14
- end
15
-
16
- def balance
17
- get(Sms77::Endpoint::BALANCE)
18
- end
19
-
20
- def contacts(params)
21
- get_or_post(Sms77::Contacts::Action::READ == params[:action], Sms77::Endpoint::CONTACTS, params)
22
- end
23
-
24
- def hooks(params)
25
- Sms77::Hooks::Validator::validate(params)
26
-
27
- get_or_post(Sms77::Hooks::Action::READ == params[:action], Sms77::Endpoint::HOOKS, params)
28
- end
29
-
30
- def journal(params)
31
- get(Sms77::Endpoint::JOURNAL, params)
32
- end
33
-
34
- def lookup(params)
35
- post(Sms77::Endpoint::LOOKUP, params)
36
- end
37
-
38
- def pricing(params = {})
39
- get(Sms77::Endpoint::PRICING, params)
40
- end
41
-
42
- def sms(params)
43
- post(Sms77::Endpoint::SMS, params)
44
- end
45
-
46
- def status(params)
47
- get(Sms77::Endpoint::STATUS, params)
48
- end
49
-
50
- def validate_for_voice(params)
51
- post(Sms77::Endpoint::VALIDATE_FOR_VOICE, params)
52
- end
53
-
54
- def voice(params)
55
- post(Sms77::Endpoint::VOICE, params)
56
- end
17
+ class Client
18
+ # @param resource [Sms77::Resource]
19
+ def initialize(resource)
20
+ Sms77::Util::get_namespace_classes(Sms77::Resources).each do |cls|
21
+ name = cls.name.split('::').last
57
22
 
58
- private
23
+ instance_variable_set("@#{name}", cls.new(resource))
59
24
 
60
- def get_or_post(bool, *args)
61
- method(bool ? :get : :post).call(*args)
25
+ singleton_class.instance_eval("attr_reader :#{name}")
26
+ end
62
27
  end
63
28
  end
64
29
  end
@@ -27,7 +27,7 @@ module Sms77::Hooks
27
27
  if Sms77::Hooks::Action::SUBSCRIBE == action
28
28
  raise 'Parameter validation failed' unless Sms77::Hooks::Validator::subscribe(params)
29
29
  elsif Sms77::Hooks::Action::UNSUBSCRIBE == action
30
- raise 'ID must be a positive integer' unless Sms77::Util::is_positive_integer?(params[:id])
30
+ raise 'ID must be a positive integer' unless Sms77::Hooks::Validator::unsubscribe(params)
31
31
  end
32
32
  end
33
33
 
@@ -39,6 +39,10 @@ module Sms77::Hooks
39
39
  self.target_url?(params[:target_url])
40
40
  end
41
41
 
42
+ def self.unsubscribe(params)
43
+ Sms77::Util::is_positive_integer?(params[:id])
44
+ end
45
+
42
46
  def self.is_action?(str)
43
47
  Sms77::Util::in_module_constants?(str, Sms77::Hooks::Action)
44
48
  end
@@ -6,14 +6,10 @@ require 'faraday'
6
6
  require 'sms77/endpoint'
7
7
 
8
8
  module Sms77
9
- class Base
9
+ class Resource
10
+ attr_reader :api_key, :endpoint, :sent_with, :http_methods, :request_methods, :builder, :conn
11
+
10
12
  BASE_PATH = '/api/'
11
- CONN = Faraday.new("https://gateway.sms77.io#{BASE_PATH}")
12
- HTTP_GET = CONN.method(:get).freeze
13
- HTTP_POST = CONN.method(:post).freeze
14
- CONN.freeze
15
- HTTP_METHODS = [HTTP_GET, HTTP_POST].freeze
16
- BUILDER = CONN.builder
17
13
 
18
14
  def initialize(api_key, sent_with = 'ruby')
19
15
  raise 'missing api_key in config' if api_key.to_s.empty?
@@ -21,36 +17,48 @@ module Sms77
21
17
 
22
18
  @api_key = api_key
23
19
  @sent_with = sent_with
24
-
25
- HTTP_METHODS.each do |method|
26
- define_singleton_method(method.name) { |*args| request(method, *args) }
27
- end
20
+ @endpoint = self.class.get_endpoint
21
+ @http_methods = self.class.get_http_methods
22
+ @conn = Faraday.new("https://gateway.sms77.io#{BASE_PATH}")
28
23
  end
29
24
 
30
- attr_reader :api_key, :sent_with
31
-
32
25
  protected
33
26
 
34
- def request(method, path, payload = {})
35
- if !payload.empty? && HTTP_GET == method
36
- path = "#{path}?#{URI.encode_www_form(payload)}"
27
+ def request(payload = {}, query = {})
28
+ path = @endpoint
29
+ http_method = @http_methods[caller_locations.first.label.to_sym]
30
+
31
+ if :get == http_method
32
+ query = payload
37
33
 
38
34
  payload = {}
39
35
  end
40
36
 
41
- method = method.name
37
+ query.each do |key, val|
38
+ query.store(key, Sms77::Util::to_numbered_bool(val))
39
+ end
40
+
41
+ payload.each do |key, val|
42
+ payload.store(key, Sms77::Util::to_numbered_bool(val))
43
+ end
44
+
45
+ unless query.empty?
46
+ path = "#{path}?#{URI.encode_www_form(query)}"
47
+ end
48
+
42
49
  headers = Hash[
43
50
  Faraday::Request::Authorization::KEY, "Bearer #{@api_key}",
44
51
  'sentWith', @sent_with
45
52
  ]
46
53
 
47
- res = CONN.run_request(method, path, payload, headers)
54
+ res = @conn.run_request(http_method, path, payload, headers)
48
55
 
49
56
  puts JSON.pretty_generate(res.to_hash.merge({
50
- :method => method,
57
+ :method => http_method,
51
58
  :path => path,
52
59
  :payload => payload,
53
- :req_headers => headers
60
+ :req_headers => headers,
61
+ :query => query,
54
62
  }).compact) if ENV['SMS77_DEBUG']
55
63
 
56
64
  raise "Error requesting (#{self.class.name}) with code #{res.status}" unless 200 == res.status
@@ -71,5 +79,15 @@ module Sms77
71
79
 
72
80
  body
73
81
  end
82
+
83
+ class << self
84
+ def get_http_methods
85
+ @http_methods
86
+ end
87
+
88
+ def get_endpoint
89
+ @endpoint
90
+ end
91
+ end
74
92
  end
75
93
  end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Analytics < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::ANALYTICS
8
+ @http_methods = {
9
+ :retrieve => :get,
10
+ }
11
+
12
+ def retrieve(params = {})
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Balance < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::BALANCE
8
+ @http_methods = {
9
+ :retrieve => :get,
10
+ }
11
+
12
+ def retrieve
13
+ request
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,26 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Contacts < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::CONTACTS
8
+ @http_methods = {
9
+ :delete => :post,
10
+ :read => :get,
11
+ :write => :post,
12
+ }
13
+
14
+ def read(params = {})
15
+ request(params.merge({ :action => Sms77::Contacts::Action::READ }))
16
+ end
17
+
18
+ def delete(params)
19
+ request({}, params.merge({ :action => Sms77::Contacts::Action::DEL }))
20
+ end
21
+
22
+ def write(params)
23
+ request({}, params.merge({ :action => Sms77::Contacts::Action::WRITE }))
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Hooks < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::HOOKS
8
+ @http_methods = {
9
+ :read => :get,
10
+ :subscribe => :post,
11
+ :unsubscribe => :post,
12
+ }
13
+
14
+ def read(params = {})
15
+ request(params.merge({ :action => Sms77::Hooks::Action::READ }))
16
+ end
17
+
18
+ def subscribe(params)
19
+ Sms77::Hooks::Validator::subscribe(params)
20
+
21
+ request(params.merge({ :action => Sms77::Hooks::Action::SUBSCRIBE }))
22
+ end
23
+
24
+ def unsubscribe(params)
25
+ Sms77::Hooks::Validator::unsubscribe(params)
26
+
27
+ request(params.merge({ :action => Sms77::Hooks::Action::UNSUBSCRIBE }))
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Journal < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::JOURNAL
8
+ @http_methods = {
9
+ :retrieve => :get,
10
+ }
11
+
12
+ def retrieve(params)
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,30 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+ module Sms77::Resources
5
+ class Lookup < Sms77::Resource
6
+ @endpoint = Sms77::Endpoint::LOOKUP
7
+ @http_methods = {
8
+ :cnam => :post,
9
+ :format => :post,
10
+ :hlr => :post,
11
+ :mnp => :post,
12
+ }
13
+
14
+ def cnam(params)
15
+ request(params.merge({ :type => Sms77::Lookup::Type::CNAM }))
16
+ end
17
+
18
+ def format(params)
19
+ request(params.merge({ :type => Sms77::Lookup::Type::FORMAT }))
20
+ end
21
+
22
+ def hlr(params)
23
+ request(params.merge({ :type => Sms77::Lookup::Type::HLR }))
24
+ end
25
+
26
+ def mnp(params)
27
+ request(params.merge({ :type => Sms77::Lookup::Type::MNP }))
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Pricing < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::PRICING
8
+ @http_methods = {
9
+ :retrieve => :get,
10
+ }
11
+
12
+ def retrieve(params = {})
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Sms < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::SMS
8
+ @http_methods = {
9
+ :retrieve => :post,
10
+ }
11
+
12
+ def retrieve(params)
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Status < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::STATUS
8
+ @http_methods = {
9
+ :retrieve => :get,
10
+ }
11
+
12
+ def retrieve(params)
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class ValidateForVoice < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::VALIDATE_FOR_VOICE
8
+ @http_methods = {
9
+ :retrieve => :post,
10
+ }
11
+
12
+ def retrieve(params)
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,16 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sms77/resource'
4
+
5
+ module Sms77::Resources
6
+ class Voice < Sms77::Resource
7
+ @endpoint = Sms77::Endpoint::VOICE
8
+ @http_methods = {
9
+ :send => :post,
10
+ }
11
+
12
+ def send(params)
13
+ request(params)
14
+ end
15
+ end
16
+ end
@@ -1,6 +1,24 @@
1
1
  require 'date'
2
2
 
3
3
  module Sms77::Util
4
+ def self.to_numbered_bool(val)
5
+ if true == val
6
+ return 1
7
+ elsif false == val
8
+ return 0
9
+ end
10
+
11
+ return val
12
+ end
13
+
14
+ def self.get_namespace_members_by_type(ns, type)
15
+ ns.constants.map(&ns.method(:const_get)).grep(type)
16
+ end
17
+
18
+ def self.get_namespace_classes(ns)
19
+ return self.get_namespace_members_by_type(ns, Class)
20
+ end
21
+
4
22
  def self.get_module_constant_values(mod)
5
23
  mod.constants(false).map &mod.method(:const_get)
6
24
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Sms77
4
- VERSION = '0.2.0'
4
+ VERSION = '0.3.0'
5
5
  end
@@ -0,0 +1,15 @@
1
+ class EnvKeyStore
2
+ def initialize(key)
3
+ @key = "SMS77_TEST_#{key}"
4
+
5
+ @store = ENV[@key]
6
+ end
7
+
8
+ def get(fallback = nil)
9
+ @store.nil? ? fallback : @store
10
+ end
11
+
12
+ def set(val, only_on_nil = false)
13
+ @store = val unless only_on_nil
14
+ end
15
+ end
@@ -0,0 +1,23 @@
1
+ RSpec::Matchers.define :be_nil_or_lengthy_string do
2
+ match do |val|
3
+ Sms77::Util::nil_or_lengthy_string?(val)
4
+ end
5
+ end
6
+
7
+ RSpec::Matchers.define :be_boolean do
8
+ match do |val|
9
+ Sms77::Util::boolean?(val)
10
+ end
11
+ end
12
+
13
+ RSpec::Matchers.define :be_numeric do
14
+ match do |val|
15
+ Sms77::Util::numeric?(val)
16
+ end
17
+ end
18
+
19
+ RSpec::Matchers.define :be_lengthy_string do
20
+ match do |val|
21
+ Sms77::Util::lengthy_string?(val)
22
+ end
23
+ end
@@ -1,10 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
4
+ require 'sms77/resources/balance'
5
5
 
6
6
  RSpec.describe Sms77, 'balance' do
7
7
  it 'returns the account balance' do
8
- expect(Helper.get(Sms77::Endpoint::BALANCE, 12.34)).to be_a(Float)
8
+ helper = Helper.new(Sms77::Resources::Balance)
9
+ balance = helper.request(helper.resource.method(:retrieve), 155.55)
10
+ expect(balance).to be_a(Float)
9
11
  end
10
12
  end
@@ -1,18 +1,15 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require 'sms77/client'
4
+ require 'sms77/resource'
3
5
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
6
 
6
7
  RSpec.describe Sms77, 'client' do
7
- it 'checks api key' do
8
- expect(Helper.client.api_key).to be_lengthy_string
9
- end
10
-
11
- it 'checks sentWith' do
12
- expect(Helper.client.sent_with).to be_lengthy_string
13
- end
8
+ it 'should contain all resource modules' do
9
+ client = Sms77::Client.new(Sms77::Resource.new('x'))
14
10
 
15
- it 'fails authentication' do
16
- expect { Sms77::Client.new('') }.to raise_error(RuntimeError)
11
+ client.instance_variables.each do |var|
12
+ expect(Sms77::Resources.const_get(client.instance_variable_get(var).class.name)).to be_truthy
13
+ end
17
14
  end
18
15
  end
@@ -1,11 +1,12 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
4
  require 'sms77/contacts'
5
+ require 'sms77/resources/contacts'
6
6
 
7
7
  RSpec.describe Sms77, 'contacts' do
8
8
  $new_contact_id = nil
9
+ HELPER = Helper.new(Sms77::Resources::Contacts)
9
10
 
10
11
  def assert_new(response_body)
11
12
  if response_body.is_a?(String)
@@ -38,11 +39,6 @@ RSpec.describe Sms77, 'contacts' do
38
39
  expect(number.sub('+', '')).to be_numeric
39
40
  end
40
41
 
41
- def request(action, stub, extra_params = {})
42
- Helper.method(Sms77::Contacts::Action::READ == action ? :get : :post)
43
- .call(Sms77::Endpoint::CONTACTS, stub, { action: action }.merge(extra_params))
44
- end
45
-
46
42
  it 'returns all contacts as CSV' do
47
43
  stub = <<~CSV
48
44
  "4848436";"";""
@@ -55,7 +51,7 @@ RSpec.describe Sms77, 'contacts' do
55
51
  "2925186";"Tom Tester";"004901234567890"
56
52
  CSV
57
53
 
58
- body = request(Sms77::Contacts::Action::READ, stub)
54
+ body = HELPER.request(HELPER.resource.method(:read), stub)
59
55
 
60
56
  expect(body).to be_a(String)
61
57
 
@@ -76,7 +72,7 @@ RSpec.describe Sms77, 'contacts' do
76
72
  { ID: '2925186', Name: 'Tom Tester', Number: '004901234567890' }
77
73
  ]
78
74
 
79
- body = request(Sms77::Contacts::Action::READ, stub, { json: 1 })
75
+ body = HELPER.request(HELPER.resource.method(:read), stub, { json: true })
80
76
 
81
77
  expect(body).to be_a(Array)
82
78
 
@@ -91,7 +87,7 @@ RSpec.describe Sms77, 'contacts' do
91
87
  4868400
92
88
  TEXT
93
89
 
94
- body = request(Sms77::Contacts::Action::WRITE, stub)
90
+ body = HELPER.request(HELPER.resource.method(:write), stub, {})
95
91
 
96
92
  expect(body).to be_a(String)
97
93
 
@@ -99,11 +95,11 @@ RSpec.describe Sms77, 'contacts' do
99
95
  end
100
96
 
101
97
  it 'deletes a contact with given ID and return code' do
102
- expect(request(Sms77::Contacts::Action::DEL, 152, { id: $new_contact_id })).to be_a(Integer)
98
+ expect(HELPER.request(HELPER.resource.method(:delete), 152, { id: $new_contact_id })).to be_a(Integer)
103
99
  end
104
100
 
105
101
  it 'creates a contact and returns its ID as JSON' do
106
- body = request(Sms77::Contacts::Action::WRITE, { id: 4868401, return: '152' }, { json: 1 })
102
+ body = HELPER.request(HELPER.resource.method(:write), { id: 4868401, return: '152' }, { json: true })
107
103
 
108
104
  expect(body).to be_a(Hash)
109
105
 
@@ -111,7 +107,8 @@ RSpec.describe Sms77, 'contacts' do
111
107
  end
112
108
 
113
109
  it 'deletes a contact with given ID and return code as JSON' do
114
- body = request(Sms77::Contacts::Action::DEL, { return: '152' }, { id: $new_contact_id, json: 1 })
110
+ body = HELPER.request(
111
+ HELPER.resource.method(:delete), { return: '152' }, { id: $new_contact_id, json: true })
115
112
 
116
113
  expect(body).to be_a(Hash)
117
114
  expect(body[:return]).to be_a(String)
@@ -3,10 +3,12 @@
3
3
  require 'securerandom'
4
4
  require 'sms77/hooks'
5
5
  require 'sms77/util'
6
+ require 'sms77/resources/hooks'
6
7
  require 'spec_helper'
7
8
 
8
9
  RSpec.describe Sms77, 'hooks' do
9
10
  HOOK_ID = EnvKeyStore.new('HOOK_ID')
11
+ HELPER = Helper.new(Sms77::Resources::Hooks)
10
12
 
11
13
  def alter_action_stub
12
14
  {
@@ -15,13 +17,13 @@ RSpec.describe Sms77, 'hooks' do
15
17
  }
16
18
  end
17
19
 
18
- def request(action, stub, extra_params = {})
19
- res = Helper.method(Sms77::Hooks::Action::READ == action ? :get : :post)
20
- .call(Sms77::Endpoint::HOOKS, stub, { action: action }.merge(extra_params))
20
+ def request(fn, stub, extra_params = {})
21
+ res = HELPER.request(fn, stub, extra_params)
21
22
 
22
23
  expect(res).to be_a(Hash)
23
24
 
24
25
  stub_keys = stub.keys
26
+
25
27
  res.each do |k, v|
26
28
  expect(stub_keys).to include(k)
27
29
  expect(v.class).to match(stub[:"#{k}"].class)
@@ -31,7 +33,7 @@ RSpec.describe Sms77, 'hooks' do
31
33
  end
32
34
 
33
35
  it 'returns all hooks' do
34
- res = request(Sms77::Hooks::Action::READ, {
36
+ res = request(HELPER.resource.method(:read), {
35
37
  :code => nil,
36
38
  :hooks => [
37
39
  {
@@ -45,9 +47,16 @@ RSpec.describe Sms77, 'hooks' do
45
47
  :success => true
46
48
  })
47
49
 
50
+ expect(res).to include(:code, :hooks, :success)
51
+ expect(res[:code]).to eq(nil)
52
+ expect(res[:hooks]).to be_a(Array)
53
+ expect(res[:success]).to be_boolean
54
+
48
55
  res[:hooks].each do |hook|
56
+ expect(hook).to include(:created, :event_type, :id, :request_method, :target_url)
57
+
49
58
  expect(Sms77::Util::is_valid_datetime?(hook[:created])).to be
50
- expect(hook[:created] =~ /^\d\d\d\d-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01]) (00|[0-9]|1[0-9]|2[0-3]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/).to be
59
+ expect(hook[:created]).to match(/^\d\d\d\d-(0?[1-9]|1[0-2])-(0?[1-9]|[12][0-9]|3[01]) (1[0-9]|2[0-3]|0[0-9]):([0-9]|[0-5][0-9]):([0-9]|[0-5][0-9])$/)
51
60
  expect(Sms77::Hooks::Validator::event_type?(hook[:event_type])).to be
52
61
  expect(Sms77::Util::is_positive_integer?(hook[:id])).to be
53
62
  expect(Sms77::Hooks::Validator::request_method?(hook[:request_method])).to be
@@ -55,10 +64,11 @@ RSpec.describe Sms77, 'hooks' do
55
64
  end
56
65
  end
57
66
 
67
+ =begin
58
68
  it 'subscribes' do
59
69
  stub = alter_action_stub.merge({ :id => rand(1...1000000) })
60
70
 
61
- res = request(Sms77::Hooks::Action::SUBSCRIBE, stub, {
71
+ res = request(HELPER.resource.method(:subscribe), stub, {
62
72
  :event_type => Sms77::Hooks::EventType::NEW_INBOUND_SMS,
63
73
  :request_method => Sms77::Hooks::RequestMethod::GET,
64
74
  :target_url => "http://ruby.tld/#{SecureRandom.uuid}"
@@ -66,18 +76,18 @@ RSpec.describe Sms77, 'hooks' do
66
76
 
67
77
  expect(Sms77::Util::is_positive_integer?(res[:id])).to be
68
78
  expect(res[:id]).to be_a(Integer)
69
- expect(stub[:id]).to match(res[:id]) unless Helper.is_http
79
+ expect(stub[:id]).to match(res[:id]) unless Helper::IS_HTTP
70
80
 
71
81
  assert_alter_response(res)
72
82
 
73
- puts "Subscribed ID: #{Helper.is_http ? res[:id] : stub[:id]}"
83
+ puts "Subscribed ID: #{Helper::IS_HTTP ? res[:id] : stub[:id]}"
74
84
 
75
85
  HOOK_ID.set(res[:id])
76
86
  end
77
87
 
78
88
  it 'unsubscribes' do
79
89
  id = HOOK_ID.get
80
- res = request(Sms77::Hooks::Action::UNSUBSCRIBE, alter_action_stub, { :id => id })
90
+ res = request(HELPER.resource.method(:unubscribe), alter_action_stub, { :id => id })
81
91
 
82
92
  assert_alter_response(res)
83
93
 
@@ -87,6 +97,7 @@ RSpec.describe Sms77, 'hooks' do
87
97
 
88
98
  res[:success]
89
99
  end
100
+ =end
90
101
 
91
102
  def assert_alter_response(res)
92
103
  expect(res[:code]).to match(nil)
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'spec_helper'
4
+ require 'sms77/resource'
5
+
6
+ RSpec.describe Sms77, 'instance' do
7
+ helper = Helper.new(Sms77::Resource)
8
+
9
+ it 'checks api key' do
10
+ expect(helper.resource.api_key).to be_lengthy_string
11
+ end
12
+
13
+ it 'checks sentWith' do
14
+ expect(helper.resource.sent_with).to be_lengthy_string
15
+ end
16
+
17
+ it 'fails authentication' do
18
+ expect { Sms77::Resource.new('') }.to raise_error(RuntimeError)
19
+ end
20
+ end
@@ -1,8 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
4
  require 'sms77/journal'
5
+ require 'sms77/resources/journal'
6
6
  require 'sms77/sms'
7
7
 
8
8
  RSpec.describe Sms77, 'journal' do
@@ -20,7 +20,8 @@ RSpec.describe Sms77, 'journal' do
20
20
  :to => "49170123456789",
21
21
  }]
22
22
 
23
- res = Helper.get(Sms77::Endpoint::JOURNAL, stub, { type: type })
23
+ helper = Helper.new(Sms77::Resources::Journal)
24
+ res = helper.request(helper.resource.method(:retrieve), stub, { type: type })
24
25
 
25
26
  expect(res).to be_a(Array)
26
27
 
@@ -3,11 +3,16 @@
3
3
  require 'spec_helper'
4
4
  require 'sms77/endpoint'
5
5
  require 'sms77/lookup'
6
+ require 'sms77/resources/lookup'
6
7
  require 'json'
7
8
 
8
9
  RSpec.describe Sms77, 'lookup' do
9
10
  def request(type, stub, extra_args = {})
10
- Helper.post(Sms77::Endpoint::LOOKUP, stub, { type: type, number: '+491771783130' }.merge(extra_args))
11
+ helper = Helper.new(Sms77::Resources::Lookup)
12
+ helper.request(
13
+ helper.resource.method(type),
14
+ stub,
15
+ { number: '+491771783130' }.merge(extra_args))
11
16
  end
12
17
 
13
18
  it 'misses number to lookup' do
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
- require 'json'
4
+ require 'sms77/resources/pricing'
6
5
 
7
6
  RSpec.describe Sms77, 'pricing' do
8
7
  it 'returns all countries pricing as json' do
@@ -36,7 +35,8 @@ RSpec.describe Sms77, 'pricing' do
36
35
  ]
37
36
  }
38
37
 
39
- res = Helper.get(Sms77::Endpoint::PRICING, stub)
38
+ helper = Helper.new(Sms77::Resources::Pricing)
39
+ res = helper.request(helper.resource.method(:retrieve), stub)
40
40
  countries = res[:countries]
41
41
 
42
42
  expect(res).to be_a(Hash)
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
- require 'sms77/contacts'
4
+ require 'sms77/resources/sms'
6
5
 
7
6
  RSpec.describe Sms77, 'sms' do
8
7
  $text = 'Your glasses are ready for pickup.'
@@ -23,12 +22,13 @@ RSpec.describe Sms77, 'sms' do
23
22
 
24
23
  def request(stub, extra_params = {})
25
24
  params = {
26
- from: Helper.virtual_inbound_nr_eplus,
25
+ from: Helper::VIRTUAL_INBOUNDS[:eplus],
27
26
  text: $text,
28
- to: Helper.virtual_inbound_nr_eplus
27
+ to: Helper::VIRTUAL_INBOUNDS[:eplus]
29
28
  }.merge(extra_params)
30
29
 
31
- Helper.post(Sms77::Endpoint::SMS, stub, params)
30
+ helper = Helper.new(Sms77::Resources::Sms)
31
+ helper.request(helper.resource.method(:retrieve), stub, params)
32
32
  end
33
33
 
34
34
  it 'sends a single sms and returns success code' do
@@ -1,17 +1,17 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
- require 'json'
4
+ require 'sms77/resources/validate_for_voice'
6
5
 
7
6
  RSpec.describe Sms77, 'validate_for_voice' do
8
7
  it 'returns caller id information' do
9
8
  number = '491771783130'
10
- callback_host = Helper.is_http ? `curl http://ipecho.net/plain` : '127.0.0.1'
9
+ callback_host = Helper::IS_HTTP ? `curl http://ipecho.net/plain` : '127.0.0.1'
11
10
  callback = "#{callback_host}/callback.php"
12
11
  stub = { success: true }
13
12
 
14
- body = Helper.post(Sms77::Endpoint::VALIDATE_FOR_VOICE, stub, { number: number, callback: callback })
13
+ helper = Helper.new(Sms77::Resources::ValidateForVoice)
14
+ body = helper.request(helper.resource.method(:retrieve), stub, { number: number, callback: callback })
15
15
 
16
16
  expect(body).to be_a(Hash)
17
17
  expect(body[:success]).to be_boolean
@@ -1,8 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'spec_helper'
4
- require 'sms77/endpoint'
5
- require 'sms77/contacts'
4
+ require 'sms77/resources/voice'
6
5
 
7
6
  RSpec.describe Sms77, 'voice' do
8
7
  def assert_response(response)
@@ -23,16 +22,17 @@ RSpec.describe Sms77, 'voice' do
23
22
  TEXT
24
23
 
25
24
  params = {
26
- from: Helper.virtual_inbound_nr_eplus,
25
+ from: Helper::VIRTUAL_INBOUNDS[:eplus],
27
26
  text: text,
28
- to: Helper.virtual_inbound_nr_eplus
27
+ to: Helper::VIRTUAL_INBOUNDS[:eplus]
29
28
  }.merge(extra_params)
30
29
 
31
- Helper.post(Sms77::Endpoint::VOICE, stub, params)
30
+ helper = Helper.new(Sms77::Resources::Voice)
31
+ assert_response(helper.request(helper.resource.method(:send), stub, params))
32
32
  end
33
33
 
34
34
  it 'calls a number with text input' do
35
- assert_response(request('Your glasses are ready for pickup.'))
35
+ request('Your glasses are ready for pickup.')
36
36
  end
37
37
 
38
38
  it 'calls a number with xml input' do
@@ -46,6 +46,6 @@ RSpec.describe Sms77, 'voice' do
46
46
  </Response>
47
47
  XML
48
48
 
49
- assert_response(request(text, { xml: 1 }))
49
+ request(text, { xml: true })
50
50
  end
51
51
  end
@@ -3,66 +3,51 @@
3
3
  $LOAD_PATH.unshift File.expand_path('../lib', __dir__)
4
4
 
5
5
  require 'sms77'
6
+ require 'sms77/resource'
6
7
  require 'sms77/util'
8
+ require 'matchers'
9
+ require 'EnvKeyStore'
7
10
 
8
- RSpec::Matchers.define :be_nil_or_lengthy_string do
9
- match do |val|
10
- Sms77::Util::nil_or_lengthy_string?(val)
11
- end
12
- end
11
+ SMS77_TEST_HTTP = (ENV['SMS77_TEST_HTTP'].nil? ? false : true).freeze
13
12
 
14
- RSpec::Matchers.define :be_boolean do
15
- match do |val|
16
- Sms77::Util::boolean?(val)
13
+ RSpec.configure do |config|
14
+ SMS77_TEST_HTTP && config.after do
15
+ sleep(1.125)
17
16
  end
18
17
  end
19
18
 
20
- RSpec::Matchers.define :be_numeric do
21
- match do |val|
22
- Sms77::Util::numeric?(val)
23
- end
24
- end
25
-
26
- RSpec::Matchers.define :be_lengthy_string do
27
- match do |val|
28
- Sms77::Util::lengthy_string?(val)
29
- end
30
- end
19
+ class Helper
20
+ attr_reader :resource
31
21
 
32
- class EnvKeyStore
33
- def initialize(key)
34
- @key = "SMS77_TEST_#{key}"
22
+ IS_HTTP = SMS77_TEST_HTTP
23
+ VIRTUAL_INBOUNDS = {
24
+ eplus: '+491771783130',
25
+ }.freeze
35
26
 
36
- @store = ENV[@key]
37
- end
27
+ # @param resource [Class<Sms77::Resource>]
28
+ def initialize(resource)
29
+ @resource = resource.new(ENV['SMS77_DUMMY_API_KEY'], 'ruby-test')
38
30
 
39
- def get(fallback = nil)
40
- @store.nil? ? fallback : @store
31
+ unless Helper::IS_HTTP
32
+ @stubs = Faraday::Adapter::Test::Stubs.new
33
+ @resource.conn.builder.adapter(:test, @stubs)
34
+ end
41
35
  end
42
36
 
43
- def set(val, only_on_nil = false)
44
- @store = val unless only_on_nil
45
- end
46
- end
37
+ def create_stub(fn_name, stub)
38
+ http_fn = @resource.http_methods[fn_name]
39
+ puts "creating stub for #{http_fn} @ #{@resource.class.name}.#{fn_name}"
47
40
 
48
- class Helper
49
- @client = Sms77::Client.new(ENV['SMS77_DUMMY_API_KEY'], 'ruby-test')
50
- @is_http = ENV['SMS77_TEST_HTTP'].freeze
51
- @stubs = Faraday::Adapter::Test::Stubs.new
52
- @virtual_inbound_nr_eplus = '+491771783130'
53
- Sms77::Client::BUILDER.adapter(:test, @stubs) unless @is_http
41
+ @stubs.method(http_fn).call(Sms77::Resource::BASE_PATH + @resource.endpoint) do
42
+ puts "stub: " + stub.inspect
54
43
 
55
- Sms77::Client::HTTP_METHODS.each do |method|
56
- self.class.define_method(method.name) { |*args| request(@stubs.method(method.name.to_sym), *args) }
44
+ [200, {}, stub]
45
+ end
57
46
  end
58
47
 
59
- def self.request(method, endpoint, stub, params = nil)
60
- method.call(Sms77::Client::BASE_PATH + endpoint) { || [200, {}, stub] } unless @is_http
61
-
62
- @client.method(endpoint).call(*[params].compact)
63
- end
48
+ def request(fn, stub, params = nil)
49
+ create_stub(fn.name, stub) unless Helper::IS_HTTP
64
50
 
65
- class << self
66
- attr_reader :is_http, :virtual_inbound_nr_eplus, :client
51
+ fn.call(*[params].compact)
67
52
  end
68
53
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sms77
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - sms77 e.K.
@@ -78,21 +78,35 @@ files:
78
78
  - README.md
79
79
  - Rakefile
80
80
  - lib/sms77.rb
81
- - lib/sms77/base.rb
82
81
  - lib/sms77/client.rb
83
82
  - lib/sms77/contacts.rb
84
83
  - lib/sms77/endpoint.rb
85
84
  - lib/sms77/hooks.rb
86
85
  - lib/sms77/journal.rb
87
86
  - lib/sms77/lookup.rb
87
+ - lib/sms77/resource.rb
88
+ - lib/sms77/resources/analytics.rb
89
+ - lib/sms77/resources/balance.rb
90
+ - lib/sms77/resources/contacts.rb
91
+ - lib/sms77/resources/hooks.rb
92
+ - lib/sms77/resources/journal.rb
93
+ - lib/sms77/resources/lookup.rb
94
+ - lib/sms77/resources/pricing.rb
95
+ - lib/sms77/resources/sms.rb
96
+ - lib/sms77/resources/status.rb
97
+ - lib/sms77/resources/validate_for_voice.rb
98
+ - lib/sms77/resources/voice.rb
88
99
  - lib/sms77/sms.rb
89
100
  - lib/sms77/util.rb
90
101
  - lib/sms77/version.rb
91
102
  - sms77.gemspec
103
+ - spec/EnvKeyStore.rb
104
+ - spec/matchers.rb
92
105
  - spec/sms77/balance_spec.rb
93
106
  - spec/sms77/client_spec.rb
94
107
  - spec/sms77/contacts_spec.rb
95
108
  - spec/sms77/hooks_spec.rb
109
+ - spec/sms77/instance_spec.rb
96
110
  - spec/sms77/journal_spec.rb
97
111
  - spec/sms77/lookup_spec.rb
98
112
  - spec/sms77/pricing_spec.rb
@@ -125,8 +139,10 @@ signing_key:
125
139
  specification_version: 4
126
140
  summary: Official API Client for the Sms77.io SMS Gateway
127
141
  test_files:
142
+ - spec/EnvKeyStore.rb
128
143
  - spec/spec_helper.rb
129
144
  - spec/sms77_spec.rb
145
+ - spec/matchers.rb
130
146
  - spec/sms77/voice_spec.rb
131
147
  - spec/sms77/client_spec.rb
132
148
  - spec/sms77/lookup_spec.rb
@@ -137,3 +153,4 @@ test_files:
137
153
  - spec/sms77/balance_spec.rb
138
154
  - spec/sms77/validate_for_voice_spec.rb
139
155
  - spec/sms77/journal_spec.rb
156
+ - spec/sms77/instance_spec.rb