Commit 55b747ee authored by Jan Provaznik's avatar Jan Provaznik Committed by Thong Kuah

Create an event on epic actions

Creates new event when an epic is created, closed, reopened or
commented.
parent 6898a225
......@@ -19,6 +19,7 @@ class Board < ApplicationRecord
def parent
@parent ||= group || project
end
alias_method :resource_parent, :parent
def group_board?
group_id.present?
......
......@@ -277,6 +277,10 @@ module Issuable
end
end
def resource_parent
project
end
def milestone_available?
project_id == milestone&.project_id || project.ancestors_upto.compact.include?(milestone&.group)
end
......
......@@ -51,6 +51,7 @@ class Event < ApplicationRecord
belongs_to :author, class_name: "User"
belongs_to :project
belongs_to :group
belongs_to :target, -> {
# If the association for "target" defines an "author" association we want to
......
......@@ -262,6 +262,7 @@ class Milestone < ApplicationRecord
def parent
group || project
end
alias_method :resource_parent, :parent
def group_milestone?
group_id.present?
......
......@@ -477,6 +477,7 @@ class Note < ApplicationRecord
def parent
project
end
alias_method :resource_parent, :parent
private
......
......@@ -146,6 +146,7 @@ class Todo < ApplicationRecord
def parent
project
end
alias_method :resource_parent, :parent
def unmergeable?
action == UNMERGEABLE
......
......@@ -95,16 +95,25 @@ class EventCreateService
private
def create_record_event(record, current_user, status)
create_event(record.project, current_user, status, target_id: record.id, target_type: record.class.name)
create_event(record.resource_parent, current_user, status, target_id: record.id, target_type: record.class.name)
end
def create_event(project, current_user, status, attributes = {})
def create_event(resource_parent, current_user, status, attributes = {})
attributes.reverse_merge!(
project: project,
action: status,
author_id: current_user.id
)
resource_parent_attr = case resource_parent
when Project
:project
when Group
:group
end
attributes[resource_parent_attr] = resource_parent if resource_parent_attr
Event.create!(attributes)
end
end
EventCreateService.prepend_if_ee('EE::EventCreateService')
# frozen_string_literal: true
class AddGroupColumnToEvents < ActiveRecord::Migration[5.2]
DOWNTIME = false
def change
add_reference :events, :group, index: true, foreign_key: { to_table: :namespaces, on_delete: :cascade }
end
end
......@@ -1310,9 +1310,11 @@ ActiveRecord::Schema.define(version: 2019_09_02_160015) do
t.datetime_with_timezone "updated_at", null: false
t.integer "action", limit: 2, null: false
t.string "target_type"
t.bigint "group_id"
t.index ["action"], name: "index_events_on_action"
t.index ["author_id", "project_id"], name: "index_events_on_author_id_and_project_id"
t.index ["created_at", "author_id"], name: "analytics_index_events_on_created_at_and_author_id"
t.index ["group_id"], name: "index_events_on_group_id"
t.index ["project_id", "created_at"], name: "index_events_on_project_id_and_created_at"
t.index ["project_id", "id"], name: "index_events_on_project_id_and_id"
t.index ["target_type", "target_id"], name: "index_events_on_target_type_and_target_id"
......@@ -3838,6 +3840,7 @@ ActiveRecord::Schema.define(version: 2019_09_02_160015) do
add_foreign_key "epics", "users", column: "assignee_id", name: "fk_dccd3f98fc", on_delete: :nullify
add_foreign_key "epics", "users", column: "author_id", name: "fk_3654b61b03", on_delete: :cascade
add_foreign_key "epics", "users", column: "closed_by_id", name: "fk_aa5798e761", on_delete: :nullify
add_foreign_key "events", "namespaces", column: "group_id", on_delete: :cascade
add_foreign_key "events", "projects", on_delete: :cascade
add_foreign_key "events", "users", column: "author_id", name: "fk_edfd187b6f", on_delete: :cascade
add_foreign_key "fork_network_members", "fork_networks", on_delete: :cascade
......
......@@ -37,6 +37,7 @@ module EE
belongs_to :due_date_sourcing_milestone, class_name: 'Milestone'
belongs_to :parent, class_name: "Epic"
has_many :children, class_name: "Epic", foreign_key: :parent_id
has_many :events, as: :target, dependent: :delete_all # rubocop:disable Cop/ActiveRecordDependent
has_internal_id :iid, scope: :group, init: ->(s) { s&.group&.epics&.maximum(:iid) }
......@@ -208,6 +209,10 @@ module EE
end
end
def resource_parent
group
end
def assignees
Array(assignee)
end
......
......@@ -58,6 +58,7 @@ module EE
def parent
for_epic? ? noteable.group : super
end
alias_method :resource_parent, :parent
def notify_after_create
noteable&.after_note_created(self)
......
......@@ -8,6 +8,7 @@ module EE
def parent
project || group
end
alias_method :resource_parent, :parent
def for_design?
target_type == DesignManagement::Design.name
......
# frozen_string_literal: true
module EE
module EventCreateService
def open_epic(epic, current_user)
create_record_event(epic, current_user, ::Event::CREATED)
end
def close_epic(epic, current_user)
create_record_event(epic, current_user, ::Event::CLOSED)
end
def reopen_epic(epic, current_user)
create_record_event(epic, current_user, ::Event::REOPENED)
end
end
end
......@@ -13,6 +13,7 @@ module Epics
def close_epic(epic)
if epic.close
epic.update(closed_by: current_user)
event_service.close_epic(epic, current_user)
SystemNoteService.change_status(epic, nil, current_user, epic.state)
notification_service.close_epic(epic, current_user)
end
......
......@@ -12,6 +12,7 @@ module Epics
def reopen_epic(epic)
if epic.reopen
event_service.reopen_epic(epic, current_user)
SystemNoteService.change_status(epic, nil, current_user, epic.state)
notification_service.reopen_epic(epic, current_user)
end
......
......@@ -7,6 +7,7 @@ class NewEpicWorker
def perform(epic_id, user_id)
return unless objects_found?(epic_id, user_id)
EventCreateService.new.open_epic(issuable, user)
NotificationService.new.new_epic(issuable)
issuable.create_cross_references!(user)
end
......
# frozen_string_literal: true
require 'spec_helper'
describe EventCreateService do
let(:service) { described_class.new }
describe 'Epics' do
let(:epic) { create(:epic) }
describe '#open_epic' do
it "creates new event" do
event = service.open_epic(epic, epic.author)
expect_event(event, Event::CREATED)
end
end
describe '#close_epic' do
it "creates new event" do
event = service.close_epic(epic, epic.author)
expect_event(event, Event::CLOSED)
end
end
describe '#reopen_epic' do
it "creates new event" do
event = service.reopen_epic(epic, epic.author)
expect_event(event, Event::REOPENED)
end
end
describe '#leave_note' do
it "creates new event" do
note = create(:note, noteable: epic)
event = service.leave_note(note, epic.author)
expect_event(event, Event::COMMENTED)
end
end
def expect_event(event, action)
expect(event).to be_persisted
expect(event.action).to eq action
expect(event.project_id).to be_nil
expect(event.group_id).to eq epic.group_id
end
end
end
......@@ -59,6 +59,10 @@ describe Epics::CloseService do
subject.execute(epic)
end
it "creates new event" do
expect { subject.execute(epic) }.to change { Event.count }
end
end
context 'when trying to close a closed epic' do
......@@ -87,6 +91,10 @@ describe Epics::CloseService do
subject.execute(epic)
end
it "does not create an event" do
expect { subject.execute(epic) }.not_to change { Event.count }
end
end
end
......
......@@ -59,6 +59,10 @@ describe Epics::ReopenService do
subject.execute(epic)
end
it "creates new event" do
expect { subject.execute(epic) }.to change { Event.count }
end
end
context 'when trying to reopen an opened epic' do
......@@ -87,6 +91,10 @@ describe Epics::ReopenService do
subject.execute(epic)
end
it "does not create an event" do
expect { subject.execute(epic) }.not_to change { Event.count }
end
end
end
......
......@@ -42,6 +42,10 @@ describe NewEpicWorker do
stub_licensed_features(epics: true)
end
it 'creates an event' do
expect { worker.perform(epic.id, user.id) }.to change { Event.count }.from(0).to(1)
end
context 'user watches group' do
before do
create(
......
......@@ -26,6 +26,7 @@ issues:
events:
- author
- project
- group
- target
- push_event_payload
notes:
......
......@@ -33,6 +33,7 @@ Event:
- target_type
- target_id
- project_id
- group_id
- created_at
- updated_at
- action
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment