Commit 3ea0b037 authored by James Lopez's avatar James Lopez

Merge branch 'add-state-events-to-burnup-chart-data-pd' into 'master'

Add state events to burnup chart data

See merge request gitlab-org/gitlab!33048
parents d56fd504 dd144109
...@@ -9,6 +9,7 @@ class BurnupChartService ...@@ -9,6 +9,7 @@ class BurnupChartService
WEIGHT = 'value'.freeze WEIGHT = 'value'.freeze
ACTION = 'action'.freeze ACTION = 'action'.freeze
ISSUE_ID = 'issue_id'.freeze ISSUE_ID = 'issue_id'.freeze
STATE = 'value'.freeze
def initialize(milestone:, user:) def initialize(milestone:, user:)
@user = user @user = user
...@@ -64,7 +65,7 @@ class BurnupChartService ...@@ -64,7 +65,7 @@ class BurnupChartService
end end
def all_events def all_events
[milestone_events, weight_events] [milestone_events, weight_events, state_events]
end end
def weight_events def weight_events
...@@ -77,6 +78,11 @@ class BurnupChartService ...@@ -77,6 +78,11 @@ class BurnupChartService
.select('\'milestone\' as event_type, created_at, milestone_id as value, action, issue_id') .select('\'milestone\' as event_type, created_at, milestone_id as value, action, issue_id')
end end
def state_events
ResourceStateEvent.by_issue_ids_and_created_at_earlier_or_equal_to(relevant_issue_ids, end_time)
.select('\'state\' as event_type, created_at, state as value, null as action, issue_id')
end
def create_burnup_graph_event_by(event, assigned_milestones) def create_burnup_graph_event_by(event, assigned_milestones)
{ {
event_type: event[EVENT_TYPE], event_type: event[EVENT_TYPE],
...@@ -84,10 +90,17 @@ class BurnupChartService ...@@ -84,10 +90,17 @@ class BurnupChartService
action: action_of(event), action: action_of(event),
milestone_id: milestone_id_of(event, assigned_milestones), milestone_id: milestone_id_of(event, assigned_milestones),
issue_id: event[ISSUE_ID], issue_id: event[ISSUE_ID],
weight: weight_of(event) weight: weight_of(event),
state: state_of(event)
} }
end end
def state_of(event)
return unless state_event?(event)
ResourceStateEvent.states.key(event[STATE])
end
def action_of(event) def action_of(event)
return unless milestone_event?(event) return unless milestone_event?(event)
...@@ -111,6 +124,8 @@ class BurnupChartService ...@@ -111,6 +124,8 @@ class BurnupChartService
end end
def milestone_id_of(event, assigned_milestones) def milestone_id_of(event, assigned_milestones)
return unless milestone_event?(event)
if remove_milestone?(event) && event[MILESTONE_ID].nil? if remove_milestone?(event) && event[MILESTONE_ID].nil?
return assigned_milestones[event[ISSUE_ID]] return assigned_milestones[event[ISSUE_ID]]
end end
...@@ -134,6 +149,10 @@ class BurnupChartService ...@@ -134,6 +149,10 @@ class BurnupChartService
event[EVENT_TYPE] == 'milestone' event[EVENT_TYPE] == 'milestone'
end end
def state_event?(event)
event[EVENT_TYPE] == 'state'
end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def relevant_issue_ids def relevant_issue_ids
# We are using all resource milestone events where the # We are using all resource milestone events where the
......
---
title: Add state events to burnup chart data
merge_request: 33048
author:
type: added
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
], ],
"properties": { "properties": {
"event_type": { "event_type": {
"type": { "enum": [ "milestone", "weight" ] } "type": { "enum": [ "milestone", "weight", "state" ] }
}, },
"weight": { "weight": {
"type": ["integer", "null"] "type": ["integer", "null"]
...@@ -17,6 +17,9 @@ ...@@ -17,6 +17,9 @@
"milestone_id": { "milestone_id": {
"type": ["integer", "null"] "type": ["integer", "null"]
}, },
"state": {
"type": ["string", "null"]
},
"issue_id": { "issue_id": {
"type": "integer" "type": "integer"
}, },
......
...@@ -32,6 +32,12 @@ describe BurnupChartService do ...@@ -32,6 +32,12 @@ describe BurnupChartService do
let_it_be(:event5) { create(:resource_milestone_event, issue: issue3, action: :add, milestone: milestone2, created_at: start_date + 3.days) } let_it_be(:event5) { create(:resource_milestone_event, issue: issue3, action: :add, milestone: milestone2, created_at: start_date + 3.days) }
let_it_be(:event6) { create(:resource_milestone_event, issue: issue3, action: :remove, milestone: nil, created_at: start_date + 4.days) } let_it_be(:event6) { create(:resource_milestone_event, issue: issue3, action: :remove, milestone: nil, created_at: start_date + 4.days) }
let_it_be(:state_event1) { create(:resource_state_event, issue: issue1, state: :opened, created_at: start_date + 5.seconds) }
let_it_be(:state_event2) { create(:resource_state_event, issue: issue2, state: :closed, created_at: start_date + 6.seconds) }
let_it_be(:state_event3) { create(:resource_state_event, issue: issue3, state: :opened, created_at: start_date + 3.days + 1.second) }
let_it_be(:state_event4) { create(:resource_state_event, issue: issue3, state: :closed, created_at: start_date + 3.days + 23.hours + 59.minutes + 58.seconds) }
let_it_be(:state_event5) { create(:resource_state_event, issue: issue3, state: :reopened, created_at: start_date + 4.days + 2.seconds) }
before do before do
project.add_maintainer(user) project.add_maintainer(user)
end end
...@@ -49,20 +55,25 @@ describe BurnupChartService do ...@@ -49,20 +55,25 @@ describe BurnupChartService do
data = described_class.new(milestone: milestone1, user: user).execute data = described_class.new(milestone: milestone1, user: user).execute
expect(data.size).to eq(12) expect(data.size).to eq(17)
expect(data[0]).to include(event_type: 'milestone', action: 'add', issue_id: issue1.id, milestone_id: milestone2.id, created_at: start_date.beginning_of_day - 1.second) expect(data[0]).to include(event_type: 'milestone', action: 'add', issue_id: issue1.id, milestone_id: milestone2.id, created_at: start_date.beginning_of_day - 1.second)
expect(data[1]).to include(event_type: 'milestone', action: 'add', issue_id: issue1.id, milestone_id: milestone1.id, created_at: start_date + 1.second) expect(data[1]).to include(event_type: 'milestone', action: 'add', issue_id: issue1.id, milestone_id: milestone1.id, created_at: start_date + 1.second)
expect(data[2]).to include(event_type: 'weight', issue_id: issue1.id, weight: 9, created_at: start_date + 2.seconds) expect(data[2]).to include(event_type: 'weight', issue_id: issue1.id, weight: 9, created_at: start_date + 2.seconds)
expect(data[3]).to include(event_type: 'weight', issue_id: issue2.id, weight: 3, created_at: start_date + 3.seconds) expect(data[3]).to include(event_type: 'weight', issue_id: issue2.id, weight: 3, created_at: start_date + 3.seconds)
expect(data[4]).to include(event_type: 'milestone', action: 'add', issue_id: issue2.id, milestone_id: milestone1.id, created_at: start_date + 4.seconds) expect(data[4]).to include(event_type: 'milestone', action: 'add', issue_id: issue2.id, milestone_id: milestone1.id, created_at: start_date + 4.seconds)
expect(data[5]).to include(event_type: 'milestone', action: 'add', issue_id: issue3.id, milestone_id: milestone1.id, created_at: start_date + 1.day) expect(data[5]).to include(event_type: 'state', issue_id: issue1.id, state: 'opened', created_at: start_date + 5.seconds)
expect(data[6]).to include(event_type: 'weight', issue_id: issue3.id, weight: 1, created_at: start_date + 2.days) expect(data[6]).to include(event_type: 'state', issue_id: issue2.id, state: 'closed', created_at: start_date + 6.seconds)
expect(data[7]).to include(event_type: 'milestone', action: 'remove', issue_id: issue3.id, milestone_id: milestone1.id, created_at: start_date + 2.days + 1.second) expect(data[7]).to include(event_type: 'milestone', action: 'add', issue_id: issue3.id, milestone_id: milestone1.id, created_at: start_date + 1.day)
expect(data[8]).to include(event_type: 'weight', issue_id: issue3.id, weight: 2, created_at: start_date + 2.days + 23.hours + 59.minutes + 59.seconds) expect(data[8]).to include(event_type: 'weight', issue_id: issue3.id, weight: 1, created_at: start_date + 2.days)
expect(data[9]).to include(event_type: 'milestone', action: 'add', issue_id: issue3.id, milestone_id: milestone2.id, created_at: start_date + 3.days) expect(data[9]).to include(event_type: 'milestone', action: 'remove', issue_id: issue3.id, milestone_id: milestone1.id, created_at: start_date + 2.days + 1.second)
expect(data[10]).to include(event_type: 'milestone', action: 'remove', issue_id: issue3.id, milestone_id: milestone2.id, created_at: start_date + 4.days) expect(data[10]).to include(event_type: 'weight', issue_id: issue3.id, weight: 2, created_at: start_date + 2.days + 23.hours + 59.minutes + 59.seconds)
expect(data[11]).to include(event_type: 'weight', issue_id: issue3.id, weight: 7, created_at: start_date + 4.days + 1.second) expect(data[11]).to include(event_type: 'milestone', action: 'add', issue_id: issue3.id, milestone_id: milestone2.id, created_at: start_date + 3.days)
expect(data[12]).to include(event_type: 'state', issue_id: issue3.id, state: 'opened', created_at: start_date + 3.days + 1.second)
expect(data[13]).to include(event_type: 'state', issue_id: issue3.id, state: 'closed', created_at: start_date + 3.days + 23.hours + 59.minutes + 58.seconds)
expect(data[14]).to include(event_type: 'milestone', action: 'remove', issue_id: issue3.id, milestone_id: milestone2.id, created_at: start_date + 4.days)
expect(data[15]).to include(event_type: 'weight', issue_id: issue3.id, weight: 7, created_at: start_date + 4.days + 1.second)
expect(data[16]).to include(event_type: 'state', issue_id: issue3.id, state: 'reopened', created_at: start_date + 4.days + 2.seconds)
end end
it 'excludes issues which should not be visible to the user ' do it 'excludes issues which should not be visible to the user ' do
......
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