summaryrefslogtreecommitdiff
path: root/spec/lib/gitlab
diff options
context:
space:
mode:
authorGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-09-06 14:29:17 +0200
committerGrzegorz Bizon <grzesiek.bizon@gmail.com>2017-09-06 14:29:17 +0200
commit3b9f9aa00bc0c3afb65d803c3f7071fa7a113628 (patch)
treeffd17afd5d11304fa561831ce409fba7c4a0aa45 /spec/lib/gitlab
parentdeaa7f54e016b6ae1051c38abb95586451f470c1 (diff)
parentd1b60cbc67dc14b21820ef3f823a8e1ea851697d (diff)
downloadgitlab-ce-3b9f9aa00bc0c3afb65d803c3f7071fa7a113628.tar.gz
Merge commit 'd1b60cbc67dc14b21820ef3f823a8e1ea851697d' into feature/gb/download-single-job-artifact-using-api
* commit 'd1b60cbc67dc14b21820ef3f823a8e1ea851697d': (210 commits)
Diffstat (limited to 'spec/lib/gitlab')
-rw-r--r--spec/lib/gitlab/ci/config/entry/policy_spec.rb48
-rw-r--r--spec/lib/gitlab/git/repository_spec.rb38
-rw-r--r--spec/lib/gitlab/gpg/commit_spec.rb232
-rw-r--r--spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb43
-rw-r--r--spec/lib/gitlab/gpg_spec.rb15
-rw-r--r--spec/lib/gitlab/i18n/po_linter_spec.rb1
-rw-r--r--spec/lib/gitlab/import_export/all_models.yml1
-rw-r--r--spec/lib/gitlab/import_export/safe_model_attributes.yml1
-rw-r--r--spec/lib/gitlab/issuables_count_for_state_spec.rb37
-rw-r--r--spec/lib/gitlab/sql/pattern_spec.rb120
10 files changed, 432 insertions, 104 deletions
diff --git a/spec/lib/gitlab/ci/config/entry/policy_spec.rb b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
index 36a84da4a52..5e83abf645b 100644
--- a/spec/lib/gitlab/ci/config/entry/policy_spec.rb
+++ b/spec/lib/gitlab/ci/config/entry/policy_spec.rb
@@ -16,8 +16,8 @@ describe Gitlab::Ci::Config::Entry::Policy do
end
describe '#value' do
- it 'returns key value' do
- expect(entry.value).to eq config
+ it 'returns refs hash' do
+ expect(entry.value).to eq(refs: config)
end
end
end
@@ -56,6 +56,50 @@ describe Gitlab::Ci::Config::Entry::Policy do
end
end
+ context 'when using complex policy' do
+ context 'when specifiying refs policy' do
+ let(:config) { { refs: ['master'] } }
+
+ it 'is a correct configuraton' do
+ expect(entry).to be_valid
+ expect(entry.value).to eq(refs: %w[master])
+ end
+ end
+
+ context 'when specifying kubernetes policy' do
+ let(:config) { { kubernetes: 'active' } }
+
+ it 'is a correct configuraton' do
+ expect(entry).to be_valid
+ expect(entry.value).to eq(kubernetes: 'active')
+ end
+ end
+
+ context 'when specifying invalid kubernetes policy' do
+ let(:config) { { kubernetes: 'something' } }
+
+ it 'reports an error about invalid policy' do
+ expect(entry.errors).to include /unknown value: something/
+ end
+ end
+
+ context 'when specifying unknown policy' do
+ let(:config) { { refs: ['master'], invalid: :something } }
+
+ it 'returns error about invalid key' do
+ expect(entry.errors).to include /unknown keys: invalid/
+ end
+ end
+
+ context 'when policy is empty' do
+ let(:config) { {} }
+
+ it 'is not a valid configuration' do
+ expect(entry.errors).to include /can't be blank/
+ end
+ end
+ end
+
context 'when policy strategy does not match' do
let(:config) { 'string strategy' }
diff --git a/spec/lib/gitlab/git/repository_spec.rb b/spec/lib/gitlab/git/repository_spec.rb
index 4cfb4b7d357..08959e7bc16 100644
--- a/spec/lib/gitlab/git/repository_spec.rb
+++ b/spec/lib/gitlab/git/repository_spec.rb
@@ -916,27 +916,37 @@ describe Gitlab::Git::Repository, seed_helper: true do
end
describe '#find_branch' do
- it 'should return a Branch for master' do
- branch = repository.find_branch('master')
+ shared_examples 'finding a branch' do
+ it 'should return a Branch for master' do
+ branch = repository.find_branch('master')
- expect(branch).to be_a_kind_of(Gitlab::Git::Branch)
- expect(branch.name).to eq('master')
- end
+ expect(branch).to be_a_kind_of(Gitlab::Git::Branch)
+ expect(branch.name).to eq('master')
+ end
- it 'should handle non-existent branch' do
- branch = repository.find_branch('this-is-garbage')
+ it 'should handle non-existent branch' do
+ branch = repository.find_branch('this-is-garbage')
- expect(branch).to eq(nil)
+ expect(branch).to eq(nil)
+ end
end
- it 'should reload Rugged::Repository and return master' do
- expect(Rugged::Repository).to receive(:new).twice.and_call_original
+ context 'when Gitaly find_branch feature is enabled' do
+ it_behaves_like 'finding a branch'
+ end
- repository.find_branch('master')
- branch = repository.find_branch('master', force_reload: true)
+ context 'when Gitaly find_branch feature is disabled', skip_gitaly_mock: true do
+ it_behaves_like 'finding a branch'
- expect(branch).to be_a_kind_of(Gitlab::Git::Branch)
- expect(branch.name).to eq('master')
+ it 'should reload Rugged::Repository and return master' do
+ expect(Rugged::Repository).to receive(:new).twice.and_call_original
+
+ repository.find_branch('master')
+ branch = repository.find_branch('master', force_reload: true)
+
+ expect(branch).to be_a_kind_of(Gitlab::Git::Branch)
+ expect(branch.name).to eq('master')
+ end
end
end
diff --git a/spec/lib/gitlab/gpg/commit_spec.rb b/spec/lib/gitlab/gpg/commit_spec.rb
index e521fcc6dc1..b07462e4978 100644
--- a/spec/lib/gitlab/gpg/commit_spec.rb
+++ b/spec/lib/gitlab/gpg/commit_spec.rb
@@ -2,45 +2,9 @@ require 'rails_helper'
describe Gitlab::Gpg::Commit do
describe '#signature' do
- let!(:project) { create :project, :repository, path: 'sample-project' }
- let!(:commit_sha) { '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33' }
-
- context 'unsigned commit' do
- it 'returns nil' do
- expect(described_class.new(project, commit_sha).signature).to be_nil
- end
- end
-
- context 'known and verified public key' do
- let!(:gpg_key) do
- create :gpg_key, key: GpgHelpers::User1.public_key, user: create(:user, email: GpgHelpers::User1.emails.first)
- end
-
- before do
- allow(Rugged::Commit).to receive(:extract_signature)
- .with(Rugged::Repository, commit_sha)
- .and_return(
- [
- GpgHelpers::User1.signed_commit_signature,
- GpgHelpers::User1.signed_commit_base_data
- ]
- )
- end
-
- it 'returns a valid signature' do
- expect(described_class.new(project, commit_sha).signature).to have_attributes(
- commit_sha: commit_sha,
- project: project,
- gpg_key: gpg_key,
- gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- gpg_key_user_name: GpgHelpers::User1.names.first,
- gpg_key_user_email: GpgHelpers::User1.emails.first,
- valid_signature: true
- )
- end
-
+ shared_examples 'returns the cached signature on second call' do
it 'returns the cached signature on second call' do
- gpg_commit = described_class.new(project, commit_sha)
+ gpg_commit = described_class.new(commit)
expect(gpg_commit).to receive(:using_keychain).and_call_original
gpg_commit.signature
@@ -51,11 +15,140 @@ describe Gitlab::Gpg::Commit do
end
end
- context 'known but unverified public key' do
- let!(:gpg_key) { create :gpg_key, key: GpgHelpers::User1.public_key }
+ let!(:project) { create :project, :repository, path: 'sample-project' }
+ let!(:commit_sha) { '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33' }
- before do
- allow(Rugged::Commit).to receive(:extract_signature)
+ context 'unsigned commit' do
+ let!(:commit) { create :commit, project: project, sha: commit_sha }
+
+ it 'returns nil' do
+ expect(described_class.new(commit).signature).to be_nil
+ end
+ end
+
+ context 'known key' do
+ context 'user matches the key uid' do
+ context 'user email matches the email committer' do
+ let!(:commit) { create :commit, project: project, sha: commit_sha, committer_email: GpgHelpers::User1.emails.first }
+
+ let!(:user) { create(:user, email: GpgHelpers::User1.emails.first) }
+
+ let!(:gpg_key) do
+ create :gpg_key, key: GpgHelpers::User1.public_key, user: user
+ end
+
+ before do
+ allow(Rugged::Commit).to receive(:extract_signature)
+ .with(Rugged::Repository, commit_sha)
+ .and_return(
+ [
+ GpgHelpers::User1.signed_commit_signature,
+ GpgHelpers::User1.signed_commit_base_data
+ ]
+ )
+ end
+
+ it 'returns a valid signature' do
+ expect(described_class.new(commit).signature).to have_attributes(
+ commit_sha: commit_sha,
+ project: project,
+ gpg_key: gpg_key,
+ gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
+ gpg_key_user_name: GpgHelpers::User1.names.first,
+ gpg_key_user_email: GpgHelpers::User1.emails.first,
+ verification_status: 'verified'
+ )
+ end
+
+ it_behaves_like 'returns the cached signature on second call'
+ end
+
+ context 'user email does not match the committer email, but is the same user' do
+ let!(:commit) { create :commit, project: project, sha: commit_sha, committer_email: GpgHelpers::User2.emails.first }
+
+ let(:user) do
+ create(:user, email: GpgHelpers::User1.emails.first).tap do |user|
+ create :email, user: user, email: GpgHelpers::User2.emails.first
+ end
+ end
+
+ let!(:gpg_key) do
+ create :gpg_key, key: GpgHelpers::User1.public_key, user: user
+ end
+
+ before do
+ allow(Rugged::Commit).to receive(:extract_signature)
+ .with(Rugged::Repository, commit_sha)
+ .and_return(
+ [
+ GpgHelpers::User1.signed_commit_signature,
+ GpgHelpers::User1.signed_commit_base_data
+ ]
+ )
+ end
+
+ it 'returns an invalid signature' do
+ expect(described_class.new(commit).signature).to have_attributes(
+ commit_sha: commit_sha,
+ project: project,
+ gpg_key: gpg_key,
+ gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
+ gpg_key_user_name: GpgHelpers::User1.names.first,
+ gpg_key_user_email: GpgHelpers::User1.emails.first,
+ verification_status: 'same_user_different_email'
+ )
+ end
+
+ it_behaves_like 'returns the cached signature on second call'
+ end
+
+ context 'user email does not match the committer email' do
+ let!(:commit) { create :commit, project: project, sha: commit_sha, committer_email: GpgHelpers::User2.emails.first }
+
+ let(:user) { create(:user, email: GpgHelpers::User1.emails.first) }
+
+ let!(:gpg_key) do
+ create :gpg_key, key: GpgHelpers::User1.public_key, user: user
+ end
+
+ before do
+ allow(Rugged::Commit).to receive(:extract_signature)
+ .with(Rugged::Repository, commit_sha)
+ .and_return(
+ [
+ GpgHelpers::User1.signed_commit_signature,
+ GpgHelpers::User1.signed_commit_base_data
+ ]
+ )
+ end
+
+ it 'returns an invalid signature' do
+ expect(described_class.new(commit).signature).to have_attributes(
+ commit_sha: commit_sha,
+ project: project,
+ gpg_key: gpg_key,
+ gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
+ gpg_key_user_name: GpgHelpers::User1.names.first,
+ gpg_key_user_email: GpgHelpers::User1.emails.first,
+ verification_status: 'other_user'
+ )
+ end
+
+ it_behaves_like 'returns the cached signature on second call'
+ end
+ end
+
+ context 'user does not match the key uid' do
+ let!(:commit) { create :commit, project: project, sha: commit_sha }
+
+ let(:user) { create(:user, email: GpgHelpers::User2.emails.first) }
+
+ let!(:gpg_key) do
+ create :gpg_key, key: GpgHelpers::User1.public_key, user: user
+ end
+
+ before do
+ allow(Rugged::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha)
.and_return(
[
@@ -63,33 +156,27 @@ describe Gitlab::Gpg::Commit do
GpgHelpers::User1.signed_commit_base_data
]
)
- end
-
- it 'returns an invalid signature' do
- expect(described_class.new(project, commit_sha).signature).to have_attributes(
- commit_sha: commit_sha,
- project: project,
- gpg_key: gpg_key,
- gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- gpg_key_user_name: GpgHelpers::User1.names.first,
- gpg_key_user_email: GpgHelpers::User1.emails.first,
- valid_signature: false
- )
- end
-
- it 'returns the cached signature on second call' do
- gpg_commit = described_class.new(project, commit_sha)
-
- expect(gpg_commit).to receive(:using_keychain).and_call_original
- gpg_commit.signature
+ end
+
+ it 'returns an invalid signature' do
+ expect(described_class.new(commit).signature).to have_attributes(
+ commit_sha: commit_sha,
+ project: project,
+ gpg_key: gpg_key,
+ gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
+ gpg_key_user_name: GpgHelpers::User1.names.first,
+ gpg_key_user_email: GpgHelpers::User1.emails.first,
+ verification_status: 'unverified_key'
+ )
+ end
- # consecutive call
- expect(gpg_commit).not_to receive(:using_keychain).and_call_original
- gpg_commit.signature
+ it_behaves_like 'returns the cached signature on second call'
end
end
- context 'unknown public key' do
+ context 'unknown key' do
+ let!(:commit) { create :commit, project: project, sha: commit_sha }
+
before do
allow(Rugged::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha)
@@ -102,27 +189,18 @@ describe Gitlab::Gpg::Commit do
end
it 'returns an invalid signature' do
- expect(described_class.new(project, commit_sha).signature).to have_attributes(
+ expect(described_class.new(commit).signature).to have_attributes(
commit_sha: commit_sha,
project: project,
gpg_key: nil,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
gpg_key_user_name: nil,
gpg_key_user_email: nil,
- valid_signature: false
+ verification_status: 'unknown_key'
)
end
- it 'returns the cached signature on second call' do
- gpg_commit = described_class.new(project, commit_sha)
-
- expect(gpg_commit).to receive(:using_keychain).and_call_original
- gpg_commit.signature
-
- # consecutive call
- expect(gpg_commit).not_to receive(:using_keychain).and_call_original
- gpg_commit.signature
- end
+ it_behaves_like 'returns the cached signature on second call'
end
end
end
diff --git a/spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb b/spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb
index 4de4419de27..b9fd4d02156 100644
--- a/spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb
+++ b/spec/lib/gitlab/gpg/invalid_gpg_signature_updater_spec.rb
@@ -4,8 +4,29 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
describe '#run' do
let!(:commit_sha) { '0beec7b5ea3f0fdbc95d0dd47f3c5bc275da8a33' }
let!(:project) { create :project, :repository, path: 'sample-project' }
+ let!(:raw_commit) do
+ raw_commit = double(
+ :raw_commit,
+ signature: [
+ GpgHelpers::User1.signed_commit_signature,
+ GpgHelpers::User1.signed_commit_base_data
+ ],
+ sha: commit_sha,
+ committer_email: GpgHelpers::User1.emails.first
+ )
+
+ allow(raw_commit).to receive :save!
+
+ raw_commit
+ end
+
+ let!(:commit) do
+ create :commit, git_commit: raw_commit, project: project
+ end
before do
+ allow_any_instance_of(Project).to receive(:commit).and_return(commit)
+
allow(Rugged::Commit).to receive(:extract_signature)
.with(Rugged::Repository, commit_sha)
.and_return(
@@ -25,7 +46,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: nil,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: true
+ verification_status: 'verified'
end
it 'assigns the gpg key to the signature when the missing gpg key is added' do
@@ -39,7 +60,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: gpg_key,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: true
+ verification_status: 'verified'
)
end
@@ -54,7 +75,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: nil,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: true
+ verification_status: 'verified'
)
end
end
@@ -68,7 +89,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: nil,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: false
+ verification_status: 'unknown_key'
end
it 'updates the signature to being valid when the missing gpg key is added' do
@@ -82,7 +103,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: gpg_key,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: true
+ verification_status: 'verified'
)
end
@@ -97,7 +118,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: nil,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: false
+ verification_status: 'unknown_key'
)
end
end
@@ -115,7 +136,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: nil,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: false
+ verification_status: 'unknown_key'
end
it 'updates the signature to being valid when the user updates the email address' do
@@ -123,7 +144,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
key: GpgHelpers::User1.public_key,
user: user
- expect(invalid_gpg_signature.reload.valid_signature).to be_falsey
+ expect(invalid_gpg_signature.reload.verification_status).to eq 'unverified_key'
# InvalidGpgSignatureUpdater is called by the after_update hook
user.update_attributes!(email: GpgHelpers::User1.emails.first)
@@ -133,7 +154,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: gpg_key,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: true
+ verification_status: 'verified'
)
end
@@ -147,7 +168,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: gpg_key,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: false
+ verification_status: 'unverified_key'
)
# InvalidGpgSignatureUpdater is called by the after_update hook
@@ -158,7 +179,7 @@ RSpec.describe Gitlab::Gpg::InvalidGpgSignatureUpdater do
commit_sha: commit_sha,
gpg_key: gpg_key,
gpg_key_primary_keyid: GpgHelpers::User1.primary_keyid,
- valid_signature: false
+ verification_status: 'unverified_key'
)
end
end
diff --git a/spec/lib/gitlab/gpg_spec.rb b/spec/lib/gitlab/gpg_spec.rb
index 30ad033b204..11a2aea1915 100644
--- a/spec/lib/gitlab/gpg_spec.rb
+++ b/spec/lib/gitlab/gpg_spec.rb
@@ -42,6 +42,21 @@ describe Gitlab::Gpg do
described_class.user_infos_from_key('bogus')
).to eq []
end
+
+ it 'downcases the email' do
+ public_key = double(:key)
+ fingerprints = double(:fingerprints)
+ uid = double(:uid, name: 'Nannie Bernhard', email: 'NANNIE.BERNHARD@EXAMPLE.COM')
+ raw_key = double(:raw_key, uids: [uid])
+ allow(Gitlab::Gpg::CurrentKeyChain).to receive(:fingerprints_from_key).with(public_key).and_return(fingerprints)
+ allow(GPGME::Key).to receive(:find).with(:public, anything).and_return([raw_key])
+
+ user_infos = described_class.user_infos_from_key(public_key)
+ expect(user_infos).to eq([{
+ name: 'Nannie Bernhard',
+ email: 'nannie.bernhard@example.com'
+ }])
+ end
end
describe '.current_home_dir' do
diff --git a/spec/lib/gitlab/i18n/po_linter_spec.rb b/spec/lib/gitlab/i18n/po_linter_spec.rb
index cd5c2b99751..3a962ba7f22 100644
--- a/spec/lib/gitlab/i18n/po_linter_spec.rb
+++ b/spec/lib/gitlab/i18n/po_linter_spec.rb
@@ -1,4 +1,5 @@
require 'spec_helper'
+require 'simple_po_parser'
describe Gitlab::I18n::PoLinter do
let(:linter) { described_class.new(po_path) }
diff --git a/spec/lib/gitlab/import_export/all_models.yml b/spec/lib/gitlab/import_export/all_models.yml
index 8da02b0cf00..beed4e77e8b 100644
--- a/spec/lib/gitlab/import_export/all_models.yml
+++ b/spec/lib/gitlab/import_export/all_models.yml
@@ -264,6 +264,7 @@ project:
- statistics
- container_repositories
- uploads
+- members_and_requesters
award_emoji:
- awardable
- user
diff --git a/spec/lib/gitlab/import_export/safe_model_attributes.yml b/spec/lib/gitlab/import_export/safe_model_attributes.yml
index 27f2ce60084..b852ac570a3 100644
--- a/spec/lib/gitlab/import_export/safe_model_attributes.yml
+++ b/spec/lib/gitlab/import_export/safe_model_attributes.yml
@@ -278,6 +278,7 @@ CommitStatus:
- auto_canceled_by_id
- retried
- protected
+- failure_reason
Ci::Variable:
- id
- project_id
diff --git a/spec/lib/gitlab/issuables_count_for_state_spec.rb b/spec/lib/gitlab/issuables_count_for_state_spec.rb
new file mode 100644
index 00000000000..c262fdfcb61
--- /dev/null
+++ b/spec/lib/gitlab/issuables_count_for_state_spec.rb
@@ -0,0 +1,37 @@
+require 'spec_helper'
+
+describe Gitlab::IssuablesCountForState do
+ let(:finder) do
+ double(:finder, count_by_state: { opened: 2, closed: 1 })
+ end
+
+ let(:counter) { described_class.new(finder) }
+
+ describe '#for_state_or_opened' do
+ it 'returns the number of issuables for the given state' do
+ expect(counter.for_state_or_opened(:closed)).to eq(1)
+ end
+
+ it 'returns the number of open issuables when no state is given' do
+ expect(counter.for_state_or_opened).to eq(2)
+ end
+
+ it 'returns the number of open issuables when a nil value is given' do
+ expect(counter.for_state_or_opened(nil)).to eq(2)
+ end
+ end
+
+ describe '#[]' do
+ it 'returns the number of issuables for the given state' do
+ expect(counter[:closed]).to eq(1)
+ end
+
+ it 'casts valid states from Strings to Symbols' do
+ expect(counter['closed']).to eq(1)
+ end
+
+ it 'returns 0 when using an invalid state name as a String' do
+ expect(counter['kittens']).to be_zero
+ end
+ end
+end
diff --git a/spec/lib/gitlab/sql/pattern_spec.rb b/spec/lib/gitlab/sql/pattern_spec.rb
index 9d7b2136dab..48d56628ed5 100644
--- a/spec/lib/gitlab/sql/pattern_spec.rb
+++ b/spec/lib/gitlab/sql/pattern_spec.rb
@@ -52,4 +52,124 @@ describe Gitlab::SQL::Pattern do
end
end
end
+
+ describe '.select_fuzzy_words' do
+ subject(:select_fuzzy_words) { Issue.select_fuzzy_words(query) }
+
+ context 'with a word equal to 3 chars' do
+ let(:query) { 'foo' }
+
+ it 'returns array cotaining a word' do
+ expect(select_fuzzy_words).to match_array(['foo'])
+ end
+ end
+
+ context 'with a word shorter than 3 chars' do
+ let(:query) { 'fo' }
+
+ it 'returns empty array' do
+ expect(select_fuzzy_words).to match_array([])
+ end
+ end
+
+ context 'with two words both equal to 3 chars' do
+ let(:query) { 'foo baz' }
+
+ it 'returns array containing two words' do
+ expect(select_fuzzy_words).to match_array(%w[foo baz])
+ end
+ end
+
+ context 'with two words divided by two spaces both equal to 3 chars' do
+ let(:query) { 'foo baz' }
+
+ it 'returns array containing two words' do
+ expect(select_fuzzy_words).to match_array(%w[foo baz])
+ end
+ end
+
+ context 'with two words equal to 3 chars and shorter than 3 chars' do
+ let(:query) { 'foo ba' }
+
+ it 'returns array containing a word' do
+ expect(select_fuzzy_words).to match_array(['foo'])
+ end
+ end
+
+ context 'with a multi-word surrounded by double quote' do
+ let(:query) { '"really bar"' }
+
+ it 'returns array containing a multi-word' do
+ expect(select_fuzzy_words).to match_array(['really bar'])
+ end
+ end
+
+ context 'with a multi-word surrounded by double quote and two words' do
+ let(:query) { 'foo "really bar" baz' }
+
+ it 'returns array containing a multi-word and tow words' do
+ expect(select_fuzzy_words).to match_array(['foo', 'really bar', 'baz'])
+ end
+ end
+
+ context 'with a multi-word surrounded by double quote missing a spece before the first double quote' do
+ let(:query) { 'foo"really bar"' }
+
+ it 'returns array containing two words with double quote' do
+ expect(select_fuzzy_words).to match_array(['foo"really', 'bar"'])
+ end
+ end
+
+ context 'with a multi-word surrounded by double quote missing a spece after the second double quote' do
+ let(:query) { '"really bar"baz' }
+
+ it 'returns array containing two words with double quote' do
+ expect(select_fuzzy_words).to match_array(['"really', 'bar"baz'])
+ end
+ end
+
+ context 'with two multi-word surrounded by double quote and two words' do
+ let(:query) { 'foo "really bar" baz "awesome feature"' }
+
+ it 'returns array containing two multi-words and tow words' do
+ expect(select_fuzzy_words).to match_array(['foo', 'really bar', 'baz', 'awesome feature'])
+ end
+ end
+ end
+
+ describe '.to_fuzzy_arel' do
+ subject(:to_fuzzy_arel) { Issue.to_fuzzy_arel(:title, query) }
+
+ context 'with a word equal to 3 chars' do
+ let(:query) { 'foo' }
+
+ it 'returns a single ILIKE condition' do
+ expect(to_fuzzy_arel.to_sql).to match(/title.*I?LIKE '\%foo\%'/)
+ end
+ end
+
+ context 'with a word shorter than 3 chars' do
+ let(:query) { 'fo' }
+
+ it 'returns nil' do
+ expect(to_fuzzy_arel).to be_nil
+ end
+ end
+
+ context 'with two words both equal to 3 chars' do
+ let(:query) { 'foo baz' }
+
+ it 'returns a joining LIKE condition using a AND' do
+ expect(to_fuzzy_arel.to_sql).to match(/title.+I?LIKE '\%foo\%' AND .*title.*I?LIKE '\%baz\%'/)
+ end
+ end
+
+ context 'with a multi-word surrounded by double quote and two words' do
+ let(:query) { 'foo "really bar" baz' }
+
+ it 'returns a joining LIKE condition using a AND' do
+ expect(to_fuzzy_arel.to_sql).to match(/title.+I?LIKE '\%foo\%' AND .*title.*I?LIKE '\%baz\%' AND .*title.*I?LIKE '\%really bar\%'/)
+ end
+ end
+ end
end