diff --git a/app/controllers/works_controller.rb b/app/controllers/works_controller.rb index 154b866ea..6e3fb2316 100644 --- a/app/controllers/works_controller.rb +++ b/app/controllers/works_controller.rb @@ -88,9 +88,13 @@ def resolve_ark def edit @work = Work.find(params[:id]) if current_user && @work.editable_by?(current_user) - @uploads = @work.uploads - @wizard_mode = wizard_mode? - render "edit" + if @work.approved? && @work.submitted_by?(current_user) + redirect_to root_path, notice: I18n.t("works.approved.uneditable") + else + @uploads = @work.uploads + @wizard_mode = wizard_mode? + render "edit" + end else Rails.logger.warn("Unauthorized attempt to edit work #{@work.id} by user #{current_user.uid}") redirect_to root_path diff --git a/app/models/work.rb b/app/models/work.rb index d2abb20c9..7ab328ed5 100644 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -60,12 +60,16 @@ class Work < ApplicationRecord # @param [User] # @return [Boolean] def editable_by?(user) - return true if created_by_user_id == user.id + return true if submitted_by?(user) collection = Collection.find(collection_id) return true if user.has_role?(:collection_admin, collection) false end + def submitted_by?(user) + return true if created_by_user_id == user.id + end + class << self def unfinished_works(user) works_by_user_state(user, ["none", "draft", "awaiting_approval"]) diff --git a/config/locales/en.yml b/config/locales/en.yml index df854270f..9399a2b87 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -58,3 +58,5 @@ en: replace_upload: "Replace Upload" empty: "No files in S3" delete_upload: "Delete Upload" + approved: + uneditable: "This work has been approved. Edits are no longer available." diff --git a/spec/controllers/works_controller_spec.rb b/spec/controllers/works_controller_spec.rb index 149b10747..7e172388a 100644 --- a/spec/controllers/works_controller_spec.rb +++ b/spec/controllers/works_controller_spec.rb @@ -61,12 +61,6 @@ expect(response.location.start_with?("http://test.host/works/")).to be true end - it "renders the edit page on edit" do - sign_in user - get :edit, params: { id: work.id } - expect(response).to render_template("edit") - end - it "handles the update page" do params = { "title_main" => "test dataset updated", @@ -1161,4 +1155,52 @@ end end end + + describe "#edit" do + it "renders the edit page on edit" do + sign_in user + get :edit, params: { id: work.id } + expect(response).to render_template("edit") + end + + context "the work is approved" do + let(:work) { FactoryBot.create :approved_work } + context "the submitter" do + let(:user) { work.created_by_user } + + it "redirects the home page on edit with informational message" do + sign_in user + get :edit, params: { id: work.id } + expect(response).to redirect_to(root_path) + expect(controller.flash[:notice]).to eq("This work has been approved. Edits are no longer available.") + end + end + context "another user" do + let(:other_user) { FactoryBot.create(:user) } + it "redirects the home page on edit" do + sign_in other_user + get :edit, params: { id: work.id } + expect(response).to redirect_to(root_path) + end + end + context "a curator" do + let(:user) { FactoryBot.create(:research_data_moderator) } + it "renders the edit page on edit" do + stub_s3 + sign_in user + get :edit, params: { id: work.id } + expect(response).to render_template("edit") + end + end + context "a super admin" do + let(:user) { FactoryBot.create(:super_admin_user) } + it "renders the edit page on edit" do + stub_s3 + sign_in user + get :edit, params: { id: work.id } + expect(response).to render_template("edit") + end + end + end + end end diff --git a/spec/factories/work.rb b/spec/factories/work.rb index 173d0ebe5..0ac06a733 100644 --- a/spec/factories/work.rb +++ b/spec/factories/work.rb @@ -23,6 +23,17 @@ resource { FactoryBot.build :resource, doi: doi, ark: ark } end + factory :approved_work do + transient do + doi { "10.34770/123-abc" } + ark { nil } + end + collection { Collection.research_data } + state { "approved" } + created_by_user_id { FactoryBot.create(:user).id } + resource { FactoryBot.build :resource, doi: doi, ark: ark } + end + factory :shakespeare_and_company_work do collection { Collection.research_data } resource do