http_stub 0.1.4 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -7,7 +7,11 @@ require 'immutable_struct'
7
7
  require 'net/http'
8
8
  require 'json'
9
9
 
10
- require File.expand_path('../http_stub/stub', __FILE__)
11
- require File.expand_path('../http_stub/registry', __FILE__)
10
+ require File.expand_path('../http_stub/response', __FILE__)
11
+ require File.expand_path('../http_stub/models/stub', __FILE__)
12
+ require File.expand_path('../http_stub/models/alias', __FILE__)
13
+ require File.expand_path('../http_stub/models/registry', __FILE__)
14
+ require File.expand_path('../http_stub/controllers/stub_controller', __FILE__)
15
+ require File.expand_path('../http_stub/controllers/alias_controller', __FILE__)
12
16
  require File.expand_path('../http_stub/server', __FILE__)
13
- require File.expand_path('../http_stub/client', __FILE__)
17
+ require File.expand_path('../http_stub/configurer', __FILE__)
@@ -0,0 +1,75 @@
1
+ module HttpStub
2
+
3
+ module Configurer
4
+
5
+ def self.included(mod)
6
+ mod.extend(HttpStub::Configurer::ClassMethods)
7
+ mod.send(:include, HttpStub::Configurer::InstanceMethods)
8
+ end
9
+
10
+ module ClassMethods
11
+
12
+ def host(host)
13
+ @host = host
14
+ end
15
+
16
+ def port(port)
17
+ @port = port
18
+ end
19
+
20
+ def stub_alias(alias_uri, stub_uri, options)
21
+ response_options = options[:response]
22
+ request = Net::HTTP::Post.new("/stubs/aliases")
23
+ request.content_type = "application/json"
24
+ request.body = {
25
+ "alias_uri" => alias_uri,
26
+ "uri" => stub_uri,
27
+ "method" => options[:method],
28
+ "parameters" => options[:parameters] || {},
29
+ "response" => {
30
+ "status" => response_options[:status] || "200",
31
+ "body" => response_options[:body]
32
+ }
33
+ }.to_json
34
+ response = submit(request)
35
+ raise "Unable to establish stub alias: #{response.message}" unless response.code == "200"
36
+ end
37
+
38
+ def submit(request)
39
+ Net::HTTP.new(@host, @port).start { |http| http.request(request) }
40
+ end
41
+
42
+ end
43
+
44
+ module InstanceMethods
45
+
46
+ def stub!(uri, options)
47
+ response_options = options[:response]
48
+ request = Net::HTTP::Post.new("/stubs")
49
+ request.content_type = "application/json"
50
+ request.body = {
51
+ "uri" => uri,
52
+ "method" => options[:method],
53
+ "parameters" => options[:parameters] || {},
54
+ "response" => {
55
+ "status" => response_options[:status] || "200",
56
+ "body" => response_options[:body]
57
+ }
58
+ }.to_json
59
+ response = self.class.submit(request)
60
+ raise "Unable to establish stub: #{response.message}" unless response.code == "200"
61
+ end
62
+
63
+ alias_method :stub_response!, :stub!
64
+
65
+ def clear!
66
+ request = Net::HTTP::Delete.new("/stubs")
67
+ response = self.class.submit(request)
68
+ raise "Unable to clear stubs: #{response.message}" unless response.code == "200"
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,29 @@
1
+ module HttpStub
2
+ module Controllers
3
+
4
+ class AliasController
5
+
6
+ def initialize(alias_registry, stub_registry)
7
+ @alias_registry = alias_registry
8
+ @stub_registry = stub_registry
9
+ end
10
+
11
+ def register(request)
12
+ @alias_registry.add(HttpStub::Models::Alias.new(request.body.read), request)
13
+ HttpStub::Response::SUCCESS
14
+ end
15
+
16
+ def activate(request)
17
+ the_alias = @alias_registry.find_for(request)
18
+ if the_alias
19
+ @stub_registry.add(the_alias.the_stub, request)
20
+ HttpStub::Response::SUCCESS
21
+ else
22
+ HttpStub::Response::EMPTY
23
+ end
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,27 @@
1
+ module HttpStub
2
+ module Controllers
3
+
4
+ class StubController
5
+
6
+ def initialize(registry)
7
+ @registry = registry
8
+ end
9
+
10
+ def register(request)
11
+ @registry.add(HttpStub::Models::Stub.new(request.body.read), request)
12
+ HttpStub::Response::SUCCESS
13
+ end
14
+
15
+ def replay(request)
16
+ stub = @registry.find_for(request)
17
+ stub ? stub.response : HttpStub::Response::EMPTY
18
+ end
19
+
20
+ def clear(request)
21
+ @registry.clear(request)
22
+ end
23
+
24
+ end
25
+
26
+ end
27
+ end
@@ -0,0 +1,22 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class Alias
5
+
6
+ def initialize(request_body)
7
+ @data = JSON.parse(request_body)
8
+ @stub = HttpStub::Models::Stub.new(request_body)
9
+ end
10
+
11
+ def satisfies?(request)
12
+ @data["alias_uri"] == request.path_info
13
+ end
14
+
15
+ def the_stub
16
+ @stub
17
+ end
18
+
19
+ end
20
+
21
+ end
22
+ end
@@ -0,0 +1,29 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class Registry
5
+
6
+ def initialize(model_name)
7
+ @model_name = model_name
8
+ @models = []
9
+ end
10
+
11
+ def add(model, request)
12
+ @models.unshift(model)
13
+ request.logger.info "Registered #{@model_name}: #{model}"
14
+ end
15
+
16
+ def find_for(request)
17
+ request.logger.info "Finding #{@model_name} satisfying: #{request.inspect}"
18
+ @models.find { |model| model.satisfies?(request) }
19
+ end
20
+
21
+ def clear(request)
22
+ request.logger.info "Clearing #{@model_name} registry"
23
+ @models.clear
24
+ end
25
+
26
+ end
27
+
28
+ end
29
+ end
@@ -0,0 +1,35 @@
1
+ module HttpStub
2
+ module Models
3
+
4
+ class Stub
5
+
6
+ attr_reader :response
7
+
8
+ def initialize(request_body)
9
+ @data = JSON.parse(request_body)
10
+ @response = HttpStub::Response.new(status: @data["response"]["status"], body: @data["response"]["body"])
11
+ end
12
+
13
+ def satisfies?(request)
14
+ @data["uri"] == request.path_info &&
15
+ @data["method"].downcase == request.request_method.downcase &&
16
+ parameters_match?(request)
17
+ end
18
+
19
+ def to_s
20
+ @data.to_s
21
+ end
22
+
23
+ private
24
+
25
+ def parameters_match?(request)
26
+ parameters = @data["parameters"]
27
+ parameters.nil? || parameters.reduce(true) do |result, parameter|
28
+ result && (request.params[parameter[0]] == parameter[1])
29
+ end
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+ end
@@ -0,0 +1,14 @@
1
+ module HttpStub
2
+
3
+ class Response < ImmutableStruct.new(:status, :body)
4
+ SUCCESS = HttpStub::Response.new(status: 200, body: "")
5
+ ERROR = HttpStub::Response.new(status: 404, body: "")
6
+ EMPTY = HttpStub::Response.new()
7
+
8
+ def empty?
9
+ self == HttpStub::Response::EMPTY
10
+ end
11
+
12
+ end
13
+
14
+ end
@@ -6,7 +6,10 @@ module HttpStub
6
6
 
