diff options
Diffstat (limited to 'spec/factories/design_management/versions.rb')
-rw-r--r-- | spec/factories/design_management/versions.rb | 142 |
1 files changed, 142 insertions, 0 deletions
diff --git a/spec/factories/design_management/versions.rb b/spec/factories/design_management/versions.rb new file mode 100644 index 00000000000..878665e02e5 --- /dev/null +++ b/spec/factories/design_management/versions.rb @@ -0,0 +1,142 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :design_version, class: 'DesignManagement::Version' do + sequence(:sha) { |n| Digest::SHA1.hexdigest("commit-like-#{n}") } + 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.zero? || 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 |