diff --git a/src/helpers/types.ts b/src/helpers/types.ts index cbf41e49c6076d0744cfa309be5348d17d231517..2e4bc66cf658765d3a2f83911b253e0158362728 100644 --- a/src/helpers/types.ts +++ b/src/helpers/types.ts @@ -112,8 +112,8 @@ export type Issue = { state: StateGL; created_at: string; updated_at: string; - closed_at: string; - closed_by: string; + closed_at: string | null; + closed_by: string | null; labels: string[]; milestone: Milestone; assignees: []; diff --git a/src/tests/App.test.tsx b/src/tests/App.test.tsx deleted file mode 100644 index 9c7faf5092a3218f8c68194cb0392280a08f8886..0000000000000000000000000000000000000000 --- a/src/tests/App.test.tsx +++ /dev/null @@ -1,10 +0,0 @@ -import { render } from '@testing-library/react'; -import React from 'react'; -import App from '../App'; - -test('renders learn react link', () => { - render(<App />); - const a = true; - const b = true; - expect(a).toEqual(b); -}); diff --git a/src/tests/calculations.test.ts b/src/tests/calculations.test.ts new file mode 100644 index 0000000000000000000000000000000000000000..b80521522974a14fe8869b50635effb80a69fad6 --- /dev/null +++ b/src/tests/calculations.test.ts @@ -0,0 +1,28 @@ +import { BarDataItem } from '../helpers/types'; +import { avgTimePerIssueLabel } from './../pages/TimePerIssueLabelPage/utils'; +import { ISSUE_1, NON_CLOSED_ISSUES, NO_DATA, USED_LABELS } from './dummydata'; + +describe('Testing that the avgTimePerIssueLabel works as expected', () => { + test('Test that for an empty issuelist, an empty list is returned', () => { + const result = avgTimePerIssueLabel([], USED_LABELS); + expect(result).toEqual(NO_DATA); + }); + + test('Test that for a single issue, the time used for that issue is returned', () => { + const result = avgTimePerIssueLabel([ISSUE_1], USED_LABELS); + if (ISSUE_1.closed_at == null) return fail(); + const expected_ms = + new Date(ISSUE_1.closed_at).getTime() - new Date(ISSUE_1.created_at).getTime(); + const expected_h = expected_ms / (60 * 60 * 1000); + const expected: BarDataItem[] = NO_DATA.map((barItem) => ({ + ...barItem, + barValue: expected_h, + })); + expect(result).toEqual(expected); + }); + + test('Test that for a list of an issue with no closed issues, an empty list is returned', () => { + const result = avgTimePerIssueLabel(NON_CLOSED_ISSUES, USED_LABELS); + expect(result).toEqual(NO_DATA); + }); +}); diff --git a/src/tests/dummydata.ts b/src/tests/dummydata.ts new file mode 100644 index 0000000000000000000000000000000000000000..9c0ced15b0b3c8b6283cd7e83c8a1b8fae5eb47a --- /dev/null +++ b/src/tests/dummydata.ts @@ -0,0 +1,127 @@ +import { Label } from '../helpers/constants'; +import { BarDataItem, Issue } from '../helpers/types'; + +// Other created issues owerwrite this, as most is not used data. +const issueRest: Issue = { + id: 2, + iid: 2, + project_id: 2, + state: 'active', + title: 'Some issue', + description: '', + created_at: '', + closed_at: null, + labels: [''], + updated_at: '', + closed_by: '', + milestone: { + id: 2, + iid: 2, + project_id: '', + title: '', + description: '', + state: 'active', + created_at: '', + updated_at: '', + due_date: '', + start_date: '', + expired: '', + web_url: '', + }, + assignees: [], + author: { + id: 3, + name: 'hei', + username: 'hei', + state: 'active', + avatar_url: 'hei', + web_url: 'hei', + }, + type: 'ISSUE', + assignee: [], + user_notes_count: 2, + merge_requests_count: 2, + upvotes: 2, + downvotes: 2, + due_date: '', + confidential: false, + discussion_locked: null, + issue_type: 'issue', + web_url: '', + time_stats: { + time_estimate: 4, + total_time_spent: 4, + human_time_estimate: null, + human_total_time_spent: null, + }, + task_completion_status: { count: 5, completed_count: 5 }, + has_tasks: true, + _links: { self: 'hei', notes: 'hei', award_emoji: 'hei', project: 'hei' }, + references: { short: 'dfsf', relative: 'dfsf', full: 'dfsf' }, + moved_to_id: null, + service_desk_reply_to: null, +}; + +/* type IssueMatters = { + title: string; + description: string; + created_at: string; + closed_at: string; + labels: string[]; +}; */ + +export const ISSUE_1: Issue = { + ...issueRest, + created_at: '"2021-09-09T11:47:21.510+02:00"', + closed_at: '2021-09-27T13:30:39.518+02:00', + labels: [Label.API, Label.BROWSER_STORAGE, Label.IMPORTANT], +}; + +export const ISSUE_2: Issue = { + ...issueRest, + created_at: '"2021-09-01T11:47:21.510+02:00"', + closed_at: '2021-09-10T13:30:39.518+02:00', + labels: [Label.API], +}; + +export const ISSUE_3: Issue = { + ...issueRest, + created_at: '"2021-09-09T11:47:21.510+02:00"', + closed_at: '2021-09-11T13:30:39.518+02:00', + labels: [Label.BROWSER_STORAGE], +}; + +export const ISSUE_4: Issue = { + ...issueRest, + created_at: '"2021-09-08T11:47:21.510+02:00"', + closed_at: '2021-09-11T13:30:39.518+02:00', + labels: [Label.API], +}; + +export const ISSUE_5: Issue = { + ...issueRest, + created_at: '"2021-09-08T11:47:21.510+02:00"', + labels: [Label.BROWSER_STORAGE, Label.IMPORTANT], +}; + +export const ISSUE_6: Issue = { + ...issueRest, + created_at: '"2021-09-08T11:47:21.510+02:00"', + labels: [Label.IMPORTANT], +}; + +export const USED_LABELS = [Label.API, Label.BROWSER_STORAGE, Label.IMPORTANT]; + +export const ALL_ISSUES = [ISSUE_1, ISSUE_2, ISSUE_3, ISSUE_4, ISSUE_5, ISSUE_6]; + +export const NON_CLOSED_ISSUES = [ISSUE_5, ISSUE_6]; + +export const NO_DATA: BarDataItem[] = USED_LABELS.reduce((data: BarDataItem[], label) => { + return [ + ...data, + { + barLabel: label, + barValue: 0, + }, + ]; +}, []);