dupe 0.4.9 → 0.5.0
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.
- 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
|