142 lines
4.2 KiB
Ruby
142 lines
4.2 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
FactoryBot.define do
|
|
factory :design_version, class: 'DesignManagement::Version' do
|
|
sha
|
|
issue { designs.first&.issue || create(:issue) }
|
|
author { issue&.author || create(:user) }
|
|
|
|
transient do
|
|
designs_count { 1 }
|
|
created_designs { [] }
|
|
modified_designs { [] }
|
|
deleted_designs { [] }
|
|
end
|
|
|
|
# Warning: this will intentionally result in an invalid version!
|
|
trait :empty do
|
|
designs_count { 0 }
|
|
end
|
|
|
|
trait :importing do
|
|
issue { nil }
|
|
|
|
designs_count { 0 }
|
|
importing { true }
|
|
imported { false }
|
|
end
|
|
|
|
trait :imported do
|
|
importing { false }
|
|
imported { true }
|
|
end
|
|
|
|
after(:build) do |version, evaluator|
|
|
# By default all designs are created_designs, so just add them.
|
|
specific_designs = [].concat(
|
|
evaluator.created_designs,
|
|
evaluator.modified_designs,
|
|
evaluator.deleted_designs
|
|
)
|
|
version.designs += specific_designs
|
|
|
|
unless evaluator.designs_count == 0 || version.designs.present?
|
|
version.designs << create(:design, issue: version.issue)
|
|
end
|
|
end
|
|
|
|
after :create do |version, evaluator|
|
|
# FactoryBot does not like methods, so we use lambdas instead
|
|
events = DesignManagement::Action.events
|
|
|
|
version.actions
|
|
.where(design_id: evaluator.modified_designs.map(&:id))
|
|
.update_all(event: events[:modification])
|
|
|
|
version.actions
|
|
.where(design_id: evaluator.deleted_designs.map(&:id))
|
|
.update_all(event: events[:deletion])
|
|
|
|
version.designs.reload
|
|
# Ensure version.issue == design.issue for all version.designs
|
|
version.designs.update_all(issue_id: version.issue_id)
|
|
|
|
needed = evaluator.designs_count
|
|
have = version.designs.size
|
|
|
|
create_list(:design, [0, needed - have].max, issue: version.issue).each do |d|
|
|
version.designs << d
|
|
end
|
|
|
|
version.actions.reset
|
|
end
|
|
|
|
# Use this trait to build versions with designs that are backed by Git LFS, committed
|
|
# to the repository, and with an LfsObject correctly created for it.
|
|
trait :with_lfs_file do
|
|
committed
|
|
|
|
transient do
|
|
raw_file { fixture_file_upload('spec/fixtures/dk.png', 'image/png') }
|
|
lfs_pointer { Gitlab::Git::LfsPointerFile.new(SecureRandom.random_bytes) }
|
|
file { lfs_pointer.pointer }
|
|
end
|
|
|
|
after :create do |version, evaluator|
|
|
lfs_object = create(:lfs_object, file: evaluator.raw_file, oid: evaluator.lfs_pointer.sha256, size: evaluator.lfs_pointer.size)
|
|
create(:lfs_objects_project, project: version.project, lfs_object: lfs_object, repository_type: :design)
|
|
end
|
|
end
|
|
|
|
# This trait is for versions that must be present in the git repository.
|
|
trait :committed do
|
|
transient do
|
|
file { File.join(Rails.root, 'spec/fixtures/dk.png') }
|
|
end
|
|
|
|
after :create do |version, evaluator|
|
|
project = version.issue.project
|
|
repository = project.design_repository
|
|
repository.create_if_not_exists
|
|
|
|
designs = version.designs_by_event
|
|
base_change = { content: evaluator.file }
|
|
|
|
actions = %w[modification deletion].flat_map { |k| designs.fetch(k, []) }.map do |design|
|
|
base_change.merge(action: :create, file_path: design.full_path)
|
|
end
|
|
|
|
if actions.present?
|
|
repository.multi_action(
|
|
evaluator.author,
|
|
branch_name: 'master',
|
|
message: "created #{actions.size} files",
|
|
actions: actions
|
|
)
|
|
end
|
|
|
|
mapping = {
|
|
'creation' => :create,
|
|
'modification' => :update,
|
|
'deletion' => :delete
|
|
}
|
|
|
|
version_actions = designs.flat_map do |(event, designs)|
|
|
base = event == 'deletion' ? {} : base_change
|
|
designs.map do |design|
|
|
base.merge(action: mapping[event], file_path: design.full_path)
|
|
end
|
|
end
|
|
|
|
sha = repository.multi_action(
|
|
evaluator.author,
|
|
branch_name: 'master',
|
|
message: "edited #{version_actions.size} files",
|
|
actions: version_actions
|
|
)
|
|
|
|
version.update!(sha: sha)
|
|
end
|
|
end
|
|
end
|
|
end
|