Skip to content
Snippets Groups Projects
Commit b84eeb25 authored by GitLab Bot's avatar GitLab Bot
Browse files

Add latest changes from gitlab-org/gitlab@master

parent 53ae6b7e
No related branches found
No related tags found
No related merge requests found
Showing with 430 additions and 30 deletions
Loading
Loading
@@ -74,6 +74,15 @@ describe Gitlab::Ci::Reports::TestSuite do
 
it { is_expected.to eq(Gitlab::Ci::Reports::TestCase::STATUS_FAILED) }
end
context 'when a test case errored' do
before do
test_suite.add_test_case(test_case_success)
test_suite.add_test_case(test_case_error)
end
it { is_expected.to eq(Gitlab::Ci::Reports::TestCase::STATUS_FAILED) }
end
end
 
Gitlab::Ci::Reports::TestCase::STATUS_TYPES.each do |status_type|
Loading
Loading
Loading
Loading
@@ -36,8 +36,6 @@ issues:
- vulnerability_links
- related_vulnerabilities
- user_mentions
- blocked_by_issue_links
- blocked_by_issues
events:
- author
- project
Loading
Loading
Loading
Loading
@@ -50,7 +50,7 @@ describe Gitlab::Runtime do
allow(puma_type).to receive_message_chain(:cli_config, :options).and_return(max_threads: 2)
end
 
it_behaves_like "valid runtime", :puma, 2
it_behaves_like "valid runtime", :puma, 3
end
 
context "unicorn" do
Loading
Loading
@@ -71,7 +71,7 @@ describe Gitlab::Runtime do
allow(sidekiq_type).to receive(:options).and_return(concurrency: 2)
end
 
it_behaves_like "valid runtime", :sidekiq, 2
it_behaves_like "valid runtime", :sidekiq, 4
end
 
context "console" do
Loading
Loading
Loading
Loading
@@ -19,6 +19,25 @@ describe Emails::Pipelines do
expect(subject).to have_body_text status_text
end
 
context 'when pipeline on master branch has a merge request' do
let(:pipeline) { create(:ci_pipeline, ref: 'master', sha: sha, project: project) }
let!(:merge_request) do
create(:merge_request, source_branch: 'master', target_branch: 'feature',
source_project: project, target_project: project)
end
it 'has correct information that there is no merge request link' do
expect(subject)
.to have_subject "#{project.name} | Pipeline ##{pipeline.id} has " \
"#{status} for #{pipeline.source_ref} | " \
"#{pipeline.short_sha}".to_s
expect(subject).to have_body_text pipeline.source_ref
expect(subject).to have_body_text status_text
end
end
context 'when pipeline for merge requests' do
let(:pipeline) { merge_request.all_pipelines.first }
 
Loading
Loading
@@ -28,7 +47,7 @@ describe Emails::Pipelines do
target_project: project)
end
 
it 'has a correct information with merge request link' do
it 'has correct information that there is a merge request link' do
expect(subject)
.to have_subject "#{project.name} | Pipeline ##{pipeline.id} has " \
"#{status} for #{pipeline.source_ref} | " \
Loading
Loading
@@ -39,6 +58,27 @@ describe Emails::Pipelines do
expect(subject).not_to have_body_text pipeline.ref
end
end
context 'when branch pipeline is set to a merge request as a head pipeline' do
let(:pipeline) do
create(:ci_pipeline, project: project, ref: ref, sha: sha,
merge_requests_as_head_pipeline: [merge_request])
end
let(:merge_request) do
create(:merge_request, source_project: project, target_project: project)
end
it 'has correct information that there is a merge request link' do
expect(subject)
.to have_subject "#{project.name} | Pipeline ##{pipeline.id} has " \
"#{status} for #{pipeline.source_ref} | " \
"#{pipeline.short_sha} in !#{merge_request.iid}".to_s
expect(subject).to have_body_text merge_request.to_reference
expect(subject).to have_body_text pipeline.source_ref
end
end
end
 
