summaryrefslogtreecommitdiff
path: root/spec
diff options
context:
space:
mode:
authorMarkus Koller <markus-koller@gmx.ch>2017-09-28 16:49:42 +0000
committerRémy Coutable <remy@rymai.me>2017-09-28 16:49:42 +0000
commite9eae3eb0dd25e4a34c9a4b6bcc7de312dde4489 (patch)
treed2402a99dd96927ae458f49cbd7de8ad043e297a /spec
parent93a33556e3e01a83c1af9c21e11ff433b624c40d (diff)
downloadgitlab-ce-e9eae3eb0dd25e4a34c9a4b6bcc7de312dde4489.tar.gz
Support custom attributes on users
Diffstat (limited to 'spec')
-rw-r--r--spec/factories/user_custom_attributes.rb7
-rw-r--r--spec/finders/users_finder_spec.rb22
-rw-r--r--spec/models/ci/pipeline_variable_spec.rb2
-rw-r--r--spec/models/repository_spec.rb2
-rw-r--r--spec/models/user_custom_attribute_spec.rb16
-rw-r--r--spec/models/user_spec.rb1
-rw-r--r--spec/policies/global_policy_spec.rb14
-rw-r--r--spec/requests/api/users_spec.rb4
-rw-r--r--spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb103
9 files changed, 169 insertions, 2 deletions
diff --git a/spec/factories/user_custom_attributes.rb b/spec/factories/user_custom_attributes.rb
new file mode 100644
index 00000000000..278cf290d4f
--- /dev/null
+++ b/spec/factories/user_custom_attributes.rb
@@ -0,0 +1,7 @@
+FactoryGirl.define do
+ factory :user_custom_attribute do
+ user
+ sequence(:key) { |n| "key#{n}" }
+ sequence(:value) { |n| "value#{n}" }
+ end
+end
diff --git a/spec/finders/users_finder_spec.rb b/spec/finders/users_finder_spec.rb
index 1bab6d64388..4249c52c481 100644
--- a/spec/finders/users_finder_spec.rb
+++ b/spec/finders/users_finder_spec.rb
@@ -56,6 +56,15 @@ describe UsersFinder do
expect(users.map(&:username)).not_to include([filtered_user_before.username, filtered_user_after.username])
end
+
+ it 'does not filter by custom attributes' do
+ users = described_class.new(
+ user,
+ custom_attributes: { foo: 'bar' }
+ ).execute
+
+ expect(users).to contain_exactly(user, user1, user2, omniauth_user)
+ end
end
context 'with an admin user' do
@@ -72,6 +81,19 @@ describe UsersFinder do
expect(users).to contain_exactly(admin, user1, user2, external_user, omniauth_user)
end
+
+ it 'filters by custom attributes' do
+ create :user_custom_attribute, user: user1, key: 'foo', value: 'foo'
+ create :user_custom_attribute, user: user1, key: 'bar', value: 'bar'
+ create :user_custom_attribute, user: user2, key: 'foo', value: 'foo'
+
+ users = described_class.new(
+ admin,
+ custom_attributes: { foo: 'foo', bar: 'bar' }
+ ).execute
+
+ expect(users).to contain_exactly(user1)
+ end
end
end
end
diff --git a/spec/models/ci/pipeline_variable_spec.rb b/spec/models/ci/pipeline_variable_spec.rb
index 2ce78e34b0c..889c243c8d8 100644
--- a/spec/models/ci/pipeline_variable_spec.rb
+++ b/spec/models/ci/pipeline_variable_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Ci::PipelineVariable, models: true do
+describe Ci::PipelineVariable do
subject { build(:ci_pipeline_variable) }
it { is_expected.to include_module(HasVariable) }
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index 76bb658b10d..07d9b66060e 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -1,6 +1,6 @@
require 'spec_helper'
-describe Repository, models: true do
+describe Repository do
include RepoHelpers
TestBlob = Struct.new(:path)
diff --git a/spec/models/user_custom_attribute_spec.rb b/spec/models/user_custom_attribute_spec.rb
new file mode 100644
index 00000000000..37fc3cb64f0
--- /dev/null
+++ b/spec/models/user_custom_attribute_spec.rb
@@ -0,0 +1,16 @@
+require 'spec_helper'
+
+describe UserCustomAttribute do
+ describe 'assocations' do
+ it { is_expected.to belong_to(:user) }
+ end
+
+ describe 'validations' do
+ subject { build :user_custom_attribute }
+
+ it { is_expected.to validate_presence_of(:user_id) }
+ it { is_expected.to validate_presence_of(:key) }
+ it { is_expected.to validate_presence_of(:value) }
+ it { is_expected.to validate_uniqueness_of(:key).scoped_to(:user_id) }
+ end
+end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index c1affa812aa..62890dd5002 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -39,6 +39,7 @@ describe User do
it { is_expected.to have_many(:chat_names).dependent(:destroy) }
it { is_expected.to have_many(:uploads).dependent(:destroy) }
it { is_expected.to have_many(:reported_abuse_reports).dependent(:destroy).class_name('AbuseReport') }
+ it { is_expected.to have_many(:custom_attributes).class_name('UserCustomAttribute') }
describe "#abuse_report" do
let(:current_user) { create(:user) }
diff --git a/spec/policies/global_policy_spec.rb b/spec/policies/global_policy_spec.rb
index a6bf70c1e09..983f0e52d31 100644
--- a/spec/policies/global_policy_spec.rb
+++ b/spec/policies/global_policy_spec.rb
@@ -51,4 +51,18 @@ describe GlobalPolicy do
end
end
end
+
+ describe 'custom attributes' do
+ context 'regular user' do
+ it { is_expected.not_to be_allowed(:read_custom_attribute) }
+ it { is_expected.not_to be_allowed(:update_custom_attribute) }
+ end
+
+ context 'admin' do
+ let(:current_user) { create(:user, :admin) }
+
+ it { is_expected.to be_allowed(:read_custom_attribute) }
+ it { is_expected.to be_allowed(:update_custom_attribute) }
+ end
+ end
end
diff --git a/spec/requests/api/users_spec.rb b/spec/requests/api/users_spec.rb
index c30188b1b41..69c8aa4482a 100644
--- a/spec/requests/api/users_spec.rb
+++ b/spec/requests/api/users_spec.rb
@@ -1905,4 +1905,8 @@ describe API::Users do
expect(impersonation_token.reload.revoked).to be_truthy
end
end
+
+ include_examples 'custom attributes endpoints', 'users' do
+ let(:attributable) { user }
+ end
end
diff --git a/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
new file mode 100644
index 00000000000..c9302f7b750
--- /dev/null
+++ b/spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb
@@ -0,0 +1,103 @@
+shared_examples 'custom attributes endpoints' do |attributable_name|
+ let!(:custom_attribute1) { attributable.custom_attributes.create key: 'foo', value: 'foo' }
+ let!(:custom_attribute2) { attributable.custom_attributes.create key: 'bar', value: 'bar' }
+
+ describe "GET /#{attributable_name} with custom attributes filter" do
+ let!(:other_attributable) { create attributable.class.name.underscore }
+
+ context 'with an unauthorized user' do
+ it 'does not filter by custom attributes' do
+ get api("/#{attributable_name}", user), custom_attributes: { foo: 'foo', bar: 'bar' }
+
+ expect(response).to have_http_status(200)
+ expect(json_response.size).to be 2
+ end
+ end
+
+ it 'filters by custom attributes' do
+ get api("/#{attributable_name}", admin), custom_attributes: { foo: 'foo', bar: 'bar' }
+
+ expect(response).to have_http_status(200)
+ expect(json_response.size).to be 1
+ expect(json_response.first['id']).to eq attributable.id
+ end
+ end
+
+ describe "GET /#{attributable_name}/:id/custom_attributes" do
+ context 'with an unauthorized user' do
+ subject { get api("/#{attributable_name}/#{attributable.id}/custom_attributes", user) }
+
+ it_behaves_like 'an unauthorized API user'
+ end
+
+ it 'returns all custom attributes' do
+ get api("/#{attributable_name}/#{attributable.id}/custom_attributes", admin)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to contain_exactly(
+ { 'key' => 'foo', 'value' => 'foo' },
+ { 'key' => 'bar', 'value' => 'bar' }
+ )
+ end
+ end
+
+ describe "GET /#{attributable_name}/:id/custom_attributes/:key" do
+ context 'with an unauthorized user' do
+ subject { get api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user) }
+
+ it_behaves_like 'an unauthorized API user'
+ end
+
+ it 'returns a single custom attribute' do
+ get api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to eq({ 'key' => 'foo', 'value' => 'foo' })
+ end
+ end
+
+ describe "PUT /#{attributable_name}/:id/custom_attributes/:key" do
+ context 'with an unauthorized user' do
+ subject { put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user), value: 'new' }
+
+ it_behaves_like 'an unauthorized API user'
+ end
+
+ it 'creates a new custom attribute' do
+ expect do
+ put api("/#{attributable_name}/#{attributable.id}/custom_attributes/new", admin), value: 'new'
+ end.to change { attributable.custom_attributes.count }.by(1)
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to eq({ 'key' => 'new', 'value' => 'new' })
+ expect(attributable.custom_attributes.find_by(key: 'new').value).to eq 'new'
+ end
+
+ it 'updates an existing custom attribute' do
+ expect do
+ put api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin), value: 'new'
+ end.not_to change { attributable.custom_attributes.count }
+
+ expect(response).to have_http_status(200)
+ expect(json_response).to eq({ 'key' => 'foo', 'value' => 'new' })
+ expect(custom_attribute1.reload.value).to eq 'new'
+ end
+ end
+
+ describe "DELETE /#{attributable_name}/:id/custom_attributes/:key" do
+ context 'with an unauthorized user' do
+ subject { delete api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", user) }
+
+ it_behaves_like 'an unauthorized API user'
+ end
+
+ it 'deletes an existing custom attribute' do
+ expect do
+ delete api("/#{attributable_name}/#{attributable.id}/custom_attributes/foo", admin)
+ end.to change { attributable.custom_attributes.count }.by(-1)
+
+ expect(response).to have_http_status(204)
+ expect(attributable.custom_attributes.find_by(key: 'foo')).to be_nil
+ end
+ end
+end