diff options
Diffstat (limited to 'spec')
-rw-r--r-- | spec/factories/ci/secure_files.rb | 10 | ||||
-rw-r--r-- | spec/fixtures/ci_secure_files/upload-keystore.jks | bin | 0 -> 2760 bytes | |||
-rw-r--r-- | spec/frontend/content_editor/extensions/code_spec.js | 8 | ||||
-rw-r--r-- | spec/frontend/content_editor/extensions/frontmatter_spec.js | 25 | ||||
-rw-r--r-- | spec/frontend/content_editor/services/markdown_serializer_spec.js | 11 | ||||
-rw-r--r-- | spec/lib/banzai/filter/syntax_highlight_filter_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/import_export/all_models.yml | 1 | ||||
-rw-r--r-- | spec/models/ci/secure_file_spec.rb | 55 | ||||
-rw-r--r-- | spec/support/helpers/stub_object_storage.rb | 6 | ||||
-rw-r--r-- | spec/uploaders/ci/secure_file_uploader_spec.rb | 72 |
10 files changed, 192 insertions, 4 deletions
diff --git a/spec/factories/ci/secure_files.rb b/spec/factories/ci/secure_files.rb new file mode 100644 index 00000000000..9198ea61d14 --- /dev/null +++ b/spec/factories/ci/secure_files.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +FactoryBot.define do + factory :ci_secure_file, class: 'Ci::SecureFile' do + name { 'filename' } + file { fixture_file_upload('spec/fixtures/ci_secure_files/upload-keystore.jks', 'application/octet-stream') } + checksum { 'foo1234' } + project + end +end diff --git a/spec/fixtures/ci_secure_files/upload-keystore.jks b/spec/fixtures/ci_secure_files/upload-keystore.jks Binary files differnew file mode 100644 index 00000000000..715adad4a89 --- /dev/null +++ b/spec/fixtures/ci_secure_files/upload-keystore.jks diff --git a/spec/frontend/content_editor/extensions/code_spec.js b/spec/frontend/content_editor/extensions/code_spec.js new file mode 100644 index 00000000000..0a54ac6a96b --- /dev/null +++ b/spec/frontend/content_editor/extensions/code_spec.js @@ -0,0 +1,8 @@ +import Code from '~/content_editor/extensions/code'; +import { EXTENSION_PRIORITY_LOWER } from '~/content_editor/constants'; + +describe('content_editor/extensions/code', () => { + it('has a lower loading priority', () => { + expect(Code.config.priority).toBe(EXTENSION_PRIORITY_LOWER); + }); +}); diff --git a/spec/frontend/content_editor/extensions/frontmatter_spec.js b/spec/frontend/content_editor/extensions/frontmatter_spec.js index 517f6947b9a..a8cbad6ef81 100644 --- a/spec/frontend/content_editor/extensions/frontmatter_spec.js +++ b/spec/frontend/content_editor/extensions/frontmatter_spec.js @@ -1,30 +1,47 @@ import Frontmatter from '~/content_editor/extensions/frontmatter'; +import CodeBlockHighlight from '~/content_editor/extensions/code_block_highlight'; import { createTestEditor, createDocBuilder, triggerNodeInputRule } from '../test_utils'; describe('content_editor/extensions/frontmatter', () => { let tiptapEditor; let doc; - let p; + let frontmatter; + let codeBlock; beforeEach(() => { - tiptapEditor = createTestEditor({ extensions: [Frontmatter] }); + tiptapEditor = createTestEditor({ extensions: [Frontmatter, CodeBlockHighlight] }); ({ - builders: { doc, p }, + builders: { doc, codeBlock, frontmatter }, } = createDocBuilder({ tiptapEditor, names: { frontmatter: { nodeType: Frontmatter.name }, + codeBlock: { nodeType: CodeBlockHighlight.name }, }, })); }); it('does not insert a frontmatter block when executing code block input rule', () => { - const expectedDoc = doc(p('')); + const expectedDoc = doc(codeBlock('')); const inputRuleText = '``` '; triggerNodeInputRule({ tiptapEditor, inputRuleText }); expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON()); }); + + it.each` + command | result | resultDesc + ${'toggleCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'} + ${'setCodeBlock'} | ${() => doc(codeBlock(''))} | ${'code block element'} + ${'setFrontmatter'} | ${() => doc(frontmatter(''))} | ${'frontmatter element'} + ${'toggleFrontmatter'} | ${() => doc(frontmatter(''))} | ${'frontmatter element'} + `('executing $command should generate a document with a $resultDesc', ({ command, result }) => { + const expectedDoc = result(); + + tiptapEditor.commands[command](); + + expect(tiptapEditor.getJSON()).toEqual(expectedDoc.toJSON()); + }); }); diff --git a/spec/frontend/content_editor/services/markdown_serializer_spec.js b/spec/frontend/content_editor/services/markdown_serializer_spec.js index 97f6d8f6334..68ccb01ddd1 100644 --- a/spec/frontend/content_editor/services/markdown_serializer_spec.js +++ b/spec/frontend/content_editor/services/markdown_serializer_spec.js @@ -164,6 +164,17 @@ describe('markdownSerializer', () => { expect(serialize(paragraph(italic('italics')))).toBe('_italics_'); }); + it('correctly serializes code blocks wrapped by italics and bold marks', () => { + const text = 'code block'; + + expect(serialize(paragraph(italic(code(text))))).toBe(`_\`${text}\`_`); + expect(serialize(paragraph(code(italic(text))))).toBe(`_\`${text}\`_`); + expect(serialize(paragraph(bold(code(text))))).toBe(`**\`${text}\`**`); + expect(serialize(paragraph(code(bold(text))))).toBe(`**\`${text}\`**`); + expect(serialize(paragraph(strike(code(text))))).toBe(`~~\`${text}\`~~`); + expect(serialize(paragraph(code(strike(text))))).toBe(`~~\`${text}\`~~`); + }); + it('correctly serializes inline diff', () => { expect( serialize( diff --git a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb index 83df8328791..aee4bd93207 100644 --- a/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb +++ b/spec/lib/banzai/filter/syntax_highlight_filter_spec.rb @@ -37,6 +37,14 @@ RSpec.describe Banzai::Filter::SyntaxHighlightFilter do end end + context "when <pre> contains multiple <code> tags" do + it "ignores the block" do + result = filter('<pre><code>one</code> and <code>two</code></pre>') + + expect(result.to_html).to eq('<pre><code>one</code> and <code>two</code></pre>') + end + end + context "when a valid language is specified" do it "highlights as that language" do result = filter('<pre lang="ruby"><code>def fun end</code></pre>') diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml index fb7eb4668b9..625e94e3d77 100644 --- a/spec/lib/gitlab/import_export/all_models.yml +++ b/spec/lib/gitlab/import_export/all_models.yml @@ -602,6 +602,7 @@ project: - bulk_import_exports - ci_project_mirror - sync_events +- secure_files award_emoji: - awardable - user diff --git a/spec/models/ci/secure_file_spec.rb b/spec/models/ci/secure_file_spec.rb new file mode 100644 index 00000000000..ae57b63e7a4 --- /dev/null +++ b/spec/models/ci/secure_file_spec.rb @@ -0,0 +1,55 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::SecureFile do + let(:sample_file) { fixture_file('ci_secure_files/upload-keystore.jks') } + + subject { create(:ci_secure_file) } + + before do + stub_ci_secure_file_object_storage + end + + it { is_expected.to be_a FileStoreMounter } + + it { is_expected.to belong_to(:project).required } + + it_behaves_like 'having unique enum values' + + describe 'validations' do + it { is_expected.to validate_presence_of(:checksum) } + it { is_expected.to validate_presence_of(:file_store) } + it { is_expected.to validate_presence_of(:name) } + it { is_expected.to validate_presence_of(:permissions) } + it { is_expected.to validate_presence_of(:project_id) } + end + + describe '#permissions' do + it 'defaults to read_only file permssions' do + expect(subject.permissions).to eq('read_only') + end + end + + describe '#checksum' do + it 'computes SHA256 checksum on the file before encrypted' do + subject.file = CarrierWaveStringFile.new(sample_file) + subject.save! + expect(subject.checksum).to eq(Digest::SHA256.hexdigest(sample_file)) + end + end + + describe '#checksum_algorithm' do + it 'returns the configured checksum_algorithm' do + expect(subject.checksum_algorithm).to eq('sha256') + end + end + + describe '#file' do + it 'returns the saved file' do + subject.file = CarrierWaveStringFile.new(sample_file) + subject.save! + expect(Base64.encode64(subject.file.read)).to eq(Base64.encode64(sample_file)) + end + end +end diff --git a/spec/support/helpers/stub_object_storage.rb b/spec/support/helpers/stub_object_storage.rb index 5e86b08aa45..d49a14f7f5b 100644 --- a/spec/support/helpers/stub_object_storage.rb +++ b/spec/support/helpers/stub_object_storage.rb @@ -91,6 +91,12 @@ module StubObjectStorage **params) end + def stub_ci_secure_file_object_storage(**params) + stub_object_storage_uploader(config: Gitlab.config.ci_secure_files.object_store, + uploader: Ci::SecureFileUploader, + **params) + end + def stub_terraform_state_object_storage(**params) stub_object_storage_uploader(config: Gitlab.config.terraform_state.object_store, uploader: Terraform::StateUploader, diff --git a/spec/uploaders/ci/secure_file_uploader_spec.rb b/spec/uploaders/ci/secure_file_uploader_spec.rb new file mode 100644 index 00000000000..3be4f742a24 --- /dev/null +++ b/spec/uploaders/ci/secure_file_uploader_spec.rb @@ -0,0 +1,72 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Ci::SecureFileUploader do + subject { ci_secure_file.file } + + let(:project) { create(:project) } + let(:ci_secure_file) { create(:ci_secure_file) } + let(:sample_file) { fixture_file('ci_secure_files/upload-keystore.jks') } + + before do + stub_ci_secure_file_object_storage + end + + describe '#key' do + it 'creates a digest with a secret key and the project id' do + expect(OpenSSL::HMAC) + .to receive(:digest) + .with('SHA256', Gitlab::Application.secrets.db_key_base, ci_secure_file.project_id.to_s) + .and_return('digest') + + expect(subject.key).to eq('digest') + end + end + + describe '.checksum' do + it 'returns a SHA256 checksum for the unencrypted file' do + expect(subject.checksum).to eq(Digest::SHA256.hexdigest(sample_file)) + end + end + + describe 'encryption' do + it 'encrypts the stored file' do + expect(Base64.encode64(subject.file.read)).not_to eq(Base64.encode64(sample_file)) + end + + it 'decrypts the file when reading' do + expect(Base64.encode64(subject.read)).to eq(Base64.encode64(sample_file)) + end + end + + describe '.direct_upload_enabled?' do + it 'returns false' do + expect(described_class.direct_upload_enabled?).to eq(false) + end + end + + describe '.background_upload_enabled?' do + it 'returns false' do + expect(described_class.background_upload_enabled?).to eq(false) + end + end + + describe '.default_store' do + context 'when object storage is enabled' do + it 'returns REMOTE' do + expect(described_class.default_store).to eq(ObjectStorage::Store::REMOTE) + end + end + + context 'when object storage is disabled' do + before do + stub_ci_secure_file_object_storage(enabled: false) + end + + it 'returns LOCAL' do + expect(described_class.default_store).to eq(ObjectStorage::Store::LOCAL) + end + end + end +end |