http_stub 0.16.0.pre1 → 0.17.0.pre1

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.
Files changed (40) hide show
  1. checksums.yaml +13 -5
  2. data/lib/http_stub.rb +10 -5
  3. data/lib/http_stub/configurer.rb +1 -21
  4. data/lib/http_stub/configurer/dsl/{sanctioned.rb → server.rb} +7 -1
  5. data/lib/http_stub/configurer/dsl/stub_builder.rb +4 -0
  6. data/lib/http_stub/configurer/request/stub.rb +1 -0
  7. data/lib/http_stub/configurer/server/command_processor.rb +3 -3
  8. data/lib/http_stub/rake/server_tasks.rb +1 -1
  9. data/lib/http_stub/server/daemon.rb +3 -1
  10. data/lib/http_stub/server/stub/instance.rb +3 -2
  11. data/lib/http_stub/server/stub/json_request_body.rb +35 -0
  12. data/lib/http_stub/server/stub/request_body.rb +44 -0
  13. data/lib/http_stub/server/stub/simple_request_body.rb +23 -0
  14. data/lib/http_stub/server/stub/truthy_request_matcher.rb +23 -0
  15. data/lib/http_stub/server/views/_stub.haml +3 -0
  16. data/lib/http_stub/version.rb +1 -1
  17. data/spec/acceptance/configurer_initialization_spec.rb +1 -1
  18. data/spec/acceptance/stub_body_schema_validation_spec.rb +67 -0
  19. data/spec/acceptance/stub_control_values_spec.rb +2 -2
  20. data/spec/acceptance/stub_spec.rb +1 -1
  21. data/spec/lib/http_stub/configurer/dsl/{sanctioned_spec.rb → server_spec.rb} +34 -15
  22. data/spec/lib/http_stub/configurer/dsl/stub_builder_spec.rb +18 -0
  23. data/spec/lib/http_stub/configurer/request/stub_spec.rb +52 -20
  24. data/spec/lib/http_stub/configurer/server/command_processor_integration_spec.rb +7 -4
  25. data/spec/lib/http_stub/rake/server_tasks_smoke_spec.rb +54 -13
  26. data/spec/lib/http_stub/server/application_integration_spec.rb +22 -2
  27. data/spec/lib/http_stub/server/daemon_integration_spec.rb +1 -1
  28. data/spec/lib/http_stub/server/daemon_spec.rb +50 -2
  29. data/spec/lib/http_stub/server/stub/instance_spec.rb +44 -10
  30. data/spec/lib/http_stub/server/stub/json_request_body_spec.rb +102 -0
  31. data/spec/lib/http_stub/server/stub/request_body_spec.rb +120 -0
  32. data/spec/lib/http_stub/server/stub/simple_request_body_spec.rb +43 -0
  33. data/spec/lib/http_stub/server/stub/string_value_matcher_spec.rb +2 -2
  34. data/spec/lib/http_stub/server/stub/truthy_request_matcher_spec.rb +23 -0
  35. data/spec/lib/http_stub/server/stub/uri_spec.rb +1 -1
  36. data/spec/spec_helper.rb +3 -2
  37. data/spec/support/configurer_integration.rb +2 -2
  38. data/spec/support/stub_fixture.rb +2 -1
  39. metadata +307 -281
  40. data/spec/lib/http_stub/configurer_spec.rb +0 -22
checksums.yaml CHANGED
@@ -1,7 +1,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: e089a8fb77ad42e2691e6c05fe6a2d766ac07626
4
- data.tar.gz: 5bb5f0740862f3e106b5fc9015c85fddb3452d49
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ YTlmNDUyNWZjZjhjODYwMjcyNDViZWE1MDY4NzljZTc3MDJhYmYxMA==
5
+ data.tar.gz: !binary |-
6
+ ZTdhZmExMjY3NTBkNzZmZGMwYTdjMTJhZWM1ODAzMzcyZWZhZThmOQ==
5
7
  SHA512:
