Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
369de19d79
commit
7c42073320
|
@ -1 +1 @@
|
|||
a6c5964bb455f77a0c79898f0b99c4c7df3aee3a
|
||||
e3aa6272e47af528b7599f93db2b02c76c55718e
|
||||
|
|
|
@ -121,9 +121,10 @@ export default {
|
|||
},
|
||||
created() {
|
||||
const [tabQueryParam] = getParameterValues(TAB_QUERY_PARAM);
|
||||
const tabName = Object.keys(TABS_INDEX)[tabQueryParam];
|
||||
|
||||
if (tabQueryParam && TABS_INDEX[tabQueryParam]) {
|
||||
this.setDefaultTab(tabQueryParam);
|
||||
if (tabName) {
|
||||
this.setDefaultTab(tabName);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
|
|
|
@ -62,6 +62,7 @@ export default {
|
|||
return {
|
||||
hasActionTooltip: false,
|
||||
isActionLoading: false,
|
||||
isExpandBtnFocus: false,
|
||||
};
|
||||
},
|
||||
computed: {
|
||||
|
@ -89,6 +90,9 @@ export default {
|
|||
? ['gl-border-r-0!', ...this.$options.styles.flatRightBorder]
|
||||
: ['gl-border-l-0!', ...this.$options.styles.flatLeftBorder];
|
||||
},
|
||||
buttonShadowClass() {
|
||||
return this.isExpandBtnFocus ? '' : 'gl-shadow-none!';
|
||||
},
|
||||
buttonId() {
|
||||
return `js-linked-pipeline-${this.pipeline.id}`;
|
||||
},
|
||||
|
@ -214,6 +218,9 @@ export default {
|
|||
setActionTooltip(flag) {
|
||||
this.hasActionTooltip = flag;
|
||||
},
|
||||
setExpandBtnActiveState(flag) {
|
||||
this.isExpandBtnFocus = flag;
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
@ -277,12 +284,16 @@ export default {
|
|||
<div class="gl-display-flex">
|
||||
<gl-button
|
||||
:id="buttonId"
|
||||
class="gl-border! gl-shadow-none! gl-rounded-lg!"
|
||||
:class="[`js-pipeline-expand-${pipeline.id}`, buttonBorderClasses]"
|
||||
class="gl-border! gl-rounded-lg!"
|
||||
:class="[`js-pipeline-expand-${pipeline.id}`, buttonBorderClasses, buttonShadowClass]"
|
||||
:icon="expandedIcon"
|
||||
:aria-label="__('Expand pipeline')"
|
||||
data-testid="expand-pipeline-button"
|
||||
data-qa-selector="expand_linked_pipeline_button"
|
||||
@mouseover="setExpandBtnActiveState(true)"
|
||||
@mouseout="setExpandBtnActiveState(false)"
|
||||
@focus="setExpandBtnActiveState(true)"
|
||||
@blur="setExpandBtnActiveState(false)"
|
||||
@click="onClickLinkedPipeline"
|
||||
/>
|
||||
</div>
|
||||
|
|
|
@ -187,14 +187,12 @@ module Namespaces
|
|||
superset_sql = <<~SQL
|
||||
SELECT d1.traversal_ids
|
||||
FROM #{base_name} d1
|
||||
LEFT JOIN LATERAL (
|
||||
SELECT d2.id as ancestor_id
|
||||
WHERE NOT EXISTS (
|
||||
SELECT 1
|
||||
FROM #{base_name} d2
|
||||
WHERE d2.id = ANY(d1.traversal_ids)
|
||||
AND d2.id <> d1.id
|
||||
LIMIT 1
|
||||
) covered ON TRUE
|
||||
WHERE covered.ancestor_id IS NULL
|
||||
)
|
||||
SQL
|
||||
|
||||
Gitlab::SQL::CTE.new(:superset, superset_sql, materialized: false)
|
||||
|
|
|
@ -2,6 +2,9 @@
|
|||
|
||||
module PagesDomains
|
||||
class CreateAcmeOrderService
|
||||
# elliptic curve algorithm to generate the private key
|
||||
ECDSA_CURVE = "prime256v1"
|
||||
|
||||
attr_reader :pages_domain
|
||||
|
||||
def initialize(pages_domain)
|
||||
|
@ -14,7 +17,12 @@ module PagesDomains
|
|||
|
||||
challenge = order.new_challenge
|
||||
|
||||
private_key = OpenSSL::PKey::RSA.new(4096)
|
||||
private_key = if Feature.enabled?(:pages_lets_encrypt_ecdsa, pages_domain.project)
|
||||
OpenSSL::PKey::EC.generate(ECDSA_CURVE)
|
||||
else
|
||||
OpenSSL::PKey::RSA.new(4096)
|
||||
end
|
||||
|
||||
saved_order = pages_domain.acme_orders.create!(
|
||||
url: order.url,
|
||||
expires_at: order.expires,
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
---
|
||||
name: pages_lets_encrypt_ecdsa
|
||||
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/88125
|
||||
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/363026
|
||||
milestone: '15.1'
|
||||
type: development
|
||||
group: group::editor
|
||||
default_enabled: false
|
|
@ -1,20 +1,21 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: usage_activity_by_stage_monthly.manage.omniauth_providers
|
||||
description: Number of unique user logins using an OmniAuth provider
|
||||
description: List of unique OmniAuth providers
|
||||
product_section: dev
|
||||
product_stage: manage
|
||||
product_group: group::access
|
||||
product_category: authentication_and_authorization
|
||||
value_type: number
|
||||
value_type: object
|
||||
status: active
|
||||
time_frame: 28d
|
||||
data_source: database
|
||||
data_source: system
|
||||
distribution:
|
||||
- ce
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
value_json_schema: 'config/metrics/objects_schemas/omniauth_providers_schema.json'
|
||||
performance_indicator_type: []
|
||||
milestone: "<13.9"
|
||||
|
|
|
@ -1,19 +1,20 @@
|
|||
---
|
||||
data_category: optional
|
||||
key_path: usage_activity_by_stage.manage.omniauth_providers
|
||||
description: Number of unique user logins using an OmniAuth provider
|
||||
description: List of unique OmniAuth providers
|
||||
product_section: dev
|
||||
product_stage: manage
|
||||
product_group: group::access
|
||||
product_category: authentication_and_authorization
|
||||
value_type: number
|
||||
value_type: object
|
||||
status: active
|
||||
time_frame: all
|
||||
data_source: database
|
||||
data_source: system
|
||||
distribution:
|
||||
- ce
|
||||
tier:
|
||||
- free
|
||||
- premium
|
||||
- ultimate
|
||||
value_json_schema: 'config/metrics/objects_schemas/omniauth_providers_schema.json'
|
||||
milestone: "<13.9"
|
||||
|
|
|
@ -0,0 +1,6 @@
|
|||
{
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": ["string", "null"]
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AddIndexOnExpirableUnknownArtifactsForRemoval < Gitlab::Database::Migration[2.0]
|
||||
disable_ddl_transaction!
|
||||
|
||||
TABLE_NAME = 'ci_job_artifacts'
|
||||
INDEX_NAME = 'tmp_index_ci_job_artifacts_on_expire_at_where_locked_unknown'
|
||||
CONDITIONS = 'locked = 2 AND expire_at IS NOT NULL'
|
||||
|
||||
def up
|
||||
add_concurrent_index TABLE_NAME, [:expire_at, :job_id], name: INDEX_NAME, where: CONDITIONS
|
||||
end
|
||||
|
||||
def down
|
||||
remove_concurrent_index_by_name TABLE_NAME, INDEX_NAME
|
||||
end
|
||||
end
|
|
@ -0,0 +1 @@
|
|||
6f8ddb4ba8931d00caa05e193a238add12176e82e25692186595ab0d847c74ea
|
|
@ -29963,6 +29963,8 @@ CREATE UNIQUE INDEX term_agreements_unique_index ON term_agreements USING btree
|
|||
|
||||
CREATE INDEX tmp_idx_container_repos_on_non_migrated ON container_repositories USING btree (project_id, id) WHERE ((migration_state <> 'import_done'::text) AND (created_at < '2022-01-23 00:00:00'::timestamp without time zone));
|
||||
|
||||
CREATE INDEX tmp_index_ci_job_artifacts_on_expire_at_where_locked_unknown ON ci_job_artifacts USING btree (expire_at, job_id) WHERE ((locked = 2) AND (expire_at IS NOT NULL));
|
||||
|
||||
CREATE INDEX tmp_index_ci_job_artifacts_on_id_where_trace_and_expire_at ON ci_job_artifacts USING btree (id) WHERE ((file_type = 3) AND (expire_at = ANY (ARRAY['2021-04-22 00:00:00+00'::timestamp with time zone, '2021-05-22 00:00:00+00'::timestamp with time zone, '2021-06-22 00:00:00+00'::timestamp with time zone, '2022-01-22 00:00:00+00'::timestamp with time zone, '2022-02-22 00:00:00+00'::timestamp with time zone, '2022-03-22 00:00:00+00'::timestamp with time zone, '2022-04-22 00:00:00+00'::timestamp with time zone])));
|
||||
|
||||
CREATE INDEX tmp_index_container_repositories_on_id_migration_state ON container_repositories USING btree (id, migration_state);
|
||||
|
|
|
@ -6,12 +6,10 @@ info: To determine the technical writer assigned to the Stage/Group associated w
|
|||
|
||||
# Compliance features **(FREE)**
|
||||
|
||||
These GitLab features can help ensure that your GitLab instance meets common
|
||||
compliance standards. For more information about compliance management, see the
|
||||
compliance management [solutions page](https://about.gitlab.com/solutions/compliance/).
|
||||
GitLab compliance features ensure your GitLab instance meets common compliance standards, and are available at various pricing tiers. For more information about compliance management, see the compliance
|
||||
management [solutions page](https://about.gitlab.com/solutions/compliance/).
|
||||
|
||||
The [security features](../security/index.md) in GitLab may also help you meet
|
||||
relevant compliance standards.
|
||||
The [security features](../security/index.md) in GitLab may also help you meet relevant compliance standards.
|
||||
|
||||
## Policy management
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ It is the properties of the GraphQL query tree that create opportunities for bat
|
|||
|
||||
## When should you use it?
|
||||
|
||||
We should try to batch DB requests as much as possible during GraphQL **query** execution. There is no need to batch loading during **mutations** because they are executed serially. If you need to make a database query, and it is possible to combine two similar (but not identical) queries, then consider using the batch-loader.
|
||||
We should try to batch DB requests as much as possible during GraphQL **query** execution. There is no need to batch loading during **mutations** because they are executed serially. If you need to make a database query, and it is possible to combine two similar (but not necessarily identical) queries, then consider using the batch-loader.
|
||||
|
||||
When implementing a new endpoint we should aim to minimise the number of SQL queries. For stability and scalability we must also ensure that our queries do not suffer from N+1 performance issues.
|
||||
|
||||
|
@ -47,6 +47,26 @@ end
|
|||
|
||||
Here an [example MR](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/46549) illustrating how to use our `BatchLoading` mechanism.
|
||||
|
||||
## The `BatchModelLoader`
|
||||
|
||||
For ID lookups, the advice is to use the `BatchModelLoader`:
|
||||
|
||||
```ruby
|
||||
def project
|
||||
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Project, object.project_id).find
|
||||
end
|
||||
```
|
||||
|
||||
To preload associations, you can pass an array of them:
|
||||
|
||||
```ruby
|
||||
def issue(lookahead:)
|
||||
preloads = [:author] if lookahead.selects?(:author)
|
||||
|
||||
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Issue, object.issue_id, preloads).find
|
||||
end
|
||||
```
|
||||
|
||||
## How does it work exactly?
|
||||
|
||||
Each lazy object knows which data it needs to load and how to batch the query. When we need to use the lazy objects (which we announce by calling `#sync`), they will be loaded along with all other similar objects in the current batch.
|
||||
|
@ -61,9 +81,28 @@ BatchLoader::GraphQL.for(username).batch do |usernames, loader|
|
|||
end
|
||||
```
|
||||
|
||||
The batch-loader uses the source code location of the block to determine
|
||||
which requests belong in the same queue, but only one instance of the block
|
||||
is evaluated for each batch. You do not control which one.
|
||||
|
||||
For this reason, it is important that:
|
||||
|
||||
- The block must not refer to (close over) any instance state on objects. The best practice
|
||||
is to pass all data the block needs through to it in the `for(data)` call.
|
||||
- The block must be specific to a kind of batched data. Implementing generic
|
||||
loaders (such as the `BatchModelLoader`) is possible, but it requires the use
|
||||
of an injective `key` argument.
|
||||
- Batches are not shared unless they refer to the same block - two identical blocks
|
||||
with the same behavior, parameters, and keys do not get shared. For this reason,
|
||||
never implement batched ID lookups on your own, instead use the `BatchModelLoader` for
|
||||
maximum sharing. If you see two fields define the same batch-loading, consider
|
||||
extracting that out to a new `Loader`, and enabling them to share.
|
||||
|
||||
### What does lazy mean?
|
||||
|
||||
It is important to avoid syncing batches too early. In the example below we can see how calling sync too early can eliminate opportunities for batching:
|
||||
It is important to avoid syncing batches (forcing their evaluation) too early. The following example shows how calling sync too early can eliminate opportunities for batching.
|
||||
|
||||
This example calls sync on `x` too early:
|
||||
|
||||
```ruby
|
||||
x = find_lazy(1)
|
||||
|
@ -80,6 +119,8 @@ z.sync
|
|||
# => will run 2 queries
|
||||
```
|
||||
|
||||
However, this example waits until all requests are queued, and eliminates the extra query:
|
||||
|
||||
```ruby
|
||||
x = find_lazy(1)
|
||||
y = find_lazy(2)
|
||||
|
@ -92,9 +133,38 @@ z.sync
|
|||
# => will run 1 query
|
||||
```
|
||||
|
||||
NOTE:
|
||||
There is no dependency analysis in the use of batch-loading. There is simply
|
||||
a pending queue of requests, and as soon as any one result is needed, all pending
|
||||
requests are evaluated.
|
||||
|
||||
You should never call `batch.sync` or use `Lazy.force` in resolver code.
|
||||
If you depend on a lazy value, use `Lazy.with_value` instead:
|
||||
|
||||
```ruby
|
||||
def publisher
|
||||
::Gitlab::Graphql::Loaders::BatchModelLoader.new(::Publisher, object.publisher_id).find
|
||||
end
|
||||
|
||||
# Here we need the publisher in order to generate the catalog URL
|
||||
def catalog_url
|
||||
::Gitlab::Graphql::Lazy.with_value(publisher) do |p|
|
||||
UrlHelpers.book_catalog_url(publisher, object.isbn)
|
||||
end
|
||||
end
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
Any GraphQL field that supports `BatchLoading` should be tested using the `batch_sync` method available in [GraphQLHelpers](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/support/helpers/graphql_helpers.rb).
|
||||
Ideally, do all your testing using request specs, and using `Schema.execute`. If
|
||||
you do so, you do not need to manage the lifecycle of lazy values yourself, and
|
||||
you are assured accurate results.
|
||||
|
||||
GraphQL fields that return lazy values may need these values forced in tests.
|
||||
Forcing refers to explicit demands for evaluation, where this would normally
|
||||
be arranged by the framework.
|
||||
|
||||
You can force a lazy value with the `GraphqlHelpers#batch_sync` method available in [GraphQLHelpers](https://gitlab.com/gitlab-org/gitlab/-/blob/master/spec/support/helpers/graphql_helpers.rb), or by using `Gitlab::Graphql::Lazy.force`. For example:
|
||||
|
||||
```ruby
|
||||
it 'returns data as a batch' do
|
||||
|
@ -114,8 +184,8 @@ We can also use [QueryRecorder](../query_recorder.md) to make sure we are perfor
|
|||
|
||||
```ruby
|
||||
it 'executes only 1 SQL query' do
|
||||
query_count = ActiveRecord::QueryRecorder.new { subject }.count
|
||||
query_count = ActiveRecord::QueryRecorder.new { subject }
|
||||
|
||||
expect(query_count).to eq(1)
|
||||
expect(query_count).not_to exceed_query_limit(1)
|
||||
end
|
||||
```
|
||||
|
|
|
@ -430,6 +430,10 @@ before this occurs.
|
|||
- To resume functionality, activate a new license.
|
||||
- To fall back to Free features, delete the expired license.
|
||||
|
||||
## Activate a license file or key
|
||||
|
||||
If you have a license file or key, you can activate it [in the Admin Area](../../user/admin_area/license_file.md#activate-gitlab-ee-with-a-license-file-or-key).
|
||||
|
||||
## Contact Support
|
||||
|
||||
Learn more about:
|
||||
|
|
|
@ -209,7 +209,7 @@ module API
|
|||
.select { |_role, role_access_level| role_access_level <= user_access_level }
|
||||
.map(&:first)
|
||||
|
||||
environment = if environment_slug = current_authenticated_job.deployment&.environment&.slug
|
||||
environment = if environment_slug = current_authenticated_job.persisted_environment&.slug
|
||||
{ slug: environment_slug }
|
||||
end
|
||||
|
||||
|
|
|
@ -21423,9 +21423,6 @@ msgstr ""
|
|||
msgid "Iterations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Add a duration, and number of upcoming iterations in order to convert this cadence to automatic scheduling."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Add iteration"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21438,6 +21435,9 @@ msgstr ""
|
|||
msgid "Iterations|Cadence name"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Can be converted"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Cancel"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21492,10 +21492,10 @@ msgstr ""
|
|||
msgid "Iterations|Iterations are a way to track issues over a period of time, allowing teams to also track velocity and volatility metrics."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Iterations can no longer be scheduled manually. Convert all cadences to automatic scheduling to keep your iterations working as expected."
|
||||
msgid "Iterations|Learn more about automatic scheduling"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Learn more about automatic scheduling"
|
||||
msgid "Iterations|Manual management of iterations will be deprecated in GitLab 15.6. Convert your manual cadence to use automated scheduling when you are ready."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Move incomplete issues to the next iteration."
|
||||
|
@ -21531,9 +21531,6 @@ msgstr ""
|
|||
msgid "Iterations|Open"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Requires update"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Roll over issues"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21549,9 +21546,6 @@ msgstr ""
|
|||
msgid "Iterations|Select start date"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Some of your cadences need to be updated"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Start date"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21564,7 +21558,7 @@ msgstr ""
|
|||
msgid "Iterations|The start date of the first iteration determines when your cadence begins."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|This cadence requires an update"
|
||||
msgid "Iterations|This cadence can be converted to use automated scheduling"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|This will delete the cadence as well as all of the iterations within it."
|
||||
|
@ -21576,6 +21570,9 @@ msgstr ""
|
|||
msgid "Iterations|Title"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|To convert this cadence to automatic scheduling, add a duration and number of upcoming iterations. The upgrade is irreversible."
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Unable to find iteration cadence."
|
||||
msgstr ""
|
||||
|
||||
|
@ -21588,6 +21585,9 @@ msgstr ""
|
|||
msgid "Iterations|Upcoming iterations"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iterations|Your manual cadence can be converted to use automated scheduling"
|
||||
msgstr ""
|
||||
|
||||
msgid "Iteration|Dates cannot overlap with other existing Iterations within this group"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ module QA
|
|||
describe 'Project transfer between groups', :reliable do
|
||||
let(:source_group) do
|
||||
Resource::Group.fabricate_via_api! do |group|
|
||||
group.path = 'source-group'
|
||||
group.path = "source-group-#{SecureRandom.hex(8)}"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -13,9 +13,7 @@ import {
|
|||
EDITOR_APP_STATUS_LOADING,
|
||||
EDITOR_APP_STATUS_INVALID,
|
||||
EDITOR_APP_STATUS_VALID,
|
||||
MERGED_TAB,
|
||||
TAB_QUERY_PARAM,
|
||||
TABS_INDEX,
|
||||
} from '~/pipeline_editor/constants';
|
||||
import PipelineGraph from '~/pipelines/components/pipeline_graph/pipeline_graph.vue';
|
||||
import { mockLintResponse, mockLintResponseWithoutMerged, mockCiYml } from '../mock_data';
|
||||
|
@ -221,18 +219,6 @@ describe('Pipeline editor tabs component', () => {
|
|||
search: `?${TAB_QUERY_PARAM}=${queryValue}`,
|
||||
});
|
||||
});
|
||||
|
||||
it('is the tab specified in query param and transform it into an index value', async () => {
|
||||
setWindowLocation(`${gitlabUrl}?${TAB_QUERY_PARAM}=${MERGED_TAB}`);
|
||||
createComponent();
|
||||
|
||||
// If the query param has changed to an index, it means we have synced the
|
||||
// query with.
|
||||
expect(window.location).toMatchObject({
|
||||
...matchObject,
|
||||
search: `?${TAB_QUERY_PARAM}=${TABS_INDEX[MERGED_TAB]}`,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('glTabs', () => {
|
||||
|
|
|
@ -2,6 +2,7 @@ import { shallowMount } from '@vue/test-utils';
|
|||
import { nextTick } from 'vue';
|
||||
import { GlButton, GlDrawer, GlModal } from '@gitlab/ui';
|
||||
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
|
||||
import setWindowLocation from 'helpers/set_window_location_helper';
|
||||
import CiEditorHeader from '~/pipeline_editor/components/editor/ci_editor_header.vue';
|
||||
import CommitSection from '~/pipeline_editor/components/commit/commit_section.vue';
|
||||
import PipelineEditorDrawer from '~/pipeline_editor/components/drawer/pipeline_editor_drawer.vue';
|
||||
|
@ -11,11 +12,12 @@ import BranchSwitcher from '~/pipeline_editor/components/file_nav/branch_switche
|
|||
import PipelineEditorHeader from '~/pipeline_editor/components/header/pipeline_editor_header.vue';
|
||||
import PipelineEditorTabs from '~/pipeline_editor/components/pipeline_editor_tabs.vue';
|
||||
import {
|
||||
MERGED_TAB,
|
||||
VISUALIZE_TAB,
|
||||
CREATE_TAB,
|
||||
LINT_TAB,
|
||||
FILE_TREE_DISPLAY_KEY,
|
||||
LINT_TAB,
|
||||
MERGED_TAB,
|
||||
TABS_INDEX,
|
||||
VISUALIZE_TAB,
|
||||
} from '~/pipeline_editor/constants';
|
||||
import PipelineEditorHome from '~/pipeline_editor/pipeline_editor_home.vue';
|
||||
|
||||
|
@ -162,6 +164,24 @@ describe('Pipeline editor home wrapper', () => {
|
|||
await nextTick();
|
||||
expect(findCommitSection().exists()).toBe(true);
|
||||
});
|
||||
|
||||
describe('rendering with tab params', () => {
|
||||
it.each`
|
||||
tab | shouldShow
|
||||
${MERGED_TAB} | ${false}
|
||||
${VISUALIZE_TAB} | ${false}
|
||||
${LINT_TAB} | ${false}
|
||||
${CREATE_TAB} | ${true}
|
||||
`(
|
||||
'when the tab query param is $tab the commit form is shown: $shouldShow',
|
||||
async ({ tab, shouldShow }) => {
|
||||
setWindowLocation(`https://gitlab.test/ci/editor/?tab=${TABS_INDEX[tab]}`);
|
||||
await createComponent({ stubs: { PipelineEditorTabs } });
|
||||
|
||||
expect(findCommitSection().exists()).toBe(shouldShow);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('WalkthroughPopover events', () => {
|
||||
|
|
|
@ -378,6 +378,31 @@ describe('Linked pipeline', () => {
|
|||
expect(findExpandButton().classes()).toContain(buttonBorderClasses);
|
||||
},
|
||||
);
|
||||
|
||||
describe('shadow border', () => {
|
||||
beforeEach(() => {
|
||||
createWrapper({ propsData: downstreamProps });
|
||||
});
|
||||
|
||||
it.each`
|
||||
activateEventName | deactivateEventName
|
||||
${'mouseover'} | ${'mouseout'}
|
||||
${'focus'} | ${'blur'}
|
||||
`(
|
||||
'applies the class on $activateEventName and removes it on $deactivateEventName ',
|
||||
async ({ activateEventName, deactivateEventName }) => {
|
||||
const shadowClass = 'gl-shadow-none!';
|
||||
|
||||
expect(findExpandButton().classes()).toContain(shadowClass);
|
||||
|
||||
await findExpandButton().vm.$emit(activateEventName);
|
||||
expect(findExpandButton().classes()).not.toContain(shadowClass);
|
||||
|
||||
await findExpandButton().vm.$emit(deactivateEventName);
|
||||
expect(findExpandButton().classes()).toContain(shadowClass);
|
||||
},
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('when isLoading is true', () => {
|
||||
|
|
|
@ -239,6 +239,17 @@ RSpec.describe API::Ci::Jobs do
|
|||
end
|
||||
end
|
||||
|
||||
context 'when non-deployment environment action' do
|
||||
let(:job) do
|
||||
create(:environment, name: 'review', project_id: project.id)
|
||||
create(:ci_build, :artifacts, :stop_review_app, environment: 'review', pipeline: pipeline, user: api_user, status: job_status)
|
||||
end
|
||||
|
||||
it 'includes environment slug' do
|
||||
expect(json_response.dig('environment', 'slug')).to eq('review')
|
||||
end
|
||||
end
|
||||
|
||||
context 'when passing the token as params' do
|
||||
let(:headers) { {} }
|
||||
let(:params) { { job_token: job.token } }
|
||||
|
|
|
@ -38,13 +38,21 @@ RSpec.describe PagesDomains::CreateAcmeOrderService do
|
|||
expect(challenge).to have_received(:request_validation).ordered
|
||||
end
|
||||
|
||||
it 'generates and saves private key' do
|
||||
it 'generates and saves private key: rsa' do
|
||||
stub_feature_flags(pages_lets_encrypt_ecdsa: false)
|
||||
service.execute
|
||||
|
||||
saved_order = PagesDomainAcmeOrder.last
|
||||
expect { OpenSSL::PKey::RSA.new(saved_order.private_key) }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'generates and saves private key: ec' do
|
||||
service.execute
|
||||
|
||||
saved_order = PagesDomainAcmeOrder.last
|
||||
expect { OpenSSL::PKey::EC.new(saved_order.private_key) }.not_to raise_error
|
||||
end
|
||||
|
||||
it 'properly saves order attributes' do
|
||||
service.execute
|
||||
|
||||
|
|
Loading…
Reference in New Issue