sufia 0.1.0 → 1.0.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.
Files changed (129) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +4 -0
  3. data/.travis.yml +6 -0
  4. data/Gemfile +5 -2
  5. data/History.md +6 -0
  6. data/README.md +40 -0
  7. data/Rakefile +4 -0
  8. data/app/assets/javascripts/sufia.js +3 -115
  9. data/app/assets/javascripts/sufia/batch_select_all.js +179 -0
  10. data/app/assets/javascripts/sufia/edit_metadata.js +86 -0
  11. data/app/assets/javascripts/sufia/multiForm.js +57 -0
  12. data/app/assets/javascripts/terms_of_service.js +7 -0
  13. data/app/assets/stylesheets/audio-js.css +3 -0
  14. data/app/assets/stylesheets/dashboard.css.scss +51 -0
  15. data/app/assets/stylesheets/generic_files.css +36 -0
  16. data/app/assets/stylesheets/sufia.css.scss +2 -0
  17. data/app/controllers/batch_controller.rb +11 -0
  18. data/app/controllers/batch_edits_controller.rb +1 -77
  19. data/app/controllers/generic_files_controller.rb +1 -0
  20. data/app/controllers/mailbox_controller.rb +1 -1
  21. data/app/controllers/single_use_link_controller.rb +11 -7
  22. data/app/helpers/generic_file_helper.rb +11 -3
  23. data/app/helpers/sufia_helper.rb +13 -10
  24. data/app/models/batch.rb +1 -1
  25. data/app/models/datastreams/fits_datastream.rb +2 -2
  26. data/app/models/datastreams/generic_file_rdf_datastream.rb +22 -18
  27. data/app/models/datastreams/properties_datastream.rb +2 -2
  28. data/app/views/_user_util_links.html.erb +2 -2
  29. data/app/views/batch/_metadata.html.erb +82 -0
  30. data/app/views/batch/_more_metadata.html.erb +6 -0
  31. data/app/views/batch/edit.html.erb +1 -8
  32. data/app/views/batch_edits/_check_all.html.erb +0 -157
  33. data/app/views/batch_edits/edit.html.erb +0 -29
  34. data/app/views/catalog/_index_partials/_list_files.html.erb +8 -10
  35. data/app/views/catalog/_recent_document.html.erb +9 -18
  36. data/app/views/catalog/_results_pagination.html.erb +1 -1
  37. data/app/views/contact_form/new.html.erb +1 -1
  38. data/app/views/dashboard/_index_partials/_default_group.html.erb +1 -1
  39. data/app/views/dashboard/_index_partials/_list_files.html.erb +12 -14
  40. data/app/views/dashboard/_index_partials/_thumbnail_display.html.erb +9 -19
  41. data/app/views/dashboard/_results_pagination.html.erb +1 -1
  42. data/app/views/dashboard/index.html.erb +6 -82
  43. data/app/views/error/single_use_error.html.erb +35 -0
  44. data/app/views/generic_files/_descriptions.html.erb +2 -2
  45. data/app/views/generic_files/_extra_fields_modal.html.erb +1 -1
  46. data/app/views/generic_files/_field_form.html.erb +2 -5
  47. data/app/views/generic_files/_media_display.html.erb +8 -6
  48. data/app/views/generic_files/_permission.html.erb +2 -2
  49. data/app/views/generic_files/_rights_modal.html.erb +1 -1
  50. data/app/views/generic_files/_show_actions.html.erb +1 -1
  51. data/app/views/generic_files/_show_details.html.erb +11 -6
  52. data/app/views/generic_files/edit.html.erb +0 -8
  53. data/app/views/generic_files/edit_fields/_type.html.erb +1 -1
  54. data/app/views/generic_files/show.html.erb +5 -8
  55. data/app/views/generic_files/show_fields/_based_near.html.erb +4 -1
  56. data/app/views/generic_files/show_fields/_contributor.html.erb +4 -1
  57. data/app/views/generic_files/show_fields/_creator.html.erb +4 -1
  58. data/app/views/generic_files/show_fields/_date_created.html.erb +4 -1
  59. data/app/views/generic_files/show_fields/_description.html.erb +4 -1
  60. data/app/views/generic_files/show_fields/_language.html.erb +1 -1
  61. data/app/views/generic_files/show_fields/_publisher.html.erb +4 -1
  62. data/app/views/generic_files/show_fields/_related_url.html.erb +3 -1
  63. data/app/views/generic_files/show_fields/_resource_type.html.erb +1 -1
  64. data/app/views/generic_files/show_fields/_subject.html.erb +4 -1
  65. data/app/views/generic_files/show_fields/_tag.html.erb +1 -1
  66. data/app/views/generic_files/show_fields/_title.html.erb +4 -1
  67. data/app/views/layouts/error.html.erb +0 -4
  68. data/app/views/layouts/hydra-head.html.erb +2 -6
  69. data/app/views/single_use_link/show.html.erb +1 -1
  70. data/app/views/users/index.html.erb +1 -1
  71. data/app/views/users/show.html.erb +1 -1
  72. data/config/locales/sufia.en.yml +1 -0
  73. data/config/routes.rb +11 -4
  74. data/lib/generators/sufia/sufia_generator.rb +2 -1
  75. data/lib/generators/sufia/templates/catalog_controller.rb +143 -117
  76. data/lib/generators/sufia/templates/config/resque_admin.rb +10 -0
  77. data/lib/generators/sufia/templates/config/sufia.rb +8 -0
  78. data/lib/sufia.rb +4 -14
  79. data/lib/sufia/batch_edits_controller_behavior.rb +89 -0
  80. data/lib/sufia/controller.rb +7 -5
  81. data/lib/sufia/downloads_controller_behavior.rb +14 -19
  82. data/lib/sufia/file_content/extract_metadata.rb +11 -4
  83. data/lib/sufia/files_controller_behavior.rb +63 -44
  84. data/lib/sufia/generic_file.rb +29 -11
  85. data/lib/sufia/generic_file/audit.rb +1 -1
  86. data/lib/sufia/generic_file/thumbnail.rb +51 -26
  87. data/lib/sufia/id_service.rb +28 -11
  88. data/lib/sufia/jobs/batch_update_job.rb +2 -2
  89. data/lib/sufia/jobs/characterize_job.rb +11 -3
  90. data/lib/sufia/jobs/ffmpeg_transcode_job.rb +61 -0
  91. data/lib/sufia/jobs/resolrize_job.rb +1 -1
  92. data/lib/sufia/jobs/transcode_audio_job.rb +40 -0
  93. data/lib/sufia/jobs/transcode_video_job.rb +9 -49
  94. data/lib/sufia/queue/resque.rb +2 -2
  95. data/lib/sufia/single_use_error.rb +4 -0
  96. data/lib/sufia/solr_document_behavior.rb +108 -1
  97. data/lib/sufia/version.rb +1 -1
  98. data/solr_conf/conf/schema.xml +332 -652
  99. data/solr_conf/conf/solrconfig.xml +60 -196
  100. data/spec/controllers/batch_controller_spec.rb +4 -5
  101. data/spec/controllers/catalog_controller_spec.rb +13 -13
  102. data/spec/controllers/dashboard_controller_spec.rb +2 -2
  103. data/spec/controllers/downloads_controller_spec.rb +74 -62
  104. data/spec/controllers/generic_files_controller_spec.rb +10 -8
  105. data/spec/controllers/single_use_link_controller_spec.rb +12 -4
  106. data/spec/fixtures/Example.ogg +0 -0
  107. data/spec/fixtures/piano_note.wav +0 -0
  108. data/spec/fixtures/sufia_generic_stub.descMeta.txt +1 -1
  109. data/spec/helpers/sufia_helper_spec.rb +12 -0
  110. data/spec/models/characterize_job_spec.rb +89 -0
  111. data/spec/models/checksum_audit_log_spec.rb +1 -0
  112. data/spec/models/event_jobs_spec.rb +9 -9
  113. data/spec/models/file_content_datastream_spec.rb +16 -10
  114. data/spec/models/fits_datastream_spec.rb +2 -8
  115. data/spec/models/generic_file_spec.rb +131 -60
  116. data/spec/models/solr_document_spec.rb +21 -0
  117. data/spec/models/transcode_audio_job_spec.rb +81 -0
  118. data/spec/models/transcode_video_job_spec.rb +2 -2
  119. data/spec/models/unzip_job_spec.rb +3 -3
  120. data/spec/spec_helper.rb +21 -0
  121. data/spec/support/Gemfile +7 -3
  122. data/sufia.gemspec +8 -11
  123. data/tasks/cucumber.rake +1 -2
  124. data/tasks/sufia-dev.rake +13 -2
  125. data/tasks/sufia.rake +1 -1
  126. metadata +77 -118
  127. data/app/views/batch_edits/_metadata.html.erb +0 -180
  128. data/lib/generators/sufia/templates/config/hydra_config.rb +0 -32
  129. data/lib/kaminari/helpers/tag.rb +0 -11
