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.
@@ -0,0 +1,3 @@
1
+ module Nelumba
2
+ MONGODB_VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,26 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'nelumba-mongodb/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "nelumba-mongodb"
8
+ gem.version = Nelumba::MONGODB_VERSION
9
+ gem.authors = ["wilkie"]
10
+ gem.email = ["wilkie@xomb.com"]
11
+ gem.description = %q{A persistence layer for nelumba.}
12
+ gem.summary = %q{A persistence layer for nelumba.}
13
+ gem.homepage = "https://github.com/hotsh/nelumba-mongodb"
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ["lib"]
19
+
20
+ #gem.add_dependency "nelumba"
21
+ gem.add_dependency "redcarpet" # Markdown renderer
22
+ gem.add_dependency "bson_ext" # Database
23
+ gem.add_dependency "mongo_mapper" # Database
24
+ gem.add_dependency "bcrypt-ruby" # Basic Authentication
25
+ gem.add_dependency "rmagick" # Used for avatar resizing
26
+ end
@@ -0,0 +1,337 @@
1
+ require_relative 'helper'
2
+
3
+ describe Nelumba::Activity do
4
+ describe "Schema" do
5
+ it "should have a feed_id" do
6
+ Nelumba::Activity.keys.keys.must_include "feed_id"
7
+ end
8
+
9
+ it "should have a uid" do
10
+ Nelumba::Activity.keys.keys.must_include "uid"
11
+ end
12
+
13
+ it "should have a url" do
14
+ Nelumba::Activity.keys.keys.must_include "url"
15
+ end
16
+
17
+ it "should have a type" do
18
+ Nelumba::Activity.keys.keys.must_include "type"
19
+ end
20
+
21
+ it "should have an actor_id" do
22
+ Nelumba::Activity.keys.keys.must_include "actor_id"
23
+ end
24
+
25
+ it "should have an actor_type" do
26
+ Nelumba::Activity.keys.keys.must_include "actor_type"
27
+ end
28
+
29
+ it "should have a target_id" do
30
+ Nelumba::Activity.keys.keys.must_include "target_id"
31
+ end
32
+
33
+ it "should have a target_type" do
34
+ Nelumba::Activity.keys.keys.must_include "target_type"
35
+ end
36
+
37
+ it "should have an external_object_id" do
38
+ Nelumba::Activity.keys.keys.must_include "external_object_id"
39
+ end
40
+
41
+ it "should have an external_object_type" do
42
+ Nelumba::Activity.keys.keys.must_include "external_object_type"
43
+ end
44
+
45
+ it "should have a title" do
46
+ Nelumba::Activity.keys.keys.must_include "title"
47
+ end
48
+
49
+ it "should have a content" do
50
+ Nelumba::Activity.keys.keys.must_include "content"
51
+ end
52
+
53
+ it "should have a source" do
54
+ Nelumba::Activity.keys.keys.must_include "source"
55
+ end
56
+
57
+ it "should have an in_reply_to_ids" do
58
+ Nelumba::Activity.keys.keys.must_include "in_reply_to_ids"
59
+ end
60
+
61
+ it "should have an replies_ids" do
62
+ Nelumba::Activity.keys.keys.must_include "replies_ids"
63
+ end
64
+
65
+ it "should have an shares_ids" do
66
+ Nelumba::Activity.keys.keys.must_include "shares_ids"
67
+ end
68
+
69
+ it "should have an mentions_ids" do
70
+ Nelumba::Activity.keys.keys.must_include "mentions_ids"
71
+ end
72
+
73
+ it "should have an likes_ids" do
74
+ Nelumba::Activity.keys.keys.must_include "likes_ids"
75
+ end
76
+
77
+ it "should have a published" do
78
+ Nelumba::Activity.keys.keys.must_include "published"
79
+ end
80
+
81
+ it "should have a updated" do
82
+ Nelumba::Activity.keys.keys.must_include "updated"
83
+ end
84
+ end
85
+
86
+ describe "create!" do
87
+ it "should assign default uid" do
88
+ activity = Nelumba::Activity.new
89
+ activity.run_callbacks :create
90
+
91
+ activity.uid.must_equal "/activities/#{activity.id}"
92
+ end
93
+
94
+ it "should assign default url" do
95
+ activity = Nelumba::Activity.new
96
+ activity.run_callbacks :create
97
+
98
+ activity.url.must_equal "/activities/#{activity.id}"
99
+ end
100
+ end
101
+
102
+ describe "#actor=" do
103
+ it "should assign actor_id to the id of a given Nelumba::Person" do
104
+ activity = Nelumba::Activity.new
105
+ actor = Nelumba::Person.new
106
+
107
+ activity.actor = actor
108
+
109
+ activity.actor_id.must_equal actor.id
110
+ end
111
+
112
+ it "should assign actor_id to the id of a given Nelumba::Activity" do
113
+ activity = Nelumba::Activity.new
114
+ actor = Nelumba::Activity.new
115
+
116
+ activity.actor = actor
117
+
118
+ activity.actor_id.must_equal actor.id
119
+ end
120
+
121
+ it "should assign actor_type appropriately for a given Nelumba::Person" do
122
+ activity = Nelumba::Activity.new
123
+ actor = Nelumba::Person.new
124
+
125
+ activity.actor = actor
126
+
127
+ activity.actor_type.must_equal "Person"
128
+ end
129
+
130
+ it "should assign actor_type appropriately for a given Nelumba::Activity" do
131
+ activity = Nelumba::Activity.new
132
+ actor = Nelumba::Activity.new
133
+
134
+ activity.actor = actor
135
+
136
+ activity.actor_type.must_equal "Activity"
137
+ end
138
+
139
+ it "should return the given object instead of querying the database" do
140
+ activity = Nelumba::Activity.new
141
+ actor = Nelumba::Activity.new
142
+
143
+ activity.actor = actor
144
+
145
+ activity.actor.id.must_equal actor.id
146
+ end
147
+ end
148
+
149
+ describe "#actor" do
150
+ it "should retrieve a stored Nelumba::Person" do
151
+ actor = Nelumba::Person.create
152
+ activity = Nelumba::Activity.new(:actor_id => actor.id,
153
+ :actor_type => "Person")
154
+
155
+ activity.actor.id.must_equal actor.id
156
+ activity.actor.class.must_equal Nelumba::Person
157
+ end
158
+
159
+ it "should retrieve a stored Nelumba::Activity" do
160
+ actor = Nelumba::Activity.create
161
+ activity = Nelumba::Activity.new(:actor_id => actor.id,
162
+ :actor_type => "Activity")
163
+
164
+ activity.actor.id.must_equal actor.id
165
+ activity.actor.class.must_equal Nelumba::Activity
166
+ end
167
+ end
168
+
169
+ describe "find_or_create_by_uid!" do
170
+ it "should return the existing Nelumba::Activity" do
171
+ activity = Nelumba::Activity.create!(:uid => "UID",
172
+ :url => "URL")
173
+
174
+ Nelumba::Activity.find_or_create_by_uid!(:uid => "UID").uid.must_equal activity.uid
175
+ end
176
+
177
+ it "should return the existing Nelumba::Activity via Nelumba::Activity" do
178
+ activity = Nelumba::Activity.create!(:uid => "UID",
179
+ :url => "URL")
180
+
181
+ nelumba_activity = Nelumba::Activity.new(:uid => "UID")
182
+
183
+ Nelumba::Activity.find_or_create_by_uid!(nelumba_activity).uid.must_equal activity.uid
184
+ end
185
+
186
+ it "should create when the Nelumba::Activity is not found" do
187
+ Nelumba::Activity.expects(:create!).with({:uid => "UID"})
188
+ Nelumba::Activity.find_or_create_by_uid!(:uid => "UID")
189
+ end
190
+
191
+ it "should save the given Nelumba::Activity when not found" do
192
+ nelumba_activity = Nelumba::Activity.new
193
+ nelumba_activity.stubs(:id).returns("UID")
194
+
195
+ nelumba_activity.expects(:save)
196
+ Nelumba::Activity.find_or_create_by_uid!(nelumba_activity)
197
+ end
198
+
199
+ it "should create a Nelumba::Activity from a hash when not found" do
200
+ hash = {:uid => "UID"}
201
+
202
+ Nelumba::Activity.expects(:create!).with(hash)
203
+ Nelumba::Activity.find_or_create_by_uid!(hash)
204
+ end
205
+
206
+ it "should account for race condition where entry was created after find" do
207
+ Nelumba::Activity.stubs(:first).returns(nil).then.returns("activity")
208
+ Nelumba::Activity.stubs(:create!).raises("")
209
+ Nelumba::Activity.find_or_create_by_uid!(:uid => "UID").must_equal "activity"
210
+ end
211
+
212
+ it "should save the attached author found in the given hash" do
213
+ author_hash = {:uid => "PERSON_UID"}
214
+ hash = {:uid => "UID", :author => author_hash}
215
+
216
+ Nelumba::Person.expects(:find_or_create_by_uid!).with(author_hash)
217
+ Nelumba::Activity.find_or_create_by_uid!(hash)
218
+ end
219
+ end
220
+
221
+ describe "discover!" do
222
+ it "should call out to Nelumba to discover the given Nelumba::Activity" do
223
+ Nelumba::Discover.expects(:activity).with("activity_url")
224
+ Nelumba::Activity.discover!("activity_url")
225
+ end
226
+
227
+ it "should return false when the Nelumba::Activity cannot be discovered" do
228
+ Nelumba::Discover.stubs(:activity).returns(false)
229
+ Nelumba::Activity.discover!("activity_url").must_equal false
230
+ end
231
+
232
+ it "should return the existing Nelumba::Activity if it is found by url" do
233
+ activity = Nelumba::Activity.create!(:url => "activity_url",
234
+ :uid => "uid")
235
+ Nelumba::Activity.discover!("activity_url").id.must_equal activity.id
236
+ end
237
+
238
+ it "should return the existing Nelumba::Activity if uid matches" do
239
+ activity = Nelumba::Activity.create!(:url => "activity_url",
240
+ :uid => "ID")
241
+
242
+ nelumba_activity = Nelumba::Activity.new(:uid => "ID")
243
+
244
+ Nelumba::Discover.stubs(:activity).returns(nelumba_activity)
245
+ Nelumba::Activity.discover!("alternative_url").uid.must_equal activity.uid
246
+ end
247
+
248
+ it "should create a new Nelumba::Activity from the discovered Nelumba::Activity" do
249
+ nelumba_activity = Nelumba::Activity.new
250
+ nelumba_activity.stubs(:id).returns("ID")
251
+
252
+ Nelumba::Discover.stubs(:activity).returns(nelumba_activity)
253
+ Nelumba::Activity.expects(:create!).returns("new_activity")
254
+ Nelumba::Activity.discover!("alternative_url")
255
+ end
256
+
257
+ it "should return the new Nelumba::Activity from the discovered Nelumba::Activity" do
258
+ nelumba_activity = Nelumba::Activity.new
259
+ nelumba_activity.stubs(:id).returns("ID")
260
+
261
+ Nelumba::Discover.stubs(:activity).returns(nelumba_activity)
262
+ Nelumba::Activity.stubs(:create!).returns("new_activity")
263
+ Nelumba::Activity.discover!("alternative_url").must_equal "new_activity"
264
+ end
265
+ end
266
+
267
+ describe "create_from_notification!" do
268
+ before do
269
+ activity_author = Nelumba::Person.create :url => "acct:wilkie@rstat.us",
270
+ :uid => "AUTHOR ID"
271
+
272
+ activity = Nelumba::Activity.new :verb => :follow,
273
+ :uid => "1",
274
+ :title => "New Title",
275
+ :url => "foo",
276
+ :actor => activity_author
277
+
278
+ @notification = mock('Nelumba::Notification')
279
+ @notification.stubs(:activity).returns(activity)
280
+ @notification.stubs(:account).returns("acct:wilkie@rstat.us")
281
+ @notification.stubs(:verified?).returns(true)
282
+
283
+ Nelumba::Person.stubs(:find_or_create_by_uid!).returns(activity_author)
284
+ Nelumba::Person.stubs(:find_by_id).returns(activity_author)
285
+
286
+ @identity = Nelumba::Identity.new
287
+ @identity.stubs(:return_or_discover_public_key).returns("RSA_PUBLIC_KEY")
288
+ @identity.stubs(:discover_person!)
289
+ @identity.stubs(:author).returns(activity_author)
290
+
291
+ Nelumba::Identity.stubs(:discover!).with("acct:wilkie@rstat.us").returns(@identity)
292
+ end
293
+
294
+ it "should verify the content" do
295
+ @notification.expects(:verified?).with("RSA_PUBLIC_KEY").returns(true)
296
+
297
+ Nelumba::Activity.create_from_notification! @notification
298
+ end
299
+
300
+ it "should discover the account that sent the salmon" do
301
+ Nelumba::Identity.expects(:discover!).with(@notification.account).returns(@identity)
302
+
303
+ Nelumba::Activity.create_from_notification! @notification
304
+ end
305
+
306
+ it "should return nil when the payload is not verified" do
307
+ @notification.stubs(:verified?).returns(false)
308
+ Nelumba::Activity.create_from_notification!(@notification).must_equal nil
309
+ end
310
+
311
+ it "should return the new activity" do
312
+ Nelumba::Activity.create_from_notification!(@notification)
313
+ .class.must_equal Nelumba::Activity
314
+ end
315
+
316
+ it "should return the old activity when already exists" do
317
+ old = Nelumba::Activity.create_from_notification!(@notification)
318
+ Nelumba::Activity.create_from_notification!(@notification).must_equal old
319
+ end
320
+
321
+ it "should return nil if the update exists under a different author" do
322
+ old = Nelumba::Activity.create_from_notification!(@notification)
323
+
324
+ activity_author = Nelumba::Person.create :url => "acct:bogus@rstat.us",
325
+ :uid => "AUTHOR ID"
326
+ activity = Nelumba::Activity.new :verb => :follow,
327
+ :uid => "1",
328
+ :title => "New Title",
329
+ :url => "foo",
330
+ :actor => activity_author
331
+
332
+ @notification.stubs(:activity).returns(activity)
333
+
334
+ Nelumba::Activity.create_from_notification!(@notification).must_equal nil
335
+ end
336
+ end
337
+ end
@@ -0,0 +1,71 @@
1
+ require_relative 'helper'
2
+
3
+ describe Nelumba::Article do
4
+ describe "Schema" do
5
+ it "should have a title" do
6
+ Nelumba::Article.keys.keys.must_include "title"
7
+ end
8
+
9
+ it "should have a content" do
10
+ Nelumba::Article.keys.keys.must_include "content"
11
+ end
12
+
13
+ it "should have a uid" do
14
+ Nelumba::Article.keys.keys.must_include "uid"
15
+ end
16
+
17
+ it "should have a url" do
18
+ Nelumba::Article.keys.keys.must_include "url"
19
+ end
20
+
21
+ it "should have a display_name" do
22
+ Nelumba::Article.keys.keys.must_include "display_name"
23
+ end
24
+
25
+ it "should have a summary" do
26
+ Nelumba::Article.keys.keys.must_include "summary"
27
+ end
28
+
29
+ it "should have an image" do
30
+ Nelumba::Article.keys.keys.must_include "image"
31
+ end
32
+
33
+ it "should have an author_id" do
34
+ Nelumba::Article.keys.keys.must_include "author_id"
35
+ end
36
+
37
+ it "should have a published" do
38
+ Nelumba::Article.keys.keys.must_include "published"
39
+ end
40
+
41
+ it "should have a updated" do
42
+ Nelumba::Article.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::Note.new(:content => "foo",
49
+ :title => "bar")
50
+ activity = Nelumba::Activity.create :object => note
51
+
52
+ Nelumba::Article.find_by_id(note.id).must_equal nil
53
+ end
54
+
55
+ it "should not find by BSON id" do
56
+ article = Nelumba::Article.new(:content => "foo",
57
+ :title => "bar")
58
+ activity = Nelumba::Activity.create :object => article
59
+
60
+ Nelumba::Article.find_by_id(article.id).must_equal article
61
+ end
62
+
63
+ it "should not find by string id" do
64
+ article = Nelumba::Article.new(:content => "foo",
65
+ :title => "bar")
66
+ activity = Nelumba::Activity.create :object => article
67
+
68
+ Nelumba::Article.find_by_id(article.id).must_equal article
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,514 @@
1
+ require_relative 'helper'
2
+
3
+ require 'xml'
4
+
5
+ module Nelumba
6
+ BCRYPT_ROUNDS = 1234
7
+ end
8
+
9
+ def create_authorization(params)
10
+ params["domain"] ||= "www.example.com"
11
+
12
+ Nelumba::Authorization.stubs(:hash_password).returns("hashed")
13
+
14
+ keypair = Struct.new(:public_key, :private_key).new("PUBKEY", "PRIVKEY")
15
+ Nelumba::Crypto.stubs(:new_keypair).returns(keypair)
16
+
17
+ authorization = Nelumba::Authorization.new(params)
18
+
19
+ authorization
20
+ end
21
+
22
+ describe Nelumba::Authorization do
23
+ describe "Schema" do
24
+ it "should have a person_id" do
25
+ Nelumba::Authorization.keys.keys.must_include "person_id"
26
+ end
27
+
28
+ it "should have an identity_id" do
29
+ Nelumba::Authorization.keys.keys.must_include "identity_id"
30
+ end
31
+
32
+ it "should belong to a identity" do
33
+ Nelumba::Authorization.belongs_to?(:identity).must_equal true
34
+ end
35
+
36
+ it "should have a username" do
37
+ Nelumba::Authorization.keys.keys.must_include "username"
38
+ end
39
+
40
+ it "should have a private_key" do
41
+ Nelumba::Authorization.keys.keys.must_include "private_key"
42
+ end
43
+
44
+ it "should have a hashed_password" do
45
+ Nelumba::Authorization.keys.keys.must_include "hashed_password"
46
+ end
47
+
48
+ it "should have an updated_at" do
49
+ Nelumba::Authorization.keys.keys.must_include "updated_at"
50
+ end
51
+
52
+ it "should have a created_at" do
53
+ Nelumba::Authorization.keys.keys.must_include "created_at"
54
+ end
55
+
56
+ it "should not have a password" do
57
+ Nelumba::Authorization.keys.keys.wont_include "password"
58
+ end
59
+ end
60
+
61
+ describe "create" do
62
+ before do
63
+ Nelumba::Authorization.stubs(:hash_password).returns("hashed")
64
+
65
+ keypair = Struct.new(:public_key, :private_key).new("PUBKEY", "PRIVKEY")
66
+ Nelumba::Crypto.stubs(:new_keypair).returns(keypair)
67
+ end
68
+
69
+ it "should create a person attached to this authorization" do
70
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
71
+ Nelumba::Person.expects(:new_local).returns(person)
72
+
73
+ Nelumba::Authorization.new("username" => "wilkie",
74
+ "password" => "foobar",
75
+ "domain" => "www.example.com",
76
+ "ssl" => true)
77
+ end
78
+
79
+ it "should save the person attached to this authorization" do
80
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
81
+ Nelumba::Person.stubs(:new_local).returns(person)
82
+
83
+ Nelumba::Authorization.new("username" => "wilkie",
84
+ "password" => "foobar",
85
+ "domain" => "www.example.com",
86
+ "ssl" => true)
87
+
88
+ Nelumba::Person.first(:id => person.id).activities_id.wont_equal nil
89
+ end
90
+
91
+ it "should create a Person with the given username" do
92
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
93
+ Nelumba::Person.expects(:new_local)
94
+ .with("wilkie", anything, anything, anything)
95
+ .returns(person)
96
+
97
+ Nelumba::Authorization.new("username" => "wilkie",
98
+ "password" => "foobar",
99
+ "domain" => "www.example.com",
100
+ "ssl" => true)
101
+ end
102
+
103
+ it "should create a Person with the given domain" do
104
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
105
+ Nelumba::Person.expects(:new_local)
106
+ .with(anything, "www.example.com", anything, anything)
107
+ .returns(person)
108
+
109
+ Nelumba::Authorization.new("username" => "wilkie",
110
+ "password" => "foobar",
111
+ "domain" => "www.example.com",
112
+ "ssl" => true)
113
+ end
114
+
115
+ it "should create a Person with the given ssl requirements" do
116
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
117
+ Nelumba::Person.expects(:new_local)
118
+ .with(anything, anything, anything, true)
119
+ .returns(person)
120
+
121
+ Nelumba::Authorization.new("username" => "wilkie",
122
+ "password" => "foobar",
123
+ "domain" => "www.example.com",
124
+ "ssl" => true)
125
+ end
126
+
127
+ it "should create an Nelumba::Identity" do
128
+ Nelumba::Identity.expects(:new_local)
129
+ .returns(Nelumba::Identity.new)
130
+
131
+ Nelumba::Authorization.new("username" => "wilkie",
132
+ "password" => "foobar",
133
+ "domain" => "www.example.com",
134
+ "ssl" => true)
135
+ end
136
+
137
+ it "should create an Nelumba::Identity with the generated public key" do
138
+ Nelumba::Identity.expects(:new_local)
139
+ .with(anything, anything, anything, anything, anything, "PUBKEY")
140
+ .returns(Nelumba::Identity.new)
141
+
142
+ Nelumba::Authorization.new("username" => "wilkie",
143
+ "password" => "foobar",
144
+ "domain" => "www.example.com",
145
+ "ssl" => true)
146
+ end
147
+
148
+ it "should create an Nelumba::Identity with the given username" do
149
+ Nelumba::Identity.expects(:new_local)
150
+ .with(anything, "wilkie", anything, anything, anything, anything)
151
+ .returns(Nelumba::Identity.new)
152
+
153
+ Nelumba::Authorization.new("username" => "wilkie",
154
+ "password" => "foobar",
155
+ "domain" => "www.example.com",
156
+ "ssl" => true)
157
+ end
158
+
159
+ it "should create an Nelumba::Identity with the given domain" do
160
+ Nelumba::Identity.expects(:new_local)
161
+ .with(anything, anything, "www.example.com", anything, anything, anything)
162
+ .returns(Nelumba::Identity.new)
163
+
164
+ Nelumba::Authorization.new("username" => "wilkie",
165
+ "password" => "foobar",
166
+ "domain" => "www.example.com",
167
+ "ssl" => true)
168
+ end
169
+
170
+ it "should create an Nelumba::Identity with the given ssl requirements" do
171
+ Nelumba::Identity.expects(:new_local)
172
+ .with(anything, anything, anything, anything, true, anything)
173
+ .returns(Nelumba::Identity.new)
174
+
175
+ Nelumba::Authorization.new("username" => "wilkie",
176
+ "password" => "foobar",
177
+ "domain" => "www.example.com",
178
+ "ssl" => true)
179
+ end
180
+
181
+ it "should create an Nelumba::Identity with the new person's author" do
182
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
183
+ Nelumba::Person.stubs(:new_local).returns(person)
184
+
185
+ Nelumba::Identity.expects(:new_local)
186
+ .with(person, anything, anything, anything, anything, anything)
187
+ .returns(Nelumba::Identity.new)
188
+
189
+ Nelumba::Authorization.new("username" => "wilkie",
190
+ "password" => "foobar",
191
+ "domain" => "www.example.com",
192
+ "ssl" => true)
193
+ end
194
+
195
+ it "should associate a new Nelumba::Identity with this Nelumba::Authorization" do
196
+ person = Nelumba::Person.new_local "wilkie", "www.example.com", nil, true
197
+ Nelumba::Person.stubs(:new_local).returns(person)
198
+
199
+ auth = Nelumba::Authorization.new("username" => "wilkie",
200
+ "password" => "foobar",
201
+ "domain" => "www.example.com",
202
+ "ssl" => true)
203
+
204
+ auth.identity_id.must_equal person.identity.id
205
+ end
206
+
207
+ it "should store the private key" do
208
+ auth = Nelumba::Authorization.new("username" => "wilkie",
209
+ "password" => "foobar",
210
+ "domain" => "www.example.com",
211
+ "ssl" => true)
212
+
213
+ auth.private_key.must_equal "PRIVKEY"
214
+ end
215
+ end
216
+
217
+ describe "lrdd" do
218
+ it "returns nil when the username cannot be found" do
219
+ Nelumba::Authorization.stubs(:find_by_username).returns(nil)
220
+ Nelumba::Authorization.lrdd("bogus@www.example.com").must_equal nil
221
+ end
222
+
223
+ it "should contain a subject matching their webfinger" do
224
+ authorization = create_authorization("username" => "wilkie",
225
+ "password" => "foobar")
226
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
227
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:subject]
228
+ .must_equal "acct:wilkie@www.example.com"
229
+ end
230
+
231
+ it "should contain an alias to the profile" do
232
+ authorization = create_authorization("username" => "wilkie",
233
+ "password" => "foobar")
234
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
235
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:aliases]
236
+ .must_include "http://www.example.com/people/#{authorization.person.id}"
237
+ end
238
+
239
+ it "should contain an alias to the profile" do
240
+ authorization = create_authorization("username" => "wilkie",
241
+ "password" => "foobar")
242
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
243
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:aliases]
244
+ .must_include "http://www.example.com/people/#{authorization.person.id}"
245
+ end
246
+
247
+ it "should contain an alias to the feed" do
248
+ authorization = create_authorization("username" => "wilkie",
249
+ "password" => "foobar")
250
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
251
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:aliases].must_include(
252
+ "http://www.example.com/feeds/#{authorization.identity.outbox.id}")
253
+ end
254
+
255
+ it "should contain profile-page link" do
256
+ authorization = create_authorization("username" => "wilkie",
257
+ "password" => "foobar")
258
+ person_id = authorization.person.id
259
+
260
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
261
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
262
+ .must_include({:rel => "http://webfinger.net/rel/profile-page",
263
+ :href => "http://www.example.com/people/#{person_id}"})
264
+ end
265
+
266
+ it "should contain updates-from link" do
267
+ authorization = create_authorization("username" => "wilkie",
268
+ "password" => "foobar")
269
+ feed_id = authorization.identity.outbox.id
270
+
271
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
272
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
273
+ .must_include({:rel => "http://schemas.google.com/g/2010#updates-from",
274
+ :href => "http://www.example.com/feeds/#{feed_id}"})
275
+ end
276
+
277
+ it "should contain salmon link" do
278
+ authorization = create_authorization("username" => "wilkie",
279
+ "password" => "foobar")
280
+ person_id = authorization.person.id
281
+
282
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
283
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
284
+ .must_include(:rel => "salmon",
285
+ :href => "http://www.example.com/people/#{person_id}/salmon")
286
+ end
287
+
288
+ it "should contain salmon-replies link" do
289
+ authorization = create_authorization("username" => "wilkie",
290
+ "password" => "foobar")
291
+ person_id = authorization.person.id
292
+
293
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
294
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
295
+ .must_include(:rel => "http://salmon-protocol.org/ns/salmon-replies",
296
+ :href => "http://www.example.com/people/#{person_id}/salmon")
297
+ end
298
+
299
+ it "should contain salmon-mention link" do
300
+ authorization = create_authorization("username" => "wilkie",
301
+ "password" => "foobar")
302
+ person_id = authorization.person.id
303
+
304
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
305
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
306
+ .must_include(:rel => "http://salmon-protocol.org/ns/salmon-mention",
307
+ :href => "http://www.example.com/people/#{person_id}/salmon")
308
+ end
309
+
310
+ it "should contain magic-public-key link" do
311
+ authorization = create_authorization("username" => "wilkie",
312
+ "password" => "foobar")
313
+ person_id = authorization.person.id
314
+
315
+ authorization.identity.public_key = "PUBLIC_KEY"
316
+
317
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
318
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
319
+ .must_include(:rel => "magic-public-key",
320
+ :href => "data:application/magic-public-key,PUBLIC_KEY")
321
+ end
322
+
323
+ it "should contain an expires link that is 1 month away from retrieval" do
324
+ authorization = create_authorization("username" => "wilkie",
325
+ "password" => "foobar")
326
+
327
+ check_date = Date.new(2012, 1, 1)
328
+ Date.any_instance.expects(:>>).with(1).returns(check_date)
329
+
330
+ Nelumba::Authorization.stubs(:find_by_username).returns(authorization)
331
+ Nelumba::Authorization.lrdd("wilkie@www.example.com")[:expires].must_equal(
332
+ "#{check_date.xmlschema}Z")
333
+ end
334
+ end
335
+
336
+ describe "jrd" do
337
+ it "should simply take the lrdd and run to_json" do
338
+ lrdd_hash = {}
339
+ Nelumba::Authorization.stubs(:lrdd).with("wilkie@www.example.com").returns(lrdd_hash)
340
+ lrdd_hash.stubs(:to_json).returns("JSON")
341
+
342
+ Nelumba::Authorization.jrd("wilkie@www.example.com").must_equal "JSON"
343
+ end
344
+
345
+ it "should return nil when lrdd returns nil" do
346
+ Nelumba::Authorization.stubs(:lrdd).returns(nil)
347
+ Nelumba::Authorization.jrd("bogus@www.example.com").must_equal nil
348
+ end
349
+ end
350
+
351
+ describe "xrd" do
352
+ before do
353
+ @authorization = create_authorization("username" => "wilkie",
354
+ "password" => "foobar")
355
+
356
+ Nelumba::Authorization.stubs(:lrdd).returns(:subject => "Subject",
357
+ :expires => "Date",
358
+ :aliases => ["alias_a",
359
+ "alias_b"],
360
+ :links => [
361
+ {:rel => "a rel",
362
+ :href => "a href"},
363
+ {:rel => "b rel",
364
+ :href => "b href"}])
365
+
366
+ @xrd = Nelumba::Authorization.xrd("wilkie@www.example.com")
367
+
368
+ @xml = XML::Parser.string(@xrd).parse
369
+ end
370
+
371
+ it "should return nil when lrdd returns nil" do
372
+ Nelumba::Authorization.stubs(:lrdd).returns(nil)
373
+ Nelumba::Authorization.xrd("bogus@www.example.com").must_equal nil
374
+ end
375
+
376
+ it "should publish a version of 1.0" do
377
+ @xrd.must_match /^<\?xml[^>]*\sversion="1\.0"/
378
+ end
379
+
380
+ it "should encode in utf-8" do
381
+ @xrd.must_match /^<\?xml[^>]*\sencoding="UTF-8"/
382
+ end
383
+
384
+ it "should contain the XRD namespace" do
385
+ @xml.root.namespaces
386
+ .find_by_href('http://docs.oasis-open.org/ns/xri/xrd-1.0').to_s
387
+ .must_equal 'http://docs.oasis-open.org/ns/xri/xrd-1.0'
388
+ end
389
+
390
+ it "should contain the xsi namespace" do
391
+ @xml.root.namespaces
392
+ .find_by_prefix('xsi').to_s
393
+ .must_equal 'xsi:http://www.w3.org/2001/XMLSchema-instance'
394
+ end
395
+
396
+ it "should contain the <Subject>" do
397
+ @xml.root.find_first('xmlns:Subject',
398
+ 'xmlns:http://docs.oasis-open.org/ns/xri/xrd-1.0')
399
+ .content.must_equal Nelumba::Authorization.lrdd("wilkie@www.example.com")[:subject]
400
+ end
401
+
402
+ it "should contain the <Expires>" do
403
+ @xml.root.find_first('xmlns:Expires',
404
+ 'xmlns:http://docs.oasis-open.org/ns/xri/xrd-1.0')
405
+ .content.must_equal Nelumba::Authorization.lrdd("wilkie@www.example.com")[:expires]
406
+ end
407
+
408
+ it "should contain the <Alias> tags" do
409
+ aliases = Nelumba::Authorization.lrdd("wilkie@www.example.com")[:aliases]
410
+ @xml.root.find('xmlns:Alias',
411
+ 'xmlns:http://docs.oasis-open.org/ns/xri/xrd-1.0').each do |t|
412
+ index = aliases.index(t.content)
413
+ index.wont_equal nil
414
+
415
+ aliases.delete_at index
416
+ end
417
+ end
418
+
419
+ it "should contain the <Link> tags" do
420
+ links = Nelumba::Authorization.lrdd("wilkie@www.example.com")[:links]
421
+ @xml.root.find('xmlns:Link',
422
+ 'xmlns:http://docs.oasis-open.org/ns/xri/xrd-1.0').each do |t|
423
+ link = {:rel => t.attributes.get_attribute('rel').value,
424
+ :href => t.attributes.get_attribute('href').value}
425
+ index = links.index(link)
426
+ index.wont_equal nil
427
+
428
+ links.delete_at index
429
+ end
430
+ end
431
+ end
432
+
433
+ describe "hash_password" do
434
+ it "should call bcrypt with the application specified number of rounds" do
435
+ BCrypt::Password.expects(:create).with(anything, has_entry(:cost, 1234))
436
+ Nelumba::Authorization.hash_password("foobar")
437
+ end
438
+
439
+ it "should call bcrypt with the given password" do
440
+ BCrypt::Password.expects(:create).with("foobar", anything)
441
+ Nelumba::Authorization.hash_password("foobar")
442
+ end
443
+
444
+ it "should return the hashed password" do
445
+ BCrypt::Password.expects(:create).returns("hashed!")
446
+ Nelumba::Authorization.hash_password("foobar").must_equal "hashed!"
447
+ end
448
+ end
449
+
450
+ describe "#authenticated?" do
451
+ it "should compare the given password with the stored password" do
452
+ authorization = create_authorization("username" => "wilkie",
453
+ "password" => "foobar")
454
+
455
+ checker = stub('String')
456
+ BCrypt::Password.stubs(:new).with("hashed").returns(checker)
457
+
458
+ checker.expects(:==).with("foobar")
459
+ authorization.authenticated?("foobar")
460
+ end
461
+ end
462
+
463
+ describe "sanitize_params" do
464
+ it "should allow Nelumba::Authorization keys" do
465
+ hash = {}
466
+ Nelumba::Authorization.keys.keys.each do |k|
467
+ next if ["_id"].include? k
468
+ hash[k] = "foobar"
469
+ end
470
+
471
+ hash = Nelumba::Authorization.sanitize_params(hash)
472
+
473
+ Nelumba::Authorization.keys.keys.each do |k|
474
+ next if ["_id"].include? k
475
+ hash[k.intern].must_equal "foobar"
476
+ end
477
+ end
478
+
479
+ it "should remove password key" do
480
+ hash = {"password" => "foobar"}
481
+ hash = Nelumba::Authorization.sanitize_params(hash)
482
+ hash.keys.wont_include :password
483
+ end
484
+
485
+ it "should convert strings to symbols" do
486
+ hash = {}
487
+ Nelumba::Authorization.keys.keys.each do |k|
488
+ next if ["_id"].include? k
489
+ hash[k] = "foobar"
490
+ end
491
+
492
+ hash = Nelumba::Authorization.sanitize_params(hash)
493
+
494
+ Nelumba::Authorization.keys.keys.each do |k|
495
+ next if ["_id"].include? k
496
+ hash[k.intern].must_equal "foobar"
497
+ end
498
+ end
499
+
500
+ it "should not allow _id" do
501
+ hash = {"_id" => "bogus"}
502
+ hash = Nelumba::Authorization.sanitize_params(hash)
503
+ hash.keys.wont_include :_id
504
+ end
505
+
506
+ it "should not allow arbitrary keys" do
507
+ hash = {:bogus => "foobar"}
508
+
509
+ hash = Nelumba::Authorization.sanitize_params(hash)
510
+
511
+ hash.keys.wont_include :bogus
512
+ end
513
+ end
514
+ end