6
- metadata.gz: 51fb2fc9c208dc1af31405a5bc1520c743693cf155a6834d6a555d414c5cf1d722b7eca43edb2c3e7d2e60d8bf7d589776b8f7499097f3d026edf4c3ee416031
7
- data.tar.gz: 3403a0f714d40df0e387332213695d672f0f443adff2031b061bd65f46a6b17e989c1bb47677b1842febdf2a5cd3edd71ac7a2fb1a903bc26189226f387a116c
8
+ metadata.gz: !binary |-
9
+ ZWI2MDc1ZThkNjQ4OWE2YWQ4YWM3MjM1YThlYzc5ZTg4OWE1MzFmM2EyZGUx
10
+ N2ZiM2Q5Y2ZhN2I3MGQ2ZGUzNTdmM2ViM2M0MGQwNDI5ODZhMTdjODM5MjBl
11
+ ZjMyNmMwMTJkMWNmNjk4MTk3NDg5ZGIxNTRlYmFiNDk1MzJjYWI=
12
+ data.tar.gz: !binary |-
13
+ OWI1OGY4MzNiOGU3MjdkNGFmZDgxNjRhMjlkNmIxZjA5N2FmYjc0NDE3MmM5
14
+ NThiZDAyNzQzNTRjMTBjODFlMTA3MDJhZGEwMjUwZmUxMTBjOTcxNWMwZDhm
15
+ NWVlYzgxMzIwNWYxZmJhZTk5NWUxOWUzZTYzMTQzOTdhNjJiZTQ=
data/lib/http_stub.rb CHANGED
@@ -1,11 +1,12 @@
1
1
  require 'sinatra'
2
2
  require 'sinatra/partial'
3
- require 'haml'
4
- require 'sass'
5
3
  require 'json'
6
4
  require 'net/http'
7
5
  require 'net/http/post/multipart'
6
+ require 'json-schema'
8
7
  require 'http_server_manager'
8
+ require 'haml'
9
+ require 'sass'
9
10
 
10
11
  require 'active_support/core_ext/module/aliasing'
11
12
  require 'active_support/core_ext/module/delegation'
@@ -28,10 +29,14 @@ require_relative 'http_stub/server/stub/headers'
28
29
  require_relative 'http_stub/server/stub/request_header_parser'
29
30
  require_relative 'http_stub/server/stub/payload_file_consolidator'
30
31
  require_relative 'http_stub/server/stub/request_parser'
31
- require_relative 'http_stub/server/stub/method'
32
+ require_relative 'http_stub/server/stub/truthy_request_matcher'
32
33
  require_relative 'http_stub/server/stub/uri'
33
- require_relative 'http_stub/server/stub/request_parameters'
34
+ require_relative 'http_stub/server/stub/method'
34
35
  require_relative 'http_stub/server/stub/request_headers'
36
+ require_relative 'http_stub/server/stub/request_parameters'
37
+ require_relative 'http_stub/server/stub/simple_request_body'
38
+ require_relative 'http_stub/server/stub/json_request_body'
39
+ require_relative 'http_stub/server/stub/request_body'
35
40
  require_relative 'http_stub/server/stub/response/base'
36
41
  require_relative 'http_stub/server/stub/response/text'
37
42
  require_relative 'http_stub/server/stub/response/file'
@@ -70,6 +75,6 @@ require_relative 'http_stub/configurer/dsl/stub_builder_producer'
70
75
  require_relative 'http_stub/configurer/dsl/scenario_activator'
71
76
  require_relative 'http_stub/configurer/dsl/scenario_builder'
72
77
  require_relative 'http_stub/configurer/dsl/stub_activator_builder'
73
- require_relative 'http_stub/configurer/dsl/sanctioned'
78
+ require_relative 'http_stub/configurer/dsl/server'
74
79
  require_relative 'http_stub/configurer/dsl/deprecated'
75
80
  require_relative 'http_stub/configurer'
