diff --git a/app/services/repository_rows/create_repository_row_service.rb b/app/services/repository_rows/create_repository_row_service.rb new file mode 100644 index 000000000..87c601b0c --- /dev/null +++ b/app/services/repository_rows/create_repository_row_service.rb @@ -0,0 +1,61 @@ +# frozen_string_literal: true + +module RepositoryRows + class CreateRepositoryRowService + extend Service + + attr_reader :repository, :params, :errors, :repository_row + + def initialize(repository:, user:, params:) + @repository = repository + @user = user + @params = params + @errors = {} + @repository_row = nil + end + + def call + return self unless valid? + + ActiveRecord::Base.transaction do + @repository_row = RepositoryRow.new(params[:repository_row]) + @repository_row.repository = @repository + @repository_row.last_modified_by = @user + @repository_row.created_by = @user + @repository_row.save! + + params[:repository_cells]&.each do |column_id, value| + column = @repository.repository_columns.find_by(id: column_id) + next unless column + + RepositoryCell.create_with_value!(@repository_row, column, value, @user) + end + rescue ActiveRecord::RecordInvalid => e + @errors[e.record.class.name.underscore] = e.record.errors.full_messages + raise ActiveRecord::Rollback + end + + self + end + + def succeed? + @errors.none? + end + + private + + def valid? + unless @user && @repository && @params + @errors[:invalid_arguments] = + { 'repository': @repository, + 'params': @params, + 'user': @user } + .map do |key, value| + I18n.t('repositories.multiple_share_service.invalid_arguments', key: key.capitalize) if value.nil? + end.compact + return false + end + true + end + end +end diff --git a/spec/services/repository_rows/create_repository_row_service_spec.rb b/spec/services/repository_rows/create_repository_row_service_spec.rb new file mode 100644 index 000000000..109885e2d --- /dev/null +++ b/spec/services/repository_rows/create_repository_row_service_spec.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +require 'rails_helper' + +describe RepositoryRows::CreateRepositoryRowService do + let(:user) { create :user } + let(:repository) { create :repository } + let!(:column) { create :repository_column, :text_type, repository: repository } + let(:service_call) do + RepositoryRows::CreateRepositoryRowService + .call(repository: repository, user: user, params: params) + end + + context 'when service succeed' do + let(:params) do + { + repository_cells: Hash[column.id, 'some value'], + repository_row: { + name: 'repo name' + } + } + end + + it 'creates new row' do + expect { service_call }.to change(RepositoryRow, :count).by(1) + end + + it 'creates new cell' do + expect { service_call }.to change(RepositoryCell, :count).by(1) + end + + it 'returns true for succeeded' do + expect(service_call.succeed?).to be_truthy + end + end + + context 'when service does not succeed' do + context 'when repository_row is valid but cell is not' do + let(:params) do + { + repository_cells: Hash[column.id, ''], + repository_row: { name: 'name' } + } + end + + it 'reverts repository_row creation' do + expect { service_call }.not_to(change(RepositoryRow, :count)) + end + end + end +end