diff options
author | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-03 12:07:35 +0300 |
---|---|---|
committer | GitLab Bot <gitlab-bot@gitlab.com> | 2023-02-03 12:07:35 +0300 |
commit | a9c5941625be2416fbf3b514019886e8f9658416 (patch) | |
tree | 6c6bff089f4bf8ed2c1d5fe184a40975383f7022 /spec | |
parent | 18876223fd5dc347c26a65838b4e93fbd2702b9f (diff) |
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'spec')
18 files changed, 629 insertions, 15 deletions
diff --git a/spec/fixtures/blockquote_fence_after.md b/spec/fixtures/blockquote_fence_after.md index 18500d94c7a..c60daf49f3d 100644 --- a/spec/fixtures/blockquote_fence_after.md +++ b/spec/fixtures/blockquote_fence_after.md @@ -130,6 +130,35 @@ Double `>>>` inside HTML inside blockquote: > Quote +Blockquote inside an unordered list + +- Item one + + + > Foo and + > bar + + + - Sub item + + + > Foo + + +Blockquote inside an ordered list + +1. Item one + + + > Bar + + + 1. Sub item + + + > Foo + + Requires a leading blank line >>> Not a quote diff --git a/spec/fixtures/blockquote_fence_before.md b/spec/fixtures/blockquote_fence_before.md index 895bff73404..1f4b8196def 100644 --- a/spec/fixtures/blockquote_fence_before.md +++ b/spec/fixtures/blockquote_fence_before.md @@ -130,6 +130,35 @@ Quote Quote >>> +Blockquote inside an unordered list + +- Item one + + >>> + Foo and + bar + >>> + + - Sub item + + >>> + Foo + >>> + +Blockquote inside an ordered list + +1. Item one + + >>> + Bar + >>> + + 1. Sub item + + >>> + Foo + >>> + Requires a leading blank line >>> Not a quote diff --git a/spec/fixtures/emails/html_table_and_blockquote.eml b/spec/fixtures/emails/html_table_and_blockquote.eml new file mode 100644 index 00000000000..554d17def50 --- /dev/null +++ b/spec/fixtures/emails/html_table_and_blockquote.eml @@ -0,0 +1,41 @@ +MIME-Version: 1.0 +Received: by 10.25.161.144 with HTTP; Tue, 7 Oct 2014 22:17:17 -0700 (PDT) +X-Originating-IP: [117.207.85.84] +In-Reply-To: <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail> +References: <topic/35@discourse.techapj.com> + <5434c8b52bb3a_623ff09fec70f049749@discourse-app.mail> +Date: Wed, 8 Oct 2014 10:47:17 +0530 +Delivered-To: arpit@techapj.com +Message-ID: <CAOJeqne=SJ_LwN4sb-0Y95ejc2OpreVhdmcPn0TnmwSvTCYzzQ@mail.gmail.com> +Subject: Re: [Discourse] [Meta] Welcome to techAPJ's Discourse! +From: Arpit Jalan <arpit@techapj.com> +To: Discourse <mail+e1c7f2a380e33840aeb654f075490bad@arpitjalan.com> +Content-Type: multipart/related; boundary=001a114119d8f4e46e0504e26d5b + +--001a114119d8f4e46e0504e26d5b +Content-Type: text/html; charset=UTF-8 +Content-Transfer-Encoding: quoted-printable + +<table> + <tr> + <th>Company</th> + <th>Contact</th> + <th>Country</th> + </tr> + <tr> + <td>Alfreds Futterkiste</td> + <td>Maria Anders</td> + <td>Germany</td> + </tr> + <tr> + <td>Centro comercial Moctezuma</td> + <td>Francisco Chang</td> + <td>Mexico</td> + </tr> +</table> + +<blockquote cite="https://www.huxley.net/bnw/four.html"> + <p>Words can be like X-rays, if you use them properly—they’ll go through anything. You read and you’re pierced.</p> +</blockquote> + +--001a114119d8f4e46e0504e26d5b-- diff --git a/spec/fixtures/mail_room/encrypted_secrets/incoming_email.yaml.enc b/spec/fixtures/mail_room/encrypted_secrets/incoming_email.yaml.enc new file mode 100644 index 00000000000..c11722e6847 --- /dev/null +++ b/spec/fixtures/mail_room/encrypted_secrets/incoming_email.yaml.enc @@ -0,0 +1 @@ +v7dkZ/3zpOBsA6XhOq99ai5S4czZlkdLUmNcH8AYOw56b7PgEMmtLHu39Fcyd4ZvERJNMIqyLuCwooqvJKfUeFRi9HpY0Q==--GldddWssSV3R/Ood--1XlQ63E4XCVqcfZVAd+NGQ==
\ No newline at end of file diff --git a/spec/fixtures/mail_room/encrypted_secrets/service_desk_email.yaml.enc b/spec/fixtures/mail_room/encrypted_secrets/service_desk_email.yaml.enc new file mode 100644 index 00000000000..bad1f2bbce1 --- /dev/null +++ b/spec/fixtures/mail_room/encrypted_secrets/service_desk_email.yaml.enc @@ -0,0 +1 @@ +nWE1RNp/i+RzboK4SqbQBI52cFP14G3hduqIOdus2Ffgul8n0vL/bKHMHaiCttq2hzGnzw5zcMGUWxJu3RkAhR0jnLAgbpBrYsxKTH72cqkJfw==--5FtWCIPwB8DldWkY--FLjDkVAsCzDM9VY1x7yifg==
\ No newline at end of file diff --git a/spec/fixtures/mail_room/secrets.yml.erb b/spec/fixtures/mail_room/secrets.yml.erb new file mode 100644 index 00000000000..fce7ff3180e --- /dev/null +++ b/spec/fixtures/mail_room/secrets.yml.erb @@ -0,0 +1,11 @@ +--- +production: + an_unread_key: 'this key will not be in the secrets' +shared: + a_shared_key: 'this key is shared' + an_overriden_shared_key: 'this key is overwritten by merge' +test: + an_environment_specific_key: 'test environment value' + an_overriden_shared_key: 'the merge overwrote this key' + erb_env_key: <%= ENV['KEY'] %> + encrypted_settings_key_base: <%= '0123456789abcdef' * 8 %> diff --git a/spec/frontend/artifacts/components/app_spec.js b/spec/frontend/artifacts/components/app_spec.js new file mode 100644 index 00000000000..931c4703e95 --- /dev/null +++ b/spec/frontend/artifacts/components/app_spec.js @@ -0,0 +1,109 @@ +import { GlSkeletonLoader } from '@gitlab/ui'; +import VueApollo from 'vue-apollo'; +import Vue from 'vue'; +import { numberToHumanSize } from '~/lib/utils/number_utils'; +import ArtifactsApp from '~/artifacts/components/app.vue'; +import JobArtifactsTable from '~/artifacts/components/job_artifacts_table.vue'; +import getBuildArtifactsSizeQuery from '~/artifacts/graphql/queries/get_build_artifacts_size.query.graphql'; +import { shallowMountExtended } from 'helpers/vue_test_utils_helper'; +import createMockApollo from 'helpers/mock_apollo_helper'; +import waitForPromises from 'helpers/wait_for_promises'; +import { PAGE_TITLE, TOTAL_ARTIFACTS_SIZE, SIZE_UNKNOWN } from '~/artifacts/constants'; + +const TEST_BUILD_ARTIFACTS_SIZE = 1024; +const TEST_PROJECT_PATH = 'project/path'; +const TEST_PROJECT_ID = 'gid://gitlab/Project/22'; + +const createBuildArtifactsSizeResponse = (buildArtifactsSize) => ({ + data: { + project: { + __typename: 'Project', + id: TEST_PROJECT_ID, + statistics: { + __typename: 'ProjectStatistics', + buildArtifactsSize, + }, + }, + }, +}); + +Vue.use(VueApollo); + +describe('ArtifactsApp component', () => { + let wrapper; + let apolloProvider; + let getBuildArtifactsSizeSpy; + + const findTitle = () => wrapper.findByTestId('artifacts-page-title'); + const findBuildArtifactsSize = () => wrapper.findByTestId('build-artifacts-size'); + const findJobArtifactsTable = () => wrapper.findComponent(JobArtifactsTable); + const findSkeletonLoader = () => wrapper.findComponent(GlSkeletonLoader); + + const createComponent = () => { + wrapper = shallowMountExtended(ArtifactsApp, { + provide: { projectPath: 'project/path' }, + apolloProvider, + }); + }; + + beforeEach(() => { + getBuildArtifactsSizeSpy = jest.fn(); + + apolloProvider = createMockApollo([[getBuildArtifactsSizeQuery, getBuildArtifactsSizeSpy]]); + }); + + describe('when loading', () => { + beforeEach(() => { + // Promise that never resolves so it's always loading + getBuildArtifactsSizeSpy.mockReturnValue(new Promise(() => {})); + + createComponent(); + }); + + it('shows the page title', () => { + expect(findTitle().text()).toBe(PAGE_TITLE); + }); + + it('shows a skeleton while loading the artifacts size', () => { + expect(findSkeletonLoader().exists()).toBe(true); + }); + + it('shows the job artifacts table', () => { + expect(findJobArtifactsTable().exists()).toBe(true); + }); + + it('does not show message', () => { + expect(findBuildArtifactsSize().text()).toBe(''); + }); + + it('calls apollo query', () => { + expect(getBuildArtifactsSizeSpy).toHaveBeenCalledWith({ projectPath: TEST_PROJECT_PATH }); + }); + }); + + describe.each` + buildArtifactsSize | expectedText + ${TEST_BUILD_ARTIFACTS_SIZE} | ${numberToHumanSize(TEST_BUILD_ARTIFACTS_SIZE)} + ${null} | ${SIZE_UNKNOWN} + `('when buildArtifactsSize is $buildArtifactsSize', ({ buildArtifactsSize, expectedText }) => { + beforeEach(async () => { + getBuildArtifactsSizeSpy.mockResolvedValue( + createBuildArtifactsSizeResponse(buildArtifactsSize), + ); + + createComponent(); + + await waitForPromises(); + }); + + it('hides loader', () => { + expect(findSkeletonLoader().exists()).toBe(false); + }); + + it('shows the size', () => { + expect(findBuildArtifactsSize().text()).toMatchInterpolatedText( + `${TOTAL_ARTIFACTS_SIZE} ${expectedText}`, + ); + }); + }); +}); diff --git a/spec/frontend/diffs/components/tree_list_spec.js b/spec/frontend/diffs/components/tree_list_spec.js index ca7de8fd751..1656eaf8ba0 100644 --- a/spec/frontend/diffs/components/tree_list_spec.js +++ b/spec/frontend/diffs/components/tree_list_spec.js @@ -49,6 +49,7 @@ describe('Diffs tree list component', () => { tempFile: true, type: 'blob', parentPath: 'app', + tree: [], }, 'test.rb': { addedLines: 0, @@ -62,6 +63,7 @@ describe('Diffs tree list component', () => { tempFile: true, type: 'blob', parentPath: 'app', + tree: [], }, app: { key: 'app', diff --git a/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js b/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js index 4764f3607bc..60edab8766a 100644 --- a/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js +++ b/spec/frontend/sidebar/components/assignees/assignee_avatar_link_spec.js @@ -1,7 +1,7 @@ import { shallowMount } from '@vue/test-utils'; import { GlLink } from '@gitlab/ui'; import { TEST_HOST } from 'helpers/test_constants'; -import { TYPE_USER } from '~/graphql_shared/constants'; +import { TYPENAME_USER } from '~/graphql_shared/constants'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import AssigneeAvatar from '~/sidebar/components/assignees/assignee_avatar.vue'; import AssigneeAvatarLink from '~/sidebar/components/assignees/assignee_avatar_link.vue'; @@ -133,7 +133,7 @@ describe('AssigneeAvatarLink component', () => { createComponent({ tooltipHasName: true, issuableType: 'issue', - user: { ...userDataMock(), id: convertToGraphQLId(TYPE_USER, userId) }, + user: { ...userDataMock(), id: convertToGraphQLId(TYPENAME_USER, userId) }, }); expect(findUserLink().attributes('data-user-id')).toBe(String(userId)); diff --git a/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js b/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js index 452240dd81b..715f66d305a 100644 --- a/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js +++ b/spec/frontend/sidebar/components/time_tracking/create_timelog_form_spec.js @@ -7,7 +7,7 @@ import waitForPromises from 'helpers/wait_for_promises'; import { convertToGraphQLId } from '~/graphql_shared/utils'; import CreateTimelogForm from '~/sidebar/components/time_tracking/create_timelog_form.vue'; import createTimelogMutation from '~/sidebar/queries/create_timelog.mutation.graphql'; -import { TYPENAME_ISSUE, TYPE_MERGE_REQUEST } from '~/graphql_shared/constants'; +import { TYPENAME_ISSUE, TYPENAME_MERGE_REQUEST } from '~/graphql_shared/constants'; const mockMutationErrorMessage = 'Example error message'; @@ -158,7 +158,7 @@ describe('Create Timelog Form', () => { it.each` issuableType | typeConstant ${'issue'} | ${TYPENAME_ISSUE} - ${'merge_request'} | ${TYPE_MERGE_REQUEST} + ${'merge_request'} | ${TYPENAME_MERGE_REQUEST} `( 'calls the mutation with all the fields when the the form is submitted and issuable type is $issuableType', async ({ issuableType, typeConstant }) => { diff --git a/spec/frontend/vue_shared/components/file_row_spec.js b/spec/frontend/vue_shared/components/file_row_spec.js index c3a71d7fda3..b70d4565f56 100644 --- a/spec/frontend/vue_shared/components/file_row_spec.js +++ b/spec/frontend/vue_shared/components/file_row_spec.js @@ -100,15 +100,6 @@ describe('File row component', () => { }); }); - it('indents row based on level', () => { - createComponent({ - file: file('t4'), - level: 2, - }); - - expect(wrapper.find('.file-row-name').element.style.marginLeft).toBe('16px'); - }); - it('renders header for file', () => { createComponent({ file: { diff --git a/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb b/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb index a0846f2b388..575d4879f84 100644 --- a/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb +++ b/spec/lib/banzai/filter/blockquote_fence_filter_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' RSpec.describe Banzai::Filter::BlockquoteFenceFilter, feature_category: :team_planning do include FilterSpecHelper - it 'converts blockquote fences to blockquote lines' do + it 'converts blockquote fences to blockquote lines', :unlimited_max_formatted_output_length do content = File.read(Rails.root.join('spec/fixtures/blockquote_fence_before.md')) expected = File.read(Rails.root.join('spec/fixtures/blockquote_fence_after.md')) diff --git a/spec/lib/gitlab/email/reply_parser_spec.rb b/spec/lib/gitlab/email/reply_parser_spec.rb index c61d941406b..10ffb420508 100644 --- a/spec/lib/gitlab/email/reply_parser_spec.rb +++ b/spec/lib/gitlab/email/reply_parser_spec.rb @@ -63,6 +63,18 @@ RSpec.describe Gitlab::Email::ReplyParser do ) end + it "properly renders html-only email with table and blockquote" do + expect(test_parse_body(fixture_file("emails/html_table_and_blockquote.eml"))) + .to eq( + <<-BODY.strip_heredoc.chomp + Company Contact Country + Alfreds Futterkiste Maria Anders Germany + Centro comercial Moctezuma Francisco Chang Mexico + Words can be like X-rays, if you use them properly—they’ll go through anything. You read and you’re pierced. + BODY + ) + end + it "supports a Dutch reply" do expect(test_parse_body(fixture_file("emails/dutch.eml"))).to eq("Dit is een antwoord in het Nederlands.") end diff --git a/spec/lib/gitlab/mail_room/mail_room_spec.rb b/spec/lib/gitlab/mail_room/mail_room_spec.rb index 0c2c9b89005..7259b5e2484 100644 --- a/spec/lib/gitlab/mail_room/mail_room_spec.rb +++ b/spec/lib/gitlab/mail_room/mail_room_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Gitlab::MailRoom do +RSpec.describe Gitlab::MailRoom, feature_category: :build do let(:default_port) { 143 } let(:log_path) { Rails.root.join('log', 'mail_room_json.log').to_s } @@ -328,4 +328,123 @@ RSpec.describe Gitlab::MailRoom do end end end + + describe 'mailroom encrypted configuration' do + context "when parsing secrets.yml" do + let(:application_secrets_file) { Rails.root.join('spec/fixtures/mail_room/secrets.yml.erb').to_s } + let(:encrypted_settings_key_base) { '0123456789abcdef' * 8 } + + before do + allow(described_class).to receive(:application_secrets_file).and_return(application_secrets_file) + stub_env('KEY', 'an environment variable value') + described_class.instance_variable_set(:@application_secrets, nil) + end + + after do + described_class.instance_variable_set(:@application_secrets, nil) + end + + it 'reads in the secrets.yml file as erb and merges shared and test environments' do + application_secrets = described_class.send(:application_secrets) + + expect(application_secrets).to match(a_hash_including( + a_shared_key: 'this key is shared', + an_overriden_shared_key: 'the merge overwrote this key', + an_environment_specific_key: 'test environment value', + erb_env_key: 'an environment variable value', + encrypted_settings_key_base: encrypted_settings_key_base + )) + + expect(application_secrets[:an_unread_key]).to be_nil + end + end + + context "when parsing gitlab.yml" do + let(:plain_configs) { configs } + let(:shared_path_config) do + { shared: { path: '/this/is/my/shared_path' } }.merge(configs) + end + + let(:encrypted_settings_config) do + { + shared: { path: '/this/is/my/shared_path' }, + encrypted_settings: { path: '/this/is/my_custom_encrypted_path' } + }.merge(configs) + end + + let(:encrypted_file_config) do + configs.deep_merge({ + incoming_email: { encrypted_secret_file: '/custom_incoming_secret.yaml.enc' }, + service_desk_email: { encrypted_secret_file: '/custom_service_desk_secret.yaml.enc' } + }) + end + + it 'returns default encrypted_secret_file path' do + allow(described_class).to receive(:load_yaml).and_return(plain_configs) + + expect(described_class.send(:encrypted_secret_file, :incoming_email)) + .to end_with('shared/encrypted_settings/incoming_email.yaml.enc') + + expect(described_class.send(:encrypted_secret_file, :service_desk_email)) + .to end_with('shared/encrypted_settings/service_desk_email.yaml.enc') + end + + it 'returns encrypted_secret_file relative to custom shared path' do + allow(described_class).to receive(:load_yaml).and_return(shared_path_config) + + expect(described_class.send(:encrypted_secret_file, :incoming_email)) + .to eq('/this/is/my/shared_path/encrypted_settings/incoming_email.yaml.enc') + + expect(described_class.send(:encrypted_secret_file, :service_desk_email)) + .to eq('/this/is/my/shared_path/encrypted_settings/service_desk_email.yaml.enc') + end + + it 'returns custom encrypted_secret_file' do + allow(described_class).to receive(:load_yaml).and_return(encrypted_file_config) + + expect(described_class.send(:encrypted_secret_file, :incoming_email)) + .to eq('/custom_incoming_secret.yaml.enc') + + expect(described_class.send(:encrypted_secret_file, :service_desk_email)) + .to eq('/custom_service_desk_secret.yaml.enc') + end + end + + context 'when using encrypted secrets' do + let(:mail_room_template) { ERB.new(File.read(Rails.root.join("./config/mail_room.yml"))).result } + let(:mail_room_yml) { YAML.safe_load(mail_room_template, permitted_classes: [Symbol]) } + let(:application_secrets) { { encrypted_settings_key_base: '0123456789abcdef' * 8 } } # gitleaks:allow + let(:configs) do + { + encrypted_settings: { path: 'spec/fixtures/mail_room/encrypted_secrets' } + }.merge({ + incoming_email: incoming_email_config, + service_desk_email: service_desk_email_config + }) + end + + before do + allow(described_class).to receive(:application_secrets).and_return(application_secrets) + end + + it 'renders the encrypted secrets into the configuration correctly' do + expect(mail_room_yml[:mailboxes]).to be_an(Array) + expect(mail_room_yml[:mailboxes].length).to eq(2) + + expect(mail_room_yml[:mailboxes][0]).to match( + a_hash_including( + password: 'abc123', + email: 'incoming-test-account@gitlab.com' + ) + ) + + expect(mail_room_yml[:mailboxes][1]).to match( + a_hash_including( + password: '123abc', + email: 'service-desk-test-account@gitlab.example.com' + ) + ) + end + end + end end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/incoming_email_encrypted_secrets_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/incoming_email_encrypted_secrets_enabled_metric_spec.rb new file mode 100644 index 00000000000..ed35b2c8cde --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/incoming_email_encrypted_secrets_enabled_metric_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::IncomingEmailEncryptedSecretsEnabledMetric, +feature_category: :service_ping do + it_behaves_like 'a correct instrumented metric value', { time_frame: 'none', data_source: 'ruby' } do + let(:expected_value) { ::Gitlab::IncomingEmail.encrypted_secrets.active? } + end +end diff --git a/spec/lib/gitlab/usage/metrics/instrumentations/service_desk_email_encrypted_secrets_enabled_metric_spec.rb b/spec/lib/gitlab/usage/metrics/instrumentations/service_desk_email_encrypted_secrets_enabled_metric_spec.rb new file mode 100644 index 00000000000..d602eae3159 --- /dev/null +++ b/spec/lib/gitlab/usage/metrics/instrumentations/service_desk_email_encrypted_secrets_enabled_metric_spec.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::ServiceDeskEmailEncryptedSecretsEnabledMetric, +feature_category: :service_ping do + it_behaves_like 'a correct instrumented metric value', { time_frame: 'none', data_source: 'ruby' } do + let(:expected_value) { ::Gitlab::ServiceDeskEmail.encrypted_secrets.active? } + end +end diff --git a/spec/tasks/gitlab/incoming_email_rake_spec.rb b/spec/tasks/gitlab/incoming_email_rake_spec.rb new file mode 100644 index 00000000000..3e1cc663ddb --- /dev/null +++ b/spec/tasks/gitlab/incoming_email_rake_spec.rb @@ -0,0 +1,122 @@ +# frozen_string_literal: true + +require 'rake_helper' + +RSpec.describe 'gitlab:incoming_email:secret rake tasks', :silence_stdout, feature_category: :build do + let(:encrypted_secret_file_dir) { Pathname.new(Dir.mktmpdir) } + let(:encrypted_secret_file) { encrypted_secret_file_dir.join('incoming_email.yaml.enc') } + + before do + Rake.application.rake_require 'tasks/gitlab/incoming_email' + stub_env('EDITOR', 'cat') + stub_warn_user_is_not_gitlab + allow(Gitlab.config.incoming_email).to receive(:encrypted_secret_file).and_return(encrypted_secret_file) + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(SecureRandom.hex(64)) + end + + after do + FileUtils.rm_rf(Rails.root.join('tmp/tests/incoming_email_enc')) + end + + describe ':show' do + it 'displays error when file does not exist' do + expect { run_rake_task('gitlab:incoming_email:secret:show') }.to \ + output(/File .* does not exist. Use `gitlab-rake gitlab:incoming_email:secret:edit` to change that./).to_stdout + end + + it 'displays error when key does not exist' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil) + expect { run_rake_task('gitlab:incoming_email:secret:show') }.to \ + output(/Missing encryption key encrypted_settings_key_base./).to_stderr + end + + it 'displays error when key is changed' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(SecureRandom.hex(64)) + expect { run_rake_task('gitlab:incoming_email:secret:show') }.to \ + output(/Couldn't decrypt .* Perhaps you passed the wrong key?/).to_stderr + end + + it 'outputs the unencrypted content when present' do + encrypted = Settings.encrypted(encrypted_secret_file) + encrypted.write('somevalue') + expect { run_rake_task('gitlab:incoming_email:secret:show') }.to output(/somevalue/).to_stdout + end + end + + describe 'edit' do + it 'creates encrypted file' do + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to output(/File encrypted and saved./).to_stdout + expect(File.exist?(encrypted_secret_file)).to be true + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/password: '123'/) + end + + it 'displays error when key does not exist' do + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil) + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to \ + output(/Missing encryption key encrypted_settings_key_base./).to_stderr + end + + it 'displays error when key is changed' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(SecureRandom.hex(64)) + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to \ + output(/Couldn't decrypt .* Perhaps you passed the wrong key?/).to_stderr + end + + it 'displays error when write directory does not exist' do + FileUtils.rm_rf(encrypted_secret_file_dir) + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to \ + output(/Directory .* does not exist./).to_stderr + end + + it 'shows a warning when content is invalid' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to \ + output(/WARNING: Content was not a valid INCOMING_EMAIL secret yml file/).to_stdout + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/somevalue/) + end + + it 'displays error when $EDITOR is not set' do + stub_env('EDITOR', nil) + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to \ + output(/No \$EDITOR specified to open file. Please provide one when running the command/).to_stderr + end + end + + describe 'write' do + before do + allow($stdin).to receive(:tty?).and_return(false) + allow($stdin).to receive(:read).and_return('username: foo') + end + + it 'creates encrypted file from stdin' do + expect { run_rake_task('gitlab:incoming_email:secret:write') }.to output(/File encrypted and saved./).to_stdout + expect(File.exist?(encrypted_secret_file)).to be true + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/username: foo/) + end + + it 'displays error when key does not exist' do + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil) + expect { run_rake_task('gitlab:incoming_email:secret:write') }.to \ + output(/Missing encryption key encrypted_settings_key_base./).to_stderr + end + + it 'displays error when write directory does not exist' do + FileUtils.rm_rf(encrypted_secret_file_dir) + expect { run_rake_task('gitlab:incoming_email:secret:write') }.to output(/Directory .* does not exist./).to_stderr + end + + it 'shows a warning when content is invalid' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + expect { run_rake_task('gitlab:incoming_email:secret:edit') }.to \ + output(/WARNING: Content was not a valid INCOMING_EMAIL secret yml file/).to_stdout + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/somevalue/) + end + end +end diff --git a/spec/tasks/gitlab/service_desk_email_rake_spec.rb b/spec/tasks/gitlab/service_desk_email_rake_spec.rb new file mode 100644 index 00000000000..6a1a7473f4a --- /dev/null +++ b/spec/tasks/gitlab/service_desk_email_rake_spec.rb @@ -0,0 +1,127 @@ +# frozen_string_literal: true + +require 'rake_helper' + +RSpec.describe 'gitlab:service_desk_email:secret rake tasks', :silence_stdout, feature_category: :build do + let(:encrypted_secret_file_dir) { Pathname.new(Dir.mktmpdir) } + let(:encrypted_secret_file) { encrypted_secret_file_dir.join('service_desk_email.yaml.enc') } + + before do + Rake.application.rake_require 'tasks/gitlab/service_desk_email' + stub_env('EDITOR', 'cat') + stub_warn_user_is_not_gitlab + FileUtils.mkdir_p('tmp/tests/service_desk_email_enc/') + allow(Gitlab.config.service_desk_email).to receive(:encrypted_secret_file).and_return(encrypted_secret_file) + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(SecureRandom.hex(64)) + end + + after do + FileUtils.rm_rf(Rails.root.join('tmp/tests/service_desk_email_enc')) + end + + describe ':show' do + it 'displays error when file does not exist' do + expect { run_rake_task('gitlab:service_desk_email:secret:show') }.to \ + output(/File .* does not exist. Use `gitlab-rake gitlab:service_desk_email:secret:edit` to change that./) \ + .to_stdout + end + + it 'displays error when key does not exist' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil) + expect { run_rake_task('gitlab:service_desk_email:secret:show') }.to \ + output(/Missing encryption key encrypted_settings_key_base./).to_stderr + end + + it 'displays error when key is changed' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(SecureRandom.hex(64)) + expect { run_rake_task('gitlab:service_desk_email:secret:show') }.to \ + output(/Couldn't decrypt .* Perhaps you passed the wrong key?/).to_stderr + end + + it 'outputs the unencrypted content when present' do + encrypted = Settings.encrypted(encrypted_secret_file) + encrypted.write('somevalue') + expect { run_rake_task('gitlab:service_desk_email:secret:show') }.to output(/somevalue/).to_stdout + end + end + + describe 'edit' do + it 'creates encrypted file' do + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/File encrypted and saved./).to_stdout + expect(File.exist?(encrypted_secret_file)).to be true + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/password: '123'/) + end + + it 'displays error when key does not exist' do + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil) + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/Missing encryption key encrypted_settings_key_base./).to_stderr + end + + it 'displays error when key is changed' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(SecureRandom.hex(64)) + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/Couldn't decrypt .* Perhaps you passed the wrong key?/).to_stderr + end + + it 'displays error when write directory does not exist' do + FileUtils.rm_rf(encrypted_secret_file_dir) + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/Directory .* does not exist./).to_stderr + end + + it 'shows a warning when content is invalid' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/WARNING: Content was not a valid SERVICE_DESK_EMAIL secret yml file/).to_stdout + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/somevalue/) + end + + it 'displays error when $EDITOR is not set' do + stub_env('EDITOR', nil) + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/No \$EDITOR specified to open file. Please provide one when running the command/).to_stderr + end + end + + describe 'write' do + before do + allow($stdin).to receive(:tty?).and_return(false) + allow($stdin).to receive(:read).and_return('username: foo') + end + + it 'creates encrypted file from stdin' do + expect { run_rake_task('gitlab:service_desk_email:secret:write') }.to \ + output(/File encrypted and saved./).to_stdout + expect(File.exist?(encrypted_secret_file)).to be true + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/username: foo/) + end + + it 'displays error when key does not exist' do + allow(Gitlab::Application.secrets).to receive(:encrypted_settings_key_base).and_return(nil) + expect { run_rake_task('gitlab:service_desk_email:secret:write') }.to \ + output(/Missing encryption key encrypted_settings_key_base./).to_stderr + end + + it 'displays error when write directory does not exist' do + FileUtils.rm_rf(encrypted_secret_file_dir) + expect { run_rake_task('gitlab:service_desk_email:secret:write') }.to \ + output(/Directory .* does not exist./).to_stderr + end + + it 'shows a warning when content is invalid' do + Settings.encrypted(encrypted_secret_file).write('somevalue') + expect { run_rake_task('gitlab:service_desk_email:secret:edit') }.to \ + output(/WARNING: Content was not a valid SERVICE_DESK_EMAIL secret yml file/).to_stdout + value = Settings.encrypted(encrypted_secret_file) + expect(value.read).to match(/somevalue/) + end + end +end |