Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.rubocop_todo/style/open_struct_use.yml2
-rw-r--r--app/assets/javascripts/access_tokens/graphql/queries/get_projects.query.graphql1
-rw-r--r--app/assets/javascripts/actioncable_link.js2
-rw-r--r--app/assets/javascripts/alert_management/list.js2
-rw-r--r--app/assets/javascripts/alerts_settings/graphql.js12
-rw-r--r--app/assets/javascripts/alerts_settings/graphql/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql1
-rw-r--r--app/assets/javascripts/analytics/usage_trends/graphql/fragments/count.fragment.graphql1
-rw-r--r--app/assets/javascripts/boards/graphql.js9
-rw-r--r--app/assets/javascripts/boards/mount_multiple_boards_switcher.js15
-rw-r--r--app/assets/javascripts/captcha/apollo_captcha_link.js2
-rw-r--r--app/assets/javascripts/clusters/agents/graphql/provider.js17
-rw-r--r--app/assets/javascripts/design_management/graphql.js8
-rw-r--r--app/assets/javascripts/design_management/graphql/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js17
-rw-r--r--app/assets/javascripts/graphql_shared/possibleTypes.json1
-rw-r--r--app/assets/javascripts/issues/list/components/issues_list_app.vue3
-rw-r--r--app/assets/javascripts/issues/list/queries/issue.fragment.graphql3
-rw-r--r--app/assets/javascripts/jobs/components/table/jobs_table_app.vue4
-rw-r--r--app/assets/javascripts/lib/apollo/instrumentation_link.js2
-rw-r--r--app/assets/javascripts/lib/apollo/suppress_network_errors_during_navigation_link.js4
-rw-r--r--app/assets/javascripts/lib/graphql.js96
-rw-r--r--app/assets/javascripts/lib/utils/apollo_startup_js_link.js2
-rw-r--r--app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue3
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/fragmentTypes.json17
-rw-r--r--app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js15
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue14
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js2
-rw-r--r--app/assets/javascripts/pages/projects/learn_gitlab/index/index.js6
-rw-r--r--app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue2
-rw-r--r--app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue4
-rw-r--r--app/assets/javascripts/pipelines/components/jobs/jobs_app.vue3
-rw-r--r--app/assets/javascripts/pipelines/graphql/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/pipelines/pipeline_shared_client.js9
-rw-r--r--app/assets/javascripts/related_issues/components/add_issuable_form.vue12
-rw-r--r--app/assets/javascripts/related_issues/components/related_issues_block.vue19
-rw-r--r--app/assets/javascripts/related_issues/constants.js25
-rw-r--r--app/assets/javascripts/related_issues/index.js1
-rw-r--r--app/assets/javascripts/repository/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/repository/graphql.js9
-rw-r--r--app/assets/javascripts/runner/graphql/get_group_runners.query.graphql2
-rw-r--r--app/assets/javascripts/runner/graphql/get_runner.query.graphql1
-rw-r--r--app/assets/javascripts/runner/graphql/get_runners.query.graphql1
-rw-r--r--app/assets/javascripts/runner/graphql/runner_node.fragment.graphql1
-rw-r--r--app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/confidential/sidebar_confidentiality_widget.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/date/sidebar_date_widget.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue3
-rw-r--r--app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue4
-rw-r--r--app/assets/javascripts/sidebar/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/sidebar/graphql.js12
-rw-r--r--app/assets/javascripts/terraform/index.js2
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql1
-rw-r--r--app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql1
-rw-r--r--app/assets/javascripts/vue_shared/alert_details/index.js2
-rw-r--r--app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue11
-rw-r--r--app/assets/javascripts/vue_shared/issuable/list/components/issuable_list_root.vue6
-rw-r--r--app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue4
-rw-r--r--app/assets/javascripts/work_items/graphql/fragmentTypes.json1
-rw-r--r--app/assets/javascripts/work_items/graphql/provider.js9
-rw-r--r--app/controllers/admin/runners_controller.rb2
-rw-r--r--app/controllers/groups/runners_controller.rb2
-rw-r--r--app/controllers/projects/runners_controller.rb2
-rw-r--r--app/graphql/mutations/ci/runner/delete.rb2
-rw-r--r--app/graphql/mutations/work_items/create.rb8
-rw-r--r--app/services/ci/unregister_runner_service.rb16
-rw-r--r--app/services/work_items/create_service.rb22
-rw-r--r--app/views/doorkeeper/authorized_applications/_delete_form.html.haml2
-rw-r--r--app/views/projects/learn_gitlab/index.html.haml3
-rw-r--r--config/webpack.config.js2
-rw-r--r--config/webpack.vendor.config.js2
-rw-r--r--doc/api/graphql/index.md2
-rw-r--r--doc/api/lint.md2
-rw-r--r--doc/user/project/milestones/burndown_and_burnup_charts.md25
-rw-r--r--doc/user/project/milestones/index.md4
-rw-r--r--lib/api/ci/runner.rb2
-rw-r--r--lib/api/ci/runners.rb2
-rw-r--r--lib/api/lint.rb6
-rw-r--r--lib/gitlab/ci/lint.rb8
-rw-r--r--locale/gitlab.pot21
-rw-r--r--package.json14
-rw-r--r--spec/controllers/admin/runners_controller_spec.rb7
-rw-r--r--spec/controllers/groups/clusters_controller_spec.rb3
-rw-r--r--spec/controllers/groups/runners_controller_spec.rb4
-rw-r--r--spec/controllers/projects/runners_controller_spec.rb4
-rw-r--r--spec/features/projects/clusters_spec.rb3
-rw-r--r--spec/frontend/__helpers__/mock_apollo_helper.js13
-rw-r--r--spec/frontend/__helpers__/test_apollo_link.js5
-rw-r--r--spec/frontend/actioncable_link_spec.js2
-rw-r--r--spec/frontend/admin/users/components/users_table_spec.js1
-rw-r--r--spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js11
-rw-r--r--spec/frontend/alerts_settings/components/mocks/apollo_mock.js6
-rw-r--r--spec/frontend/analytics/usage_trends/apollo_mock_data.js1
-rw-r--r--spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js2
-rw-r--r--spec/frontend/analytics/usage_trends/components/users_chart_spec.js5
-rw-r--r--spec/frontend/analytics/usage_trends/mock_data.js20
-rw-r--r--spec/frontend/boards/board_list_spec.js5
-rw-r--r--spec/frontend/captcha/apollo_captcha_link_spec.js2
-rw-r--r--spec/frontend/clusters/agents/components/show_spec.js15
-rw-r--r--spec/frontend/clusters_list/components/agents_spec.js7
-rw-r--r--spec/frontend/clusters_list/components/install_agent_modal_spec.js3
-rw-r--r--spec/frontend/clusters_list/mocks/apollo.js1
-rw-r--r--spec/frontend/design_management/pages/index_spec.js5
-rw-r--r--spec/frontend/design_management/utils/cache_update_spec.js2
-rw-r--r--spec/frontend/environment.js3
-rw-r--r--spec/frontend/environments/new_environments_app_spec.js6
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js2
-rw-r--r--spec/frontend/import_entities/import_groups/graphql/fixtures.js1
-rw-r--r--spec/frontend/incidents/mocks/incidents.json4
-rw-r--r--spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js25
-rw-r--r--spec/frontend/issuable/related_issues/components/related_issues_block_spec.js29
-rw-r--r--spec/frontend/issues/list/components/issues_list_app_spec.js8
-rw-r--r--spec/frontend/issues/list/mock_data.js5
-rw-r--r--spec/frontend/jobs/components/table/job_table_app_spec.js44
-rw-r--r--spec/frontend/jobs/mock_data.js38
-rw-r--r--spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js2
-rw-r--r--spec/frontend/lib/utils/apollo_startup_js_link_spec.js2
-rw-r--r--spec/frontend/notes/components/comment_form_spec.js1
-rw-r--r--spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js9
-rw-r--r--spec/frontend/packages_and_registries/package_registry/mock_data.js1
-rw-r--r--spec/frontend/packages_and_registries/package_registry/pages/details_spec.js10
-rw-r--r--spec/frontend/packages_and_registries/settings/project/settings/mock_data.js1
-rw-r--r--spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js29
-rw-r--r--spec/frontend/pipeline_editor/components/commit/commit_section_spec.js18
-rw-r--r--spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js46
-rw-r--r--spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js2
-rw-r--r--spec/frontend/pipelines/graph/linked_pipelines_column_spec.js27
-rw-r--r--spec/frontend/repository/components/blob_content_viewer_spec.js2
-rw-r--r--spec/frontend/repository/mock_data.js1
-rw-r--r--spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js2
-rw-r--r--spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js2
-rw-r--r--spec/frontend/runner/admin_runners/admin_runners_app_spec.js5
-rw-r--r--spec/frontend/runner/components/cells/runner_actions_cell_spec.js5
-rw-r--r--spec/frontend/runner/components/registration/registration_dropdown_spec.js2
-rw-r--r--spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js4
-rw-r--r--spec/frontend/runner/components/runner_pause_button_spec.js2
-rw-r--r--spec/frontend/runner/components/runner_update_form_spec.js5
-rw-r--r--spec/frontend/runner/group_runners/group_runners_app_spec.js6
-rw-r--r--spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js17
-rw-r--r--spec/frontend/sidebar/components/mock_data.js2
-rw-r--r--spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js5
-rw-r--r--spec/frontend/sidebar/mock_data.js10
-rw-r--r--spec/frontend/snippets/components/edit_spec.js5
-rw-r--r--spec/frontend/terraform/components/terraform_list_spec.js1
-rw-r--r--spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js4
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js12
-rw-r--r--spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js3
-rw-r--r--spec/frontend/vue_shared/components/user_select_spec.js4
-rw-r--r--spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js14
-rw-r--r--spec/frontend/vue_shared/security_reports/mock_data.js2
-rw-r--r--spec/frontend/work_items/pages/work_item_root_spec.js6
-rw-r--r--spec/graphql/mutations/ci/runner/delete_spec.rb15
-rw-r--r--spec/lib/gitlab/ci/lint_spec.rb26
-rw-r--r--spec/requests/api/ci/runners_spec.rb16
-rw-r--r--spec/requests/api/graphql/mutations/work_items/create_spec.rb12
-rw-r--r--spec/services/ci/unregister_runner_service_spec.rb15
-rw-r--r--spec/services/work_items/create_service_spec.rb56
-rw-r--r--yarn.lock309
159 files changed, 955 insertions, 625 deletions
diff --git a/.rubocop_todo/style/open_struct_use.yml b/.rubocop_todo/style/open_struct_use.yml
index 54ae23d232a..18b1015a6ba 100644
--- a/.rubocop_todo/style/open_struct_use.yml
+++ b/.rubocop_todo/style/open_struct_use.yml
@@ -12,11 +12,9 @@ Style/OpenStructUse:
- lib/gitlab/import_export/after_export_strategies/base_after_export_strategy.rb
- lib/gitlab/testing/request_inspector_middleware.rb
- lib/mattermost/session.rb
- - spec/controllers/groups/clusters_controller_spec.rb
- spec/controllers/projects/clusters_controller_spec.rb
- spec/factories/go_module_versions.rb
- spec/factories/wiki_pages.rb
- - spec/features/projects/clusters_spec.rb
- spec/graphql/mutations/branches/create_spec.rb
- spec/graphql/mutations/clusters/agent_tokens/create_spec.rb
- spec/graphql/mutations/clusters/agents/create_spec.rb
diff --git a/app/assets/javascripts/access_tokens/graphql/queries/get_projects.query.graphql b/app/assets/javascripts/access_tokens/graphql/queries/get_projects.query.graphql
index 09278e1776a..cdc8a952ead 100644
--- a/app/assets/javascripts/access_tokens/graphql/queries/get_projects.query.graphql
+++ b/app/assets/javascripts/access_tokens/graphql/queries/get_projects.query.graphql
@@ -22,6 +22,7 @@ query accessTokensGetProjects(
avatarUrl
}
pageInfo {
+ __typename
...PageInfo
}
}
diff --git a/app/assets/javascripts/actioncable_link.js b/app/assets/javascripts/actioncable_link.js
index 895a34ba157..cf53d9e21b4 100644
--- a/app/assets/javascripts/actioncable_link.js
+++ b/app/assets/javascripts/actioncable_link.js
@@ -1,4 +1,4 @@
-import { ApolloLink, Observable } from 'apollo-link';
+import { ApolloLink, Observable } from '@apollo/client/core';
import { print } from 'graphql';
import cable from '~/actioncable_consumer';
import { uuids } from '~/lib/utils/uuids';
diff --git a/app/assets/javascripts/alert_management/list.js b/app/assets/javascripts/alert_management/list.js
index b23f8a8eba4..42cbeef56bf 100644
--- a/app/assets/javascripts/alert_management/list.js
+++ b/app/assets/javascripts/alert_management/list.js
@@ -1,4 +1,4 @@
-import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import { defaultDataIdFromObject } from '@apollo/client/core';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
diff --git a/app/assets/javascripts/alerts_settings/graphql.js b/app/assets/javascripts/alerts_settings/graphql.js
index b64e2e3eefa..36a98145457 100644
--- a/app/assets/javascripts/alerts_settings/graphql.js
+++ b/app/assets/javascripts/alerts_settings/graphql.js
@@ -1,15 +1,9 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import produce from 'immer';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import introspectionQueryResultData from './graphql/fragmentTypes.json';
import getCurrentIntegrationQuery from './graphql/queries/get_current_integration.query.graphql';
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
-
Vue.use(VueApollo);
const resolvers = {
@@ -55,9 +49,5 @@ const resolvers = {
};
export default new VueApollo({
- defaultClient: createDefaultClient(resolvers, {
- cacheConfig: {
- fragmentMatcher,
- },
- }),
+ defaultClient: createDefaultClient(resolvers),
});
diff --git a/app/assets/javascripts/alerts_settings/graphql/fragmentTypes.json b/app/assets/javascripts/alerts_settings/graphql/fragmentTypes.json
deleted file mode 100644
index 07dfc43aa6c..00000000000
--- a/app/assets/javascripts/alerts_settings/graphql/fragmentTypes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__schema":{"types":[{"kind":"UNION","name":"AlertManagementIntegration","possibleTypes":[{"name":"AlertManagementHttpIntegration"},{"name":"AlertManagementPrometheusIntegration"}]}]}}
diff --git a/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql b/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql
index 3cd3f2d92f8..ac9304391f9 100644
--- a/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql
+++ b/app/assets/javascripts/alerts_settings/graphql/queries/get_integrations.query.graphql
@@ -5,6 +5,7 @@ query getIntegrations($projectPath: ID!) {
id
alertManagementIntegrations {
nodes {
+ __typename
...IntegrationItem
}
}
diff --git a/app/assets/javascripts/analytics/usage_trends/graphql/fragments/count.fragment.graphql b/app/assets/javascripts/analytics/usage_trends/graphql/fragments/count.fragment.graphql
index 2bde5973600..b353bcdfd0e 100644
--- a/app/assets/javascripts/analytics/usage_trends/graphql/fragments/count.fragment.graphql
+++ b/app/assets/javascripts/analytics/usage_trends/graphql/fragments/count.fragment.graphql
@@ -1,4 +1,5 @@
fragment Count on UsageTrendsMeasurement {
+ __typename
count
recordedAt
}
diff --git a/app/assets/javascripts/boards/graphql.js b/app/assets/javascripts/boards/graphql.js
index 64938cb42ed..95863d4d5ac 100644
--- a/app/assets/javascripts/boards/graphql.js
+++ b/app/assets/javascripts/boards/graphql.js
@@ -1,10 +1,5 @@
-import { IntrospectionFragmentMatcher, defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import { defaultDataIdFromObject } from '@apollo/client/core';
import createDefaultClient from '~/lib/graphql';
-import introspectionQueryResultData from '~/sidebar/fragmentTypes.json';
-
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
export const gqlClient = createDefaultClient(
{},
@@ -14,8 +9,6 @@ export const gqlClient = createDefaultClient(
// eslint-disable-next-line no-underscore-dangle
return object.__typename === 'BoardList' ? object.iid : defaultDataIdFromObject(object);
},
-
- fragmentMatcher,
},
},
);
diff --git a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
index ed32579a9c3..26dd8b99f98 100644
--- a/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
+++ b/app/assets/javascripts/boards/mount_multiple_boards_switcher.js
@@ -1,27 +1,14 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import BoardsSelector from 'ee_else_ce/boards/components/boards_selector.vue';
import store from '~/boards/stores';
import createDefaultClient from '~/lib/graphql';
import { parseBoolean } from '~/lib/utils/common_utils';
-import introspectionQueryResultData from '~/sidebar/fragmentTypes.json';
Vue.use(VueApollo);
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
-
const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(
- {},
- {
- cacheConfig: {
- fragmentMatcher,
- },
- },
- ),
+ defaultClient: createDefaultClient(),
});
export default (params = {}) => {
diff --git a/app/assets/javascripts/captcha/apollo_captcha_link.js b/app/assets/javascripts/captcha/apollo_captcha_link.js
index e49abc10b29..d63ffaf5f1a 100644
--- a/app/assets/javascripts/captcha/apollo_captcha_link.js
+++ b/app/assets/javascripts/captcha/apollo_captcha_link.js
@@ -1,4 +1,4 @@
-import { ApolloLink, Observable } from 'apollo-link';
+import { ApolloLink, Observable } from '@apollo/client/core';
export const apolloCaptchaLink = new ApolloLink((operation, forward) =>
forward(operation).flatMap((result) => {
diff --git a/app/assets/javascripts/clusters/agents/graphql/provider.js b/app/assets/javascripts/clusters/agents/graphql/provider.js
index 8b068fa1eee..9153c5252b3 100644
--- a/app/assets/javascripts/clusters/agents/graphql/provider.js
+++ b/app/assets/javascripts/clusters/agents/graphql/provider.js
@@ -1,25 +1,10 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import { vulnerabilityLocationTypes } from '~/graphql_shared/fragment_types/vulnerability_location_types';
Vue.use(VueApollo);
-// We create a fragment matcher so that we can create a fragment from an interface
-// Without this, Apollo throws a heuristic fragment matcher warning
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData: vulnerabilityLocationTypes,
-});
-
-const defaultClient = createDefaultClient(
- {},
- {
- cacheConfig: {
- fragmentMatcher,
- },
- },
-);
+const defaultClient = createDefaultClient();
export default new VueApollo({
defaultClient,
diff --git a/app/assets/javascripts/design_management/graphql.js b/app/assets/javascripts/design_management/graphql.js
index 5cf32cb7fe3..8c44c5a5d0a 100644
--- a/app/assets/javascripts/design_management/graphql.js
+++ b/app/assets/javascripts/design_management/graphql.js
@@ -1,11 +1,10 @@
-import { defaultDataIdFromObject, IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
+import { defaultDataIdFromObject } from '@apollo/client/core';
import produce from 'immer';
import { uniqueId } from 'lodash';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import axios from '~/lib/utils/axios_utils';
-import introspectionQueryResultData from './graphql/fragmentTypes.json';
import activeDiscussionQuery from './graphql/queries/active_discussion.query.graphql';
import getDesignQuery from './graphql/queries/get_design.query.graphql';
import typeDefs from './graphql/typedefs.graphql';
@@ -13,10 +12,6 @@ import { addPendingTodoToStore } from './utils/cache_update';
import { extractTodoIdFromDeletePath, createPendingTodo } from './utils/design_management_utils';
import { CREATE_DESIGN_TODO_EXISTS_ERROR } from './utils/error_messages';
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
-
Vue.use(VueApollo);
const resolvers = {
@@ -85,7 +80,6 @@ const defaultClient = createDefaultClient(
}
return defaultDataIdFromObject(object);
},
- fragmentMatcher,
},
typeDefs,
},
diff --git a/app/assets/javascripts/design_management/graphql/fragmentTypes.json b/app/assets/javascripts/design_management/graphql/fragmentTypes.json
deleted file mode 100644
index 0953231ea4c..00000000000
--- a/app/assets/javascripts/design_management/graphql/fragmentTypes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__schema":{"types":[{"kind":"INTERFACE","name":"User","possibleTypes":[{"name":"UserCore"}]},{"kind":"UNION","name":"NoteableType","possibleTypes":[{"name":"Design"},{"name":"Issue"},{"name":"MergeRequest"}]}]}}
diff --git a/app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js b/app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js
deleted file mode 100644
index 30888e20a46..00000000000
--- a/app/assets/javascripts/graphql_shared/fragment_types/vulnerability_location_types.js
+++ /dev/null
@@ -1,17 +0,0 @@
-export const vulnerabilityLocationTypes = {
- __schema: {
- types: [
- {
- kind: 'UNION',
- name: 'VulnerabilityLocation',
- possibleTypes: [
- { name: 'VulnerabilityLocationContainerScanning' },
- { name: 'VulnerabilityLocationDast' },
- { name: 'VulnerabilityLocationDependencyScanning' },
- { name: 'VulnerabilityLocationSast' },
- { name: 'VulnerabilityLocationSecretDetection' },
- ],
- },
- ],
- },
-};
diff --git a/app/assets/javascripts/graphql_shared/possibleTypes.json b/app/assets/javascripts/graphql_shared/possibleTypes.json
new file mode 100644
index 00000000000..9a24d2a3afc
--- /dev/null
+++ b/app/assets/javascripts/graphql_shared/possibleTypes.json
@@ -0,0 +1 @@
+{"AlertManagementIntegration":["AlertManagementHttpIntegration","AlertManagementPrometheusIntegration"],"CurrentUserTodos":["BoardEpic","Design","Epic","EpicIssue","Issue","MergeRequest"],"DependencyLinkMetadata":["NugetDependencyLinkMetadata"],"DesignFields":["Design","DesignAtVersion"],"Entry":["Blob","Submodule","TreeEntry"],"Eventable":["BoardEpic","Epic"],"Issuable":["Epic","Issue","MergeRequest"],"JobNeedUnion":["CiBuildNeed","CiJob"],"MemberInterface":["GroupMember","ProjectMember"],"NoteableInterface":["AlertManagementAlert","BoardEpic","Design","Epic","EpicIssue","Issue","MergeRequest","Snippet","Vulnerability"],"NoteableType":["Design","Issue","MergeRequest"],"OrchestrationPolicy":["ScanExecutionPolicy","ScanResultPolicy"],"PackageFileMetadata":["ConanFileMetadata","HelmFileMetadata"],"PackageMetadata":["ComposerMetadata","ConanMetadata","MavenMetadata","NugetMetadata","PypiMetadata"],"ResolvableInterface":["Discussion","Note"],"Service":["BaseService","JiraService"],"TimeboxReportInterface":["Iteration","Milestone"],"User":["MergeRequestAssignee","MergeRequestReviewer","UserCore"],"VulnerabilityDetail":["VulnerabilityDetailBase","VulnerabilityDetailBoolean","VulnerabilityDetailCode","VulnerabilityDetailCommit","VulnerabilityDetailDiff","VulnerabilityDetailFileLocation","VulnerabilityDetailInt","VulnerabilityDetailList","VulnerabilityDetailMarkdown","VulnerabilityDetailModuleLocation","VulnerabilityDetailTable","VulnerabilityDetailText","VulnerabilityDetailUrl"],"VulnerabilityLocation":["VulnerabilityLocationClusterImageScanning","VulnerabilityLocationContainerScanning","VulnerabilityLocationCoverageFuzzing","VulnerabilityLocationDast","VulnerabilityLocationDependencyScanning","VulnerabilityLocationGeneric","VulnerabilityLocationSast","VulnerabilityLocationSecretDetection"]}
diff --git a/app/assets/javascripts/issues/list/components/issues_list_app.vue b/app/assets/javascripts/issues/list/components/issues_list_app.vue
index a2bb6c3cd77..3866a7b3305 100644
--- a/app/assets/javascripts/issues/list/components/issues_list_app.vue
+++ b/app/assets/javascripts/issues/list/components/issues_list_app.vue
@@ -181,6 +181,9 @@ export default {
return data[this.namespace]?.issues.nodes ?? [];
},
result({ data }) {
+ if (!data) {
+ return;
+ }
this.pageInfo = data[this.namespace]?.issues.pageInfo ?? {};
this.exportCsvPathWithQuery = this.getExportCsvPathWithQuery();
},
diff --git a/app/assets/javascripts/issues/list/queries/issue.fragment.graphql b/app/assets/javascripts/issues/list/queries/issue.fragment.graphql
index 07dae3fd756..430d494deab 100644
--- a/app/assets/javascripts/issues/list/queries/issue.fragment.graphql
+++ b/app/assets/javascripts/issues/list/queries/issue.fragment.graphql
@@ -1,4 +1,5 @@
fragment IssueFragment on Issue {
+ __typename
id
iid
closedAt
@@ -18,6 +19,7 @@ fragment IssueFragment on Issue {
webUrl
assignees {
nodes {
+ __typename
id
avatarUrl
name
@@ -26,6 +28,7 @@ fragment IssueFragment on Issue {
}
}
author {
+ __typename
id
avatarUrl
name
diff --git a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
index c786d35ac68..81f42c1e293 100644
--- a/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
+++ b/app/assets/javascripts/jobs/components/table/jobs_table_app.vue
@@ -51,7 +51,9 @@ export default {
},
data() {
return {
- jobs: {},
+ jobs: {
+ list: [],
+ },
hasError: false,
isAlertDismissed: false,
scope: null,
diff --git a/app/assets/javascripts/lib/apollo/instrumentation_link.js b/app/assets/javascripts/lib/apollo/instrumentation_link.js
index 2ab364557b8..bbe16d260e7 100644
--- a/app/assets/javascripts/lib/apollo/instrumentation_link.js
+++ b/app/assets/javascripts/lib/apollo/instrumentation_link.js
@@ -1,4 +1,4 @@
-import { ApolloLink } from 'apollo-link';
+import { ApolloLink } from '@apollo/client/core';
import { memoize } from 'lodash';
export const FEATURE_CATEGORY_HEADER = 'x-gitlab-feature-category';
diff --git a/app/assets/javascripts/lib/apollo/suppress_network_errors_during_navigation_link.js b/app/assets/javascripts/lib/apollo/suppress_network_errors_during_navigation_link.js
index 9b7901685b6..b2a86ac257b 100644
--- a/app/assets/javascripts/lib/apollo/suppress_network_errors_during_navigation_link.js
+++ b/app/assets/javascripts/lib/apollo/suppress_network_errors_during_navigation_link.js
@@ -1,5 +1,5 @@
-import { Observable } from 'apollo-link';
-import { onError } from 'apollo-link-error';
+import { Observable } from '@apollo/client/core';
+import { onError } from '@apollo/client/link/error';
import { isNavigatingAway } from '~/lib/utils/is_navigating_away';
/**
diff --git a/app/assets/javascripts/lib/graphql.js b/app/assets/javascripts/lib/graphql.js
index df2e85afe24..0fb7bf52562 100644
--- a/app/assets/javascripts/lib/graphql.js
+++ b/app/assets/javascripts/lib/graphql.js
@@ -1,11 +1,9 @@
-import { InMemoryCache } from 'apollo-cache-inmemory';
-import { ApolloClient } from 'apollo-client';
-import { ApolloLink } from 'apollo-link';
-import { BatchHttpLink } from 'apollo-link-batch-http';
-import { HttpLink } from 'apollo-link-http';
+import { ApolloClient, InMemoryCache, ApolloLink, HttpLink } from '@apollo/client/core';
+import { BatchHttpLink } from '@apollo/client/link/batch-http';
import { createUploadLink } from 'apollo-upload-client';
import ActionCableLink from '~/actioncable_link';
import { apolloCaptchaLink } from '~/captcha/apollo_captcha_link';
+import possibleTypes from '~/graphql_shared/possibleTypes.json';
import { StartupJSLink } from '~/lib/utils/apollo_startup_js_link';
import csrf from '~/lib/utils/csrf';
import { objectToQuery, queryToObject } from '~/lib/utils/url_utility';
@@ -21,6 +19,33 @@ export const fetchPolicies = {
CACHE_ONLY: 'cache-only',
};
+export const typePolicies = {
+ Repository: {
+ merge: true,
+ },
+ UserPermissions: {
+ merge: true,
+ },
+ MergeRequestPermissions: {
+ merge: true,
+ },
+ ContainerRepositoryConnection: {
+ merge: true,
+ },
+ TimelogConnection: {
+ merge: true,
+ },
+ BranchList: {
+ merge: true,
+ },
+ InstanceSecurityDashboard: {
+ merge: true,
+ },
+ PipelinePermissions: {
+ merge: true,
+ },
+};
+
export const stripWhitespaceFromQuery = (url, path) => {
/* eslint-disable-next-line no-unused-vars */
const [_, params] = url.split(path);
@@ -46,6 +71,30 @@ export const stripWhitespaceFromQuery = (url, path) => {
return `${path}?${reassembled}`;
};
+const acs = [];
+
+let pendingApolloMutations = 0;
+
+// ### Why track pendingApolloMutations, but calculate pendingApolloRequests?
+//
+// In Apollo 2, we had a single link for counting operations.
+//
+// With Apollo 3, the `forward().map(...)` of deduped queries is never called.
+// So, we resorted to calculating the sum of `inFlightLinkObservables?.size`.
+// However! Mutations don't use `inFLightLinkObservables`, but since they are likely
+// not deduped we can count them...
+//
+// https://gitlab.com/gitlab-org/gitlab/-/merge_requests/55062#note_838943715
+// https://www.apollographql.com/docs/react/v2/networking/network-layer/#query-deduplication
+Object.defineProperty(window, 'pendingApolloRequests', {
+ get() {
+ return acs.reduce(
+ (sum, ac) => sum + (ac?.queryManager?.inFlightLinkObservables?.size || 0),
+ pendingApolloMutations,
+ );
+ },
+});
+
export default (resolvers = {}, config = {}) => {
const {
baseUrl,
@@ -56,6 +105,7 @@ export default (resolvers = {}, config = {}) => {
path = '/api/graphql',
useGet = false,
} = config;
+ let ac = null;
let uri = `${gon.relative_url_root || ''}${path}`;
if (baseUrl) {
@@ -75,16 +125,6 @@ export default (resolvers = {}, config = {}) => {
batchMax,
};
- const requestCounterLink = new ApolloLink((operation, forward) => {
- window.pendingApolloRequests = window.pendingApolloRequests || 0;
- window.pendingApolloRequests += 1;
-
- return forward(operation).map((response) => {
- window.pendingApolloRequests -= 1;
- return response;
- });
- });
-
/*
This custom fetcher intervention is to deal with an issue where we are using GET to access
eTag polling, but Apollo Client adds excessive whitespace, which causes the
@@ -138,6 +178,22 @@ export default (resolvers = {}, config = {}) => {
);
};
+ const hasMutation = (operation) =>
+ (operation?.query?.definitions || []).some((x) => x.operation === 'mutation');
+
+ const requestCounterLink = new ApolloLink((operation, forward) => {
+ if (hasMutation(operation)) {
+ pendingApolloMutations += 1;
+ }
+
+ return forward(operation).map((response) => {
+ if (hasMutation(operation)) {
+ pendingApolloMutations -= 1;
+ }
+ return response;
+ });
+ });
+
const appLink = ApolloLink.split(
hasSubscriptionOperation,
new ActionCableLink(),
@@ -155,19 +211,23 @@ export default (resolvers = {}, config = {}) => {
),
);
- return new ApolloClient({
+ ac = new ApolloClient({
typeDefs,
link: appLink,
cache: new InMemoryCache({
+ typePolicies,
+ possibleTypes,
...cacheConfig,
- freezeResults: true,
}),
resolvers,
- assumeImmutableResults: true,
defaultOptions: {
query: {
fetchPolicy,
},
},
});
+
+ acs.push(ac);
+
+ return ac;
};
diff --git a/app/assets/javascripts/lib/utils/apollo_startup_js_link.js b/app/assets/javascripts/lib/utils/apollo_startup_js_link.js
index 014823f3831..f240226e991 100644
--- a/app/assets/javascripts/lib/utils/apollo_startup_js_link.js
+++ b/app/assets/javascripts/lib/utils/apollo_startup_js_link.js
@@ -1,4 +1,4 @@
-import { ApolloLink, Observable } from 'apollo-link';
+import { ApolloLink, Observable } from '@apollo/client/core';
import { parse } from 'graphql';
import { isEqual, pickBy } from 'lodash';
diff --git a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
index ad3a3596991..e2acebf39d6 100644
--- a/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
+++ b/app/assets/javascripts/packages_and_registries/container_registry/explorer/pages/list.vue
@@ -96,6 +96,9 @@ export default {
return data[this.graphqlResource]?.containerRepositories.nodes;
},
result({ data }) {
+ if (!data) {
+ return;
+ }
this.pageInfo = data[this.graphqlResource]?.containerRepositories?.pageInfo;
this.containerRepositoriesCount = data[this.graphqlResource]?.containerRepositoriesCount;
},
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/fragmentTypes.json b/app/assets/javascripts/packages_and_registries/package_registry/graphql/fragmentTypes.json
deleted file mode 100644
index c61a653d10b..00000000000
--- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/fragmentTypes.json
+++ /dev/null
@@ -1,17 +0,0 @@
-{
- "__schema": {
- "types": [
- {
- "kind": "UNION",
- "name": "PackageMetadata",
- "possibleTypes": [
- { "name": "ComposerMetadata" },
- { "name": "ConanMetadata" },
- { "name": "MavenMetadata" },
- { "name": "NugetMetadata" },
- { "name": "PypiMetadata" }
- ]
- }
- ]
- }
-}
diff --git a/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js b/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js
index 21d6fbc9e1f..56f95fa2c1f 100644
--- a/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js
+++ b/app/assets/javascripts/packages_and_registries/package_registry/graphql/index.js
@@ -1,22 +1,9 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
-import introspectionQueryResultData from './fragmentTypes.json';
-
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
Vue.use(VueApollo);
export const apolloProvider = new VueApollo({
- defaultClient: createDefaultClient(
- {},
- {
- cacheConfig: {
- fragmentMatcher,
- },
- },
- ),
+ defaultClient: createDefaultClient(),
});
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
index 42c40cda601..d50945e0be2 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/components/learn_gitlab.vue
@@ -2,7 +2,8 @@
import { GlProgressBar, GlSprintf, GlAlert } from '@gitlab/ui';
import eventHub from '~/invite_members/event_hub';
import { s__ } from '~/locale';
-import { ACTION_LABELS, ACTION_SECTIONS } from '../constants';
+import { getCookie, removeCookie, parseBoolean } from '~/lib/utils/common_utils';
+import { ACTION_LABELS, ACTION_SECTIONS, INVITE_MODAL_OPEN_COOKIE } from '../constants';
import LearnGitlabSectionCard from './learn_gitlab_section_card.vue';
export default {
@@ -26,7 +27,7 @@ export default {
required: true,
type: Object,
},
- inviteMembersOpen: {
+ inviteMembers: {
type: Boolean,
required: false,
default: false,
@@ -53,7 +54,7 @@ export default {
},
},
mounted() {
- if (this.inviteMembersOpen) {
+ if (this.inviteMembers && this.getCookieForInviteMembers()) {
this.openInviteMembersModal('celebrate');
}
@@ -63,6 +64,13 @@ export default {
eventHub.$off('showSuccessfulInvitationsAlert', this.handleShowSuccessfulInvitationsAlert);
},
methods: {
+ getCookieForInviteMembers() {
+ const value = parseBoolean(getCookie(INVITE_MODAL_OPEN_COOKIE));
+
+ removeCookie(INVITE_MODAL_OPEN_COOKIE);
+
+ return value;
+ },
openInviteMembersModal(mode) {
eventHub.$emit('openModal', { mode, inviteeType: 'members', source: 'learn-gitlab' });
},
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
index 8a88ad299b4..880cf699e5e 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/constants/index.js
@@ -95,3 +95,5 @@ export const ACTION_SECTIONS = {
),
},
};
+
+export const INVITE_MODAL_OPEN_COOKIE = 'confetti_post_signup';
diff --git a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
index 1f91cc46946..c62cab1a425 100644
--- a/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
+++ b/app/assets/javascripts/pages/projects/learn_gitlab/index/index.js
@@ -1,6 +1,6 @@
import Vue from 'vue';
import initInviteMembersModal from '~/invite_members/init_invite_members_modal';
-import { convertObjectPropsToCamelCase } from '~/lib/utils/common_utils';
+import { convertObjectPropsToCamelCase, parseBoolean } from '~/lib/utils/common_utils';
import LearnGitlab from '../components/learn_gitlab.vue';
function initLearnGitlab() {
@@ -13,13 +13,13 @@ function initLearnGitlab() {
const actions = convertObjectPropsToCamelCase(JSON.parse(el.dataset.actions));
const sections = convertObjectPropsToCamelCase(JSON.parse(el.dataset.sections));
const project = convertObjectPropsToCamelCase(JSON.parse(el.dataset.project));
- const { inviteMembersOpen } = el.dataset;
+ const { inviteMembers } = el.dataset;
return new Vue({
el,
render(createElement) {
return createElement(LearnGitlab, {
- props: { actions, sections, project, inviteMembersOpen },
+ props: { actions, sections, project, inviteMembers: parseBoolean(inviteMembers) },
});
},
});
diff --git a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
index 72b492a5877..4b9c98135ec 100644
--- a/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
+++ b/app/assets/javascripts/pipeline_editor/components/header/pipeline_status.vue
@@ -49,7 +49,7 @@ export default {
pipelineEtag: {
query: getPipelineEtag,
update(data) {
- return data.etags.pipeline;
+ return data.etags?.pipeline;
},
},
pipeline: {
diff --git a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
index 604f87a0cda..1da50c55a68 100644
--- a/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
+++ b/app/assets/javascripts/pipeline_editor/pipeline_editor_app.vue
@@ -196,7 +196,7 @@ export default {
currentBranch: {
query: getCurrentBranch,
update(data) {
- return data.workBranches.current.name;
+ return data.workBranches?.current?.name;
},
},
starterTemplate: {
@@ -214,7 +214,7 @@ export default {
return data.project?.ciTemplate?.content || '';
},
result({ data }) {
- this.updateCiConfig(data.project?.ciTemplate?.content || '');
+ this.updateCiConfig(data?.project?.ciTemplate?.content || '');
},
error() {
this.reportFailure(LOAD_FAILURE_UNKNOWN);
diff --git a/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue b/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
index 6f35cdac641..99fb5c146ba 100644
--- a/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
+++ b/app/assets/javascripts/pipelines/components/jobs/jobs_app.vue
@@ -36,6 +36,9 @@ export default {
return data.project?.pipeline?.jobs?.nodes || [];
},
result({ data }) {
+ if (!data) {
+ return;
+ }
this.jobsPageInfo = data.project?.pipeline?.jobs?.pageInfo || {};
},
error() {
diff --git a/app/assets/javascripts/pipelines/graphql/fragmentTypes.json b/app/assets/javascripts/pipelines/graphql/fragmentTypes.json
deleted file mode 100644
index 4601b74b5c1..00000000000
--- a/app/assets/javascripts/pipelines/graphql/fragmentTypes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__schema":{"types":[{"kind":"UNION","name":"JobNeedUnion","possibleTypes":[{"name":"CiBuildNeed"},{"name":"CiJob"}]}]}} \ No newline at end of file
diff --git a/app/assets/javascripts/pipelines/pipeline_shared_client.js b/app/assets/javascripts/pipelines/pipeline_shared_client.js
index 84276588d6a..c3be487caae 100644
--- a/app/assets/javascripts/pipelines/pipeline_shared_client.js
+++ b/app/assets/javascripts/pipelines/pipeline_shared_client.js
@@ -1,19 +1,10 @@
import VueApollo from 'vue-apollo';
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import createDefaultClient from '~/lib/graphql';
-import introspectionQueryResultData from './graphql/fragmentTypes.json';
-
-export const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
export const apolloProvider = new VueApollo({
defaultClient: createDefaultClient(
{},
{
- cacheConfig: {
- fragmentMatcher,
- },
useGet: true,
},
),
diff --git a/app/assets/javascripts/related_issues/components/add_issuable_form.vue b/app/assets/javascripts/related_issues/components/add_issuable_form.vue
index f936c03c5d3..9ee2e7a4ffd 100644
--- a/app/assets/javascripts/related_issues/components/add_issuable_form.vue
+++ b/app/assets/javascripts/related_issues/components/add_issuable_form.vue
@@ -9,6 +9,8 @@ import {
linkedIssueTypesMap,
addRelatedIssueErrorMap,
addRelatedItemErrorMap,
+ issuablesFormCategoryHeaderTextMap,
+ issuablesFormInputTextMap,
} from '../constants';
import RelatedIssuableInput from './related_issuable_input.vue';
@@ -134,6 +136,12 @@ export default {
epics: mergeUrlParams({ confidential_only: true }, this.autoCompleteSources.epics),
};
},
+ issuableCategoryHeaderText() {
+ return issuablesFormCategoryHeaderTextMap[this.issuableType];
+ },
+ issuableInputText() {
+ return issuablesFormInputTextMap[this.issuableType];
+ },
},
methods: {
onPendingIssuableRemoveRequest(params) {
@@ -162,7 +170,7 @@ export default {
<form @submit.prevent="onFormSubmit">
<template v-if="showCategorizedIssues">
<gl-form-group
- :label="__('The current issue')"
+ :label="issuableCategoryHeaderText"
label-for="linked-issue-type-radio"
label-class="label-bold"
class="mb-2"
@@ -175,7 +183,7 @@ export default {
/>
</gl-form-group>
<p class="bold">
- {{ __('the following issue(s)') }}
+ {{ issuableInputText }}
</p>
</template>
<related-issuable-input
diff --git a/app/assets/javascripts/related_issues/components/related_issues_block.vue b/app/assets/javascripts/related_issues/components/related_issues_block.vue
index 94535e1b8c9..bc97fab9ad2 100644
--- a/app/assets/javascripts/related_issues/components/related_issues_block.vue
+++ b/app/assets/javascripts/related_issues/components/related_issues_block.vue
@@ -5,6 +5,9 @@ import {
issuableQaClassMap,
linkedIssueTypesMap,
linkedIssueTypesTextMap,
+ issuablesBlockHeaderTextMap,
+ issuablesBlockHelpTextMap,
+ issuablesBlockAddButtonTextMap,
} from '../constants';
import AddIssuableForm from './add_issuable_form.vue';
import RelatedIssuesList from './related_issues_list.vue';
@@ -105,6 +108,15 @@ export default {
hasBody() {
return this.isFormVisible || this.shouldShowTokenBody;
},
+ headerText() {
+ return issuablesBlockHeaderTextMap[this.issuableType];
+ },
+ helpLinkText() {
+ return issuablesBlockHelpTextMap[this.issuableType];
+ },
+ addIssuableButtonText() {
+ return issuablesBlockAddButtonTextMap[this.issuableType];
+ },
badgeLabel() {
return this.isFetching && this.relatedIssues.length === 0 ? '...' : this.relatedIssues.length;
},
@@ -138,13 +150,14 @@ export default {
href="#related-issues"
aria-hidden="true"
/>
- <slot name="header-text">{{ __('Linked issues') }}</slot>
+ <slot name="header-text">{{ headerText }}</slot>
<gl-link
v-if="hasHelpPath"
:href="helpPath"
target="_blank"
class="gl-display-flex gl-align-items-center gl-ml-2 gl-text-gray-500"
- :aria-label="__('Read more about related issues')"
+ data-testid="help-link"
+ :aria-label="helpLinkText"
>
<gl-icon name="question" :size="12" />
</gl-link>
@@ -160,7 +173,7 @@ export default {
v-if="canAdmin"
data-qa-selector="related_issues_plus_button"
icon="plus"
- :aria-label="__('Add a related issue')"
+ :aria-label="addIssuableButtonText"
:class="qaClass"
@click="$emit('toggleAddRelatedIssuesForm', $event)"
/>
diff --git a/app/assets/javascripts/related_issues/constants.js b/app/assets/javascripts/related_issues/constants.js
index 89eae069a24..f911468d8f1 100644
--- a/app/assets/javascripts/related_issues/constants.js
+++ b/app/assets/javascripts/related_issues/constants.js
@@ -104,3 +104,28 @@ export const PathIdSeparator = {
Epic: '&',
Issue: '#',
};
+
+export const issuablesBlockHeaderTextMap = {
+ [issuableTypesMap.ISSUE]: __('Linked issues'),
+ [issuableTypesMap.EPIC]: __('Linked epics'),
+};
+
+export const issuablesBlockHelpTextMap = {
+ [issuableTypesMap.ISSUE]: __('Read more about related issues'),
+ [issuableTypesMap.EPIC]: __('Read more about related epics'),
+};
+
+export const issuablesBlockAddButtonTextMap = {
+ [issuableTypesMap.ISSUE]: __('Add a related issue'),
+ [issuableTypesMap.EPIC]: __('Add a related epic'),
+};
+
+export const issuablesFormCategoryHeaderTextMap = {
+ [issuableTypesMap.ISSUE]: __('The current issue'),
+ [issuableTypesMap.EPIC]: __('The current epic'),
+};
+
+export const issuablesFormInputTextMap = {
+ [issuableTypesMap.ISSUE]: __('the following issue(s)'),
+ [issuableTypesMap.EPIC]: __('the following epic(s)'),
+};
diff --git a/app/assets/javascripts/related_issues/index.js b/app/assets/javascripts/related_issues/index.js
index 0ee99df1455..bd9845e616b 100644
--- a/app/assets/javascripts/related_issues/index.js
+++ b/app/assets/javascripts/related_issues/index.js
@@ -8,6 +8,7 @@ export default function initRelatedIssues() {
// eslint-disable-next-line no-new
new Vue({
el: relatedIssuesRootElement,
+ name: 'RelatedIssuesApp',
components: {
relatedIssuesRoot: RelatedIssuesRoot,
},
diff --git a/app/assets/javascripts/repository/fragmentTypes.json b/app/assets/javascripts/repository/fragmentTypes.json
deleted file mode 100644
index 949ebca432b..00000000000
--- a/app/assets/javascripts/repository/fragmentTypes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__schema":{"types":[{"kind":"INTERFACE","name":"Entry","possibleTypes":[{"name":"Blob"},{"name":"Submodule"},{"name":"TreeEntry"}]}]}}
diff --git a/app/assets/javascripts/repository/graphql.js b/app/assets/javascripts/repository/graphql.js
index 96d712ce9b4..29aabe1b00f 100644
--- a/app/assets/javascripts/repository/graphql.js
+++ b/app/assets/javascripts/repository/graphql.js
@@ -1,19 +1,11 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
import axios from '~/lib/utils/axios_utils';
-import introspectionQueryResultData from './fragmentTypes.json';
import { fetchLogsTree } from './log_tree';
Vue.use(VueApollo);
-// We create a fragment matcher so that we can create a fragment from an interface
-// Without this, Apollo throws a heuristic fragment matcher warning
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
-
const defaultClient = createDefaultClient(
{
Query: {
@@ -43,7 +35,6 @@ const defaultClient = createDefaultClient(
},
{
cacheConfig: {
- fragmentMatcher,
dataIdFromObject: (obj) => {
/* eslint-disable @gitlab/require-i18n-strings */
// eslint-disable-next-line no-underscore-dangle
diff --git a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
index f7bcd683718..986dd16b992 100644
--- a/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_group_runners.query.graphql
@@ -28,10 +28,12 @@ query getGroupRunners(
edges {
webUrl
node {
+ __typename
...RunnerNode
}
}
pageInfo {
+ __typename
...PageInfo
}
}
diff --git a/app/assets/javascripts/runner/graphql/get_runner.query.graphql b/app/assets/javascripts/runner/graphql/get_runner.query.graphql
index 59c55eae060..f6ce8281c64 100644
--- a/app/assets/javascripts/runner/graphql/get_runner.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_runner.query.graphql
@@ -4,6 +4,7 @@ query getRunner($id: CiRunnerID!) {
# We have an id in deeply nested fragment
# eslint-disable-next-line @graphql-eslint/require-id-when-available
runner(id: $id) {
+ __typename
...RunnerDetails
}
}
diff --git a/app/assets/javascripts/runner/graphql/get_runners.query.graphql b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
index 05df399fa6a..ed03a8c34ae 100644
--- a/app/assets/javascripts/runner/graphql/get_runners.query.graphql
+++ b/app/assets/javascripts/runner/graphql/get_runners.query.graphql
@@ -29,6 +29,7 @@ query getRunners(
editAdminUrl
}
pageInfo {
+ __typename
...PageInfo
}
}
diff --git a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql b/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
index 4a771d779dc..fbdef817f2f 100644
--- a/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
+++ b/app/assets/javascripts/runner/graphql/runner_node.fragment.graphql
@@ -1,4 +1,5 @@
fragment RunnerNode on CiRunner {
+ __typename
id
description
runnerType
diff --git a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
index 5b4dc20e9c8..18654b73ab3 100644
--- a/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
+++ b/app/assets/javascripts/sidebar/components/assignees/sidebar_assignees_widget.vue
@@ -96,6 +96,9 @@ export default {
return data.workspace?.issuable;
},
result({ data }) {
+ if (!data) {
+ return;
+ }
const issuable = data.workspace?.issuable;
if (issuable) {
this.selected = cloneDeep(issuable.assignees.nodes);
diff --git a/app/assets/javascripts/sidebar/components/confidential/sidebar_confidentiality_widget.vue b/app/assets/javascripts/sidebar/components/confidential/sidebar_confidentiality_widget.vue
index dc0f2b54a7b..f234c5ea3c9 100644
--- a/app/assets/javascripts/sidebar/components/confidential/sidebar_confidentiality_widget.vue
+++ b/app/assets/javascripts/sidebar/components/confidential/sidebar_confidentiality_widget.vue
@@ -66,6 +66,9 @@ export default {
return data.workspace?.issuable?.confidential || false;
},
result({ data }) {
+ if (!data) {
+ return;
+ }
this.$emit('confidentialityUpdated', data.workspace?.issuable?.confidential);
},
error() {
diff --git a/app/assets/javascripts/sidebar/components/date/sidebar_date_widget.vue b/app/assets/javascripts/sidebar/components/date/sidebar_date_widget.vue
index 404bcc3122a..be7a89c2869 100644
--- a/app/assets/javascripts/sidebar/components/date/sidebar_date_widget.vue
+++ b/app/assets/javascripts/sidebar/components/date/sidebar_date_widget.vue
@@ -86,6 +86,9 @@ export default {
return data.workspace?.issuable || {};
},
result({ data }) {
+ if (!data) {
+ return;
+ }
this.$emit(`${this.dateType}Updated`, data.workspace?.issuable?.[this.dateType]);
},
error() {
diff --git a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue
index 701833c4e95..7a10a9f3a4c 100644
--- a/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue
+++ b/app/assets/javascripts/sidebar/components/subscriptions/sidebar_subscriptions_widget.vue
@@ -61,6 +61,9 @@ export default {
return data.workspace?.issuable?.subscribed || false;
},
result({ data }) {
+ if (!data) {
+ return;
+ }
this.emailsDisabled = this.parentIsGroup
? data.workspace?.emailsDisabled
: data.workspace?.issuable?.emailsDisabled;
diff --git a/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue b/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
index 8c56c3cbd57..eabba619af5 100644
--- a/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
+++ b/app/assets/javascripts/sidebar/components/todo_toggle/sidebar_todo_widget.vue
@@ -59,6 +59,10 @@ export default {
return data.workspace?.issuable?.currentUserTodos.nodes[0]?.id;
},
result({ data }) {
+ if (!data) {
+ return;
+ }
+
const currentUserTodos = data.workspace?.issuable?.currentUserTodos?.nodes ?? [];
this.todoId = currentUserTodos[0]?.id;
this.$emit('todoUpdated', currentUserTodos.length > 0);
diff --git a/app/assets/javascripts/sidebar/fragmentTypes.json b/app/assets/javascripts/sidebar/fragmentTypes.json
deleted file mode 100644
index a1c68bba454..00000000000
--- a/app/assets/javascripts/sidebar/fragmentTypes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__schema":{"types":[{"kind":"UNION","name":"Issuable","possibleTypes":[{"name":"Issue"},{"name":"MergeRequest"}]}, {"kind":"INTERFACE","name":"User","possibleTypes":[{"name":"UserCore"}]}]}}
diff --git a/app/assets/javascripts/sidebar/graphql.js b/app/assets/javascripts/sidebar/graphql.js
index c5d94cfa5e8..fc757922f09 100644
--- a/app/assets/javascripts/sidebar/graphql.js
+++ b/app/assets/javascripts/sidebar/graphql.js
@@ -1,14 +1,8 @@
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import produce from 'immer';
import VueApollo from 'vue-apollo';
import getIssueStateQuery from '~/issues/show/queries/get_issue_state.query.graphql';
import { resolvers as workItemResolvers } from '~/work_items/graphql/resolvers';
import createDefaultClient from '~/lib/graphql';
-import introspectionQueryResultData from './fragmentTypes.json';
-
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
const resolvers = {
...workItemResolvers,
@@ -24,11 +18,7 @@ const resolvers = {
},
};
-export const defaultClient = createDefaultClient(resolvers, {
- cacheConfig: {
- fragmentMatcher,
- },
-});
+export const defaultClient = createDefaultClient(resolvers);
export const apolloProvider = new VueApollo({
defaultClient,
diff --git a/app/assets/javascripts/terraform/index.js b/app/assets/javascripts/terraform/index.js
index 1b8cab0d51e..34261f3c4db 100644
--- a/app/assets/javascripts/terraform/index.js
+++ b/app/assets/javascripts/terraform/index.js
@@ -1,5 +1,5 @@
+import { defaultDataIdFromObject } from '@apollo/client/core';
import { GlToast } from '@gitlab/ui';
-import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createDefaultClient from '~/lib/graphql';
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql
index 0b8396b4461..25c44beaf18 100644
--- a/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/get_state.query.graphql
@@ -3,7 +3,6 @@ query getState($projectPath: ID!, $iid: String!) {
id
archived
onlyAllowMergeIfPipelineSucceeds
-
mergeRequest(iid: $iid) {
id
autoMergeEnabled
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql
index 2d79d35cf24..ad93a3a7371 100644
--- a/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/auto_merge_enabled.query.graphql
@@ -4,6 +4,7 @@ query autoMergeEnabled($projectPath: ID!, $iid: String!) {
project(fullPath: $projectPath) {
id
mergeRequest(iid: $iid) {
+ id
...autoMergeEnabled
}
}
diff --git a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql
index f713739f65a..556ecee254d 100644
--- a/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql
+++ b/app/assets/javascripts/vue_merge_request_widget/queries/states/ready_to_merge.query.graphql
@@ -2,6 +2,7 @@
query readyToMerge($projectPath: ID!, $iid: String!) {
project(fullPath: $projectPath) {
+ id
...ReadyToMerge
}
}
diff --git a/app/assets/javascripts/vue_shared/alert_details/index.js b/app/assets/javascripts/vue_shared/alert_details/index.js
index 9f1da9ae173..8a0de3b74bc 100644
--- a/app/assets/javascripts/vue_shared/alert_details/index.js
+++ b/app/assets/javascripts/vue_shared/alert_details/index.js
@@ -1,4 +1,4 @@
-import { defaultDataIdFromObject } from 'apollo-cache-inmemory';
+import { defaultDataIdFromObject } from '@apollo/client/core';
import produce from 'immer';
import Vue from 'vue';
import VueApollo from 'vue-apollo';
diff --git a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue
index 138284c9f6b..8008b85bbdb 100644
--- a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue
+++ b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_item.vue
@@ -31,10 +31,6 @@ export default {
type: Object,
required: true,
},
- enableLabelPermalinks: {
- type: Boolean,
- required: true,
- },
labelFilterParam: {
type: String,
required: false,
@@ -142,11 +138,8 @@ export default {
return label.title || label.name;
},
labelTarget(label) {
- if (this.enableLabelPermalinks) {
- const value = encodeURIComponent(this.labelTitle(label));
- return `?${this.labelFilterParam}[]=${value}`;
- }
- return '#';
+ const value = encodeURIComponent(this.labelTitle(label));
+ return `?${this.labelFilterParam}[]=${value}`;
},
/**
* This is needed as an independent method since
diff --git a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_list_root.vue b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_list_root.vue
index 6fd2baeb2c6..028d48e7e8a 100644
--- a/app/assets/javascripts/vue_shared/issuable/list/components/issuable_list_root.vue
+++ b/app/assets/javascripts/vue_shared/issuable/list/components/issuable_list_root.vue
@@ -133,11 +133,6 @@ export default {
required: false,
default: 2,
},
- enableLabelPermalinks: {
- type: Boolean,
- required: false,
- default: true,
- },
labelFilterParam: {
type: String,
required: false,
@@ -321,7 +316,6 @@ export default {
:data-qa-issuable-title="issuable.title"
:issuable-symbol="issuableSymbol"
:issuable="issuable"
- :enable-label-permalinks="enableLabelPermalinks"
:label-filter-param="labelFilterParam"
:show-checkbox="showBulkEditSidebar"
:checked="issuableChecked(issuable)"
diff --git a/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue b/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue
index 12f2bc71505..f6d85599dba 100644
--- a/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue
+++ b/app/assets/javascripts/vue_shared/security_reports/security_reports_app.vue
@@ -102,8 +102,8 @@ export default {
error(error) {
this.showError(error);
},
- result({ loading }) {
- if (loading) {
+ result({ loading, data }) {
+ if (loading || !data) {
return;
}
diff --git a/app/assets/javascripts/work_items/graphql/fragmentTypes.json b/app/assets/javascripts/work_items/graphql/fragmentTypes.json
deleted file mode 100644
index 3b837e84ee9..00000000000
--- a/app/assets/javascripts/work_items/graphql/fragmentTypes.json
+++ /dev/null
@@ -1 +0,0 @@
-{"__schema":{"types":[{"kind":"INTERFACE","name":"LocalWorkItemWidget","possibleTypes":[{"name":"LocalTitleWidget"}]}]}}
diff --git a/app/assets/javascripts/work_items/graphql/provider.js b/app/assets/javascripts/work_items/graphql/provider.js
index fb536a425c0..676fffb12d8 100644
--- a/app/assets/javascripts/work_items/graphql/provider.js
+++ b/app/assets/javascripts/work_items/graphql/provider.js
@@ -1,23 +1,14 @@
import Vue from 'vue';
import VueApollo from 'vue-apollo';
-import { IntrospectionFragmentMatcher } from 'apollo-cache-inmemory';
import createDefaultClient from '~/lib/graphql';
import workItemQuery from './work_item.query.graphql';
-import introspectionQueryResultData from './fragmentTypes.json';
import { resolvers } from './resolvers';
import typeDefs from './typedefs.graphql';
-const fragmentMatcher = new IntrospectionFragmentMatcher({
- introspectionQueryResultData,
-});
-
export function createApolloProvider() {
Vue.use(VueApollo);
const defaultClient = createDefaultClient(resolvers, {
- cacheConfig: {
- fragmentMatcher,
- },
typeDefs,
});
diff --git a/app/controllers/admin/runners_controller.rb b/app/controllers/admin/runners_controller.rb
index 63ae34f5ed3..f7f78ab3229 100644
--- a/app/controllers/admin/runners_controller.rb
+++ b/app/controllers/admin/runners_controller.rb
@@ -34,7 +34,7 @@ class Admin::RunnersController < Admin::ApplicationController
end
def destroy
- @runner.destroy
+ Ci::UnregisterRunnerService.new(@runner).execute
redirect_to admin_runners_path, status: :found
end
diff --git a/app/controllers/groups/runners_controller.rb b/app/controllers/groups/runners_controller.rb
index d171df12eac..b194aeff80d 100644
--- a/app/controllers/groups/runners_controller.rb
+++ b/app/controllers/groups/runners_controller.rb
@@ -35,7 +35,7 @@ class Groups::RunnersController < Groups::ApplicationController
if @runner.belongs_to_more_than_one_project?
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found, alert: _('Runner was not deleted because it is assigned to multiple projects.')
else
- @runner.destroy
+ Ci::UnregisterRunnerService.new(@runner).execute
redirect_to group_settings_ci_cd_path(@group, anchor: 'runners-settings'), status: :found
end
diff --git a/app/controllers/projects/runners_controller.rb b/app/controllers/projects/runners_controller.rb
index 62a9f8a4625..192a29730d9 100644
--- a/app/controllers/projects/runners_controller.rb
+++ b/app/controllers/projects/runners_controller.rb
@@ -23,7 +23,7 @@ class Projects::RunnersController < Projects::ApplicationController
def destroy
if @runner.only_for?(project)
- @runner.destroy
+ Ci::UnregisterRunnerService.new(@runner).execute
end
redirect_to project_runners_path(@project), status: :found
diff --git a/app/graphql/mutations/ci/runner/delete.rb b/app/graphql/mutations/ci/runner/delete.rb
index 88dc426398b..21c3d55881c 100644
--- a/app/graphql/mutations/ci/runner/delete.rb
+++ b/app/graphql/mutations/ci/runner/delete.rb
@@ -20,7 +20,7 @@ module Mutations
error = authenticate_delete_runner!(runner)
return { errors: [error] } if error
- runner.destroy!
+ ::Ci::UnregisterRunnerService.new(runner).execute
{ errors: runner.errors.full_messages }
end
diff --git a/app/graphql/mutations/work_items/create.rb b/app/graphql/mutations/work_items/create.rb
index 88b8cefd8d2..3e76239396a 100644
--- a/app/graphql/mutations/work_items/create.rb
+++ b/app/graphql/mutations/work_items/create.rb
@@ -32,13 +32,13 @@ module Mutations
params = global_id_compatibility_params(attributes).merge(author_id: current_user.id)
spam_params = ::Spam::SpamParams.new_from_request(request: context[:request])
- work_item = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
+ create_result = ::WorkItems::CreateService.new(project: project, current_user: current_user, params: params, spam_params: spam_params).execute
- check_spam_action_response!(work_item)
+ check_spam_action_response!(create_result[:work_item]) if create_result[:work_item]
{
- work_item: work_item.valid? ? work_item : nil,
- errors: errors_on_object(work_item)
+ work_item: create_result.success? ? create_result[:work_item] : nil,
+ errors: create_result.errors
}
end
diff --git a/app/services/ci/unregister_runner_service.rb b/app/services/ci/unregister_runner_service.rb
new file mode 100644
index 00000000000..97d9852b7ed
--- /dev/null
+++ b/app/services/ci/unregister_runner_service.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+
+module Ci
+ class UnregisterRunnerService
+ attr_reader :runner
+
+ # @param [Ci::Runner] runner the runner to unregister/destroy
+ def initialize(runner)
+ @runner = runner
+ end
+
+ def execute
+ @runner&.destroy
+ end
+ end
+end
diff --git a/app/services/work_items/create_service.rb b/app/services/work_items/create_service.rb
index 49f7b89158b..705735fe403 100644
--- a/app/services/work_items/create_service.rb
+++ b/app/services/work_items/create_service.rb
@@ -2,6 +2,8 @@
module WorkItems
class CreateService
+ include ::Services::ReturnServiceResponses
+
def initialize(project:, current_user: nil, params: {}, spam_params:)
@create_service = ::Issues::CreateService.new(
project: project,
@@ -10,10 +12,28 @@ module WorkItems
spam_params: spam_params,
build_service: ::WorkItems::BuildService.new(project: project, current_user: current_user, params: params)
)
+ @current_user = current_user
+ @project = project
end
def execute
- @create_service.execute
+ unless @current_user.can?(:create_work_item, @project)
+ return error(_('Operation not allowed'), :forbidden)
+ end
+
+ work_item = @create_service.execute
+
+ if work_item.valid?
+ success(payload(work_item))
+ else
+ error(work_item.errors.full_messages, :unprocessable_entity, pass_back: payload(work_item))
+ end
+ end
+
+ private
+
+ def payload(work_item)
+ { work_item: work_item }
end
end
end
diff --git a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml
index d73d171798e..fcd52f33121 100644
--- a/app/views/doorkeeper/authorized_applications/_delete_form.html.haml
+++ b/app/views/doorkeeper/authorized_applications/_delete_form.html.haml
@@ -5,4 +5,4 @@
= form_tag path do
%input{ :name => "_method", :type => "hidden", :value => "delete" }/
- = submit_tag _('Revoke'), class: 'gl-button btn btn-danger btn-sm', data: { confirm: _('Are you sure?') }
+ = submit_tag _('Revoke'), class: 'gl-button btn btn-danger btn-sm', aria: { label: s_('AuthorizedApplication|Revoke application') }, data: { confirm: s_('AuthorizedApplication|Are you sure you want to revoke this application?'), confirm_btn_variant: 'danger' }
diff --git a/app/views/projects/learn_gitlab/index.html.haml b/app/views/projects/learn_gitlab/index.html.haml
index 6bca145dc18..9924b172875 100644
--- a/app/views/projects/learn_gitlab/index.html.haml
+++ b/app/views/projects/learn_gitlab/index.html.haml
@@ -2,7 +2,6 @@
- page_title _("Learn GitLab")
- add_page_specific_style 'page_bundles/learn_gitlab'
- data = learn_gitlab_data(@project)
-- invite_members_open = session.delete(:confetti_post_signup)
= render 'projects/invite_members_modal', project: @project
@@ -10,4 +9,4 @@
- e.control do
#js-learn-gitlab-app{ data: data }
- e.candidate do
- #js-learn-gitlab-app{ data: data.merge(invite_members_open: invite_members_open) }
+ #js-learn-gitlab-app{ data: data.merge(invite_members: 'true') }
diff --git a/config/webpack.config.js b/config/webpack.config.js
index c010a12745f..7b559c8881b 100644
--- a/config/webpack.config.js
+++ b/config/webpack.config.js
@@ -150,6 +150,8 @@ function generateEntries() {
}
const alias = {
+ // Map Apollo client to apollo/client/core to prevent react related imports from being loaded
+ '@apollo/client$': '@apollo/client/core',
'~': path.join(ROOT_PATH, 'app/assets/javascripts'),
emojis: path.join(ROOT_PATH, 'fixtures/emojis'),
empty_states: path.join(ROOT_PATH, 'app/views/shared/empty_states'),
diff --git a/config/webpack.vendor.config.js b/config/webpack.vendor.config.js
index 84fd993ed14..30d60c0b5e6 100644
--- a/config/webpack.vendor.config.js
+++ b/config/webpack.vendor.config.js
@@ -47,7 +47,7 @@ module.exports = {
'bootstrap/dist/js/bootstrap.js',
'sortablejs/modular/sortable.esm.js',
'popper.js',
- 'apollo-client',
+ '@apollo/client/core',
'source-map',
'mousetrap',
],
diff --git a/doc/api/graphql/index.md b/doc/api/graphql/index.md
index 14512286ade..d0e65b8c4eb 100644
--- a/doc/api/graphql/index.md
+++ b/doc/api/graphql/index.md
@@ -152,7 +152,7 @@ Root-level queries are defined in
### Multiplex queries
GitLab supports batching queries into a single request using
-[apollo-link-batch-http](https://www.apollographql.com/docs/link/links/batch-http/). More
+[`@apollo/client/link/batch-http`](https://www.apollographql.com/docs/react/api/link/apollo-link-batch-http/). More
information about multiplexed queries is also available for
[GraphQL Ruby](https://graphql-ruby.org/queries/multiplex.html), the
library GitLab uses on the backend.
diff --git a/doc/api/lint.md b/doc/api/lint.md
index f8d871d070d..e432b3b276f 100644
--- a/doc/api/lint.md
+++ b/doc/api/lint.md
@@ -171,6 +171,7 @@ POST /projects/:id/ci/lint
| `content` | string | yes | The CI/CD configuration content. |
| `dry_run` | boolean | no | Run [pipeline creation simulation](../ci/lint.md#simulate-a-pipeline), or only do static check. This is false by default. |
| `include_jobs` | boolean | no | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. This is false by default. |
+| `ref` | string | no | When `dry_run` is `true`, sets the branch or tag to use. Defaults to the project's default branch when not set. |
Example request:
@@ -220,6 +221,7 @@ GET /projects/:id/ci/lint
| ---------- | ------- | -------- | -------- |
| `dry_run` | boolean | no | Run pipeline creation simulation, or only do static check. |
| `include_jobs` | boolean | no | If the list of jobs that would exist in a static check or pipeline simulation should be included in the response. This is false by default. |
+| `ref` | string | no | When `dry_run` is `true`, sets the branch or tag to use. Defaults to the project's default branch when not set. |
Example request:
diff --git a/doc/user/project/milestones/burndown_and_burnup_charts.md b/doc/user/project/milestones/burndown_and_burnup_charts.md
index c6becc59ddc..05cc424e5ee 100644
--- a/doc/user/project/milestones/burndown_and_burnup_charts.md
+++ b/doc/user/project/milestones/burndown_and_burnup_charts.md
@@ -73,10 +73,8 @@ The chart indicates the project's progress throughout that milestone (for issues
In particular, it shows how many issues were or are still open for a given day in the
milestone's corresponding period.
-The burndown chart can also be toggled to display the cumulative open issue
-weight for a given day. When using this feature, make sure issue weights have
-been properly assigned, since an open issue with no weight adds zero to the
-cumulative value.
+You can also toggle the burndown chart to display the
+[cumulative open issue weight](#switch-between-number-of-issues-and-issue-weight) for a given day.
### Fixed burndown charts
@@ -123,12 +121,21 @@ To view a group's burnup chart:
### How burnup charts work
Burnup charts have separate lines for total work and completed work. The total line
-shows when scope is reduced or added to a milestone. The completed work is a count
-of issues closed.
+shows changes to the scope of a milestone. When an open issue is moved to another
+milestone, the "total issues" goes down but the "completed issues" stays the same.
+The completed work is a count of issues closed. When an issue is closed, the "total
+issues" remains the same and "completed issues" goes up.
-Burnup charts can show either the total number of issues or total weight for each
-day of the milestone. Use the toggle above the charts to switch between total
-and weight.
+## Switch between number of issues and issue weight
+
+In both burndown or burnup charts you can view them
+either by the total number of issues
+or the total weight for each day of the milestone.
+
+To switch between the two settings, select either **Issues** or **Issue weight** above the charts.
+
+When sorting by weight, make sure all your issues
+have weight assigned, because issues with no weight don't show on the chart.
<!-- ## Troubleshooting
diff --git a/doc/user/project/milestones/index.md b/doc/user/project/milestones/index.md
index f9742e8d3c6..4501cf500b0 100644
--- a/doc/user/project/milestones/index.md
+++ b/doc/user/project/milestones/index.md
@@ -151,10 +151,10 @@ There are also tabs below these that show the following:
### Burndown Charts
-The milestone view contains a [burndown chart](burndown_and_burnup_charts.md),
+The milestone view contains a [burndown and burnup chart](burndown_and_burnup_charts.md),
showing the progress of completing a milestone.
-![burndown chart](img/burndown_chart_v13_6.png)
+![burndown chart](img/burndown_and_burnup_charts_v13_6.png)
### Milestone sidebar
diff --git a/lib/api/ci/runner.rb b/lib/api/ci/runner.rb
index 9dcb10dd5e2..4df9600322c 100644
--- a/lib/api/ci/runner.rb
+++ b/lib/api/ci/runner.rb
@@ -57,7 +57,7 @@ module API
delete '/', feature_category: :runner do
authenticate_runner!
- destroy_conditionally!(current_runner)
+ destroy_conditionally!(current_runner) { ::Ci::UnregisterRunnerService.new(current_runner).execute }
end
desc 'Validates authentication credentials' do
diff --git a/lib/api/ci/runners.rb b/lib/api/ci/runners.rb
index 12c336e0938..4cef4212634 100644
--- a/lib/api/ci/runners.rb
+++ b/lib/api/ci/runners.rb
@@ -110,7 +110,7 @@ module API
authenticate_delete_runner!(runner)
- destroy_conditionally!(runner)
+ destroy_conditionally!(runner) { ::Ci::UnregisterRunnerService.new(runner).execute }
end
desc 'List jobs running on a runner' do
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index 886fca07b96..6de78c81cac 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -42,6 +42,7 @@ module API
params do
optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check.'
optional :include_jobs, type: Boolean, desc: 'Whether or not to include CI jobs in the response'
+ optional :ref, type: String, desc: 'Branch or tag used to execute a dry run. Defaults to the default branch of the project. Only used when dry_run is true'
end
get ':id/ci/lint', urgency: :low do
authorize! :download_code, user_project
@@ -52,7 +53,7 @@ module API
result = Gitlab::Ci::Lint
.new(project: user_project, current_user: current_user)
- .validate(content, dry_run: params[:dry_run])
+ .validate(content, dry_run: params[:dry_run], ref: params[:ref] || user_project.default_branch)
present result, with: Entities::Ci::Lint::Result, current_user: current_user, include_jobs: params[:include_jobs]
end
@@ -66,13 +67,14 @@ module API
requires :content, type: String, desc: 'Content of .gitlab-ci.yml'
optional :dry_run, type: Boolean, default: false, desc: 'Run pipeline creation simulation, or only do static check.'
optional :include_jobs, type: Boolean, desc: 'Whether or not to include CI jobs in the response'
+ optional :ref, type: String, desc: 'Branch or tag used to execute a dry run. Defaults to the default branch of the project. Only used when dry_run is true'
end
post ':id/ci/lint', urgency: :low do
authorize! :create_pipeline, user_project
result = Gitlab::Ci::Lint
.new(project: user_project, current_user: current_user)
- .validate(params[:content], dry_run: params[:dry_run])
+ .validate(params[:content], dry_run: params[:dry_run], ref: params[:ref] || user_project.default_branch)
status 200
present result, with: Entities::Ci::Lint::Result, current_user: current_user, include_jobs: params[:include_jobs]
diff --git a/lib/gitlab/ci/lint.rb b/lib/gitlab/ci/lint.rb
index 8c1067b9bc6..c93dfe3f202 100644
--- a/lib/gitlab/ci/lint.rb
+++ b/lib/gitlab/ci/lint.rb
@@ -24,9 +24,9 @@ module Gitlab
@sha = sha || project&.repository&.commit&.sha
end
- def validate(content, dry_run: false)
+ def validate(content, dry_run: false, ref: @project&.default_branch)
if dry_run
- simulate_pipeline_creation(content)
+ simulate_pipeline_creation(content, ref)
else
static_validation(content)
end
@@ -34,9 +34,9 @@ module Gitlab
private
- def simulate_pipeline_creation(content)
+ def simulate_pipeline_creation(content, ref)
pipeline = ::Ci::CreatePipelineService
- .new(@project, @current_user, ref: @project.default_branch)
+ .new(@project, @current_user, ref: ref)
.execute(:push, dry_run: true, content: content)
.payload
diff --git a/locale/gitlab.pot b/locale/gitlab.pot
index 76ce6fc67c9..ef2825c9a26 100644
--- a/locale/gitlab.pot
+++ b/locale/gitlab.pot
@@ -2091,6 +2091,9 @@ msgstr ""
msgid "Add a numbered list"
msgstr ""
+msgid "Add a related epic"
+msgstr ""
+
msgid "Add a related issue"
msgstr ""
@@ -5158,6 +5161,12 @@ msgstr ""
msgid "Authorized applications (%{size})"
msgstr ""
+msgid "AuthorizedApplication|Are you sure you want to revoke this application?"
+msgstr ""
+
+msgid "AuthorizedApplication|Revoke application"
+msgstr ""
+
msgid "Authors: %{authors}"
msgstr ""
@@ -21755,6 +21764,9 @@ msgstr ""
msgid "Linked emails (%{email_count})"
msgstr ""
+msgid "Linked epics"
+msgstr ""
+
msgid "Linked issues"
msgstr ""
@@ -29685,6 +29697,9 @@ msgstr ""
msgid "Read more about project permissions %{help_link_open}here%{help_link_close}"
msgstr ""
+msgid "Read more about related epics"
+msgstr ""
+
msgid "Read more about related issues"
msgstr ""
@@ -36091,6 +36106,9 @@ msgstr ""
msgid "The contents of this group, its subgroups and projects will be permanently removed after %{deletion_adjourned_period} days on %{date}. After this point, your data cannot be recovered."
msgstr ""
+msgid "The current epic"
+msgstr ""
+
msgid "The current issue"
msgstr ""
@@ -44006,6 +44024,9 @@ msgstr ""
msgid "the file"
msgstr ""
+msgid "the following epic(s)"
+msgstr ""
+
msgid "the following issue(s)"
msgstr ""
diff --git a/package.json b/package.json
index c98c3e9b8e4..7e20c5d223e 100644
--- a/package.json
+++ b/package.json
@@ -47,6 +47,7 @@
"webpack-prod": "NODE_OPTIONS=\"--max-old-space-size=3584\" NODE_ENV=production webpack --config config/webpack.config.js"
},
"dependencies": {
+ "@apollo/client": "^3.3.11",
"@babel/core": "^7.10.1",
"@babel/plugin-proposal-class-properties": "^7.10.1",
"@babel/plugin-proposal-json-strings": "^7.10.1",
@@ -94,13 +95,7 @@
"@tiptap/vue-2": "^2.0.0-beta.77",
"@toast-ui/editor": "^2.5.2",
"@toast-ui/vue-editor": "^2.5.2",
- "apollo-cache-inmemory": "^1.6.6",
- "apollo-client": "^2.6.10",
- "apollo-link": "^1.2.14",
- "apollo-link-batch-http": "^1.2.14",
- "apollo-link-error": "^1.1.13",
- "apollo-link-http": "^1.5.17",
- "apollo-upload-client": "^13.0.0",
+ "apollo-upload-client": "^14.1.3",
"autosize": "^5.0.1",
"aws-sdk": "^2.637.0",
"axios": "^0.24.0",
@@ -186,7 +181,7 @@
"uuid": "8.1.0",
"visibilityjs": "^1.2.4",
"vue": "^2.6.12",
- "vue-apollo": "^3.0.3",
+ "vue-apollo": "^3.0.7",
"vue-loader": "^15.9.6",
"vue-observe-visibility": "^1.0.0",
"vue-resize": "^1.0.1",
@@ -244,7 +239,7 @@
"markdownlint-cli": "0.31.0",
"md5": "^2.2.1",
"miragejs": "^0.1.40",
- "mock-apollo-client": "^0.7.0",
+ "mock-apollo-client": "1.2.0",
"nodemon": "^2.0.4",
"postcss": "^8.4.5",
"prettier": "2.2.1",
@@ -266,6 +261,7 @@
"bootstrap-vue": "https://docs.gitlab.com/ee/development/fe_guide/dependencies.html#bootstrapvue"
},
"resolutions": {
+ "@apollo/client/subscriptions-transport-ws": "0.11.0",
"chokidar": "^3.4.0",
"@types/node": "14.17.5"
},
diff --git a/spec/controllers/admin/runners_controller_spec.rb b/spec/controllers/admin/runners_controller_spec.rb
index 08fb12c375e..74f352e8ec2 100644
--- a/spec/controllers/admin/runners_controller_spec.rb
+++ b/spec/controllers/admin/runners_controller_spec.rb
@@ -4,9 +4,10 @@ require 'spec_helper'
RSpec.describe Admin::RunnersController do
let_it_be(:runner) { create(:ci_runner) }
+ let_it_be(:user) { create(:admin) }
before do
- sign_in(create(:admin))
+ sign_in(user)
end
describe '#index' do
@@ -104,6 +105,10 @@ RSpec.describe Admin::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
+ expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
delete :destroy, params: { id: runner.id }
expect(response).to have_gitlab_http_status(:found)
diff --git a/spec/controllers/groups/clusters_controller_spec.rb b/spec/controllers/groups/clusters_controller_spec.rb
index bc4eaf029e9..710e983dfbd 100644
--- a/spec/controllers/groups/clusters_controller_spec.rb
+++ b/spec/controllers/groups/clusters_controller_spec.rb
@@ -309,7 +309,8 @@ RSpec.describe Groups::ClustersController do
.to receive(:expires_at_in_session).and_return(1.hour.since.to_i.to_s)
allow_any_instance_of(GoogleApi::CloudPlatform::Client)
.to receive(:projects_zones_clusters_create) do
- OpenStruct.new(
+ double(
+ 'instance',
self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123',
status: 'RUNNING'
)
diff --git a/spec/controllers/groups/runners_controller_spec.rb b/spec/controllers/groups/runners_controller_spec.rb
index a8830efe653..9f0615a96ae 100644
--- a/spec/controllers/groups/runners_controller_spec.rb
+++ b/spec/controllers/groups/runners_controller_spec.rb
@@ -190,6 +190,10 @@ RSpec.describe Groups::RunnersController do
end
it 'destroys the runner and redirects' do
+ expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
delete :destroy, params: params
expect(response).to have_gitlab_http_status(:found)
diff --git a/spec/controllers/projects/runners_controller_spec.rb b/spec/controllers/projects/runners_controller_spec.rb
index 70ff77d7ff0..246a37129d7 100644
--- a/spec/controllers/projects/runners_controller_spec.rb
+++ b/spec/controllers/projects/runners_controller_spec.rb
@@ -37,6 +37,10 @@ RSpec.describe Projects::RunnersController do
describe '#destroy' do
it 'destroys the runner' do
+ expect_next_instance_of(Ci::UnregisterRunnerService, runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
delete :destroy, params: params
expect(response).to have_gitlab_http_status(:found)
diff --git a/spec/features/projects/clusters_spec.rb b/spec/features/projects/clusters_spec.rb
index 6e45529c659..b0406e1f3c4 100644
--- a/spec/features/projects/clusters_spec.rb
+++ b/spec/features/projects/clusters_spec.rb
@@ -99,7 +99,8 @@ RSpec.describe 'Clusters', :js do
allow_any_instance_of(GoogleApi::CloudPlatform::Client)
.to receive(:projects_zones_clusters_create) do
- OpenStruct.new(
+ double(
+ 'cluster_control',
self_link: 'projects/gcp-project-12345/zones/us-central1-a/operations/ope-123',
status: 'RUNNING'
)
diff --git a/spec/frontend/__helpers__/mock_apollo_helper.js b/spec/frontend/__helpers__/mock_apollo_helper.js
index 2dff9acbc76..c07a6d8ef85 100644
--- a/spec/frontend/__helpers__/mock_apollo_helper.js
+++ b/spec/frontend/__helpers__/mock_apollo_helper.js
@@ -1,15 +1,14 @@
-import { InMemoryCache } from 'apollo-cache-inmemory';
+import { InMemoryCache } from '@apollo/client/core';
import { createMockClient as createMockApolloClient } from 'mock-apollo-client';
import VueApollo from 'vue-apollo';
-
-const defaultCacheOptions = {
- fragmentMatcher: { match: () => true },
- addTypename: false,
-};
+import possibleTypes from '~/graphql_shared/possibleTypes.json';
+import { typePolicies } from '~/lib/graphql';
export function createMockClient(handlers = [], resolvers = {}, cacheOptions = {}) {
const cache = new InMemoryCache({
- ...defaultCacheOptions,
+ possibleTypes,
+ typePolicies,
+ addTypename: false,
...cacheOptions,
});
diff --git a/spec/frontend/__helpers__/test_apollo_link.js b/spec/frontend/__helpers__/test_apollo_link.js
index dde3a4e99bb..eab0c2de212 100644
--- a/spec/frontend/__helpers__/test_apollo_link.js
+++ b/spec/frontend/__helpers__/test_apollo_link.js
@@ -1,7 +1,4 @@
-import { InMemoryCache } from 'apollo-cache-inmemory';
-import { ApolloClient } from 'apollo-client';
-import { ApolloLink } from 'apollo-link';
-import gql from 'graphql-tag';
+import { InMemoryCache, ApolloClient, ApolloLink, gql } from '@apollo/client/core';
const FOO_QUERY = gql`
query {
diff --git a/spec/frontend/actioncable_link_spec.js b/spec/frontend/actioncable_link_spec.js
index c785151f8fd..b15b93cb11d 100644
--- a/spec/frontend/actioncable_link_spec.js
+++ b/spec/frontend/actioncable_link_spec.js
@@ -1,5 +1,5 @@
import { print } from 'graphql';
-import gql from 'graphql-tag';
+import { gql } from '@apollo/client/core';
import cable from '~/actioncable_consumer';
import ActionCableLink from '~/actioncable_link';
diff --git a/spec/frontend/admin/users/components/users_table_spec.js b/spec/frontend/admin/users/components/users_table_spec.js
index dffe8d6893b..ad1c45495b5 100644
--- a/spec/frontend/admin/users/components/users_table_spec.js
+++ b/spec/frontend/admin/users/components/users_table_spec.js
@@ -135,7 +135,6 @@ describe('AdminUsersTable component', () => {
});
it('creates a flash message and captures the error', () => {
- expect(createFlash).toHaveBeenCalledTimes(2);
expect(createFlash).toHaveBeenCalledWith({
message: 'Could not load user group counts. Please refresh the page to try again.',
captureError: true,
diff --git a/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js b/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js
index 152061790e5..6193233881d 100644
--- a/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js
+++ b/spec/frontend/alerts_settings/components/alerts_settings_wrapper_spec.js
@@ -1,7 +1,7 @@
import { GlLoadingIcon, GlAlert } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
import AxiosMockAdapter from 'axios-mock-adapter';
-import Vue, { nextTick } from 'vue';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/create_http_integration.mutation.graphql';
import updateHttpIntegrationMutation from 'ee_else_ce/alerts_settings/graphql/mutations/update_http_integration.mutation.graphql';
@@ -68,10 +68,7 @@ describe('AlertsSettingsWrapper', () => {
const findAlertsSettingsForm = () => wrapper.findComponent(AlertsSettingsForm);
const findAlert = () => wrapper.findComponent(GlAlert);
- async function destroyHttpIntegration(localWrapper) {
- await jest.runOnlyPendingTimers();
- await nextTick();
-
+ function destroyHttpIntegration(localWrapper) {
localWrapper
.find(IntegrationsList)
.vm.$emit('delete-integration', { id: integrationToDestroy.id });
@@ -474,11 +471,11 @@ describe('AlertsSettingsWrapper', () => {
it('calls a mutation with correct parameters and destroys a integration', async () => {
createComponentWithApollo();
+ await waitForPromises();
- await destroyHttpIntegration(wrapper);
+ destroyHttpIntegration(wrapper);
expect(destroyIntegrationHandler).toHaveBeenCalled();
-
await waitForPromises();
expect(findIntegrations()).toHaveLength(3);
diff --git a/spec/frontend/alerts_settings/components/mocks/apollo_mock.js b/spec/frontend/alerts_settings/components/mocks/apollo_mock.js
index e7ad2cd1d2a..694dff56632 100644
--- a/spec/frontend/alerts_settings/components/mocks/apollo_mock.js
+++ b/spec/frontend/alerts_settings/components/mocks/apollo_mock.js
@@ -38,6 +38,7 @@ export const getIntegrationsQueryResponse = {
alertManagementIntegrations: {
nodes: [
{
+ __typename: 'AlertManagementIntegration',
id: '37',
type: 'HTTP',
active: true,
@@ -48,6 +49,7 @@ export const getIntegrationsQueryResponse = {
apiUrl: null,
},
{
+ __typename: 'AlertManagementIntegration',
id: '41',
type: 'HTTP',
active: true,
@@ -58,6 +60,7 @@ export const getIntegrationsQueryResponse = {
apiUrl: null,
},
{
+ __typename: 'AlertManagementIntegration',
id: '40',
type: 'HTTP',
active: true,
@@ -68,6 +71,7 @@ export const getIntegrationsQueryResponse = {
apiUrl: null,
},
{
+ __typename: 'AlertManagementIntegration',
id: '12',
type: 'PROMETHEUS',
active: false,
@@ -83,6 +87,7 @@ export const getIntegrationsQueryResponse = {
};
export const integrationToDestroy = {
+ __typename: 'AlertManagementIntegration',
id: '37',
type: 'HTTP',
active: true,
@@ -97,6 +102,7 @@ export const destroyIntegrationResponse = {
httpIntegrationDestroy: {
errors: [],
integration: {
+ __typename: 'AlertManagementIntegration',
id: '37',
type: 'HTTP',
active: true,
diff --git a/spec/frontend/analytics/usage_trends/apollo_mock_data.js b/spec/frontend/analytics/usage_trends/apollo_mock_data.js
index 98eabd577ee..934bbc63689 100644
--- a/spec/frontend/analytics/usage_trends/apollo_mock_data.js
+++ b/spec/frontend/analytics/usage_trends/apollo_mock_data.js
@@ -1,4 +1,5 @@
const defaultPageInfo = {
+ __typename: 'PageInfo',
hasNextPage: false,
hasPreviousPage: false,
startCursor: null,
diff --git a/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js b/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js
index 9696e069b9c..02cf7f42a0b 100644
--- a/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js
+++ b/spec/frontend/analytics/usage_trends/components/usage_trends_count_chart_spec.js
@@ -129,7 +129,7 @@ describe('UsageTrendsCountChart', () => {
const recordedAt = '2020-08-01';
describe('when the fetchMore query returns data', () => {
beforeEach(async () => {
- const newData = [{ recordedAt, count: 5 }];
+ const newData = [{ __typename: 'UsageTrendsMeasurement', recordedAt, count: 5 }];
queryHandler = mockQueryResponse({
key: queryResponseDataKey,
data: mockCountsData1,
diff --git a/spec/frontend/analytics/usage_trends/components/users_chart_spec.js b/spec/frontend/analytics/usage_trends/components/users_chart_spec.js
index 0cd605ca1bf..32a664a5026 100644
--- a/spec/frontend/analytics/usage_trends/components/users_chart_spec.js
+++ b/spec/frontend/analytics/usage_trends/components/users_chart_spec.js
@@ -4,6 +4,7 @@ import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
import UsersChart from '~/analytics/usage_trends/components/users_chart.vue';
import usersQuery from '~/analytics/usage_trends/graphql/queries/users.query.graphql';
import ChartSkeletonLoader from '~/vue_shared/components/resizable_chart/skeleton_loader.vue';
@@ -86,7 +87,7 @@ describe('UsersChart', () => {
describe('with data', () => {
beforeEach(async () => {
wrapper = createComponent({ users: mockCountsData2 });
- await nextTick();
+ await waitForPromises();
});
it('hides the skeleton loader', () => {
@@ -156,7 +157,7 @@ describe('UsersChart', () => {
jest
.spyOn(wrapper.vm.$apollo.queries.users, 'fetchMore')
.mockImplementation(jest.fn().mockRejectedValue());
- await nextTick();
+ await waitForPromises();
});
it('calls fetchMore', () => {
diff --git a/spec/frontend/analytics/usage_trends/mock_data.js b/spec/frontend/analytics/usage_trends/mock_data.js
index d96dfa26209..77bd44d17f5 100644
--- a/spec/frontend/analytics/usage_trends/mock_data.js
+++ b/spec/frontend/analytics/usage_trends/mock_data.js
@@ -4,11 +4,11 @@ export const mockUsageCounts = [
];
export const mockCountsData1 = [
- { recordedAt: '2020-07-23', count: 52 },
- { recordedAt: '2020-07-22', count: 40 },
- { recordedAt: '2020-07-21', count: 31 },
- { recordedAt: '2020-06-14', count: 23 },
- { recordedAt: '2020-06-12', count: 20 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-07-23', count: 52 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-07-22', count: 40 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-07-21', count: 31 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-06-14', count: 23 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-06-12', count: 20 },
];
export const countsMonthlyChartData1 = [
@@ -17,11 +17,11 @@ export const countsMonthlyChartData1 = [
];
export const mockCountsData2 = [
- { recordedAt: '2020-07-28', count: 10 },
- { recordedAt: '2020-07-27', count: 9 },
- { recordedAt: '2020-06-26', count: 14 },
- { recordedAt: '2020-06-25', count: 23 },
- { recordedAt: '2020-06-24', count: 25 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-07-28', count: 10 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-07-27', count: 9 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-06-26', count: 14 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-06-25', count: 23 },
+ { __typename: 'UsageTrendsMeasurement', recordedAt: '2020-06-24', count: 25 },
];
export const countsMonthlyChartData2 = [
diff --git a/spec/frontend/boards/board_list_spec.js b/spec/frontend/boards/board_list_spec.js
index d07173c8411..fd9d2b6823d 100644
--- a/spec/frontend/boards/board_list_spec.js
+++ b/spec/frontend/boards/board_list_spec.js
@@ -106,10 +106,6 @@ describe('Board list component', () => {
fetchItemsForList: jest.fn(),
};
- beforeEach(() => {
- wrapper = createComponent();
- });
-
it('does not load issues if already loading', () => {
wrapper = createComponent({
actions,
@@ -143,6 +139,7 @@ describe('Board list component', () => {
await nextTick();
await waitForPromises();
await nextTick();
+ await nextTick();
expect(wrapper.find('.board-list-count').text()).toBe('Showing 1 of 20 issues');
});
diff --git a/spec/frontend/captcha/apollo_captcha_link_spec.js b/spec/frontend/captcha/apollo_captcha_link_spec.js
index e7ff4812ee7..eab52344d1f 100644
--- a/spec/frontend/captcha/apollo_captcha_link_spec.js
+++ b/spec/frontend/captcha/apollo_captcha_link_spec.js
@@ -1,4 +1,4 @@
-import { ApolloLink, Observable } from 'apollo-link';
+import { ApolloLink, Observable } from '@apollo/client/core';
import { apolloCaptchaLink } from '~/captcha/apollo_captcha_link';
import UnsolvedCaptchaError from '~/captcha/unsolved_captcha_error';
diff --git a/spec/frontend/clusters/agents/components/show_spec.js b/spec/frontend/clusters/agents/components/show_spec.js
index c92bf634a92..f2f073544e3 100644
--- a/spec/frontend/clusters/agents/components/show_spec.js
+++ b/spec/frontend/clusters/agents/components/show_spec.js
@@ -137,7 +137,8 @@ describe('ClusterAgentShow', () => {
await waitForPromises();
});
- it('displays agent create information with unknown user', () => {
+ it('displays agent create information with unknown user', async () => {
+ await waitForPromises();
expect(findCreatedText()).toMatchInterpolatedText('Created by Unknown user 2 days ago');
});
});
@@ -153,19 +154,25 @@ describe('ClusterAgentShow', () => {
await waitForPromises();
});
- it('displays token header with no count', () => {
+ it('displays token header with no count', async () => {
+ await waitForPromises();
expect(findTokenCount()).toMatchInterpolatedText(`${ClusterAgentShow.i18n.tokens}`);
});
});
describe('when the token list has additional pages', () => {
- const pageInfo = {
+ const pageInfoResponse = {
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'prev',
endCursor: 'next',
};
+ const pageInfo = {
+ ...pageInfoResponse,
+ __typename: 'PageInfo',
+ };
+
const tokenPagination = {
...defaultClusterAgent,
tokens: {
@@ -184,7 +191,7 @@ describe('ClusterAgentShow', () => {
});
it('should pass pageInfo to the pagination component', () => {
- expect(findPaginationButtons().props()).toMatchObject(pageInfo);
+ expect(findPaginationButtons().props()).toMatchObject(pageInfoResponse);
});
});
diff --git a/spec/frontend/clusters_list/components/agents_spec.js b/spec/frontend/clusters_list/components/agents_spec.js
index e1bd0b1a990..3cfa4b92bc0 100644
--- a/spec/frontend/clusters_list/components/agents_spec.js
+++ b/spec/frontend/clusters_list/components/agents_spec.js
@@ -92,6 +92,7 @@ describe('Agents', () => {
let testDate = new Date();
const agents = [
{
+ __typename: 'ClusterAgent',
id: '1',
name: 'agent-1',
webPath: '/agent-1',
@@ -99,6 +100,7 @@ describe('Agents', () => {
tokens: null,
},
{
+ __typename: 'ClusterAgent',
id: '2',
name: 'agent-2',
webPath: '/agent-2',
@@ -254,7 +256,10 @@ describe('Agents', () => {
beforeEach(() => {
return createWrapper({
agents,
- pageInfo,
+ pageInfo: {
+ ...pageInfo,
+ __typename: 'PageInfo',
+ },
});
});
diff --git a/spec/frontend/clusters_list/components/install_agent_modal_spec.js b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
index 3530c978370..37432ed0193 100644
--- a/spec/frontend/clusters_list/components/install_agent_modal_spec.js
+++ b/spec/frontend/clusters_list/components/install_agent_modal_spec.js
@@ -49,7 +49,8 @@ describe('InstallAgentModal', () => {
const apolloQueryResponse = {
data: {
project: {
- id: '1',
+ __typename: 'Project',
+ id: 'project-1',
clusterAgents: { nodes: [] },
agentConfigurations: { nodes: configurations },
},
diff --git a/spec/frontend/clusters_list/mocks/apollo.js b/spec/frontend/clusters_list/mocks/apollo.js
index 176896215a4..b0f2978a230 100644
--- a/spec/frontend/clusters_list/mocks/apollo.js
+++ b/spec/frontend/clusters_list/mocks/apollo.js
@@ -70,6 +70,7 @@ export const createAgentTokenErrorResponse = {
export const getAgentResponse = {
data: {
project: {
+ __typename: 'Project',
id: 'project-1',
clusterAgents: { nodes: [{ ...agent, connections, tokens }], pageInfo, count },
repository: {
diff --git a/spec/frontend/design_management/pages/index_spec.js b/spec/frontend/design_management/pages/index_spec.js
index 5a2f3bdeef8..a240a41959f 100644
--- a/spec/frontend/design_management/pages/index_spec.js
+++ b/spec/frontend/design_management/pages/index_spec.js
@@ -757,14 +757,13 @@ describe('Design management index page', () => {
expect(moveDesignHandler).toHaveBeenCalled();
- await nextTick();
+ await waitForPromises();
expect(findDesigns().at(0).props('id')).toBe('2');
});
it('prevents reordering when reorderDesigns mutation is in progress', async () => {
createComponentWithApollo({});
-
await moveDesigns(wrapper);
expect(draggableAttributes().disabled).toBe(true);
@@ -780,7 +779,6 @@ describe('Design management index page', () => {
});
await moveDesigns(wrapper);
-
await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({ message: 'Houston, we have a problem' });
@@ -792,7 +790,6 @@ describe('Design management index page', () => {
});
await moveDesigns(wrapper);
-
await waitForPromises();
expect(createFlash).toHaveBeenCalledWith({
diff --git a/spec/frontend/design_management/utils/cache_update_spec.js b/spec/frontend/design_management/utils/cache_update_spec.js
index fa6a666bb37..5e2c37e24a1 100644
--- a/spec/frontend/design_management/utils/cache_update_spec.js
+++ b/spec/frontend/design_management/utils/cache_update_spec.js
@@ -1,4 +1,4 @@
-import { InMemoryCache } from 'apollo-cache-inmemory';
+import { InMemoryCache } from '@apollo/client/core';
import {
updateStoreAfterDesignsDelete,
updateStoreAfterAddImageDiffNote,
diff --git a/spec/frontend/environment.js b/spec/frontend/environment.js
index cf47a1cd7bb..d7acf75fc95 100644
--- a/spec/frontend/environment.js
+++ b/spec/frontend/environment.js
@@ -29,6 +29,9 @@ class CustomEnvironment extends JSDOMEnvironment {
},
warn(...args) {
+ if (args[0].includes('The updateQuery callback for fetchMore is deprecated')) {
+ return;
+ }
throw new ErrorWithStack(
`Unexpected call of console.warn() with:\n\n${args.join(', ')}`,
this.warn,
diff --git a/spec/frontend/environments/new_environments_app_spec.js b/spec/frontend/environments/new_environments_app_spec.js
index 3b68a23bd32..be86a202499 100644
--- a/spec/frontend/environments/new_environments_app_spec.js
+++ b/spec/frontend/environments/new_environments_app_spec.js
@@ -28,6 +28,8 @@ describe('~/environments/components/new_environments_app.vue', () => {
folder: environmentFolderMock,
pageInfo: paginationMock,
environmentToStop: environmentToStopMock,
+ environmentToDelete: jest.fn().mockResolvedValue(resolvedEnvironment),
+ environmentToRollback: jest.fn().mockResolvedValue(resolvedEnvironment),
},
};
@@ -80,7 +82,7 @@ describe('~/environments/components/new_environments_app.vue', () => {
});
afterEach(() => {
- wrapper?.destroy();
+ wrapper.destroy();
});
it('should show all the folders that are fetched', async () => {
@@ -150,8 +152,6 @@ describe('~/environments/components/new_environments_app.vue', () => {
},
folder: resolvedFolder,
});
- await waitForPromises();
- await nextTick();
const button = wrapper.findByRole('button', { name: s__('Environments|Enable review app') });
expect(button.exists()).toBe(false);
diff --git a/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js b/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
index c6ddce17fe4..52c868e5356 100644
--- a/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
+++ b/spec/frontend/import_entities/import_groups/graphql/client_factory_spec.js
@@ -1,4 +1,4 @@
-import { InMemoryCache } from 'apollo-cache-inmemory';
+import { InMemoryCache } from '@apollo/client/core';
import MockAdapter from 'axios-mock-adapter';
import { createMockClient } from 'mock-apollo-client';
import waitForPromises from 'helpers/wait_for_promises';
diff --git a/spec/frontend/import_entities/import_groups/graphql/fixtures.js b/spec/frontend/import_entities/import_groups/graphql/fixtures.js
index ed4e343f331..938020e03f0 100644
--- a/spec/frontend/import_entities/import_groups/graphql/fixtures.js
+++ b/spec/frontend/import_entities/import_groups/graphql/fixtures.js
@@ -16,6 +16,7 @@ export const generateFakeEntry = ({ id, status, message, ...rest }) => ({
status === STATUSES.NONE || status === STATUSES.PENDING
? null
: {
+ __typename: clientTypenames.BulkImportProgress,
id,
status,
message: message || '',
diff --git a/spec/frontend/incidents/mocks/incidents.json b/spec/frontend/incidents/mocks/incidents.json
index 78783a0dce5..357b94e5b6c 100644
--- a/spec/frontend/incidents/mocks/incidents.json
+++ b/spec/frontend/incidents/mocks/incidents.json
@@ -1,5 +1,6 @@
[
{
+ "id": 1,
"iid": "15",
"title": "New: Alert",
"createdAt": "2020-06-03T15:46:08Z",
@@ -9,6 +10,7 @@
"slaDueAt": "2020-06-04T12:46:08Z"
},
{
+ "id": 2,
"iid": "14",
"title": "Create issue4",
"createdAt": "2020-05-19T09:26:07Z",
@@ -27,6 +29,7 @@
"slaDueAt": null
},
{
+ "id": 3,
"iid": "13",
"title": "Create issue3",
"createdAt": "2020-05-19T08:53:55Z",
@@ -35,6 +38,7 @@
"severity": "LOW"
},
{
+ "id": 4,
"iid": "12",
"title": "Create issue2",
"createdAt": "2020-05-18T17:13:35Z",
diff --git a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
index 2ae32e89605..ce98a16dbb7 100644
--- a/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
+++ b/spec/frontend/issuable/related_issues/components/add_issuable_form_spec.js
@@ -1,3 +1,4 @@
+import { GlFormGroup } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
import { nextTick } from 'vue';
import AddIssuableForm from '~/related_issues/components/add_issuable_form.vue';
@@ -153,6 +154,30 @@ describe('AddIssuableForm', () => {
});
});
+ describe('categorized issuables', () => {
+ it.each`
+ issuableType | pathIdSeparator | contextHeader | contextFooter
+ ${issuableTypesMap.ISSUE} | ${PathIdSeparator.Issue} | ${'The current issue'} | ${'the following issue(s)'}
+ ${issuableTypesMap.EPIC} | ${PathIdSeparator.Epic} | ${'The current epic'} | ${'the following epic(s)'}
+ `(
+ 'show header text as "$contextHeader" and footer text as "$contextFooter" issuableType is set to $issuableType',
+ ({ issuableType, contextHeader, contextFooter }) => {
+ wrapper = shallowMount(AddIssuableForm, {
+ propsData: {
+ issuableType,
+ inputValue: '',
+ showCategorizedIssues: true,
+ pathIdSeparator,
+ pendingReferences: [],
+ },
+ });
+
+ expect(wrapper.findComponent(GlFormGroup).attributes('label')).toBe(contextHeader);
+ expect(wrapper.find('p.bold').text()).toContain(contextFooter);
+ },
+ );
+ });
+
describe('when it is a Linked Issues form', () => {
beforeEach(() => {
wrapper = mount(AddIssuableForm, {
diff --git a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
index 608fec45bbd..c7925034eb0 100644
--- a/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
+++ b/spec/frontend/issuable/related_issues/components/related_issues_block_spec.js
@@ -7,6 +7,7 @@ import {
} from 'jest/issuable/components/related_issuable_mock_data';
import RelatedIssuesBlock from '~/related_issues/components/related_issues_block.vue';
import {
+ issuableTypesMap,
linkedIssueTypesMap,
linkedIssueTypesTextMap,
PathIdSeparator,
@@ -29,14 +30,34 @@ describe('RelatedIssuesBlock', () => {
wrapper = mount(RelatedIssuesBlock, {
propsData: {
pathIdSeparator: PathIdSeparator.Issue,
- issuableType: 'issue',
+ issuableType: issuableTypesMap.ISSUE,
},
});
});
- it('displays "Linked issues" in the header', () => {
- expect(wrapper.find('.card-title').text()).toContain('Linked issues');
- });
+ it.each`
+ issuableType | pathIdSeparator | titleText | helpLinkText | addButtonText
+ ${'issue'} | ${PathIdSeparator.Issue} | ${'Linked issues'} | ${'Read more about related issues'} | ${'Add a related issue'}
+ ${'epic'} | ${PathIdSeparator.Epic} | ${'Linked epics'} | ${'Read more about related epics'} | ${'Add a related epic'}
+ `(
+ 'displays "$titleText" in the header, "$helpLinkText" aria-label for help link, and "$addButtonText" aria-label for add button when issuableType is set to "$issuableType"',
+ ({ issuableType, pathIdSeparator, titleText, helpLinkText, addButtonText }) => {
+ wrapper = mount(RelatedIssuesBlock, {
+ propsData: {
+ pathIdSeparator,
+ issuableType,
+ canAdmin: true,
+ helpPath: '/help/user/project/issues/related_issues',
+ },
+ });
+
+ expect(wrapper.find('.card-title').text()).toContain(titleText);
+ expect(wrapper.find('[data-testid="help-link"]').attributes('aria-label')).toBe(
+ helpLinkText,
+ );
+ expect(findIssueCountBadgeAddButton().attributes('aria-label')).toBe(addButtonText);
+ },
+ );
it('unable to add new related issues', () => {
expect(findIssueCountBadgeAddButton().exists()).toBe(false);
diff --git a/spec/frontend/issues/list/components/issues_list_app_spec.js b/spec/frontend/issues/list/components/issues_list_app_spec.js
index f8eabc951d3..88652ddc3cc 100644
--- a/spec/frontend/issues/list/components/issues_list_app_spec.js
+++ b/spec/frontend/issues/list/components/issues_list_app_spec.js
@@ -624,7 +624,7 @@ describe('CE IssuesListApp component', () => {
it('shows an error message', () => {
expect(findIssuableList().props('error')).toBe(message);
- expect(Sentry.captureException).toHaveBeenCalledWith(new Error('Network error: ERROR'));
+ expect(Sentry.captureException).toHaveBeenCalledWith(new Error('ERROR'));
});
});
@@ -717,12 +717,13 @@ describe('CE IssuesListApp component', () => {
`(
'when moving issue $description',
({ issueToMove, oldIndex, newIndex, moveBeforeId, moveAfterId }) => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper = mountComponent({
provide: { isProject },
issuesQueryResponse: jest.fn().mockResolvedValue(response(isProject)),
});
jest.runOnlyPendingTimers();
+ await waitForPromises();
});
it('makes API call to reorder the issue', async () => {
@@ -744,11 +745,12 @@ describe('CE IssuesListApp component', () => {
});
describe('when unsuccessful', () => {
- beforeEach(() => {
+ beforeEach(async () => {
wrapper = mountComponent({
issuesQueryResponse: jest.fn().mockResolvedValue(response()),
});
jest.runOnlyPendingTimers();
+ await waitForPromises();
});
it('displays an error message', async () => {
diff --git a/spec/frontend/issues/list/mock_data.js b/spec/frontend/issues/list/mock_data.js
index f9a49254275..c883b20682e 100644
--- a/spec/frontend/issues/list/mock_data.js
+++ b/spec/frontend/issues/list/mock_data.js
@@ -7,8 +7,10 @@ export const getIssuesQueryResponse = {
data: {
project: {
id: '1',
+ __typename: 'Project',
issues: {
pageInfo: {
+ __typename: 'PageInfo',
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'startcursor',
@@ -16,6 +18,7 @@ export const getIssuesQueryResponse = {
},
nodes: [
{
+ __typename: 'Issue',
id: 'gid://gitlab/Issue/123456',
iid: '789',
closedAt: null,
@@ -36,6 +39,7 @@ export const getIssuesQueryResponse = {
assignees: {
nodes: [
{
+ __typename: 'UserCore',
id: 'gid://gitlab/User/234',
avatarUrl: 'avatar/url',
name: 'Marge Simpson',
@@ -45,6 +49,7 @@ export const getIssuesQueryResponse = {
],
},
author: {
+ __typename: 'UserCore',
id: 'gid://gitlab/User/456',
avatarUrl: 'avatar/url',
name: 'Homer Simpson',
diff --git a/spec/frontend/jobs/components/table/job_table_app_spec.js b/spec/frontend/jobs/components/table/job_table_app_spec.js
index 7808a22e1f6..5ccd38af735 100644
--- a/spec/frontend/jobs/components/table/job_table_app_spec.js
+++ b/spec/frontend/jobs/components/table/job_table_app_spec.js
@@ -1,6 +1,6 @@
import { GlSkeletonLoader, GlAlert, GlEmptyState, GlPagination } from '@gitlab/ui';
import { mount, shallowMount } from '@vue/test-utils';
-import Vue, { nextTick } from 'vue';
+import Vue from 'vue';
import VueApollo from 'vue-apollo';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
@@ -8,7 +8,12 @@ import getJobsQuery from '~/jobs/components/table/graphql/queries/get_jobs.query
import JobsTable from '~/jobs/components/table/jobs_table.vue';
import JobsTableApp from '~/jobs/components/table/jobs_table_app.vue';
import JobsTableTabs from '~/jobs/components/table/jobs_table_tabs.vue';
-import { mockJobsQueryResponse, mockJobsQueryEmptyResponse } from '../../mock_data';
+import {
+ mockJobsQueryResponse,
+ mockJobsQueryEmptyResponse,
+ mockJobsQueryResponseLastPage,
+ mockJobsQueryResponseFirstPage,
+} from '../../mock_data';
const projectPath = 'gitlab-org/gitlab';
Vue.use(VueApollo);
@@ -95,36 +100,15 @@ describe('Job table app', () => {
describe('pagination', () => {
it('should disable the next page button on the last page', async () => {
createComponent({
- handler: successHandler,
+ handler: jest.fn().mockResolvedValue(mockJobsQueryResponseLastPage),
mountFn: mount,
data: {
- pagination: {
- currentPage: 3,
- },
- jobs: {
- pageInfo: {
- hasPreviousPage: true,
- startCursor: 'abc',
- endCursor: 'bcd',
- },
- },
+ pagination: { currentPage: 3 },
},
});
await waitForPromises();
- // setData usage is discouraged. See https://gitlab.com/groups/gitlab-org/-/epics/7330 for details
- // eslint-disable-next-line no-restricted-syntax
- wrapper.setData({
- jobs: {
- pageInfo: {
- hasNextPage: false,
- },
- },
- });
-
- await nextTick();
-
expect(findPrevious().exists()).toBe(true);
expect(findNext().exists()).toBe(true);
expect(findNext().classes('disabled')).toBe(true);
@@ -132,20 +116,12 @@ describe('Job table app', () => {
it('should disable the previous page button on the first page', async () => {
createComponent({
- handler: successHandler,
+ handler: jest.fn().mockResolvedValue(mockJobsQueryResponseFirstPage),
mountFn: mount,
data: {
pagination: {
currentPage: 1,
},
- jobs: {
- pageInfo: {
- hasNextPage: true,
- hasPreviousPage: false,
- startCursor: 'abc',
- endCursor: 'bcd',
- },
- },
},
});
diff --git a/spec/frontend/jobs/mock_data.js b/spec/frontend/jobs/mock_data.js
index 4aabefc1f66..2be78bac8a9 100644
--- a/spec/frontend/jobs/mock_data.js
+++ b/spec/frontend/jobs/mock_data.js
@@ -1579,6 +1579,44 @@ export const mockJobsQueryResponse = {
},
};
+export const mockJobsQueryResponseLastPage = {
+ data: {
+ project: {
+ id: '1',
+ jobs: {
+ ...mockJobsQueryResponse.data.project.jobs,
+ pageInfo: {
+ endCursor: 'eyJpZCI6IjIzMTcifQ',
+ hasNextPage: false,
+ hasPreviousPage: true,
+ startCursor: 'eyJpZCI6IjIzMzYifQ',
+ __typename: 'PageInfo',
+ },
+ },
+ __typename: 'Project',
+ },
+ },
+};
+
+export const mockJobsQueryResponseFirstPage = {
+ data: {
+ project: {
+ id: '1',
+ jobs: {
+ ...mockJobsQueryResponse.data.project.jobs,
+ pageInfo: {
+ endCursor: 'eyJpZCI6IjIzMTcifQ',
+ hasNextPage: true,
+ hasPreviousPage: false,
+ startCursor: 'eyJpZCI6IjIzMzYifQ',
+ __typename: 'PageInfo',
+ },
+ },
+ __typename: 'Project',
+ },
+ },
+};
+
export const mockJobsQueryEmptyResponse = {
data: {
project: {
diff --git a/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js b/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js
index 7b604724977..971ba8b583c 100644
--- a/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js
+++ b/spec/frontend/lib/apollo/suppress_network_errors_during_navigation_link_spec.js
@@ -1,4 +1,4 @@
-import { ApolloLink, Observable } from 'apollo-link';
+import { ApolloLink, Observable } from '@apollo/client/core';
import waitForPromises from 'helpers/wait_for_promises';
import { getSuppressNetworkErrorsDuringNavigationLink } from '~/lib/apollo/suppress_network_errors_during_navigation_link';
import { isNavigatingAway } from '~/lib/utils/is_navigating_away';
diff --git a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js
index c0e5b06651f..e58bc063004 100644
--- a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js
+++ b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js
@@ -1,4 +1,4 @@
-import { ApolloLink, Observable } from 'apollo-link';
+import { ApolloLink, Observable } from '@apollo/client/core';
import { StartupJSLink } from '~/lib/utils/apollo_startup_js_link';
describe('StartupJSLink', () => {
diff --git a/spec/frontend/notes/components/comment_form_spec.js b/spec/frontend/notes/components/comment_form_spec.js
index 1e4d9f313f0..a605edc4357 100644
--- a/spec/frontend/notes/components/comment_form_spec.js
+++ b/spec/frontend/notes/components/comment_form_spec.js
@@ -20,7 +20,6 @@ import { loggedOutnoteableData, notesDataMock, userDataMock, noteableDataMock }
jest.mock('autosize');
jest.mock('~/commons/nav/user_merge_requests');
jest.mock('~/flash');
-jest.mock('~/gl_form');
Vue.use(Vuex);
diff --git a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
index bda0f3616a4..bd126fe532d 100644
--- a/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
+++ b/spec/frontend/packages_and_registries/container_registry/explorer/pages/list_spec.js
@@ -305,15 +305,8 @@ describe('List Page', () => {
await selectImageForDeletion();
findDeleteModal().vm.$emit('primary');
- await waitForApolloRequestRender();
-
- expect(wrapper.vm.itemToDelete).toEqual(deletedContainerRepository);
-
- const updatedImage = findImageList()
- .props('images')
- .find((i) => i.id === deletedContainerRepository.id);
- expect(updatedImage.status).toBe(deletedContainerRepository.status);
+ expect(mutationResolver).toHaveBeenCalledWith({ id: deletedContainerRepository.id });
});
it('should show a success alert when delete request is successful', async () => {
diff --git a/spec/frontend/packages_and_registries/package_registry/mock_data.js b/spec/frontend/packages_and_registries/package_registry/mock_data.js
index c6a59f20998..0a4747fc9ec 100644
--- a/spec/frontend/packages_and_registries/package_registry/mock_data.js
+++ b/spec/frontend/packages_and_registries/package_registry/mock_data.js
@@ -119,6 +119,7 @@ export const packageVersions = () => [
];
export const packageData = (extend) => ({
+ __typename: 'Package',
id: 'gid://gitlab/Packages::Package/111',
canDestroy: true,
name: '@gitlab-org/package-15',
diff --git a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
index b9fbaad7734..a7e31d42c9e 100644
--- a/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
+++ b/spec/frontend/packages_and_registries/package_registry/pages/details_spec.js
@@ -57,6 +57,8 @@ describe('PackagesApp', () => {
breadCrumbState,
};
+ const { __typename, ...packageWithoutTypename } = packageData();
+
function createComponent({
resolver = jest.fn().mockResolvedValue(packageDetailsQuery()),
fileDeleteMutationResolver = jest.fn().mockResolvedValue(packageDestroyFileMutation()),
@@ -130,7 +132,7 @@ describe('PackagesApp', () => {
expect(findPackageTitle().exists()).toBe(true);
expect(findPackageTitle().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
+ packageEntity: expect.objectContaining(packageWithoutTypename),
});
});
@@ -153,7 +155,7 @@ describe('PackagesApp', () => {
expect(findPackageHistory().exists()).toBe(true);
expect(findPackageHistory().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
+ packageEntity: expect.objectContaining(packageWithoutTypename),
projectName: packageDetailsQuery().data.package.project.name,
});
});
@@ -165,7 +167,7 @@ describe('PackagesApp', () => {
expect(findAdditionalMetadata().exists()).toBe(true);
expect(findAdditionalMetadata().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
+ packageEntity: expect.objectContaining(packageWithoutTypename),
});
});
@@ -176,7 +178,7 @@ describe('PackagesApp', () => {
expect(findInstallationCommands().exists()).toBe(true);
expect(findInstallationCommands().props()).toMatchObject({
- packageEntity: expect.objectContaining(packageData()),
+ packageEntity: expect.objectContaining(packageWithoutTypename),
});
});
diff --git a/spec/frontend/packages_and_registries/settings/project/settings/mock_data.js b/spec/frontend/packages_and_registries/settings/project/settings/mock_data.js
index a56bb75f8ed..33406c98f4b 100644
--- a/spec/frontend/packages_and_registries/settings/project/settings/mock_data.js
+++ b/spec/frontend/packages_and_registries/settings/project/settings/mock_data.js
@@ -13,6 +13,7 @@ export const expirationPolicyPayload = (override) => ({
project: {
id: '1',
containerExpirationPolicy: {
+ __typename: 'ContainerExpirationPolicy',
...containerExpirationPolicyData(),
...override,
},
diff --git a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
index 7e71622770f..f6e3a72b5e0 100644
--- a/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
+++ b/spec/frontend/pages/projects/learn_gitlab/components/learn_gitlab_spec.js
@@ -1,13 +1,15 @@
import { GlProgressBar, GlAlert } from '@gitlab/ui';
import { mount } from '@vue/test-utils';
+import Cookies from 'js-cookie';
import LearnGitlab from '~/pages/projects/learn_gitlab/components/learn_gitlab.vue';
import eventHub from '~/invite_members/event_hub';
+import { INVITE_MODAL_OPEN_COOKIE } from '~/pages/projects/learn_gitlab/constants';
import { testActions, testSections, testProject } from './mock_data';
describe('Learn GitLab', () => {
let wrapper;
let sidebar;
- let inviteMembersOpen = false;
+ let inviteMembers = false;
const createWrapper = () => {
wrapper = mount(LearnGitlab, {
@@ -15,7 +17,7 @@ describe('Learn GitLab', () => {
actions: testActions,
sections: testSections,
project: testProject,
- inviteMembersOpen,
+ inviteMembers,
},
});
};
@@ -36,7 +38,7 @@ describe('Learn GitLab', () => {
afterEach(() => {
wrapper.destroy();
wrapper = null;
- inviteMembersOpen = false;
+ inviteMembers = false;
sidebar.remove();
});
@@ -59,13 +61,20 @@ describe('Learn GitLab', () => {
describe('Invite Members Modal', () => {
let spy;
+ let cookieSpy;
beforeEach(() => {
spy = jest.spyOn(eventHub, '$emit');
+ cookieSpy = jest.spyOn(Cookies, 'remove');
+ });
+
+ afterEach(() => {
+ Cookies.remove(INVITE_MODAL_OPEN_COOKIE);
});
it('emits openModal', () => {
- inviteMembersOpen = true;
+ inviteMembers = true;
+ Cookies.set(INVITE_MODAL_OPEN_COOKIE, true);
createWrapper();
@@ -74,9 +83,19 @@ describe('Learn GitLab', () => {
inviteeType: 'members',
source: 'learn-gitlab',
});
+ expect(cookieSpy).toHaveBeenCalledWith(INVITE_MODAL_OPEN_COOKIE);
+ });
+
+ it('does not emit openModal when cookie is not set', () => {
+ inviteMembers = true;
+
+ createWrapper();
+
+ expect(spy).not.toHaveBeenCalled();
+ expect(cookieSpy).toHaveBeenCalledWith(INVITE_MODAL_OPEN_COOKIE);
});
- it('does not emit openModal', () => {
+ it('does not emit openModal when inviteMembers is false', () => {
createWrapper();
expect(spy).not.toHaveBeenCalled();
diff --git a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
index b84dad5a988..b54feea6ff7 100644
--- a/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
+++ b/spec/frontend/pipeline_editor/components/commit/commit_section_spec.js
@@ -12,7 +12,9 @@ import {
COMMIT_SUCCESS,
COMMIT_SUCCESS_WITH_REDIRECT,
} from '~/pipeline_editor/constants';
+import { resolvers } from '~/pipeline_editor/graphql/resolvers';
import commitCreate from '~/pipeline_editor/graphql/mutations/commit_ci_file.mutation.graphql';
+import getCurrentBranch from '~/pipeline_editor/graphql/queries/client/current_branch.query.graphql';
import updatePipelineEtag from '~/pipeline_editor/graphql/mutations/client/update_pipeline_etag.mutation.graphql';
import {
@@ -70,7 +72,20 @@ describe('Pipeline Editor | Commit section', () => {
const createComponentWithApollo = (options) => {
const handlers = [[commitCreate, mockMutateCommitData]];
Vue.use(VueApollo);
- mockApollo = createMockApollo(handlers);
+ mockApollo = createMockApollo(handlers, resolvers);
+
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getCurrentBranch,
+ data: {
+ workBranches: {
+ __typename: 'BranchList',
+ current: {
+ __typename: 'WorkBranch',
+ name: mockDefaultBranch,
+ },
+ },
+ },
+ });
const apolloConfig = {
apolloProvider: mockApollo,
@@ -198,6 +213,7 @@ describe('Pipeline Editor | Commit section', () => {
const newBranch = 'new-branch';
beforeEach(async () => {
+ mockMutateCommitData.mockResolvedValue(mockCommitCreateResponse);
createComponentWithApollo();
mockMutateCommitData.mockResolvedValue(mockCommitCreateResponse);
await submitCommit({
diff --git a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
index ab9027a56a4..7dbacad34bf 100644
--- a/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
+++ b/spec/frontend/pipeline_editor/components/file-nav/branch_switcher_spec.js
@@ -12,6 +12,10 @@ import waitForPromises from 'helpers/wait_for_promises';
import BranchSwitcher from '~/pipeline_editor/components/file_nav/branch_switcher.vue';
import { DEFAULT_FAILURE } from '~/pipeline_editor/constants';
import getAvailableBranchesQuery from '~/pipeline_editor/graphql/queries/available_branches.query.graphql';
+import getCurrentBranch from '~/pipeline_editor/graphql/queries/client/current_branch.query.graphql';
+import getLastCommitBranch from '~/pipeline_editor/graphql/queries/client/last_commit_branch.query.graphql';
+import { resolvers } from '~/pipeline_editor/graphql/resolvers';
+
import {
mockBranchPaginationLimit,
mockDefaultBranch,
@@ -34,6 +38,7 @@ describe('Pipeline editor branch switcher', () => {
const createComponent = ({
currentBranch = mockDefaultBranch,
+ availableBranches = ['main'],
isQueryLoading = false,
mountFn = shallowMount,
options = {},
@@ -59,7 +64,7 @@ describe('Pipeline editor branch switcher', () => {
},
data() {
return {
- availableBranches: ['main'],
+ availableBranches,
currentBranch,
};
},
@@ -67,13 +72,44 @@ describe('Pipeline editor branch switcher', () => {
});
};
- const createComponentWithApollo = ({ mountFn = shallowMount, props = {} } = {}) => {
+ const createComponentWithApollo = ({
+ mountFn = shallowMount,
+ props = {},
+ availableBranches = ['main'],
+ } = {}) => {
const handlers = [[getAvailableBranchesQuery, mockAvailableBranchQuery]];
- mockApollo = createMockApollo(handlers);
+ mockApollo = createMockApollo(handlers, resolvers);
+
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getCurrentBranch,
+ data: {
+ workBranches: {
+ __typename: 'BranchList',
+ current: {
+ __typename: 'WorkBranch',
+ name: mockDefaultBranch,
+ },
+ },
+ },
+ });
+
+ mockApollo.clients.defaultClient.cache.writeQuery({
+ query: getLastCommitBranch,
+ data: {
+ workBranches: {
+ __typename: 'BranchList',
+ lastCommit: {
+ __typename: 'WorkBranch',
+ name: '',
+ },
+ },
+ },
+ });
createComponent({
mountFn,
props,
+ availableBranches,
options: {
localVue,
apolloProvider: mockApollo,
@@ -113,7 +149,7 @@ describe('Pipeline editor branch switcher', () => {
describe('when querying for the first time', () => {
beforeEach(() => {
- createComponentWithApollo();
+ createComponentWithApollo({ availableBranches: [] });
});
it('disables the dropdown', () => {
@@ -153,7 +189,7 @@ describe('Pipeline editor branch switcher', () => {
describe('on fetch error', () => {
beforeEach(async () => {
setAvailableBranchesMock(new Error());
- createComponentWithApollo();
+ createComponentWithApollo({ availableBranches: [] });
await waitForPromises();
});
diff --git a/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js b/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
index aae8656b4ad..93eb18c90cf 100644
--- a/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
+++ b/spec/frontend/pipeline_editor/components/header/pipline_editor_mini_graph_spec.js
@@ -96,7 +96,7 @@ describe('Pipeline Status', () => {
});
it('should emit an error event when query fails', async () => {
- expect(wrapper.emitted('showError')).toHaveLength(2);
+ expect(wrapper.emitted('showError')).toHaveLength(1);
expect(wrapper.emitted('showError')[0]).toEqual([
{
type: PIPELINE_FAILURE,
diff --git a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
index ca283f3b4ce..1673065e09c 100644
--- a/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
+++ b/spec/frontend/pipelines/graph/linked_pipelines_column_spec.js
@@ -90,11 +90,6 @@ describe('Linked Pipelines Column', () => {
await waitForPromises();
};
- const clickExpandButtonAndAwaitTimers = async () => {
- await clickExpandButton();
- jest.runOnlyPendingTimers();
- };
-
describe('layer type rendering', () => {
let layersFn;
@@ -105,7 +100,7 @@ describe('Linked Pipelines Column', () => {
it('calls listByLayers only once no matter how many times view is switched', async () => {
expect(layersFn).not.toHaveBeenCalled();
- await clickExpandButtonAndAwaitTimers();
+ await clickExpandButton();
await wrapper.setProps({ viewType: LAYER_VIEW });
await nextTick();
expect(layersFn).toHaveBeenCalledTimes(1);
@@ -131,7 +126,7 @@ describe('Linked Pipelines Column', () => {
});
it('shows the stage view, even when the main graph view type is layers', async () => {
- await clickExpandButtonAndAwaitTimers();
+ await clickExpandButton();
expect(findPipelineGraph().props('viewType')).toBe(STAGE_VIEW);
});
});
@@ -144,7 +139,7 @@ describe('Linked Pipelines Column', () => {
it('toggles the pipeline visibility', async () => {
expect(findPipelineGraph().exists()).toBe(false);
- await clickExpandButtonAndAwaitTimers();
+ await clickExpandButton();
expect(findPipelineGraph().exists()).toBe(true);
await clickExpandButton();
expect(findPipelineGraph().exists()).toBe(false);
@@ -161,15 +156,12 @@ describe('Linked Pipelines Column', () => {
it('emits the error', async () => {
await clickExpandButton();
- expect(wrapper.emitted().error).toEqual([
- [{ type: LOAD_FAILURE, skipSentry: true }],
- [{ type: LOAD_FAILURE, skipSentry: true }],
- ]);
+ expect(wrapper.emitted().error).toEqual([[{ type: LOAD_FAILURE, skipSentry: true }]]);
});
it('does not show the pipeline', async () => {
expect(findPipelineGraph().exists()).toBe(false);
- await clickExpandButtonAndAwaitTimers();
+ await clickExpandButton();
expect(findPipelineGraph().exists()).toBe(false);
});
});
@@ -197,7 +189,7 @@ describe('Linked Pipelines Column', () => {
it('toggles the pipeline visibility', async () => {
expect(findPipelineGraph().exists()).toBe(false);
- await clickExpandButtonAndAwaitTimers();
+ await clickExpandButton();
expect(findPipelineGraph().exists()).toBe(true);
await clickExpandButton();
expect(findPipelineGraph().exists()).toBe(false);
@@ -215,15 +207,12 @@ describe('Linked Pipelines Column', () => {
it('emits the error', async () => {
await clickExpandButton();
- expect(wrapper.emitted().error).toEqual([
- [{ type: LOAD_FAILURE, skipSentry: true }],
- [{ type: LOAD_FAILURE, skipSentry: true }],
- ]);
+ expect(wrapper.emitted().error).toEqual([[{ type: LOAD_FAILURE, skipSentry: true }]]);
});
it('does not show the pipeline', async () => {
expect(findPipelineGraph().exists()).toBe(false);
- await clickExpandButtonAndAwaitTimers();
+ await clickExpandButton();
expect(findPipelineGraph().exists()).toBe(false);
});
});
diff --git a/spec/frontend/repository/components/blob_content_viewer_spec.js b/spec/frontend/repository/components/blob_content_viewer_spec.js
index 53479e3cdb7..109e5cef49b 100644
--- a/spec/frontend/repository/components/blob_content_viewer_spec.js
+++ b/spec/frontend/repository/components/blob_content_viewer_spec.js
@@ -79,6 +79,8 @@ const createComponent = async (mockData = {}, mountFn = shallowMount) => {
propsData: propsMock,
mixins: [{ data: () => ({ ref: refMock }) }],
provide: {
+ targetBranch: 'test',
+ originalBranch: 'default-ref',
...inject,
glFeatures: {
highlightJs,
diff --git a/spec/frontend/repository/mock_data.js b/spec/frontend/repository/mock_data.js
index 52c68c7925c..5a6551cb94a 100644
--- a/spec/frontend/repository/mock_data.js
+++ b/spec/frontend/repository/mock_data.js
@@ -50,6 +50,7 @@ export const userPermissionsMock = {
};
export const projectMock = {
+ __typename: 'Project',
id: '1234',
userPermissions: userPermissionsMock,
pathLocks: {
diff --git a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
index e694fbf86a3..ff6a632a4f8 100644
--- a/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
+++ b/spec/frontend/runner/admin_runner_edit/admin_runner_edit_app_spec.js
@@ -76,7 +76,7 @@ describe('AdminRunnerEditApp', () => {
it('error is reported to sentry', () => {
expect(captureException).toHaveBeenCalledWith({
- error: new Error('Network error: Error!'),
+ error: new Error('Error!'),
component: 'AdminRunnerEditApp',
});
});
diff --git a/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js b/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
index 9a02e9057c2..031da47acb4 100644
--- a/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
+++ b/spec/frontend/runner/admin_runner_show/admin_runner_show_app_spec.js
@@ -137,7 +137,7 @@ describe('AdminRunnerShowApp', () => {
it('error is reported to sentry', () => {
expect(captureException).toHaveBeenCalledWith({
- error: new Error('Network error: Error!'),
+ error: new Error('Error!'),
component: 'AdminRunnerShowApp',
});
});
diff --git a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
index 35df27e02ea..995f0cf7ba1 100644
--- a/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
+++ b/spec/frontend/runner/admin_runners/admin_runners_app_spec.js
@@ -302,17 +302,18 @@ describe('AdminRunnersApp', () => {
it('error is reported to sentry', async () => {
expect(captureException).toHaveBeenCalledWith({
- error: new Error('Network error: Error!'),
+ error: new Error('Error!'),
component: 'AdminRunnersApp',
});
});
});
describe('Pagination', () => {
- beforeEach(() => {
+ beforeEach(async () => {
mockRunnersQuery = jest.fn().mockResolvedValue(runnersDataPaginated);
createComponent({ mountFn: mountExtended });
+ await waitForPromises();
});
it('more pages can be selected', () => {
diff --git a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
index b2c740c3f27..dcb0af67784 100644
--- a/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
+++ b/spec/frontend/runner/components/cells/runner_actions_cell_spec.js
@@ -206,7 +206,8 @@ describe('RunnerTypeCell', () => {
expect(getTooltip(findDeleteBtn())).toBe('');
});
- it('The toast notification is shown', () => {
+ it('The toast notification is shown', async () => {
+ await waitForPromises();
expect(mockToastShow).toHaveBeenCalledTimes(1);
expect(mockToastShow).toHaveBeenCalledWith(
expect.stringContaining(`#${getIdFromGraphQLId(mockRunner.id)} (${mockRunner.shortSha})`),
@@ -227,7 +228,7 @@ describe('RunnerTypeCell', () => {
it('error is reported to sentry', () => {
expect(captureException).toHaveBeenCalledWith({
- error: new Error(`Network error: ${mockErrorMsg}`),
+ error: new Error(mockErrorMsg),
component: 'RunnerActionsCell',
});
});
diff --git a/spec/frontend/runner/components/registration/registration_dropdown_spec.js b/spec/frontend/runner/components/registration/registration_dropdown_spec.js
index 26d3f852a1e..da8ef7c3af0 100644
--- a/spec/frontend/runner/components/registration/registration_dropdown_spec.js
+++ b/spec/frontend/runner/components/registration/registration_dropdown_spec.js
@@ -5,6 +5,7 @@ import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
import { extendedWrapper } from 'helpers/vue_test_utils_helper';
import createMockApollo from 'helpers/mock_apollo_helper';
+import waitForPromises from 'helpers/wait_for_promises';
import RegistrationDropdown from '~/runner/components/registration/registration_dropdown.vue';
import RegistrationTokenResetDropdownItem from '~/runner/components/registration/registration_token_reset_dropdown_item.vue';
@@ -96,6 +97,7 @@ describe('RegistrationDropdown', () => {
);
await findRegistrationInstructionsDropdownItem().trigger('click');
+ await waitForPromises();
});
afterEach(() => {
diff --git a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
index 43b9aa9c413..d2deb49a5f7 100644
--- a/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
+++ b/spec/frontend/runner/components/registration/registration_token_reset_dropdown_item_spec.js
@@ -162,10 +162,10 @@ describe('RegistrationTokenResetDropdownItem', () => {
await waitForPromises();
expect(createAlert).toHaveBeenLastCalledWith({
- message: `Network error: ${mockErrorMsg}`,
+ message: mockErrorMsg,
});
expect(captureException).toHaveBeenCalledWith({
- error: new Error(`Network error: ${mockErrorMsg}`),
+ error: new Error(mockErrorMsg),
component: 'RunnerRegistrationTokenReset',
});
});
diff --git a/spec/frontend/runner/components/runner_pause_button_spec.js b/spec/frontend/runner/components/runner_pause_button_spec.js
index 34510883a25..278f3dec2ee 100644
--- a/spec/frontend/runner/components/runner_pause_button_spec.js
+++ b/spec/frontend/runner/components/runner_pause_button_spec.js
@@ -150,7 +150,7 @@ describe('RunnerPauseButton', () => {
it('error is reported to sentry', () => {
expect(captureException).toHaveBeenCalledWith({
- error: new Error(`Network error: ${mockErrorMsg}`),
+ error: new Error(mockErrorMsg),
component: 'RunnerPauseButton',
});
});
diff --git a/spec/frontend/runner/components/runner_update_form_spec.js b/spec/frontend/runner/components/runner_update_form_spec.js
index f92244f41f7..36120a4c7ed 100644
--- a/spec/frontend/runner/components/runner_update_form_spec.js
+++ b/spec/frontend/runner/components/runner_update_form_spec.js
@@ -132,6 +132,7 @@ describe('RunnerUpdateForm', () => {
userPermissions,
version,
groups,
+ __typename,
...submitted
} = mockRunner;
@@ -245,11 +246,11 @@ describe('RunnerUpdateForm', () => {
await submitFormAndWait();
expect(createAlert).toHaveBeenLastCalledWith({
- message: `Network error: ${mockErrorMsg}`,
+ message: mockErrorMsg,
});
expect(captureException).toHaveBeenCalledWith({
component: 'RunnerUpdateForm',
- error: new Error(`Network error: ${mockErrorMsg}`),
+ error: new Error(mockErrorMsg),
});
expect(findSubmitDisabledAttr()).toBeUndefined();
});
diff --git a/spec/frontend/runner/group_runners/group_runners_app_spec.js b/spec/frontend/runner/group_runners/group_runners_app_spec.js
index f1802ac78a1..7cb1f49d4f7 100644
--- a/spec/frontend/runner/group_runners/group_runners_app_spec.js
+++ b/spec/frontend/runner/group_runners/group_runners_app_spec.js
@@ -262,6 +262,7 @@ describe('GroupRunnersApp', () => {
mockGroupRunnersQuery = jest.fn().mockResolvedValue({
data: {
group: {
+ id: '1',
runners: { nodes: [] },
},
},
@@ -288,17 +289,18 @@ describe('GroupRunnersApp', () => {
it('error is reported to sentry', async () => {
expect(captureException).toHaveBeenCalledWith({
- error: new Error('Network error: Error!'),
+ error: new Error('Error!'),
component: 'GroupRunnersApp',
});
});
});
describe('Pagination', () => {
- beforeEach(() => {
+ beforeEach(async () => {
mockGroupRunnersQuery = jest.fn().mockResolvedValue(groupRunnersDataPaginated);
createComponent({ mountFn: mountExtended });
+ await waitForPromises();
});
it('more pages can be selected', () => {
diff --git a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
index 3045b8c5842..def46255994 100644
--- a/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
+++ b/spec/frontend/sidebar/components/assignees/sidebar_assignees_widget_spec.js
@@ -137,9 +137,17 @@ describe('Sidebar assignees widget', () => {
createComponent();
await waitForPromises();
- expect(findAssignees().props('users')).toEqual(
- issuableQueryResponse.data.workspace.issuable.assignees.nodes,
- );
+ expect(findAssignees().props('users')).toEqual([
+ {
+ id: 'gid://gitlab/User/2',
+ avatarUrl:
+ 'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon',
+ name: 'Jacki Kub',
+ username: 'francina.skiles',
+ webUrl: '/franc',
+ status: null,
+ },
+ ]);
});
it('renders an error when issuable query is rejected', async () => {
@@ -195,7 +203,7 @@ describe('Sidebar assignees widget', () => {
{
assignees: [
{
- __typename: 'User',
+ __typename: 'UserCore',
avatarUrl:
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80&d=identicon',
id: 'gid://gitlab/User/1',
@@ -353,6 +361,7 @@ describe('Sidebar assignees widget', () => {
describe('when making changes to participants list', () => {
beforeEach(async () => {
createComponent();
+ await waitForPromises();
});
it('passes falsy `isDirty` prop to editable item if no changes to selected users were made', () => {
diff --git a/spec/frontend/sidebar/components/mock_data.js b/spec/frontend/sidebar/components/mock_data.js
index 70c3f8a3012..a9a00b3cfdf 100644
--- a/spec/frontend/sidebar/components/mock_data.js
+++ b/spec/frontend/sidebar/components/mock_data.js
@@ -1,6 +1,7 @@
export const getIssueCrmContactsQueryResponse = {
data: {
issue: {
+ __typename: 'Issue',
id: 'gid://gitlab/Issue/123',
customerRelationsContacts: {
nodes: [
@@ -37,6 +38,7 @@ export const issueCrmContactsUpdateNullResponse = {
export const issueCrmContactsUpdateResponse = {
data: {
issueCrmContactsUpdated: {
+ __typename: 'Issue',
id: 'gid://gitlab/Issue/123',
customerRelationsContacts: {
nodes: [
diff --git a/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js b/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js
index 859e63b3df6..338ecf944f3 100644
--- a/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js
+++ b/spec/frontend/sidebar/components/participants/sidebar_participants_widget_spec.js
@@ -1,6 +1,7 @@
import { shallowMount } from '@vue/test-utils';
import Vue, { nextTick } from 'vue';
import VueApollo from 'vue-apollo';
+import { stripTypenames } from 'helpers/graphql_helpers';
import createMockApollo from 'helpers/mock_apollo_helper';
import waitForPromises from 'helpers/wait_for_promises';
import Participants from '~/sidebar/components/participants/participants.vue';
@@ -66,9 +67,11 @@ describe('Sidebar Participants Widget', () => {
});
it('passes participants to child component', () => {
- expect(findParticipants().props('participants')).toEqual(
+ const participantsWithoutTypename = stripTypenames(
epicParticipantsResponse().data.workspace.issuable.participants.nodes,
);
+
+ expect(findParticipants().props('participants')).toEqual(participantsWithoutTypename);
});
});
diff --git a/spec/frontend/sidebar/mock_data.js b/spec/frontend/sidebar/mock_data.js
index 42e89a3ba84..30972484a08 100644
--- a/spec/frontend/sidebar/mock_data.js
+++ b/spec/frontend/sidebar/mock_data.js
@@ -276,6 +276,7 @@ export const epicParticipantsResponse = () => ({
participants: {
nodes: [
{
+ __typename: 'UserCore',
id: 'gid://gitlab/User/2',
avatarUrl:
'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon',
@@ -332,6 +333,7 @@ export const issuableQueryResponse = {
assignees: {
nodes: [
{
+ __typename: 'UserCore',
id: 'gid://gitlab/User/2',
avatarUrl:
'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon',
@@ -389,7 +391,7 @@ export const updateIssueAssigneesMutationResponse = {
assignees: {
nodes: [
{
- __typename: 'User',
+ __typename: 'UserCore',
id: 'gid://gitlab/User/1',
avatarUrl:
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
@@ -414,6 +416,7 @@ export const subscriptionNullResponse = {
};
const mockUser1 = {
+ __typename: 'UserCore',
id: 'gid://gitlab/User/1',
avatarUrl:
'https://www.gravatar.com/avatar/e64c7d89f26bd1972efa854d13d7dd61?s=80\u0026d=identicon',
@@ -424,6 +427,7 @@ const mockUser1 = {
};
export const mockUser2 = {
+ __typename: 'UserCore',
id: 'gid://gitlab/User/4',
avatarUrl: '/avatar2',
name: 'rookie',
@@ -470,6 +474,7 @@ export const projectMembersResponse = {
{
id: 'user-4',
user: {
+ __typename: 'UserCore',
id: 'gid://gitlab/User/2',
avatarUrl:
'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon',
@@ -503,6 +508,7 @@ export const groupMembersResponse = {
{
id: 'user-3',
user: {
+ __typename: 'UserCore',
id: 'gid://gitlab/User/2',
avatarUrl:
'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon',
@@ -535,6 +541,7 @@ export const participantsQueryResponse = {
mockUser1,
mockUser1,
{
+ __typename: 'UserCore',
id: 'gid://gitlab/User/2',
avatarUrl:
'https://www.gravatar.com/avatar/a95e5b71488f4b9d69ce5ff58bfd28d6?s=80\u0026d=identicon',
@@ -546,6 +553,7 @@ export const participantsQueryResponse = {
},
},
{
+ __typename: 'UserCore',
id: 'gid://gitlab/User/3',
avatarUrl: '/avatar',
name: 'John Doe',
diff --git a/spec/frontend/snippets/components/edit_spec.js b/spec/frontend/snippets/components/edit_spec.js
index 9f608765183..61424fa1eb2 100644
--- a/spec/frontend/snippets/components/edit_spec.js
+++ b/spec/frontend/snippets/components/edit_spec.js
@@ -329,6 +329,7 @@ describe('Snippet Edit app', () => {
mutateSpy.mockRejectedValue(TEST_API_ERROR);
await createComponentAndSubmit();
+ await nextTick();
});
it('should not redirect', () => {
@@ -338,7 +339,7 @@ describe('Snippet Edit app', () => {
it('should flash', () => {
// Apollo automatically wraps the resolver's error in a NetworkError
expect(createFlash).toHaveBeenCalledWith({
- message: `Can't update snippet: Network error: ${TEST_API_ERROR.message}`,
+ message: `Can't update snippet: ${TEST_API_ERROR.message}`,
});
});
@@ -348,7 +349,7 @@ describe('Snippet Edit app', () => {
// eslint-disable-next-line no-console
expect(console.error).toHaveBeenCalledWith(
'[gitlab] unexpected error while updating snippet',
- expect.objectContaining({ message: `Network error: ${TEST_API_ERROR.message}` }),
+ expect.objectContaining({ message: `${TEST_API_ERROR.message}` }),
);
});
});
diff --git a/spec/frontend/terraform/components/terraform_list_spec.js b/spec/frontend/terraform/components/terraform_list_spec.js
index 803f1723645..c8b4cd564d9 100644
--- a/spec/frontend/terraform/components/terraform_list_spec.js
+++ b/spec/frontend/terraform/components/terraform_list_spec.js
@@ -99,6 +99,7 @@ describe('TerraformList', () => {
nodes: states,
count: states.length,
pageInfo: {
+ __typename: 'PageInfo',
hasNextPage: true,
hasPreviousPage: false,
startCursor: 'prev',
diff --git a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
index 7808bdb8db3..0da9939e97f 100644
--- a/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
+++ b/spec/frontend/vue_shared/components/runner_instructions/runner_instructions_modal_spec.js
@@ -77,6 +77,7 @@ describe('RunnerInstructionsModal component', () => {
runnerSetupInstructionsHandler = jest.fn().mockResolvedValue(mockGraphqlInstructions);
createComponent();
+ await waitForPromises();
});
afterEach(() => {
@@ -199,7 +200,8 @@ describe('RunnerInstructionsModal component', () => {
expect(findGlLoadingIcon().exists()).toBe(false);
await nextTick();
- await jest.runOnlyPendingTimers();
+ jest.runOnlyPendingTimers();
+ await nextTick();
await nextTick();
expect(findGlLoadingIcon().exists()).toBe(true);
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
index a4199bb3e27..67e1a3ce932 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/labels_select_root_spec.js
@@ -117,9 +117,15 @@ describe('LabelsSelectRoot', () => {
it('renders dropdown value component when query labels is resolved', () => {
expect(findDropdownValue().exists()).toBe(true);
- expect(findDropdownValue().props('selectedLabels')).toEqual(
- issuableLabelsQueryResponse.data.workspace.issuable.labels.nodes,
- );
+ expect(findDropdownValue().props('selectedLabels')).toEqual([
+ {
+ color: '#330066',
+ description: null,
+ id: 'gid://gitlab/ProjectLabel/1',
+ title: 'Label1',
+ textColor: '#000000',
+ },
+ ]);
});
it('emits `onLabelRemove` event on dropdown value label remove event', () => {
diff --git a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
index 6ef54ce37ce..49224fb915c 100644
--- a/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
+++ b/spec/frontend/vue_shared/components/sidebar/labels_select_widget/mock_data.js
@@ -96,6 +96,7 @@ export const workspaceLabelsQueryResponse = {
labels: {
nodes: [
{
+ __typename: 'Label',
color: '#330066',
description: null,
id: 'gid://gitlab/ProjectLabel/1',
@@ -103,6 +104,7 @@ export const workspaceLabelsQueryResponse = {
textColor: '#000000',
},
{
+ __typename: 'Label',
color: '#2f7b2e',
description: null,
id: 'gid://gitlab/ProjectLabel/2',
@@ -125,6 +127,7 @@ export const issuableLabelsQueryResponse = {
labels: {
nodes: [
{
+ __typename: 'Label',
color: '#330066',
description: null,
id: 'gid://gitlab/ProjectLabel/1',
diff --git a/spec/frontend/vue_shared/components/user_select_spec.js b/spec/frontend/vue_shared/components/user_select_spec.js
index 8994e16e517..411a15e1c74 100644
--- a/spec/frontend/vue_shared/components/user_select_spec.js
+++ b/spec/frontend/vue_shared/components/user_select_spec.js
@@ -104,14 +104,14 @@ describe('User select dropdown', () => {
createComponent({ participantsQueryHandler: mockError });
await waitForPromises();
- expect(wrapper.emitted('error')).toEqual([[], []]);
+ expect(wrapper.emitted('error')).toEqual([[]]);
});
it('emits an `error` event if search query was rejected', async () => {
createComponent({ searchQueryHandler: mockError });
await waitForSearch();
- expect(wrapper.emitted('error')).toEqual([[], []]);
+ expect(wrapper.emitted('error')).toEqual([[]]);
});
it('renders current user if they are not in participants or assignees', async () => {
diff --git a/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js b/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js
index 0585b6c55fd..65eb42ef053 100644
--- a/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js
+++ b/spec/frontend/vue_shared/issuable/list/components/issuable_item_spec.js
@@ -10,7 +10,6 @@ import { mockIssuable, mockRegularLabel, mockScopedLabel } from '../mock_data';
const createComponent = ({
issuableSymbol = '#',
issuable = mockIssuable,
- enableLabelPermalinks = true,
showCheckbox = true,
slots = {},
} = {}) =>
@@ -18,7 +17,6 @@ const createComponent = ({
propsData: {
issuableSymbol,
issuable,
- enableLabelPermalinks,
showDiscussions: true,
showCheckbox,
},
@@ -212,23 +210,13 @@ describe('IssuableItem', () => {
});
describe('labelTarget', () => {
- it('returns target string for a provided label param when `enableLabelPermalinks` is true', () => {
+ it('returns target string for a provided label param', () => {
wrapper = createComponent();
expect(wrapper.vm.labelTarget(mockRegularLabel)).toBe(
'?label_name[]=Documentation%20Update',
);
});
-
- it('returns string "#" for a provided label param when `enableLabelPermalinks` is false', async () => {
- wrapper = createComponent({
- enableLabelPermalinks: false,
- });
-
- await nextTick();
-
- expect(wrapper.vm.labelTarget(mockRegularLabel)).toBe('#');
- });
});
});
diff --git a/spec/frontend/vue_shared/security_reports/mock_data.js b/spec/frontend/vue_shared/security_reports/mock_data.js
index 2b1513bb0f8..dac9accbbf5 100644
--- a/spec/frontend/vue_shared/security_reports/mock_data.js
+++ b/spec/frontend/vue_shared/security_reports/mock_data.js
@@ -324,7 +324,9 @@ export const secretDetectionDiffSuccessMock = {
export const securityReportMergeRequestDownloadPathsQueryNoArtifactsResponse = {
project: {
+ id: 'project-1',
mergeRequest: {
+ id: 'mr-1',
headPipeline: {
id: 'gid://gitlab/Ci::Pipeline/176',
jobs: {
diff --git a/spec/frontend/work_items/pages/work_item_root_spec.js b/spec/frontend/work_items/pages/work_item_root_spec.js
index ea26b2b4fb3..d0e40680b55 100644
--- a/spec/frontend/work_items/pages/work_item_root_spec.js
+++ b/spec/frontend/work_items/pages/work_item_root_spec.js
@@ -23,7 +23,11 @@ describe('Work items root component', () => {
const findTitle = () => wrapper.findComponent(ItemTitle);
const createComponent = ({ queryResponse = workItemQueryResponse } = {}) => {
- fakeApollo = createMockApollo([], resolvers);
+ fakeApollo = createMockApollo([], resolvers, {
+ possibleTypes: {
+ LocalWorkItemWidget: ['LocalTitleWidget'],
+ },
+ });
fakeApollo.clients.defaultClient.cache.writeQuery({
query: workItemQuery,
variables: {
diff --git a/spec/graphql/mutations/ci/runner/delete_spec.rb b/spec/graphql/mutations/ci/runner/delete_spec.rb
index 9f30c95edd5..b53ee30f826 100644
--- a/spec/graphql/mutations/ci/runner/delete_spec.rb
+++ b/spec/graphql/mutations/ci/runner/delete_spec.rb
@@ -11,9 +11,7 @@ RSpec.describe Mutations::Ci::Runner::Delete do
let(:current_ctx) { { current_user: user } }
let(:mutation_params) do
- {
- id: runner.to_global_id
- }
+ { id: runner.to_global_id }
end
specify { expect(described_class).to require_graphql_authorizations(:delete_runner) }
@@ -57,6 +55,10 @@ RSpec.describe Mutations::Ci::Runner::Delete do
it 'deletes runner' do
mutation_params[:id] = project_runner.to_global_id
+ expect_next_instance_of(::Ci::UnregisterRunnerService, project_runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
expect { subject }.to change { Ci::Runner.count }.by(-1)
expect(subject[:errors]).to be_empty
end
@@ -73,6 +75,9 @@ RSpec.describe Mutations::Ci::Runner::Delete do
it 'does not delete project runner' do
mutation_params[:id] = two_projects_runner.to_global_id
+ allow_next_instance_of(::Ci::UnregisterRunnerService) do |service|
+ expect(service).not_to receive(:execute).once
+ end
expect { subject }.not_to change { Ci::Runner.count }
expect(subject[:errors]).to contain_exactly("Runner #{two_projects_runner.to_global_id} associated with more than one project")
end
@@ -84,6 +89,10 @@ RSpec.describe Mutations::Ci::Runner::Delete do
let(:current_ctx) { { current_user: admin_user } }
it 'deletes runner' do
+ expect_next_instance_of(::Ci::UnregisterRunnerService, runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
expect { subject }.to change { Ci::Runner.count }.by(-1)
expect(subject[:errors]).to be_empty
end
diff --git a/spec/lib/gitlab/ci/lint_spec.rb b/spec/lib/gitlab/ci/lint_spec.rb
index 1e433d7854a..652fe0c4f94 100644
--- a/spec/lib/gitlab/ci/lint_spec.rb
+++ b/spec/lib/gitlab/ci/lint_spec.rb
@@ -7,9 +7,10 @@ RSpec.describe Gitlab::Ci::Lint do
let_it_be(:user) { create(:user) }
let(:lint) { described_class.new(project: project, current_user: user) }
+ let(:ref) { project.default_branch }
describe '#validate' do
- subject { lint.validate(content, dry_run: dry_run) }
+ subject { lint.validate(content, dry_run: dry_run, ref: ref) }
shared_examples 'content is valid' do
let(:content) do
@@ -251,6 +252,29 @@ RSpec.describe Gitlab::Ci::Lint do
end
end
+ context 'when using a ref other than the default branch' do
+ let(:ref) { 'feature' }
+ let(:content) do
+ <<~YAML
+ build:
+ stage: build
+ script: echo 1
+ rules:
+ - if: "$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH"
+ test:
+ stage: test
+ script: echo 2
+ rules:
+ - if: "$CI_COMMIT_BRANCH != $CI_DEFAULT_BRANCH"
+ YAML
+ end
+
+ it 'includes only jobs that are excluded on the default branch' do
+ expect(subject.jobs.size).to eq(1)
+ expect(subject.jobs[0][:name]).to eq('test')
+ end
+ end
+
it_behaves_like 'sets merged yaml'
include_context 'advanced validations' do
diff --git a/spec/requests/api/ci/runners_spec.rb b/spec/requests/api/ci/runners_spec.rb
index 466ae29cc4c..c309140362e 100644
--- a/spec/requests/api/ci/runners_spec.rb
+++ b/spec/requests/api/ci/runners_spec.rb
@@ -530,6 +530,10 @@ RSpec.describe API::Ci::Runners do
context 'admin user' do
context 'when runner is shared' do
it 'deletes runner' do
+ expect_next_instance_of(Ci::UnregisterRunnerService, shared_runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
expect do
delete api("/runners/#{shared_runner.id}", admin)
@@ -544,6 +548,10 @@ RSpec.describe API::Ci::Runners do
context 'when runner is not shared' do
it 'deletes used project runner' do
+ expect_next_instance_of(Ci::UnregisterRunnerService, project_runner) do |service|
+ expect(service).to receive(:execute).once.and_call_original
+ end
+
expect do
delete api("/runners/#{project_runner.id}", admin)
@@ -553,6 +561,10 @@ RSpec.describe API::Ci::Runners do
end
it 'returns 404 if runner does not exist' do
+ allow_next_instance_of(Ci::UnregisterRunnerService) do |service|
+ expect(service).not_to receive(:execute)
+ end
+
delete api('/runners/0', admin)
expect(response).to have_gitlab_http_status(:not_found)
@@ -634,6 +646,10 @@ RSpec.describe API::Ci::Runners do
context 'unauthorized user' do
it 'does not delete project runner' do
+ allow_next_instance_of(Ci::UnregisterRunnerService) do |service|
+ expect(service).not_to receive(:execute)
+ end
+
delete api("/runners/#{project_runner.id}")
expect(response).to have_gitlab_http_status(:unauthorized)
diff --git a/spec/requests/api/graphql/mutations/work_items/create_spec.rb b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
index e7a0c7753fb..006fe03378f 100644
--- a/spec/requests/api/graphql/mutations/work_items/create_spec.rb
+++ b/spec/requests/api/graphql/mutations/work_items/create_spec.rb
@@ -47,6 +47,18 @@ RSpec.describe 'Create a work item' do
)
end
+ context 'when input is invalid' do
+ let(:input) { { 'title' => '', 'workItemTypeId' => WorkItems::Type.default_by_type(:task).to_global_id.to_s } }
+
+ it 'does not create and returns validation errors' do
+ expect do
+ post_graphql_mutation(mutation, current_user: current_user)
+ end.to not_change(WorkItem, :count)
+
+ expect(graphql_mutation_response(:work_item_create)['errors']).to contain_exactly("Title can't be blank")
+ end
+ end
+
it_behaves_like 'has spam protection' do
let(:mutation_class) { ::Mutations::WorkItems::Create }
end
diff --git a/spec/services/ci/unregister_runner_service_spec.rb b/spec/services/ci/unregister_runner_service_spec.rb
new file mode 100644
index 00000000000..f427e04f228
--- /dev/null
+++ b/spec/services/ci/unregister_runner_service_spec.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+RSpec.describe ::Ci::UnregisterRunnerService, '#execute' do
+ subject { described_class.new(runner).execute }
+
+ let(:runner) { create(:ci_runner) }
+
+ it 'destroys runner' do
+ expect(runner).to receive(:destroy).once.and_call_original
+ expect { subject }.to change { Ci::Runner.count }.by(-1)
+ expect(runner[:errors]).to be_nil
+ end
+end
diff --git a/spec/services/work_items/create_service_spec.rb b/spec/services/work_items/create_service_spec.rb
index 2c054ae59a0..f495e967b26 100644
--- a/spec/services/work_items/create_service_spec.rb
+++ b/spec/services/work_items/create_service_spec.rb
@@ -5,34 +5,46 @@ require 'spec_helper'
RSpec.describe WorkItems::CreateService do
include AfterNextHelpers
- let_it_be(:group) { create(:group) }
- let_it_be_with_reload(:project) { create(:project, group: group) }
- let_it_be(:user) { create(:user) }
+ let_it_be_with_reload(:project) { create(:project) }
+ let_it_be(:guest) { create(:user) }
+ let_it_be(:user_with_no_access) { create(:user) }
let(:spam_params) { double }
+ let(:current_user) { guest }
+ let(:opts) do
+ {
+ title: 'Awesome work_item',
+ description: 'please fix'
+ }
+ end
+
+ before_all do
+ project.add_guest(guest)
+ end
describe '#execute' do
- let(:work_item) { described_class.new(project: project, current_user: user, params: opts, spam_params: spam_params).execute }
+ subject(:service_result) { described_class.new(project: project, current_user: current_user, params: opts, spam_params: spam_params).execute }
before do
stub_spam_services
end
- context 'when params are valid' do
- before_all do
- project.add_guest(user)
- end
+ context 'when user is not allowed to create a work item in the project' do
+ let(:current_user) { user_with_no_access }
+
+ it { is_expected.to be_error }
- let(:opts) do
- {
- title: 'Awesome work_item',
- description: 'please fix'
- }
+ it 'returns an access error' do
+ expect(service_result.errors).to contain_exactly('Operation not allowed')
end
+ end
+ context 'when params are valid' do
it 'created instance is a WorkItem' do
expect(Issuable::CommonSystemNotesService).to receive_message_chain(:new, :execute)
+ work_item = service_result[:work_item]
+
expect(work_item).to be_persisted
expect(work_item).to be_a(::WorkItem)
expect(work_item.title).to eq('Awesome work_item')
@@ -41,17 +53,17 @@ RSpec.describe WorkItems::CreateService do
end
end
- context 'checking spam' do
- let(:params) do
- {
- title: 'Spam work_item'
- }
- end
+ context 'when params are invalid' do
+ let(:opts) { { title: '' } }
- subject do
- described_class.new(project: project, current_user: user, params: params, spam_params: spam_params)
+ it { is_expected.to be_error }
+
+ it 'returns validation errors' do
+ expect(service_result.errors).to contain_exactly("Title can't be blank")
end
+ end
+ context 'checking spam' do
it 'executes SpamActionService' do
expect_next_instance_of(
Spam::SpamActionService,
@@ -65,7 +77,7 @@ RSpec.describe WorkItems::CreateService do
expect(instance).to receive(:execute)
end
- subject.execute
+ service_result
end
end
end
diff --git a/yarn.lock b/yarn.lock
index 22e6b2b569a..48a86fd48dd 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -2,6 +2,25 @@
# yarn lockfile v1
+"@apollo/client@^3.2.5", "@apollo/client@^3.3.11":
+ version "3.3.11"
+ resolved "https://registry.yarnpkg.com/@apollo/client/-/client-3.3.11.tgz#125051405e83dc899d471d43b79fd6045d92a802"
+ integrity sha512-54+D5FB6RJlQ+g37f432gaexnyvDsG5X6L9VO5kqN54HJlbF8hCf/8CXtAQEHCWodAwZhy6kOLp2RM96829q3A==
+ dependencies:
+ "@graphql-typed-document-node/core" "^3.0.0"
+ "@types/zen-observable" "^0.8.0"
+ "@wry/context" "^0.5.2"
+ "@wry/equality" "^0.3.0"
+ fast-json-stable-stringify "^2.0.0"
+ graphql-tag "^2.12.0"
+ hoist-non-react-statics "^3.3.2"
+ optimism "^0.14.0"
+ prop-types "^15.7.2"
+ symbol-observable "^2.0.0"
+ ts-invariant "^0.6.0"
+ tslib "^1.10.0"
+ zen-observable "^0.8.14"
+
"@babel/code-frame@7.12.11":
version "7.12.11"
resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.12.11.tgz#f4ad435aa263db935b8f10f2c552d23fb716a63f"
@@ -810,7 +829,7 @@
core-js-pure "^3.0.0"
regenerator-runtime "^0.13.4"
-"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.13.10", "@babel/runtime@^7.8.4", "@babel/runtime@^7.9.2":
+"@babel/runtime@^7.10.2", "@babel/runtime@^7.10.3", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.8.4":
version "7.14.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.14.0.tgz#46794bc20b612c5f75e62dd071e24dfd95f1cbe6"
integrity sha512-JELkvo/DlpNdJ7dlyw/eY7E0suy5i5GQH+Vlxaq1nsNJ+H7f4Vtv3jMeCEgRhZZQFXTjldYfQgv2qmM6M1v5wA==
@@ -1149,6 +1168,11 @@
tslib "~2.3.0"
value-or-promise "1.0.11"
+"@graphql-typed-document-node/core@^3.0.0":
+ version "3.1.0"
+ resolved "https://registry.yarnpkg.com/@graphql-typed-document-node/core/-/core-3.1.0.tgz#0eee6373e11418bfe0b5638f654df7a4ca6a3950"
+ integrity sha512-wYn6r8zVZyQJ6rQaALBEln5B1pzxb9shV5Ef97kTvn6yVGrqyXVnDqnU24MXnFubR+rZjBY9NWuxX3FB2sTsjg==
+
"@humanwhocodes/config-array@^0.5.0":
version "0.5.0"
resolved "https://registry.yarnpkg.com/@humanwhocodes/config-array/-/config-array-0.5.0.tgz#1407967d4c6eecd7388f83acf1eaf4d0c6e58ef9"
@@ -1928,7 +1952,7 @@
resolved "https://registry.yarnpkg.com/@types/minimist/-/minimist-1.2.2.tgz#ee771e2ba4b3dc5b372935d549fd9617bf345b8c"
integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==
-"@types/node@*", "@types/node@14.17.5", "@types/node@>=6":
+"@types/node@*", "@types/node@14.17.5":
version "14.17.5"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.5.tgz#b59daf6a7ffa461b5648456ca59050ba8e40ed54"
integrity sha512-bjqH2cX/O33jXT/UmReo2pM7DIJREPMnarixbQ57DOOzzFaI6D2+IcwaJQaJpv0M1E9TIhPCYVxrkcityLjlqA==
@@ -2090,6 +2114,11 @@
dependencies:
"@types/estree" "*"
+"@types/ungap__global-this@^0.3.1":
+ version "0.3.1"
+ resolved "https://registry.yarnpkg.com/@types/ungap__global-this/-/ungap__global-this-0.3.1.tgz#18ce9f657da556037a29d50604335614ce703f4c"
+ integrity sha512-+/DsiV4CxXl6ZWefwHZDXSe1Slitz21tom38qPCaG0DYCS1NnDPIQDTKcmQ/tvK/edJUKkmuIDBJbmKDiB0r/g==
+
"@types/websocket@1.0.4":
version "1.0.4"
resolved "https://registry.yarnpkg.com/@types/websocket/-/websocket-1.0.4.tgz#1dc497280d8049a5450854dd698ee7e6ea9e60b8"
@@ -2144,6 +2173,11 @@
semver "^6.3.0"
tsutils "^3.17.1"
+"@ungap/global-this@^0.4.2":
+ version "0.4.4"
+ resolved "https://registry.yarnpkg.com/@ungap/global-this/-/global-this-0.4.4.tgz#8a1b2cfcd3e26e079a847daba879308c924dd695"
+ integrity sha512-mHkm6FvepJECMNthFuIgpAEFmPOk71UyXuIxYfjytvFTnSDBIz7jmViO+LfHI/AjrazWije0PnSP3+/NlwzqtA==
+
"@vue/component-compiler-utils@^3.1.0":
version "3.1.1"
resolved "https://registry.yarnpkg.com/@vue/component-compiler-utils/-/component-compiler-utils-3.1.1.tgz#d4ef8f80292674044ad6211e336a302e4d2a6575"
@@ -2330,20 +2364,26 @@
resolved "https://registry.yarnpkg.com/@webpack-cli/serve/-/serve-1.6.1.tgz#0de2875ac31b46b6c5bb1ae0a7d7f0ba5678dffe"
integrity sha512-gNGTiTrjEVQ0OcVnzsRSqTxaBSr+dmTfm+qJsCDluky8uhdLWep7Gcr62QsAKHTMxjCS/8nEITsmFAhfIx+QSw==
-"@wry/context@^0.4.0":
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.4.4.tgz#e50f5fa1d6cfaabf2977d1fda5ae91717f8815f8"
- integrity sha512-LrKVLove/zw6h2Md/KZyWxIkFM6AoyKp71OqpH9Hiip1csjPVoD3tPxlbQUNxEnHENks3UGgNpSBCAfq9KWuag==
+"@wry/context@^0.5.2":
+ version "0.5.4"
+ resolved "https://registry.yarnpkg.com/@wry/context/-/context-0.5.4.tgz#b6c28038872e0a0e1ff14eb40b5bf4cab2ab4e06"
+ integrity sha512-/pktJKHUXDr4D6TJqWgudOPJW2Z+Nb+bqk40jufA3uTkLbnCRKdJPiYDIa/c7mfcPH8Hr6O8zjCERpg5Sq04Zg==
dependencies:
- "@types/node" ">=6"
- tslib "^1.9.3"
+ tslib "^1.14.1"
-"@wry/equality@^0.1.2":
- version "0.1.9"
- resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.1.9.tgz#b13e18b7a8053c6858aa6c85b54911fb31e3a909"
- integrity sha512-mB6ceGjpMGz1ZTza8HYnrPGos2mC6So4NhS1PtZ8s4Qt0K7fBiIGhpSxUbQmhwcSWE3no+bYxmI2OL6KuXYmoQ==
+"@wry/equality@^0.3.0":
+ version "0.3.3"
+ resolved "https://registry.yarnpkg.com/@wry/equality/-/equality-0.3.3.tgz#1ec8f9af01d40a2eb00d055d9a3173315126c648"
+ integrity sha512-pMrKHIgDAWxLDTGsbaVag+USmwZ2+gGrSBrtyGUxp2pxRg1Cad70lI/hd0NTPtJ4zJxN16EQ679U1Rts83AF5g==
dependencies:
- tslib "^1.9.3"
+ tslib "^1.14.1"
+
+"@wry/trie@^0.2.1":
+ version "0.2.2"
+ resolved "https://registry.yarnpkg.com/@wry/trie/-/trie-0.2.2.tgz#99f20f0fcbbcda17006069b155c826cbabfc402f"
+ integrity sha512-OxqBB39x6MfHaa2HpMiRMfhuUnQTddD32Ko020eBeJXq87ivX6xnSSnzKHVbA21p7iqBASz8n/07b6W5wW1BVQ==
+ dependencies:
+ tslib "^1.14.1"
"@xtuc/ieee754@^1.2.0":
version "1.2.0"
@@ -2556,113 +2596,14 @@ anymatch@^3.0.3, anymatch@~3.1.1:
normalize-path "^3.0.0"
picomatch "^2.0.4"
-apollo-cache-inmemory@^1.6.6:
- version "1.6.6"
- resolved "https://registry.yarnpkg.com/apollo-cache-inmemory/-/apollo-cache-inmemory-1.6.6.tgz#56d1f2a463a6b9db32e9fa990af16d2a008206fd"
- integrity sha512-L8pToTW/+Xru2FFAhkZ1OA9q4V4nuvfoPecBM34DecAugUZEBhI2Hmpgnzq2hTKZ60LAMrlqiASm0aqAY6F8/A==
- dependencies:
- apollo-cache "^1.3.5"
- apollo-utilities "^1.3.4"
- optimism "^0.10.0"
- ts-invariant "^0.4.0"
- tslib "^1.10.0"
-
-apollo-cache@1.3.5, apollo-cache@^1.3.5:
- version "1.3.5"
- resolved "https://registry.yarnpkg.com/apollo-cache/-/apollo-cache-1.3.5.tgz#9dbebfc8dbe8fe7f97ba568a224bca2c5d81f461"
- integrity sha512-1XoDy8kJnyWY/i/+gLTEbYLnoiVtS8y7ikBr/IfmML4Qb+CM7dEEbIUOjnY716WqmZ/UpXIxTfJsY7rMcqiCXA==
- dependencies:
- apollo-utilities "^1.3.4"
- tslib "^1.10.0"
-
-apollo-client@^2.6.10:
- version "2.6.10"
- resolved "https://registry.yarnpkg.com/apollo-client/-/apollo-client-2.6.10.tgz#86637047b51d940c8eaa771a4ce1b02df16bea6a"
- integrity sha512-jiPlMTN6/5CjZpJOkGeUV0mb4zxx33uXWdj/xQCfAMkuNAC3HN7CvYDyMHHEzmcQ5GV12LszWoQ/VlxET24CtA==
- dependencies:
- "@types/zen-observable" "^0.8.0"
- apollo-cache "1.3.5"
- apollo-link "^1.0.0"
- apollo-utilities "1.3.4"
- symbol-observable "^1.0.2"
- ts-invariant "^0.4.0"
- tslib "^1.10.0"
- zen-observable "^0.8.0"
-
-apollo-link-batch-http@^1.2.14:
- version "1.2.14"
- resolved "https://registry.yarnpkg.com/apollo-link-batch-http/-/apollo-link-batch-http-1.2.14.tgz#4502109d3f32a94d88eabd3a89274ae3a6e2f56f"
- integrity sha512-LFUmfV3OXR3Er+zSgFxPY/qUe4Wyx0HS1euJZ36RCCaDvPegr24C9OQgKFScHy91VbjRTtFUyjXXVq1xFGPMvQ==
- dependencies:
- apollo-link "^1.2.14"
- apollo-link-batch "^1.1.15"
- apollo-link-http-common "^0.2.16"
- tslib "^1.9.3"
-
-apollo-link-batch@^1.1.15:
- version "1.1.15"
- resolved "https://registry.yarnpkg.com/apollo-link-batch/-/apollo-link-batch-1.1.15.tgz#3a5b8c7d9cf1b7840ce630238249b95070e75e54"
- integrity sha512-XbfQI/FNxJW9RSgJTfAl7RDFxxN77425yDtT7YgsImH4/2NQ+U4SWN6thWE3ZU1Wf7ktXd+XFa3KkenBRTybOQ==
- dependencies:
- apollo-link "^1.2.14"
- tslib "^1.9.3"
-
-apollo-link-error@^1.1.13:
- version "1.1.13"
- resolved "https://registry.yarnpkg.com/apollo-link-error/-/apollo-link-error-1.1.13.tgz#c1a1bb876ffe380802c8df0506a32c33aad284cd"
- integrity sha512-jAZOOahJU6bwSqb2ZyskEK1XdgUY9nkmeclCrW7Gddh1uasHVqmoYc4CKdb0/H0Y1J9lvaXKle2Wsw/Zx1AyUg==
- dependencies:
- apollo-link "^1.2.14"
- apollo-link-http-common "^0.2.16"
- tslib "^1.9.3"
-
-apollo-link-http-common@^0.2.14, apollo-link-http-common@^0.2.16:
- version "0.2.16"
- resolved "https://registry.yarnpkg.com/apollo-link-http-common/-/apollo-link-http-common-0.2.16.tgz#756749dafc732792c8ca0923f9a40564b7c59ecc"
- integrity sha512-2tIhOIrnaF4UbQHf7kjeQA/EmSorB7+HyJIIrUjJOKBgnXwuexi8aMecRlqTIDWcyVXCeqLhUnztMa6bOH/jTg==
- dependencies:
- apollo-link "^1.2.14"
- ts-invariant "^0.4.0"
- tslib "^1.9.3"
-
-apollo-link-http@^1.5.17:
- version "1.5.17"
- resolved "https://registry.yarnpkg.com/apollo-link-http/-/apollo-link-http-1.5.17.tgz#499e9f1711bf694497f02c51af12d82de5d8d8ba"
- integrity sha512-uWcqAotbwDEU/9+Dm9e1/clO7hTB2kQ/94JYcGouBVLjoKmTeJTUPQKcJGpPwUjZcSqgYicbFqQSoJIW0yrFvg==
- dependencies:
- apollo-link "^1.2.14"
- apollo-link-http-common "^0.2.16"
- tslib "^1.9.3"
-
-apollo-link@^1.0.0, apollo-link@^1.2.12, apollo-link@^1.2.14:
- version "1.2.14"
- resolved "https://registry.yarnpkg.com/apollo-link/-/apollo-link-1.2.14.tgz#3feda4b47f9ebba7f4160bef8b977ba725b684d9"
- integrity sha512-p67CMEFP7kOG1JZ0ZkYZwRDa369w5PIjtMjvrQd/HnIV8FRsHRqLqK+oAZQnFa1DDdZtOtHTi+aMIW6EatC2jg==
- dependencies:
- apollo-utilities "^1.3.0"
- ts-invariant "^0.4.0"
- tslib "^1.9.3"
- zen-observable-ts "^0.8.21"
-
-apollo-upload-client@^13.0.0:
- version "13.0.0"
- resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-13.0.0.tgz#146d1ddd85d711fcac8ca97a72d3ca6787f2b71b"
- integrity sha512-lJ9/bk1BH1lD15WhWRha2J3+LrXrPIX5LP5EwiOUHv8PCORp4EUrcujrA3rI5hZeZygrTX8bshcuMdpqpSrvtA==
+apollo-upload-client@^14.1.3:
+ version "14.1.3"
+ resolved "https://registry.yarnpkg.com/apollo-upload-client/-/apollo-upload-client-14.1.3.tgz#91f39011897bd08e99c0de0164e77ad2f3402247"
+ integrity sha512-X2T+7pHk5lcaaWnvP9h2tuAAMCzOW6/9juedQ0ZuGp3Ufl81BpDISlCs0o6u29wBV0RRT/QpMU2gbP+3FCfVpQ==
dependencies:
- "@babel/runtime" "^7.9.2"
- apollo-link "^1.2.12"
- apollo-link-http-common "^0.2.14"
- extract-files "^8.0.0"
-
-apollo-utilities@1.3.4, apollo-utilities@^1.3.0, apollo-utilities@^1.3.4:
- version "1.3.4"
- resolved "https://registry.yarnpkg.com/apollo-utilities/-/apollo-utilities-1.3.4.tgz#6129e438e8be201b6c55b0f13ce49d2c7175c9cf"
- integrity sha512-pk2hiWrCXMAy2fRPwEyhvka+mqwzeP60Jr1tRYi5xru+3ko94HI9o6lK0CT33/w4RDlxWchmdhDCrvdr+pHCig==
- dependencies:
- "@wry/equality" "^0.1.2"
- fast-json-stable-stringify "^2.0.0"
- ts-invariant "^0.4.0"
- tslib "^1.10.0"
+ "@apollo/client" "^3.2.5"
+ "@babel/runtime" "^7.12.5"
+ extract-files "^9.0.0"
aproba@^1.1.1:
version "1.2.0"
@@ -5760,10 +5701,10 @@ extract-files@11.0.0:
resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-11.0.0.tgz#b72d428712f787eef1f5193aff8ab5351ca8469a"
integrity sha512-FuoE1qtbJ4bBVvv94CC7s0oTnKUGvQs+Rjf1L2SJFfS+HTVVjhPFtehPdQ0JiGPqVNfSSZvL5yzHHQq2Z4WNhQ==
-extract-files@^8.0.0:
- version "8.1.0"
- resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-8.1.0.tgz#46a0690d0fe77411a2e3804852adeaa65cd59288"
- integrity sha512-PTGtfthZK79WUMk+avLmwx3NGdU8+iVFXC2NMGxKsn0MnihOG2lvumj+AZo8CTwTrwjXDgZ5tztbRlEdRjBonQ==
+extract-files@^9.0.0:
+ version "9.0.0"
+ resolved "https://registry.yarnpkg.com/extract-files/-/extract-files-9.0.0.tgz#8a7744f2437f81f5ed3250ed9f1550de902fe54a"
+ integrity sha512-CvdFfHkC95B4bBBk36hcEmvdR2awOdhhVUYH6S/zrVj3477zven/fJMYg7121h4T1xHZC+tetUpubpAhxwI7hQ==
extract-from-css@^0.4.4:
version "0.4.4"
@@ -6306,10 +6247,12 @@ graphql-sse@^1.0.1:
resolved "https://registry.yarnpkg.com/graphql-sse/-/graphql-sse-1.0.4.tgz#051598b0e06c225327aac659f19fcc18bcaa0191"
integrity sha512-oB43ifRcEdElgep9jTP9qsj5cJ7Ny/1tAFyIl1W3A0hXRRg/P71tUHzMFBrRkEsJ9IA7MTp+RKSJfh52QR6PBQ==
-graphql-tag@^2.11.0:
- version "2.11.0"
- resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.11.0.tgz#1deb53a01c46a7eb401d6cb59dec86fa1cccbffd"
- integrity sha512-VmsD5pJqWJnQZMUeRwrDhfgoyqcfwEkvtpANqcoUG8/tOLkwNgU9mzub/Mc78OJMhHjx7gfAMTxzdG43VGg3bA==
+graphql-tag@^2.11.0, graphql-tag@^2.12.0:
+ version "2.12.1"
+ resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.1.tgz#b065ef885e4800e4afd0842811b718a205f4aa58"
+ integrity sha512-LPewEE1vzGkHnCO8zdOGogKsHHBdtpGyihow1UuMwp6RnZa0lAS7NcbvltLOuo4pi5diQCPASAXZkQq44ffixA==
+ dependencies:
+ tslib "^1.14.1"
graphql-ws@^5.4.1:
version "5.5.3"
@@ -6473,6 +6416,20 @@ hmac-drbg@^1.0.1:
minimalistic-assert "^1.0.0"
minimalistic-crypto-utils "^1.0.1"
+hoist-non-react-statics@^3.3.2:
+ version "3.3.2"
+ resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
+ integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
+ dependencies:
+ react-is "^16.7.0"
+
+homedir-polyfill@^1.0.1:
+ version "1.0.1"
+ resolved "https://registry.yarnpkg.com/homedir-polyfill/-/homedir-polyfill-1.0.1.tgz#4c2bbc8a758998feebf5ed68580f76d46768b4bc"
+ integrity sha1-TCu8inWJmP7r9e1oWA921GdotLw=
+ dependencies:
+ parse-passwd "^1.0.0"
+
hosted-git-info@^2.1.4:
version "2.8.8"
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
@@ -8141,7 +8098,12 @@ lodash@^4.17.10, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
-loose-envify@^1.0.0:
+loglevel@^1.6.8:
+ version "1.7.1"
+ resolved "https://registry.yarnpkg.com/loglevel/-/loglevel-1.7.1.tgz#005fde2f5e6e47068f935ff28573e125ef72f197"
+ integrity sha512-Hesni4s5UkWkwCGJMQGAh71PaLUmKFM60dHvq0zi/vDhhrzuk+4GgNbTXJ12YYQJn6ZKBDNIjYcuQGKudvqrIw==
+
+loose-envify@^1.0.0, loose-envify@^1.4.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
@@ -8641,10 +8603,10 @@ mkdirp@^1.0.3, mkdirp@^1.0.4, mkdirp@~1.0.3:
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-1.0.4.tgz#3eb5ed62622756d79a5f0e2a221dfebad75c2f7e"
integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==
-mock-apollo-client@^0.7.0:
- version "0.7.0"
- resolved "https://registry.yarnpkg.com/mock-apollo-client/-/mock-apollo-client-0.7.0.tgz#5f70e75c842a9f3b3da2252f68fd47f2d9955f77"
- integrity sha512-r0ICU01m007W0MwMej0lzlg1REtepDZ15Fyj8Hz9tiW/1TPb0PyHryGykrg9YhfbB8/+ZF2ovz+88yMF75TDoA==
+mock-apollo-client@1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/mock-apollo-client/-/mock-apollo-client-1.2.0.tgz#72543df0d74577d29be1b34cecba8898c7e71451"
+ integrity sha512-zCVHv3p7zvUmen9zce9l965ZrI6rMbrm2/oqGaTerVYOaYskl/cVgTG/L7iIToTIpI7onk/f6tu8hxPXZdyy/g==
moment-mini@^2.24.0:
version "2.24.0"
@@ -8934,6 +8896,11 @@ oauth-sign@~0.9.0:
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455"
integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==
+object-assign@^4.0.1, object-assign@^4.1.1:
+ version "4.1.1"
+ resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
+ integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=
+
object-copy@^0.1.0:
version "0.1.0"
resolved "https://registry.yarnpkg.com/object-copy/-/object-copy-0.1.0.tgz#7e7d858b781bd7c991a41ba975ed3812754e998c"
@@ -9042,12 +9009,20 @@ opener@^1.5.2:
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
-optimism@^0.10.0:
- version "0.10.3"
- resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.10.3.tgz#163268fdc741dea2fb50f300bedda80356445fd7"
- integrity sha512-9A5pqGoQk49H6Vhjb9kPgAeeECfUDF6aIICbMDL23kDLStBn1MWk3YvcZ4xWF9CsSf6XEgvRLkXy4xof/56vVw==
+opn@^5.5.0:
+ version "5.5.0"
+ resolved "https://registry.yarnpkg.com/opn/-/opn-5.5.0.tgz#fc7164fab56d235904c51c3b27da6758ca3b9bfc"
+ integrity sha512-PqHpggC9bLV0VeWcdKhkpxY+3JTzetLSqTCWL/z/tFIbI6G8JCjondXklT1JinczLz2Xib62sSp0T/gKT4KksA==
dependencies:
- "@wry/context" "^0.4.0"
+ is-wsl "^1.1.0"
+
+optimism@^0.14.0:
+ version "0.14.0"
+ resolved "https://registry.yarnpkg.com/optimism/-/optimism-0.14.0.tgz#256fb079a3428585b40a3a8462f907e0abd2fc49"
+ integrity sha512-ygbNt8n4DOCVpkwiLF+IrKKeNHOjtr9aXLWGP9HNJGoblSGsnVbJLstcH6/nE9Xy5ZQtlkSioFQNnthmENW6FQ==
+ dependencies:
+ "@wry/context" "^0.5.2"
+ "@wry/trie" "^0.2.1"
optionator@^0.8.1:
version "0.8.3"
@@ -9642,6 +9617,15 @@ prompts@^2.0.1:
kleur "^3.0.3"
sisteransi "^1.0.4"
+prop-types@^15.7.2:
+ version "15.7.2"
+ resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5"
+ integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==
+ dependencies:
+ loose-envify "^1.4.0"
+ object-assign "^4.1.1"
+ react-is "^16.8.1"
+
prosemirror-collab@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/prosemirror-collab/-/prosemirror-collab-1.2.2.tgz#8d2c0e82779cfef5d051154bd0836428bd6d9c4a"
@@ -9965,7 +9949,7 @@ rc@^1.2.8:
minimist "^1.2.0"
strip-json-comments "~2.0.1"
-react-is@^16.12.0:
+react-is@^16.12.0, react-is@^16.7.0, react-is@^16.8.1:
version "16.13.1"
resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
@@ -10536,7 +10520,7 @@ send@0.17.1:
range-parser "~1.2.1"
statuses "~1.5.0"
-serialize-javascript@^2.1.0, serialize-javascript@^2.1.2:
+serialize-javascript@^2.1.2:
version "2.1.2"
resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-2.1.2.tgz#ecec53b0e0317bdc95ef76ab7074b7384785fa61"
integrity sha512-rs9OggEUF0V4jUSecXazOYsLfu7OGK2qIn3c7IPBiffz32XniEp/TX9Xmc9LQfK2nQ2QKHvZ2oygKUGU0lG4jQ==
@@ -11161,7 +11145,7 @@ stylis@^4.0.10:
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.10.tgz#446512d1097197ab3f02fb3c258358c3f7a14240"
integrity sha512-m3k+dk7QeJw660eIKRRn3xPF6uuvHs/FFzjX3HQ5ove0qYsiygoAhwn5a3IYKaZPo5LrYD0rfVmtv1gNY1uYwg==
-subscriptions-transport-ws@^0.11.0:
+subscriptions-transport-ws@0.11.0, subscriptions-transport-ws@^0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/subscriptions-transport-ws/-/subscriptions-transport-ws-0.11.0.tgz#baf88f050cba51d52afe781de5e81b3c31f89883"
integrity sha512-8D4C6DIH5tGiAIpp5I0wD/xRlNiZAPGHygzCe7VzyzUoxHtawzjNAY9SUTXU05/EY2NMY9/9GF0ycizkXr1CWQ==
@@ -11209,11 +11193,16 @@ swagger-ui-dist@^3.52.3:
resolved "https://registry.yarnpkg.com/swagger-ui-dist/-/swagger-ui-dist-3.52.3.tgz#a09b5cdccac69e3f5f1cbd258654a110119a7f0e"
integrity sha512-7QSY4milmYx5O8dbzU5tTftiaoZt+4JGxahTTBiLAnbTvhTyzum9rsjDIJjC+xeT8Tt1KfB38UuQQjmrh2THDQ==
-symbol-observable@^1.0.2, symbol-observable@^1.0.4:
+symbol-observable@^1.0.4:
version "1.2.0"
resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804"
integrity sha512-e900nM8RRtGhlV36KGEU9k65K3mPb1WV70OdjfxlG2EAuM1noi/E/BaW/uMhL7bPEssK8QV57vN3esixjUvcXQ==
+symbol-observable@^2.0.0:
+ version "2.0.3"
+ resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-2.0.3.tgz#5b521d3d07a43c351055fa43b8355b62d33fd16a"
+ integrity sha512-sQV7phh2WCYAn81oAkakC5qjq2Ml0g8ozqz03wOGnx9dDlG1de6yrF+0RAzSJD8fPUow3PTSMf2SAbOGxb93BA==
+
symbol-tree@^3.2.4:
version "3.2.4"
resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.4.tgz#430637d248ba77e078883951fb9aa0eed7c63fa2"
@@ -11551,11 +11540,13 @@ trim-newlines@^3.0.0:
resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.1.tgz#260a5d962d8b752425b32f3a7db0dcacd176c144"
integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==
-ts-invariant@^0.4.0:
- version "0.4.4"
- resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.4.4.tgz#97a523518688f93aafad01b0e80eb803eb2abd86"
- integrity sha512-uEtWkFM/sdZvRNNDL3Ehu4WVpwaulhwQszV8mrtcdeE8nN00BV9mAmQ88RkrBhFgl9gMgvjJLAQcZbnPXI9mlA==
+ts-invariant@^0.6.0:
+ version "0.6.1"
+ resolved "https://registry.yarnpkg.com/ts-invariant/-/ts-invariant-0.6.1.tgz#eb4c52b45daaca8367abbfd6cff998ea871d592d"
+ integrity sha512-QQgN33g8E8yrdDuH29HASveLtbzMnRRgWh0i/JNTW4+zcLsdIOnfsgEDi/NKx4UckQyuMFt9Ujm6TWLWQ58Kvg==
dependencies:
+ "@types/ungap__global-this" "^0.3.1"
+ "@ungap/global-this" "^0.4.2"
tslib "^1.9.3"
ts-node@^9:
@@ -11585,7 +11576,7 @@ tslib@2.3.0, tslib@^2, tslib@^2.2.0, tslib@~2.3.0:
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e"
integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg==
-tslib@^1.10.0, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
+tslib@^1.10.0, tslib@^1.14.1, tslib@^1.8.1, tslib@^1.9.0, tslib@^1.9.3:
version "1.14.1"
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
@@ -12041,13 +12032,13 @@ vscode-uri@^2.1.1, vscode-uri@^2.1.2:
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-2.1.2.tgz#c8d40de93eb57af31f3c715dd650e2ca2c096f1c"
integrity sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==
-vue-apollo@^3.0.3:
- version "3.0.3"
- resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.3.tgz#7f29558df76eec0f03251847eef153816a261827"
- integrity sha512-WJaQ1v/i46/oIPlKv7J0Tx6tTlbuaeCdhrAbL06h+Zca2gzr5ywjUFpl8ijMTGJsQ+Ph/U4xEpBFBOMxQmL+7g==
+vue-apollo@^3.0.7:
+ version "3.0.7"
+ resolved "https://registry.yarnpkg.com/vue-apollo/-/vue-apollo-3.0.7.tgz#97a031d45641faa4888a6d5a7f71c40834359704"
+ integrity sha512-EUfIn4cJmoflnDJiSNP8gH4fofIEzd0I2AWnd9nhHB8mddmzIfgSNjIRihDcRB10wypYG1OG0GcU335CFgZRfA==
dependencies:
chalk "^2.4.2"
- serialize-javascript "^2.1.0"
+ serialize-javascript "^4.0.0"
throttle-debounce "^2.1.0"
vue-eslint-parser@^7.0.0, vue-eslint-parser@^7.4.1:
@@ -12667,18 +12658,10 @@ yocto-queue@^0.1.0:
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"
integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==
-zen-observable-ts@^0.8.21:
- version "0.8.21"
- resolved "https://registry.yarnpkg.com/zen-observable-ts/-/zen-observable-ts-0.8.21.tgz#85d0031fbbde1eba3cd07d3ba90da241215f421d"
- integrity sha512-Yj3yXweRc8LdRMrCC8nIc4kkjWecPAUVh0TI0OUrWXx6aX790vLcDlWca6I4vsyCGH3LpWxq0dJRcMOFoVqmeg==
- dependencies:
- tslib "^1.9.3"
- zen-observable "^0.8.0"
-
-zen-observable@^0.8.0:
- version "0.8.11"
- resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.11.tgz#d3415885eeeb42ee5abb9821c95bb518fcd6d199"
- integrity sha512-N3xXQVr4L61rZvGMpWe8XoCGX8vhU35dPyQ4fm5CY/KDlG0F75un14hjbckPXTDuKUY6V0dqR2giT6xN8Y4GEQ==
+zen-observable@^0.8.14:
+ version "0.8.15"
+ resolved "https://registry.yarnpkg.com/zen-observable/-/zen-observable-0.8.15.tgz#96415c512d8e3ffd920afd3889604e30b9eaac15"
+ integrity sha512-PQ2PC7R9rslx84ndNBZB/Dkv8V8fZEpk83RLgXtYd0fwUgEjseMn1Dgajh2x6S8QbZAFa9p2qVCEuYZNgve0dQ==
zrender@5.2.1:
version "5.2.1"