diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/controllers/concerns/sourcegraph_gon_spec.rb | 118 | ||||
-rw-r--r-- | spec/controllers/projects/pages_domains_controller_spec.rb | 12 | ||||
-rw-r--r-- | spec/features/projects/pages_lets_encrypt_spec.rb | 31 | ||||
-rw-r--r-- | spec/features/projects/pages_spec.rb | 62 | ||||
-rw-r--r-- | spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json | 3 | ||||
-rw-r--r-- | spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json | 3 | ||||
-rw-r--r-- | spec/frontend/repository/log_tree_spec.js | 18 | ||||
-rw-r--r-- | spec/frontend/repository/utils/commit_spec.js | 30 | ||||
-rw-r--r-- | spec/helpers/sourcegraph_helper_spec.rb | 64 | ||||
-rw-r--r-- | spec/lib/gitlab/sourcegraph_spec.rb | 66 | ||||
-rw-r--r-- | spec/models/application_setting_spec.rb | 30 | ||||
-rw-r--r-- | spec/requests/api/pages_domains_spec.rb | 94 | ||||
-rw-r--r-- | spec/requests/api/settings_spec.rb | 19 | ||||
-rw-r--r-- | spec/views/admin/application_settings/integrations.html.haml_spec.rb | 34 | ||||
-rw-r--r-- | spec/views/profiles/preferences/show.html.haml_spec.rb | 72 | ||||
-rw-r--r-- | spec/views/projects/pages_domains/show.html.haml_spec.rb | 34 |
16 files changed, 601 insertions, 89 deletions
diff --git a/spec/controllers/concerns/sourcegraph_gon_spec.rb b/spec/controllers/concerns/sourcegraph_gon_spec.rb new file mode 100644 index 00000000000..4fb7e37d148 --- /dev/null +++ b/spec/controllers/concerns/sourcegraph_gon_spec.rb @@ -0,0 +1,118 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe SourcegraphGon do + let_it_be(:enabled_user) { create(:user, sourcegraph_enabled: true) } + let_it_be(:disabled_user) { create(:user, sourcegraph_enabled: false) } + let_it_be(:public_project) { create(:project, :public) } + let_it_be(:internal_project) { create(:project, :internal) } + + let(:sourcegraph_url) { 'http://sourcegraph.gitlab.com' } + let(:feature_enabled) { true } + let(:sourcegraph_enabled) { true } + let(:sourcegraph_public_only) { false } + let(:format) { :html } + let(:user) { enabled_user } + let(:project) { internal_project } + + controller(ApplicationController) do + include SourcegraphGon # rubocop:disable RSpec/DescribedClass + + def index + head :ok + end + end + + before do + Feature.get(:sourcegraph).enable(feature_enabled) + + stub_application_setting(sourcegraph_url: sourcegraph_url, sourcegraph_enabled: sourcegraph_enabled, sourcegraph_public_only: sourcegraph_public_only) + + allow(controller).to receive(:project).and_return(project) + + Gon.clear + + sign_in user if user + end + + after do + Feature.get(:sourcegraph).disable + end + + subject do + get :index, format: format + + Gon.sourcegraph + end + + shared_examples 'enabled' do + it { is_expected.to eq({ url: sourcegraph_url }) } + end + + shared_examples 'disabled' do + it { is_expected.to be_nil } + end + + context 'with feature enabled, application enabled, and user enabled' do + it_behaves_like 'enabled' + end + + context 'with feature enabled for specific project' do + let(:feature_enabled) { project } + + it_behaves_like 'enabled' + end + + context 'with feature enabled for different project' do + let(:feature_enabled) { create(:project) } + + it_behaves_like 'disabled' + end + + context 'with feature disabled' do + let(:feature_enabled) { false } + + it_behaves_like 'disabled' + end + + context 'with admin settings disabled' do + let(:sourcegraph_enabled) { false } + + it_behaves_like 'disabled' + end + + context 'with public only' do + let(:sourcegraph_public_only) { true } + + context 'with internal project' do + let(:project) { internal_project } + + it_behaves_like 'disabled' + end + + context 'with public project' do + let(:project) { public_project } + + it_behaves_like 'enabled' + end + end + + context 'with user disabled' do + let(:user) { disabled_user } + + it_behaves_like 'disabled' + end + + context 'with no user' do + let(:user) { nil } + + it_behaves_like 'disabled' + end + + context 'with non-html format' do + let(:format) { :json } + + it_behaves_like 'disabled' + end +end diff --git a/spec/controllers/projects/pages_domains_controller_spec.rb b/spec/controllers/projects/pages_domains_controller_spec.rb index 1db1fff02d8..3987bebb124 100644 --- a/spec/controllers/projects/pages_domains_controller_spec.rb +++ b/spec/controllers/projects/pages_domains_controller_spec.rb @@ -32,10 +32,10 @@ describe Projects::PagesDomainsController do get(:show, params: request_params.merge(id: pages_domain.domain)) end - it "displays the 'show' page" do + it "redirects to the 'edit' page" do make_request - expect(response).to have_gitlab_http_status(200) - expect(response).to render_template('show') + + expect(response).to redirect_to(edit_project_pages_domain_path(project, pages_domain.domain)) end context 'when user is developer' do @@ -69,7 +69,7 @@ describe Projects::PagesDomainsController do created_domain = PagesDomain.reorder(:id).last expect(created_domain).to be_present - expect(response).to redirect_to(project_pages_domain_path(project, created_domain)) + expect(response).to redirect_to(edit_project_pages_domain_path(project, created_domain)) end end @@ -160,7 +160,7 @@ describe Projects::PagesDomainsController do post :verify, params: params - expect(response).to redirect_to project_pages_domain_path(project, pages_domain) + expect(response).to redirect_to edit_project_pages_domain_path(project, pages_domain) expect(flash[:notice]).to eq('Successfully verified domain ownership') end @@ -169,7 +169,7 @@ describe Projects::PagesDomainsController do post :verify, params: params - expect(response).to redirect_to project_pages_domain_path(project, pages_domain) + expect(response).to redirect_to edit_project_pages_domain_path(project, pages_domain) expect(flash[:alert]).to eq('Failed to verify domain ownership') end diff --git a/spec/features/projects/pages_lets_encrypt_spec.rb b/spec/features/projects/pages_lets_encrypt_spec.rb index c33a2896952..19c61487e16 100644 --- a/spec/features/projects/pages_lets_encrypt_spec.rb +++ b/spec/features/projects/pages_lets_encrypt_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' describe "Pages with Let's Encrypt", :https_pages_enabled do include LetsEncryptHelpers - let(:project) { create(:project) } + let(:project) { create(:project, pages_https_only: false) } let(:user) { create(:user) } let(:role) { :maintainer } let(:certificate_pem) { attributes_for(:pages_domain)[:certificate] } @@ -34,14 +34,14 @@ describe "Pages with Let's Encrypt", :https_pages_enabled do expect(domain.auto_ssl_enabled).to eq false expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'false' - expect(page).to have_field 'Certificate (PEM)', type: 'textarea' - expect(page).to have_field 'Key (PEM)', type: 'textarea' + expect(page).to have_selector '.card-header', text: 'Certificate' + expect(page).to have_text domain.subject find('.js-auto-ssl-toggle-container .project-feature-toggle').click expect(find("#pages_domain_auto_ssl_enabled", visible: false).value).to eq 'true' - expect(page).not_to have_field 'Certificate (PEM)', type: 'textarea' - expect(page).not_to have_field 'Key (PEM)', type: 'textarea' + expect(page).not_to have_selector '.card-header', text: 'Certificate' + expect(page).not_to have_text domain.subject click_on 'Save Changes' @@ -67,9 +67,6 @@ describe "Pages with Let's Encrypt", :https_pages_enabled do expect(page).to have_field 'Certificate (PEM)', type: 'textarea' expect(page).to have_field 'Key (PEM)', type: 'textarea' - fill_in 'Certificate (PEM)', with: certificate_pem - fill_in 'Key (PEM)', with: certificate_key - click_on 'Save Changes' expect(domain.reload.auto_ssl_enabled).to eq false @@ -81,7 +78,8 @@ describe "Pages with Let's Encrypt", :https_pages_enabled do it 'user do not see private key' do visit edit_project_pages_domain_path(project, domain) - expect(find_field('Key (PEM)', visible: :all, disabled: :all).value).to be_blank + expect(page).not_to have_selector '.card-header', text: 'Certificate' + expect(page).not_to have_text domain.subject end end @@ -100,10 +98,21 @@ describe "Pages with Let's Encrypt", :https_pages_enabled do context 'when certificate is provided by user' do let(:domain) { create(:pages_domain, project: project) } - it 'user sees private key' do + it 'user sees certificate subject' do + visit edit_project_pages_domain_path(project, domain) + + expect(page).to have_selector '.card-header', text: 'Certificate' + expect(page).to have_text domain.subject + end + + it 'user can delete the certificate', :js do visit edit_project_pages_domain_path(project, domain) - expect(find_field('Key (PEM)').value).not_to be_blank + expect(page).to have_selector '.card-header', text: 'Certificate' + expect(page).to have_text domain.subject + within('.card') { accept_confirm { click_on 'Remove' } } + expect(page).to have_field 'Certificate (PEM)', with: '' + expect(page).to have_field 'Key (PEM)', with: '' end end end diff --git a/spec/features/projects/pages_spec.rb b/spec/features/projects/pages_spec.rb index 17a2d30e784..eab0aefbe84 100644 --- a/spec/features/projects/pages_spec.rb +++ b/spec/features/projects/pages_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' shared_examples 'pages settings editing' do - let(:project) { create(:project) } + let_it_be(:project) { create(:project, pages_https_only: false) } let(:user) { create(:user) } let(:role) { :maintainer } @@ -185,6 +185,21 @@ shared_examples 'pages settings editing' do expect(page).to have_content('my.test.domain.com') end + describe 'with dns verification enabled' do + before do + stub_application_setting(pages_domain_verification_enabled: true) + end + + it 'shows the DNS verification record' do + domain = create(:pages_domain, project: project) + + visit project_pages_path(project) + + within('#content-body') { click_link 'Edit' } + expect(page).to have_field :domain_verification, with: "#{domain.verification_domain} TXT #{domain.keyed_verification_code}" + end + end + describe 'updating the certificate for an existing domain' do let!(:domain) do create(:pages_domain, project: project) @@ -193,19 +208,22 @@ shared_examples 'pages settings editing' do it 'allows the certificate to be updated' do visit project_pages_path(project) - within('#content-body') { click_link 'Details' } - click_link 'Edit' + within('#content-body') { click_link 'Edit' } click_button 'Save Changes' expect(page).to have_content('Domain was updated') end context 'when the certificate is invalid' do + let_it_be(:domain) do + create(:pages_domain, :without_certificate, :without_key, project: project) + end + it 'tells the user what the problem is' do visit project_pages_path(project) - within('#content-body') { click_link 'Details' } - click_link 'Edit' + within('#content-body') { click_link 'Edit' } + fill_in 'Certificate (PEM)', with: 'invalid data' click_button 'Save Changes' @@ -214,6 +232,27 @@ shared_examples 'pages settings editing' do expect(page).to have_content("Key doesn't match the certificate") end end + + it 'allows the certificate to be removed', :js do + visit project_pages_path(project) + + within('#content-body') { click_link 'Edit' } + + accept_confirm { click_link 'Remove' } + + expect(page).to have_field('Certificate (PEM)', with: '') + expect(page).to have_field('Key (PEM)', with: '') + domain.reload + expect(domain.certificate).to be_nil + expect(domain.key).to be_nil + end + + it 'shows the DNS CNAME record' do + visit project_pages_path(project) + + within('#content-body') { click_link 'Edit' } + expect(page).to have_field :domain_dns, with: "#{domain.domain} CNAME #{domain.project.pages_subdomain}.#{Settings.pages.host}." + end end end end @@ -250,7 +289,7 @@ shared_examples 'pages settings editing' do end end - describe 'HTTPS settings', :js, :https_pages_enabled do + describe 'HTTPS settings', :https_pages_enabled do before do project.namespace.update(owner: user) @@ -358,18 +397,21 @@ shared_examples 'pages settings editing' do expect(page).to have_link('Remove pages') - click_link 'Remove pages' + accept_confirm { click_link 'Remove pages' } - expect(project.pages_deployed?).to be_falsey + expect(page).to have_content('Pages were removed') + expect(project.reload.pages_deployed?).to be_falsey end end end end -describe 'Pages' do +describe 'Pages', :js do include LetsEncryptHelpers - include_examples 'pages settings editing' + context 'when editing normally' do + include_examples 'pages settings editing' + end context 'when letsencrypt support is enabled' do before do diff --git a/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json b/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json index ed8ed9085c0..721b8d4641f 100644 --- a/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json +++ b/spec/fixtures/api/schemas/public_api/v4/pages_domain/basic.json @@ -7,6 +7,7 @@ "verified": { "type": "boolean" }, "verification_code": { "type": ["string", "null"] }, "enabled_until": { "type": ["date", "null"] }, + "auto_ssl_enabled": { "type": "boolean" }, "certificate_expiration": { "type": "object", "properties": { @@ -17,6 +18,6 @@ "additionalProperties": false } }, - "required": ["domain", "url", "project_id", "verified", "verification_code", "enabled_until"], + "required": ["domain", "url", "project_id", "verified", "verification_code", "enabled_until", "auto_ssl_enabled"], "additionalProperties": false } diff --git a/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json b/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json index b57d544f896..3dd80a6f11b 100644 --- a/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json +++ b/spec/fixtures/api/schemas/public_api/v4/pages_domain/detail.json @@ -6,6 +6,7 @@ "verified": { "type": "boolean" }, "verification_code": { "type": ["string", "null"] }, "enabled_until": { "type": ["date", "null"] }, + "auto_ssl_enabled": { "type": "boolean" }, "certificate": { "type": "object", "properties": { @@ -18,6 +19,6 @@ "additionalProperties": false } }, - "required": ["domain", "url", "verified", "verification_code", "enabled_until"], + "required": ["domain", "url", "verified", "verification_code", "enabled_until", "auto_ssl_enabled"], "additionalProperties": false } diff --git a/spec/frontend/repository/log_tree_spec.js b/spec/frontend/repository/log_tree_spec.js index 9eee89cd07b..ad42f8b2ffc 100644 --- a/spec/frontend/repository/log_tree_spec.js +++ b/spec/frontend/repository/log_tree_spec.js @@ -1,6 +1,6 @@ import MockAdapter from 'axios-mock-adapter'; import axios from '~/lib/utils/axios_utils'; -import { normalizeData, resolveCommit, fetchLogsTree } from '~/repository/log_tree'; +import { resolveCommit, fetchLogsTree } from '~/repository/log_tree'; const mockData = [ { @@ -15,22 +15,6 @@ const mockData = [ }, ]; -describe('normalizeData', () => { - it('normalizes data into LogTreeCommit object', () => { - expect(normalizeData(mockData)).toEqual([ - { - sha: '123', - message: 'testing message', - committedDate: '2019-01-01', - commitPath: 'https://test.com', - fileName: 'index.js', - type: 'blob', - __typename: 'LogTreeCommit', - }, - ]); - }); -}); - describe('resolveCommit', () => { it('calls resolve when commit found', () => { const resolver = { diff --git a/spec/frontend/repository/utils/commit_spec.js b/spec/frontend/repository/utils/commit_spec.js new file mode 100644 index 00000000000..2d75358106c --- /dev/null +++ b/spec/frontend/repository/utils/commit_spec.js @@ -0,0 +1,30 @@ +import { normalizeData } from '~/repository/utils/commit'; + +const mockData = [ + { + commit: { + id: '123', + message: 'testing message', + committed_date: '2019-01-01', + }, + commit_path: `https://test.com`, + file_name: 'index.js', + type: 'blob', + }, +]; + +describe('normalizeData', () => { + it('normalizes data into LogTreeCommit object', () => { + expect(normalizeData(mockData)).toEqual([ + { + sha: '123', + message: 'testing message', + committedDate: '2019-01-01', + commitPath: 'https://test.com', + fileName: 'index.js', + type: 'blob', + __typename: 'LogTreeCommit', + }, + ]); + }); +}); diff --git a/spec/helpers/sourcegraph_helper_spec.rb b/spec/helpers/sourcegraph_helper_spec.rb new file mode 100644 index 00000000000..830bbb3129f --- /dev/null +++ b/spec/helpers/sourcegraph_helper_spec.rb @@ -0,0 +1,64 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe SourcegraphHelper do + describe '#sourcegraph_url_message' do + let(:sourcegraph_url) { 'http://sourcegraph.example.com' } + + before do + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url).and_return(sourcegraph_url) + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_url_is_com?).and_return(is_com) + end + + subject { helper.sourcegraph_url_message } + + context 'with .com sourcegraph url' do + let(:is_com) { true } + + it { is_expected.to have_text('Uses Sourcegraph.com') } + it { is_expected.to have_link('Sourcegraph.com', href: sourcegraph_url) } + end + + context 'with custom sourcegraph url' do + let(:is_com) { false } + + it { is_expected.to have_text('Uses a custom Sourcegraph instance') } + it { is_expected.to have_link('Sourcegraph instance', href: sourcegraph_url) } + + context 'with unsafe url' do + let(:sourcegraph_url) { '\" onload=\"alert(1);\"' } + + it { is_expected.to have_link('Sourcegraph instance', href: sourcegraph_url) } + end + end + end + + context '#sourcegraph_experimental_message' do + let(:feature_conditional) { false } + let(:public_only) { false } + + before do + allow(Gitlab::CurrentSettings).to receive(:sourcegraph_public_only).and_return(public_only) + allow(Gitlab::Sourcegraph).to receive(:feature_conditional?).and_return(feature_conditional) + end + + subject { helper.sourcegraph_experimental_message } + + context 'when not limited by feature or public only' do + it { is_expected.to eq "This feature is experimental." } + end + + context 'when limited by feature' do + let(:feature_conditional) { true } + + it { is_expected.to eq "This feature is experimental and currently limited to certain projects." } + end + + context 'when limited by public only' do + let(:public_only) { true } + + it { is_expected.to eq "This feature is experimental and limited to public projects." } + end + end +end diff --git a/spec/lib/gitlab/sourcegraph_spec.rb b/spec/lib/gitlab/sourcegraph_spec.rb new file mode 100644 index 00000000000..e081ae32175 --- /dev/null +++ b/spec/lib/gitlab/sourcegraph_spec.rb @@ -0,0 +1,66 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe Gitlab::Sourcegraph do + let_it_be(:user) { create(:user) } + let(:feature_scope) { true } + + before do + Feature.enable(:sourcegraph, feature_scope) + end + + describe '.feature_conditional?' do + subject { described_class.feature_conditional? } + + context 'when feature is enabled globally' do + it { is_expected.to be_falsey } + end + + context 'when feature is enabled only to a resource' do + let(:feature_scope) { user } + + it { is_expected.to be_truthy } + end + end + + describe '.feature_available?' do + subject { described_class.feature_available? } + + context 'when feature is enabled globally' do + it { is_expected.to be_truthy } + end + + context 'when feature is enabled only to a resource' do + let(:feature_scope) { user } + + it { is_expected.to be_truthy } + end + end + + describe '.feature_enabled?' do + let(:current_user) { nil } + + subject { described_class.feature_enabled?(current_user) } + + context 'when feature is enabled globally' do + it { is_expected.to be_truthy } + end + + context 'when feature is enabled only to a resource' do + let(:feature_scope) { user } + + context 'for the same resource' do + let(:current_user) { user } + + it { is_expected.to be_truthy } + end + + context 'for a different resource' do + let(:current_user) { create(:user) } + + it { is_expected.to be_falsey } + end + end + end +end diff --git a/spec/models/application_setting_spec.rb b/spec/models/application_setting_spec.rb index 4aa8f2d959d..ba3b99f4421 100644 --- a/spec/models/application_setting_spec.rb +++ b/spec/models/application_setting_spec.rb @@ -3,6 +3,8 @@ require 'spec_helper' describe ApplicationSetting do + using RSpec::Parameterized::TableSyntax + subject(:setting) { described_class.create_from_defaults } it { include(CacheableAttributes) } @@ -495,6 +497,15 @@ describe ApplicationSetting do it { is_expected.not_to allow_value(nil).for(:static_objects_external_storage_auth_token) } end end + + context 'sourcegraph settings' do + it 'is invalid if sourcegraph is enabled and no url is provided' do + allow(subject).to receive(:sourcegraph_enabled).and_return(true) + + expect(subject.sourcegraph_url).to be_nil + is_expected.to be_invalid + end + end end context 'restrict creating duplicates' do @@ -583,5 +594,24 @@ describe ApplicationSetting do end end + describe '#sourcegraph_url_is_com?' do + where(:url, :is_com) do + 'https://sourcegraph.com' | true + 'https://sourcegraph.com/' | true + 'https://www.sourcegraph.com' | true + 'shttps://www.sourcegraph.com' | false + 'https://sourcegraph.example.com/' | false + 'https://sourcegraph.org/' | false + end + + with_them do + it 'matches the url with sourcegraph.com' do + setting.sourcegraph_url = url + + expect(setting.sourcegraph_url_is_com?).to eq(is_com) + end + end + end + it_behaves_like 'application settings examples' end diff --git a/spec/requests/api/pages_domains_spec.rb b/spec/requests/api/pages_domains_spec.rb index ee3ee9c4d23..6b774e9335e 100644 --- a/spec/requests/api/pages_domains_spec.rb +++ b/spec/requests/api/pages_domains_spec.rb @@ -3,15 +3,20 @@ require 'spec_helper' describe API::PagesDomains do - set(:project) { create(:project, path: 'my.project', pages_https_only: false) } - set(:user) { create(:user) } - set(:admin) { create(:admin) } + let_it_be(:project) { create(:project, path: 'my.project', pages_https_only: false) } + let_it_be(:user) { create(:user) } + let_it_be(:admin) { create(:admin) } - set(:pages_domain) { create(:pages_domain, :without_key, :without_certificate, domain: 'www.domain.test', project: project) } - set(:pages_domain_secure) { create(:pages_domain, domain: 'ssl.domain.test', project: project) } - set(:pages_domain_expired) { create(:pages_domain, :with_expired_certificate, domain: 'expired.domain.test', project: project) } + let_it_be(:pages_domain) { create(:pages_domain, :without_key, :without_certificate, domain: 'www.domain.test', project: project) } + let_it_be(:pages_domain_secure) { create(:pages_domain, domain: 'ssl.domain.test', project: project) } + let_it_be(:pages_domain_with_letsencrypt) { create(:pages_domain, :letsencrypt, domain: 'letsencrypt.domain.test', project: project) } + let_it_be(:pages_domain_expired) { create(:pages_domain, :with_expired_certificate, domain: 'expired.domain.test', project: project) } let(:pages_domain_params) { build(:pages_domain, :without_key, :without_certificate, domain: 'www.other-domain.test').slice(:domain) } + let(:pages_domain_with_letsencrypt_params) do + build(:pages_domain, :without_key, :without_certificate, domain: 'www.other-domain.test', auto_ssl_enabled: true) + .slice(:domain, :auto_ssl_enabled) + end let(:pages_domain_secure_params) { build(:pages_domain, domain: 'ssl.other-domain.test', project: project).slice(:domain, :certificate, :key) } let(:pages_domain_secure_key_missmatch_params) {build(:pages_domain, :with_trusted_chain, project: project).slice(:domain, :certificate, :key) } let(:pages_domain_secure_missing_chain_params) {build(:pages_domain, :with_missing_chain, project: project).slice(:certificate) } @@ -22,6 +27,7 @@ describe API::PagesDomains do let(:route_secure_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_secure.domain}" } let(:route_expired_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_expired.domain}" } let(:route_vacant_domain) { "/projects/#{project.id}/pages/domains/www.vacant-domain.test" } + let(:route_letsencrypt_domain) { "/projects/#{project.id}/pages/domains/#{pages_domain_with_letsencrypt.domain}" } before do allow(Gitlab.config.pages).to receive(:enabled).and_return(true) @@ -47,9 +53,10 @@ describe API::PagesDomains do expect(response).to match_response_schema('public_api/v4/pages_domain_basics') expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response.size).to eq(3) + expect(json_response.size).to eq(4) expect(json_response.last).to have_key('domain') expect(json_response.last).to have_key('project_id') + expect(json_response.last).to have_key('auto_ssl_enabled') expect(json_response.last).to have_key('certificate_expiration') expect(json_response.last['certificate_expiration']['expired']).to be true expect(json_response.first).not_to have_key('certificate_expiration') @@ -73,7 +80,7 @@ describe API::PagesDomains do expect(response).to match_response_schema('public_api/v4/pages_domains') expect(response).to include_pagination_headers expect(json_response).to be_an Array - expect(json_response.size).to eq(3) + expect(json_response.size).to eq(4) expect(json_response.map { |pages_domain| pages_domain['domain'] }).to include(pages_domain.domain) expect(json_response.last).to have_key('domain') end @@ -166,6 +173,7 @@ describe API::PagesDomains do expect(json_response['url']).to eq(pages_domain_secure.url) expect(json_response['certificate']['subject']).to eq(pages_domain_secure.subject) expect(json_response['certificate']['expired']).to be false + expect(json_response['auto_ssl_enabled']).to be false end it 'returns pages domain with an expired certificate' do @@ -175,6 +183,18 @@ describe API::PagesDomains do expect(response).to match_response_schema('public_api/v4/pages_domain/detail') expect(json_response['certificate']['expired']).to be true end + + it 'returns pages domain with letsencrypt' do + get api(route_letsencrypt_domain, user) + + expect(response).to have_gitlab_http_status(200) + expect(response).to match_response_schema('public_api/v4/pages_domain/detail') + expect(json_response['domain']).to eq(pages_domain_with_letsencrypt.domain) + expect(json_response['url']).to eq(pages_domain_with_letsencrypt.url) + expect(json_response['certificate']['subject']).to eq(pages_domain_with_letsencrypt.subject) + expect(json_response['certificate']['expired']).to be false + expect(json_response['auto_ssl_enabled']).to be true + end end context 'when domain is vacant' do @@ -246,6 +266,7 @@ describe API::PagesDomains do expect(pages_domain.domain).to eq(params[:domain]) expect(pages_domain.certificate).to be_nil expect(pages_domain.key).to be_nil + expect(pages_domain.auto_ssl_enabled).to be false end it 'creates a new secure pages domain' do @@ -257,6 +278,29 @@ describe API::PagesDomains do expect(pages_domain.domain).to eq(params_secure[:domain]) expect(pages_domain.certificate).to eq(params_secure[:certificate]) expect(pages_domain.key).to eq(params_secure[:key]) + expect(pages_domain.auto_ssl_enabled).to be false + end + + it 'creates domain with letsencrypt enabled' do + post api(route, user), params: pages_domain_with_letsencrypt_params + pages_domain = PagesDomain.find_by(domain: json_response['domain']) + + expect(response).to have_gitlab_http_status(201) + expect(response).to match_response_schema('public_api/v4/pages_domain/detail') + expect(pages_domain.domain).to eq(pages_domain_with_letsencrypt_params[:domain]) + expect(pages_domain.auto_ssl_enabled).to be true + end + + it 'creates domain with letsencrypt enabled and provided certificate' do + post api(route, user), params: params_secure.merge(auto_ssl_enabled: true) + pages_domain = PagesDomain.find_by(domain: json_response['domain']) + + expect(response).to have_gitlab_http_status(201) + expect(response).to match_response_schema('public_api/v4/pages_domain/detail') + expect(pages_domain.domain).to eq(params_secure[:domain]) + expect(pages_domain.certificate).to eq(params_secure[:certificate]) + expect(pages_domain.key).to eq(params_secure[:key]) + expect(pages_domain.auto_ssl_enabled).to be true end it 'fails to create pages domain without key' do @@ -323,13 +367,14 @@ describe API::PagesDomains do shared_examples_for 'put pages domain' do it 'updates pages domain removing certificate' do - put api(route_secure_domain, user) + put api(route_secure_domain, user), params: { certificate: nil, key: nil } pages_domain_secure.reload expect(response).to have_gitlab_http_status(200) expect(response).to match_response_schema('public_api/v4/pages_domain/detail') expect(pages_domain_secure.certificate).to be_nil expect(pages_domain_secure.key).to be_nil + expect(pages_domain_secure.auto_ssl_enabled).to be false end it 'updates pages domain adding certificate' do @@ -342,6 +387,37 @@ describe API::PagesDomains do expect(pages_domain.key).to eq(params_secure[:key]) end + it 'updates pages domain adding certificate with letsencrypt' do + put api(route_domain, user), params: params_secure.merge(auto_ssl_enabled: true) + pages_domain.reload + + expect(response).to have_gitlab_http_status(200) + expect(response).to match_response_schema('public_api/v4/pages_domain/detail') + expect(pages_domain.certificate).to eq(params_secure[:certificate]) + expect(pages_domain.key).to eq(params_secure[:key]) + expect(pages_domain.auto_ssl_enabled).to be true + end + + it 'updates pages domain enabling letsencrypt' do + put api(route_domain, user), params: { auto_ssl_enabled: true } + pages_domain.reload + + expect(response).to have_gitlab_http_status(200) + expect(response).to match_response_schema('public_api/v4/pages_domain/detail') + expect(pages_domain.auto_ssl_enabled).to be true + end + + it 'updates pages domain disabling letsencrypt while preserving the certificate' do + put api(route_letsencrypt_domain, user), params: { auto_ssl_enabled: false } + pages_domain_with_letsencrypt.reload + + expect(response).to have_gitlab_http_status(200) + expect(response).to match_response_schema('public_api/v4/pages_domain/detail') + expect(pages_domain_with_letsencrypt.auto_ssl_enabled).to be false + expect(pages_domain_with_letsencrypt.key).to be + expect(pages_domain_with_letsencrypt.certificate).to be + end + it 'updates pages domain with expired certificate' do put api(route_expired_domain, user), params: params_secure pages_domain_expired.reload diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb index 3190de03d1a..b7586307929 100644 --- a/spec/requests/api/settings_spec.rb +++ b/spec/requests/api/settings_spec.rb @@ -19,6 +19,9 @@ describe API::Settings, 'Settings' do expect(json_response['plantuml_enabled']).to be_falsey expect(json_response['plantuml_url']).to be_nil expect(json_response['default_ci_config_path']).to be_nil + expect(json_response['sourcegraph_enabled']).to be_falsey + expect(json_response['sourcegraph_url']).to be_nil + expect(json_response['sourcegraph_public_only']).to be_truthy expect(json_response['default_project_visibility']).to be_a String expect(json_response['default_snippet_visibility']).to be_a String expect(json_response['default_group_visibility']).to be_a String @@ -45,6 +48,7 @@ describe API::Settings, 'Settings' do storages = Gitlab.config.repositories.storages .merge({ 'custom' => 'tmp/tests/custom_repositories' }) allow(Gitlab.config.repositories).to receive(:storages).and_return(storages) + Feature.get(:sourcegraph).enable end it "updates application settings" do @@ -57,6 +61,9 @@ describe API::Settings, 'Settings' do repository_storages: ['custom'], plantuml_enabled: true, plantuml_url: 'http://plantuml.example.com', + sourcegraph_enabled: true, + sourcegraph_url: 'https://sourcegraph.com', + sourcegraph_public_only: false, default_snippet_visibility: 'internal', restricted_visibility_levels: ['public'], default_artifacts_expire_in: '2 days', @@ -89,6 +96,9 @@ describe API::Settings, 'Settings' do expect(json_response['repository_storages']).to eq(['custom']) expect(json_response['plantuml_enabled']).to be_truthy expect(json_response['plantuml_url']).to eq('http://plantuml.example.com') + expect(json_response['sourcegraph_enabled']).to be_truthy + expect(json_response['sourcegraph_url']).to eq('https://sourcegraph.com') + expect(json_response['sourcegraph_public_only']).to eq(false) expect(json_response['default_snippet_visibility']).to eq('internal') expect(json_response['restricted_visibility_levels']).to eq(['public']) expect(json_response['default_artifacts_expire_in']).to eq('2 days') @@ -355,5 +365,14 @@ describe API::Settings, 'Settings' do expect(json_response['domain_blacklist']).to eq(['domain3.com', '*.domain4.com']) end end + + context "missing sourcegraph_url value when sourcegraph_enabled is true" do + it "returns a blank parameter error message" do + put api("/application/settings", admin), params: { sourcegraph_enabled: true } + + expect(response).to have_gitlab_http_status(400) + expect(json_response['error']).to eq('sourcegraph_url is missing') + end + end end end diff --git a/spec/views/admin/application_settings/integrations.html.haml_spec.rb b/spec/views/admin/application_settings/integrations.html.haml_spec.rb new file mode 100644 index 00000000000..392d43ef2d4 --- /dev/null +++ b/spec/views/admin/application_settings/integrations.html.haml_spec.rb @@ -0,0 +1,34 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'admin/application_settings/integrations.html.haml' do + let(:app_settings) { build(:application_setting) } + + describe 'sourcegraph integration' do + let(:sourcegraph_flag) { true } + + before do + assign(:application_setting, app_settings) + allow(Gitlab::Sourcegraph).to receive(:feature_available?).and_return(sourcegraph_flag) + end + + context 'when sourcegraph feature is enabled' do + it 'show the form' do + render + + expect(rendered).to have_field('application_setting_sourcegraph_enabled') + end + end + + context 'when sourcegraph feature is disabled' do + let(:sourcegraph_flag) { false } + + it 'show the form' do + render + + expect(rendered).not_to have_field('application_setting_sourcegraph_enabled') + end + end + end +end diff --git a/spec/views/profiles/preferences/show.html.haml_spec.rb b/spec/views/profiles/preferences/show.html.haml_spec.rb new file mode 100644 index 00000000000..52933c42621 --- /dev/null +++ b/spec/views/profiles/preferences/show.html.haml_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'spec_helper' + +describe 'profiles/preferences/show' do + using RSpec::Parameterized::TableSyntax + + let_it_be(:user) { build(:user) } + + before do + assign(:user, user) + allow(controller).to receive(:current_user).and_return(user) + end + + context 'sourcegraph' do + def have_sourcegraph_field(*args) + have_field('user_sourcegraph_enabled', *args) + end + + def have_integrations_section + have_css('.profile-settings-sidebar', { text: 'Integrations' }) + end + + before do + # Can't use stub_feature_flags because we use Feature.get to check if conditinally applied + Feature.get(:sourcegraph).enable sourcegraph_feature + stub_application_setting(sourcegraph_enabled: sourcegraph_enabled) + end + + context 'when not fully enabled' do + where(:feature, :admin_enabled) do + false | false + false | true + true | false + end + + with_them do + let(:sourcegraph_feature) { feature } + let(:sourcegraph_enabled) { admin_enabled } + + before do + render + end + + it 'does not display sourcegraph field' do + expect(rendered).not_to have_sourcegraph_field + end + + it 'does not display integrations settings' do + expect(rendered).not_to have_integrations_section + end + end + end + + context 'when fully enabled' do + let(:sourcegraph_feature) { true } + let(:sourcegraph_enabled) { true } + + before do + render + end + + it 'displays the sourcegraph field' do + expect(rendered).to have_sourcegraph_field + end + + it 'displays the integrations section' do + expect(rendered).to have_integrations_section + end + end + end +end diff --git a/spec/views/projects/pages_domains/show.html.haml_spec.rb b/spec/views/projects/pages_domains/show.html.haml_spec.rb index ba0544a49b0..331bfe63f28 100644 --- a/spec/views/projects/pages_domains/show.html.haml_spec.rb +++ b/spec/views/projects/pages_domains/show.html.haml_spec.rb @@ -30,39 +30,5 @@ describe 'projects/pages_domains/show' do expect(rendered).to have_content("GitLab is obtaining a Let's Encrypt SSL certificate for this domain. This process can take some time. Please try again later.") end end - - context 'when certificate is present' do - let(:domain) { create(:pages_domain, :letsencrypt, project: project) } - - it 'shows certificate info' do - render - - # test just a random part of cert represenations(X509v3 Subject Key Identifier:) - expect(rendered).to have_content("C6:5F:56:4B:10:69:AC:1D:33:D2:26:C9:B3:7A:D7:12:4D:3E:F7:90") - end - end - end - - context 'when auto_ssl is disabled' do - context 'when certificate is present' do - let(:domain) { create(:pages_domain, project: project) } - - it 'shows certificate info' do - render - - # test just a random part of cert represenations(X509v3 Subject Key Identifier:) - expect(rendered).to have_content("C6:5F:56:4B:10:69:AC:1D:33:D2:26:C9:B3:7A:D7:12:4D:3E:F7:90") - end - end - - context 'when certificate is absent' do - let(:domain) { create(:pages_domain, :without_certificate, :without_key, project: project) } - - it 'shows missing certificate' do - render - - expect(rendered).to have_content("missing") - end - end end end |