Add service for multiple share

This commit is contained in:
Urban Rotnik 2019-08-06 11:16:58 +02:00
parent 2648521924
commit 6cbece9f86
2 changed files with 238 additions and 0 deletions

View file

@ -0,0 +1,107 @@
# frozen_string_literal: true
module Repositories
class MultipleShareUpdateService
extend Service
include Canaid::Helpers::PermissionsHelper
attr_reader :repository, :user, :errors
def initialize(repository_id:,
user_id:,
team_id:,
team_ids_for_share: [],
team_ids_for_unshare: [],
team_ids_for_update: [])
@repository = Repository.find_by_id repository_id
@user = User.find_by_id user_id
@team = Team.find_by_id team_id
@team_ids_for_share = team_ids_for_share
@team_ids_for_unshare = team_ids_for_unshare
@team_ids_for_update = team_ids_for_update
@errors = { shares: [] }
end
def call
return self unless valid?
@team_ids_for_share.each do |share|
team_repository = TeamRepository.new(repository: @repository,
team_id: share[:id],
permission_level: share[:permission_level])
if team_repository.save
log_activity(:share_inventory, team_repository)
else
@errors[:shares] << I18n.t('repositories.multiple_share_service.unable_to_share',
repository: @repository.name, team: share[:id])
end
end
@team_ids_for_unshare.each do |unshare|
team_repository = TeamRepository.where(repository: @repository, team_id: unshare[:id]).first
if team_repository
log_activity(:unshare_inventory, team_repository)
team_repository.destroy
else
@errors[:shares] << I18n.t('repositories.multiple_share_service.unable_to_unshare',
repository: @repository.name, team: unshare[:id])
end
end
@team_ids_for_update.each do |update|
team_repository = TeamRepository.where(repository: @repository, team_id: update[:id]).first
team_repository.permission_level = update[:permission_level] if team_repository
if team_repository&.save
log_activity(:update_share_inventory, team_repository)
else
@errors[:shares] << I18n.t('repositories.multiple_share_service.unable_to_update',
repository: @repository.name, team: update[:id])
end
end
self
end
def succeed?
# Shares are not errors but more like warnings.
@errors.except(:shares).none?
end
private
def valid?
unless @user && @repository
@errors[:invalid_arguments] =
{ 'repository': @repository,
'user': @user,
'team': @team }
.map do |key, value|
"Can't find #{key.capitalize}" if value.nil?
end.compact
return false
end
if can_manage_repository?(@user, @repository)
true
else
@errors[:user_without_permissions] =
['You are not allowed to share this repository']
false
end
end
def log_activity(type_of, team_repository)
Activities::CreateActivityService
.call(activity_type: type_of,
owner: @user,
subject: team_repository.repository,
team: @team,
message_items: { repository: team_repository.repository.id,
team: team_repository.team.id,
permission_level: team_repository.permission_level })
end
end
end

View file

@ -0,0 +1,131 @@
# frozen_string_literal: true
require 'rails_helper'
describe Repositories::MultipleShareUpdateService do
let(:user) { create :user }
let!(:user_team) { create :user_team, :admin, user: user, team: team }
let(:team) { create :team }
let(:team2) { create :team }
let(:team3) { create :team }
let(:repository) { create :repository, team: team }
context 'when user do not have permissions' do
it 'returns error about permissions' do
new_repo = create :repository
service_call = Repositories::MultipleShareUpdateService.call(repository_id: new_repo.id,
user_id: user.id,
team_id: team.id)
expect(service_call.errors).to have_key(:user_without_permissions)
end
end
context 'when repository not found' do
it 'returns error about repository' do
service_call = Repositories::MultipleShareUpdateService.call(repository_id: -1,
user_id: user.id,
team_id: team.id)
expect(service_call.errors).to have_key(:invalid_arguments)
end
end
context 'when share' do
let(:service_call) do
Repositories::MultipleShareUpdateService.call(repository_id: repository.id,
user_id: user.id,
team_id: team.id,
team_ids_for_share: [{ id: team2.id, permission_level: 'read' }])
end
it 'adds TeamRepository record' do
expect { service_call }.to change { TeamRepository.count }.by(1)
end
it 'adds Activity record' do
expect { service_call }.to(change { Activity.all.count }.by(1))
end
context 'when cannot generate share' do
let(:service_call) do
Repositories::MultipleShareUpdateService.call(repository_id: repository.id,
user_id: user.id,
team_id: team.id,
team_ids_for_share: [{ id: -1, permission_level: 'read' }])
end
it 'returns error' do
expect(service_call.errors[:shares].count).to eq(1)
end
end
end
context 'when unshare' do
let(:service_call) do
Repositories::MultipleShareUpdateService.call(repository_id: repository.id,
user_id: user.id,
team_id: team.id,
team_ids_for_unshare: [{ id: team2.id }])
end
it 'removes TeamRepository record' do
create :team_repository, :write, team: team2, repository: repository
expect { service_call }.to change { TeamRepository.count }.by(-1)
end
it 'adds Activity record' do
create :team_repository, :write, team: team2, repository: repository
expect { service_call }.to(change { Activity.all.count }.by(1))
end
context 'when cannot delete share' do
let(:service_call) do
Repositories::MultipleShareUpdateService.call(repository_id: repository.id,
user_id: user.id,
team_id: team.id,
team_ids_for_unshare: [{ id: -1 }])
end
it 'returns error' do
expect(service_call.errors[:shares].count).to eq(1)
end
end
end
context 'when updates share permissions' do
let(:service_call) do
Repositories::MultipleShareUpdateService.call(repository_id: repository.id,
user_id: user.id,
team_id: team.id,
team_ids_for_update: [{ id: team2.id, permission_level: 'read' }])
end
it 'updates permission for share record' do
tr = create :team_repository, :write, team: team2, repository: repository
expect { service_call }.to(change { tr.reload.permission_level })
end
it 'adds Activity record' do
create :team_repository, :write, team: team2, repository: repository
expect { service_call }.to(change { Activity.all.count }.by(1))
end
context 'when cannot update share' do
let(:service_call) do
Repositories::MultipleShareUpdateService.call(repository_id: repository.id,
user_id: user.id,
team_id: team.id,
team_ids_for_update: [{ id: -1, permission_level: 'read' }])
end
it 'returns error' do
expect(service_call.errors[:shares].count).to eq(1)
end
end
end
end