Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
514ada7cc9
commit
026ef03e77
|
@ -10,7 +10,7 @@ class-methods-use-this */
|
|||
deprecated_notes_spec.js is the spec for the legacy, jQuery notes application. It has nothing to do with the new, fancy Vue notes app.
|
||||
*/
|
||||
|
||||
import { GlDeprecatedSkeletonLoading as GlSkeletonLoading } from '@gitlab/ui';
|
||||
import { GlSkeletonLoader } from '@gitlab/ui';
|
||||
import Autosize from 'autosize';
|
||||
import $ from 'jquery';
|
||||
import { escape, uniqueId } from 'lodash';
|
||||
|
@ -1233,10 +1233,10 @@ export default class Notes {
|
|||
new Vue({
|
||||
el,
|
||||
components: {
|
||||
GlSkeletonLoading,
|
||||
GlSkeletonLoader,
|
||||
},
|
||||
render(createElement) {
|
||||
return createElement('gl-skeleton-loading');
|
||||
return createElement('gl-skeleton-loader');
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ import {
|
|||
fromSearchToVariables,
|
||||
isSearchFiltered,
|
||||
} from 'ee_else_ce/runner/runner_search_utils';
|
||||
import runnersAdminQuery from 'ee_else_ce/runner/graphql/list/admin_runners.query.graphql';
|
||||
import allRunnersQuery from 'ee_else_ce/runner/graphql/list/all_runners.query.graphql';
|
||||
|
||||
import RegistrationDropdown from '../components/registration/registration_dropdown.vue';
|
||||
import RunnerFilteredSearchBar from '../components/runner_filtered_search_bar.vue';
|
||||
|
@ -64,7 +64,7 @@ export default {
|
|||
},
|
||||
apollo: {
|
||||
runners: {
|
||||
query: runnersAdminQuery,
|
||||
query: allRunnersQuery,
|
||||
fetchPolicy: fetchPolicies.NETWORK_ONLY,
|
||||
variables() {
|
||||
return this.variables;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<script>
|
||||
import { fetchPolicies } from '~/lib/graphql';
|
||||
import { captureException } from '../../sentry_utils';
|
||||
import runnersAdminCountQuery from '../../graphql/list/admin_runners_count.query.graphql';
|
||||
import allRunnersCountQuery from '../../graphql/list/all_runners_count.query.graphql';
|
||||
import groupRunnersCountQuery from '../../graphql/list/group_runners_count.query.graphql';
|
||||
import { INSTANCE_TYPE, GROUP_TYPE } from '../../constants';
|
||||
|
||||
|
@ -53,7 +53,7 @@ export default {
|
|||
count: {
|
||||
query() {
|
||||
if (this.scope === INSTANCE_TYPE) {
|
||||
return runnersAdminCountQuery;
|
||||
return allRunnersCountQuery;
|
||||
} else if (this.scope === GROUP_TYPE) {
|
||||
return groupRunnersCountQuery;
|
||||
}
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
#import "ee_else_ce/runner/graphql/list/list_item.fragment.graphql"
|
||||
#import "~/graphql_shared/fragments/page_info.fragment.graphql"
|
||||
|
||||
query getRunners(
|
||||
query getAllRunners(
|
||||
$before: String
|
||||
$after: String
|
||||
$first: Int
|
|
@ -1,4 +1,4 @@
|
|||
query getRunnersCount(
|
||||
query getAllRunnersCount(
|
||||
$paused: Boolean
|
||||
$status: CiRunnerStatus
|
||||
$type: CiRunnerType
|
|
@ -126,7 +126,7 @@ module GroupsHelper
|
|||
group.root? && current_user.can?(:admin_setting_to_allow_project_access_token_creation, group)
|
||||
end
|
||||
|
||||
def show_thanks_for_purchase_banner?
|
||||
def show_thanks_for_purchase_alert?
|
||||
params.key?(:purchased_quantity) && params[:purchased_quantity].to_i > 0
|
||||
end
|
||||
|
||||
|
|
|
@ -33,9 +33,12 @@ module WorkItems
|
|||
end
|
||||
|
||||
def transaction_create(work_item)
|
||||
super
|
||||
|
||||
execute_widgets(work_item: work_item, callback: :after_create_in_transaction, widget_params: @widget_params)
|
||||
super.tap do |save_result|
|
||||
if save_result
|
||||
execute_widgets(work_item: work_item, callback: :after_create_in_transaction,
|
||||
widget_params: @widget_params)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
|
|
@ -3,8 +3,8 @@
|
|||
- @skip_current_level_breadcrumb = true
|
||||
- add_page_specific_style 'page_bundles/group'
|
||||
|
||||
- if show_thanks_for_purchase_banner?
|
||||
= render_if_exists 'shared/thanks_for_purchase_banner', plan_title: plan_title, quantity: params[:purchased_quantity].to_i
|
||||
- if show_thanks_for_purchase_alert?
|
||||
= render_if_exists 'shared/thanks_for_purchase_alert', plan_title: plan_title, quantity: params[:purchased_quantity].to_i
|
||||
|
||||
= render_if_exists 'shared/qrtly_reconciliation_alert', group: @group
|
||||
= render_if_exists 'shared/free_user_cap_alert', source: @group
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
= form_for [@project, @trigger], html: { class: 'gl-show-field-errors' } do |f|
|
||||
= form_errors(@trigger)
|
||||
= form_errors(@trigger, pajamas_alert: true)
|
||||
|
||||
- if @trigger.token
|
||||
.form-group
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
= gitlab_ui_form_for [@project.namespace, @project, @deploy_keys.new_key], url: namespace_project_deploy_keys_path, html: { class: "js-requires-input container" } do |f|
|
||||
= form_errors(@deploy_keys.new_key)
|
||||
= form_errors(@deploy_keys.new_key, pajamas_alert: true)
|
||||
.form-group.row
|
||||
= f.label :title, class: "label-bold"
|
||||
= f.text_field :title, class: 'form-control gl-form-input', required: true, data: { qa_selector: 'deploy_key_title_field' }
|
||||
|
|
|
@ -651,8 +651,11 @@ to start again from scratch, there are a few steps that can help you:
|
|||
|
||||
1. Reset the Tracking Database.
|
||||
|
||||
WARNING:
|
||||
If you skipped the optional step 3, be sure both `geo-postgresql` and `postgresql` services are running.
|
||||
|
||||
```shell
|
||||
gitlab-rake db:drop:geo # on a secondary app node
|
||||
gitlab-rake db:drop:geo DISABLE_DATABASE_ENVIRONMENT_CHECK=1 # on a secondary app node
|
||||
gitlab-ctl reconfigure # on the tracking database node
|
||||
gitlab-rake db:migrate:geo # on a secondary app node
|
||||
```
|
||||
|
|
|
@ -502,6 +502,8 @@ Feedback is welcome on our vision for [unifying the user experience for these tw
|
|||
|
||||
## Troubleshooting
|
||||
|
||||
<!-- NOTE: The below subsection(`### Secure job failing with exit code 1`) documentation URL is referred in the [/gitlab-org/security-products/analyzers/command](https://gitlab.com/gitlab-org/security-products/analyzers/command/-/blob/main/command.go#L19) repository. If this section/subsection changes, please ensure to update the corresponding URL in the mentioned repository.
|
||||
-->
|
||||
### Secure job failing with exit code 1
|
||||
|
||||
If a Secure job is failing and it's unclear why, add `SECURE_LOG_LEVEL: "debug"` as a global CI/CD variable for
|
||||
|
|
|
@ -115,6 +115,15 @@ module API
|
|||
redirect(download_path)
|
||||
end
|
||||
|
||||
get do
|
||||
latest_package = packages.order_version.last
|
||||
|
||||
render_api_error!({ error: "No version found for #{params[:module_name]} module" }, :not_found) if latest_package&.version.nil?
|
||||
|
||||
presenter = ::Terraform::ModuleVersionPresenter.new(latest_package, params[:module_system])
|
||||
present presenter, with: ::API::Entities::Terraform::ModuleVersion
|
||||
end
|
||||
|
||||
params do
|
||||
includes :module_version
|
||||
end
|
||||
|
|
|
@ -8,7 +8,7 @@ code_quality:
|
|||
variables:
|
||||
DOCKER_DRIVER: overlay2
|
||||
DOCKER_TLS_CERTDIR: ""
|
||||
CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.26"
|
||||
CODE_QUALITY_IMAGE: "registry.gitlab.com/gitlab-org/ci-cd/codequality:0.85.29"
|
||||
needs: []
|
||||
script:
|
||||
- export SOURCE_CODE=$PWD
|
||||
|
|
|
@ -11454,9 +11454,6 @@ msgstr ""
|
|||
msgid "CycleAnalyticsStage|should be under a group"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|%{selectedLabelsCount} selected (%{maxLabels} max)"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|'%{name}' is collecting the data. This can take a few minutes."
|
||||
msgstr ""
|
||||
|
||||
|
@ -11481,9 +11478,6 @@ msgstr ""
|
|||
msgid "CycleAnalytics|Date"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|Display chart filters"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|If you have recently upgraded to GitLab Premium, it can take up to 30 minutes for data to collect and display."
|
||||
msgstr ""
|
||||
|
||||
|
@ -11493,20 +11487,11 @@ msgstr ""
|
|||
msgid "CycleAnalytics|Number of tasks"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|Only %{maxLabels} labels can be selected at this time"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|Project selected"
|
||||
msgid_plural "CycleAnalytics|%d projects selected"
|
||||
msgstr[0] ""
|
||||
msgstr[1] ""
|
||||
|
||||
msgid "CycleAnalytics|Select labels"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|Show"
|
||||
msgstr ""
|
||||
|
||||
msgid "CycleAnalytics|Stage time: %{title}"
|
||||
msgstr ""
|
||||
|
||||
|
@ -36141,6 +36126,9 @@ msgstr ""
|
|||
msgid "Showing version #%{versionNumber}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shows issues and %{labels_count} label for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019"
|
||||
msgstr ""
|
||||
|
||||
msgid "Shows issues and %{labels_count} labels for group '%{group_name}' from Nov 1, 2019 to Dec 31, 2019"
|
||||
msgstr ""
|
||||
|
||||
|
@ -37596,9 +37584,6 @@ msgstr ""
|
|||
msgid "Succeeded"
|
||||
msgstr ""
|
||||
|
||||
msgid "Successful purchase image"
|
||||
msgstr ""
|
||||
|
||||
msgid "Successfully activated"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -192,7 +192,7 @@ module QA
|
|||
find_element(:commit_sha_content).text
|
||||
end
|
||||
|
||||
def commit_changes(commit_message = nil, open_merge_request: false)
|
||||
def commit_changes(commit_message = nil, open_merge_request: false, wait_for_success: true)
|
||||
# Clicking :begin_commit_button switches from the
|
||||
# edit to the commit view
|
||||
click_element(:begin_commit_button)
|
||||
|
@ -226,13 +226,17 @@ module QA
|
|||
end
|
||||
click_element(:commit_button) if has_element?(:commit_button)
|
||||
|
||||
break unless wait_for_success
|
||||
|
||||
# If this is the first commit, the commit SHA only appears after reloading
|
||||
wait_until(reload: true) do
|
||||
active_element?(:edit_mode_tab) && commit_sha != original_commit
|
||||
end
|
||||
end
|
||||
|
||||
raise "The changes do not appear to have been committed successfully." unless commit_success
|
||||
if wait_for_success
|
||||
raise "The changes do not appear to have been committed successfully." unless commit_success
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,34 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module QA
|
||||
RSpec.describe 'Create', :skip_live_env, except: { job: 'review-qa-*' } do
|
||||
describe 'Git Server Hooks' do
|
||||
let(:file_path) { File.absolute_path(File.join('qa', 'fixtures', 'web_ide', 'README.md')) }
|
||||
|
||||
let(:project) do
|
||||
Resource::Project.fabricate_via_api! do |project|
|
||||
# Projects that have names that include pattern 'reject-prereceive' trigger a server hook on orchestrated env
|
||||
# that returns an error string using GL-HOOK-ERR
|
||||
project.name = "project-reject-prereceive-#{SecureRandom.hex(8)}"
|
||||
end
|
||||
end
|
||||
|
||||
before do
|
||||
Flow::Login.sign_in
|
||||
project.visit!
|
||||
end
|
||||
|
||||
context 'Custom error messages' do
|
||||
it 'renders preconfigured error message when user hook failed on commit in WebIDE',
|
||||
testcase: 'https://gitlab.com/gitlab-org/gitlab/-/quality/test_cases/364751' do
|
||||
Page::Project::Show.perform(&:open_web_ide_via_shortcut)
|
||||
Page::Project::WebIDE::Edit.perform do |ide|
|
||||
ide.upload_file(file_path)
|
||||
ide.commit_changes(wait_for_success: false)
|
||||
expect(ide).to have_text('Custom error message rejecting prereceive hook for projects with GL_PROJECT_PATH')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -22,7 +22,7 @@ RSpec.describe 'Group' do
|
|||
end
|
||||
|
||||
describe 'as a non-admin' do
|
||||
it 'creates a group and persists visibility radio selection', :js, :saas do
|
||||
it 'creates a group and persists visibility radio selection', :js do
|
||||
stub_application_setting(default_group_visibility: :private)
|
||||
|
||||
fill_in 'Group name', with: 'test-group'
|
||||
|
|
|
@ -39,19 +39,19 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
|
|||
end
|
||||
|
||||
describe GraphQL::Query, type: :request do
|
||||
admin_runners_query = 'list/admin_runners.query.graphql'
|
||||
all_runners_query = 'list/all_runners.query.graphql'
|
||||
|
||||
let_it_be(:query) do
|
||||
get_graphql_query_as_string("#{query_path}#{admin_runners_query}")
|
||||
get_graphql_query_as_string("#{query_path}#{all_runners_query}")
|
||||
end
|
||||
|
||||
it "#{fixtures_path}#{admin_runners_query}.json" do
|
||||
it "#{fixtures_path}#{all_runners_query}.json" do
|
||||
post_graphql(query, current_user: admin, variables: {})
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
end
|
||||
|
||||
it "#{fixtures_path}#{admin_runners_query}.paginated.json" do
|
||||
it "#{fixtures_path}#{all_runners_query}.paginated.json" do
|
||||
post_graphql(query, current_user: admin, variables: { first: 2 })
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
|
@ -59,13 +59,13 @@ RSpec.describe 'Runner (JavaScript fixtures)' do
|
|||
end
|
||||
|
||||
describe GraphQL::Query, type: :request do
|
||||
admin_runners_count_query = 'list/admin_runners_count.query.graphql'
|
||||
all_runners_count_query = 'list/all_runners_count.query.graphql'
|
||||
|
||||
let_it_be(:query) do
|
||||
get_graphql_query_as_string("#{query_path}#{admin_runners_count_query}")
|
||||
get_graphql_query_as_string("#{query_path}#{all_runners_count_query}")
|
||||
end
|
||||
|
||||
it "#{fixtures_path}#{admin_runners_count_query}.json" do
|
||||
it "#{fixtures_path}#{all_runners_count_query}.json" do
|
||||
post_graphql(query, current_user: admin, variables: {})
|
||||
|
||||
expect_graphql_errors_to_be_empty
|
||||
|
|
|
@ -41,14 +41,14 @@ import {
|
|||
STATUS_STALE,
|
||||
RUNNER_PAGE_SIZE,
|
||||
} from '~/runner/constants';
|
||||
import adminRunnersQuery from 'ee_else_ce/runner/graphql/list/admin_runners.query.graphql';
|
||||
import adminRunnersCountQuery from '~/runner/graphql/list/admin_runners_count.query.graphql';
|
||||
import allRunnersQuery from 'ee_else_ce/runner/graphql/list/all_runners.query.graphql';
|
||||
import allRunnersCountQuery from '~/runner/graphql/list/all_runners_count.query.graphql';
|
||||
import { captureException } from '~/runner/sentry_utils';
|
||||
|
||||
import {
|
||||
runnersData,
|
||||
allRunnersData,
|
||||
runnersCountData,
|
||||
runnersDataPaginated,
|
||||
allRunnersDataPaginated,
|
||||
onlineContactTimeoutSecs,
|
||||
staleTimeoutSecs,
|
||||
emptyStateSvgPath,
|
||||
|
@ -56,11 +56,11 @@ import {
|
|||
} from '../mock_data';
|
||||
|
||||
const mockRegistrationToken = 'MOCK_REGISTRATION_TOKEN';
|
||||
const mockRunners = runnersData.data.runners.nodes;
|
||||
const mockRunners = allRunnersData.data.runners.nodes;
|
||||
const mockRunnersCount = runnersCountData.data.runners.count;
|
||||
|
||||
const mockRunnersQuery = jest.fn();
|
||||
const mockRunnersCountQuery = jest.fn();
|
||||
const mockRunnersHandler = jest.fn();
|
||||
const mockRunnersCountHandler = jest.fn();
|
||||
|
||||
jest.mock('~/flash');
|
||||
jest.mock('~/runner/sentry_utils');
|
||||
|
@ -96,8 +96,8 @@ describe('AdminRunnersApp', () => {
|
|||
({ cacheConfig, localMutations } = createLocalState());
|
||||
|
||||
const handlers = [
|
||||
[adminRunnersQuery, mockRunnersQuery],
|
||||
[adminRunnersCountQuery, mockRunnersCountQuery],
|
||||
[allRunnersQuery, mockRunnersHandler],
|
||||
[allRunnersCountQuery, mockRunnersCountHandler],
|
||||
];
|
||||
|
||||
wrapper = mountFn(AdminRunnersApp, {
|
||||
|
@ -121,13 +121,13 @@ describe('AdminRunnersApp', () => {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockRunnersQuery.mockResolvedValue(runnersData);
|
||||
mockRunnersCountQuery.mockResolvedValue(runnersCountData);
|
||||
mockRunnersHandler.mockResolvedValue(allRunnersData);
|
||||
mockRunnersCountHandler.mockResolvedValue(runnersCountData);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockRunnersQuery.mockReset();
|
||||
mockRunnersCountQuery.mockReset();
|
||||
mockRunnersHandler.mockReset();
|
||||
mockRunnersCountHandler.mockReset();
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
|
@ -149,9 +149,9 @@ describe('AdminRunnersApp', () => {
|
|||
it('shows total runner counts', async () => {
|
||||
await createComponent({ mountFn: mountExtended });
|
||||
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith({ status: STATUS_ONLINE });
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith({ status: STATUS_OFFLINE });
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith({ status: STATUS_STALE });
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith({ status: STATUS_ONLINE });
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith({ status: STATUS_OFFLINE });
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith({ status: STATUS_STALE });
|
||||
|
||||
expect(findRunnerStats().text()).toContain(
|
||||
`${s__('Runners|Online runners')} ${mockRunnersCount}`,
|
||||
|
@ -197,7 +197,7 @@ describe('AdminRunnersApp', () => {
|
|||
it('requests the runners with no filters', async () => {
|
||||
await createComponent();
|
||||
|
||||
expect(mockRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockRunnersHandler).toHaveBeenLastCalledWith({
|
||||
status: undefined,
|
||||
type: undefined,
|
||||
sort: DEFAULT_SORT,
|
||||
|
@ -234,7 +234,7 @@ describe('AdminRunnersApp', () => {
|
|||
const FILTERED_COUNT_QUERIES = 4; // Smart queries that display a count of runners in tabs
|
||||
|
||||
beforeEach(async () => {
|
||||
mockRunnersCountQuery.mockClear();
|
||||
mockRunnersCountHandler.mockClear();
|
||||
|
||||
await createComponent({ mountFn: mountExtended });
|
||||
showToast = jest.spyOn(wrapper.vm.$root.$toast, 'show');
|
||||
|
@ -248,11 +248,11 @@ describe('AdminRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('When runner is paused or unpaused, some data is refetched', async () => {
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledTimes(COUNT_QUERIES);
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledTimes(COUNT_QUERIES);
|
||||
|
||||
findRunnerActionsCell().vm.$emit('toggledPaused');
|
||||
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledTimes(COUNT_QUERIES + FILTERED_COUNT_QUERIES);
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledTimes(COUNT_QUERIES + FILTERED_COUNT_QUERIES);
|
||||
expect(showToast).toHaveBeenCalledTimes(0);
|
||||
});
|
||||
|
||||
|
@ -289,7 +289,7 @@ describe('AdminRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('requests the runners with filter parameters', () => {
|
||||
expect(mockRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockRunnersHandler).toHaveBeenLastCalledWith({
|
||||
status: STATUS_ONLINE,
|
||||
type: INSTANCE_TYPE,
|
||||
tagList: ['tag1'],
|
||||
|
@ -299,7 +299,7 @@ describe('AdminRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('fetches count results for requested status', () => {
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith({
|
||||
type: INSTANCE_TYPE,
|
||||
status: STATUS_ONLINE,
|
||||
tagList: ['tag1'],
|
||||
|
@ -334,7 +334,7 @@ describe('AdminRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('requests the runners with filters', () => {
|
||||
expect(mockRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockRunnersHandler).toHaveBeenLastCalledWith({
|
||||
status: STATUS_ONLINE,
|
||||
tagList: ['tag1'],
|
||||
sort: CREATED_ASC,
|
||||
|
@ -343,7 +343,7 @@ describe('AdminRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('fetches count results for requested status', () => {
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith({
|
||||
tagList: ['tag1'],
|
||||
status: STATUS_ONLINE,
|
||||
});
|
||||
|
@ -392,7 +392,7 @@ describe('AdminRunnersApp', () => {
|
|||
|
||||
describe('when no runners are found', () => {
|
||||
beforeEach(async () => {
|
||||
mockRunnersQuery.mockResolvedValue({
|
||||
mockRunnersHandler.mockResolvedValue({
|
||||
data: {
|
||||
runners: { nodes: [] },
|
||||
},
|
||||
|
@ -423,7 +423,7 @@ describe('AdminRunnersApp', () => {
|
|||
|
||||
describe('when runners query fails', () => {
|
||||
beforeEach(async () => {
|
||||
mockRunnersQuery.mockRejectedValue(new Error('Error!'));
|
||||
mockRunnersHandler.mockRejectedValue(new Error('Error!'));
|
||||
await createComponent();
|
||||
});
|
||||
|
||||
|
@ -441,7 +441,7 @@ describe('AdminRunnersApp', () => {
|
|||
|
||||
describe('Pagination', () => {
|
||||
beforeEach(async () => {
|
||||
mockRunnersQuery.mockResolvedValue(runnersDataPaginated);
|
||||
mockRunnersHandler.mockResolvedValue(allRunnersDataPaginated);
|
||||
|
||||
await createComponent({ mountFn: mountExtended });
|
||||
});
|
||||
|
@ -449,10 +449,10 @@ describe('AdminRunnersApp', () => {
|
|||
it('navigates to the next page', async () => {
|
||||
await findRunnerPaginationNext().trigger('click');
|
||||
|
||||
expect(mockRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockRunnersHandler).toHaveBeenLastCalledWith({
|
||||
sort: CREATED_DESC,
|
||||
first: RUNNER_PAGE_SIZE,
|
||||
after: runnersDataPaginated.data.runners.pageInfo.endCursor,
|
||||
after: allRunnersDataPaginated.data.runners.pageInfo.endCursor,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -4,9 +4,9 @@ import RunnerActionsCell from '~/runner/components/cells/runner_actions_cell.vue
|
|||
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
|
||||
import RunnerEditButton from '~/runner/components/runner_edit_button.vue';
|
||||
import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
|
||||
import { runnersData } from '../../mock_data';
|
||||
import { allRunnersData } from '../../mock_data';
|
||||
|
||||
const mockRunner = runnersData.data.runners.nodes[0];
|
||||
const mockRunner = allRunnersData.data.runners.nodes[0];
|
||||
|
||||
describe('RunnerActionsCell', () => {
|
||||
let wrapper;
|
||||
|
|
|
@ -17,9 +17,9 @@ import {
|
|||
|
||||
import RunnerDeleteButton from '~/runner/components/runner_delete_button.vue';
|
||||
import RunnerDeleteModal from '~/runner/components/runner_delete_modal.vue';
|
||||
import { runnersData } from '../mock_data';
|
||||
import { allRunnersData } from '../mock_data';
|
||||
|
||||
const mockRunner = runnersData.data.runners.nodes[0];
|
||||
const mockRunner = allRunnersData.data.runners.nodes[0];
|
||||
const mockRunnerId = getIdFromGraphQLId(mockRunner.id);
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
|
|
@ -7,9 +7,9 @@ import {
|
|||
import { getIdFromGraphQLId } from '~/graphql_shared/utils';
|
||||
import RunnerList from '~/runner/components/runner_list.vue';
|
||||
import RunnerStatusPopover from '~/runner/components/runner_status_popover.vue';
|
||||
import { runnersData, onlineContactTimeoutSecs, staleTimeoutSecs } from '../mock_data';
|
||||
import { allRunnersData, onlineContactTimeoutSecs, staleTimeoutSecs } from '../mock_data';
|
||||
|
||||
const mockRunners = runnersData.data.runners.nodes;
|
||||
const mockRunners = allRunnersData.data.runners.nodes;
|
||||
const mockActiveRunnersCount = mockRunners.length;
|
||||
|
||||
describe('RunnerList', () => {
|
||||
|
|
|
@ -16,9 +16,9 @@ import {
|
|||
} from '~/runner/constants';
|
||||
|
||||
import RunnerPauseButton from '~/runner/components/runner_pause_button.vue';
|
||||
import { runnersData } from '../mock_data';
|
||||
import { allRunnersData } from '../mock_data';
|
||||
|
||||
const mockRunner = runnersData.data.runners.nodes[0];
|
||||
const mockRunner = allRunnersData.data.runners.nodes[0];
|
||||
|
||||
Vue.use(VueApollo);
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ import createMockApollo from 'helpers/mock_apollo_helper';
|
|||
import waitForPromises from 'helpers/wait_for_promises';
|
||||
import { captureException } from '~/runner/sentry_utils';
|
||||
|
||||
import adminRunnersCountQuery from '~/runner/graphql/list/admin_runners_count.query.graphql';
|
||||
import getGroupRunnersCountQuery from '~/runner/graphql/list/group_runners_count.query.graphql';
|
||||
import allRunnersCountQuery from '~/runner/graphql/list/all_runners_count.query.graphql';
|
||||
import groupRunnersCountQuery from '~/runner/graphql/list/group_runners_count.query.graphql';
|
||||
|
||||
import { runnersCountData, groupRunnersCountData } from '../../mock_data';
|
||||
|
||||
|
@ -18,13 +18,13 @@ Vue.use(VueApollo);
|
|||
|
||||
describe('RunnerCount', () => {
|
||||
let wrapper;
|
||||
let mockRunnersCountQuery;
|
||||
let mockGroupRunnersCountQuery;
|
||||
let mockRunnersCountHandler;
|
||||
let mockGroupRunnersCountHandler;
|
||||
|
||||
const createComponent = ({ props = {}, ...options } = {}) => {
|
||||
const handlers = [
|
||||
[adminRunnersCountQuery, mockRunnersCountQuery],
|
||||
[getGroupRunnersCountQuery, mockGroupRunnersCountQuery],
|
||||
[allRunnersCountQuery, mockRunnersCountHandler],
|
||||
[groupRunnersCountQuery, mockGroupRunnersCountHandler],
|
||||
];
|
||||
|
||||
wrapper = shallowMount(RunnerCount, {
|
||||
|
@ -42,8 +42,8 @@ describe('RunnerCount', () => {
|
|||
};
|
||||
|
||||
beforeEach(() => {
|
||||
mockRunnersCountQuery = jest.fn().mockResolvedValue(runnersCountData);
|
||||
mockGroupRunnersCountQuery = jest.fn().mockResolvedValue(groupRunnersCountData);
|
||||
mockRunnersCountHandler = jest.fn().mockResolvedValue(runnersCountData);
|
||||
mockGroupRunnersCountHandler = jest.fn().mockResolvedValue(groupRunnersCountData);
|
||||
});
|
||||
|
||||
describe('in admin scope', () => {
|
||||
|
@ -54,21 +54,21 @@ describe('RunnerCount', () => {
|
|||
});
|
||||
|
||||
it('fetches data from admin query', () => {
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledTimes(1);
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith({});
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledTimes(1);
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith({});
|
||||
});
|
||||
|
||||
it('fetches data with filters', async () => {
|
||||
await createComponent({ props: { scope: INSTANCE_TYPE, variables: mockVariables } });
|
||||
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledTimes(2);
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledWith(mockVariables);
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledTimes(2);
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledWith(mockVariables);
|
||||
|
||||
expect(wrapper.html()).toBe(`<strong>${runnersCountData.data.runners.count}</strong>`);
|
||||
});
|
||||
|
||||
it('does not fetch from the group query', async () => {
|
||||
expect(mockGroupRunnersCountQuery).not.toHaveBeenCalled();
|
||||
expect(mockGroupRunnersCountHandler).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
describe('when this query is skipped after data was loaded', () => {
|
||||
|
@ -90,8 +90,8 @@ describe('RunnerCount', () => {
|
|||
});
|
||||
|
||||
it('does not fetch data', async () => {
|
||||
expect(mockRunnersCountQuery).not.toHaveBeenCalled();
|
||||
expect(mockGroupRunnersCountQuery).not.toHaveBeenCalled();
|
||||
expect(mockRunnersCountHandler).not.toHaveBeenCalled();
|
||||
expect(mockGroupRunnersCountHandler).not.toHaveBeenCalled();
|
||||
|
||||
expect(wrapper.html()).toBe('<strong></strong>');
|
||||
});
|
||||
|
@ -101,7 +101,7 @@ describe('RunnerCount', () => {
|
|||
const mockError = new Error('error!');
|
||||
|
||||
beforeEach(async () => {
|
||||
mockRunnersCountQuery.mockRejectedValue(mockError);
|
||||
mockRunnersCountHandler.mockRejectedValue(mockError);
|
||||
|
||||
await createComponent({ props: { scope: INSTANCE_TYPE } });
|
||||
});
|
||||
|
@ -122,8 +122,8 @@ describe('RunnerCount', () => {
|
|||
});
|
||||
|
||||
it('fetches data from the group query', async () => {
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledTimes(1);
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledWith({});
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledTimes(1);
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledWith({});
|
||||
|
||||
expect(wrapper.html()).toBe(
|
||||
`<strong>${groupRunnersCountData.data.group.runners.count}</strong>`,
|
||||
|
@ -131,7 +131,7 @@ describe('RunnerCount', () => {
|
|||
});
|
||||
|
||||
it('does not fetch from the group query', () => {
|
||||
expect(mockRunnersCountQuery).not.toHaveBeenCalled();
|
||||
expect(mockRunnersCountHandler).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -142,7 +142,7 @@ describe('RunnerCount', () => {
|
|||
});
|
||||
|
||||
it('data is not shown and error is reported', async () => {
|
||||
expect(mockRunnersCountQuery).toHaveBeenCalledTimes(2);
|
||||
expect(mockRunnersCountHandler).toHaveBeenCalledTimes(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -39,8 +39,8 @@ import {
|
|||
RUNNER_PAGE_SIZE,
|
||||
I18N_EDIT,
|
||||
} from '~/runner/constants';
|
||||
import getGroupRunnersQuery from '~/runner/graphql/list/group_runners.query.graphql';
|
||||
import getGroupRunnersCountQuery from '~/runner/graphql/list/group_runners_count.query.graphql';
|
||||
import groupRunnersQuery from '~/runner/graphql/list/group_runners.query.graphql';
|
||||
import groupRunnersCountQuery from '~/runner/graphql/list/group_runners_count.query.graphql';
|
||||
import GroupRunnersApp from '~/runner/group_runners/group_runners_app.vue';
|
||||
import { captureException } from '~/runner/sentry_utils';
|
||||
import {
|
||||
|
@ -61,8 +61,8 @@ const mockRegistrationToken = 'AABBCC';
|
|||
const mockGroupRunnersEdges = groupRunnersData.data.group.runners.edges;
|
||||
const mockGroupRunnersCount = mockGroupRunnersEdges.length;
|
||||
|
||||
const mockGroupRunnersQuery = jest.fn();
|
||||
const mockGroupRunnersCountQuery = jest.fn();
|
||||
const mockGroupRunnersHandler = jest.fn();
|
||||
const mockGroupRunnersCountHandler = jest.fn();
|
||||
|
||||
jest.mock('~/flash');
|
||||
jest.mock('~/runner/sentry_utils');
|
||||
|
@ -87,8 +87,8 @@ describe('GroupRunnersApp', () => {
|
|||
|
||||
const createComponent = ({ props = {}, mountFn = shallowMountExtended, ...options } = {}) => {
|
||||
const handlers = [
|
||||
[getGroupRunnersQuery, mockGroupRunnersQuery],
|
||||
[getGroupRunnersCountQuery, mockGroupRunnersCountQuery],
|
||||
[groupRunnersQuery, mockGroupRunnersHandler],
|
||||
[groupRunnersCountQuery, mockGroupRunnersCountHandler],
|
||||
];
|
||||
|
||||
wrapper = mountFn(GroupRunnersApp, {
|
||||
|
@ -112,13 +112,13 @@ describe('GroupRunnersApp', () => {
|
|||
};
|
||||
|
||||
beforeEach(async () => {
|
||||
mockGroupRunnersQuery.mockResolvedValue(groupRunnersData);
|
||||
mockGroupRunnersCountQuery.mockResolvedValue(groupRunnersCountData);
|
||||
mockGroupRunnersHandler.mockResolvedValue(groupRunnersData);
|
||||
mockGroupRunnersCountHandler.mockResolvedValue(groupRunnersCountData);
|
||||
});
|
||||
|
||||
afterEach(() => {
|
||||
mockGroupRunnersQuery.mockReset();
|
||||
mockGroupRunnersCountQuery.mockReset();
|
||||
mockGroupRunnersHandler.mockReset();
|
||||
mockGroupRunnersCountHandler.mockReset();
|
||||
wrapper.destroy();
|
||||
});
|
||||
|
||||
|
@ -140,15 +140,15 @@ describe('GroupRunnersApp', () => {
|
|||
it('shows total runner counts', async () => {
|
||||
await createComponent({ mountFn: mountExtended });
|
||||
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledWith({
|
||||
status: STATUS_ONLINE,
|
||||
groupFullPath: mockGroupFullPath,
|
||||
});
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledWith({
|
||||
status: STATUS_OFFLINE,
|
||||
groupFullPath: mockGroupFullPath,
|
||||
});
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledWith({
|
||||
status: STATUS_STALE,
|
||||
groupFullPath: mockGroupFullPath,
|
||||
});
|
||||
|
@ -174,7 +174,7 @@ describe('GroupRunnersApp', () => {
|
|||
it('requests the runners with group path and no other filters', async () => {
|
||||
await createComponent();
|
||||
|
||||
expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockGroupRunnersHandler).toHaveBeenLastCalledWith({
|
||||
groupFullPath: mockGroupFullPath,
|
||||
status: undefined,
|
||||
type: undefined,
|
||||
|
@ -231,11 +231,11 @@ describe('GroupRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('When runner is paused or unpaused, some data is refetched', async () => {
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledTimes(COUNT_QUERIES);
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledTimes(COUNT_QUERIES);
|
||||
|
||||
findRunnerActionsCell().vm.$emit('toggledPaused');
|
||||
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledTimes(
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledTimes(
|
||||
COUNT_QUERIES + FILTERED_COUNT_QUERIES,
|
||||
);
|
||||
|
||||
|
@ -272,7 +272,7 @@ describe('GroupRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('requests the runners with filter parameters', () => {
|
||||
expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockGroupRunnersHandler).toHaveBeenLastCalledWith({
|
||||
groupFullPath: mockGroupFullPath,
|
||||
status: STATUS_ONLINE,
|
||||
type: INSTANCE_TYPE,
|
||||
|
@ -282,7 +282,7 @@ describe('GroupRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('fetches count results for requested status', () => {
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledWith({
|
||||
groupFullPath: mockGroupFullPath,
|
||||
type: INSTANCE_TYPE,
|
||||
status: STATUS_ONLINE,
|
||||
|
@ -319,7 +319,7 @@ describe('GroupRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('requests the runners with filters', () => {
|
||||
expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockGroupRunnersHandler).toHaveBeenLastCalledWith({
|
||||
groupFullPath: mockGroupFullPath,
|
||||
status: STATUS_ONLINE,
|
||||
tagList: ['tag1'],
|
||||
|
@ -329,7 +329,7 @@ describe('GroupRunnersApp', () => {
|
|||
});
|
||||
|
||||
it('fetches count results for requested status', () => {
|
||||
expect(mockGroupRunnersCountQuery).toHaveBeenCalledWith({
|
||||
expect(mockGroupRunnersCountHandler).toHaveBeenCalledWith({
|
||||
groupFullPath: mockGroupFullPath,
|
||||
tagList: ['tag1'],
|
||||
status: STATUS_ONLINE,
|
||||
|
@ -344,7 +344,7 @@ describe('GroupRunnersApp', () => {
|
|||
|
||||
describe('when no runners are found', () => {
|
||||
beforeEach(async () => {
|
||||
mockGroupRunnersQuery.mockResolvedValue({
|
||||
mockGroupRunnersHandler.mockResolvedValue({
|
||||
data: {
|
||||
group: {
|
||||
id: '1',
|
||||
|
@ -362,7 +362,7 @@ describe('GroupRunnersApp', () => {
|
|||
|
||||
describe('when runners query fails', () => {
|
||||
beforeEach(async () => {
|
||||
mockGroupRunnersQuery.mockRejectedValue(new Error('Error!'));
|
||||
mockGroupRunnersHandler.mockRejectedValue(new Error('Error!'));
|
||||
await createComponent();
|
||||
});
|
||||
|
||||
|
@ -380,7 +380,7 @@ describe('GroupRunnersApp', () => {
|
|||
|
||||
describe('Pagination', () => {
|
||||
beforeEach(async () => {
|
||||
mockGroupRunnersQuery.mockResolvedValue(groupRunnersDataPaginated);
|
||||
mockGroupRunnersHandler.mockResolvedValue(groupRunnersDataPaginated);
|
||||
|
||||
await createComponent({ mountFn: mountExtended });
|
||||
});
|
||||
|
@ -388,7 +388,7 @@ describe('GroupRunnersApp', () => {
|
|||
it('navigates to the next page', async () => {
|
||||
await findRunnerPaginationNext().trigger('click');
|
||||
|
||||
expect(mockGroupRunnersQuery).toHaveBeenLastCalledWith({
|
||||
expect(mockGroupRunnersHandler).toHaveBeenLastCalledWith({
|
||||
groupFullPath: mockGroupFullPath,
|
||||
sort: CREATED_DESC,
|
||||
first: RUNNER_PAGE_SIZE,
|
||||
|
|
|
@ -10,9 +10,9 @@ import runnerJobsData from 'test_fixtures/graphql/runner/show/runner_jobs.query.
|
|||
import runnerFormData from 'test_fixtures/graphql/runner/edit/runner_form.query.graphql.json';
|
||||
|
||||
// List queries
|
||||
import runnersData from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.json';
|
||||
import runnersDataPaginated from 'test_fixtures/graphql/runner/list/admin_runners.query.graphql.paginated.json';
|
||||
import runnersCountData from 'test_fixtures/graphql/runner/list/admin_runners_count.query.graphql.json';
|
||||
import allRunnersData from 'test_fixtures/graphql/runner/list/all_runners.query.graphql.json';
|
||||
import allRunnersDataPaginated from 'test_fixtures/graphql/runner/list/all_runners.query.graphql.paginated.json';
|
||||
import runnersCountData from 'test_fixtures/graphql/runner/list/all_runners_count.query.graphql.json';
|
||||
import groupRunnersData from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.json';
|
||||
import groupRunnersDataPaginated from 'test_fixtures/graphql/runner/list/group_runners.query.graphql.paginated.json';
|
||||
import groupRunnersCountData from 'test_fixtures/graphql/runner/list/group_runners_count.query.graphql.json';
|
||||
|
@ -227,8 +227,8 @@ export const emptyStateSvgPath = 'emptyStateSvgPath.svg';
|
|||
export const emptyStateFilteredSvgPath = 'emptyStateFilteredSvgPath.svg';
|
||||
|
||||
export {
|
||||
runnersData,
|
||||
runnersDataPaginated,
|
||||
allRunnersData,
|
||||
allRunnersDataPaginated,
|
||||
runnersCountData,
|
||||
groupRunnersData,
|
||||
groupRunnersDataPaginated,
|
||||
|
|
|
@ -355,8 +355,8 @@ RSpec.describe GroupsHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe '#show_thanks_for_purchase_banner?' do
|
||||
subject { helper.show_thanks_for_purchase_banner? }
|
||||
describe '#show_thanks_for_purchase_alert?' do
|
||||
subject { helper.show_thanks_for_purchase_alert? }
|
||||
|
||||
it 'returns true with purchased_quantity present in params' do
|
||||
allow(controller).to receive(:params) { { purchased_quantity: '1' } }
|
||||
|
|
|
@ -51,7 +51,7 @@ RSpec.describe StorageHelper do
|
|||
end
|
||||
end
|
||||
|
||||
describe "storage_enforcement_banner", :saas do
|
||||
describe "storage_enforcement_banner" do
|
||||
let_it_be_with_refind(:current_user) { create(:user) }
|
||||
let_it_be(:free_group) { create(:group) }
|
||||
let_it_be(:paid_group) { create(:group) }
|
||||
|
|
|
@ -84,7 +84,7 @@ RSpec.describe Gitlab::Ci::Pipeline::Chain::Validate::External do
|
|||
end
|
||||
end
|
||||
|
||||
it 'respects the defined payload schema', :saas do
|
||||
it 'respects the defined payload schema' do
|
||||
expect(::Gitlab::HTTP).to receive(:post) do |_url, params|
|
||||
expect(params[:body]).to match_schema('/external_validation')
|
||||
expect(params[:timeout]).to eq(described_class::DEFAULT_VALIDATION_REQUEST_TIMEOUT)
|
||||
|
|
|
@ -100,7 +100,7 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
|
|||
|
||||
describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system/download' do
|
||||
context 'empty registry' do
|
||||
let(:url) { api("/packages/terraform/modules/v1/module-2/system/download") }
|
||||
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/module-2/system/download") }
|
||||
let(:headers) { {} }
|
||||
|
||||
subject { get(url, headers: headers) }
|
||||
|
@ -171,6 +171,74 @@ RSpec.describe API::Terraform::Modules::V1::Packages do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system' do
|
||||
context 'empty registry' do
|
||||
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/non-existent/system") }
|
||||
let(:headers) { { 'Authorization' => "Bearer #{tokens[:personal_access_token]}" } }
|
||||
|
||||
subject { get(url, headers: headers) }
|
||||
|
||||
it 'returns not found when there is no module' do
|
||||
subject
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
|
||||
context 'with valid namespace' do
|
||||
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}") }
|
||||
|
||||
subject { get(url, headers: headers) }
|
||||
|
||||
where(:visibility, :user_role, :member, :token_type, :shared_examples_name, :expected_status) do
|
||||
:public | :developer | true | :personal_access_token | 'returns terraform module version' | :success
|
||||
:public | :guest | true | :personal_access_token | 'returns terraform module version' | :success
|
||||
:public | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :developer | false | :personal_access_token | 'returns terraform module version' | :success
|
||||
:public | :guest | false | :personal_access_token | 'returns terraform module version' | :success
|
||||
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :anonymous | false | nil | 'returns terraform module version' | :success
|
||||
:private | :developer | true | :personal_access_token | 'returns terraform module version' | :success
|
||||
:private | :guest | true | :personal_access_token | 'rejects terraform module packages access' | :forbidden
|
||||
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :developer | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
|
||||
:private | :guest | false | :personal_access_token | 'rejects terraform module packages access' | :forbidden
|
||||
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :anonymous | false | nil | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :developer | true | :job_token | 'returns terraform module version' | :success
|
||||
:public | :guest | true | :job_token | 'returns terraform module version' | :success
|
||||
:public | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :developer | false | :job_token | 'returns terraform module version' | :success
|
||||
:public | :guest | false | :job_token | 'returns terraform module version' | :success
|
||||
:public | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:public | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :developer | true | :job_token | 'returns terraform module version' | :success
|
||||
:private | :guest | true | :job_token | 'rejects terraform module packages access' | :forbidden
|
||||
:private | :developer | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :guest | true | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :developer | false | :job_token | 'rejects terraform module packages access' | :forbidden
|
||||
:private | :guest | false | :job_token | 'rejects terraform module packages access' | :forbidden
|
||||
:private | :developer | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
:private | :guest | false | :invalid | 'rejects terraform module packages access' | :unauthorized
|
||||
end
|
||||
|
||||
with_them do
|
||||
let(:headers) { user_role == :anonymous ? {} : { 'Authorization' => "Bearer #{token}" } }
|
||||
|
||||
before do
|
||||
group.update!(visibility: visibility.to_s)
|
||||
project.update!(visibility: visibility.to_s)
|
||||
end
|
||||
|
||||
it_behaves_like params[:shared_examples_name], params[:user_role], params[:expected_status], params[:member]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET /api/v4/packages/terraform/modules/v1/:module_namespace/:module_name/:module_system/:module_version' do
|
||||
let(:url) { api("/packages/terraform/modules/v1/#{group.path}/#{package.name}/#{package.version}") }
|
||||
let(:headers) { {} }
|
||||
|
|
|
@ -27,16 +27,18 @@ RSpec.describe WorkItems::CreateService do
|
|||
end
|
||||
|
||||
describe '#execute' do
|
||||
subject(:service_result) do
|
||||
let(:service) do
|
||||
described_class.new(
|
||||
project: project,
|
||||
current_user: current_user,
|
||||
params: opts,
|
||||
spam_params: spam_params,
|
||||
widget_params: widget_params
|
||||
).execute
|
||||
)
|
||||
end
|
||||
|
||||
subject(:service_result) { service.execute }
|
||||
|
||||
before do
|
||||
stub_spam_services
|
||||
end
|
||||
|
@ -73,6 +75,14 @@ RSpec.describe WorkItems::CreateService do
|
|||
it 'returns validation errors' do
|
||||
expect(service_result.errors).to contain_exactly("Title can't be blank")
|
||||
end
|
||||
|
||||
it 'does not execute after-create transaction widgets' do
|
||||
expect(service).to receive(:create).and_call_original
|
||||
expect(service).not_to receive(:execute_widgets)
|
||||
.with(callback: :after_create_in_transaction, widget_params: widget_params)
|
||||
|
||||
service_result
|
||||
end
|
||||
end
|
||||
|
||||
context 'checking spam' do
|
||||
|
|
Loading…
Reference in New Issue