@@ -10,28 +10,8 @@ module HttpStub
10
10
 
11
11
  module ClassMethods
12
12
 
13
- def get_host
14
- @host
15
- end
16
-
17
- def host(host)
18
- @host = host
19
- end
20
-
21
- def get_port
22
- @port
23
- end
24
-
25
- def port(port)
26
- @port = port
27
- end
28
-
29
- def get_base_uri
30
- "http://#{@host}:#{@port}"
31
- end
32
-
33
13
  def stub_server
34
- @dsl ||= HttpStub::Configurer::DSL::Sanctioned.new(server_facade)
14
+ @stub_server ||= HttpStub::Configurer::DSL::Server.new(server_facade)
35
15
  end
36
16
 
37
17
  def initialize!
@@ -2,15 +2,21 @@ module HttpStub
2
2
  module Configurer
3
3
  module DSL
4
4
 
5
- class Sanctioned
5
+ class Server
6
6
  include HttpStub::Configurer::DSL::StubBuilderProducer
7
7
  include HttpStub::Configurer::DSL::ScenarioActivator
8
8
 
9
+ attr_accessor :host, :port
10
+
9
11
  def initialize(server_facade)
10
12
  @server_facade = server_facade
11
13
  @response_defaults = {}
12
14
  end
13
15
 
16
+ def base_uri
17
+ "http://#{host}:#{port}"
18
+ end
19
+
14
20
  def response_defaults=(args)
15
21
  @response_defaults = args
16
22
  end
@@ -13,6 +13,10 @@ module HttpStub
13
13
  self.tap { @request = { uri: uri }.merge(args) }
14
14
  end
15
15
 
16
+ def schema(type, definition)
17
+ { schema: { type: type, definition: definition } }
18
+ end
19
+
16
20
  def respond_with(args)
17
21
  self.tap { @response.deep_merge!(args) }
18
22
  end
@@ -18,6 +18,7 @@ module HttpStub
18
18
  method: @request[:method],
19
19
  headers: HttpStub::Configurer::Request::ControllableValue.format(@request[:headers] || {}),
20
20
  parameters: HttpStub::Configurer::Request::ControllableValue.format(@request[:parameters] || {}),
21
+ body: HttpStub::Configurer::Request::ControllableValue.format(@request[:body] || {}),
21
22
  response: @response.payload,
22
23
  triggers: @triggers.map(&:payload)
23
24
  }
@@ -20,15 +20,15 @@ module HttpStub
20
20
  private
21
21
 
22
22
  def host
23
- @configurer.get_host
23
+ @configurer.stub_server.host
24
24
  end
25
25
 
26
26
  def port
27
- @configurer.get_port
27
+ @configurer.stub_server.port
28
28
  end
29
29
 
30
30
  def error_message_prefix(command)
31
- "Error occurred #{command.description} whilst configuring #{@configurer.get_base_uri}: "
31
+ "Error occurred #{command.description} whilst configuring #{@configurer.stub_server.base_uri}: "
32
32
  end
33
33
 
34
34
  end
@@ -18,7 +18,7 @@ module HttpStub
18
18
  task(:foreground) do
19
19
  HttpStub::Server::Application.instance_eval do
20
20
  set :environment, :test
21
- set :port, args[:port]
21
+ set :port, args[:configurer] ? args[:configurer].stub_server.port : args[:port]
22
22
  run!
23
23
  end
24
24
  end
@@ -16,8 +16,10 @@ module HttpStub
16
16
  end
17
17
 
18
18
  def initialize(args)
19
- super({ host: "localhost" }.merge(args))
20
19
  @configurer = args[:configurer]
20
+ default_args = @configurer ?
21
+ { host: @configurer.stub_server.host, port: @configurer.stub_server.port } : { host: "localhost" }
22
+ super(default_args.merge(args))
21
23
  end
22
24
 
23
25
  def start!
@@ -4,20 +4,21 @@ module HttpStub
4
4
 
5
5
  class Instance
6
6
 
