Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
1
Merge Requests
1
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
nexedi
gitlab-ce
Commits
18e04efc
Commit
18e04efc
authored
Jul 23, 2021
by
Ezekiel Kigbo
Committed by
Savas Vedova
Jul 23, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
VSA Stage ID mismatch in specs [RUN AS-IF-FOSS]
parent
64a920f2
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
199 additions
and
327 deletions
+199
-327
ee/spec/frontend/analytics/cycle_analytics/mock_data.js
ee/spec/frontend/analytics/cycle_analytics/mock_data.js
+17
-32
ee/spec/frontend/analytics/cycle_analytics/store/getters_spec.js
.../frontend/analytics/cycle_analytics/store/getters_spec.js
+2
-2
spec/frontend/cycle_analytics/base_spec.js
spec/frontend/cycle_analytics/base_spec.js
+2
-1
spec/frontend/cycle_analytics/mock_data.js
spec/frontend/cycle_analytics/mock_data.js
+28
-265
spec/frontend/cycle_analytics/stage_table_spec.js
spec/frontend/cycle_analytics/stage_table_spec.js
+33
-25
spec/frontend/cycle_analytics/store/mutations_spec.js
spec/frontend/cycle_analytics/store/mutations_spec.js
+4
-2
spec/frontend/fixtures/analytics.rb
spec/frontend/fixtures/analytics.rb
+113
-0
No files found.
ee/spec/frontend/analytics/cycle_analytics/mock_data.js
View file @
18e04efc
...
@@ -17,13 +17,14 @@ import {
...
@@ -17,13 +17,14 @@ import {
rawStageMedians
,
rawStageMedians
,
createdBefore
,
createdBefore
,
createdAfter
,
createdAfter
,
deepCamelCase
,
}
from
'
jest/cycle_analytics/mock_data
'
;
}
from
'
jest/cycle_analytics/mock_data
'
;
import
{
import
{
PAGINATION_TYPE
,
PAGINATION_TYPE
,
PAGINATION_SORT_DIRECTION_DESC
,
PAGINATION_SORT_DIRECTION_DESC
,
PAGINATION_SORT_FIELD_END_EVENT
,
PAGINATION_SORT_FIELD_END_EVENT
,
}
from
'
~/cycle_analytics/constants
'
;
}
from
'
~/cycle_analytics/constants
'
;
import
{
transformStagesForPathNavigation
}
from
'
~/cycle_analytics/utils
'
;
import
{
transformStagesForPathNavigation
,
formatMedianValues
}
from
'
~/cycle_analytics/utils
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
getDatesInRange
}
from
'
~/lib/utils/datetime_utility
'
;
import
{
getDatesInRange
}
from
'
~/lib/utils/datetime_utility
'
;
...
@@ -105,8 +106,6 @@ export const stagingStage = getStageByTitle(dummyState.stages, 'staging');
...
@@ -105,8 +106,6 @@ export const stagingStage = getStageByTitle(dummyState.stages, 'staging');
export
const
allowedStages
=
[
issueStage
,
planStage
,
codeStage
];
export
const
allowedStages
=
[
issueStage
,
planStage
,
codeStage
];
const
deepCamelCase
=
(
obj
)
=>
convertObjectPropsToCamelCase
(
obj
,
{
deep
:
true
});
const
stageFixtures
=
defaultStages
.
reduce
((
acc
,
stage
)
=>
{
const
stageFixtures
=
defaultStages
.
reduce
((
acc
,
stage
)
=>
{
const
events
=
getJSONFixture
(
fixtureEndpoints
.
stageEvents
(
stage
));
const
events
=
getJSONFixture
(
fixtureEndpoints
.
stageEvents
(
stage
));
return
{
return
{
...
@@ -115,43 +114,29 @@ const stageFixtures = defaultStages.reduce((acc, stage) => {
...
@@ -115,43 +114,29 @@ const stageFixtures = defaultStages.reduce((acc, stage) => {
};
};
},
{});
},
{});
export
const
stageMedians
=
rawStageMedians
.
reduce
(
const
getStageId
=
(
name
)
=>
{
(
acc
,
{
id
,
value
})
=>
({
const
{
id
}
=
getStageByTitle
(
dummyState
.
stages
,
name
);
...
acc
,
return
id
;
[
id
]:
value
,
};
export
const
stageMediansWithNumericIds
=
formatMedianValues
(
rawStageMedians
.
map
(({
id
:
name
,
...
rest
})
=>
{
const
id
=
getStageId
(
name
);
return
{
...
rest
,
name
,
id
};
}),
}),
{},
);
);
export
const
stageMediansWithNumericIds
=
rawStageMedians
.
reduce
((
acc
,
{
id
,
value
})
=>
{
const
{
id
:
stageId
}
=
getStageByTitle
(
dummyState
.
stages
,
id
);
return
{
...
acc
,
[
stageId
]:
value
,
};
},
{});
export
const
rawStageCounts
=
defaultStages
.
map
((
id
)
=>
({
export
const
rawStageCounts
=
defaultStages
.
map
((
id
)
=>
({
id
,
id
,
...
getJSONFixture
(
fixtureEndpoints
.
stageCount
(
id
)),
...
getJSONFixture
(
fixtureEndpoints
.
stageCount
(
id
)),
}));
}));
// Once https://gitlab.com/gitlab-org/gitlab/-/issues/328422 is fixed
export
const
stageCounts
=
rawStageCounts
.
reduce
((
acc
,
{
id
:
name
,
count
})
=>
{
// we should be able to use the rawStageCounts for building
const
id
=
getStageId
(
name
);
// the stage counts mock data
return
{
/*
export const stageCounts = rawStageCounts.reduce(
(acc, { id, value }) => ({
...
acc
,
...
acc
,
[id]: value,
[
id
]:
count
,
}),
};
{},
);
*/
export
const
stageCounts
=
rawStageMedians
.
reduce
((
acc
,
{
id
,
value
})
=>
{
const
{
id
:
stageId
}
=
getStageByTitle
(
dummyState
.
stages
,
id
);
return
{
...
acc
,
[
stageId
]:
value
};
},
{});
},
{});
export
const
issueEvents
=
deepCamelCase
(
stageFixtures
.
issue
);
export
const
issueEvents
=
deepCamelCase
(
stageFixtures
.
issue
);
...
@@ -172,7 +157,7 @@ export const rawCustomStage = {
...
@@ -172,7 +157,7 @@ export const rawCustomStage = {
end_event_identifier
:
'
issue_first_added_to_board
'
,
end_event_identifier
:
'
issue_first_added_to_board
'
,
};
};
export
const
medians
=
stageMedians
;
export
const
medians
=
stageMedians
WithNumericIds
;
export
const
rawCustomStageEvents
=
customizableStagesAndEvents
.
events
;
export
const
rawCustomStageEvents
=
customizableStagesAndEvents
.
events
;
export
const
camelCasedStageEvents
=
rawCustomStageEvents
.
map
(
deepCamelCase
);
export
const
camelCasedStageEvents
=
rawCustomStageEvents
.
map
(
deepCamelCase
);
...
...
ee/spec/frontend/analytics/cycle_analytics/store/getters_spec.js
View file @
18e04efc
...
@@ -12,7 +12,7 @@ import {
...
@@ -12,7 +12,7 @@ import {
import
{
import
{
allowedStages
,
allowedStages
,
issueStage
,
issueStage
,
stageMedians
,
stageMedians
WithNumericIds
,
stageCounts
,
stageCounts
,
basePaginationResult
,
basePaginationResult
,
initialPaginationState
,
initialPaginationState
,
...
@@ -212,7 +212,7 @@ describe('Value Stream Analytics getters', () => {
...
@@ -212,7 +212,7 @@ describe('Value Stream Analytics getters', () => {
it
(
'
returns the transformed data
'
,
()
=>
{
it
(
'
returns the transformed data
'
,
()
=>
{
state
=
{
state
=
{
stages
:
allowedStages
,
stages
:
allowedStages
,
medians
:
stageMedians
,
medians
:
stageMedians
WithNumericIds
,
selectedStage
:
issueStage
,
selectedStage
:
issueStage
,
stageCounts
,
stageCounts
,
};
};
...
...
spec/frontend/cycle_analytics/base_spec.js
View file @
18e04efc
...
@@ -8,8 +8,9 @@ import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
...
@@ -8,8 +8,9 @@ import PathNavigation from '~/cycle_analytics/components/path_navigation.vue';
import
StageTable
from
'
~/cycle_analytics/components/stage_table.vue
'
;
import
StageTable
from
'
~/cycle_analytics/components/stage_table.vue
'
;
import
{
NOT_ENOUGH_DATA_ERROR
}
from
'
~/cycle_analytics/constants
'
;
import
{
NOT_ENOUGH_DATA_ERROR
}
from
'
~/cycle_analytics/constants
'
;
import
initState
from
'
~/cycle_analytics/store/state
'
;
import
initState
from
'
~/cycle_analytics/store/state
'
;
import
{
selectedStage
,
convertedEvents
as
selectedStag
eEvents
}
from
'
./mock_data
'
;
import
{
selectedStage
,
issu
eEvents
}
from
'
./mock_data
'
;
const
selectedStageEvents
=
issueEvents
.
events
;
const
noDataSvgPath
=
'
path/to/no/data
'
;
const
noDataSvgPath
=
'
path/to/no/data
'
;
const
noAccessSvgPath
=
'
path/to/no/access
'
;
const
noAccessSvgPath
=
'
path/to/no/access
'
;
...
...
spec/frontend/cycle_analytics/mock_data.js
View file @
18e04efc
import
{
getJSONFixture
}
from
'
helpers/fixtures
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
DEFAULT_VALUE_STREAM
,
DEFAULT_DAYS_IN_PAST
}
from
'
~/cycle_analytics/constants
'
;
import
{
DEFAULT_VALUE_STREAM
,
DEFAULT_DAYS_IN_PAST
}
from
'
~/cycle_analytics/constants
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
import
{
convertObjectPropsToCamelCase
}
from
'
~/lib/utils/common_utils
'
;
...
@@ -6,11 +7,30 @@ import { getDateInPast } from '~/lib/utils/datetime_utility';
...
@@ -6,11 +7,30 @@ import { getDateInPast } from '~/lib/utils/datetime_utility';
export
const
createdBefore
=
new
Date
(
2019
,
0
,
14
);
export
const
createdBefore
=
new
Date
(
2019
,
0
,
14
);
export
const
createdAfter
=
getDateInPast
(
createdBefore
,
DEFAULT_DAYS_IN_PAST
);
export
const
createdAfter
=
getDateInPast
(
createdBefore
,
DEFAULT_DAYS_IN_PAST
);
export
const
deepCamelCase
=
(
obj
)
=>
convertObjectPropsToCamelCase
(
obj
,
{
deep
:
true
});
export
const
getStageByTitle
=
(
stages
,
title
)
=>
export
const
getStageByTitle
=
(
stages
,
title
)
=>
stages
.
find
((
stage
)
=>
stage
.
title
&&
stage
.
title
.
toLowerCase
().
trim
()
===
title
)
||
{};
stages
.
find
((
stage
)
=>
stage
.
title
&&
stage
.
title
.
toLowerCase
().
trim
()
===
title
)
||
{};
const
fixtureEndpoints
=
{
customizableCycleAnalyticsStagesAndEvents
:
'
projects/analytics/value_stream_analytics/stages
'
,
stageEvents
:
(
stage
)
=>
`projects/analytics/value_stream_analytics/events/
${
stage
}
`
,
};
export
const
customizableStagesAndEvents
=
getJSONFixture
(
fixtureEndpoints
.
customizableCycleAnalyticsStagesAndEvents
,
);
export
const
defaultStages
=
[
'
issue
'
,
'
plan
'
,
'
review
'
,
'
code
'
,
'
test
'
,
'
staging
'
];
export
const
defaultStages
=
[
'
issue
'
,
'
plan
'
,
'
review
'
,
'
code
'
,
'
test
'
,
'
staging
'
];
const
stageFixtures
=
defaultStages
.
reduce
((
acc
,
stage
)
=>
{
const
events
=
getJSONFixture
(
fixtureEndpoints
.
stageEvents
(
stage
));
return
{
...
acc
,
[
stage
]:
events
,
};
},
{});
export
const
summary
=
[
export
const
summary
=
[
{
value
:
'
20
'
,
title
:
'
New Issues
'
},
{
value
:
'
20
'
,
title
:
'
New Issues
'
},
{
value
:
null
,
title
:
'
Commits
'
},
{
value
:
null
,
title
:
'
Commits
'
},
...
@@ -109,50 +129,13 @@ export const convertedData = {
...
@@ -109,50 +129,13 @@ export const convertedData = {
],
],
};
};
export
const
rawEvents
=
[
export
const
rawIssueEvents
=
stageFixtures
.
issue
;
{
export
const
issueEvents
=
deepCamelCase
(
rawIssueEvents
);
title
:
'
Brockfunc-1617160796
'
,
export
const
planEvents
=
deepCamelCase
(
stageFixtures
.
plan
);
author
:
{
export
const
reviewEvents
=
deepCamelCase
(
stageFixtures
.
review
);
id
:
275
,
export
const
codeEvents
=
deepCamelCase
(
stageFixtures
.
code
);
name
:
'
VSM User4
'
,
export
const
testEvents
=
deepCamelCase
(
stageFixtures
.
test
);
username
:
'
vsm-user-4-1617160796
'
,
export
const
stagingEvents
=
deepCamelCase
(
stageFixtures
.
staging
);
state
:
'
active
'
,
avatar_url
:
'
https://www.gravatar.com/avatar/6a6f5480ae582ba68982a34169420747?s=80&d=identicon
'
,
web_url
:
'
http://gdk.test:3001/vsm-user-4-1617160796
'
,
show_status
:
false
,
path
:
'
/vsm-user-4-1617160796
'
,
},
iid
:
'
16
'
,
total_time
:
{
days
:
1
,
hours
:
9
},
created_at
:
'
about 1 month ago
'
,
url
:
'
http://gdk.test:3001/vsa-life/ror-project-vsa/-/issues/16
'
,
short_sha
:
'
some_sha
'
,
commit_url
:
'
some_commit_url
'
,
},
{
title
:
'
Subpod-1617160796
'
,
author
:
{
id
:
274
,
name
:
'
VSM User3
'
,
username
:
'
vsm-user-3-1617160796
'
,
state
:
'
active
'
,
avatar_url
:
'
https://www.gravatar.com/avatar/fde853fc3ab7dc552e649dcb4fcf5f7f?s=80&d=identicon
'
,
web_url
:
'
http://gdk.test:3001/vsm-user-3-1617160796
'
,
show_status
:
false
,
path
:
'
/vsm-user-3-1617160796
'
,
},
iid
:
'
20
'
,
total_time
:
{
days
:
2
,
hours
:
18
},
created_at
:
'
about 1 month ago
'
,
url
:
'
http://gdk.test:3001/vsa-life/ror-project-vsa/-/issues/20
'
,
},
];
export
const
convertedEvents
=
rawEvents
.
map
((
ev
)
=>
convertObjectPropsToCamelCase
(
ev
,
{
deep
:
true
}),
);
export
const
pathNavIssueMetric
=
172800
;
export
const
pathNavIssueMetric
=
172800
;
...
@@ -251,228 +234,8 @@ export const selectedProjects = [
...
@@ -251,228 +234,8 @@ export const selectedProjects = [
},
},
];
];
export
const
rawValueStreamStages
=
[
export
const
rawValueStreamStages
=
customizableStagesAndEvents
.
stages
;
{
title
:
'
Issue
'
,
hidden
:
false
,
legend
:
''
,
description
:
'
Time before an issue gets scheduled
'
,
id
:
'
issue
'
,
custom
:
false
,
start_event_html_description
:
'
\
u003cp data-sourcepos="1:1-1:13" dir="auto"
\
u003eIssue created
\
u003c/p
\
u003e
'
,
end_event_html_description
:
'
\
u003cp data-sourcepos="1:1-1:71" dir="auto"
\
u003eIssue first associated with a milestone or issue first added to a board
\
u003c/p
\
u003e
'
,
},
{
title
:
'
Plan
'
,
hidden
:
false
,
legend
:
''
,
description
:
'
Time before an issue starts implementation
'
,
id
:
'
plan
'
,
custom
:
false
,
start_event_html_description
:
'
\
u003cp data-sourcepos="1:1-1:71" dir="auto"
\
u003eIssue first associated with a milestone or issue first added to a board
\
u003c/p
\
u003e
'
,
end_event_html_description
:
'
\
u003cp data-sourcepos="1:1-1:33" dir="auto"
\
u003eIssue first mentioned in a commit
\
u003c/p
\
u003e
'
,
},
{
title
:
'
Code
'
,
hidden
:
false
,
legend
:
''
,
description
:
'
Time until first merge request
'
,
id
:
'
code
'
,
custom
:
false
,
start_event_html_description
:
'
\
u003cp data-sourcepos="1:1-1:33" dir="auto"
\
u003eIssue first mentioned in a commit
\
u003c/p
\
u003e
'
,
end_event_html_description
:
'
\
u003cp data-sourcepos="1:1-1:21" dir="auto"
\
u003eMerge request created
\
u003c/p
\
u003e
'
,
},
];
export
const
valueStreamStages
=
rawValueStreamStages
.
map
((
s
)
=>
export
const
valueStreamStages
=
rawValueStreamStages
.
map
((
s
)
=>
convertObjectPropsToCamelCase
(
s
,
{
deep
:
true
}),
convertObjectPropsToCamelCase
(
s
,
{
deep
:
true
}),
);
);
// Temporary workaronud until we have relevant backend fixtures endpoints
export
const
testEvents
=
[
{
name
:
'
test
'
,
id
:
53
,
branch
:
{
name
:
'
master
'
,
url
:
'
http://localhost/group3/project9/-/tree/master
'
,
},
shortSha
:
'
b83d6e39
'
,
author
:
{
id
:
18
,
name
:
'
John Doe21
'
,
username
:
'
user12
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/70a85d1042e02066f7451ae831689be0?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user12
'
,
showStatus
:
false
,
path
:
'
/user12
'
,
},
date
:
'
about 1 hour ago
'
,
totalTime
:
{
mins
:
2
},
url
:
'
http://localhost/group3/project9/-/jobs/53
'
,
commitUrl
:
'
http://localhost/group3/project9/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0
'
,
},
{
name
:
'
test
'
,
id
:
54
,
branch
:
{
name
:
'
master
'
,
url
:
'
http://localhost/group3/project9/-/tree/master
'
,
},
shortSha
:
'
b83d6e39
'
,
author
:
{
id
:
18
,
name
:
'
John Doe21
'
,
username
:
'
user12
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/70a85d1042e02066f7451ae831689be0?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user12
'
,
showStatus
:
false
,
path
:
'
/user12
'
,
},
date
:
'
about 1 hour ago
'
,
totalTime
:
{
mins
:
2
},
url
:
'
http://localhost/group3/project9/-/jobs/54
'
,
commitUrl
:
'
http://localhost/group3/project9/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0
'
,
},
];
export
const
stagingEvents
=
[
{
name
:
'
test
'
,
id
:
83
,
branch
:
{
name
:
'
master
'
,
url
:
'
http://localhost/group3/project9/-/tree/master
'
,
},
shortSha
:
'
b83d6e39
'
,
author
:
{
id
:
18
,
name
:
'
John Doe21
'
,
username
:
'
user12
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/70a85d1042e02066f7451ae831689be0?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user12
'
,
showStatus
:
false
,
path
:
'
/user12
'
,
},
date
:
'
about 1 hour ago
'
,
totalTime
:
{
mins
:
2
},
url
:
'
http://localhost/group3/project9/-/jobs/83
'
,
commitUrl
:
'
http://localhost/group3/project9/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0
'
,
},
{
name
:
'
test
'
,
id
:
84
,
branch
:
{
name
:
'
master
'
,
url
:
'
http://localhost/group3/project9/-/tree/master
'
,
},
shortSha
:
'
b83d6e39
'
,
author
:
{
id
:
18
,
name
:
'
John Doe21
'
,
username
:
'
user12
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/70a85d1042e02066f7451ae831689be0?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user12
'
,
showStatus
:
false
,
path
:
'
/user12
'
,
},
date
:
'
about 1 hour ago
'
,
totalTime
:
{
mins
:
2
},
url
:
'
http://localhost/group3/project9/-/jobs/84
'
,
commitUrl
:
'
http://localhost/group3/project9/-/commit/b83d6e391c22777fca1ed3012fce84f633d7fed0
'
,
},
];
export
const
reviewEvents
=
[
{
title
:
'
My title 98
'
,
author
:
{
id
:
17
,
name
:
'
John Doe20
'
,
username
:
'
user11
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/fb32cf62136a195ec4f40ec6d1cfffdc?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user11
'
,
showStatus
:
false
,
path
:
'
/user11
'
,
},
iid
:
'
3
'
,
totalTime
:
{
days
:
15
},
createdAt
:
'
20 days ago
'
,
url
:
'
http://localhost/group3/project9/-/merge_requests/3
'
,
state
:
'
opened
'
,
},
{
title
:
'
My title 99
'
,
author
:
{
id
:
17
,
name
:
'
John Doe20
'
,
username
:
'
user11
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/fb32cf62136a195ec4f40ec6d1cfffdc?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user11
'
,
showStatus
:
false
,
path
:
'
/user11
'
,
},
iid
:
'
4
'
,
totalTime
:
{
days
:
9
},
createdAt
:
'
19 days ago
'
,
url
:
'
http://localhost/group3/project9/-/merge_requests/4
'
,
state
:
'
opened
'
,
},
];
export
const
issueEvents
=
[
{
title
:
'
My title 24
'
,
author
:
{
id
:
17
,
name
:
'
John Doe20
'
,
username
:
'
user11
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/fb32cf62136a195ec4f40ec6d1cfffdc?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user11
'
,
showStatus
:
false
,
path
:
'
/user11
'
,
},
iid
:
'
3
'
,
totalTime
:
{
days
:
2
},
createdAt
:
'
4 days ago
'
,
url
:
'
http://localhost/group3/project9/-/issues/3
'
,
},
{
title
:
'
My title 23
'
,
author
:
{
id
:
17
,
name
:
'
John Doe20
'
,
username
:
'
user11
'
,
state
:
'
active
'
,
avatarUrl
:
'
https://www.gravatar.com/avatar/fb32cf62136a195ec4f40ec6d1cfffdc?s=80&d=identicon
'
,
webUrl
:
'
http://localhost/user11
'
,
showStatus
:
false
,
path
:
'
/user11
'
,
},
iid
:
'
2
'
,
totalTime
:
{
days
:
2
},
createdAt
:
'
5 days ago
'
,
url
:
'
http://localhost/group3/project9/-/issues/2
'
,
},
];
spec/frontend/cycle_analytics/stage_table_spec.js
View file @
18e04efc
...
@@ -21,16 +21,23 @@ let trackingSpy = null;
...
@@ -21,16 +21,23 @@ let trackingSpy = null;
const
noDataSvgPath
=
'
path/to/no/data
'
;
const
noDataSvgPath
=
'
path/to/no/data
'
;
const
emptyStateTitle
=
'
Too much data
'
;
const
emptyStateTitle
=
'
Too much data
'
;
const
notEnoughDataError
=
"
We don't have enough data to show this stage.
"
;
const
notEnoughDataError
=
"
We don't have enough data to show this stage.
"
;
const
[
firstIssueEvent
]
=
issueEvents
;
const
issueEventItems
=
issueEvents
.
events
;
const
[
firstStagingEvent
]
=
stagingEvents
;
const
stagingEventItems
=
stagingEvents
.
events
;
const
[
firstTestEvent
]
=
testEvents
;
const
testEventItems
=
testEvents
.
events
;
const
[
firstReviewEvent
]
=
reviewEvents
;
const
reviewEventItems
=
reviewEvents
.
events
;
const
[
firstIssueEvent
]
=
issueEventItems
;
const
[
firstStagingEvent
]
=
stagingEventItems
;
const
[
firstTestEvent
]
=
testEventItems
;
const
[
firstReviewEvent
]
=
reviewEventItems
;
const
pagination
=
{
page
:
1
,
hasNextPage
:
true
};
const
pagination
=
{
page
:
1
,
hasNextPage
:
true
};
const
findStageEvents
=
()
=>
wrapper
.
findAllByTestId
(
'
vsa-stage-event
'
);
const
findStageEvents
=
()
=>
wrapper
.
findAllByTestId
(
'
vsa-stage-event
'
);
const
findPagination
=
()
=>
wrapper
.
findByTestId
(
'
vsa-stage-pagination
'
);
const
findPagination
=
()
=>
wrapper
.
findByTestId
(
'
vsa-stage-pagination
'
);
const
findTable
=
()
=>
wrapper
.
findComponent
(
GlTable
);
const
findTable
=
()
=>
wrapper
.
findComponent
(
GlTable
);
const
findTableHead
=
()
=>
wrapper
.
find
(
'
thead
'
);
const
findStageEventTitle
=
(
ev
)
=>
extendedWrapper
(
ev
).
findByTestId
(
'
vsa-stage-event-title
'
);
const
findStageEventTitle
=
(
ev
)
=>
extendedWrapper
(
ev
).
findByTestId
(
'
vsa-stage-event-title
'
);
const
findStageTime
=
()
=>
wrapper
.
findByTestId
(
'
vsa-stage-event-time
'
);
const
findIcon
=
(
name
)
=>
wrapper
.
findByTestId
(
`
${
name
}
-icon`
);
function
createComponent
(
props
=
{},
shallow
=
false
)
{
function
createComponent
(
props
=
{},
shallow
=
false
)
{
const
func
=
shallow
?
shallowMount
:
mount
;
const
func
=
shallow
?
shallowMount
:
mount
;
...
@@ -38,7 +45,7 @@ function createComponent(props = {}, shallow = false) {
...
@@ -38,7 +45,7 @@ function createComponent(props = {}, shallow = false) {
func
(
StageTable
,
{
func
(
StageTable
,
{
propsData
:
{
propsData
:
{
isLoading
:
false
,
isLoading
:
false
,
stageEvents
:
issueEvents
,
stageEvents
:
issueEvent
Item
s
,
noDataSvgPath
,
noDataSvgPath
,
selectedStage
:
issueStage
,
selectedStage
:
issueStage
,
pagination
,
pagination
,
...
@@ -64,10 +71,10 @@ describe('StageTable', () => {
...
@@ -64,10 +71,10 @@ describe('StageTable', () => {
it
(
'
will render the correct events
'
,
()
=>
{
it
(
'
will render the correct events
'
,
()
=>
{
const
evs
=
findStageEvents
();
const
evs
=
findStageEvents
();
expect
(
evs
).
toHaveLength
(
issueEvents
.
length
);
expect
(
evs
).
toHaveLength
(
issueEvent
Item
s
.
length
);
const
titles
=
evs
.
wrappers
.
map
((
ev
)
=>
findStageEventTitle
(
ev
).
text
());
const
titles
=
evs
.
wrappers
.
map
((
ev
)
=>
findStageEventTitle
(
ev
).
text
());
issueEvents
.
forEach
((
ev
,
index
)
=>
{
issueEvent
Item
s
.
forEach
((
ev
,
index
)
=>
{
expect
(
titles
[
index
]).
toBe
(
ev
.
title
);
expect
(
titles
[
index
]).
toBe
(
ev
.
title
);
});
});
});
});
...
@@ -84,10 +91,10 @@ describe('StageTable', () => {
...
@@ -84,10 +91,10 @@ describe('StageTable', () => {
it
(
'
will render the correct events
'
,
()
=>
{
it
(
'
will render the correct events
'
,
()
=>
{
const
evs
=
findStageEvents
();
const
evs
=
findStageEvents
();
expect
(
evs
).
toHaveLength
(
issueEvents
.
length
);
expect
(
evs
).
toHaveLength
(
issueEvent
Item
s
.
length
);
const
titles
=
evs
.
wrappers
.
map
((
ev
)
=>
findStageEventTitle
(
ev
).
text
());
const
titles
=
evs
.
wrappers
.
map
((
ev
)
=>
findStageEventTitle
(
ev
).
text
());
issueEvents
.
forEach
((
ev
,
index
)
=>
{
issueEvent
Item
s
.
forEach
((
ev
,
index
)
=>
{
expect
(
titles
[
index
]).
toBe
(
ev
.
title
);
expect
(
titles
[
index
]).
toBe
(
ev
.
title
);
});
});
});
});
...
@@ -106,19 +113,20 @@ describe('StageTable', () => {
...
@@ -106,19 +113,20 @@ describe('StageTable', () => {
});
});
it
(
'
will set the workflow title to "Issues"
'
,
()
=>
{
it
(
'
will set the workflow title to "Issues"
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
toContain
(
'
Issues
'
);
expect
(
findTableHead
(
).
text
()).
toContain
(
'
Issues
'
);
});
});
it
(
'
does not render the fork icon
'
,
()
=>
{
it
(
'
does not render the fork icon
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
fork-icon
'
).
exists
()).
toBe
(
false
);
expect
(
findIcon
(
'
fork
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
does not render the branch icon
'
,
()
=>
{
it
(
'
does not render the branch icon
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
commit-icon
'
).
exists
()).
toBe
(
false
);
expect
(
findIcon
(
'
commit
'
).
exists
()).
toBe
(
false
);
});
});
it
(
'
will render the total time
'
,
()
=>
{
it
(
'
will render the total time
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
vsa-stage-event-time
'
).
text
()).
toBe
(
'
2 days
'
);
const
createdAt
=
firstIssueEvent
.
createdAt
.
replace
(
'
ago
'
,
''
);
expect
(
findStageTime
().
text
()).
toBe
(
createdAt
);
});
});
it
(
'
will render the author
'
,
()
=>
{
it
(
'
will render the author
'
,
()
=>
{
...
@@ -143,8 +151,8 @@ describe('StageTable', () => {
...
@@ -143,8 +151,8 @@ describe('StageTable', () => {
});
});
it
(
'
will set the workflow title to "Merge requests"
'
,
()
=>
{
it
(
'
will set the workflow title to "Merge requests"
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
toContain
(
'
Merge requests
'
);
expect
(
findTableHead
(
).
text
()).
toContain
(
'
Merge requests
'
);
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
not
.
toContain
(
'
Issues
'
);
expect
(
findTableHead
(
).
text
()).
not
.
toContain
(
'
Issues
'
);
});
});
});
});
...
@@ -157,8 +165,8 @@ describe('StageTable', () => {
...
@@ -157,8 +165,8 @@ describe('StageTable', () => {
});
});
it
(
'
will set the workflow title to "Deployments"
'
,
()
=>
{
it
(
'
will set the workflow title to "Deployments"
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
toContain
(
'
Deployments
'
);
expect
(
findTableHead
(
).
text
()).
toContain
(
'
Deployments
'
);
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
not
.
toContain
(
'
Issues
'
);
expect
(
findTableHead
(
).
text
()).
not
.
toContain
(
'
Issues
'
);
});
});
it
(
'
will not render the event title
'
,
()
=>
{
it
(
'
will not render the event title
'
,
()
=>
{
...
@@ -166,15 +174,15 @@ describe('StageTable', () => {
...
@@ -166,15 +174,15 @@ describe('StageTable', () => {
});
});
it
(
'
will render the fork icon
'
,
()
=>
{
it
(
'
will render the fork icon
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
fork-icon
'
).
exists
()).
toBe
(
true
);
expect
(
findIcon
(
'
fork
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
will render the branch icon
'
,
()
=>
{
it
(
'
will render the branch icon
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
commit-icon
'
).
exists
()).
toBe
(
true
);
expect
(
findIcon
(
'
commit
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
will render the total time
'
,
()
=>
{
it
(
'
will render the total time
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
vsa-stage-event-time
'
).
text
()).
toBe
(
'
2 mins
'
);
expect
(
findStageTime
(
).
text
()).
toBe
(
'
2 mins
'
);
});
});
it
(
'
will render the build shortSha
'
,
()
=>
{
it
(
'
will render the build shortSha
'
,
()
=>
{
...
@@ -199,8 +207,8 @@ describe('StageTable', () => {
...
@@ -199,8 +207,8 @@ describe('StageTable', () => {
});
});
it
(
'
will set the workflow title to "Jobs"
'
,
()
=>
{
it
(
'
will set the workflow title to "Jobs"
'
,
()
=>
{
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
toContain
(
'
Jobs
'
);
expect
(
findTableHead
(
).
text
()).
toContain
(
'
Jobs
'
);
expect
(
wrapper
.
find
(
'
thead
'
).
text
()).
not
.
toContain
(
'
Issues
'
);
expect
(
findTableHead
(
).
text
()).
not
.
toContain
(
'
Issues
'
);
});
});
it
(
'
will not render the event title
'
,
()
=>
{
it
(
'
will not render the event title
'
,
()
=>
{
...
@@ -208,15 +216,15 @@ describe('StageTable', () => {
...
@@ -208,15 +216,15 @@ describe('StageTable', () => {
});
});
it
(
'
will render the fork icon
'
,
()
=>
{
it
(
'
will render the fork icon
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
fork-icon
'
).
exists
()).
toBe
(
true
);
expect
(
findIcon
(
'
fork
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
will render the branch icon
'
,
()
=>
{
it
(
'
will render the branch icon
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
commit-icon
'
).
exists
()).
toBe
(
true
);
expect
(
findIcon
(
'
commit
'
).
exists
()).
toBe
(
true
);
});
});
it
(
'
will render the total time
'
,
()
=>
{
it
(
'
will render the total time
'
,
()
=>
{
expect
(
wrapper
.
findByTestId
(
'
vsa-stage-event-time
'
).
text
()).
toBe
(
'
2 mins
'
);
expect
(
findStageTime
(
).
text
()).
toBe
(
'
2 mins
'
);
});
});
it
(
'
will render the build shortSha
'
,
()
=>
{
it
(
'
will render the build shortSha
'
,
()
=>
{
...
...
spec/frontend/cycle_analytics/store/mutations_spec.js
View file @
18e04efc
...
@@ -4,8 +4,8 @@ import * as types from '~/cycle_analytics/store/mutation_types';
...
@@ -4,8 +4,8 @@ import * as types from '~/cycle_analytics/store/mutation_types';
import
mutations
from
'
~/cycle_analytics/store/mutations
'
;
import
mutations
from
'
~/cycle_analytics/store/mutations
'
;
import
{
import
{
selectedStage
,
selectedStage
,
rawEvents
,
raw
Issue
Events
,
converted
Events
,
issue
Events
,
rawData
,
rawData
,
convertedData
,
convertedData
,
selectedValueStream
,
selectedValueStream
,
...
@@ -16,6 +16,8 @@ import {
...
@@ -16,6 +16,8 @@ import {
}
from
'
../mock_data
'
;
}
from
'
../mock_data
'
;
let
state
;
let
state
;
const
rawEvents
=
rawIssueEvents
.
events
;
const
convertedEvents
=
issueEvents
.
events
;
const
mockRequestPath
=
'
fake/request/path
'
;
const
mockRequestPath
=
'
fake/request/path
'
;
const
mockCreatedAfter
=
'
2020-06-18
'
;
const
mockCreatedAfter
=
'
2020-06-18
'
;
const
mockCreatedBefore
=
'
2020-07-18
'
;
const
mockCreatedBefore
=
'
2020-07-18
'
;
...
...
spec/frontend/fixtures/analytics.rb
0 → 100644
View file @
18e04efc
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
'Analytics (JavaScript fixtures)'
,
:sidekiq_inline
do
include
JavaScriptFixturesHelpers
let_it_be
(
:value_stream_id
)
{
'default'
}
let_it_be
(
:group
)
{
create
(
:group
)
}
let_it_be
(
:project
)
{
create
(
:project
,
:repository
,
namespace:
group
)
}
let_it_be
(
:user
)
{
create
(
:user
,
:admin
)
}
let_it_be
(
:milestone
)
{
create
(
:milestone
,
project:
project
)
}
let
(
:issue
)
{
create
(
:issue
,
project:
project
,
created_at:
4
.
days
.
ago
)
}
let
(
:issue_1
)
{
create
(
:issue
,
project:
project
,
created_at:
5
.
days
.
ago
)
}
let
(
:issue_2
)
{
create
(
:issue
,
project:
project
,
created_at:
4
.
days
.
ago
,
milestone:
milestone
)
}
let
(
:issue_3
)
{
create
(
:issue
,
project:
project
,
created_at:
3
.
days
.
ago
,
milestone:
milestone
)
}
let
(
:mr_1
)
{
create
(
:merge_request
,
source_project:
project
,
allow_broken:
true
,
created_at:
5
.
days
.
ago
)
}
let
(
:mr_2
)
{
create
(
:merge_request
,
source_project:
project
,
allow_broken:
true
,
created_at:
4
.
days
.
ago
)
}
let
(
:pipeline_1
)
{
create
(
:ci_empty_pipeline
,
status:
'created'
,
project:
project
,
ref:
mr_1
.
source_branch
,
sha:
mr_1
.
source_branch_sha
,
head_pipeline_of:
mr_1
)
}
let
(
:pipeline_2
)
{
create
(
:ci_empty_pipeline
,
status:
'created'
,
project:
project
,
ref:
mr_2
.
source_branch
,
sha:
mr_2
.
source_branch_sha
,
head_pipeline_of:
mr_2
)
}
let
(
:build_1
)
{
create
(
:ci_build
,
:success
,
pipeline:
pipeline_1
,
author:
user
)
}
let
(
:build_2
)
{
create
(
:ci_build
,
:success
,
pipeline:
pipeline_2
,
author:
user
)
}
def
prepare_cycle_analytics_data
group
.
add_maintainer
(
user
)
project
.
add_maintainer
(
user
)
create_commit_referencing_issue
(
issue_1
)
create_commit_referencing_issue
(
issue_2
)
create_merge_request_closing_issue
(
user
,
project
,
issue_1
)
create_merge_request_closing_issue
(
user
,
project
,
issue_2
)
merge_merge_requests_closing_issue
(
user
,
project
,
issue_3
)
end
def
create_deployment
deploy_master
(
user
,
project
,
environment:
'staging'
)
deploy_master
(
user
,
project
)
end
def
update_metrics
issue_1
.
metrics
.
update!
(
first_added_to_board_at:
3
.
days
.
ago
,
first_mentioned_in_commit_at:
2
.
days
.
ago
)
issue_2
.
metrics
.
update!
(
first_added_to_board_at:
2
.
days
.
ago
,
first_mentioned_in_commit_at:
1
.
day
.
ago
)
mr_1
.
metrics
.
update!
({
merged_at:
5
.
days
.
ago
,
first_deployed_to_production_at:
1
.
day
.
ago
,
latest_build_started_at:
5
.
days
.
ago
,
latest_build_finished_at:
1
.
day
.
ago
,
pipeline:
build_1
.
pipeline
})
mr_2
.
metrics
.
update!
({
merged_at:
10
.
days
.
ago
,
first_deployed_to_production_at:
5
.
days
.
ago
,
latest_build_started_at:
9
.
days
.
ago
,
latest_build_finished_at:
7
.
days
.
ago
,
pipeline:
build_2
.
pipeline
})
end
before
(
:all
)
do
clean_frontend_fixtures
(
'projects/analytics/value_stream_analytics/'
)
end
before
do
stub_licensed_features
(
cycle_analytics_for_groups:
true
)
prepare_cycle_analytics_data
update_metrics
create_deployment
end
describe
Projects
::
Analytics
::
CycleAnalytics
::
StagesController
,
type: :controller
do
render_views
let
(
:params
)
{
{
namespace_id:
group
,
project_id:
project
,
value_stream_id:
value_stream_id
}
}
before
do
project
.
add_developer
(
user
)
sign_in
(
user
)
end
it
'projects/analytics/value_stream_analytics/stages'
do
get
(
:index
,
params:
params
,
format: :json
)
expect
(
response
).
to
be_successful
end
end
describe
Projects
::
CycleAnalytics
::
EventsController
,
type: :controller
do
render_views
let
(
:params
)
{
{
namespace_id:
group
,
project_id:
project
,
value_stream_id:
value_stream_id
}
}
before
do
project
.
add_developer
(
user
)
sign_in
(
user
)
end
Gitlab
::
Analytics
::
CycleAnalytics
::
DefaultStages
.
all
.
each
do
|
stage
|
it
"projects/analytics/value_stream_analytics/events/
#{
stage
[
:name
]
}
"
do
get
(
stage
[
:name
],
params:
params
,
format: :json
)
expect
(
response
).
to
be_successful
end
end
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment