diff options
-rw-r--r-- | app/models/concerns/valid_attribute.rb | 10 | ||||
-rw-r--r-- | app/models/project.rb | 20 | ||||
-rw-r--r-- | changelogs/unreleased/fix-project-delete-tooltip.yml | 4 | ||||
-rw-r--r-- | spec/models/project_spec.rb | 30 |
4 files changed, 59 insertions, 5 deletions
diff --git a/app/models/concerns/valid_attribute.rb b/app/models/concerns/valid_attribute.rb new file mode 100644 index 00000000000..8c35cea8d58 --- /dev/null +++ b/app/models/concerns/valid_attribute.rb @@ -0,0 +1,10 @@ +module ValidAttribute + extend ActiveSupport::Concern + + # Checks whether an attribute has failed validation or not + # + # +attribute+ The symbolised name of the attribute i.e :name + def valid_attribute?(attribute) + self.errors.empty? || self.errors.messages[attribute].nil? + end +end diff --git a/app/models/project.rb b/app/models/project.rb index 94a6f3ba799..c22386c84e9 100644 --- a/app/models/project.rb +++ b/app/models/project.rb @@ -12,6 +12,7 @@ class Project < ActiveRecord::Base include AfterCommitQueue include CaseSensitivity include TokenAuthenticatable + include ValidAttribute include ProjectFeaturesCompatibility include SelectForProjectAuthorization include Routable @@ -65,6 +66,8 @@ class Project < ActiveRecord::Base end end + after_validation :check_pending_delete + ActsAsTaggableOn.strict_case_match = true acts_as_taggable_on :tags @@ -1320,4 +1323,21 @@ class Project < ActiveRecord::Base stats = statistics || build_statistics stats.update(namespace_id: namespace_id) end + + def check_pending_delete + return if valid_attribute?(:name) && valid_attribute?(:path) + return unless pending_delete_twin + + %i[route route.path name path].each do |error| + errors.delete(error) + end + + errors.add(:base, "The project is still being deleted. Please try again later.") + end + + def pending_delete_twin + return false unless path + + Project.unscoped.where(pending_delete: true).find_with_namespace(path_with_namespace) + end end diff --git a/changelogs/unreleased/fix-project-delete-tooltip.yml b/changelogs/unreleased/fix-project-delete-tooltip.yml new file mode 100644 index 00000000000..42fd9c32519 --- /dev/null +++ b/changelogs/unreleased/fix-project-delete-tooltip.yml @@ -0,0 +1,4 @@ +--- +title: Fix project queued for deletion re-creation tooltip +merge_request: +author: diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb index 3ec7bb46686..32779eb92ef 100644 --- a/spec/models/project_spec.rb +++ b/spec/models/project_spec.rb @@ -190,34 +190,54 @@ describe Project, models: true do end it 'does not allow an invalid URI as import_url' do - project2 = build(:project, import_url: 'invalid://') + project2 = build(:empty_project, import_url: 'invalid://') expect(project2).not_to be_valid end it 'does allow a valid URI as import_url' do - project2 = build(:project, import_url: 'ssh://test@gitlab.com/project.git') + project2 = build(:empty_project, import_url: 'ssh://test@gitlab.com/project.git') expect(project2).to be_valid end it 'allows an empty URI' do - project2 = build(:project, import_url: '') + project2 = build(:empty_project, import_url: '') expect(project2).to be_valid end it 'does not produce import data on an empty URI' do - project2 = build(:project, import_url: '') + project2 = build(:empty_project, import_url: '') expect(project2.import_data).to be_nil end it 'does not produce import data on an invalid URI' do - project2 = build(:project, import_url: 'test://') + project2 = build(:empty_project, import_url: 'test://') expect(project2.import_data).to be_nil end + + describe 'project pending deletion' do + let!(:project_pending_deletion) do + create(:empty_project, + pending_delete: true) + end + let(:new_project) do + build(:empty_project, + name: project_pending_deletion.name, + namespace: project_pending_deletion.namespace) + end + + before do + new_project.validate + end + + it 'contains errors related to the project being deleted' do + expect(new_project.errors.full_messages.first).to eq('The project is still being deleted. Please try again later.') + end + end end describe 'default_scope' do |