Commit aa10b541 authored by GitLab Bot's avatar GitLab Bot

Add latest changes from gitlab-org/gitlab@master

parent a5ba0dd8
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants';
......
/* eslint-disable no-new */
import memberExpirationDate from '~/member_expiration_date';
import Members from 'ee_else_ce/members';
import memberExpirationDate from '~/member_expiration_date';
import UsersSelect from '~/users_select';
document.addEventListener('DOMContentLoaded', () => {
......
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import initIssuablesList from '~/issuables_list';
import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import issuableInitBulkUpdateSidebar from '~/issuable_init_bulk_update_sidebar';
import { FILTERED_SEARCH } from '~/pages/constants';
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import initManualOrdering from '~/manual_ordering';
const ISSUE_BULK_UPDATE_PREFIX = 'issue_';
......
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import projectSelect from '~/project_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import issuableInitBulkUpdateSidebar from '~/issuable_init_bulk_update_sidebar';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import { FILTERED_SEARCH } from '~/pages/constants';
const ISSUABLE_BULK_UPDATE_PREFIX = 'merge_request_';
......
import _ from 'underscore';
import InputValidator from '~/validators/input_validator';
import _ from 'underscore';
import fetchGroupPathAvailability from './fetch_group_path_availability';
import flash from '~/flash';
import { __ } from '~/locale';
......
import $ from 'jquery';
import createFlash from '~/flash';
import GfmAutoComplete from 'ee_else_ce/gfm_auto_complete';
import emojiRegex from 'emoji-regex';
import createFlash from '~/flash';
import EmojiMenu from './emoji_menu';
import { __ } from '~/locale';
......
/* eslint-disable no-new */
import $ from 'jquery';
import GLForm from '~/gl_form';
import IssuableForm from 'ee_else_ce/issuable_form';
import GLForm from '~/gl_form';
import LabelsSelect from '~/labels_select';
import MilestoneSelect from '~/milestone_select';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
......
/* eslint-disable no-new */
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import IssuableIndex from '~/issuable_index';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
import IssuableFilteredSearchTokenKeys from 'ee_else_ce/filtered_search/issuable_filtered_search_token_keys';
import initManualOrdering from '~/manual_ordering';
document.addEventListener('DOMContentLoaded', () => {
......
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import IssuableIndex from '~/issuable_index';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import UsersSelect from '~/users_select';
import initFilteredSearch from '~/pages/search/init_filtered_search';
import addExtraTokensForMergeRequests from 'ee_else_ce/filtered_search/add_extra_tokens_for_merge_requests';
import IssuableFilteredSearchTokenKeys from '~/filtered_search/issuable_filtered_search_token_keys';
import { FILTERED_SEARCH } from '~/pages/constants';
import { ISSUABLE_INDEX } from '~/pages/projects/constants';
......
/* eslint-disable no-new */
import $ from 'jquery';
import IssuableForm from 'ee_else_ce/issuable_form';
import Diff from '~/diff';
import ShortcutsNavigation from '~/behaviors/shortcuts/shortcuts_navigation';
import GLForm from '~/gl_form';
import IssuableForm from 'ee_else_ce/issuable_form';
import LabelsSelect from '~/labels_select';
import MilestoneSelect from '~/milestone_select';
import IssuableTemplateSelectors from '~/templates/issuable_template_selectors';
......
<script>
import _ from 'underscore';
import { s__, sprintf } from '~/locale';
import { GlModal, GlModalDirective } from '@gitlab/ui';
import { s__, sprintf } from '~/locale';
export default {
components: {
......
import _ from 'underscore';
import InputValidator from '~/validators/input_validator';
import _ from 'underscore';
import axios from '~/lib/utils/axios_utils';
import flash from '~/flash';
import { __ } from '~/locale';
......
import $ from 'jquery';
import UserCallout from '~/user_callout';
import Cookies from 'js-cookie';
import UserCallout from '~/user_callout';
import UserTabs from './user_tabs';
function initUserProfile(action) {
......
......@@ -15,8 +15,7 @@ class Projects::PagesController < Projects::ApplicationController
# rubocop: enable CodeReuse/ActiveRecord
def destroy
project.remove_pages
project.pages_domains.destroy_all # rubocop: disable DestroyAll
::Pages::DeleteService.new(@project, current_user).execute
respond_to do |format|
format.html do
......
# frozen_string_literal: true
module Pages
class DeleteService < BaseService
def execute
project.remove_pages
project.pages_domains.destroy_all # rubocop: disable DestroyAll
end
end
end
---
title: Add API endpoint to unpublish GitLab Pages
merge_request: 19781
author:
type: added
# Pages API
Endpoints for managing [GitLab Pages](https://about.gitlab.com/product/pages/).
The GitLab Pages feature must be enabled to use these endpoints. Find out more about [administering](../administration/pages/index.md) and [using](../user/project/pages/index.md) the feature.
## Unpublish pages
Remove pages. The user must have admin priviledges.
```text
DELETE /projects/:id/pages
```
| Attribute | Type | Required | Description |
| --------- | -------------- | -------- | ---------------------------------------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the project](README.md#namespaced-path-encoding) owned by the authenticated user |
```bash
curl --request 'DELETE' --header "PRIVATE-TOKEN: <your_access_token>" https://gitlab.example.com/api/v4/projects/2/pages
```
......@@ -137,6 +137,7 @@ module API
mount ::API::Discussions
mount ::API::ResourceLabelEvents
mount ::API::NotificationSettings
mount ::API::Pages
mount ::API::PagesDomains
mount ::API::Pipelines
mount ::API::PipelineSchedules
......
# frozen_string_literal: true
module API
class Pages < Grape::API
before do
require_pages_config_enabled!
authenticated_with_full_private_access!
end
params do
requires :id, type: String, desc: 'The ID of a project'
end
resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
desc 'Unpublish pages' do
detail 'This feature was introduced in GitLab 12.6'
end
delete ':id/pages' do
authorize! :remove_pages, user_project
status 204
::Pages::DeleteService.new(user_project, current_user).execute
end
end
end
end
......@@ -64,7 +64,7 @@ module QA
end
def visit!
Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"]) if Runtime::Env.debug?
Runtime::Logger.debug(%Q[Visiting #{self.class.name} at "#{web_url}"])
Support::Retrier.retry_until do
visit(web_url)
......
......@@ -79,7 +79,7 @@ module QA
def api_delete
super
QA::Runtime::Logger.debug("Deleted user '#{username}'") if Runtime::Env.debug?
QA::Runtime::Logger.debug("Deleted user '#{username}'")
end
def api_delete_path
......
......@@ -24,7 +24,7 @@ module QA
# Wait for Action Mailer to deliver messages
mailhog_json = Support::Retrier.retry_until(sleep_interval: 1) do
Runtime::Logger.debug(%Q[retrieving "#{QA::Runtime::MailHog.api_messages_url}"]) if Runtime::Env.debug?
Runtime::Logger.debug(%Q[retrieving "#{QA::Runtime::MailHog.api_messages_url}"])
mailhog_response = get QA::Runtime::MailHog.api_messages_url
......
......@@ -8,7 +8,7 @@ module QA
module Page
class Login < Page::Base
def login(username, password)
QA::Runtime::Logger.debug("Logging into SAMLIdp with username: #{username} and password:#{password}") if QA::Runtime::Env.debug?
QA::Runtime::Logger.debug("Logging into SAMLIdp with username: #{username} and password:#{password}")
fill_in 'username', with: username
fill_in 'password', with: password
......@@ -21,7 +21,7 @@ module QA
def login_required?
login_required = page.has_text?('Enter your username and password')
QA::Runtime::Logger.debug("login_required: #{login_required}") if QA::Runtime::Env.debug?
QA::Runtime::Logger.debug("login_required: #{login_required}")
login_required
end
end
......
......@@ -20,7 +20,7 @@ RSpec.configure do |config|
QA::Specs::Helpers::Quarantine.configure_rspec
config.before do |example|
QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n") if QA::Runtime::Env.debug?
QA::Runtime::Logger.debug("\nStarting test: #{example.full_description}\n")
end
config.after(:context) do
......
import * as monitoringUtils from '~/monitoring/utils';
import { timeWindows, timeWindowsKeyNames } from '~/monitoring/constants';
import {
graphDataPrometheusQuery,
graphDataPrometheusQueryRange,
anomalyMockGraphData,
} from './mock_data';
describe('Snowplow Events', () => {
describe('monitoring/utils', () => {
const generatedLink = 'http://chart.link.com';
const chartTitle = 'Some metric chart';
......@@ -51,4 +57,338 @@ describe('Snowplow Events', () => {
});
});
});
describe('getTimeDiff', () => {
function secondsBetween({ start, end }) {
return (new Date(end) - new Date(start)) / 1000;
}
function minutesBetween(timeRange) {
return secondsBetween(timeRange) / 60;
}
function hoursBetween(timeRange) {
return minutesBetween(timeRange) / 60;
}
it('defaults to an 8 hour (28800s) difference', () => {
const params = monitoringUtils.getTimeDiff();
expect(hoursBetween(params)).toEqual(8);
});
it('accepts time window as an argument', () => {
const params = monitoringUtils.getTimeDiff('thirtyMinutes');
expect(minutesBetween(params)).toEqual(30);
});
it('returns a value for every defined time window', () => {
const nonDefaultWindows = Object.keys(timeWindows).filter(window => window !== 'eightHours');
nonDefaultWindows.forEach(timeWindow => {
const params = monitoringUtils.getTimeDiff(timeWindow);
// Ensure we're not returning the default
expect(hoursBetween(params)).not.toEqual(8);
});
});
});
describe('getTimeWindow', () => {
[
{
args: [
{
start: '2019-10-01T18:27:47.000Z',
end: '2019-10-01T21:27:47.000Z',
},
],
expected: timeWindowsKeyNames.threeHours,
},
{
args: [
{
start: '2019-10-01T28:27:47.000Z',
end: '2019-10-01T21:27:47.000Z',
},
],
expected: null,
},
{
args: [
{
start: '',
end: '',
},
],
expected: null,
},
{
args: [
{
start: null,
end: null,
},
],
expected: null,
},
{
args: [{}],
expected: null,
},
].forEach(({ args, expected }) => {
it(`returns "${expected}" with args=${JSON.stringify(args)}`, () => {
expect(monitoringUtils.getTimeWindow(...args)).toEqual(expected);
});
});
});
describe('graphDataValidatorForValues', () => {
/*
* When dealing with a metric using the query format, e.g.
* query: 'max(go_memstats_alloc_bytes{job="prometheus"}) by (job) /1024/1024'
* the validator will look for the `value` key instead of `values`
*/
it('validates data with the query format', () => {
const validGraphData = monitoringUtils.graphDataValidatorForValues(
true,
graphDataPrometheusQuery,
);
expect(validGraphData).toBe(true);
});
/*
* When dealing with a metric using the query?range format, e.g.
* query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024',
* the validator will look for the `values` key instead of `value`
*/
it('validates data with the query_range format', () => {
const validGraphData = monitoringUtils.graphDataValidatorForValues(
false,
graphDataPrometheusQueryRange,
);
expect(validGraphData).toBe(true);
});
});
describe('stringToISODate', () => {
['', 'null', undefined, 'abc'].forEach(input => {
it(`throws error for invalid input like ${input}`, done => {
try {
monitoringUtils.stringToISODate(input);
} catch (e) {
expect(e).toBeDefined();
done();
}
});
});
[
{
input: '2019-09-09 01:01:01',
output: '2019-09-09T01:01:01Z',
},
{
input: '2019-09-09 00:00:00',
output: '2019-09-09T00:00:00Z',
},
{
input: '2019-09-09 23:59:59',
output: '2019-09-09T23:59:59Z',
},
{
input: '2019-09-09',
output: '2019-09-09T00:00:00Z',
},
].forEach(({ input, output }) => {
it(`returns ${output} from ${input}`, () => {
expect(monitoringUtils.stringToISODate(input)).toBe(output);
});
});
});
describe('ISODateToString', () => {
[
{
input: new Date('2019-09-09T00:00:00.000Z'),
output: '2019-09-09 00:00:00',
},
{
input: new Date('2019-09-09T07:00:00.000Z'),
output: '2019-09-09 07:00:00',
},
].forEach(({ input, output }) => {
it(`ISODateToString return ${output} for ${input}`, () => {
expect(monitoringUtils.ISODateToString(input)).toBe(output);
});
});
});
describe('truncateZerosInDateTime', () => {
[
{
input: '',
output: '',
},
{
input: '2019-10-10',
output: '2019-10-10',
},
{
input: '2019-10-10 00:00:01',
output: '2019-10-10 00:00:01',
},
{
input: '2019-10-10 00:00:00',
output: '2019-10-10',
},
].forEach(({ input, output }) => {
it(`truncateZerosInDateTime return ${output} for ${input}`, () => {
expect(monitoringUtils.truncateZerosInDateTime(input)).toBe(output);
});
});
});
describe('isValidDate', () => {
[
{
input: '2019-09-09T00:00:00.000Z',
output: true,
},
{
input: '2019-09-09T000:00.000Z',
output: false,
},
{
input: 'a2019-09-09T000:00.000Z',
output: false,
},
{
input: '2019-09-09T',
output: false,
},
{
input: '2019-09-09',
output: true,
},
{
input: '2019-9-9',
output: true,
},
{
input: '2019-9-',
output: true,
},
{
input: '2019--',
output: false,
},
{
input: '2019',
output: true,
},
{
input: '',
output: false,
},
{
input: null,
output: false,
},
].forEach(({ input, output }) => {
it(`isValidDate return ${output} for ${input}`, () => {
expect(monitoringUtils.isValidDate(input)).toBe(output);
});
});
});
describe('isDateTimePickerInputValid', () => {
[
{
input: null,
output: false,
},
{
input: '',
output: false,
},
{
input: 'xxxx-xx-xx',
output: false,
},
{
input: '9999-99-19',
output: false,
},
{
input: '2019-19-23',
output: false,
},
{
input: '2019-09-23',
output: true,
},
{
input: '2019-09-23 x',
output: false,
},
{
input: '2019-09-29 0:0:0',
output: false,
},
{
input: '2019-09-29 00:00:00',
output: true,
},
{
input: '2019-09-29 24:24:24',
output: false,
},
{
input: '2019-09-29 23:24:24',
output: true,
},
{
input: '2019-09-29 23:24:24 ',
output: false,
},
].forEach(({ input, output }) => {
it(`returns ${output} for ${input}`, () => {
expect(monitoringUtils.isDateTimePickerInputValid(input)).toBe(output);
});
});
});
describe('graphDataValidatorForAnomalyValues', () => {
let oneMetric;
let threeMetrics;
let fourMetrics;
beforeEach(() => {
oneMetric = graphDataPrometheusQuery;
threeMetrics = anomalyMockGraphData;
const metrics = [...threeMetrics.metrics];
metrics.push(threeMetrics.metrics[0]);
fourMetrics = {
...anomalyMockGraphData,
metrics,
};
});
/*
* Anomaly charts can accept results for exactly 3 metrics,
*/
it('validates passes with the right query format', () => {
expect(monitoringUtils.graphDataValidatorForAnomalyValues(threeMetrics)).toBe(true);
});
it('validation fails for wrong format, 1 metric', () => {
expect(monitoringUtils.graphDataValidatorForAnomalyValues(oneMetric)).toBe(false);
});
it('validation fails for wrong format, more than 3 metrics', () => {
expect(monitoringUtils.graphDataValidatorForAnomalyValues(fourMetrics)).toBe(false);
});
});
});
import {
getTimeDiff,
getTimeWindow,
graphDataValidatorForValues,
isDateTimePickerInputValid,
truncateZerosInDateTime,
stringToISODate,
ISODateToString,
isValidDate,
graphDataValidatorForAnomalyValues,
} from '~/monitoring/utils';
import { timeWindows, timeWindowsKeyNames } from '~/monitoring/constants';
import {
graphDataPrometheusQuery,
graphDataPrometheusQueryRange,
anomalyMockGraphData,
} from './mock_data';
describe('getTimeDiff', () => {
function secondsBetween({ start, end }) {
return (new Date(end) - new Date(start)) / 1000;
}
function minutesBetween(timeRange) {
return secondsBetween(timeRange) / 60;
}
function hoursBetween(timeRange) {
return minutesBetween(timeRange) / 60;
}
it('defaults to an 8 hour (28800s) difference', () => {
const params = getTimeDiff();
expect(hoursBetween(params)).toEqual(8);
});
it('accepts time window as an argument', () => {
const params = getTimeDiff('thirtyMinutes');
expect(minutesBetween(params)).toEqual(30);
});
it('returns a value for every defined time window', () => {
const nonDefaultWindows = Object.keys(timeWindows).filter(window => window !== 'eightHours');
nonDefaultWindows.forEach(timeWindow => {
const params = getTimeDiff(timeWindow);
// Ensure we're not returning the default
expect(hoursBetween(params)).not.toEqual(8);
});
});
});
describe('getTimeWindow', () => {
[
{
args: [
{
start: '2019-10-01T18:27:47.000Z',
end: '2019-10-01T21:27:47.000Z',
},
],
expected: timeWindowsKeyNames.threeHours,
},
{
args: [
{
start: '2019-10-01T28:27:47.000Z',
end: '2019-10-01T21:27:47.000Z',
},
],
expected: null,
},
{
args: [
{
start: '',
end: '',
},
],
expected: null,
},
{
args: [
{
start: null,
end: null,
},
],
expected: null,
},
{
args: [{}],
expected: null,
},
].forEach(({ args, expected }) => {
it(`returns "${expected}" with args=${JSON.stringify(args)}`, () => {
expect(getTimeWindow(...args)).toEqual(expected);
});
});
});
describe('graphDataValidatorForValues', () => {
/*
* When dealing with a metric using the query format, e.g.
* query: 'max(go_memstats_alloc_bytes{job="prometheus"}) by (job) /1024/1024'
* the validator will look for the `value` key instead of `values`
*/
it('validates data with the query format', () => {
const validGraphData = graphDataValidatorForValues(true, graphDataPrometheusQuery);
expect(validGraphData).toBe(true);
});
/*
* When dealing with a metric using the query?range format, e.g.
* query_range: 'avg(sum(container_memory_usage_bytes{container_name!="POD",pod_name=~"^%{ci_environment_slug}-(.*)",namespace="%{kube_namespace}"}) by (job)) without (job) /1024/1024/1024',
* the validator will look for the `values` key instead of `value`
*/
it('validates data with the query_range format', () => {
const validGraphData = graphDataValidatorForValues(false, graphDataPrometheusQueryRange);
expect(validGraphData).toBe(true);
});
});
describe('stringToISODate', () => {
['', 'null', undefined, 'abc'].forEach(input => {
it(`throws error for invalid input like ${input}`, done => {
try {
stringToISODate(input);
} catch (e) {
expect(e).toBeDefined();
done();
}
});
});
[
{
input: '2019-09-09 01:01:01',
output: '2019-09-09T01:01:01Z',
},
{
input: '2019-09-09 00:00:00',
output: '2019-09-09T00:00:00Z',
},
{
input: '2019-09-09 23:59:59',
output: '2019-09-09T23:59:59Z',
},
{
input: '2019-09-09',
output: '2019-09-09T00:00:00Z',
},
].forEach(({ input, output }) => {
it(`returns ${output} from ${input}`, () => {
expect(stringToISODate(input)).toBe(output);
});
});
});
describe('ISODateToString', () => {
[
{
input: new Date('2019-09-09T00:00:00.000Z'),
output: '2019-09-09 00:00:00',
},
{
input: new Date('2019-09-09T07:00:00.000Z'),
output: '2019-09-09 07:00:00',
},
].forEach(({ input, output }) => {
it(`ISODateToString return ${output} for ${input}`, () => {
expect(ISODateToString(input)).toBe(output);
});
});
});
describe('truncateZerosInDateTime', () => {
[
{
input: '',
output: '',
},
{
input: '2019-10-10',
output: '2019-10-10',
},
{
input: '2019-10-10 00:00:01',
output: '2019-10-10 00:00:01',
},
{
input: '2019-10-10 00:00:00',
output: '2019-10-10',
},
].forEach(({ input, output }) => {
it(`truncateZerosInDateTime return ${output} for ${input}`, () => {
expect(truncateZerosInDateTime(input)).toBe(output);
});
});
});
describe('isValidDate', () => {
[
{
input: '2019-09-09T00:00:00.000Z',
output: true,
},
{
input: '2019-09-09T000:00.000Z',
output: false,
},
{
input: 'a2019-09-09T000:00.000Z',
output: false,
},
{
input: '2019-09-09T',
output: false,
},
{
input: '2019-09-09',
output: true,
},
{
input: '2019-9-9',
output: true,
},
{
input: '2019-9-',
output: true,
},
{
input: '2019--',
output: false,
},
{
input: '2019',
output: true,
},
{
input: '',
output: false,
},
{
input: null,
output: false,
},
].forEach(({ input, output }) => {
it(`isValidDate return ${output} for ${input}`, () => {
expect(isValidDate(input)).toBe(output);
});
});
});
describe('isDateTimePickerInputValid', () => {
[
{
input: null,
output: false,
},
{
input: '',
output: false,
},
{
input: 'xxxx-xx-xx',
output: false,
},
{
input: '9999-99-19',
output: false,
},
{
input: '2019-19-23',
output: false,
},
{
input: '2019-09-23',
output: true,
},
{
input: '2019-09-23 x',
output: false,
},
{
input: '2019-09-29 0:0:0',
output: false,
},
{
input: '2019-09-29 00:00:00',
output: true,
},
{
input: '2019-09-29 24:24:24',
output: false,
},
{
input: '2019-09-29 23:24:24',
output: true,
},
{
input: '2019-09-29 23:24:24 ',
output: false,
},
].forEach(({ input, output }) => {
it(`returns ${output} for ${input}`, () => {
expect(isDateTimePickerInputValid(input)).toBe(output);
});
});
});
describe('graphDataValidatorForAnomalyValues', () => {
let oneMetric;
let threeMetrics;
let fourMetrics;
beforeEach(() => {
oneMetric = graphDataPrometheusQuery;
threeMetrics = anomalyMockGraphData;
const metrics = [...threeMetrics.metrics];
metrics.push(threeMetrics.metrics[0]);
fourMetrics = {
...anomalyMockGraphData,
metrics,
};
});
/*
* Anomaly charts can accept results for exactly 3 metrics,
*/
it('validates passes with the right query format', () => {
expect(graphDataValidatorForAnomalyValues(threeMetrics)).toBe(true);
});
it('validation fails for wrong format, 1 metric', () => {
expect(graphDataValidatorForAnomalyValues(oneMetric)).toBe(false);
});
it('validation fails for wrong format, more than 3 metrics', () => {
expect(graphDataValidatorForAnomalyValues(fourMetrics)).toBe(false);
});
});
# frozen_string_literal: true
require 'spec_helper'
describe API::Pages do
let_it_be(:project) { create(:project, path: 'my.project', pages_https_only: false) }
let_it_be(:admin) { create(:admin) }
let_it_be(:user) { create(:user) }
before do
project.add_maintainer(user)
project.mark_pages_as_deployed
end
describe 'DELETE /projects/:id/pages' do
context 'when Pages is disabled' do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(false)
end
it_behaves_like '404 response' do
let(:request) { delete api("/projects/#{project.id}/pages", admin)}
end
end
context 'when Pages is enabled' do
before do
allow(Gitlab.config.pages).to receive(:enabled).and_return(true)
end
context 'when Pages are deployed' do
it 'returns 204' do
delete api("/projects/#{project.id}/pages", admin)
expect(response).to have_gitlab_http_status(204)
end
it 'removes the pages' do
expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project).and_return true
expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, project.namespace.full_path, anything)
delete api("/projects/#{project.id}/pages", admin )
expect(project.reload.pages_metadatum.deployed?).to be(false)
end
end
context 'when pages are not deployed' do
before do
project.mark_pages_as_not_deployed
end
it 'returns 204' do
delete api("/projects/#{project.id}/pages", admin)
expect(response).to have_gitlab_http_status(204)
end
end
context 'when there is no project' do
it 'returns 404' do
id = -1
delete api("/projects/#{id}/pages", admin)
expect(response).to have_gitlab_http_status(404)
end
end
end
end
end
# frozen_string_literal: true
require 'spec_helper'
describe Pages::DeleteService do
let_it_be(:project) { create(:project, path: "my.project")}
let_it_be(:admin) { create(:admin) }
let_it_be(:domain) { create(:pages_domain, project: project) }
let_it_be(:service) { described_class.new(project, admin)}
it 'deletes published pages' do
expect_any_instance_of(Gitlab::PagesTransfer).to receive(:rename_project).and_return true
expect(PagesWorker).to receive(:perform_in).with(5.minutes, :remove, project.namespace.full_path, anything)
service.execute
expect(project.reload.pages_metadatum.deployed?).to be(false)
end
it 'deletes all domains' do
expect(project.pages_domains.count).to be 1
service.execute
expect(project.reload.pages_domains.count).to be 0
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment