http_stub 0.16.0.pre1 → 0.17.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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")