Commit dd144109 authored by Patrick Derichs's avatar Patrick Derichs

Add state events to burnup chart data

Also update schema and add specs.
parent 92864ce5
......@@ -9,6 +9,7 @@ class BurnupChartService
WEIGHT = 'value'.freeze
ACTION = 'action'.freeze
ISSUE_ID = 'issue_id'.freeze
STATE = 'value'.freeze
def initialize(milestone:, user:)
@user = user
......@@ -64,7 +65,7 @@ class BurnupChartService
end
def all_events
[milestone_events, weight_events]
[milestone_events, weight_events, state_events]
end
def weight_events
......@@ -77,6 +78,11 @@ class BurnupChartService
.select('\'milestone\' as event_type, created_at, milestone_id as value, action, issue_id')
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)
{
event_type: event[EVENT_TYPE],
......@@ -84,10 +90,17 @@ class BurnupChartService
action: action_of(event),
milestone_id: milestone_id_of(event, assigned_milestones),
issue_id: event[ISSUE_ID],
weight: weight_of(event)
weight: weight_of(event),
state: state_of(event)
}
end
def state_of(event)
return unless state_event?(event)
ResourceStateEvent.states.key(event[STATE])
end
def action_of(event)
return unless milestone_event?(event)
......@@ -111,6 +124,8 @@ class BurnupChartService
end
def milestone_id_of(event, assigned_milestones)
return unless milestone_event?(event)
if remove_milestone?(event) && event[MILESTONE_ID].nil?
return assigned_milestones[event[ISSUE_ID]]
end
......@@ -134,6 +149,10 @@ class BurnupChartService
event[EVENT_TYPE] == 'milestone'
end
def state_event?(event)
event[EVENT_TYPE] == 'state'
end
# rubocop: disable CodeReuse/ActiveRecord
def relevant_issue_ids
# 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 @@
],
"properties": {
"event_type": {
"type": { "enum": [ "milestone", "weight" ] }
"type": { "enum": [ "milestone", "weight", "state" ] }
},
"weight": {
"type": ["integer", "null"]
......@@ -17,6 +17,9 @@
"milestone_id": {
"type": ["integer", "null"]
},
"state": {
"type": ["string", "null"]
},
"issue_id": {
"type": "integer"
},
......
......@@ -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(: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
project.add_maintainer(user)
end
......@@ -49,20 +55,25 @@ describe BurnupChartService do
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[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[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[5]).to include(event_type: 'milestone', action: 'add', issue_id: issue3.id, milestone_id: milestone1.id, created_at: start_date + 1.day)
expect(data[6]).to include(event_type: 'weight', issue_id: issue3.id, weight: 1, created_at: start_date + 2.days)
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[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[9]).to include(event_type: 'milestone', action: 'add', issue_id: issue3.id, milestone_id: milestone2.id, created_at: start_date + 3.days)
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[11]).to include(event_type: 'weight', issue_id: issue3.id, weight: 7, created_at: start_date + 4.days + 1.second)
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: 'state', issue_id: issue2.id, state: 'closed', created_at: start_date + 6.seconds)
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: 1, created_at: start_date + 2.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: '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: '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
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