diff --git a/app/assets/javascripts/api.js b/app/assets/javascripts/api.js index cc6bd873ede..516235657cb 100644 --- a/app/assets/javascripts/api.js +++ b/app/assets/javascripts/api.js @@ -796,7 +796,7 @@ const Api = { return axios.delete(url, { data }); }, - getRawFile(id, path, params = { ref: 'master' }) { + getRawFile(id, path, params = {}) { const url = Api.buildUrl(this.rawFilePath) .replace(':id', encodeURIComponent(id)) .replace(':path', encodeURIComponent(path)); diff --git a/app/assets/javascripts/projects/pipelines/charts/components/app.vue b/app/assets/javascripts/projects/pipelines/charts/components/app.vue index 5f11bd62fdc..8a4e6c4e51c 100644 --- a/app/assets/javascripts/projects/pipelines/charts/components/app.vue +++ b/app/assets/javascripts/projects/pipelines/charts/components/app.vue @@ -18,6 +18,10 @@ export default { type: Boolean, default: false, }, + shouldRenderLeadTimeCharts: { + type: Boolean, + default: false, + }, }, data() { return { @@ -26,11 +30,17 @@ export default { }, computed: { charts() { + const chartsToShow = ['pipelines']; + if (this.shouldRenderDeploymentFrequencyCharts) { - return ['pipelines', 'deployments', 'lead-time']; + chartsToShow.push('deployments'); } - return ['pipelines', 'lead-time']; + if (this.shouldRenderLeadTimeCharts) { + chartsToShow.push('lead-time'); + } + + return chartsToShow; }, }, created() { @@ -55,16 +65,17 @@ export default { diff --git a/app/assets/javascripts/projects/pipelines/charts/index.js b/app/assets/javascripts/projects/pipelines/charts/index.js index 7e746423b6a..05866fb2fc9 100644 --- a/app/assets/javascripts/projects/pipelines/charts/index.js +++ b/app/assets/javascripts/projects/pipelines/charts/index.js @@ -16,6 +16,7 @@ const mountPipelineChartsApp = (el) => { const shouldRenderDeploymentFrequencyCharts = parseBoolean( el.dataset.shouldRenderDeploymentFrequencyCharts, ); + const shouldRenderLeadTimeCharts = parseBoolean(el.dataset.shouldRenderLeadTimeCharts); return new Vue({ el, @@ -27,6 +28,7 @@ const mountPipelineChartsApp = (el) => { provide: { projectPath, shouldRenderDeploymentFrequencyCharts, + shouldRenderLeadTimeCharts, }, render: (createElement) => createElement(ProjectPipelinesCharts, {}), }); diff --git a/app/helpers/graph_helper.rb b/app/helpers/graph_helper.rb index abb3c5a7af8..d2820325f23 100644 --- a/app/helpers/graph_helper.rb +++ b/app/helpers/graph_helper.rb @@ -26,6 +26,10 @@ module GraphHelper def should_render_deployment_frequency_charts false end + + def should_render_lead_time_charts + false + end end GraphHelper.prepend_if_ee('EE::GraphHelper') diff --git a/app/views/projects/pages/_ssl_limitations_warning.html.haml b/app/views/projects/pages/_ssl_limitations_warning.html.haml index 5826fad0224..de74b703e95 100644 --- a/app/views/projects/pages/_ssl_limitations_warning.html.haml +++ b/app/views/projects/pages/_ssl_limitations_warning.html.haml @@ -3,4 +3,5 @@ %strong= _("Warning:") - pages_host = Gitlab.config.pages.host - docs_link_start = "".html_safe + - link_end = ''.html_safe = s_("GitLabPages|When using Pages under the general domain of a GitLab instance (%{pages_host}), you cannot use HTTPS with sub-subdomains. This means that if your username/groupname contains a dot it will not work. This is a limitation of the HTTP Over TLS protocol. HTTP pages will continue to work provided you don't redirect HTTP to HTTPS. %{docs_link_start}Learn more.%{link_end}").html_safe % { pages_host: pages_host, docs_link_start: docs_link_start, link_end: link_end } diff --git a/app/views/projects/pipelines/charts.html.haml b/app/views/projects/pipelines/charts.html.haml index 139f6e3c94d..76186ed5979 100644 --- a/app/views/projects/pipelines/charts.html.haml +++ b/app/views/projects/pipelines/charts.html.haml @@ -1,4 +1,5 @@ - page_title _('CI/CD Analytics') #js-project-pipelines-charts-app{ data: { project_path: @project.full_path, - should_render_deployment_frequency_charts: should_render_deployment_frequency_charts.to_s } } + should_render_deployment_frequency_charts: should_render_deployment_frequency_charts.to_s, + should_render_lead_time_charts: should_render_lead_time_charts.to_s } } diff --git a/changelogs/unreleased/sh-log-all-api-project-uploads.yml b/changelogs/unreleased/sh-log-all-api-project-uploads.yml new file mode 100644 index 00000000000..d7499a37470 --- /dev/null +++ b/changelogs/unreleased/sh-log-all-api-project-uploads.yml @@ -0,0 +1,5 @@ +--- +title: Log all API uploads that exceed max attachment size +merge_request: 59292 +author: +type: changed diff --git a/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml b/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml new file mode 100644 index 00000000000..a6186d44698 --- /dev/null +++ b/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml @@ -0,0 +1,20 @@ +--- +key_path: redis_hll_counters.testing.i_testing_summary_widget_total_monthly +description: Unique users that expand the test summary merge request widget by month +product_section: ops +product_stage: verify +product_group: group::testing +product_category: testing +value_type: number +status: implemented +milestone: "13.11" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59316 +time_frame: 28d +data_source: redis_hll +distribution: +- ee +- ce +tier: +- free +- premium +- ultimate diff --git a/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml b/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml new file mode 100644 index 00000000000..f44347f5159 --- /dev/null +++ b/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml @@ -0,0 +1,20 @@ +--- +key_path: redis_hll_counters.testing.i_testing_summary_widget_total_weekly +description: Unique users that expand the test summary merge request widget by week +product_section: ops +product_stage: verify +product_group: group::testing +product_category: testing +value_type: number +status: implemented +milestone: "13.11" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/59316 +time_frame: 7d +data_source: redis_hll +distribution: +- ee +- ce +tier: +- free +- premium +- ultimate diff --git a/doc/administration/incoming_email.md b/doc/administration/incoming_email.md index 867877bbe62..22cd6ca097c 100644 --- a/doc/administration/incoming_email.md +++ b/doc/administration/incoming_email.md @@ -615,3 +615,59 @@ incoming_email: # Whether the IMAP server uses SSL ssl: true ``` + +#### Microsoft Graph + +> Introduced in [GitLab 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/214900). + +GitLab can read incoming email using the Microsoft Graph API instead of +IMAP. Because [Microsoft is deprecating IMAP usage with Basic Authentication](https://techcommunity.microsoft.com/t5/exchange-team-blog/announcing-oauth-2-0-support-for-imap-and-smtp-auth-protocols-in/ba-p/1330432), the Microsoft Graph API will soon be required for new Microsoft Exchange Online +mailboxes. + +To configure GitLab for Microsoft Graph, you will need to register an +OAuth2 application in your Azure Active Directory that has the +`Mail.ReadWrite` permission for all mailboxes. See the [MailRoom step-by-step guide](https://github.com/tpitale/mail_room/#microsoft-graph-configuration) +and [Microsoft instructions](https://docs.microsoft.com/en-us/azure/active-directory/develop/quickstart-register-app) +for more details. + +Record the following when you configure your OAuth2 application: + +- Tenant ID for your Azure Active Directory +- Client ID for your OAuth2 application +- Client secret your OAuth2 application + +##### Restrict mailbox access + +For MailRoom to work as a service account, the application you create +in Azure Active Directory requires that you set the `Mail.ReadWrite` property +to read/write mail in *all* mailboxes. + +To mitigate security concerns, we recommend configuring an application access +policy which limits the mailbox access for all accounts, as described in +[Microsoft documentation](https://docs.microsoft.com/en-us/graph/auth-limit-mailbox-access). + +This example for Omnibus GitLab assumes you're using the following mailbox: `incoming@example.onmicrosoft.com`: + +##### Configure Microsoft Graph + +```ruby +gitlab_rails['incoming_email_enabled'] = true + +# The email address including the `%{key}` placeholder that will be replaced +# to reference the item being replied to. The placeholder can be omitted, but if +# present, it must appear in the "user" part of the address (before the `@`). +gitlab_rails['incoming_email_address'] = "incoming+%{key}@example.onmicrosoft.com" + +# Email account username +gitlab_rails['incoming_email_email'] = "incoming@example.onmicrosoft.com" + +gitlab_rails['incoming_email_inbox_method'] = 'microsoft_graph' +gitlab_rails['incoming_email_inbox_options'] = { + 'tenant_id': '', + 'client_id': '', + 'client_secret': '', + 'poll_interval': 60 # Optional +} +``` + +The Microsoft Graph API is not yet supported in source installations. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/326169) for more details. diff --git a/doc/api/merge_request_approvals.md b/doc/api/merge_request_approvals.md index fb9ec76b90a..be973518d89 100644 --- a/doc/api/merge_request_approvals.md +++ b/doc/api/merge_request_approvals.md @@ -7,7 +7,9 @@ type: reference, api # Merge request approvals API **(PREMIUM)** -Configuration for approvals on all Merge Requests (MR) in the project. Must be authenticated for all endpoints. +Configuration for +[approvals on all merge requests](../user/project/merge_requests/merge_request_approvals.md) +in the project. Must be authenticated for all endpoints. ## Project-level MR approvals diff --git a/doc/development/usage_ping/dictionary.md b/doc/development/usage_ping/dictionary.md index 2e5183e4a60..f47c81f3f13 100644 --- a/doc/development/usage_ping/dictionary.md +++ b/doc/development/usage_ping/dictionary.md @@ -13784,6 +13784,30 @@ Status: `data_available` Tiers: `premium`, `ultimate` +### `redis_hll_counters.testing.i_testing_summary_widget_total_monthly` + +Unique users that expand the test summary merge request widget by month + +[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_28d/20210413205507_i_testing_summary_widget_total_monthly.yml) + +Group: `group::testing` + +Status: `implemented` + +Tiers: `free`, `premium`, `ultimate` + +### `redis_hll_counters.testing.i_testing_summary_widget_total_weekly` + +Unique users that expand the test summary merge request widget by week + +[YAML definition](https://gitlab.com/gitlab-org/gitlab/-/blob/master/config/metrics/counts_7d/20210413205507_i_testing_summary_widget_total_weekly.yml) + +Group: `group::testing` + +Status: `implemented` + +Tiers: `free`, `premium`, `ultimate` + ### `redis_hll_counters.testing.i_testing_test_case_parsed_monthly` Internal Tracking to count number of unit tests parsed for planning of future code testing features. Data available [here](https://app.periscopedata.com/app/gitlab/788674/Verify:Testing-Group-Metrics?widget=10454394&udv=0) diff --git a/doc/user/project/merge_requests/merge_request_approvals.md b/doc/user/project/merge_requests/merge_request_approvals.md index 96952d2adb2..835350ade44 100644 --- a/doc/user/project/merge_requests/merge_request_approvals.md +++ b/doc/user/project/merge_requests/merge_request_approvals.md @@ -13,6 +13,7 @@ type: reference, concepts Code review is an essential practice of every successful project. Approving a merge request is an important part of the review process, as it clearly communicates the ability to merge the change. +A [merge request approvals API](../../../api/merge_request_approvals.md) is also available. ## Optional Approvals diff --git a/doc/user/project/service_desk.md b/doc/user/project/service_desk.md index 76337b62da2..dd646a54b43 100644 --- a/doc/user/project/service_desk.md +++ b/doc/user/project/service_desk.md @@ -183,7 +183,7 @@ always use separate mailboxes. This is important, because emails picked from `service_desk_email` mailbox are processed by a different worker and it would not recognize `incoming_email` emails. -To configure a custom email address for Service Desk, add the following snippets to your configuration file: +To configure a custom email address for Service Desk with IMAP, add the following snippets to your configuration file: - Example for installations from source: @@ -236,6 +236,38 @@ As a result, a new Service Desk issue is created from this email in the `mygroup The configuration options are the same as for configuring [incoming email](../../administration/incoming_email.md#set-it-up). +#### Microsoft Graph + +> Introduced in [GitLab 13.11](https://gitlab.com/gitlab-org/gitlab/-/issues/214900) + +Service Desk can be configured to read Microsoft Exchange Online mailboxes with the Microsoft +Graph API instead of IMAP. Follow the [documentation in the incoming e-mail section for setting up an OAuth2 application for Microsoft Graph](../../administration/incoming_email.md#microsoft-graph). + +- Example for Omnibus GitLab installations: + + ```ruby + gitlab_rails['service_desk_email_enabled'] = true + + gitlab_rails['service_desk_email_address'] = "project_contact+%{key}@example.onmicrosoft.com" + + gitlab_rails['service_desk_email_email'] = "project_contact@example.onmicrosoft.com" + + gitlab_rails['service_desk_email_mailbox_name'] = "inbox" + + gitlab_rails['service_desk_email_log_file'] = "/var/log/gitlab/mailroom/mail_room_json.log" + + gitlab_rails['service_desk_inbox_method'] = 'microsoft_graph' + + gitlab_rails['service_desk_inbox_options'] = { + 'tenant_id': '', + 'client_id': '', + 'client_secret': '', + 'poll_interval': 60 # Optional + } + ``` + +The Microsoft Graph API is not yet supported in source installations. See [this issue](https://gitlab.com/gitlab-org/gitlab/-/issues/326169) for more details. + ## Using Service Desk You can use Service Desk to [create an issue](#as-an-end-user-issue-creator) or [respond to one](#as-a-responder-to-the-issue). diff --git a/lib/api/projects.rb b/lib/api/projects.rb index 7674e67cd8f..92f6970e6fc 100644 --- a/lib/api/projects.rb +++ b/lib/api/projects.rb @@ -71,10 +71,10 @@ module API # This is to help determine which projects to use in https://gitlab.com/gitlab-org/gitlab/-/issues/325788 def log_if_upload_exceed_max_size(user_project, file) return if file.size <= user_project.max_attachment_size - return if exempt_from_global_attachment_size?(user_project) if file.size > user_project.max_attachment_size - Gitlab::AppLogger.info({ message: "File exceeds maximum size", file_bytes: file.size, project_id: user_project.id, project_path: user_project.full_path }) + allowed = exempt_from_global_attachment_size?(user_project) + Gitlab::AppLogger.info({ message: "File exceeds maximum size", file_bytes: file.size, project_id: user_project.id, project_path: user_project.full_path, upload_allowed: allowed }) end end end diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 48ce8e39124..14ceabd3084 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -14284,6 +14284,9 @@ msgstr "" msgid "Geo|Data replication lag" msgstr "" +msgid "Geo|Data type" +msgstr "" + msgid "Geo|Discover GitLab Geo" msgstr "" @@ -14413,9 +14416,6 @@ msgstr "" msgid "Geo|Replication Details" msgstr "" -msgid "Geo|Replication counts" -msgstr "" - msgid "Geo|Replication details" msgstr "" @@ -14470,6 +14470,9 @@ msgstr "" msgid "Geo|Synced at" msgstr "" +msgid "Geo|Synchronization" +msgstr "" + msgid "Geo|Synchronization failed - %{error}" msgstr "" @@ -14509,6 +14512,9 @@ msgstr "" msgid "Geo|Unknown state" msgstr "" +msgid "Geo|Verification" +msgstr "" + msgid "Geo|Verification failed - %{error}" msgstr "" diff --git a/package.json b/package.json index 55982beb3f0..d528b15d6b8 100644 --- a/package.json +++ b/package.json @@ -49,9 +49,9 @@ "@babel/preset-env": "^7.10.1", "@gitlab/at.js": "1.5.7", "@gitlab/favicon-overlay": "2.0.0", - "@gitlab/svgs": "1.188.0", + "@gitlab/svgs": "1.189.0", "@gitlab/tributejs": "1.0.0", - "@gitlab/ui": "29.4.0", + "@gitlab/ui": "29.5.0", "@gitlab/visual-review-tools": "1.6.1", "@rails/actioncable": "^6.0.3-4", "@rails/ujs": "^6.0.3-4", diff --git a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb index c8c483fc2aa..5072b6d48bf 100644 --- a/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb +++ b/qa/qa/specs/features/browser_ui/1_manage/project/import_github_repo_spec.rb @@ -29,7 +29,7 @@ module QA user.remove_via_api! end - it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/385' do + it 'imports a GitHub repo', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1762' do Flow::Login.sign_in(as: user) imported_project # import the project diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb index 43cf701acdd..6afc7549c59 100644 --- a/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/design_management/archive_design_content_spec.rb @@ -23,7 +23,7 @@ module QA Flow::Login.sign_in end - it 'user archives a design', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/274' do + it 'user archives a design', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1761' do third_design.issue.visit! Page::Project::Issue::Show.perform do |issue| diff --git a/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb b/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb index 9fbb0d69de1..dfdc9b7c9b4 100644 --- a/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/design_management/modify_design_content_spec.rb @@ -13,7 +13,7 @@ module QA Flow::Login.sign_in end - it 'user adds a design and modifies it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/273' do + it 'user adds a design and modifies it', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1760' do design.issue.visit! Page::Project::Issue::Show.perform do |issue| diff --git a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb index 38c9216005f..ef3d45724db 100644 --- a/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb +++ b/qa/qa/specs/features/browser_ui/3_create/repository/protocol_v2_push_ssh_spec.rb @@ -27,7 +27,7 @@ module QA Page::Main::Menu.perform(&:sign_out_if_signed_in) end - it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/386' do + it 'user pushes to the repository', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1763' do project = Resource::Project.fabricate_via_api! do |project| project.name = 'git-protocol-project' end diff --git a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb index fcd8cb02870..39cbd0028c0 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/ci_variable/add_remove_ci_variable_spec.rb @@ -16,7 +16,7 @@ module QA add_ci_variable end - it 'user adds a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/395' do + it 'user adds a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1759' do Page::Project::Settings::CiVariables.perform do |ci_variable| expect(ci_variable).to have_text('VARIABLE_KEY') expect(ci_variable).not_to have_text('some_CI_variable') @@ -27,7 +27,7 @@ module QA end end - it 'user removes a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/394' do + it 'user removes a CI variable', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1758' do Page::Project::Settings::CiVariables.perform do |ci_variable| ci_variable.click_edit_ci_variable ci_variable.click_ci_variable_delete_button diff --git a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb index 9ce87f353d0..916b809ebc1 100644 --- a/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb +++ b/qa/qa/specs/features/browser_ui/4_verify/runner/register_runner_spec.rb @@ -15,7 +15,7 @@ module QA runner.remove_via_api! end - it 'user registers a new specific runner', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/392' do + it 'user registers a new specific runner', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1764' do Flow::Login.sign_in runner.project.visit! diff --git a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb index 87bd2b76560..713b32de217 100644 --- a/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb +++ b/qa/qa/specs/features/browser_ui/6_release/deploy_key/add_deploy_key_spec.rb @@ -3,7 +3,7 @@ module QA RSpec.describe 'Release' do describe 'Deploy key creation' do - it 'user adds a deploy key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/390' do + it 'user adds a deploy key', testcase: 'https://gitlab.com/gitlab-org/quality/testcases/-/issues/1765' do Flow::Login.sign_in key = Runtime::Key::RSA.new diff --git a/spec/frontend/api_spec.js b/spec/frontend/api_spec.js index 5523fe13cd6..cb29dab86bf 100644 --- a/spec/frontend/api_spec.js +++ b/spec/frontend/api_spec.js @@ -1222,13 +1222,26 @@ describe('Api', () => { )}/repository/files/${encodeURIComponent(dummyFilePath)}/raw`; describe('when the raw file is successfully fetched', () => { - it('resolves the Promise', () => { + beforeEach(() => { mock.onGet(expectedUrl).replyOnce(httpStatus.OK); + }); + it('resolves the Promise', () => { return Api.getRawFile(dummyProjectPath, dummyFilePath).then(() => { expect(mock.history.get).toHaveLength(1); }); }); + + describe('when the method is called with params', () => { + it('sets the params on the request', () => { + const params = { ref: 'main' }; + jest.spyOn(axios, 'get'); + + Api.getRawFile(dummyProjectPath, dummyFilePath, params); + + expect(axios.get).toHaveBeenCalledWith(expectedUrl, { params }); + }); + }); }); describe('when an error occurs while getting a raw file', () => { diff --git a/spec/frontend/projects/pipelines/charts/components/app_spec.js b/spec/frontend/projects/pipelines/charts/components/app_spec.js index 2aab50985cf..ab1ce260c07 100644 --- a/spec/frontend/projects/pipelines/charts/components/app_spec.js +++ b/spec/frontend/projects/pipelines/charts/components/app_spec.js @@ -22,7 +22,8 @@ describe('ProjectsPipelinesChartsApp', () => { {}, { provide: { - shouldRenderDeploymentFrequencyCharts: false, + shouldRenderDeploymentFrequencyCharts: true, + shouldRenderLeadTimeCharts: true, }, stubs: { DeploymentFrequencyCharts: DeploymentFrequencyChartsStub, @@ -34,45 +35,45 @@ describe('ProjectsPipelinesChartsApp', () => { ); } - beforeEach(() => { - createComponent(); - }); - afterEach(() => { wrapper.destroy(); - wrapper = null; }); const findGlTabs = () => wrapper.find(GlTabs); - const findAllGlTab = () => wrapper.findAll(GlTab); - const findGlTabAt = (i) => findAllGlTab().at(i); + const findAllGlTabs = () => wrapper.findAll(GlTab); const findLeadTimeCharts = () => wrapper.find(LeadTimeChartsStub); const findDeploymentFrequencyCharts = () => wrapper.find(DeploymentFrequencyChartsStub); const findPipelineCharts = () => wrapper.find(PipelineCharts); - it('renders the pipeline charts', () => { - expect(findPipelineCharts().exists()).toBe(true); - }); - - it('renders the lead time charts', () => { - expect(findLeadTimeCharts().exists()).toBe(true); - }); - - describe('when shouldRenderDeploymentFrequencyCharts is true', () => { - beforeEach(() => { - createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: true } }); - }); - + const expectCorrectTabs = ({ pipelines, leadTime, deploymentFreqency }) => { it('renders the expected tabs', () => { expect(findGlTabs().exists()).toBe(true); - expect(findGlTabAt(0).attributes('title')).toBe('Pipelines'); - expect(findGlTabAt(1).attributes('title')).toBe('Deployments'); - expect(findGlTabAt(2).attributes('title')).toBe('Lead Time'); + + const allTabTitles = findAllGlTabs().wrappers.map((w) => w.attributes('title')); + + if (pipelines) { + expect(allTabTitles).toContain('Pipelines'); + expect(findPipelineCharts().exists()).toBe(true); + } + + if (deploymentFreqency) { + expect(allTabTitles).toContain('Deployments'); + expect(findDeploymentFrequencyCharts().exists()).toBe(true); + } + + if (leadTime) { + expect(allTabTitles).toContain('Lead Time'); + expect(findLeadTimeCharts().exists()).toBe(true); + } + }); + }; + + describe('when all charts are available', () => { + beforeEach(() => { + createComponent(); }); - it('renders the deployment frequency charts', () => { - expect(findDeploymentFrequencyCharts().exists()).toBe(true); - }); + expectCorrectTabs({ pipelines: true, deploymentFreqency: true, leadTime: true }); it('sets the tab and url when a tab is clicked', async () => { let chartsPath; @@ -172,14 +173,33 @@ describe('ProjectsPipelinesChartsApp', () => { createComponent({ provide: { shouldRenderDeploymentFrequencyCharts: false } }); }); - it('renders the expected tabs', () => { - expect(findGlTabs().exists()).toBe(true); - expect(findGlTabAt(0).attributes('title')).toBe('Pipelines'); - expect(findGlTabAt(1).attributes('title')).toBe('Lead Time'); + expectCorrectTabs({ pipelines: true, deploymentFreqency: false, leadTime: true }); + }); + + describe('when shouldRenderLeadTimeCharts is false', () => { + beforeEach(() => { + createComponent({ provide: { shouldRenderLeadTimeCharts: false } }); }); - it('does not render the deployment frequency charts in a tab', () => { - expect(findDeploymentFrequencyCharts().exists()).toBe(false); + expectCorrectTabs({ pipelines: true, deploymentFreqency: true, leadTime: false }); + }); + + describe('when shouldRenderDeploymentFrequencyCharts and shouldRenderLeadTimeCharts are false', () => { + beforeEach(() => { + createComponent({ + provide: { + shouldRenderDeploymentFrequencyCharts: false, + shouldRenderLeadTimeCharts: false, + }, + }); + }); + + it('does not render tabs', () => { + expect(findGlTabs().exists()).toBe(false); + }); + + it('renders the pipeline charts', () => { + expect(findPipelineCharts().exists()).toBe(true); }); }); }); diff --git a/spec/helpers/graph_helper_spec.rb b/spec/helpers/graph_helper_spec.rb index 682f6365481..5b5ad59ed0d 100644 --- a/spec/helpers/graph_helper_spec.rb +++ b/spec/helpers/graph_helper_spec.rb @@ -27,4 +27,16 @@ RSpec.describe GraphHelper do expect(should_render_deployment_frequency_charts).to be(false) end end + + describe '#should_render_lead_time_charts' do + let(:project) { create(:project, :private) } + + before do + self.instance_variable_set(:@project, project) + end + + it 'always returns false' do + expect(should_render_lead_time_charts).to be(false) + end + end end diff --git a/spec/requests/api/projects_spec.rb b/spec/requests/api/projects_spec.rb index d4fb49a8f50..b0ecb711283 100644 --- a/spec/requests/api/projects_spec.rb +++ b/spec/requests/api/projects_spec.rb @@ -1587,14 +1587,6 @@ RSpec.describe API::Projects do expect(json_response['full_path']).to start_with("/#{project.namespace.path}/#{project.path}/uploads") end - it "logs a warning if file exceeds attachment size" do - allow(Gitlab::CurrentSettings).to receive(:max_attachment_size).and_return(0) - - expect(Gitlab::AppLogger).to receive(:info).with(hash_including(message: 'File exceeds maximum size')).and_call_original - - post api("/projects/#{project.id}/uploads", user), params: { file: file } - end - it "does not leave the temporary file in place after uploading, even when the tempfile reaper does not run" do stub_env('GITLAB_TEMPFILE_IMMEDIATE_UNLINK', '1') tempfile = Tempfile.new('foo') @@ -1613,7 +1605,7 @@ RSpec.describe API::Projects do expect(File.exist?(path)).to be(false) end - shared_examples 'capped upload attachments' do + shared_examples 'capped upload attachments' do |upload_allowed| it "limits the upload to 1 GB" do expect_next_instance_of(UploadService) do |instance| expect(instance).to receive(:override_max_attachment_size=).with(1.gigabyte).and_call_original @@ -1623,6 +1615,16 @@ RSpec.describe API::Projects do expect(response).to have_gitlab_http_status(:created) end + + it "logs a warning if file exceeds attachment size" do + allow(Gitlab::CurrentSettings).to receive(:max_attachment_size).and_return(0) + + expect(Gitlab::AppLogger).to receive(:info).with( + hash_including(message: 'File exceeds maximum size', upload_allowed: upload_allowed)) + .and_call_original + + post api("/projects/#{project.id}/uploads", user), params: { file: file } + end end context 'with exempted project' do @@ -1630,7 +1632,7 @@ RSpec.describe API::Projects do stub_env('GITLAB_UPLOAD_API_ALLOWLIST', project.id) end - it_behaves_like 'capped upload attachments' + it_behaves_like 'capped upload attachments', true end context 'with upload size enforcement disabled' do @@ -1638,7 +1640,7 @@ RSpec.describe API::Projects do stub_feature_flags(enforce_max_attachment_size_upload_api: false) end - it_behaves_like 'capped upload attachments' + it_behaves_like 'capped upload attachments', false end end diff --git a/yarn.lock b/yarn.lock index bed82f6a675..d24a087c2ac 100644 --- a/yarn.lock +++ b/yarn.lock @@ -897,20 +897,20 @@ stylelint-declaration-strict-value "1.7.7" stylelint-scss "3.18.0" -"@gitlab/svgs@1.188.0": - version "1.188.0" - resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.188.0.tgz#b98e279663776cf2c7bebaacc19eaab78362ccd8" - integrity sha512-7skRsKn3jzUpXwz0wOvQgVXZ2n1f7iZ5KURyUSWHe3gLMVWAPJmGBHHtdNSIq9hhsdVFPcwYBaKm26KvnkZr5A== +"@gitlab/svgs@1.189.0": + version "1.189.0" + resolved "https://registry.yarnpkg.com/@gitlab/svgs/-/svgs-1.189.0.tgz#1ba972bfbcf46e52321c50fd57d00315535c3d1b" + integrity sha512-64QcwA0E1aR9cK6PepGiH494de7oIrXRydaWWS0RH2OtSnd0OfzfcZtZI6V0yLpJRgE3uZZ3sK95kFu+vFXH9g== "@gitlab/tributejs@1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@gitlab/tributejs/-/tributejs-1.0.0.tgz#672befa222aeffc83e7d799b0500a7a4418e59b8" integrity sha512-nmKw1+hB6MHvlmPz63yPwVs1qQkycHwsKgxpEbzmky16Y6mL4EJMk3w1b8QlOAF/AIAzjCERPhe/R4MJiohbZw== -"@gitlab/ui@29.4.0": - version "29.4.0" - resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.4.0.tgz#601b13700c5af4eeb6ca60fe72e59a2ee1b3d19a" - integrity sha512-GdV1DIP0Oq/abzlh93FPpJX/kb1Swk81znXEYpzhoL7vrg4Lotbkhlz+oaNMZF/F/YOZ8QUCKTcs2Q7HGgkKmQ== +"@gitlab/ui@29.5.0": + version "29.5.0" + resolved "https://registry.yarnpkg.com/@gitlab/ui/-/ui-29.5.0.tgz#5f8cdf062ef69800c5a6f4a4871b7283f59de34a" + integrity sha512-ebNNKZORRIoqQRF+tCaiS17pyt9qI46ULgyUYJkXHmwQKMUL0sqXRoPMPVK6T2snzMUnyNeKBMoMxTy5BiTnNA== dependencies: "@babel/standalone" "^7.0.0" "@gitlab/vue-toasted" "^1.3.0"