simply_stored 0.5.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,249 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/fixtures/couch')
3
-
4
- class InstanceLifecycleTest < Test::Unit::TestCase
5
- context "A simply stored couch instance" do
6
- setup do
7
- CouchPotato::Config.database_name = 'simply_stored_test'
8
- recreate_db
9
- end
10
-
11
- context "design documents" do
12
- should "delete all" do
13
- db = "http://127.0.0.1:5984/#{CouchPotato::Config.database_name}"
14
- assert_equal 0, SimplyStored::Couch.delete_all_design_documents(db)
15
- user = User.create
16
- Post.create(:user => user)
17
- user.posts
18
- assert_equal 1, SimplyStored::Couch.delete_all_design_documents(db)
19
- end
20
-
21
- should "compact all" do
22
- db = "http://127.0.0.1:5984/#{CouchPotato::Config.database_name}"
23
- assert_equal 0, SimplyStored::Couch.compact_all_design_documents(db)
24
- user = User.create
25
- Post.create(:user => user)
26
- user.posts
27
- assert_equal 1, SimplyStored::Couch.compact_all_design_documents(db)
28
- end
29
- end
30
-
31
- context "when creating instances" do
32
- should "populate the attributes" do
33
- user = User.create(:title => "Mr.", :name => "Host Master")
34
- assert_equal "Mr.", user.title
35
- assert_equal "Host Master", user.name
36
- end
37
-
38
- should "save the instance" do
39
- user = User.create(:title => "Mr.")
40
- assert !user.new_record?
41
- end
42
-
43
- context "with a bang" do
44
- should 'not raise an exception when saving succeeded' do
45
- assert_nothing_raised do
46
- User.create!(:title => "Mr.")
47
- end
48
- end
49
-
50
- should 'save the user' do
51
- user = User.create!(:title => "Mr.")
52
- assert !user.new_record?
53
- end
54
-
55
- should 'raise an error when the validations failed' do
56
- assert_raises(CouchPotato::Database::ValidationsFailedError) do
57
- User.create!(:title => nil)
58
- end
59
- end
60
- end
61
-
62
- context "with a block" do
63
- should 'call the block with the record' do
64
- user = User.create do |u|
65
- u.title = "Mr."
66
- end
67
-
68
- assert_equal "Mr.", user.title
69
- end
70
-
71
- should 'save the record' do
72
- user = User.create do |u|
73
- u.title = "Mr."
74
- end
75
- assert !user.new_record?
76
- end
77
-
78
- should 'assign attributes via the hash' do
79
- user = User.create(:title => "Mr.") do |u|
80
- u.name = "Host Master"
81
- end
82
-
83
- assert_equal "Mr.", user.title
84
- assert_equal "Host Master", user.name
85
- end
86
- end
87
- end
88
-
89
- context "when saving an instance" do
90
- should "um, save the instance" do
91
- user = User.new(:title => "Mr.")
92
- assert user.new_record?
93
- user.save
94
- assert !user.new_record?
95
- end
96
-
97
- context "when using save!" do
98
- should 'raise an exception when a validation isnt fulfilled' do
99
- user = User.new
100
- assert_raises(CouchPotato::Database::ValidationsFailedError) do
101
- user.save!
102
- end
103
- end
104
- end
105
-
106
- context "when using save(false)" do
107
- should "not run the validations" do
108
- user = User.new
109
- user.save(false)
110
- assert !user.new?
111
- assert !user.dirty?
112
- end
113
- end
114
- end
115
-
116
- context "when destroying an instance" do
117
- should "remove the instance" do
118
- user = User.create(:title => "Mr")
119
- assert_difference 'User.find(:all).size', -1 do
120
- user.destroy
121
- end
122
- end
123
-
124
- should 'return the frozen instance, brrrr' do
125
- user = User.create(:title => "Mr")
126
- assert_equal user, user.destroy
127
- end
128
- end
129
-
130
- context "when updating attributes" do
131
- should "merge in the updated attributes" do
132
- user = User.create(:title => "Mr.")
133
- user.update_attributes(:title => "Mrs.")
134
- assert_equal "Mrs.", user.title
135
- end
136
-
137
- should "save the instance" do
138
- user = User.create(:title => "Mr.")
139
- user.update_attributes(:title => "Mrs.")
140
- assert !user.dirty?
141
- end
142
- end
143
-
144
-
145
- context "when counting" do
146
- setup do
147
- recreate_db
148
- end
149
-
150
- context "when counting all" do
151
- should "return the number of objects in the database" do
152
- CountMe.create(:title => "Mr.")
153
- CountMe.create(:title => "Mrs.")
154
- assert_equal 2, CountMe.find(:all).size
155
- assert_equal 2, CountMe.count
156
- end
157
-
158
- should "only count the correct class" do
159
- CountMe.create(:title => "Mr.")
160
- DontCountMe.create(:title => 'Foo')
161
- assert_equal 1, CountMe.find(:all).size
162
- assert_equal 1, CountMe.count
163
- end
164
- end
165
-
166
- context "when counting by prefix" do
167
- should "return the number of matching objects" do
168
- CountMe.create(:title => "Mr.")
169
- CountMe.create(:title => "Mrs.")
170
- assert_equal 1, CountMe.find_all_by_title('Mr.').size
171
- assert_equal 1, CountMe.count_by_title('Mr.')
172
- end
173
-
174
- should "only count the correct class" do
175
- CountMe.create(:title => "Mr.")
176
- DontCountMe.create(:title => 'Mr.')
177
- assert_equal 1, CountMe.find_all_by_title('Mr.').size
178
- assert_equal 1, CountMe.count_by_title('Mr.')
179
- end
180
- end
181
- end
182
-
183
- context "when reloading an instance" do
184
- should "reload new attributes from the database" do
185
- user = User.create(:title => "Mr.", :name => "Host Master")
186
- user2 = User.find(user.id)
187
- user2.update_attributes(:title => "Mrs.", :name => "Hostess Masteress")
188
- user.reload
189
- assert_equal "Mrs.", user.title
190
- assert_equal "Hostess Masteress", user.name
191
- end
192
-
193
- should "remove attributes that are no longer in the database" do
194
- user = User.create(:title => "Mr.", :name => "Host Master")
195
- assert_not_nil user.name
196
- same_user_in_different_thread = User.find(user.id)
197
- same_user_in_different_thread.name = nil
198
- same_user_in_different_thread.save!
199
- assert_nil user.reload.name
200
- end
201
-
202
- should "also remove foreign key attributes that are no longer in the database" do
203
- user = User.create(:title => "Mr.", :name => "Host Master")
204
- post = Post.create(:user => user)
205
- assert_not_nil post.user_id
206
- same_post_in_different_thread = Post.find(post.id)
207
- same_post_in_different_thread.user = nil
208
- same_post_in_different_thread.save!
209
- assert_nil post.reload.user_id
210
- end
211
-
212
- should "not be dirty after reloading" do
213
- user = User.create(:title => "Mr.", :name => "Host Master")
214
- user2 = User.find(user.id)
215
- user2.update_attributes(:title => "Mrs.", :name => "Hostess Masteress")
216
- user.reload
217
- assert !user.dirty?
218
- end
219
-
220
- should "ensure that association caches for has_many are cleared" do
221
- user = User.create(:title => "Mr.", :name => "Host Master")
222
- post = Post.create(:user => user)
223
- assert_equal 1, user.posts.size
224
- assert_not_nil user.instance_variable_get("@posts")
225
- user.reload
226
- assert_nil user.instance_variable_get("@posts")
227
- assert_not_nil user.posts.first
228
- end
229
-
230
- should "ensure that association caches for belongs_to are cleared" do
231
- user = User.create(:title => "Mr.", :name => "Host Master")
232
- post = Post.create(:user => user)
233
- post.user
234
- assert_not_nil post.instance_variable_get("@user")
235
- post.reload
236
- assert_nil post.instance_variable_get("@user")
237
- assert_not_nil post.user
238
- end
239
-
240
- should "update the revision" do
241
- user = User.create(:title => "Mr.", :name => "Host Master")
242
- user2 = User.find(user.id)
243
- user2.update_attributes(:title => "Mrs.", :name => "Hostess Masteress")
244
- user.reload
245
- assert_equal user._rev, user2._rev
246
- end
247
- end
248
- end
249
- end
@@ -1,77 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/fixtures/couch')
3
-
4
- class MassAssignmentProtectionTest < Test::Unit::TestCase
5
- context "attribute proctection against mass assignment" do
6
- setup do
7
- CouchPotato::Config.database_name = 'simply_stored_test'
8
- recreate_db
9
- end
10
-
11
- context "when using attr_protected" do
12
- setup do
13
- Category.instance_eval do
14
- @_accessible_attributes = []
15
- attr_protected :parent, :alias
16
- end
17
- end
18
-
19
- should "not allow to set with mass assignment using attributes=" do
20
- item = Category.new
21
- item.attributes = {:parent => 'a', :name => 'c'}
22
- assert_equal 'c', item.name
23
- assert_nil item.parent
24
- end
25
-
26
- should "not allow to set with mass assignment using attributes= - ignore string vs. symbol" do
27
- item = Category.new
28
- item.attributes = {'parent' => 'a', 'name' => 'c'}
29
- assert_equal 'c', item.name
30
- assert_nil item.parent
31
- end
32
-
33
- should "not allow to set with mass assignment using the constructor" do
34
- item = Category.new(:parent => 'a', :name => 'c')
35
- assert_equal 'c', item.name
36
- assert_nil item.parent
37
- end
38
-
39
- should "not allow to set with mass assignment using update_attributes" do
40
- item = Category.new
41
- item.update_attributes(:parent => 'a', :name => 'c')
42
- assert_equal 'c', item.name
43
- assert_nil item.parent
44
- end
45
- end
46
-
47
- context "attr_accessible" do
48
- setup do
49
- Category.instance_eval do
50
- @_protected_attributes = []
51
- attr_accessible :name
52
- end
53
- end
54
-
55
- should "not allow to set with mass assignment using attributes=" do
56
- item = Category.new
57
- item.attributes = {:parent => 'a', :name => 'c'}
58
- assert_equal 'c', item.name
59
- assert_nil item.parent
60
- end
61
-
62
- should "not allow to set with mass assignment using the constructor" do
63
- item = Category.new(:parent => 'a', :name => 'c')
64
- assert_equal 'c', item.name
65
- assert_nil item.parent
66
- end
67
-
68
- should "not allow to set with mass assignment using update_attributes" do
69
- item = Category.new
70
- item.update_attributes(:parent => 'a', :name => 'c')
71
- # item.reload
72
- assert_equal 'c', item.name
73
- assert_nil item.parent
74
- end
75
- end
76
- end
77
- end
data/test/s3_test.rb DELETED
@@ -1,256 +0,0 @@
1
- require File.expand_path(File.dirname(__FILE__) + '/test_helper')
2
- require File.expand_path(File.dirname(__FILE__) + '/fixtures/couch')
3
-
4
- class S3Test < Test::Unit::TestCase
5
- context "with s3 interaction" do
6
- setup do
7
- CouchPotato::Config.database_name = 'simply_stored_test'
8
- recreate_db
9
- CouchLogItem.instance_variable_set(:@_s3_connection, nil)
10
- CouchLogItem._s3_options[:log_data][:ca_file] = nil
11
-
12
- bucket = stub(:bckt) do
13
- stubs(:put).returns(true)
14
- stubs(:get).returns(true)
15
- end
16
-
17
- @bucket = bucket
18
-
19
- @s3 = stub(:s3) do
20
- stubs(:bucket).returns(bucket)
21
- end
22
-
23
- RightAws::S3.stubs(:new).returns @s3
24
- @log_item = CouchLogItem.new
25
- end
26
-
27
- context "when saving the attachment" do
28
- should "fetch the collection" do
29
- @log_item.log_data = "Yay! It logged!"
30
- RightAws::S3.expects(:new).with('abcdef', 'secret!', :multi_thread => true, :ca_file => nil, :logger => nil).returns(@s3)
31
- @log_item.save
32
- end
33
-
34
- should "upload the file" do
35
- @log_item.log_data = "Yay! It logged!"
36
- @bucket.expects(:put).with(anything, "Yay! It logged!", {}, anything)
37
- @log_item.save
38
- end
39
-
40
- should "also upload on save!" do
41
- @log_item.log_data = "Yay! It logged!"
42
- @bucket.expects(:put).with(anything, "Yay! It logged!", {}, anything)
43
- @log_item.save!
44
- end
45
-
46
- should "use the specified bucket" do
47
- @log_item.log_data = "Yay! It logged!"
48
- CouchLogItem._s3_options[:log_data][:bucket] = 'mybucket'
49
- @s3.expects(:bucket).with('mybucket').returns(@bucket)
50
- @log_item.save
51
- end
52
-
53
- should "create the bucket if it doesn't exist" do
54
- @log_item.log_data = "Yay! log me"
55
- CouchLogItem._s3_options[:log_data][:bucket] = 'mybucket'
56
-
57
- @s3.expects(:bucket).with('mybucket').returns(nil)
58
- @s3.expects(:bucket).with('mybucket', true, 'private', :location => nil).returns(@bucket)
59
- @log_item.save
60
- end
61
-
62
- should "accept :us location option but not set it in RightAWS::S3" do
63
- @log_item.log_data = "Yay! log me"
64
- CouchLogItem._s3_options[:log_data][:bucket] = 'mybucket'
65
- CouchLogItem._s3_options[:log_data][:location] = :us
66
-
67
- @s3.expects(:bucket).with('mybucket').returns(nil)
68
- @s3.expects(:bucket).with('mybucket', true, 'private', :location => nil).returns(@bucket)
69
- @log_item.save
70
- end
71
-
72
- should "raise an error if the bucket is not ours" do
73
- @log_item.log_data = "Yay! log me too"
74
- CouchLogItem._s3_options[:log_data][:bucket] = 'mybucket'
75
- CouchLogItem._s3_options[:log_data][:location] = :eu
76
-
77
- @s3.expects(:bucket).with('mybucket').returns(nil)
78
- @s3.expects(:bucket).with('mybucket', true, 'private', :location => :eu).raises(RightAws::AwsError, 'BucketAlreadyExists: The requested bucket name is not available. The bucket namespace is shared by all users of the system. Please select a different name and try again')
79
-
80
- assert_raise(ArgumentError) do
81
- @log_item.save
82
- end
83
- end
84
-
85
- should "pass the logger object down to RightAws" do
86
- logger = mock()
87
- @log_item.log_data = "Yay! log me"
88
- CouchLogItem._s3_options[:log_data][:bucket] = 'mybucket'
89
- CouchLogItem._s3_options[:log_data][:logger] = logger
90
-
91
- RightAws::S3.expects(:new).with(anything, anything, {:logger => logger, :ca_file => nil, :multi_thread => true}).returns(@s3)
92
- @log_item.save
93
- end
94
-
95
- should "not upload the attachment when it hasn't been changed" do
96
- @bucket.expects(:put).never
97
- @log_item.save
98
- end
99
-
100
- should "set the permissions to private by default" do
101
- class Item
102
- include SimplyStored::Couch
103
- has_s3_attachment :log_data, :bucket => 'mybucket'
104
- end
105
- @bucket.expects(:put).with(anything, anything, {}, 'private')
106
- @log_item = Item.new
107
- @log_item.log_data = 'Yay!'
108
- @log_item.save
109
- end
110
-
111
- should "set the permissions to whatever's specified in the options for the attachment" do
112
- @log_item.save
113
- old_perms = CouchLogItem._s3_options[:log_data][:permissions]
114
- CouchLogItem._s3_options[:log_data][:permissions] = 'public-read'
115
- @bucket.expects(:put).with(anything, anything, {}, 'public-read')
116
- @log_item.log_data = 'Yay!'
117
- @log_item.save
118
- CouchLogItem._s3_options[:log_data][:permissions] = old_perms
119
- end
120
-
121
- should "use the full class name and the id as key" do
122
- @log_item.save
123
- @bucket.expects(:put).with("couch_log_items/log_data/#{@log_item.id}", 'Yay!', {}, anything)
124
- @log_item.log_data = 'Yay!'
125
- @log_item.save
126
- end
127
-
128
- should "mark the attachment as not dirty after uploading" do
129
- @log_item.log_data = 'Yay!'
130
- @log_item.save
131
- assert !@log_item.instance_variable_get(:@_s3_attachments)[:log_data][:dirty]
132
- end
133
-
134
- should 'store the attachment when the validations succeeded' do
135
- @log_item.log_data = 'Yay!'
136
- @log_item.stubs(:valid?).returns(true)
137
- @bucket.expects(:put)
138
- @log_item.save
139
- end
140
-
141
- should "not store the attachment when the validations failed" do
142
- @log_item.log_data = 'Yay!'
143
- @log_item.stubs(:valid?).returns(false)
144
- @bucket.expects(:put).never
145
- @log_item.save
146
- end
147
-
148
- should "save the attachment status" do
149
- @log_item.save
150
- @log_item.attributes["log_data_attachments"]
151
- end
152
-
153
- should "save generate the url for the attachment" do
154
- @log_item._s3_options[:log_data][:bucket] = 'bucket-for-monsieur'
155
- @log_item._s3_options[:log_data][:permissions] = 'public-read'
156
- @log_item.save
157
- assert_equal "http://bucket-for-monsieur.s3.amazonaws.com/#{@log_item.s3_attachment_key(:log_data)}", @log_item.log_data_url
158
- end
159
-
160
- should "add a short-lived access key for private attachments" do
161
- @log_item._s3_options[:log_data][:bucket] = 'bucket-for-monsieur'
162
- @log_item._s3_options[:log_data][:location] = :us
163
- @log_item._s3_options[:log_data][:permissions] = 'private'
164
- @log_item.save
165
- assert @log_item.log_data_url.gsub("%2F", '/').include?("https://bucket-for-monsieur.s3.amazonaws.com:443/#{@log_item.s3_attachment_key(:log_data)}"), @log_item.log_data_url
166
- assert @log_item.log_data_url.include?("Signature=")
167
- assert @log_item.log_data_url.include?("Expires=")
168
- end
169
-
170
- should "serialize data other than strings to json" do
171
- @log_item.log_data = ['one log entry', 'and another one']
172
- @bucket.expects(:put).with(anything, '["one log entry","and another one"]', {}, anything)
173
- @log_item.save
174
- end
175
-
176
- context "when noting the size of the attachment" do
177
- should "store on upload" do
178
- @log_item.log_data = 'abc'
179
- @bucket.expects(:put)
180
- assert @log_item.save
181
- assert_equal 3, @log_item.log_data_size
182
- end
183
-
184
- should "update the size if the attachment gets updated" do
185
- @log_item.log_data = 'abc'
186
- @bucket.stubs(:put)
187
- assert @log_item.save
188
- assert_equal 3, @log_item.log_data_size
189
-
190
- @log_item.log_data = 'example'
191
- assert @log_item.save
192
- assert_equal 7, @log_item.log_data_size
193
- end
194
-
195
- should "store the size of json attachments" do
196
- @log_item.log_data = ['abc']
197
- @bucket.stubs(:put)
198
- assert @log_item.save
199
- assert_equal ['abc'].to_json.size, @log_item.log_data_size
200
- end
201
- end
202
- end
203
-
204
- context "when fetching the data" do
205
- should "create a configured S3 connection" do
206
- CouchLogItem._s3_options[:log_data][:bucket] = 'mybucket'
207
- CouchLogItem._s3_options[:log_data][:location] = :eu
208
- CouchLogItem._s3_options[:log_data][:ca_file] = '/etc/ssl/ca.crt'
209
-
210
- RightAws::S3.expects(:new).with('abcdef', 'secret!', :multi_thread => true, :ca_file => '/etc/ssl/ca.crt', :logger => nil).returns(@s3)
211
-
212
- @log_item.log_data
213
- end
214
-
215
- should "fetch the data from s3 and set the attachment attribute" do
216
- @log_item.instance_variable_set(:@_s3_attachments, {})
217
- @bucket.expects(:get).with("couch_log_items/log_data/#{@log_item.id}").returns("Yay!")
218
- assert_equal "Yay!", @log_item.log_data
219
- end
220
-
221
- should "not mark the the attachment as dirty" do
222
- @log_item.instance_variable_set(:@_s3_attachments, {})
223
- @bucket.expects(:get).with("couch_log_items/log_data/#{@log_item.id}").returns("Yay!")
224
- @log_item.log_data
225
- assert !@log_item._s3_attachments[:log_data][:dirty]
226
- end
227
-
228
- should "not try to fetch the attachment if the value is already set" do
229
- @log_item.log_data = "Yay!"
230
- @bucket.expects(:get).never
231
- assert_equal "Yay!", @log_item.log_data
232
- end
233
- end
234
-
235
- context "when deleting" do
236
- setup do
237
- CouchLogItem._s3_options[:log_data][:after_delete] = :nothing
238
- @log_item.log_data = 'Yatzzee'
239
- @log_item.save
240
- end
241
-
242
- should "do nothing to S3" do
243
- @bucket.expects(:key).never
244
- @log_item.delete
245
- end
246
-
247
- should "also delete on S3 if configured so" do
248
- CouchLogItem._s3_options[:log_data][:after_delete] = :delete
249
- s3_key = mock(:delete => true)
250
- @bucket.expects(:key).with(@log_item.s3_attachment_key('log_data'), true).returns(s3_key)
251
- @log_item.delete
252
- end
253
-
254
- end
255
- end
256
- end