slaskis-fleakr 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 +350 -0
- data/Rakefile +41 -0
- data/lib/fleakr.rb +164 -0
- data/lib/fleakr/api.rb +8 -0
- data/lib/fleakr/api/file_parameter.rb +47 -0
- data/lib/fleakr/api/method_request.rb +66 -0
- data/lib/fleakr/api/option.rb +175 -0
- data/lib/fleakr/api/parameter.rb +35 -0
- data/lib/fleakr/api/parameter_list.rb +97 -0
- data/lib/fleakr/api/response.rb +35 -0
- data/lib/fleakr/api/upload_request.rb +75 -0
- data/lib/fleakr/api/value_parameter.rb +36 -0
- data/lib/fleakr/core_ext.rb +3 -0
- data/lib/fleakr/core_ext/false_class.rb +7 -0
- data/lib/fleakr/core_ext/hash.rb +22 -0
- data/lib/fleakr/core_ext/true_class.rb +7 -0
- data/lib/fleakr/objects.rb +13 -0
- data/lib/fleakr/objects/authentication_token.rb +60 -0
- data/lib/fleakr/objects/comment.rb +49 -0
- data/lib/fleakr/objects/contact.rb +31 -0
- data/lib/fleakr/objects/error.rb +22 -0
- data/lib/fleakr/objects/group.rb +36 -0
- data/lib/fleakr/objects/image.rb +50 -0
- data/lib/fleakr/objects/photo.rb +147 -0
- data/lib/fleakr/objects/photo_context.rb +49 -0
- data/lib/fleakr/objects/search.rb +30 -0
- data/lib/fleakr/objects/set.rb +51 -0
- data/lib/fleakr/objects/tag.rb +56 -0
- data/lib/fleakr/objects/user.rb +95 -0
- data/lib/fleakr/support.rb +2 -0
- data/lib/fleakr/support/attribute.rb +46 -0
- data/lib/fleakr/support/object.rb +112 -0
- data/lib/fleakr/version.rb +13 -0
- data/test/fixtures/auth.checkToken.xml +8 -0
- data/test/fixtures/auth.getFullToken.xml +8 -0
- data/test/fixtures/auth.getToken.xml +8 -0
- data/test/fixtures/contacts.getPublicList.xml +7 -0
- data/test/fixtures/groups.pools.getPhotos.xml +7 -0
- data/test/fixtures/people.findByEmail.xml +6 -0
- data/test/fixtures/people.findByUsername.xml +6 -0
- data/test/fixtures/people.getInfo.xml +18 -0
- data/test/fixtures/people.getPublicGroups.xml +7 -0
- data/test/fixtures/people.getPublicPhotos.xml +7 -0
- data/test/fixtures/photos.comments.getList.xml +7 -0
- data/test/fixtures/photos.getContext.xml +6 -0
- data/test/fixtures/photos.getInfo.xml +20 -0
- data/test/fixtures/photos.getSizes.xml +10 -0
- data/test/fixtures/photos.search.xml +7 -0
- data/test/fixtures/photosets.comments.getList.xml +7 -0
- data/test/fixtures/photosets.getList.xml +13 -0
- data/test/fixtures/photosets.getPhotos.xml +7 -0
- data/test/fixtures/tags.getListPhoto.xml +9 -0
- data/test/fixtures/tags.getListUser.xml +10 -0
- data/test/fixtures/tags.getRelated.xml +9 -0
- data/test/test_helper.rb +141 -0
- data/test/unit/fleakr/api/file_parameter_test.rb +63 -0
- data/test/unit/fleakr/api/method_request_test.rb +94 -0
- data/test/unit/fleakr/api/option_test.rb +179 -0
- data/test/unit/fleakr/api/parameter_list_test.rb +176 -0
- data/test/unit/fleakr/api/parameter_test.rb +34 -0
- data/test/unit/fleakr/api/response_test.rb +49 -0
- data/test/unit/fleakr/api/upload_request_test.rb +149 -0
- data/test/unit/fleakr/api/value_parameter_test.rb +41 -0
- data/test/unit/fleakr/core_ext/false_class_test.rb +13 -0
- data/test/unit/fleakr/core_ext/hash_test.rb +32 -0
- data/test/unit/fleakr/core_ext/true_class_test.rb +13 -0
- data/test/unit/fleakr/objects/authentication_token_test.rb +61 -0
- data/test/unit/fleakr/objects/comment_test.rb +66 -0
- data/test/unit/fleakr/objects/contact_test.rb +61 -0
- data/test/unit/fleakr/objects/error_test.rb +21 -0
- data/test/unit/fleakr/objects/group_test.rb +46 -0
- data/test/unit/fleakr/objects/image_test.rb +81 -0
- data/test/unit/fleakr/objects/photo_context_test.rb +80 -0
- data/test/unit/fleakr/objects/photo_test.rb +246 -0
- data/test/unit/fleakr/objects/search_test.rb +74 -0
- data/test/unit/fleakr/objects/set_test.rb +82 -0
- data/test/unit/fleakr/objects/tag_test.rb +98 -0
- data/test/unit/fleakr/objects/user_test.rb +91 -0
- data/test/unit/fleakr/support/attribute_test.rb +126 -0
- data/test/unit/fleakr/support/object_test.rb +129 -0
- data/test/unit/fleakr_test.rb +171 -0
- metadata +175 -0
@@ -0,0 +1,34 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Api
|
4
|
+
class ParameterTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the Parameter class" do
|
7
|
+
|
8
|
+
should "have a name" do
|
9
|
+
parameter = Parameter.new('foo')
|
10
|
+
parameter.name.should == 'foo'
|
11
|
+
end
|
12
|
+
|
13
|
+
should "know to include it in the signature by default" do
|
14
|
+
parameter = Parameter.new('foo')
|
15
|
+
parameter.include_in_signature?.should be(true)
|
16
|
+
end
|
17
|
+
|
18
|
+
should "know not to include it in the signature" do
|
19
|
+
parameter = Parameter.new('foo', false)
|
20
|
+
parameter.include_in_signature?.should be(false)
|
21
|
+
end
|
22
|
+
|
23
|
+
should "be able to compare itself to another parameter instance" do
|
24
|
+
p1 = Parameter.new('z', 'a')
|
25
|
+
p2 = Parameter.new('a', 'z')
|
26
|
+
|
27
|
+
(p1 <=> p2).should == 1
|
28
|
+
end
|
29
|
+
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Api
|
4
|
+
class ResponseTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of Response" do
|
7
|
+
|
8
|
+
should "provide the response body as an Hpricot element" do
|
9
|
+
response_xml = '<xml>'
|
10
|
+
hpricot_stub = stub()
|
11
|
+
|
12
|
+
Hpricot.expects(:XML).with(response_xml).returns(hpricot_stub)
|
13
|
+
|
14
|
+
response = Response.new(response_xml)
|
15
|
+
response.body.should == hpricot_stub
|
16
|
+
end
|
17
|
+
|
18
|
+
should "memoize the Hpricot document" do
|
19
|
+
response = Response.new('<xml>')
|
20
|
+
|
21
|
+
Hpricot.expects(:XML).with(kind_of(String)).once.returns(stub())
|
22
|
+
|
23
|
+
2.times { response.body }
|
24
|
+
end
|
25
|
+
|
26
|
+
should "know if there are errors in the response" do
|
27
|
+
response_xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<rsp stat=\"fail\">\n\t<err code=\"1\" msg=\"User not found\" />\n</rsp>\n"
|
28
|
+
response = Response.new(response_xml)
|
29
|
+
|
30
|
+
response.error?.should be(true)
|
31
|
+
end
|
32
|
+
|
33
|
+
should "not have an error if there are no errors in the XML" do
|
34
|
+
response = Response.new(read_fixture('people.findByUsername'))
|
35
|
+
response.error.should be(nil)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "have an error if there is an error in the response" do
|
39
|
+
response_xml = "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n<rsp stat=\"fail\">\n\t<err code=\"1\" msg=\"User not found\" />\n</rsp>\n"
|
40
|
+
response = Response.new(response_xml)
|
41
|
+
|
42
|
+
response.error.code.should == '1'
|
43
|
+
response.error.message.should == 'User not found'
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,149 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Api
|
4
|
+
class UploadRequestTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the UploadRequest class" do
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@secret = 'sekrit'
|
10
|
+
Fleakr.stubs(:shared_secret).with().returns(@secret)
|
11
|
+
end
|
12
|
+
|
13
|
+
should "have a collection of upload_options" do
|
14
|
+
request = UploadRequest.new('foo', :create, {:title => 'foo', :tags => %w(a b)})
|
15
|
+
|
16
|
+
option_1, option_2 = [stub(:to_hash => {:one => 'value_1'}), stub(:to_hash => {:two => 'value_2'})]
|
17
|
+
|
18
|
+
Option.expects(:for).with(:title, 'foo').returns(option_1)
|
19
|
+
Option.expects(:for).with(:tags, %w(a b)).returns(option_2)
|
20
|
+
|
21
|
+
request.upload_options.should == {:one => 'value_1', :two => 'value_2'}
|
22
|
+
end
|
23
|
+
|
24
|
+
should "create a file parameter on initialization" do
|
25
|
+
filename = '/path/to/image.jpg'
|
26
|
+
|
27
|
+
parameter = stub()
|
28
|
+
FileParameter.expects(:new).with('photo', filename).returns(parameter)
|
29
|
+
|
30
|
+
parameter_list = mock()
|
31
|
+
parameter_list.expects(:<<).with(parameter)
|
32
|
+
|
33
|
+
ParameterList.expects(:new).with({}).returns(parameter_list)
|
34
|
+
|
35
|
+
UploadRequest.new(filename)
|
36
|
+
end
|
37
|
+
|
38
|
+
should "allow setting options on initialization" do
|
39
|
+
option = stub()
|
40
|
+
option.stubs(:to_hash).with().returns({:title => 'foo'})
|
41
|
+
|
42
|
+
Option.expects(:for).with(:title, 'foo').returns(option)
|
43
|
+
|
44
|
+
ParameterList.expects(:new).with({:title => 'foo'}).returns(stub(:<<))
|
45
|
+
|
46
|
+
UploadRequest.new('filename', :create, {:title => 'foo'})
|
47
|
+
end
|
48
|
+
|
49
|
+
context "after initialization" do
|
50
|
+
|
51
|
+
setup { ParameterList.stubs(:new).returns(stub(:<< => nil)) }
|
52
|
+
|
53
|
+
should "default the type to :create" do
|
54
|
+
request = UploadRequest.new('file')
|
55
|
+
request.type.should == :create
|
56
|
+
end
|
57
|
+
|
58
|
+
should "allow setting the type to :update" do
|
59
|
+
request = UploadRequest.new('file', :update)
|
60
|
+
request.type.should == :update
|
61
|
+
end
|
62
|
+
|
63
|
+
should "know the endpoint_uri" do
|
64
|
+
request = UploadRequest.new('filename')
|
65
|
+
request.__send__(:endpoint_uri).should == URI.parse('http://api.flickr.com/services/upload/')
|
66
|
+
end
|
67
|
+
|
68
|
+
should "know the endpoint_uri for an :update request" do
|
69
|
+
request = UploadRequest.new('filename', :update)
|
70
|
+
request.__send__(:endpoint_uri).should == URI.parse('http://api.flickr.com/services/replace/')
|
71
|
+
end
|
72
|
+
|
73
|
+
should "only parse the endpoint URI once" do
|
74
|
+
request = UploadRequest.new('filename')
|
75
|
+
URI.expects(:parse).with(kind_of(String)).once.returns('uri')
|
76
|
+
|
77
|
+
2.times { request.__send__(:endpoint_uri) }
|
78
|
+
end
|
79
|
+
|
80
|
+
should "have a collection of required headers" do
|
81
|
+
form_data = 'data'
|
82
|
+
|
83
|
+
request = UploadRequest.new('filename')
|
84
|
+
request.parameters.stubs(:boundary).with().returns('bound')
|
85
|
+
request.parameters.stubs(:to_form).with().returns(form_data)
|
86
|
+
|
87
|
+
expected = {
|
88
|
+
'Content-Type' => 'multipart/form-data; boundary=bound'
|
89
|
+
}
|
90
|
+
|
91
|
+
request.headers.should == expected
|
92
|
+
end
|
93
|
+
|
94
|
+
should "be able to send a POST request to the API service" do
|
95
|
+
request = UploadRequest.new('filename')
|
96
|
+
|
97
|
+
uri = stub()
|
98
|
+
uri.stubs(:host).with().returns('host')
|
99
|
+
uri.stubs(:path).with().returns('path')
|
100
|
+
uri.stubs(:port).with().returns(80)
|
101
|
+
|
102
|
+
request.stubs(:endpoint_uri).with().returns(uri)
|
103
|
+
|
104
|
+
request.stubs(:headers).with().returns('header' => 'value')
|
105
|
+
request.parameters.stubs(:to_form).with().returns('form')
|
106
|
+
|
107
|
+
http = mock()
|
108
|
+
http.expects(:post).with('path', 'form', {'header' => 'value'})
|
109
|
+
|
110
|
+
Net::HTTP.expects(:start).with('host', 80).yields(http).returns(stub(:body))
|
111
|
+
|
112
|
+
request.send
|
113
|
+
end
|
114
|
+
|
115
|
+
should "get back a response from a POST operation" do
|
116
|
+
response = stub()
|
117
|
+
|
118
|
+
Net::HTTP.expects(:start).with(kind_of(String), kind_of(Fixnum)).returns(stub(:body => '<xml>'))
|
119
|
+
Response.expects(:new).with('<xml>').returns(response)
|
120
|
+
|
121
|
+
request = UploadRequest.new('filename')
|
122
|
+
request.send.should == response
|
123
|
+
end
|
124
|
+
|
125
|
+
should "be able to make a full request and response cycle" do
|
126
|
+
filename = 'filename'
|
127
|
+
response = stub(:error? => false)
|
128
|
+
|
129
|
+
UploadRequest.expects(:new).with(filename, :create, {}).returns(stub(:send => response))
|
130
|
+
UploadRequest.with_response!(filename).should == response
|
131
|
+
end
|
132
|
+
|
133
|
+
should "raise an exception when the full request / response cycle has errors" do
|
134
|
+
filename = 'filename'
|
135
|
+
response = stub(:error? => true, :error => stub(:code => '1', :message => 'User not found'))
|
136
|
+
|
137
|
+
UploadRequest.expects(:new).with(filename, :create, {}).returns(stub(:send => response))
|
138
|
+
|
139
|
+
lambda do
|
140
|
+
UploadRequest.with_response!(filename)
|
141
|
+
end.should raise_error(Fleakr::ApiError)
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
end
|
149
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Api
|
4
|
+
class ValueParameterTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "An instance of the ValueParameter class" do
|
7
|
+
|
8
|
+
should "have a value" do
|
9
|
+
parameter = ValueParameter.new('foo', 'bar')
|
10
|
+
parameter.value.should == 'bar'
|
11
|
+
end
|
12
|
+
|
13
|
+
should "know how to generate the query representation of itself" do
|
14
|
+
parameter = ValueParameter.new('foo', 'bar')
|
15
|
+
parameter.to_query.should == 'foo=bar'
|
16
|
+
end
|
17
|
+
|
18
|
+
should "escape the value when generating the query representation" do
|
19
|
+
parameter = ValueParameter.new('foo', 'Mr. Crystal?')
|
20
|
+
parameter.to_query.should == 'foo=Mr.+Crystal%3F'
|
21
|
+
end
|
22
|
+
|
23
|
+
should "use an empty string when generating a query if the parameter value is nil" do
|
24
|
+
parameter = ValueParameter.new('foo', nil)
|
25
|
+
parameter.to_query.should == 'foo='
|
26
|
+
end
|
27
|
+
|
28
|
+
should "know how to generate the form representation of itself" do
|
29
|
+
parameter = ValueParameter.new('foo', 'bar')
|
30
|
+
expected =
|
31
|
+
'Content-Disposition: form-data; name="foo"' + "\r\n" +
|
32
|
+
"\r\n" +
|
33
|
+
"bar\r\n"
|
34
|
+
|
35
|
+
parameter.to_form.should == expected
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
class HashTest < Test::Unit::TestCase
|
4
|
+
|
5
|
+
context "An instance of Hash" do
|
6
|
+
context "when extracting key/value pairs" do
|
7
|
+
|
8
|
+
setup do
|
9
|
+
@hash = {:one => 'two', :three => 'four'}
|
10
|
+
end
|
11
|
+
|
12
|
+
should "return a hash with the matching key/value pairs" do
|
13
|
+
@hash.extract!(:one).should == {:one => 'two'}
|
14
|
+
end
|
15
|
+
|
16
|
+
should "return an empty hash if the key isn't found" do
|
17
|
+
@hash.extract!(:foo).should == {}
|
18
|
+
end
|
19
|
+
|
20
|
+
should "alter the original hash when a value is extracted" do
|
21
|
+
@hash.extract!(:one)
|
22
|
+
@hash.should == {:three => 'four'}
|
23
|
+
end
|
24
|
+
|
25
|
+
should "be able to extract multiple keys" do
|
26
|
+
@hash.extract!(:one, :three, :missing).should == {:one => 'two', :three => 'four'}
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Objects
|
4
|
+
class AuthenticationTokenTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The AuthenticationToken class" do
|
7
|
+
|
8
|
+
should "be able to create an instance from a mini_token" do
|
9
|
+
token = '123-123-123'
|
10
|
+
auth_token = stub()
|
11
|
+
|
12
|
+
response = mock_request_cycle :for => 'auth.getFullToken', :with => {:mini_token => token, :authenticate? => false}
|
13
|
+
|
14
|
+
AuthenticationToken.expects(:new).with(response.body).returns(auth_token)
|
15
|
+
|
16
|
+
AuthenticationToken.from_mini_token(token).should == auth_token
|
17
|
+
end
|
18
|
+
|
19
|
+
should "be able to create an instance from an auth_token" do
|
20
|
+
token = 'abc123'
|
21
|
+
auth_token = stub()
|
22
|
+
|
23
|
+
response = mock_request_cycle :for => 'auth.checkToken', :with => {:auth_token => token, :authenticate? => false}
|
24
|
+
|
25
|
+
AuthenticationToken.expects(:new).with(response.body).returns(auth_token)
|
26
|
+
AuthenticationToken.from_auth_token(token).should == auth_token
|
27
|
+
end
|
28
|
+
|
29
|
+
|
30
|
+
should "be able to create an instance from a frob" do
|
31
|
+
frob = '12345678901234567-abcde89012fg3456-7890123'
|
32
|
+
auth_token = stub()
|
33
|
+
|
34
|
+
response = mock_request_cycle :for => 'auth.getToken', :with => {:frob => frob, :authenticate? => false}
|
35
|
+
|
36
|
+
AuthenticationToken.expects(:new).with(response.body).returns(auth_token)
|
37
|
+
AuthenticationToken.from_frob(frob).should == auth_token
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
|
42
|
+
context "An instance of the AuthenticationToken class" do
|
43
|
+
|
44
|
+
context "when populating from an XML document" do
|
45
|
+
|
46
|
+
setup do
|
47
|
+
@object = AuthenticationToken.new(Hpricot.XML(read_fixture('auth.getFullToken')))
|
48
|
+
end
|
49
|
+
|
50
|
+
should_have_a_value_for :value => 'abc-123'
|
51
|
+
should_have_a_value_for :permissions => 'delete'
|
52
|
+
should_have_a_value_for :user_id => '31066442@N69'
|
53
|
+
should_have_a_value_for :full_name => 'Sir Froot Pants'
|
54
|
+
should_have_a_value_for :user_name => 'frootpantz'
|
55
|
+
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../../../test_helper'
|
2
|
+
|
3
|
+
module Fleakr::Objects
|
4
|
+
class CommentTest < Test::Unit::TestCase
|
5
|
+
|
6
|
+
context "The Comment class" do
|
7
|
+
|
8
|
+
should_find_all :comments, :by => :photo_id, :call => 'photos.comments.getList', :path => 'rsp/comments/comment'
|
9
|
+
should_find_all :comments, :by => :set_id, :using => :photoset_id, :call => 'photosets.comments.getList', :path => 'rsp/comments/comment'
|
10
|
+
|
11
|
+
end
|
12
|
+
|
13
|
+
context "An instance of the Comment class" do
|
14
|
+
|
15
|
+
context "when populating from the photos_comments_getList XML data" do
|
16
|
+
setup do
|
17
|
+
@object = Comment.new(Hpricot.XML(read_fixture('photos.comments.getList')).at('rsp/comments/comment'))
|
18
|
+
end
|
19
|
+
|
20
|
+
should_have_a_value_for :id => '1'
|
21
|
+
should_have_a_value_for :author_id => '10490170@N04'
|
22
|
+
should_have_a_value_for :created => '1239217523'
|
23
|
+
should_have_a_value_for :url => 'http://www.flickr.com/photos/frootpantz/3422268412/#comment72157616515348062'
|
24
|
+
should_have_a_value_for :body => 'comment one'
|
25
|
+
|
26
|
+
end
|
27
|
+
|
28
|
+
context "in general" do
|
29
|
+
|
30
|
+
setup { @comment = Comment.new }
|
31
|
+
|
32
|
+
should "have a value for :created_at" do
|
33
|
+
@comment.expects(:created).with().returns('1239217523')
|
34
|
+
Time.expects(:at).with(1239217523).returns('time')
|
35
|
+
|
36
|
+
@comment.created_at.should == 'time'
|
37
|
+
end
|
38
|
+
|
39
|
+
should "use the body as the string representation" do
|
40
|
+
@comment.expects(:body).with().returns('bod')
|
41
|
+
@comment.to_s.should == 'bod'
|
42
|
+
end
|
43
|
+
|
44
|
+
should "be able to find the author of the comment" do
|
45
|
+
author = stub()
|
46
|
+
|
47
|
+
|
48
|
+
@comment.stubs(:author_id).with().returns('1')
|
49
|
+
User.expects(:find_by_id).with('1').returns(author)
|
50
|
+
|
51
|
+
@comment.author.should == author
|
52
|
+
end
|
53
|
+
|
54
|
+
should "memoize the owner information" do
|
55
|
+
@comment.stubs(:author_id).with().returns('1')
|
56
|
+
|
57
|
+
User.expects(:find_by_id).with('1').once.returns(stub())
|
58
|
+
|
59
|
+
2.times { @comment.author }
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
end
|
66
|
+
end
|