@@ -74,6 +74,8 @@ describe GenericFilesController do
74
74
  end
75
75
 
76
76
  it "should create and save a file asset from the given params" do
77
+ date_today = Date.today
78
+ Date.stub(:today).and_return(date_today)
77
79
  file = fixture_file_upload('/world.png','image/png')
78
80
  xhr :post, :create, :files=>[file], :Filename=>"The world", :batch_id => "sample:batch_id", :permission=>{"group"=>{"public"=>"read"} }, :terms_of_service => '1'
79
81
  response.should be_success
@@ -87,8 +89,8 @@ describe GenericFilesController do
87
89
  saved_file.content.dsChecksumValid.should be_true
88
90
 
89
91
  # Confirming that date_uploaded and date_modified were set
90
- saved_file.date_uploaded.should have_at_least(1).items
91
- saved_file.date_modified.should have_at_least(1).items
92
+ saved_file.date_uploaded.should == date_today
93
+ saved_file.date_modified.should == date_today
92
94
  end
93
95
 
94
96
  it "should record what user created the first version of content" do
@@ -124,12 +126,12 @@ describe GenericFilesController do
124
126
  #TODO make sure this is moved to scholarsphere:
125
127
  #saved_file.depositor.should == 'jilluser'
126
128
  saved_file.depositor.should == 'jilluser@example.com'
127
- saved_file.properties.to_solr.keys.should include('depositor_t')
129
+ saved_file.properties.to_solr.keys.should include('depositor_tesim')
128
130
  #TODO make sure this is moved to scholarsphere:
129
131
  #saved_file.properties.to_solr['depositor_t'].should == ['jilluser']
130
- saved_file.properties.to_solr['depositor_t'].should == ['jilluser@example.com']
131
- saved_file.to_solr.keys.should include('depositor_t')
132
- saved_file.to_solr['depositor_t'].should == ['jilluser@example.com']
132
+ saved_file.properties.to_solr['depositor_tesim'].should == ['jilluser@example.com']
133
+ saved_file.to_solr.keys.should include('depositor_tesim')
134
+ saved_file.to_solr['depositor_tesim'].should == ['jilluser@example.com']
133
135
  end
134
136
  it "Should call virus check" do
135
137
  controller.should_receive(:virus_check).and_return(0)
@@ -284,7 +286,7 @@ describe GenericFilesController do
284
286
  CharacterizeJob.should_receive(:new).with(@generic_file.pid).and_return(s2)
285
287
  Sufia.queue.should_receive(:push).with(s2).once
286
288
  file = fixture_file_upload('/image.jp2','image/jp2')
