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
path: root/spec
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2020-02-11 21:08:58 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2020-02-11 21:08:58 +0300
commit1ca9950d5f890cd8f185e1eda158b969a7244fe2 (patch)
tree6f62715938a4b2b001705c51c697609a8e0850ae /spec
parentbcc77054ee9aefd1e332e04a4189390fd5a3112e (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
-rw-r--r--spec/controllers/admin/services_controller_spec.rb12
-rw-r--r--spec/controllers/projects/serverless/functions_controller_spec.rb105
-rw-r--r--spec/controllers/projects/services_controller_spec.rb6
-rw-r--r--spec/factories/pages_domains.rb4
-rw-r--r--spec/finders/projects/serverless/functions_finder_spec.rb4
-rw-r--r--spec/fixtures/trace/sample_trace2
-rw-r--r--spec/frontend/environments/environments_app_spec.js168
-rw-r--r--spec/frontend/monitoring/components/dashboard_spec.js200
-rw-r--r--spec/frontend/monitoring/components/dashboards_dropdown_spec.js63
-rw-r--r--spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js35
-rw-r--r--spec/frontend/monitoring/components/graph_group_spec.js15
-rw-r--r--spec/frontend/monitoring/components/panel_type_spec.js14
-rw-r--r--spec/graphql/types/snippets/blob_type_spec.rb7
-rw-r--r--spec/javascripts/environments/environments_app_spec.js279
-rw-r--r--spec/lib/gitlab/import_export/project_tree_restorer_spec.rb4
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml2
-rw-r--r--spec/lib/gitlab/serverless/service_spec.rb134
-rw-r--r--spec/lib/gitlab/usage_data_spec.rb2
-rw-r--r--spec/migrations/migrate_propagate_service_template_sidekiq_queue_spec.rb29
-rw-r--r--spec/models/service_spec.rb52
-rw-r--r--spec/presenters/snippet_blob_presenter_spec.rb38
-rw-r--r--spec/services/projects/create_service_spec.rb14
-rw-r--r--spec/services/projects/propagate_service_template_spec.rb (renamed from spec/services/projects/propagate_instance_level_service_spec.rb)36
-rw-r--r--spec/support/helpers/kubernetes_helpers.rb16
-rw-r--r--spec/support/shared_examples/workers/pages_domain_cron_worker_shared_examples.rb21
-rw-r--r--spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb8
-rw-r--r--spec/workers/pages_domain_verification_cron_worker_spec.rb8
-rw-r--r--spec/workers/propagate_instance_level_service_worker_spec.rb31
-rw-r--r--spec/workers/propagate_service_template_worker_spec.rb31
29 files changed, 708 insertions, 632 deletions
diff --git a/spec/controllers/admin/services_controller_spec.rb b/spec/controllers/admin/services_controller_spec.rb
index 6f59a5ac016..44233776865 100644
--- a/spec/controllers/admin/services_controller_spec.rb
+++ b/spec/controllers/admin/services_controller_spec.rb
@@ -15,11 +15,11 @@ describe Admin::ServicesController do
Service.available_services_names.each do |service_name|
context "#{service_name}" do
let!(:service) do
- service_instance = "#{service_name}_service".camelize.constantize
- service_instance.where(instance: true).first_or_create
+ service_template = "#{service_name}_service".camelize.constantize
+ service_template.where(template: true).first_or_create
end
- it 'successfully displays the service' do
+ it 'successfully displays the template' do
get :edit, params: { id: service.id }
expect(response).to have_gitlab_http_status(:ok)
@@ -34,7 +34,7 @@ describe Admin::ServicesController do
RedmineService.create(
project: project,
active: false,
- instance: true,
+ template: true,
properties: {
project_url: 'http://abc',
issues_url: 'http://abc',
@@ -44,7 +44,7 @@ describe Admin::ServicesController do
end
it 'calls the propagation worker when service is active' do
- expect(PropagateInstanceLevelServiceWorker).to receive(:perform_async).with(service.id)
+ expect(PropagateServiceTemplateWorker).to receive(:perform_async).with(service.id)
put :update, params: { id: service.id, service: { active: true } }
@@ -52,7 +52,7 @@ describe Admin::ServicesController do
end
it 'does not call the propagation worker when service is not active' do
- expect(PropagateInstanceLevelServiceWorker).not_to receive(:perform_async)
+ expect(PropagateServiceTemplateWorker).not_to receive(:perform_async)
put :update, params: { id: service.id, service: { properties: {} } }
diff --git a/spec/controllers/projects/serverless/functions_controller_spec.rb b/spec/controllers/projects/serverless/functions_controller_spec.rb
index f0153ac37bf..db7533eb609 100644
--- a/spec/controllers/projects/serverless/functions_controller_spec.rb
+++ b/spec/controllers/projects/serverless/functions_controller_spec.rb
@@ -14,9 +14,11 @@ describe Projects::Serverless::FunctionsController do
let!(:deployment) { create(:deployment, :success, environment: environment, cluster: cluster) }
let(:knative_services_finder) { environment.knative_services_finder }
let(:function_description) { 'A serverless function' }
+ let(:function_name) { 'some-function-name' }
let(:knative_stub_options) do
- { namespace: namespace.namespace, name: cluster.project.name, description: function_description }
+ { namespace: namespace.namespace, name: function_name, description: function_description }
end
+ let(:knative) { create(:clusters_applications_knative, :installed, cluster: cluster) }
let(:namespace) do
create(:cluster_kubernetes_namespace,
@@ -87,25 +89,65 @@ describe Projects::Serverless::FunctionsController do
end
context 'when functions were found' do
- let(:functions) { ["asdf"] }
+ let(:functions) { [{}, {}] }
before do
- stub_kubeclient_knative_services(namespace: namespace.namespace)
- get :index, params: params({ format: :json })
+ stub_kubeclient_knative_services(namespace: namespace.namespace, cluster_id: cluster.id, name: function_name)
end
it 'returns functions' do
+ get :index, params: params({ format: :json })
expect(json_response["functions"]).not_to be_empty
end
- it { expect(response).to have_gitlab_http_status(:ok) }
+ it 'filters out the functions whose cluster the user does not have permission to read' do
+ allow(controller).to receive(:can?).and_return(true)
+ expect(controller).to receive(:can?).with(user, :read_cluster, cluster).and_return(false)
+
+ get :index, params: params({ format: :json })
+
+ expect(json_response["functions"]).to be_empty
+ end
+
+ it 'returns a successful response status' do
+ get :index, params: params({ format: :json })
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+
+ context 'when there is serverless domain for a cluster' do
+ let!(:serverless_domain_cluster) do
+ create(:serverless_domain_cluster, clusters_applications_knative_id: knative.id)
+ end
+
+ it 'returns JSON with function details with serverless domain URL' do
+ get :index, params: params({ format: :json })
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(json_response["functions"]).not_to be_empty
+
+ expect(json_response["functions"]).to all(
+ include(
+ 'url' => "https://#{function_name}-#{serverless_domain_cluster.uuid[0..1]}a1#{serverless_domain_cluster.uuid[2..-3]}f2#{serverless_domain_cluster.uuid[-2..-1]}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}"
+ )
+ )
+ end
+ end
+
+ context 'when there is no serverless domain for a cluster' do
+ it 'keeps function URL as it was' do
+ expect(Gitlab::Serverless::Domain).not_to receive(:new)
+
+ get :index, params: params({ format: :json })
+ expect(response).to have_gitlab_http_status(:ok)
+ end
+ end
end
end
end
describe 'GET #show' do
- context 'invalid data' do
- it 'has a bad function name' do
+ context 'with function that does not exist' do
+ it 'returns 404' do
get :show, params: params({ format: :json, environment_id: "*", id: "foo" })
expect(response).to have_gitlab_http_status(:not_found)
end
@@ -113,15 +155,50 @@ describe Projects::Serverless::FunctionsController do
context 'with valid data', :use_clean_rails_memory_store_caching do
shared_examples 'GET #show with valid data' do
- it 'has a valid function name' do
- get :show, params: params({ format: :json, environment_id: "*", id: cluster.project.name })
+ context 'when there is serverless domain for a cluster' do
+ let!(:serverless_domain_cluster) do
+ create(:serverless_domain_cluster, clusters_applications_knative_id: knative.id)
+ end
+
+ it 'returns JSON with function details with serverless domain URL' do
+ get :show, params: params({ format: :json, environment_id: "*", id: function_name })
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(json_response).to include(
+ 'url' => "https://#{function_name}-#{serverless_domain_cluster.uuid[0..1]}a1#{serverless_domain_cluster.uuid[2..-3]}f2#{serverless_domain_cluster.uuid[-2..-1]}#{"%x" % environment.id}-#{environment.slug}.#{serverless_domain_cluster.domain}"
+ )
+ end
+
+ it 'returns 404 when user does not have permission to read the cluster' do
+ allow(controller).to receive(:can?).and_return(true)
+ expect(controller).to receive(:can?).with(user, :read_cluster, cluster).and_return(false)
+
+ get :show, params: params({ format: :json, environment_id: "*", id: function_name })
+
+ expect(response).to have_gitlab_http_status(:not_found)
+ end
+ end
+
+ context 'when there is no serverless domain for a cluster' do
+ it 'keeps function URL as it was' do
+ get :show, params: params({ format: :json, environment_id: "*", id: function_name })
+ expect(response).to have_gitlab_http_status(:ok)
+
+ expect(json_response).to include(
+ 'url' => "http://#{function_name}.#{namespace.namespace}.example.com"
+ )
+ end
+ end
+
+ it 'return json with function details' do
+ get :show, params: params({ format: :json, environment_id: "*", id: function_name })
expect(response).to have_gitlab_http_status(:ok)
expect(json_response).to include(
- 'name' => project.name,
- 'url' => "http://#{project.name}.#{namespace.namespace}.example.com",
+ 'name' => function_name,
+ 'url' => "http://#{function_name}.#{namespace.namespace}.example.com",
'description' => function_description,
- 'podcount' => 1
+ 'podcount' => 0
)
end
end
@@ -180,8 +257,8 @@ describe Projects::Serverless::FunctionsController do
'knative_installed' => 'checking',
'functions' => [
a_hash_including(
- 'name' => project.name,
- 'url' => "http://#{project.name}.#{namespace.namespace}.example.com",
+ 'name' => function_name,
+ 'url' => "http://#{function_name}.#{namespace.namespace}.example.com",
'description' => function_description
)
]
diff --git a/spec/controllers/projects/services_controller_spec.rb b/spec/controllers/projects/services_controller_spec.rb
index b6c64a964a6..fb7cca3997b 100644
--- a/spec/controllers/projects/services_controller_spec.rb
+++ b/spec/controllers/projects/services_controller_spec.rb
@@ -154,12 +154,12 @@ describe Projects::ServicesController do
end
end
- context 'when activating Jira service from instance level service' do
+ context 'when activating Jira service from a template' do
let(:service) do
- create(:jira_service, project: project, instance: true)
+ create(:jira_service, project: project, template: true)
end
- it 'activate Jira service from instance level service' do
+ it 'activate Jira service from template' do
expect(flash[:notice]).to eq 'Jira activated.'
end
end
diff --git a/spec/factories/pages_domains.rb b/spec/factories/pages_domains.rb
index 7606e806e04..f914128ed3b 100644
--- a/spec/factories/pages_domains.rb
+++ b/spec/factories/pages_domains.rb
@@ -380,5 +380,9 @@ x6zG6WoibsbsJMj70nwseUnPTBQNDP+j61RJjC/r
scope { :instance }
usage { :serverless }
end
+
+ trait :with_project do
+ association :project
+ end
end
end
diff --git a/spec/finders/projects/serverless/functions_finder_spec.rb b/spec/finders/projects/serverless/functions_finder_spec.rb
index 67eda297b91..4e9f3d371ce 100644
--- a/spec/finders/projects/serverless/functions_finder_spec.rb
+++ b/spec/finders/projects/serverless/functions_finder_spec.rb
@@ -153,8 +153,8 @@ describe Projects::Serverless::FunctionsFinder do
*knative_services_finder.cache_args)
result = finder.service(cluster.environment_scope, cluster.project.name)
- expect(result).not_to be_empty
- expect(result["metadata"]["name"]).to be_eql(cluster.project.name)
+ expect(result).to be_present
+ expect(result.name).to be_eql(cluster.project.name)
end
it 'has metrics', :use_clean_rails_memory_store_caching do
diff --git a/spec/fixtures/trace/sample_trace b/spec/fixtures/trace/sample_trace
index 1aba1e76d0b..d774d154496 100644
--- a/spec/fixtures/trace/sample_trace
+++ b/spec/fixtures/trace/sample_trace
@@ -2736,7 +2736,7 @@ Service
when repository is empty
test runs execute
Template
- .build_from_instance
+ .build_from_template
when template is invalid
sets service template to inactive when template is invalid
for pushover service
diff --git a/spec/frontend/environments/environments_app_spec.js b/spec/frontend/environments/environments_app_spec.js
new file mode 100644
index 00000000000..f3d2bd2462e
--- /dev/null
+++ b/spec/frontend/environments/environments_app_spec.js
@@ -0,0 +1,168 @@
+import { mount, shallowMount } from '@vue/test-utils';
+import axios from '~/lib/utils/axios_utils';
+import MockAdapter from 'axios-mock-adapter';
+import Container from '~/environments/components/container.vue';
+import EmptyState from '~/environments/components/empty_state.vue';
+import EnvironmentsApp from '~/environments/components/environments_app.vue';
+import { environment, folder } from './mock_data';
+
+describe('Environment', () => {
+ let mock;
+ let wrapper;
+
+ const mockData = {
+ endpoint: 'environments.json',
+ canCreateEnvironment: true,
+ canReadEnvironment: true,
+ newEnvironmentPath: 'environments/new',
+ helpPagePath: 'help',
+ canaryDeploymentFeatureId: 'canary_deployment',
+ showCanaryDeploymentCallout: true,
+ userCalloutsPath: '/callouts',
+ lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
+ helpCanaryDeploymentsPath: 'help/canary-deployments',
+ };
+
+ const mockRequest = (response, body) => {
+ mock.onGet(mockData.endpoint).reply(response, body, {
+ 'X-nExt-pAge': '2',
+ 'x-page': '1',
+ 'X-Per-Page': '1',
+ 'X-Prev-Page': '',
+ 'X-TOTAL': '37',
+ 'X-Total-Pages': '2',
+ });
+ };
+
+ const createWrapper = (shallow = false) => {
+ const fn = shallow ? shallowMount : mount;
+ wrapper = fn(EnvironmentsApp, { propsData: mockData });
+ return axios.waitForAll();
+ };
+
+ beforeEach(() => {
+ mock = new MockAdapter(axios);
+ });
+
+ afterEach(() => {
+ wrapper.destroy();
+ mock.restore();
+ });
+
+ describe('successful request', () => {
+ describe('without environments', () => {
+ beforeEach(() => {
+ mockRequest(200, { environments: [] });
+ return createWrapper(true);
+ });
+
+ it('should render the empty state', () => {
+ expect(wrapper.find(EmptyState).exists()).toBe(true);
+ });
+
+ describe('when it is possible to enable a review app', () => {
+ beforeEach(() => {
+ mockRequest(200, { environments: [], review_app: { can_setup_review_app: true } });
+ return createWrapper();
+ });
+
+ it('should render the enable review app button', () => {
+ expect(wrapper.find('.js-enable-review-app-button').text()).toContain(
+ 'Enable review app',
+ );
+ });
+ });
+ });
+
+ describe('with paginated environments', () => {
+ const environmentList = [environment];
+
+ beforeEach(() => {
+ mockRequest(200, {
+ environments: environmentList,
+ stopped_count: 1,
+ available_count: 0,
+ });
+ return createWrapper();
+ });
+
+ it('should render a conatiner table with environments', () => {
+ const containerTable = wrapper.find(Container);
+
+ expect(containerTable.exists()).toBe(true);
+ expect(containerTable.props('environments').length).toEqual(environmentList.length);
+ expect(containerTable.find('.environment-name').text()).toEqual(environmentList[0].name);
+ });
+
+ describe('pagination', () => {
+ it('should render pagination', () => {
+ expect(wrapper.findAll('.gl-pagination li').length).toEqual(9);
+ });
+
+ it('should make an API request when page is clicked', () => {
+ jest.spyOn(wrapper.vm, 'updateContent').mockImplementation(() => {});
+
+ wrapper.find('.gl-pagination li:nth-child(3) .page-link').trigger('click');
+ expect(wrapper.vm.updateContent).toHaveBeenCalledWith({ scope: 'available', page: '2' });
+ });
+
+ it('should make an API request when using tabs', () => {
+ jest.spyOn(wrapper.vm, 'updateContent').mockImplementation(() => {});
+ wrapper.find('.js-environments-tab-stopped').trigger('click');
+ expect(wrapper.vm.updateContent).toHaveBeenCalledWith({ scope: 'stopped', page: '1' });
+ });
+ });
+ });
+ });
+
+ describe('unsuccessful request', () => {
+ beforeEach(() => {
+ mockRequest(500, {});
+ return createWrapper(true);
+ });
+
+ it('should render empty state', () => {
+ expect(wrapper.find(EmptyState).exists()).toBe(true);
+ });
+ });
+
+ describe('expandable folders', () => {
+ beforeEach(() => {
+ mockRequest(200, {
+ environments: [folder],
+ stopped_count: 1,
+ available_count: 0,
+ });
+
+ mock.onGet(environment.folder_path).reply(200, { environments: [environment] });
+
+ return createWrapper().then(() => {
+ // open folder
+ wrapper.find('.folder-name').trigger('click');
+ return axios.waitForAll();
+ });
+ });
+
+ it('should open a closed folder', () => {
+ expect(wrapper.find('.folder-icon.ic-chevron-right').exists()).toBe(false);
+ });
+
+ it('should close an opened folder', () => {
+ expect(wrapper.find('.folder-icon.ic-chevron-down').exists()).toBe(true);
+
+ // close folder
+ wrapper.find('.folder-name').trigger('click');
+ wrapper.vm.$nextTick(() => {
+ expect(wrapper.find('.folder-icon.ic-chevron-down').exists()).toBe(false);
+ });
+ });
+
+ it('should show children environments', () => {
+ expect(wrapper.findAll('.js-child-row').length).toEqual(1);
+ });
+
+ it('should show a button to show all environments', () => {
+ expect(wrapper.find('.text-center > a.btn').text()).toContain('Show all');
+ });
+ });
+});
diff --git a/spec/frontend/monitoring/components/dashboard_spec.js b/spec/frontend/monitoring/components/dashboard_spec.js
index 7a039d46d39..15c82242262 100644
--- a/spec/frontend/monitoring/components/dashboard_spec.js
+++ b/spec/frontend/monitoring/components/dashboard_spec.js
@@ -91,10 +91,10 @@ describe('Dashboard', () => {
});
describe('no data found', () => {
- beforeEach(done => {
+ beforeEach(() => {
createShallowWrapper();
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('shows the environment selector dropdown', () => {
@@ -118,20 +118,15 @@ describe('Dashboard', () => {
});
});
- it('shows up a loading state', done => {
+ it('shows up a loading state', () => {
createShallowWrapper({ hasMetrics: true }, { methods: {} });
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.vm.emptyState).toEqual('loading');
-
- done();
- })
- .catch(done.fail);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.emptyState).toEqual('loading');
+ });
});
- it('hides the group panels when showPanels is false', done => {
+ it('hides the group panels when showPanels is false', () => {
createMountedWrapper(
{ hasMetrics: true, showPanels: false },
{ stubs: ['graph-group', 'panel-type'] },
@@ -139,15 +134,10 @@ describe('Dashboard', () => {
setupComponentStore(wrapper);
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.vm.showEmptyState).toEqual(false);
- expect(wrapper.findAll('.prometheus-panel')).toHaveLength(0);
-
- done();
- })
- .catch(done.fail);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.vm.showEmptyState).toEqual(false);
+ expect(wrapper.findAll('.prometheus-panel')).toHaveLength(0);
+ });
});
it('fetches the metrics data with proper time window', () => {
@@ -171,43 +161,32 @@ describe('Dashboard', () => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper);
+
+ return wrapper.vm.$nextTick();
});
- it('renders the environments dropdown with a number of environments', done => {
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length);
-
- findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => {
- const anchorEl = itemWrapper.find('a');
- if (anchorEl.exists() && environmentData[index].metrics_path) {
- const href = anchorEl.attributes('href');
- expect(href).toBe(environmentData[index].metrics_path);
- }
- });
+ it('renders the environments dropdown with a number of environments', () => {
+ expect(findAllEnvironmentsDropdownItems().length).toEqual(environmentData.length);
- done();
- })
- .catch(done.fail);
+ findAllEnvironmentsDropdownItems().wrappers.forEach((itemWrapper, index) => {
+ const anchorEl = itemWrapper.find('a');
+ if (anchorEl.exists() && environmentData[index].metrics_path) {
+ const href = anchorEl.attributes('href');
+ expect(href).toBe(environmentData[index].metrics_path);
+ }
+ });
});
- it('renders the environments dropdown with a single active element', done => {
- wrapper.vm
- .$nextTick()
- .then(() => {
- const activeItem = findAllEnvironmentsDropdownItems().wrappers.filter(itemWrapper =>
- itemWrapper.find('.active').exists(),
- );
+ it('renders the environments dropdown with a single active element', () => {
+ const activeItem = findAllEnvironmentsDropdownItems().wrappers.filter(itemWrapper =>
+ itemWrapper.find('.active').exists(),
+ );
- expect(activeItem.length).toBe(1);
- done();
- })
- .catch(done.fail);
+ expect(activeItem.length).toBe(1);
});
});
- it('hides the environments dropdown list when there is no environments', done => {
+ it('hides the environments dropdown list when there is no environments', () => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
wrapper.vm.$store.commit(
@@ -219,35 +198,27 @@ describe('Dashboard', () => {
mockedQueryResultPayload,
);
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(findAllEnvironmentsDropdownItems()).toHaveLength(0);
- done();
- })
- .catch(done.fail);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findAllEnvironmentsDropdownItems()).toHaveLength(0);
+ });
});
- it('renders the datetimepicker dropdown', done => {
+ it('renders the datetimepicker dropdown', () => {
createMountedWrapper({ hasMetrics: true }, { stubs: ['graph-group', 'panel-type'] });
setupComponentStore(wrapper);
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(wrapper.find(DateTimePicker).exists()).toBe(true);
- done();
- })
- .catch(done.fail);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(wrapper.find(DateTimePicker).exists()).toBe(true);
+ });
});
describe('when one of the metrics is missing', () => {
- beforeEach(done => {
+ beforeEach(() => {
createShallowWrapper({ hasMetrics: true });
setupComponentStore(wrapper);
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('shows a group empty area', () => {
@@ -300,7 +271,7 @@ describe('Dashboard', () => {
const resultEnvs = environmentData.filter(({ name }) => name.indexOf(searchTerm) !== -1);
setSearchTerm(searchTerm);
- return wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick().then(() => {
expect(findAllEnvironmentsDropdownItems().length).toEqual(resultEnvs.length);
});
});
@@ -349,12 +320,12 @@ describe('Dashboard', () => {
const findDraggablePanels = () => wrapper.findAll('.js-draggable-panel');
const findRearrangeButton = () => wrapper.find('.js-rearrange-button');
- beforeEach(done => {
+ beforeEach(() => {
createShallowWrapper({ hasMetrics: true });
setupComponentStore(wrapper);
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('wraps vuedraggable', () => {
@@ -368,9 +339,9 @@ describe('Dashboard', () => {
});
describe('when rearrange is enabled', () => {
- beforeEach(done => {
+ beforeEach(() => {
wrapper.setProps({ rearrangePanelsAvailable: true });
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('displays rearrange button', () => {
@@ -383,9 +354,9 @@ describe('Dashboard', () => {
.at(0)
.find('.js-draggable-remove');
- beforeEach(done => {
+ beforeEach(() => {
findRearrangeButton().vm.$emit('click');
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('it enables draggables', () => {
@@ -393,7 +364,7 @@ describe('Dashboard', () => {
expect(findEnabledDraggables()).toEqual(findDraggables());
});
- it('metrics can be swapped', done => {
+ it('metrics can be swapped', () => {
const firstDraggable = findDraggables().at(0);
const mockMetrics = [...metricsDashboardPayload.panel_groups[1].panels];
@@ -404,33 +375,30 @@ describe('Dashboard', () => {
[mockMetrics[0], mockMetrics[1]] = [mockMetrics[1], mockMetrics[0]];
firstDraggable.vm.$emit('input', mockMetrics);
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
const { panels } = wrapper.vm.dashboard.panel_groups[1];
expect(panels[1].title).toEqual(firstTitle);
expect(panels[0].title).toEqual(secondTitle);
- done();
});
});
- it('shows a remove button, which removes a panel', done => {
+ it('shows a remove button, which removes a panel', () => {
expect(findFirstDraggableRemoveButton().isEmpty()).toBe(false);
expect(findDraggablePanels().length).toEqual(expectedPanelCount);
findFirstDraggableRemoveButton().trigger('click');
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findDraggablePanels().length).toEqual(expectedPanelCount - 1);
- done();
});
});
- it('it disables draggables when clicked again', done => {
+ it('it disables draggables when clicked again', () => {
findRearrangeButton().vm.$emit('click');
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findRearrangeButton().attributes('pressed')).toBeFalsy();
expect(findEnabledDraggables().length).toBe(0);
- done();
});
});
});
@@ -438,13 +406,13 @@ describe('Dashboard', () => {
});
describe('cluster health', () => {
- beforeEach(done => {
+ beforeEach(() => {
mock.onGet(propsData.metricsEndpoint).reply(statusCodes.OK, JSON.stringify({}));
createShallowWrapper({ hasMetrics: true, showHeader: false });
// all_dashboards is not defined in health dashboards
wrapper.vm.$store.commit(`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`, undefined);
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('hides dashboard header by default', () => {
@@ -460,33 +428,29 @@ describe('Dashboard', () => {
describe('dashboard edit link', () => {
const findEditLink = () => wrapper.find('.js-edit-link');
- beforeEach(done => {
+ beforeEach(() => {
createShallowWrapper({ hasMetrics: true });
wrapper.vm.$store.commit(
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
dashboardGitResponse,
);
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('is not present for the default dashboard', () => {
expect(findEditLink().exists()).toBe(false);
});
- it('is present for a custom dashboard, and links to its edit_path', done => {
+ it('is present for a custom dashboard, and links to its edit_path', () => {
const dashboard = dashboardGitResponse[1]; // non-default dashboard
const currentDashboard = dashboard.path;
wrapper.setProps({ currentDashboard });
- wrapper.vm
- .$nextTick()
- .then(() => {
- expect(findEditLink().exists()).toBe(true);
- expect(findEditLink().attributes('href')).toBe(dashboard.project_blob_path);
- done();
- })
- .catch(done.fail);
+ return wrapper.vm.$nextTick().then(() => {
+ expect(findEditLink().exists()).toBe(true);
+ expect(findEditLink().attributes('href')).toBe(dashboard.project_blob_path);
+ });
});
});
@@ -498,18 +462,14 @@ describe('Dashboard', () => {
`monitoringDashboard/${types.SET_ALL_DASHBOARDS}`,
dashboardGitResponse,
);
+
+ return wrapper.vm.$nextTick();
});
- it('shows the dashboard dropdown', done => {
- wrapper.vm
- .$nextTick()
- .then(() => {
- const dashboardDropdown = wrapper.find(DashboardsDropdown);
+ it('shows the dashboard dropdown', () => {
+ const dashboardDropdown = wrapper.find(DashboardsDropdown);
- expect(dashboardDropdown.exists()).toBe(true);
- done();
- })
- .catch(done.fail);
+ expect(dashboardDropdown.exists()).toBe(true);
});
});
@@ -524,20 +484,16 @@ describe('Dashboard', () => {
},
{ stubs: ['graph-group', 'panel-type'] },
);
+
+ return wrapper.vm.$nextTick();
});
- it('shows the link', done => {
- wrapper.vm
- .$nextTick()
- .then(() => {
- const externalDashboardButton = wrapper.find('.js-external-dashboard-link');
+ it('shows the link', () => {
+ const externalDashboardButton = wrapper.find('.js-external-dashboard-link');
- expect(externalDashboardButton.exists()).toBe(true);
- expect(externalDashboardButton.is(GlButton)).toBe(true);
- expect(externalDashboardButton.text()).toContain('View full dashboard');
- done();
- })
- .catch(done.fail);
+ expect(externalDashboardButton.exists()).toBe(true);
+ expect(externalDashboardButton.is(GlButton)).toBe(true);
+ expect(externalDashboardButton.text()).toContain('View full dashboard');
});
});
@@ -550,12 +506,12 @@ describe('Dashboard', () => {
.at(i)
.props('clipboardText');
- beforeEach(done => {
+ beforeEach(() => {
createShallowWrapper({ hasMetrics: true, currentDashboard });
setupComponentStore(wrapper);
- wrapper.vm.$nextTick(done);
+ return wrapper.vm.$nextTick();
});
it('contains a link to the dashboard', () => {
@@ -565,23 +521,21 @@ describe('Dashboard', () => {
expect(getClipboardTextAt(0)).toContain(`y_label=`);
});
- it('strips the undefined parameter', done => {
+ it('strips the undefined parameter', () => {
wrapper.setProps({ currentDashboard: undefined });
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(getClipboardTextAt(0)).not.toContain(`dashboard=`);
expect(getClipboardTextAt(0)).toContain(`y_label=`);
- done();
});
});
- it('null parameter is stripped', done => {
+ it('null parameter is stripped', () => {
wrapper.setProps({ currentDashboard: null });
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(getClipboardTextAt(0)).not.toContain(`dashboard=`);
expect(getClipboardTextAt(0)).toContain(`y_label=`);
- done();
});
});
});
diff --git a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
index 51c7b22f242..0bcfabe6415 100644
--- a/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
+++ b/spec/frontend/monitoring/components/dashboards_dropdown_spec.js
@@ -131,20 +131,17 @@ describe('DashboardsDropdown', () => {
expect(findModal().contains(DuplicateDashboardForm)).toBe(true);
});
- it('saves a new dashboard', done => {
+ it('saves a new dashboard', () => {
findModal().vm.$emit('ok', okEvent);
- waitForPromises()
- .then(() => {
- expect(okEvent.preventDefault).toHaveBeenCalled();
-
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- expect(wrapper.vm.$refs.duplicateDashboardModal.hide).toHaveBeenCalled();
- expect(wrapper.emitted().selectDashboard).toBeTruthy();
- expect(findAlert().exists()).toBe(false);
- done();
- })
- .catch(done.fail);
+ return waitForPromises().then(() => {
+ expect(okEvent.preventDefault).toHaveBeenCalled();
+
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.vm.$refs.duplicateDashboardModal.hide).toHaveBeenCalled();
+ expect(wrapper.emitted().selectDashboard).toBeTruthy();
+ expect(findAlert().exists()).toBe(false);
+ });
});
describe('when a new dashboard is saved succesfully', () => {
@@ -167,52 +164,42 @@ describe('DashboardsDropdown', () => {
findModal().vm.$emit('ok', okEvent);
};
- it('to the default branch, redirects to the new dashboard', done => {
+ it('to the default branch, redirects to the new dashboard', () => {
submitForm({
branch: defaultBranch,
});
- waitForPromises()
- .then(() => {
- expect(wrapper.emitted().selectDashboard[0][0]).toEqual(newDashboard);
- done();
- })
- .catch(done.fail);
+ return waitForPromises().then(() => {
+ expect(wrapper.emitted().selectDashboard[0][0]).toEqual(newDashboard);
+ });
});
- it('to a new branch refreshes in the current dashboard', done => {
+ it('to a new branch refreshes in the current dashboard', () => {
submitForm({
branch: 'another-branch',
});
- waitForPromises()
- .then(() => {
- expect(wrapper.emitted().selectDashboard[0][0]).toEqual(dashboardGitResponse[0]);
- done();
- })
- .catch(done.fail);
+ return waitForPromises().then(() => {
+ expect(wrapper.emitted().selectDashboard[0][0]).toEqual(dashboardGitResponse[0]);
+ });
});
});
- it('handles error when a new dashboard is not saved', done => {
+ it('handles error when a new dashboard is not saved', () => {
const errMsg = 'An error occurred';
duplicateDashboardAction.mockRejectedValueOnce(errMsg);
findModal().vm.$emit('ok', okEvent);
- waitForPromises()
- .then(() => {
- expect(okEvent.preventDefault).toHaveBeenCalled();
-
- expect(findAlert().exists()).toBe(true);
- expect(findAlert().text()).toBe(errMsg);
+ return waitForPromises().then(() => {
+ expect(okEvent.preventDefault).toHaveBeenCalled();
- expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
- expect(wrapper.vm.$refs.duplicateDashboardModal.hide).not.toHaveBeenCalled();
+ expect(findAlert().exists()).toBe(true);
+ expect(findAlert().text()).toBe(errMsg);
- done();
- })
- .catch(done.fail);
+ expect(wrapper.find(GlLoadingIcon).exists()).toBe(false);
+ expect(wrapper.vm.$refs.duplicateDashboardModal.hide).not.toHaveBeenCalled();
+ });
});
it('id is correct, as the value of modal directive binding matches modal id', () => {
diff --git a/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js b/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
index 75a488b5c7b..10fd58f749d 100644
--- a/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
+++ b/spec/frontend/monitoring/components/duplicate_dashboard_form_spec.js
@@ -44,30 +44,27 @@ describe('DuplicateDashboardForm', () => {
describe('validates the file name', () => {
const findInvalidFeedback = () => findByRef('fileNameFormGroup').find('.invalid-feedback');
- it('when is empty', done => {
+ it('when is empty', () => {
setValue('fileName', '');
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findByRef('fileNameFormGroup').is('.is-valid')).toBe(true);
expect(findInvalidFeedback().exists()).toBe(false);
- done();
});
});
- it('when is valid', done => {
+ it('when is valid', () => {
setValue('fileName', 'my_dashboard.yml');
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findByRef('fileNameFormGroup').is('.is-valid')).toBe(true);
expect(findInvalidFeedback().exists()).toBe(false);
- done();
});
});
- it('when is not valid', done => {
+ it('when is not valid', () => {
setValue('fileName', 'my_dashboard.exe');
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findByRef('fileNameFormGroup').is('.is-invalid')).toBe(true);
expect(findInvalidFeedback().text()).toBeTruthy();
- done();
});
});
});
@@ -124,30 +121,26 @@ describe('DuplicateDashboardForm', () => {
});
});
- it('when a `default` branch option is set, branch input is invisible and ignored', done => {
+ it('when a `default` branch option is set, branch input is invisible and ignored', () => {
setChecked(wrapper.vm.$options.radioVals.DEFAULT);
setValue('branchName', 'a-new-branch');
expect(lastChange()).resolves.toMatchObject({
branch: defaultBranch,
});
- wrapper.vm.$nextTick(() => {
+
+ return wrapper.vm.$nextTick(() => {
expect(findByRef('branchName').isVisible()).toBe(false);
- done();
});
});
- it('when `new` branch option is chosen, focuses on the branch name input', done => {
+ it('when `new` branch option is chosen, focuses on the branch name input', () => {
setChecked(wrapper.vm.$options.radioVals.NEW);
- wrapper.vm
- .$nextTick()
- .then(() => {
- wrapper.find('form').trigger('change');
- expect(findByRef('branchName').is(':focus')).toBe(true);
- })
- .then(done)
- .catch(done.fail);
+ return wrapper.vm.$nextTick().then(() => {
+ wrapper.find('form').trigger('change');
+ expect(findByRef('branchName').is(':focus')).toBe(true);
+ });
});
});
});
diff --git a/spec/frontend/monitoring/components/graph_group_spec.js b/spec/frontend/monitoring/components/graph_group_spec.js
index 983785d0ecc..28a6af64394 100644
--- a/spec/frontend/monitoring/components/graph_group_spec.js
+++ b/spec/frontend/monitoring/components/graph_group_spec.js
@@ -32,25 +32,23 @@ describe('Graph group component', () => {
expect(findCaretIcon().props('name')).toBe('angle-down');
});
- it('should show the angle-right caret icon when the user collapses the group', done => {
+ it('should show the angle-right caret icon when the user collapses the group', () => {
wrapper.vm.collapse();
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findContent().isVisible()).toBe(false);
expect(findCaretIcon().props('name')).toBe('angle-right');
- done();
});
});
- it('should show the open the group when collapseGroup is set to true', done => {
+ it('should show the open the group when collapseGroup is set to true', () => {
wrapper.setProps({
collapseGroup: true,
});
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findContent().isVisible()).toBe(true);
expect(findCaretIcon().props('name')).toBe('angle-down');
- done();
});
});
@@ -102,13 +100,12 @@ describe('Graph group component', () => {
expect(findCaretIcon().exists()).toBe(false);
});
- it('should show the panel content when clicked', done => {
+ it('should show the panel content when clicked', () => {
wrapper.vm.collapse();
- wrapper.vm.$nextTick(() => {
+ return wrapper.vm.$nextTick(() => {
expect(findContent().isVisible()).toBe(true);
expect(findCaretIcon().exists()).toBe(false);
- done();
});
});
});
diff --git a/spec/frontend/monitoring/components/panel_type_spec.js b/spec/frontend/monitoring/components/panel_type_spec.js
index 6d8bd1d3a30..0d79babf386 100644
--- a/spec/frontend/monitoring/components/panel_type_spec.js
+++ b/spec/frontend/monitoring/components/panel_type_spec.js
@@ -28,6 +28,8 @@ describe('Panel Type component', () => {
const exampleText = 'example_text';
+ const findCopyLink = () => wrapper.find({ ref: 'copyChartLink' });
+
const createWrapper = props => {
wrapper = shallowMount(PanelType, {
propsData: {
@@ -96,8 +98,7 @@ describe('Panel Type component', () => {
});
it('sets no clipboard copy link on dropdown by default', () => {
- const link = () => wrapper.find({ ref: 'copyChartLink' });
- expect(link().exists()).toBe(false);
+ expect(findCopyLink().exists()).toBe(false);
});
describe('Time Series Chart panel type', () => {
@@ -204,7 +205,6 @@ describe('Panel Type component', () => {
});
describe('when cliboard data is available', () => {
- const link = () => wrapper.find({ ref: 'copyChartLink' });
const clipboardText = 'A value to copy.';
beforeEach(() => {
@@ -219,16 +219,16 @@ describe('Panel Type component', () => {
});
it('sets clipboard text on the dropdown', () => {
- expect(link().exists()).toBe(true);
- expect(link().element.dataset.clipboardText).toBe(clipboardText);
+ expect(findCopyLink().exists()).toBe(true);
+ expect(findCopyLink().element.dataset.clipboardText).toBe(clipboardText);
});
it('adds a copy button to the dropdown', () => {
- expect(link().text()).toContain('Generate link to chart');
+ expect(findCopyLink().text()).toContain('Generate link to chart');
});
it('opens a toast on click', () => {
- link().vm.$emit('click');
+ findCopyLink().vm.$emit('click');
expect(wrapper.vm.$toast.show).toHaveBeenCalled();
});
diff --git a/spec/graphql/types/snippets/blob_type_spec.rb b/spec/graphql/types/snippets/blob_type_spec.rb
index e7d4e5dfa2d..a263fada644 100644
--- a/spec/graphql/types/snippets/blob_type_spec.rb
+++ b/spec/graphql/types/snippets/blob_type_spec.rb
@@ -4,10 +4,9 @@ require 'spec_helper'
describe GitlabSchema.types['SnippetBlob'] do
it 'has the correct fields' do
- expected_fields = [:highlighted_data, :raw_path,
- :size, :binary, :name, :path,
- :simple_viewer, :rich_viewer,
- :mode]
+ expected_fields = [:highlighted_data, :plain_highlighted_data,
+ :raw_path, :size, :binary, :name, :path,
+ :simple_viewer, :rich_viewer, :mode]
is_expected.to have_graphql_fields(*expected_fields)
end
diff --git a/spec/javascripts/environments/environments_app_spec.js b/spec/javascripts/environments/environments_app_spec.js
deleted file mode 100644
index 6c05b609923..00000000000
--- a/spec/javascripts/environments/environments_app_spec.js
+++ /dev/null
@@ -1,279 +0,0 @@
-import Vue from 'vue';
-import MockAdapter from 'axios-mock-adapter';
-import mountComponent from 'spec/helpers/vue_mount_component_helper';
-import axios from '~/lib/utils/axios_utils';
-import environmentsComponent from '~/environments/components/environments_app.vue';
-import { environment, folder } from './mock_data';
-
-describe('Environment', () => {
- const mockData = {
- endpoint: 'environments.json',
- canCreateEnvironment: true,
- canReadEnvironment: true,
- newEnvironmentPath: 'environments/new',
- helpPagePath: 'help',
- canaryDeploymentFeatureId: 'canary_deployment',
- showCanaryDeploymentCallout: true,
- userCalloutsPath: '/callouts',
- lockPromotionSvgPath: '/assets/illustrations/lock-promotion.svg',
- helpCanaryDeploymentsPath: 'help/canary-deployments',
- };
-
- let EnvironmentsComponent;
- let component;
- let mock;
-
- beforeEach(() => {
- mock = new MockAdapter(axios);
-
- EnvironmentsComponent = Vue.extend(environmentsComponent);
- });
-
- afterEach(() => {
- component.$destroy();
- mock.restore();
- });
-
- describe('successful request', () => {
- describe('without environments', () => {
- beforeEach(done => {
- mock.onGet(mockData.endpoint).reply(200, { environments: [] });
-
- component = mountComponent(EnvironmentsComponent, mockData);
-
- setTimeout(() => {
- done();
- }, 0);
- });
-
- it('should render the empty state', () => {
- expect(component.$el.querySelector('.js-new-environment-button').textContent).toContain(
- 'New environment',
- );
-
- expect(component.$el.querySelector('.js-blank-state-title').textContent).toContain(
- "You don't have any environments right now",
- );
- });
-
- describe('when it is possible to enable a review app', () => {
- beforeEach(done => {
- mock
- .onGet(mockData.endpoint)
- .reply(200, { environments: [], review_app: { can_setup_review_app: true } });
-
- component = mountComponent(EnvironmentsComponent, mockData);
-
- setTimeout(() => {
- done();
- }, 0);
- });
-
- it('should render the enable review app button', () => {
- expect(component.$el.querySelector('.js-enable-review-app-button').textContent).toContain(
- 'Enable review app',
- );
- });
- });
- });
-
- describe('with paginated environments', () => {
- beforeEach(done => {
- mock.onGet(mockData.endpoint).reply(
- 200,
- {
- environments: [environment],
- stopped_count: 1,
- available_count: 0,
- },
- {
- 'X-nExt-pAge': '2',
- 'x-page': '1',
- 'X-Per-Page': '1',
- 'X-Prev-Page': '',
- 'X-TOTAL': '37',
- 'X-Total-Pages': '2',
- },
- );
-
- component = mountComponent(EnvironmentsComponent, mockData);
-
- setTimeout(() => {
- done();
- }, 0);
- });
-
- it('should render a table with environments', () => {
- expect(component.$el.querySelectorAll('table')).not.toBeNull();
- expect(component.$el.querySelector('.environment-name').textContent.trim()).toEqual(
- environment.name,
- );
- });
-
- describe('pagination', () => {
- it('should render pagination', () => {
- expect(component.$el.querySelectorAll('.gl-pagination li').length).toEqual(9);
- });
-
- it('should make an API request when page is clicked', done => {
- spyOn(component, 'updateContent');
- setTimeout(() => {
- component.$el.querySelector('.gl-pagination li:nth-child(3) .page-link').click();
-
- expect(component.updateContent).toHaveBeenCalledWith({ scope: 'available', page: '2' });
- done();
- }, 0);
- });
-
- it('should make an API request when using tabs', done => {
- setTimeout(() => {
- spyOn(component, 'updateContent');
- component.$el.querySelector('.js-environments-tab-stopped').click();
-
- expect(component.updateContent).toHaveBeenCalledWith({ scope: 'stopped', page: '1' });
- done();
- }, 0);
- });
- });
- });
- });
-
- describe('unsuccessfull request', () => {
- beforeEach(done => {
- mock.onGet(mockData.endpoint).reply(500, {});
-
- component = mountComponent(EnvironmentsComponent, mockData);
-
- setTimeout(() => {
- done();
- }, 0);
- });
-
- it('should render empty state', () => {
- expect(component.$el.querySelector('.js-blank-state-title').textContent).toContain(
- "You don't have any environments right now",
- );
- });
- });
-
- describe('expandable folders', () => {
- beforeEach(() => {
- mock.onGet(mockData.endpoint).reply(
- 200,
- {
- environments: [folder],
- stopped_count: 0,
- available_count: 1,
- },
- {
- 'X-nExt-pAge': '2',
- 'x-page': '1',
- 'X-Per-Page': '1',
- 'X-Prev-Page': '',
- 'X-TOTAL': '37',
- 'X-Total-Pages': '2',
- },
- );
-
- mock.onGet(environment.folder_path).reply(200, { environments: [environment] });
-
- component = mountComponent(EnvironmentsComponent, mockData);
- });
-
- it('should open a closed folder', done => {
- setTimeout(() => {
- component.$el.querySelector('.folder-name').click();
-
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.folder-icon.ic-chevron-right')).toBe(null);
- done();
- });
- }, 0);
- });
-
- it('should close an opened folder', done => {
- setTimeout(() => {
- // open folder
- component.$el.querySelector('.folder-name').click();
-
- Vue.nextTick(() => {
- // close folder
- component.$el.querySelector('.folder-name').click();
-
- Vue.nextTick(() => {
- expect(component.$el.querySelector('.folder-icon.ic-chevron-down')).toBe(null);
- done();
- });
- });
- }, 0);
- });
-
- it('should show children environments and a button to show all environments', done => {
- setTimeout(() => {
- // open folder
- component.$el.querySelector('.folder-name').click();
-
- Vue.nextTick(() => {
- // wait for next async request
- setTimeout(() => {
- expect(component.$el.querySelectorAll('.js-child-row').length).toEqual(1);
- expect(component.$el.querySelector('.text-center > a.btn').textContent).toContain(
- 'Show all',
- );
- done();
- });
- });
- }, 0);
- });
- });
-
- describe('methods', () => {
- beforeEach(() => {
- mock.onGet(mockData.endpoint).reply(
- 200,
- {
- environments: [],
- stopped_count: 0,
- available_count: 1,
- },
- {},
- );
-
- component = mountComponent(EnvironmentsComponent, mockData);
- spyOn(window.history, 'pushState').and.stub();
- });
-
- describe('updateContent', () => {
- it('should set given parameters', done => {
- component
- .updateContent({ scope: 'stopped', page: '3' })
- .then(() => {
- expect(component.page).toEqual('3');
- expect(component.scope).toEqual('stopped');
- expect(component.requestData.scope).toEqual('stopped');
- expect(component.requestData.page).toEqual('3');
- done();
- })
- .catch(done.fail);
- });
- });
-
- describe('onChangeTab', () => {
- it('should set page to 1', () => {
- spyOn(component, 'updateContent');
- component.onChangeTab('stopped');
-
- expect(component.updateContent).toHaveBeenCalledWith({ scope: 'stopped', page: '1' });
- });
- });
-
- describe('onChangePage', () => {
- it('should update page and keep scope', () => {
- spyOn(component, 'updateContent');
- component.onChangePage(4);
-
- expect(component.updateContent).toHaveBeenCalledWith({ scope: component.scope, page: '4' });
- });
- });
- });
-});
diff --git a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
index f4d3c9e613e..c899217d164 100644
--- a/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
+++ b/spec/lib/gitlab/import_export/project_tree_restorer_spec.rb
@@ -652,10 +652,10 @@ describe Gitlab::ImportExport::ProjectTreeRestorer do
setup_import_export_config('light')
end
- it 'does not import any instance-level services' do
+ it 'does not import any templated services' do
expect(restored_project_json).to eq(true)
- expect(project.services.where(instance: true).count).to eq(0)
+ expect(project.services.where(template: true).count).to eq(0)
end
it 'imports labels' do
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 7695617cb57..55e7d6bd1e3 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -453,7 +453,7 @@ Service:
- updated_at
- active
- properties
-- instance
+- template
- push_events
- issues_events
- commit_events
diff --git a/spec/lib/gitlab/serverless/service_spec.rb b/spec/lib/gitlab/serverless/service_spec.rb
new file mode 100644
index 00000000000..f618dd02cdb
--- /dev/null
+++ b/spec/lib/gitlab/serverless/service_spec.rb
@@ -0,0 +1,134 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe Gitlab::Serverless::Service do
+ let(:cluster) { create(:cluster) }
+ let(:environment) { create(:environment) }
+ let(:attributes) do
+ {
+ 'apiVersion' => 'serving.knative.dev/v1alpha1',
+ 'kind' => 'Service',
+ 'metadata' => {
+ 'creationTimestamp' => '2019-10-22T21:19:13Z',
+ 'name' => 'kubetest',
+ 'namespace' => 'project1-1-environment1'
+ },
+ 'spec' => {
+ 'runLatest' => {
+ 'configuration' => {
+ 'build' => {
+ 'template' => {
+ 'name' => 'some-image'
+ }
+ }
+ }
+ }
+ },
+ 'environment_scope' => '*',
+ 'cluster' => cluster,
+ 'environment' => environment,
+ 'podcount' => 0
+ }
+ end
+
+ it 'exposes methods extracting data from the attributes hash' do
+ service = Gitlab::Serverless::Service.new(attributes)
+
+ expect(service.name).to eq('kubetest')
+ expect(service.namespace).to eq('project1-1-environment1')
+ expect(service.environment_scope).to eq('*')
+ expect(service.podcount).to eq(0)
+ expect(service.created_at).to eq(DateTime.parse('2019-10-22T21:19:13Z'))
+ expect(service.image).to eq('some-image')
+ expect(service.cluster).to eq(cluster)
+ expect(service.environment).to eq(environment)
+ end
+
+ it 'returns nil for missing attributes' do
+ service = Gitlab::Serverless::Service.new({})
+
+ [:name, :namespace, :environment_scope, :cluster, :podcount, :created_at, :image, :description, :url, :environment].each do |method|
+ expect(service.send(method)).to be_nil
+ end
+ end
+
+ describe '#description' do
+ it 'extracts the description in knative 7 format if available' do
+ attributes = {
+ 'spec' => {
+ 'template' => {
+ 'metadata' => {
+ 'annotations' => {
+ 'Description' => 'some description'
+ }
+ }
+ }
+ }
+ }
+ service = Gitlab::Serverless::Service.new(attributes)
+
+ expect(service.description).to eq('some description')
+ end
+
+ it 'extracts the description in knative 5/6 format if 7 is not available' do
+ attributes = {
+ 'spec' => {
+ 'runLatest' => {
+ 'configuration' => {
+ 'revisionTemplate' => {
+ 'metadata' => {
+ 'annotations' => {
+ 'Description' => 'some description'
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ service = Gitlab::Serverless::Service.new(attributes)
+
+ expect(service.description).to eq('some description')
+ end
+ end
+
+ describe '#url' do
+ it 'returns proxy URL if cluster has serverless domain' do
+ # cluster = create(:cluster)
+ knative = create(:clusters_applications_knative, :installed, cluster: cluster)
+ create(:serverless_domain_cluster, clusters_applications_knative_id: knative.id)
+ service = Gitlab::Serverless::Service.new(attributes.merge('cluster' => cluster))
+
+ expect(Gitlab::Serverless::FunctionURI).to receive(:new).with(
+ function: service.name,
+ cluster: service.cluster.serverless_domain,
+ environment: service.environment
+ ).and_return('https://proxy.example.com')
+
+ expect(service.url).to eq('https://proxy.example.com')
+ end
+
+ it 'returns the URL from the knative 6/7 format' do
+ attributes = {
+ 'status' => {
+ 'url' => 'https://example.com'
+ }
+ }
+ service = Gitlab::Serverless::Service.new(attributes)
+
+ expect(service.url).to eq('https://example.com')
+ end
+
+ it 'returns the URL from the knative 5 format' do
+ attributes = {
+ 'status' => {
+ 'domain' => 'example.com'
+ }
+ }
+ service = Gitlab::Serverless::Service.new(attributes)
+
+ expect(service.url).to eq('http://example.com')
+ end
+ end
+end
diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb
index 8e9a816ba6a..9a49d334f52 100644
--- a/spec/lib/gitlab/usage_data_spec.rb
+++ b/spec/lib/gitlab/usage_data_spec.rb
@@ -18,7 +18,7 @@ describe Gitlab::UsageData do
create(:service, project: projects[1], type: 'SlackService', active: true)
create(:service, project: projects[2], type: 'SlackService', active: true)
create(:service, project: projects[2], type: 'MattermostService', active: false)
- create(:service, project: projects[2], type: 'MattermostService', active: true, instance: true)
+ create(:service, project: projects[2], type: 'MattermostService', active: true, template: true)
create(:service, project: projects[2], type: 'CustomIssueTrackerService', active: true)
create(:project_error_tracking_setting, project: projects[0])
create(:project_error_tracking_setting, project: projects[1], enabled: false)
diff --git a/spec/migrations/migrate_propagate_service_template_sidekiq_queue_spec.rb b/spec/migrations/migrate_propagate_service_template_sidekiq_queue_spec.rb
deleted file mode 100644
index 2fffe638117..00000000000
--- a/spec/migrations/migrate_propagate_service_template_sidekiq_queue_spec.rb
+++ /dev/null
@@ -1,29 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-require Rails.root.join('db', 'post_migrate', '20200206111847_migrate_propagate_service_template_sidekiq_queue.rb')
-
-describe MigratePropagateServiceTemplateSidekiqQueue, :sidekiq, :redis do
- include Gitlab::Database::MigrationHelpers
- include StubWorker
-
- context 'when there are jobs in the queue' do
- it 'correctly migrates queue when migrating up' do
- Sidekiq::Testing.disable! do
- stub_worker(queue: 'propagate_service_template').perform_async('Something', [1])
- stub_worker(queue: 'propagate_instance_level_service').perform_async('Something', [1])
-
- described_class.new.up
-
- expect(sidekiq_queue_length('propagate_service_template')).to eq 0
- expect(sidekiq_queue_length('propagate_instance_level_service')).to eq 2
- end
- end
- end
-
- context 'when there are no jobs in the queues' do
- it 'does not raise error when migrating up' do
- expect { described_class.new.up }.not_to raise_error
- end
- end
-end
diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb
index df2ed4911ec..f58bcbebd67 100644
--- a/spec/models/service_spec.rb
+++ b/spec/models/service_spec.rb
@@ -97,23 +97,23 @@ describe Service do
end
end
- describe "Instance" do
+ describe "Template" do
let(:project) { create(:project) }
- describe '.build_from_instance' do
- context 'when instance level integration is invalid' do
- it 'sets instance level integration to inactive when instance is invalid' do
- instance = build(:prometheus_service, instance: true, active: true, properties: {})
- instance.save(validate: false)
+ describe '.build_from_template' do
+ context 'when template is invalid' do
+ it 'sets service template to inactive when template is invalid' do
+ template = build(:prometheus_service, template: true, active: true, properties: {})
+ template.save(validate: false)
- service = described_class.build_from_instance(project.id, instance)
+ service = described_class.build_from_template(project.id, template)
expect(service).to be_valid
expect(service.active).to be false
end
end
- describe 'build issue tracker from a instance level integration' do
+ describe 'build issue tracker from a template' do
let(:title) { 'custom title' }
let(:description) { 'custom description' }
let(:url) { 'http://jira.example.com' }
@@ -127,9 +127,9 @@ describe Service do
}
end
- shared_examples 'integration creation from instance level' do
+ shared_examples 'service creation from a template' do
it 'creates a correct service' do
- service = described_class.build_from_instance(project.id, instance_level_integration)
+ service = described_class.build_from_template(project.id, template)
expect(service).to be_active
expect(service.title).to eq(title)
@@ -144,38 +144,38 @@ describe Service do
# this will be removed as part of https://gitlab.com/gitlab-org/gitlab/issues/29404
context 'when data are stored in properties' do
let(:properties) { data_params.merge(title: title, description: description) }
- let!(:instance_level_integration) do
- create(:jira_service, :without_properties_callback, instance: true, properties: properties.merge(additional: 'something'))
+ let!(:template) do
+ create(:jira_service, :without_properties_callback, template: true, properties: properties.merge(additional: 'something'))
end
- it_behaves_like 'integration creation from instance level'
+ it_behaves_like 'service creation from a template'
end
context 'when data are stored in separated fields' do
- let(:instance_level_integration) do
- create(:jira_service, data_params.merge(properties: {}, title: title, description: description, instance: true))
+ let(:template) do
+ create(:jira_service, data_params.merge(properties: {}, title: title, description: description, template: true))
end
- it_behaves_like 'integration creation from instance level'
+ it_behaves_like 'service creation from a template'
end
context 'when data are stored in both properties and separated fields' do
let(:properties) { data_params.merge(title: title, description: description) }
- let(:instance_level_integration) do
- create(:jira_service, :without_properties_callback, active: true, instance: true, properties: properties).tap do |service|
+ let(:template) do
+ create(:jira_service, :without_properties_callback, active: true, template: true, properties: properties).tap do |service|
create(:jira_tracker_data, data_params.merge(service: service))
end
end
- it_behaves_like 'integration creation from instance level'
+ it_behaves_like 'service creation from a template'
end
end
end
describe "for pushover service" do
- let!(:instance_level_integration) do
+ let!(:service_template) do
PushoverService.create(
- instance: true,
+ template: true,
properties: {
device: 'MyDevice',
sound: 'mic',
@@ -188,7 +188,7 @@ describe Service do
it "has all fields prefilled" do
service = project.find_or_initialize_service('pushover')
- expect(service.instance).to eq(false)
+ expect(service.template).to eq(false)
expect(service.device).to eq('MyDevice')
expect(service.sound).to eq('mic')
expect(service.priority).to eq(4)
@@ -391,6 +391,14 @@ describe Service do
end
end
+ describe '.find_by_template' do
+ let!(:service) { create(:service, template: true) }
+
+ it 'returns service template' do
+ expect(described_class.find_by_template).to eq(service)
+ end
+ end
+
describe '#api_field_names' do
let(:fake_service) do
Class.new(Service) do
diff --git a/spec/presenters/snippet_blob_presenter_spec.rb b/spec/presenters/snippet_blob_presenter_spec.rb
index 2a113e353c8..92893ec597a 100644
--- a/spec/presenters/snippet_blob_presenter_spec.rb
+++ b/spec/presenters/snippet_blob_presenter_spec.rb
@@ -18,7 +18,7 @@ describe SnippetBlobPresenter do
snippet.file_name = 'test.md'
snippet.content = '*foo*'
- expect(subject).to eq '<p data-sourcepos="1:1-1:5" dir="auto"><em>foo</em></p>'
+ expect(subject).to eq '<span id="LC1" class="line" lang="markdown"><span class="ge">*foo*</span></span>'
end
it 'returns syntax highlighted content' do
@@ -33,7 +33,41 @@ describe SnippetBlobPresenter do
snippet.file_name = 'test'
snippet.content = 'foo'
- expect(described_class.new(snippet.blob).highlighted_data).to eq '<span id="LC1" class="line" lang="plaintext">foo</span>'
+ expect(subject).to eq '<span id="LC1" class="line" lang="plaintext">foo</span>'
+ end
+ end
+
+ describe '#plain_highlighted_data' do
+ let(:snippet) { build(:personal_snippet) }
+
+ subject { described_class.new(snippet.blob).plain_highlighted_data }
+
+ it 'returns nil when the snippet blob is binary' do
+ allow(snippet.blob).to receive(:binary?).and_return(true)
+
+ expect(subject).to be_nil
+ end
+
+ it 'returns plain content when snippet file is markup' do
+ snippet.file_name = 'test.md'
+ snippet.content = '*foo*'
+
+ expect(subject).to eq '<span id="LC1" class="line" lang="">*foo*</span>'
+ end
+
+ it 'returns plain syntax content' do
+ snippet.file_name = 'test.rb'
+ snippet.content = 'class Foo;end'
+
+ expect(subject)
+ .to eq '<span id="LC1" class="line" lang="">class Foo;end</span>'
+ end
+
+ it 'returns plain text highlighted content' do
+ snippet.file_name = 'test'
+ snippet.content = 'foo'
+
+ expect(subject).to eq '<span id="LC1" class="line" lang="">foo</span>'
end
end
diff --git a/spec/services/projects/create_service_spec.rb b/spec/services/projects/create_service_spec.rb
index 9d23556efda..a8e7919dc81 100644
--- a/spec/services/projects/create_service_spec.rb
+++ b/spec/services/projects/create_service_spec.rb
@@ -15,7 +15,7 @@ describe Projects::CreateService, '#execute' do
}
end
- it 'creates labels on Project creation if there are instance level services' do
+ it 'creates labels on Project creation if there are templates' do
Label.create(title: "bug", template: true)
project = create_project(user, opts)
@@ -96,7 +96,7 @@ describe Projects::CreateService, '#execute' do
end
it 'sets invalid service as inactive' do
- create(:service, type: 'JiraService', project: nil, instance: true, active: true)
+ create(:service, type: 'JiraService', project: nil, template: true, active: true)
project = create_project(user, opts)
service = project.services.first
@@ -342,22 +342,22 @@ describe Projects::CreateService, '#execute' do
end
end
- context 'when there is an active instance level service' do
+ context 'when there is an active service template' do
before do
- create(:service, project: nil, instance: true, active: true)
+ create(:service, project: nil, template: true, active: true)
end
- it 'creates a service from instance level service' do
+ it 'creates a service from this template' do
project = create_project(user, opts)
expect(project.services.count).to eq 1
end
end
- context 'when a bad instance level service is created' do
+ context 'when a bad service template is created' do
it 'sets service to be inactive' do
opts[:import_url] = 'http://www.gitlab.com/gitlab-org/gitlab-foss'
- create(:service, type: 'DroneCiService', project: nil, instance: true, active: true)
+ create(:service, type: 'DroneCiService', project: nil, template: true, active: true)
project = create_project(user, opts)
service = project.services.first
diff --git a/spec/services/projects/propagate_instance_level_service_spec.rb b/spec/services/projects/propagate_service_template_spec.rb
index a842842a010..2c3effec617 100644
--- a/spec/services/projects/propagate_instance_level_service_spec.rb
+++ b/spec/services/projects/propagate_service_template_spec.rb
@@ -2,11 +2,11 @@
require 'spec_helper'
-describe Projects::PropagateInstanceLevelService do
+describe Projects::PropagateServiceTemplate do
describe '.propagate' do
- let!(:instance_level_integration) do
+ let!(:service_template) do
PushoverService.create(
- instance: true,
+ template: true,
active: true,
properties: {
device: 'MyDevice',
@@ -22,14 +22,14 @@ describe Projects::PropagateInstanceLevelService do
it 'creates services for projects' do
expect(project.pushover_service).to be_nil
- described_class.propagate(instance_level_integration)
+ described_class.propagate(service_template)
expect(project.reload.pushover_service).to be_present
end
it 'creates services for a project that has another service' do
BambooService.create(
- instance: true,
+ template: true,
active: true,
project: project,
properties: {
@@ -42,14 +42,14 @@ describe Projects::PropagateInstanceLevelService do
expect(project.pushover_service).to be_nil
- described_class.propagate(instance_level_integration)
+ described_class.propagate(service_template)
expect(project.reload.pushover_service).to be_present
end
it 'does not create the service if it exists already' do
other_service = BambooService.create(
- instance: true,
+ template: true,
active: true,
properties: {
bamboo_url: 'http://gitlab.com',
@@ -59,17 +59,17 @@ describe Projects::PropagateInstanceLevelService do
}
)
- Service.build_from_instance(project.id, instance_level_integration).save!
- Service.build_from_instance(project.id, other_service).save!
+ Service.build_from_template(project.id, service_template).save!
+ Service.build_from_template(project.id, other_service).save!
- expect { described_class.propagate(instance_level_integration) }
+ expect { described_class.propagate(service_template) }
.not_to change { Service.count }
end
- it 'creates the service containing the instance attributes' do
- described_class.propagate(instance_level_integration)
+ it 'creates the service containing the template attributes' do
+ described_class.propagate(service_template)
- expect(project.pushover_service.properties).to eq(instance_level_integration.properties)
+ expect(project.pushover_service.properties).to eq(service_template.properties)
end
describe 'bulk update', :use_sql_query_cache do
@@ -80,7 +80,7 @@ describe Projects::PropagateInstanceLevelService do
project_total.times { create(:project) }
- described_class.propagate(instance_level_integration)
+ described_class.propagate(service_template)
end
it 'creates services for all projects' do
@@ -90,18 +90,18 @@ describe Projects::PropagateInstanceLevelService do
describe 'external tracker' do
it 'updates the project external tracker' do
- instance_level_integration.update!(category: 'issue_tracker', default: false)
+ service_template.update!(category: 'issue_tracker', default: false)
- expect { described_class.propagate(instance_level_integration) }
+ expect { described_class.propagate(service_template) }
.to change { project.reload.has_external_issue_tracker }.to(true)
end
end
describe 'external wiki' do
it 'updates the project external tracker' do
- instance_level_integration.update!(type: 'ExternalWikiService')
+ service_template.update!(type: 'ExternalWikiService')
- expect { described_class.propagate(instance_level_integration) }
+ expect { described_class.propagate(service_template) }
.to change { project.reload.has_external_wiki }.to(true)
end
end
diff --git a/spec/support/helpers/kubernetes_helpers.rb b/spec/support/helpers/kubernetes_helpers.rb
index 0d312575e91..e2d96db02be 100644
--- a/spec/support/helpers/kubernetes_helpers.rb
+++ b/spec/support/helpers/kubernetes_helpers.rb
@@ -557,7 +557,7 @@ module KubernetesHelpers
end
# noinspection RubyStringKeysInHashInspection
- def knative_06_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ def knative_06_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production', cluster_id: 9)
{ "apiVersion" => "serving.knative.dev/v1alpha1",
"kind" => "Service",
"metadata" =>
@@ -612,12 +612,12 @@ module KubernetesHelpers
"url" => "http://#{name}.#{namespace}.#{domain}"
},
"environment_scope" => environment,
- "cluster_id" => 9,
+ "cluster_id" => cluster_id,
"podcount" => 0 }
end
# noinspection RubyStringKeysInHashInspection
- def knative_07_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ def knative_07_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production', cluster_id: 5)
{ "apiVersion" => "serving.knative.dev/v1alpha1",
"kind" => "Service",
"metadata" =>
@@ -664,12 +664,12 @@ module KubernetesHelpers
"traffic" => [{ "latestRevision" => true, "percent" => 100, "revisionName" => "#{name}-92tsj" }],
"url" => "http://#{name}.#{namespace}.#{domain}" },
"environment_scope" => environment,
- "cluster_id" => 5,
+ "cluster_id" => cluster_id,
"podcount" => 0 }
end
# noinspection RubyStringKeysInHashInspection
- def knative_09_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ def knative_09_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production', cluster_id: 5)
{ "apiVersion" => "serving.knative.dev/v1alpha1",
"kind" => "Service",
"metadata" =>
@@ -716,12 +716,12 @@ module KubernetesHelpers
"traffic" => [{ "latestRevision" => true, "percent" => 100, "revisionName" => "#{name}-92tsj" }],
"url" => "http://#{name}.#{namespace}.#{domain}" },
"environment_scope" => environment,
- "cluster_id" => 5,
+ "cluster_id" => cluster_id,
"podcount" => 0 }
end
# noinspection RubyStringKeysInHashInspection
- def knative_05_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production')
+ def knative_05_service(name: 'kubetest', namespace: 'default', domain: 'example.com', description: 'a knative service', environment: 'production', cluster_id: 8)
{ "apiVersion" => "serving.knative.dev/v1alpha1",
"kind" => "Service",
"metadata" =>
@@ -771,7 +771,7 @@ module KubernetesHelpers
"observedGeneration" => 1,
"traffic" => [{ "percent" => 100, "revisionName" => "#{name}-58qgr" }] },
"environment_scope" => environment,
- "cluster_id" => 8,
+ "cluster_id" => cluster_id,
"podcount" => 0 }
end
diff --git a/spec/support/shared_examples/workers/pages_domain_cron_worker_shared_examples.rb b/spec/support/shared_examples/workers/pages_domain_cron_worker_shared_examples.rb
new file mode 100644
index 00000000000..9e8102aea53
--- /dev/null
+++ b/spec/support/shared_examples/workers/pages_domain_cron_worker_shared_examples.rb
@@ -0,0 +1,21 @@
+# frozen_string_literal: true
+
+RSpec.shared_examples 'a pages cronjob scheduling jobs with context' do |scheduled_worker_class|
+ let(:worker) { described_class.new }
+
+ it 'does not cause extra queries for multiple domains' do
+ control = ActiveRecord::QueryRecorder.new { worker.perform }
+
+ extra_domain
+
+ expect { worker.perform }.not_to exceed_query_limit(control)
+ end
+
+ it 'schedules the renewal with a context' do
+ extra_domain
+
+ worker.perform
+
+ expect(scheduled_worker_class.jobs.last).to include("meta.project" => extra_domain.project.full_path)
+ end
+end
diff --git a/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb b/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb
index 10c23cbb6d4..736acc40371 100644
--- a/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb
+++ b/spec/workers/pages_domain_ssl_renewal_cron_worker_spec.rb
@@ -12,7 +12,7 @@ describe PagesDomainSslRenewalCronWorker do
end
describe '#perform' do
- let(:project) { create :project }
+ let_it_be(:project) { create :project }
let!(:domain) { create(:pages_domain, project: project, auto_ssl_enabled: false) }
let!(:domain_with_enabled_auto_ssl) { create(:pages_domain, project: project, auto_ssl_enabled: true) }
let!(:domain_with_obtained_letsencrypt) do
@@ -35,12 +35,16 @@ describe PagesDomainSslRenewalCronWorker do
[domain,
domain_with_obtained_letsencrypt].each do |domain|
- expect(PagesDomainVerificationWorker).not_to receive(:perform_async).with(domain.id)
+ expect(PagesDomainSslRenewalWorker).not_to receive(:perform_async).with(domain.id)
end
worker.perform
end
+ it_behaves_like 'a pages cronjob scheduling jobs with context', PagesDomainSslRenewalWorker do
+ let(:extra_domain) { create(:pages_domain, :with_project, auto_ssl_enabled: true) }
+ end
+
shared_examples 'does nothing' do
it 'does nothing' do
expect(PagesDomainSslRenewalWorker).not_to receive(:perform_async)
diff --git a/spec/workers/pages_domain_verification_cron_worker_spec.rb b/spec/workers/pages_domain_verification_cron_worker_spec.rb
index 3fb86adee11..6dd6c33f5fe 100644
--- a/spec/workers/pages_domain_verification_cron_worker_spec.rb
+++ b/spec/workers/pages_domain_verification_cron_worker_spec.rb
@@ -5,9 +5,9 @@ require 'spec_helper'
describe PagesDomainVerificationCronWorker do
subject(:worker) { described_class.new }
- describe '#perform' do
+ describe '#perform', :sidekiq do
let!(:verified) { create(:pages_domain) }
- let!(:reverify) { create(:pages_domain, :reverify) }
+ let!(:reverify) { create(:pages_domain, :reverify, :with_project) }
let!(:disabled) { create(:pages_domain, :disabled) }
it 'does nothing if the database is read-only' do
@@ -26,5 +26,9 @@ describe PagesDomainVerificationCronWorker do
worker.perform
end
+
+ it_behaves_like 'a pages cronjob scheduling jobs with context', PagesDomainVerificationWorker do
+ let(:extra_domain) { create(:pages_domain, :reverify, :with_project) }
+ end
end
end
diff --git a/spec/workers/propagate_instance_level_service_worker_spec.rb b/spec/workers/propagate_instance_level_service_worker_spec.rb
deleted file mode 100644
index 6552b198181..00000000000
--- a/spec/workers/propagate_instance_level_service_worker_spec.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-require 'spec_helper'
-
-describe PropagateInstanceLevelServiceWorker do
- include ExclusiveLeaseHelpers
-
- describe '#perform' do
- it 'calls the propagate service with the instance level service' do
- instance_level_service = PushoverService.create(
- instance: true,
- active: true,
- properties: {
- device: 'MyDevice',
- sound: 'mic',
- priority: 4,
- user_key: 'asdf',
- api_key: '123456789'
- })
-
- stub_exclusive_lease("propagate_instance_level_service_worker:#{instance_level_service.id}",
- timeout: PropagateInstanceLevelServiceWorker::LEASE_TIMEOUT)
-
- expect(Projects::PropagateInstanceLevelService)
- .to receive(:propagate)
- .with(instance_level_service)
-
- subject.perform(instance_level_service.id)
- end
- end
-end
diff --git a/spec/workers/propagate_service_template_worker_spec.rb b/spec/workers/propagate_service_template_worker_spec.rb
new file mode 100644
index 00000000000..fb4ced77832
--- /dev/null
+++ b/spec/workers/propagate_service_template_worker_spec.rb
@@ -0,0 +1,31 @@
+# frozen_string_literal: true
+
+require 'spec_helper'
+
+describe PropagateServiceTemplateWorker do
+ include ExclusiveLeaseHelpers
+
+ describe '#perform' do
+ it 'calls the propagate service with the template' do
+ template = PushoverService.create(
+ template: true,
+ active: true,
+ properties: {
+ device: 'MyDevice',
+ sound: 'mic',
+ priority: 4,
+ user_key: 'asdf',
+ api_key: '123456789'
+ })
+
+ stub_exclusive_lease("propagate_service_template_worker:#{template.id}",
+ timeout: PropagateServiceTemplateWorker::LEASE_TIMEOUT)
+
+ expect(Projects::PropagateServiceTemplate)
+ .to receive(:propagate)
+ .with(template)
+
+ subject.perform(template.id)
+ end
+ end
+end