diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/frontend/monitoring/utils_spec.js | 342 | ||||
-rw-r--r-- | spec/javascripts/monitoring/utils_spec.js | 345 | ||||
-rw-r--r-- | spec/requests/api/pages/pages_spec.rb | 71 | ||||
-rw-r--r-- | spec/services/pages/delete_services_spec.rb | 27 |
4 files changed, 439 insertions, 346 deletions
diff --git a/spec/frontend/monitoring/utils_spec.js b/spec/frontend/monitoring/utils_spec.js index 1e8d5753885..9b1a331e3b5 100644 --- a/spec/frontend/monitoring/utils_spec.js +++ b/spec/frontend/monitoring/utils_spec.js @@ -1,6 +1,12 @@ 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); + }); + }); }); diff --git a/spec/javascripts/monitoring/utils_spec.js b/spec/javascripts/monitoring/utils_spec.js deleted file mode 100644 index 3459b44c7ec..00000000000 --- a/spec/javascripts/monitoring/utils_spec.js +++ /dev/null @@ -1,345 +0,0 @@ -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); - }); -}); diff --git a/spec/requests/api/pages/pages_spec.rb b/spec/requests/api/pages/pages_spec.rb new file mode 100644 index 00000000000..2085c509eff --- /dev/null +++ b/spec/requests/api/pages/pages_spec.rb @@ -0,0 +1,71 @@ +# 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 diff --git a/spec/services/pages/delete_services_spec.rb b/spec/services/pages/delete_services_spec.rb new file mode 100644 index 00000000000..c253f294e80 --- /dev/null +++ b/spec/services/pages/delete_services_spec.rb @@ -0,0 +1,27 @@ +# 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 |