287
- post :update, :id=>@generic_file.pid, :filedata=>file, :Filename=>"The world", :generic_file=>{:tag=>[''] }
289
+ post :update, :id=>@generic_file.pid, :filedata=>file, :Filename=>"The world"
288
290
 
289
291
  edited_file = GenericFile.find(@generic_file.pid)
290
292
  version2 = edited_file.content.latest_version
@@ -302,7 +304,7 @@ describe GenericFilesController do
302
304
  s2 = stub('one')
303
305
  CharacterizeJob.should_receive(:new).with(@generic_file.pid).and_return(s2)
304
306
  Sufia.queue.should_receive(:push).with(s2).once
305
- post :update, :id=>@generic_file.pid, :revision=>'content.0', :generic_file=>{:tag=>['']}
307
+ post :update, :id=>@generic_file.pid, :revision=>'content.0'
306
308
 
307
309
  restored_file = GenericFile.find(@generic_file.pid)
308
310
  version3 = restored_file.content.latest_version
@@ -92,10 +92,14 @@ describe SingleUseLinkController do
92
92
  it "and_return 404 on second attempt" do
93
93
  get :download, id:@dhash
94
94
  response.should be_success
95
- lambda {get :download, id:@dhash}.should raise_error ActionController::RoutingError
95
+ get :download, id:@dhash
96
+ response.should render_template('error/single_use_error')
96
97
  end
97
98
  it "and_return 404 on attempt to get download with show" do
98
- lambda {get :download, id:@shash}.should raise_error ActionController::RoutingError
99
+ get :download, id:@dhash
100
+ response.should be_success
101
+ get :download, id:@dhash
102
+ response.should render_template('error/single_use_error')
99
103
  end
100
104
  end
101
105
 
@@ -108,10 +112,14 @@ describe SingleUseLinkController do
108
112
  it "and_return 404 on second attempt" do
109
113
  get :show, id:@shash
110
114
  response.should be_success
111
- lambda {get :show, id:@shash}.should raise_error ActionController::RoutingError
115
+ get :show, id:@shash
116
+ response.should render_template('error/single_use_error')
112
117
  end
113
118
  it "and_return 404 on attempt to get show with download" do
114
- lambda {get :show, id:@dhash}.should raise_error ActionController::RoutingError
119
+ get :show, id:@shash
120
+ response.should be_success
121
+ get :show, id:@shash
122
+ response.should render_template('error/single_use_error')
115
123
  end
116
124
  end
117
125
  end
Binary file
@@ -1,6 +1,6 @@
1
1
  <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/publisher> "<%= @user %>" .
2
2
  <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/description> "<%= @title %> Description" .
3
- <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/created> "<%= Time.now.strftime("%m/%d/%Y") %>" .
3
+ <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/created> "<%= Time.now.ctime %>" .
4
4
  <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/contributor> "<%= @user %>" .
5
5
  <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/title> "<%= @title %>" .
6
6
  <info:fedora/sufia:<%= @id %>> <http://purl.org/dc/terms/relation> "test" .
@@ -0,0 +1,12 @@
1
+ require 'spec_helper'
2
+
3
+ describe SufiaHelper do
4
+ describe "link_to_profile" do
5
+ it "should use User#to_params" do
6
+ u = User.new
7
+ u.stub(:user_key).and_return('justin@example.com')
8
+ User.should_receive(:find_by_user_key).with('justin@example.com').and_return(u)
9
+ helper.link_to_profile('justin@example.com').should == "<a href=\"/users/justin@example-dot-com\">justin@example.com</a>"
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,89 @@
1
+ require 'spec_helper'
2
+
3
+ describe CharacterizeJob do
4
+ before do
5
+ @generic_file = GenericFile.new
6
+ @generic_file.apply_depositor_metadata('jcoyne@example.com')
7
+ @generic_file.save!
8
+ end
9
+
10
+ after do
11
+ @generic_file.delete
12
+ end
13
+
14
+ subject { CharacterizeJob.new(@generic_file.id)}
15
+
16
+ describe "with a AVI (video) file" do
17
+ before do
18
+ @generic_file.add_file_datastream(File.new(fixture_path + '/countdown.avi'), :dsid=>'content', :mime_type=>'video/avi')
19
+ @generic_file.stub(:characterize_if_changed).and_yield
20
+ @generic_file.save!
21
+ end
22
+ it "should create a transcode job" do
23
+ job = stub("stub video job")
24
+ if $in_travis
25
+ @generic_file.stub(:video?).and_return(true)
26
+ GenericFile.should_receive(:find).with(@generic_file.id).and_return(@generic_file)
27
+ end
28
+ TranscodeVideoJob.should_receive(:new).with(@generic_file.id, 'content').and_return(job)
29
+ Sufia.queue.should_receive(:push).with(job)
30
+ subject.run
31
+ end
32
+ it "should create a thumbnail" do
33
+ GenericFile.any_instance.should_receive(:create_thumbnail)
34
+ subject.run
35
+ end
36
+ end
37
+
38
+ describe "with a WAV (audio) file" do
39
+ before do
40
+ @generic_file.add_file_datastream(File.new(fixture_path + '/piano_note.wav'), :dsid=>'content', :mime_type=>'audio/wav')
41
+ @generic_file.stub(:characterize_if_changed).and_yield
42
+ @generic_file.save!
43
+ end
44
+ it "should create a transcode job" do
45
+ job = stub("stub audio job")
46
+ if $in_travis
47
+ @generic_file.stub(:audio?).and_return(true)
48
+ GenericFile.should_receive(:find).with(@generic_file.id).and_return(@generic_file)
49
+ end
50
+ TranscodeAudioJob.should_receive(:new).with(@generic_file.id, 'content').and_return(job)
51
+ Sufia.queue.should_receive(:push).with(job)
52
+ subject.run
53
+ end
54
+ end
55
+
56
+ describe "with an mp3 (audio) file" do
57
+ before do
58
+ @generic_file.add_file_datastream(File.new(fixture_path + '/sufia/sufia_test5.mp3'), :dsid=>'content', :mime_type=>'audio/mp3')
59
+ @generic_file.stub(:characterize_if_changed).and_yield
60
+ @generic_file.save!
61
+ end
62
+ it "should create a transcode job. (we'd like ogg too)" do
63
+ # TODO just copy the 'content' datastream to the mp3 datastream if it's an mp3, and then transcode to ogg
64
+ job = stub("stub audio job")
65
+ if $in_travis
66
+ @generic_file.stub(:audio?).and_return(true)
67
+ GenericFile.should_receive(:find).with(@generic_file.id).and_return(@generic_file)
68
+ end
69
+ TranscodeAudioJob.should_receive(:new).with(@generic_file.id, 'content').and_return(job)
70
+ Sufia.queue.should_receive(:push).with(job)
71
+ subject.run
72
+ end
73
+ end
74
+
75
+ describe "with an jpeg2000 (image) file" do
76
+ before do
77
+ @generic_file.add_file_datastream(File.new(fixture_path + '/image.jp2'), :dsid=>'content', :mime_type=>'image/jp2')
78
+ @generic_file.stub(:characterize_if_changed).and_yield
79
+ @generic_file.save!
80
+ end
81
+
82
+ it "should create a thumbnail" do
83
+ GenericFile.any_instance.should_receive(:create_thumbnail)
84
+ subject.run
85
+ end
86
+ end
87
+ end
88
+
89
+
@@ -19,6 +19,7 @@ describe ChecksumAuditLog do
19
19
  @f = GenericFile.new
