diff options
author | Jose Ivan Vargas <jvargas@gitlab.com> | 2017-09-03 16:09:59 -0500 |
---|---|---|
committer | Jose Ivan Vargas <jvargas@gitlab.com> | 2017-09-03 16:09:59 -0500 |
commit | b623807682022a54344d8213d6f1c902be6ade37 (patch) | |
tree | 478ee3a25d67cb452aac09cfd42967fcfc7c22b9 /spec/lib/gitlab | |
parent | 28060caa0ade7566a38e3ed17f2db8bf9116dc1b (diff) | |
parent | 81002745184df28fc9d969afc524986279c653bb (diff) | |
download | gitlab-ce-b623807682022a54344d8213d6f1c902be6ade37.tar.gz |
Merge branch 'master' of gitlab.com:gitlab-org/gitlab-ce
Diffstat (limited to 'spec/lib/gitlab')
-rw-r--r-- | spec/lib/gitlab/auth_spec.rb | 10 | ||||
-rw-r--r-- | spec/lib/gitlab/git_access_spec.rb | 38 | ||||
-rw-r--r-- | spec/lib/gitlab/i18n/metadata_entry_spec.rb | 51 | ||||
-rw-r--r-- | spec/lib/gitlab/i18n/po_linter_spec.rb | 337 | ||||
-rw-r--r-- | spec/lib/gitlab/i18n/translation_entry_spec.rb | 203 | ||||
-rw-r--r-- | spec/lib/gitlab/key_fingerprint_spec.rb | 82 | ||||
-rw-r--r-- | spec/lib/gitlab/sentry_spec.rb | 13 | ||||
-rw-r--r-- | spec/lib/gitlab/ssh_public_key_spec.rb | 136 | ||||
-rw-r--r-- | spec/lib/gitlab/utils_spec.rb | 8 | ||||
-rw-r--r-- | spec/lib/gitlab/workhorse_spec.rb | 17 |
10 files changed, 788 insertions, 107 deletions
diff --git a/spec/lib/gitlab/auth_spec.rb b/spec/lib/gitlab/auth_spec.rb index 4a498e79c87..f685bb83d0d 100644 --- a/spec/lib/gitlab/auth_spec.rb +++ b/spec/lib/gitlab/auth_spec.rb @@ -279,16 +279,6 @@ describe Gitlab::Auth do gl_auth.find_with_user_password('ldap_user', 'password') end end - - context "with sign-in disabled" do - before do - stub_application_setting(password_authentication_enabled: false) - end - - it "does not find user by valid login/password" do - expect(gl_auth.find_with_user_password(username, password)).to be_nil - end - end end private diff --git a/spec/lib/gitlab/git_access_spec.rb b/spec/lib/gitlab/git_access_spec.rb index 295a979da76..458627ee4de 100644 --- a/spec/lib/gitlab/git_access_spec.rb +++ b/spec/lib/gitlab/git_access_spec.rb @@ -155,6 +155,44 @@ describe Gitlab::GitAccess do end end + shared_examples '#check with a key that is not valid' do + before do + project.add_master(user) + end + + context 'key is too small' do + before do + stub_application_setting(rsa_key_restriction: 4096) + end + + it 'does not allow keys which are too small', aggregate_failures: true do + expect(actor).not_to be_valid + expect { pull_access_check }.to raise_unauthorized('Your SSH key must be at least 4096 bits.') + expect { push_access_check }.to raise_unauthorized('Your SSH key must be at least 4096 bits.') + end + end + + context 'key type is not allowed' do + before do + stub_application_setting(rsa_key_restriction: ApplicationSetting::FORBIDDEN_KEY_VALUE) + end + + it 'does not allow keys which are too small', aggregate_failures: true do + expect(actor).not_to be_valid + expect { pull_access_check }.to raise_unauthorized(/Your SSH key type is forbidden/) + expect { push_access_check }.to raise_unauthorized(/Your SSH key type is forbidden/) + end + end + end + + it_behaves_like '#check with a key that is not valid' do + let(:actor) { build(:rsa_key_2048, user: user) } + end + + it_behaves_like '#check with a key that is not valid' do + let(:actor) { build(:rsa_deploy_key_2048, user: user) } + end + describe '#check_project_moved!' do before do project.add_master(user) diff --git a/spec/lib/gitlab/i18n/metadata_entry_spec.rb b/spec/lib/gitlab/i18n/metadata_entry_spec.rb new file mode 100644 index 00000000000..ab71d6454a9 --- /dev/null +++ b/spec/lib/gitlab/i18n/metadata_entry_spec.rb @@ -0,0 +1,51 @@ +require 'spec_helper' + +describe Gitlab::I18n::MetadataEntry do + describe '#expected_plurals' do + it 'returns the number of plurals' do + data = { + msgid: "", + msgstr: [ + "", + "Project-Id-Version: gitlab 1.0.0\\n", + "Report-Msgid-Bugs-To: \\n", + "PO-Revision-Date: 2017-07-13 12:10-0500\\n", + "Language-Team: Spanish\\n", + "Language: es\\n", + "MIME-Version: 1.0\\n", + "Content-Type: text/plain; charset=UTF-8\\n", + "Content-Transfer-Encoding: 8bit\\n", + "Plural-Forms: nplurals=2; plural=n != 1;\\n", + "Last-Translator: Bob Van Landuyt <bob@gitlab.com>\\n", + "X-Generator: Poedit 2.0.2\\n" + ] + } + entry = described_class.new(data) + + expect(entry.expected_plurals).to eq(2) + end + + it 'returns 0 for the POT-metadata' do + data = { + msgid: "", + msgstr: [ + "", + "Project-Id-Version: gitlab 1.0.0\\n", + "Report-Msgid-Bugs-To: \\n", + "PO-Revision-Date: 2017-07-13 12:10-0500\\n", + "Language-Team: Spanish\\n", + "Language: es\\n", + "MIME-Version: 1.0\\n", + "Content-Type: text/plain; charset=UTF-8\\n", + "Content-Transfer-Encoding: 8bit\\n", + "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n", + "Last-Translator: Bob Van Landuyt <bob@gitlab.com>\\n", + "X-Generator: Poedit 2.0.2\\n" + ] + } + entry = described_class.new(data) + + expect(entry.expected_plurals).to eq(0) + end + end +end diff --git a/spec/lib/gitlab/i18n/po_linter_spec.rb b/spec/lib/gitlab/i18n/po_linter_spec.rb new file mode 100644 index 00000000000..cd5c2b99751 --- /dev/null +++ b/spec/lib/gitlab/i18n/po_linter_spec.rb @@ -0,0 +1,337 @@ +require 'spec_helper' + +describe Gitlab::I18n::PoLinter do + let(:linter) { described_class.new(po_path) } + let(:po_path) { 'spec/fixtures/valid.po' } + + describe '#errors' do + it 'only calls validation once' do + expect(linter).to receive(:validate_po).once.and_call_original + + 2.times { linter.errors } + end + end + + describe '#validate_po' do + subject(:errors) { linter.validate_po } + + context 'for a fuzzy message' do + let(:po_path) { 'spec/fixtures/fuzzy.po' } + + it 'has an error' do + is_expected.to include('PipelineSchedules|Remove variable row' => ['is marked fuzzy']) + end + end + + context 'for a translations with newlines' do + let(:po_path) { 'spec/fixtures/newlines.po' } + + it 'has an error for a normal string' do + message_id = "You are going to remove %{group_name}.\\nRemoved groups CANNOT be restored!\\nAre you ABSOLUTELY sure?" + expected_message = "is defined over multiple lines, this breaks some tooling." + + expect(errors[message_id]).to include(expected_message) + end + + it 'has an error when a translation is defined over multiple lines' do + message_id = "You are going to remove %{group_name}.\\nRemoved groups CANNOT be restored!\\nAre you ABSOLUTELY sure?" + expected_message = "has translations defined over multiple lines, this breaks some tooling." + + expect(errors[message_id]).to include(expected_message) + end + + it 'raises an error when a plural translation is defined over multiple lines' do + message_id = 'With plural' + expected_message = "has translations defined over multiple lines, this breaks some tooling." + + expect(errors[message_id]).to include(expected_message) + end + + it 'raises an error when the plural id is defined over multiple lines' do + message_id = 'multiline plural id' + expected_message = "plural is defined over multiple lines, this breaks some tooling." + + expect(errors[message_id]).to include(expected_message) + end + end + + context 'with an invalid po' do + let(:po_path) { 'spec/fixtures/invalid.po' } + + it 'returns the error' do + is_expected.to include('PO-syntax errors' => a_kind_of(Array)) + end + + it 'does not validate entries' do + expect(linter).not_to receive(:validate_entries) + + linter.validate_po + end + end + + context 'with missing metadata' do + let(:po_path) { 'spec/fixtures/missing_metadata.po' } + + it 'returns the an error' do + is_expected.to include('PO-syntax errors' => a_kind_of(Array)) + end + end + + context 'with a valid po' do + it 'parses the file' do + expect(linter).to receive(:parse_po).and_call_original + + linter.validate_po + end + + it 'validates the entries' do + expect(linter).to receive(:validate_entries).and_call_original + + linter.validate_po + end + + it 'has no errors' do + is_expected.to be_empty + end + end + + context 'with missing plurals' do + let(:po_path) { 'spec/fixtures/missing_plurals.po' } + + it 'has errors' do + is_expected.not_to be_empty + end + end + + context 'with multiple plurals' do + let(:po_path) { 'spec/fixtures/multiple_plurals.po' } + + it 'has errors' do + is_expected.not_to be_empty + end + end + + context 'with unescaped chars' do + let(:po_path) { 'spec/fixtures/unescaped_chars.po' } + + it 'contains an error' do + message_id = 'You are going to transfer %{project_name_with_namespace} to another owner. Are you ABSOLUTELY sure?' + expected_error = 'translation contains unescaped `%`, escape it using `%%`' + + expect(errors[message_id]).to include(expected_error) + end + end + end + + describe '#parse_po' do + context 'with a valid po' do + it 'fills in the entries' do + linter.parse_po + + expect(linter.translation_entries).not_to be_empty + expect(linter.metadata_entry).to be_kind_of(Gitlab::I18n::MetadataEntry) + end + + it 'does not have errors' do + expect(linter.parse_po).to be_nil + end + end + + context 'with an invalid po' do + let(:po_path) { 'spec/fixtures/invalid.po' } + + it 'contains an error' do + expect(linter.parse_po).not_to be_nil + end + + it 'sets the entries to an empty array' do + linter.parse_po + + expect(linter.translation_entries).to eq([]) + end + end + end + + describe '#validate_entries' do + it 'keeps track of errors for entries' do + fake_invalid_entry = Gitlab::I18n::TranslationEntry.new( + { msgid: "Hello %{world}", msgstr: "Bonjour %{monde}" }, 2 + ) + allow(linter).to receive(:translation_entries) { [fake_invalid_entry] } + + expect(linter).to receive(:validate_entry) + .with(fake_invalid_entry) + .and_call_original + + expect(linter.validate_entries).to include("Hello %{world}" => an_instance_of(Array)) + end + end + + describe '#validate_entry' do + it 'validates the flags, variable usage, newlines, and unescaped chars' do + fake_entry = double + + expect(linter).to receive(:validate_flags).with([], fake_entry) + expect(linter).to receive(:validate_variables).with([], fake_entry) + expect(linter).to receive(:validate_newlines).with([], fake_entry) + expect(linter).to receive(:validate_number_of_plurals).with([], fake_entry) + expect(linter).to receive(:validate_unescaped_chars).with([], fake_entry) + + linter.validate_entry(fake_entry) + end + end + + describe '#validate_number_of_plurals' do + it 'validates when there are an incorrect number of translations' do + fake_metadata = double + allow(fake_metadata).to receive(:expected_plurals).and_return(2) + allow(linter).to receive(:metadata_entry).and_return(fake_metadata) + + fake_entry = Gitlab::I18n::TranslationEntry.new( + { msgid: 'the singular', msgid_plural: 'the plural', 'msgstr[0]' => 'the singular' }, + 2 + ) + errors = [] + + linter.validate_number_of_plurals(errors, fake_entry) + + expect(errors).to include('should have 2 translations') + end + end + + describe '#validate_variables' do + it 'validates both signular and plural in a pluralized string when the entry has a singular' do + pluralized_entry = Gitlab::I18n::TranslationEntry.new( + { msgid: 'Hello %{world}', + msgid_plural: 'Hello all %{world}', + 'msgstr[0]' => 'Bonjour %{world}', + 'msgstr[1]' => 'Bonjour tous %{world}' }, + 2 + ) + + expect(linter).to receive(:validate_variables_in_message) + .with([], 'Hello %{world}', 'Bonjour %{world}') + .and_call_original + expect(linter).to receive(:validate_variables_in_message) + .with([], 'Hello all %{world}', 'Bonjour tous %{world}') + .and_call_original + + linter.validate_variables([], pluralized_entry) + end + + it 'only validates plural when there is no separate singular' do + pluralized_entry = Gitlab::I18n::TranslationEntry.new( + { msgid: 'Hello %{world}', + msgid_plural: 'Hello all %{world}', + 'msgstr[0]' => 'Bonjour %{world}' }, + 1 + ) + + expect(linter).to receive(:validate_variables_in_message) + .with([], 'Hello all %{world}', 'Bonjour %{world}') + + linter.validate_variables([], pluralized_entry) + end + + it 'validates the message variables' do + entry = Gitlab::I18n::TranslationEntry.new( + { msgid: 'Hello', msgstr: 'Bonjour' }, + 2 + ) + + expect(linter).to receive(:validate_variables_in_message) + .with([], 'Hello', 'Bonjour') + + linter.validate_variables([], entry) + end + end + + describe '#validate_variables_in_message' do + it 'detects when a variables are used incorrectly' do + errors = [] + + expected_errors = ['<hello %{world} %d> is missing: [%{hello}]', + '<hello %{world} %d> is using unknown variables: [%{world}]', + 'is combining multiple unnamed variables'] + + linter.validate_variables_in_message(errors, '%{hello} world %d', 'hello %{world} %d') + + expect(errors).to include(*expected_errors) + end + end + + describe '#validate_translation' do + it 'succeeds with valid variables' do + errors = [] + + linter.validate_translation(errors, 'Hello %{world}', ['%{world}']) + + expect(errors).to be_empty + end + + it 'adds an error message when translating fails' do + errors = [] + + expect(FastGettext::Translation).to receive(:_) { raise 'broken' } + + linter.validate_translation(errors, 'Hello', []) + + expect(errors).to include('Failure translating to en with []: broken') + end + + it 'adds an error message when translating fails when translating with context' do + errors = [] + + expect(FastGettext::Translation).to receive(:s_) { raise 'broken' } + + linter.validate_translation(errors, 'Tests|Hello', []) + + expect(errors).to include('Failure translating to en with []: broken') + end + + it "adds an error when trying to translate with incorrect variables when using unnamed variables" do + errors = [] + + linter.validate_translation(errors, 'Hello %d', ['%s']) + + expect(errors.first).to start_with("Failure translating to en with") + end + + it "adds an error when trying to translate with named variables when unnamed variables are expected" do + errors = [] + + linter.validate_translation(errors, 'Hello %d', ['%{world}']) + + expect(errors.first).to start_with("Failure translating to en with") + end + + it 'adds an error when translated with incorrect variables using named variables' do + errors = [] + + linter.validate_translation(errors, 'Hello %{thing}', ['%d']) + + expect(errors.first).to start_with("Failure translating to en with") + end + end + + describe '#fill_in_variables' do + it 'builds an array for %d translations' do + result = linter.fill_in_variables(['%d']) + + expect(result).to contain_exactly(a_kind_of(Integer)) + end + + it 'builds an array for %s translations' do + result = linter.fill_in_variables(['%s']) + + expect(result).to contain_exactly(a_kind_of(String)) + end + + it 'builds a hash for named variables' do + result = linter.fill_in_variables(['%{hello}']) + + expect(result).to be_a(Hash) + expect(result).to include('hello' => an_instance_of(String)) + end + end +end diff --git a/spec/lib/gitlab/i18n/translation_entry_spec.rb b/spec/lib/gitlab/i18n/translation_entry_spec.rb new file mode 100644 index 00000000000..f68bc8feff9 --- /dev/null +++ b/spec/lib/gitlab/i18n/translation_entry_spec.rb @@ -0,0 +1,203 @@ +require 'spec_helper' + +describe Gitlab::I18n::TranslationEntry do + describe '#singular_translation' do + it 'returns the normal `msgstr` for translations without plural' do + data = { msgid: 'Hello world', msgstr: 'Bonjour monde' } + entry = described_class.new(data, 2) + + expect(entry.singular_translation).to eq('Bonjour monde') + end + + it 'returns the first string for entries with plurals' do + data = { + msgid: 'Hello world', + msgid_plural: 'Hello worlds', + 'msgstr[0]' => 'Bonjour monde', + 'msgstr[1]' => 'Bonjour mondes' + } + entry = described_class.new(data, 2) + + expect(entry.singular_translation).to eq('Bonjour monde') + end + end + + describe '#all_translations' do + it 'returns all translations for singular translations' do + data = { msgid: 'Hello world', msgstr: 'Bonjour monde' } + entry = described_class.new(data, 2) + + expect(entry.all_translations).to eq(['Bonjour monde']) + end + + it 'returns all translations when including plural translations' do + data = { + msgid: 'Hello world', + msgid_plural: 'Hello worlds', + 'msgstr[0]' => 'Bonjour monde', + 'msgstr[1]' => 'Bonjour mondes' + } + entry = described_class.new(data, 2) + + expect(entry.all_translations).to eq(['Bonjour monde', 'Bonjour mondes']) + end + end + + describe '#plural_translations' do + it 'returns all translations if there is only one plural' do + data = { + msgid: 'Hello world', + msgid_plural: 'Hello worlds', + 'msgstr[0]' => 'Bonjour monde' + } + entry = described_class.new(data, 1) + + expect(entry.plural_translations).to eq(['Bonjour monde']) + end + + it 'returns all translations except for the first one if there are multiple' do + data = { + msgid: 'Hello world', + msgid_plural: 'Hello worlds', + 'msgstr[0]' => 'Bonjour monde', + 'msgstr[1]' => 'Bonjour mondes', + 'msgstr[2]' => 'Bonjour tous les mondes' + } + entry = described_class.new(data, 3) + + expect(entry.plural_translations).to eq(['Bonjour mondes', 'Bonjour tous les mondes']) + end + end + + describe '#has_singular_translation?' do + it 'has a singular when the translation is not pluralized' do + data = { + msgid: 'hello world', + msgstr: 'hello' + } + entry = described_class.new(data, 2) + + expect(entry).to have_singular_translation + end + + it 'has a singular when plural and singular are separately defined' do + data = { + msgid: 'hello world', + msgid_plural: 'hello worlds', + "msgstr[0]" => 'hello world', + "msgstr[1]" => 'hello worlds' + } + entry = described_class.new(data, 2) + + expect(entry).to have_singular_translation + end + + it 'does not have a separate singular if the plural string only has one translation' do + data = { + msgid: 'hello world', + msgid_plural: 'hello worlds', + "msgstr[0]" => 'hello worlds' + } + entry = described_class.new(data, 1) + + expect(entry).not_to have_singular_translation + end + end + + describe '#msgid_contains_newlines' do + it 'is true when the msgid is an array' do + data = { msgid: %w(hello world) } + entry = described_class.new(data, 2) + + expect(entry.msgid_contains_newlines?).to be_truthy + end + end + + describe '#plural_id_contains_newlines' do + it 'is true when the msgid is an array' do + data = { msgid_plural: %w(hello world) } + entry = described_class.new(data, 2) + + expect(entry.plural_id_contains_newlines?).to be_truthy + end + end + + describe '#translations_contain_newlines' do + it 'is true when the msgid is an array' do + data = { msgstr: %w(hello world) } + entry = described_class.new(data, 2) + + expect(entry.translations_contain_newlines?).to be_truthy + end + end + + describe '#contains_unescaped_chars' do + let(:data) { { msgid: '' } } + let(:entry) { described_class.new(data, 2) } + it 'is true when the msgid is an array' do + string = '「100%確定」' + + expect(entry.contains_unescaped_chars?(string)).to be_truthy + end + + it 'is false when the `%` char is escaped' do + string = '「100%%確定」' + + expect(entry.contains_unescaped_chars?(string)).to be_falsy + end + + it 'is false when using an unnamed variable' do + string = '「100%d確定」' + + expect(entry.contains_unescaped_chars?(string)).to be_falsy + end + + it 'is false when using a named variable' do + string = '「100%{named}確定」' + + expect(entry.contains_unescaped_chars?(string)).to be_falsy + end + + it 'is true when an unnamed variable is not closed' do + string = '「100%{named確定」' + + expect(entry.contains_unescaped_chars?(string)).to be_truthy + end + + it 'is true when the string starts with a `%`' do + string = '%10' + + expect(entry.contains_unescaped_chars?(string)).to be_truthy + end + end + + describe '#msgid_contains_unescaped_chars' do + it 'is true when the msgid contains a `%`' do + data = { msgid: '「100%確定」' } + entry = described_class.new(data, 2) + + expect(entry).to receive(:contains_unescaped_chars?).and_call_original + expect(entry.msgid_contains_unescaped_chars?).to be_truthy + end + end + + describe '#plural_id_contains_unescaped_chars' do + it 'is true when the plural msgid contains a `%`' do + data = { msgid_plural: '「100%確定」' } + entry = described_class.new(data, 2) + + expect(entry).to receive(:contains_unescaped_chars?).and_call_original + expect(entry.plural_id_contains_unescaped_chars?).to be_truthy + end + end + + describe '#translations_contain_unescaped_chars' do + it 'is true when the translation contains a `%`' do + data = { msgstr: '「100%確定」' } + entry = described_class.new(data, 2) + + expect(entry).to receive(:contains_unescaped_chars?).and_call_original + expect(entry.translations_contain_unescaped_chars?).to be_truthy + end + end +end diff --git a/spec/lib/gitlab/key_fingerprint_spec.rb b/spec/lib/gitlab/key_fingerprint_spec.rb deleted file mode 100644 index d643dc5342d..00000000000 --- a/spec/lib/gitlab/key_fingerprint_spec.rb +++ /dev/null @@ -1,82 +0,0 @@ -require 'spec_helper' - -describe Gitlab::KeyFingerprint, lib: true do - KEYS = { - rsa: - 'example.com ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC5z65PwQ1GE6foJgwk' \ - '9rmQi/glaXbUeVa5uvQpnZ3Z5+forcI7aTngh3aZ/H2UDP2L70TGy7kKNyp0J3a8/OdG' \ - 'Z08y5yi3JlbjFARO1NyoFEjw2H1SJxeJ43L6zmvTlu+hlK1jSAlidl7enS0ufTlzEEj4' \ - 'iJcuTPKdVzKRgZuTRVm9woWNVKqIrdRC0rJiTinERnfSAp/vNYERMuaoN4oJt8p/NEek' \ - 'rmFoDsQOsyDW5RAnCnjWUU+jFBKDpfkJQ1U2n6BjJewC9dl6ODK639l3yN4WOLZEk4tN' \ - 'UysfbGeF3rmMeflaD6O1Jplpv3YhwVGFNKa7fMq6k3Z0tszTJPYh', - ecdsa: - 'example.com ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAI' \ - 'bmlzdHAyNTYAAABBBKTJy43NZzJSfNxpv/e2E6Zy3qoHoTQbmOsU5FEfpWfWa1MdTeXQ' \ - 'YvKOi+qz/1AaNx6BK421jGu74JCDJtiZWT8=', - ed25519: - '@revoked example.com ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIAfuCHKVTjq' \ - 'uxvt6CM6tdG4SLp1Btn/nOeHHE5UOzRdf', - dss: - 'example.com ssh-dss AAAAB3NzaC1kc3MAAACBAP1/U4EddRIpUt9KnC7s5Of2EbdS' \ - 'PO9EAMMeP4C2USZpRV1AIlH7WT2NWPq/xfW6MPbLm1Vs14E7gB00b/JmYLdrmVClpJ+f' \ - '6AR7ECLCT7up1/63xhv4O1fnxqimFQ8E+4P208UewwI1VBNaFpEy9nXzrith1yrv8iID' \ - 'GZ3RSAHHAAAAFQCXYFCPFSMLzLKSuYKi64QL8Fgc9QAAAIEA9+GghdabPd7LvKtcNrhX' \ - 'uXmUr7v6OuqC+VdMCz0HgmdRWVeOutRZT+ZxBxCBgLRJFnEj6EwoFhO3zwkyjMim4TwW' \ - 'eotUfI0o4KOuHiuzpnWRbqN/C/ohNWLx+2J6ASQ7zKTxvqhRkImog9/hWuWfBpKLZl6A' \ - 'e1UlZAFMO/7PSSoAAACBAJcQ4JODqhuGbXIEpqxetm7PWbdbCcr3y/GzIZ066pRovpL6' \ - 'qm3qCVIym4cyChxWwb8qlyCIi+YRUUWm1z/wiBYT2Vf3S4FXBnyymCkKEaV/EY7+jd4X' \ - '1bXI58OD2u+bLCB/sInM4fGB8CZUIWT9nJH0Ve9jJUge2ms348/QOJ1+' - }.freeze - - MD5_FINGERPRINTS = { - rsa: '06:b2:8a:92:df:0e:11:2c:ca:7b:8f:a4:ba:6e:4b:fd', - ecdsa: '45:ff:5b:98:9a:b6:8a:41:13:c1:30:8b:09:5e:7b:4e', - ed25519: '2e:65:6a:c8:cf:bf:b2:8b:9a:bd:6d:9f:11:5c:12:16', - dss: '57:98:86:02:5f:9c:f4:9b:ad:5a:1e:51:92:0e:fd:2b' - }.freeze - - BIT_COUNTS = { - rsa: 2048, - ecdsa: 256, - ed25519: 256, - dss: 1024 - }.freeze - - describe '#type' do - KEYS.each do |type, key| - it "calculates the type of #{type} keys" do - calculated_type = described_class.new(key).type - - expect(calculated_type).to eq(type.to_s.upcase) - end - end - end - - describe '#fingerprint' do - KEYS.each do |type, key| - it "calculates the MD5 fingerprint for #{type} keys" do - fp = described_class.new(key).fingerprint - - expect(fp).to eq(MD5_FINGERPRINTS[type]) - end - end - end - - describe '#bits' do - KEYS.each do |type, key| - it "calculates the number of bits in #{type} keys" do - bits = described_class.new(key).bits - - expect(bits).to eq(BIT_COUNTS[type]) - end - end - end - - describe '#key' do - it 'carries the unmodified key data' do - key = described_class.new(KEYS[:rsa]).key - - expect(key).to eq(KEYS[:rsa]) - end - end -end diff --git a/spec/lib/gitlab/sentry_spec.rb b/spec/lib/gitlab/sentry_spec.rb new file mode 100644 index 00000000000..8c211d1c63f --- /dev/null +++ b/spec/lib/gitlab/sentry_spec.rb @@ -0,0 +1,13 @@ +require 'spec_helper' + +describe Gitlab::Sentry do + describe '.context' do + it 'adds the locale to the tags' do + expect(described_class).to receive(:enabled?).and_return(true) + + described_class.context(nil) + + expect(Raven.tags_context[:locale]).to eq(I18n.locale.to_s) + end + end +end diff --git a/spec/lib/gitlab/ssh_public_key_spec.rb b/spec/lib/gitlab/ssh_public_key_spec.rb new file mode 100644 index 00000000000..93d538141ce --- /dev/null +++ b/spec/lib/gitlab/ssh_public_key_spec.rb @@ -0,0 +1,136 @@ +require 'spec_helper' + +describe Gitlab::SSHPublicKey, lib: true do + let(:key) { attributes_for(:rsa_key_2048)[:key] } + let(:public_key) { described_class.new(key) } + + describe '.technology(name)' do + it 'returns nil for an unrecognised name' do + expect(described_class.technology(:foo)).to be_nil + end + + where(:name) do + [:rsa, :dsa, :ecdsa, :ed25519] + end + + with_them do + it { expect(described_class.technology(name).name).to eq(name) } + it { expect(described_class.technology(name.to_s).name).to eq(name) } + end + end + + describe '.supported_sizes(name)' do + where(:name, :sizes) do + [ + [:rsa, [1024, 2048, 3072, 4096]], + [:dsa, [1024, 2048, 3072]], + [:ecdsa, [256, 384, 521]], + [:ed25519, [256]] + ] + end + + subject { described_class.supported_sizes(name) } + + with_them do + it { expect(described_class.supported_sizes(name)).to eq(sizes) } + it { expect(described_class.supported_sizes(name.to_s)).to eq(sizes) } + end + end + + describe '#valid?' do + subject { public_key } + + context 'with a valid SSH key' do + it { is_expected.to be_valid } + end + + context 'with an invalid SSH key' do + let(:key) { 'this is not a key' } + + it { is_expected.not_to be_valid } + end + end + + describe '#type' do + subject { public_key.type } + + where(:factory, :type) do + [ + [:rsa_key_2048, :rsa], + [:dsa_key_2048, :dsa], + [:ecdsa_key_256, :ecdsa], + [:ed25519_key_256, :ed25519] + ] + end + + with_them do + let(:key) { attributes_for(factory)[:key] } + + it { is_expected.to eq(type) } + end + + context 'with an invalid SSH key' do + let(:key) { 'this is not a key' } + + it { is_expected.to be_nil } + end + end + + describe '#bits' do + subject { public_key.bits } + + where(:factory, :bits) do + [ + [:rsa_key_2048, 2048], + [:dsa_key_2048, 2048], + [:ecdsa_key_256, 256], + [:ed25519_key_256, 256] + ] + end + + with_them do + let(:key) { attributes_for(factory)[:key] } + + it { is_expected.to eq(bits) } + end + + context 'with an invalid SSH key' do + let(:key) { 'this is not a key' } + + it { is_expected.to be_nil } + end + end + + describe '#fingerprint' do + subject { public_key.fingerprint } + + where(:factory, :fingerprint) do + [ + [:rsa_key_2048, '2e:ca:dc:e0:37:29:ed:fc:f0:1d:bf:66:d4:cd:51:b1'], + [:dsa_key_2048, 'bc:c1:a4:be:7e:8c:84:56:b3:58:93:53:c6:80:78:8c'], + [:ecdsa_key_256, '67:a3:a9:7d:b8:e1:15:d4:80:40:21:34:bb:ed:97:38'], + [:ed25519_key_256, 'e6:eb:45:8a:3c:59:35:5f:e9:5b:80:12:be:7e:22:73'] + ] + end + + with_them do + let(:key) { attributes_for(factory)[:key] } + + it { is_expected.to eq(fingerprint) } + end + + context 'with an invalid SSH key' do + let(:key) { 'this is not a key' } + + it { is_expected.to be_nil } + end + end + + describe '#key_text' do + let(:key) { 'this is not a key' } + + it 'carries the unmodified key data' do + expect(public_key.key_text).to eq(key) + end + end +end diff --git a/spec/lib/gitlab/utils_spec.rb b/spec/lib/gitlab/utils_spec.rb index 92787bb262e..3137a72fdc4 100644 --- a/spec/lib/gitlab/utils_spec.rb +++ b/spec/lib/gitlab/utils_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' describe Gitlab::Utils do - delegate :to_boolean, :boolean_to_yes_no, :slugify, to: :described_class + delegate :to_boolean, :boolean_to_yes_no, :slugify, :random_string, to: :described_class describe '.slugify' do { @@ -53,4 +53,10 @@ describe Gitlab::Utils do expect(boolean_to_yes_no(false)).to eq('No') end end + + describe '.random_string' do + it 'generates a string' do + expect(random_string).to be_kind_of(String) + end + end end diff --git a/spec/lib/gitlab/workhorse_spec.rb b/spec/lib/gitlab/workhorse_spec.rb index b66afafa174..699184ad9fe 100644 --- a/spec/lib/gitlab/workhorse_spec.rb +++ b/spec/lib/gitlab/workhorse_spec.rb @@ -228,21 +228,10 @@ describe Gitlab::Workhorse do let(:action) { 'git_upload_pack' } let(:feature_flag) { :post_upload_pack } - context 'when action is enabled by feature flag' do - it 'includes Gitaly params in the returned value' do - allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(feature_flag).and_return(true) + it 'includes Gitaly params in the returned value' do + allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(feature_flag).and_return(true) - expect(subject).to include(gitaly_params) - end - end - - context 'when action is not enabled by feature flag' do - it 'does not include Gitaly params in the returned value' do - status_opt_out = Gitlab::GitalyClient::MigrationStatus::OPT_OUT - allow(Gitlab::GitalyClient).to receive(:feature_enabled?).with(feature_flag, status: status_opt_out).and_return(false) - - expect(subject).not_to include(gitaly_params) - end + expect(subject).to include(gitaly_params) end end |