describe '#pipeline_success_email' do
Loading
Loading
Loading
Loading
@@ -153,6 +153,16 @@ describe Project do
expect(project.container_expiration_policy).to be_persisted
end
 
it 'does not create another container expiration policy if there is already one' do
project = build(:project)
expect do
container_expiration_policy = create(:container_expiration_policy, project: project)
expect(project.container_expiration_policy).to eq(container_expiration_policy)
end.to change { ContainerExpirationPolicy.count }.by(1)
end
it 'automatically creates a Pages metadata row' do
expect(project.pages_metadatum).to be_an_instance_of(ProjectPagesMetadatum)
expect(project.pages_metadatum).to be_persisted
Loading
Loading
# frozen_string_literal: true
require 'spec_helper'
describe 'Updating an image DiffNote' do
include GraphqlHelpers
using RSpec::Parameterized::TableSyntax
let_it_be(:noteable) { create(:merge_request, :with_diffs) }
let_it_be(:original_body) { 'Original body' }
let_it_be(:original_position) do
Gitlab::Diff::Position.new(
old_path: 'files/images/any_image.png',
new_path: 'files/images/any_image.png',
width: 10,
height: 20,
x: 1,
y: 2,
diff_refs: noteable.diff_refs,
position_type: 'image'
)
end
let_it_be(:updated_body) { 'Updated body' }
let_it_be(:updated_width) { 50 }
let_it_be(:updated_height) { 100 }
let_it_be(:updated_x) { 5 }
let_it_be(:updated_y) { 10 }
let(:updated_position) do
{
width: updated_width,
height: updated_height,
x: updated_x,
y: updated_y
}
end
let!(:diff_note) do
create(:image_diff_note_on_merge_request,
noteable: noteable,
project: noteable.project,
note: original_body,
position: original_position)
end
let(:mutation) do
variables = {
id: GitlabSchema.id_from_object(diff_note).to_s,
body: updated_body,
position: updated_position
}
graphql_mutation(:update_image_diff_note, variables)
end
def mutation_response
graphql_mutation_response(:update_image_diff_note)
end
context 'when the user does not have permission' do
let_it_be(:current_user) { create(:user) }
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
it 'does not update the DiffNote' do
post_graphql_mutation(mutation, current_user: current_user)
diff_note.reload
expect(diff_note).to have_attributes(
note: original_body,
position: have_attributes(
width: original_position.width,
height: original_position.height,
x: original_position.x,
y: original_position.y
)
)
end
end
context 'when the user has permission' do
let(:current_user) { diff_note.author }
it 'updates the DiffNote' do
post_graphql_mutation(mutation, current_user: current_user)
diff_note.reload
expect(diff_note).to have_attributes(
note: updated_body,
position: have_attributes(
width: updated_width,
height: updated_height,
x: updated_x,
y: updated_y
)
)
end
it 'returns the updated DiffNote' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['note']).to include(
'body' => updated_body,
'position' => hash_including(
'width' => updated_width,
'height' => updated_height,
'x' => updated_x,
'y' => updated_y
)
)
end
describe 'updating single properties at a time' do
where(:property, :new_value) do
:body | 'foo'
:width | 19
:height | 18
:x | 17
:y | 16
end
with_them do
# Properties that will be POSTed:
let(:updated_body) { value(:body) }
let(:updated_width) { value(:width) }
let(:updated_height) { value(:height) }
let(:updated_x) { value(:x) }
let(:updated_y) { value(:y) }
# Expectations of the properties:
let(:expected_body) { value(:body) || original_body }
let(:expected_width) { value(:width) || original_position.width }
let(:expected_height) { value(:height) || original_position.height }
let(:expected_x) { value(:x) || original_position.x }
let(:expected_y) { value(:y) || original_position.y }
def value(prop)
new_value if property == prop
end
it 'updates the DiffNote correctly' do
post_graphql_mutation(mutation, current_user: current_user)
diff_note.reload
expect(diff_note).to have_attributes(
note: expected_body,
position: have_attributes(
width: expected_width,
height: expected_height,
x: expected_x,
y: expected_y
)
)
end
end
context 'when position is nil' do
let(:updated_position) { nil }
it 'updates the DiffNote correctly' do
post_graphql_mutation(mutation, current_user: current_user)
diff_note.reload
expect(diff_note).to have_attributes(
note: updated_body,
position: original_position
)
end
end
end
context 'when both body and position args are blank' do
let(:updated_body) { nil }
let(:updated_position) { nil }
it_behaves_like 'a mutation that returns top-level errors', errors: ['body or position arguments are required']
end
context 'when resource is not a DiffNote on an image' do
let!(:diff_note) { create(:diff_note_on_merge_request, note: original_body) }
it_behaves_like 'a mutation that returns top-level errors', errors: ['Resource is not an ImageDiffNote']
end
context 'when there are ActiveRecord validation errors' do
before do
expect(diff_note).to receive_message_chain(
:errors,
:full_messages
).and_return(['Error 1', 'Error 2'])
expect_next_instance_of(Notes::UpdateService) do |service|
expect(service).to receive(:execute).and_return(diff_note)
end
end
it_behaves_like 'a mutation that returns errors in the response', errors: ['Error 1', 'Error 2']
it 'does not update the DiffNote' do
post_graphql_mutation(mutation, current_user: current_user)
diff_note.reload
expect(diff_note).to have_attributes(
note: original_body,
position: have_attributes(
width: original_position.width,
height: original_position.height,
x: original_position.x,
y: original_position.y
)
)
end
it 'returns the DiffNote with its original body' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response['note']).to include(
'body' => original_body,
'position' => hash_including(
'width' => original_position.width,
'height' => original_position.height,
'x' => original_position.x,
'y' => original_position.y
)
)
end
end
context 'when body only contains quick actions' do
let(:updated_body) { '/close' }
it 'returns a nil note and empty errors' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to include(
'errors' => [],
'note' => nil
)
end
end
end
end
Loading
Loading
@@ -22,7 +22,7 @@ describe 'Updating a Note' do
end
 
