Commit a357dc82 authored by Simon Knox's avatar Simon Knox Committed by Heinrich Lee Yu

[Feature flag] Remove burnup_charts and iteration_charts

parent c0f7c071
...@@ -5,9 +5,6 @@ class Groups::MilestonesController < Groups::ApplicationController ...@@ -5,9 +5,6 @@ class Groups::MilestonesController < Groups::ApplicationController
before_action :milestone, only: [:edit, :show, :update, :issues, :merge_requests, :participants, :labels, :destroy] before_action :milestone, only: [:edit, :show, :update, :issues, :merge_requests, :participants, :labels, :destroy]
before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update, :destroy] before_action :authorize_admin_milestones!, only: [:edit, :new, :create, :update, :destroy]
before_action do
push_frontend_feature_flag(:burnup_charts, @group, default_enabled: true)
end
feature_category :issue_tracking feature_category :issue_tracking
......
...@@ -6,9 +6,6 @@ class Projects::MilestonesController < Projects::ApplicationController ...@@ -6,9 +6,6 @@ class Projects::MilestonesController < Projects::ApplicationController
before_action :check_issuables_available! before_action :check_issuables_available!
before_action :milestone, only: [:edit, :update, :destroy, :show, :issues, :merge_requests, :participants, :labels, :promote] before_action :milestone, only: [:edit, :update, :destroy, :show, :issues, :merge_requests, :participants, :labels, :promote]
before_action do
push_frontend_feature_flag(:burnup_charts, @project, default_enabled: true)
end
# Allow read any milestone # Allow read any milestone
before_action :authorize_read_milestone! before_action :authorize_read_milestone!
......
---
name: burnup_charts
introduced_by_url:
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/268350
milestone: '13.6'
type: development
group: group::project management
default_enabled: true
...@@ -76,12 +76,7 @@ To view an iteration report, go to the iterations list page and click an iterati ...@@ -76,12 +76,7 @@ To view an iteration report, go to the iterations list page and click an iterati
### Iteration burndown and burnup charts ### Iteration burndown and burnup charts
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222750) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/222750) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.5.
> - It was deployed behind a feature flag, disabled by default. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/269972) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.7.
> - [Became enabled by default](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/45492) on GitLab 13.6.
> - It's enabled on GitLab.com.
> - It's able to be enabled or disabled per-group.
> - It's recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#disable-iteration-charts). **(STARTER ONLY)**
The iteration report includes [burndown and burnup charts](../../project/milestones/burndown_and_burnup_charts.md), The iteration report includes [burndown and burnup charts](../../project/milestones/burndown_and_burnup_charts.md),
similar to how they appear when viewing a [milestone](../../project/milestones/index.md). similar to how they appear when viewing a [milestone](../../project/milestones/index.md).
...@@ -113,30 +108,6 @@ Feature.disable(:group_iterations) ...@@ -113,30 +108,6 @@ Feature.disable(:group_iterations)
Feature.disable(:group_iterations, Group.find(<group ID>)) Feature.disable(:group_iterations, Group.find(<group ID>))
``` ```
## Disable iteration charts **(STARTER ONLY)**
GitLab iteration charts feature is deployed with a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
can disable it for your instance. `:iteration_charts` can be enabled or disabled per-group.
To enable it:
```ruby
# Instance-wide
Feature.enable(:iteration_charts)
# or by group
Feature.enable(:iteration_charts, Group.find(<group ID>))
```
To disable it:
```ruby
# Instance-wide
Feature.disable(:iteration_charts)
# or by group
Feature.disable(:iteration_charts, Group.find(<group ID>))
```
<!-- ## Troubleshooting <!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
...@@ -104,13 +104,7 @@ Reopened issues are considered as having been opened on the day after they were ...@@ -104,13 +104,7 @@ Reopened issues are considered as having been opened on the day after they were
## Burnup charts ## Burnup charts
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.6. > - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/6903) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.6.
> - It's [deployed behind a feature flag](../../feature_flags.md), enabled by default. > - [Feature flag removed](https://gitlab.com/gitlab-org/gitlab/-/issues/268350) in [GitLab Starter](https://about.gitlab.com/pricing/) 13.7.
> - It's enabled on GitLab.com.
> - It's recommended for production use.
> - For GitLab self-managed instances, GitLab administrators can opt to [disable it](#enable-or-disable-burnup-charts). **(STARTER ONLY)**
CAUTION: **Warning:**
This feature might not be available to you. Check the **version history** note above for details.
Burnup charts show the assigned and completed work for a milestone. Burnup charts show the assigned and completed work for a milestone.
...@@ -136,25 +130,6 @@ Burnup charts can show either the total number of issues or total weight for eac ...@@ -136,25 +130,6 @@ Burnup charts can show either the total number of issues or total weight for eac
day of the milestone. Use the toggle above the charts to switch between total day of the milestone. Use the toggle above the charts to switch between total
and weight. and weight.
### Enable or disable burnup charts **(STARTER ONLY)**
Burnup charts is under development but ready for production use.
It is deployed behind a feature flag that is **enabled by default**.
[GitLab administrators with access to the GitLab Rails console](../../../administration/feature_flags.md)
can opt to disable it.
To enable it:
```ruby
Feature.enable(:burnup_charts)
```
To disable it:
```ruby
Feature.disable(:burnup_charts)
```
<!-- ## Troubleshooting <!-- ## Troubleshooting
Include any troubleshooting steps that you can foresee. If you know beforehand what issues Include any troubleshooting steps that you can foresee. If you know beforehand what issues
......
...@@ -54,7 +54,7 @@ export default { ...@@ -54,7 +54,7 @@ export default {
apollo: { apollo: {
burnupData: { burnupData: {
skip() { skip() {
return !this.glFeatures.burnupCharts || (!this.milestoneId && !this.iterationId); return !this.milestoneId && !this.iterationId;
}, },
query: BurnupQuery, query: BurnupQuery,
variables() { variables() {
...@@ -79,7 +79,7 @@ export default { ...@@ -79,7 +79,7 @@ export default {
openIssuesWeight: [], openIssuesWeight: [],
issuesSelected: true, issuesSelected: true,
burnupData: [], burnupData: [],
useLegacyBurndown: !this.glFeatures.burnupCharts, useLegacyBurndown: false,
showInfo: this.showNewOldBurndownToggle, showInfo: this.showNewOldBurndownToggle,
error: '', error: '',
}; };
...@@ -89,7 +89,7 @@ export default { ...@@ -89,7 +89,7 @@ export default {
return this.iterationId ? 'iteration' : 'milestone'; return this.iterationId ? 'iteration' : 'milestone';
}, },
title() { title() {
return this.glFeatures.burnupCharts ? __('Charts') : __('Burndown chart'); return __('Charts');
}, },
issueButtonCategory() { issueButtonCategory() {
return this.issuesSelected ? 'primary' : 'secondary'; return this.issuesSelected ? 'primary' : 'secondary';
...@@ -110,11 +110,6 @@ export default { ...@@ -110,11 +110,6 @@ export default {
return this.pluckBurnupDataProperties('scopeWeight', 'completedWeight'); return this.pluckBurnupDataProperties('scopeWeight', 'completedWeight');
}, },
}, },
mounted() {
if (!this.glFeatures.burnupCharts) {
this.fetchLegacyBurndownEvents();
}
},
methods: { methods: {
fetchLegacyBurndownEvents() { fetchLegacyBurndownEvents() {
this.fetchedLegacyData = true; this.fetchedLegacyData = true;
...@@ -230,12 +225,7 @@ export default { ...@@ -230,12 +225,7 @@ export default {
<template> <template>
<div> <div>
<gl-alert <gl-alert v-if="showInfo" variant="info" class="col-12 gl-mt-3" @dismiss="showInfo = false">
v-if="glFeatures.burnupCharts && showInfo"
variant="info"
class="col-12 gl-mt-3"
@dismiss="showInfo = false"
>
<gl-sprintf <gl-sprintf
:message=" :message="
__( __(
...@@ -272,7 +262,7 @@ export default { ...@@ -272,7 +262,7 @@ export default {
</gl-button> </gl-button>
</gl-button-group> </gl-button-group>
<gl-button-group v-if="glFeatures.burnupCharts && showNewOldBurndownToggle"> <gl-button-group v-if="showNewOldBurndownToggle">
<gl-button <gl-button
ref="oldBurndown" ref="oldBurndown"
:category="useLegacyBurndown ? 'primary' : 'secondary'" :category="useLegacyBurndown ? 'primary' : 'secondary'"
...@@ -293,7 +283,7 @@ export default { ...@@ -293,7 +283,7 @@ export default {
</gl-button> </gl-button>
</gl-button-group> </gl-button-group>
</div> </div>
<div v-if="glFeatures.burnupCharts" class="row"> <div class="row">
<gl-alert v-if="error" variant="danger" class="col-12" @dismiss="error = ''"> <gl-alert v-if="error" variant="danger" class="col-12" @dismiss="error = ''">
{{ error }} {{ error }}
</gl-alert> </gl-alert>
...@@ -313,14 +303,5 @@ export default { ...@@ -313,14 +303,5 @@ export default {
class="col-md-6" class="col-md-6"
/> />
</div> </div>
<burndown-chart
v-else
:show-title="false"
:start-date="startDate"
:due-date="dueDate"
:open-issues-count="openIssuesCount"
:open-issues-weight="openIssuesWeight"
:issues-selected="issuesSelected"
/>
</div> </div>
</template> </template>
...@@ -220,7 +220,6 @@ export default { ...@@ -220,7 +220,6 @@ export default {
:namespace-type="namespaceType" :namespace-type="namespaceType"
/> />
<burn-charts <burn-charts
v-if="glFeatures.iterationCharts && glFeatures.burnupCharts"
:start-date="iteration.startDate" :start-date="iteration.startDate"
:due-date="iteration.dueDate" :due-date="iteration.dueDate"
:iteration-id="iteration.id" :iteration-id="iteration.id"
......
...@@ -4,10 +4,6 @@ class Groups::IterationsController < Groups::ApplicationController ...@@ -4,10 +4,6 @@ class Groups::IterationsController < Groups::ApplicationController
before_action :check_iterations_available! before_action :check_iterations_available!
before_action :authorize_show_iteration!, only: [:index, :show] before_action :authorize_show_iteration!, only: [:index, :show]
before_action :authorize_create_iteration!, only: [:new, :edit] before_action :authorize_create_iteration!, only: [:new, :edit]
before_action do
push_frontend_feature_flag(:iteration_charts, group, default_enabled: true)
push_frontend_feature_flag(:burnup_charts, group, default_enabled: true)
end
feature_category :issue_tracking feature_category :issue_tracking
......
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
class Projects::Iterations::InheritedController < Projects::ApplicationController class Projects::Iterations::InheritedController < Projects::ApplicationController
before_action :check_iterations_available! before_action :check_iterations_available!
before_action :authorize_show_iteration! before_action :authorize_show_iteration!
before_action do
push_frontend_feature_flag(:iteration_charts, project, default_enabled: true)
push_frontend_feature_flag(:burnup_charts, project, default_enabled: true)
end
feature_category :issue_tracking feature_category :issue_tracking
......
...@@ -3,10 +3,6 @@ ...@@ -3,10 +3,6 @@
class Projects::IterationsController < Projects::ApplicationController class Projects::IterationsController < Projects::ApplicationController
before_action :check_iterations_available! before_action :check_iterations_available!
before_action :authorize_show_iteration! before_action :authorize_show_iteration!
before_action do
push_frontend_feature_flag(:iteration_charts, project, default_enabled: true)
push_frontend_feature_flag(:burnup_charts, project, default_enabled: true)
end
feature_category :issue_tracking feature_category :issue_tracking
......
...@@ -7,8 +7,6 @@ module Resolvers ...@@ -7,8 +7,6 @@ module Resolvers
alias_method :timebox, :synchronized_object alias_method :timebox, :synchronized_object
def resolve(*args) def resolve(*args)
return {} unless timebox.burnup_charts_available?
response = TimeboxReportService.new(timebox).execute response = TimeboxReportService.new(timebox).execute
raise GraphQL::ExecutionError, response.message if response.error? raise GraphQL::ExecutionError, response.message if response.error?
......
...@@ -46,10 +46,6 @@ module EE ...@@ -46,10 +46,6 @@ module EE
resource_parent&.feature_available?(:iterations) && weight_available? resource_parent&.feature_available?(:iterations) && weight_available?
end end
def burnup_charts_available?
::Feature.enabled?(:iteration_charts, resource_parent, default_enabled: true)
end
private private
def timebox_format_reference(format = :id) def timebox_format_reference(format = :id)
......
...@@ -15,9 +15,5 @@ module EE ...@@ -15,9 +15,5 @@ module EE
end end
alias_method :supports_timebox_charts?, :supports_milestone_charts? alias_method :supports_timebox_charts?, :supports_milestone_charts?
def burnup_charts_available?
::Feature.enabled?(:burnup_charts, resource_parent, default_enabled: true)
end
end end
end end
---
name: iteration_charts
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/41280
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/229046
milestone: '13.4'
type: development
group: group::project management
default_enabled: true
...@@ -52,20 +52,6 @@ RSpec.describe 'Burnup charts', :js do ...@@ -52,20 +52,6 @@ RSpec.describe 'Burnup charts', :js do
end end
end end
describe 'feature flag disabled' do
before do
stub_licensed_features(milestone_charts: true)
stub_feature_flags(burnup_charts: false)
end
it 'only shows burndown chart' do
visit group_milestone_path(milestone.group, milestone)
expect(page).to have_selector(burndown_chart_selector)
expect(page).not_to have_selector(burnup_chart_selector)
end
end
def burnup_chart_points def burnup_chart_points
fill_color = "#5772ff" fill_color = "#5772ff"
burnup_chart.all("path[fill='#{fill_color}']", count: 12) burnup_chart.all("path[fill='#{fill_color}']", count: 12)
......
...@@ -6,8 +6,7 @@ import BurnCharts from 'ee/burndown_chart/components/burn_charts.vue'; ...@@ -6,8 +6,7 @@ import BurnCharts from 'ee/burndown_chart/components/burn_charts.vue';
import BurndownChart from 'ee/burndown_chart/components/burndown_chart.vue'; import BurndownChart from 'ee/burndown_chart/components/burndown_chart.vue';
import BurnupChart from 'ee/burndown_chart/components/burnup_chart.vue'; import BurnupChart from 'ee/burndown_chart/components/burnup_chart.vue';
import { useFakeDate } from 'helpers/fake_date'; import { useFakeDate } from 'helpers/fake_date';
import waitForPromises from 'helpers/wait_for_promises'; import { day1, day2, day3, day4 } from '../mock_data';
import { day1, day2, day3, day4, legacyBurndownEvents } from '../mock_data';
function fakeDate({ date }) { function fakeDate({ date }) {
const [year, month, day] = date.split('-'); const [year, month, day] = date.split('-');
...@@ -37,7 +36,7 @@ describe('burndown_chart', () => { ...@@ -37,7 +36,7 @@ describe('burndown_chart', () => {
burndownEventsPath: '/api/v4/projects/1234/milestones/1/burndown_events', burndownEventsPath: '/api/v4/projects/1234/milestones/1/burndown_events',
}; };
const createComponent = ({ props = {}, featureEnabled = false, data = {} } = {}) => { const createComponent = ({ props = {}, data = {} } = {}) => {
wrapper = shallowMount(BurnCharts, { wrapper = shallowMount(BurnCharts, {
propsData: { propsData: {
...defaultProps, ...defaultProps,
...@@ -46,9 +45,6 @@ describe('burndown_chart', () => { ...@@ -46,9 +45,6 @@ describe('burndown_chart', () => {
data() { data() {
return data; return data;
}, },
provide: {
glFeatures: { burnupCharts: featureEnabled },
},
}); });
}; };
...@@ -58,6 +54,7 @@ describe('burndown_chart', () => { ...@@ -58,6 +54,7 @@ describe('burndown_chart', () => {
afterEach(() => { afterEach(() => {
mock.restore(); mock.restore();
wrapper.destroy();
}); });
it('includes Issues and Issue weight buttons', () => { it('includes Issues and Issue weight buttons', () => {
...@@ -95,136 +92,61 @@ describe('burndown_chart', () => { ...@@ -95,136 +92,61 @@ describe('burndown_chart', () => {
expect(findBurndownChart().props('issuesSelected')).toBe(false); expect(findBurndownChart().props('issuesSelected')).toBe(false);
}); });
describe('feature disabled', () => { it('reduces width of burndown chart', () => {
beforeEach(() => { createComponent();
fakeDate(day4);
mock.onGet(defaultProps.burndownEventsPath).reply(200, legacyBurndownEvents);
createComponent({ featureEnabled: false });
});
it('calls fetchLegacyBurndownEvents when mounted', async () => {
await waitForPromises();
await wrapper.vm.$nextTick();
await wrapper.vm.$nextTick();
expect(findBurndownChart().props().openIssuesCount).toEqual([
[defaultProps.startDate, 0],
[day1.date, 1],
[day2.date, 2],
[day3.date, 3],
[day4.date, 2],
]);
expect(findBurndownChart().props().openIssuesWeight).toEqual([
[defaultProps.startDate, 0],
[day1.date, 2],
[day2.date, 3],
[day3.date, 4],
[day4.date, 2],
]);
});
it('does not reduce width of burndown chart', () => {
expect(findBurndownChart().classes()).toEqual([]);
});
it('sets section title and chart title correctly', () => {
expect(findChartsTitle().text()).toBe('Burndown chart');
expect(findBurndownChart().props().showTitle).toBe(false);
});
it('does not show old/new burndown buttons', () => {
expect(findOldBurndownChartButton().exists()).toBe(false);
expect(findNewBurndownChartButton().exists()).toBe(false);
});
it('uses count and weight from data', () => {
const expectedCount = [day2.date, day2.scopeCount];
const expectedWeight = [day2.date, day2.scopeWeight];
createComponent({ expect(findBurndownChart().classes()).toContain('col-md-6');
data: { });
burnupData: [day1],
openIssuesCount: [expectedCount],
openIssuesWeight: [expectedWeight],
},
props: {
milestoneId: '1234',
},
featureEnabled: false,
});
const { openIssuesCount, openIssuesWeight } = findBurndownChart().props(); it('sets section title and chart title correctly', () => {
createComponent();
expect(openIssuesCount).toEqual([expectedCount]); expect(findChartsTitle().text()).toBe('Charts');
expect(openIssuesWeight).toEqual([expectedWeight]); expect(findBurndownChart().props().showTitle).toBe(true);
});
}); });
describe('feature enabled', () => { it('sets weight prop of burnup chart', async () => {
beforeEach(() => { createComponent();
createComponent({ featureEnabled: true });
});
it('reduces width of burndown chart', () => {
expect(findBurndownChart().classes()).toContain('col-md-6');
});
it('sets section title and chart title correctly', () => { findWeightButton().vm.$emit('click');
expect(findChartsTitle().text()).toBe('Charts');
expect(findBurndownChart().props().showTitle).toBe(true);
});
it('sets weight prop of burnup chart', async () => { await wrapper.vm.$nextTick();
findWeightButton().vm.$emit('click');
await wrapper.vm.$nextTick(); expect(findBurnupChart().props('issuesSelected')).toBe(false);
});
expect(findBurnupChart().props('issuesSelected')).toBe(false); it('uses burndown data computed from burnup data', () => {
createComponent({
data: {
burnupData: [day1],
},
}); });
const { openIssuesCount, openIssuesWeight } = findBurndownChart().props();
it('uses burndown data computed from burnup data', () => { const expectedCount = [day1.date, day1.scopeCount - day1.completedCount];
createComponent({ const expectedWeight = [day1.date, day1.scopeWeight - day1.completedWeight];
data: {
burnupData: [day1],
},
featureEnabled: true,
});
const { openIssuesCount, openIssuesWeight } = findBurndownChart().props();
const expectedCount = [day1.date, day1.scopeCount - day1.completedCount]; expect(openIssuesCount).toEqual([expectedCount]);
const expectedWeight = [day1.date, day1.scopeWeight - day1.completedWeight]; expect(openIssuesWeight).toEqual([expectedWeight]);
expect(openIssuesCount).toEqual([expectedCount]);
expect(openIssuesWeight).toEqual([expectedWeight]);
});
}); });
describe('showNewOldBurndownToggle', () => { describe('showNewOldBurndownToggle', () => {
it('hides old/new burndown buttons if feature disabled', () => {
createComponent({ featureEnabled: false, props: { showNewOldBurndownToggle: true } });
expect(findOldBurndownChartButton().exists()).toBe(false);
expect(findNewBurndownChartButton().exists()).toBe(false);
});
it('hides old/new burndown buttons if props is false', () => { it('hides old/new burndown buttons if props is false', () => {
createComponent({ featureEnabled: true, props: { showNewOldBurndownToggle: false } }); createComponent({ props: { showNewOldBurndownToggle: false } });
expect(findOldBurndownChartButton().exists()).toBe(false); expect(findOldBurndownChartButton().exists()).toBe(false);
expect(findNewBurndownChartButton().exists()).toBe(false); expect(findNewBurndownChartButton().exists()).toBe(false);
}); });
it('shows old/new burndown buttons if prop true', () => { it('shows old/new burndown buttons if prop true', () => {
createComponent({ featureEnabled: true, props: { showNewOldBurndownToggle: true } }); createComponent({ props: { showNewOldBurndownToggle: true } });
expect(findOldBurndownChartButton().exists()).toBe(true); expect(findOldBurndownChartButton().exists()).toBe(true);
expect(findNewBurndownChartButton().exists()).toBe(true); expect(findNewBurndownChartButton().exists()).toBe(true);
}); });
it('calls fetchLegacyBurndownEvents, but only once', () => { it('calls fetchLegacyBurndownEvents, but only once', () => {
createComponent({ featureEnabled: true, props: { showNewOldBurndownToggle: true } }); createComponent({ props: { showNewOldBurndownToggle: true } });
jest.spyOn(wrapper.vm, 'fetchLegacyBurndownEvents'); jest.spyOn(wrapper.vm, 'fetchLegacyBurndownEvents');
mock.onGet(defaultProps.burndownEventsPath).reply(200, []); mock.onGet(defaultProps.burndownEventsPath).reply(200, []);
...@@ -239,7 +161,6 @@ describe('burndown_chart', () => { ...@@ -239,7 +161,6 @@ describe('burndown_chart', () => {
beforeEach(() => { beforeEach(() => {
createComponent({ createComponent({
props: { startDate: day1.date, dueDate: day4.date }, props: { startDate: day1.date, dueDate: day4.date },
featureEnabled: true,
}); });
fakeDate(day4); fakeDate(day4);
......
...@@ -18,54 +18,38 @@ RSpec.describe Resolvers::TimeboxReportResolver do ...@@ -18,54 +18,38 @@ RSpec.describe Resolvers::TimeboxReportResolver do
RSpec.shared_examples 'timebox time series' do RSpec.shared_examples 'timebox time series' do
subject { resolve(described_class, obj: timebox) } subject { resolve(described_class, obj: timebox) }
context 'when the feature flag is disabled' do it 'returns burnup chart data' do
before do expect(subject).to eq(
stub_feature_flags(burnup_charts: false, iteration_charts: false) stats: {
end complete: { count: 0, weight: 0 },
incomplete: { count: 2, weight: 0 },
it 'returns empty data' do total: { count: 2, weight: 0 }
expect(subject).to be_empty },
end burnup_time_series: [
{
date: start_date + 4.days,
scope_count: 1,
scope_weight: 0,
completed_count: 0,
completed_weight: 0
},
{
date: start_date + 9.days,
scope_count: 2,
scope_weight: 0,
completed_count: 0,
completed_weight: 0
}
])
end end
context 'when the feature flag is enabled' do context 'when the service returns an error' do
before do before do
stub_feature_flags(burnup_charts: true, iteration_charts: true) stub_const('TimeboxReportService::EVENT_COUNT_LIMIT', 1)
end end
it 'returns burnup chart data' do it 'raises a GraphQL exception' do
expect(subject).to eq( expect { subject }.to raise_error(GraphQL::ExecutionError, 'Burnup chart could not be generated due to too many events')
stats: {
complete: { count: 0, weight: 0 },
incomplete: { count: 2, weight: 0 },
total: { count: 2, weight: 0 }
},
burnup_time_series: [
{
date: start_date + 4.days,
scope_count: 1,
scope_weight: 0,
completed_count: 0,
completed_weight: 0
},
{
date: start_date + 9.days,
scope_count: 2,
scope_weight: 0,
completed_count: 0,
completed_weight: 0
}
])
end
context 'when the service returns an error' do
before do
stub_const('TimeboxReportService::EVENT_COUNT_LIMIT', 1)
end
it 'raises a GraphQL exception' do
expect { subject }.to raise_error(GraphQL::ExecutionError, 'Burnup chart could not be generated due to too many events')
end
end end
end end
end end
......
...@@ -40,58 +40,39 @@ RSpec.describe 'Querying a Milestone' do ...@@ -40,58 +40,39 @@ RSpec.describe 'Querying a Milestone' do
create(:resource_milestone_event, issue: issue, milestone: milestone, action: :add, created_at: '2020-01-05') create(:resource_milestone_event, issue: issue, milestone: milestone, action: :add, created_at: '2020-01-05')
end end
context 'when feature flag is enabled' do context 'with insufficient license' do
before do before do
stub_feature_flags(burnup_charts: true) stub_licensed_features(milestone_charts: false)
end end
context 'with insufficient license' do it 'returns an error' do
before do post_graphql(query, current_user: current_user)
stub_licensed_features(milestone_charts: false)
end
it 'returns an error' do
post_graphql(query, current_user: current_user)
expect(graphql_errors).to include(a_hash_including('message' => 'Milestone does not support burnup charts'))
end
end
context 'with correct license' do
before do
stub_licensed_features(milestone_charts: true, issue_weights: true)
end
it 'returns burnup chart data' do
post_graphql(query, current_user: current_user)
expect(subject).to eq({ expect(graphql_errors).to include(a_hash_including('message' => 'Milestone does not support burnup charts'))
'report' => {
'burnupTimeSeries' => [
{
'date' => '2020-01-05',
'scopeCount' => 1,
'scopeWeight' => 0,
'completedCount' => 0,
'completedWeight' => 0
}
]
}
})
end
end end
end end
context 'when feature flag is disabled' do context 'with correct license' do
before do before do
stub_feature_flags(burnup_charts: false)
stub_licensed_features(milestone_charts: true, issue_weights: true) stub_licensed_features(milestone_charts: true, issue_weights: true)
end end
it 'returns empty results' do it 'returns burnup chart data' do
post_graphql(query, current_user: current_user) post_graphql(query, current_user: current_user)
expect(subject).to eq({ 'report' => { 'burnupTimeSeries' => nil } }) expect(subject).to eq({
'report' => {
'burnupTimeSeries' => [
{
'date' => '2020-01-05',
'scopeCount' => 1,
'scopeWeight' => 0,
'completedCount' => 0,
'completedWeight' => 0
}
]
}
})
end end
end end
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