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/spec/helper.rb ADDED
@@ -0,0 +1,72 @@
1
+ require 'minitest/spec'
2
+ require 'turn/autorun'
3
+
4
+ Turn.config do |c|
5
+ c.natural = true
6
+ end
7
+
8
+ require "mocha/setup"
9
+ require "debugger"
10
+
11
+ require 'mongo_mapper'
12
+
13
+ require 'nelumba'
14
+
15
+ module ActiveSupport::Callbacks::ClassMethods
16
+ def callbacks
17
+ return @callbacks if @callbacks
18
+
19
+ @callbacks ||= {}
20
+ [:create, :save].each do |method|
21
+ self.send(:"_#{method}_callbacks").each do |callback|
22
+ @callbacks[:"#{callback.kind}_#{method}"] ||= []
23
+ @callbacks[:"#{callback.kind}_#{method}"] << callback.raw_filter
24
+ end
25
+ end
26
+ @callbacks
27
+ end
28
+
29
+ def before_create_callbacks
30
+ callbacks[:before_create]
31
+ end
32
+
33
+ def after_create_callbacks
34
+ callbacks[:after_create]
35
+ end
36
+ end
37
+
38
+ module MongoMapper::Plugins::Associations::ClassMethods
39
+ def has_one?(id)
40
+ association = self.associations[id]
41
+ return nil unless association
42
+
43
+ association.is_a? MongoMapper::Plugins::Associations::OneAssociation
44
+ end
45
+
46
+ def belongs_to?(id)
47
+ association = self.associations[id]
48
+ return nil unless association
49
+
50
+ association.is_a? MongoMapper::Plugins::Associations::BelongsToAssociation
51
+ end
52
+
53
+ def has_many?(id)
54
+ association = self.associations[id]
55
+ return nil unless association
56
+
57
+ association.is_a? MongoMapper::Plugins::Associations::ManyAssociation
58
+ end
59
+ end
60
+
61
+ require_relative '../lib/nelumba-mongodb.rb'
62
+
63
+ MongoMapper.connection = Mongo::Connection.new('localhost')
64
+ MongoMapper.database = "nelumba-test"
65
+
66
+ class MiniTest::Unit::TestCase
67
+ def teardown
68
+ MongoMapper.database.collections.each do |collection|
69
+ collection.remove unless collection.name.match /^system\./
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,245 @@
1
+ require_relative 'helper'
2
+
3
+ describe Nelumba::Identity do
4
+ describe "Schema" do
5
+ it "should have a username" do
6
+ Nelumba::Identity.keys.keys.must_include "username"
7
+ end
8
+
9
+ it "should have an ssl field" do
10
+ Nelumba::Identity.keys.keys.must_include "ssl"
11
+ end
12
+
13
+ it "should have a domain" do
14
+ Nelumba::Identity.keys.keys.must_include "domain"
15
+ end
16
+
17
+ it "should have a public_key" do
18
+ Nelumba::Identity.keys.keys.must_include "public_key"
19
+ end
20
+
21
+ it "should have a salmon_endpoint" do
22
+ Nelumba::Identity.keys.keys.must_include "salmon_endpoint"
23
+ end
24
+
25
+ it "should have a dialback_endpoint" do
26
+ Nelumba::Identity.keys.keys.must_include "dialback_endpoint"
27
+ end
28
+
29
+ it "should have an activity_inbox_endpoint" do
30
+ Nelumba::Identity.keys.keys.must_include "activity_inbox_endpoint"
31
+ end
32
+
33
+ it "should have an activity_outbox_endpoint" do
34
+ Nelumba::Identity.keys.keys.must_include "activity_inbox_endpoint"
35
+ end
36
+
37
+ it "should have a profile_page" do
38
+ Nelumba::Identity.keys.keys.must_include "profile_page"
39
+ end
40
+
41
+ it "should have an outbox_id" do
42
+ Nelumba::Identity.keys.keys.must_include "outbox_id"
43
+ end
44
+
45
+ it "should have a created_at" do
46
+ Nelumba::Identity.keys.keys.must_include "created_at"
47
+ end
48
+
49
+ it "should have a updated_at" do
50
+ Nelumba::Identity.keys.keys.must_include "updated_at"
51
+ end
52
+ end
53
+
54
+ describe "find_by_identifier" do
55
+ it "should return nil when the identifier cannot be found" do
56
+ Nelumba::Identity.create!(:username => "bogus",
57
+ :domain => "rstat.us")
58
+
59
+ Nelumba::Identity.find_by_identifier("wilkie@rstat.us").must_equal nil
60
+ end
61
+
62
+ it "should return the Nelumba::Identity when the identifier is found" do
63
+ identity = Nelumba::Identity.create!(:username => "wilkie",
64
+ :domain => "rstat.us")
65
+
66
+ Nelumba::Identity.find_by_identifier("wilkie@rstat.us")
67
+ .id.must_equal identity.id
68
+ end
69
+
70
+ it "should search without case sensitivity of the username" do
71
+ identity = Nelumba::Identity.create!(:username => "WilkiE",
72
+ :domain => "rstat.us")
73
+
74
+ Nelumba::Identity.find_by_identifier("wiLkIe@rstat.us")
75
+ .id.must_equal identity.id
76
+ end
77
+
78
+ it "should search without case sensitivity of the domain" do
79
+ identity = Nelumba::Identity.create!(:username => "wilkie",
80
+ :domain => "rStat.uS")
81
+
82
+ Nelumba::Identity.find_by_identifier("wilkie@rstAt.Us")
83
+ .id.must_equal identity.id
84
+ end
85
+
86
+ it "should ignore url scheme" do
87
+ identity = Nelumba::Identity.create!(:username => "wilkie",
88
+ :domain => "rstat.us")
89
+
90
+ Nelumba::Identity.find_by_identifier("acct:wilkie@rstat.us")
91
+ .id.must_equal identity.id
92
+ end
93
+ end
94
+
95
+ describe "create!" do
96
+ it "should take a Nelumba::Identity" do
97
+ identity = Nelumba::Identity.new
98
+ identity.stubs(:to_hash).returns({"username" => "wilkie"})
99
+
100
+ Nelumba::Identity.create!(identity).username.must_equal "wilkie"
101
+ end
102
+
103
+ it "should allow a hash of values" do
104
+ Nelumba::Identity.create!("username" => "wilkie").username.must_equal "wilkie"
105
+ end
106
+
107
+ it "should not store arbitrary fields" do
108
+ Nelumba::Identity.create!(:foobar => "bar").serializable_hash.keys
109
+ .wont_include "foobar"
110
+ end
111
+ end
112
+
113
+ describe "sanitize_params" do
114
+ it "should allow Nelumba::Identity keys" do
115
+ hash = {}
116
+ Nelumba::Identity.keys.keys.each do |k|
117
+ next if ["_id"].include? k
118
+ hash[k.to_str] = "foobar"
119
+ end
120
+
121
+ hash = Nelumba::Identity.sanitize_params(hash)
122
+
123
+ Nelumba::Identity.keys.keys.each do |k|
124
+ next if ["_id"].include? k
125
+ hash[k.intern].must_equal "foobar"
126
+ end
127
+ end
128
+
129
+ it "should convert strings to symbols" do
130
+ hash = {}
131
+ Nelumba::Identity.keys.keys.each do |k|
132
+ next if ["_id"].include? k
133
+ hash[k.to_str] = "foobar"
134
+ end
135
+
136
+ hash = Nelumba::Identity.sanitize_params(hash)
137
+
138
+ Nelumba::Identity.keys.keys.each do |k|
139
+ next if ["_id"].include? k
140
+ hash[k.intern].must_equal "foobar"
141
+ end
142
+ end
143
+
144
+ it "should not allow _id" do
145
+ hash = {"_id" => "bogus"}
146
+ hash = Nelumba::Identity.sanitize_params(hash)
147
+ hash.keys.wont_include "_id"
148
+ end
149
+
150
+ it "should not allow arbitrary keys" do
151
+ hash = {:bogus => "foobar"}
152
+
153
+ hash = Nelumba::Identity.sanitize_params(hash)
154
+
155
+ hash.keys.wont_include :bogus
156
+ end
157
+ end
158
+
159
+ describe "discover!" do
160
+ it "should use Nelumba to discover an identity given the account" do
161
+ Nelumba.expects(:discover_identity)
162
+
163
+ Nelumba::Identity.discover!("wilkie@rstat.us")
164
+ end
165
+
166
+ it "should simply report the identity if already known" do
167
+ identity = Nelumba::Identity.create(:username => "wilkie",
168
+ :domain => "rstat.us")
169
+ Nelumba.expects(:discover_identity).never
170
+
171
+ Nelumba::Identity.discover!("wilkie@rstat.us").id.must_equal identity.id
172
+ end
173
+
174
+ it "should create the Nelumba::Identity upon discovery" do
175
+ identity = Nelumba::Identity.new
176
+ Nelumba.stubs(:discover_identity).returns(identity)
177
+
178
+ Nelumba::Identity.stubs(:create!).with(identity)
179
+
180
+ Nelumba::Identity.discover!("wilkie@rstat.us")
181
+ end
182
+
183
+ it "should return the created Nelumba::Identity upon discovery" do
184
+ identity = Nelumba::Identity.new
185
+ Nelumba.stubs(:discover_identity).returns(identity)
186
+
187
+ Nelumba::Identity.stubs(:create!).with(identity).returns("new identity")
188
+
189
+ Nelumba::Identity.discover!("wilkie@rstat.us").must_equal "new identity"
190
+ end
191
+ end
192
+
193
+ describe "discover_person!" do
194
+ it "should discover the author through Nelumba::Person" do
195
+ identity = Nelumba::Identity.new(:username => "wilkie", :domain => "rstat.us")
196
+ Nelumba::Person.expects(:discover!).with("acct:wilkie@rstat.us").returns("author")
197
+
198
+ identity.discover_person!
199
+ end
200
+ end
201
+
202
+ describe "return_or_discover_public_key" do
203
+ it "should return public_key when public_key_lease is not expired" do
204
+ days = Nelumba::Identity::PUBLIC_KEY_LEASE_DAYS
205
+ identity = Nelumba::Identity.new(:public_key => "KEY",
206
+ :public_key_lease => (DateTime.now+days).to_date,
207
+ :username => "wilkie",
208
+ :domain => "rstat.us")
209
+
210
+ Nelumba.expects(:discover_identity).never
211
+
212
+ identity.return_or_discover_public_key.must_equal "KEY"
213
+ end
214
+
215
+ it "should discover the public key when the public_key_lease has expired" do
216
+ identity = Nelumba::Identity.new(:public_key => "BOGUS",
217
+ :public_key_lease => (DateTime.now-1).to_date,
218
+ :username => "wilkie",
219
+ :domain => "rstat.us")
220
+
221
+ identity.expects(:reset_key_lease)
222
+
223
+ nelumba_identity = mock('Nelumba::Identity')
224
+ nelumba_identity.stubs(:public_key).returns("KEY")
225
+ Nelumba.expects(:discover_identity).returns(nelumba_identity)
226
+
227
+ identity.return_or_discover_public_key.must_equal "KEY"
228
+ end
229
+
230
+ it "should discover the public key when the public_key_lease is nil" do
231
+ identity = Nelumba::Identity.new(:public_key => "BOGUS",
232
+ :public_key_lease => nil,
233
+ :username => "wilkie",
234
+ :domain => "rstat.us")
235
+
236
+ identity.expects(:reset_key_lease)
237
+
238
+ nelumba_identity = mock('Nelumba::Identity')
239
+ nelumba_identity.stubs(:public_key).returns("KEY")
240
+ Nelumba.expects(:discover_identity).returns(nelumba_identity)
241
+
242
+ identity.return_or_discover_public_key.must_equal "KEY"
243
+ end
244
+ end
245
+ end
data/spec/note_spec.rb ADDED
@@ -0,0 +1,71 @@
1
+ require_relative 'helper'
2
+
3
+ describe Nelumba::Note do
4
+ describe "Schema" do
5
+ it "should have a title" do
6
+ Nelumba::Note.keys.keys.must_include "title"
7
+ end
8
+
9
+ it "should have a content" do
10
+ Nelumba::Note.keys.keys.must_include "content"
11
+ end
12
+
13
+ it "should have a uid" do
14
+ Nelumba::Note.keys.keys.must_include "uid"
15
+ end
16
+
17
+ it "should have a url" do
18
+ Nelumba::Note.keys.keys.must_include "url"
19
+ end
20
+
21
+ it "should have a display_name" do
22
+ Nelumba::Note.keys.keys.must_include "display_name"
23
+ end
24
+
25
+ it "should have a summary" do
26
+ Nelumba::Note.keys.keys.must_include "summary"
27
+ end
28
+
29
+ it "should have an image" do
30
+ Nelumba::Note.keys.keys.must_include "image"
31
+ end
32
+
33
+ it "should have an author_id" do
34
+ Nelumba::Note.keys.keys.must_include "author_id"
35
+ end
36
+
37
+ it "should have a published" do
38
+ Nelumba::Note.keys.keys.must_include "published"
39
+ end
40
+
41
+ it "should have a updated" do
42
+ Nelumba::Note.keys.keys.must_include "updated"
43
+ end
44
+ end
45
+
46
+ describe "self.find_by_id" do
47
+ it "should not find a different type of object" do
48
+ note = Nelumba::Article.new(:content => "foo",
49
+ :title => "bar")
50
+ activity = Nelumba::Activity.create :object => note
51
+
52
+ Nelumba::Note.find_by_id(note.id).must_equal nil
53
+ end
54
+
55
+ it "should not find by BSON id" do
56
+ article = Nelumba::Note.new(:content => "foo",
57
+ :title => "bar")
58
+ activity = Nelumba::Activity.create :object => article
59
+
60
+ Nelumba::Note.find_by_id(article.id).must_equal article
61
+ end
62
+
63
+ it "should not find by string id" do
64
+ article = Nelumba::Note.new(:content => "foo",
65
+ :title => "bar")
66
+ activity = Nelumba::Activity.create :object => article
67
+
68
+ Nelumba::Note.find_by_id(article.id).must_equal article
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,922 @@
1
+ require_relative 'helper'
2
+
3
+ describe Nelumba::Person do
4
+ describe "Schema" do
5
+ it "should have one authorization" do
6
+ Nelumba::Person.has_one?(:authorization).must_equal true
7
+ end
8
+
9
+ it "should have one identity" do
10
+ Nelumba::Person.has_one?(:identity).must_equal true
11
+ end
12
+
13
+ it "should have one avatar" do
14
+ Nelumba::Person.has_one?(:avatar).must_equal true
15
+ end
16
+
17
+ it "should have a uid" do
18
+ Nelumba::Person.keys.keys.must_include "uid"
19
+ end
20
+
21
+ it "should have a nickname" do
22
+ Nelumba::Person.keys.keys.must_include "nickname"
23
+ end
24
+
25
+ it "should have an extended_name" do
26
+ Nelumba::Person.keys.keys.must_include "extended_name"
27
+ end
28
+
29
+ it "should have a url" do
30
+ Nelumba::Person.keys.keys.must_include "url"
31
+ end
32
+
33
+ it "should have an email" do
34
+ Nelumba::Person.keys.keys.must_include "email"
35
+ end
36
+
37
+ it "should have a name" do
38
+ Nelumba::Person.keys.keys.must_include "name"
39
+ end
40
+
41
+ it "should have an organization" do
42
+ Nelumba::Person.keys.keys.must_include "organization"
43
+ end
44
+
45
+ it "should have an address" do
46
+ Nelumba::Person.keys.keys.must_include "address"
47
+ end
48
+
49
+ it "should have a gender" do
50
+ Nelumba::Person.keys.keys.must_include "gender"
51
+ end
52
+
53
+ it "should have a pronoun" do
54
+ Nelumba::Person.keys.keys.must_include "pronoun"
55
+ end
56
+
57
+ it "should have a note" do
58
+ Nelumba::Person.keys.keys.must_include "note"
59
+ end
60
+
61
+ it "should have a display_name" do
62
+ Nelumba::Person.keys.keys.must_include "display_name"
63
+ end
64
+
65
+ it "should have a preferred_username" do
66
+ Nelumba::Person.keys.keys.must_include "preferred_username"
67
+ end
68
+
69
+ it "should have a birthday" do
70
+ Nelumba::Person.keys.keys.must_include "birthday"
71
+ end
72
+
73
+ it "should have an anniversary" do
74
+ Nelumba::Person.keys.keys.must_include "anniversary"
75
+ end
76
+
77
+ it "should have a published" do
78
+ Nelumba::Person.keys.keys.must_include "published"
79
+ end
80
+
81
+ it "should have a updated" do
82
+ Nelumba::Person.keys.keys.must_include "updated"
83
+ end
84
+
85
+ it "should have an activities id" do
86
+ Nelumba::Person.keys.keys.must_include "activities_id"
87
+ end
88
+
89
+ it "should have a timeline id" do
90
+ Nelumba::Person.keys.keys.must_include "timeline_id"
91
+ end
92
+
93
+ it "should have a favorites id" do
94
+ Nelumba::Person.keys.keys.must_include "favorites_id"
95
+ end
96
+
97
+ it "should have a shared id" do
98
+ Nelumba::Person.keys.keys.must_include "shared_id"
99
+ end
100
+
101
+ it "should have a replies id" do
102
+ Nelumba::Person.keys.keys.must_include "replies_id"
103
+ end
104
+
105
+ it "should have a mentions id" do
106
+ Nelumba::Person.keys.keys.must_include "mentions_id"
107
+ end
108
+
109
+ it "should have a following_ids array" do
110
+ Nelumba::Person.keys.keys.must_include "following_ids"
111
+ end
112
+
113
+ it "should have a followers_ids array" do
114
+ Nelumba::Person.keys.keys.must_include "followers_ids"
115
+ end
116
+ end
117
+
118
+ describe "create" do
119
+ before do
120
+ @author = Nelumba::Person.new
121
+ Nelumba::Person.stubs(:create).returns(@author)
122
+
123
+ @aggregate = Nelumba::Feed.new
124
+ Nelumba::Feed.stubs(:create).returns(@aggregate)
125
+
126
+ @person = Nelumba::Person.new
127
+ end
128
+ end
129
+
130
+ describe "new_local" do
131
+ before do
132
+ @aggregate = Nelumba::Feed.new
133
+ Nelumba::Feed.stubs(:new).returns(@aggregate)
134
+
135
+ @person = Nelumba::Person.new
136
+ Nelumba::Person.stubs(:new).returns(@person)
137
+ end
138
+
139
+ it "should create an activities aggregate upon creation" do
140
+ @person.expects(:activities_id=).with(@aggregate.id)
141
+ Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
142
+ end
143
+
144
+ it "should create a timeline aggregate upon creation" do
145
+ @person.expects(:timeline_id=).with(@aggregate.id)
146
+ Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
147
+ end
148
+
149
+ it "should create a shared aggregate upon creation" do
150
+ @person.expects(:shared_id=).with(@aggregate.id)
151
+ Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
152
+ end
153
+
154
+ it "should create a favorites aggregate upon creation" do
155
+ @person.expects(:favorites_id=).with(@aggregate.id)
156
+ Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
157
+ end
158
+
159
+ it "should create a replies aggregate upon creation" do
160
+ @person.expects(:replies_id=).with(@aggregate.id)
161
+ Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
162
+ end
163
+
164
+ it "should create a mentions aggregate upon creation" do
165
+ @person.expects(:mentions_id=).with(@aggregate.id)
166
+ Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
167
+ end
168
+
169
+ it "should set the url to a valid url for the given domain" do
170
+ @person.expects(:url=).with("http://status.example.com/people/#{@person.id}")
171
+ Nelumba::Person.new_local "wilkie", "status.example.com", nil, false
172
+ end
173
+
174
+ it "should respect ssl requirements in the url" do
175
+ @person.expects(:url=).with("https://status.example.com/people/#{@person.id}")
176
+ Nelumba::Person.new_local "wilkie", "status.example.com", nil, true
177
+ end
178
+ end
179
+
180
+ describe "#follow!" do
181
+ before do
182
+ @person = Nelumba::Person.new
183
+ @person.stubs(:save)
184
+
185
+ timeline = Nelumba::Feed.new
186
+ timeline.stubs(:follow!)
187
+ timeline.stubs(:save)
188
+ @person.stubs(:timeline).returns(timeline)
189
+
190
+ activities = Nelumba::Feed.new
191
+ activities.stubs(:save)
192
+ activities.stubs(:post!)
193
+ @person.stubs(:activities).returns(activities)
194
+
195
+ @author = Nelumba::Person.new({:local => false})
196
+ @author.stubs(:local?).returns(false)
197
+
198
+ feed = Nelumba::Feed.new
199
+ feed.stubs(:save)
200
+
201
+ outbox = Nelumba::Feed.new
202
+ outbox.stubs(:save)
203
+ outbox.stubs(:feed).returns(feed)
204
+
205
+ identity = Nelumba::Identity.new(:outbox_id => outbox.id,
206
+ :author_id => @author.id)
207
+ identity.stubs(:outbox).returns(outbox)
208
+ identity.stubs(:person).returns(@author)
209
+ identity.stubs(:save)
210
+
211
+ @author.stubs(:identity).returns(identity)
212
+ @author.stubs(:save)
213
+
214
+ @person.stubs(:author).returns(@author)
215
+ end
216
+
217
+ it "should add the given remote Nelumba::Person to the following list" do
218
+ @person.follow! @author
219
+ @person.following_ids.must_include @author.id
220
+ end
221
+
222
+ it "should allow an Nelumba::Identity to be given" do
223
+ @person.follow! @author.identity
224
+ @person.following_ids.must_include @author.id
225
+ end
226
+
227
+ it "should add the given local Nelumba::Person to the following list" do
228
+ @author.stubs(:local?).returns(true)
229
+
230
+ @author.stubs(:followed_by!)
231
+
232
+ @person.follow! @author
233
+ @person.following_ids.must_include @author.id
234
+ end
235
+
236
+ it "should add self to the local Nelumba::Person's followers list" do
237
+ @author.stubs(:local?).returns(true)
238
+
239
+ @author.expects(:followed_by!)
240
+
241
+ @person.follow! @author
242
+ end
243
+ end
244
+
245
+ describe "#unfollow!" do
246
+ before do
247
+ @person = Nelumba::Person.new
248
+ @person.stubs(:save)
249
+
250
+ timeline = Nelumba::Feed.new
251
+ timeline.stubs(:follow!)
252
+ timeline.stubs(:save)
253
+ @person.stubs(:timeline).returns(timeline)
254
+
255
+ activities = Nelumba::Feed.new
256
+ activities.stubs(:save)
257
+ activities.stubs(:post!)
258
+ @person.stubs(:activities).returns(activities)
259
+
260
+ @author = Nelumba::Person.new
261
+
262
+ feed = Nelumba::Feed.new
263
+ feed.stubs(:save)
264
+
265
+ outbox = Nelumba::Feed.new
266
+ outbox.stubs(:save)
267
+ outbox.stubs(:feed).returns(feed)
268
+
269
+ identity = Nelumba::Identity.new(:outbox_id => outbox.id,
270
+ :author_id => @author.id)
271
+ identity.stubs(:outbox).returns(outbox)
272
+ identity.stubs(:person).returns(@author)
273
+ identity.stubs(:save)
274
+
275
+ @author.stubs(:identity).returns(identity)
276
+ @author.stubs(:save)
277
+
278
+ @person.following_ids = [@author.id]
279
+ end
280
+
281
+ it "should remove the given remote Nelumba::Person from the following list" do
282
+ @person.unfollow! @author
283
+ @person.following_ids.wont_include @author.id
284
+ end
285
+
286
+ it "should allow an Nelumba::Identity to be given" do
287
+ @person.unfollow! @author.identity
288
+ @person.following_ids.wont_include @author.id
289
+ end
290
+
291
+ it "should remove the given local Nelumba::Person from the following list" do
292
+ @author.stubs(:local).returns(true)
293
+
294
+ local_person = Nelumba::Person.new
295
+ local_person.stubs(:save)
296
+ @author.stubs(:person).returns(local_person)
297
+
298
+ local_person.stubs(:unfollowed_by!)
299
+
300
+ @person.unfollow! @author
301
+ @person.following_ids.wont_include @author.id
302
+ end
303
+
304
+ it "should remove self from the local Nelumba::Person's followers list" do
305
+ @author.stubs(:local?).returns(true)
306
+
307
+ @author.expects(:unfollowed_by!)
308
+
309
+ @person.unfollow! @author
310
+ end
311
+ end
312
+
313
+ describe "#followed_by!" do
314
+ before do
315
+ activities = Nelumba::Feed.new
316
+ activities.stubs(:followed_by!)
317
+
318
+ @person = Nelumba::Person.new
319
+ @person.stubs(:save)
320
+ @person.stubs(:activities).returns(activities)
321
+
322
+ @author = Nelumba::Person.new
323
+ @author.stubs(:save)
324
+
325
+ aggregate = Nelumba::Feed.new
326
+ aggregate.stubs(:feed).returns(Nelumba::Feed.new)
327
+ aggregate.stubs(:save)
328
+
329
+ aggregate_in = Nelumba::Feed.new
330
+ aggregate_in.stubs(:feed).returns(Nelumba::Feed.new)
331
+ aggregate_in.stubs(:save)
332
+
333
+ @identity = Nelumba::Identity.new(:outbox_id => aggregate.id,
334
+ :inbox_id => aggregate_in.id,
335
+ :author_id => @author.id)
336
+
337
+ @identity.stubs(:person).returns(@author)
338
+ @identity.stubs(:outbox).returns(aggregate)
339
+ @identity.stubs(:inbox).returns(aggregate_in)
340
+ @author.stubs(:identity).returns(@identity)
341
+ end
342
+
343
+ it "should add the given remote Nelumba::Person to our followers list" do
344
+ @person.followed_by! @author
345
+ @person.followers_ids.must_include @author.id
346
+ end
347
+
348
+ it "should add the given Nelumba::Identity to our followers list" do
349
+ @person.followed_by! @identity
350
+ @person.followers_ids.must_include @author.id
351
+ end
352
+
353
+ it "should add outbox to activities' followers list" do
354
+ @person.activities.expects(:followed_by!).with(@identity.inbox)
355
+ @person.followed_by! @author
356
+ end
357
+ end
358
+
359
+ describe "#unfollowed_by!" do
360
+ before do
361
+ activities = Nelumba::Feed.new
362
+ activities.stubs(:unfollowed_by!)
363
+
364
+ @person = Nelumba::Person.new
365
+ @person.stubs(:save)
366
+ @person.stubs(:activities).returns(activities)
367
+
368
+ @author = Nelumba::Person.new
369
+ @author.stubs(:save)
370
+
371
+ aggregate = Nelumba::Feed.new
372
+ aggregate.stubs(:save)
373
+
374
+ aggregate_in = Nelumba::Feed.new
375
+ aggregate_in.stubs(:save)
376
+
377
+ @identity = Nelumba::Identity.new(:outbox_id => aggregate.id,
378
+ :inbox_id => aggregate_in.id,
379
+ :author_id => @author.id)
380
+
381
+ @identity.stubs(:person).returns(@author)
382
+ @identity.stubs(:outbox).returns(aggregate)
383
+ @identity.stubs(:inbox).returns(aggregate_in)
384
+ @author.stubs(:identity).returns(@identity)
385
+ end
386
+
387
+ it "should remove the given remote Nelumba::Person from our followers list" do
388
+ @person.unfollowed_by! @author
389
+ @person.followers_ids.wont_include @author.id
390
+ end
391
+
392
+ it "should remove the given Nelumba::Identity from our followers list" do
393
+ @person.unfollowed_by! @identity
394
+ @person.followers_ids.wont_include @author.id
395
+ end
396
+
397
+ it "should remove outbox from activities' followers list" do
398
+ @person.activities.expects(:unfollowed_by!).with(@identity.inbox)
399
+ @person.unfollowed_by! @author
400
+ end
401
+ end
402
+
403
+ describe "#favorite!" do
404
+ before do
405
+ activities = Nelumba::Feed.new
406
+ activities.stubs(:post!)
407
+ favorites = Nelumba::Feed.new
408
+ favorites.stubs(:repost!)
409
+
410
+ @person = Nelumba::Person.new
411
+ @person.stubs(:activities).returns(activities)
412
+ @person.stubs(:favorites).returns(favorites)
413
+ end
414
+
415
+ it "should repost the given activity to our favorites aggregate" do
416
+ activity = Nelumba::Activity.new
417
+
418
+ @person.favorites.expects(:repost!).with(activity)
419
+ @person.favorite! activity
420
+ end
421
+
422
+ it "should post an activity to our activities with favorite verb" do
423
+ activity = Nelumba::Activity.new
424
+
425
+ @person.activities.expects(:post!).with(has_entry(:verb, :favorite))
426
+ @person.favorite! activity
427
+ end
428
+
429
+ it "should post an activity to our activities with our author as actor" do
430
+ activity = Nelumba::Activity.new
431
+
432
+ @person.activities.expects(:post!)
433
+ .with(has_entries(:actor_id => @person.id,
434
+ :actor_type => 'Person'))
435
+
436
+ @person.favorite! activity
437
+ end
438
+
439
+ it "should post an activity to our activities with favorited activity" do
440
+ activity = Nelumba::Activity.new
441
+
442
+ @person.activities.expects(:post!)
443
+ .with(has_entries(:external_object_id => activity.id,
444
+ :external_object_type => 'Activity'))
445
+
446
+ @person.favorite! activity
447
+ end
448
+ end
449
+
450
+ describe "#unfavorite!" do
451
+ before do
452
+ activities = Nelumba::Feed.new
453
+ activities.stubs(:post!)
454
+ favorites = Nelumba::Feed.new
455
+ favorites.stubs(:delete!)
456
+
457
+ author = Nelumba::Person.new
458
+
459
+ @person = Nelumba::Person.new
460
+ @person.stubs(:activities).returns(activities)
461
+ @person.stubs(:favorites).returns(favorites)
462
+ @person.stubs(:author).returns(author)
463
+ end
464
+
465
+ it "should repost the given activity to our favorites aggregate" do
466
+ activity = Nelumba::Activity.new
467
+
468
+ @person.favorites.expects(:delete!).with(activity)
469
+ @person.unfavorite! activity
470
+ end
471
+
472
+ it "should post an activity to our activities with favorite verb" do
473
+ activity = Nelumba::Activity.new
474
+
475
+ @person.activities.expects(:post!).with(has_entry(:verb, :unfavorite))
476
+ @person.unfavorite! activity
477
+ end
478
+
479
+ it "should post an activity to our activities with our author as actor" do
480
+ activity = Nelumba::Activity.new
481
+
482
+ @person.activities.expects(:post!)
483
+ .with(has_entries(:actor_id => @person.id,
484
+ :actor_type => 'Person'))
485
+
486
+ @person.unfavorite! activity
487
+ end
488
+
489
+ it "should post an activity to our activities with favorited activity" do
490
+ activity = Nelumba::Activity.new
491
+
492
+ @person.activities.expects(:post!)
493
+ .with(has_entries(:external_object_id => activity.id,
494
+ :external_object_type => 'Activity'))
495
+
496
+ @person.unfavorite! activity
497
+ end
498
+ end
499
+
500
+ describe "#mentioned_by!" do
501
+ it "should repost the activity to our mentions aggregate" do
502
+ person = Nelumba::Person.new
503
+ activity = Nelumba::Activity.new
504
+
505
+ person.stubs(:mentions).returns(Nelumba::Feed.new)
506
+
507
+ person.mentions.expects(:repost!).with(activity)
508
+ person.mentioned_by! activity
509
+ end
510
+ end
511
+
512
+ describe "#replied_by!" do
513
+ it "should repost the activity to our replies aggregate" do
514
+ person = Nelumba::Person.new
515
+ activity = Nelumba::Activity.new
516
+
517
+ person.stubs(:replies).returns(Nelumba::Feed.new)
518
+
519
+ person.replies.expects(:repost!).with(activity)
520
+ person.replied_by! activity
521
+ end
522
+ end
523
+
524
+ describe "#post!" do
525
+ it "should post the activity to our activities aggregate" do
526
+ person = Nelumba::Person.new
527
+ activity = Nelumba::Activity.new
528
+
529
+ person.stubs(:timeline).returns(Nelumba::Feed.new)
530
+ person.stubs(:activities).returns(Nelumba::Feed.new)
531
+
532
+ person.activities.expects(:post!).with(activity)
533
+ person.timeline.stubs(:repost!).with(activity)
534
+ person.post! activity
535
+ end
536
+
537
+ it "should repost the activity to our timeline" do
538
+ person = Nelumba::Person.new
539
+ activity = Nelumba::Activity.new
540
+
541
+ person.stubs(:timeline).returns(Nelumba::Feed.new)
542
+ person.stubs(:activities).returns(Nelumba::Feed.new)
543
+
544
+ person.activities.stubs(:post!).with(activity)
545
+ person.timeline.expects(:repost!).with(activity)
546
+ person.post! activity
547
+ end
548
+
549
+ it "should create an activity if passed a hash" do
550
+ activity = Nelumba::Activity.new
551
+ person = Nelumba::Person.new
552
+
553
+ person.stubs(:timeline).returns(Nelumba::Feed.new)
554
+ person.stubs(:activities).returns(Nelumba::Feed.new)
555
+
556
+ hash = {:content => "Hello"}
557
+
558
+ person.activities.stubs(:post!).with(activity)
559
+ person.timeline.stubs(:repost!).with(activity)
560
+
561
+ Nelumba::Activity.expects(:create!).with(hash).returns(activity)
562
+ person.post! hash
563
+ end
564
+ end
565
+
566
+ describe "#share!" do
567
+ before do
568
+ @person = Nelumba::Person.new
569
+ @person.stubs(:timeline).returns(Nelumba::Feed.new)
570
+ @person.stubs(:shared).returns(Nelumba::Feed.new)
571
+ @person.stubs(:activities).returns(Nelumba::Feed.new)
572
+
573
+ @person.shared.stubs(:repost!)
574
+ @person.timeline.stubs(:repost!)
575
+ @person.activities.stubs(:post!)
576
+ end
577
+
578
+ it "should repost the activity to our timeline aggregate" do
579
+ activity = Nelumba::Activity.new
580
+
581
+ @person.timeline.expects(:repost!).with(activity)
582
+ @person.share! activity
583
+ end
584
+
585
+ it "should repost the activity to our shared aggregate" do
586
+ activity = Nelumba::Activity.new
587
+
588
+ @person.shared.expects(:repost!).with(activity)
589
+ @person.share! activity
590
+ end
591
+
592
+ it "should post an activity to our activities with the share verb" do
593
+ @person.activities.expects(:post!)
594
+ .with(has_entry(:verb, :share))
595
+
596
+ @person.share! Nelumba::Activity.new
597
+ end
598
+
599
+ it "should post an activity to our activities with the correct actor" do
600
+ activity = Nelumba::Activity.new
601
+
602
+ @person.activities.expects(:post!)
603
+ .with(has_entries(:actor_id => @person.id,
604
+ :actor_type => 'Person'))
605
+
606
+ @person.share! activity
607
+ end
608
+
609
+ it "should post an activity to our activities with shared activity" do
610
+ activity = Nelumba::Activity.new
611
+
612
+ @person.activities.expects(:post!)
613
+ .with(has_entries(:external_object_id => activity.id,
614
+ :external_object_type => 'Activity'))
615
+
616
+ @person.share! activity
617
+ end
618
+ end
619
+
620
+ describe "discover!" do
621
+ it "should create an identity when author is discovered" do
622
+ identity = Nelumba::Identity.new
623
+
624
+ Nelumba::Identity.stubs(:find_by_identifier).returns(nil)
625
+ Nelumba::Discover.stubs(:identity).with("wilkie@rstat.us").returns(identity)
626
+
627
+ feed = Nelumba::Feed.new(:authors => [Nelumba::Person.new])
628
+ feed.stubs(:save)
629
+
630
+ Nelumba::Discover.stubs(:feed).with(identity).returns(feed)
631
+
632
+ Nelumba::Identity.expects(:create!).returns(identity)
633
+ Nelumba::Person.discover! "wilkie@rstat.us"
634
+ end
635
+
636
+ it "should return nil if identity cannot be discovered" do
637
+ Nelumba::Discover.stubs(:identity).returns(nil)
638
+
639
+ Nelumba::Person.discover!("bogus@rstat.us").must_equal nil
640
+ end
641
+
642
+ it "should return nil if feed cannot be discovered" do
643
+ identity = Nelumba::Identity.new
644
+
645
+ Nelumba::Identity.stubs(:find_by_identifier).returns(nil)
646
+
647
+ Nelumba::Discover.stubs(:identity).returns(identity)
648
+
649
+ Nelumba::Discover.stubs(:feed).returns(nil)
650
+
651
+ Nelumba::Person.discover!("bogus@rstat.us").must_equal nil
652
+ end
653
+
654
+ it "should return Nelumba::Person if one does not exist" do
655
+ Nelumba::Identity.stubs(:find_by_identifier).returns(nil)
656
+
657
+ identity = Nelumba::Identity.new
658
+ Nelumba::Discover.stubs(:identity).with("wilkie@rstat.us").returns(identity)
659
+
660
+ author = Nelumba::Person.new
661
+ feed = Nelumba::Feed.new(:authors => [author])
662
+ feed.stubs(:save)
663
+
664
+ Nelumba::Discover.stubs(:feed).with(identity).returns(feed)
665
+
666
+ Nelumba::Person.discover!("wilkie@rstat.us").must_equal author
667
+ end
668
+
669
+ it "should return existing Nelumba::Person if it can" do
670
+ author = Nelumba::Person.new
671
+ identity = Nelumba::Identity.new(:person => author)
672
+
673
+ Nelumba::Identity.stubs(:find_by_identifier).returns(identity)
674
+ Nelumba::Discover.stubs(:identity).with("wilkie@rstat.us").returns(nil)
675
+
676
+ Nelumba::Person.discover!("wilkie@rstat.us").must_equal author
677
+ end
678
+
679
+ it "should assign the Identity outbox to the discovered feed" do
680
+ identity = Nelumba::Identity.new
681
+
682
+ Nelumba::Identity.stubs(:find_by_identifier).returns(nil)
683
+ Nelumba::Discover.stubs(:identity).with("wilkie@rstat.us").returns(identity)
684
+
685
+ feed = Nelumba::Feed.new(:authors => [Nelumba::Person.new])
686
+ Nelumba::Discover.stubs(:feed).with(identity).returns(feed)
687
+
688
+ Nelumba::Identity.expects(:create!)
689
+ .with(has_entry(:outbox, feed))
690
+ .returns(identity)
691
+
692
+ Nelumba::Person.discover! "wilkie@rstat.us"
693
+ end
694
+
695
+ it "should assign the Identity person to the discovered Person" do
696
+ identity = Nelumba::Identity.new
697
+ Nelumba::Identity.stubs(:find_by_identifier).returns(nil)
698
+ Nelumba::Discover.stubs(:identity).with("wilkie@rstat.us").returns(identity)
699
+
700
+ author = Nelumba::Person.new
701
+ feed = Nelumba::Feed.new(:authors => [author])
702
+ Nelumba::Discover.stubs(:feed).with(identity).returns(feed)
703
+
704
+ Nelumba::Identity.expects(:create!)
705
+ .with(has_entry(:person_id, author.id))
706
+ .returns(identity)
707
+
708
+ Nelumba::Person.discover! "wilkie@rstat.us"
709
+ end
710
+ end
711
+
712
+ describe "#discover_feed!" do
713
+ it "should use Nelumba to discover a feed from the identity" do
714
+ author = Nelumba::Person.create!
715
+ identity = Nelumba::Identity.create!(:person_id => author.id)
716
+
717
+ Nelumba::Discover.expects(:feed).with(identity)
718
+
719
+ author.discover_feed!
720
+ end
721
+ end
722
+
723
+ describe "sanitize_params" do
724
+ it "should allow extended name" do
725
+ Nelumba::Person.sanitize_params({:extended_name => {}})
726
+ .keys.must_include :extended_name
727
+ end
728
+
729
+ it "should allow extended name's formatted field" do
730
+ hash = {"extended_name" => {:formatted => "foobar"}}
731
+ Nelumba::Person.sanitize_params(hash)[:extended_name][:formatted]
732
+ .must_equal "foobar"
733
+ end
734
+
735
+ it "should allow extended name's given_name field" do
736
+ hash = {"extended_name" => {:given_name => "foobar"}}
737
+ Nelumba::Person.sanitize_params(hash)[:extended_name][:given_name]
738
+ .must_equal "foobar"
739
+ end
740
+
741
+ it "should allow extended name's family_name field" do
742
+ hash = {"extended_name" => {:family_name => "foobar"}}
743
+ Nelumba::Person.sanitize_params(hash)[:extended_name][:family_name]
744
+ .must_equal "foobar"
745
+ end
746
+
747
+ it "should allow extended name's honorific_prefix field" do
748
+ hash = {"extended_name" => {:honorific_prefix => "foobar"}}
749
+ Nelumba::Person.sanitize_params(hash)[:extended_name][:honorific_prefix]
750
+ .must_equal "foobar"
751
+ end
752
+
753
+ it "should allow extended name's honorific_suffix field" do
754
+ hash = {"extended_name" => {:honorific_suffix => "foobar"}}
755
+ Nelumba::Person.sanitize_params(hash)[:extended_name][:honorific_suffix]
756
+ .must_equal "foobar"
757
+ end
758
+
759
+ it "should allow extended name's middle_name field" do
760
+ hash = {"extended_name" => {:middle_name => "foobar"}}
761
+ Nelumba::Person.sanitize_params(hash)[:extended_name][:middle_name]
762
+ .must_equal "foobar"
763
+ end
764
+
765
+ it "should allow organization" do
766
+ Nelumba::Person.sanitize_params({"organization" => {}})
767
+ .keys.must_include :organization
768
+ end
769
+
770
+ it "should allow organization's name field" do
771
+ hash = {"organization" => {:name => "foobar"}}
772
+ Nelumba::Person.sanitize_params(hash)[:organization][:name]
773
+ .must_equal "foobar"
774
+ end
775
+
776
+ it "should allow organization's department field" do
777
+ hash = {"organization" => {:department => "foobar"}}
778
+ Nelumba::Person.sanitize_params(hash)[:organization][:department]
779
+ .must_equal "foobar"
780
+ end
781
+
782
+ it "should allow organization's title field" do
783
+ hash = {"organization" => {:title => "foobar"}}
784
+ Nelumba::Person.sanitize_params(hash)[:organization][:title]
785
+ .must_equal "foobar"
786
+ end
787
+
788
+ it "should allow organization's type field" do
789
+ hash = {"organization" => {:type => "foobar"}}
790
+ Nelumba::Person.sanitize_params(hash)[:organization][:type]
791
+ .must_equal "foobar"
792
+ end
793
+
794
+ it "should allow organization's start_date field" do
795
+ hash = {"organization" => {:start_date => "foobar"}}
796
+ Nelumba::Person.sanitize_params(hash)[:organization][:start_date]
797
+ .must_equal "foobar"
798
+ end
799
+
800
+ it "should allow organization's end_date field" do
801
+ hash = {"organization" => {:end_date => "foobar"}}
802
+ Nelumba::Person.sanitize_params(hash)[:organization][:end_date]
803
+ .must_equal "foobar"
804
+ end
805
+
806
+ it "should allow organization's description field" do
807
+ hash = {"organization" => {:description => "foobar"}}
808
+ Nelumba::Person.sanitize_params(hash)[:organization][:description]
809
+ .must_equal "foobar"
810
+ end
811
+
812
+ it "should allow address" do
813
+ Nelumba::Person.sanitize_params({"address" => {}})
814
+ .keys.must_include :address
815
+ end
816
+
817
+ it "should allow address's formatted field" do
818
+ hash = {"address" => {:formatted => "foobar"}}
819
+ Nelumba::Person.sanitize_params(hash)[:address][:formatted]
820
+ .must_equal "foobar"
821
+ end
822
+
823
+ it "should allow address's street_address field" do
824
+ hash = {"address" => {:street_address => "foobar"}}
825
+ Nelumba::Person.sanitize_params(hash)[:address][:street_address]
826
+ .must_equal "foobar"
827
+ end
828
+
829
+ it "should allow address's locality field" do
830
+ hash = {"address" => {:locality => "foobar"}}
831
+ Nelumba::Person.sanitize_params(hash)[:address][:locality]
832
+ .must_equal "foobar"
833
+ end
834
+
835
+ it "should allow address's region field" do
836
+ hash = {"address" => {:region => "foobar"}}
837
+ Nelumba::Person.sanitize_params(hash)[:address][:region]
838
+ .must_equal "foobar"
839
+ end
840
+
841
+ it "should allow address's country field" do
842
+ hash = {"address" => {:country => "foobar"}}
843
+ Nelumba::Person.sanitize_params(hash)[:address][:country]
844
+ .must_equal "foobar"
845
+ end
846
+
847
+ it "should allow address's postal_code field" do
848
+ hash = {"address" => {:postal_code => "foobar"}}
849
+ Nelumba::Person.sanitize_params(hash)[:address][:postal_code]
850
+ .must_equal "foobar"
851
+ end
852
+
853
+ it "should allow Nelumba::Person keys" do
854
+ hash = {}
855
+ Nelumba::Person.keys.keys.each do |k|
856
+ next if ["extended_name", "organization", "address", "_id"].include? k
857
+ hash[k] = "foobar"
858
+ end
859
+
860
+ hash = Nelumba::Person.sanitize_params(hash)
861
+
862
+ Nelumba::Person.keys.keys.each do |k|
863
+ next if ["extended_name", "organization", "address", "_id"].include? k
864
+ hash[k.intern].must_equal "foobar"
865
+ end
866
+ end
867
+
868
+ it "should convert strings to symbols" do
869
+ hash = {}
870
+ Nelumba::Person.keys.keys.each do |k|
871
+ next if ["extended_name", "organization", "address", "_id"].include? k
872
+ hash[k] = "foobar"
873
+ end
874
+
875
+ hash = Nelumba::Person.sanitize_params(hash)
876
+
877
+ Nelumba::Person.keys.keys.each do |k|
878
+ next if ["extended_name", "organization", "address", "_id"].include? k
879
+ hash[k.intern].must_equal "foobar"
880
+ end
881
+ end
882
+
883
+ it "should not allow _id" do
884
+ hash = {"_id" => "bogus"}
885
+ hash = Nelumba::Person.sanitize_params(hash)
886
+ hash.keys.wont_include :_id
887
+ end
888
+
889
+ it "should not allow arbitrary keys" do
890
+ hash = {:bogus => "foobar"}
891
+
892
+ hash = Nelumba::Person.sanitize_params(hash)
893
+
894
+ hash.keys.wont_include :bogus
895
+ end
896
+ end
897
+
898
+ describe "#update_avatar!" do
899
+ it "should pass through the url to Avatar.from_url!" do
900
+ Nelumba::Avatar.expects(:from_url!).with(anything, "avatar_url", anything)
901
+
902
+ author = Nelumba::Person.create
903
+ author.update_avatar! "avatar_url"
904
+ end
905
+
906
+ it "should pass through author instance to Avatar.from_url!" do
907
+ author = Nelumba::Person.create
908
+
909
+ Nelumba::Avatar.expects(:from_url!).with(author, anything, anything)
910
+
911
+ author.update_avatar! "avatar_url"
912
+ end
913
+
914
+ it "should pass through appropriate avatar size" do
915
+ Nelumba::Avatar.expects(:from_url!)
916
+ .with(anything, anything, has_entry(:sizes, [[48, 48]]))
917
+
918
+ author = Nelumba::Person.create
919
+ author.update_avatar! "avatar_url"
920
+ end
921
+ end
922
+ end