Skip to content

Commit

Permalink
Refactor ProjectMediaflux tests (#709)
Browse files Browse the repository at this point in the history
By actually connecting to MediaFlux we catch some errors that we were
otherwise missing. Also, it'll make it easier to extend this class
without needing to re-create our mocked interactions every time.
  • Loading branch information
bess authored May 10, 2024
1 parent 5ba9f89 commit 4b84902
Show file tree
Hide file tree
Showing 2 changed files with 67 additions and 51 deletions.
6 changes: 5 additions & 1 deletion app/models/project_mediaflux.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# frozen_string_literal: true

# A custom exception class for when a namespace path is already taken
class MediafluxDuplicateNamespaceError < StandardError
end

# Take an instance of Project and adds it to MediaFlux
class ProjectMediaflux
# Create a project in MediaFlux
Expand All @@ -20,7 +24,7 @@ def self.create!(project:, session_id:, xml_namespace: nil)
project_namespace = "#{project_name}NS"
namespace = Mediaflux::Http::NamespaceCreateRequest.new(namespace: project_namespace, description: "Namespace for project #{project.title}", store: store_name, session_token: session_id)
if namespace.error?
raise "Can not create the namespace #{namespace.response_error}"
raise MediafluxDuplicateNamespaceError.new("Can not create the namespace #{namespace.response_error}")
end
# Create a collection asset under the root namespace and set its metadata
tigerdata_values = project_values(project: project)
Expand Down
112 changes: 62 additions & 50 deletions spec/models/project_mediaflux_spec.rb
Original file line number Diff line number Diff line change
@@ -1,80 +1,92 @@
# frozen_string_literal: true
require "rails_helper"

RSpec.describe ProjectMediaflux, type: :model, stub_mediaflux: true do
let(:namespace_request) { instance_double(Mediaflux::Http::NamespaceCreateRequest, resolve: true, "error?": false) }
let(:collection_request) { instance_double(Mediaflux::Http::AssetCreateRequest, id: 123) }
let(:metadata_request) { instance_double(Mediaflux::Http::AssetMetadataRequest, metadata: collection_metadata) }
let(:parent_metadata_request) { instance_double(Mediaflux::Http::AssetMetadataRequest, "error?": false) }
RSpec.describe ProjectMediaflux, type: :model do
let(:collection_metadata) { { id: "abc", name: "test", path: "td-demo-001/rc/test-ns/test", description: "description", namespace: "td-demo-001/rc/test-ns" } }
let(:project) { FactoryBot.build :project }
let(:project) { FactoryBot.build :project_with_doi }
let(:current_user) { FactoryBot.create(:user, uid: "jh1234") }
let(:asset_create_request) { instance_double(Mediaflux::Http::AssetMetadataRequest) }

describe "#create!" do
describe "#create!", connect_to_mediaflux: true do
context "Using test data" do
before do
allow(Mediaflux::Http::NamespaceCreateRequest).to receive(:new).with(session_token: "test-session-token",
namespace: "/td-test-001/tigerdataNS/big-dataNS",
description: "Namespace for project #{project.title}",
store: "db").and_return(namespace_request)
allow(Mediaflux::Http::AssetCreateRequest).to receive(:new).with(hash_including(session_token: "test-session-token", name: "big-data",
namespace: "/td-test-001/tigerdataNS/big-dataNS",
pid: "path=/td-test-001/tigerdata")).and_return(asset_create_request)
allow(Mediaflux::Http::AssetMetadataRequest).to receive(:new).with(hash_including(session_token: "test-session-token",
id: "path=/td-test-001/tigerdata")).and_return(parent_metadata_request)
allow(asset_create_request).to receive(:resolve).and_return("<xml>...")
allow(asset_create_request).to receive(:id).and_return("123")
end

context "it formats dates correctly for MediaFlux" do
let(:project) { FactoryBot.build(:project, created_on: "2024-02-22T13:57:19-05:00", updated_on: "2024-02-26T13:57:19-05:00") }
let(:project_values) { described_class.project_values(project: project) }
# Mediaflux date format is like " 9-FEB-2024 14:53:23"
let(:date_regexp) { /\d-[A-Z]{3}-\d{4} \d{2}:\d{2}:\d{2}/ }
it "formats created_on as expected" do
project_values = ProjectMediaflux.project_values(project: project)
expect(project_values[:created_on]).to eq "22-FEB-2024 13:57:19"
created_on = project_values[:created_on].strip
expect(created_on.match?(date_regexp)).to eq true
end
it "formats updated_on as expected" do
project_values = ProjectMediaflux.project_values(project: project)
expect(project_values[:updated_on]).to eq "26-FEB-2024 13:57:19"
updated_on = project_values[:updated_on].strip
expect(updated_on.match?(date_regexp)).to eq true
end
end

it "creates a project namespace and collection and returns the mediaflux id" do
mediaflux_id = described_class.create!(project: project, session_id: "test-session-token")
expect(namespace_request).to have_received("error?")
expect(parent_metadata_request).to have_received("error?")
expect(asset_create_request).to have_received("id")
expect(mediaflux_id).to be "123"
mediaflux_id = described_class.create!(project: project, session_id: current_user.mediaflux_session)
mediaflux_metadata = Mediaflux::Http::AssetMetadataRequest.new(
session_token: current_user.mediaflux_session,
id: mediaflux_id
).metadata
namespace_path = mediaflux_metadata[:namespace]
namespace_metadata = Mediaflux::Http::NamespaceDescribeRequest.new(
session_token: current_user.mediaflux_session,
path: namespace_path
).metadata
expect(namespace_metadata[:description]).to match(/Namespace for/)
end

context "when the name is already taken" do
before do
allow(asset_create_request).to receive(:id).and_return(nil)
allow(asset_create_request).to receive(:response_error).and_return({message: "call to service 'asset.create' failed: The namespace /td-test-001/tigerdataNS/big-dataNS already contains an asset named 'big-data'"})
end

it "raises an error" do
# Make the project once
described_class.create!(project: project, session_id: current_user.mediaflux_session)
# It should raise a duplicate namespace error the second time
expect do
described_class.create!(project: project, session_id: "test-session-token")
end.to raise_error(StandardError) #Raises standard error when a duplicate project already exists
described_class.create!(project: project, session_id: current_user.mediaflux_session)
end.to raise_error(MediafluxDuplicateNamespaceError) # Raises custom error when a duplicate project already exists
end
end

context "when the parent colllection does not exist" do
let(:parent_metadata_request) { instance_double(Mediaflux::Http::AssetMetadataRequest, metadata: {}, "error?": true) }
let(:parent_collection_request) { instance_double(Mediaflux::Http::AssetCreateRequest, id: 567, "error?": false) }
let(:mediaflux_id) { described_class.create!(
project: project,
session_id: current_user.mediaflux_session) }
let(:mediaflux_metadata) do
Mediaflux::Http::AssetMetadataRequest.new(
session_token: current_user.mediaflux_session,
id: mediaflux_id
).metadata
end
let(:project_parent) { Rails.configuration.mediaflux["api_root_collection"] }

before do
allow(Mediaflux::Http::AssetCreateRequest).to receive(:new).with(hash_including(session_token: "test-session-token", name: "tigerdata",
namespace: "/td-test-001")).and_return(parent_collection_request)
# Destroy the parent collection
Mediaflux::Http::NamespaceDestroyRequest.new(
session_token: current_user.mediaflux_session,
namespace: project_parent
).destroy
end

it "creates a project namespace and collection and parent collection and returns the mediaflux id" do
mediaflux_id = described_class.create!(project: project, session_id: "test-session-token")
expect(namespace_request).to have_received("error?")
expect(parent_collection_request).to have_received("error?")
expect(asset_create_request).to have_received("id")
expect(mediaflux_id).to be "123"
it "creates a project namespace" do
namespace_path = mediaflux_metadata[:namespace]
namespace_metadata = Mediaflux::Http::NamespaceDescribeRequest.new(
session_token: current_user.mediaflux_session,
path: namespace_path
).metadata

expect(namespace_metadata[:description]).to match(/Namespace for/)
end

it "creates a collection" do
expect(mediaflux_metadata[:collection]).to eq true
end

it "creates a parent collection" do
parent_collection_metadata = Mediaflux::Http::AssetMetadataRequest.new(
session_token: current_user.mediaflux_session,
id: project_parent
).metadata
expect(parent_collection_metadata[:path]).to eq project_parent.gsub("path=",'')
end
end
end
Expand Down Expand Up @@ -124,7 +136,7 @@

#raise an error & log what was returned from mediaflux
expect {
collection_id = ProjectMediaflux.create!(project: incomplete_project, session_id: session_token)
ProjectMediaflux.create!(project: incomplete_project, session_id: session_token)
}.to raise_error do |error|
expect(error).to be_a(StandardError)
expect(error.message).to include("call to service 'asset.create' failed: XPath tigerdata:project/ProjectID is invalid: missing value")
Expand Down

0 comments on commit 4b84902

Please sign in to comment.