sufia 5.0.0 → 6.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +1 -8
- data/Gemfile +3 -12
- data/History.md +0 -36
- data/LICENSE.md +14 -0
- data/README.md +4 -8
- data/SUFIA_VERSION +1 -1
- data/app/assets/javascripts/sufia.js +1 -17
- data/app/assets/javascripts/sufia/batch_edit.js +43 -28
- data/app/assets/javascripts/sufia/edit_metadata.js +9 -14
- data/app/assets/javascripts/sufia/multiForm.js +67 -0
- data/app/assets/javascripts/sufia/permissions.js +92 -35
- data/app/assets/stylesheets/sufia.css.scss +1 -6
- data/app/assets/stylesheets/sufia/_batch-edit.scss +0 -8
- data/app/assets/stylesheets/sufia/_dashboard.scss +1 -15
- data/app/assets/stylesheets/sufia/_file-listing.scss +1 -1
- data/app/assets/stylesheets/sufia/_settings.scss +0 -1
- data/app/controllers/concerns/sufia/batch_edits_controller_behavior.rb +3 -10
- data/app/controllers/concerns/sufia/breadcrumbs.rb +3 -8
- data/app/controllers/concerns/sufia/catalog.rb +1 -1
- data/app/controllers/concerns/sufia/controller.rb +3 -1
- data/app/controllers/concerns/sufia/downloads_controller_behavior.rb +1 -1
- data/app/controllers/concerns/sufia/files_controller/browse_everything.rb +1 -1
- data/app/controllers/concerns/sufia/files_controller_behavior.rb +16 -4
- data/app/controllers/concerns/sufia/homepage_controller.rb +1 -1
- data/app/controllers/concerns/sufia/my_controller_behavior.rb +2 -2
- data/app/controllers/concerns/sufia/transfers_controller_behavior.rb +3 -4
- data/app/controllers/concerns/sufia/users_controller_behavior.rb +2 -7
- data/app/controllers/my/collections_controller.rb +3 -4
- data/app/controllers/my/highlights_controller.rb +2 -2
- data/app/controllers/my/shares_controller.rb +3 -3
- data/app/controllers/single_use_links_controller.rb +5 -9
- data/app/controllers/single_use_links_viewer_controller.rb +4 -4
- data/app/helpers/generic_file_helper.rb +9 -0
- data/app/helpers/sufia/records_helper_behavior.rb +16 -0
- data/app/helpers/sufia/sufia_helper_behavior.rb +0 -11
- data/app/jobs/content_depositor_change_event_job.rb +1 -1
- data/app/jobs/ingest_local_file_job.rb +2 -1
- data/app/models/concerns/sufia/solr_document_behavior.rb +10 -10
- data/app/models/featured_work_list.rb +7 -9
- data/app/presenters/sufia/version_list_presenter.rb +15 -0
- data/app/presenters/sufia/version_presenter.rb +30 -0
- data/app/views/batch/_metadata.html.erb +51 -29
- data/app/views/batch/_more_metadata.html.erb +1 -1
- data/app/views/batch/edit.html.erb +10 -8
- data/app/views/batch_edits/edit.html.erb +13 -9
- data/app/views/collections/_edit_descriptions.html.erb +1 -1
- data/app/views/collections/_form.html.erb +4 -4
- data/app/views/collections/_form_for_select_collection.html.erb +1 -1
- data/app/views/collections/_show_document_list_menu.html.erb +7 -5
- data/app/views/collections/_show_document_list_row.html.erb +2 -2
- data/app/views/collections/edit.html.erb +0 -1
- data/app/views/collections/edit_fields/_description.html.erb +4 -0
- data/app/views/collections/edit_fields/_title.html.erb +3 -0
- data/app/views/collections/show.html.erb +0 -1
- data/app/views/dashboard/_index_partials/_stats.html.erb +3 -3
- data/app/views/generic_files/_descriptions.html.erb +9 -9
- data/app/views/generic_files/_field_form.html.erb +11 -25
- data/app/views/generic_files/_permission.html.erb +6 -4
- data/app/views/generic_files/_permission_form.html.erb +15 -17
- data/app/views/generic_files/_show_details.html.erb +1 -11
- data/app/views/generic_files/_versioning.html.erb +5 -5
- data/app/views/generic_files/edit.html.erb +5 -4
- data/app/views/generic_files/show.html.erb +6 -6
- data/app/views/homepage/_featured_fields.html.erb +2 -2
- data/app/views/homepage/_recent_document.html.erb +1 -1
- data/app/views/layouts/_head_tag_content.html.erb +0 -2
- data/app/views/layouts/error.html.erb +0 -1
- data/app/views/my/_index_partials/_default_group.html.erb +1 -1
- data/app/views/my/_index_partials/_list_files.html.erb +1 -1
- data/app/views/my/index.html.erb +2 -2
- data/app/views/records/_edit_field.html.erb +17 -19
- data/app/views/records/edit_fields/_default.html.erb +10 -12
- data/app/views/records/edit_fields/_description.html.erb +10 -3
- data/app/views/records/edit_fields/_resource_type.html.erb +4 -5
- data/app/views/records/edit_fields/_rights.html.erb +9 -2
- data/app/views/records/edit_fields/_suffix.html.erb +10 -0
- data/app/views/records/edit_fields/_type.html.erb +8 -2
- data/app/views/records/show_fields/_based_near.html.erb +1 -1
- data/app/views/records/show_fields/_creator.html.erb +1 -1
- data/app/views/records/show_fields/_language.html.erb +1 -1
- data/app/views/records/show_fields/_publisher.html.erb +1 -1
- data/app/views/records/show_fields/_resource_type.html.erb +1 -1
- data/app/views/records/show_fields/_subject.html.erb +1 -1
- data/app/views/records/show_fields/_tag.html.erb +1 -1
- data/app/views/single_use_links/new_download.html.erb +2 -2
- data/app/views/users/_profile.html.erb +2 -1
- data/app/views/users/_social_media_info.html.erb +20 -0
- data/app/views/users/_user_info.html.erb +3 -20
- data/app/views/users/edit.html.erb +2 -11
- data/app/views/users/show.html.erb +1 -1
- data/bin/audit_repository +1 -1
- data/config/initializers/sufia_events.rb +4 -4
- data/config/locales/sufia.en.yml +0 -5
- data/config/routes.rb +1 -1
- data/lib/generators/sufia/install_generator.rb +0 -4
- data/lib/generators/sufia/templates/catalog_controller.rb +59 -59
- data/lib/sufia.rb +1 -4
- data/lib/sufia/version.rb +1 -1
- data/spec/actors/generic_file/actor_spec.rb +67 -8
- data/spec/controllers/batch_controller_spec.rb +72 -86
- data/spec/controllers/batch_edits_controller_spec.rb +17 -19
- data/spec/controllers/catalog_controller_spec.rb +16 -24
- data/spec/controllers/collections_controller_spec.rb +47 -74
- data/spec/controllers/downloads_controller_spec.rb +40 -35
- data/spec/controllers/generic_files_controller_spec.rb +363 -428
- data/spec/controllers/homepage_controller_spec.rb +12 -9
- data/spec/controllers/mailbox_controller_spec.rb +1 -4
- data/spec/controllers/my/files_controller_spec.rb +0 -10
- data/spec/controllers/single_use_links_controller_spec.rb +28 -35
- data/spec/controllers/single_use_links_viewer_controller_spec.rb +27 -41
- data/spec/controllers/transfers_controller_spec.rb +6 -6
- data/spec/controllers/users_controller_spec.rb +121 -124
- data/spec/factories/generic_files.rb +9 -17
- data/spec/features/browse_dashboard_files_spec.rb +8 -10
- data/spec/features/browse_files_spec.rb +12 -25
- data/spec/features/catalog_search_spec.rb +49 -49
- data/spec/features/collection_spec.rb +18 -24
- data/spec/features/contact_form_spec.rb +26 -20
- data/spec/features/ingest_upload_files_spec.rb +8 -6
- data/spec/features/ownership_transfer_spec.rb +2 -6
- data/spec/features/proxy_spec.rb +1 -1
- data/spec/features/search_spec.rb +2 -3
- data/spec/features/single_use_links_spec.rb +1 -1
- data/spec/features/users_spec.rb +1 -1
- data/spec/helpers/records_helper_spec.rb +24 -10
- data/spec/jobs/active_fedora_pid_based_job_spec.rb +1 -5
- data/spec/jobs/audit_job_spec.rb +66 -21
- data/spec/jobs/batch_update_job_spec.rb +49 -36
- data/spec/jobs/content_depositor_change_event_job_spec.rb +2 -4
- data/spec/jobs/create_derivatives_job_spec.rb +18 -19
- data/spec/jobs/event_jobs_spec.rb +17 -21
- data/spec/jobs/import_url_job_spec.rb +1 -6
- data/spec/jobs/ingest_local_file_job_spec.rb +0 -4
- data/spec/lib/sufia/breadcrumbs_spec.rb +8 -46
- data/spec/lib/sufia/id_service_spec.rb +8 -3
- data/spec/lib/sufia/user_stat_importer_spec.rb +18 -25
- data/spec/lib/sufia/writable_permissions_spec.rb +0 -4
- data/spec/models/ability_spec.rb +25 -18
- data/spec/models/batch_spec.rb +16 -45
- data/spec/models/characterization_spec.rb +1 -1
- data/spec/models/checksum_audit_log_spec.rb +51 -29
- data/spec/models/collection_spec.rb +0 -5
- data/spec/models/featured_work_list_spec.rb +2 -4
- data/spec/models/file_content_datastream_spec.rb +27 -60
- data/spec/models/file_usage_spec.rb +16 -21
- data/spec/models/fits_datastream_spec.rb +47 -2
- data/spec/models/generic_file/web_form_spec.rb +1 -1
- data/spec/models/generic_file_spec.rb +238 -735
- data/spec/models/local_authority_spec.rb +8 -13
- data/spec/models/proxy_deposit_request_spec.rb +3 -7
- data/spec/models/single_use_link_spec.rb +12 -16
- data/spec/models/solr_document_spec.rb +1 -1
- data/spec/models/trophy_spec.rb +1 -3
- data/spec/models/user_spec.rb +47 -75
- data/spec/presenters/sufia/version_list_presenter_spec.rb +22 -0
- data/spec/presenters/sufia/version_presenter_spec.rb +51 -0
- data/spec/services/generic_file_audit_service_spec.rb +85 -0
- data/spec/services/repository_audit_service_spec.rb +18 -0
- data/spec/spec_helper.rb +26 -7
- data/spec/support/fixture_helpers.rb +2 -4
- data/spec/test_app_templates/lib/generators/test_app_generator.rb +0 -4
- data/spec/views/batch/edit.html.erb_spec.rb +17 -7
- data/spec/views/catalog/index.html.erb_spec.rb +8 -6
- data/spec/views/collections/_form.html.erb_spec.rb +4 -2
- data/spec/views/collections/_show_document_list.erb_spec.rb +31 -0
- data/spec/views/dashboard/index_spec.rb +2 -2
- data/spec/views/generic_file/edit.html.erb_spec.rb +20 -6
- data/spec/views/generic_file/show.html.erb_spec.rb +3 -3
- data/spec/views/users/show.html.erb_spec.rb +1 -1
- data/sufia-models/app/actors/sufia/generic_file/actor.rb +8 -10
- data/sufia-models/app/jobs/active_fedora_pid_based_job.rb +2 -3
- data/sufia-models/app/jobs/audit_job.rb +46 -32
- data/sufia-models/app/jobs/batch_update_job.rb +9 -8
- data/sufia-models/app/jobs/import_url_job.rb +2 -2
- data/sufia-models/app/models/batch.rb +11 -12
- data/sufia-models/app/models/checksum_audit_log.rb +12 -10
- data/sufia-models/app/models/concerns/sufia/ability.rb +4 -6
- data/sufia-models/app/models/concerns/sufia/collection.rb +4 -5
- data/sufia-models/app/models/concerns/sufia/generic_file.rb +3 -86
- data/sufia-models/app/models/concerns/sufia/generic_file/batches.rb +29 -0
- data/sufia-models/app/models/concerns/sufia/generic_file/characterization.rb +3 -3
- data/sufia-models/app/models/concerns/sufia/generic_file/content.rb +13 -0
- data/sufia-models/app/models/concerns/sufia/generic_file/derivatives.rb +5 -5
- data/sufia-models/app/models/concerns/sufia/generic_file/export.rb +4 -0
- data/sufia-models/app/models/concerns/sufia/generic_file/full_text_indexing.rb +2 -2
- data/sufia-models/app/models/concerns/sufia/generic_file/indexing.rb +23 -0
- data/sufia-models/app/models/concerns/sufia/generic_file/metadata.rb +80 -11
- data/sufia-models/app/models/concerns/sufia/generic_file/proxy_deposit.rb +12 -3
- data/sufia-models/app/models/concerns/sufia/generic_file/versions.rb +4 -4
- data/sufia-models/app/models/concerns/sufia/generic_file/web_form.rb +14 -6
- data/sufia-models/app/models/concerns/sufia/model_methods.rb +11 -9
- data/sufia-models/app/models/concerns/sufia/user.rb +11 -33
- data/sufia-models/app/models/datastreams/file_content_datastream.rb +1 -1
- data/sufia-models/app/models/datastreams/fits_datastream.rb +1 -1
- data/sufia-models/app/models/file_usage.rb +3 -3
- data/sufia-models/app/models/local_authority.rb +2 -2
- data/sufia-models/app/models/proxy_deposit_request.rb +1 -1
- data/sufia-models/app/services/sufia/generic_file_audit_service.rb +83 -0
- data/sufia-models/app/services/sufia/id_service.rb +5 -5
- data/sufia-models/app/services/sufia/noid.rb +10 -7
- data/sufia-models/app/services/sufia/repository_audit_service.rb +9 -0
- data/sufia-models/lib/generators/sufia/models/cached_stats_generator.rb +47 -3
- data/sufia-models/lib/generators/sufia/models/install_generator.rb +31 -11
- data/sufia-models/lib/generators/sufia/models/proxies_generator.rb +31 -2
- data/sufia-models/lib/generators/sufia/models/templates/config/sufia.rb +10 -0
- data/sufia-models/lib/generators/sufia/models/upgrade400_generator.rb +33 -2
- data/sufia-models/lib/sufia/models/engine.rb +13 -4
- data/sufia-models/lib/sufia/models/file_content/versions.rb +9 -11
- data/sufia-models/lib/sufia/models/stats/user_stat_importer.rb +5 -9
- data/sufia-models/lib/sufia/models/version.rb +1 -1
- data/sufia-models/lib/sufia/permissions/writable.rb +34 -16
- data/sufia-models/sufia-models.gemspec +4 -2
- data/sufia.gemspec +4 -5
- data/tasks/jetty.rake +0 -26
- data/tasks/sufia-dev.rake +14 -2
- metadata +49 -64
- data/LICENSE +0 -15
- data/app/assets/images/orcid.png +0 -0
- data/app/assets/javascripts/sufia/manage_repeating_fields.js +0 -74
- data/app/assets/stylesheets/sufia/_multi_value_fields.css.scss +0 -67
- data/app/inputs/multi_value_input.rb +0 -84
- data/app/views/records/_rights_modal.html.erb +0 -1
- data/config/initializers/simple_form.rb +0 -167
- data/config/initializers/simple_form_bootstrap.rb +0 -137
- data/config/locales/simple_form.en.yml +0 -31
- data/fedora_conf/conf/development/fedora.fcfg +0 -946
- data/fedora_conf/conf/test/fedora.fcfg +0 -946
- data/spec/models/generic_file/reload_on_save_spec.rb +0 -25
- data/spec/models/generic_file_rdf_datastream_spec.rb +0 -12
- data/spec/models/properties_datastream_spec.rb +0 -41
- data/spec/views/generic_file/_permission_form.html.erb_spec.rb +0 -19
- data/sufia-models/app/models/concerns/sufia/generic_file/audit.rb +0 -116
- data/sufia-models/app/models/concerns/sufia/generic_file/reload_on_save.rb +0 -18
- data/sufia-models/app/models/concerns/sufia/properties_datastream_behavior.rb +0 -32
- data/sufia-models/app/models/datastreams/batch_rdf_datastream.rb +0 -6
- data/sufia-models/app/models/datastreams/generic_file_rdf_datastream.rb +0 -69
- data/sufia-models/app/models/datastreams/paranoid_rights_datastream.rb +0 -22
- data/sufia-models/app/models/datastreams/properties_datastream.rb +0 -4
- data/sufia-models/app/models/sufia/orcid_validator.rb +0 -8
- data/sufia-models/lib/generators/sufia/models/abstract_migration_generator.rb +0 -30
- data/sufia-models/lib/generators/sufia/models/orcid_field_generator.rb +0 -19
- data/sufia-models/lib/generators/sufia/models/templates/migrations/add_orcid_to_users.rb +0 -5
- data/sufia-models/lib/generators/sufia/models/user_stats_generator.rb +0 -31
@@ -5,7 +5,7 @@ describe Sufia::GenericFile::Characterization, :type => :model do
|
|
5
5
|
class TestClass < ActiveFedora::Base
|
6
6
|
include Sufia::GenericFile::Characterization
|
7
7
|
|
8
|
-
|
8
|
+
contains 'content', class_name: 'FileContentDatastream'
|
9
9
|
attr_accessor :title, :creator
|
10
10
|
end
|
11
11
|
end
|
@@ -1,43 +1,65 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
describe ChecksumAuditLog
|
3
|
+
describe ChecksumAuditLog do
|
4
|
+
before do
|
5
|
+
allow_any_instance_of(GenericFile).to receive(:characterize).and_return(true) # stub out characterization so it does not get audited
|
6
|
+
end
|
7
|
+
|
4
8
|
let(:f) do
|
5
|
-
GenericFile.
|
9
|
+
GenericFile.create do |gf|
|
6
10
|
gf.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
7
11
|
gf.apply_depositor_metadata('mjg36')
|
8
|
-
gf.save!
|
9
12
|
end
|
10
13
|
end
|
11
|
-
|
12
|
-
let(:
|
13
|
-
|
14
|
-
|
15
|
-
let(:new)
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
allow_any_instance_of(GenericFile).to receive(:characterize).and_return(true) # stub out characterization so it does not get audited
|
14
|
+
|
15
|
+
let(:version_uri) { f.content.versions.first.uri }
|
16
|
+
let(:version_path) { 'content' }
|
17
|
+
let(:old) { ChecksumAuditLog.create(pid: f.id, dsid: version_path, version: version_uri, pass: 1, created_at: 2.minutes.ago) }
|
18
|
+
let(:new) { ChecksumAuditLog.create(pid: f.id, dsid: version_path, version: version_uri, pass: 0, created_at: 1.minute.ago) }
|
19
|
+
|
20
|
+
context "a file with multiple checksums audits" do
|
21
|
+
specify "should return a list of logs for this datastream sorted by date descending" do
|
22
|
+
logs = ChecksumAuditLog.logs_for(f.id, version_path)
|
23
|
+
expect(logs).to eq([new, old])
|
24
|
+
end
|
23
25
|
end
|
24
|
-
|
25
|
-
|
26
|
+
|
27
|
+
context "after multiple checksum audits where the checksum does not change" do
|
28
|
+
specify "only one of them should be kept" do
|
29
|
+
success1 = ChecksumAuditLog.create(pid: f.id, dsid: version_path, version: version_uri, pass: 1)
|
30
|
+
ChecksumAuditLog.prune_history(f.id, version_path)
|
31
|
+
success2 = ChecksumAuditLog.create(pid: f.id, dsid: version_path, version: version_uri, pass: 1)
|
32
|
+
ChecksumAuditLog.prune_history(f.id, version_path)
|
33
|
+
success3 = ChecksumAuditLog.create(pid: f.id, dsid: version_path, version: version_uri, pass: 1)
|
34
|
+
ChecksumAuditLog.prune_history(f.id, version_path)
|
35
|
+
|
36
|
+
expect { ChecksumAuditLog.find(success2.id) }.to raise_exception ActiveRecord::RecordNotFound
|
37
|
+
expect { ChecksumAuditLog.find(success3.id) }.to raise_exception ActiveRecord::RecordNotFound
|
38
|
+
expect(ChecksumAuditLog.find(success1.id)).not_to be_nil
|
39
|
+
logs = ChecksumAuditLog.logs_for(f.id, version_path)
|
40
|
+
expect(logs).to eq([success1, new, old])
|
41
|
+
end
|
26
42
|
end
|
27
|
-
|
43
|
+
|
44
|
+
context "should have an audit log history" do
|
28
45
|
before do
|
29
|
-
|
30
|
-
ChecksumAuditLog.
|
31
|
-
@success2 = ChecksumAuditLog.create(pid: f.pid, dsid: version.dsid, version: version.versionID, pass: 1)
|
32
|
-
ChecksumAuditLog.prune_history(version)
|
33
|
-
@success3 = ChecksumAuditLog.create(pid: f.pid, dsid: version.dsid, version: version.versionID, pass: 1)
|
34
|
-
ChecksumAuditLog.prune_history(version)
|
46
|
+
ChecksumAuditLog.create(pid: f.id, dsid: 'content', version: 'v2', pass: 1)
|
47
|
+
ChecksumAuditLog.create(pid: f.id, dsid: 'thumbnail', version: 'v1', pass: 1)
|
35
48
|
end
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
expect(
|
40
|
-
expect(
|
49
|
+
|
50
|
+
specify "should have an audit log history" do
|
51
|
+
audit = ChecksumAuditLog.get_audit_log(f.id, 'content', version_uri)
|
52
|
+
expect(audit.pid).to eq(f.id)
|
53
|
+
expect(audit.version).to eq(version_uri)
|
54
|
+
|
55
|
+
audit = ChecksumAuditLog.get_audit_log(f.id, 'content', 'v2')
|
56
|
+
expect(audit.pid).to eq(f.id)
|
57
|
+
expect(audit.version).to eq('v2')
|
58
|
+
|
59
|
+
audit = ChecksumAuditLog.get_audit_log(f.id, 'thumbnail', 'v1')
|
60
|
+
expect(audit.pid).to eq(f.id)
|
61
|
+
expect(audit.version).to eq('v1')
|
62
|
+
|
41
63
|
end
|
42
64
|
end
|
43
65
|
end
|
@@ -9,15 +9,13 @@ describe FeaturedWorkList, :type => :model do
|
|
9
9
|
FeaturedWork.create(generic_file_id: file2.noid)
|
10
10
|
end
|
11
11
|
|
12
|
-
after { GenericFile.destroy_all }
|
13
|
-
|
14
12
|
describe 'featured_works' do
|
15
13
|
it 'should be a list of the featured work objects, each with the generic_file\'s solr_doc' do
|
16
14
|
expect(subject.featured_works.size).to eq 2
|
17
15
|
solr_doc = subject.featured_works.first.generic_file_solr_document
|
18
16
|
expect(solr_doc).to be_kind_of SolrDocument
|
19
|
-
expect(solr_doc.noid).to eq file1.noid
|
20
|
-
end
|
17
|
+
expect(solr_doc.noid).to eq file1.noid
|
18
|
+
end
|
21
19
|
end
|
22
20
|
|
23
21
|
describe 'file deleted' do
|
@@ -1,81 +1,48 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe FileContentDatastream, :type => :model do
|
4
|
-
describe "
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
@file = f.reload
|
11
|
-
end
|
12
|
-
after do
|
13
|
-
@file.delete
|
14
|
-
end
|
15
|
-
it "should have a list of versions with one entry" do
|
16
|
-
@file.content.versions.count == 1
|
17
|
-
end
|
18
|
-
it "should return the expected version ID" do
|
19
|
-
expect(@file.content.versions.first.versionID).to eq("content.0")
|
20
|
-
end
|
21
|
-
it "should support latest_version" do
|
22
|
-
expect(@file.content.latest_version.versionID).to eq("content.0")
|
23
|
-
end
|
24
|
-
it "should return the same version via get_version" do
|
25
|
-
expect(@file.content.get_version("content.0").versionID).to eq(@file.content.latest_version.versionID)
|
4
|
+
describe "#latest_version" do
|
5
|
+
let(:file) do
|
6
|
+
GenericFile.create do |f|
|
7
|
+
f.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
8
|
+
f.apply_depositor_metadata('mjg36')
|
9
|
+
end
|
26
10
|
end
|
27
|
-
|
28
|
-
|
11
|
+
|
12
|
+
context "with one version" do
|
13
|
+
subject { file.content.latest_version.label }
|
14
|
+
it { is_expected.to eq "version1" }
|
29
15
|
end
|
30
|
-
|
16
|
+
|
17
|
+
context "with two versions" do
|
31
18
|
before do
|
32
|
-
|
33
|
-
|
34
|
-
end
|
35
|
-
it "should return two versions" do
|
36
|
-
@file.content.versions.count == 2
|
37
|
-
end
|
38
|
-
it "should return the newer version via latest_version" do
|
39
|
-
expect(@file.content.versions.first.versionID).to eq("content.1")
|
40
|
-
end
|
41
|
-
it "should return the same version via get_version" do
|
42
|
-
expect(@file.content.get_version("content.1").versionID).to eq(@file.content.latest_version.versionID)
|
19
|
+
file.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
20
|
+
file.save
|
43
21
|
end
|
22
|
+
subject { file.content.latest_version.label }
|
23
|
+
it { is_expected.to eq "version2" }
|
44
24
|
end
|
45
25
|
end
|
26
|
+
|
46
27
|
describe "extract_metadata" do
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
28
|
+
let(:datastream) { FileContentDatastream.new('foo/content') }
|
29
|
+
let(:file) { ActionDispatch::Http::UploadedFile.new(tempfile: File.new(fixture_path + '/world.png'),
|
30
|
+
filename: 'world.png') }
|
31
|
+
before { datastream.content = file }
|
32
|
+
let(:document) { Nokogiri::XML.parse(datastream.extract_metadata).root }
|
33
|
+
let(:namespace) { { 'ns'=>'http://hul.harvard.edu/ois/xml/ns/fits/fits_output' } }
|
34
|
+
|
52
35
|
it "should return an xml document", unless: $in_travis do
|
53
|
-
|
54
|
-
@subject.content = f.read
|
55
|
-
xml = @subject.extract_metadata
|
56
|
-
doc = Nokogiri::XML.parse(xml)
|
57
|
-
expect(doc.root.xpath('//ns:imageWidth/text()', {'ns'=>'http://hul.harvard.edu/ois/xml/ns/fits/fits_output'}).inner_text).to eq('50')
|
58
|
-
end
|
59
|
-
it "should return expected results when invoked via HTTP", unless: $in_travis do
|
60
|
-
f = ActionDispatch::Http::UploadedFile.new(tempfile: File.new(fixture_path + '/world.png'),
|
61
|
-
filename: 'world.png')
|
62
|
-
content = double("file")
|
63
|
-
allow(content).to receive_messages(read: f.read)
|
64
|
-
allow(content).to receive_messages(rewind: f.rewind)
|
65
|
-
allow(@subject).to receive(:content).and_return(f)
|
66
|
-
xml = @subject.extract_metadata
|
67
|
-
doc = Nokogiri::XML.parse(xml)
|
68
|
-
expect(doc.root.xpath('//ns:identity/@mimetype', {'ns'=>'http://hul.harvard.edu/ois/xml/ns/fits/fits_output'}).first.value).to eq('image/png')
|
36
|
+
expect(document.xpath('//ns:identity/@mimetype', namespace).first.value).to eq 'image/png'
|
69
37
|
end
|
70
38
|
end
|
39
|
+
|
71
40
|
describe "changed?" do
|
72
41
|
before do
|
73
42
|
@generic_file = GenericFile.new
|
74
43
|
@generic_file.apply_depositor_metadata('mjg36')
|
75
44
|
end
|
76
|
-
|
77
|
-
@generic_file.delete
|
78
|
-
end
|
45
|
+
|
79
46
|
it "should only return true when the datastream has actually changed" do
|
80
47
|
@generic_file.add_file(File.open(fixture_path + '/world.png', 'rb'), 'content', 'world.png')
|
81
48
|
expect(@generic_file.content).to be_changed
|
@@ -2,14 +2,11 @@ require 'spec_helper'
|
|
2
2
|
|
3
3
|
describe FileUsage, :type => :model do
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
after :all do
|
12
|
-
@file.delete
|
5
|
+
let(:file) do
|
6
|
+
GenericFile.new.tap do |file|
|
7
|
+
file.apply_depositor_metadata("awead")
|
8
|
+
file.save
|
9
|
+
end
|
13
10
|
end
|
14
11
|
|
15
12
|
let(:dates) {
|
@@ -33,7 +30,7 @@ describe FileUsage, :type => :model do
|
|
33
30
|
|
34
31
|
# This is what the data looks like that's returned from Google Analytics (GA) via the Legato gem
|
35
32
|
# Due to the nature of querying GA, testing this data in an automated fashion is problematc.
|
36
|
-
# Sample data structures were created by sending real events to GA from a test instance of
|
33
|
+
# Sample data structures were created by sending real events to GA from a test instance of
|
37
34
|
# Scholarsphere. The data below are essentially a "cut and paste" from the output of query
|
38
35
|
# results from the Legato gem.
|
39
36
|
|
@@ -61,21 +58,21 @@ describe FileUsage, :type => :model do
|
|
61
58
|
allow_any_instance_of(GenericFile).to receive(:create_date).and_return((Date.today-4.day).to_s)
|
62
59
|
expect(FileDownloadStat).to receive(:ga_statistics).and_return(sample_download_statistics)
|
63
60
|
expect(FileViewStat).to receive(:ga_statistics).and_return(sample_pageview_statistics)
|
64
|
-
FileUsage.new(
|
61
|
+
FileUsage.new(file.id)
|
65
62
|
}
|
66
63
|
|
67
64
|
describe "#initialize" do
|
68
65
|
|
69
66
|
it "should set the id" do
|
70
|
-
expect(usage.id).to eq(
|
67
|
+
expect(usage.id).to eq(file.id)
|
71
68
|
end
|
72
69
|
|
73
70
|
it "should set the path" do
|
74
|
-
expect(usage.path).to eq("/files/#{Sufia::Noid.noidify(
|
71
|
+
expect(usage.path).to eq("/files/#{URI.encode(Sufia::Noid.noidify(file.id), '/')}")
|
75
72
|
end
|
76
73
|
|
77
74
|
it "should set the created date" do
|
78
|
-
expect(usage.created).to eq(
|
75
|
+
expect(usage.created).to eq(file.create_date)
|
79
76
|
end
|
80
77
|
|
81
78
|
end
|
@@ -106,12 +103,10 @@ describe FileUsage, :type => :model do
|
|
106
103
|
expect(usage.to_flot[1][:data]).to include(*download_output)
|
107
104
|
end
|
108
105
|
|
109
|
-
let(:create_date) {DateTime.new(2014, 01, 01)}
|
106
|
+
let(:create_date) { DateTime.new(2014, 01, 01).iso8601 }
|
110
107
|
|
111
108
|
describe "analytics start date set" do
|
112
|
-
let(:earliest) {
|
113
|
-
DateTime.new(2014, 01, 02)
|
114
|
-
}
|
109
|
+
let(:earliest) { DateTime.new(2014, 01, 02).iso8601 }
|
115
110
|
|
116
111
|
before do
|
117
112
|
Sufia.config.analytic_start_date = earliest
|
@@ -122,7 +117,7 @@ describe FileUsage, :type => :model do
|
|
122
117
|
allow_any_instance_of(GenericFile).to receive(:create_date).and_return(create_date.to_s)
|
123
118
|
expect(FileDownloadStat).to receive(:ga_statistics).and_return(sample_download_statistics)
|
124
119
|
expect(FileViewStat).to receive(:ga_statistics).and_return(sample_pageview_statistics)
|
125
|
-
FileUsage.new(
|
120
|
+
FileUsage.new(file.id)
|
126
121
|
}
|
127
122
|
it "should set the created date to the earliest date not the created date" do
|
128
123
|
expect(usage.created).to eq(earliest)
|
@@ -136,10 +131,10 @@ describe FileUsage, :type => :model do
|
|
136
131
|
expect(FileDownloadStat).to receive(:ga_statistics).and_return(sample_download_statistics)
|
137
132
|
expect(FileViewStat).to receive(:ga_statistics).and_return(sample_pageview_statistics)
|
138
133
|
Sufia.config.analytic_start_date = earliest
|
139
|
-
FileUsage.new(
|
134
|
+
FileUsage.new(file.id)
|
140
135
|
}
|
141
136
|
it "should set the created date to the earliest date not the created date" do
|
142
|
-
expect(usage.created).to eq(
|
137
|
+
expect(usage.created).to eq(file.create_date)
|
143
138
|
end
|
144
139
|
end
|
145
140
|
end
|
@@ -152,7 +147,7 @@ describe FileUsage, :type => :model do
|
|
152
147
|
allow_any_instance_of(GenericFile).to receive(:create_date).and_return(create_date.to_s)
|
153
148
|
expect(FileDownloadStat).to receive(:ga_statistics).and_return(sample_download_statistics)
|
154
149
|
expect(FileViewStat).to receive(:ga_statistics).and_return(sample_pageview_statistics)
|
155
|
-
FileUsage.new(
|
150
|
+
FileUsage.new(file.id)
|
156
151
|
}
|
157
152
|
it "should set the created date to the earliest date not the created date" do
|
158
153
|
expect(usage.created).to eq(create_date)
|
@@ -3,7 +3,7 @@ require 'spec_helper'
|
|
3
3
|
describe FitsDatastream, type: :model, unless: $in_travis do
|
4
4
|
describe "image" do
|
5
5
|
before(:all) do
|
6
|
-
@file = GenericFile.new
|
6
|
+
@file = GenericFile.new(id: 'foo123')
|
7
7
|
@file.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
8
8
|
@file.characterize
|
9
9
|
end
|
@@ -31,10 +31,24 @@ describe FitsDatastream, type: :model, unless: $in_travis do
|
|
31
31
|
it "should have a width" do
|
32
32
|
expect(@file.width).to eq ["50"]
|
33
33
|
end
|
34
|
+
|
35
|
+
let(:datastream) { @file.characterization }
|
36
|
+
let(:xml) { datastream.ng_xml }
|
37
|
+
let(:namespace) { {'ns'=>'http://hul.harvard.edu/ois/xml/ns/fits/fits_output'} }
|
38
|
+
let(:solr_doc) { @file.to_solr }
|
39
|
+
|
40
|
+
it "should make the fits XML" do
|
41
|
+
expect(xml.xpath('//ns:imageWidth/text()', namespace).inner_text).to eq '50'
|
42
|
+
end
|
43
|
+
|
44
|
+
it "should index into solr" do
|
45
|
+
expect(solr_doc[Solrizer.solr_name("mime_type")].first).to eq "image/png"
|
46
|
+
end
|
34
47
|
end
|
48
|
+
|
35
49
|
describe "video" do
|
36
50
|
before(:all) do
|
37
|
-
@file = GenericFile.new
|
51
|
+
@file = GenericFile.new(id: 'foo123')
|
38
52
|
@file.add_file(File.open(fixture_path + '/sample_mpeg4.mp4'), 'content', 'sample_mpeg4.mp4')
|
39
53
|
@file.characterize
|
40
54
|
end
|
@@ -73,4 +87,35 @@ describe FitsDatastream, type: :model, unless: $in_travis do
|
|
73
87
|
expect(@file.frame_rate[0].to_f).to eq 30.0
|
74
88
|
end
|
75
89
|
end
|
90
|
+
|
91
|
+
describe "pdf" do
|
92
|
+
before do
|
93
|
+
@myfile = GenericFile.new(id: 'foo123')
|
94
|
+
@myfile.add_file(File.open(fixture_path + '/sufia/sufia_test4.pdf', 'rb').read, 'content', 'sufia_test4.pdf')
|
95
|
+
@myfile.apply_depositor_metadata('mjg36')
|
96
|
+
# characterize method saves
|
97
|
+
@myfile.characterize
|
98
|
+
@myfile.reload
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should return expected results after a save" do
|
102
|
+
expect(@myfile.file_size).to eq ['218882']
|
103
|
+
expect(@myfile.original_checksum).to eq ['5a2d761cab7c15b2b3bb3465ce64586d']
|
104
|
+
|
105
|
+
expect(@myfile.characterization_terms[:format_label]).to eq ["Portable Document Format"]
|
106
|
+
expect(@myfile.characterization_terms[:mime_type]).to eq "application/pdf"
|
107
|
+
expect(@myfile.characterization_terms[:file_size]).to eq ["218882"]
|
108
|
+
expect(@myfile.characterization_terms[:original_checksum]).to eq ["5a2d761cab7c15b2b3bb3465ce64586d"]
|
109
|
+
expect(@myfile.characterization_terms.keys).to include(:last_modified, :filename)
|
110
|
+
|
111
|
+
expect(@myfile.title).to include("Microsoft Word - sample.pdf.docx")
|
112
|
+
expect(@myfile.filename[0]).to eq 'sufia_test4.pdf'
|
113
|
+
|
114
|
+
@myfile.append_metadata
|
115
|
+
expect(@myfile.format_label).to eq ["Portable Document Format"]
|
116
|
+
expect(@myfile.title).to include("Microsoft Word - sample.pdf.docx")
|
117
|
+
|
118
|
+
expect(@myfile.full_text.content).to eq("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nMicrosoft Word - sample.pdf.docx\n\n\n \n \n\n \n\n \n\n \n\nThis PDF file was created using CutePDF. \n\nwww.cutepdf.com")
|
119
|
+
end
|
120
|
+
end
|
76
121
|
end
|
@@ -23,7 +23,7 @@ describe GenericFile, :type => :model do
|
|
23
23
|
describe "accessible_attributes" do
|
24
24
|
it "should have a list" do
|
25
25
|
expect(subject.accessible_attributes).to include(:part_of, :resource_type, :title, :creator, :contributor, :description,
|
26
|
-
:tag, :rights, :publisher, :date_created, :subject, :language, :identifier, :based_near, :related_url, :
|
26
|
+
:tag, :rights, :publisher, :date_created, :subject, :language, :identifier, :based_near, :related_url, :permissions_attributes)
|
27
27
|
end
|
28
28
|
|
29
29
|
it "should sanitize them" do
|
@@ -12,9 +12,6 @@ describe GenericFile, :type => :model do
|
|
12
12
|
before do
|
13
13
|
@transfer_to = FactoryGirl.find_or_create(:jill)
|
14
14
|
end
|
15
|
-
after do
|
16
|
-
@file.destroy
|
17
|
-
end
|
18
15
|
|
19
16
|
it "transfers the request" do
|
20
17
|
@file.on_behalf_of = @transfer_to.user_key
|
@@ -36,12 +33,6 @@ describe GenericFile, :type => :model do
|
|
36
33
|
end
|
37
34
|
end
|
38
35
|
|
39
|
-
subject { GenericFile.new }
|
40
|
-
|
41
|
-
before do
|
42
|
-
subject.apply_depositor_metadata('jcoyne')
|
43
|
-
end
|
44
|
-
|
45
36
|
describe '#to_s' do
|
46
37
|
it 'uses the provided titles' do
|
47
38
|
subject.title = ["Hello", "World"]
|
@@ -63,76 +54,84 @@ describe GenericFile, :type => :model do
|
|
63
54
|
|
64
55
|
describe "assign_pid" do
|
65
56
|
it "should use the noid id service" do
|
66
|
-
|
67
|
-
|
57
|
+
expect(Sufia::IdService).to receive(:mint)
|
58
|
+
subject.assign_pid
|
68
59
|
end
|
69
60
|
end
|
70
61
|
|
71
62
|
describe "mime type recognition" do
|
72
|
-
context "
|
73
|
-
|
74
|
-
subject.mime_type = 'image/jp2'
|
75
|
-
|
63
|
+
context "#image?" do
|
64
|
+
context "when image/jp2" do
|
65
|
+
before { subject.mime_type = 'image/jp2' }
|
66
|
+
it { should be_image }
|
76
67
|
end
|
77
|
-
|
78
|
-
subject.mime_type = 'image/jpg'
|
79
|
-
|
68
|
+
context "when image/jpg" do
|
69
|
+
before { subject.mime_type = 'image/jpg' }
|
70
|
+
it { should be_image }
|
80
71
|
end
|
81
|
-
|
82
|
-
subject.mime_type = 'image/png'
|
83
|
-
|
72
|
+
context "when image/png" do
|
73
|
+
before { subject.mime_type = 'image/png' }
|
74
|
+
it { should be_image }
|
84
75
|
end
|
85
|
-
|
86
|
-
subject.mime_type = 'image/tiff'
|
87
|
-
|
76
|
+
context "when image/tiff" do
|
77
|
+
before { subject.mime_type = 'image/tiff' }
|
78
|
+
it { should be_image }
|
88
79
|
end
|
89
80
|
end
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
end
|
81
|
+
|
82
|
+
describe "#pdf?" do
|
83
|
+
before { subject.mime_type = 'application/pdf' }
|
84
|
+
it { should be_pdf }
|
95
85
|
end
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
86
|
+
|
87
|
+
describe "#audio?" do
|
88
|
+
context "when x-wave" do
|
89
|
+
before { subject.mime_type = 'audio/x-wave' }
|
90
|
+
it { should be_audio }
|
91
|
+
end
|
92
|
+
context "when x-wav" do
|
93
|
+
before { subject.mime_type = 'audio/x-wav' }
|
94
|
+
it { should be_audio }
|
102
95
|
end
|
103
|
-
|
104
|
-
subject.mime_type = 'audio/mpeg'
|
105
|
-
|
106
|
-
subject.mime_type = 'audio/mp3'
|
107
|
-
expect(subject).to be_audio
|
96
|
+
context "when mpeg" do
|
97
|
+
before { subject.mime_type = 'audio/mpeg' }
|
98
|
+
it { should be_audio }
|
108
99
|
end
|
109
|
-
|
110
|
-
subject.mime_type = 'audio/
|
111
|
-
|
100
|
+
context "when mp3" do
|
101
|
+
before { subject.mime_type = 'audio/mp3' }
|
102
|
+
it { should be_audio }
|
103
|
+
end
|
104
|
+
context "when ogg" do
|
105
|
+
before { subject.mime_type = 'audio/ogg' }
|
106
|
+
it { should be_audio }
|
112
107
|
end
|
113
108
|
end
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
109
|
+
|
110
|
+
describe "#video?" do
|
111
|
+
context "should be true for avi" do
|
112
|
+
before { subject.mime_type = 'video/avi' }
|
113
|
+
it { should be_video }
|
118
114
|
end
|
119
|
-
|
120
|
-
|
121
|
-
|
115
|
+
|
116
|
+
context "should be true for webm" do
|
117
|
+
before { subject.mime_type = 'video/webm' }
|
118
|
+
it { should be_video }
|
119
|
+
end
|
120
|
+
context "should be true for mp4" do
|
121
|
+
before { subject.mime_type = 'video/mp4' }
|
122
|
+
it { should be_video }
|
122
123
|
end
|
123
|
-
|
124
|
-
subject.mime_type = 'video/
|
125
|
-
|
126
|
-
subject.mime_type = 'video/mpeg'
|
127
|
-
expect(subject).to be_video
|
124
|
+
context "should be true for mpeg" do
|
125
|
+
before { subject.mime_type = 'video/mpeg' }
|
126
|
+
it { should be_video }
|
128
127
|
end
|
129
|
-
|
130
|
-
subject.mime_type = 'video/quicktime'
|
131
|
-
|
128
|
+
context "should be true for quicktime" do
|
129
|
+
before { subject.mime_type = 'video/quicktime' }
|
130
|
+
it { should be_video }
|
132
131
|
end
|
133
|
-
|
134
|
-
subject.mime_type = 'application/mxf'
|
135
|
-
|
132
|
+
context "should be true for mxf" do
|
133
|
+
before { subject.mime_type = 'application/mxf' }
|
134
|
+
it { should be_video }
|
136
135
|
end
|
137
136
|
end
|
138
137
|
end
|
@@ -153,82 +152,42 @@ describe GenericFile, :type => :model do
|
|
153
152
|
|
154
153
|
end
|
155
154
|
|
156
|
-
describe "
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
expect(subject.
|
162
|
-
end
|
163
|
-
it "should have apply_depositor_metadata" do
|
164
|
-
expect(subject.rightsMetadata.edit_access).to eq(['jcoyne'])
|
165
|
-
expect(subject.depositor).to eq('jcoyne')
|
155
|
+
describe "#apply_depositor_metadata" do
|
156
|
+
before { subject.apply_depositor_metadata('jcoyne') }
|
157
|
+
|
158
|
+
it "should grant edit access and record the depositor" do
|
159
|
+
expect(subject.edit_users).to eq ['jcoyne']
|
160
|
+
expect(subject.depositor).to eq 'jcoyne'
|
166
161
|
end
|
162
|
+
end
|
163
|
+
|
164
|
+
describe "attributes" do
|
167
165
|
it "should have a set of permissions" do
|
168
166
|
subject.read_groups=['group1', 'group2']
|
169
167
|
subject.edit_users=['user1']
|
170
168
|
subject.read_users=['user2', 'user3']
|
171
|
-
expect(subject.permissions).to
|
169
|
+
expect(subject.permissions.map(&:to_hash)).to match_array [
|
170
|
+
{type: "group", access: "read", name: "group1"},
|
172
171
|
{type: "group", access: "read", name: "group2"},
|
173
|
-
{type: "
|
174
|
-
{type: "
|
175
|
-
{type: "
|
176
|
-
end
|
177
|
-
describe "updating permissions" do
|
178
|
-
it "should create new group permissions" do
|
179
|
-
subject.permissions = {new_group_name: {'group1'=>'read'}}
|
180
|
-
expect(subject.permissions).to eq([{type: "group", access: "read", name: "group1"},
|
181
|
-
{type: "user", access: "edit", name: "jcoyne"}])
|
182
|
-
end
|
183
|
-
it "should create new user permissions" do
|
184
|
-
subject.permissions = {new_user_name: {'user1'=>'read'}}
|
185
|
-
expect(subject.permissions).to eq([{type: "user", access: "read", name: "user1"},
|
186
|
-
{type: "user", access: "edit", name: "jcoyne"}])
|
187
|
-
end
|
188
|
-
it "should not replace existing groups" do
|
189
|
-
subject.permissions = {new_group_name: {'group1' => 'read'}}
|
190
|
-
subject.permissions = {new_group_name: {'group2' => 'read'}}
|
191
|
-
expect(subject.permissions).to eq([{type: "group", access: "read", name: "group1"},
|
192
|
-
{type: "group", access: "read", name: "group2"},
|
193
|
-
{type: "user", access: "edit", name: "jcoyne"}])
|
194
|
-
end
|
195
|
-
it "should not replace existing users" do
|
196
|
-
subject.permissions = {new_user_name:{'user1'=>'read'}}
|
197
|
-
subject.permissions = {new_user_name:{'user2'=>'read'}}
|
198
|
-
expect(subject.permissions).to eq([{type: "user", access: "read", name: "user1"},
|
199
|
-
{type: "user", access: "read", name: "user2"},
|
200
|
-
{type: "user", access: "edit", name: "jcoyne"}])
|
201
|
-
end
|
202
|
-
it "should update permissions on existing users" do
|
203
|
-
subject.permissions = {new_user_name:{'user1'=>'read'}}
|
204
|
-
subject.permissions = {user:{'user1'=>'edit'}}
|
205
|
-
expect(subject.permissions).to eq([{type: "user", access: "edit", name: "user1"},
|
206
|
-
{type: "user", access: "edit", name: "jcoyne"}])
|
207
|
-
end
|
208
|
-
it "should update permissions on existing groups" do
|
209
|
-
subject.permissions = {new_group_name:{'group1'=>'read'}}
|
210
|
-
subject.permissions = {group:{'group1'=>'edit'}}
|
211
|
-
expect(subject.permissions).to eq([{type: "group", access: "edit", name: "group1"},
|
212
|
-
{type: "user", access: "edit", name: "jcoyne"}])
|
213
|
-
end
|
172
|
+
{type: "person", access: "read", name: "user2"},
|
173
|
+
{type: "person", access: "read", name: "user3"},
|
174
|
+
{type: "person", access: "edit", name: "user1"}]
|
214
175
|
end
|
176
|
+
|
215
177
|
it "should have a characterization datastream" do
|
216
178
|
expect(subject.characterization).to be_kind_of FitsDatastream
|
217
179
|
end
|
218
|
-
|
219
|
-
expect(subject.descMetadata).to be_kind_of GenericFileRdfDatastream
|
220
|
-
end
|
180
|
+
|
221
181
|
it "should have content datastream" do
|
222
182
|
subject.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
223
183
|
expect(subject.content).to be_kind_of FileContentDatastream
|
224
184
|
end
|
225
185
|
end
|
226
|
-
|
227
|
-
|
186
|
+
|
187
|
+
describe "metadata" do
|
188
|
+
it "should have descriptive metadata" do
|
228
189
|
expect(subject).to respond_to(:relative_path)
|
229
190
|
expect(subject).to respond_to(:depositor)
|
230
|
-
end
|
231
|
-
it "should delegate methods to descriptive metadata" do
|
232
191
|
expect(subject).to respond_to(:related_url)
|
233
192
|
expect(subject).to respond_to(:based_near)
|
234
193
|
expect(subject).to respond_to(:part_of)
|
@@ -259,59 +218,54 @@ describe GenericFile, :type => :model do
|
|
259
218
|
expect(subject).to respond_to(:page_count)
|
260
219
|
end
|
261
220
|
it "should redefine to_param to make redis keys more recognizable" do
|
262
|
-
expect(subject.to_param).to eq
|
221
|
+
expect(subject.to_param).to eq subject.noid
|
263
222
|
end
|
223
|
+
|
264
224
|
describe "that have been saved" do
|
265
|
-
|
266
|
-
|
267
|
-
# Sufia.queue.should_receive(:push).once
|
268
|
-
# end
|
269
|
-
after(:each) do
|
270
|
-
unless subject.inner_object.class == ActiveFedora::UnsavedDigitalObject
|
271
|
-
begin
|
272
|
-
subject.delete
|
273
|
-
rescue ActiveFedora::ObjectNotFoundError
|
274
|
-
# do nothing
|
275
|
-
end
|
276
|
-
end
|
277
|
-
end
|
225
|
+
before { subject.apply_depositor_metadata('jcoyne') }
|
226
|
+
|
278
227
|
it "should have activity stream-related methods defined" do
|
279
|
-
subject.save
|
228
|
+
subject.save!
|
280
229
|
f = subject.reload
|
281
230
|
expect(f).to respond_to(:stream)
|
282
231
|
expect(f).to respond_to(:events)
|
283
232
|
expect(f).to respond_to(:create_event)
|
284
233
|
expect(f).to respond_to(:log_event)
|
285
234
|
end
|
235
|
+
|
286
236
|
it "should be able to set values via delegated methods" do
|
287
237
|
subject.related_url = ["http://example.org/"]
|
288
238
|
subject.creator = ["John Doe"]
|
289
239
|
subject.title = ["New work"]
|
290
240
|
subject.save
|
291
241
|
f = subject.reload
|
292
|
-
expect(f.related_url).to eq
|
293
|
-
expect(f.creator).to eq
|
294
|
-
expect(f.title).to eq
|
242
|
+
expect(f.related_url).to eq ["http://example.org/"]
|
243
|
+
expect(f.creator).to eq ["John Doe"]
|
244
|
+
expect(f.title).to eq ["New work"]
|
295
245
|
end
|
246
|
+
|
296
247
|
it "should be able to be added to w/o unexpected graph behavior" do
|
297
248
|
subject.creator = ["John Doe"]
|
298
249
|
subject.title = ["New work"]
|
299
|
-
subject.save
|
250
|
+
subject.save!
|
300
251
|
f = subject.reload
|
301
|
-
expect(f.creator).to eq
|
302
|
-
expect(f.title).to eq
|
252
|
+
expect(f.creator).to eq ["John Doe"]
|
253
|
+
expect(f.title).to eq ["New work"]
|
303
254
|
f.creator = ["Jane Doe"]
|
304
|
-
f.title
|
255
|
+
f.title += ["Newer work"]
|
305
256
|
f.save
|
306
257
|
f = subject.reload
|
307
|
-
expect(f.creator).to eq
|
308
|
-
|
258
|
+
expect(f.creator).to eq ["Jane Doe"]
|
259
|
+
# TODO: Is order important?
|
260
|
+
expect(f.title).to include("New work")
|
261
|
+
expect(f.title).to include("Newer work")
|
309
262
|
end
|
310
263
|
end
|
311
264
|
end
|
265
|
+
|
312
266
|
describe "to_solr" do
|
313
267
|
before do
|
314
|
-
allow(subject).to receive(:
|
268
|
+
allow(subject).to receive(:id).and_return('stubbed_pid')
|
315
269
|
subject.part_of = ["Arabiana"]
|
316
270
|
subject.contributor = ["Mohammad"]
|
317
271
|
subject.creator = ["Allah"]
|
@@ -332,28 +286,29 @@ describe GenericFile, :type => :model do
|
|
332
286
|
subject.format_label = ["JPEG Image"]
|
333
287
|
subject.full_text.content = 'abcxyz'
|
334
288
|
end
|
289
|
+
|
335
290
|
it "supports to_solr" do
|
336
291
|
local = subject.to_solr
|
337
|
-
expect(local[Solrizer.solr_name("
|
338
|
-
expect(local[Solrizer.solr_name("
|
339
|
-
expect(local[Solrizer.solr_name("
|
340
|
-
expect(local[Solrizer.solr_name("
|
341
|
-
expect(local[Solrizer.solr_name("
|
342
|
-
expect(local[Solrizer.solr_name("
|
343
|
-
expect(local[Solrizer.solr_name("
|
344
|
-
expect(local[Solrizer.solr_name("
|
345
|
-
expect(local[Solrizer.solr_name("
|
346
|
-
expect(local[Solrizer.solr_name("
|
347
|
-
expect(local["
|
348
|
-
expect(local[Solrizer.solr_name("
|
349
|
-
expect(local[Solrizer.solr_name("
|
350
|
-
expect(local[Solrizer.solr_name("
|
351
|
-
expect(local[Solrizer.solr_name("
|
352
|
-
expect(local[Solrizer.solr_name("
|
353
|
-
expect(local[Solrizer.solr_name("
|
292
|
+
expect(local[Solrizer.solr_name("part_of")]).to be_nil
|
293
|
+
expect(local[Solrizer.solr_name("date_uploaded")]).to be_nil
|
294
|
+
expect(local[Solrizer.solr_name("date_modified")]).to be_nil
|
295
|
+
expect(local[Solrizer.solr_name("date_uploaded", :stored_sortable, type: :date)]).to eq '2011-01-01T00:00:00Z'
|
296
|
+
expect(local[Solrizer.solr_name("date_modified", :stored_sortable, type: :date)]).to eq '2012-01-01T00:00:00Z'
|
297
|
+
expect(local[Solrizer.solr_name("rights")]).to eq ["Wide open, buddy."]
|
298
|
+
expect(local[Solrizer.solr_name("related_url")]).to eq ["http://example.org/TheWork/"]
|
299
|
+
expect(local[Solrizer.solr_name("contributor")]).to eq ["Mohammad"]
|
300
|
+
expect(local[Solrizer.solr_name("creator")]).to eq ["Allah"]
|
301
|
+
expect(local[Solrizer.solr_name("title")]).to eq ["The Work"]
|
302
|
+
expect(local[Solrizer.solr_name("title", :facetable)]).to eq ["The Work"]
|
303
|
+
expect(local[Solrizer.solr_name("description")]).to eq ["The work by Allah"]
|
304
|
+
expect(local[Solrizer.solr_name("publisher")]).to eq ["Vertigo Comics"]
|
305
|
+
expect(local[Solrizer.solr_name("subject")]).to eq ["Theology"]
|
306
|
+
expect(local[Solrizer.solr_name("language")]).to eq ["Arabic"]
|
307
|
+
expect(local[Solrizer.solr_name("date_created")]).to eq ["1200-01-01"]
|
308
|
+
expect(local[Solrizer.solr_name("resource_type")]).to eq ["Book"]
|
354
309
|
expect(local[Solrizer.solr_name("file_format")]).to eq "jpeg (JPEG Image)"
|
355
|
-
expect(local[Solrizer.solr_name("
|
356
|
-
expect(local[Solrizer.solr_name("
|
310
|
+
expect(local[Solrizer.solr_name("identifier")]).to eq ["urn:isbn:1234567890"]
|
311
|
+
expect(local[Solrizer.solr_name("based_near")]).to eq ["Medina, Saudi Arabia"]
|
357
312
|
expect(local[Solrizer.solr_name("mime_type")]).to eq ["image/jpeg"]
|
358
313
|
expect(local["noid_tsi"]).to eq 'stubbed_pid'
|
359
314
|
expect(local['all_text_timv']).to eq('abcxyz')
|
@@ -366,26 +321,23 @@ describe GenericFile, :type => :model do
|
|
366
321
|
end
|
367
322
|
it "should support setting and getting the relative_path value" do
|
368
323
|
subject.relative_path = "documents/research/NSF/2010"
|
369
|
-
expect(subject.relative_path).to eq
|
324
|
+
expect(subject.relative_path).to eq "documents/research/NSF/2010"
|
370
325
|
end
|
371
326
|
describe "create_thumbnail" do
|
372
327
|
before do
|
373
328
|
@f = GenericFile.new
|
374
329
|
@f.apply_depositor_metadata('mjg36')
|
375
330
|
end
|
376
|
-
after do
|
377
|
-
@f.delete
|
378
|
-
end
|
379
331
|
describe "with a video", if: Sufia.config.enable_ffmpeg do
|
380
332
|
before do
|
381
|
-
allow(@f).to
|
333
|
+
allow(@f).to receive(mime_type: 'video/quicktime') #Would get set by the characterization job
|
382
334
|
@f.add_file(File.open("#{fixture_path}/countdown.avi", 'rb'), 'content', 'countdown.avi')
|
383
335
|
@f.save
|
384
336
|
end
|
385
337
|
it "should make a png thumbnail" do
|
386
338
|
@f.create_thumbnail
|
387
|
-
expect(@f.thumbnail.content.size).to eq
|
388
|
-
expect(@f.thumbnail.
|
339
|
+
expect(@f.thumbnail.content.size).to eq 4768 # this is a bad test. I just want to show that it did something.
|
340
|
+
expect(@f.thumbnail.mime_type).to eq 'image/png'
|
389
341
|
end
|
390
342
|
end
|
391
343
|
end
|
@@ -407,84 +359,6 @@ describe GenericFile, :type => :model do
|
|
407
359
|
end
|
408
360
|
end
|
409
361
|
|
410
|
-
describe "audit" do
|
411
|
-
before do
|
412
|
-
u = FactoryGirl.find_or_create(:jill)
|
413
|
-
f = GenericFile.new
|
414
|
-
f.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
415
|
-
f.apply_depositor_metadata(u)
|
416
|
-
f.save!
|
417
|
-
@f = f.reload
|
418
|
-
end
|
419
|
-
it "should schedule a audit job for each datastream" do
|
420
|
-
s0 = double('zero')
|
421
|
-
expect(AuditJob).to receive(:new).with(@f.pid, 'descMetadata', "descMetadata.0").and_return(s0)
|
422
|
-
expect(Sufia.queue).to receive(:push).with(s0)
|
423
|
-
s1 = double('one')
|
424
|
-
expect(AuditJob).to receive(:new).with(@f.pid, 'DC', "DC1.0").and_return(s1)
|
425
|
-
expect(Sufia.queue).to receive(:push).with(s1)
|
426
|
-
s2 = double('two')
|
427
|
-
expect(AuditJob).to receive(:new).with(@f.pid, 'RELS-EXT', "RELS-EXT.0").and_return(s2)
|
428
|
-
expect(Sufia.queue).to receive(:push).with(s2)
|
429
|
-
s3 = double('three')
|
430
|
-
expect(AuditJob).to receive(:new).with(@f.pid, 'rightsMetadata', "rightsMetadata.0").and_return(s3)
|
431
|
-
expect(Sufia.queue).to receive(:push).with(s3)
|
432
|
-
s4 = double('four')
|
433
|
-
expect(AuditJob).to receive(:new).with(@f.pid, 'properties', "properties.0").and_return(s4)
|
434
|
-
expect(Sufia.queue).to receive(:push).with(s4)
|
435
|
-
s5 = double('five')
|
436
|
-
expect(AuditJob).to receive(:new).with(@f.pid, 'content', "content.0").and_return(s5)
|
437
|
-
expect(Sufia.queue).to receive(:push).with(s5)
|
438
|
-
@f.audit!
|
439
|
-
end
|
440
|
-
it "should log a failing audit" do
|
441
|
-
@f.datastreams.each { |ds| allow(ds).to receive(:dsChecksumValid).and_return(false) }
|
442
|
-
allow(GenericFile).to receive(:run_audit).and_return(double(:respose, pass:1, created_at: '2005-12-20', pid: 'foo:123', dsid: 'foo', version: '1'))
|
443
|
-
@f.audit!
|
444
|
-
expect(ChecksumAuditLog.all).to be_all { |cal| cal.pass == 0 }
|
445
|
-
end
|
446
|
-
it "should log a passing audit" do
|
447
|
-
allow(GenericFile).to receive(:run_audit).and_return(double(:respose, pass:1, created_at: '2005-12-20', pid: 'foo:123', dsid: 'foo', version: '1'))
|
448
|
-
@f.audit!
|
449
|
-
expect(ChecksumAuditLog.all).to be_all { |cal| cal.pass == 1 }
|
450
|
-
end
|
451
|
-
|
452
|
-
it "should return true on audit_status" do
|
453
|
-
expect(@f.audit_stat).to be_truthy
|
454
|
-
end
|
455
|
-
end
|
456
|
-
|
457
|
-
describe "run_audit" do
|
458
|
-
before do
|
459
|
-
@f = GenericFile.new
|
460
|
-
@f.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
461
|
-
@f.apply_depositor_metadata('mjg36')
|
462
|
-
@f.save!
|
463
|
-
@version = @f.datastreams['content'].versions.first
|
464
|
-
@old = ChecksumAuditLog.create(pid: @f.pid, dsid: @version.dsid, version: @version.versionID, pass: 1, created_at: 2.minutes.ago)
|
465
|
-
@new = ChecksumAuditLog.create(pid: @f.pid, dsid: @version.dsid, version: @version.versionID, pass: 0)
|
466
|
-
end
|
467
|
-
it "should not prune failed audits" do
|
468
|
-
expect(@version).to receive(:dsChecksumValid).and_return(true)
|
469
|
-
GenericFile.run_audit(@version)
|
470
|
-
|
471
|
-
expect(@version).to receive(:dsChecksumValid).and_return(false)
|
472
|
-
GenericFile.run_audit(@version)
|
473
|
-
|
474
|
-
expect(@version).to receive(:dsChecksumValid).and_return(false)
|
475
|
-
GenericFile.run_audit(@version)
|
476
|
-
|
477
|
-
expect(@version).to receive(:dsChecksumValid).and_return(true)
|
478
|
-
GenericFile.run_audit(@version)
|
479
|
-
|
480
|
-
expect(@version).to receive(:dsChecksumValid).and_return(false)
|
481
|
-
GenericFile.run_audit(@version)
|
482
|
-
|
483
|
-
expect(@f.logs(@version.dsid).map(&:pass)).to eq([0, 1, 0, 0, 1, 0, 1])
|
484
|
-
end
|
485
|
-
|
486
|
-
end
|
487
|
-
|
488
362
|
describe "#related_files" do
|
489
363
|
let!(:f1) do
|
490
364
|
GenericFile.new.tap do |f|
|
@@ -527,551 +401,180 @@ describe GenericFile, :type => :model do
|
|
527
401
|
end
|
528
402
|
end
|
529
403
|
end
|
404
|
+
|
530
405
|
describe "noid integration" do
|
531
|
-
|
532
|
-
|
533
|
-
@new_file.apply_depositor_metadata('mjg36')
|
534
|
-
@new_file.save
|
535
|
-
end
|
536
|
-
after(:all) do
|
537
|
-
@new_file.delete
|
538
|
-
end
|
539
|
-
it "should support the noid method" do
|
540
|
-
expect(@new_file).to respond_to(:noid)
|
541
|
-
end
|
406
|
+
subject { GenericFile.new(id: 'wd3763094') }
|
407
|
+
|
542
408
|
it "should return the expected identifier" do
|
543
|
-
expect(
|
409
|
+
expect(subject.noid).to eq 'wd3763094'
|
544
410
|
end
|
545
|
-
|
546
|
-
|
547
|
-
|
548
|
-
expect(Sufia::Noid.noidify(new_id)).to eq(noid)
|
549
|
-
end
|
550
|
-
end
|
551
|
-
describe "characterize" do
|
552
|
-
it "should return expected results when called", unless: $in_travis do
|
553
|
-
subject.add_file(File.open(fixture_path + '/world.png'), 'content', 'world.png')
|
554
|
-
subject.characterize
|
555
|
-
doc = Nokogiri::XML.parse(subject.characterization.content)
|
556
|
-
expect(doc.root.xpath('//ns:imageWidth/text()', {'ns'=>'http://hul.harvard.edu/ois/xml/ns/fits/fits_output'}).inner_text).to eq('50')
|
411
|
+
|
412
|
+
it "should have a tree-like URL" do
|
413
|
+
expect(subject.uri).to eq 'http://localhost:8983/fedora/rest/test/wd/37/63/09/wd3763094'
|
557
414
|
end
|
558
|
-
|
559
|
-
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
myfile.apply_depositor_metadata('mjg36')
|
564
|
-
# characterize method saves
|
565
|
-
myfile.characterize
|
566
|
-
@myfile = myfile.reload
|
567
|
-
end
|
568
|
-
after(:all) do
|
569
|
-
@myfile.destroy
|
570
|
-
end
|
571
|
-
it "should return expected results after a save" do
|
572
|
-
expect(@myfile.file_size).to eq(['218882'])
|
573
|
-
expect(@myfile.original_checksum).to eq(['5a2d761cab7c15b2b3bb3465ce64586d'])
|
574
|
-
end
|
575
|
-
it "should return a hash of all populated values from the characterization terminology" do
|
576
|
-
expect(@myfile.characterization_terms[:format_label]).to eq(["Portable Document Format"])
|
577
|
-
expect(@myfile.characterization_terms[:mime_type]).to eq("application/pdf")
|
578
|
-
expect(@myfile.characterization_terms[:file_size]).to eq(["218882"])
|
579
|
-
expect(@myfile.characterization_terms[:original_checksum]).to eq(["5a2d761cab7c15b2b3bb3465ce64586d"])
|
580
|
-
expect(@myfile.characterization_terms.keys).to include(:last_modified)
|
581
|
-
expect(@myfile.characterization_terms.keys).to include(:filename)
|
582
|
-
end
|
583
|
-
it "should append metadata from the characterization" do
|
584
|
-
expect(@myfile.title).to include("Microsoft Word - sample.pdf.docx")
|
585
|
-
expect(@myfile.filename[0]).to eq(@myfile.label)
|
586
|
-
end
|
587
|
-
it "should append each term only once" do
|
588
|
-
@myfile.append_metadata
|
589
|
-
expect(@myfile.format_label).to eq(["Portable Document Format"])
|
590
|
-
expect(@myfile.title).to include("Microsoft Word - sample.pdf.docx")
|
591
|
-
end
|
592
|
-
it 'includes extracted full-text content' do
|
593
|
-
expect(@myfile.full_text.content).to eq("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nMicrosoft Word - sample.pdf.docx\n\n\n \n \n\n \n\n \n\n \n\nThis PDF file was created using CutePDF. \n\nwww.cutepdf.com")
|
415
|
+
|
416
|
+
context "when a url is provided" do
|
417
|
+
let(:url) { 'http://localhost:8983/fedora/rest/test/wd/37/63/09/wd3763094' }
|
418
|
+
it "should be able to get the id" do
|
419
|
+
expect(GenericFile.uri_to_id(url)).to eq 'wd3763094'
|
594
420
|
end
|
595
421
|
end
|
596
422
|
end
|
597
|
-
|
598
|
-
|
599
|
-
subject.label = "My New Label"
|
600
|
-
expect(subject.inner_object.label).to eq("My New Label")
|
601
|
-
end
|
602
|
-
end
|
603
|
-
context "with rightsMetadata" do
|
423
|
+
|
424
|
+
context "with access control metadata" do
|
604
425
|
subject do
|
605
|
-
|
606
|
-
|
607
|
-
|
608
|
-
|
426
|
+
GenericFile.new do |m|
|
427
|
+
m.apply_depositor_metadata('jcoyne')
|
428
|
+
m.permissions_attributes = [{type: 'person', access: 'read', name: "person1"},
|
429
|
+
{type: 'person', access: 'read', name: "person2"},
|
430
|
+
{type: 'group', access: 'read', name: "group-6"},
|
431
|
+
{type: 'group', access: 'read', name: "group-7"},
|
432
|
+
{type: 'group', access: 'edit', name: "group-8"}]
|
433
|
+
end
|
609
434
|
end
|
435
|
+
|
610
436
|
it "should have read groups accessor" do
|
611
|
-
expect(subject.read_groups).to eq
|
437
|
+
expect(subject.read_groups).to eq ['group-6', 'group-7']
|
612
438
|
end
|
439
|
+
|
613
440
|
it "should have read groups string accessor" do
|
614
|
-
expect(subject.read_groups_string).to eq
|
441
|
+
expect(subject.read_groups_string).to eq 'group-6, group-7'
|
615
442
|
end
|
443
|
+
|
616
444
|
it "should have read groups writer" do
|
617
445
|
subject.read_groups = ['group-2', 'group-3']
|
618
|
-
expect(subject.
|
619
|
-
expect(subject.rightsMetadata.users).to eq({"person1"=>"read","person2"=>"read", 'jcoyne' => 'edit'})
|
446
|
+
expect(subject.read_groups).to eq ['group-2', 'group-3']
|
620
447
|
end
|
621
448
|
|
622
449
|
it "should have read groups string writer" do
|
623
450
|
subject.read_groups_string = 'umg/up.dlt.staff, group-3'
|
624
|
-
expect(subject.
|
625
|
-
expect(subject.
|
451
|
+
expect(subject.read_groups).to eq ['umg/up.dlt.staff', 'group-3']
|
452
|
+
expect(subject.edit_groups).to eq ['group-8']
|
453
|
+
expect(subject.read_users).to eq ['person1', 'person2']
|
454
|
+
expect(subject.edit_users).to eq ['jcoyne']
|
626
455
|
end
|
456
|
+
|
627
457
|
it "should only revoke eligible groups" do
|
628
458
|
subject.set_read_groups(['group-2', 'group-3'], ['group-6'])
|
629
459
|
# 'group-7' is not eligible to be revoked
|
630
|
-
expect(subject.
|
631
|
-
expect(subject.
|
460
|
+
expect(subject.read_groups).to match_array ['group-2', 'group-3', 'group-7']
|
461
|
+
expect(subject.edit_groups).to eq ['group-8']
|
462
|
+
expect(subject.read_users).to match_array ['person1', 'person2']
|
463
|
+
expect(subject.edit_users).to eq ['jcoyne']
|
632
464
|
end
|
633
465
|
end
|
466
|
+
|
634
467
|
describe "permissions validation" do
|
635
|
-
|
636
|
-
|
637
|
-
|
638
|
-
|
639
|
-
|
640
|
-
end
|
641
|
-
before(:all) do
|
642
|
-
@rights_xml = <<-RIGHTS
|
643
|
-
<rightsMetadata xmlns="http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1" version="0.1">
|
644
|
-
<copyright>
|
645
|
-
<human></human>
|
646
|
-
<machine></machine>
|
647
|
-
</copyright>
|
648
|
-
<access type="read">
|
649
|
-
<human></human>
|
650
|
-
<machine></machine>
|
651
|
-
</access>
|
652
|
-
<access type="read">
|
653
|
-
<human></human>
|
654
|
-
<machine>
|
655
|
-
<person>mjg36</person>
|
656
|
-
</machine>
|
657
|
-
</access>
|
658
|
-
<access type="edit">
|
659
|
-
<human></human>
|
660
|
-
<machine></machine>
|
661
|
-
</access>
|
662
|
-
<embargo>
|
663
|
-
<human></human>
|
664
|
-
<machine></machine>
|
665
|
-
</embargo>
|
666
|
-
</rightsMetadata>
|
667
|
-
RIGHTS
|
668
|
-
end
|
669
|
-
it "should work via permissions=()" do
|
670
|
-
@file.permissions = {user: {'mjg36' => 'read'}}
|
671
|
-
expect { @file.save }.not_to raise_error
|
672
|
-
expect(@file).to be_new_record
|
673
|
-
expect(@file.errors).to include(:edit_users)
|
674
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
675
|
-
expect(@file).to_not be_valid
|
676
|
-
end
|
677
|
-
it "should work via update_attributes" do
|
678
|
-
# automatically triggers save
|
679
|
-
expect { @file.update_attributes(read_users_string: 'mjg36') }.not_to raise_error
|
680
|
-
expect(@file).to be_new_record
|
681
|
-
expect(@file.errors).to include(:edit_users)
|
682
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
683
|
-
expect(@file).to_not be_valid
|
684
|
-
end
|
685
|
-
it "should work via update_indexed_attributes" do
|
686
|
-
@rightsmd.update_indexed_attributes([:edit_access, :person] => '')
|
687
|
-
expect { @file.save }.not_to raise_error
|
688
|
-
expect(@file).to be_new_record
|
689
|
-
expect(@file.errors).to include(:edit_users)
|
690
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
691
|
-
expect(@file).to_not be_valid
|
692
|
-
end
|
693
|
-
it "should work via permissions()" do
|
694
|
-
@rightsmd.permissions({person: "mjg36"}, "read")
|
695
|
-
expect { @file.save }.not_to raise_error
|
696
|
-
expect(@file).to be_new_record
|
697
|
-
expect(@file.errors).to include(:edit_users)
|
698
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
699
|
-
expect(@file).to_not be_valid
|
700
|
-
end
|
701
|
-
it "should work via update_permissions()" do
|
702
|
-
@rightsmd.update_permissions({"person" => {"mjg36" => "read"}})
|
703
|
-
expect { @file.save }.not_to raise_error
|
704
|
-
expect(@file).to be_new_record
|
705
|
-
expect(@file.errors).to include(:edit_users)
|
706
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
707
|
-
expect(@file).to_not be_valid
|
708
|
-
end
|
709
|
-
it "should work via content=()" do
|
710
|
-
@rightsmd.content=(@rights_xml)
|
711
|
-
expect { @file.save }.not_to raise_error
|
712
|
-
expect(@file).to be_new_record
|
713
|
-
expect(@file.errors).to include(:edit_users)
|
714
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
715
|
-
expect(@file).to_not be_valid
|
716
|
-
end
|
717
|
-
it "should work via ng_xml=()" do
|
718
|
-
@rightsmd.ng_xml=(Nokogiri::XML::Document.parse(@rights_xml))
|
719
|
-
expect { @file.save }.not_to raise_error
|
720
|
-
expect(@file).to be_new_record
|
721
|
-
expect(@file.errors).to include(:edit_users)
|
722
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
723
|
-
expect(@file).to_not be_valid
|
468
|
+
before { subject.apply_depositor_metadata('mjg36') }
|
469
|
+
|
470
|
+
context "when the depositor does not have edit access" do
|
471
|
+
before do
|
472
|
+
subject.permissions = [ Hydra::AccessControls::Permission.new(type: 'person', name: 'mjg36', access: 'read')]
|
724
473
|
end
|
725
|
-
it "should
|
726
|
-
|
727
|
-
expect
|
728
|
-
expect(@file).to be_new_record
|
729
|
-
expect(@file.errors).to include(:edit_users)
|
730
|
-
expect(@file.errors[:edit_users]).to include('Depositor must have edit access')
|
731
|
-
expect(@file).to_not be_valid
|
474
|
+
it "should be invalid" do
|
475
|
+
expect(subject).to_not be_valid
|
476
|
+
expect(subject.errors[:edit_users]).to include('Depositor must have edit access')
|
732
477
|
end
|
733
478
|
end
|
734
|
-
|
735
|
-
|
736
|
-
|
737
|
-
|
738
|
-
|
739
|
-
|
740
|
-
|
741
|
-
before(:all) do
|
742
|
-
@rights_xml = <<-RIGHTS
|
743
|
-
<rightsMetadata xmlns="http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1" version="0.1">
|
744
|
-
<copyright>
|
745
|
-
<human></human>
|
746
|
-
<machine></machine>
|
747
|
-
</copyright>
|
748
|
-
<access type="read">
|
749
|
-
<human></human>
|
750
|
-
<machine></machine>
|
751
|
-
</access>
|
752
|
-
<access type="read">
|
753
|
-
<human></human>
|
754
|
-
<machine></machine>
|
755
|
-
</access>
|
756
|
-
<access type="edit">
|
757
|
-
<human></human>
|
758
|
-
<machine>
|
759
|
-
<group>public</group>
|
760
|
-
</machine>
|
761
|
-
</access>
|
762
|
-
<embargo>
|
763
|
-
<human></human>
|
764
|
-
<machine></machine>
|
765
|
-
</embargo>
|
766
|
-
</rightsMetadata>
|
767
|
-
RIGHTS
|
768
|
-
end
|
769
|
-
it "should work via permissions=()" do
|
770
|
-
@file.permissions = {group: {'public' => 'edit'}}
|
771
|
-
expect { @file.save }.not_to raise_error
|
772
|
-
expect(@file).to be_new_record
|
773
|
-
expect(@file.errors).to include(:edit_groups)
|
774
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
775
|
-
expect(@file).to_not be_valid
|
776
|
-
end
|
777
|
-
it "should work via update_attributes" do
|
778
|
-
# automatically triggers save
|
779
|
-
expect { @file.update_attributes(edit_groups_string: 'public') }.not_to raise_error
|
780
|
-
expect(@file).to be_new_record
|
781
|
-
expect(@file.errors).to include(:edit_groups)
|
782
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
783
|
-
expect(@file).to_not be_valid
|
784
|
-
end
|
785
|
-
it "should work via update_indexed_attributes" do
|
786
|
-
@rightsmd.update_indexed_attributes([:edit_access, :group] => 'public')
|
787
|
-
expect { @file.save }.not_to raise_error
|
788
|
-
expect(@file).to be_new_record
|
789
|
-
expect(@file.errors).to include(:edit_groups)
|
790
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
791
|
-
expect(@file).to_not be_valid
|
792
|
-
end
|
793
|
-
it "should work via permissions()" do
|
794
|
-
@rightsmd.permissions({group: "public"}, "edit")
|
795
|
-
expect { @file.save }.not_to raise_error
|
796
|
-
expect(@file).to be_new_record
|
797
|
-
expect(@file.errors).to include(:edit_groups)
|
798
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
799
|
-
expect(@file).to_not be_valid
|
800
|
-
end
|
801
|
-
it "should work via update_permissions()" do
|
802
|
-
@rightsmd.update_permissions({"group" => {"public" => "edit"}})
|
803
|
-
expect { @file.save }.not_to raise_error
|
804
|
-
expect(@file).to be_new_record
|
805
|
-
expect(@file.errors).to include(:edit_groups)
|
806
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
807
|
-
expect(@file).to_not be_valid
|
808
|
-
end
|
809
|
-
it "should work via content=()" do
|
810
|
-
@rightsmd.content=(@rights_xml)
|
811
|
-
expect { @file.save }.not_to raise_error
|
812
|
-
expect(@file).to be_new_record
|
813
|
-
expect(@file.errors).to include(:edit_groups)
|
814
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
815
|
-
expect(@file).to_not be_valid
|
816
|
-
end
|
817
|
-
it "should work via ng_xml=()" do
|
818
|
-
@rightsmd.ng_xml=(Nokogiri::XML::Document.parse(@rights_xml))
|
819
|
-
expect { @file.save }.not_to raise_error
|
820
|
-
expect(@file).to be_new_record
|
821
|
-
expect(@file.errors).to include(:edit_groups)
|
822
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
823
|
-
expect(@file).to_not be_valid
|
824
|
-
end
|
825
|
-
it "should work via update_values()" do
|
826
|
-
@rightsmd.update_values([:edit_access, :group] => 'public')
|
827
|
-
expect { @file.save }.not_to raise_error
|
828
|
-
expect(@file).to be_new_record
|
829
|
-
expect(@file.errors).to include(:edit_groups)
|
830
|
-
expect(@file.errors[:edit_groups]).to include('Public cannot have edit access')
|
831
|
-
expect(@file).to_not be_valid
|
479
|
+
|
480
|
+
context "when the public has edit access" do
|
481
|
+
before { subject.edit_groups = ['public'] }
|
482
|
+
|
483
|
+
it "should be invalid" do
|
484
|
+
expect(subject).to_not be_valid
|
485
|
+
expect(subject.errors[:edit_groups]).to include('Public cannot have edit access')
|
832
486
|
end
|
833
487
|
end
|
834
|
-
|
835
|
-
|
836
|
-
|
837
|
-
|
838
|
-
|
839
|
-
|
840
|
-
|
841
|
-
before(:all) do
|
842
|
-
@rights_xml = <<-RIGHTS
|
843
|
-
<rightsMetadata xmlns="http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1" version="0.1">
|
844
|
-
<copyright>
|
845
|
-
<human></human>
|
846
|
-
<machine></machine>
|
847
|
-
</copyright>
|
848
|
-
<access type="read">
|
849
|
-
<human></human>
|
850
|
-
<machine></machine>
|
851
|
-
</access>
|
852
|
-
<access type="read">
|
853
|
-
<human></human>
|
854
|
-
<machine></machine>
|
855
|
-
</access>
|
856
|
-
<access type="edit">
|
857
|
-
<human></human>
|
858
|
-
<machine>
|
859
|
-
<group>registered</group>
|
860
|
-
</machine>
|
861
|
-
</access>
|
862
|
-
<embargo>
|
863
|
-
<human></human>
|
864
|
-
<machine></machine>
|
865
|
-
</embargo>
|
866
|
-
</rightsMetadata>
|
867
|
-
RIGHTS
|
868
|
-
end
|
869
|
-
it "should work via permissions=()" do
|
870
|
-
@file.permissions = {group: {'registered' => 'edit'}}
|
871
|
-
expect { @file.save }.not_to raise_error
|
872
|
-
expect(@file).to be_new_record
|
873
|
-
expect(@file.errors).to include(:edit_groups)
|
874
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
875
|
-
expect(@file).to_not be_valid
|
876
|
-
end
|
877
|
-
it "should work via update_attributes" do
|
878
|
-
# automatically triggers save
|
879
|
-
expect { @file.update_attributes(edit_groups_string: 'registered') }.not_to raise_error
|
880
|
-
expect(@file).to be_new_record
|
881
|
-
expect(@file.errors).to include(:edit_groups)
|
882
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
883
|
-
expect(@file).to_not be_valid
|
884
|
-
end
|
885
|
-
it "should work via update_indexed_attributes" do
|
886
|
-
@rightsmd.update_indexed_attributes([:edit_access, :group] => 'registered')
|
887
|
-
expect { @file.save }.not_to raise_error
|
888
|
-
expect(@file).to be_new_record
|
889
|
-
expect(@file.errors).to include(:edit_groups)
|
890
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
891
|
-
expect(@file).to_not be_valid
|
892
|
-
end
|
893
|
-
it "should work via permissions()" do
|
894
|
-
@rightsmd.permissions({group: "registered"}, "edit")
|
895
|
-
expect { @file.save }.not_to raise_error
|
896
|
-
expect(@file).to be_new_record
|
897
|
-
expect(@file.errors).to include(:edit_groups)
|
898
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
899
|
-
expect(@file).to_not be_valid
|
900
|
-
end
|
901
|
-
it "should work via update_permissions()" do
|
902
|
-
@rightsmd.update_permissions({"group" => {"registered" => "edit"}})
|
903
|
-
expect { @file.save }.not_to raise_error
|
904
|
-
expect(@file).to be_new_record
|
905
|
-
expect(@file.errors).to include(:edit_groups)
|
906
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
907
|
-
expect(@file).to_not be_valid
|
908
|
-
end
|
909
|
-
it "should work via content=()" do
|
910
|
-
@rightsmd.content=(@rights_xml)
|
911
|
-
expect { @file.save }.not_to raise_error
|
912
|
-
expect(@file).to be_new_record
|
913
|
-
expect(@file.errors).to include(:edit_groups)
|
914
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
915
|
-
expect(@file).to_not be_valid
|
916
|
-
end
|
917
|
-
it "should work via ng_xml=()" do
|
918
|
-
@rightsmd.ng_xml=(Nokogiri::XML::Document.parse(@rights_xml))
|
919
|
-
expect { @file.save }.not_to raise_error
|
920
|
-
expect(@file).to be_new_record
|
921
|
-
expect(@file.errors).to include(:edit_groups)
|
922
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
923
|
-
expect(@file).to_not be_valid
|
924
|
-
end
|
925
|
-
it "should work via update_values()" do
|
926
|
-
@rightsmd.update_values([:edit_access, :group] => 'registered')
|
927
|
-
expect { @file.save }.not_to raise_error
|
928
|
-
expect(@file).to be_new_record
|
929
|
-
expect(@file.errors).to include(:edit_groups)
|
930
|
-
expect(@file.errors[:edit_groups]).to include('Registered cannot have edit access')
|
931
|
-
expect(@file).to_not be_valid
|
488
|
+
|
489
|
+
context "when registered has edit access" do
|
490
|
+
before { subject.edit_groups = ['registered'] }
|
491
|
+
|
492
|
+
it "should be invalid" do
|
493
|
+
expect(subject).to_not be_valid
|
494
|
+
expect(subject.errors[:edit_groups]).to include('Registered cannot have edit access')
|
932
495
|
end
|
933
496
|
end
|
497
|
+
|
934
498
|
context "everything is copacetic" do
|
935
|
-
|
936
|
-
|
937
|
-
@file.apply_depositor_metadata('mjg36')
|
938
|
-
@file.read_groups = ['public']
|
939
|
-
@rightsmd = @file.rightsMetadata
|
940
|
-
end
|
941
|
-
after(:each) do
|
942
|
-
@file.delete
|
943
|
-
end
|
944
|
-
before(:all) do
|
945
|
-
@rights_xml = <<-RIGHTS
|
946
|
-
<rightsMetadata xmlns="http://hydra-collab.stanford.edu/schemas/rightsMetadata/v1" version="0.1">
|
947
|
-
<copyright>
|
948
|
-
<human></human>
|
949
|
-
<machine></machine>
|
950
|
-
</copyright>
|
951
|
-
<access type="read">
|
952
|
-
<human></human>
|
953
|
-
<machine>
|
954
|
-
<group>public</group>
|
955
|
-
<group>registered</group>
|
956
|
-
</machine>
|
957
|
-
</access>
|
958
|
-
<access type="edit">
|
959
|
-
<human></human>
|
960
|
-
<machine>
|
961
|
-
<person>mjg36</person>
|
962
|
-
</machine>
|
963
|
-
</access>
|
964
|
-
<embargo>
|
965
|
-
<human></human>
|
966
|
-
<machine></machine>
|
967
|
-
</embargo>
|
968
|
-
</rightsMetadata>
|
969
|
-
RIGHTS
|
970
|
-
end
|
971
|
-
it "should work via permissions=()" do
|
972
|
-
@file.permissions = {group: {'registered' => 'read'}}
|
973
|
-
expect { @file.save }.not_to raise_error
|
974
|
-
expect(@file).to_not be_new_record
|
975
|
-
expect(@file.errors).to be_empty
|
976
|
-
expect(@file).to be_valid
|
977
|
-
end
|
978
|
-
it "should work via update_attributes" do
|
979
|
-
# automatically triggers save
|
980
|
-
expect { @file.update_attributes(read_groups_string: 'registered') }.not_to raise_error
|
981
|
-
expect(@file).to_not be_new_record
|
982
|
-
expect(@file.errors).to be_empty
|
983
|
-
expect(@file).to be_valid
|
984
|
-
end
|
985
|
-
it "should work via update_indexed_attributes" do
|
986
|
-
@rightsmd.update_indexed_attributes([:read_access, :group] => 'registered')
|
987
|
-
expect { @file.save }.not_to raise_error
|
988
|
-
expect(@file).to_not be_new_record
|
989
|
-
expect(@file.errors).to be_empty
|
990
|
-
expect(@file).to be_valid
|
991
|
-
end
|
992
|
-
it "should work via permissions()" do
|
993
|
-
@rightsmd.permissions({group: "registered"}, "read")
|
994
|
-
expect { @file.save }.not_to raise_error
|
995
|
-
expect(@file).to_not be_new_record
|
996
|
-
expect(@file.errors).to be_empty
|
997
|
-
expect(@file).to be_valid
|
998
|
-
end
|
999
|
-
it "should work via update_permissions()" do
|
1000
|
-
@rightsmd.update_permissions({"group" => {"registered" => "read"}})
|
1001
|
-
expect { @file.save }.not_to raise_error
|
1002
|
-
expect(@file).to_not be_new_record
|
1003
|
-
expect(@file.errors).to be_empty
|
1004
|
-
expect(@file).to be_valid
|
1005
|
-
end
|
1006
|
-
it "should work via content=()" do
|
1007
|
-
@rightsmd.content=(@rights_xml)
|
1008
|
-
expect { @file.save }.not_to raise_error
|
1009
|
-
expect(@file).to_not be_new_record
|
1010
|
-
expect(@file.errors).to be_empty
|
1011
|
-
expect(@file).to be_valid
|
1012
|
-
end
|
1013
|
-
it "should work via ng_xml=()" do
|
1014
|
-
@rightsmd.ng_xml=(Nokogiri::XML::Document.parse(@rights_xml))
|
1015
|
-
expect { @file.save }.not_to raise_error
|
1016
|
-
expect(@file).to_not be_new_record
|
1017
|
-
expect(@file.errors).to be_empty
|
1018
|
-
expect(@file).to be_valid
|
1019
|
-
end
|
1020
|
-
it "should work via update_values()" do
|
1021
|
-
@rightsmd.update_values([:read_access, :group] => 'registered')
|
1022
|
-
expect { @file.save }.not_to raise_error
|
1023
|
-
expect(@file).to_not be_new_record
|
1024
|
-
expect(@file.errors).to be_empty
|
1025
|
-
expect(@file).to be_valid
|
499
|
+
it "should be valid" do
|
500
|
+
expect(subject).to be_valid
|
1026
501
|
end
|
1027
502
|
end
|
1028
503
|
end
|
504
|
+
|
1029
505
|
describe "file content validation" do
|
1030
506
|
context "when file contains a virus" do
|
1031
507
|
let(:f) { File.new(fixture_path + '/small_file.txt') }
|
1032
|
-
|
1033
|
-
|
508
|
+
|
509
|
+
before do
|
510
|
+
subject.add_file(f, 'content', 'small_file.txt')
|
511
|
+
subject.apply_depositor_metadata('mjg36')
|
1034
512
|
end
|
513
|
+
|
1035
514
|
it "populates the errors hash during validation" do
|
1036
515
|
allow(Sufia::GenericFile::Actor).to receive(:virus_check).and_raise(Sufia::VirusFoundError, "A virus was found in #{f.path}: EL CRAPO VIRUS")
|
1037
|
-
subject.add_file(f, 'content', 'small_file.txt')
|
1038
516
|
subject.save
|
1039
517
|
expect(subject).not_to be_persisted
|
1040
518
|
expect(subject.errors.messages).to eq(base: ["A virus was found in #{f.path}: EL CRAPO VIRUS"])
|
1041
519
|
end
|
520
|
+
|
1042
521
|
it "does not save a new version of a GenericFile" do
|
1043
|
-
subject.
|
1044
|
-
subject.save
|
522
|
+
subject.save!
|
1045
523
|
allow(Sufia::GenericFile::Actor).to receive(:virus_check).and_raise(Sufia::VirusFoundError)
|
1046
524
|
subject.add_file(File.new(fixture_path + '/sufia_generic_stub.txt') , 'content', 'sufia_generic_stub.txt')
|
1047
525
|
subject.save
|
1048
|
-
expect(subject.reload.content.content).to eq
|
526
|
+
expect(subject.reload.content.content).to eq "small\n"
|
1049
527
|
end
|
1050
528
|
end
|
1051
529
|
end
|
1052
530
|
|
1053
|
-
describe "
|
531
|
+
describe "#remove_blank_assertions" do
|
1054
532
|
before do
|
1055
|
-
subject.
|
533
|
+
subject.title = ["foo"]
|
534
|
+
subject.description = [""]
|
535
|
+
subject.remove_blank_assertions
|
1056
536
|
end
|
1057
|
-
|
1058
|
-
|
537
|
+
|
538
|
+
it "should only change title" do
|
539
|
+
expect(subject.title).to eq(["foo"])
|
540
|
+
expect(subject.description).to be_empty
|
1059
541
|
end
|
1060
|
-
|
1061
|
-
|
1062
|
-
|
1063
|
-
|
1064
|
-
|
1065
|
-
|
1066
|
-
|
1067
|
-
|
1068
|
-
|
1069
|
-
expect(f1.to_solr[mime_type_key]).to eq([f1.mime_type])
|
1070
|
-
expect(f1.to_solr[title_key]).to_not eq(f2.title)
|
1071
|
-
f2.save
|
1072
|
-
expect(f2.to_solr[mime_type_key]).to eq([f1.mime_type])
|
1073
|
-
expect(f2.to_solr[title_key]).to eq(f2.title)
|
542
|
+
end
|
543
|
+
|
544
|
+
describe "to_solr record" do
|
545
|
+
let(:depositor) { 'jcoyne' }
|
546
|
+
subject do
|
547
|
+
GenericFile.new.tap do |f|
|
548
|
+
f.apply_depositor_metadata(depositor)
|
549
|
+
f.save
|
550
|
+
end
|
1074
551
|
end
|
552
|
+
let(:depositor_key) { Solrizer.solr_name("depositor") }
|
553
|
+
let(:title_key) { Solrizer.solr_name("title", :stored_searchable, type: :string) }
|
554
|
+
let(:title) { ["abc123"] }
|
555
|
+
let(:no_terms) { GenericFile.find(subject.id).to_solr }
|
556
|
+
let(:terms) {
|
557
|
+
file = GenericFile.find(subject.id)
|
558
|
+
file.title = title
|
559
|
+
file.save
|
560
|
+
file.to_solr
|
561
|
+
}
|
562
|
+
|
563
|
+
context "without terms" do
|
564
|
+
specify "title is nil" do
|
565
|
+
expect(no_terms[title_key]).to be_nil
|
566
|
+
end
|
567
|
+
end
|
568
|
+
|
569
|
+
context "with terms" do
|
570
|
+
specify "depositor is set" do
|
571
|
+
expect(terms[depositor_key].first).to eql(depositor)
|
572
|
+
end
|
573
|
+
specify "title is set" do
|
574
|
+
expect(terms[title_key]).to eql(title)
|
575
|
+
end
|
576
|
+
end
|
577
|
+
|
1075
578
|
end
|
1076
579
|
|
1077
580
|
describe "public?" do
|