diff options
author | Markus Koller <markus-koller@gmx.ch> | 2017-09-28 16:49:42 +0000 |
---|---|---|
committer | Rémy Coutable <remy@rymai.me> | 2017-09-28 16:49:42 +0000 |
commit | e9eae3eb0dd25e4a34c9a4b6bcc7de312dde4489 (patch) | |
tree | d2402a99dd96927ae458f49cbd7de8ad043e297a /spec | |
parent | 93a33556e3e01a83c1af9c21e11ff433b624c40d (diff) | |
download | gitlab-ce-e9eae3eb0dd25e4a34c9a4b6bcc7de312dde4489.tar.gz |
Support custom attributes on users
Diffstat (limited to 'spec')
-rw-r--r-- | spec/factories/user_custom_attributes.rb | 7 | ||||
-rw-r--r-- | spec/finders/users_finder_spec.rb | 22 | ||||
-rw-r--r-- | spec/models/ci/pipeline_variable_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/repository_spec.rb | 2 | ||||
-rw-r--r-- | spec/models/user_custom_attribute_spec.rb | 16 | ||||
-rw-r--r-- | spec/models/user_spec.rb | 1 | ||||
-rw-r--r-- | spec/policies/global_policy_spec.rb | 14 | ||||
-rw-r--r-- | spec/requests/api/users_spec.rb | 4 | ||||
-rw-r--r-- | spec/support/shared_examples/requests/api/custom_attributes_shared_examples.rb | 103 |
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 |