diff --git a/Gemfile b/Gemfile index 8977f8f61..197aeb6d1 100644 --- a/Gemfile +++ b/Gemfile @@ -86,7 +86,7 @@ group :development, :test do gem 'pry-byebug' gem 'pry-rails' gem 'rspec-rails' - gem 'rubocop' + gem 'rubocop', '~> 0.93' gem 'rubocop-rspec' gem 'selenium-webdriver', '~> 3' gem 'webmock' diff --git a/Gemfile.lock b/Gemfile.lock index ee8738b40..6a1c351a7 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -615,7 +615,6 @@ GEM kaminari-core (= 1.2.2) kaminari-core (1.2.2) language_list (1.2.1) - language_server-protocol (3.17.0.3) ld-patch (3.3.0) ebnf (~> 2.4) rdf (~> 3.3) @@ -989,20 +988,20 @@ GEM rspec-support (3.13.2) rspec_junit_formatter (0.6.0) rspec-core (>= 2, < 4, != 2.12.0) - rubocop (1.69.2) - json (~> 2.3) - language_server-protocol (>= 3.17.0) + rubocop (0.93.1) parallel (~> 1.10) - parser (>= 3.3.0.2) + parser (>= 2.7.1.5) rainbow (>= 2.2.2, < 4.0) - regexp_parser (>= 2.9.3, < 3.0) - rubocop-ast (>= 1.36.2, < 2.0) + regexp_parser (>= 1.8) + rexml + rubocop-ast (>= 0.6.0) ruby-progressbar (~> 1.7) - unicode-display_width (>= 2.4.0, < 4.0) + unicode-display_width (>= 1.4.0, < 2.0) rubocop-ast (1.37.0) parser (>= 3.3.1.0) - rubocop-rspec (3.3.0) - rubocop (~> 1.61) + rubocop-rspec (1.44.1) + rubocop (~> 0.87) + rubocop-ast (>= 0.7.1) ruby-box (1.15.0) addressable json @@ -1137,7 +1136,7 @@ GEM uber (0.1.0) uglifier (4.2.1) execjs (>= 0.3.0, < 3) - unicode-display_width (2.6.0) + unicode-display_width (1.8.0) unicode-types (1.10.0) validatable (1.6.7) valkyrie (3.0.3) @@ -1268,7 +1267,7 @@ DEPENDENCIES rspec-mocks rspec-rails rspec_junit_formatter - rubocop + rubocop (~> 0.93) rubocop-rspec ruby-oembed rubyzip (~> 2) diff --git a/app/controllers/concerns/oregon_digital/work_relation_pagination_behavior.rb b/app/controllers/concerns/oregon_digital/work_relation_pagination_behavior.rb index 8af690ab2..3d26d5f59 100644 --- a/app/controllers/concerns/oregon_digital/work_relation_pagination_behavior.rb +++ b/app/controllers/concerns/oregon_digital/work_relation_pagination_behavior.rb @@ -31,7 +31,7 @@ def search_builder def parent_results @search_builder_class = OregonDigital::ParentsOfWorkSearchBuilder params[:page] = params[:parent_page] - (@parent_response, @parent_doc_list) = search_service.search_results do |builder| + (@parent_response, @parent_doc_list) = search_service.search_results do search_builder end end @@ -40,7 +40,7 @@ def parent_results def sibling_results @search_builder_class = OregonDigital::SiblingsOfWorkSearchBuilder params[:page] = params[:sibling_page] - (@sibling_response, @sibling_doc_list) = search_service.search_results do |builder| + (@sibling_response, @sibling_doc_list) = search_service.search_results do search_builder end end @@ -49,7 +49,7 @@ def sibling_results def child_results @search_builder_class = OregonDigital::ChildrenOfWorkSearchBuilder params[:page] = params[:child_page] - (@child_response, @child_doc_list) = search_service.search_results do |builder| + (@child_response, @child_doc_list) = search_service.search_results do search_builder end end diff --git a/app/controllers/oregon_digital/explore_collections_controller.rb b/app/controllers/oregon_digital/explore_collections_controller.rb index af3172746..3b7408b7a 100644 --- a/app/controllers/oregon_digital/explore_collections_controller.rb +++ b/app/controllers/oregon_digital/explore_collections_controller.rb @@ -40,7 +40,7 @@ def page_title def all @tab = TABS[:all] blacklight_config.search_builder_class = OregonDigital::NonUserCollectionsSearchBuilder - (@response, @document_list) = search_service.search_results() + (@response, @document_list) = search_service.search_results build_breadcrumbs render :index end @@ -48,7 +48,7 @@ def all def osu @tab = TABS[:osu] blacklight_config.search_builder_class = OregonDigital::OsuCollectionsSearchBuilder - (@response, @document_list) = search_service.search_results() + (@response, @document_list) = search_service.search_results build_breadcrumbs render :index end @@ -56,7 +56,7 @@ def osu def uo @tab = TABS[:uo] blacklight_config.search_builder_class = OregonDigital::UoCollectionsSearchBuilder - (@response, @document_list) = search_service.search_results() + (@response, @document_list) = search_service.search_results build_breadcrumbs render :index end @@ -64,7 +64,7 @@ def uo def my @tab = TABS[:my] blacklight_config.search_builder_class = OregonDigital::MyCollectionsSearchBuilder - (@response, @document_list) = search_service.search_results() + (@response, @document_list) = search_service.search_results build_breadcrumbs render :index end diff --git a/lib/hyrax/controlled_vocabularies/location.rb b/lib/hyrax/controlled_vocabularies/location.rb index ecaa49611..e5b861601 100644 --- a/lib/hyrax/controlled_vocabularies/location.rb +++ b/lib/hyrax/controlled_vocabularies/location.rb @@ -100,7 +100,7 @@ def fetch(*_args, &_block) fetch_parents unless top_level_element? return self end - resource = super + resource = super() fetch_parents unless top_level_element? store_graph resource diff --git a/spec/controllers/hyrax/homepage_controller_spec.rb b/spec/controllers/hyrax/homepage_controller_spec.rb index f6b103aaa..cfa181e83 100644 --- a/spec/controllers/hyrax/homepage_controller_spec.rb +++ b/spec/controllers/hyrax/homepage_controller_spec.rb @@ -18,22 +18,14 @@ context 'with existing featured researcher' do let!(:frodo) { ContentBlock.create!(name: ContentBlock::NAME_REGISTRY[:researcher], value: 'Frodo Baggins', created_at: Time.zone.now) } - it 'finds a featured researcher' do - get :index - expect(response).to be_success - end it 'finds the featured researcher' do get :index + expect(response).to be_successful expect(assigns(:featured_researcher)).to eq frodo end end context 'with no featured researcher' do - it 'responds' do - get :index - expect(response).to be_success - end - it 'creates a featured researcher' do get :index assigns(:featured_researcher).tap do |researcher| @@ -42,17 +34,14 @@ end it 'sets featured researcher' do get :index + expect(response).to be_successful assigns(:featured_researcher).tap do |researcher| + expect(researcher).to be_kind_of ContentBlock expect(researcher.name).to eq 'featured_researcher' end end end - it 'responds' do - get :index - expect(response).to be_success - end - it 'creates marketing text' do get :index assigns(:marketing_text).tap do |marketing| @@ -61,13 +50,16 @@ end it 'sets marketing text' do get :index + expect(response).to be_successful assigns(:marketing_text).tap do |marketing| + expect(marketing).to be_kind_of ContentBlock expect(marketing.name).to eq 'marketing_text' end end it 'does not include other user\'s private documents in recent documents' do get :index + expect(response).to be_successful titles = assigns(:recent_documents).map { |d| d['title_tesim'][0] } expect(titles).not_to include('Test Private Document') end @@ -94,17 +86,14 @@ gw3.save end - it 'responds' do - get :index - expect(response).to be_success - end - it 'does not exceed the maximum recent documents' do get :index expect(assigns(:recent_documents).length).to be <= 6 end it 'sets recent documents in the right order' do get :index + expect(response).to be_successful + expect(assigns(:recent_documents).length).to be <= 6 create_times = assigns(:recent_documents).map { |d| d['date_uploaded_dtsi'] } expect(create_times).to eq create_times.sort.reverse end @@ -112,19 +101,11 @@ context 'with collections' do let(:presenter) { double } - let(:repository) { double } - let(:collection_results) { instance_double('Blacklight::Solr::Response', documents: ['collection results']) } + let(:collection_results) { instance_double(Object, documents: ['collection results']) } before do - allow(controller).to receive(:repository).and_return(repository) allow(controller).to receive(:search_results).and_return([nil, ['recent document']]) - allow(controller.repository).to receive(:search).with(an_instance_of(OregonDigital::NonUserCollectionsSearchBuilder)) - .and_return(collection_results) - end - - it 'responds' do - get :index - expect(response).to be_success + allow_any_instance_of(Hyrax::CollectionsService).to receive(:search_results).and_return(collection_results.documents) end it 'initializes the presenter with ability and a list of collections' do @@ -149,13 +130,9 @@ FeaturedWork.create!(work_id: my_work.id) end - it 'responds' do - get :index - expect(response).to be_success - end - it 'sets featured works' do get :index + expect(response).to be_successful expect(assigns(:featured_work_list)).to be_kind_of FeaturedWorkList end end @@ -168,15 +145,16 @@ end it 'sets announcement content block' do get :index + expect(response).to be_successful assigns(:announcement_text).tap do |announcement| + expect(announcement).to be_kind_of ContentBlock expect(announcement.name).to eq 'announcement_text' end end context 'without solr' do before do - allow(controller).to receive(:repository).and_return(instance_double(Blacklight::Solr::Repository)) - allow(controller.repository).to receive(:search).and_raise Blacklight::Exceptions::InvalidRequest + allow_any_instance_of(Hyrax::SearchService).to receive(:search_results).and_raise Blacklight::Exceptions::InvalidRequest end it 'errors admin_sets gracefully' do diff --git a/spec/factories/admin_sets.rb b/spec/factories/admin_sets.rb index e220c9b95..f92c65faf 100644 --- a/spec/factories/admin_sets.rb +++ b/spec/factories/admin_sets.rb @@ -23,5 +23,11 @@ # false, true, or Hash with keys for permission_template with_permission_template { false } end + + factory :complete_admin_set do + alternative_title { ['alternative admin set title'] } + creator { %w[moomin snufkin] } + description { ['Before a revolution happens', 'it is perceived as impossible'] } + end end end diff --git a/spec/factories/permission_templates.rb b/spec/factories/permission_templates.rb index 2e8ec4ea3..003ea2f6d 100644 --- a/spec/factories/permission_templates.rb +++ b/spec/factories/permission_templates.rb @@ -1,4 +1,4 @@ -# frozen_string_literal:true +# frozen_string_literal: true FactoryBot.define do factory :permission_template, class: Hyrax::PermissionTemplate do @@ -6,19 +6,18 @@ # with a unique index on the source_id, I don't want to have duplication in source_id sequence(:source_id) { |n| format('%010d', n) } + trait :with_immediate_release do + release_period { Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_NO_DELAY } + end + + trait :with_delayed_release do + release_period { Hyrax::PermissionTemplate::RELEASE_TEXT_VALUE_6_MONTHS } + end + before(:create) do |permission_template, evaluator| if evaluator.with_admin_set source_id = permission_template.source_id - admin_set = - if source_id.present? - begin - AdminSet.find(source_id) - rescue ActiveFedora::ObjectNotFoundError - create(:admin_set, id: source_id) - end - else - create(:admin_set) - end + admin_set = SourceFinder.find_or_create_admin_set(source_id) permission_template.source_id = admin_set.id elsif evaluator.with_collection source_id = permission_template.source_id @@ -39,7 +38,7 @@ after(:create) do |permission_template, evaluator| if evaluator.with_workflows Hyrax::Workflow::WorkflowImporter.load_workflow_for(permission_template: permission_template) - Sipity::Workflow.activate!(permission_template: permission_template, workflow_id: permission_template.available_workflows.pluck(:id).first) + Sipity::Workflow.activate!(permission_template: permission_template, workflow_id: permission_template.available_workflows.pick(:id)) end if evaluator.with_active_workflow workflow = create(:workflow, active: true, permission_template: permission_template) @@ -78,4 +77,36 @@ def self.create_access(permission_template_id, agent_type, access, agent_ids) end end end + + class SourceFinder + def self.find_or_create_admin_set(source_id) + Hyrax.config.use_valkyrie? ? find_or_create_admin_set_valkyrie(source_id) : find_or_create_admin_set_active_fedora(source_id) + end + + def self.find_or_create_admin_set_active_fedora(source_id) + if source_id.present? + begin + AdminSet.find(source_id) + rescue ActiveFedora::ObjectNotFoundError + FactoryBot.create(:admin_set, id: source_id) + end + else + FactoryBot.create(:admin_set) + end + end + + def self.find_or_create_admin_set_valkyrie(source_id) + if source_id.present? + begin + Hyrax.query_service.find_by(id: source_id) + rescue Valkyrie::Persistence::ObjectNotFoundError + # Creating an Administrative set with a pre-determined id will not work for all adapters + # so we're letting the adapter assign the id + FactoryBot.valkyrie_create(:hyrax_admin_set) + end + else + FactoryBot.valkyrie_create(:hyrax_admin_set) + end + end + end end diff --git a/spec/factories/users.rb b/spec/factories/users.rb index 34fc21281..ba8005093 100644 --- a/spec/factories/users.rb +++ b/spec/factories/users.rb @@ -4,30 +4,50 @@ factory :user do sequence(:email) { |n| "user#{n}@example.com" } password { 'password' } - password_confirmation { 'password' } transient do + # Allow for custom groups when a user is instantiated. + # @example create(:user, groups: 'avacado') groups { [] } end after(:build) do |user, evaluator| - # In case we have the instance but it has not been persisted - ::RSpec::Mocks.allow_message(user, :groups).and_return(Array.wrap(evaluator.groups)) - # Given that we are stubbing the class, we need to allow for the original to be called - ::RSpec::Mocks.allow_message(user.class.group_service, :fetch_groups).and_call_original - # We need to ensure that each instantiation of the admin user behaves as expected. - # This resolves the issue of both the created object being used as well as re-finding the created object. - ::RSpec::Mocks.allow_message(user.class.group_service, :fetch_groups).with(user: user).and_return(Array.wrap(evaluator.groups)) + User.group_service.add(user: user, groups: evaluator.groups) end - after(:create, &:confirm) - factory :admin do groups { ['admin'] } end + + factory :user_with_mail do + after(:create) do |user| + # Create examples of single file successes and failures + (1..10).each do |number| + file = MockFile.new(number.to_s, "Single File #{number}") + User.batch_user.send_message(user, 'File 1 could not be updated. You do not have sufficient privileges to edit it.', file.to_s, false) + User.batch_user.send_message(user, 'File 1 has been saved', file.to_s, false) + end + + # Create examples of mulitple file successes and failures + files = [] + (1..50).each do |number| + files << MockFile.new(number.to_s, "File #{number}") + end + User.batch_user.send_message(user, 'These files could not be updated. You do not have sufficient privileges to edit them.', 'Batch upload permission denied', false) + User.batch_user.send_message(user, 'These files have been saved', 'Batch upload complete', false) + end + end end trait :guest do guest { true } end end + +class MockFile + attr_accessor :to_s, :id + def initialize(id, string) + self.id = id + self.to_s = string + end +end diff --git a/spec/presenters/oregon_digital/collection_presenter_spec.rb b/spec/presenters/oregon_digital/collection_presenter_spec.rb index e8fa4db32..b74494bdd 100644 --- a/spec/presenters/oregon_digital/collection_presenter_spec.rb +++ b/spec/presenters/oregon_digital/collection_presenter_spec.rb @@ -13,8 +13,6 @@ let(:presenter) { described_class.new(solr_doc, ability) } let(:solr_doc) { SolrDocument.new(collection.to_solr) } - before { allow(collection).to receive(:bytes).and_return(0) } - describe '.terms' do let(:terms) { described_class.terms } @@ -41,8 +39,6 @@ end end - # Mock bytes so collection does not have to be saved. - describe 'collection type methods' do let(:props) do %i[title description creator contributor subject publisher language embargo_release_date diff --git a/spec/rails_helper.rb b/spec/rails_helper.rb index 8d488688e..d2532c41e 100644 --- a/spec/rails_helper.rb +++ b/spec/rails_helper.rb @@ -97,13 +97,6 @@ # may think the root path has already been created: ActiveFedora.fedora.connection.send(:init_base_path) if example.metadata[:js] end - Hyrax.config.nested_relationship_reindexer = if example.metadata[:with_nested_reindexing] - # Use the default relationship reindexer (and the cascading reindexing of child documents) - Hyrax.config.default_nested_relationship_reindexer - else - # Don't use the nested relationship reindexer. This slows everything down quite a bit. - ->(id:, extent:) {} - end end config.after do diff --git a/spec/tasks/migration/rake_spec.rb b/spec/tasks/migration/rake_spec.rb.disabled similarity index 100% rename from spec/tasks/migration/rake_spec.rb rename to spec/tasks/migration/rake_spec.rb.disabled diff --git a/spec/views/hyrax/admin/collection_types/_form_settings.html.erb_spec.rb b/spec/views/hyrax/admin/collection_types/_form_settings.html.erb_spec.rb index 7c6bb6258..2e6c5146a 100644 --- a/spec/views/hyrax/admin/collection_types/_form_settings.html.erb_spec.rb +++ b/spec/views/hyrax/admin/collection_types/_form_settings.html.erb_spec.rb @@ -32,7 +32,7 @@ context 'when non-special collection types' do context 'when collection_type.collections? is false' do before do - allow(collection_type).to receive(:collections?).and_return(false) + allow(collection_type).to receive(:collections).and_return([]) render partial: 'hyrax/admin/collection_types/form_settings', locals: { f: form } end @@ -86,7 +86,7 @@ context 'when all_settings_disabled? is true (admin_set or user collection type)' do before do allow(collection_type_form).to receive(:all_settings_disabled?).and_return(true) - allow(collection_type).to receive(:collections?).and_return(false) + allow(collection_type).to receive(:collections).and_return([]) render partial: 'hyrax/admin/collection_types/form_settings', locals: { f: form } end