diff options
Diffstat (limited to 'spec')
23 files changed, 368 insertions, 49 deletions
diff --git a/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb b/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb index d20471ef603..3c9452cc42a 100644 --- a/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb +++ b/spec/controllers/concerns/controller_with_cross_project_access_check_spec.rb @@ -27,11 +27,11 @@ describe ControllerWithCrossProjectAccessCheck do if: -> { if_condition } def index - render nothing: true + head :ok end def show - render nothing: true + head :ok end def unless_condition @@ -88,15 +88,15 @@ describe ControllerWithCrossProjectAccessCheck do if: -> { if_condition } def index - render nothing: true + head :ok end def show - render nothing: true + head :ok end def edit - render nothing: true + head :ok end def unless_condition diff --git a/spec/controllers/concerns/lfs_request_spec.rb b/spec/controllers/concerns/lfs_request_spec.rb index 33b23db302a..76c878ec5d7 100644 --- a/spec/controllers/concerns/lfs_request_spec.rb +++ b/spec/controllers/concerns/lfs_request_spec.rb @@ -10,7 +10,7 @@ describe LfsRequest do def show storage_project - render nothing: true + head :ok end def project diff --git a/spec/controllers/profiles/keys_controller_spec.rb b/spec/controllers/profiles/keys_controller_spec.rb index ea26bc83353..685db8488f0 100644 --- a/spec/controllers/profiles/keys_controller_spec.rb +++ b/spec/controllers/profiles/keys_controller_spec.rb @@ -62,8 +62,15 @@ describe Profiles::KeysController do it "responds with text/plain content type" do get :get_keys, username: user.username + expect(response.content_type).to eq("text/plain") end + + it "responds with attachment content disposition" do + get :get_keys, username: user.username + + expect(response.headers['Content-Disposition']).to eq('attachment') + end end end end diff --git a/spec/factories/clusters/applications/helm.rb b/spec/factories/clusters/applications/helm.rb index ff65c76cf26..7fc3d16e864 100644 --- a/spec/factories/clusters/applications/helm.rb +++ b/spec/factories/clusters/applications/helm.rb @@ -49,6 +49,11 @@ FactoryBot.define do cluster factory: %i(cluster with_installed_helm provided_by_gcp) end + factory :clusters_applications_cert_managers, class: Clusters::Applications::CertManager do + email 'admin@example.com' + cluster factory: %i(cluster with_installed_helm provided_by_gcp) + end + factory :clusters_applications_prometheus, class: Clusters::Applications::Prometheus do cluster factory: %i(cluster with_installed_helm provided_by_gcp) end diff --git a/spec/features/dashboard/merge_requests_spec.rb b/spec/features/dashboard/merge_requests_spec.rb index 282bf542e77..9ffa75aee47 100644 --- a/spec/features/dashboard/merge_requests_spec.rb +++ b/spec/features/dashboard/merge_requests_spec.rb @@ -6,6 +6,7 @@ describe 'Dashboard Merge Requests' do include ProjectForksHelper let(:current_user) { create :user } + let(:user) { current_user } let(:project) { create(:project) } let(:public_project) { create(:project, :public, :repository) } diff --git a/spec/features/help_pages_spec.rb b/spec/features/help_pages_spec.rb index 0d04ed612c2..c29dfb01381 100644 --- a/spec/features/help_pages_spec.rb +++ b/spec/features/help_pages_spec.rb @@ -4,7 +4,7 @@ describe 'Help Pages' do describe 'Get the main help page' do shared_examples_for 'help page' do |prefix: ''| it 'prefixes links correctly' do - expect(page).to have_selector(%(div.documentation-index > ul a[href="#{prefix}/help/api/README.md"])) + expect(page).to have_selector(%(div.documentation-index > table tbody tr td a[href="#{prefix}/help/api/README.md"])) end end diff --git a/spec/features/issues_spec.rb b/spec/features/issues_spec.rb index 4d9b8a10e04..5c1ffb76351 100644 --- a/spec/features/issues_spec.rb +++ b/spec/features/issues_spec.rb @@ -8,6 +8,17 @@ describe 'Issues' do let(:user) { create(:user) } let(:project) { create(:project, :public) } + shared_examples_for 'empty state with filters' do + it 'user sees empty state with filters' do + create(:issue, author: user, project: project) + + visit project_issues_path(project, milestone_title: "1.0") + + expect(page).to have_content('Sorry, your filter produced no results') + expect(page).to have_content('To widen your search, change or remove filters above') + end + end + describe 'while user is signed out' do describe 'empty state' do it 'user sees empty state' do @@ -17,6 +28,8 @@ describe 'Issues' do expect(page).to have_content('The Issue Tracker is the place to add things that need to be improved or solved in a project.') expect(page).to have_content('You can register or sign in to create issues for this project.') end + + it_behaves_like 'empty state with filters' end end @@ -37,6 +50,8 @@ describe 'Issues' do expect(page).to have_content('Issues can be bugs, tasks or ideas to be discussed. Also, issues are searchable and filterable.') expect(page).to have_content('New issue') end + + it_behaves_like 'empty state with filters' end describe 'Edit issue' do diff --git a/spec/features/merge_request/user_sees_empty_state_spec.rb b/spec/features/merge_request/user_sees_empty_state_spec.rb index 482f31b02d4..012bfd6e458 100644 --- a/spec/features/merge_request/user_sees_empty_state_spec.rb +++ b/spec/features/merge_request/user_sees_empty_state_spec.rb @@ -19,12 +19,20 @@ describe 'Merge request > User sees empty state' do context 'if there are merge requests' do before do create(:merge_request, source_project: project) - - visit project_merge_requests_path(project) end it 'does not show an empty state' do + visit project_merge_requests_path(project) + expect(page).not_to have_selector('.empty-state') end + + it 'shows empty state when filter results empty' do + visit project_merge_requests_path(project, milestone_title: "1.0") + + expect(page).to have_selector('.empty-state') + expect(page).to have_content('Sorry, your filter produced no results') + expect(page).to have_content('To widen your search, change or remove filters above') + end end end diff --git a/spec/finders/issues_finder_spec.rb b/spec/finders/issues_finder_spec.rb index c0488c83bd8..515f6f70b99 100644 --- a/spec/finders/issues_finder_spec.rb +++ b/spec/finders/issues_finder_spec.rb @@ -256,19 +256,51 @@ describe IssuesFinder do create(:label_link, label: label2, target: issue2) end - it 'returns the unique issues with any of those labels' do + it 'returns the unique issues with all those labels' do + expect(issues).to contain_exactly(issue2) + end + end + + context 'filtering by a label that includes any or none in the title' do + let(:params) { { label_name: [label.title, label2.title].join(',') } } + let(:label) { create(:label, title: 'any foo', project: project2) } + let(:label2) { create(:label, title: 'bar none', project: project2) } + + it 'returns the unique issues with all those labels' do + create(:label_link, label: label2, target: issue2) + expect(issues).to contain_exactly(issue2) end end context 'filtering by no label' do - let(:params) { { label_name: Label::None.title } } + let(:params) { { label_name: described_class::FILTER_NONE } } it 'returns issues with no labels' do expect(issues).to contain_exactly(issue1, issue3, issue4) end end + context 'filtering by legacy No+Label' do + let(:params) { { label_name: Label::NONE } } + + it 'returns issues with no labels' do + expect(issues).to contain_exactly(issue1, issue3, issue4) + end + end + + context 'filtering by any label' do + let(:params) { { label_name: described_class::FILTER_ANY } } + + it 'returns issues that have one or more label' do + 2.times do + create(:label_link, label: create(:label, project: project2), target: issue3) + end + + expect(issues).to contain_exactly(issue2, issue3) + end + end + context 'filtering by issue term' do let(:params) { { search: 'git' } } diff --git a/spec/javascripts/clusters/components/applications_spec.js b/spec/javascripts/clusters/components/applications_spec.js index 0e2cc13fa52..928bf70f3a2 100644 --- a/spec/javascripts/clusters/components/applications_spec.js +++ b/spec/javascripts/clusters/components/applications_spec.js @@ -20,6 +20,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller' }, ingress: { title: 'Ingress' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub' }, @@ -36,6 +37,10 @@ describe('Applications', () => { expect(vm.$el.querySelector('.js-cluster-application-row-ingress')).toBeDefined(); }); + it('renders a row for Cert-Manager', () => { + expect(vm.$el.querySelector('.js-cluster-application-row-cert_manager')).toBeDefined(); + }); + it('renders a row for Prometheus', () => { expect(vm.$el.querySelector('.js-cluster-application-row-prometheus')).toBeDefined(); }); @@ -65,6 +70,7 @@ describe('Applications', () => { externalIp: '0.0.0.0', }, helm: { title: 'Helm Tiller' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '' }, @@ -89,6 +95,7 @@ describe('Applications', () => { status: 'installed', }, helm: { title: 'Helm Tiller' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '' }, @@ -109,6 +116,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller' }, ingress: { title: 'Ingress' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '' }, @@ -128,6 +136,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller', status: 'installed' }, ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '', status: 'installable' }, @@ -145,6 +154,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller', status: 'installed' }, ingress: { title: 'Ingress', status: 'installed' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', hostname: '', status: 'installable' }, @@ -162,6 +172,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller', status: 'installed' }, ingress: { title: 'Ingress', status: 'installed', externalIp: '1.1.1.1' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', status: 'installed', hostname: '' }, @@ -179,6 +190,7 @@ describe('Applications', () => { applications: { helm: { title: 'Helm Tiller' }, ingress: { title: 'Ingress' }, + cert_manager: { title: 'Cert-Manager' }, runner: { title: 'GitLab Runner' }, prometheus: { title: 'Prometheus' }, jupyter: { title: 'JupyterHub', status: 'not_installable' }, diff --git a/spec/javascripts/clusters/services/mock_data.js b/spec/javascripts/clusters/services/mock_data.js index 73abf6504c0..540d7f30858 100644 --- a/spec/javascripts/clusters/services/mock_data.js +++ b/spec/javascripts/clusters/services/mock_data.js @@ -38,6 +38,11 @@ const CLUSTERS_MOCK_DATA = { status: APPLICATION_STATUS.INSTALLING, status_reason: 'Cannot connect', }, + { + name: 'cert_manager', + status: APPLICATION_STATUS.ERROR, + status_reason: 'Cannot connect', + }, ], }, }, @@ -77,6 +82,11 @@ const CLUSTERS_MOCK_DATA = { status: APPLICATION_STATUS.INSTALLABLE, status_reason: 'Cannot connect', }, + { + name: 'cert_manager', + status: APPLICATION_STATUS.ERROR, + status_reason: 'Cannot connect', + }, ], }, }, @@ -84,6 +94,7 @@ const CLUSTERS_MOCK_DATA = { POST: { '/gitlab-org/gitlab-shell/clusters/1/applications/helm': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/ingress': {}, + '/gitlab-org/gitlab-shell/clusters/1/applications/cert_manager': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/runner': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/prometheus': {}, '/gitlab-org/gitlab-shell/clusters/1/applications/jupyter': {}, diff --git a/spec/javascripts/clusters/stores/clusters_store_spec.js b/spec/javascripts/clusters/stores/clusters_store_spec.js index 34ed36afa5b..6a08d08f33e 100644 --- a/spec/javascripts/clusters/stores/clusters_store_spec.js +++ b/spec/javascripts/clusters/stores/clusters_store_spec.js @@ -108,6 +108,13 @@ describe('Clusters Store', () => { requestReason: null, hostname: null, }, + cert_manager: { + title: 'Cert-Manager', + status: mockResponseData.applications[6].status, + statusReason: mockResponseData.applications[6].status_reason, + requestStatus: null, + requestReason: null, + }, }, }); }); diff --git a/spec/javascripts/notes/components/noteable_discussion_spec.js b/spec/javascripts/notes/components/noteable_discussion_spec.js index 81cb3e1f74d..4b4403689d9 100644 --- a/spec/javascripts/notes/components/noteable_discussion_spec.js +++ b/spec/javascripts/notes/components/noteable_discussion_spec.js @@ -6,6 +6,7 @@ import { noteableDataMock, discussionMock, notesDataMock } from '../mock_data'; import mockDiffFile from '../../diffs/mock_data/diff_file'; const discussionWithTwoUnresolvedNotes = 'merge_requests/resolved_diff_discussion.json'; +const diffDiscussionFixture = 'merge_requests/diff_discussion.json'; describe('noteable_discussion component', () => { const Component = Vue.extend(noteableDiscussion); @@ -115,6 +116,49 @@ describe('noteable_discussion component', () => { .catch(done.fail); }); }); + + describe('isRepliesCollapsed', () => { + it('should return false for diff discussions', done => { + const diffDiscussion = getJSONFixture(diffDiscussionFixture)[0]; + vm.$store.dispatch('setInitialNotes', [diffDiscussion]); + + Vue.nextTick() + .then(() => { + expect(vm.isRepliesCollapsed).toEqual(false); + expect(vm.$el.querySelector('.js-toggle-replies')).not.toBeNull(); + expect(vm.$el.querySelector('.discussion-reply-holder')).not.toBeNull(); + }) + .then(done) + .catch(done.fail); + }); + + it('should return false if discussion does not have a reply', () => { + const discussion = { ...discussionMock, resolved: true }; + discussion.notes = discussion.notes.slice(0, 1); + const noRepliesVm = new Component({ + store, + propsData: { discussion }, + }).$mount(); + + expect(noRepliesVm.isRepliesCollapsed).toEqual(false); + expect(noRepliesVm.$el.querySelector('.js-toggle-replies')).toBeNull(); + expect(vm.$el.querySelector('.discussion-reply-holder')).not.toBeNull(); + noRepliesVm.$destroy(); + }); + + it('should return true for resolved non-diff discussion which has replies', () => { + const discussion = { ...discussionMock, resolved: true }; + const resolvedDiscussionVm = new Component({ + store, + propsData: { discussion }, + }).$mount(); + + expect(resolvedDiscussionVm.isRepliesCollapsed).toEqual(true); + expect(resolvedDiscussionVm.$el.querySelector('.js-toggle-replies')).not.toBeNull(); + expect(vm.$el.querySelector('.discussion-reply-holder')).not.toBeNull(); + resolvedDiscussionVm.$destroy(); + }); + }); }); describe('methods', () => { diff --git a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb index 39852b7fe29..82ed4d47857 100644 --- a/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb +++ b/spec/lib/gitlab/kubernetes/helm/install_command_spec.rb @@ -43,6 +43,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS @@ -101,6 +102,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS @@ -126,7 +128,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do <<~EOS.strip /bin/date /bin/true - helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml + helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS end end @@ -148,7 +150,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do let(:helm_install_command) do <<~EOS.strip - helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml + helm install chart-name --name app-name --tls --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem --version 1.2.3 --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml /bin/date /bin/false EOS @@ -175,6 +177,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do helm install chart-name --name app-name --version 1.2.3 + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS @@ -204,6 +207,7 @@ describe Gitlab::Kubernetes::Helm::InstallCommand do --tls-ca-cert /data/helm/app-name/config/ca.pem --tls-cert /data/helm/app-name/config/cert.pem --tls-key /data/helm/app-name/config/key.pem + --set rbac.create\\=false,rbac.enabled\\=false --namespace gitlab-managed-apps -f /data/helm/app-name/config/values.yaml EOS diff --git a/spec/lib/gitlab/usage_data_spec.rb b/spec/lib/gitlab/usage_data_spec.rb index b212d2b05f2..5390f237073 100644 --- a/spec/lib/gitlab/usage_data_spec.rb +++ b/spec/lib/gitlab/usage_data_spec.rb @@ -19,6 +19,7 @@ describe Gitlab::UsageData do create(:cluster, :provided_by_user, :disabled) create(:clusters_applications_helm, :installed, cluster: gcp_cluster) create(:clusters_applications_ingress, :installed, cluster: gcp_cluster) + create(:clusters_applications_cert_managers, :installed, cluster: gcp_cluster) create(:clusters_applications_prometheus, :installed, cluster: gcp_cluster) create(:clusters_applications_runner, :installed, cluster: gcp_cluster) create(:clusters_applications_knative, :installed, cluster: gcp_cluster) @@ -81,6 +82,7 @@ describe Gitlab::UsageData do clusters_platforms_user clusters_applications_helm clusters_applications_ingress + clusters_applications_cert_managers clusters_applications_prometheus clusters_applications_runner clusters_applications_knative @@ -131,6 +133,7 @@ describe Gitlab::UsageData do expect(count_data[:clusters_platforms_user]).to eq(1) expect(count_data[:clusters_applications_helm]).to eq(1) expect(count_data[:clusters_applications_ingress]).to eq(1) + expect(count_data[:clusters_applications_cert_managers]).to eq(1) expect(count_data[:clusters_applications_prometheus]).to eq(1) expect(count_data[:clusters_applications_runner]).to eq(1) expect(count_data[:clusters_applications_knative]).to eq(1) diff --git a/spec/models/clusters/applications/cert_manager_spec.rb b/spec/models/clusters/applications/cert_manager_spec.rb new file mode 100644 index 00000000000..170c6001eaf --- /dev/null +++ b/spec/models/clusters/applications/cert_manager_spec.rb @@ -0,0 +1,79 @@ +require 'rails_helper' + +describe Clusters::Applications::CertManager do + let(:cert_manager) { create(:clusters_applications_cert_managers) } + + include_examples 'cluster application core specs', :clusters_applications_cert_managers + + describe '#make_installing!' do + before do + application.make_installing! + end + + context 'application install previously errored with older version' do + let(:application) { create(:clusters_applications_cert_managers, :scheduled, version: 'v0.4.0') } + + it 'updates the application version' do + expect(application.reload.version).to eq('v0.5.0') + end + end + end + + describe '#install_command' do + let(:cluster_issuer_file) { { "cluster_issuer.yaml": "---\napiVersion: certmanager.k8s.io/v1alpha1\nkind: ClusterIssuer\nmetadata:\n name: letsencrypt-prod\nspec:\n acme:\n server: https://acme-v02.api.letsencrypt.org/directory\n email: admin@example.com\n privateKeySecretRef:\n name: letsencrypt-prod\n http01: {}\n" } } + subject { cert_manager.install_command } + + it { is_expected.to be_an_instance_of(Gitlab::Kubernetes::Helm::InstallCommand) } + + it 'should be initialized with cert_manager arguments' do + expect(subject.name).to eq('certmanager') + expect(subject.chart).to eq('stable/cert-manager') + expect(subject.version).to eq('v0.5.0') + expect(subject).not_to be_rbac + expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file)) + expect(subject.postinstall).to eq(['/usr/bin/kubectl create -f /data/helm/certmanager/config/cluster_issuer.yaml']) + end + + context 'for a specific user' do + before do + cert_manager.email = 'abc@xyz.com' + cluster_issuer_file[:'cluster_issuer.yaml'].gsub! 'admin@example.com', 'abc@xyz.com' + end + + it 'should use his/her email to register issuer with certificate provider' do + expect(subject.files).to eq(cert_manager.files.merge(cluster_issuer_file)) + end + end + + context 'on a rbac enabled cluster' do + before do + cert_manager.cluster.platform_kubernetes.rbac! + end + + it { is_expected.to be_rbac } + end + + context 'application failed to install previously' do + let(:cert_manager) { create(:clusters_applications_cert_managers, :errored, version: '0.0.1') } + + it 'should be initialized with the locked version' do + expect(subject.version).to eq('v0.5.0') + end + end + end + + describe '#files' do + let(:application) { cert_manager } + let(:values) { subject[:'values.yaml'] } + + subject { application.files } + + it 'should include cert_manager specific keys in the values.yaml file' do + expect(values).to include('ingressShim') + end + end + + describe 'validations' do + it { is_expected.to validate_presence_of(:email) } + end +end diff --git a/spec/models/clusters/cluster_spec.rb b/spec/models/clusters/cluster_spec.rb index 98d7e799d67..eb68ebccdcb 100644 --- a/spec/models/clusters/cluster_spec.rb +++ b/spec/models/clusters/cluster_spec.rb @@ -311,13 +311,14 @@ describe Clusters::Cluster do context 'when applications are created' do let!(:helm) { create(:clusters_applications_helm, cluster: cluster) } let!(:ingress) { create(:clusters_applications_ingress, cluster: cluster) } + let!(:cert_manager) { create(:clusters_applications_cert_managers, cluster: cluster) } let!(:prometheus) { create(:clusters_applications_prometheus, cluster: cluster) } let!(:runner) { create(:clusters_applications_runner, cluster: cluster) } let!(:jupyter) { create(:clusters_applications_jupyter, cluster: cluster) } let!(:knative) { create(:clusters_applications_knative, cluster: cluster) } it 'returns a list of created applications' do - is_expected.to contain_exactly(helm, ingress, prometheus, runner, jupyter, knative) + is_expected.to contain_exactly(helm, ingress, cert_manager, prometheus, runner, jupyter, knative) end end end diff --git a/spec/models/concerns/relative_positioning_spec.rb b/spec/models/concerns/relative_positioning_spec.rb index 66c1f47d12b..ac8da30b6c9 100644 --- a/spec/models/concerns/relative_positioning_spec.rb +++ b/spec/models/concerns/relative_positioning_spec.rb @@ -14,6 +14,14 @@ describe RelativePositioning do expect(issue.prev_relative_position).to eq nil expect(issue1.next_relative_position).to eq nil end + + it 'does not perform any moves if all issues have their relative_position set' do + issue.update!(relative_position: 1) + + expect(issue).not_to receive(:save) + + Issue.move_to_end([issue]) + end end describe '#max_relative_position' do diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb index a2b41d56b8b..334dbb1c34c 100644 --- a/spec/requests/api/files_spec.rb +++ b/spec/requests/api/files_spec.rb @@ -178,6 +178,14 @@ describe API::Files do expect(response).to have_gitlab_http_status(200) end + it 'forces attachment content disposition' do + url = route(file_path) + "/raw" + + get api(url, current_user), params + + expect(headers['Content-Disposition']).to match(/^attachment/) + end + context 'when mandatory params are not given' do it_behaves_like '400 response' do let(:request) { get api(route("any%2Ffile"), current_user) } diff --git a/spec/requests/api/issues_spec.rb b/spec/requests/api/issues_spec.rb index 3d532dd83c7..1827da61e2d 100644 --- a/spec/requests/api/issues_spec.rb +++ b/spec/requests/api/issues_spec.rb @@ -300,17 +300,31 @@ describe API::Issues do expect(json_response.first['state']).to eq('opened') end - it 'returns unlabeled issues for "No Label" label' do - get api("/issues", user), labels: 'No Label' + it 'returns an empty array if no issue matches labels and state filters' do + get api("/issues", user), labels: label.title, state: :closed + + expect_paginated_array_response(size: 0) + end + + it 'returns an array of issues with any label' do + get api("/issues", user), labels: IssuesFinder::FILTER_ANY expect_paginated_array_response(size: 1) - expect(json_response.first['labels']).to be_empty + expect(json_response.first['id']).to eq(issue.id) end - it 'returns an empty array if no issue matches labels and state filters' do - get api("/issues?labels=#{label.title}&state=closed", user) + it 'returns an array of issues with no label' do + get api("/issues", user), labels: IssuesFinder::FILTER_NONE - expect_paginated_array_response(size: 0) + expect_paginated_array_response(size: 1) + expect(json_response.first['id']).to eq(closed_issue.id) + end + + it 'returns an array of issues with no label when using the legacy No+Label filter' do + get api("/issues", user), labels: "No Label" + + expect_paginated_array_response(size: 1) + expect(json_response.first['id']).to eq(closed_issue.id) end it 'returns an empty array if no issue matches milestone' do @@ -492,58 +506,58 @@ describe API::Issues do end it 'returns group issues without confidential issues for non project members' do - get api("#{base_url}?state=opened", non_member) + get api(base_url, non_member), state: :opened expect_paginated_array_response(size: 1) expect(json_response.first['title']).to eq(group_issue.title) end it 'returns group confidential issues for author' do - get api("#{base_url}?state=opened", author) + get api(base_url, author), state: :opened expect_paginated_array_response(size: 2) end it 'returns group confidential issues for assignee' do - get api("#{base_url}?state=opened", assignee) + get api(base_url, assignee), state: :opened expect_paginated_array_response(size: 2) end it 'returns group issues with confidential issues for project members' do - get api("#{base_url}?state=opened", user) + get api(base_url, user), state: :opened expect_paginated_array_response(size: 2) end it 'returns group confidential issues for admin' do - get api("#{base_url}?state=opened", admin) + get api(base_url, admin), state: :opened expect_paginated_array_response(size: 2) end it 'returns an array of labeled group issues' do - get api("#{base_url}?labels=#{group_label.title}", user) + get api(base_url, user), labels: group_label.title expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([group_label.title]) end it 'returns an array of labeled group issues where all labels match' do - get api("#{base_url}?labels=#{group_label.title},foo,bar", user) + get api(base_url, user), labels: "#{group_label.title},foo,bar" expect_paginated_array_response(size: 0) end it 'returns issues matching given search string for title' do - get api("#{base_url}?search=#{group_issue.title}", user) + get api(base_url, user), search: group_issue.title expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) end it 'returns issues matching given search string for description' do - get api("#{base_url}?search=#{group_issue.description}", user) + get api(base_url, user), search: group_issue.description expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) @@ -556,7 +570,7 @@ describe API::Issues do create(:label_link, label: label_b, target: group_issue) create(:label_link, label: label_c, target: group_issue) - get api("#{base_url}", user), labels: "#{group_label.title},#{label_b.title},#{label_c.title}" + get api(base_url, user), labels: "#{group_label.title},#{label_b.title},#{label_c.title}" expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label_c.title, label_b.title, group_label.title]) @@ -576,40 +590,55 @@ describe API::Issues do end it 'returns an empty array if no group issue matches labels' do - get api("#{base_url}?labels=foo,bar", user) + get api(base_url, user), labels: 'foo,bar' expect_paginated_array_response(size: 0) end + it 'returns an array of group issues with any label' do + get api(base_url, user), labels: IssuesFinder::FILTER_ANY + + expect_paginated_array_response(size: 1) + expect(json_response.first['id']).to eq(group_issue.id) + end + + it 'returns an array of group issues with no label' do + get api(base_url, user), labels: IssuesFinder::FILTER_NONE + + response_ids = json_response.map { |issue| issue['id'] } + + expect_paginated_array_response(size: 2) + expect(response_ids).to contain_exactly(group_closed_issue.id, group_confidential_issue.id) + end + it 'returns an empty array if no issue matches milestone' do - get api("#{base_url}?milestone=#{group_empty_milestone.title}", user) + get api(base_url, user), milestone: group_empty_milestone.title expect_paginated_array_response(size: 0) end it 'returns an empty array if milestone does not exist' do - get api("#{base_url}?milestone=foo", user) + get api(base_url, user), milestone: 'foo' expect_paginated_array_response(size: 0) end it 'returns an array of issues in given milestone' do - get api("#{base_url}?state=opened&milestone=#{group_milestone.title}", user) + get api(base_url, user), state: :opened, milestone: group_milestone.title expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_issue.id) end it 'returns an array of issues matching state in milestone' do - get api("#{base_url}?milestone=#{group_milestone.title}"\ - '&state=closed', user) + get api(base_url, user), milestone: group_milestone.title, state: :closed expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(group_closed_issue.id) end it 'returns an array of issues with no milestone' do - get api("#{base_url}?milestone=#{no_milestone_title}", user) + get api(base_url, user), milestone: no_milestone_title expect(response).to have_gitlab_http_status(200) @@ -645,7 +674,7 @@ describe API::Issues do end it 'sorts by updated_at ascending when requested' do - get api("#{base_url}?order_by=updated_at&sort=asc", user) + get api(base_url, user), order_by: :updated_at, sort: :asc response_dates = json_response.map { |issue| issue['updated_at'] } @@ -748,7 +777,7 @@ describe API::Issues do end it 'returns an array of labeled project issues' do - get api("#{base_url}/issues?labels=#{label.title}", user) + get api("#{base_url}/issues", user), labels: label.title expect_paginated_array_response(size: 1) expect(json_response.first['labels']).to eq([label.title]) @@ -800,26 +829,42 @@ describe API::Issues do expect_paginated_array_response(size: 0) end + it 'returns an array of project issues with any label' do + get api("#{base_url}/issues", user), labels: IssuesFinder::FILTER_ANY + + expect_paginated_array_response(size: 1) + expect(json_response.first['id']).to eq(issue.id) + end + + it 'returns an array of project issues with no label' do + get api("#{base_url}/issues", user), labels: IssuesFinder::FILTER_NONE + + response_ids = json_response.map { |issue| issue['id'] } + + expect_paginated_array_response(size: 2) + expect(response_ids).to contain_exactly(closed_issue.id, confidential_issue.id) + end + it 'returns an empty array if no project issue matches labels' do - get api("#{base_url}/issues?labels=foo,bar", user) + get api("#{base_url}/issues", user), labels: 'foo,bar' expect_paginated_array_response(size: 0) end it 'returns an empty array if no issue matches milestone' do - get api("#{base_url}/issues?milestone=#{empty_milestone.title}", user) + get api("#{base_url}/issues", user), milestone: empty_milestone.title expect_paginated_array_response(size: 0) end it 'returns an empty array if milestone does not exist' do - get api("#{base_url}/issues?milestone=foo", user) + get api("#{base_url}/issues", user), milestone: :foo expect_paginated_array_response(size: 0) end it 'returns an array of issues in given milestone' do - get api("#{base_url}/issues?milestone=#{milestone.title}", user) + get api("#{base_url}/issues", user), milestone: milestone.title expect_paginated_array_response(size: 2) expect(json_response.first['id']).to eq(issue.id) @@ -827,21 +872,21 @@ describe API::Issues do end it 'returns an array of issues matching state in milestone' do - get api("#{base_url}/issues?milestone=#{milestone.title}&state=closed", user) + get api("#{base_url}/issues", user), milestone: milestone.title, state: :closed expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(closed_issue.id) end it 'returns an array of issues with no milestone' do - get api("#{base_url}/issues?milestone=#{no_milestone_title}", user) + get api("#{base_url}/issues", user), milestone: no_milestone_title expect_paginated_array_response(size: 1) expect(json_response.first['id']).to eq(confidential_issue.id) end it 'returns an array of issues with any milestone' do - get api("#{base_url}/issues?milestone=#{any_milestone_title}", user) + get api("#{base_url}/issues", user), milestone: any_milestone_title response_ids = json_response.map { |issue| issue['id'] } @@ -859,7 +904,7 @@ describe API::Issues do end it 'sorts ascending when requested' do - get api("#{base_url}/issues?sort=asc", user) + get api("#{base_url}/issues", user), sort: :asc response_dates = json_response.map { |issue| issue['created_at'] } @@ -868,7 +913,7 @@ describe API::Issues do end it 'sorts by updated_at descending when requested' do - get api("#{base_url}/issues?order_by=updated_at", user) + get api("#{base_url}/issues", user), order_by: :updated_at response_dates = json_response.map { |issue| issue['updated_at'] } @@ -877,7 +922,7 @@ describe API::Issues do end it 'sorts by updated_at ascending when requested' do - get api("#{base_url}/issues?order_by=updated_at&sort=asc", user) + get api("#{base_url}/issues", user), order_by: :updated_at, sort: :asc response_dates = json_response.map { |issue| issue['updated_at'] } diff --git a/spec/requests/api/repositories_spec.rb b/spec/requests/api/repositories_spec.rb index fa38751fe58..de141377793 100644 --- a/spec/requests/api/repositories_spec.rb +++ b/spec/requests/api/repositories_spec.rb @@ -168,6 +168,12 @@ describe API::Repositories do expect(response).to have_gitlab_http_status(200) end + it 'forces attachment content disposition' do + get api(route, current_user) + + expect(headers['Content-Disposition']).to match(/^attachment/) + end + context 'when sha does not exist' do it_behaves_like '404 response' do let(:request) { get api(route.sub(sample_blob.oid, '123456'), current_user) } diff --git a/spec/requests/api/snippets_spec.rb b/spec/requests/api/snippets_spec.rb index 6da769cb3ed..c546ba3e127 100644 --- a/spec/requests/api/snippets_spec.rb +++ b/spec/requests/api/snippets_spec.rb @@ -94,6 +94,12 @@ describe API::Snippets do expect(response.body).to eq(snippet.content) end + it 'forces attachment content disposition' do + get api("/snippets/#{snippet.id}/raw", user) + + expect(headers['Content-Disposition']).to match(/^attachment/) + end + it 'returns 404 for invalid snippet id' do get api("/snippets/1234/raw", user) diff --git a/spec/support/shared_examples/requests/api/merge_requests_list.rb b/spec/support/shared_examples/requests/api/merge_requests_list.rb index 668a390b5d2..92d4dd598d5 100644 --- a/spec/support/shared_examples/requests/api/merge_requests_list.rb +++ b/spec/support/shared_examples/requests/api/merge_requests_list.rb @@ -186,6 +186,23 @@ shared_examples 'merge requests list' do expect(json_response.length).to eq(0) end + it 'returns an array of merge requests with any label when filtering by any label' do + get api(endpoint_path, user), labels: IssuesFinder::FILTER_ANY + + expect_paginated_array_response + expect(json_response.length).to eq(1) + expect(json_response.first['id']).to eq(merge_request.id) + end + + it 'returns an array of merge requests without a label when filtering by no label' do + get api(endpoint_path, user), labels: IssuesFinder::FILTER_NONE + + response_ids = json_response.map { |merge_request| merge_request['id'] } + + expect_paginated_array_response + expect(response_ids).to contain_exactly(merge_request_closed.id, merge_request_merged.id, merge_request_locked.id) + end + it 'returns an array of labeled merge requests that are merged for a milestone' do bug_label = create(:label, title: 'bug', color: '#FFAABB', project: project) |