From 9989c18c4cdb7dc0175e28c560d16d5861d69f3d Mon Sep 17 00:00:00 2001 From: "James R. Griffin III" <1443986+jrgriffiniii@users.noreply.github.com> Date: Tue, 19 Sep 2023 10:03:03 -0400 Subject: [PATCH] Ensuring that the JSON-serialized Works render the Solr-formatted embargo dates and hide file attachments (#1517) --- app/models/work.rb | 58 +++++++++++++++++++++++--------- spec/models/work_spec.rb | 71 ++++++++++++++++++++++++++++++++++++++-- 2 files changed, 111 insertions(+), 18 deletions(-) diff --git a/app/models/work.rb b/app/models/work.rb index 9c3775a1..5c6699f4 100644 --- a/app/models/work.rb +++ b/app/models/work.rb @@ -371,7 +371,7 @@ def file_list "size": s3_file.size, "display_size": s3_file.display_size, "url": s3_file.url - } + } end files_info end @@ -434,25 +434,21 @@ def find_post_curation_s3_dir(bucket_name:) nil end + # Generates the JSON serialized expression of the Work + # @param args [Array] + # @option args [Boolean] :force_post_curation Force the request of AWS S3 + # Resources, clearing the in-memory cache + # @return [String] def as_json(*args) - force_post_curation = args.any? {|arg| arg[:force_post_curation] == true } - # Pre-curation files are not accessible externally, - # so we are not interested in listing them in JSON. - files = post_curation_uploads(force_post_curation:).map do |upload| - { - "filename": upload.filename, - "size": upload.size, - "display_size": upload.display_size, - "url": upload.globus_url - } - end + files = files_as_json(*args) # to_json returns a string of serialized JSON. # as_json returns the corresponding hash. { "resource" => resource.as_json, "files" => files, - "group" => group.as_json.except("id") + "group" => group.as_json.except("id"), + "embargo_date" => embargo_date_as_json } end @@ -512,9 +508,11 @@ def track_change(action, filename) changes << { action: action, filename: filename } end + # rubocop:disable Naming/PredicateName def has_rights?(rights_id) resource.rights_many.index { |rights| rights.identifier == rights_id } != nil end + # rubocop:enable Naming/PredicateName # This is the solr id / work show page in PDC Discovery def pdc_discovery_url @@ -592,7 +590,6 @@ def track_state_change(user, state = aasm.to_state) WorkStateTransitionNotification.new(self, user.id).send end - def validate_ark return if ark.blank? return false unless unique_ark @@ -691,12 +688,41 @@ def publish_precurated_files(user) end def latest_snapshot - upload_snapshot = upload_snapshots.first - upload_snapshot ||= UploadSnapshot.new(work: self, files: []) + return upload_snapshots.first unless upload_snapshots.empty? + + UploadSnapshot.new(work: self, files: []) end def datacite_service @datacite_service ||= PULDatacite.new(self) end + + def files_as_json(*args) + return [] if embargoed? + + force_post_curation = args.any? { |arg| arg[:force_post_curation] == true } + + # Pre-curation files are not accessible externally, + # so we are not interested in listing them in JSON. + post_curation_uploads(force_post_curation: force_post_curation).map do |upload| + { + "filename": upload.filename, + "size": upload.size, + "display_size": upload.display_size, + "url": upload.globus_url + } + end + end + + def embargo_date_as_json + if embargo_date.present? + embargo_datetime = embargo_date.to_datetime + embargo_date_iso8601 = embargo_datetime.iso8601 + # Apache Solr timestamps require the following format: + # 1972-05-20T17:33:18Z + # https://solr.apache.org/guide/solr/latest/indexing-guide/date-formatting-math.html + embargo_date_iso8601.gsub(/\+.+$/, "Z") + end + end end # rubocop:enable Metrics/ClassLength diff --git a/spec/models/work_spec.rb b/spec/models/work_spec.rb index eebfbd89..59c59a12 100644 --- a/spec/models/work_spec.rb +++ b/spec/models/work_spec.rb @@ -32,11 +32,12 @@ end context "fixed time" do + let(:embargo_date) { Date.parse("2023-09-14") } before do allow(Time).to receive(:now).and_return(Time.parse("2022-01-01T00:00:00.000Z")) end it "captures everything needed for PDC Describe in JSON" do - work = Work.new(group: group, resource: FactoryBot.build(:tokamak_work)) + work = Work.new(group: group, embargo_date: embargo_date, resource: FactoryBot.build(:tokamak_work)) expect(JSON.parse(work.to_json)).to eq( { "resource" => { @@ -69,7 +70,8 @@ "code" => "RD", "created_at" => "2021-12-31T19:00:00.000-05:00", "updated_at" => "2021-12-31T19:00:00.000-05:00" - } + }, + "embargo_date" => "2023-09-14T00:00:00Z" } ) end @@ -207,6 +209,71 @@ expect(work.as_json["files"][0][:display_size]).to eq("1 KB") expect(work.as_json["files"][0][:url]).to eq "https://example.data.globus.org/10.34770/123-abc/#{work.id}/us_covid_2019.csv" end + + context "when the Work is under active embargo" do + subject(:work) { FactoryBot.create(:awaiting_approval_work, doi: "10.34770/123-abc", embargo_date: embargo_date) } + + let(:embargo_date) { Date.parse("2033-09-14") } + let(:json) { JSON.parse(work.to_json) } + let(:uploaded_file) do + fixture_file_upload("us_covid_2019.csv", "text/csv") + end + let(:uploaded_file2) do + fixture_file_upload("us_covid_2019.csv", "text/csv") + end + + before do + stub_request(:put, /#{attachment_url}/).with( + body: "date,state,fips,cases,deaths\n2020-01-21,Washington,53,1,0\n2022-07-10,Wyoming,56,165619,1834\n" + ).to_return(status: 200) + + stub_datacite_doi + work.approve!(curator_user) + work.reload + end + + it "serializes the embargo date in JSON" do + expect(json).to include("embargo_date") + expect(json["embargo_date"]).to eq("2033-09-14T00:00:00Z") + end + + it "does not serialize the files in JSON" do + expect(work.post_curation_uploads).not_to be_empty + + expect(json).to include("files") + expect(json["files"]).to be_empty + end + end + + context "when the Work is under an expired embargo" do + subject(:work) { FactoryBot.create(:awaiting_approval_work, doi: "10.34770/123-abc", embargo_date: embargo_date) } + + let(:embargo_date) { Date.parse("2023-09-14") } + let(:json) { JSON.parse(work.to_json) } + let(:uploaded_file) do + fixture_file_upload("us_covid_2019.csv", "text/csv") + end + let(:uploaded_file2) do + fixture_file_upload("us_covid_2019.csv", "text/csv") + end + + before do + stub_request(:put, /#{attachment_url}/).with( + body: "date,state,fips,cases,deaths\n2020-01-21,Washington,53,1,0\n2022-07-10,Wyoming,56,165619,1834\n" + ).to_return(status: 200) + + stub_datacite_doi + work.approve!(curator_user) + work.reload + end + + it "does serialize the files in JSON" do + expect(work.post_curation_uploads).not_to be_empty + + expect(json).to include("files") + expect(json["files"]).not_to be_empty + end + end end context "when the doi is empty" do