7
7
  def initialize
8
8
  super()
9
- @registry = HttpStub::Registry.new
9
+ @stub_registry = HttpStub::Models::Registry.new("stub")
10
+ @alias_registry = HttpStub::Models::Registry.new("alias")
11
+ @stub_controller = HttpStub::Controllers::StubController.new(@stub_registry)
12
+ @alias_controller = HttpStub::Controllers::AliasController.new(@alias_registry, @stub_registry)
10
13
  end
11
14
 
12
15
  private
@@ -32,23 +35,35 @@ module HttpStub
32
35
  # "body": "Hello World"
33
36
  # }
34
37
  # }
35
- post "/stub" do
36
- @registry.add(HttpStub::Stub.new(request), request)
37
- halt 200
38
+ post "/stubs" do
39
+ response = @stub_controller.register(request)
40
+ halt(response.status, response.body)
41
+ end
42
+
43
+ # Sample request body:
44
+ # {
45
+ # "alias_uri": "/some/path",
46
+ # ... see /stub ...
47
+ # }
48
+ post "/stubs/aliases" do
49
+ response = @alias_controller.register(request)
50
+ halt(response.status, response.body)
38
51
  end
39
52
 
40
53
  delete "/stubs" do
41
- @registry.clear(request)
54
+ @stub_controller.clear(request)
42
55
  halt 200
