dupe 0.4.9 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +64 -8
- data/lib/dupe/active_resource_extensions.rb +30 -1
- data/lib/dupe/custom_mocks.rb +6 -0
- data/lib/dupe/dupe.rb +10 -1
- data/lib/dupe/mock.rb +45 -14
- data/lib/dupe/network.rb +14 -4
- data/spec/lib_specs/active_resource_extensions_spec.rb +36 -0
- data/spec/lib_specs/{hash_pruner.rb → hash_pruner_spec.rb} +0 -0
- data/spec/lib_specs/mock_definitions_spec.rb +26 -0
- data/spec/lib_specs/mock_spec.rb +43 -13
- data/spec/lib_specs/network_spec.rb +33 -1
- metadata +3 -3
data/README.rdoc
CHANGED
@@ -374,6 +374,10 @@ Similarly:
|
|
374
374
|
|
375
375
|
Dupe knew how to handle simple find by id and find :all lookups from ActiveResource. But what about other requests we might potentially make?
|
376
376
|
|
377
|
+
===GET requests
|
378
|
+
|
379
|
+
In this section, you'll learn how to mock custom GET requests.
|
380
|
+
|
377
381
|
irb# Dupe.create :author, :name => 'Monkey', :published => true
|
378
382
|
==> <#Duped::Author name="Monkey" published=true id=1>
|
379
383
|
|
@@ -384,14 +388,7 @@ Dupe knew how to handle simple find by id and find :all lookups from ActiveResou
|
|
384
388
|
==> ""
|
385
389
|
|
386
390
|
irb# Author.find :all, :from => :published
|
387
|
-
|
388
|
-
from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/network.rb:32:in `match'
|
389
|
-
from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/network.rb:17:in `request'
|
390
|
-
from /Library/Ruby/Gems/1.8/gems/dupe-0.4.0/lib/dupe/active_resource_extensions.rb:15:in `get'
|
391
|
-
from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/custom_methods.rb:57:in `get'
|
392
|
-
from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:632:in `find_every'
|
393
|
-
from /Library/Ruby/Gems/1.8/gems/activeresource-2.3.5/lib/active_resource/base.rb:582:in `find'
|
394
|
-
from (irb):12
|
391
|
+
==> Dupe::Network::RequestNotFoundError: No mocked service response found for '/authors/published.xml'
|
395
392
|
|
396
393
|
Obviously, Dupe had no way of anticipating this possibility. However, you can create your own custom intercept mock for this:
|
397
394
|
|
@@ -472,7 +469,66 @@ We can mock this with the following:
|
|
472
469
|
</author>
|
473
470
|
</authors>
|
474
471
|
|
472
|
+
===POST requests
|
473
|
+
|
474
|
+
Out of the box you get a POST intercept mock:
|
475
|
+
|
476
|
+
irb# Dupe.define :author
|
477
|
+
|
478
|
+
irb# class Author < ActiveResource::Base; self.site = ''; end
|
479
|
+
==> ""
|
480
|
+
|
481
|
+
irb# Author.create :name => "CS Lewis"
|
482
|
+
==> #<Author:0x1a4ca58 @attributes={"name"=>"CS Lewis", "id"=>1}, @prefix_options={}>
|
483
|
+
|
484
|
+
Author.create sent a network POST to /authors.xml and Dupe responded by creating the resource with the requested parameters:
|
485
|
+
|
486
|
+
irb# Dupe.find :authors
|
487
|
+
==> [<#Duped::Author name="CS Lewis" id=1>]
|
488
|
+
|
489
|
+
You can also overwrite the default POST intercept mock for your resource by using the Post method:
|
490
|
+
|
491
|
+
irb# Post %r{/authors\.xml} do |post_data|
|
492
|
+
raise Dupe::UnprocessableEntity.new(:name => " must be present.") unless post_data["name"]
|
493
|
+
Dupe.create :author, post_data
|
494
|
+
end
|
495
|
+
==> #<Dupe::Network::PostMock:0x1a1afe4 @url_pattern=/\/authors\.xml/, @response=#<Proc:0x01a1b084@(irb):13>, @verb=:post>
|
496
|
+
|
497
|
+
Now, when you try to create an Author without a name, it will respond with the appropriate mocked errors.
|
498
|
+
|
499
|
+
irb# Dupe.find(:authors)
|
500
|
+
==> []
|
501
|
+
|
502
|
+
irb# a = Author.create
|
503
|
+
==> a = #<Author:0x1a19fb8 @attributes={}, @errors=#<ActiveResource::Errors:0x1a10bc0 @errors={"base"=>["name must be present."]}, @base=#<Author:0x1a19fb8 ...>>, @prefix_options={}>
|
504
|
+
|
505
|
+
irb# a = a.valid?
|
506
|
+
==> false
|
507
|
+
|
508
|
+
irb# a = a.new?
|
509
|
+
==> true
|
510
|
+
|
511
|
+
Because the resource would invalidate, the Dupe object is not created.
|
512
|
+
|
513
|
+
irb# Dupe.find(:authors)
|
514
|
+
==> []
|
515
|
+
|
516
|
+
When we create the Author with the required attributes, it will now be considered valid.
|
517
|
+
|
518
|
+
irb# a = Author.create :name => "CS Lewis"
|
519
|
+
==> #<Author:0x19f1edc @attributes={"name"=>"CS Lewis", "id"=>1}, @prefix_options={}>
|
520
|
+
|
521
|
+
irb# a.valid?
|
522
|
+
==> true
|
523
|
+
|
524
|
+
irb# a.new?
|
525
|
+
==> false
|
526
|
+
|
527
|
+
Now, Dupe will go ahead and create the resource.
|
475
528
|
|
529
|
+
irb# Dupe.find(:authors)
|
530
|
+
==> [<#Duped::Author name="CS Lewis" id=1>]
|
531
|
+
|
476
532
|
== More
|
477
533
|
|
478
534
|
Consult the API documentation at http://moonmaster9000.github.com/dupe/api/
|
@@ -14,12 +14,41 @@ module ActiveResource #:nodoc:
|
|
14
14
|
rescue
|
15
15
|
mocked_response = Dupe.network.request(:get, path)
|
16
16
|
ActiveResource::HttpMock.respond_to do |mock|
|
17
|
-
mock.get
|
17
|
+
mock.get(path, {}, mocked_response)
|
18
18
|
end
|
19
19
|
response = request(:get, path, build_request_headers(headers, :get))
|
20
20
|
ActiveResource::HttpMock.delete_mock(:get, path)
|
21
21
|
end
|
22
22
|
format.decode(response.body)
|
23
23
|
end
|
24
|
+
|
25
|
+
def post(path, body = '', headers = {}) #:nodoc:
|
26
|
+
begin
|
27
|
+
response = request(:post, path, body.to_s, build_request_headers(headers, :post))
|
28
|
+
|
29
|
+
# if the request threw an exception
|
30
|
+
rescue
|
31
|
+
resource_hash = Hash.from_xml(body)
|
32
|
+
resource_hash = resource_hash[resource_hash.keys.first]
|
33
|
+
resource_hash = {} unless resource_hash.kind_of?(Hash)
|
34
|
+
begin
|
35
|
+
mocked_response, new_path = Dupe.network.request(:post, path, resource_hash)
|
36
|
+
error = false
|
37
|
+
rescue Dupe::UnprocessableEntity => e
|
38
|
+
mocked_response = {:error => e.message.to_s}.to_xml(:root => 'errors')
|
39
|
+
error = true
|
40
|
+
end
|
41
|
+
ActiveResource::HttpMock.respond_to do |mock|
|
42
|
+
if error
|
43
|
+
mock.post(path, {}, mocked_response, 422, "Content-Type" => 'application/xml')
|
44
|
+
else
|
45
|
+
mock.post(path, {}, mocked_response, 201, "Location" => new_path)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
response = request(:post, path, body.to_s, build_request_headers(headers, :post))
|
49
|
+
ActiveResource::HttpMock.delete_mock(:post, path)
|
50
|
+
end
|
51
|
+
response
|
52
|
+
end
|
24
53
|
end
|
25
54
|
end
|
data/lib/dupe/custom_mocks.rb
CHANGED
@@ -97,6 +97,12 @@
|
|
97
97
|
# <id type="integer">2</id>
|
98
98
|
# </author>
|
99
99
|
# </authors>
|
100
|
+
|
101
|
+
|
100
102
|
def Get(url_pattern, &block)
|
101
103
|
Dupe.network.define_service_mock :get, url_pattern, block
|
104
|
+
end
|
105
|
+
|
106
|
+
def Post(url_pattern, &block)
|
107
|
+
Dupe.network.define_service_mock :post, url_pattern, block
|
102
108
|
end
|
data/lib/dupe/dupe.rb
CHANGED
@@ -178,7 +178,12 @@ class Dupe
|
|
178
178
|
:get,
|
179
179
|
%r{^#{model_name.to_s.titleize.constantize.prefix rescue '/'}#{model_name.to_s.pluralize}/(\\d+)\\.xml$},
|
180
180
|
proc {|id| Dupe.find(:#{model_name}) {|resource| resource.id == id.to_i}}
|
181
|
-
)
|
181
|
+
)
|
182
|
+
network.define_service_mock(
|
183
|
+
:post,
|
184
|
+
%r{^#{model_name.to_s.titleize.constantize.prefix rescue '/'}#{model_name.to_s.pluralize}\\.xml$},
|
185
|
+
proc { |post_body| Dupe.create(:#{model_name.to_s}, post_body) }
|
186
|
+
)
|
182
187
|
}
|
183
188
|
eval(mocks)
|
184
189
|
end
|
@@ -509,3 +514,7 @@ class Dupe
|
|
509
514
|
end
|
510
515
|
end
|
511
516
|
end
|
517
|
+
|
518
|
+
class Dupe
|
519
|
+
class UnprocessableEntity < StandardError; end
|
520
|
+
end
|
data/lib/dupe/mock.rb
CHANGED
@@ -26,33 +26,64 @@ class Dupe
|
|
26
26
|
url_pattern =~ url ? true : false
|
27
27
|
end
|
28
28
|
|
29
|
-
def mocked_response(url)
|
29
|
+
def mocked_response(url, body = nil)
|
30
30
|
raise(
|
31
31
|
StandardError,
|
32
32
|
"Tried to mock a response to a non-matched url! This should never occur. My pattern: #{@url_pattern}. Url: #{url}"
|
33
33
|
) unless match?(url)
|
34
34
|
|
35
35
|
grouped_results = url_pattern.match(url)[1..-1]
|
36
|
+
grouped_results << body if body
|
36
37
|
resp = @response.call *grouped_results
|
38
|
+
process_response(resp, url)
|
39
|
+
end
|
37
40
|
|
41
|
+
def process_response(resp, url)
|
42
|
+
raise NotImplementedError, "Need to specify the appropriate mock class: GetMock, PostMock, PutMock or DeleteMock"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
class Dupe
|
49
|
+
class Network
|
50
|
+
class GetMock < Mock #:nodoc:
|
51
|
+
def process_response(resp, url)
|
38
52
|
case resp
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
53
|
+
when NilClass
|
54
|
+
raise ResourceNotFoundError, "Failed with 404: the request '#{url}' returned nil."
|
55
|
+
when Dupe::Database::Record
|
56
|
+
resp = resp.to_xml_safe(:root => resp.__model__.name.to_s)
|
57
|
+
when Array
|
58
|
+
if resp.empty?
|
59
|
+
resp = [].to_xml :root => 'results'
|
60
|
+
else
|
61
|
+
resp = resp.map {|r| HashPruner.prune(r)}.to_xml(:root => resp.first.__model__.name.to_s.pluralize)
|
62
|
+
end
|
49
63
|
end
|
50
|
-
|
51
64
|
Dupe.network.log.add_request @verb, url, resp
|
52
|
-
|
53
65
|
resp
|
54
66
|
end
|
55
|
-
|
56
67
|
end
|
57
68
|
end
|
58
69
|
end
|
70
|
+
|
71
|
+
class Dupe
|
72
|
+
class Network
|
73
|
+
class PostMock < Mock #:nodoc:
|
74
|
+
def process_response(resp, url)
|
75
|
+
case resp
|
76
|
+
when NilClass
|
77
|
+
raise ResourceNotFoundError, "Failed with 404: the request '#{url}' returned nil."
|
78
|
+
when Dupe::Database::Record
|
79
|
+
new_path = "/#{resp.__model__.name.to_s.pluralize}/#{resp.id}.xml"
|
80
|
+
resp = resp.to_xml_safe(:root => resp.__model__.name.to_s)
|
81
|
+
Dupe.network.log.add_request @verb, url, resp
|
82
|
+
return resp, new_path
|
83
|
+
else
|
84
|
+
raise StandardError, "Unknown PostMock Response. Your Post intercept mocks must return a Duped resource object or nil"
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
data/lib/dupe/network.rb
CHANGED
@@ -12,14 +12,24 @@ class Dupe
|
|
12
12
|
VERBS.each { |verb| @mocks[verb] = [] }
|
13
13
|
end
|
14
14
|
|
15
|
-
def request(verb, url)
|
15
|
+
def request(verb, url, body=nil)
|
16
16
|
validate_request_type verb
|
17
|
-
match(verb, url).mocked_response(url)
|
17
|
+
match(verb, url).mocked_response(url, body)
|
18
18
|
end
|
19
19
|
|
20
20
|
def define_service_mock(verb, url_pattern, response_proc=nil)
|
21
|
-
|
22
|
-
|
21
|
+
validate_request_type verb
|
22
|
+
case verb
|
23
|
+
when :get
|
24
|
+
GetMock.new(verb, url_pattern, response_proc).tap do |mock|
|
25
|
+
@mocks[verb] << mock
|
26
|
+
end
|
27
|
+
when :post
|
28
|
+
PostMock.new(verb, url_pattern, response_proc).tap do |mock|
|
29
|
+
@mocks[verb].unshift mock
|
30
|
+
end
|
31
|
+
else
|
32
|
+
raise StandardError, "Dupe does not (yet) support mocking #{verb.to_s.upcase} requests."
|
23
33
|
end
|
24
34
|
end
|
25
35
|
|
@@ -26,4 +26,40 @@ describe ActiveResource::Connection do
|
|
26
26
|
books.first.label.should == 'rooby'
|
27
27
|
end
|
28
28
|
end
|
29
|
+
|
30
|
+
describe "#post" do
|
31
|
+
before do
|
32
|
+
@book = Dupe.create :book, :label => 'rooby', :title => 'Rooby'
|
33
|
+
@book.delete(:id)
|
34
|
+
class Book < ActiveResource::Base
|
35
|
+
self.site = ''
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
it "should pass a request off to the Dupe network if the original request failed" do
|
40
|
+
Dupe.network.should_receive(:request).with(:post, '/books.xml', Hash.from_xml(@book.to_xml(:root => 'book'))["book"] ).once
|
41
|
+
book = Book.create({:label => 'rooby', :title => 'Rooby'})
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should parse the xml and turn the result into active resource objects" do
|
45
|
+
book = Book.create({:label => 'rooby', :title => 'Rooby'})
|
46
|
+
book.id.should == 2
|
47
|
+
book.title.should == 'Rooby'
|
48
|
+
book.label.should == 'rooby'
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should make ActiveResource throw an unprocessable entity exception if our Post mock throws a Dupe::UnprocessableEntity exception" do
|
52
|
+
Post %r{/books\.xml} do |post_data|
|
53
|
+
raise Dupe::UnprocessableEntity.new(:title => "must be present.") unless post_data["title"]
|
54
|
+
Dupe.create :book, post_data
|
55
|
+
end
|
56
|
+
|
57
|
+
b = Book.create
|
58
|
+
b.new?.should be_true
|
59
|
+
b.errors.errors.should_not be_empty
|
60
|
+
b = Book.create(:title => "hello")
|
61
|
+
b.new?.should be_false
|
62
|
+
b.errors.should be_empty
|
63
|
+
end
|
64
|
+
end
|
29
65
|
end
|
File without changes
|
@@ -29,4 +29,30 @@ describe "Mock Definition Methods" do
|
|
29
29
|
Dupe.network.request(:get, '/books/rooby.xml').should == book.to_xml_safe(:root => 'book')
|
30
30
|
end
|
31
31
|
end
|
32
|
+
|
33
|
+
describe "Post" do
|
34
|
+
it "should require a url pattern that is a regex" do
|
35
|
+
proc { Post() }.should raise_error(ArgumentError)
|
36
|
+
proc { Post 'not a regexp' }.should raise_error(ArgumentError)
|
37
|
+
proc { Post %r{/some_url} }.should_not raise_error
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should create and return a Dupe::Network::Mock of type :post" do
|
41
|
+
@book = Dupe.create :book, :label => 'rooby'
|
42
|
+
Dupe.network.mocks[:post].should_not be_empty
|
43
|
+
Dupe.network.mocks[:post].length.should == 1
|
44
|
+
|
45
|
+
mock = Post %r{/books\.xml} do |post_data|
|
46
|
+
Dupe.create(:book, post_data)
|
47
|
+
end
|
48
|
+
|
49
|
+
Dupe.network.mocks[:post].length.should == 2
|
50
|
+
Dupe.network.mocks[:post].first.should == mock
|
51
|
+
Dupe.network.mocks[:post].first.url_pattern.should == %r{/books\.xml}
|
52
|
+
book_post = Dupe.create(:book, {:title => "Rooby", :label => "rooby"})
|
53
|
+
book_post.delete(:id)
|
54
|
+
book_response = Dupe.create(:book, {:title => "Rooby", :label => "rooby"})
|
55
|
+
Dupe.network.request(:post, '/books.xml', book_post).should == [Dupe.find(:book) {|b| b.id == 4}.to_xml_safe(:root => 'book'), "/books/4.xml"]
|
56
|
+
end
|
57
|
+
end
|
32
58
|
end
|
data/spec/lib_specs/mock_spec.rb
CHANGED
@@ -40,6 +40,12 @@ describe Dupe::Network::Mock do
|
|
40
40
|
mock.match?('/bogs/1.xml').should == false
|
41
41
|
end
|
42
42
|
end
|
43
|
+
end
|
44
|
+
|
45
|
+
describe Dupe::Network::GetMock do
|
46
|
+
before do
|
47
|
+
Dupe.reset
|
48
|
+
end
|
43
49
|
|
44
50
|
describe "mocked_response" do
|
45
51
|
describe "on a mock object whose response returns a Dupe.find with actual results" do
|
@@ -47,13 +53,13 @@ describe Dupe::Network::Mock do
|
|
47
53
|
url_pattern = %r{/books/(\d+)\.xml}
|
48
54
|
response = proc {|id| Dupe.find(:book) {|b| b.id == id.to_i}}
|
49
55
|
book = Dupe.create :book
|
50
|
-
mock = Dupe::Network::
|
56
|
+
mock = Dupe::Network::GetMock.new :get, url_pattern, response
|
51
57
|
mock.mocked_response('/books/1.xml').should == book.to_xml(:root => 'book')
|
52
58
|
|
53
|
-
proc { mock.mocked_response('/books/2.xml') }.should raise_error(Dupe::Network::
|
59
|
+
proc { mock.mocked_response('/books/2.xml') }.should raise_error(Dupe::Network::GetMock::ResourceNotFoundError)
|
54
60
|
|
55
61
|
Dupe.define :author
|
56
|
-
mock = Dupe::Network::
|
62
|
+
mock = Dupe::Network::GetMock.new :get, %r{/authors\.xml$}, proc {Dupe.find :authors}
|
57
63
|
mock.mocked_response('/authors.xml').should == [].to_xml(:root => 'results')
|
58
64
|
end
|
59
65
|
|
@@ -61,7 +67,7 @@ describe Dupe::Network::Mock do
|
|
61
67
|
url_pattern = %r{/books/([a-zA-Z0-9-]+)\.xml}
|
62
68
|
response = proc {|label| Dupe.find(:book) {|b| b.label == label}}
|
63
69
|
book = Dupe.create :book, :label => 'rooby'
|
64
|
-
mock = Dupe::Network::
|
70
|
+
mock = Dupe::Network::GetMock.new :get, url_pattern, response
|
65
71
|
Dupe.network.log.requests.length.should == 0
|
66
72
|
mock.mocked_response('/books/rooby.xml')
|
67
73
|
Dupe.network.log.requests.length.should == 1
|
@@ -73,21 +79,21 @@ describe Dupe::Network::Mock do
|
|
73
79
|
url_pattern = %r{/authors/(\d+)\.xml}
|
74
80
|
response = proc { |id| Dupe.find(:author) {|a| a.id == id.to_i}}
|
75
81
|
Dupe.define :author
|
76
|
-
mock = Dupe::Network::
|
77
|
-
proc {mock.mocked_response('/authors/1.xml')}.should raise_error(Dupe::Network::
|
82
|
+
mock = Dupe::Network::GetMock.new :get, url_pattern, response
|
83
|
+
proc {mock.mocked_response('/authors/1.xml')}.should raise_error(Dupe::Network::GetMock::ResourceNotFoundError)
|
78
84
|
end
|
79
85
|
end
|
80
86
|
|
81
87
|
describe "on a mock object whose response returns an empty array" do
|
82
88
|
it "should convert the empty array to an xml array record set with root 'results'" do
|
83
89
|
Dupe.define :author
|
84
|
-
mock = Dupe::Network::
|
90
|
+
mock = Dupe::Network::GetMock.new :get, %r{/authors\.xml$}, proc {Dupe.find :authors}
|
85
91
|
mock.mocked_response('/authors.xml').should == [].to_xml(:root => 'results')
|
86
92
|
end
|
87
93
|
|
88
94
|
it "should add a request to the Dupe::Network#log" do
|
89
95
|
Dupe.define :author
|
90
|
-
mock = Dupe::Network::
|
96
|
+
mock = Dupe::Network::GetMock.new :get, %r{/authors\.xml$}, proc {Dupe.find :authors}
|
91
97
|
Dupe.network.log.requests.length.should == 0
|
92
98
|
mock.mocked_response('/authors.xml')
|
93
99
|
Dupe.network.log.requests.length.should == 1
|
@@ -97,19 +103,43 @@ describe Dupe::Network::Mock do
|
|
97
103
|
describe "on a mock object whose response returns an array of duped records" do
|
98
104
|
it "should convert the array to xml" do
|
99
105
|
Dupe.create :author
|
100
|
-
mock = Dupe::Network::
|
106
|
+
mock = Dupe::Network::GetMock.new :get, %r{/authors\.xml$}, proc {Dupe.find :authors}
|
101
107
|
mock.mocked_response('/authors.xml').should == Dupe.find(:authors).to_xml(:root => 'authors')
|
102
108
|
end
|
103
109
|
|
104
110
|
it "should add a request to the Dupe::Network#log" do
|
105
111
|
Dupe.create :author
|
106
|
-
mock = Dupe::Network::
|
112
|
+
mock = Dupe::Network::GetMock.new :get, %r{/authors\.xml$}, proc {Dupe.find :authors}
|
107
113
|
Dupe.network.log.requests.length.should == 0
|
108
114
|
mock.mocked_response('/authors.xml')
|
109
115
|
Dupe.network.log.requests.length.should == 1
|
110
116
|
end
|
111
|
-
end
|
117
|
+
end
|
112
118
|
end
|
113
|
-
|
114
|
-
|
115
119
|
end
|
120
|
+
|
121
|
+
describe Dupe::Network::PostMock do
|
122
|
+
before do
|
123
|
+
Dupe.reset
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "mocked_response" do
|
127
|
+
describe "on a mock object whose response returns a location of a new record" do
|
128
|
+
it "should convert the new post to xml" do
|
129
|
+
Dupe.define :author
|
130
|
+
mock = Dupe::Network::PostMock.new :post, %r{/authors\.xml$}, proc {|post_data| Dupe.create(:author, post_data)}
|
131
|
+
resp, url = mock.mocked_response('/authors.xml', {:name => "Rachel"})
|
132
|
+
resp.should == Dupe.find(:authors).first.to_xml_safe(:root => 'author')
|
133
|
+
url.should == "/authors/1.xml"
|
134
|
+
end
|
135
|
+
|
136
|
+
it "should add a request to the Dupe::Network#log" do
|
137
|
+
Dupe.define :author
|
138
|
+
mock = Dupe::Network::PostMock.new :post, %r{/authors\.xml$}, proc {|post_data| Dupe.create(:author, post_data)}
|
139
|
+
Dupe.network.log.requests.length.should == 0
|
140
|
+
mock.mocked_response('/authors.xml', {:name => "Rachel"})
|
141
|
+
Dupe.network.log.requests.length.should == 1
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
@@ -27,20 +27,34 @@ describe Dupe::Network do
|
|
27
27
|
proc { @network.request }.should raise_error
|
28
28
|
proc { @network.request :invalid_rest_verb, '/some_url' }.should raise_error(Dupe::Network::UnknownRestVerbError)
|
29
29
|
proc { @network.request :get, '/some_url' }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
30
|
+
proc { @network.request :post, '/some_url', 'some body' }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
31
|
+
proc { @network.request :put, '/some_url' }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
32
|
+
proc { @network.request :delete, '/some_url' }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
30
33
|
end
|
31
34
|
|
32
35
|
it "should require a URL" do
|
33
36
|
proc { @network.request :get }.should raise_error(ArgumentError)
|
34
37
|
proc { @network.request :get, 'some_url'}.should_not raise_error(ArgumentError)
|
38
|
+
proc { @network.request :post, 'some_url', 'some body'}.should_not raise_error(ArgumentError)
|
39
|
+
proc { @network.request :put, 'some_url'}.should_not raise_error(ArgumentError)
|
40
|
+
proc { @network.request :delete, 'some_url'}.should_not raise_error(ArgumentError)
|
35
41
|
end
|
36
42
|
|
37
43
|
it "should raise an exception if the network has no mocks that match the url" do
|
38
44
|
proc { @network.request(:get, '/some_url')}.should raise_error(Dupe::Network::RequestNotFoundError)
|
45
|
+
proc { @network.request(:post, '/some_url', 'some body')}.should raise_error(Dupe::Network::RequestNotFoundError)
|
46
|
+
proc { @network.request(:put, '/some_url')}.should raise_error(Dupe::Network::RequestNotFoundError)
|
47
|
+
proc { @network.request(:delete, '/some_url')}.should raise_error(Dupe::Network::RequestNotFoundError)
|
39
48
|
end
|
40
49
|
|
41
50
|
it "should return the appropriate mock response if a mock matches the url" do
|
42
51
|
@network.define_service_mock :get, %r{/greeting$}, proc { "hello" }
|
43
52
|
@network.request(:get, '/greeting').should == 'hello'
|
53
|
+
|
54
|
+
@network.define_service_mock :post, %r{/greeting$}, proc { |post_data| Dupe.create(:greeting, post_data) }
|
55
|
+
resp, url = @network.request(:post, '/greeting', {} )
|
56
|
+
resp.should == Dupe.find(:greeting).to_xml_safe(:root => 'greeting')
|
57
|
+
url.should == "/greetings/1.xml"
|
44
58
|
end
|
45
59
|
end
|
46
60
|
|
@@ -53,24 +67,42 @@ describe Dupe::Network do
|
|
53
67
|
proc { @network.define_service_mock }.should raise_error
|
54
68
|
proc { @network.define_service_mock :invalid_rest_verb, // }.should raise_error(Dupe::Network::UnknownRestVerbError)
|
55
69
|
proc { @network.define_service_mock :get, // }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
70
|
+
proc { @network.define_service_mock :post, // }.should_not raise_error(Dupe::Network::UnknownRestVerbError)
|
71
|
+
|
56
72
|
end
|
57
73
|
|
58
74
|
it "should require a valid Regexp url pattern" do
|
59
75
|
proc { @network.define_service_mock :get, 'not a regular expression' }.should raise_error(ArgumentError)
|
76
|
+
proc { @network.define_service_mock :post, 'not a regular expression' }.should raise_error(ArgumentError)
|
60
77
|
proc { @network.define_service_mock :get, // }.should_not raise_error
|
78
|
+
proc { @network.define_service_mock :post, // }.should_not raise_error
|
79
|
+
|
61
80
|
end
|
62
81
|
|
63
|
-
it "should create and return a new service mock when given valid parameters" do
|
82
|
+
it "should create and return a new get service mock when given valid parameters" do
|
64
83
|
verb = :get
|
65
84
|
pattern = //
|
66
85
|
response = proc { 'test' }
|
67
86
|
@network.mocks[:get].should be_empty
|
68
87
|
mock = @network.define_service_mock verb, pattern, response
|
69
88
|
@network.mocks[:get].should_not be_empty
|
89
|
+
@network.mocks[:post].first.class == "GetMock"
|
70
90
|
@network.mocks[:get].length.should == 1
|
71
91
|
@network.mocks[:get].first.should == mock
|
72
92
|
end
|
73
93
|
|
94
|
+
it "should create and return a new post service mock when given valid parameters" do
|
95
|
+
verb = :post
|
96
|
+
pattern = //
|
97
|
+
response = proc { 'test' }
|
98
|
+
@network.mocks[:post].should be_empty
|
99
|
+
mock = @network.define_service_mock verb, pattern, response
|
100
|
+
@network.mocks[:post].should_not be_empty
|
101
|
+
@network.mocks[:post].first.class == "PostMock"
|
102
|
+
@network.mocks[:post].length.should == 1
|
103
|
+
@network.mocks[:post].first.should == mock
|
104
|
+
end
|
105
|
+
|
74
106
|
|
75
107
|
end
|
76
108
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dupe
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Matt Parker
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2010-
|
12
|
+
date: 2010-03-12 00:00:00 -05:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -91,7 +91,7 @@ test_files:
|
|
91
91
|
- spec/lib_specs/attribute_template_spec.rb
|
92
92
|
- spec/lib_specs/database_spec.rb
|
93
93
|
- spec/lib_specs/dupe_spec.rb
|
94
|
-
- spec/lib_specs/
|
94
|
+
- spec/lib_specs/hash_pruner_spec.rb
|
95
95
|
- spec/lib_specs/log_spec.rb
|
96
96
|
- spec/lib_specs/logged_request_spec.rb
|
97
97
|
- spec/lib_specs/mock_definitions_spec.rb
|