nelumba-mongodb 0.0.1
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/.gitignore +17 -0
- data/.travis.yml +10 -0
- data/Gemfile +25 -0
- data/LICENSE +127 -0
- data/README.md +29 -0
- data/Rakefile +60 -0
- data/lib/nelumba-mongodb.rb +35 -0
- data/lib/nelumba-mongodb/activity.rb +316 -0
- data/lib/nelumba-mongodb/article.rb +30 -0
- data/lib/nelumba-mongodb/authorization.rb +213 -0
- data/lib/nelumba-mongodb/avatar.rb +130 -0
- data/lib/nelumba-mongodb/comment.rb +7 -0
- data/lib/nelumba-mongodb/embedded_object.rb +43 -0
- data/lib/nelumba-mongodb/feed.rb +268 -0
- data/lib/nelumba-mongodb/identity.rb +191 -0
- data/lib/nelumba-mongodb/image.rb +121 -0
- data/lib/nelumba-mongodb/note.rb +5 -0
- data/lib/nelumba-mongodb/object.rb +43 -0
- data/lib/nelumba-mongodb/person.rb +533 -0
- data/lib/nelumba-mongodb/version.rb +3 -0
- data/nelumba-mongodb.gemspec +26 -0
- data/spec/activity_spec.rb +337 -0
- data/spec/article_spec.rb +71 -0
- data/spec/authorization_spec.rb +514 -0
- data/spec/avatar_spec.rb +418 -0
- data/spec/feed_spec.rb +485 -0
- data/spec/helper.rb +72 -0
- data/spec/identity_spec.rb +245 -0
- data/spec/note_spec.rb +71 -0
- data/spec/person_spec.rb +922 -0
- metadata +164 -0
data/spec/avatar_spec.rb
ADDED
@@ -0,0 +1,418 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class HTTPSuccess; end
|
5
|
+
|
6
|
+
class HTTPNotFound; def initialize; end; end
|
7
|
+
class HTTPRedirection; def initialize; end; end
|
8
|
+
class HTTPOK < HTTPSuccess; def initialize; end; end
|
9
|
+
|
10
|
+
class HTTP
|
11
|
+
class Get; end
|
12
|
+
class Post; end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module Base64; end
|
17
|
+
|
18
|
+
describe Nelumba::Avatar do
|
19
|
+
before do
|
20
|
+
Nelumba::Avatar.class_variable_set :@@grid, nil
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "Schema" do
|
24
|
+
it "should have an author_id" do
|
25
|
+
Nelumba::Avatar.keys.keys.must_include "author_id"
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should have a sizes array" do
|
29
|
+
Nelumba::Avatar.keys.keys.must_include "sizes"
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should has a default sizes array of []" do
|
33
|
+
Nelumba::Avatar.new.sizes.must_equal []
|
34
|
+
end
|
35
|
+
|
36
|
+
it "should have a content_type" do
|
37
|
+
Nelumba::Avatar.keys.keys.must_include "content_type"
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should have a created_at" do
|
41
|
+
Nelumba::Avatar.keys.keys.must_include "created_at"
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should have a updated_at" do
|
45
|
+
Nelumba::Avatar.keys.keys.must_include "updated_at"
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
describe "from_url!" do
|
50
|
+
it "should return nil if url is not found" do
|
51
|
+
uri = stub('URI')
|
52
|
+
uri.stubs(:request_uri)
|
53
|
+
uri.stubs(:hostname)
|
54
|
+
uri.stubs(:port)
|
55
|
+
uri.stubs(:scheme)
|
56
|
+
Nelumba::Avatar.stubs(:URI).returns(uri)
|
57
|
+
|
58
|
+
request = stub('Net::HTTP::Request')
|
59
|
+
Net::HTTP::Get.stubs(:new).returns(request)
|
60
|
+
|
61
|
+
http = stub('Net::HTTP')
|
62
|
+
http.stubs(:use_ssl=)
|
63
|
+
http.stubs(:verify_mode=)
|
64
|
+
Net::HTTP.stubs(:new).returns(http)
|
65
|
+
|
66
|
+
response = stub('Net::HTTP::Response')
|
67
|
+
response.stubs(:class).returns(Net::HTTPNotFound)
|
68
|
+
response.stubs(:is_a?).returns false
|
69
|
+
http.stubs(:request).returns(response)
|
70
|
+
|
71
|
+
Magick::ImageList.stubs(:new)
|
72
|
+
|
73
|
+
author = Nelumba::Person.create
|
74
|
+
Nelumba::Avatar.from_url!(author, "bogus").must_equal nil
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should destroy any previous avatar" do
|
78
|
+
uri = stub('URI')
|
79
|
+
uri.stubs(:request_uri)
|
80
|
+
uri.stubs(:hostname)
|
81
|
+
uri.stubs(:port)
|
82
|
+
uri.stubs(:scheme).returns("https")
|
83
|
+
Nelumba::Avatar.stubs(:URI).with("valid").returns(uri)
|
84
|
+
|
85
|
+
request = stub('Net::HTTP::Request')
|
86
|
+
Net::HTTP::Get.stubs(:new).returns(request)
|
87
|
+
|
88
|
+
http = stub('Net::HTTP')
|
89
|
+
http.stubs(:use_ssl=)
|
90
|
+
http.stubs(:verify_mode=)
|
91
|
+
Net::HTTP.stubs(:new).returns(http)
|
92
|
+
|
93
|
+
response = Net::HTTPOK.new
|
94
|
+
response.stubs(:body)
|
95
|
+
http.stubs(:request).returns(response)
|
96
|
+
|
97
|
+
new_image = stub('Magick::ImageList')
|
98
|
+
new_image.stubs(:to_blob).returns("NEW IMAGE")
|
99
|
+
|
100
|
+
image = stub('Magick::ImageList')
|
101
|
+
image.stubs(:from_blob)
|
102
|
+
image.stubs(:mime_type).returns("MIME")
|
103
|
+
image.stubs(:resize_to_fill).with(48, 48).returns(new_image)
|
104
|
+
Magick::ImageList.stubs(:new).returns(image)
|
105
|
+
|
106
|
+
author = Nelumba::Person.create
|
107
|
+
|
108
|
+
io = stub('IO')
|
109
|
+
io.stubs(:put)
|
110
|
+
|
111
|
+
gridfs = stub('Mongo::Grid')
|
112
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
113
|
+
|
114
|
+
avatar = stub('Avatar')
|
115
|
+
avatar.stubs(:id).returns("ID")
|
116
|
+
avatar.stubs(:content_type=)
|
117
|
+
avatar.stubs(:save)
|
118
|
+
avatar.stubs(:_id).returns("ID")
|
119
|
+
Nelumba::Avatar.stubs(:new).returns(avatar)
|
120
|
+
|
121
|
+
gridfs.stubs(:put).with("NEW IMAGE", :_id => "avatar_ID_48x48")
|
122
|
+
|
123
|
+
old = Nelumba::Avatar.new
|
124
|
+
Nelumba::Avatar.stubs(:first).with(has_entry(:author_id => author.id)).returns(old)
|
125
|
+
old.expects(:destroy)
|
126
|
+
|
127
|
+
Nelumba::Avatar.from_url!(author, "valid", :sizes => [[48, 48]])
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should use ssl and verify when given" do
|
131
|
+
uri = stub('URI')
|
132
|
+
uri.stubs(:request_uri)
|
133
|
+
uri.stubs(:hostname)
|
134
|
+
uri.stubs(:port)
|
135
|
+
uri.stubs(:scheme).returns("https")
|
136
|
+
Nelumba::Avatar.stubs(:URI).with("valid").returns(uri)
|
137
|
+
|
138
|
+
request = stub('Net::HTTP::Request')
|
139
|
+
Net::HTTP::Get.stubs(:new).returns(request)
|
140
|
+
|
141
|
+
http = stub('Net::HTTP')
|
142
|
+
Net::HTTP.stubs(:new).returns(http)
|
143
|
+
|
144
|
+
response = stub('Net::HTTP::Response')
|
145
|
+
response.stubs(:class).returns(Net::HTTPNotFound)
|
146
|
+
http.stubs(:request).returns(response)
|
147
|
+
|
148
|
+
Magick::ImageList.stubs(:new)
|
149
|
+
|
150
|
+
author = Nelumba::Person.create
|
151
|
+
Nelumba::Avatar.stubs(:first).with(has_entry(:author_id => author.id)).returns(nil)
|
152
|
+
|
153
|
+
http.expects(:use_ssl=).with(true)
|
154
|
+
http.expects(:verify_mode=).with(OpenSSL::SSL::VERIFY_PEER)
|
155
|
+
Nelumba::Avatar.from_url!(author, "valid")
|
156
|
+
end
|
157
|
+
|
158
|
+
it "should query ImageMagick for the content type" do
|
159
|
+
uri = stub('URI')
|
160
|
+
uri.stubs(:request_uri)
|
161
|
+
uri.stubs(:hostname)
|
162
|
+
uri.stubs(:port)
|
163
|
+
uri.stubs(:scheme).returns("https")
|
164
|
+
Nelumba::Avatar.stubs(:URI).with("valid").returns(uri)
|
165
|
+
|
166
|
+
request = stub('Net::HTTP::Request')
|
167
|
+
Net::HTTP::Get.stubs(:new).returns(request)
|
168
|
+
|
169
|
+
http = stub('Net::HTTP')
|
170
|
+
http.stubs(:use_ssl=)
|
171
|
+
http.stubs(:verify_mode=)
|
172
|
+
Net::HTTP.stubs(:new).returns(http)
|
173
|
+
|
174
|
+
response = Net::HTTPOK.new
|
175
|
+
response.stubs(:body)
|
176
|
+
http.stubs(:request).returns(response)
|
177
|
+
|
178
|
+
image = stub('Magick::ImageList')
|
179
|
+
image.stubs(:from_blob)
|
180
|
+
image.stubs(:mime_type).returns("MIME")
|
181
|
+
Magick::ImageList.stubs(:new).returns(image)
|
182
|
+
|
183
|
+
author = Nelumba::Person.create
|
184
|
+
|
185
|
+
Nelumba::Avatar.stubs(:first).with(has_entry(:author_id => author.id)).returns(nil)
|
186
|
+
|
187
|
+
Nelumba::Avatar.from_url!(author, "valid").content_type.must_equal "MIME"
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should query ImageMagick to resize and fill to the given sizes" do
|
191
|
+
uri = stub('URI')
|
192
|
+
uri.stubs(:request_uri)
|
193
|
+
uri.stubs(:hostname)
|
194
|
+
uri.stubs(:port)
|
195
|
+
uri.stubs(:scheme).returns("https")
|
196
|
+
Nelumba::Avatar.stubs(:URI).with("valid").returns(uri)
|
197
|
+
|
198
|
+
request = stub('Net::HTTP::Request')
|
199
|
+
Net::HTTP::Get.stubs(:new).returns(request)
|
200
|
+
|
201
|
+
http = stub('Net::HTTP')
|
202
|
+
http.stubs(:use_ssl=)
|
203
|
+
http.stubs(:verify_mode=)
|
204
|
+
Net::HTTP.stubs(:new).returns(http)
|
205
|
+
|
206
|
+
response = Net::HTTPOK.new
|
207
|
+
response.stubs(:body)
|
208
|
+
http.stubs(:request).returns(response)
|
209
|
+
|
210
|
+
image = stub('Magick::ImageList')
|
211
|
+
image.stubs(:from_blob)
|
212
|
+
image.stubs(:mime_type).returns("MIME")
|
213
|
+
Magick::ImageList.stubs(:new).returns(image)
|
214
|
+
|
215
|
+
author = Nelumba::Person.create
|
216
|
+
|
217
|
+
io = stub('IO')
|
218
|
+
io.stubs(:put)
|
219
|
+
|
220
|
+
gridfs = stub('Mongo::Grid')
|
221
|
+
gridfs.stubs(:put)
|
222
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
223
|
+
|
224
|
+
new_image = stub('Magick::ImageList')
|
225
|
+
new_image.stubs(:to_blob).returns("NEW IMAGE")
|
226
|
+
|
227
|
+
image.expects(:resize_to_fill).with(48, 48).returns(new_image)
|
228
|
+
|
229
|
+
Nelumba::Avatar.stubs(:first).with(has_entry(:author_id => author.id)).returns(nil)
|
230
|
+
|
231
|
+
Nelumba::Avatar.from_url!(author, "valid", :sizes => [[48, 48]])
|
232
|
+
end
|
233
|
+
|
234
|
+
it "should store the resultant image to GridFS" do
|
235
|
+
uri = stub('URI')
|
236
|
+
uri.stubs(:request_uri)
|
237
|
+
uri.stubs(:hostname)
|
238
|
+
uri.stubs(:port)
|
239
|
+
uri.stubs(:scheme).returns("https")
|
240
|
+
Nelumba::Avatar.stubs(:URI).with("valid").returns(uri)
|
241
|
+
|
242
|
+
request = stub('Net::HTTP::Request')
|
243
|
+
Net::HTTP::Get.stubs(:new).returns(request)
|
244
|
+
|
245
|
+
http = stub('Net::HTTP')
|
246
|
+
http.stubs(:use_ssl=)
|
247
|
+
http.stubs(:verify_mode=)
|
248
|
+
Net::HTTP.stubs(:new).returns(http)
|
249
|
+
|
250
|
+
response = Net::HTTPOK.new
|
251
|
+
response.stubs(:body)
|
252
|
+
http.stubs(:request).returns(response)
|
253
|
+
|
254
|
+
new_image = stub('Magick::ImageList')
|
255
|
+
new_image.stubs(:to_blob).returns("NEW IMAGE")
|
256
|
+
|
257
|
+
image = stub('Magick::ImageList')
|
258
|
+
image.stubs(:from_blob)
|
259
|
+
image.stubs(:mime_type).returns("MIME")
|
260
|
+
image.stubs(:resize_to_fill).with(48, 48).returns(new_image)
|
261
|
+
Magick::ImageList.stubs(:new).returns(image)
|
262
|
+
|
263
|
+
author = Nelumba::Person.create
|
264
|
+
|
265
|
+
io = stub('IO')
|
266
|
+
io.stubs(:put)
|
267
|
+
|
268
|
+
gridfs = stub('Mongo::Grid')
|
269
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
270
|
+
|
271
|
+
avatar = stub('Avatar')
|
272
|
+
avatar.stubs(:id).returns("ID")
|
273
|
+
avatar.stubs(:content_type=)
|
274
|
+
avatar.stubs(:save)
|
275
|
+
avatar.stubs(:_id).returns("ID")
|
276
|
+
Nelumba::Avatar.stubs(:new).returns(avatar)
|
277
|
+
|
278
|
+
Nelumba::Avatar.stubs(:first).with(has_entry(:author_id => author.id)).returns(nil)
|
279
|
+
|
280
|
+
gridfs.expects(:put).with("NEW IMAGE", :_id => "avatar_ID_48x48")
|
281
|
+
Nelumba::Avatar.from_url!(author, "valid", :sizes => [[48, 48]])
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "#url" do
|
286
|
+
it "should return a url crafted from the given size" do
|
287
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48]])
|
288
|
+
|
289
|
+
avatar.url([48, 48]).must_equal "/avatars/#{avatar.id}/48x48"
|
290
|
+
end
|
291
|
+
|
292
|
+
it "should return nil if the given size doesn't exist" do
|
293
|
+
avatar = Nelumba::Avatar.create(:sizes => [[50, 50]])
|
294
|
+
|
295
|
+
avatar.url([48, 48]).must_equal nil
|
296
|
+
end
|
297
|
+
|
298
|
+
it "should return nil when no sizes exist" do
|
299
|
+
avatar = Nelumba::Avatar.create
|
300
|
+
|
301
|
+
avatar.url([48, 48]).must_equal nil
|
302
|
+
end
|
303
|
+
|
304
|
+
it "should return nil when no sizes exist and none where given" do
|
305
|
+
avatar = Nelumba::Avatar.create
|
306
|
+
|
307
|
+
avatar.url.must_equal nil
|
308
|
+
end
|
309
|
+
|
310
|
+
it "should return first size given upon creation when none where given" do
|
311
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48], [64, 64]])
|
312
|
+
|
313
|
+
avatar.url([48, 48]).must_equal "/avatars/#{avatar.id}/48x48"
|
314
|
+
end
|
315
|
+
end
|
316
|
+
|
317
|
+
describe "#read" do
|
318
|
+
it "should call out to GridFS with the correct id" do
|
319
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48]])
|
320
|
+
|
321
|
+
io = stub('IO')
|
322
|
+
io.stubs(:read).returns("bytes")
|
323
|
+
|
324
|
+
gridfs = stub('Mongo::Grid')
|
325
|
+
gridfs.expects(:get).with("avatar_#{avatar.id}_48x48").returns(io)
|
326
|
+
|
327
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
328
|
+
|
329
|
+
avatar.read.must_equal "bytes"
|
330
|
+
end
|
331
|
+
|
332
|
+
it "should call out to GridFS with the correct id when size is given" do
|
333
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48]])
|
334
|
+
|
335
|
+
io = stub('IO')
|
336
|
+
io.stubs(:read).returns("bytes")
|
337
|
+
|
338
|
+
gridfs = stub('Mongo::Grid')
|
339
|
+
gridfs.expects(:get).with("avatar_#{avatar.id}_48x48").returns(io)
|
340
|
+
|
341
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
342
|
+
|
343
|
+
avatar.read([48, 48]).must_equal "bytes"
|
344
|
+
end
|
345
|
+
|
346
|
+
it "should return nil when no sizes exist and no size is given" do
|
347
|
+
avatar = Nelumba::Avatar.create
|
348
|
+
|
349
|
+
avatar.read([48, 48]).must_equal nil
|
350
|
+
end
|
351
|
+
|
352
|
+
it "should return nil when no sizes exist and size is given" do
|
353
|
+
avatar = Nelumba::Avatar.create
|
354
|
+
|
355
|
+
avatar.read([48, 48]).must_equal nil
|
356
|
+
end
|
357
|
+
|
358
|
+
it "should return nil when sizes exist but wrong size is given" do
|
359
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48]])
|
360
|
+
|
361
|
+
avatar.read([64, 64]).must_equal nil
|
362
|
+
end
|
363
|
+
end
|
364
|
+
|
365
|
+
describe "#read_base64" do
|
366
|
+
before do
|
367
|
+
Base64.stubs(:encode64).returns("data_as_base64")
|
368
|
+
end
|
369
|
+
|
370
|
+
it "should call out to GridFS with the correct id" do
|
371
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48]],
|
372
|
+
:content_type => "mime")
|
373
|
+
|
374
|
+
io = stub('IO')
|
375
|
+
io.stubs(:read).returns("bytes")
|
376
|
+
|
377
|
+
gridfs = stub('Mongo::Grid')
|
378
|
+
gridfs.expects(:get).with("avatar_#{avatar.id}_48x48").returns(io)
|
379
|
+
|
380
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
381
|
+
|
382
|
+
avatar.read_base64([48, 48]).must_equal "data:mime;base64,data_as_base64"
|
383
|
+
end
|
384
|
+
|
385
|
+
it "should call out to GridFS with the correct id when size is given" do
|
386
|
+
avatar = Nelumba::Avatar.create(:sizes => [[48, 48]],
|
387
|
+
:content_type => "mime")
|
388
|
+
|
389
|
+
io = stub('IO')
|
390
|
+
io.stubs(:read).returns("bytes")
|
391
|
+
|
392
|
+
gridfs = stub('Mongo::Grid')
|
393
|
+
gridfs.expects(:get).with("avatar_#{avatar.id}_48x48").returns(io)
|
394
|
+
|
395
|
+
Mongo::Grid.stubs(:new).returns(gridfs)
|
396
|
+
|
397
|
+
avatar.read_base64([48, 48]).must_equal "data:mime;base64,data_as_base64"
|
398
|
+
end
|
399
|
+
|
400
|
+
it "should return nil when no sizes exist and no size is given" do
|
401
|
+
avatar = Nelumba::Avatar.create
|
402
|
+
|
403
|
+
avatar.read_base64([48, 48]).must_equal nil
|
404
|
+
end
|
405
|
+
|
406
|
+
it "should return nil when no sizes exist and size is given" do
|
407
|
+
avatar = Nelumba::Avatar.create(:content_type => "mime")
|
408
|
+
|
409
|
+
avatar.read_base64([48, 48]).must_equal nil
|
410
|
+
end
|
411
|
+
|
412
|
+
it "should return nil when sizes exist but wrong size is given" do
|
413
|
+
avatar = Nelumba::Avatar.create(:content_type => "mime")
|
414
|
+
|
415
|
+
avatar.read_base64([64, 64]).must_equal nil
|
416
|
+
end
|
417
|
+
end
|
418
|
+
end
|
data/spec/feed_spec.rb
ADDED
@@ -0,0 +1,485 @@
|
|
1
|
+
require_relative 'helper'
|
2
|
+
|
3
|
+
describe Nelumba::Feed do
|
4
|
+
describe "Schema" do
|
5
|
+
it "should have a url" do
|
6
|
+
Nelumba::Feed.keys.keys.must_include "url"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "should have a uid" do
|
10
|
+
Nelumba::Feed.keys.keys.must_include "uid"
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should have categories" do
|
14
|
+
Nelumba::Feed.keys.keys.must_include "categories"
|
15
|
+
end
|
16
|
+
|
17
|
+
it "should default categories to []" do
|
18
|
+
Nelumba::Feed.new.categories.must_equal []
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should have a rights field" do
|
22
|
+
Nelumba::Feed.keys.keys.must_include "rights"
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should have a title" do
|
26
|
+
Nelumba::Feed.keys.keys.must_include "title"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should have a title_type" do
|
30
|
+
Nelumba::Feed.keys.keys.must_include "title_type"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should have a subtitle" do
|
34
|
+
Nelumba::Feed.keys.keys.must_include "subtitle"
|
35
|
+
end
|
36
|
+
|
37
|
+
it "should have a subtitle_type" do
|
38
|
+
Nelumba::Feed.keys.keys.must_include "subtitle_type"
|
39
|
+
end
|
40
|
+
|
41
|
+
it "should have contributors_ids" do
|
42
|
+
Nelumba::Feed.keys.keys.must_include "contributors_ids"
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should have authors_ids" do
|
46
|
+
Nelumba::Feed.keys.keys.must_include "authors_ids"
|
47
|
+
end
|
48
|
+
|
49
|
+
it "should have items_ids" do
|
50
|
+
Nelumba::Feed.keys.keys.must_include "items_ids"
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should have a generator" do
|
54
|
+
Nelumba::Feed.keys.keys.must_include "generator"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should have a published" do
|
58
|
+
Nelumba::Feed.keys.keys.must_include "published"
|
59
|
+
end
|
60
|
+
|
61
|
+
it "should have a updated" do
|
62
|
+
Nelumba::Feed.keys.keys.must_include "updated"
|
63
|
+
end
|
64
|
+
|
65
|
+
it "should have a person_id" do
|
66
|
+
Nelumba::Feed.keys.keys.must_include "person_id"
|
67
|
+
end
|
68
|
+
|
69
|
+
it "should have a following_ids array" do
|
70
|
+
Nelumba::Feed.keys.keys.must_include "following_ids"
|
71
|
+
end
|
72
|
+
|
73
|
+
it "should have many following" do
|
74
|
+
Nelumba::Feed.has_many?(:following).must_equal true
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should have a followers_ids array" do
|
78
|
+
Nelumba::Feed.keys.keys.must_include "followers_ids"
|
79
|
+
end
|
80
|
+
|
81
|
+
it "should have many followers" do
|
82
|
+
Nelumba::Feed.has_many?(:followers).must_equal true
|
83
|
+
end
|
84
|
+
|
85
|
+
it "should have a subscription_secret" do
|
86
|
+
Nelumba::Feed.keys.keys.must_include "subscription_secret"
|
87
|
+
end
|
88
|
+
|
89
|
+
it "should have a verification_token" do
|
90
|
+
Nelumba::Feed.keys.keys.must_include "verification_token"
|
91
|
+
end
|
92
|
+
|
93
|
+
it "should belong to person" do
|
94
|
+
Nelumba::Feed.belongs_to?(:person).must_equal true
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
describe "find_or_create_by_uid!" do
|
99
|
+
it "should return the existing Nelumba::Feed" do
|
100
|
+
feed = Nelumba::Feed.create!(:uid => "UID")
|
101
|
+
|
102
|
+
Nelumba::Feed.find_or_create_by_uid!(:uid => "UID").id.must_equal feed.id
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should return the existing Nelumba::Feed via Nelumba::Feed" do
|
106
|
+
feed = Nelumba::Feed.create!(:uid => "UID")
|
107
|
+
|
108
|
+
nelumba_feed = Nelumba::Feed.new
|
109
|
+
nelumba_feed.stubs(:uid).returns("UID")
|
110
|
+
|
111
|
+
Nelumba::Feed.find_or_create_by_uid!(nelumba_feed).uid.must_equal feed.uid
|
112
|
+
end
|
113
|
+
|
114
|
+
it "should create when the Nelumba::Feed is not found" do
|
115
|
+
Nelumba::Feed.expects(:create!).with({:uid => "UID"})
|
116
|
+
Nelumba::Feed.find_or_create_by_uid!(:uid => "UID")
|
117
|
+
end
|
118
|
+
|
119
|
+
it "should create via Nelumba::Feed when the Nelumba::Feed is not found" do
|
120
|
+
nelumba_feed = Nelumba::Feed.new
|
121
|
+
nelumba_feed.stubs(:id).returns("UID")
|
122
|
+
|
123
|
+
Nelumba::Feed.expects(:create!).with(nelumba_feed)
|
124
|
+
Nelumba::Feed.find_or_create_by_uid!(nelumba_feed)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should account for race condition where entry was created after find" do
|
128
|
+
Nelumba::Feed.stubs(:first).returns(nil).then.returns("feed")
|
129
|
+
Nelumba::Feed.stubs(:create!).raises("")
|
130
|
+
Nelumba::Feed.find_or_create_by_uid!(:uid => "UID").must_equal "feed"
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "#initialize" do
|
135
|
+
it "should allow a Nelumba::Feed" do
|
136
|
+
nelumba_feed = Nelumba::Feed.new(:uid => "UID",
|
137
|
+
:authors => [],
|
138
|
+
:contributors => [],
|
139
|
+
:items => [])
|
140
|
+
|
141
|
+
Nelumba::Feed.new(nelumba_feed).uid.must_equal "UID"
|
142
|
+
end
|
143
|
+
|
144
|
+
it "should find or create Nelumba::Persons for those given in Nelumba::Feed" do
|
145
|
+
author = Nelumba::Person.new
|
146
|
+
Nelumba::Person.expects(:find_or_create_by_uid!).returns(author)
|
147
|
+
|
148
|
+
Nelumba::Feed.new(:id => "UID",
|
149
|
+
:authors => [{:uid => "author UID",
|
150
|
+
:url => "author URL"}],
|
151
|
+
:contributors => [],
|
152
|
+
:items => [])
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should find or create Nelumba::Persons for contributors given in Nelumba::Feed" do
|
156
|
+
author = Nelumba::Person.new
|
157
|
+
Nelumba::Person.expects(:find_or_create_by_uid!).returns(author)
|
158
|
+
|
159
|
+
Nelumba::Feed.new(:id => "UID",
|
160
|
+
:contributors => [{:uid => "author UID",
|
161
|
+
:url => "author URL"}],
|
162
|
+
:authors => [],
|
163
|
+
:items => [])
|
164
|
+
end
|
165
|
+
|
166
|
+
it "should find or create Nelumba::Activities for items given in Nelumba::Feed" do
|
167
|
+
activity = Nelumba::Activity.new
|
168
|
+
Nelumba::Activity.expects(:find_or_create_by_uid!).returns(activity)
|
169
|
+
|
170
|
+
Nelumba::Feed.new(:id => "UID",
|
171
|
+
:items => [{:uid => "author UID",
|
172
|
+
:url => "author URL"}],
|
173
|
+
:authors => [],
|
174
|
+
:contributors => [])
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "discover!" do
|
179
|
+
it "should use Nelumba to discover the feed given by the url" do
|
180
|
+
Nelumba::Discover.expects(:feed).with("feed_url")
|
181
|
+
Nelumba::Feed.discover!("feed_url")
|
182
|
+
end
|
183
|
+
|
184
|
+
it "should return false when the feed cannot be discovered" do
|
185
|
+
Nelumba::Discover.stubs(:feed).returns(nil)
|
186
|
+
Nelumba::Feed.discover!("feed_url").must_equal false
|
187
|
+
end
|
188
|
+
|
189
|
+
it "should create a new feed when the discovered feed does not exist" do
|
190
|
+
nelumba_feed = Nelumba::Feed.new
|
191
|
+
nelumba_feed.stubs(:id).returns("UID")
|
192
|
+
Nelumba::Discover.stubs(:feed).returns(nelumba_feed)
|
193
|
+
|
194
|
+
Nelumba::Feed.expects(:create!).with(nelumba_feed)
|
195
|
+
Nelumba::Feed.discover!("feed_url")
|
196
|
+
end
|
197
|
+
|
198
|
+
it "should return a known feed when url matches given" do
|
199
|
+
feed = Nelumba::Feed.new
|
200
|
+
Nelumba::Feed.stubs(:first).with(has_entry(:url, "feed_url")).returns(feed)
|
201
|
+
|
202
|
+
Nelumba::Feed.discover!("feed_url").must_equal feed
|
203
|
+
end
|
204
|
+
|
205
|
+
it "should return a known feed when uids match" do
|
206
|
+
nelumba_feed = Nelumba::Feed.new
|
207
|
+
nelumba_feed.stubs(:uid).returns("UID")
|
208
|
+
Nelumba::Discover.stubs(:feed).returns(nelumba_feed)
|
209
|
+
|
210
|
+
feed = Nelumba::Feed.new
|
211
|
+
Nelumba::Feed.stubs(:first).with(has_entry(:url, "feed_url")).returns(nil)
|
212
|
+
Nelumba::Feed.stubs(:first).with(has_entry(:uid, "UID")).returns(feed)
|
213
|
+
Nelumba::Discover.stubs(:feed).returns(nelumba_feed)
|
214
|
+
|
215
|
+
Nelumba::Feed.discover!("feed_url").must_equal feed
|
216
|
+
end
|
217
|
+
end
|
218
|
+
|
219
|
+
describe "#post!" do
|
220
|
+
it "should allow a Hash to be given" do
|
221
|
+
feed = Nelumba::Feed.new
|
222
|
+
feed.stubs(:save)
|
223
|
+
|
224
|
+
activity = Nelumba::Activity.new
|
225
|
+
activity.stubs(:save)
|
226
|
+
|
227
|
+
hash = {}
|
228
|
+
Nelumba::Activity.expects(:create!).with(hash).returns(activity)
|
229
|
+
|
230
|
+
feed.post! hash
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should allow a Nelumba::Activity to be given" do
|
234
|
+
feed = Nelumba::Feed.new
|
235
|
+
feed.stubs(:save)
|
236
|
+
|
237
|
+
activity = Nelumba::Activity.new
|
238
|
+
activity.stubs(:save)
|
239
|
+
|
240
|
+
nelumba_activity = Nelumba::Activity.new
|
241
|
+
Nelumba::Activity.expects(:create!).never
|
242
|
+
nelumba_activity.expects(:save).at_least 1
|
243
|
+
|
244
|
+
feed.post! nelumba_activity
|
245
|
+
end
|
246
|
+
|
247
|
+
it "should save the association to this feed" do
|
248
|
+
feed = Nelumba::Feed.new
|
249
|
+
feed.stubs(:save)
|
250
|
+
|
251
|
+
activity = Nelumba::Activity.new
|
252
|
+
activity.expects(:feed_id=).with(feed.id)
|
253
|
+
activity.expects(:save).at_least 1
|
254
|
+
|
255
|
+
feed.post! activity
|
256
|
+
end
|
257
|
+
|
258
|
+
it "should add the activity to the items" do
|
259
|
+
feed = Nelumba::Feed.new
|
260
|
+
feed.stubs(:save)
|
261
|
+
|
262
|
+
activity = Nelumba::Activity.new
|
263
|
+
activity.stubs(:save)
|
264
|
+
|
265
|
+
feed.post! activity
|
266
|
+
|
267
|
+
feed.items_ids.must_include activity.id
|
268
|
+
end
|
269
|
+
|
270
|
+
it "should save" do
|
271
|
+
feed = Nelumba::Feed.new
|
272
|
+
|
273
|
+
activity = Nelumba::Activity.new
|
274
|
+
activity.stubs(:save)
|
275
|
+
|
276
|
+
feed.expects(:save)
|
277
|
+
|
278
|
+
feed.post! activity
|
279
|
+
end
|
280
|
+
end
|
281
|
+
|
282
|
+
describe "#repost!" do
|
283
|
+
it "should simply add the activity to items" do
|
284
|
+
feed = Nelumba::Feed.new
|
285
|
+
feed.stubs(:save)
|
286
|
+
|
287
|
+
activity = Nelumba::Activity.new
|
288
|
+
activity.stubs(:save)
|
289
|
+
|
290
|
+
feed.repost! activity
|
291
|
+
|
292
|
+
feed.items_ids.must_include activity.id
|
293
|
+
end
|
294
|
+
|
295
|
+
it "should save" do
|
296
|
+
feed = Nelumba::Feed.new
|
297
|
+
|
298
|
+
activity = Nelumba::Activity.new
|
299
|
+
activity.stubs(:save)
|
300
|
+
|
301
|
+
feed.expects(:save)
|
302
|
+
|
303
|
+
feed.repost! activity
|
304
|
+
end
|
305
|
+
end
|
306
|
+
|
307
|
+
describe "#delete!" do
|
308
|
+
it "should remove the given activity from items" do
|
309
|
+
feed = Nelumba::Feed.new
|
310
|
+
feed.stubs(:save)
|
311
|
+
|
312
|
+
activity = Nelumba::Activity.new
|
313
|
+
activity.stubs(:save)
|
314
|
+
|
315
|
+
feed.items << activity
|
316
|
+
|
317
|
+
feed.delete! activity
|
318
|
+
feed.items_ids.wont_include activity.id
|
319
|
+
end
|
320
|
+
|
321
|
+
it "should save" do
|
322
|
+
feed = Nelumba::Feed.new
|
323
|
+
|
324
|
+
activity = Nelumba::Activity.new
|
325
|
+
activity.stubs(:save)
|
326
|
+
|
327
|
+
feed.items << activity
|
328
|
+
|
329
|
+
feed.expects(:save)
|
330
|
+
feed.delete! activity
|
331
|
+
end
|
332
|
+
end
|
333
|
+
|
334
|
+
describe "#merge!" do
|
335
|
+
it "should update base attributes" do
|
336
|
+
feed = Nelumba::Feed.new
|
337
|
+
feed.stubs(:save)
|
338
|
+
feed.stubs(:save!)
|
339
|
+
|
340
|
+
nelumba_feed = Nelumba::Feed.new
|
341
|
+
nelumba_feed.stubs(:authors).returns([])
|
342
|
+
nelumba_feed.stubs(:contributors).returns([])
|
343
|
+
nelumba_feed.stubs(:items).returns([])
|
344
|
+
nelumba_feed.stubs(:to_hash).returns({:rights => "NEW RIGHTS",
|
345
|
+
:url => "NEW URL",
|
346
|
+
:subtitle => "NEW SUBTITLE"})
|
347
|
+
|
348
|
+
feed.merge! nelumba_feed
|
349
|
+
|
350
|
+
feed.subtitle.must_equal "NEW SUBTITLE"
|
351
|
+
end
|
352
|
+
end
|
353
|
+
|
354
|
+
describe "#ordered" do
|
355
|
+
it "should return a query for the items in descending order" do
|
356
|
+
feed = Nelumba::Feed.new
|
357
|
+
feed.stubs(:save)
|
358
|
+
feed.items_ids = ["id1", "id2"]
|
359
|
+
|
360
|
+
query = stub('Plucky')
|
361
|
+
query.expects(:order)
|
362
|
+
.with(has_entry(:published, :desc))
|
363
|
+
.returns("ordered")
|
364
|
+
|
365
|
+
Nelumba::Activity
|
366
|
+
.expects(:where)
|
367
|
+
.with(has_entry(:id, ["id1", "id2"]))
|
368
|
+
.returns(query)
|
369
|
+
|
370
|
+
feed.ordered.must_equal "ordered"
|
371
|
+
end
|
372
|
+
end
|
373
|
+
|
374
|
+
describe "#follow!" do
|
375
|
+
it "should add the given feed to the following list" do
|
376
|
+
aggregate = Nelumba::Feed.new
|
377
|
+
aggregate.stubs(:save)
|
378
|
+
|
379
|
+
feed = Nelumba::Feed.new
|
380
|
+
feed.stubs(:save)
|
381
|
+
|
382
|
+
aggregate.follow! feed
|
383
|
+
|
384
|
+
aggregate.following_ids.must_include feed.id
|
385
|
+
end
|
386
|
+
|
387
|
+
it "should save" do
|
388
|
+
aggregate = Nelumba::Feed.new
|
389
|
+
feed = Nelumba::Feed.new
|
390
|
+
feed.stubs(:save)
|
391
|
+
|
392
|
+
aggregate.expects(:save)
|
393
|
+
|
394
|
+
aggregate.follow! feed
|
395
|
+
end
|
396
|
+
end
|
397
|
+
|
398
|
+
describe "#unfollow!" do
|
399
|
+
it "should remove the given feed from the following list" do
|
400
|
+
aggregate = Nelumba::Feed.new
|
401
|
+
aggregate.stubs(:save)
|
402
|
+
|
403
|
+
feed = Nelumba::Feed.new
|
404
|
+
feed.stubs(:save)
|
405
|
+
|
406
|
+
aggregate.unfollow! feed
|
407
|
+
|
408
|
+
aggregate.following_ids.wont_include feed.id
|
409
|
+
end
|
410
|
+
|
411
|
+
it "should save" do
|
412
|
+
aggregate = Nelumba::Feed.new
|
413
|
+
feed = Nelumba::Feed.new
|
414
|
+
feed.stubs(:save)
|
415
|
+
|
416
|
+
aggregate.expects(:save)
|
417
|
+
|
418
|
+
aggregate.unfollow! feed
|
419
|
+
end
|
420
|
+
end
|
421
|
+
|
422
|
+
describe "#followed_by!" do
|
423
|
+
it "should add the given feed to the followers list" do
|
424
|
+
aggregate = Nelumba::Feed.new
|
425
|
+
aggregate.stubs(:save)
|
426
|
+
|
427
|
+
feed = Nelumba::Feed.new
|
428
|
+
feed.stubs(:save)
|
429
|
+
|
430
|
+
aggregate.followed_by! feed
|
431
|
+
|
432
|
+
aggregate.followers_ids.must_include feed.id
|
433
|
+
end
|
434
|
+
|
435
|
+
it "should save" do
|
436
|
+
aggregate = Nelumba::Feed.new
|
437
|
+
feed = Nelumba::Feed.new
|
438
|
+
feed.stubs(:save)
|
439
|
+
|
440
|
+
aggregate.expects(:save)
|
441
|
+
|
442
|
+
aggregate.followed_by! feed
|
443
|
+
end
|
444
|
+
end
|
445
|
+
|
446
|
+
describe "#unfollowed_by!" do
|
447
|
+
it "should remove the given feed from the followers list" do
|
448
|
+
aggregate = Nelumba::Feed.new
|
449
|
+
aggregate.stubs(:save)
|
450
|
+
|
451
|
+
feed = Nelumba::Feed.new
|
452
|
+
feed.stubs(:save)
|
453
|
+
|
454
|
+
aggregate.unfollowed_by! feed
|
455
|
+
|
456
|
+
aggregate.followers_ids.wont_include feed.id
|
457
|
+
end
|
458
|
+
|
459
|
+
it "should save" do
|
460
|
+
aggregate = Nelumba::Feed.new
|
461
|
+
feed = Nelumba::Feed.new
|
462
|
+
feed.stubs(:save)
|
463
|
+
|
464
|
+
aggregate.expects(:save)
|
465
|
+
|
466
|
+
aggregate.unfollowed_by! feed
|
467
|
+
end
|
468
|
+
end
|
469
|
+
|
470
|
+
describe "#publish" do
|
471
|
+
it "should repost in every feed that follows this aggregate" do
|
472
|
+
activity = Nelumba::Activity.new
|
473
|
+
|
474
|
+
aggregate = Nelumba::Feed.new
|
475
|
+
feeds = [Nelumba::Feed.new, Nelumba::Feed.new, Nelumba::Feed.new]
|
476
|
+
|
477
|
+
feeds.each do |f|
|
478
|
+
f.expects(:repost!).with(activity)
|
479
|
+
end
|
480
|
+
|
481
|
+
aggregate.stubs(:followers).returns(feeds)
|
482
|
+
aggregate.publish activity
|
483
|
+
end
|
484
|
+
end
|
485
|
+
end
|