7
- attr_reader :method, :uri, :headers, :parameters, :response, :triggers
7
+ attr_reader :method, :uri, :headers, :parameters, :body, :response, :triggers
8
8
 
9
9
  def initialize(args)
10
10
  @method = HttpStub::Server::Stub::Method.new(args["method"])
11
11
  @uri = HttpStub::Server::Stub::Uri.new(args["uri"])
12
12
  @headers = HttpStub::Server::Stub::RequestHeaders.new(args["headers"])
13
13
  @parameters = HttpStub::Server::Stub::RequestParameters.new(args["parameters"])
14
+ @body = HttpStub::Server::Stub::RequestBody.create(args["body"])
14
15
  @response = HttpStub::Server::Stub::Response.create(args["response"])
15
16
  @triggers = HttpStub::Server::Stub::Triggers.new(args["triggers"])
16
17
  @description = args.to_s
17
18
  end
18
19
 
19
20
  def satisfies?(request)
20
- [ @uri, @method, @headers, @parameters ].all? { |matcher| matcher.match?(request) }
21
+ [ @uri, @method, @headers, @parameters, @body ].all? { |matcher| matcher.match?(request) }
21
22
  end
22
23
 
23
24
  def to_s
@@ -0,0 +1,35 @@
1
+ module HttpStub
2
+ module Server
3
+ module Stub
4
+
5
+ class JsonRequestBody
6
+
7
+ def initialize(schema_definition)
8
+ @schema_definition = schema_definition
9
+ end
10
+
11
+ def match?(request)
12
+ validate_against_schema(request).tap do |errors|
13
+ errors.each { |error| request.logger.info(error) }
14
+ end.empty?
15
+ end
16
+
17
+ def to_s
18
+ @schema_definition.to_json
19
+ end
20
+
21
+ private
22
+
23
+ def validate_against_schema(request)
24
+ begin
25
+ JSON::Validator.fully_validate(@schema_definition, request.body.read, validate_schema: true, json: true)
26
+ rescue Exception => exc
27
+ [ exc.message ]
28
+ end
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,44 @@
1
+ module HttpStub
2
+ module Server
3
+ module Stub
4
+
5
+ class RequestBody
6
+
7
+ private
8
+
9
+ SCHEMA_PROPERTIES = %w{ type definition }.freeze
10
+
11
+ public
12
+
13
+ class << self
14
+
15
+ def create(body)
16
+ matcher = create_schema_request_body(body["schema"]) if body.is_a?(Hash) && body["schema"]
17
+ matcher ||= HttpStub::Server::Stub::SimpleRequestBody.new(body) if !body.blank?
18
+ matcher || HttpStub::Server::Stub::TruthyRequestMatcher
19
+ end
20
+
21
+ private
22
+
23
+ def create_schema_request_body(schema)
24
+ validate_schema_properties(schema)
25
+ begin
26
+ HttpStub::Server::Stub.const_get("#{schema["type"].capitalize}RequestBody").new(schema["definition"])
27
+ rescue NameError
28
+ raise "Stub request body schema #{schema} is invalid: #{schema["type"]} schema is not supported"
29
+ end
30
+ end
31
+
32
+ def validate_schema_properties(schema)
33
+ SCHEMA_PROPERTIES.each do |property|
34
+ raise "Stub request body schema #{schema} is invalid: #{property} expected" unless schema[property]
35
+ end
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,23 @@
1
+ module HttpStub
2
+ module Server
3
+ module Stub
4
+
5
+ class SimpleRequestBody
6
+
7
+ def initialize(body)
8
+ @body = HttpStub::Server::Stub::StringValueMatcher.new(body)
9
+ end
10
+
11
+ def match?(request)
12
+ @body.match?(request.body.read)
13
+ end
14
+
15
+ def to_s
16
+ @body.to_s
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ module HttpStub
2
+ module Server
3
+ module Stub
4
+
5
+ class TruthyRequestMatcher
6
+
7
+ class << self
8
+
9
+ def match?(_request)
10
+ true
11
+ end
12
+
13
+ def to_s
14
+ ""
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
23
+ end
@@ -11,6 +11,9 @@
11
11
  %tr
