diff options
Diffstat (limited to 'spec')
18 files changed, 547 insertions, 481 deletions
diff --git a/spec/factories/alert_management/alerts.rb b/spec/factories/alert_management/alerts.rb index 589a62a68bb..7e9e58edc1e 100644 --- a/spec/factories/alert_management/alerts.rb +++ b/spec/factories/alert_management/alerts.rb @@ -113,20 +113,6 @@ FactoryBot.define do end end - trait :cilium do - monitoring_tool { Gitlab::AlertManagement::Payload::MONITORING_TOOLS[:cilium] } - payload do - { - annotations: { - title: 'This is a cilium alert', - summary: 'Summary of the alert', - description: 'Description of the alert' - }, - startsAt: started_at - }.with_indifferent_access - end - end - trait :all_fields do with_incident with_assignee diff --git a/spec/factories/deploy_tokens.rb b/spec/factories/deploy_tokens.rb index b2c478fd3fe..a2116b738fd 100644 --- a/spec/factories/deploy_tokens.rb +++ b/spec/factories/deploy_tokens.rb @@ -2,7 +2,6 @@ FactoryBot.define do factory :deploy_token do - token { nil } token_encrypted { Gitlab::CryptoHelper.aes256_gcm_encrypt(SecureRandom.hex(50)) } sequence(:name) { |n| "PDT #{n}" } read_repository { true } diff --git a/spec/features/groups/issues_spec.rb b/spec/features/groups/issues_spec.rb index 6b663445124..ef3346b9763 100644 --- a/spec/features/groups/issues_spec.rb +++ b/spec/features/groups/issues_spec.rb @@ -11,6 +11,10 @@ RSpec.describe 'Group issues page' do let(:project_with_issues_disabled) { create(:project, :issues_disabled, group: group) } let(:path) { issues_group_path(group) } + before do + stub_feature_flags(vue_issues_list: true) + end + context 'with shared examples', :js do let(:issuable) { create(:issue, project: project, title: "this is my created issuable")} @@ -58,10 +62,10 @@ RSpec.describe 'Group issues page' do let(:user2) { user_outside_group } it 'filters by only group users' do - filtered_search.set('assignee:=') + select_tokens 'Assignee', '=' - expect(find('#js-dropdown-assignee .filter-dropdown')).to have_content(user.name) - expect(find('#js-dropdown-assignee .filter-dropdown')).not_to have_content(user2.name) + expect_suggestion(user.name) + expect_no_suggestion(user2.name) end end end @@ -76,23 +80,9 @@ RSpec.describe 'Group issues page' do it 'returns all group and subgroup issues' do visit issues_group_path(group) - page.within('.issuable-list') do - expect(page).to have_selector('li.issue', count: 2) - expect(page).to have_content('root group issue') - expect(page).to have_content('subgroup issue') - end - end - - it 'truncates issue counts if over the threshold', :clean_gitlab_redis_cache do - allow(Rails.cache).to receive(:read).and_call_original - allow(Rails.cache).to receive(:read).with( - ['group', group.id, 'issues'], - { expires_in: Gitlab::IssuablesCountForState::CACHE_EXPIRES_IN } - ).and_return({ opened: 1050, closed: 500, all: 1550 }) - - visit issues_group_path(group) - - expect(page).to have_text('Open 1.1k Closed 500 All 1.6k') + expect(page).to have_selector('li.issue', count: 2) + expect(page).to have_content('root group issue') + expect(page).to have_content('subgroup issue') end context 'when project is archived' do @@ -115,7 +105,6 @@ RSpec.describe 'Group issues page' do let!(:subgroup_issue) { create(:issue, project: subgroup_project) } before do - stub_feature_flags(vue_issues_list: true) visit issues_group_path(group_with_no_issues) end @@ -135,14 +124,10 @@ RSpec.describe 'Group issues page' do end it 'shows projects only with issues feature enabled', :js do - within '.empty-state' do - click_button 'Toggle project select' - end + click_button 'Toggle project select' - page.within('.select2-results') do - expect(page).to have_content(project.full_name) - expect(page).not_to have_content(project_with_issues_disabled.full_name) - end + expect(page).to have_button project.full_name + expect(page).not_to have_button project_with_issues_disabled.full_name end end end @@ -155,15 +140,15 @@ RSpec.describe 'Group issues page' do let!(:issue3) { create(:issue, project: project, title: 'Issue #3', relative_position: 3) } before do + stub_feature_flags(vue_issues_list: false) + sign_in(user_in_group) end it 'displays all issues' do visit issues_group_path(group, sort: 'relative_position') - page.within('.issues-list') do - expect(page).to have_selector('li.issue', count: 3) - end + expect(page).to have_selector('li.issue', count: 3) end it 'has manual-ordering css applied' do @@ -218,11 +203,9 @@ RSpec.describe 'Group issues page' do end def check_issue_order - page.within('.manual-ordering') do - expect(find('.issue:nth-child(1) .title')).to have_content('Issue #2') - expect(find('.issue:nth-child(2) .title')).to have_content('Issue #3') - expect(find('.issue:nth-child(3) .title')).to have_content('Issue #1') - end + expect(page).to have_css('.issue:nth-child(1) .title', text: 'Issue #2') + expect(page).to have_css('.issue:nth-child(2) .title', text: 'Issue #3') + expect(page).to have_css('.issue:nth-child(3) .title', text: 'Issue #1') end end @@ -239,14 +222,8 @@ RSpec.describe 'Group issues page' do end it 'shows the pagination' do - expect(page).to have_link 'Prev' - expect(page).to have_link 'Next' - end - - it 'first pagination item is active' do - page.within('.gl-pagination') do - expect(find('li.active')).to have_content('1') - end + expect(page).to have_button 'Prev', disabled: true + expect(page).to have_button 'Next' end end end diff --git a/spec/features/labels_hierarchy_spec.rb b/spec/features/labels_hierarchy_spec.rb index 479199b72b7..ea888d4b254 100644 --- a/spec/features/labels_hierarchy_spec.rb +++ b/spec/features/labels_hierarchy_spec.rb @@ -17,6 +17,8 @@ RSpec.describe 'Labels Hierarchy', :js do let!(:project_label_1) { create(:label, project: project_1, title: 'Label_4') } before do + stub_feature_flags(vue_issues_list: true) + grandparent.add_owner(user) sign_in(user) @@ -34,8 +36,6 @@ RSpec.describe 'Labels Hierarchy', :js do click_on 'Close' end - wait_for_requests - expect(page).to have_selector('.gl-label', text: label.title) end end @@ -44,8 +44,6 @@ RSpec.describe 'Labels Hierarchy', :js do page.within('.block.labels') do click_on 'Edit' - wait_for_requests - expect(page).not_to have_text(child_group_label.title) end end @@ -54,15 +52,21 @@ RSpec.describe 'Labels Hierarchy', :js do shared_examples 'filtering by ancestor labels for projects' do |board = false| it 'filters by ancestor labels' do [grandparent_group_label, parent_group_label, project_label_1].each do |label| - select_label_on_dropdown(label.title) - - wait_for_requests - if board + select_label_on_dropdown(label.title) + expect(page).to have_selector('.board-card-title') do |card| expect(card).to have_selector('a', text: labeled_issue.title) end else + within '[data-testid="filtered-search-input"]' do + click_filtered_search_bar + click_on 'Label' + click_on '= is' + click_on label.title + send_keys :enter + end + expect_issues_list_count(1) expect(page).to have_selector('.issue-title', text: labeled_issue.title) end @@ -70,9 +74,11 @@ RSpec.describe 'Labels Hierarchy', :js do end it 'does not filter by descendant group labels' do - filtered_search.set("label=") - - wait_for_requests + if board + filtered_search.set("label=") + else + select_tokens 'Label', '=' + end expect(page).not_to have_link child_group_label.title end @@ -93,11 +99,9 @@ RSpec.describe 'Labels Hierarchy', :js do it 'filters by ancestors and current group labels' do [grandparent_group_label, parent_group_label].each do |label| - select_label_on_dropdown(label.title) - - wait_for_requests - if board + select_label_on_dropdown(label.title) + expect(page).to have_selector('.board-card-title') do |card| expect(card).to have_selector('a', text: labeled_issue.title) end @@ -106,6 +110,14 @@ RSpec.describe 'Labels Hierarchy', :js do expect(card).to have_selector('a', text: labeled_issue_2.title) end else + within '[data-testid="filtered-search-input"]' do + click_filtered_search_bar + click_on 'Label' + click_on '= is' + click_on label.title + send_keys :enter + end + expect_issues_list_count(3) expect(page).to have_selector('.issue-title', text: labeled_issue.title) expect(page).to have_selector('.issue-title', text: labeled_issue_2.title) @@ -115,11 +127,9 @@ RSpec.describe 'Labels Hierarchy', :js do end it 'filters by descendant group labels' do - wait_for_requests - - select_label_on_dropdown(group_label_3.title) - if board + select_label_on_dropdown(group_label_3.title) + expect(page).to have_selector('.board-card-title') do |card| expect(card).not_to have_selector('a', text: labeled_issue_2.title) end @@ -128,17 +138,23 @@ RSpec.describe 'Labels Hierarchy', :js do expect(card).to have_selector('a', text: labeled_issue_3.title) end else + select_tokens 'Label', '=', group_label_3.title, submit: true + expect_issues_list_count(1) expect(page).to have_selector('.issue-title', text: labeled_issue_3.title) end end it 'does not filter by descendant group project labels' do - filtered_search.set("label=") + if board + filtered_search.set("label=") - wait_for_requests + expect(page).not_to have_selector('.btn-link', text: project_label_3.title) + else + select_tokens 'Label', '=' - expect(page).not_to have_selector('.btn-link', text: project_label_3.title) + expect(page).not_to have_link project_label_3.title + end end end @@ -195,9 +211,7 @@ RSpec.describe 'Labels Hierarchy', :js do it_behaves_like 'filtering by ancestor labels for projects' it 'does not filter by descendant group labels' do - filtered_search.set("label=") - - wait_for_requests + select_tokens 'Label', '=' expect(page).not_to have_link child_group_label.title end diff --git a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb index 7d67cde4bbb..f5b5460769e 100644 --- a/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb +++ b/spec/features/merge_request/user_interacts_with_batched_mr_diffs_spec.rb @@ -59,7 +59,6 @@ RSpec.describe 'Batch diffs', :js do # Confirm scrolled to correct UI element expect(get_first_diff.find('.discussion-notes .timeline-entry li.note[id]').obscured?).to be_falsey - expect(get_second_diff.find('.discussion-notes .timeline-entry li.note[id]').obscured?).to be_truthy end end diff --git a/spec/features/merge_request/user_manages_subscription_spec.rb b/spec/features/merge_request/user_manages_subscription_spec.rb index 3cdb22000f6..c64c761b8d1 100644 --- a/spec/features/merge_request/user_manages_subscription_spec.rb +++ b/spec/features/merge_request/user_manages_subscription_spec.rb @@ -6,29 +6,60 @@ RSpec.describe 'User manages subscription', :js do let(:project) { create(:project, :public, :repository) } let(:merge_request) { create(:merge_request, source_project: project, target_project: project) } let(:user) { create(:user) } + let(:moved_mr_sidebar_enabled) { false } before do + stub_feature_flags(moved_mr_sidebar: moved_mr_sidebar_enabled) + project.add_maintainer(user) sign_in(user) visit(merge_request_path(merge_request)) end - it 'toggles subscription' do - page.within('[data-testid="subscription-toggle"]') do + context 'moved sidebar flag disabled' do + it 'toggles subscription' do + page.within('[data-testid="subscription-toggle"]') do + wait_for_requests + + expect(page).to have_css 'button:not(.is-checked)' + find('button:not(.is-checked)').click + + wait_for_requests + + expect(page).to have_css 'button.is-checked' + find('button.is-checked').click + + wait_for_requests + + expect(page).to have_css 'button:not(.is-checked)' + end + end + end + + context 'moved sidebar flag enabled' do + let(:moved_mr_sidebar_enabled) { true } + + it 'toggles subscription' do wait_for_requests - expect(page).to have_css 'button:not(.is-checked)' - find('button:not(.is-checked)').click + click_button 'Toggle dropdown' + + expect(page).to have_content('Turn on notifications') + click_button 'Turn on notifications' wait_for_requests - expect(page).to have_css 'button.is-checked' - find('button.is-checked').click + click_button 'Toggle dropdown' + + expect(page).to have_content('Turn off notifications') + click_button 'Turn off notifications' wait_for_requests - expect(page).to have_css 'button:not(.is-checked)' + click_button 'Toggle dropdown' + + expect(page).to have_content('Turn on notifications') end end end diff --git a/spec/features/merge_request/user_views_open_merge_request_spec.rb b/spec/features/merge_request/user_views_open_merge_request_spec.rb index fbb4847130c..1f4682b4a46 100644 --- a/spec/features/merge_request/user_views_open_merge_request_spec.rb +++ b/spec/features/merge_request/user_views_open_merge_request_spec.rb @@ -119,6 +119,8 @@ RSpec.describe 'User views an open merge request' do let(:source_branch) { "'><iframe/srcdoc=''></iframe>" } before do + stub_feature_flags(moved_mr_sidebar: false) + project.repository.create_branch(source_branch, "master") mr = create(:merge_request, source_project: project, target_project: project, source_branch: source_branch) diff --git a/spec/fixtures/security_reports/master/gl-common-scanning-report.json b/spec/fixtures/security_reports/master/gl-common-scanning-report.json index 1fb00b2ff3a..787573301bb 100644 --- a/spec/fixtures/security_reports/master/gl-common-scanning-report.json +++ b/spec/fixtures/security_reports/master/gl-common-scanning-report.json @@ -1,300 +1,422 @@ { - "vulnerabilities": [ - { - "category": "dependency_scanning", - "name": "Vulnerabilities in libxml2", - "message": "Vulnerabilities in libxml2 in nokogiri", - "description": "", - "cve": "CVE-1020", - "severity": "High", - "solution": "Upgrade to latest version.", - "scanner": { - "id": "gemnasium", - "name": "Gemnasium" - }, - "evidence": { - "source": { - "id": "assert:CORS - Bad 'Origin' value", - "name": "CORS - Bad 'Origin' value" - }, - "summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n", - "request": { - "headers": [ - { - "name": "Host", - "value": "127.0.0.1:7777" - } - ], - "method": "GET", - "url": "http://127.0.0.1:7777/api/users", - "body": "" - }, - "response": { - "headers": [ - { - "name": "Server", - "value": "TwistedWeb/20.3.0" - } - ], - "reason_phrase": "OK", - "status_code": 200, - "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" - }, - "supporting_messages": [ - { - "name": "Origional", - "request": { - "headers": [ - { - "name": "Host", - "value": "127.0.0.1:7777" - } - ], - "method": "GET", - "url": "http://127.0.0.1:7777/api/users", - "body": "" - } - }, - { - "name": "Recorded", - "request": { - "headers": [ - { - "name": "Host", - "value": "127.0.0.1:7777" - } - ], - "method": "GET", - "url": "http://127.0.0.1:7777/api/users", - "body": "" - }, - "response": { - "headers": [ - { - "name": "Server", - "value": "TwistedWeb/20.3.0" - } - ], - "reason_phrase": "OK", - "status_code": 200, - "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" - } - } - ] - }, - "location": {}, - "identifiers": [ - { - "type": "GitLab", - "name": "Foo vulnerability", - "value": "foo" - } - ], - "links": [ - { - "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020" - } - ], - "details": { - "commit": { - "name": [ - { - "lang": "en", - "value": "The Commit" - } - ], - "description": [ - { - "lang": "en", - "value": "Commit where the vulnerability was identified" - } - ], - "type": "commit", - "value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19" - } - } + "vulnerabilities": [{ + "category": "dependency_scanning", + "name": "Vulnerability for remediation testing 1", + "message": "This vulnerability should have ONE remediation", + "description": "", + "cve": "CVE-2137", + "severity": "High", + "solution": "Upgrade to latest version.", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "location": {}, + "identifiers": [{ + "type": "GitLab", + "name": "Foo vulnerability", + "value": "foo" + }], + "links": [{ + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2137" + }], + "details": { + "commit": { + "name": [{ + "lang": "en", + "value": "The Commit" + }], + "description": [{ + "lang": "en", + "value": "Commit where the vulnerability was identified" + }], + "type": "commit", + "value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19" + } + } + }, + { + "category": "dependency_scanning", + "name": "Vulnerability for remediation testing 2", + "message": "This vulnerability should have ONE remediation", + "description": "", + "cve": "CVE-2138", + "severity": "High", + "solution": "Upgrade to latest version.", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "location": {}, + "identifiers": [{ + "type": "GitLab", + "name": "Foo vulnerability", + "value": "foo" + }], + "links": [{ + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2138" + }], + "details": { + "commit": { + "name": [{ + "lang": "en", + "value": "The Commit" + }], + "description": [{ + "lang": "en", + "value": "Commit where the vulnerability was identified" + }], + "type": "commit", + "value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19" + } + } + }, + { + "category": "dependency_scanning", + "name": "Vulnerability for remediation testing 3", + "message": "Remediation for this vulnerability should remediate CVE-2140 as well", + "description": "", + "cve": "CVE-2139", + "severity": "High", + "solution": "Upgrade to latest version.", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "location": {}, + "identifiers": [{ + "type": "GitLab", + "name": "Foo vulnerability", + "value": "foo" + }], + "links": [{ + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2139" + }], + "details": { + "commit": { + "name": [{ + "lang": "en", + "value": "The Commit" + }], + "description": [{ + "lang": "en", + "value": "Commit where the vulnerability was identified" + }], + "type": "commit", + "value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19" + } + } + }, + { + "category": "dependency_scanning", + "name": "Vulnerability for remediation testing 4", + "message": "Remediation for this vulnerability should remediate CVE-2139 as well", + "description": "", + "cve": "CVE-2140", + "severity": "High", + "solution": "Upgrade to latest version.", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "location": {}, + "identifiers": [{ + "type": "GitLab", + "name": "Foo vulnerability", + "value": "foo" + }], + "links": [{ + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2140" + }], + "details": { + "commit": { + "name": [{ + "lang": "en", + "value": "The Commit" + }], + "description": [{ + "lang": "en", + "value": "Commit where the vulnerability was identified" + }], + "type": "commit", + "value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19" + } + } + }, + { + "category": "dependency_scanning", + "name": "Vulnerabilities in libxml2", + "message": "Vulnerabilities in libxml2 in nokogiri", + "description": "", + "cve": "CVE-1020", + "severity": "High", + "solution": "Upgrade to latest version.", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "evidence": { + "source": { + "id": "assert:CORS - Bad 'Origin' value", + "name": "CORS - Bad 'Origin' value" }, - { - "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3", - "category": "dependency_scanning", - "name": "Regular Expression Denial of Service", - "message": "Regular Expression Denial of Service in debug", - "description": "", - "cve": "CVE-1030", - "severity": "Unknown", - "solution": "Upgrade to latest versions.", - "scanner": { - "id": "gemnasium", - "name": "Gemnasium" - }, - "evidence": { - "source": { - "id": "assert:CORS - Bad 'Origin' value", - "name": "CORS - Bad 'Origin' value" - }, - "summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n", - "request": { - "headers": [ - { - "name": "Host", - "value": "127.0.0.1:7777" - } - ], - "method": "GET", - "url": "http://127.0.0.1:7777/api/users", - "body": "" - }, - "response": { - "headers": [ - { - "name": "Server", - "value": "TwistedWeb/20.3.0" - } - ], - "reason_phrase": "OK", - "status_code": 200, - "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" - }, - "supporting_messages": [ - { - "name": "Origional", - "request": { - "headers": [ - { - "name": "Host", - "value": "127.0.0.1:7777" - } - ], - "method": "GET", - "url": "http://127.0.0.1:7777/api/users", - "body": "" - } - }, - { - "name": "Recorded", - "request": { - "headers": [ - { - "name": "Host", - "value": "127.0.0.1:7777" - } - ], - "method": "GET", - "url": "http://127.0.0.1:7777/api/users", - "body": "" - }, - "response": { - "headers": [ - { - "name": "Server", - "value": "TwistedWeb/20.3.0" - } - ], - "reason_phrase": "OK", - "status_code": 200, - "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" - } - } - ] - }, - "location": {}, - "identifiers": [ - { - "type": "GitLab", - "name": "Bar vulnerability", - "value": "bar" - } - ], - "links": [ - { - "name": "CVE-1030", - "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030" - } - ] + "summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n", + "request": { + "headers": [{ + "name": "Host", + "value": "127.0.0.1:7777" + }], + "method": "GET", + "url": "http://127.0.0.1:7777/api/users", + "body": "" }, - { - "category": "dependency_scanning", - "name": "Authentication bypass via incorrect DOM traversal and canonicalization", - "message": "Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js", - "description": "", - "cve": "yarn/yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98", - "severity": "Unknown", - "solution": "Upgrade to fixed version.\r\n", - "scanner": { - "id": "gemnasium", - "name": "Gemnasium" + "response": { + "headers": [{ + "name": "Server", + "value": "TwistedWeb/20.3.0" + }], + "reason_phrase": "OK", + "status_code": 200, + "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" + }, + "supporting_messages": [{ + "name": "Origional", + "request": { + "headers": [{ + "name": "Host", + "value": "127.0.0.1:7777" + }], + "method": "GET", + "url": "http://127.0.0.1:7777/api/users", + "body": "" + } + }, + { + "name": "Recorded", + "request": { + "headers": [{ + "name": "Host", + "value": "127.0.0.1:7777" + }], + "method": "GET", + "url": "http://127.0.0.1:7777/api/users", + "body": "" }, - "location": {}, - "identifiers": [], - "links": [ - ] + "response": { + "headers": [{ + "name": "Server", + "value": "TwistedWeb/20.3.0" + }], + "reason_phrase": "OK", + "status_code": 200, + "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" + } + } + ] + }, + "location": {}, + "identifiers": [{ + "type": "GitLab", + "name": "Foo vulnerability", + "value": "foo" + }], + "links": [{ + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020" + }], + "details": { + "commit": { + "name": [{ + "lang": "en", + "value": "The Commit" + }], + "description": [{ + "lang": "en", + "value": "Commit where the vulnerability was identified" + }], + "type": "commit", + "value": "41df7b7eb3be2b5be2c406c2f6d28cd6631eeb19" } - ], - "remediations": [ - { - "fixes": [ - { - "cve": "CVE-1020" - } - ], - "summary": "", - "diff": "" - }, - { - "fixes": [ - { - "cve": "CVE", - "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3" - } - ], - "summary": "", - "diff": "" + } + }, + { + "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3", + "category": "dependency_scanning", + "name": "Regular Expression Denial of Service", + "message": "Regular Expression Denial of Service in debug", + "description": "", + "cve": "CVE-1030", + "severity": "Unknown", + "solution": "Upgrade to latest versions.", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "evidence": { + "source": { + "id": "assert:CORS - Bad 'Origin' value", + "name": "CORS - Bad 'Origin' value" }, - { - "fixes": [ - { - "cve": "CVE", - "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3" - } - ], - "summary": "", - "diff": "" + "summary": "The Origin header was changed to an invalid value of http://peachapisecurity.com and the response contained an Access-Control-Allow-Origin header which included this invalid Origin, indicating that the CORS configuration on the server is overly permissive.\n\n\n", + "request": { + "headers": [{ + "name": "Host", + "value": "127.0.0.1:7777" + }], + "method": "GET", + "url": "http://127.0.0.1:7777/api/users", + "body": "" }, - { - "fixes": [ - { - "id": "2134", - "cve": "CVE-1" - } - ], - "summary": "", - "diff": "" - } - ], - "dependency_files": [], - "scan": { - "analyzer": { - "id": "common-analyzer", - "name": "Common Analyzer", - "url": "https://site.com/analyzer/common", - "version": "2.0.1", - "vendor": { - "name": "Common" - } + "response": { + "headers": [{ + "name": "Server", + "value": "TwistedWeb/20.3.0" + }], + "reason_phrase": "OK", + "status_code": 200, + "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" }, - "scanner": { - "id": "gemnasium", - "name": "Gemnasium", - "url": "https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven", - "vendor": { - "name": "GitLab" + "supporting_messages": [{ + "name": "Origional", + "request": { + "headers": [{ + "name": "Host", + "value": "127.0.0.1:7777" + }], + "method": "GET", + "url": "http://127.0.0.1:7777/api/users", + "body": "" + } + }, + { + "name": "Recorded", + "request": { + "headers": [{ + "name": "Host", + "value": "127.0.0.1:7777" + }], + "method": "GET", + "url": "http://127.0.0.1:7777/api/users", + "body": "" }, - "version": "2.18.0" - }, - "type": "dependency_scanning", - "start_time": "placeholder-value", - "end_time": "placeholder-value", - "status": "success" + "response": { + "headers": [{ + "name": "Server", + "value": "TwistedWeb/20.3.0" + }], + "reason_phrase": "OK", + "status_code": 200, + "body": "[{\"user_id\":1,\"user\":\"admin\",\"first\":\"Joe\",\"last\":\"Smith\",\"password\":\"Password!\"}]" + } + } + ] + }, + "location": {}, + "identifiers": [{ + "type": "GitLab", + "name": "Bar vulnerability", + "value": "bar" + }], + "links": [{ + "name": "CVE-1030", + "url": "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030" + }] + }, + { + "category": "dependency_scanning", + "name": "Authentication bypass via incorrect DOM traversal and canonicalization", + "message": "Authentication bypass via incorrect DOM traversal and canonicalization in saml2-js", + "description": "", + "cve": "yarn/yarn.lock:saml2-js:gemnasium:9952e574-7b5b-46fa-a270-aeb694198a98", + "severity": "Unknown", + "solution": "Upgrade to fixed version.\r\n", + "scanner": { + "id": "gemnasium", + "name": "Gemnasium" + }, + "location": {}, + "identifiers": [], + "links": [] + } + ], + "remediations": [{ + "fixes": [{ + "cve": "CVE-2137" + }], + "summary": "this remediates CVE-2137", + "diff": "dG90YWxseSBsZWdpdCBkaWZm" + }, + { + "fixes": [{ + "cve": "CVE-2138" + }], + "summary": "this remediates CVE-2138", + "diff": "dG90YWxseSBsZWdpdCBkaWZm" + }, + { + "fixes": [{ + "cve": "CVE-2139" + }, { + "cve": "CVE-2140" + }], + "summary": "this remediates CVE-2139 and CVE-2140", + "diff": "dG90YWxseSBsZWdpdGltYXRlIGRpZmYsIDEwLzEwIHdvdWxkIGFwcGx5" + }, + { + "fixes": [{ + "cve": "CVE-1020" + }], + "summary": "", + "diff": "" + }, + { + "fixes": [{ + "cve": "CVE", + "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3" + }], + "summary": "", + "diff": "" + }, + { + "fixes": [{ + "cve": "CVE", + "id": "bb2fbeb1b71ea360ce3f86f001d4e84823c3ffe1a1f7d41ba7466b14cfa953d3" + }], + "summary": "", + "diff": "" + }, + { + "fixes": [{ + "id": "2134", + "cve": "CVE-1" + }], + "summary": "", + "diff": "" + } + ], + "dependency_files": [], + "scan": { + "analyzer": { + "id": "common-analyzer", + "name": "Common Analyzer", + "url": "https://site.com/analyzer/common", + "version": "2.0.1", + "vendor": { + "name": "Common" + } + }, + "scanner": { + "id": "gemnasium", + "name": "Gemnasium", + "url": "https://gitlab.com/gitlab-org/security-products/analyzers/gemnasium-maven", + "vendor": { + "name": "GitLab" + }, + "version": "2.18.0" }, - "version": "14.0.2" + "type": "dependency_scanning", + "start_time": "placeholder-value", + "end_time": "placeholder-value", + "status": "success" + }, + "version": "14.0.2" } diff --git a/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js b/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js index edcacb0f740..e6e587ff44b 100644 --- a/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js +++ b/spec/frontend/behaviors/shortcuts/shortcuts_issuable_spec.js @@ -1,5 +1,4 @@ import $ from 'jquery'; -import Mousetrap from 'mousetrap'; import { loadHTMLFixture, resetHTMLFixture } from 'helpers/fixtures'; import waitForPromises from 'helpers/wait_for_promises'; import initCopyAsGFM, { CopyAsGFM } from '~/behaviors/markdown/copy_as_gfm'; @@ -13,7 +12,6 @@ jest.mock('~/lib/utils/common_utils', () => ({ describe('ShortcutsIssuable', () => { const snippetShowFixtureName = 'snippets/show.html'; - const mrShowFixtureName = 'merge_requests/merge_request_of_current_user.html'; beforeAll(() => { initCopyAsGFM(); @@ -282,40 +280,4 @@ describe('ShortcutsIssuable', () => { }); }); }); - - describe('copyBranchName', () => { - let sidebarCollapsedBtn; - let sidebarExpandedBtn; - - beforeEach(() => { - loadHTMLFixture(mrShowFixtureName); - - window.shortcut = new ShortcutsIssuable(); - - [sidebarCollapsedBtn, sidebarExpandedBtn] = document.querySelectorAll( - '.js-source-branch-copy', - ); - - [sidebarCollapsedBtn, sidebarExpandedBtn].forEach((btn) => jest.spyOn(btn, 'click')); - }); - - afterEach(() => { - delete window.shortcut; - resetHTMLFixture(); - }); - - describe('when the sidebar is expanded', () => { - beforeEach(() => { - // simulate the applied CSS styles when the - // sidebar is expanded - sidebarCollapsedBtn.style.display = 'none'; - - Mousetrap.trigger('b'); - }); - - it('clicks the "expanded" version of the copy source branch button', () => { - expect(sidebarExpandedBtn.click).toHaveBeenCalled(); - }); - }); - }); }); diff --git a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb index c042f6dac19..14ebe85d80e 100644 --- a/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb +++ b/spec/graphql/resolvers/alert_management/alert_resolver_spec.rb @@ -39,8 +39,8 @@ RSpec.describe Resolvers::AlertManagement::AlertResolver do end context 'filtering by domain' do - let_it_be(:alert1) { create(:alert_management_alert, project: project, monitoring_tool: 'Cilium', domain: :threat_monitoring) } - let_it_be(:alert2) { create(:alert_management_alert, project: project, monitoring_tool: 'Cilium', domain: :threat_monitoring) } + let_it_be(:alert1) { create(:alert_management_alert, project: project, monitoring_tool: 'other', domain: :threat_monitoring) } + let_it_be(:alert2) { create(:alert_management_alert, project: project, monitoring_tool: 'other', domain: :threat_monitoring) } let_it_be(:alert3) { create(:alert_management_alert, project: project, monitoring_tool: 'generic') } let(:args) { { domain: 'operations' } } diff --git a/spec/graphql/types/ci/runner_type_spec.rb b/spec/graphql/types/ci/runner_type_spec.rb index b2fbfda898e..26ac7a4da8d 100644 --- a/spec/graphql/types/ci/runner_type_spec.rb +++ b/spec/graphql/types/ci/runner_type_spec.rb @@ -12,7 +12,7 @@ RSpec.describe GitlabSchema.types['CiRunner'] do id description created_at contacted_at maximum_timeout access_level active paused status version short_sha revision locked run_untagged ip_address runner_type tag_list project_count job_count admin_url edit_admin_url user_permissions executor_name architecture_name platform_name - groups projects jobs token_expires_at + maintenance_note groups projects jobs token_expires_at ] expect(described_class).to include_graphql_fields(*expected_fields) diff --git a/spec/lib/gitlab/ci/parsers/security/common_spec.rb b/spec/lib/gitlab/ci/parsers/security/common_spec.rb index dfc5dec1481..6495d1f654b 100644 --- a/spec/lib/gitlab/ci/parsers/security/common_spec.rb +++ b/spec/lib/gitlab/ci/parsers/security/common_spec.rb @@ -292,7 +292,7 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do expect(scans.map(&:status).all?('success')).to be(true) expect(scans.map(&:start_time).all?('placeholder-value')).to be(true) expect(scans.map(&:end_time).all?('placeholder-value')).to be(true) - expect(scans.size).to eq(3) + expect(scans.size).to eq(7) expect(scans.first).to be_a(::Gitlab::Ci::Reports::Security::Scan) end @@ -348,22 +348,29 @@ RSpec.describe Gitlab::Ci::Parsers::Security::Common do it 'returns links object for each finding', :aggregate_failures do links = report.findings.flat_map(&:links) - expect(links.map(&:url)).to match_array(['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030']) - expect(links.map(&:name)).to match_array([nil, 'CVE-1030']) - expect(links.size).to eq(2) + expect(links.map(&:url)).to match_array(['https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1020', 'https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-1030', + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2137", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2138", + "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2139", "https://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2020-2140"]) + expect(links.map(&:name)).to match_array([nil, nil, nil, nil, nil, 'CVE-1030']) + expect(links.size).to eq(6) expect(links.first).to be_a(::Gitlab::Ci::Reports::Security::Link) end end describe 'parsing evidence' do - it 'returns evidence object for each finding', :aggregate_failures do - evidences = report.findings.map(&:evidence) + RSpec::Matchers.define_negated_matcher :have_values, :be_empty - expect(evidences.first.data).not_to be_empty - expect(evidences.first.data["summary"]).to match(/The Origin header was changed/) - expect(evidences.size).to eq(3) - expect(evidences.compact.size).to eq(2) - expect(evidences.first).to be_a(::Gitlab::Ci::Reports::Security::Evidence) + it 'returns evidence object for each finding', :aggregate_failures do + all_evidences = report.findings.map(&:evidence) + evidences = all_evidences.compact + data = evidences.map(&:data) + summaries = evidences.map { |e| e.data["summary"] } + + expect(all_evidences.size).to eq(7) + expect(evidences.size).to eq(2) + expect(evidences).to all( be_a(::Gitlab::Ci::Reports::Security::Evidence) ) + expect(data).to all( have_values ) + expect(summaries).to all( match(/The Origin header was changed/) ) end end diff --git a/spec/lib/gitlab/query_limiting/transaction_spec.rb b/spec/lib/gitlab/query_limiting/transaction_spec.rb index 32a31f091bb..27da1f23556 100644 --- a/spec/lib/gitlab/query_limiting/transaction_spec.rb +++ b/spec/lib/gitlab/query_limiting/transaction_spec.rb @@ -85,6 +85,12 @@ RSpec.describe Gitlab::QueryLimiting::Transaction do expect do transaction.increment(described_class::GEO_NODES_LOAD) transaction.increment(described_class::LICENSES_LOAD) + transaction.increment('SELECT a.attname, a.other_column FROM pg_attribute a') + transaction.increment('SELECT x.foo, a.attname FROM some_table x JOIN pg_attribute a') + transaction.increment(<<-SQL) + SELECT a.attname, a.other_column + FROM pg_attribute a + SQL end.not_to change(transaction, :count) end end diff --git a/spec/models/deploy_token_spec.rb b/spec/models/deploy_token_spec.rb index 86eb38814ed..635326eeadc 100644 --- a/spec/models/deploy_token_spec.rb +++ b/spec/models/deploy_token_spec.rb @@ -73,10 +73,10 @@ RSpec.describe DeployToken do describe '#ensure_token' do it 'ensures a token' do - deploy_token.token = nil + deploy_token.token_encrypted = nil deploy_token.save! - expect(deploy_token.token).not_to be_empty + expect(deploy_token.token_encrypted).not_to be_empty end end diff --git a/spec/requests/api/graphql/ci/runner_spec.rb b/spec/requests/api/graphql/ci/runner_spec.rb index 46361e49d5e..6fa455cbfca 100644 --- a/spec/requests/api/graphql/ci/runner_spec.rb +++ b/spec/requests/api/graphql/ci/runner_spec.rb @@ -11,7 +11,8 @@ RSpec.describe 'Query.runner(id)' do let_it_be(:active_instance_runner) do create(:ci_runner, :instance, description: 'Runner 1', contacted_at: 2.hours.ago, active: true, version: 'adfe156', revision: 'a', locked: true, ip_address: '127.0.0.1', maximum_timeout: 600, - access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :custom) + access_level: 0, tag_list: %w[tag1 tag2], run_untagged: true, executor_type: :custom, + maintenance_note: 'Test maintenance note') end let_it_be(:inactive_instance_runner) do @@ -64,6 +65,7 @@ RSpec.describe 'Query.runner(id)' do 'executorName' => runner.executor_type&.dasherize, 'architectureName' => runner.architecture, 'platformName' => runner.platform, + 'maintenanceNote' => runner.maintenance_note, 'jobCount' => 0, 'jobs' => a_hash_including("count" => 0, "nodes" => [], "pageInfo" => anything), 'projectCount' => nil, diff --git a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb index 98963f57341..90956e7b4ea 100644 --- a/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_namespace_service_spec.rb @@ -39,8 +39,6 @@ RSpec.describe Clusters::Kubernetes::CreateOrUpdateNamespaceService, '#execute' stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME, namespace: namespace) stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace) - stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME, namespace: namespace) - stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME, namespace: namespace) stub_kubeclient_get_secret( api_url, diff --git a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb index 11045dfe950..a4f018aec0c 100644 --- a/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb +++ b/spec/services/clusters/kubernetes/create_or_update_service_account_service_spec.rb @@ -147,8 +147,6 @@ RSpec.describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_KNATIVE_SERVING_ROLE_BINDING_NAME, namespace: namespace) stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_NAME, namespace: namespace) stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CROSSPLANE_DATABASE_ROLE_BINDING_NAME, namespace: namespace) - stub_kubeclient_put_role(api_url, Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME, namespace: namespace) - stub_kubeclient_put_role_binding(api_url, Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME, namespace: namespace) end it 'creates a namespace object' do @@ -245,47 +243,6 @@ RSpec.describe Clusters::Kubernetes::CreateOrUpdateServiceAccountService do ) ) end - - it 'creates a role granting cilium permissions to the service account' do - subject - - expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/roles/#{Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME}").with( - body: hash_including( - metadata: { - name: Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME, - namespace: namespace - }, - rules: [{ - apiGroups: %w(cilium.io), - resources: %w(ciliumnetworkpolicies), - verbs: %w(get list create update patch) - }] - ) - ) - end - - it 'creates a role binding granting cilium permissions to the service account' do - subject - - expect(WebMock).to have_requested(:put, api_url + "/apis/rbac.authorization.k8s.io/v1/namespaces/#{namespace}/rolebindings/#{Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME}").with( - body: hash_including( - metadata: { - name: Clusters::Kubernetes::GITLAB_CILIUM_ROLE_BINDING_NAME, - namespace: namespace - }, - roleRef: { - apiGroup: 'rbac.authorization.k8s.io', - kind: 'Role', - name: Clusters::Kubernetes::GITLAB_CILIUM_ROLE_NAME - }, - subjects: [{ - kind: 'ServiceAccount', - name: service_account_name, - namespace: namespace - }] - ) - ) - end end end end diff --git a/spec/support/helpers/filtered_search_helpers.rb b/spec/support/helpers/filtered_search_helpers.rb index 5b74f347a44..93122ca3d0c 100644 --- a/spec/support/helpers/filtered_search_helpers.rb +++ b/spec/support/helpers/filtered_search_helpers.rb @@ -274,6 +274,10 @@ module FilteredSearchHelpers expect(page).to have_css '.gl-filtered-search-token', text: "Milestone != %#{value}" end + def expect_epic_token(value) + expect(page).to have_css '.gl-filtered-search-token', text: "Epic = #{value}" + end + def expect_search_term(value) value.split(' ').each do |term| expect(page).to have_css '.gl-filtered-search-term', text: term |