diff options
Diffstat (limited to 'spec/frontend/cycle_analytics/utils_spec.js')
-rw-r--r-- | spec/frontend/cycle_analytics/utils_spec.js | 129 |
1 files changed, 102 insertions, 27 deletions
diff --git a/spec/frontend/cycle_analytics/utils_spec.js b/spec/frontend/cycle_analytics/utils_spec.js index 73e26e1cdcc..15137bb0571 100644 --- a/spec/frontend/cycle_analytics/utils_spec.js +++ b/spec/frontend/cycle_analytics/utils_spec.js @@ -1,5 +1,22 @@ -import { decorateEvents, decorateData } from '~/cycle_analytics/utils'; -import { selectedStage, rawData, convertedData, rawEvents } from './mock_data'; +import { + decorateEvents, + decorateData, + transformStagesForPathNavigation, + timeSummaryForPathNavigation, + medianTimeToParsedSeconds, + formatMedianValues, + filterStagesByHiddenStatus, +} from '~/cycle_analytics/utils'; +import { + selectedStage, + rawData, + convertedData, + rawEvents, + allowedStages, + stageMedians, + pathNavIssueMetric, + rawStageMedians, +} from './mock_data'; describe('Value stream analytics utils', () => { describe('decorateEvents', () => { @@ -36,17 +53,6 @@ describe('Value stream analytics utils', () => { expect(result.summary).toEqual(convertedData.summary); }); - it('returns the stages data', () => { - expect(result.stages).toEqual(convertedData.stages); - }); - - it('returns each of the default value stream stages', () => { - const stages = result.stages.map(({ name }) => name); - ['issue', 'plan', 'code', 'test', 'review', 'staging'].forEach((stageName) => { - expect(stages).toContain(stageName); - }); - }); - it('returns `-` for summary data that has no value', () => { const singleSummaryResult = decorateData({ stats: [], @@ -55,23 +61,92 @@ describe('Value stream analytics utils', () => { }); expect(singleSummaryResult.summary).toEqual([{ value: '-', title: 'Commits' }]); }); + }); + + describe('transformStagesForPathNavigation', () => { + const stages = allowedStages; + const response = transformStagesForPathNavigation({ + stages, + medians: stageMedians, + selectedStage, + }); + + describe('transforms the data as expected', () => { + it('returns an array of stages', () => { + expect(Array.isArray(response)).toBe(true); + expect(response.length).toBe(stages.length); + }); + + it('selects the correct stage', () => { + const selected = response.filter((stage) => stage.selected === true)[0]; + + expect(selected.title).toBe(selectedStage.title); + }); + + it('includes the correct metric for the associated stage', () => { + const issue = response.filter((stage) => stage.name === 'issue')[0]; - it('returns additional fields for each stage', () => { - const singleStageResult = decorateData({ - stats: [{ name: 'issue', value: null }], - permissions: { issue: false }, + expect(issue.metric).toBe(pathNavIssueMetric); }); - const stage = singleStageResult.stages[0]; - const txt = - 'The issue stage shows the time it takes from creating an issue to assigning the issue to a milestone, or add the issue to a list on your Issue Board. Begin creating issues to see data for this stage.'; - - expect(stage).toMatchObject({ - active: false, - isUserAllowed: false, - emptyStageText: txt, - slug: 'issue', - component: 'stage-issue-component', + }); + }); + + describe('timeSummaryForPathNavigation', () => { + it.each` + unit | value | result + ${'months'} | ${1.5} | ${'1.5M'} + ${'weeks'} | ${1.25} | ${'1.5w'} + ${'days'} | ${2} | ${'2d'} + ${'hours'} | ${10} | ${'10h'} + ${'minutes'} | ${20} | ${'20m'} + ${'seconds'} | ${10} | ${'<1m'} + ${'seconds'} | ${0} | ${'-'} + `('will format $value $unit to $result', ({ unit, value, result }) => { + expect(timeSummaryForPathNavigation({ [unit]: value })).toBe(result); + }); + }); + + describe('medianTimeToParsedSeconds', () => { + it.each` + value | result + ${1036800} | ${'1w'} + ${259200} | ${'3d'} + ${172800} | ${'2d'} + ${86400} | ${'1d'} + ${1000} | ${'16m'} + ${61} | ${'1m'} + ${59} | ${'<1m'} + ${0} | ${'-'} + `('will correctly parse $value seconds into $result', ({ value, result }) => { + expect(medianTimeToParsedSeconds(value)).toBe(result); + }); + }); + + describe('formatMedianValues', () => { + const calculatedMedians = formatMedianValues(rawStageMedians); + + it('returns an object with each stage and their median formatted for display', () => { + rawStageMedians.forEach(({ id, value }) => { + expect(calculatedMedians).toMatchObject({ [id]: medianTimeToParsedSeconds(value) }); }); }); }); + + describe('filterStagesByHiddenStatus', () => { + const hiddenStages = [{ title: 'three', hidden: true }]; + const visibleStages = [ + { title: 'one', hidden: false }, + { title: 'two', hidden: false }, + ]; + const mockStages = [...visibleStages, ...hiddenStages]; + + it.each` + isHidden | result + ${false} | ${visibleStages} + ${undefined} | ${hiddenStages} + ${true} | ${hiddenStages} + `('with isHidden=$isHidden returns matching stages', ({ isHidden, result }) => { + expect(filterStagesByHiddenStatus(mockStages, isHidden)).toEqual(result); + }); + }); }); |