diff --git a/.rubocop_fixme.yml b/.rubocop_fixme.yml
index a51fe2641b..e86d00e2bd 100644
--- a/.rubocop_fixme.yml
+++ b/.rubocop_fixme.yml
@@ -152,3 +152,35 @@ RSpec/AnyInstance:
- 'spec/services/hyrax/workflow/sipity_actions_generator_spec.rb'
- 'spec/services/hyrax/workflow/state_machine_generator_spec.rb'
- 'spec/services/hyrax/workflow/workflow_permissions_generator_spec.rb'
+
+# Offense count: 51
+RSpec/ExpectInHook:
+ Enabled: false
+
+# Offense count: 31
+RSpec/LetBeforeExamples:
+ Exclude:
+ - 'spec/forms/hyrax/forms/collection_form_spec.rb'
+ - 'spec/presenters/hyrax/collection_presenter_spec.rb'
+ - 'spec/presenters/hyrax/trophy_presenter_spec.rb'
+ - 'spec/services/hyrax/query_service_spec.rb'
+ - 'spec/services/hyrax/workflow/action_taken_service_spec.rb'
+ - 'spec/services/hyrax/workflow/notification_service_spec.rb'
+
+# Offense count: 27
+# Configuration parameters: EnforcedStyle, SupportedStyles.
+# SupportedStyles: and_return, block
+RSpec/ReturnFromStub:
+ Exclude:
+ - 'spec/controllers/hyrax/api/items_controller_spec.rb'
+ - 'spec/controllers/hyrax/file_sets_controller_spec.rb'
+ - 'spec/lib/hyrax/arkivo/create_subscription_job_spec.rb'
+ - 'spec/models/file_set_spec.rb'
+ - 'spec/presenters/hyrax/admin_set_options_presenter_spec.rb'
+ - 'spec/routing/api_route_spec.rb'
+ - 'spec/views/_user_util_links.html.erb_spec.rb'
+ - 'spec/views/hyrax/base/_attributes.html.erb_spec.rb'
+ - 'spec/views/hyrax/base/_form.html.erb_spec.rb'
+ - 'spec/views/hyrax/base/file_manager.html.erb_spec.rb'
+ - 'spec/views/hyrax/dashboard/profiles/edit.html.erb_spec.rb'
+ - 'spec/views/hyrax/users/_user_info.html.erb_spec.rb'
diff --git a/README.md b/README.md
index d34f75b6b0..6a1a0ac908 100644
--- a/README.md
+++ b/README.md
@@ -63,7 +63,7 @@ The Samvera community is here to help. Please see our [support guide](./.github/
# Getting started
This document contains instructions specific to setting up an app with __Hyrax
-v2.0.0.beta2__. If you are looking for instructions on installing a different
+v2.0.0.beta3__. If you are looking for instructions on installing a different
version, be sure to select the appropriate branch or tag from the drop-down
menu above.
@@ -160,7 +160,7 @@ NOTE: The steps need to be done in order to create a new Hyrax based app.
Generate a new Rails application using the template.
```
-rails _5.0.5_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.0.0.beta2/template.rb
+rails _5.0.5_ new my_app -m https://raw.githubusercontent.com/samvera/hyrax/v2.0.0.beta3/template.rb
```
Generating a new Rails application using Hyrax's template above takes cares of a number of steps for you, including:
diff --git a/app/assets/javascripts/hyrax/app.js.erb b/app/assets/javascripts/hyrax/app.js.erb
index e37f91a75b..5bd25e8591 100644
--- a/app/assets/javascripts/hyrax/app.js.erb
+++ b/app/assets/javascripts/hyrax/app.js.erb
@@ -103,6 +103,10 @@ Hyrax = {
// ActionCable for user notifications. This is displayed in the navbar.
notifications: function() {
+ // Do not create a consumer if user is not logged in
+ if ($("meta[name='current-user']").length === 0)
+ return;
+ <% if Hyrax.config.realtime_notifications? %>
var consumer = ActionCable.createConsumer("<%= Hyrax::Engine.routes.url_helpers.notifications_endpoint_path %>");
consumer.subscriptions.create("Hyrax::NotificationsChannel", {
connected: function(data) {
@@ -114,6 +118,7 @@ Hyrax = {
new Notification($('.notify-number')).update(data.notifications_count, data.notifications_label);
}
});
+ <% end %>
},
// Search for a user to transfer a work to
diff --git a/app/assets/javascripts/hyrax/channels/notifications.js b/app/assets/javascripts/hyrax/channels/notifications.js
deleted file mode 100644
index e69de29bb2..0000000000
diff --git a/app/controllers/hyrax/citations_controller.rb b/app/controllers/hyrax/citations_controller.rb
index 2522e0a918..5dbf70ef99 100644
--- a/app/controllers/hyrax/citations_controller.rb
+++ b/app/controllers/hyrax/citations_controller.rb
@@ -4,6 +4,7 @@ class CitationsController < ApplicationController
include Breadcrumbs
include SingularSubresourceController
+ layout :decide_layout
before_action :build_breadcrumbs, only: [:work, :file]
def work
@@ -24,5 +25,16 @@ def file
def show_presenter
WorkShowPresenter
end
+
+ def decide_layout
+ case action_name
+ when 'work', 'file'
+ theme
+ else
+ # Not currently used in this controller, but left here to
+ # support dashboard-based work views which are ticketed
+ 'dashboard'
+ end
+ end
end
end
diff --git a/app/jobs/stream_notifications_job.rb b/app/jobs/stream_notifications_job.rb
index 822729fc81..0c0773a396 100644
--- a/app/jobs/stream_notifications_job.rb
+++ b/app/jobs/stream_notifications_job.rb
@@ -1,5 +1,7 @@
class StreamNotificationsJob < Hyrax::ApplicationJob
def perform(users)
+ # Do not use the ActionCable machinery if the feature is disabled
+ return unless Hyrax.config.realtime_notifications?
Array.wrap(users).each do |user|
mailbox = UserMailbox.new(user)
Hyrax::NotificationsChannel.broadcast_to(user,
diff --git a/app/services/hyrax/curation_concern.rb b/app/services/hyrax/curation_concern.rb
index 8a7f1d9163..8b31fbc197 100644
--- a/app/services/hyrax/curation_concern.rb
+++ b/app/services/hyrax/curation_concern.rb
@@ -17,7 +17,7 @@ class CurationConcern
# is used. Once it is used, it becomes immutable.
# @return [ActionDispatch::MiddlewareStack]
def self.actor_factory
- Hyrax::DefaultMiddlewareStack.build_stack
+ @actor_factory ||= Hyrax::DefaultMiddlewareStack.build_stack
end
# A consumer of this method can inject a different factory
diff --git a/app/views/layouts/_head_tag_content.html.erb b/app/views/layouts/_head_tag_content.html.erb
index 88a2b49a05..29a404e97a 100644
--- a/app/views/layouts/_head_tag_content.html.erb
+++ b/app/views/layouts/_head_tag_content.html.erb
@@ -1,6 +1,11 @@
<%= csrf_meta_tag %>
-
+<%# Only display meta tag, which enables creation of the ActionCable
+consumer, when realtime notifications are enabled and the user is
+signed in %>
+<% if Hyrax.config.realtime_notifications? && signed_in? %>
+ <%= tag :meta, name: 'current-user', data: { user_key: current_user.user_key } %>
+<% end %>
diff --git a/config/routes.rb b/config/routes.rb
index ef53d1c872..81e14faa00 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -92,9 +92,11 @@
delete 'delete_all'
end
end
- namespace :notifications do
- # WebSocket for notifications
- mount ActionCable.server => 'endpoint', as: :endpoint
+ if Hyrax.config.realtime_notifications?
+ namespace :notifications do
+ # WebSocket for notifications
+ mount ActionCable.server => 'endpoint', as: :endpoint
+ end
end
# User profile
diff --git a/hyrax.gemspec b/hyrax.gemspec
index f054a89165..ecd21cdd71 100644
--- a/hyrax.gemspec
+++ b/hyrax.gemspec
@@ -40,8 +40,8 @@ EOF
spec.add_dependency 'blacklight-gallery', '~> 0.7'
spec.add_dependency 'tinymce-rails', '~> 4.1'
spec.add_dependency 'font-awesome-rails', '~> 4.2'
- spec.add_dependency 'select2-rails', '~> 3.5.9'
- spec.add_dependency 'json-schema' # for Arkivio
+ spec.add_dependency 'select2-rails', '~> 3.5'
+ spec.add_dependency 'json-schema' # for Arkivo
spec.add_dependency 'nest', '~> 2.0'
spec.add_dependency 'mailboxer', '~> 0.12'
spec.add_dependency 'carrierwave', '~> 1.0'
@@ -51,18 +51,20 @@ EOF
spec.add_dependency 'legato', '~> 0.3'
spec.add_dependency 'posix-spawn'
spec.add_dependency 'jquery-ui-rails', '~> 5.0'
- spec.add_dependency 'redis-namespace', '~> 1.5.2'
+ spec.add_dependency 'redis-namespace', '~> 1.5'
+ # Pin more tightly because 0.x gems are potentially unstable
spec.add_dependency 'flot-rails', '~> 0.0.6'
spec.add_dependency 'almond-rails', '~> 0.1'
spec.add_dependency 'qa', '~> 1.0' # questioning_authority
spec.add_dependency 'flipflop', '~> 2.3'
- spec.add_dependency 'jquery-datatables-rails', '~> 3.4.0'
+ spec.add_dependency 'jquery-datatables-rails', '~> 3.4'
spec.add_dependency 'rdf-rdfxml' # controlled vocabulary importer
spec.add_dependency 'clipboard-rails', '~> 1.5'
spec.add_dependency 'rails_autolink', '~> 1.1'
spec.add_dependency 'active_fedora-noid', '~> 2.0', '>= 2.0.2'
spec.add_dependency 'awesome_nested_set', '~> 3.1'
spec.add_dependency 'breadcrumbs_on_rails', '~> 3.0'
+ # Pin more tightly because 0.x gems are potentially unstable
spec.add_dependency 'kaminari_route_prefix', '~> 0.1.1'
spec.add_dependency 'power_converter', '~> 0.1', '>= 0.1.2'
spec.add_dependency 'dry-validation', '~> 0.9'
@@ -89,8 +91,18 @@ EOF
spec.add_development_dependency "factory_girl_rails", '~> 4.4'
spec.add_development_dependency "equivalent-xml", '~> 0.5'
spec.add_development_dependency "jasmine", '~> 2.3'
+ # Pin rubocop and rubocop-rspec tightly. Minor-level version bumps
+ # in these gems cause Rubocop violations, and those violations cause
+ # continuous integration builds to fail, and those failures prevent
+ # us from merging pull requests. As a community, we have decided
+ # that it is not reasonable to manage style violations to be dealt
+ # with in a pull request *unless* said pull request's intent is to
+ # bring the codebase in further alignment with community style
+ # conventions. This allows us to take a managed approach to code
+ # style -- we choose to update style when we wish, not when a
+ # minor-level version bump in a dependency comes out.
spec.add_development_dependency 'rubocop', '~> 0.49.1'
- spec.add_development_dependency 'rubocop-rspec', '~> 1.15.0'
+ spec.add_development_dependency 'rubocop-rspec', '~> 1.16.0'
spec.add_development_dependency 'shoulda-matchers', '~> 3.1'
spec.add_development_dependency 'rails-controller-testing', '~> 0'
spec.add_development_dependency 'webmock'
diff --git a/lib/generators/hyrax/templates/config/hyrax.rb b/lib/generators/hyrax/templates/config/hyrax.rb
index 1cc439b46f..e3480e737e 100644
--- a/lib/generators/hyrax/templates/config/hyrax.rb
+++ b/lib/generators/hyrax/templates/config/hyrax.rb
@@ -89,6 +89,9 @@
# of Zotero-managed research items.
# config.arkivo_api = false
+ # Stream realtime notifications to users in the browser
+ # config.realtime_notifications = true
+
# Location autocomplete uses geonames to search for named regions
# Username for connecting to geonames
# config.geonames_username = ''
diff --git a/lib/hyrax/configuration.rb b/lib/hyrax/configuration.rb
index 9e4f0beba5..5db832fa67 100644
--- a/lib/hyrax/configuration.rb
+++ b/lib/hyrax/configuration.rb
@@ -279,6 +279,22 @@ def arkivo_api?
@arkivo_api ||= false
end
+ # rubocop:disable Metrics/LineLength
+ attr_writer :realtime_notifications
+ def realtime_notifications?
+ # Coerce @realtime_notifications to false if server software
+ # does not support WebSockets, and warn the user that we are
+ # overriding the value in their config unless it's already
+ # flipped to false
+ if ENV.fetch('SERVER_SOFTWARE', '').match(/Apache.*Phusion_Passenger/).present?
+ Rails.logger.warn('Cannot enable realtime notifications atop Passenger + Apache. Coercing `Hyrax.config.realtime_notifications` to `false`. Set this value to `false` in config/initializers/hyrax.rb to stop seeing this warning.') unless @realtime_notifications == false
+ @realtime_notifications = false
+ end
+ return @realtime_notifications unless @realtime_notifications.nil?
+ @realtime_notifications = true
+ end
+ # rubocop:enable Metrics/LineLength
+
def geonames_username=(username)
Qa::Authorities::Geonames.username = username
end
diff --git a/lib/hyrax/version.rb b/lib/hyrax/version.rb
index 774d628324..f3023c2334 100644
--- a/lib/hyrax/version.rb
+++ b/lib/hyrax/version.rb
@@ -1,3 +1,3 @@
module Hyrax
- VERSION = '2.0.0.beta2'.freeze
+ VERSION = '2.0.0.beta3'.freeze
end
diff --git a/solr/config/schema.xml b/solr/config/schema.xml
index 2e9deac632..8eda5703de 100644
--- a/solr/config/schema.xml
+++ b/solr/config/schema.xml
@@ -334,12 +334,6 @@
-->
id
-
-
-
-
-
-
diff --git a/spec/controllers/hyrax/citations_controller_spec.rb b/spec/controllers/hyrax/citations_controller_spec.rb
index fab85e62fc..be301c5f7f 100644
--- a/spec/controllers/hyrax/citations_controller_spec.rb
+++ b/spec/controllers/hyrax/citations_controller_spec.rb
@@ -14,6 +14,7 @@
expect(controller).to receive(:add_breadcrumb).with('My Dashboard', Hyrax::Engine.routes.url_helpers.dashboard_path(locale: 'en'))
get :work, params: { id: work }
expect(response).to be_successful
+ expect(response).to render_template('layouts/hyrax')
expect(assigns(:presenter)).to be_kind_of Hyrax::WorkShowPresenter
end
end
@@ -41,6 +42,7 @@
expect(controller).to receive(:add_breadcrumb).with('My Dashboard', Hyrax::Engine.routes.url_helpers.dashboard_path(locale: 'en'))
get :file, params: { id: file_set }
expect(response).to be_successful
+ expect(response).to render_template('layouts/hyrax')
expect(assigns(:presenter)).to be_kind_of Hyrax::FileSetPresenter
end
end
diff --git a/spec/jobs/stream_notifications_job_spec.rb b/spec/jobs/stream_notifications_job_spec.rb
index 697008bdc4..46d43703a3 100644
--- a/spec/jobs/stream_notifications_job_spec.rb
+++ b/spec/jobs/stream_notifications_job_spec.rb
@@ -1,4 +1,10 @@
RSpec.describe StreamNotificationsJob do
+ let(:realtime_notifications) { true }
+
+ before do
+ allow(Hyrax.config).to receive(:realtime_notifications?).and_return(realtime_notifications)
+ end
+
describe '#perform' do
context 'with zero users' do
let(:users) { nil }
@@ -25,6 +31,15 @@
notifications_label: "You've got mail!")
described_class.perform_now(users)
end
+
+ context 'when realtime notifications feature is disabled' do
+ let(:realtime_notifications) { false }
+
+ it 'does not broadcast' do
+ expect(Hyrax::NotificationsChannel).not_to receive(:broadcast_to)
+ described_class.perform_now(users)
+ end
+ end
end
end
end
diff --git a/spec/lib/hyrax/configuration_spec.rb b/spec/lib/hyrax/configuration_spec.rb
index 01315a1824..bb27f5c236 100644
--- a/spec/lib/hyrax/configuration_spec.rb
+++ b/spec/lib/hyrax/configuration_spec.rb
@@ -50,6 +50,8 @@
it { is_expected.to respond_to(:permission_levels) }
it { is_expected.to respond_to(:permission_options) }
it { is_expected.to respond_to(:persistent_hostpath) }
+ it { is_expected.to respond_to(:realtime_notifications?) }
+ it { is_expected.to respond_to(:realtime_notifications=) }
it { is_expected.to respond_to(:redis_namespace) }
it { is_expected.to respond_to(:subject_prefix) }
it { is_expected.to respond_to(:translate_id_to_uri) }
diff --git a/spec/services/hyrax/curation_concern_spec.rb b/spec/services/hyrax/curation_concern_spec.rb
index 36b6a4b7b4..a45fdbcde5 100644
--- a/spec/services/hyrax/curation_concern_spec.rb
+++ b/spec/services/hyrax/curation_concern_spec.rb
@@ -7,4 +7,12 @@
it { is_expected.to be_kind_of Hyrax::Actors::TransactionalRequest }
end
+
+ describe ".actor_factory" do
+ subject { described_class.actor_factory }
+
+ it "returns same ActionDispatch::MiddlewareStack instance" do
+ is_expected.to eq described_class.actor_factory
+ end
+ end
end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 01d0529fd0..668a75429d 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -142,7 +142,7 @@ def main_app
Hyrax.config.enable_noids = false
end
- config.before :each do |example|
+ config.before do |example|
if example.metadata[:type] == :feature && Capybara.current_driver != :rack_test
DatabaseCleaner.strategy = :truncation
else
diff --git a/spec/tasks/rake_spec.rb b/spec/tasks/rake_spec.rb
index b3a33742e5..5b2cf09e77 100644
--- a/spec/tasks/rake_spec.rb
+++ b/spec/tasks/rake_spec.rb
@@ -11,15 +11,15 @@
it "creates a file" do
run_task "hyrax:user:list_emails"
- expect(File.exist?("user_emails.txt")).to be_truthy
+ expect(File).to exist("user_emails.txt")
expect(IO.read("user_emails.txt")).to include(user1.email, user2.email)
File.delete("user_emails.txt")
end
it "creates a file I give it" do
run_task "hyrax:user:list_emails", "abc123.txt"
- expect(File.exist?("user_emails.txt")).not_to be_truthy
- expect(File.exist?("abc123.txt")).to be_truthy
+ expect(File).not_to exist("user_emails.txt")
+ expect(File).to exist("abc123.txt")
expect(IO.read("abc123.txt")).to include(user1.email, user2.email)
File.delete("abc123.txt")
end
diff --git a/spec/views/hyrax/base/show.html.erb_spec.rb b/spec/views/hyrax/base/show.html.erb_spec.rb
index 6e2957e232..dab12cb721 100644
--- a/spec/views/hyrax/base/show.html.erb_spec.rb
+++ b/spec/views/hyrax/base/show.html.erb_spec.rb
@@ -49,6 +49,7 @@
allow(controller).to receive(:current_user).and_return(depositor)
allow(User).to receive(:find_by_user_key).and_return(depositor.user_key)
allow(view).to receive(:blacklight_config).and_return(Blacklight::Configuration.new)
+ allow(view).to receive(:signed_in?)
allow(view).to receive(:on_the_dashboard?).and_return(false)
stub_template 'hyrax/base/_metadata.html.erb' => ''
stub_template 'hyrax/base/_relationships.html.erb' => ''
diff --git a/spec/views/hyrax/homepage/index.html.erb_spec.rb b/spec/views/hyrax/homepage/index.html.erb_spec.rb
index 8ab8d9aac9..bee96e7737 100644
--- a/spec/views/hyrax/homepage/index.html.erb_spec.rb
+++ b/spec/views/hyrax/homepage/index.html.erb_spec.rb
@@ -4,15 +4,59 @@
let(:presenter) { instance_double(Hyrax::HomepagePresenter) }
let(:type_presenter) { instance_double(Hyrax::SelectTypeListPresenter, many?: true) }
- describe "share your work button" do
+ before do
+ allow(view).to receive(:create_work_presenter).and_return(type_presenter)
+ allow(view).to receive(:signed_in?).and_return(signed_in)
+ allow(controller).to receive(:current_ability).and_return(ability)
+ assign(:presenter, presenter)
+ stub_template "hyrax/homepage/_marketing.html.erb" => "marketing"
+ stub_template "hyrax/homepage/_home_content.html.erb" => "home content"
+ end
+
+ describe 'meta tag with current user info' do
+ let(:realtime_notifications) { true }
+
before do
- allow(view).to receive(:create_work_presenter).and_return(type_presenter)
- allow(view).to receive(:signed_in?).and_return(signed_in)
- assign(:presenter, presenter)
+ allow(Hyrax.config).to receive(:realtime_notifications?).and_return(realtime_notifications)
+ allow(view).to receive(:on_the_dashboard?).and_return(false)
+ allow(controller).to receive(:current_user).and_return(current_user)
allow(controller).to receive(:current_ability).and_return(ability)
+ allow(presenter).to receive(:display_share_button?).and_return(true)
+ stub_template "_controls.html.erb" => "controls"
+ stub_template "_masthead.html.erb" => "masthead"
+ render template: 'hyrax/homepage/index', layout: 'layouts/homepage'
+ end
+
+ context 'when signed in' do
+ let(:signed_in) { true }
+ let(:current_user) { create(:user) }
+
+ it 'renders' do
+ expect(rendered).to have_selector('meta[name="current-user"]', visible: false)
+ end
+
+ context 'when realtime notifications are disabled' do
+ let(:realtime_notifications) { false }
+
+ it 'does not render' do
+ expect(rendered).not_to have_selector('meta[name="current-user"]', visible: false)
+ end
+ end
+ end
+
+ context 'when not signed in' do
+ let(:signed_in) { false }
+ let(:current_user) { nil }
+
+ it 'does not render' do
+ expect(rendered).not_to have_selector('meta[name="current-user"]', visible: false)
+ end
+ end
+ end
+
+ describe "share your work button" do
+ before do
allow(presenter).to receive(:display_share_button?).and_return(display_share_button)
- stub_template "hyrax/homepage/_marketing.html.erb" => "marketing"
- stub_template "hyrax/homepage/_home_content.html.erb" => "home content"
render
end
diff --git a/spec/views/pages/show.html.erb_spec.rb b/spec/views/pages/show.html.erb_spec.rb
index d6adc39af4..8732b09b86 100644
--- a/spec/views/pages/show.html.erb_spec.rb
+++ b/spec/views/pages/show.html.erb_spec.rb
@@ -3,6 +3,7 @@
before do
assign(:page, content_block)
+ allow(view).to receive(:signed_in?)
allow(view).to receive(:displayable_content_block)
allow(view).to receive(:can?).and_return(false)
stub_template 'catalog/_search_form.html.erb' => ''
diff --git a/template.rb b/template.rb
index 034ffad4ca..19bd226559 100644
--- a/template.rb
+++ b/template.rb
@@ -1,4 +1,4 @@
-gem 'hyrax', '2.0.0.beta2'
+gem 'hyrax', '2.0.0.beta3'
run 'bundle install'
generate 'hyrax:install', '-f'
rails_command 'db:migrate'