diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-19 03:09:03 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2022-03-19 03:09:03 +0300 |
commit | cd49d91db362a479c1b53de07741713f7e7ea2cc (patch) | |
tree | 6d5f244f9d6e805a15ffc93172454788658af1d7 /spec | |
parent | 705210af74e93f829f59e00f311cba07ea8bd5c7 (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
8 files changed, 403 insertions, 227 deletions
diff --git a/spec/experiments/video_tutorials_continuous_onboarding_experiment_spec.rb b/spec/experiments/video_tutorials_continuous_onboarding_experiment_spec.rb new file mode 100644 index 00000000000..596791308a4 --- /dev/null +++ b/spec/experiments/video_tutorials_continuous_onboarding_experiment_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe VideoTutorialsContinuousOnboardingExperiment do + it "defines a control and candidate" do + expect(subject.behaviors.keys).to match_array(%w[control candidate]) + end +end diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_section_card_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_section_card_spec.js.snap index 9e00ace761c..83feb621478 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_section_card_spec.js.snap +++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_section_card_spec.js.snap @@ -2,31 +2,26 @@ exports[`Learn GitLab Section Card renders correctly 1`] = ` <gl-card-stub - bodyclass="" - class="gl-pt-0 learn-gitlab-section-card" + bodyclass="gl-pt-0" + class="gl-pt-0 h-100" footerclass="" - headerclass="" + headerclass="gl-bg-white gl-border-0 gl-pb-0" > - <div - class="learn-gitlab-section-card-header" + <img + src="workspace.svg" + /> + + <h2 + class="gl-font-lg gl-mb-3" > - <img - src="workspace.svg" - /> - - <h2 - class="gl-font-lg gl-mb-3" - > - Set up your workspace - </h2> - - <p - class="gl-text-gray-700 gl-mb-6" - > - Complete these tasks first so you can enjoy GitLab's features to their fullest: - </p> - </div> + Set up your workspace + </h2> + <p + class="gl-text-gray-700 gl-mb-6" + > + Complete these tasks first so you can enjoy GitLab's features to their fullest: + </p> <learn-gitlab-section-link-stub action="userAdded" value="[object Object]" diff --git a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap index 62cf769cffd..269c7467c8b 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap +++ b/spec/frontend/pages/projects/learn_gitlab/components/__snapshots__/learn_gitlab_spec.js.snap @@ -51,170 +51,204 @@ exports[`Learn GitLab renders correctly 1`] = ` </div> <div - class="row row-cols-1 row-cols-md-3 gl-mt-5" + class="row" > <div - class="col gl-mb-6" + class="gl-mt-5 col-sm-12 col-mb-6 col-lg-4" > <div - class="gl-card gl-pt-0 learn-gitlab-section-card" + class="gl-card gl-pt-0 h-100" > - <!----> - <div - class="gl-card-body" + class="gl-card-header gl-bg-white gl-border-0 gl-pb-0" > - <div - class="learn-gitlab-section-card-header" + <img + src="workspace.svg" + /> + + <h2 + class="gl-font-lg gl-mb-3" > - <img - src="workspace.svg" - /> - - <h2 - class="gl-font-lg gl-mb-3" - > - Set up your workspace - </h2> - - <p - class="gl-text-gray-700 gl-mb-6" - > - Complete these tasks first so you can enjoy GitLab's features to their fullest: - </p> - </div> + Set up your workspace + </h2> + <p + class="gl-text-gray-700 gl-mb-6" + > + Complete these tasks first so you can enjoy GitLab's features to their fullest: + </p> + </div> + + <div + class="gl-card-body gl-pt-0" + > <div class="gl-mb-4" > - <span - class="gl-text-green-500" + <!----> + + <div + class="flex align-items-center" > - <svg - aria-hidden="true" - class="gl-icon s16" - data-testid="completed-icon" - role="img" + <span + class="gl-text-green-500" > - <use - href="#check-circle-filled" - /> - </svg> - - Invite your colleagues - - </span> - - <!----> + <svg + aria-hidden="true" + class="gl-icon s16" + data-testid="completed-icon" + role="img" + > + <use + href="#check-circle-filled" + /> + </svg> + + Invite your colleagues + + </span> + + <!----> + </div> </div> <div class="gl-mb-4" > - <span - class="gl-text-green-500" + <!----> + + <div + class="flex align-items-center" > - <svg - aria-hidden="true" - class="gl-icon s16" - data-testid="completed-icon" - role="img" + <span + class="gl-text-green-500" > - <use - href="#check-circle-filled" - /> - </svg> - - Create or import a repository - - </span> - - <!----> + <svg + aria-hidden="true" + class="gl-icon s16" + data-testid="completed-icon" + role="img" + > + <use + href="#check-circle-filled" + /> + </svg> + + Create or import a repository + + </span> + + <!----> + </div> </div> <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Set up CI/CD" - href="http://example.com/" - target="_self" - > - - Set up CI/CD - - </a> - <!----> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Set up CI/CD" + href="http://example.com/" + target="_self" + > + + Set up CI/CD + + </a> + + <!----> + </div> </div> <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Start a free Ultimate trial" - href="http://example.com/" - target="_self" - > - - Start a free Ultimate trial - - </a> - <!----> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Start a free Ultimate trial" + href="http://example.com/" + target="_self" + > + + Start a free Ultimate trial + + </a> + + <!----> + </div> </div> <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Add code owners" - href="http://example.com/" - target="_self" - > - - Add code owners - - </a> - - <span + <div class="gl-font-style-italic gl-text-gray-500" data-testid="trial-only" > - - Trial only + Trial only - </span> + </div> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Add code owners" + href="http://example.com/" + target="_self" + > + + Add code owners + + </a> + + <!----> + </div> </div> <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Add merge request approval" - href="http://example.com/" - target="_self" - > - - Add merge request approval - - </a> - - <span + <div class="gl-font-style-italic gl-text-gray-500" data-testid="trial-only" > - - Trial only + Trial only - </span> + </div> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Add merge request approval" + href="http://example.com/" + target="_self" + > + + Add merge request approval + + </a> + + <!----> + </div> </div> </div> @@ -222,71 +256,81 @@ exports[`Learn GitLab renders correctly 1`] = ` </div> </div> <div - class="col gl-mb-6" + class="gl-mt-5 col-sm-12 col-mb-6 col-lg-4" > <div - class="gl-card gl-pt-0 learn-gitlab-section-card" + class="gl-card gl-pt-0 h-100" > - <!----> - <div - class="gl-card-body" + class="gl-card-header gl-bg-white gl-border-0 gl-pb-0" > - <div - class="learn-gitlab-section-card-header" + <img + src="plan.svg" + /> + + <h2 + class="gl-font-lg gl-mb-3" > - <img - src="plan.svg" - /> - - <h2 - class="gl-font-lg gl-mb-3" - > - Plan and execute - </h2> - - <p - class="gl-text-gray-700 gl-mb-6" - > - Create a workflow for your new workspace, and learn how GitLab features work together: - </p> - </div> + Plan and execute + </h2> + <p + class="gl-text-gray-700 gl-mb-6" + > + Create a workflow for your new workspace, and learn how GitLab features work together: + </p> + </div> + + <div + class="gl-card-body gl-pt-0" + > <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Create an issue" - href="http://example.com/" - target="_self" - > - - Create an issue - - </a> - <!----> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Create an issue" + href="http://example.com/" + target="_self" + > + + Create an issue + + </a> + + <!----> + </div> </div> <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Submit a merge request" - href="http://example.com/" - target="_self" - > - - Submit a merge request - - </a> - <!----> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Submit a merge request" + href="http://example.com/" + target="_self" + > + + Submit a merge request + + </a> + + <!----> + </div> </div> </div> @@ -294,54 +338,58 @@ exports[`Learn GitLab renders correctly 1`] = ` </div> </div> <div - class="col gl-mb-6" + class="gl-mt-5 col-sm-12 col-mb-6 col-lg-4" > <div - class="gl-card gl-pt-0 learn-gitlab-section-card" + class="gl-card gl-pt-0 h-100" > - <!----> - <div - class="gl-card-body" + class="gl-card-header gl-bg-white gl-border-0 gl-pb-0" > - <div - class="learn-gitlab-section-card-header" + <img + src="deploy.svg" + /> + + <h2 + class="gl-font-lg gl-mb-3" > - <img - src="deploy.svg" - /> - - <h2 - class="gl-font-lg gl-mb-3" - > - Deploy - </h2> - - <p - class="gl-text-gray-700 gl-mb-6" - > - Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure: - </p> - </div> + Deploy + </h2> + <p + class="gl-text-gray-700 gl-mb-6" + > + Use your new GitLab workflow to deploy your application, monitor its health, and keep it secure: + </p> + </div> + + <div + class="gl-card-body gl-pt-0" + > <div class="gl-mb-4" > - <a - class="gl-link" - data-testid="uncompleted-learn-gitlab-link" - data-track-action="click_link" - data-track-label="Run a Security scan using CI/CD" - href="https://docs.gitlab.com/ee/foobar/" - rel="noopener noreferrer" - target="_blank" - > - - Run a Security scan using CI/CD - - </a> - <!----> + + <div + class="flex align-items-center" + > + <a + class="gl-link" + data-testid="uncompleted-learn-gitlab-link" + data-track-action="click_link" + data-track-label="Run a Security scan using CI/CD" + href="https://docs.gitlab.com/ee/foobar/" + rel="noopener noreferrer" + target="_blank" + > + + Run a Security scan using CI/CD + + </a> + + <!----> + </div> </div> </div> diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js index e21371123e8..551c68a99ab 100644 --- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js +++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_section_link_spec.js @@ -1,4 +1,4 @@ -import { shallowMount } from '@vue/test-utils'; +import { mount } from '@vue/test-utils'; import { stubExperiments } from 'helpers/experimentation_helper'; import { mockTracking, triggerEvent, unmockTracking } from 'helpers/tracking_helper'; import eventHub from '~/invite_members/event_hub'; @@ -26,7 +26,7 @@ describe('Learn GitLab Section Link', () => { }); const createWrapper = (action = defaultAction, props = {}) => { - wrapper = shallowMount(LearnGitlabSectionLink, { + wrapper = mount(LearnGitlabSectionLink, { propsData: { action, value: { ...defaultProps, ...props } }, }); }; @@ -36,6 +36,8 @@ describe('Learn GitLab Section Link', () => { const findUncompletedLink = () => wrapper.find('[data-testid="uncompleted-learn-gitlab-link"]'); + const videoTutorialLink = () => wrapper.find('[data-testid="video-tutorial-link"]'); + it('renders no icon when not completed', () => { createWrapper(undefined, { completed: false }); @@ -130,4 +132,44 @@ describe('Learn GitLab Section Link', () => { unmockTracking(); }); }); + + describe('video_tutorials_continuous_onboarding experiment', () => { + describe('when control', () => { + beforeEach(() => { + stubExperiments({ video_tutorials_continuous_onboarding: 'control' }); + createWrapper('codeOwnersEnabled'); + }); + + it('renders no video link', () => { + expect(videoTutorialLink().exists()).toBe(false); + }); + }); + + describe('when candidate', () => { + beforeEach(() => { + stubExperiments({ video_tutorials_continuous_onboarding: 'candidate' }); + createWrapper('codeOwnersEnabled'); + }); + + it('renders video link with blank target', () => { + const videoLinkElement = videoTutorialLink(); + + expect(videoLinkElement.exists()).toBe(true); + expect(videoLinkElement.attributes('target')).toEqual('_blank'); + }); + + it('tracks the click', () => { + const trackingSpy = mockTracking('_category_', wrapper.element, jest.spyOn); + + videoTutorialLink().trigger('click'); + + expect(trackingSpy).toHaveBeenCalledWith('_category_', 'click_video_link', { + label: 'Add code owners', + property: 'Growth::Conversion::Experiment::LearnGitLab', + }); + + unmockTracking(); + }); + }); + }); }); diff --git a/spec/graphql/resolvers/issues_resolver_spec.rb b/spec/graphql/resolvers/issues_resolver_spec.rb index 5e9a3d0a68b..81aeee0a3d2 100644 --- a/spec/graphql/resolvers/issues_resolver_spec.rb +++ b/spec/graphql/resolvers/issues_resolver_spec.rb @@ -522,11 +522,53 @@ RSpec.describe Resolvers::IssuesResolver do end end + context 'when sorting by escalation status' do + let_it_be(:project) { create(:project, :public) } + let_it_be(:triggered_incident) { create(:incident, :with_escalation_status, project: project) } + let_it_be(:issue_no_status) { create(:issue, project: project) } + let_it_be(:resolved_incident) do + create(:incident, :with_escalation_status, project: project) + .tap { |issue| issue.escalation_status.resolve } + end + + it 'sorts issues ascending' do + issues = resolve_issues(sort: :escalation_status_asc).to_a + expect(issues).to eq([triggered_incident, resolved_incident, issue_no_status]) + end + + it 'sorts issues descending' do + issues = resolve_issues(sort: :escalation_status_desc).to_a + expect(issues).to eq([resolved_incident, triggered_incident, issue_no_status]) + end + + it 'sorts issues created_at' do + issues = resolve_issues(sort: :created_desc).to_a + expect(issues).to eq([resolved_incident, issue_no_status, triggered_incident]) + end + + context 'when incident_escalations feature flag is disabled' do + before do + stub_feature_flags(incident_escalations: false) + end + + it 'defaults ascending status sort to created_desc' do + issues = resolve_issues(sort: :escalation_status_asc).to_a + expect(issues).to eq([resolved_incident, issue_no_status, triggered_incident]) + end + + it 'defaults descending status sort to created_desc' do + issues = resolve_issues(sort: :escalation_status_desc).to_a + expect(issues).to eq([resolved_incident, issue_no_status, triggered_incident]) + end + end + end + context 'when sorting with non-stable cursors' do %i[priority_asc priority_desc popularity_asc popularity_desc label_priority_asc label_priority_desc - milestone_due_asc milestone_due_desc].each do |sort_by| + milestone_due_asc milestone_due_desc + escalation_status_asc escalation_status_desc].each do |sort_by| it "uses offset-pagination when sorting by #{sort_by}" do resolved = resolve_issues(sort: sort_by) diff --git a/spec/graphql/types/issue_sort_enum_spec.rb b/spec/graphql/types/issue_sort_enum_spec.rb index 4433709d193..95184477e75 100644 --- a/spec/graphql/types/issue_sort_enum_spec.rb +++ b/spec/graphql/types/issue_sort_enum_spec.rb @@ -9,7 +9,7 @@ RSpec.describe GitlabSchema.types['IssueSort'] do it 'exposes all the existing issue sort values' do expect(described_class.values.keys).to include( - *%w[DUE_DATE_ASC DUE_DATE_DESC RELATIVE_POSITION_ASC SEVERITY_ASC SEVERITY_DESC] + *%w[DUE_DATE_ASC DUE_DATE_DESC RELATIVE_POSITION_ASC SEVERITY_ASC SEVERITY_DESC ESCALATION_STATUS_ASC ESCALATION_STATUS_DESC] ) end end diff --git a/spec/models/issue_spec.rb b/spec/models/issue_spec.rb index 29305ba435c..61ad9dc26be 100644 --- a/spec/models/issue_spec.rb +++ b/spec/models/issue_spec.rb @@ -238,6 +238,24 @@ RSpec.describe Issue do end end + context 'order by escalation status' do + let_it_be(:triggered_incident) { create(:incident_management_issuable_escalation_status, :triggered).issue } + let_it_be(:resolved_incident) { create(:incident_management_issuable_escalation_status, :resolved).issue } + let_it_be(:issue_no_status) { create(:issue) } + + describe '.order_escalation_status_asc' do + subject { described_class.order_escalation_status_asc } + + it { is_expected.to eq([triggered_incident, resolved_incident, issue_no_status]) } + end + + describe '.order_escalation_status_desc' do + subject { described_class.order_escalation_status_desc } + + it { is_expected.to eq([resolved_incident, triggered_incident, issue_no_status]) } + end + end + # TODO: Remove when NOT NULL constraint is added to the relationship describe '#work_item_type' do let(:issue) { create(:issue, :incident, project: reusable_project, work_item_type: nil) } diff --git a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb index e1c7fd9d60d..85194e6eb20 100644 --- a/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb +++ b/spec/requests/api/graphql/mutations/user_preferences/update_spec.rb @@ -28,6 +28,17 @@ RSpec.describe Mutations::UserPreferences::Update do expect(current_user.user_preference.persisted?).to eq(true) expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s) end + + context 'when incident_escalations feature flag is disabled' do + let(:sort_value) { 'ESCALATION_STATUS_ASC' } + + before do + stub_feature_flags(incident_escalations: false) + end + + it_behaves_like 'a mutation that returns top-level errors', + errors: ['Feature flag `incident_escalations` must be enabled to use this sort order.'] + end end context 'when user has existing preference' do @@ -45,5 +56,16 @@ RSpec.describe Mutations::UserPreferences::Update do expect(current_user.user_preference.issues_sort).to eq(Types::IssueSortEnum.values[sort_value].value.to_s) end + + context 'when incident_escalations feature flag is disabled' do + let(:sort_value) { 'ESCALATION_STATUS_DESC' } + + before do + stub_feature_flags(incident_escalations: false) + end + + it_behaves_like 'a mutation that returns top-level errors', + errors: ['Feature flag `incident_escalations` must be enabled to use this sort order.'] + end end end |