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

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-03-17 21:09:44 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-03-17 21:09:44 +0300
commit2c156e3c7bbade01c36eee18327f1ced6eebea79 (patch)
tree115fa8dbf6bc05037378b380311d31acb805f54c /spec/lib/gitlab
parent8e129497b2565b8c595ef4f806d9a9595ca654e5 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec/lib/gitlab')
-rw-r--r--spec/lib/gitlab/ci/config/entry/reports_spec.rb1
-rw-r--r--spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb176
-rw-r--r--spec/lib/gitlab/ci/parsers_spec.rb10
-rw-r--r--spec/lib/gitlab/ci/reports/coverage_reports_spec.rb66
-rw-r--r--spec/lib/gitlab/import_export/group/tree_saver_spec.rb2
-rw-r--r--spec/lib/gitlab/import_export/json/legacy_writer_spec.rb79
-rw-r--r--spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb (renamed from spec/lib/gitlab/import_export/relation_tree_saver_spec.rb)2
-rw-r--r--spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb397
-rw-r--r--spec/lib/gitlab/import_export/project/tree_saver_spec.rb53
9 files changed, 731 insertions, 55 deletions
diff --git a/spec/lib/gitlab/ci/config/entry/reports_spec.rb b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
index 31e1aaa42bf..2c8f76c8f34 100644
--- a/spec/lib/gitlab/ci/config/entry/reports_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/reports_spec.rb
@@ -45,6 +45,7 @@ describe Gitlab::Ci::Config::Entry::Reports do
:performance | 'performance.json'
:lsif | 'lsif.json'
:dotenv | 'build.dotenv'
+ :cobertura | 'cobertura-coverage.xml'
end
with_them do
diff --git a/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb b/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb
new file mode 100644
index 00000000000..e97544683db
--- /dev/null
+++ b/spec/lib/gitlab/ci/parsers/coverage/cobertura_spec.rb
@@ -0,0 +1,176 @@
+# frozen_string_literal: true
+
+require 'fast_spec_helper'
+
+describe Gitlab::Ci::Parsers::Coverage::Cobertura do
+ describe '#parse!' do
+ subject { described_class.new.parse!(cobertura, coverage_report) }
+
+ let(:coverage_report) { Gitlab::Ci::Reports::CoverageReports.new }
+
+ context 'when data is Cobertura style XML' do
+ context 'when there is no <class>' do
+ let(:cobertura) { '' }
+
+ it 'parses XML and returns empty coverage' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'when there is a single <class>' do
+ context 'with no lines' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <classes><class filename="app.rb"></class></classes>
+ EOF
+ end
+
+ it 'parses XML and returns empty coverage' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({})
+ end
+ end
+
+ context 'with a single line' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <classes>
+ <class filename="app.rb"><lines>
+ <line number="1" hits="2"/>
+ </lines></class>
+ </classes>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with coverage' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2 } })
+ end
+ end
+
+ context 'with multipe lines and methods info' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ </classes>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with coverage' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+ end
+
+ context 'when there are multipe <class>' do
+ context 'with the same filename and different lines' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="app.rb"><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with merged coverage' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0, 6 => 1, 7 => 1 } })
+ end
+ end
+
+ context 'with the same filename and lines' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <packages><package><classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="1"/>
+ <line number="2" hits="1"/>
+ </lines></class>
+ </classes></package></packages>
+ EOF
+ end
+
+ it 'parses XML and returns a single file with summed-up coverage' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 3, 2 => 1 } })
+ end
+ end
+
+ context 'with missing filename' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class><methods/><lines>
+ <line number="6" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes>
+ EOF
+ end
+
+ it 'parses XML and ignores class with missing name' do
+ expect { subject }.not_to raise_error
+
+ expect(coverage_report.files).to eq({ 'app.rb' => { 1 => 2, 2 => 0 } })
+ end
+ end
+
+ context 'with invalid line information' do
+ let(:cobertura) do
+ <<-EOF.strip_heredoc
+ <classes>
+ <class filename="app.rb"><methods/><lines>
+ <line number="1" hits="2"/>
+ <line number="2" hits="0"/>
+ </lines></class>
+ <class filename="app.rb"><methods/><lines>
+ <line null="test" hits="1"/>
+ <line number="7" hits="1"/>
+ </lines></class>
+ </classes>
+ EOF
+ end
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(described_class::CoberturaParserError)
+ end
+ end
+ end
+ end
+
+ context 'when data is not Cobertura style XML' do
+ let(:cobertura) { { coverage: '12%' }.to_json }
+
+ it 'raises an error' do
+ expect { subject }.to raise_error(described_class::CoberturaParserError)
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/ci/parsers_spec.rb b/spec/lib/gitlab/ci/parsers_spec.rb
index 4b647bffe59..9d6896b3cb4 100644
--- a/spec/lib/gitlab/ci/parsers_spec.rb
+++ b/spec/lib/gitlab/ci/parsers_spec.rb
@@ -6,7 +6,7 @@ describe Gitlab::Ci::Parsers do
describe '.fabricate!' do
subject { described_class.fabricate!(file_type) }
- context 'when file_type exists' do
+ context 'when file_type is junit' do
let(:file_type) { 'junit' }
it 'fabricates the class' do
@@ -14,6 +14,14 @@ describe Gitlab::Ci::Parsers do
end
end
+ context 'when file_type is cobertura' do
+ let(:file_type) { 'cobertura' }
+
+ it 'fabricates the class' do
+ is_expected.to be_a(described_class::Coverage::Cobertura)
+ end
+ end
+
context 'when file_type does not exist' do
let(:file_type) { 'undefined' }
diff --git a/spec/lib/gitlab/ci/reports/coverage_reports_spec.rb b/spec/lib/gitlab/ci/reports/coverage_reports_spec.rb
new file mode 100644
index 00000000000..7cf43ceab32
--- /dev/null
+++ b/spec/lib/gitlab/ci/reports/coverage_reports_spec.rb
@@ -0,0 +1,66 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Ci::Reports::CoverageReports do
+ let(:coverage_report) { described_class.new }
+
+ it { expect(coverage_report.files).to eq({}) }
+
+ describe '#pick' do
+ before do
+ coverage_report.add_file('app.rb', { 1 => 0, 2 => 1 })
+ coverage_report.add_file('routes.rb', { 3 => 1, 4 => 0 })
+ end
+
+ it 'returns only picked files while ignoring nonexistent ones' do
+ expect(coverage_report.pick(['routes.rb', 'nonexistent.txt'])).to eq({
+ files: { 'routes.rb' => { 3 => 1, 4 => 0 } }
+ })
+ end
+ end
+
+ describe '#add_file' do
+ context 'when providing two individual files' do
+ before do
+ coverage_report.add_file('app.rb', { 1 => 0, 2 => 1 })
+ coverage_report.add_file('routes.rb', { 3 => 1, 4 => 0 })
+ end
+
+ it 'initializes a new test suite and returns it' do
+ expect(coverage_report.files).to eq({
+ 'app.rb' => { 1 => 0, 2 => 1 },
+ 'routes.rb' => { 3 => 1, 4 => 0 }
+ })
+ end
+ end
+
+ context 'when providing the same files twice' do
+ context 'with different line coverage' do
+ before do
+ coverage_report.add_file('admin.rb', { 1 => 0, 2 => 1 })
+ coverage_report.add_file('admin.rb', { 3 => 1, 4 => 0 })
+ end
+
+ it 'initializes a new test suite and returns it' do
+ expect(coverage_report.files).to eq({
+ 'admin.rb' => { 1 => 0, 2 => 1, 3 => 1, 4 => 0 }
+ })
+ end
+ end
+
+ context 'with identical line coverage' do
+ before do
+ coverage_report.add_file('projects.rb', { 1 => 0, 2 => 1 })
+ coverage_report.add_file('projects.rb', { 1 => 0, 2 => 1 })
+ end
+
+ it 'initializes a new test suite and returns it' do
+ expect(coverage_report.files).to eq({
+ 'projects.rb' => { 1 => 0, 2 => 2 }
+ })
+ end
+ end
+ end
+ end
+end
diff --git a/spec/lib/gitlab/import_export/group/tree_saver_spec.rb b/spec/lib/gitlab/import_export/group/tree_saver_spec.rb
index a7440ac24ca..44fd49f0ac3 100644
--- a/spec/lib/gitlab/import_export/group/tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/group/tree_saver_spec.rb
@@ -197,6 +197,6 @@ describe Gitlab::ImportExport::Group::TreeSaver do
end
def group_json(filename)
- JSON.parse(IO.read(filename))
+ ::JSON.parse(IO.read(filename))
end
end
diff --git a/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb b/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb
new file mode 100644
index 00000000000..b4cdfee3b22
--- /dev/null
+++ b/spec/lib/gitlab/import_export/json/legacy_writer_spec.rb
@@ -0,0 +1,79 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ImportExport::JSON::LegacyWriter do
+ let(:path) { "#{Dir.tmpdir}/legacy_writer_spec/test.json" }
+
+ subject { described_class.new(path) }
+
+ after do
+ FileUtils.rm_rf(path)
+ end
+
+ describe "#write" do
+ context "when key is already written" do
+ it "raises exception" do
+ key = "key"
+ value = "value"
+ subject.write(key, value)
+
+ expect { subject.write(key, "new value") }.to raise_exception("key '#{key}' already written")
+ end
+ end
+
+ context "when key is not already written" do
+ context "when multiple key value pairs are stored" do
+ it "writes correct json" do
+ expected_hash = { "key" => "value_1", "key_1" => "value_2" }
+ expected_hash.each do |key, value|
+ subject.write(key, value)
+ end
+ subject.close
+
+ expect(saved_json(path)).to eq(expected_hash)
+ end
+ end
+ end
+ end
+
+ describe "#append" do
+ context "when key is already written" do
+ it "appends values under a given key" do
+ key = "key"
+ values = %w(value_1 value_2)
+ expected_hash = { key => values }
+ values.each do |value|
+ subject.append(key, value)
+ end
+ subject.close
+
+ expect(saved_json(path)).to eq(expected_hash)
+ end
+ end
+
+ context "when key is not already written" do
+ it "writes correct json" do
+ expected_hash = { "key" => ["value"] }
+ subject.append("key", "value")
+ subject.close
+
+ expect(saved_json(path)).to eq(expected_hash)
+ end
+ end
+ end
+
+ describe "#set" do
+ it "writes correct json" do
+ expected_hash = { "key" => "value_1", "key_1" => "value_2" }
+ subject.set(expected_hash)
+ subject.close
+
+ expect(saved_json(path)).to eq(expected_hash)
+ end
+ end
+
+ def saved_json(filename)
+ ::JSON.parse(IO.read(filename))
+ end
+end
diff --git a/spec/lib/gitlab/import_export/relation_tree_saver_spec.rb b/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
index 2fc26c0e3d4..db77bd338e1 100644
--- a/spec/lib/gitlab/import_export/relation_tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/legacy_relation_tree_saver_spec.rb
@@ -2,7 +2,7 @@
require 'spec_helper'
-describe Gitlab::ImportExport::RelationTreeSaver do
+describe Gitlab::ImportExport::LegacyRelationTreeSaver do
let(:exportable) { create(:group) }
let(:relation_tree_saver) { described_class.new }
let(:tree) { {} }
diff --git a/spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb b/spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb
new file mode 100644
index 00000000000..d4406dbc60b
--- /dev/null
+++ b/spec/lib/gitlab/import_export/project/legacy_tree_saver_spec.rb
@@ -0,0 +1,397 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::ImportExport::Project::LegacyTreeSaver do
+ describe 'saves the project tree into a json object' do
+ let(:shared) { project.import_export_shared }
+ let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared) }
+ let(:export_path) { "#{Dir.tmpdir}/project_tree_saver_spec" }
+ let(:user) { create(:user) }
+ let!(:project) { setup_project }
+
+ before do
+ project.add_maintainer(user)
+ allow_any_instance_of(Gitlab::ImportExport).to receive(:storage_path).and_return(export_path)
+ allow_any_instance_of(MergeRequest).to receive(:source_branch_sha).and_return('ABCD')
+ allow_any_instance_of(MergeRequest).to receive(:target_branch_sha).and_return('DCBA')
+ end
+
+ after do
+ FileUtils.rm_rf(export_path)
+ end
+
+ it 'saves project successfully' do
+ expect(project_tree_saver.save).to be true
+ end
+
+ context ':export_fast_serialize feature flag checks' do
+ before do
+ expect(Gitlab::ImportExport::Reader).to receive(:new).with(shared: shared).and_return(reader)
+ expect(reader).to receive(:project_tree).and_return(project_tree)
+ end
+
+ let(:serializer) { instance_double('Gitlab::ImportExport::FastHashSerializer') }
+ let(:reader) { instance_double('Gitlab::ImportExport::Reader') }
+ let(:project_tree) do
+ {
+ include: [{ issues: { include: [] } }],
+ preload: { issues: nil }
+ }
+ end
+
+ context 'when :export_fast_serialize feature is enabled' do
+ before do
+ stub_feature_flags(export_fast_serialize: true)
+ end
+
+ it 'uses FastHashSerializer' do
+ expect(Gitlab::ImportExport::FastHashSerializer)
+ .to receive(:new)
+ .with(project, project_tree)
+ .and_return(serializer)
+
+ expect(serializer).to receive(:execute)
+
+ project_tree_saver.save
+ end
+ end
+
+ context 'when :export_fast_serialize feature is disabled' do
+ before do
+ stub_feature_flags(export_fast_serialize: false)
+ end
+
+ it 'is serialized via built-in `as_json`' do
+ expect(project).to receive(:as_json).with(project_tree)
+
+ project_tree_saver.save
+ end
+ end
+ end
+
+ # It is mostly duplicated in
+ # `spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb`
+ # except:
+ # context 'with description override' do
+ # context 'group members' do
+ # ^ These are specific for the Project::TreeSaver
+ context 'JSON' do
+ let(:saved_project_json) do
+ project_tree_saver.save
+ project_json(project_tree_saver.full_path)
+ end
+
+ # It is not duplicated in
+ # `spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb`
+ context 'with description override' do
+ let(:params) { { description: 'Foo Bar' } }
+ let(:project_tree_saver) { described_class.new(project: project, current_user: user, shared: shared, params: params) }
+
+ it 'overrides the project description' do
+ expect(saved_project_json).to include({ 'description' => params[:description] })
+ end
+ end
+
+ it 'saves the correct json' do
+ expect(saved_project_json).to include({ 'description' => 'description', 'visibility_level' => 20 })
+ end
+
+ it 'has approvals_before_merge set' do
+ expect(saved_project_json['approvals_before_merge']).to eq(1)
+ end
+
+ it 'has milestones' do
+ expect(saved_project_json['milestones']).not_to be_empty
+ end
+
+ it 'has merge requests' do
+ expect(saved_project_json['merge_requests']).not_to be_empty
+ end
+
+ it 'has merge request\'s milestones' do
+ expect(saved_project_json['merge_requests'].first['milestone']).not_to be_empty
+ end
+
+ it 'has merge request\'s source branch SHA' do
+ expect(saved_project_json['merge_requests'].first['source_branch_sha']).to eq('ABCD')
+ end
+
+ it 'has merge request\'s target branch SHA' do
+ expect(saved_project_json['merge_requests'].first['target_branch_sha']).to eq('DCBA')
+ end
+
+ it 'has events' do
+ expect(saved_project_json['merge_requests'].first['milestone']['events']).not_to be_empty
+ end
+
+ it 'has snippets' do
+ expect(saved_project_json['snippets']).not_to be_empty
+ end
+
+ it 'has snippet notes' do
+ expect(saved_project_json['snippets'].first['notes']).not_to be_empty
+ end
+
+ it 'has releases' do
+ expect(saved_project_json['releases']).not_to be_empty
+ end
+
+ it 'has no author on releases' do
+ expect(saved_project_json['releases'].first['author']).to be_nil
+ end
+
+ it 'has the author ID on releases' do
+ expect(saved_project_json['releases'].first['author_id']).not_to be_nil
+ end
+
+ it 'has issues' do
+ expect(saved_project_json['issues']).not_to be_empty
+ end
+
+ it 'has issue comments' do
+ notes = saved_project_json['issues'].first['notes']
+
+ expect(notes).not_to be_empty
+ expect(notes.first['type']).to eq('DiscussionNote')
+ end
+
+ it 'has issue assignees' do
+ expect(saved_project_json['issues'].first['issue_assignees']).not_to be_empty
+ end
+
+ it 'has author on issue comments' do
+ expect(saved_project_json['issues'].first['notes'].first['author']).not_to be_empty
+ end
+
+ it 'has project members' do
+ expect(saved_project_json['project_members']).not_to be_empty
+ end
+
+ it 'has merge requests diffs' do
+ expect(saved_project_json['merge_requests'].first['merge_request_diff']).not_to be_empty
+ end
+
+ it 'has merge request diff files' do
+ expect(saved_project_json['merge_requests'].first['merge_request_diff']['merge_request_diff_files']).not_to be_empty
+ end
+
+ it 'has merge request diff commits' do
+ expect(saved_project_json['merge_requests'].first['merge_request_diff']['merge_request_diff_commits']).not_to be_empty
+ end
+
+ it 'has merge requests comments' do
+ expect(saved_project_json['merge_requests'].first['notes']).not_to be_empty
+ end
+
+ it 'has author on merge requests comments' do
+ expect(saved_project_json['merge_requests'].first['notes'].first['author']).not_to be_empty
+ end
+
+ it 'has pipeline stages' do
+ expect(saved_project_json.dig('ci_pipelines', 0, 'stages')).not_to be_empty
+ end
+
+ it 'has pipeline statuses' do
+ expect(saved_project_json.dig('ci_pipelines', 0, 'stages', 0, 'statuses')).not_to be_empty
+ end
+
+ it 'has pipeline builds' do
+ builds_count = saved_project_json
+ .dig('ci_pipelines', 0, 'stages', 0, 'statuses')
+ .count { |hash| hash['type'] == 'Ci::Build' }
+
+ expect(builds_count).to eq(1)
+ end
+
+ it 'has no when YML attributes but only the DB column' do
+ expect_any_instance_of(Gitlab::Ci::YamlProcessor).not_to receive(:build_attributes)
+
+ saved_project_json
+ end
+
+ it 'has pipeline commits' do
+ expect(saved_project_json['ci_pipelines']).not_to be_empty
+ end
+
+ it 'has ci pipeline notes' do
+ expect(saved_project_json['ci_pipelines'].first['notes']).not_to be_empty
+ end
+
+ it 'has labels with no associations' do
+ expect(saved_project_json['labels']).not_to be_empty
+ end
+
+ it 'has labels associated to records' do
+ expect(saved_project_json['issues'].first['label_links'].first['label']).not_to be_empty
+ end
+
+ it 'has project and group labels' do
+ label_types = saved_project_json['issues'].first['label_links'].map { |link| link['label']['type'] }
+
+ expect(label_types).to match_array(%w(ProjectLabel GroupLabel))
+ end
+
+ it 'has priorities associated to labels' do
+ priorities = saved_project_json['issues'].first['label_links'].flat_map { |link| link['label']['priorities'] }
+
+ expect(priorities).not_to be_empty
+ end
+
+ it 'has issue resource label events' do
+ expect(saved_project_json['issues'].first['resource_label_events']).not_to be_empty
+ end
+
+ it 'has merge request resource label events' do
+ expect(saved_project_json['merge_requests'].first['resource_label_events']).not_to be_empty
+ end
+
+ it 'saves the correct service type' do
+ expect(saved_project_json['services'].first['type']).to eq('CustomIssueTrackerService')
+ end
+
+ it 'saves the properties for a service' do
+ expect(saved_project_json['services'].first['properties']).to eq('one' => 'value')
+ end
+
+ it 'has project feature' do
+ project_feature = saved_project_json['project_feature']
+ expect(project_feature).not_to be_empty
+ expect(project_feature["issues_access_level"]).to eq(ProjectFeature::DISABLED)
+ expect(project_feature["wiki_access_level"]).to eq(ProjectFeature::ENABLED)
+ expect(project_feature["builds_access_level"]).to eq(ProjectFeature::PRIVATE)
+ end
+
+ it 'has custom attributes' do
+ expect(saved_project_json['custom_attributes'].count).to eq(2)
+ end
+
+ it 'has badges' do
+ expect(saved_project_json['project_badges'].count).to eq(2)
+ end
+
+ it 'does not complain about non UTF-8 characters in MR diff files' do
+ ActiveRecord::Base.connection.execute("UPDATE merge_request_diff_files SET diff = '---\n- :diff: !binary |-\n LS0tIC9kZXYvbnVsbAorKysgYi9pbWFnZXMvbnVjb3IucGRmCkBAIC0wLDAg\n KzEsMTY3OSBAQAorJVBERi0xLjUNJeLjz9MNCisxIDAgb2JqDTw8L01ldGFk\n YXR'")
+
+ expect(project_tree_saver.save).to be true
+ end
+
+ context 'group members' do
+ let(:user2) { create(:user, email: 'group@member.com') }
+ let(:member_emails) do
+ saved_project_json['project_members'].map do |pm|
+ pm['user']['email']
+ end
+ end
+
+ before do
+ Group.first.add_developer(user2)
+ end
+
+ it 'does not export group members if it has no permission' do
+ Group.first.add_developer(user)
+
+ expect(member_emails).not_to include('group@member.com')
+ end
+
+ it 'does not export group members as maintainer' do
+ Group.first.add_maintainer(user)
+
+ expect(member_emails).not_to include('group@member.com')
+ end
+
+ it 'exports group members as group owner' do
+ Group.first.add_owner(user)
+
+ expect(member_emails).to include('group@member.com')
+ end
+
+ context 'as admin' do
+ let(:user) { create(:admin) }
+
+ it 'exports group members as admin' do
+ expect(member_emails).to include('group@member.com')
+ end
+
+ it 'exports group members as project members' do
+ member_types = saved_project_json['project_members'].map { |pm| pm['source_type'] }
+
+ expect(member_types).to all(eq('Project'))
+ end
+ end
+ end
+
+ context 'project attributes' do
+ it 'does not contain the runners token' do
+ expect(saved_project_json).not_to include("runners_token" => 'token')
+ end
+ end
+
+ it 'has a board and a list' do
+ expect(saved_project_json['boards'].first['lists']).not_to be_empty
+ end
+ end
+ end
+
+ def setup_project
+ release = create(:release)
+ group = create(:group)
+
+ project = create(:project,
+ :public,
+ :repository,
+ :issues_disabled,
+ :wiki_enabled,
+ :builds_private,
+ description: 'description',
+ releases: [release],
+ group: group,
+ approvals_before_merge: 1
+ )
+ allow(project).to receive(:commit).and_return(Commit.new(RepoHelpers.sample_commit, project))
+
+ issue = create(:issue, assignees: [user], project: project)
+ snippet = create(:project_snippet, project: project)
+ project_label = create(:label, project: project)
+ group_label = create(:group_label, group: group)
+ create(:label_link, label: project_label, target: issue)
+ create(:label_link, label: group_label, target: issue)
+ create(:label_priority, label: group_label, priority: 1)
+ milestone = create(:milestone, project: project)
+ merge_request = create(:merge_request, source_project: project, milestone: milestone)
+
+ ci_build = create(:ci_build, project: project, when: nil)
+ ci_build.pipeline.update(project: project)
+ create(:commit_status, project: project, pipeline: ci_build.pipeline)
+
+ create(:milestone, project: project)
+ create(:discussion_note, noteable: issue, project: project)
+ create(:note, noteable: merge_request, project: project)
+ create(:note, noteable: snippet, project: project)
+ create(:note_on_commit,
+ author: user,
+ project: project,
+ commit_id: ci_build.pipeline.sha)
+
+ create(:resource_label_event, label: project_label, issue: issue)
+ create(:resource_label_event, label: group_label, merge_request: merge_request)
+
+ create(:event, :created, target: milestone, project: project, author: user)
+ create(:service, project: project, type: 'CustomIssueTrackerService', category: 'issue_tracker', properties: { one: 'value' })
+
+ create(:project_custom_attribute, project: project)
+ create(:project_custom_attribute, project: project)
+
+ create(:project_badge, project: project)
+ create(:project_badge, project: project)
+
+ board = create(:board, project: project, name: 'TestBoard')
+ create(:list, board: board, position: 0, label: project_label)
+
+ project
+ end
+
+ def project_json(filename)
+ ::JSON.parse(IO.read(filename))
+ end
+end
diff --git a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
index 151fdf8810f..23360b725b9 100644
--- a/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
+++ b/spec/lib/gitlab/import_export/project/tree_saver_spec.rb
@@ -25,57 +25,6 @@ describe Gitlab::ImportExport::Project::TreeSaver do
expect(project_tree_saver.save).to be true
end
- context ':export_fast_serialize feature flag checks' do
- before do
- expect(Gitlab::ImportExport::Reader).to receive(:new).with(shared: shared).and_return(reader)
- expect(reader).to receive(:project_tree).and_return(project_tree)
- end
-
- let(:serializer) { instance_double('Gitlab::ImportExport::FastHashSerializer') }
- let(:reader) { instance_double('Gitlab::ImportExport::Reader') }
- let(:project_tree) do
- {
- include: [{ issues: { include: [] } }],
- preload: { issues: nil }
- }
- end
-
- context 'when :export_fast_serialize feature is enabled' do
- before do
- stub_feature_flags(export_fast_serialize: true)
- end
-
- it 'uses FastHashSerializer' do
- expect(Gitlab::ImportExport::FastHashSerializer)
- .to receive(:new)
- .with(project, project_tree)
- .and_return(serializer)
-
- expect(serializer).to receive(:execute)
-
- project_tree_saver.save
- end
- end
-
- context 'when :export_fast_serialize feature is disabled' do
- before do
- stub_feature_flags(export_fast_serialize: false)
- end
-
- it 'is serialized via built-in `as_json`' do
- expect(project).to receive(:as_json).with(project_tree)
-
- project_tree_saver.save
- end
- end
- end
-
- # It is mostly duplicated in
- # `spec/lib/gitlab/import_export/fast_hash_serializer_spec.rb`
- # except:
- # context 'with description override' do
- # context 'group members' do
- # ^ These are specific for the Project::TreeSaver
context 'JSON' do
let(:saved_project_json) do
project_tree_saver.save
@@ -392,6 +341,6 @@ describe Gitlab::ImportExport::Project::TreeSaver do
end
def project_json(filename)
- JSON.parse(IO.read(filename))
+ ::JSON.parse(IO.read(filename))
end
end