mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2024-12-26 17:51:13 +08:00
Add service for multiple share
This commit is contained in:
parent
2648521924
commit
6cbece9f86
2 changed files with 238 additions and 0 deletions
107
app/services/repositories/multiple_share_update_service.rb
Normal file
107
app/services/repositories/multiple_share_update_service.rb
Normal 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
|
131
spec/services/repositories/multiple_share_update_service_spec.rb
Normal file
131
spec/services/repositories/multiple_share_update_service_spec.rb
Normal 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
|
Loading…
Reference in a new issue