diff options
Diffstat (limited to 'spec')
16 files changed, 607 insertions, 441 deletions
diff --git a/spec/bin/feature_flag_spec.rb b/spec/bin/feature_flag_spec.rb index 03f5ac135f7..cce103965d3 100644 --- a/spec/bin/feature_flag_spec.rb +++ b/spec/bin/feature_flag_spec.rb @@ -9,7 +9,7 @@ RSpec.describe 'bin/feature-flag' do using RSpec::Parameterized::TableSyntax describe FeatureFlagCreator do - let(:argv) { %w[feature-flag-name -t development -g group::memory -i https://url -m http://url] } + let(:argv) { %w[feature-flag-name -t development -g group::geo -i https://url -m http://url] } let(:options) { FeatureFlagOptionParser.parse(argv) } let(:creator) { described_class.new(options) } let(:existing_flags) do @@ -81,8 +81,8 @@ RSpec.describe 'bin/feature-flag' do :type | %w[foo --type development] | :development :type | %w[foo -t invalid] | nil :type | %w[foo --type invalid] | nil - :group | %w[foo -g group::memory] | 'group::memory' - :group | %w[foo --group group::memory] | 'group::memory' + :group | %w[foo -g group::geo] | 'group::geo' + :group | %w[foo --group group::geo] | 'group::geo' :group | %w[foo -g invalid] | nil :group | %w[foo --group invalid] | nil end @@ -178,12 +178,12 @@ RSpec.describe 'bin/feature-flag' do end describe '.read_group' do - let(:group) { 'group::memory' } + let(:group) { 'group::geo' } it 'reads type from stdin' do expect(Readline).to receive(:readline).and_return(group) expect do - expect(described_class.read_group).to eq('group::memory') + expect(described_class.read_group).to eq('group::geo') end.to output(/Specify the group introducing the feature flag/).to_stdout end diff --git a/spec/controllers/admin/groups_controller_spec.rb b/spec/controllers/admin/groups_controller_spec.rb index 6085f0e1239..c534cf14327 100644 --- a/spec/controllers/admin/groups_controller_spec.rb +++ b/spec/controllers/admin/groups_controller_spec.rb @@ -52,4 +52,48 @@ RSpec.describe Admin::GroupsController do post :create, params: { group: { path: 'test', name: 'test' } } end end + + describe 'PUT #update' do + subject(:update!) do + put :update, params: { id: group.to_param, group: { runner_registration_enabled: new_value } } + end + + context 'with runner registration disabled' do + let(:runner_registration_enabled) { false } + let(:new_value) { '1' } + + it 'updates the setting successfully' do + update! + + expect(response).to have_gitlab_http_status(:found) + expect(group.reload.runner_registration_enabled).to eq(true) + end + + it 'does not change the registration token' do + expect do + update! + group.reload + end.not_to change(group, :runners_token) + end + end + + context 'with runner registration enabled' do + let(:runner_registration_enabled) { true } + let(:new_value) { '0' } + + it 'updates the setting successfully' do + update! + + expect(response).to have_gitlab_http_status(:found) + expect(group.reload.runner_registration_enabled).to eq(false) + end + + it 'changes the registration token' do + expect do + update! + group.reload + end.to change(group, :runners_token) + end + end + end end diff --git a/spec/fixtures/pager_duty/webhook_incident_trigger.json b/spec/fixtures/pager_duty/webhook_incident_trigger.json index 872297adcf6..9994c8c843b 100644 --- a/spec/fixtures/pager_duty/webhook_incident_trigger.json +++ b/spec/fixtures/pager_duty/webhook_incident_trigger.json @@ -1,239 +1,61 @@ { - "messages": [ - { - "event": "incident.trigger", - "log_entries": [ + "event": { + "id": "01DDZJG3TC199M1GJQ7LO67JYS", + "event_type": "incident.triggered", + "resource_type": "incident", + "occurred_at": "2022-11-30T08:46:19.079Z", + "agent": { + "html_url": "https://gitlab-1.pagerduty.com/users/PIN0B5C", + "id": "PIN0B5C", + "self": "https://api.pagerduty.com/users/PIN0B5C", + "summary": "Rajendra Kadam", + "type": "user_reference" + }, + "client": "nil", + "data": { + "id": "Q1XZUF87W1HB5A", + "type": "incident", + "self": "https://api.pagerduty.com/incidents/Q1XZUF87W1HB5A", + "html_url": "https://gitlab-1.pagerduty.com/incidents/Q1XZUF87W1HB5A", + "number": 2, + "status": "triggered", + "incident_key": "[FILTERED]", + "created_at": "2022-11-30T08:46:19Z", + "title": "[FILTERED]", + "service": { + "html_url": "https://gitlab-1.pagerduty.com/services/PK6IKMT", + "id": "PK6IKMT", + "self": "https://api.pagerduty.com/services/PK6IKMT", + "summary": "Test service", + "type": "service_reference" + }, + "assignees": [ { - "id": "R2XGXEI3W0FHMSDXHDIBQGBQ5E", - "type": "trigger_log_entry", - "summary": "Triggered through the website", - "self": "https://api.pagerduty.com/log_entries/R2XGXEI3W0FHMSDXHDIBQGBQ5E", - "html_url": "https://webdemo.pagerduty.com/incidents/PRORDTY/log_entries/R2XGXEI3W0FHMSDXHDIBQGBQ5E", - "created_at": "2017-09-26T15:14:36Z", - "agent": { - "id": "P553OPV", - "type": "user_reference", - "summary": "Laura Haley", - "self": "https://api.pagerduty.com/users/P553OPV", - "html_url": "https://webdemo.pagerduty.com/users/P553OPV" - }, - "channel": { - "type": "web_trigger", - "summary": "My new incident", - "subject": "My new incident", - "details": "Oh my gosh", - "details_omitted": false - }, - "service": { - "id": "PN49J75", - "type": "service_reference", - "summary": "Production XDB Cluster", - "self": "https://api.pagerduty.com/services/PN49J75", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75" - }, - "incident": { - "id": "PRORDTY", - "type": "incident_reference", - "summary": "[#33] My new incident", - "self": "https://api.pagerduty.com/incidents/PRORDTY", - "html_url": "https://webdemo.pagerduty.com/incidents/PRORDTY" - }, - "teams": [ - { - "id": "P4SI59S", - "type": "team_reference", - "summary": "Engineering", - "self": "https://api.pagerduty.com/teams/P4SI59S", - "html_url": "https://webdemo.pagerduty.com/teams/P4SI59S" - } - ], - "contexts": [], - "event_details": { - "description": "My new incident" - } + "html_url": "https://gitlab-1.pagerduty.com/users/PIN0B5C", + "id": "PIN0B5C", + "self": "https://api.pagerduty.com/users/PIN0B5C", + "summary": "Rajendra Kadam", + "type": "user_reference" } ], - "webhook": { - "endpoint_url": "https://requestb.in/18ao6fs1", - "name": "V2 wabhook", - "description": null, - "webhook_object": { - "id": "PN49J75", - "type": "service_reference", - "summary": "Production XDB Cluster", - "self": "https://api.pagerduty.com/services/PN49J75", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75" - }, - "config": {}, - "outbound_integration": { - "id": "PJFWPEP", - "type": "outbound_integration_reference", - "summary": "Generic V2 Webhook", - "self": "https://api.pagerduty.com/outbound_integrations/PJFWPEP", - "html_url": null - }, - "accounts_addon": null, - "id": "PKT9NNX", - "type": "webhook", - "summary": "V2 wabhook", - "self": "https://api.pagerduty.com/webhooks/PKT9NNX", - "html_url": null + "escalation_policy": { + "html_url": "https://gitlab-1.pagerduty.com/escalation_policies/PWP6XTY", + "id": "PWP6XTY", + "self": "https://api.pagerduty.com/escalation_policies/PWP6XTY", + "summary": "Default", + "type": "escalation_policy_reference" }, - "incident": { - "incident_number": 33, - "title": "My new incident", - "description": "My new incident", - "created_at": "2017-09-26T15:14:36Z", - "status": "triggered", - "pending_actions": [ - { - "type": "escalate", - "at": "2017-09-26T15:44:36Z" - }, - { - "type": "resolve", - "at": "2017-09-26T19:14:36Z" - } - ], - "incident_key": null, - "service": { - "id": "PN49J75", - "name": "Production XDB Cluster", - "description": "This service was created during onboarding on July 5, 2017.", - "auto_resolve_timeout": 14400, - "acknowledgement_timeout": 1800, - "created_at": "2017-07-05T17:33:09Z", - "status": "critical", - "last_incident_timestamp": "2017-09-26T15:14:36Z", - "teams": [ - { - "id": "P4SI59S", - "type": "team_reference", - "summary": "Engineering", - "self": "https://api.pagerduty.com/teams/P4SI59S", - "html_url": "https://webdemo.pagerduty.com/teams/P4SI59S" - } - ], - "incident_urgency_rule": { - "type": "constant", - "urgency": "high" - }, - "scheduled_actions": [], - "support_hours": null, - "escalation_policy": { - "id": "PINYWEF", - "type": "escalation_policy_reference", - "summary": "Default", - "self": "https://api.pagerduty.com/escalation_policies/PINYWEF", - "html_url": "https://webdemo.pagerduty.com/escalation_policies/PINYWEF" - }, - "addons": [], - "privilege": null, - "alert_creation": "create_alerts_and_incidents", - "integrations": [ - { - "id": "PUAYF96", - "type": "generic_events_api_inbound_integration_reference", - "summary": "API", - "self": "https://api.pagerduty.com/services/PN49J75/integrations/PUAYF96", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75/integrations/PUAYF96" - }, - { - "id": "P90GZUH", - "type": "generic_email_inbound_integration_reference", - "summary": "Email", - "self": "https://api.pagerduty.com/services/PN49J75/integrations/P90GZUH", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75/integrations/P90GZUH" - } - ], - "metadata": {}, - "type": "service", - "summary": "Production XDB Cluster", - "self": "https://api.pagerduty.com/services/PN49J75", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75" - }, - "assignments": [ - { - "at": "2017-09-26T15:14:36Z", - "assignee": { - "id": "P553OPV", - "type": "user_reference", - "summary": "Laura Haley", - "self": "https://api.pagerduty.com/users/P553OPV", - "html_url": "https://webdemo.pagerduty.com/users/P553OPV" - } - } - ], - "acknowledgements": [], - "last_status_change_at": "2017-09-26T15:14:36Z", - "last_status_change_by": { - "id": "PN49J75", - "type": "service_reference", - "summary": "Production XDB Cluster", - "self": "https://api.pagerduty.com/services/PN49J75", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75" - }, - "first_trigger_log_entry": { - "id": "R2XGXEI3W0FHMSDXHDIBQGBQ5E", - "type": "trigger_log_entry_reference", - "summary": "Triggered through the website", - "self": "https://api.pagerduty.com/log_entries/R2XGXEI3W0FHMSDXHDIBQGBQ5E", - "html_url": "https://webdemo.pagerduty.com/incidents/PRORDTY/log_entries/R2XGXEI3W0FHMSDXHDIBQGBQ5E" - }, - "escalation_policy": { - "id": "PINYWEF", - "type": "escalation_policy_reference", - "summary": "Default", - "self": "https://api.pagerduty.com/escalation_policies/PINYWEF", - "html_url": "https://webdemo.pagerduty.com/escalation_policies/PINYWEF" - }, - "privilege": null, - "teams": [ - { - "id": "P4SI59S", - "type": "team_reference", - "summary": "Engineering", - "self": "https://api.pagerduty.com/teams/P4SI59S", - "html_url": "https://webdemo.pagerduty.com/teams/P4SI59S" - } - ], - "alert_counts": { - "all": 0, - "triggered": 0, - "resolved": 0 - }, - "impacted_services": [ - { - "id": "PN49J75", - "type": "service_reference", - "summary": "Production XDB Cluster", - "self": "https://api.pagerduty.com/services/PN49J75", - "html_url": "https://webdemo.pagerduty.com/services/PN49J75" - } - ], - "is_mergeable": true, - "basic_alert_grouping": null, - "alert_grouping": null, - "metadata": {}, - "external_references": [], - "importance": null, - "incidents_responders": [], - "responder_requests": [], - "subscriber_requests": [], - "urgency": "high", - "id": "PRORDTY", - "type": "incident", - "summary": "[#33] My new incident", - "self": "https://api.pagerduty.com/incidents/PRORDTY", - "html_url": "https://webdemo.pagerduty.com/incidents/PRORDTY", - "alerts": [ - { - "alert_key": "c24117fc42e44b44b4d6876190583378" - } - ] + "teams": [], + "priority": { + "html_url": "https://gitlab-1.pagerduty.com/account/incident_priorities", + "id": "PKWBGFQ", + "self": "https://api.pagerduty.com/priorities/PKWBGFQ", + "summary": "P2", + "type": "priority_reference" }, - "id": "69a7ced0-a2cd-11e7-a799-22000a15839c", - "created_on": "2017-09-26T15:14:36Z" + "urgency": "high", + "conference_bridge": "nil", + "resolve_reason": "nil" } - ] + } } diff --git a/spec/frontend/releases/__snapshots__/util_spec.js.snap b/spec/frontend/releases/__snapshots__/util_spec.js.snap index d88d79d2cde..4084d734b83 100644 --- a/spec/frontend/releases/__snapshots__/util_spec.js.snap +++ b/spec/frontend/releases/__snapshots__/util_spec.js.snap @@ -53,6 +53,7 @@ Object { "title": "Merge branch 'branch-merged' into 'master'", }, "commitPath": "http://localhost/releases-namespace/releases-project/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0", + "createdAt": 2019-01-03T00:00:00.000Z, "descriptionHtml": "<p data-sourcepos=\\"1:1-1:23\\" dir=\\"auto\\">An okay release <gl-emoji title=\\"shrug\\" data-name=\\"shrug\\" data-unicode-version=\\"9.0\\">🤷</gl-emoji></p>", "evidences": Array [], "historicalRelease": false, @@ -150,6 +151,7 @@ Object { "title": "Merge branch 'branch-merged' into 'master'", }, "commitPath": "http://localhost/releases-namespace/releases-project/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0", + "createdAt": 2018-12-03T00:00:00.000Z, "descriptionHtml": "<p data-sourcepos=\\"1:1-1:33\\" dir=\\"auto\\">Best. Release. <strong>Ever.</strong> <gl-emoji title=\\"rocket\\" data-name=\\"rocket\\" data-unicode-version=\\"6.0\\">🚀</gl-emoji></p>", "evidences": Array [ Object { @@ -253,6 +255,7 @@ Object { "sources": Array [], }, "author": undefined, + "createdAt": 2018-12-03T00:00:00.000Z, "description": "Best. Release. **Ever.** :rocket:", "evidences": Array [], "milestones": Array [ @@ -372,6 +375,7 @@ Object { "title": "Merge branch 'branch-merged' into 'master'", }, "commitPath": "http://localhost/releases-namespace/releases-project/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0", + "createdAt": 2018-12-03T00:00:00.000Z, "descriptionHtml": "<p data-sourcepos=\\"1:1-1:33\\" dir=\\"auto\\">Best. Release. <strong>Ever.</strong> <gl-emoji title=\\"rocket\\" data-name=\\"rocket\\" data-unicode-version=\\"6.0\\">🚀</gl-emoji></p>", "evidences": Array [ Object { diff --git a/spec/frontend/releases/components/release_block_footer_spec.js b/spec/frontend/releases/components/release_block_footer_spec.js index 8f4efad197f..d13cff49db2 100644 --- a/spec/frontend/releases/components/release_block_footer_spec.js +++ b/spec/frontend/releases/components/release_block_footer_spec.js @@ -4,6 +4,7 @@ import { cloneDeep } from 'lodash'; import { nextTick } from 'vue'; import originalOneReleaseQueryResponse from 'test_fixtures/graphql/releases/graphql/queries/one_release.query.graphql.json'; import { convertOneReleaseGraphQLResponse } from '~/releases/util'; +import { RELEASED_AT_ASC, RELEASED_AT_DESC, CREATED_ASC, CREATED_DESC } from '~/releases/constants'; import { trimText } from 'helpers/text_helper'; import ReleaseBlockFooter from '~/releases/components/release_block_footer.vue'; @@ -43,88 +44,118 @@ describe('Release block footer', () => { const tagInfoSectionLink = () => tagInfoSection().findComponent(GlLink); const authorDateInfoSection = () => wrapper.find('.js-author-date-info'); - describe('with all props provided', () => { - beforeEach(() => factory()); - - it('renders the commit icon', () => { - const commitIcon = commitInfoSection().findComponent(GlIcon); - - expect(commitIcon.exists()).toBe(true); - expect(commitIcon.props('name')).toBe('commit'); - }); - - it('renders the commit SHA with a link', () => { - const commitLink = commitInfoSectionLink(); - - expect(commitLink.exists()).toBe(true); - expect(commitLink.text()).toBe(release.commit.shortId); - expect(commitLink.attributes('href')).toBe(release.commitPath); - }); - - it('renders the tag icon', () => { - const commitIcon = tagInfoSection().findComponent(GlIcon); - - expect(commitIcon.exists()).toBe(true); - expect(commitIcon.props('name')).toBe('tag'); - }); - - it('renders the tag name with a link', () => { - const commitLink = tagInfoSection().findComponent(GlLink); - - expect(commitLink.exists()).toBe(true); - expect(commitLink.text()).toBe(release.tagName); - expect(commitLink.attributes('href')).toBe(release.tagPath); - }); - - it('renders the author and creation time info', () => { - expect(trimText(authorDateInfoSection().text())).toBe( - `Created 1 year ago by ${release.author.username}`, - ); - }); - - describe('when the release date is in the past', () => { - it('prefixes the creation info with "Created"', () => { - expect(trimText(authorDateInfoSection().text())).toEqual(expect.stringMatching(/^Created/)); - }); - }); - - describe('renders the author and creation time info with future release date', () => { - beforeEach(() => { - factory({ releasedAt: mockFutureDate }); - }); - - it('renders the release date without the author name', () => { - expect(trimText(authorDateInfoSection().text())).toBe( - `Will be created in 1 month by ${release.author.username}`, - ); - }); - }); - - describe('when the release date is in the future', () => { - beforeEach(() => { - factory({ releasedAt: mockFutureDate }); - }); - - it('prefixes the creation info with "Will be created"', () => { - expect(trimText(authorDateInfoSection().text())).toEqual( - expect.stringMatching(/^Will be created/), - ); - }); - }); - - it("renders the author's avatar image", () => { - const avatarImg = authorDateInfoSection().find('img'); - - expect(avatarImg.exists()).toBe(true); - expect(avatarImg.attributes('src')).toBe(release.author.avatarUrl); - }); - - it("renders a link to the author's profile", () => { - const authorLink = authorDateInfoSection().findComponent(GlLink); - - expect(authorLink.exists()).toBe(true); - expect(authorLink.attributes('href')).toBe(release.author.webUrl); - }); + describe.each` + sortFlag | expectedInfoString + ${null} | ${'Created'} + ${CREATED_ASC} | ${'Created'} + ${CREATED_DESC} | ${'Created'} + ${RELEASED_AT_ASC} | ${'Released'} + ${RELEASED_AT_DESC} | ${'Released'} + `('with sorting set to $sortFlag', ({ sortFlag, expectedInfoString }) => { + const dateAt = + expectedInfoString === 'Created' ? originalRelease.createdAt : originalRelease.releasedAt; + + describe.each` + dateType | dateFlag | expectedInfoStringPrefix | expectedDateString + ${'empty'} | ${undefined} | ${null} | ${null} + ${'in the past'} | ${dateAt} | ${null} | ${'1 year ago'} + ${'in the future'} | ${mockFutureDate} | ${'Will be'} | ${'in 1 month'} + `( + 'with date set to $dateType', + ({ dateFlag, expectedInfoStringPrefix, expectedDateString }) => { + describe.each` + authorType | authorFlag | expectedAuthorString + ${'empty'} | ${undefined} | ${null} + ${'present'} | ${originalRelease.author} | ${'by administrator'} + `('with author set to $authorType', ({ authorFlag, expectedAuthorString }) => { + const propsData = { sort: sortFlag, author: authorFlag }; + if (dateFlag !== '') { + propsData.createdAt = dateFlag; + propsData.releasedAt = dateFlag; + } + + beforeEach(() => { + factory({ ...propsData }); + }); + + const expectedString = [ + expectedInfoStringPrefix, + expectedInfoStringPrefix ? expectedInfoString.toLowerCase() : expectedInfoString, + expectedDateString, + expectedAuthorString, + ]; + + if (authorFlag || dateFlag) { + it('renders the author and creation time info', () => { + expect(trimText(authorDateInfoSection().text())).toBe( + expectedString.filter((n) => n).join(' '), + ); + }); + if (authorFlag) { + it("renders the author's avatar image", () => { + const avatarImg = authorDateInfoSection().find('img'); + + expect(avatarImg.exists()).toBe(true); + expect(avatarImg.attributes('src')).toBe(release.author.avatarUrl); + }); + + it("renders a link to the author's profile", () => { + const authorLink = authorDateInfoSection().findComponent(GlLink); + + expect(authorLink.exists()).toBe(true); + expect(authorLink.attributes('href')).toBe(release.author.webUrl); + }); + } else { + it("does not render the author's avatar image", () => { + const avatarImg = authorDateInfoSection().find('img'); + + expect(avatarImg.exists()).toBe(false); + }); + + it("does not render a link to the author's profile", () => { + const authorLink = authorDateInfoSection().findComponent(GlLink); + + expect(authorLink.exists()).toBe(false); + }); + } + } else { + it('does not render the author and creation time info', () => { + expect(authorDateInfoSection().exists()).toBe(false); + }); + } + + it('renders the commit icon', () => { + const commitIcon = commitInfoSection().findComponent(GlIcon); + + expect(commitIcon.exists()).toBe(true); + expect(commitIcon.props('name')).toBe('commit'); + }); + + it('renders the commit SHA with a link', () => { + const commitLink = commitInfoSectionLink(); + + expect(commitLink.exists()).toBe(true); + expect(commitLink.text()).toBe(release.commit.shortId); + expect(commitLink.attributes('href')).toBe(release.commitPath); + }); + + it('renders the tag icon', () => { + const commitIcon = tagInfoSection().findComponent(GlIcon); + + expect(commitIcon.exists()).toBe(true); + expect(commitIcon.props('name')).toBe('tag'); + }); + + it('renders the tag name with a link', () => { + const commitLink = tagInfoSection().findComponent(GlLink); + + expect(commitLink.exists()).toBe(true); + expect(commitLink.text()).toBe(release.tagName); + expect(commitLink.attributes('href')).toBe(release.tagPath); + }); + }); + }, + ); }); describe('without any commit info', () => { @@ -160,40 +191,4 @@ describe('Release block footer', () => { expect(tagInfoSection().text()).toBe(release.tagName); }); }); - - describe('without any author info', () => { - beforeEach(() => factory({ author: undefined })); - - it('renders the release date without the author name', () => { - expect(trimText(authorDateInfoSection().text())).toBe(`Created 1 year ago`); - }); - }); - - describe('future release without any author info', () => { - beforeEach(() => { - factory({ author: undefined, releasedAt: mockFutureDate }); - }); - - it('renders the release date without the author name', () => { - expect(trimText(authorDateInfoSection().text())).toBe(`Will be created in 1 month`); - }); - }); - - describe('without a released at date', () => { - beforeEach(() => factory({ releasedAt: undefined })); - - it('renders the author name without the release date', () => { - expect(trimText(authorDateInfoSection().text())).toBe( - `Created by ${release.author.username}`, - ); - }); - }); - - describe('without a release date or author info', () => { - beforeEach(() => factory({ author: undefined, releasedAt: undefined })); - - it('does not render any author or release date info', () => { - expect(authorDateInfoSection().exists()).toBe(false); - }); - }); }); diff --git a/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb b/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb index c5288b9afbc..e2c67c68eb7 100644 --- a/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb +++ b/spec/lib/gitlab/incident_management/pager_duty/incident_issue_description_spec.rb @@ -10,8 +10,8 @@ RSpec.describe Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription d [{ 'summary' => 'Laura Haley', 'url' => 'https://webdemo.pagerduty.com/users/P553OPV' }] end - let(:impacted_services) do - [{ 'summary' => 'Production XDB Cluster', 'url' => 'https://webdemo.pagerduty.com/services/PN49J75' }] + let(:impacted_service) do + { 'summary' => 'Production XDB Cluster', 'url' => 'https://webdemo.pagerduty.com/services/PN49J75' } end let(:incident_payload) do @@ -24,7 +24,7 @@ RSpec.describe Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription d 'urgency' => 'high', 'incident_key' => 'SOME-KEY', 'assignees' => assignees, - 'impacted_services' => impacted_services + 'impacted_service' => impacted_service } end @@ -40,7 +40,7 @@ RSpec.describe Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription d **Incident key:** SOME-KEY#{markdown_line_break} **Created at:** 26 September 2017, 3:14PM (UTC)#{markdown_line_break} **Assignees:** [Laura Haley](https://webdemo.pagerduty.com/users/P553OPV)#{markdown_line_break} - **Impacted services:** [Production XDB Cluster](https://webdemo.pagerduty.com/services/PN49J75) + **Impacted service:** [Production XDB Cluster](https://webdemo.pagerduty.com/services/PN49J75) MARKDOWN ) end @@ -78,18 +78,15 @@ RSpec.describe Gitlab::IncidentManagement::PagerDuty::IncidentIssueDescription d end end - context 'when there are several impacted services' do - let(:impacted_services) do - [ - { 'summary' => 'XDB Cluster', 'url' => 'https://xdb.pagerduty.com' }, - { 'summary' => 'BRB Cluster', 'url' => 'https://brb.pagerduty.com' } - ] + context 'when there is an impacted service' do + let(:impacted_service) do + { 'summary' => 'XDB Cluster', 'url' => 'https://xdb.pagerduty.com' } end - it 'impacted services is a list of links' do + it 'impacted service is a single link' do expect(to_s).to include( <<~MARKDOWN.chomp - **Impacted services:** [XDB Cluster](https://xdb.pagerduty.com), [BRB Cluster](https://brb.pagerduty.com) + **Impacted service:** [XDB Cluster](https://xdb.pagerduty.com) MARKDOWN ) end diff --git a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb b/spec/lib/gitlab/merge_requests/message_generator_spec.rb index bdc9879f362..fbdd6a1e56d 100644 --- a/spec/lib/gitlab/merge_requests/commit_message_generator_spec.rb +++ b/spec/lib/gitlab/merge_requests/message_generator_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do +RSpec.describe Gitlab::MergeRequests::MessageGenerator do let(:merge_commit_template) { nil } let(:squash_commit_template) { nil } let(:project) do @@ -59,7 +59,14 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do context 'when project has commit template with only the title' do let(:merge_request) do - double(:merge_request, title: 'Fixes', target_project: project, to_reference: '!123', metrics: nil, merge_user: nil) + double( + :merge_request, + title: 'Fixes', + target_project: project, + to_reference: '!123', + metrics: nil, + merge_user: nil + ) end let(message_template_name) { '%{title}' } @@ -214,7 +221,7 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do context 'when project has template with CRLF newlines' do let(message_template_name) do - "Merge branch '%{source_branch}' into '%{target_branch}'\r\n\r\n%{title}\r\n\r\n%{description}\r\n\r\nSee merge request %{reference}" + "Merge branch '%{source_branch}' into '%{target_branch}'\r\n\r\n%{title}\r\n\r\n%{description}\r\n\r\nSee merge request %{reference}" # rubocop: disable Layout/LineLength end it 'converts it to LF newlines' do @@ -717,8 +724,8 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do end end - describe '#merge_message' do - let(:result_message) { subject.merge_message } + describe '#merge_commit_message' do + let(:result_message) { subject.merge_commit_message } it_behaves_like 'commit message with template', :merge_commit_template @@ -749,8 +756,8 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do end end - describe '#squash_message' do - let(:result_message) { subject.squash_message } + describe '#squash_commit_message' do + let(:result_message) { subject.squash_commit_message } it_behaves_like 'commit message with template', :squash_commit_template @@ -780,4 +787,95 @@ RSpec.describe Gitlab::MergeRequests::CommitMessageGenerator do end end end + + describe '#new_mr_description' do + let(:merge_request) do + build( + :merge_request, + source_project: project, + target_project: project, + target_branch: 'master', + source_branch: source_branch, + author: author, + description: merge_request_description, + title: merge_request_title + ) + end + + let(:result_message) { subject.new_mr_description } + + before do + compare = CompareService.new( + project, + merge_request.source_branch + ).execute( + project, + merge_request.target_branch + ) + + merge_request.compare_commits = compare.commits + merge_request.compare = compare + end + + context 'when project has template with all variables' do + let(:merge_request_description) { <<~MSG.rstrip } + source_branch:%{source_branch} + target_branch:%{target_branch} + title:%{title} + issues:%{issues} + description:%{description} + first_commit:%{first_commit} + first_multiline_commit:%{first_multiline_commit} + url:%{url} + approved_by:%{approved_by} + merged_by:%{merged_by} + co_authored_by:%{co_authored_by} + all_commits:%{all_commits} + MSG + + it 'renders only variables specific to a new non-persisted merge request' do + expect(result_message).to eq <<~MSG.rstrip + source_branch:feature + target_branch:master + title: + issues: + description: + first_commit:Feature added + + Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> + first_multiline_commit:Feature added + + Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> + url: + approved_by: + merged_by: + co_authored_by:Co-authored-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> + all_commits:* Feature added + + Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> + MSG + end + + context 'when no first commit exists' do + let(:source_branch) { 'master' } + + it 'does not populate any commit-related variables' do + expect(result_message).to eq <<~MSG.rstrip + source_branch:master + target_branch:master + title: + issues: + description: + first_commit: + first_multiline_commit:Bugfix + url: + approved_by: + merged_by: + co_authored_by: + all_commits: + MSG + end + end + end + end end diff --git a/spec/lib/pager_duty/webhook_payload_parser_spec.rb b/spec/lib/pager_duty/webhook_payload_parser_spec.rb index 647f19e3d3a..1606d03c746 100644 --- a/spec/lib/pager_duty/webhook_payload_parser_spec.rb +++ b/spec/lib/pager_duty/webhook_payload_parser_spec.rb @@ -10,23 +10,27 @@ RSpec.describe PagerDuty::WebhookPayloadParser do let(:triggered_event) do { - 'event' => 'incident.trigger', + 'event' => 'incident.triggered', 'incident' => { - 'url' => 'https://webdemo.pagerduty.com/incidents/PRORDTY', - 'incident_number' => 33, - 'title' => 'My new incident', + 'url' => 'https://gitlab-1.pagerduty.com/incidents/Q1XZUF87W1HB5A', + 'incident_number' => 2, + 'title' => '[FILTERED]', 'status' => 'triggered', - 'created_at' => '2017-09-26T15:14:36Z', + 'created_at' => '2022-11-30T08:46:19Z', 'urgency' => 'high', - 'incident_key' => nil, - 'assignees' => [{ - 'summary' => 'Laura Haley', - 'url' => 'https://webdemo.pagerduty.com/users/P553OPV' - }], - 'impacted_services' => [{ - 'summary' => 'Production XDB Cluster', - 'url' => 'https://webdemo.pagerduty.com/services/PN49J75' - }] + 'incident_key' => '[FILTERED]', + 'assignees' => + [ + { + 'summary' => 'Rajendra Kadam', + 'url' => 'https://gitlab-1.pagerduty.com/users/PIN0B5C' + } + ], + 'impacted_service' => + { + 'summary' => 'Test service', + 'url' => 'https://gitlab-1.pagerduty.com/services/PK6IKMT' + } } } end @@ -37,74 +41,50 @@ RSpec.describe PagerDuty::WebhookPayloadParser do let(:payload) { Gitlab::Json.parse(fixture_file) } it 'returns parsed payload' do - is_expected.to eq([triggered_event]) + is_expected.to eq(triggered_event) end context 'when assignments summary and html_url are blank' do before do - payload['messages'].each do |m| - m['incident']['assignments'] = [{ 'assignee' => { 'summary' => '', 'html_url' => '' } }] - end + payload['event']['data']['assignees'] = [{ 'summary' => '', 'html_url' => '' }] end it 'returns parsed payload with blank assignees' do - assignees = parse.map { |events| events['incident'].slice('assignees') } + assignees = parse['incident'].slice('assignees') - expect(assignees).to eq([{ 'assignees' => [] }]) + expect(assignees).to eq({ 'assignees' => [] }) end end context 'when impacted_services summary and html_url are blank' do before do - payload['messages'].each do |m| - m['incident']['impacted_services'] = [{ 'summary' => '', 'html_url' => '' }] - end + payload['event']['data']['service'] = { 'summary' => '', 'html_url' => '' } end - it 'returns parsed payload with blank assignees' do - assignees = parse.map { |events| events['incident'].slice('impacted_services') } + it 'returns parsed payload with blank impacted service' do + assignees = parse['incident'].slice('impacted_service') - expect(assignees).to eq([{ 'impacted_services' => [] }]) + expect(assignees).to eq({ 'impacted_service' => {} }) end end end context 'when payload schema is invalid' do - let(:payload) { { 'messages' => [{ 'event' => 'incident.trigger' }] } } + let(:payload) { { 'event' => 'incident.triggered' } } - it 'returns payload with blank incidents' do - is_expected.to eq([]) + it 'returns payload with blank incident' do + is_expected.to eq({}) end end - context 'when payload consists of two messages' do - context 'when one of the messages has no incident data' do - let(:payload) do - valid_payload = Gitlab::Json.parse(fixture_file) - event = { 'event' => 'incident.trigger' } - valid_payload['messages'] = valid_payload['messages'].append(event) - valid_payload - end - - it 'returns parsed payload with valid events only' do - is_expected.to eq([triggered_event]) - end + context 'when event is unknown' do + let(:payload) do + valid_payload = Gitlab::Json.parse(fixture_file) + valid_payload['event'] = 'incident.unknown' end - context 'when one of the messages has unknown event' do - let(:payload) do - valid_payload = Gitlab::Json.parse(fixture_file) - event = { 'event' => 'incident.unknown', 'incident' => valid_payload['messages'].first['incident'] } - valid_payload['messages'] = valid_payload['messages'].append(event) - valid_payload - end - - it 'returns parsed payload' do - unknown_event = triggered_event.dup - unknown_event['event'] = 'incident.unknown' - - is_expected.to contain_exactly(triggered_event, unknown_event) - end + it 'returns empty payload' do + is_expected.to be_empty end end end diff --git a/spec/models/namespace_setting_spec.rb b/spec/models/namespace_setting_spec.rb index 17c49e13c85..e06a6a30f9a 100644 --- a/spec/models/namespace_setting_spec.rb +++ b/spec/models/namespace_setting_spec.rb @@ -178,6 +178,63 @@ RSpec.describe NamespaceSetting, type: :model do end end + describe '#runner_registration_enabled?' do + context 'when not a subgroup' do + let_it_be(:settings) { create(:namespace_settings) } + let_it_be(:group) { create(:group, namespace_settings: settings) } + + before do + group.update!(runner_registration_enabled: runner_registration_enabled) + end + + context 'when :runner_registration_enabled is false' do + let(:runner_registration_enabled) { false } + + it 'returns false' do + expect(group.runner_registration_enabled?).to be_falsey + end + + it 'does not query the db' do + expect { group.runner_registration_enabled? }.not_to exceed_query_limit(0) + end + end + + context 'when :runner_registration_enabled is true' do + let(:runner_registration_enabled) { true } + + it 'returns true' do + expect(group.runner_registration_enabled?).to be_truthy + end + end + end + + context 'when a group has parent groups' do + let_it_be(:grandparent) { create(:group) } + let_it_be(:parent) { create(:group, parent: grandparent) } + let_it_be(:group) { create(:group, parent: parent) } + + before do + grandparent.update!(runner_registration_enabled: runner_registration_enabled) + end + + context 'when a parent group has runner registration disabled' do + let(:runner_registration_enabled) { false } + + it 'returns false' do + expect(group.runner_registration_enabled?).to be_falsey + end + end + + context 'when all parent groups have runner registration enabled' do + let(:runner_registration_enabled) { true } + + it 'returns true' do + expect(group.runner_registration_enabled?).to be_truthy + end + end + end + end + describe '#delayed_project_removal' do it_behaves_like 'a cascading namespace setting boolean attribute', settings_attribute_name: :delayed_project_removal end diff --git a/spec/policies/group_policy_spec.rb b/spec/policies/group_policy_spec.rb index 8cf121342a3..65abb43b6c4 100644 --- a/spec/policies/group_policy_spec.rb +++ b/spec/policies/group_policy_spec.rb @@ -1191,12 +1191,28 @@ RSpec.describe GroupPolicy do context 'when admin mode is enabled', :enable_admin_mode do it { is_expected.to be_allowed(:register_group_runners) } + context 'with specific group runner registration disabled' do + before do + group.runner_registration_enabled = false + end + + it { is_expected.to be_allowed(:register_group_runners) } + end + context 'with group runner registration disabled' do before do stub_application_setting(valid_runner_registrars: ['project']) end it { is_expected.to be_allowed(:register_group_runners) } + + context 'with specific group runner registration disabled' do + before do + group.runner_registration_enabled = false + end + + it { is_expected.to be_allowed(:register_group_runners) } + end end end @@ -1217,6 +1233,14 @@ RSpec.describe GroupPolicy do it { is_expected.to be_disallowed(:register_group_runners) } end + + context 'with specific group runner registration disabled' do + before do + group.runner_registration_enabled = false + end + + it { is_expected.to be_disallowed(:register_group_runners) } + end end context 'with maintainer' do diff --git a/spec/requests/groups/usage_quotas_controller_spec.rb b/spec/requests/groups/usage_quotas_controller_spec.rb new file mode 100644 index 00000000000..3772fc2ba3b --- /dev/null +++ b/spec/requests/groups/usage_quotas_controller_spec.rb @@ -0,0 +1,48 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Groups::UsageQuotasController, feature_category: :subscription_usage_reports do + let_it_be(:group) { create(:group) } + let_it_be(:subgroup) { create(:group, parent: group) } + let_it_be(:user) { create(:user) } + + subject(:request) { get group_usage_quotas_path(group) } + + before do + sign_in(user) + end + + describe 'GET /groups/*group_id/-/usage_quotas' do + context 'when user has read_usage_quotas permission' do + before do + group.add_owner(user) + end + + it 'renders index with 200 status code' do + request + + expect(response).to have_gitlab_http_status(:ok) + expect(response.body).to match(/Placeholder for usage quotas Vue app/) + end + + it 'renders 404 page if subgroup' do + get group_usage_quotas_path(subgroup) + + expect(response).to have_gitlab_http_status(:not_found) + end + end + + context 'when user does not have read_usage_quotas permission' do + before do + group.add_maintainer(user) + end + + it 'renders not_found' do + request + + expect(response).to have_gitlab_http_status(:not_found) + end + end + end +end diff --git a/spec/routing/group_routing_spec.rb b/spec/routing/group_routing_spec.rb index 68e619e5246..54fbe9e962d 100644 --- a/spec/routing/group_routing_spec.rb +++ b/spec/routing/group_routing_spec.rb @@ -83,6 +83,10 @@ RSpec.shared_examples 'groups routing' do it 'routes to the observability controller manage method' do expect(get("groups/#{group_path}/-/observability/manage")).to route_to('groups/observability#manage', group_id: group_path) end + + it 'routes to the usage quotas controller' do + expect(get("groups/#{group_path}/-/usage_quotas")).to route_to("groups/usage_quotas#index", group_id: group_path) + end end RSpec.describe "Groups", "routing" do diff --git a/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb b/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb index 572b1a20166..2fda789cf56 100644 --- a/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb +++ b/spec/services/incident_management/pager_duty/create_incident_issue_service_spec.rb @@ -8,7 +8,7 @@ RSpec.describe IncidentManagement::PagerDuty::CreateIncidentIssueService do let(:webhook_payload) { Gitlab::Json.parse(fixture_file('pager_duty/webhook_incident_trigger.json')) } let(:parsed_payload) { ::PagerDuty::WebhookPayloadParser.call(webhook_payload) } - let(:incident_payload) { parsed_payload.first['incident'] } + let(:incident_payload) { parsed_payload['incident'] } subject(:execute) { described_class.new(project, incident_payload).execute } @@ -41,14 +41,14 @@ RSpec.describe IncidentManagement::PagerDuty::CreateIncidentIssueService do expect(execute.payload[:issue].description).to eq( <<~MARKDOWN.chomp - **Incident:** [My new incident](https://webdemo.pagerduty.com/incidents/PRORDTY)#{markdown_line_break} - **Incident number:** 33#{markdown_line_break} + **Incident:** [[FILTERED]](https://gitlab-1.pagerduty.com/incidents/Q1XZUF87W1HB5A)#{markdown_line_break} + **Incident number:** 2#{markdown_line_break} **Urgency:** high#{markdown_line_break} **Status:** triggered#{markdown_line_break} - **Incident key:** #{markdown_line_break} - **Created at:** 26 September 2017, 3:14PM (UTC)#{markdown_line_break} - **Assignees:** [Laura Haley](https://webdemo.pagerduty.com/users/P553OPV)#{markdown_line_break} - **Impacted services:** [Production XDB Cluster](https://webdemo.pagerduty.com/services/PN49J75) + **Incident key:** [FILTERED]#{markdown_line_break} + **Created at:** 30 November 2022, 8:46AM (UTC)#{markdown_line_break} + **Assignees:** [Rajendra Kadam](https://gitlab-1.pagerduty.com/users/PIN0B5C)#{markdown_line_break} + **Impacted service:** [Test service](https://gitlab-1.pagerduty.com/services/PK6IKMT) MARKDOWN ) end diff --git a/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb b/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb index 8b6eb21c25d..e2aba0b61af 100644 --- a/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb +++ b/spec/services/incident_management/pager_duty/process_webhook_service_spec.rb @@ -34,7 +34,7 @@ RSpec.describe IncidentManagement::PagerDuty::ProcessWebhookService do end it 'processes issues' do - incident_payload = ::PagerDuty::WebhookPayloadParser.call(webhook_payload).first['incident'] + incident_payload = ::PagerDuty::WebhookPayloadParser.call(webhook_payload)['incident'] expect(::IncidentManagement::PagerDuty::ProcessIncidentWorker) .to receive(:perform_async) diff --git a/spec/services/merge_requests/build_service_spec.rb b/spec/services/merge_requests/build_service_spec.rb index 4f27ff30da7..79c779678a4 100644 --- a/spec/services/merge_requests/build_service_spec.rb +++ b/spec/services/merge_requests/build_service_spec.rb @@ -25,7 +25,9 @@ RSpec.describe MergeRequests::BuildService do safe_message: 'Initial commit', gitaly_commit?: false, id: 'f00ba6', - parent_ids: ['f00ba5']) + parent_ids: ['f00ba5'], + author_email: 'tom@example.com', + author_name: 'Tom Example') end let(:commit_2) do @@ -34,7 +36,9 @@ RSpec.describe MergeRequests::BuildService do safe_message: "Closes #1234 Second commit\n\nCreate the app", gitaly_commit?: false, id: 'f00ba7', - parent_ids: ['f00ba6']) + parent_ids: ['f00ba6'], + author_email: 'alice@example.com', + author_name: 'Alice Example') end let(:commit_3) do @@ -43,7 +47,9 @@ RSpec.describe MergeRequests::BuildService do safe_message: 'This is a bad commit message!', gitaly_commit?: false, id: 'f00ba8', - parent_ids: ['f00ba7']) + parent_ids: ['f00ba7'], + author_email: 'jo@example.com', + author_name: 'Jo Example') end let(:commits) { nil } @@ -742,4 +748,91 @@ RSpec.describe MergeRequests::BuildService do end end end + + describe '#replace_variables_in_description' do + context 'when the merge request description is blank' do + let(:description) { nil } + + it 'does not update the description' do + expect(merge_request.description).to eq(nil) + end + end + + context 'when the merge request description contains template variables' do + let(:description) { <<~MSG.rstrip } + source_branch:%{source_branch} + target_branch:%{target_branch} + title:%{title} + issues:%{issues} + description:%{description} + first_commit:%{first_commit} + first_multiline_commit:%{first_multiline_commit} + url:%{url} + approved_by:%{approved_by} + merged_by:%{merged_by} + co_authored_by:%{co_authored_by} + all_commits:%{all_commits} + MSG + + context 'when there are multiple commits in the diff' do + let(:commits) { Commit.decorate([commit_1, commit_2, commit_3], project) } + + before do + stub_compare + end + + it 'replaces the variables in the description' do + expect(merge_request.description).to eq <<~MSG.rstrip + source_branch:feature-branch + target_branch:master + title: + issues: + description: + first_commit:Initial commit + first_multiline_commit:Closes #1234 Second commit + + Create the app + url: + approved_by: + merged_by: + co_authored_by:Co-authored-by: Jo Example <jo@example.com> + Co-authored-by: Alice Example <alice@example.com> + Co-authored-by: Tom Example <tom@example.com> + all_commits:* This is a bad commit message! + + * Closes #1234 Second commit + + Create the app + + * Initial commit + MSG + end + end + + context 'when there are no commits in the diff' do + let(:commits) { [] } + + before do + stub_compare + end + + it 'replaces the variables in the description' do + expect(merge_request.description).to eq <<~MSG.rstrip + source_branch:feature-branch + target_branch:master + title: + issues: + description: + first_commit: + first_multiline_commit: + url: + approved_by: + merged_by: + co_authored_by: + all_commits: + MSG + end + end + end + end end diff --git a/spec/workers/incident_management/pager_duty/process_incident_worker_spec.rb b/spec/workers/incident_management/pager_duty/process_incident_worker_spec.rb index 2b2903733a2..b81f1a575b5 100644 --- a/spec/workers/incident_management/pager_duty/process_incident_worker_spec.rb +++ b/spec/workers/incident_management/pager_duty/process_incident_worker_spec.rb @@ -22,9 +22,9 @@ RSpec.describe IncidentManagement::PagerDuty::ProcessIncidentWorker do 'assignees' => [{ 'summary' => 'Laura Haley', 'url' => 'https://webdemo.pagerduty.com/users/P553OPV' }], - 'impacted_services' => [{ + 'impacted_service' => { 'summary' => 'Production XDB Cluster', 'url' => 'https://webdemo.pagerduty.com/services/PN49J75' - }] + } } end |
