summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/models/concerns/valid_attribute.rb10
-rw-r--r--app/models/project.rb20
-rw-r--r--changelogs/unreleased/fix-project-delete-tooltip.yml4
-rw-r--r--spec/models/project_spec.rb30
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