tinkit 0.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +176 -0
- data/README +11 -0
- data/Rakefile +75 -0
- data/lib/glue_envs/couchrest/couchrest_attachment_handler.rb +260 -0
- data/lib/glue_envs/couchrest/couchrest_files_mgr.rb +198 -0
- data/lib/glue_envs/couchrest_glue_env.rb +536 -0
- data/lib/glue_envs/files_mgr_base.rb +51 -0
- data/lib/glue_envs/filesystem/filesystem_files_mgr.rb +187 -0
- data/lib/glue_envs/filesystem_glue_env.rb +395 -0
- data/lib/glue_envs/mysql/mysql_files_mgr.rb +175 -0
- data/lib/glue_envs/mysql_glue_env.rb +428 -0
- data/lib/glue_envs/sdb_s3/sdb_s3_files_mgr.rb +314 -0
- data/lib/glue_envs/sdb_s3_glue_env.rb +248 -0
- data/lib/helpers/camel.rb +21 -0
- data/lib/helpers/filesystem_helpers.rb +27 -0
- data/lib/helpers/hash_helpers.rb +74 -0
- data/lib/helpers/log_helper.rb +34 -0
- data/lib/helpers/mime_types_new.rb +126 -0
- data/lib/helpers/old_more_open_struct.rb +28 -0
- data/lib/helpers/require_helper.rb +45 -0
- data/lib/helpers/tk_escape.rb +17 -0
- data/lib/midas/bufs_data_structure.rb +84 -0
- data/lib/midas/node_element_operations.rb +264 -0
- data/lib/tinkit.rb +38 -0
- data/lib/tinkit_base_node.rb +733 -0
- data/lib/tinkit_node_factory.rb +47 -0
- data/spec/couchrest_files_mgr_spec.rb +551 -0
- data/spec/couchrest_glue_spec.rb +246 -0
- data/spec/filesystem_files_mgr_spec.rb +236 -0
- data/spec/filesystem_glue_spec.rb +243 -0
- data/spec/filesystem_helpers_spec.rb +42 -0
- data/spec/helpers/bufs_node_builder.rb +17 -0
- data/spec/helpers/bufs_sample_dataset.rb +160 -0
- data/spec/helpers/bufs_test_environments.rb +81 -0
- data/spec/helpers/tmp_view_cleaner.rb +15 -0
- data/spec/lib_helpers/tk_escape_spec.rb +45 -0
- data/spec/mysql_files_mgr_spec.rb +250 -0
- data/spec/mysql_glue_spec.rb +214 -0
- data/spec/node_element_operations_spec.rb +392 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec1.rb +82 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec2.rb +68 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec3.rb +80 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec4.rb +110 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec5.rb +84 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec6.rb +83 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec7.rb +101 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec8.rb +92 -0
- data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec_all.rb +266 -0
- data/spec/sdb_s3_glue_spec.rb +230 -0
- data/spec/tinkit_node_factory_spec.rb +1108 -0
- metadata +114 -0
@@ -0,0 +1,47 @@
|
|
1
|
+
#require helper for cleaner require statements
|
2
|
+
require File.join(File.dirname(__FILE__), '/helpers/require_helper')
|
3
|
+
|
4
|
+
require Tinkit.lib 'tinkit_base_node'
|
5
|
+
require Tinkit.helpers 'log_helper'
|
6
|
+
|
7
|
+
class TinkitNodeFactory
|
8
|
+
#Set Logger
|
9
|
+
@@log = TinkitLog.set(self.name, :debug)
|
10
|
+
|
11
|
+
def self.make(node_env)
|
12
|
+
TinkitLog.log_raise "No Node Environment provided" unless node_env
|
13
|
+
TinkitLog.log_raise "Empty Node Environment provided" if node_env.empty?
|
14
|
+
TinkitLog.log_raise "Malformed Node Environment" unless node_env.respond_to?(:keys)
|
15
|
+
TinkitLog.log_raise "Malformed Node Environment" unless node_env.keys.include? :persist_model
|
16
|
+
|
17
|
+
|
18
|
+
neo_env = node_env[:data_model] || {}
|
19
|
+
|
20
|
+
neo = NodeElementOperations.new(neo_env)
|
21
|
+
data_model_bindings = {:key_fields => neo.key_fields,
|
22
|
+
#:data_ops_set => neo.field_op_set_sym,
|
23
|
+
:views => neo.views}
|
24
|
+
|
25
|
+
#TODO: Make setting the environment thread safe
|
26
|
+
class_environment = node_env[:persist_model]
|
27
|
+
user_doc_class_name = node_env[:node_class_id]
|
28
|
+
|
29
|
+
#Security TODO: remove spaces and other
|
30
|
+
|
31
|
+
#---- Dynamic Class Definitions ----
|
32
|
+
dyn_user_class_def = "class #{user_doc_class_name} < TinkitBaseNode
|
33
|
+
|
34
|
+
class << self; attr_accessor :user_attachClass, end
|
35
|
+
|
36
|
+
end"
|
37
|
+
|
38
|
+
TinkitNodeFactory.class_eval(dyn_user_class_def)
|
39
|
+
docClass = TinkitNodeFactory.const_get(user_doc_class_name)
|
40
|
+
|
41
|
+
docClass.data_struc = neo
|
42
|
+
|
43
|
+
#TODO: Streamline the paramaters (maybe one env paramater?)
|
44
|
+
docClass.set_environment(class_environment, data_model_bindings)
|
45
|
+
docClass
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,551 @@
|
|
1
|
+
#require helper for cleaner require statements
|
2
|
+
require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/helpers/require_helper')
|
3
|
+
|
4
|
+
require 'spec'
|
5
|
+
require 'couchrest'
|
6
|
+
|
7
|
+
require Tinkit.glue 'couchrest/couchrest_files_mgr'
|
8
|
+
|
9
|
+
include CouchrestInterface
|
10
|
+
|
11
|
+
FileMgrTestDb = CouchRest.database!("http://127.0.0.1:5984/couchrest_file_mgr_test")
|
12
|
+
FileMgrTestDb.compact!
|
13
|
+
|
14
|
+
GlueEnvMock = Struct.new(:model_key, :user_id, :moab_data)
|
15
|
+
|
16
|
+
class MockAttachClass < CouchrestAttachment
|
17
|
+
use_database FileMgrTestDb
|
18
|
+
|
19
|
+
def self.namespace
|
20
|
+
FileMgrTestDb
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
class MockNode
|
25
|
+
attr_accessor :_id, :my_GlueEnv, :_model_metadata, :attachment_doc_id
|
26
|
+
|
27
|
+
def initialize(id, glue_env, model_md)
|
28
|
+
@_id = id
|
29
|
+
@my_GlueEnv = glue_env
|
30
|
+
@_model_metadata = model_md
|
31
|
+
@atts = {}
|
32
|
+
end
|
33
|
+
|
34
|
+
def __set_userdata_key(node_att_doc_id, db_att_doc_id)
|
35
|
+
@attachment_doc_id = db_att_doc_id
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
40
|
+
describe FilesMgr, "Setup and intialization" do
|
41
|
+
|
42
|
+
before(:all) do
|
43
|
+
moab_data = {:attachClass => MockAttachClass, :db => FileMgrTestDb }
|
44
|
+
@glue_env_mock = GlueEnvMock.new("_id", "couchrest_user", moab_data)
|
45
|
+
@node_key = :_id
|
46
|
+
|
47
|
+
file1_data = "Example File1\nJust some text"
|
48
|
+
file2_data = "Example File2\nJust some more text"
|
49
|
+
file1_fname = "/tmp/example_file1.txt"
|
50
|
+
file2_fname = "/tmp/example_file2.txt"
|
51
|
+
files = {file1_fname => file1_data, file2_fname => file2_data}
|
52
|
+
files.each do |fname, data|
|
53
|
+
File.open(fname, 'w'){|f| f.write(data)}
|
54
|
+
end
|
55
|
+
@file_datas = [{:src_filename => file1_fname}, {:src_filename => file2_fname}]
|
56
|
+
@node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should initialize" do
|
60
|
+
node_key_value = @node1_data[@node_key]
|
61
|
+
attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
|
62
|
+
att_class_base_name = "MoabAttachmentHandler"
|
63
|
+
user_id = @glue_env_mock.user_id
|
64
|
+
attach_handler.attachment_doc_class.should == @glue_env_mock.moab_data[:attachClass]
|
65
|
+
end
|
66
|
+
end
|
67
|
+
|
68
|
+
describe FilesMgr, "Basic Operations" do
|
69
|
+
before(:all) do
|
70
|
+
#@user_datastore_location = "/tmp/datastore_location"
|
71
|
+
@file1_fname = "/tmp/example_file1.txt"
|
72
|
+
@file2_fname = "/tmp/example_file2.txt"
|
73
|
+
f1_bname = File.basename(@file1_fname)
|
74
|
+
f2_bname = File.basename(@file2_fname)
|
75
|
+
@file_stored_data = { f1_bname => File.open(@file1_fname, 'rb'){|f| f.read},
|
76
|
+
f2_bname =>File.open(@file2_fname, 'rb'){|f| f.read} }
|
77
|
+
|
78
|
+
@mock_key = :_id
|
79
|
+
#@nodeMockClass = Struct.new(@mock_key, :my_GlueEnv, :"_model_metadata")
|
80
|
+
|
81
|
+
moab_data = {:attachClass => MockAttachClass, :db => FileMgrTestDb }
|
82
|
+
@glue_env_mock = GlueEnvMock.new(@mock_key,
|
83
|
+
"couchrest_user", moab_data)
|
84
|
+
|
85
|
+
@file_datas = [{:src_filename => @file1_fname}, {:src_filename => @file2_fname}]
|
86
|
+
end
|
87
|
+
|
88
|
+
|
89
|
+
before(:each) do
|
90
|
+
@node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
|
91
|
+
model_metadata = {:_id => 'spec_test1'}
|
92
|
+
@node_mock = MockNode.new(@node1_data[@mock_key],
|
93
|
+
@glue_env_mock,
|
94
|
+
model_metadata)
|
95
|
+
|
96
|
+
node_key_value = @node1_data[@mock_key]
|
97
|
+
@attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
|
98
|
+
#@attach_handler.subtract_files(nil, :all)
|
99
|
+
end
|
100
|
+
|
101
|
+
after(:all) do
|
102
|
+
FileMgrTestDb.delete!
|
103
|
+
end
|
104
|
+
|
105
|
+
it "should add and retrieve files" do
|
106
|
+
node = @node_mock
|
107
|
+
|
108
|
+
@file_datas.each do |file_data|
|
109
|
+
file_basename = File.basename(file_data[:src_filename])
|
110
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
111
|
+
data.should be_nil
|
112
|
+
end
|
113
|
+
|
114
|
+
#Add the Files
|
115
|
+
@attach_handler.add(node, @file_datas)
|
116
|
+
|
117
|
+
#Get the files and verify data
|
118
|
+
@file_datas.each do |file_data|
|
119
|
+
file_basename = File.basename(file_data[:src_filename])
|
120
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
121
|
+
data.should == @file_stored_data[file_basename]
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
it "should list attachment files" do
|
126
|
+
files = @attach_handler.list(@node_mock)
|
127
|
+
files.sort.should == @file_stored_data.keys.sort
|
128
|
+
end
|
129
|
+
|
130
|
+
it "should list metadata" do
|
131
|
+
md = @attach_handler.get_attachments_metadata(@node_mock)
|
132
|
+
md.should_not == nil
|
133
|
+
@file_datas.each do |file_data|
|
134
|
+
file_basename = File.basename(file_data[:src_filename])
|
135
|
+
each_md = md[file_basename]
|
136
|
+
each_md.should_not == nil
|
137
|
+
each_md.keys.should include :content_type
|
138
|
+
each_md.keys.should include :file_modified
|
139
|
+
|
140
|
+
file_basename = File.basename(file_data[:src_filename])
|
141
|
+
md[file_basename][:content_type].should =~ /^text\/plain/
|
142
|
+
time_str = md[file_basename][:file_modified]
|
143
|
+
Time.parse(time_str).should >= Time.now - 2 #should have been modified less than 2 seconds ago
|
144
|
+
end
|
145
|
+
end
|
146
|
+
|
147
|
+
it "should be well behaved adding more files" do
|
148
|
+
node = @node_mock
|
149
|
+
|
150
|
+
#Get the original files and verify data
|
151
|
+
@file_datas.each do |file_data|
|
152
|
+
file_basename = File.basename(file_data[:src_filename])
|
153
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
154
|
+
data.should == @file_stored_data[file_basename]
|
155
|
+
end
|
156
|
+
|
157
|
+
#create some more files
|
158
|
+
file1_data = "Example File1\nNEW!! text"
|
159
|
+
file3_data = "Example File3\nYet more text"
|
160
|
+
file4_data = "Example File4\nand more text"
|
161
|
+
file3_fname = "/tmp/example_file3.txt"
|
162
|
+
file4_fname = "/tmp/example_file4.txt"
|
163
|
+
files = {@file1_fname => file1_data, file3_fname => file3_data, file4_fname => file4_data}
|
164
|
+
files.each do |fname, data|
|
165
|
+
File.open(fname, 'w'){|f| f.write(data)}
|
166
|
+
end
|
167
|
+
file1_data.should == File.open(@file1_fname){|f| f.read}
|
168
|
+
|
169
|
+
@file_datas2 = [{:src_filename => @file1_fname},
|
170
|
+
{:src_filename => file3_fname},
|
171
|
+
{:src_filename => file4_fname}]
|
172
|
+
|
173
|
+
|
174
|
+
#add them
|
175
|
+
@attach_handler.add(node, @file_datas2)
|
176
|
+
|
177
|
+
#Check the unchanged file (file2)
|
178
|
+
file2_basename = File.basename(@file2_fname)
|
179
|
+
data2 = @attach_handler.get_raw_data(node, file2_basename)
|
180
|
+
data2.should == @file_stored_data[file2_basename]
|
181
|
+
|
182
|
+
#Get the changed files and verify it is the new data
|
183
|
+
file1_basename = File.basename(@file1_fname)
|
184
|
+
data1 = @attach_handler.get_raw_data(node, file1_basename)
|
185
|
+
data1.should == file1_data
|
186
|
+
|
187
|
+
file3_basename = File.basename(file3_fname)
|
188
|
+
data3 = @attach_handler.get_raw_data(node, file3_basename)
|
189
|
+
data3.should == file3_data
|
190
|
+
|
191
|
+
file4_basename = File.basename(file4_fname)
|
192
|
+
data4 = @attach_handler.get_raw_data(node, file4_basename)
|
193
|
+
data4.should == file4_data
|
194
|
+
end
|
195
|
+
|
196
|
+
it "should delete (subtract) files" do
|
197
|
+
node = @node_mock
|
198
|
+
files_to_delete = [@file1_fname, @file2_fname]
|
199
|
+
#they should exist in the node
|
200
|
+
files_to_delete.each do |fname|
|
201
|
+
file_basename = File.basename(fname)
|
202
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
203
|
+
data.should match /^Example File/
|
204
|
+
end
|
205
|
+
|
206
|
+
basenames_to_delete = files_to_delete.map{|f| File.basename(f)}
|
207
|
+
@attach_handler.subtract(node, basenames_to_delete)
|
208
|
+
|
209
|
+
files_to_delete.each do |fname|
|
210
|
+
file_basename = File.basename(fname)
|
211
|
+
data = @attach_handler.get_raw_data(node, file_basename)
|
212
|
+
data.should be_nil
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
it "should add attachments from the raw data" do
|
217
|
+
node = @node_mock
|
218
|
+
|
219
|
+
raw_data = "Example File3\nYet more text"
|
220
|
+
content_type = "text/plain"
|
221
|
+
modified_at = Time.now.to_s
|
222
|
+
att_name = "example_raw_data.txt"
|
223
|
+
|
224
|
+
#Add the Raw Data
|
225
|
+
@attach_handler.add_raw_data(node, att_name, content_type, raw_data, modified_at)
|
226
|
+
|
227
|
+
#Get the files and verify data
|
228
|
+
|
229
|
+
data = @attach_handler.get_raw_data(node, att_name)
|
230
|
+
md = @attach_handler.get_attachments_metadata(node)[att_name]
|
231
|
+
|
232
|
+
data.should == raw_data
|
233
|
+
md[:content_type].should == content_type
|
234
|
+
md[:file_modified].should == modified_at
|
235
|
+
end
|
236
|
+
|
237
|
+
it "should delete all (subtract_all) files" do
|
238
|
+
node = @node_mock
|
239
|
+
|
240
|
+
#create some more attachments
|
241
|
+
del_data = {}
|
242
|
+
del_data["del_data1"] = "my life will be short"
|
243
|
+
del_data["del_data2"] = "alas too short"
|
244
|
+
|
245
|
+
#add the attachments
|
246
|
+
del_data.each do |name, data|
|
247
|
+
@attach_handler.add_raw_data(node, name, "text/plain", data, Time.now.to_s)
|
248
|
+
end
|
249
|
+
|
250
|
+
#verify it's there
|
251
|
+
del_data.each do |name, data|
|
252
|
+
stored_data = @attach_handler.get_raw_data(node, name)
|
253
|
+
stored_data.should == data
|
254
|
+
end
|
255
|
+
|
256
|
+
#delete it all
|
257
|
+
@attach_handler.subtract(node, :all)
|
258
|
+
|
259
|
+
#verify it's not there
|
260
|
+
del_data.each do |name, data|
|
261
|
+
stored_data = @attach_handler.get_raw_data(node, name)
|
262
|
+
stored_data.should be_nil
|
263
|
+
end
|
264
|
+
end
|
265
|
+
|
266
|
+
end
|
267
|
+
=begin
|
268
|
+
it "should create object and update the database with a single attachment if there is no other doc in database" do
|
269
|
+
#set initial conditions
|
270
|
+
test_file = @test_files['binary_data_pptx']
|
271
|
+
test_file_basename = File.basename(test_file)
|
272
|
+
test_file_modified_time = File.mtime(test_file)
|
273
|
+
test_doc = @test_doc
|
274
|
+
test_doc_id = @test_doc_id
|
275
|
+
md_params = {}
|
276
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
277
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
278
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
279
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
280
|
+
#test
|
281
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
282
|
+
#check results
|
283
|
+
|
284
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
285
|
+
bia['_id'].should == test_attachment_id
|
286
|
+
#test_doc.attachment_doc_id.should == test_attachment_id
|
287
|
+
#p bia.class
|
288
|
+
#Note the lack of escaping on the file name, this only works
|
289
|
+
#because the original file name did not need escaping
|
290
|
+
bia['md_attachments'][test_file_basename]['file_modified'].should == test_file_modified_time.to_s
|
291
|
+
bia['_attachments'][test_file_basename]['content_type'].should == md_params['content_type']
|
292
|
+
end
|
293
|
+
|
294
|
+
|
295
|
+
it "should handle file names with strange (but somewhat common) characters and convert to more standard form" do
|
296
|
+
test_file = @test_files['strange_characters_in_file_name']
|
297
|
+
test_file_basename = File.basename(test_file)
|
298
|
+
test_file_modified_time = File.mtime(test_file)
|
299
|
+
test_doc = @test_doc
|
300
|
+
test_doc_id = @test_doc_id
|
301
|
+
#test_doc_id = 'dummy_doc_strange_character_file_name'
|
302
|
+
md_params = {}
|
303
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
304
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
305
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
306
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
307
|
+
#test
|
308
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
309
|
+
#check results
|
310
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
311
|
+
bia['_id'].should == test_attachment_id
|
312
|
+
bia['md_attachments'][TkEscape.escape(test_file_basename)]['file_modified'].should == test_file_modified_time.to_s
|
313
|
+
bia['_attachments'][TkEscape.escape(test_file_basename)]['content_type'].should == md_params['content_type']
|
314
|
+
end
|
315
|
+
|
316
|
+
it "should create multiple attachments in one update" do
|
317
|
+
#set initial conditions
|
318
|
+
test_file1 = @test_files['binary_data2_docx']
|
319
|
+
test_file2 = @test_files['simple_text_file']
|
320
|
+
test_file1_basename = File.basename(test_file1)
|
321
|
+
test_file2_basename = File.basename(test_file2)
|
322
|
+
md_params1 = {}
|
323
|
+
md_params2 = {}
|
324
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
325
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
326
|
+
md_params1['file_modified'] = File.mtime(test_file1).to_s
|
327
|
+
md_params2['file_modified'] = File.mtime(test_file2).to_s
|
328
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
329
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
330
|
+
attachs = { test_file1_basename => {'data' => data1, 'md' => md_params1},
|
331
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
332
|
+
}
|
333
|
+
test_doc = @test_doc
|
334
|
+
test_doc_id = @test_doc_id
|
335
|
+
#test_doc_id = 'dummy_create_multiple_attachments'
|
336
|
+
#test
|
337
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, ::CouchrestAttachment, attachs )
|
338
|
+
#verify results
|
339
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
340
|
+
bia['_id'].should == test_attachment_id
|
341
|
+
bia['md_attachments'][TkEscape.escape(test_file1_basename)]['file_modified'].should == File.mtime(test_file1).to_s
|
342
|
+
bia['_attachments'][TkEscape.escape(test_file1_basename)]['content_type'].should == md_params1['content_type']
|
343
|
+
bia['md_attachments'][TkEscape.escape(test_file2_basename)]['file_modified'].should == File.mtime(test_file2).to_s
|
344
|
+
bia['_attachments'][TkEscape.escape(test_file2_basename)]['content_type'].should == md_params2['content_type']
|
345
|
+
end
|
346
|
+
|
347
|
+
it "should add new files to an existing attachment doc" do
|
348
|
+
#set initial conditions existing attachment
|
349
|
+
test_file1 = @test_files['binary_data2_docx']
|
350
|
+
test_file2 = @test_files['simple_text_file']
|
351
|
+
test_file1_basename = File.basename(test_file1)
|
352
|
+
test_file2_basename = File.basename(test_file2)
|
353
|
+
md_params1 = {}
|
354
|
+
md_params2 = {}
|
355
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
356
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
357
|
+
md_params1['file_modified'] = File.mtime(test_file1).to_s
|
358
|
+
md_params2['file_modified'] = File.mtime(test_file2).to_s
|
359
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
360
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
361
|
+
attachs = { test_file1_basename => {'data' => data1, 'md' => md_params1},
|
362
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
363
|
+
}
|
364
|
+
#test_doc_id = 'dummy_add_new_attachments'
|
365
|
+
test_doc = @test_doc
|
366
|
+
test_doc_id = @test_doc_id
|
367
|
+
bia_existing = CouchrestAttachment.add_attachment_package(test_doc_id, ::CouchrestAttachment, attachs )
|
368
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
369
|
+
#verify attachment exists
|
370
|
+
bia_existing['_id'].should == test_attachment_id
|
371
|
+
#set initial conditions for test file
|
372
|
+
test_file = @test_files['simple_text_file2']
|
373
|
+
test_file_modified_time = File.mtime(test_file)
|
374
|
+
test_file_basename = File.basename(test_file)
|
375
|
+
md_params = {}
|
376
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
377
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
378
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
379
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
380
|
+
bia_existing = CouchrestAttachment.get(bia_existing['_id'])
|
381
|
+
#test
|
382
|
+
bia_updated = bia_existing.class.update_attachment_package(bia_existing, attachs )
|
383
|
+
#verify results
|
384
|
+
#p test_file_basename
|
385
|
+
#p TkEscape.escape(test_file_basename)
|
386
|
+
bia_updated['_id'].should == bia_existing['_id']
|
387
|
+
bia_updated['md_attachments'][TkEscape.escape(test_file_basename)]['file_modified'].should == test_file_modified_time.to_s
|
388
|
+
bia_updated['_attachments'][TkEscape.escape(test_file_basename)]['content_type'].should == md_params['content_type']
|
389
|
+
end
|
390
|
+
|
391
|
+
it "should replace older attachment data with new ones, but not vice versa" do
|
392
|
+
#set initial conditions
|
393
|
+
test_file = @test_files['simple_text_file']
|
394
|
+
test_file_basename = File.basename(test_file)
|
395
|
+
test_file_modified_time = File.mtime(test_file)
|
396
|
+
test_doc = @test_doc
|
397
|
+
test_doc_id = @test_doc_id
|
398
|
+
#test_doc_id = 'dummy_fresh_attachment_replaces_stale'
|
399
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
400
|
+
#create a single record
|
401
|
+
md_params = {}
|
402
|
+
md_params['content_type'] = MimeNew.for_ofc_x(test_file)
|
403
|
+
md_params['file_modified'] = test_file_modified_time.to_s
|
404
|
+
data = File.open(test_file, 'rb') {|f| f.read}
|
405
|
+
attachs = {test_file_basename => {'data' => data, 'md' => md_params }}
|
406
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
407
|
+
#verify initial condition
|
408
|
+
bia['_id'].should == test_attachment_id
|
409
|
+
bia['md_attachments'][TkEscape.escape(test_file_basename)]['file_modified'].should == test_file_modified_time.to_s
|
410
|
+
bia['_attachments'][TkEscape.escape(test_file_basename)]['content_type'].should == md_params['content_type']
|
411
|
+
|
412
|
+
#set initial conditions for fresh and stale file
|
413
|
+
stale_file = @test_files['stale_file']
|
414
|
+
fresh_file = @test_files['fresh_file']
|
415
|
+
stale_basename = File.basename(stale_file)
|
416
|
+
fresh_basename = File.basename(fresh_file)
|
417
|
+
stale_modified_time = File.mtime(stale_file)
|
418
|
+
fresh_modified_time = File.mtime(fresh_file)
|
419
|
+
md_params_stale = {}
|
420
|
+
md_params_fresh = {}
|
421
|
+
md_params_stale['content_type'] = MimeNew.for_ofc_x(stale_file)
|
422
|
+
md_params_fresh['content_type'] = MimeNew.for_ofc_x(fresh_file)
|
423
|
+
md_params_stale['file_modified'] = stale_modified_time.to_s
|
424
|
+
md_params_fresh['file_modified'] = fresh_modified_time.to_s
|
425
|
+
stale_data = File.open(stale_file, 'rb') {|f| f.read}
|
426
|
+
fresh_data = File.open(fresh_file, 'rb') {|f| f.read}
|
427
|
+
attachs = {stale_basename => {'data' => stale_data, 'md' => md_params_stale},
|
428
|
+
fresh_basename => {'data' => fresh_data, 'md' => md_params_fresh}
|
429
|
+
}
|
430
|
+
|
431
|
+
#for creating, use the sid and the method create_.... for updateing, use the sia and the method update...
|
432
|
+
bia_updated = CouchrestAttachment.update_attachment_package(bia, attachs )
|
433
|
+
#verify initial conditions
|
434
|
+
bia_updated['_id'].should == test_attachment_id
|
435
|
+
bia_updated['md_attachments'][TkEscape.escape(stale_basename)]['file_modified'].should == stale_modified_time.to_s
|
436
|
+
bia_updated['_attachments'][TkEscape.escape(stale_basename)]['content_type'].should == md_params_stale['content_type']
|
437
|
+
bia_updated['md_attachments'][TkEscape.escape(fresh_basename)]['file_modified'].should == fresh_modified_time.to_s
|
438
|
+
bia_updated['_attachments'][TkEscape.escape(fresh_basename)]['content_type'].should == md_params_fresh['content_type']
|
439
|
+
#if the above tests pass, then the files and database are synchronized
|
440
|
+
|
441
|
+
sleep 1 #to put some time difference
|
442
|
+
|
443
|
+
unstale_data = stale_data + "\n This data is only for the database"
|
444
|
+
unstale_modified_time = Time.now.to_s
|
445
|
+
#puts "Unstale Mod Time (db is more recent): #{unstale_modified_time}"
|
446
|
+
unstale_content_type = 'text/plain;unstale'
|
447
|
+
unstale_params = {'file_modified' => unstale_modified_time, 'content_type' => unstale_content_type}
|
448
|
+
unstale_attach = { TkEscape.escape(stale_basename) => {'data' => unstale_data, 'md'=> unstale_params } }
|
449
|
+
|
450
|
+
CouchrestAttachment.update_attachment_package(bia, unstale_attach)
|
451
|
+
#database should now have more recent information for @stale_basename
|
452
|
+
|
453
|
+
sleep 1 #to put some time difference
|
454
|
+
#puts "Fresh File Mod Time (file is more recent): #{File.mtime(@fresh_file)}"
|
455
|
+
|
456
|
+
File.open(fresh_file, 'a'){|f| f.write("\n This data is only for the file")}
|
457
|
+
#puts "Fresh File Mod Time (file is more recent): #{File.mtime(@fresh_file)}"
|
458
|
+
#file should now have more recent information for @fresh_basename
|
459
|
+
|
460
|
+
#try and update again with both files
|
461
|
+
md_params_stale2 = {}
|
462
|
+
md_params_fresh2 = {}
|
463
|
+
md_params_stale2['content_type'] = MimeNew.for_ofc_x(stale_file)
|
464
|
+
fresh_content_type = 'text/plain;fresh'
|
465
|
+
md_params_fresh2['content_type'] = fresh_content_type #MimeNew.for_ofc_x(@fresh_file)
|
466
|
+
md_params_stale2['file_modified'] = File.mtime(stale_file).to_s
|
467
|
+
fresh_modified_time = File.mtime(fresh_file).to_s
|
468
|
+
md_params_fresh2['file_modified'] = fresh_modified_time
|
469
|
+
stale_data2 = File.open(stale_file, 'rb') {|f| f.read}
|
470
|
+
fresh_data2 = File.open(fresh_file, 'rb') {|f| f.read}
|
471
|
+
attachs = {TkEscape.escape(stale_basename) => {'data' => stale_data2, 'md' => md_params_stale2},
|
472
|
+
TkEscape.escape(fresh_basename) => {'data' => fresh_data2, 'md' => md_params_fresh2}
|
473
|
+
}
|
474
|
+
#test
|
475
|
+
new_bia = CouchrestAttachment.get(bia['_id'])
|
476
|
+
fresh_bia = CouchrestAttachment.update_attachment_package(new_bia, attachs )
|
477
|
+
|
478
|
+
#verify results
|
479
|
+
#db should have fresh file, but not stale one (and maintain older db attachment)
|
480
|
+
fresh_bia['_id'].should == test_attachment_id
|
481
|
+
fresh_bia['md_attachments'][TkEscape.escape(stale_basename)]['file_modified'].should == unstale_modified_time
|
482
|
+
fresh_bia['_attachments'][TkEscape.escape(stale_basename)]['content_type'].should == unstale_content_type
|
483
|
+
fresh_bia['md_attachments'][TkEscape.escape(fresh_basename)]['file_modified'].should == fresh_modified_time
|
484
|
+
fresh_bia['_attachments'][TkEscape.escape(fresh_basename)]['content_type'].should == fresh_content_type
|
485
|
+
end
|
486
|
+
|
487
|
+
it "should combine all attachment metadata when it is retrieved" do
|
488
|
+
#set initial conditions
|
489
|
+
test_file1 = @test_files['binary_data2_docx']
|
490
|
+
test_file2 = @test_files['simple_text_file']
|
491
|
+
test_file1_basename = File.basename(test_file1)
|
492
|
+
test_file2_basename = File.basename(test_file2)
|
493
|
+
test_file1_modified_time = File.mtime(test_file1)
|
494
|
+
test_file2_modified_time = File.mtime(test_file2)
|
495
|
+
md_params1 = {}
|
496
|
+
md_params2 = {}
|
497
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
498
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
499
|
+
md_params1['file_modified'] = test_file1_modified_time.to_s
|
500
|
+
md_params2['file_modified'] = test_file2_modified_time.to_s
|
501
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
502
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
503
|
+
attachs = {test_file1_basename => {'data' => data1, 'md' => md_params1},
|
504
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
505
|
+
}
|
506
|
+
test_doc = @test_doc
|
507
|
+
test_doc_id = test_doc._model_metadata[:_id]
|
508
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
509
|
+
test_attachment = CouchrestAttachment.get(test_attachment_id)
|
510
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
511
|
+
data = CouchrestAttachment.get_attachments(bia)
|
512
|
+
#puts "SIA data: #{data.inspect}"
|
513
|
+
data[TkEscape.escape(test_file1_basename)]['file_modified'].should == test_file1_modified_time.to_s
|
514
|
+
data[TkEscape.escape(test_file1_basename)]['content_type'].should == MimeNew.for_ofc_x(test_file1)
|
515
|
+
end
|
516
|
+
|
517
|
+
it "should delete attachments" do
|
518
|
+
#set initial conditions
|
519
|
+
test_file1 = @test_files['binary_data2_docx']
|
520
|
+
test_file2 = @test_files['simple_text_file']
|
521
|
+
test_file1_basename = File.basename(test_file1)
|
522
|
+
test_file2_basename = File.basename(test_file2)
|
523
|
+
test_file1_modified_time = File.mtime(test_file1)
|
524
|
+
test_file2_modified_time = File.mtime(test_file2)
|
525
|
+
md_params1 = {}
|
526
|
+
md_params2 = {}
|
527
|
+
md_params1['content_type'] = MimeNew.for_ofc_x(test_file1)
|
528
|
+
md_params2['content_type'] = MimeNew.for_ofc_x(test_file2)
|
529
|
+
md_params1['file_modified'] = test_file1_modified_time.to_s
|
530
|
+
md_params2['file_modified'] = test_file2_modified_time.to_s
|
531
|
+
data1 = File.open(test_file1, 'rb') {|f| f.read}
|
532
|
+
data2 = File.open(test_file2, 'rb') {|f| f.read}
|
533
|
+
attachs = {test_file1_basename => {'data' => data1, 'md' => md_params1},
|
534
|
+
test_file2_basename => {'data' => data2, 'md' => md_params2}
|
535
|
+
}
|
536
|
+
test_doc = @test_doc
|
537
|
+
test_doc_id = test_doc._model_metadata[:_id]
|
538
|
+
test_attachment_id = test_doc_id + CouchrestAttachment::AttachmentID
|
539
|
+
test_attachment = CouchrestAttachment.get(test_attachment_id)
|
540
|
+
bia = CouchrestAttachment.add_attachment_package(test_doc_id, CouchrestAttachment, attachs )
|
541
|
+
#test
|
542
|
+
bia.remove_attachment(test_file1_basename)
|
543
|
+
#verify
|
544
|
+
new_atts = bia.get_attachments
|
545
|
+
#puts "Should be only 1: #{new_atts.keys.inspect}"
|
546
|
+
new_atts.keys.size.should == 1
|
547
|
+
new_atts.keys.first.should == TkEscape.escape(test_file2_basename)
|
548
|
+
|
549
|
+
end
|
550
|
+
end
|
551
|
+
=end
|