diff --git a/.rubocop.yml b/.rubocop.yml index e2e8472..c60b001 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -62,6 +62,7 @@ RSpec/DescribeClass: RSpec/ExampleLength: Exclude: + - 'spec/controllers/pre_ingest_works_controller_spec.rb' - 'spec/zizia/hyrax/hyrax_basic_metadata_mapper_spec.rb' - 'spec/integration/import_hyrax_csv.rb' - 'spec/integration/csv_import_detail_spec.rb' diff --git a/app/assets/javascripts/zizia/zizia.js b/app/assets/javascripts/zizia/zizia.js index 465937d..69a094f 100644 --- a/app/assets/javascripts/zizia/zizia.js +++ b/app/assets/javascripts/zizia/zizia.js @@ -1,6 +1,48 @@ var Zizia = { - displayUploadedFile: function() { + displayUploadedFile: function () { var DisplayUploadedFile = require('zizia/DisplayUploadedFile') new DisplayUploadedFile().display() + }, + checkStatuses: function (options) { + var results = [] + // Go through the list of thumbnails for the work based + // on the deduplicationKey + options.thumbnails.forEach(function (thumbnail) { + $.ajax({ + type: 'HEAD', + url: thumbnail, + complete: function (xhr) { + // Request only the headers from the thumbnail url + // push the statuses into an array + results.push(xhr.getResponseHeader('status')) + // See how many urls are not returning 200 + var missingThumbnailCount = results.filter( + function (status) { + if (status !== '200 OK') { return true } + }).length + // If there are any not returning 200, the work is still being processed + if (missingThumbnailCount > 0) { + + } else { + Zizia.addSuccessClasses(options) + } + } + }) + }) + }, + displayWorkStatus: function () { + $('[id^=work-status]').each(function () { + var deduplicationKey = $(this)[0].id.split('work-status-')[1] + $.get('/pre_ingest_works/thumbnails/' + deduplicationKey, function (data) { + data.deduplicationKey = deduplicationKey + Zizia.checkStatuses(data) + }) + }) + }, + addSuccessClasses: function (options) { + $('#work-status-' + options.deduplicationKey + ' > span').removeClass('status-unknown') + $('#work-status-' + options.deduplicationKey + ' > span').removeClass('glyphicon-question-sign') + $('#work-status-' + options.deduplicationKey + ' > span').addClass('text-success') + $('#work-status-' + options.deduplicationKey + ' > span').addClass('glyphicon-ok-sign') } } diff --git a/app/controllers/zizia/pre_ingest_works_controller.rb b/app/controllers/zizia/pre_ingest_works_controller.rb new file mode 100644 index 0000000..3e6f323 --- /dev/null +++ b/app/controllers/zizia/pre_ingest_works_controller.rb @@ -0,0 +1,32 @@ +# frozen_string_literal: true + +module Zizia + class PreIngestWorksController < ::ApplicationController + before_action :merge_abilities + load_and_authorize_resource + + def thumbnails + pre_ingest_work = Zizia::PreIngestWork.where(deduplication_key: pre_ingest_works_params[:deduplication_key]).first + + @thumbnails = if pre_ingest_work + pre_ingest_work.thumbnails + else + [] + end + + respond_to do |format| + format.json { render json: { thumbnails: @thumbnails } } + end + end + + private + + def pre_ingest_works_params + params.permit(:deduplication_key, :format) + end + + def merge_abilities + current_ability.merge(Zizia::Ability.new(current_user)) + end + end +end diff --git a/app/models/zizia/ability.rb b/app/models/zizia/ability.rb new file mode 100644 index 0000000..8fdb2ea --- /dev/null +++ b/app/models/zizia/ability.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true +module Zizia + class Ability + include Hydra::Ability + include Hyrax::Ability + self.ability_logic += [:everyone_can_create_curation_concerns] + + # Define any customized permissions here. + def custom_permissions + can :manage, Zizia::CsvImport if current_user.admin? + can :manage, Zizia::CsvImportDetail if current_user.admin? + can :manage, Zizia::PreIngestWork if current_user.admin? + end + end +end diff --git a/app/models/zizia/csv_import_detail.rb b/app/models/zizia/csv_import_detail.rb index 37c4bc6..b3a3e8d 100644 --- a/app/models/zizia/csv_import_detail.rb +++ b/app/models/zizia/csv_import_detail.rb @@ -9,10 +9,6 @@ class CsvImportDetail < ::ApplicationRecord has_many :pre_ingest_works has_many :pre_ingest_files, through: :pre_ingest_works - def status - 'undetermined' - end - def total_size return 0 if pre_ingest_files.empty? pre_ingest_files.map(&:size).sum diff --git a/app/models/zizia/pre_ingest_work.rb b/app/models/zizia/pre_ingest_work.rb index f417dc1..8fcc599 100644 --- a/app/models/zizia/pre_ingest_work.rb +++ b/app/models/zizia/pre_ingest_work.rb @@ -12,5 +12,20 @@ def title return solr_title unless solr_title.nil? 'This work\'s metadata has not been indexed yet.' end + + # Returns thumbnail urls based on the work's deduplication_key + # @return [Array] the work's thumbnail urls + def thumbnails + thumbnail_urls = [] + return thumbnail_urls if deduplication_key.nil? + file_sets = ActiveFedora::SolrService.get("deduplication_key_tesim:#{deduplication_key}") + .dig('response', 'docs', 0, 'file_set_ids_ssim') + return thumbnail_urls unless file_sets + file_sets.each do |file_set_id| + thumbnail_urls.push(ActiveFedora::SolrService.get("id:#{file_set_id}") + .dig('response', 'docs', 0, 'thumbnail_path_ss')) + end + thumbnail_urls + end end end diff --git a/app/views/zizia/csv_import_details/index.html.erb b/app/views/zizia/csv_import_details/index.html.erb index 2eedab8..e85b30b 100644 --- a/app/views/zizia/csv_import_details/index.html.erb +++ b/app/views/zizia/csv_import_details/index.html.erb @@ -9,7 +9,6 @@ Number of Works Number of Files Total Size - Status Overwrite Behavior Type <% @csv_import_details.each do |csv_import_detail| %> @@ -35,9 +34,6 @@ <%= number_to_human_size(csv_import_detail.total_size) %> - - <%= csv_import_detail.status %> - <%= human_update_actor_stack(csv_import_detail.update_actor_stack) %> diff --git a/app/views/zizia/csv_import_details/show.html.erb b/app/views/zizia/csv_import_details/show.html.erb index 002c128..b0f1ecd 100644 --- a/app/views/zizia/csv_import_details/show.html.erb +++ b/app/views/zizia/csv_import_details/show.html.erb @@ -15,6 +15,7 @@ Title Files Date + Status <% @pre_ingest_works.each do |pre_ingest_work| %> @@ -30,8 +31,16 @@ <%= pre_ingest_work.created_at.strftime("%B %-d, %Y %H:%M") %> + "> + + <% end %> <%= paginate @pre_ingest_works %> + diff --git a/config/routes.rb b/config/routes.rb index 831d927..7b70c96 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -10,4 +10,5 @@ get 'csv_import_details/index' get 'csv_import_details/show/:id', to: 'csv_import_details#show', as: 'csv_import_detail' + get 'pre_ingest_works/thumbnails/:deduplication_key', to: 'pre_ingest_works#thumbnails' end diff --git a/spec/controllers/pre_ingest_works_controller_spec.rb b/spec/controllers/pre_ingest_works_controller_spec.rb new file mode 100644 index 0000000..caa3ad8 --- /dev/null +++ b/spec/controllers/pre_ingest_works_controller_spec.rb @@ -0,0 +1,56 @@ +# frozen_string_literal: true + +require 'rails_helper' + +RSpec.describe Zizia::PreIngestWorksController, :clean, type: :controller do + routes { Zizia::Engine.routes } + let(:admin_user) { FactoryBot.create(:admin) } + let(:pre_ingest_work) { FactoryBot.create(:pre_ingest_work) } + let(:pre_ingest_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: pre_ingest_work.id) } + let(:pre_ingest_file_without_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: pre_ingest_work.id, filename: File.open([Zizia::Engine.root, '/', 'spec/fixtures/dog.jpg'].join)) } + let(:work) { Work.new(title: ['a title'], deduplication_key: pre_ingest_work.deduplication_key) } + let(:file_set) do + FactoryBot.create(:file_set, + title: ['zizia.png'], + content: File.open([Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join)) + end + let(:basename) { 'zizia.png' } + before do + work.ordered_members << file_set + work.save + end + + describe 'GET thumbnails' do + context 'as a logged in user' do + it 'returns 200' do + allow(controller).to receive(:current_user).and_return(admin_user) + get :thumbnails, params: { deduplication_key: pre_ingest_work.deduplication_key, format: :json } + expect(response.status).to eq(200) + end + + it 'returns an array of thumbail paths' do + file_set.save + allow(controller).to receive(:current_user).and_return(admin_user) + get :thumbnails, params: { deduplication_key: pre_ingest_work.deduplication_key, format: :json } + parsed_json = JSON.parse(response.body) + expect(parsed_json['thumbnails']).to be_an(Array) + expect(parsed_json['thumbnails'].empty?).to eq(false) + end + + it 'returns an empty array if there aren\'t any thumbnails' do + allow(controller).to receive(:current_user).and_return(admin_user) + get :thumbnails, params: { deduplication_key: 'abc/1234', format: :json } + parsed_json = JSON.parse(response.body) + expect(parsed_json['thumbnails']).to be_an(Array) + expect(parsed_json['thumbnails'].empty?).to eq(true) + end + end + + context 'as someone not logged in' do + it 'returns 401' do + get :thumbnails, params: { deduplication_key: pre_ingest_work.deduplication_key, format: :json } + expect(response.status).to eq(401) + end + end + end +end diff --git a/spec/dummy/spec/system/csv_import_details_page_spec.rb b/spec/dummy/spec/system/csv_import_details_page_spec.rb index 0e0d525..b21bf39 100644 --- a/spec/dummy/spec/system/csv_import_details_page_spec.rb +++ b/spec/dummy/spec/system/csv_import_details_page_spec.rb @@ -1,7 +1,7 @@ require 'rails_helper' include Warden::Test::Helpers -RSpec.describe 'viewing the csv import detail page', js: true do +RSpec.describe 'viewing the csv import detail page', :clean, js: true do let(:user) { FactoryBot.create(:admin, email: 'systems@curationexperts.com')} let(:second_user) { FactoryBot.create(:user, email: 'user@curationexperts.com') } let(:csv_import) { FactoryBot.create(:csv_import) } @@ -11,6 +11,14 @@ let(:csv_import_detail_third) { FactoryBot.create(:csv_import_detail, created_at: Time.parse('Wed, 30 Oct 2019 14:20:02 UTC +00:00').utc, depositor_id: second_user.id, csv_import_id: 2) } let(:csv_pre_ingest_works) { FactoryBot.create_list(:pre_ingest_work, 12, csv_import_detail_id: 4) } let(:csv_pre_ingest_work_second) { FactoryBot.create(:pre_ingest_work, csv_import_detail_id: 5, created_at: Time.parse('Thur, 31 Oct 2019 14:20:02 UTC +00:00').utc) } + let(:pre_ingest_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: csv_pre_ingest_work_second.id) } + let(:file_set) do + FactoryBot.create(:file_set, + title: ['zizia.png'], + content: File.open([Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join)) + end + let(:work) { Work.new(title: ['a title'], deduplication_key: csv_pre_ingest_work_second.deduplication_key) } + before do user.save @@ -27,6 +35,10 @@ csv_import_detail_third.save csv_pre_ingest_works.each(&:save) csv_pre_ingest_work_second.save + pre_ingest_file.save + + work.ordered_members << file_set + work.save login_as user end @@ -34,7 +46,6 @@ visit ('/csv_import_details/index') expect(page).to have_content('ID') expect(page).to have_content('Status') - expect(page).to have_content('undetermined') click_on '1' expect(page).to have_content('Total Size') expect(page).to have_content('Deduplication Key') @@ -55,12 +66,6 @@ expect(page).to have_link '13' end - it 'has a sortable status' do - pending 'status is always undetermined currently' - visit('/csv_import_details/index?direction=asc&locale=en&sort=status') - expect(page).to have_content 'zippy' - end - it 'has a sortable date' do visit('/csv_import_details/index?direction=desc&locale=en&sort=created_at') expect(page).to have_content 'October 31' @@ -79,12 +84,6 @@ expect(page).to have_content('October 29, 2019 14:20') end - it 'displays undetermined for the status' do - visit ('/csv_import_details/index') - expect(page).to have_content('Status') - expect(page).to have_content('undetermined') - end - it 'displays the overwrite behavior type' do visit ('/csv_import_details/index') expect(page).to have_content('Overwrite Behavior Type') @@ -100,7 +99,6 @@ visit('/csv_import_details/index') expect(page).to have_content('Next') - end it 'has pagination at 10' do @@ -134,4 +132,15 @@ click_on 'View Files' expect(page).to have_content 'Row Number' end + + it 'can show a status for a file' do + file_set + visit('/csv_import_details/index') + click_on '5' + expect(page).to have_content 'View Files' + expect(page).to have_content 'Status' + expect(page.html).to match(/glyphicon-question-sign/) + click_on 'View Files' + expect(page).to have_content('Filename') + end end diff --git a/spec/factories/file_sets.rb b/spec/factories/file_sets.rb new file mode 100644 index 0000000..5517b10 --- /dev/null +++ b/spec/factories/file_sets.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true +FactoryBot.define do + factory :file_set do + transient do + user { build(:user) } + title { nil } + content { nil } + end + after(:build) do |fs, evaluator| + fs.apply_depositor_metadata evaluator.user.user_key + fs.title = evaluator.title + end + + after(:create) do |file, evaluator| + Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content + end + + trait :public do + read_groups { ["public"] } + end + + trait :registered do + read_groups { ["registered"] } + end + + factory :file_with_work do + after(:build) do |file, _evaluator| + file.title = ['testfile'] + end + after(:create) do |file, evaluator| + Hydra::Works::UploadFileToFileSet.call(file, evaluator.content) if evaluator.content + create(:work, user: evaluator.user).members << file + end + end + end +end diff --git a/spec/factories/pre_ingest_file.rb b/spec/factories/pre_ingest_file.rb index bc29afa..24cb715 100644 --- a/spec/factories/pre_ingest_file.rb +++ b/spec/factories/pre_ingest_file.rb @@ -7,7 +7,7 @@ updated_at { Time.current } row_number { 1 } row { 'sample,row' } - filename { '/a/path/to/my.csv' } + filename { [Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join } size { 100_203_424 } end end diff --git a/spec/models/zizia/pre_ingest_file_spec.rb b/spec/models/zizia/pre_ingest_file_spec.rb index c5e9840..b6469fb 100644 --- a/spec/models/zizia/pre_ingest_file_spec.rb +++ b/spec/models/zizia/pre_ingest_file_spec.rb @@ -4,9 +4,15 @@ RSpec.describe Zizia::PreIngestFile do let(:pre_ingest_work) { FactoryBot.create(:pre_ingest_work) } let(:pre_ingest_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: pre_ingest_work.id) } - let(:basename) { 'my.csv' } + let(:pre_ingest_file_without_file) { FactoryBot.create(:pre_ingest_file, pre_ingest_work_id: pre_ingest_work.id, filename: File.open([Zizia::Engine.root, '/', 'spec/fixtures/dog.jpg'].join)) } + let(:file_set) do + FactoryBot.create(:file_set, + title: ['zizia.png'], + content: File.open([Zizia::Engine.root, '/', 'spec/fixtures/zizia.png'].join)) + end + let(:basename) { 'zizia.png' } it 'can get the basename for the file' do - expect(pre_ingest_file.basename).to eq(basename) + expect(pre_ingest_file.basename).to eq basename end end diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index cfb10e5..457a0e9 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -12,6 +12,7 @@ require 'byebug' require 'rails-controller-testing' require 'selenium-webdriver' +require 'devise' # Add additional requires below this line. Rails is not loaded until this point! # Requires supporting ruby files with custom matchers and macros, etc, in @@ -38,6 +39,8 @@ exit 1 end RSpec.configure do |config| + config.include Devise::Test::ControllerHelpers, type: :controller + # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures config.fixture_path = "#{::Rails.root}/spec/fixtures"