43
56
  end
44
57
 
45
- any_request_type(//) { handle_stub_request }
58
+ any_request_type(//) { handle_request }
46
59
 
47
60
  private
48
61
 
49
- def handle_stub_request
50
- stub = @registry.find_for(request)
51
- stub ? halt(stub.response.status, stub.response.body) : halt(404)
62
+ def handle_request
63
+ response = @stub_controller.replay(request)
64
+ response = @alias_controller.activate(request) if response.empty?
65
+ response = HttpStub::Response::ERROR if response.empty?
66
+ halt(response.status, response.body)
52
67
  end
53
68
 
54
69
  end
@@ -1,5 +1,5 @@
1
1
  require File.expand_path('../../http_stub', __FILE__)
2
- require 'rake/tasklib' unless defined?(::Rake::TaskLib)
2
+ require 'rake/tasklib' unless defined? (::Rake::TaskLib)
3
3
 
4
4
  module HttpStub
5
5
 
@@ -1,3 +1,3 @@
1
1
  module HttpStub
2
- VERSION = "0.1.4"
2
+ VERSION = "0.2.0"
3
3
  end
@@ -0,0 +1,119 @@
1
+ describe HttpStub::Configurer do
2
+ include_context "server integration"
3
+
4
+ before(:all) do
5
+ class TestConfigurer
6
+ include HttpStub::Configurer
7
+
8
+ host "localhost"
9
+ port 8001
10
+
11
+ stub_alias "/an_alias", "/path1", method: :get, response: { status: 200, body: "Stub alias body" }
12
+ end
13
+ end
14
+
15
+ let(:configurer) { TestConfigurer.new }
16
+
17
+ after(:each) { configurer.clear! }
18
+
19
+ describe "when a stub alias is activated" do
20
+
21
+ before(:each) { Net::HTTP.get_response("localhost", "/an_alias", 8001) }
22
+
23
+ describe "and the stub request is made" do
24
+
25
+ let(:response) { Net::HTTP.get_response("localhost", "/path1", 8001) }
26
+
27
+ it "should replay the stubbed response" do
28
+ response.code.should eql("200")
29
+ response.body.should eql("Stub alias body")
30
+ end
31
+
32
+ end
33
+
34
+ end
35
+
36
+ describe "when a stub alias is not activated" do
37
+
38
+ describe "and the stub request is made" do
39
+
40
+ let(:response) { Net::HTTP.get_response("localhost", "/path1", 8001) }
41
+
42
+ it "should respond with a 404 status code" do
43
+ response.code.should eql("404")
44
+ end
45
+
46
+ end
47
+
48
+ end
49
+
50
+ describe "when a response for a request is stubbed" do
51
+
52
+ describe "that contains no parameters" do
53
+
54
+ before(:each) do
55
+ configurer.stub_response!("/path2", method: :get, response: { status: 201, body: "Stub body" })
56
+ end
57
+
58
+ describe "and that request is made" do
59
+
60
+ let(:response) { Net::HTTP.get_response("localhost", "/path2", 8001) }
61
+
62
+ it "should replay the stubbed response" do
63
+ response.code.should eql("201")
64
+ response.body.should eql("Stub body")
65
+ end
66
+
67
+ end
68
+
69
+ describe "and the stub is cleared" do
70
+
71
+ before(:each) { configurer.clear! }
72
+
73
+ describe "and the original request is made" do
74
+
75
+ let(:response) { Net::HTTP.get_response("localhost", "/path2", 8001) }
76
+
77
+ it "should respond with a 404 status code" do
78
+ response.code.should eql("404")
79
+ end
80
+
81
+ end
82
+
83
+ end
84
+
85
+ end
86
+
87
+ describe "that contains parameters" do
88
+
89
+ before(:each) do
90
+ configurer.stub_response!("/path3", method: :get, parameters: { key: "value" },
91
+ response: { status: 202, body: "Another stub body" })
92
+ end
93
+
94
+ describe "and that request is made" do
95
+
96
+ let(:response) { Net::HTTP.get_response("localhost", "/path3?key=value", 8001) }
97
+
98
+ it "should replay the stubbed response" do
99
+ response.code.should eql("202")
100
+ response.body.should eql("Another stub body")
101
+ end
102
+
103
+ end
104
+
105
+ describe "and a request with different parameters is made" do
106
+
107
+ let(:response) { Net::HTTP.get_response("localhost", "/path3?key=another_value", 8001) }
108
+
109
+ it "should respond with a 404 status code" do
110
+ response.code.should eql("404")
111
+ end
112
+
113
+ end
114
+
115
+ end
116
+
117
+ end
118
+
119
+ end
@@ -0,0 +1,75 @@
1
+ describe HttpStub::Controllers::AliasController do
2
+
3
+ let(:request_body) { "Some request body" }
4
+ let(:request) { double("HttpRequest", body: double("RequestBody", read: request_body)) }
5
+ let(:the_stub) { double(HttpStub::Models::Stub) }
6
+ let(:stub_alias) { double(HttpStub::Models::Alias, the_stub: the_stub) }
7
+ let(:alias_registry) { double("HttpStub::Models::AliasRegistry").as_null_object }
8
+ let(:stub_registry) { double("HttpStub::Models::StubRegistry").as_null_object }
9
+ let(:controller) { HttpStub::Controllers::AliasController.new(alias_registry, stub_registry) }
10
+
11
+ describe "#register" do
12
+
13
+ before(:each) do
14
+ HttpStub::Models::Alias.stub!(:new).and_return(stub_alias)
15
+ end
16
+
17
+ it "should create an alias from the request body" do
18
+ HttpStub::Models::Alias.should_receive(:new).with(request_body).and_return(stub_alias)
19
+
20
+ controller.register(request)
21
+ end
22
+
23
+ it "should add the created alias to the alias registry" do
24
+ alias_registry.should_receive(:add).with(stub_alias, request)
25
+
26
+ controller.register(request)
27
+ end
28
+
29
+ it "should return a success response" do
30
+ controller.register(request).should eql(HttpStub::Response::SUCCESS)
31
+ end
32
+
33
+ end
34
+
35
+ describe "#activate" do
36
+
37
+ describe "when an alias has been registered that is activated by the request" do
38
+
39
+ before(:each) do
40
+ alias_registry.stub!(:find_for).with(request).and_return(stub_alias)
41
+ end
42
+
43
+ it "should add the aliases stub to the stub registry" do
44
+ stub_registry.should_receive(:add).with(the_stub, request)
45
+
46
+ controller.activate(request)
47
+ end
48
+
49
+ it "should return a success response" do
50
+ controller.activate(request).should eql(HttpStub::Response::SUCCESS)
51
+ end
52
+
53
+ end
54
+
55
+ describe "when no alias is activated by the request" do
56
+
57
+ before(:each) do
58
+ alias_registry.stub!(:find_for).with(request).and_return(nil)
59
+ end
60
+
61
+ it "should not add a stub to the registry" do
62
+ stub_registry.should_not_receive(:add)
63
+
64
+ controller.activate(request)
65
+ end
66
+
67
+ it "should return an empty response" do
68
+ controller.activate(request).should eql(HttpStub::Response::EMPTY)
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end