mock-twilio 0.1.0 → 0.2.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 +4 -4
- data/CHANGELOG.md +5 -0
- data/Gemfile +2 -0
- data/README.md +18 -8
- data/lib/mock/twilio/client.rb +1 -1
- data/lib/mock/twilio/decorator.rb +8 -2
- data/lib/mock/twilio/schemas/api_2010.rb +13 -1
- data/lib/mock/twilio/schemas/messaging_v1.rb +1 -1
- data/lib/mock/twilio/util/configuration.rb +27 -0
- data/lib/mock/twilio/version.rb +1 -1
- data/lib/mock/twilio/webhook_client.rb +45 -0
- data/lib/mock/twilio/webhooks/base.rb +37 -0
- data/lib/mock/twilio/webhooks/messages.rb +38 -0
- data/lib/mock/twilio.rb +20 -1
- metadata +47 -1
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fbb843efbd1e8b54602d0463971c24a502b20b42ec9085530f624549190bee40
|
4
|
+
data.tar.gz: 40d24741f57296220aaa3ca36b21c2b5fd429a08c4669c2ce2cf0f636696889a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 570376720a4f739d537bdb4285cfd8aaadea578d3d076089b849a8d7f66b603a0b0562a116c0fc9ecb6462ee64d8f8fdf3cb957d2c8a4a82575111354ba16670
|
7
|
+
data.tar.gz: 41dc6b8fcd7b6e2b58b85d81eb43e75defc1969a7c8a349ef4546a4a7c9114a35e4e9d85e3e4dc804b95ea7f9de827551a2a1724dd82e52eaa8d8d0ed712f9d4
|
data/CHANGELOG.md
CHANGED
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -5,16 +5,10 @@ This is a SchoolStatus implementation to mock twilio client to perform requests
|
|
5
5
|
|
6
6
|
# Installation
|
7
7
|
|
8
|
-
To install using
|
8
|
+
To install using bundler grab the latest stable version:
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
gem
|
12
|
-
```
|
13
|
-
|
14
|
-
To manually install `twilio-ruby` via [Rubygems][rubygems] simply gem install:
|
15
|
-
|
16
|
-
```bash
|
17
|
-
gem install mock-twilio
|
11
|
+
gem "mock-twilio", "~> 0.2.0", git: "https://github.com/schoolstatus/mock-twilio.git"
|
18
12
|
```
|
19
13
|
|
20
14
|
## Requirements
|
@@ -31,7 +25,18 @@ OR
|
|
31
25
|
- `proxy_protocol = http`
|
32
26
|
|
33
27
|
## How to use
|
28
|
+
Initializer sample
|
29
|
+
```ruby
|
30
|
+
Mock::Twilio.configure do |config|
|
31
|
+
config.host = "http://shunkan-ido-service"
|
32
|
+
config.forwarded_host = "shunkan-ido-service"
|
33
|
+
config.port = "3000"
|
34
|
+
config.proto = "http"
|
35
|
+
end
|
34
36
|
|
37
|
+
```
|
38
|
+
|
39
|
+
Example
|
35
40
|
```ruby
|
36
41
|
export TWILIO_ACCOUNT_SID=ACFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
|
37
42
|
export TWILIO_API_KEY=SKXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
|
@@ -42,6 +47,11 @@ client = Twilio::REST::Client.new(nil, nil, nil, nil, mock_client)
|
|
42
47
|
client.messages.create(to: "+593978613041", body: "RB This is the ship that made the Kesssssel Run in fourteen parsecs?", from: "+13212855389")
|
43
48
|
```
|
44
49
|
|
50
|
+
## Run tests
|
51
|
+
```unix
|
52
|
+
rake test
|
53
|
+
```
|
54
|
+
|
45
55
|
## Swagger - OpenApi Issues
|
46
56
|
|
47
57
|
- Array and Boolean validations due open api formats, ie params as `status_callback_event`, `early_media`. Validations removed for them on json files.
|
data/lib/mock/twilio/client.rb
CHANGED
@@ -7,7 +7,7 @@ module Mock
|
|
7
7
|
# client.messages.create(to: "+593978613041", body: "RB This is the ship that made the Kesssssel Run in fourteen parsecs?", from: "+13212855389")
|
8
8
|
class Client
|
9
9
|
attr_accessor :adapter
|
10
|
-
attr_reader :timeout, :last_response, :last_request
|
10
|
+
attr_reader :timeout, :last_response, :last_request, :proxy_addr, :proxy_port, :proxy_prot
|
11
11
|
|
12
12
|
def initialize(proxy_prot = nil, proxy_addr = nil, proxy_port = nil, timeout: nil)
|
13
13
|
@proxy_prot = proxy_prot || 'http'
|
@@ -11,9 +11,15 @@ module Mock
|
|
11
11
|
class << self
|
12
12
|
def call(body, request)
|
13
13
|
body = JSON.parse(body)
|
14
|
+
|
15
|
+
case body["status"]
|
16
|
+
when 400..600
|
17
|
+
return body
|
18
|
+
end
|
19
|
+
|
14
20
|
schema = url_from(body, request)
|
15
|
-
# return body
|
16
|
-
return ENDPOINTS[schema].decorate(body) if schema
|
21
|
+
# return body decorate if needed
|
22
|
+
return ENDPOINTS[schema].decorate(body, request) if schema
|
17
23
|
|
18
24
|
body
|
19
25
|
end
|
@@ -19,14 +19,16 @@ module Mock
|
|
19
19
|
"uri"
|
20
20
|
].freeze
|
21
21
|
|
22
|
-
def decorate(body)
|
22
|
+
def decorate(body, request)
|
23
23
|
body["date_updated"] = Time.current.rfc2822 if body["date_updated"]
|
24
24
|
body["date_sent"] = Time.current.rfc2822 if body["date_sent"]
|
25
25
|
body["date_created"] = Time.current.rfc2822 if body["date_created"]
|
26
26
|
body["start_time"] = Time.current.rfc2822 if body["start_time"]
|
27
27
|
body["end_time"] = Time.current.rfc2822 if body["end_time"]
|
28
28
|
|
29
|
+
message_sid(body, request) if body["sid"]
|
29
30
|
pagination(body) if body["available_phone_numbers"]
|
31
|
+
|
30
32
|
body
|
31
33
|
end
|
32
34
|
|
@@ -37,6 +39,16 @@ module Mock
|
|
37
39
|
body.delete(key) if body[key]
|
38
40
|
end
|
39
41
|
end
|
42
|
+
|
43
|
+
def message_sid(body, request)
|
44
|
+
prefix = request.data["MediaUrl"] ? "MM" : "SM"
|
45
|
+
sid = prefix + SecureRandom.hex(16)
|
46
|
+
scheduler = Rufus::Scheduler.new
|
47
|
+
scheduler.in '2s' do
|
48
|
+
Mock::Twilio::Webhooks::Messages.trigger(sid)
|
49
|
+
end
|
50
|
+
body["sid"] = sid
|
51
|
+
end
|
40
52
|
end
|
41
53
|
end
|
42
54
|
end
|
@@ -5,7 +5,7 @@ module Mock
|
|
5
5
|
module Schemas
|
6
6
|
class MessagingV1
|
7
7
|
class << self
|
8
|
-
def decorate(body)
|
8
|
+
def decorate(body, request)
|
9
9
|
# Params for twilio pagination, needed for twilio-ruby serializers and absolute paths
|
10
10
|
body["meta"]["key"] = "phone_numbers" if body["meta"]
|
11
11
|
body["meta"]["page_size"] = 20 if body["meta"]
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mock
|
4
|
+
module Twilio
|
5
|
+
module Util
|
6
|
+
class Configuration
|
7
|
+
attr_accessor :host, :forwarded_host, :port, :proto
|
8
|
+
|
9
|
+
def host=(value)
|
10
|
+
@host = value
|
11
|
+
end
|
12
|
+
|
13
|
+
def forwarded_host=(value)
|
14
|
+
@forwarded_host = value
|
15
|
+
end
|
16
|
+
|
17
|
+
def port=(value)
|
18
|
+
@port = value
|
19
|
+
end
|
20
|
+
|
21
|
+
def proto=(value)
|
22
|
+
@proto = value
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
data/lib/mock/twilio/version.rb
CHANGED
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mock
|
4
|
+
module Twilio
|
5
|
+
class WebhooksClient
|
6
|
+
attr_accessor :adapter
|
7
|
+
attr_reader :timeout, :last_request
|
8
|
+
|
9
|
+
def initialize(timeout: nil)
|
10
|
+
@timeout = timeout
|
11
|
+
@adapter = Faraday.default_adapter
|
12
|
+
end
|
13
|
+
|
14
|
+
def _request(request)
|
15
|
+
@connection = Faraday.new(url: request.host + ":" + request.port.to_s, ssl: { verify: true }) do |f|
|
16
|
+
f.options.params_encoder = Faraday::FlatParamsEncoder
|
17
|
+
f.request :url_encoded
|
18
|
+
f.adapter @adapter
|
19
|
+
f.headers = request.headers
|
20
|
+
f.request(:authorization, :basic, request.auth[0], request.auth[1])
|
21
|
+
|
22
|
+
f.options.open_timeout = request.timeout || @timeout
|
23
|
+
f.options.timeout = request.timeout || @timeout
|
24
|
+
end
|
25
|
+
|
26
|
+
response = @connection.send(request.method.downcase.to_sym,
|
27
|
+
request.url,
|
28
|
+
request.method == "GET" ? request.params : request.data)
|
29
|
+
|
30
|
+
if response.body && !response.body.empty?
|
31
|
+
object = response.body
|
32
|
+
elsif response.status == 400
|
33
|
+
object = { message: "Bad request", code: 400 }.to_json
|
34
|
+
end
|
35
|
+
|
36
|
+
response
|
37
|
+
end
|
38
|
+
|
39
|
+
def request(host, port, method, url, params = {}, data = {}, headers = {}, auth = nil, timeout = nil)
|
40
|
+
request = ::Twilio::Request.new(host, port, method, url, params, data, headers, auth, timeout)
|
41
|
+
_request(request)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mock
|
4
|
+
module Twilio
|
5
|
+
module Webhooks
|
6
|
+
class RestError < StandardError
|
7
|
+
end
|
8
|
+
class Base
|
9
|
+
DELAY = [0.5, 0.8]
|
10
|
+
|
11
|
+
def self.build_signature_for_request(request_url, params)
|
12
|
+
validator = ::Twilio::Security::RequestValidator.new(::Twilio.auth_token)
|
13
|
+
validator.build_signature_for(request_url, params)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.twilio_client
|
17
|
+
::Twilio::REST::Client.new
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.webhook_client
|
21
|
+
Mock::Twilio::WebhooksClient.new
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.auth_twilio
|
25
|
+
[twilio_client.account_sid, twilio_client.auth_token]
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.headers
|
29
|
+
{
|
30
|
+
'X-Forwarded-Proto': Mock::Twilio.proto,
|
31
|
+
'Host': Mock::Twilio.forwarded_host
|
32
|
+
}
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Mock
|
4
|
+
module Twilio
|
5
|
+
module Webhooks
|
6
|
+
class Messages < Base
|
7
|
+
URL = "/api/v1/twilio_requests/webhook_message_updates"
|
8
|
+
|
9
|
+
def self.trigger(sid)
|
10
|
+
# Wait simulation from twilio
|
11
|
+
sleep DELAY.sample
|
12
|
+
|
13
|
+
request_url = Mock::Twilio.proto + "://" + Mock::Twilio.forwarded_host + URL
|
14
|
+
|
15
|
+
data = { :MessageSid=>sid, :MessageStatus=>"delivered" }
|
16
|
+
|
17
|
+
signature = build_signature_for_request(request_url, data)
|
18
|
+
|
19
|
+
response = webhook_client.request(Mock::Twilio.host,
|
20
|
+
Mock::Twilio.port,
|
21
|
+
'POST',
|
22
|
+
URL,
|
23
|
+
nil,
|
24
|
+
data,
|
25
|
+
headers.merge!({ 'X-Twilio-Signature': signature }),
|
26
|
+
auth_twilio,
|
27
|
+
nil)
|
28
|
+
case response.status
|
29
|
+
when 200..204
|
30
|
+
response
|
31
|
+
when 400..600
|
32
|
+
raise Webhooks::RestError, response.body
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
data/lib/mock/twilio.rb
CHANGED
@@ -1,8 +1,15 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "rufus-scheduler"
|
4
|
+
require "active_support"
|
5
|
+
require "active_support/core_ext/time"
|
3
6
|
require_relative "twilio/middleware/proxy"
|
4
7
|
require_relative "twilio/schemas/api_2010"
|
5
8
|
require_relative "twilio/schemas/messaging_v1"
|
9
|
+
require_relative "twilio/webhook_client"
|
10
|
+
require_relative "twilio/webhooks/base"
|
11
|
+
require_relative "twilio/webhooks/messages"
|
12
|
+
require_relative "twilio/util/configuration"
|
6
13
|
require_relative "twilio/client"
|
7
14
|
require_relative "twilio/decorator"
|
8
15
|
require_relative "twilio/response"
|
@@ -10,6 +17,18 @@ require_relative "twilio/version"
|
|
10
17
|
|
11
18
|
module Mock
|
12
19
|
module Twilio
|
13
|
-
|
20
|
+
extend SingleForwardable
|
21
|
+
|
22
|
+
def_delegators :configuration, :host, :forwarded_host, :port, :proto
|
23
|
+
|
24
|
+
def self.configure(&block)
|
25
|
+
yield configuration
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.configuration
|
29
|
+
@configuration ||= Util::Configuration.new
|
30
|
+
end
|
31
|
+
|
32
|
+
private_class_method :configuration
|
14
33
|
end
|
15
34
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mock-twilio
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- SchoolStatus Platform Team
|
@@ -24,6 +24,48 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '2.7'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rufus-scheduler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :runtime
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: twilio-ruby
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ">="
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :runtime
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ">="
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: activesupport
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - ">="
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :runtime
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - ">="
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
27
69
|
description: This repository contains Mock::Twilio::Client for Twilio's API.
|
28
70
|
email:
|
29
71
|
executables: []
|
@@ -42,7 +84,11 @@ files:
|
|
42
84
|
- lib/mock/twilio/response.rb
|
43
85
|
- lib/mock/twilio/schemas/api_2010.rb
|
44
86
|
- lib/mock/twilio/schemas/messaging_v1.rb
|
87
|
+
- lib/mock/twilio/util/configuration.rb
|
45
88
|
- lib/mock/twilio/version.rb
|
89
|
+
- lib/mock/twilio/webhook_client.rb
|
90
|
+
- lib/mock/twilio/webhooks/base.rb
|
91
|
+
- lib/mock/twilio/webhooks/messages.rb
|
46
92
|
- sig/mock/twilio.rbs
|
47
93
|
homepage: https://github.com/schoolstatus/mock-twilio
|
48
94
|
licenses:
|