12
12
  %td Parameters:
13
13
  %td=h(the_stub.parameters)
14
+ %tr
15
+ %td Body:
16
+ %td=h(the_stub.body)
14
17
  %tr
15
18
  %td Response Status:
16
19
  %td=the_stub.response.status
@@ -1,3 +1,3 @@
1
1
  module HttpStub
2
- VERSION = "0.16.0.pre1".freeze
2
+ VERSION = "0.17.0.pre1".freeze
3
3
  end
@@ -9,7 +9,7 @@ describe "Configurer initialization acceptance" do
9
9
 
10
10
  context "that contains a class stub" do
11
11
 
12
- let(:configurer) { HttpStub::Examples::ConfigurerWithStub.new }
12
+ let(:configurer) { HttpStub::Examples::ConfigurerWithTrivialStub.new }
13
13
 
14
14
  it "registers the stub" do
15
15
  response = HTTParty.get("#{server_uri}/a_class_stub")
@@ -0,0 +1,67 @@
1
+ describe "Scenario acceptance" do
2
+ include_context "configurer integration"
3
+
4
+ context "when a configurer that contains a stub matching a request body schema" do
5
+
6
+ let(:configurer) { HttpStub::Examples::ConfigurerWithSchemaValidatingStub.new }
7
+
8
+ before(:example) { configurer.class.initialize! }
9
+
10
+ context "and a request is made with a request body" do
11
+
12
+ context "that completely matches" do
13
+
14
+ let(:response) do
15
+ issue_request(body: { string_property: "some string",
16
+ integer_property: 88,
17
+ float_property: 77.7 }.to_json)
18
+ end
19
+
20
+ it "responds with the configured response" do
21
+ expect(response.code).to eql(204)
22
+ end
23
+
24
+ end
25
+
26
+ context "that partially matches" do
27
+
28
+ let(:response) do
29
+ issue_request(body: { string_property: "some string",
30
+ integer_property: 88 }.to_json)
31
+ end
32
+
33
+ it "responds with a 404 status code" do
34
+ expect(response.code).to eql(404)
35
+ end
36
+
37
+ end
38
+
39
+ context "that is completely different" do
40
+
41
+ let(:response) { issue_request(body: { some_other_key: "some string" }.to_json) }
42
+
43
+ it "responds with a 404 status code" do
44
+ expect(response.code).to eql(404)
45
+ end
46
+
47
+ end
48
+
49
+ context "that is empty" do
50
+
51
+ let(:response) { issue_request(body: {}) }
52
+
53
+ it "responds with a 404 status code" do
54
+ expect(response.code).to eql(404)
55
+ end
56
+
57
+ end
58
+
59
+ end
60
+
61
+ def issue_request(args)
62
+ HTTParty.post("#{server_uri}/matches_on_body_schema", args)
63
+ end
64
+
65
+ end
66
+
67
+ end
@@ -1,7 +1,7 @@
1
1
  describe "Stub control value acceptance" do
2
2
  include_context "configurer integration"
3
3
 
4
- let(:configurer) { HttpStub::Examples::ConfigurerWithStub.new }
4
+ let(:configurer) { HttpStub::Examples::ConfigurerWithTrivialStub.new }
5
5
 
6
6
  before(:example) { configurer.class.initialize! }
7
7
 
@@ -145,7 +145,7 @@ describe "Stub control value acceptance" do
145
145
  configurer.stub_response!("/some_stub_path", method: :get, response: { delay_in_seconds: 2 })
146
146
  end
147
147
 
148
- it "delays to response by the time provided" do
148
+ it "delays the response by the time provided" do
149
149
  start_time = Time.now
150
150
 
151
151
  response = HTTParty.get("#{server_uri}/some_stub_path")