context 'when the user does not have permission' do
let(:current_user) { create(:user) }
let_it_be(:current_user) { create(:user) }
 
it_behaves_like 'a mutation that returns top-level errors',
errors: ['The resource that you are attempting to access does not exist or you don\'t have permission to perform this action']
Loading
Loading
@@ -68,5 +68,18 @@ describe 'Updating a Note' do
expect(mutation_response['note']['body']).to eq(original_body)
end
end
context 'when body only contains quick actions' do
let(:updated_body) { '/close' }
it 'returns a nil note and empty errors' do
post_graphql_mutation(mutation, current_user: current_user)
expect(mutation_response).to include(
'errors' => [],
'note' => nil
)
end
end
end
end
Loading
Loading
@@ -24,7 +24,7 @@ describe TestReportsComparerEntity do
 
it 'contains correct compared test reports details' do
expect(subject[:status]).to eq('success')
expect(subject[:summary]).to include(total: 2, resolved: 0, failed: 0)
expect(subject[:summary]).to include(total: 2, resolved: 0, failed: 0, errored: 0)
expect(subject[:suites].first[:name]).to eq('rspec')
expect(subject[:suites].first[:status]).to eq('success')
expect(subject[:suites].second[:name]).to eq('junit')
Loading
Loading
@@ -42,7 +42,7 @@ describe TestReportsComparerEntity do
 
it 'contains correct compared test reports details' do
expect(subject[:status]).to eq('failed')
expect(subject[:summary]).to include(total: 2, resolved: 0, failed: 1)
expect(subject[:summary]).to include(total: 2, resolved: 0, failed: 1, errored: 0)
expect(subject[:suites].first[:name]).to eq('rspec')
expect(subject[:suites].first[:status]).to eq('success')
expect(subject[:suites].second[:name]).to eq('junit')
Loading
Loading
@@ -60,7 +60,7 @@ describe TestReportsComparerEntity do
 
