Welcome to mirror list, hosted at ThFree Co, Russian Federation.

relation_tree_restorer_spec.rb « group « import_export « gitlab « lib « spec - gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 495cefa002a0a77a98e816ac7e2a3b1175fd55a5 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
# frozen_string_literal: true

# This spec is a lightweight version of:
#   * project/tree_restorer_spec.rb
#
# In depth testing is being done in the above specs.
# This spec tests that restore project works
# but does not have 100% relation coverage.

require 'spec_helper'

RSpec.describe Gitlab::ImportExport::Group::RelationTreeRestorer, feature_category: :importers do
  let(:group) { create(:group).tap { |g| g.add_owner(user) } }
  let(:importable) { create(:group, parent: group) }

  include_context 'relation tree restorer shared context' do
    let(:importable_name) { 'groups/4353' }
  end

  let(:path) { Rails.root.join('spec/fixtures/lib/gitlab/import_export/group_exports/no_children/tree') }
  let(:relation_reader) do
    Gitlab::ImportExport::Json::NdjsonReader.new(path)
  end

  let(:reader) do
    Gitlab::ImportExport::Reader.new(
      shared: shared,
      config: Gitlab::ImportExport::Config.new(config: Gitlab::ImportExport.group_config_file).to_h
    )
  end

  let(:members_mapper) do
    Gitlab::ImportExport::MembersMapper.new(
      exported_members: relation_reader.consume_relation(importable_name, 'members').map(&:first),
      user: user,
      importable: importable
    )
  end

  let(:relation_tree_restorer) do
    described_class.new(
      user: user,
      shared: shared,
      relation_reader: relation_reader,
      object_builder: Gitlab::ImportExport::Group::ObjectBuilder,
      members_mapper: members_mapper,
      relation_factory: Gitlab::ImportExport::Group::RelationFactory,
      reader: reader,
      importable: importable,
      importable_path: importable_name,
      importable_attributes: attributes
    )
  end

  subject { relation_tree_restorer.restore }

  it 'restores group tree' do
    expect(subject).to eq(true)
  end

  it 'logs top-level relation creation' do
    expect(shared.logger)
      .to receive(:info)
      .with(hash_including(message: '[Project/Group Import] Created new object relation'))
      .at_least(:once)

    subject
  end

  describe 'relation object saving' do
    before do
      allow(shared.logger).to receive(:info).and_call_original
      allow(relation_reader).to receive(:consume_relation).and_call_original

      allow(relation_reader)
        .to receive(:consume_relation)
        .with(importable_name, 'labels')
        .and_return([[label, 0]])
    end

    context 'when relation object is new' do
      context 'when relation object has invalid subrelations' do
        let(:label) do
          {
            'title' => 'test',
            'priorities' => [LabelPriority.new, LabelPriority.new],
            'type' => 'GroupLabel'
          }
        end

        it 'logs invalid subrelations' do
          expect(shared.logger)
            .to receive(:info)
            .with(
              message: '[Project/Group Import] Invalid subrelation',
              group_id: importable.id,
              relation_key: 'labels',
              error_messages: "Project can't be blank, Priority can't be blank, and Priority is not a number"
            )

          subject

          label = importable.labels.first
          failure = importable.import_failures.first

          expect(importable.import_failures.count).to eq(2)
          expect(label.title).to eq('test')
          expect(failure.exception_class).to eq('ActiveRecord::RecordInvalid')
          expect(failure.source).to eq('RelationTreeRestorer#save_relation_object')
          expect(failure.exception_message)
            .to eq("Project can't be blank, Priority can't be blank, and Priority is not a number")
        end
      end
    end

    context 'when relation object is persisted' do
      context 'when relation object is invalid' do
        let(:label) { create(:group_label, group: group, title: 'test') }

        it 'saves import failure with nested errors' do
          label.priorities << [LabelPriority.new, LabelPriority.new]

          subject

          failure = importable.import_failures.first

          expect(importable.labels.count).to eq(0)
          expect(importable.import_failures.count).to eq(1)
          expect(failure.exception_class).to eq('ActiveRecord::RecordInvalid')
          expect(failure.source).to eq('process_relation_item!')
          expect(failure.exception_message)
            .to eq("Validation failed: Priorities is invalid, Project can't be blank, Priority can't be blank, " \
                   "Priority is not a number, Project can't be blank, Priority can't be blank, " \
                   "Priority is not a number")
        end
      end
    end
  end
end