Commit 028be8b7 authored by Felipe Artur's avatar Felipe Artur

Burndown Chart backend implementation

parent 77b8bac1
......@@ -39,6 +39,7 @@ class Projects::MilestonesController < Projects::ApplicationController
end
def show
@burndown = Burndown.new(@milestone)
end
def create
......
class Burndown
attr_accessor :start_date, :end_date, :open_issues_count, :open_issues_weight
def initialize(milestone)
@milestone = milestone
@start_date = @milestone.start_date
@end_date = @milestone.due_date
open_issues = @milestone.issues.opened
@open_issues_count = open_issues.count
@open_issues_weight = open_issues.sum(:weight)
end
def closed_issues
return {} unless @start_date && @end_date
Hash[
get_count.map do |row|
[row.date.strftime('%d %b'), [row.count, row.weight]]
end
]
end
private
def get_count
start_date = @start_date.to_time.beginning_of_day
end_date = @end_date.to_time.end_of_day
@milestone.issues.
select("DATE_TRUNC('day', closed_at) AS date, COUNT(*) AS count, SUM(weight) as weight").
where('closed_at BETWEEN (?) AND (?) AND state = ?', start_date, end_date, 'closed').
group(1).reorder(1)
end
end
---
title: Add burndown chart to milestones
merge_request:
author:
require './spec/support/sidekiq'
require './spec/support/test_env'
class Gitlab::Seeder::Burndown
def initialize(project, perf: false)
@project = project
end
def seed!
Sidekiq::Testing.inline! do
create_milestone
puts '.'
create_issues
puts '.'
close_issues
puts '.'
end
print '.'
end
private
def create_milestone
milestone_params = {
title: "Sprint - #{FFaker::Lorem.sentence}",
description: FFaker::Lorem.sentence,
state: 'active',
start_date: Date.today,
due_date: rand(15..30).days.from_now
}
@milestone = Milestones::CreateService.new(@project, @project.team.users.sample, milestone_params).execute
end
def create_issues
40.times do
issue_params = {
title: FFaker::Lorem.sentence(6),
description: FFaker::Lorem.sentence,
state: 'opened',
milestone: @milestone,
assignee: @project.team.users.sample
}
Issues::CreateService.new(@project, @project.team.users.sample, issue_params).execute
end
end
def close_issues
@milestone.start_date.upto(@milestone.due_date) do |date|
Timecop.travel(date)
close_number = rand(1..3)
open_issues = @milestone.issues.where(state: "opened")
open_issues = open_issues.slice(0..close_number)
open_issues.each do |issue|
Issues::CloseService.new(@project, @project.team.users.sample, {}).execute(issue)
end
end
Timecop.return
end
end
Gitlab::Seeder.quiet do
if project_id = ENV['PROJECT_ID']
project = Project.find(project_id)
seeder = Gitlab::Seeder::Burndown.new(project)
seeder.seed!
else
Project.all.each do |project|
seeder = Gitlab::Seeder::Burndown.new(project)
seeder.seed!
end
end
end
require 'spec_helper'
describe Burndown, models: true do
let(:range) { 10 }
let(:milestone) { create(:milestone, start_date: range.days.ago, due_date: Date.today) }
let(:project) { milestone.project }
let(:user) { create(:user) }
before do
project.add_master(user)
@closed_by_date = {}
range.times do |i|
date = i.days.ago
@closed_by_date[date] ||= []
issue_params = {
title: FFaker::Lorem.sentence(6),
description: FFaker::Lorem.sentence,
state: 'closed',
milestone: milestone,
closed_at: date,
weight: rand(9)
}
rand(1..4).times do |i|
@closed_by_date[date] << Issues::CreateService.new(project, user, issue_params).execute
end
end
end
subject { described_class.new(milestone).closed_issues }
it "groups count and weight by closed_at" do
sample =
Hash[
@closed_by_date.sort.map do |k, v|
[k.strftime('%d %b'), [v.count, v.map { |issues| issues.weight }.sum]]
end
]
expect(sample).to eq(subject)
end
end
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