it 'contains correct compared test reports details' do
expect(subject[:status]).to eq('success')
expect(subject[:summary]).to include(total: 2, resolved: 1, failed: 0)
expect(subject[:summary]).to include(total: 2, resolved: 1, failed: 0, errored: 0)
expect(subject[:suites].first[:name]).to eq('rspec')
expect(subject[:suites].first[:status]).to eq('success')
expect(subject[:suites].second[:name]).to eq('junit')
Loading
Loading
Loading
Loading
@@ -12,6 +12,7 @@ describe TestSuiteComparerEntity do
let(:head_suite) { Gitlab::Ci::Reports::TestSuite.new(name) }
let(:test_case_success) { create_test_case_rspec_success }
let(:test_case_failed) { create_test_case_rspec_failed }
let(:test_case_error) { create_test_case_rspec_error }
 
describe '#as_json' do
subject { entity.as_json }
Loading
Loading
@@ -25,7 +26,7 @@ describe TestSuiteComparerEntity do
it 'contains correct compared test suite details' do
expect(subject[:name]).to eq(name)
expect(subject[:status]).to eq('failed')
expect(subject[:summary]).to include(total: 1, resolved: 0, failed: 1)
expect(subject[:summary]).to include(total: 1, resolved: 0, failed: 1, errored: 0)
subject[:new_failures].first.tap do |new_failure|
expect(new_failure[:status]).to eq(test_case_failed.status)
expect(new_failure[:name]).to eq(test_case_failed.name)
Loading
Loading
@@ -37,6 +38,27 @@ describe TestSuiteComparerEntity do
end
end
 
context 'when head suite has a new error test case which does not exist in base' do
before do
base_suite.add_test_case(test_case_success)
head_suite.add_test_case(test_case_error)
end
it 'contains correct compared test suite details' do
expect(subject[:name]).to eq(name)
expect(subject[:status]).to eq('failed')
expect(subject[:summary]).to include(total: 1, resolved: 0, failed: 0, errored: 1)
subject[:new_errors].first.tap do |new_error|
expect(new_error[:status]).to eq(test_case_error.status)
expect(new_error[:name]).to eq(test_case_error.name)
expect(new_error[:execution_time]).to eq(test_case_error.execution_time)
expect(new_error[:system_output]).to eq(test_case_error.system_output)
end
expect(subject[:resolved_failures]).to be_empty
expect(subject[:existing_failures]).to be_empty
end
end
context 'when head suite still has a failed test case which failed in base' do
before do
base_suite.add_test_case(test_case_failed)
Loading
Loading
@@ -46,7 +68,7 @@ describe TestSuiteComparerEntity do
it 'contains correct compared test suite details' do
expect(subject[:name]).to eq(name)
expect(subject[:status]).to eq('failed')
expect(subject[:summary]).to include(total: 1, resolved: 0, failed: 1)
expect(subject[:summary]).to include(total: 1, resolved: 0, failed: 1, errored: 0)
expect(subject[:new_failures]).to be_empty
expect(subject[:resolved_failures]).to be_empty
subject[:existing_failures].first.tap do |existing_failure|
Loading
Loading
@@ -67,7 +89,7 @@ describe TestSuiteComparerEntity do
it 'contains correct compared test suite details' do
expect(subject[:name]).to eq(name)
expect(subject[:status]).to eq('success')
expect(subject[:summary]).to include(total: 1, resolved: 1, failed: 0)
expect(subject[:summary]).to include(total: 1, resolved: 1, failed: 0, errored: 0)
expect(subject[:new_failures]).to be_empty
subject[:resolved_failures].first.tap do |resolved_failure|
expect(resolved_failure[:status]).to eq(test_case_success.status)
Loading
Loading
@@ -88,42 +110,57 @@ describe TestSuiteComparerEntity do
context 'prefers new over existing and resolved' do
before do
3.times { add_new_failure }
3.times { add_new_error }
3.times { add_existing_failure }
3.times { add_existing_error }
3.times { add_resolved_failure }
3.times { add_resolved_error }
end
 