20
20
  @f.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
21
21
  @f.apply_depositor_metadata('mjg36')
22
+ @f.stub(:characterize_if_changed).and_yield #don't run characterization
22
23
  @f.save!
23
24
  @version = @f.datastreams['content'].versions.first
24
25
  @old = ChecksumAuditLog.create(:pid=>@f.pid, :dsid=>@version.dsid, :version=>@version.versionID, :pass=>1, :created_at=>2.minutes.ago)
@@ -40,7 +40,7 @@ describe 'event jobs' do
40
40
  count_user = @user.events.length
41
41
  count_another = @another_user.events.length
42
42
  Time.should_receive(:now).at_least(:once).and_return(1)
43
- event = { action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has edited his or her profile', timestamp: '1' }
43
+ event = { action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has edited his or her profile', timestamp: '1' }
44
44
  UserEditProfileEventJob.new(@user.user_key).run
45
45
  @user.events.length.should == count_user + 1
46
46
  @user.events.first.should == event
@@ -54,7 +54,7 @@ describe 'event jobs' do
54
54
  @another_user.events.length.should == 0
55
55
  @third_user.events.length.should == 0
56
56
  Time.should_receive(:now).at_least(:once).and_return(1)
57
- event = { action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> is now following <a href="/users/archivist1@example.com">archivist1@example.com</a>', timestamp: '1' }
57
+ event = { action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> is now following <a href="/users/archivist1@example-dot-com">archivist1@example.com</a>', timestamp: '1' }
58
58
  UserFollowEventJob.new(@user.user_key, @another_user.user_key).run
59
59
  @user.events.length.should == 1
60
60
  @user.events.first.should == event
@@ -71,7 +71,7 @@ describe 'event jobs' do
71
71
  @another_user.events.length.should == 0
72
72
  @third_user.events.length.should == 0
73
73
  Time.should_receive(:now).at_least(:once).and_return(1)
74
- event = { action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has unfollowed <a href="/users/archivist1@example.com">archivist1@example.com</a>', timestamp: '1' }
74
+ event = { action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has unfollowed <a href="/users/archivist1@example-dot-com">archivist1@example.com</a>', timestamp: '1' }
75
75
  UserUnfollowEventJob.new(@user.user_key, @another_user.user_key).run
76
76
  @user.events.length.should == 1
77
77
  @user.events.first.should == event
@@ -90,7 +90,7 @@ describe 'event jobs' do
90
90
  @third_user.events.length.should == 0
91
91
  @gf.events.length.should == 0
92
92
  Time.should_receive(:now).at_least(:once).and_return(1)
93
- event = {action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has deposited <a href="/files/123">Hamlet</a>', timestamp: '1' }
93
+ event = {action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has deposited <a href="/files/123">Hamlet</a>', timestamp: '1' }
94
94
  ContentDepositEventJob.new('test:123', @user.user_key).run
95
95
  @user.profile_events.length.should == 1
96
96
  @user.profile_events.first.should == event
@@ -111,7 +111,7 @@ describe 'event jobs' do
111
111
  @third_user.events.length.should == 0
112
112
  @gf.events.length.should == 0
113
113
  Time.should_receive(:now).at_least(:once).and_return(1)
114
- event = {action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has updated <a href="/files/123">Hamlet</a>', timestamp: '1' }
114
+ event = {action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has updated <a href="/files/123">Hamlet</a>', timestamp: '1' }
115
115
  ContentUpdateEventJob.new('test:123', @user.user_key).run
116
116
  @user.profile_events.length.should == 1
117
117
  @user.profile_events.first.should == event
@@ -132,7 +132,7 @@ describe 'event jobs' do
132
132
  @third_user.events.length.should == 0
133
133
  @gf.events.length.should == 0
134
134
  Time.should_receive(:now).at_least(:once).and_return(1)
135
- event = {action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has added a new version of <a href="/files/123">Hamlet</a>', timestamp: '1' }
135
+ event = {action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has added a new version of <a href="/files/123">Hamlet</a>', timestamp: '1' }
136
136
  ContentNewVersionEventJob.new('test:123', @user.user_key).run
137
137
  @user.profile_events.length.should == 1
138
138
  @user.profile_events.first.should == event
@@ -153,7 +153,7 @@ describe 'event jobs' do
153
153
  @third_user.events.length.should == 0
154
154
  @gf.events.length.should == 0
155
155
  Time.should_receive(:now).at_least(:once).and_return(1)
156
- event = {action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has restored a version \'content.0\' of <a href="/files/123">Hamlet</a>', timestamp: '1' }
156
+ event = {action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has restored a version \'content.0\' of <a href="/files/123">Hamlet</a>', timestamp: '1' }
157
157
  ContentRestoredVersionEventJob.new('test:123', @user.user_key, 'content.0').run
158
158
  @user.profile_events.length.should == 1
159
159
  @user.profile_events.first.should == event
@@ -172,7 +172,7 @@ describe 'event jobs' do
172
172
  @another_user.events.length.should == 0
173
173
  @third_user.events.length.should == 0
174
174
  Time.should_receive(:now).at_least(:once).and_return(1)
175
- event = {action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has deleted file \'test:123\'', timestamp: '1' }
175
+ event = {action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has deleted file \'test:123\'', timestamp: '1' }
176
176
  ContentDeleteEventJob.new('test:123', @user.user_key).run
177
177
  @user.profile_events.length.should == 1
178
178
  @user.profile_events.first.should == event
@@ -191,7 +191,7 @@ describe 'event jobs' do
191
191
  @gf.events.length.should == 0
192
192
  @now = Time.now
193
193
  Time.should_receive(:now).at_least(:once).and_return(@now)
194
- event = {action: 'User <a href="/users/jilluser@example.com">jilluser@example.com</a> has updated <a href="/files/123">Hamlet</a>', timestamp: @now.to_i.to_s }
194
+ event = {action: 'User <a href="/users/jilluser@example-dot-com">jilluser@example.com</a> has updated <a href="/files/123">Hamlet</a>', timestamp: @now.to_i.to_s }
195
195
  ContentUpdateEventJob.new('test:123', @user.user_key).run
196
196
  @user.profile_events.length.should == 1
197
197
  @user.profile_events.first.should == event
@@ -16,19 +16,18 @@ require 'spec_helper'
16
16
 
17
17
  describe FileContentDatastream do
18
18
  before do
19
- @subject = FileContentDatastream.new(nil, 'content')
20
- @subject.stub(:pid=>'my_pid')
21
- @subject.stub(:dsVersionID=>'content.7')
19
+ Sufia.queue.stub(:push).with(an_instance_of CharacterizeJob) #don't run characterization
22
20
  end
23
21
  describe "version control" do
24
- before(:all) do
22
+ before do
25
23
  f = GenericFile.new
26
24
  f.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
27
25
  f.apply_depositor_metadata('mjg36')
26
+ f.stub(:characterize_if_changed).and_yield #don't run characterization
28
27
  f.save
29
- @file = GenericFile.find(f.pid)
28
+ @file = f.reload
30
29
  end
31
- after(:all) do
30
+ after do
32
31
  @file.delete
33
32
  end
34
33
  it "should have a list of versions with one entry" do
@@ -47,8 +46,9 @@ describe FileContentDatastream do
47
46
  @file.content.get_version("foobar").should be_nil
48
47
  end
49
48
  describe "add a version" do
50
- before(:all) do
49
+ before do
51
50
  @file.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
51
+ @file.stub(:characterize_if_changed).and_yield #don't run characterization
52
52
  @file.save
53
53
  end
54
54
  it "should return two versions" do
@@ -63,10 +63,15 @@ describe FileContentDatastream do
63
63
  end
64
64
  end
65
65
  describe "extract_metadata" do
66
+ before do
67
+ @subject = FileContentDatastream.new(nil, 'content')
68
+ @subject.stub(:pid=>'my_pid')
69
+ @subject.stub(:dsVersionID=>'content.7')
70
+ end
66
71
  it "should have the path" do
67
72
  @subject.send(:fits_path).should be_present
68
73
  end
69
- it "should return an xml document" do
74
+ it "should return an xml document", :unless => $in_travis do
70
75
  repo = mock("repo")
71
76
  repo.stub(:config=>{})
72
77
  f = File.new(fixture_path + '/world.png')
@@ -78,7 +83,7 @@ describe FileContentDatastream do
78
83
  doc = Nokogiri::XML.parse(xml)
79
84
  doc.root.xpath('//ns:imageWidth/text()', {'ns'=>'http://hul.harvard.edu/ois/xml/ns/fits/fits_output'}).inner_text.should == '50'
80
85
  end
81
- it "should return expected results when invoked via HTTP" do
86
+ it "should return expected results when invoked via HTTP", :unless => $in_travis do
82
87
  repo = mock("repo")
83
88
  repo.stub(:config=>{})
84
89
  f = ActionDispatch::Http::UploadedFile.new(:tempfile => File.new(fixture_path + '/world.png'),
@@ -96,6 +101,7 @@ describe FileContentDatastream do
96
101
  before do
97
102
  @generic_file = GenericFile.new
98
103
  @generic_file.apply_depositor_metadata('mjg36')
104
+ @generic_file.stub(:characterize_if_changed).and_yield #don't run characterization
99
105
  end
100
106
  after do
101
107
  @generic_file.delete
@@ -111,7 +117,7 @@ describe FileContentDatastream do
111
117
  @generic_file.thumbnail.changed?.should be_true
112
118
  @generic_file.content.changed?.should be_false
113
119
 
114
- retrieved_file = GenericFile.find(@generic_file.pid)
120
+ retrieved_file = @generic_file.reload
115
121
  retrieved_file.content.changed?.should be_false
116
122
  end
117
123
  end
@@ -14,17 +14,11 @@
14
14
 
15
15
  require 'spec_helper'
16
16
 
17
- describe FitsDatastream do
17
+ describe FitsDatastream, :unless => $in_travis do
18
18
  before(:all) do
19
- GenericFile.any_instance.stub(:terms_of_service).and_return('1')
20
19
  @file = GenericFile.new
21
20
  @file.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
22
- @file.apply_depositor_metadata('mjg36')
23
- @file.save
24
- @file = GenericFile.find(@file.pid)
25
- end
26
- after(:all) do
27
- @file.delete
21
+ @file.characterize
28
22
  end
29
23
  it "should have a format label" do
30
24
  @file.format_label.should == ["Portable Network Graphics"]
@@ -16,14 +16,14 @@ require 'spec_helper'
16
16
 
17
17
  describe GenericFile do
18
18
  before do
19
- @file = GenericFile.new
20
- @file.apply_depositor_metadata('jcoyne')
19
+ subject.apply_depositor_metadata('jcoyne')
20
+ @file = subject #TODO remove this line someday (use subject instead)
21
21
  end
22
22
 
23
23
  describe "terms_for_editing" do
24
24
  it "should return a list" do
25
25
  @file.terms_for_editing.should == [ :contributor, :creator, :title, :description, :publisher,
26
- :date_created, :subject, :language, :rights, :identifier, :based_near, :tag, :related_url]
26
+ :date_created, :subject, :language, :rights, :resource_type, :identifier, :based_near, :tag, :related_url]
27
27
  end
28
28
  end
29
29
  describe "terms_for_display" do
@@ -34,6 +34,71 @@ describe GenericFile do
34
34
  end
35
35
  end
36
36
 
37
+ describe "mime type recognition" do
38
+ describe "image?" do
39
+ it "should be true for jpeg2000" do
40
+ subject.mime_type = 'image/jp2'
41
+ subject.should be_image
42
+ end
43
+ it "should be true for jpeg" do
44
+ subject.mime_type = 'image/jpg'
45
+ subject.should be_image
46
+ end
47
+ it "should be true for png" do
48
+ subject.mime_type = 'image/png'
49
+ subject.should be_image
50
+ end
51
+ end
52
+ describe "pdf?" do
53
+ it "should be true for pdf" do
54
+ subject.mime_type = 'application/pdf'
55
+ subject.should be_pdf
56
+ end
57
+ end
58
+ describe "audio?" do
59
+ it "should be true for wav" do
60
+ subject.mime_type = 'audio/x-wave'
61
+ subject.should be_audio
62
+ subject.mime_type = 'audio/x-wav'
63
+ subject.should be_audio
64
+ end
65
+ it "should be true for mpeg" do
66
+ subject.mime_type = 'audio/mpeg'
67
+ subject.should be_audio
68
+ subject.mime_type = 'audio/mp3'
69
+ subject.should be_audio
70
+ end
71
+ it "should be true for ogg" do
72
+ subject.mime_type = 'audio/ogg'
73
+ subject.should be_audio
74
+ end
75
+ end
76
+ describe "video?" do
77
+ it "should be true for avi" do
78
+ subject.mime_type = 'video/avi'
79
+ subject.should be_video
80
+ end
81
+ it "should be true for webm" do
82
+ subject.mime_type = 'video/webm'
83
+ subject.should be_video
84
+ end
85
+ it "should be true for mpeg" do
86
+ subject.mime_type = 'video/mp4'
87
+ subject.should be_video
88
+ subject.mime_type = 'video/mpeg'
89
+ subject.should be_video
90
+ end
91
+ it "should be true for quicktime" do
92
+ subject.mime_type = 'video/quicktime'
93
+ subject.should be_video
94
+ end
95
+ it "should be true for mxf" do
96
+ subject.mime_type = 'application/mxf'
97
+ subject.should be_video
98
+ end
99
+ end
100
+ end
101
+
37
102
  describe "attributes" do
38
103
  it "should have rightsMetadata" do
39
104
  @file.rightsMetadata.should be_instance_of ParanoidRightsDatastream
@@ -158,7 +223,7 @@ describe GenericFile do
158
223
  end
159
224
  it "should have activity stream-related methods defined" do
160
225
  @file.save
161
- f = GenericFile.find(@file.pid)
226
+ f = @file.reload
162
227
  f.should respond_to(:stream)
163
228
  f.should respond_to(:events)
164
229
  f.should respond_to(:create_event)
@@ -169,7 +234,7 @@ describe GenericFile do
169
234
  @file.creator = "John Doe"
170
235
  @file.title = "New work"
171
236
  @file.save
172
- f = GenericFile.find(@file.pid)
237
+ f = @file.reload
173
238
  f.related_url.should == ["http://example.org/"]
174
239
  f.creator.should == ["John Doe"]
175
240
  f.title.should == ["New work"]
@@ -178,13 +243,13 @@ describe GenericFile do
178
243
  @file.creator = "John Doe"
179
244
  @file.title = "New work"
180
245
  @file.save
181
- f = GenericFile.find(@file.pid)
246
+ f = @file.reload
182
247
  f.creator.should == ["John Doe"]
183
248
  f.title.should == ["New work"]
184
249
  f.creator = "Jane Doe"
185
250
  f.title << "Newer work"
186
251
  f.save
187
- f = GenericFile.find(@file.pid)
252
+ f = @file.reload
188
253
  f.creator.should == ["Jane Doe"]
189
254
  f.title.should == ["New work", "Newer work"]
190
255
  end
@@ -198,8 +263,8 @@ describe GenericFile do
198
263
  @file.description = "The work by Allah"
199
264
  @file.publisher = "Vertigo Comics"
200
265
  @file.date_created = "1200-01-01"
201
- @file.date_uploaded = "2011-01-01"
202
- @file.date_modified = "2012-01-01"
266
+ @file.date_uploaded = Date.parse("2011-01-01")
267
+ @file.date_modified = Date.parse("2012-01-01")
203
268
  @file.subject = "Theology"
204
269
  @file.language = "Arabic"
205
270
  @file.rights = "Wide open, buddy."
@@ -211,25 +276,27 @@ describe GenericFile do
211
276
  @file.format_label = "JPEG Image"
212
277
  local = @file.to_solr
213
278
  local.should_not be_nil
214
- local["desc_metadata__part_of_t"].should be_nil
215
- local["desc_metadata__date_uploaded_t"].should be_nil
216
- local["desc_metadata__date_modified_t"].should be_nil
217
- local["desc_metadata__rights_t"].should == ["Wide open, buddy."]
218
- local["desc_metadata__related_url_t"].should be_nil
219
- local["desc_metadata__contributor_t"].should == ["Mohammad"]
220
- local["desc_metadata__creator_t"].should == ["Allah"]
221
- local["desc_metadata__title_t"].should == ["The Work"]
222
- local["desc_metadata__description_t"].should == ["The work by Allah"]
223
- local["desc_metadata__publisher_t"].should == ["Vertigo Comics"]
224
- local["desc_metadata__subject_t"].should == ["Theology"]
225
- local["desc_metadata__language_t"].should == ["Arabic"]
226
- local["desc_metadata__date_created_t"].should == ["1200-01-01"]
227
- local["desc_metadata__resource_type_t"].should == ["Book"]
228
- local["file_format_t"].should == "jpeg (JPEG Image)"
229
- local["desc_metadata__identifier_t"].should == ["urn:isbn:1234567890"]
230
- local["desc_metadata__based_near_t"].should == ["Medina, Saudi Arabia"]
231
- local["mime_type_t"].should == ["image/jpeg"]
232
- local["noid_s"].should == "__DO_NOT_USE__"
279
+ local[Solrizer.solr_name("desc_metadata__part_of")].should be_nil
280
+ local[Solrizer.solr_name("desc_metadata__date_uploaded")].should be_nil
281
+ local[Solrizer.solr_name("desc_metadata__date_modified")].should be_nil
282
+ local[Solrizer.solr_name("desc_metadata__date_uploaded", :stored_sortable, type: :date)].should == ['2011-01-01T00:00:00Z']
283
+ local[Solrizer.solr_name("desc_metadata__date_modified", :stored_sortable, type: :date)].should == ['2012-01-01T00:00:00Z']
284
+ local[Solrizer.solr_name("desc_metadata__rights")].should == ["Wide open, buddy."]
285
+ local[Solrizer.solr_name("desc_metadata__related_url")].should be_nil
286
+ local[Solrizer.solr_name("desc_metadata__contributor")].should == ["Mohammad"]
287
+ local[Solrizer.solr_name("desc_metadata__creator")].should == ["Allah"]
288
+ local[Solrizer.solr_name("desc_metadata__title")].should == ["The Work"]
289
+ local[Solrizer.solr_name("desc_metadata__description")].should == ["The work by Allah"]
290
+ local[Solrizer.solr_name("desc_metadata__publisher")].should == ["Vertigo Comics"]
291
+ local[Solrizer.solr_name("desc_metadata__subject")].should == ["Theology"]
292
+ local[Solrizer.solr_name("desc_metadata__language")].should == ["Arabic"]
293
+ local[Solrizer.solr_name("desc_metadata__date_created")].should == ["1200-01-01"]
294
+ local[Solrizer.solr_name("desc_metadata__resource_type")].should == ["Book"]
295
+ local[Solrizer.solr_name("file_format")].should == "jpeg (JPEG Image)"
296
+ local[Solrizer.solr_name("desc_metadata__identifier")].should == ["urn:isbn:1234567890"]
297
+ local[Solrizer.solr_name("desc_metadata__based_near")].should == ["Medina, Saudi Arabia"]
298
+ local[Solrizer.solr_name("mime_type")].should == ["image/jpeg"]
299
+ local["noid_tsi"].should == "__DO_NOT_USE__"
233
300
  end
234
301
  it "should support multi-valued fields in solr" do
235
302
  @file.tag = ["tag1", "tag2"]
@@ -241,24 +308,41 @@ describe GenericFile do
241
308
  @file.relative_path.should == "documents/research/NSF/2010"
242
309
  end
243
310
  describe "create_thumbnail" do
311
+ before do
312
+ @f = GenericFile.new
313
+ #@f.stub(:characterize_if_changed).and_yield #don't run characterization
314
+ @f.apply_depositor_metadata('mjg36')
315
+ end
316
+ after do
317
+ @f.delete
318
+ end
319
+ describe "with a video", :if => Sufia::Engine.config.enable_ffmpeg do
320
+ before do
321
+ @f.stub(:mime_type=>'video/quicktime') #Would get set by the characterization job
322
+ @f.add_file_datastream(File.new("#{fixture_path}/countdown.avi", 'rb'), :dsid=>'content')
323
+ @f.save
324
+ end
325
+ it "should make a png thumbnail" do
326
+ @f.create_thumbnail
327
+ @f.thumbnail.content.size.should == 4768 # this is a bad test. I just want to show that it did something.
328
+ @f.thumbnail.mimeType.should == 'image/png'
329
+ end
330
+ end
331
+
244
332
  describe "with an image that doesn't get resized" do
245
333
  before do
246
- @f = GenericFile.new
247
334
  @f.stub(:mime_type=>'image/png', :width=>['50'], :height=>['50']) #Would get set by the characterization job
248
335
  @f.add_file_datastream(File.new("#{fixture_path}/world.png", 'rb'), :dsid=>'content')
249
- @f.apply_depositor_metadata('mjg36')
250
336
  @f.save
337
+ end
338
+ it "should keep the thumbnail at the original size (but transform to png)" do
251
339
  @mock_image = mock("image", :from_blob=>true)
340
+ @mock_image.should_not_receive(:scale)
341
+ @mock_image.should_receive(:to_blob).and_return('fake content')
252
342
  Magick::ImageList.should_receive(:new).and_return(@mock_image)
253
- end
254
- after do
255
- @f.delete
256
- end
257
- it "should scale the thumbnail to original size" do
258
- @mock_image.should_receive(:scale).with(50, 50).and_return(stub(:to_blob=>'fake content'))
259
343
  @f.create_thumbnail
260
- @f.content.changed?.should be_false
261
344
  @f.thumbnail.content.should == 'fake content'
345
+ @f.thumbnail.mimeType.should == 'image/png'
262
346
  end
263
347
  end
264
348
  end
@@ -266,12 +350,11 @@ describe GenericFile do
266
350
  before(:each) do
267
351
  u = FactoryGirl.create(:user)
268
352
  f = GenericFile.new
269
- f.stub(:characterize).and_return(true)
270
353
  f.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
271
354
  f.apply_depositor_metadata(u.user_key)
355
+ f.stub(:characterize_if_changed).and_yield #don't run characterization
272
356
  f.save!
273
- @f = GenericFile.find(f.pid)
274
- @f.stub(:characterize).and_return(true)
357
+ @f = f.reload
275
358
  end
276
359
  it "should schedule a audit job for each datastream" do
277
360
  s1 = stub('one')
@@ -289,12 +372,6 @@ describe GenericFile do
289
372
  s5 = stub('five')
290
373
  AuditJob.should_receive(:new).with(@f.pid, 'content', "content.0").and_return(s5)
291
374
  Sufia.queue.should_receive(:push).with(s5)
292
- s6 = stub('six')
293
- AuditJob.should_receive(:new).with(@f.pid, 'characterization', "characterization.0").and_return(s6)
294
- Sufia.queue.should_receive(:push).with(s6)
295
- s7 = stub('seven')
296
- AuditJob.should_receive(:new).with(@f.pid, 'thumbnail', "thumbnail.0").and_return(s7)
297
- Sufia.queue.should_receive(:push).with(s7)
298
375
  @f.audit!
299
376
  end
300
377
  it "should log a failing audit" do
@@ -319,6 +396,7 @@ describe GenericFile do
319
396
  @f = GenericFile.new
320
397
  @f.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
321
398
  @f.apply_depositor_metadata('mjg36')
399
+ @f.stub(:characterize_if_changed).and_yield #don't run characterization
322
400
  @f.save!
323
401
  @version = @f.datastreams['content'].versions.first
324
402
  @old = ChecksumAuditLog.create(:pid=>@f.pid, :dsid=>@version.dsid, :version=>@version.versionID, :pass=>1, :created_at=>2.minutes.ago)
@@ -455,7 +533,7 @@ describe GenericFile do
455
533
  end
456
534
  end
457
535
  describe "characterize" do
458
- it "should return expected results when called" do
536
+ it "should return expected results when called", :unless => $in_travis do
459
537
  @file.add_file_datastream(File.new(fixture_path + '/world.png'), :dsid=>'content')
460
538
  @file.characterize
461
539
  doc = Nokogiri::XML.parse(@file.characterization.content)
@@ -475,19 +553,12 @@ describe GenericFile do
475
553
  myfile = GenericFile.new
476
554
  myfile.add_file_datastream(File.new(fixture_path + '/sufia/sufia_test4.pdf'), :dsid=>'content')
477
555
  myfile.label = 'label123'
478
- myfile.thumbnail.size.nil?.should be_true
479
556
  myfile.apply_depositor_metadata('mjg36')
480
557
  myfile.save
481
- @myfile = GenericFile.find(myfile.pid)
558
+ @myfile = myfile.reload
482
559
  end
483
560
  after(:all) do
484
- unless @myfile.inner_object.kind_of? ActiveFedora::UnsavedDigitalObject
485
- begin
486
- @myfile.delete
487
- rescue ActiveFedora::ObjectNotFoundError
488
- # do nothing
489
- end
490
- end
561
+ @myfile.delete
491
562
  end
492
563
  it "should return expected results after a save" do
493
564
  @myfile.file_size.should == ['218882']
@@ -506,7 +577,7 @@ describe GenericFile do
506
577
  @myfile.filename[0].should == @myfile.label
507
578
  end
508
579
  it "should include thumbnail generation in characterization job" do
509
- @myfile.thumbnail.size.nil?.should be_false
580
+ @myfile.thumbnail.size.should_not be_nil
510
581
  end
511
582
  it "should append each term only once" do
512
583
  @myfile.append_metadata
@@ -537,19 +608,19 @@ describe GenericFile do
537
608
  it "should have read groups writer" do
538
609
  subject.read_groups = ['group-2', 'group-3']
539
610
  subject.rightsMetadata.groups.should == {'group-2' => 'read', 'group-3'=>'read', 'group-8' => 'edit'}
540
- subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"read"}
611
+ subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"read", 'jcoyne' => 'edit'}
541
612
  end
542
613
 
543
614
  it "should have read groups string writer" do
544
615
  subject.read_groups_string = 'umg/up.dlt.staff, group-3'
545
616
  subject.rightsMetadata.groups.should == {'umg/up.dlt.staff' => 'read', 'group-3'=>'read', 'group-8' => 'edit'}
546
- subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"read"}
617
+ subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"read", 'jcoyne' => 'edit'}
547
618
  end
548
619
  it "should only revoke eligible groups" do
549
620
  subject.set_read_groups(['group-2', 'group-3'], ['group-6'])
550
621
  # 'group-7' is not eligible to be revoked
551
622
  subject.rightsMetadata.groups.should == {'group-2' => 'read', 'group-3'=>'read', 'group-7' => 'read', 'group-8' => 'edit'}
552
- subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"read"}
623
+ subject.rightsMetadata.individuals.should == {"person1"=>"read","person2"=>"read", 'jcoyne' => 'edit'}
553
624
  end
554
625
  end
555
626
  describe "permissions validation" do