erithmetic-mountebank 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 5dae41e4f0fcd04086d1d174fac9a46f6b5dc4872e214a81cc5311284a67d5fc
4
+ data.tar.gz: 8d29433c98194dea11895138e880af203651e78453316b2c4270720d8c168110
5
+ SHA512:
6
+ metadata.gz: 21bfbc0344bb4e8a0fc4f3ffe0af91007b731ae32a0a6c072e94448ccc1dda30510b73999482474fbc9b8f80abb2f3602ffa96f9a2b80c26dd73fac0b747600d
7
+ data.tar.gz: 5d1b8b87cd02c468500211e1bd5a67e713cd6cad2b6d71560c548f6d7bd5861e258b4863aafdbaa3d65714fcf4b74cb54002d7931cab03d840e22046c64f442e
data/.env ADDED
@@ -0,0 +1,2 @@
1
+ MOUNTEBANK_SERVER=127.0.0.1
2
+ MOUNTEBANK_PORT=2525
data/.gitignore ADDED
@@ -0,0 +1,20 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ mb.log
16
+ mb.pid
17
+ tags
18
+ .idea/
19
+ .ruby-version
20
+ .ruby-gemset
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mountebank.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Michael Cheng
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,139 @@
1
+ # Mountebank
2
+
3
+ A simple Ruby library that lets you manage your [Mountebank test server](http://www.mbtest.org/).
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'mountebank'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install mountebank
20
+
21
+ ## Usage
22
+
23
+ ### Pre-Requisite
24
+
25
+ Install Mountebank:
26
+
27
+ ```
28
+ npm install -g mountebank --production
29
+ ```
30
+
31
+ Start Mountebank:
32
+
33
+ ```
34
+ mb --allowInjection
35
+ ```
36
+
37
+ I recommend reading the [Mountebank documentation](http://www.mbtest.org/docs/api/overview) for a deeper understanding of their API.
38
+
39
+ ### Initialization
40
+
41
+ 1. Add these to you environment hash (eg. add to your `.env` file)
42
+
43
+ ```
44
+ MOUNTEBANK_SERVER=127.0.0.1
45
+ MOUNTEBANK_PORT=2525
46
+ ```
47
+
48
+ 2. Require the lib in your `spec_helper`.
49
+
50
+ ```ruby
51
+ require 'mountebank'
52
+ ```
53
+
54
+ ### Get all available imposters
55
+
56
+ ```ruby
57
+ Mountebank.imposters
58
+ ```
59
+
60
+ ### Create Imposter
61
+
62
+ ```ruby
63
+ port = 4545
64
+ protocol = Mountebank::Imposter::PROTOCOL_HTTP
65
+ imposter = Mountebank::Imposter.create(port, protocol)
66
+ ```
67
+
68
+ ### Create Imposter with Stub
69
+
70
+ ```ruby
71
+ port = 4545
72
+ protocol = Mountebank::Imposter::PROTOCOL_HTTP
73
+ imposter = Mountebank::Imposter.build(port, protocol)
74
+
75
+ # Create a response
76
+ status_code = 200
77
+ headers = {"Content-Type" => "application/json"}
78
+ body = {foo:"bar"}.to_json
79
+ response = Mountebank::Stub::HttpResponse.create(status_code, headers, body)
80
+
81
+ imposter.add_stub(response)
82
+ imposter.save!
83
+ ```
84
+
85
+ Check the URL:
86
+ ```
87
+ curl http://127.0.0.1:4545
88
+ ```
89
+
90
+ ### Get all stubs
91
+
92
+ ```ruby
93
+ imposter = Mountbank.imposters.first
94
+ puts imposter.stubs
95
+ ```
96
+
97
+ ### Create Imposter with Stub & Predicate
98
+
99
+ ```ruby
100
+ port = 4545
101
+ protocol = Mountebank::Imposter::PROTOCOL_HTTP
102
+ imposter = Mountebank::Imposter.build(port, protocol)
103
+
104
+ # Create a response
105
+ status_code = 200
106
+ headers = {"Content-Type" => "application/json"}
107
+ body = {foo:"bar2"}.to_json
108
+ response = Mountebank::Stub::HttpResponse.create(status_code, headers, body)
109
+
110
+ # Create a predicate
111
+ data = {equals: {path:"/test"}}
112
+ predicate = Mountebank::Stub::Predicate.new(data)
113
+
114
+ imposter.add_stub(response, predicate)
115
+ imposter.save!
116
+ ```
117
+
118
+ Check the URL:
119
+ ```
120
+ curl http://127.0.0.1:4545/test
121
+ ```
122
+
123
+ ### Create a response with behaviors
124
+ [Behaviors](http://www.mbtest.org/docs/api/behaviors) can be passed through when creating a stub http response.
125
+ ```ruby
126
+ response = Mountebank::Stub::HttpResponse.create(status_code, headers, body, {wait: 1000}) # Wait 1 second before responding
127
+ ```
128
+
129
+ ## Running Specs
130
+
131
+ The current set of specs require the Mountebank instance to be started with the `--mock` flag.
132
+
133
+ ## Contributing
134
+
135
+ 1. Fork it ( https://github.com/CoderKungfu/mountebank/fork )
136
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
137
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
138
+ 4. Push to the branch (`git push origin my-new-feature`)
139
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,13 @@
1
+ require "bundler/gem_tasks"
2
+ require 'dotenv/tasks'
3
+
4
+ require 'rspec/core/rake_task'
5
+
6
+ desc "Run all specs"
7
+ RSpec::Core::RakeTask.new(:spec) do |t|
8
+ t.rspec_opts = %w[--color]
9
+ t.verbose = false
10
+ end
11
+
12
+ task :default => [:dotenv, :spec]
13
+
@@ -0,0 +1,39 @@
1
+ require 'faraday'
2
+
3
+ module Mountebank
4
+ class Helper
5
+ # Convert Ruby Hash keys into symbols
6
+ # Source: https://gist.github.com/Integralist/9503099
7
+ def self.symbolize(obj)
8
+ return obj.reduce({}) do |memo, (k, v)|
9
+ memo.tap { |m| m[k.to_sym] = symbolize(v) }
10
+ end if obj.is_a? Hash
11
+
12
+ return obj.reduce([]) do |memo, v|
13
+ memo << symbolize(v); memo
14
+ end if obj.is_a? Array
15
+
16
+ obj
17
+ end
18
+ end
19
+
20
+ class SymbolizeKeys < ::Faraday::Middleware
21
+ def initialize(app = nil, options = {})
22
+ super(app)
23
+ @options = options
24
+ @content_types = Array(options[:content_type])
25
+ end
26
+
27
+ def call(environment)
28
+ @app.call(environment).on_complete do |env|
29
+ if env[:body].is_a? Hash
30
+ env[:body] = Helper.symbolize(env[:body])
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ if ::Faraday::Middleware.respond_to? :register_middleware
37
+ ::Faraday::Response.register_middleware :symbolize_keys => lambda { Mountebank::SymbolizeKeys }
38
+ end
39
+ end
@@ -0,0 +1,134 @@
1
+ module Mountebank
2
+ class Imposter
3
+ attr_reader :port, :protocol, :name, :stubs, :requests, :matches, :mode, :record_requests
4
+
5
+ PROTOCOL_HTTP = 'http'
6
+ PROTOCOL_HTTPS = 'https'
7
+ PROTOCOL_SMTP = 'smtp'
8
+ PROTOCOL_TCP = 'tcp'
9
+
10
+ PROTOCOLS = [
11
+ PROTOCOL_HTTP,
12
+ PROTOCOL_HTTPS,
13
+ PROTOCOL_SMTP,
14
+ PROTOCOL_TCP
15
+ ]
16
+
17
+ CREATE_PARAMS_HTTP = [:protocol, :port, :name, :stubs]
18
+ CREATE_PARAMS_HTTPS = [:protocol, :port, :name, :stubs]
19
+ CREATE_PARAMS_TCP = [:protocol, :mode, :mode, :name, :stubs]
20
+ CREATE_PARAMS_SMTP = [:protocol, :port, :name]
21
+
22
+ def initialize(data={})
23
+ set_attributes(data)
24
+ end
25
+
26
+ def self.build(port, protocol=PROTOCOL_HTTP, options={})
27
+ raise 'Invalid port number' unless port.is_a? Integer
28
+ raise 'Invalid protocol' unless PROTOCOLS.include?(protocol)
29
+
30
+ data = {port: port, protocol: protocol}.merge(options)
31
+ Mountebank::Imposter.new(data)
32
+ end
33
+
34
+ def save!
35
+ delete!
36
+ response = Network.post('/imposters', replayable_data)
37
+ return reload if response.success?
38
+
39
+ false
40
+ end
41
+
42
+ def self.create(port, protocol=PROTOCOL_HTTP, options={})
43
+ self.build(port, protocol, options).save!
44
+ end
45
+
46
+ def self.find(port)
47
+ imposter_data = Imposter.get_imposter_config(port)
48
+ return Mountebank::Imposter.new(imposter_data) unless imposter_data.empty?
49
+
50
+ false
51
+ end
52
+
53
+ def self.delete(port)
54
+ response = Network.delete("/imposters/#{port}")
55
+ response.success? && !response.body.empty?
56
+ end
57
+
58
+ def delete!
59
+ Imposter.delete(@port)
60
+ end
61
+
62
+ def reload
63
+ data = Imposter.get_imposter_config(@port)
64
+ set_attributes(data) unless data.empty?
65
+
66
+ self
67
+ end
68
+
69
+ def add_stub(response=nil, predicate=nil)
70
+ responses, predicates = [], []
71
+
72
+ if response.is_a? Array
73
+ responses = response
74
+ elsif response.is_a? Mountebank::Stub::Response
75
+ responses << response
76
+ end
77
+
78
+ if predicate.is_a? Array
79
+ predicates = predicate
80
+ elsif predicate.is_a? Mountebank::Stub::Predicate
81
+ predicates << predicate
82
+ end
83
+
84
+ @stubs << Mountebank::Stub.create(responses, predicates)
85
+ end
86
+
87
+ def replayable_data
88
+ data = serializable_hash
89
+ data.delete(:requests)
90
+ data.delete(:matches)
91
+
92
+ data
93
+ end
94
+
95
+ def to_json(*args)
96
+ serializable_hash.to_json(*args)
97
+ end
98
+
99
+ private
100
+
101
+ def serializable_hash
102
+ data = {port: @port, protocol: @protocol, name: @name}
103
+ data[:stubs] = @stubs unless @stubs.empty?
104
+ data[:requests] = @requests unless @requests.empty?
105
+ data[:matches] = @matches unless @matches.empty?
106
+ data[:mode] = @mode unless @mode.nil?
107
+ data[:recordRequests] = @record_requests unless @record_requests.nil?
108
+
109
+ data
110
+ end
111
+
112
+ def self.get_imposter_config(port)
113
+ response = Network.get("/imposters/#{port}")
114
+ response.success? ? response.body : []
115
+ end
116
+
117
+ def set_attributes(data)
118
+ @port = data[:port]
119
+ @protocol = data[:protocol]
120
+ @name = data[:name] || "imposter_#{@port}"
121
+ @stubs = []
122
+ if data[:stubs].respond_to?(:each)
123
+ data[:stubs].each do |stub|
124
+ stub = Mountebank::Stub.new(stub) unless stub.is_a? Mountebank::Stub
125
+ @stubs << stub
126
+ end
127
+ end
128
+ @requests = data[:requests] || []
129
+ @matches = data[:matches] || []
130
+ @mode = data[:mode] || nil
131
+ @record_requests = data[:record_requests] || data[:recordRequests] || false
132
+ end
133
+ end
134
+ end
@@ -0,0 +1,51 @@
1
+ require 'faraday'
2
+ require 'faraday_middleware'
3
+
4
+ module Mountebank
5
+ class Network
6
+ def self.connection
7
+ @conn ||= Faraday.new(url: mountebank_server_uri) do |conn|
8
+ conn.request :json
9
+ conn.response :symbolize_keys, :content_type => /\bjson$/
10
+ conn.response :json, :content_type => /\bjson$/
11
+ conn.adapter Faraday.default_adapter
12
+ end
13
+ end
14
+
15
+ def self.get(uri)
16
+ connection.get(uri)
17
+ end
18
+
19
+ def self.post(uri, data)
20
+ connection.post do |req|
21
+ req.url uri
22
+ req.body = data
23
+ end
24
+ end
25
+
26
+ def self.put(uri, data)
27
+ connection.put do |req|
28
+ req.url uri
29
+ req.body = data
30
+ end
31
+ end
32
+
33
+ def self.delete(uri)
34
+ connection.delete do |req|
35
+ req.url uri
36
+ end
37
+ end
38
+
39
+ def self.mountebank_server
40
+ ENV['MOUNTEBANK_SERVER'] || 'localhost'
41
+ end
42
+
43
+ def self.mountebank_server_port
44
+ ENV['MOUNTEBANK_PORT'] || '2525'
45
+ end
46
+
47
+ def self.mountebank_server_uri
48
+ "http://#{mountebank_server}:#{mountebank_server_port}"
49
+ end
50
+ end
51
+ end
@@ -0,0 +1,12 @@
1
+ class Mountebank::Stub::HttpResponse < Mountebank::Stub::Response
2
+ def self.create(statusCode=200, headers={}, body='', behaviors={})
3
+ payload = {}
4
+ payload[:statusCode] = statusCode
5
+ payload[:headers] = headers unless headers.empty?
6
+ payload[:body] = body unless body.empty?
7
+
8
+ data = {is: payload}
9
+ data.merge!(_behaviors: behaviors) unless behaviors.empty?
10
+ new(data)
11
+ end
12
+ end
@@ -0,0 +1,2 @@
1
+ class Mountebank::Stub::HttpsResponse < Mountebank::Stub::HttpResponse
2
+ end
@@ -0,0 +1,26 @@
1
+ class Mountebank::Stub::Predicate
2
+ attr_accessor :equals, :deepEquals, :contains, :startsWith, :endsWith, :matches, :exists, :not, :or, :and, :inject, :caseSensitive, :except
3
+
4
+ VALID_OPERATORS = [
5
+ :equals, :deepEquals, :contains, :startsWith, :endsWith, :matches, :exists, :not,
6
+ :or, :and, :inject
7
+ ]
8
+
9
+ def initialize(data={})
10
+ VALID_OPERATORS.each do |key|
11
+ send("#{key}=", data[key]) if data.key?(key)
12
+ end
13
+ @caseSensitive = data[:caseSensitive] || nil
14
+ @except = data[:except] || nil
15
+ end
16
+
17
+ def to_json(*args)
18
+ data = {}
19
+ VALID_OPERATORS.each do |key|
20
+ data[key] = send("#{key}") if instance_variable_defined?("@#{key}")
21
+ end
22
+ data[:caseSensitive] = @caseSensitive unless @caseSensitive.nil?
23
+ data[:except] = @except unless @except.nil?
24
+ data.to_json(*args)
25
+ end
26
+ end
@@ -0,0 +1,14 @@
1
+ class Mountebank::Stub::ProxyResponse < Mountebank::Stub::Response
2
+ PROXY_MODE_ONCE = 'proxyOnce'
3
+ PROXY_MODE_ALWAYS = 'proxyAlways'
4
+
5
+ def self.create(to, mode=PROXY_MODE_ONCE, predicateGenerators=[])
6
+ data = {proxy: {
7
+ to: to,
8
+ mode: mode,
9
+ predicateGenerators: predicateGenerators
10
+ }
11
+ }
12
+ new(data)
13
+ end
14
+ end
@@ -0,0 +1,26 @@
1
+ class Mountebank::Stub::Response
2
+ attr_accessor :is, :proxy, :inject
3
+
4
+ def initialize(data={})
5
+ @is = data[:is] || nil
6
+ @proxy = data[:proxy] || nil
7
+ @inject = data[:inject] || nil
8
+ @behaviors = data[:_behaviors]
9
+ end
10
+
11
+ def self.with_injection(injection='')
12
+ return false if injection.empty?
13
+
14
+ data = {inject:injection}
15
+ new(data)
16
+ end
17
+
18
+ def to_json(*args)
19
+ data = {}
20
+ data[:is] = @is unless @is.nil?
21
+ data[:proxy] = @proxy unless @proxy.nil?
22
+ data[:inject] = @inject unless @inject.nil?
23
+ data[:_behaviors] = @behaviors unless @behaviors.nil?
24
+ data.to_json(*args)
25
+ end
26
+ end
@@ -0,0 +1,9 @@
1
+ class Mountebank::Stub::TcpResponse < Mountebank::Stub::Response
2
+ def self.create(data='')
3
+ payload = {}
4
+ payload[:data] = data unless data.empty?
5
+
6
+ data = {is: payload}
7
+ new(data)
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ class Mountebank::Stub
2
+ attr_reader :responses, :predicates
3
+
4
+ def initialize(data={})
5
+ set_attributes(data)
6
+ end
7
+
8
+ def self.create(responses=[], predicates=[])
9
+ data = {
10
+ :responses => responses,
11
+ :predicates => predicates
12
+ }
13
+ new(data)
14
+ end
15
+
16
+ def to_json(*args)
17
+ data = {}
18
+ data[:responses] = @responses unless @responses.empty?
19
+ data[:predicates] = @predicates unless @predicates.empty?
20
+ data.to_json(*args)
21
+ end
22
+
23
+ private
24
+
25
+ def set_attributes(data={})
26
+ @responses, @predicates = [], []
27
+
28
+ if data[:responses]
29
+ data[:responses].each do |response|
30
+ unless response.is_a? Mountebank::Stub::Response
31
+ response = Mountebank::Stub::Response.new(response)
32
+ end
33
+ @responses << response
34
+ end
35
+ end
36
+
37
+ if data[:predicates]
38
+ data[:predicates].each do |predicate|
39
+ unless predicate.is_a? Mountebank::Stub::Predicate
40
+ predicate = Mountebank::Stub::Predicate.new(predicate)
41
+ end
42
+ @predicates << predicate
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,3 @@
1
+ module Mountebank
2
+ VERSION = "0.0.1"
3
+ end
data/lib/mountebank.rb ADDED
@@ -0,0 +1,34 @@
1
+ require "mountebank/version"
2
+ require "mountebank/helper"
3
+ require "mountebank/network"
4
+ require "mountebank/imposter"
5
+ require "mountebank/stub"
6
+ require "mountebank/stub/response"
7
+ require "mountebank/stub/http_response"
8
+ require "mountebank/stub/https_response"
9
+ require "mountebank/stub/tcp_response"
10
+ require "mountebank/stub/proxy_response"
11
+ require "mountebank/stub/predicate"
12
+ require "json"
13
+
14
+ module Mountebank
15
+ extend self
16
+
17
+ def self.imposters
18
+ imposters = []
19
+
20
+ response = Network.get('/imposters')
21
+ if response.success?
22
+ response.body[:imposters].each do |imposter|
23
+ imposters << Mountebank::Imposter.new(imposter)
24
+ end
25
+ end
26
+
27
+ imposters
28
+ end
29
+
30
+ def self.reset
31
+ response = Network.delete('/imposters')
32
+ response.success?
33
+ end
34
+ end
@@ -0,0 +1,28 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'mountebank/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "erithmetic-mountebank"
8
+ spec.version = Mountebank::VERSION
9
+ spec.authors = ["Michael Cheng", "Erica Kastner"]
10
+ spec.email = ["mcheng.work@gmail.com"]
11
+ spec.summary = %q{Ruby GEM to manage a Mountebank Test Server}
12
+ spec.description = %q{A simple Ruby library that lets you manage your Mountebank test server.}
13
+ spec.homepage = "https://github.com/CoderKungfu/mountebank-gem"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_runtime_dependency "faraday", "~>0.9.0"
22
+ spec.add_runtime_dependency "faraday_middleware"
23
+ spec.add_development_dependency "bundler", "~> 1.7"
24
+ spec.add_development_dependency "rake", "~> 10.0"
25
+ spec.add_development_dependency "dotenv", "~> 1.0.0"
26
+ spec.add_development_dependency "rspec"
27
+ spec.add_development_dependency "pry"
28
+ end