it 'returns 2 new failures, and 1 of resolved and existing' do
expect(subject[:summary]).to include(total: 9, resolved: 3, failed: 6)
it 'returns 2 of each new category, and 1 of each resolved and existing' do
expect(subject[:summary]).to include(total: 18, resolved: 6, failed: 6, errored: 6)
expect(subject[:new_failures].count).to eq(2)
expect(subject[:new_errors].count).to eq(2)
expect(subject[:existing_failures].count).to eq(1)
expect(subject[:existing_errors].count).to eq(1)
expect(subject[:resolved_failures].count).to eq(1)
expect(subject[:resolved_errors].count).to eq(1)
end
end
 
context 'prefers existing over resolved' do
before do
3.times { add_existing_failure }
3.times { add_existing_error }
3.times { add_resolved_failure }
3.times { add_resolved_error }
end
 
it 'returns 2 existing failures, and 1 resolved' do
expect(subject[:summary]).to include(total: 6, resolved: 3, failed: 3)
it 'returns 2 of each existing category, and 1 of each resolved' do
expect(subject[:summary]).to include(total: 12, resolved: 6, failed: 3, errored: 3)
expect(subject[:new_failures].count).to eq(0)
expect(subject[:new_errors].count).to eq(0)
expect(subject[:existing_failures].count).to eq(2)
expect(subject[:existing_errors].count).to eq(2)
expect(subject[:resolved_failures].count).to eq(1)
expect(subject[:resolved_errors].count).to eq(1)
end
end
 
context 'limits amount of resolved' do
before do
3.times { add_resolved_failure }
3.times { add_resolved_error }
end
 
it 'returns 2 resolved failures' do
expect(subject[:summary]).to include(total: 3, resolved: 3, failed: 0)
it 'returns 2 of each resolved category' do
expect(subject[:summary]).to include(total: 6, resolved: 6, failed: 0, errored: 0)
expect(subject[:new_failures].count).to eq(0)
expect(subject[:new_errors].count).to eq(0)
expect(subject[:existing_failures].count).to eq(0)
expect(subject[:existing_errors].count).to eq(0)
expect(subject[:resolved_failures].count).to eq(2)
expect(subject[:resolved_errors].count).to eq(2)
end
end
 
Loading
Loading
@@ -134,19 +171,38 @@ describe TestSuiteComparerEntity do
head_suite.add_test_case(failed_case)
end
 
def add_new_error
error_case = create_test_case_rspec_error(SecureRandom.hex)
head_suite.add_test_case(error_case)
end
def add_existing_failure
failed_case = create_test_case_rspec_failed(SecureRandom.hex)
base_suite.add_test_case(failed_case)
head_suite.add_test_case(failed_case)
end
 
def add_existing_error
error_case = create_test_case_rspec_error(SecureRandom.hex)
base_suite.add_test_case(error_case)
head_suite.add_test_case(error_case)
end
def add_resolved_failure
case_name = SecureRandom.hex
failed_case = create_test_case_rspec_failed(case_name)
success_case = create_test_case_rspec_success(case_name)
failed_case = create_test_case_java_failed(case_name)
success_case = create_test_case_java_success(case_name)
base_suite.add_test_case(failed_case)
head_suite.add_test_case(success_case)
end
def add_resolved_error
case_name = SecureRandom.hex
error_case = create_test_case_java_error(case_name)
success_case = create_test_case_java_success(case_name)
base_suite.add_test_case(error_case)
head_suite.add_test_case(success_case)
end
end
end
end
Loading
Loading
@@ -143,6 +143,34 @@ describe Snippets::CreateService do
end
end
 
