summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/user.rb7
-rw-r--r--changelogs/unreleased/mk-fix-user-namespace-rename.yml5
-rw-r--r--spec/migrations/remove_dot_git_from_usernames_spec.rb3
-rw-r--r--spec/models/user_spec.rb61
-rw-r--r--spec/services/users/update_service_spec.rb15
5 files changed, 87 insertions, 4 deletions
diff --git a/app/models/user.rb b/app/models/user.rb
index 02c3ab6654b..fbd08bc4d0a 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -837,7 +837,12 @@ class User < ActiveRecord::Base
create_namespace!(path: username, name: username) unless namespace
if username_changed?
- namespace.update_attributes(path: username, name: username)
+ unless namespace.update_attributes(path: username, name: username)
+ namespace.errors.each do |attribute, message|
+ self.errors.add(:"namespace_#{attribute}", message)
+ end
+ raise ActiveRecord::RecordInvalid.new(namespace)
+ end
end
end
diff --git a/changelogs/unreleased/mk-fix-user-namespace-rename.yml b/changelogs/unreleased/mk-fix-user-namespace-rename.yml
new file mode 100644
index 00000000000..bb43b21f708
--- /dev/null
+++ b/changelogs/unreleased/mk-fix-user-namespace-rename.yml
@@ -0,0 +1,5 @@
+---
+title: Make username update fail if the namespace update fails
+merge_request: 13642
+author:
+type: fixed
diff --git a/spec/migrations/remove_dot_git_from_usernames_spec.rb b/spec/migrations/remove_dot_git_from_usernames_spec.rb
index 8737e00eaeb..129374cb38c 100644
--- a/spec/migrations/remove_dot_git_from_usernames_spec.rb
+++ b/spec/migrations/remove_dot_git_from_usernames_spec.rb
@@ -51,7 +51,6 @@ describe RemoveDotGitFromUsernames do
namespace.path = path
namespace.save!(validate: false)
- user.username = path
- user.save!(validate: false)
+ user.update_column(:username, path)
end
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 97bb91a6ac8..9a9e255f874 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -2024,4 +2024,65 @@ describe User do
expect(user.projects_limit_left).to eq(5)
end
end
+
+ describe '#ensure_namespace_correct' do
+ context 'for a new user' do
+ let(:user) { build(:user) }
+
+ it 'creates the namespace' do
+ expect(user.namespace).to be_nil
+ user.save!
+ expect(user.namespace).not_to be_nil
+ end
+ end
+
+ context 'for an existing user' do
+ let(:username) { 'foo' }
+ let(:user) { create(:user, username: username) }
+
+ context 'when the user is updated' do
+ context 'when the username is changed' do
+ let(:new_username) { 'bar' }
+
+ it 'changes the namespace (just to compare to when username is not changed)' do
+ expect do
+ user.update_attributes!(username: new_username)
+ end.to change { user.namespace.updated_at }
+ end
+
+ it 'updates the namespace name' do
+ user.update_attributes!(username: new_username)
+ expect(user.namespace.name).to eq(new_username)
+ end
+
+ it 'updates the namespace path' do
+ user.update_attributes!(username: new_username)
+ expect(user.namespace.path).to eq(new_username)
+ end
+
+ context 'when there is a validation error (namespace name taken) while updating namespace' do
+ let!(:conflicting_namespace) { create(:group, name: new_username, path: 'quz') }
+
+ it 'causes the user save to fail' do
+ expect(user.update_attributes(username: new_username)).to be_falsey
+ expect(user.namespace.errors.messages[:name].first).to eq('has already been taken')
+ end
+
+ it 'adds the namespace errors to the user' do
+ user.update_attributes(username: new_username)
+ expect(user.errors.full_messages.first).to eq('Namespace name has already been taken')
+ end
+ end
+ end
+
+ context 'when the username is not changed' do
+ it 'does not change the namespace' do
+ expect do
+ user.update_attributes!(email: 'asdf@asdf.com')
+ end.not_to change { user.namespace.updated_at }
+ end
+ end
+ end
+ end
+ end
end
diff --git a/spec/services/users/update_service_spec.rb b/spec/services/users/update_service_spec.rb
index 343804e3de0..985f6d94876 100644
--- a/spec/services/users/update_service_spec.rb
+++ b/spec/services/users/update_service_spec.rb
@@ -12,9 +12,22 @@ describe Users::UpdateService do
end
it 'returns an error result when record cannot be updated' do
+ result = {}
expect do
- update_user(user, { email: 'invalid' })
+ result = update_user(user, { email: 'invalid' })
end.not_to change { user.reload.email }
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq('Email is invalid')
+ end
+
+ it 'includes namespace error messages' do
+ create(:group, name: 'taken', path: 'something_else')
+ result = {}
+ expect do
+ result = update_user(user, { username: 'taken' })
+ end.not_to change { user.reload.username }
+ expect(result[:status]).to eq(:error)
+ expect(result[:message]).to eq('Namespace name has already been taken')
end
def update_user(user, opts)