summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2017-09-06 06:24:53 +0000
committerDouwe Maan <douwe@gitlab.com>2017-09-06 06:24:53 +0000
commit745bc35666ce7e6cc3fbdb08596e4e18a35f8e04 (patch)
treeee1c9196ff30cfe5105e5299ff644c350e0f87fe
parentd68ff7f50a93ebbff537b5e795cf6bf80bd66a6e (diff)
parent4c6898bdcf0bff6a0a3b288215271be4e916b27c (diff)
downloadgitlab-ce-745bc35666ce7e6cc3fbdb08596e4e18a35f8e04.tar.gz
Merge branch '36860-migrate-issues-author' into 'master'
Migrate old issues without author to the ghost user Closes #36860 See merge request !13860
-rw-r--r--app/views/projects/issues/show.html.haml3
-rw-r--r--app/views/shared/issuable/_close_reopen_button.html.haml3
-rw-r--r--app/views/shared/issuable/_close_reopen_report_toggle.html.haml22
-rw-r--r--changelogs/unreleased/36860-migrate-issues-author.yml5
-rw-r--r--db/migrate/20170825104051_migrate_issues_to_ghost_user.rb36
-rw-r--r--db/migrate/20170901071411_add_foreign_key_to_issue_author.rb14
-rw-r--r--db/schema.rb3
-rw-r--r--spec/features/issues/issue_detail_spec.rb14
-rw-r--r--spec/migrations/migrate_issues_to_ghost_user_spec.rb51
9 files changed, 120 insertions, 31 deletions
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index fd7ff176c5e..04b4ed95a2d 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -37,8 +37,7 @@
%ul
- if can_update_issue
%li= link_to 'Edit', edit_project_issue_path(@project, @issue)
- / TODO: simplify condition back #36860
- - if @issue.author && current_user != @issue.author
+ - unless current_user == @issue.author
%li= link_to 'Report abuse', new_abuse_report_path(user_id: @issue.author.id, ref_url: issue_url(@issue))
- if can_update_issue
%li= link_to 'Close issue', issue_path(@issue, issue: { state_event: :close }, format: 'json'), class: "btn-close js-btn-issue-action #{issue_button_visibility(@issue, true)}", title: 'Close issue'
diff --git a/app/views/shared/issuable/_close_reopen_button.html.haml b/app/views/shared/issuable/_close_reopen_button.html.haml
index cb706d80f23..f16bc8dd430 100644
--- a/app/views/shared/issuable/_close_reopen_button.html.haml
+++ b/app/views/shared/issuable/_close_reopen_button.html.haml
@@ -9,7 +9,6 @@
class: "hidden-xs hidden-sm btn btn-grouped btn-reopen js-btn-issue-action #{issuable_button_visibility(issuable, false)}", title: "Reopen #{display_issuable_type}"
- elsif can_update && !is_current_user
= render 'shared/issuable/close_reopen_report_toggle', issuable: issuable
-- elsif issuable.author
- / TODO: change back to else #36860
+- else
= link_to 'Report abuse', new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
class: 'hidden-xs hidden-sm btn btn-grouped btn-close-color', title: 'Report abuse'
diff --git a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
index d8144a39b23..a38cd319e3c 100644
--- a/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
+++ b/app/views/shared/issuable/_close_reopen_report_toggle.html.haml
@@ -37,15 +37,13 @@
%li.divider.droplab-item-ignore
- / TODO: remove condition #36860
- - if issuable.author
- %li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
- button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } }
- %button.btn.btn-transparent
- = icon('check', class: 'icon')
- .description
- %strong.title Report abuse
- %p.text
- Report
- = display_issuable_type.pluralize
- that are abusive, inappropriate or spam.
+ %li.report-item{ data: { text: 'Report abuse', url: new_abuse_report_path(user_id: issuable.author.id, ref_url: issuable_url(issuable)),
+ button_class: "#{button_class} btn-close-color", toggle_class: "#{toggle_class} btn-close-color", method: '' } }
+ %button.btn.btn-transparent
+ = icon('check', class: 'icon')
+ .description
+ %strong.title Report abuse
+ %p.text
+ Report
+ = display_issuable_type.pluralize
+ that are abusive, inappropriate or spam.
diff --git a/changelogs/unreleased/36860-migrate-issues-author.yml b/changelogs/unreleased/36860-migrate-issues-author.yml
new file mode 100644
index 00000000000..3e9fcc55836
--- /dev/null
+++ b/changelogs/unreleased/36860-migrate-issues-author.yml
@@ -0,0 +1,5 @@
+---
+title: Migrate issues authored by deleted user to the Ghost user
+merge_request:
+author:
+type: fixed
diff --git a/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb b/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb
new file mode 100644
index 00000000000..294141e4fdb
--- /dev/null
+++ b/db/migrate/20170825104051_migrate_issues_to_ghost_user.rb
@@ -0,0 +1,36 @@
+class MigrateIssuesToGhostUser < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+ DOWNTIME = false
+
+ disable_ddl_transaction!
+
+ class User < ActiveRecord::Base
+ self.table_name = 'users'
+ end
+
+ class Issue < ActiveRecord::Base
+ self.table_name = 'issues'
+
+ include ::EachBatch
+ end
+
+ def reset_column_in_migration_models
+ ActiveRecord::Base.clear_cache!
+
+ ::User.reset_column_information
+ end
+
+ def up
+ reset_column_in_migration_models
+
+ # we use the model method because rewriting it is too complicated and would require copying multiple methods
+ ghost_id = ::User.ghost.id
+
+ Issue.where('NOT EXISTS (?)', User.unscoped.select(1).where('issues.author_id = users.id')).each_batch do |relation|
+ relation.update_all(author_id: ghost_id)
+ end
+ end
+
+ def down
+ end
+end
diff --git a/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb b/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb
new file mode 100644
index 00000000000..ab6e9fb565a
--- /dev/null
+++ b/db/migrate/20170901071411_add_foreign_key_to_issue_author.rb
@@ -0,0 +1,14 @@
+class AddForeignKeyToIssueAuthor < ActiveRecord::Migration
+ include Gitlab::Database::MigrationHelpers
+
+ DOWNTIME = false
+ disable_ddl_transaction!
+
+ def up
+ add_concurrent_foreign_key(:issues, :users, column: :author_id, on_delete: :nullify)
+ end
+
+ def down
+ remove_foreign_key(:issues, column: :author_id)
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 40b84f2bddd..f980667a38f 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20170831195038) do
+ActiveRecord::Schema.define(version: 20170901071411) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -1708,6 +1708,7 @@ ActiveRecord::Schema.define(version: 20170831195038) do
add_foreign_key "issue_assignees", "users", name: "fk_5e0c8d9154", on_delete: :cascade
add_foreign_key "issue_metrics", "issues", on_delete: :cascade
add_foreign_key "issues", "projects", name: "fk_899c8f3231", on_delete: :cascade
+ add_foreign_key "issues", "users", column: "author_id", name: "fk_05f1e72feb", on_delete: :cascade
add_foreign_key "label_priorities", "labels", on_delete: :cascade
add_foreign_key "label_priorities", "projects", on_delete: :cascade
add_foreign_key "labels", "namespaces", column: "group_id", on_delete: :cascade
diff --git a/spec/features/issues/issue_detail_spec.rb b/spec/features/issues/issue_detail_spec.rb
index c470cb7c716..28b636f9359 100644
--- a/spec/features/issues/issue_detail_spec.rb
+++ b/spec/features/issues/issue_detail_spec.rb
@@ -40,18 +40,4 @@ feature 'Issue Detail', :js do
end
end
end
-
- context 'when authored by a user who is later deleted' do
- before do
- issue.update_attribute(:author_id, nil)
- sign_in(user)
- visit project_issue_path(project, issue)
- end
-
- it 'shows the issue' do
- page.within('.issuable-details') do
- expect(find('h2')).to have_content(issue.title)
- end
- end
- end
end
diff --git a/spec/migrations/migrate_issues_to_ghost_user_spec.rb b/spec/migrations/migrate_issues_to_ghost_user_spec.rb
new file mode 100644
index 00000000000..cfd4021fbac
--- /dev/null
+++ b/spec/migrations/migrate_issues_to_ghost_user_spec.rb
@@ -0,0 +1,51 @@
+require 'spec_helper'
+require Rails.root.join('db', 'migrate', '20170825104051_migrate_issues_to_ghost_user.rb')
+
+describe MigrateIssuesToGhostUser, :migration do
+ describe '#up' do
+ let(:projects) { table(:projects) }
+ let(:issues) { table(:issues) }
+ let(:users) { table(:users) }
+
+ before do
+ projects.create!(name: 'gitlab')
+ user = users.create(email: 'test@example.com')
+ issues.create(title: 'Issue 1', author_id: nil, project_id: 1)
+ issues.create(title: 'Issue 2', author_id: user.id, project_id: 1)
+ end
+
+ context 'when ghost user exists' do
+ let!(:ghost) { users.create(ghost: true, email: 'ghost@example.com') }
+
+ it 'does not create a new user' do
+ expect { schema_migrate_up! }.not_to change { User.count }
+ end
+
+ it 'migrates issues where author = nil to the ghost user' do
+ schema_migrate_up!
+
+ expect(issues.first.reload.author_id).to eq(ghost.id)
+ end
+
+ it 'does not change issues authored by an existing user' do
+ expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id}
+ end
+ end
+
+ context 'when ghost user does not exist' do
+ it 'creates a new user' do
+ expect { schema_migrate_up! }.to change { User.count }.by(1)
+ end
+
+ it 'migrates issues where author = nil to the ghost user' do
+ schema_migrate_up!
+
+ expect(issues.first.reload.author_id).to eq(User.ghost.id)
+ end
+
+ it 'does not change issues authored by an existing user' do
+ expect { schema_migrate_up! }.not_to change { issues.second.reload.author_id}
+ end
+ end
+ end
+end