shared_examples 'creates repository' do
it do
subject
expect(snippet.repository_exists?).to be_truthy
end
context 'when snippet creation fails' do
let(:extra_opts) { { content: nil } }
it 'does not create repository' do
subject
expect(snippet.repository_exists?).to be_falsey
end
end
context 'when feature flag :version_snippets is disabled' do
it 'does not create snippet repository' do
stub_feature_flags(version_snippets: false)
subject
expect(snippet.repository_exists?).to be_falsey
end
end
end
context 'when Project Snippet' do
let_it_be(:project) { create(:project) }
 
Loading
Loading
@@ -155,6 +183,7 @@ describe Snippets::CreateService do
it_behaves_like 'spam check is performed'
it_behaves_like 'snippet create data is tracked'
it_behaves_like 'an error service response when save fails'
it_behaves_like 'creates repository'
end
 
context 'when PersonalSnippet' do
Loading
Loading
@@ -165,6 +194,7 @@ describe Snippets::CreateService do
it_behaves_like 'spam check is performed'
it_behaves_like 'snippet create data is tracked'
it_behaves_like 'an error service response when save fails'
it_behaves_like 'creates repository'
end
end
end
Loading
Loading
@@ -123,7 +123,7 @@ RSpec.shared_examples 'cycle analytics label based stage' do
})
 
expect(stage).to be_invalid
expect(stage.errors[:start_event_label]).to include("can't be blank")
expect(stage.errors[:start_event_label_id]).to include("can't be blank")
end
 
it 'returns validation error when `end_event_label_id` is missing' do
Loading
Loading
@@ -135,7 +135,7 @@ RSpec.shared_examples 'cycle analytics label based stage' do
})
 
expect(stage).to be_invalid
expect(stage.errors[:end_event_label]).to include("can't be blank")
expect(stage.errors[:end_event_label_id]).to include("can't be blank")
end
end
 
Loading
Loading
@@ -145,7 +145,7 @@ RSpec.shared_examples 'cycle analytics label based stage' do
name: 'My Stage',
parent: parent,
start_event_identifier: :issue_label_added,
start_event_label: group_label,
start_event_label_id: group_label.id,
end_event_identifier: :issue_closed
})
 
Loading
Loading
@@ -159,7 +159,7 @@ RSpec.shared_examples 'cycle analytics label based stage' do
name: 'My Stage',
parent: parent_in_subgroup,
start_event_identifier: :issue_label_added,
start_event_label: group_label,
start_event_label_id: group_label.id,
end_event_identifier: :issue_closed
})
 
Loading
Loading
@@ -170,30 +170,30 @@ RSpec.shared_examples 'cycle analytics label based stage' do
context 'when label is defined for a different group' do
let(:error_message) { s_('CycleAnalyticsStage|is not available for the selected group') }
 
it 'returns validation for `start_event_label`' do
it 'returns validation for `start_event_label_id`' do
stage = described_class.new({
name: 'My Stage',
parent: parent_outside_of_group_label_scope,
start_event_identifier: :issue_label_added,
start_event_label: group_label,
start_event_label_id: group_label.id,
end_event_identifier: :issue_closed
})
 
expect(stage).to be_invalid
expect(stage.errors[:start_event_label]).to include(error_message)
expect(stage.errors[:start_event_label_id]).to include(error_message)
end
 
it 'returns validation for `end_event_label`' do
it 'returns validation for `end_event_label_id`' do
stage = described_class.new({
name: 'My Stage',
parent: parent_outside_of_group_label_scope,
start_event_identifier: :issue_closed,
end_event_identifier: :issue_label_added,
end_event_label: group_label
end_event_label_id: group_label.id
})
 
expect(stage).to be_invalid
expect(stage.errors[:end_event_label]).to include(error_message)
expect(stage.errors[:end_event_label_id]).to include(error_message)
end
end
 
Loading
Loading
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment