mock-twilio 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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:
|