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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2021-08-10 03:10:29 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2021-08-10 03:10:29 +0300
commit981771279a48c03263e29f3b4f41f54204ea3146 (patch)
tree5e48e8debb84850147d183b094ffcd9d8b084c48 /spec
parenta8648ba08604085c76be1e4f5253ffa89aa192e3 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/frontend/snippets/components/snippet_header_spec.js150
-rw-r--r--spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js3
-rw-r--r--spec/helpers/snippets_helper_spec.rb19
-rw-r--r--spec/lib/gitlab/ci/reports/security/reports_spec.rb34
4 files changed, 157 insertions, 49 deletions
diff --git a/spec/frontend/snippets/components/snippet_header_spec.js b/spec/frontend/snippets/components/snippet_header_spec.js
index e77bae79f68..fb95be3a77c 100644
--- a/spec/frontend/snippets/components/snippet_header_spec.js
+++ b/spec/frontend/snippets/components/snippet_header_spec.js
@@ -1,4 +1,4 @@
-import { GlButton, GlModal } from '@gitlab/ui';
+import { GlButton, GlModal, GlDropdown } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import { ApolloMutation } from 'vue-apollo';
import { useMockLocationHelper } from 'helpers/mock_window_location_helper';
@@ -8,8 +8,6 @@ import { differenceInMilliseconds } from '~/lib/utils/datetime_utility';
import SnippetHeader from '~/snippets/components/snippet_header.vue';
import DeleteSnippetMutation from '~/snippets/mutations/deleteSnippet.mutation.graphql';
-useMockLocationHelper();
-
describe('Snippet header component', () => {
let wrapper;
let snippet;
@@ -19,6 +17,7 @@ describe('Snippet header component', () => {
let errorMsg;
let err;
const originalRelativeUrlRoot = gon.relative_url_root;
+ const reportAbusePath = '/-/snippets/42/mark_as_spam';
const GlEmoji = { template: '<img/>' };
@@ -27,6 +26,7 @@ describe('Snippet header component', () => {
permissions = {},
mutationRes = mutationTypes.RESOLVE,
snippetProps = {},
+ provide = {},
} = {}) {
const defaultProps = Object.assign(snippet, snippetProps);
if (permissions) {
@@ -45,6 +45,10 @@ describe('Snippet header component', () => {
wrapper = mount(SnippetHeader, {
mocks: { $apollo },
+ provide: {
+ reportAbusePath,
+ ...provide,
+ },
propsData: {
snippet: {
...defaultProps,
@@ -57,9 +61,27 @@ describe('Snippet header component', () => {
});
}
- const findAuthorEmoji = () => wrapper.find(GlEmoji);
+ const findAuthorEmoji = () => wrapper.findComponent(GlEmoji);
const findAuthoredMessage = () => wrapper.find('[data-testid="authored-message"]').text();
- const buttonCount = () => wrapper.findAll(GlButton).length;
+ const findButtons = () => wrapper.findAllComponents(GlButton);
+ const findButtonsAsModel = () =>
+ findButtons().wrappers.map((x) => ({
+ text: x.text(),
+ href: x.attributes('href'),
+ category: x.props('category'),
+ variant: x.props('variant'),
+ disabled: x.props('disabled'),
+ }));
+ const findResponsiveDropdown = () => wrapper.findComponent(GlDropdown);
+ // We can't search by component here since we are full mounting and the attributes are applied to a child of the GlDropdownItem
+ const findResponsiveDropdownItems = () => findResponsiveDropdown().findAll('[role="menuitem"]');
+ const findResponsiveDropdownItemsAsModel = () =>
+ findResponsiveDropdownItems().wrappers.map((x) => ({
+ disabled: x.attributes('disabled'),
+ href: x.attributes('href'),
+ title: x.attributes('title'),
+ text: x.text(),
+ }));
beforeEach(() => {
gon.relative_url_root = '/foo/';
@@ -144,42 +166,108 @@ describe('Snippet header component', () => {
expect(text).toBe('Authored 1 month ago');
});
- it('renders action buttons based on permissions', () => {
- createComponent({
- permissions: {
- adminSnippet: false,
- updateSnippet: false,
+ it('renders a action buttons', () => {
+ createComponent();
+
+ expect(findButtonsAsModel()).toEqual([
+ {
+ category: 'primary',
+ disabled: false,
+ href: `${snippet.webUrl}/edit`,
+ text: 'Edit',
+ variant: 'default',
},
- });
- expect(buttonCount()).toEqual(0);
+ {
+ category: 'secondary',
+ disabled: false,
+ text: 'Delete',
+ variant: 'danger',
+ },
+ {
+ category: 'primary',
+ disabled: false,
+ href: reportAbusePath,
+ text: 'Submit as spam',
+ variant: 'default',
+ },
+ ]);
+ });
- createComponent({
- permissions: {
- adminSnippet: true,
- updateSnippet: false,
+ it('renders responsive dropdown for action buttons', () => {
+ createComponent();
+
+ expect(findResponsiveDropdownItemsAsModel()).toEqual([
+ {
+ href: `${snippet.webUrl}/edit`,
+ text: 'Edit',
},
- });
- expect(buttonCount()).toEqual(1);
+ {
+ text: 'Delete',
+ },
+ {
+ href: reportAbusePath,
+ text: 'Submit as spam',
+ title: 'Submit as spam',
+ },
+ ]);
+ });
+ it.each`
+ permissions | buttons
+ ${{ adminSnippet: false, updateSnippet: false }} | ${['Submit as spam']}
+ ${{ adminSnippet: true, updateSnippet: false }} | ${['Delete', 'Submit as spam']}
+ ${{ adminSnippet: false, updateSnippet: true }} | ${['Edit', 'Submit as spam']}
+ `('with permissions ($permissions), renders buttons ($buttons)', ({ permissions, buttons }) => {
createComponent({
permissions: {
- adminSnippet: true,
- updateSnippet: true,
+ ...permissions,
},
});
- expect(buttonCount()).toEqual(2);
- createComponent({
- permissions: {
- adminSnippet: true,
- updateSnippet: true,
- },
+ expect(findButtonsAsModel().map((x) => x.text)).toEqual(buttons);
+ });
+
+ it('with canCreateSnippet permission, renders create button', async () => {
+ createComponent();
+
+ // TODO: we should avoid `wrapper.setData` since they
+ // are component internals. Let's use the apollo mock helpers
+ // in a follow-up.
+ wrapper.setData({ canCreateSnippet: true });
+ await wrapper.vm.$nextTick();
+
+ expect(findButtonsAsModel()).toEqual(
+ expect.arrayContaining([
+ {
+ category: 'secondary',
+ disabled: false,
+ href: `/foo/-/snippets/new`,
+ text: 'New snippet',
+ variant: 'success',
+ },
+ ]),
+ );
+ });
+
+ describe('with guest user', () => {
+ beforeEach(() => {
+ createComponent({
+ permissions: {
+ adminSnippet: false,
+ updateSnippet: false,
+ },
+ provide: {
+ reportAbusePath: null,
+ },
+ });
});
- wrapper.setData({
- canCreateSnippet: true,
+
+ it('does not show any action buttons', () => {
+ expect(findButtons()).toHaveLength(0);
});
- return wrapper.vm.$nextTick().then(() => {
- expect(buttonCount()).toEqual(3);
+
+ it('does not show responsive action dropdown', () => {
+ expect(findResponsiveDropdown().exists()).toBe(false);
});
});
@@ -221,6 +309,8 @@ describe('Snippet header component', () => {
});
describe('in case of successful mutation, closes modal and redirects to correct listing', () => {
+ useMockLocationHelper();
+
const createDeleteSnippet = (snippetProps = {}) => {
createComponent({
snippetProps,
diff --git a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
index 19e4f2d8c92..786dfabb990 100644
--- a/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
+++ b/spec/frontend/vue_shared/components/markdown/toolbar_button_spec.js
@@ -1,4 +1,3 @@
-import { GlButton } from '@gitlab/ui';
import { shallowMount } from '@vue/test-utils';
import ToolbarButton from '~/vue_shared/components/markdown/toolbar_button.vue';
@@ -26,7 +25,7 @@ describe('toolbar_button', () => {
});
const getButtonShortcutsAttr = () => {
- return wrapper.find(GlButton).attributes('data-md-shortcuts');
+ return wrapper.find('button').attributes('data-md-shortcuts');
};
describe('keyboard shortcuts', () => {
diff --git a/spec/helpers/snippets_helper_spec.rb b/spec/helpers/snippets_helper_spec.rb
index 35882c9337b..12d791d8710 100644
--- a/spec/helpers/snippets_helper_spec.rb
+++ b/spec/helpers/snippets_helper_spec.rb
@@ -92,4 +92,23 @@ RSpec.describe SnippetsHelper do
end
end
end
+
+ describe '#snippet_report_abuse_path' do
+ let(:snippet) { public_personal_snippet }
+ let(:current_user) { create(:user) }
+
+ subject { snippet_report_abuse_path(snippet) }
+
+ it 'returns false if the user cannot submit the snippet as spam' do
+ allow(snippet).to receive(:submittable_as_spam_by?).and_return(false)
+
+ expect(subject).to be_falsey
+ end
+
+ it 'returns true if the user can submit the snippet as spam' do
+ allow(snippet).to receive(:submittable_as_spam_by?).and_return(true)
+
+ expect(subject).to be_truthy
+ end
+ end
end
diff --git a/spec/lib/gitlab/ci/reports/security/reports_spec.rb b/spec/lib/gitlab/ci/reports/security/reports_spec.rb
index d6a18828120..9b1e02f1418 100644
--- a/spec/lib/gitlab/ci/reports/security/reports_spec.rb
+++ b/spec/lib/gitlab/ci/reports/security/reports_spec.rb
@@ -54,27 +54,25 @@ RSpec.describe Gitlab::Ci::Reports::Security::Reports do
end
describe "#violates_default_policy_against?" do
- let(:low_severity_sast) { build(:ci_reports_security_finding, severity: 'low', report_type: :sast) }
let(:high_severity_dast) { build(:ci_reports_security_finding, severity: 'high', report_type: :dast) }
let(:vulnerabilities_allowed) { 0 }
+ let(:severity_levels) { %w(critical high) }
- subject { security_reports.violates_default_policy_against?(target_reports, vulnerabilities_allowed) }
+ subject { security_reports.violates_default_policy_against?(target_reports, vulnerabilities_allowed, severity_levels) }
+
+ before do
+ security_reports.get_report('sast', artifact).add_finding(high_severity_dast)
+ end
context 'when the target_reports is `nil`' do
let(:target_reports) { nil }
- context "when a report has unsafe vulnerability" do
- before do
- security_reports.get_report('sast', artifact).add_finding(high_severity_dast)
- end
-
+ context 'with severity levels matching the existing vulnerabilities' do
it { is_expected.to be(true) }
end
- context "when none of the reports have an unsafe vulnerability" do
- before do
- security_reports.get_report('sast', artifact).add_finding(low_severity_sast)
- end
+ context "without any severity levels matching the existing vulnerabilities" do
+ let(:severity_levels) { %w(critical) }
it { is_expected.to be(false) }
end
@@ -84,10 +82,8 @@ RSpec.describe Gitlab::Ci::Reports::Security::Reports do
let(:target_reports) { described_class.new(pipeline) }
context "when a report has a new unsafe vulnerability" do
- before do
- security_reports.get_report('sast', artifact).add_finding(high_severity_dast)
- security_reports.get_report('dependency_scanning', artifact).add_finding(low_severity_sast)
- target_reports.get_report('dependency_scanning', artifact).add_finding(low_severity_sast)
+ context 'with severity levels matching the existing vulnerabilities' do
+ it { is_expected.to be(true) }
end
it { is_expected.to be(true) }
@@ -97,12 +93,16 @@ RSpec.describe Gitlab::Ci::Reports::Security::Reports do
it { is_expected.to be(false) }
end
+
+ context "without any severity levels matching the existing vulnerabilities" do
+ let(:severity_levels) { %w(critical) }
+
+ it { is_expected.to be(false) }
+ end
end
context "when none of the reports have a new unsafe vulnerability" do
before do
- security_reports.get_report('sast', artifact).add_finding(high_severity_dast)
- security_reports.get_report('sast', artifact).add_finding(low_severity_sast)
target_reports.get_report('sast', artifact).add_finding(high_severity_dast)
end