diff --git a/app/models/repository_object.rb b/app/models/repository_object.rb index 67b144689..fa56688d6 100644 --- a/app/models/repository_object.rb +++ b/app/models/repository_object.rb @@ -76,20 +76,27 @@ def update_opened_version_from(cocina_object:) opened_version.update!(**RepositoryObjectVersion.to_model_hash(cocina_object)) end - def open_version! + def open_version!(description:) raise VersionAlreadyOpened, "Cannot open new version because one is already open: #{head_version.version}" if open? RepositoryObject.transaction do - version_to_open = last_closed_version.dup.tap { |object_version| object_version.version += 1 } + version_to_open = last_closed_version.dup.tap do |object_version| + object_version.version += 1 + object_version.version_description = description + end update!(opened_version: version_to_open, head_version: version_to_open) end end - def close_version! + def close_version!(description: nil) raise VersionNotOpened, "Cannot close version because head version is closed: #{head_version.version}" if closed? RepositoryObject.transaction do - version_to_close = opened_version.tap { |object_version| object_version.closed_at = Time.current } + version_to_close = opened_version.tap do |object_version| + object_version.closed_at = Time.current + object_version.version_description = description if description + end + version_to_close.save! update!(opened_version: nil, last_closed_version: version_to_close, head_version: version_to_close) end end diff --git a/app/services/version_service.rb b/app/services/version_service.rb index 298f68840..2450d4435 100644 --- a/app/services/version_service.rb +++ b/app/services/version_service.rb @@ -82,7 +82,7 @@ def open(cocina_object:, description:, opening_user_name:, assume_accessioned:, # RepositoryObject.find_by!(external_identifier: druid).open_version! repo_obj = RepositoryObject.find_by(external_identifier: druid) repo_obj = RepositoryObjectMigrator.migrate(external_identifier: druid) if repo_obj.nil? && Settings.enabled_features.repository_object_create - repo_obj&.open_version! + repo_obj&.open_version!(description:) # TODO: when we stop calling the UpdateObjectService, after we've migrated to RepostoryObjects, we may need to trigger indexing: # e.g.: Notifications::ObjectUpdated.publish(model: cocina_object_with_metadata) @@ -126,7 +126,7 @@ def close(description:, user_name:, event_factory:, start_accession: true) # TODO: After migrating to RepositoryObjects, we can get rid of the nil check and use: # RepositoryObject.find_by!(external_identifier: druid).close_version! - RepositoryObject.find_by(external_identifier: druid)&.close_version! + RepositoryObject.find_by(external_identifier: druid)&.close_version!(description:) event_factory.create(druid:, event_type: 'version_close', data: { who: user_name, version: version.to_s }) end diff --git a/spec/models/repository_object_spec.rb b/spec/models/repository_object_spec.rb index 2343957de..d04c69f97 100644 --- a/spec/models/repository_object_spec.rb +++ b/spec/models/repository_object_spec.rb @@ -122,8 +122,10 @@ describe '#open_version!' do subject(:repository_object) { create(:repository_object, **attrs) } + let(:description) { 'my new version' } + it 'raises when version is already open' do - expect { repository_object.open_version! }.to raise_error(described_class::VersionAlreadyOpened) + expect { repository_object.open_version!(description:) }.to raise_error(described_class::VersionAlreadyOpened) end context 'when closed' do @@ -132,11 +134,12 @@ end it 'creates a new version and updates the head and opened version pointers' do - expect { repository_object.open_version! }.to change(RepositoryObjectVersion, :count).by(1) + expect { repository_object.open_version!(description:) }.to change(RepositoryObjectVersion, :count).by(1) newly_created_version = repository_object.versions.last expect(newly_created_version.version).to eq(2) expect(repository_object.head_version).to eq(newly_created_version) expect(repository_object.opened_version).to eq(newly_created_version) + expect(newly_created_version.version_description).to eq(description) end end end @@ -144,6 +147,8 @@ describe '#close_version!' do subject(:repository_object) { create(:repository_object, **attrs) } + let(:description) { 'my closed version' } + it 'sets the closed_at field' do expect { repository_object.close_version! }.to change(repository_object.head_version, :closed_at).to(instance_of(ActiveSupport::TimeWithZone)) end @@ -156,6 +161,11 @@ expect(repository_object.opened_version).to be_nil end + it 'updates the version description' do + repository_object.close_version!(description:) + expect(repository_object.head_version.version_description).to eq(description) + end + context 'when closed' do before do repository_object.close_version! diff --git a/spec/services/version_service_spec.rb b/spec/services/version_service_spec.rb index 911588b60..ac3bea10a 100644 --- a/spec/services/version_service_spec.rb +++ b/spec/services/version_service_spec.rb @@ -55,6 +55,7 @@ druid:, event_type: 'version_open') expect(repository_object.reload.opened_version.version).to eq 2 + expect(repository_object.opened_version.version_description).to eq 'same as it ever was' end end @@ -251,6 +252,7 @@ before do repository_object&.save! # This can be removed after we fully migrate to RepositoryObjects + repository_object&.head_version&.update!(version: 2, version_description: 'A Second Version') allow(WorkflowClientFactory).to receive(:build).and_return(workflow_client) ObjectVersion.create(druid:, version: 1, description: 'Initial Version') ObjectVersion.create(druid:, version: 2, description: 'A Second Version') @@ -265,6 +267,7 @@ it 'sets description and an event' do close expect(repository_object.reload.last_closed_version).to be_present + expect(repository_object.last_closed_version.version_description).to eq('closing text') object_version = ObjectVersion.find_by(druid:, version: 2) expect(object_version.description).to eq('closing text') @@ -347,6 +350,7 @@ it 'closes the object version using existing signficance and description' do close expect(repository_object.reload.last_closed_version).to be_present + expect(repository_object.last_closed_version.version_description).to eq 'A Second Version' object_version = ObjectVersion.find_by(druid:, version: 2) expect(object_version.description).to eq 'A Second Version' expect(workflow_client).to have_received(:close_version)