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"