Commit 95aa9820 authored by Michael Kozono's avatar Michael Kozono

Merge branch '38319-rename-cycle-analytics-to-value-stream-analytics' into 'master'

Rename Cycle Analytics façades to Value Stream Analytics

Closes #38319

See merge request gitlab-org/gitlab!23427
parents a411d98a a1cf08b7
......@@ -27,7 +27,7 @@ export default {
<template>
<div class="landing content-block">
<button
:aria-label="__('Dismiss Cycle Analytics introduction box')"
:aria-label="__('Dismiss Value Stream Analytics introduction box')"
class="js-ca-dismiss-button dismiss-button"
type="button"
@click="dismissOverviewDialog"
......@@ -36,10 +36,10 @@ export default {
</button>
<div class="svg-container" v-html="iconCycleAnalyticsSplash"></div>
<div class="inner-content">
<h4>{{ __('Introducing Cycle Analytics') }}</h4>
<h4>{{ __('Introducing Value Stream Analytics') }}</h4>
<p>
{{
__(`Cycle Analytics gives an overview
__(`Value Stream Analytics gives an overview
of how much time it takes to go from idea to production in your project.`)
}}
</p>
......
......@@ -71,7 +71,7 @@ export default () => {
},
created() {
// Conditional check placed here to prevent this method from being called on the
// new Cycle Analytics page (i.e. the new page will be initialized blank and only
// new Value Stream Analytics page (i.e. the new page will be initialized blank and only
// after a group is selected the cycle analyitcs data will be fetched). Once the
// old (current) page has been removed this entire created method as well as the
// variable itself can be completely removed.
......@@ -81,7 +81,7 @@ export default () => {
methods: {
handleError() {
this.store.setErrorState(true);
return new Flash(__('There was an error while fetching cycle analytics data.'));
return new Flash(__('There was an error while fetching value stream analytics data.'));
},
initDropdown() {
const $dropdown = $('.js-ca-dropdown');
......
......@@ -579,7 +579,7 @@ $calendar-border-color: rgba(#000, 0.1);
$calendar-user-contrib-text: #959494;
/*
* Cycle Analytics
* Value Stream Analytics
*/
$cycle-analytics-box-padding: 30px;
$cycle-analytics-box-text-color: #8c8c8c;
......
......@@ -35,7 +35,7 @@ module AnalyticsNavbarHelper
return unless project_nav_tab?(:cycle_analytics)
navbar_sub_item(
title: _('Cycle Analytics'),
title: _('Value Stream Analytics'),
path: 'cycle_analytics#show',
link: project_cycle_analytics_path(project),
link_to_options: { class: 'shortcuts-project-cycle-analytics' }
......
......@@ -42,8 +42,8 @@
- unless should_display_analytics_pages_in_sidebar
- if can?(current_user, :read_cycle_analytics, @project)
= nav_link(path: 'cycle_analytics#show') do
= link_to project_cycle_analytics_path(@project), title: _('Cycle Analytics'), class: 'shortcuts-project-cycle-analytics' do
%span= _('Cycle Analytics')
= link_to project_cycle_analytics_path(@project), title: _('Value Stream Analytics'), class: 'shortcuts-project-cycle-analytics' do
%span= _('Value Stream Analytics')
= render_if_exists 'layouts/nav/project_insights_link'
......
......@@ -4,12 +4,12 @@
.col-md-10.offset-md-1
.row.overview-details
.col-md-6.overview-text
%h4 Introducing Cycle Analytics
%h4 Introducing Value Stream Analytics
%p
Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.
To set up CA, you must first define a production environment by setting up your CI and then deploy to production.
Value Stream Analytics (VSA) gives an overview of how much time it takes to go from idea to production in your project.
To set up VSA, you must first define a production environment by setting up your CI and then deploy to production.
%p
%a.btn{ href: help_page_path('user/analytics/cycle_analytics.md'), target: '_blank' } Read more
%a.btn{ href: help_page_path('user/analytics/value_stream_analytics.md'), target: '_blank' } Read more
.col-md-6.overview-image
%span.overview-icon
= custom_icon ('icon_cycle_analytics_overview')
- page_title "Cycle Analytics"
- page_title "Value Stream Analytics"
#cycle-analytics{ "v-cloak" => "true", data: { request_path: project_cycle_analytics_path(@project) } }
- if @cycle_analytics_no_data
%banner{ "v-if" => "!isOverviewDialogDismissed",
"documentation-link": help_page_path('user/analytics/cycle_analytics.md'),
"documentation-link": help_page_path('user/analytics/value_stream_analytics.md'),
"v-on:dismiss-overview-dialog" => "dismissOverviewDialog()" }
= icon("spinner spin", "v-show" => "isLoading")
.wrapper{ "v-show" => "!isLoading && !hasError" }
......
---
title: Rename cycle analytics interfaces to value stream analytics
merge_request: 23427
author:
type: changed
......@@ -195,9 +195,8 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
end
end
resource :cycle_analytics, only: [:show]
namespace :cycle_analytics do
resource :cycle_analytics, only: :show, path: 'value_stream_analytics'
scope module: :cycle_analytics, as: 'cycle_analytics', path: 'value_stream_analytics' do
scope :events, controller: 'events' do
get :issue
get :plan
......@@ -208,6 +207,7 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
get :production
end
end
get '/cycle_analytics', to: redirect('%{namespace_id}/%{project_id}/-/value_stream_analytics')
concerns :clusterable
......
......@@ -109,7 +109,7 @@ class Gitlab::Seeder::CycleAnalytics
def create_issues
Array.new(@issue_count) do
issue_params = {
title: "Cycle Analytics: #{FFaker::Lorem.sentence(6)}",
title: "Value Stream Analytics: #{FFaker::Lorem.sentence(6)}",
description: FFaker::Lorem.sentence,
state: 'opened',
assignees: [@project.team.users.sample]
......@@ -166,7 +166,7 @@ class Gitlab::Seeder::CycleAnalytics
Timecop.travel 12.hours.from_now
opts = {
title: 'Cycle Analytics merge_request',
title: 'Value Stream Analytics merge_request',
description: "Fixes #{issue.to_reference}",
source_branch: branch,
target_branch: 'master'
......
......@@ -88,7 +88,7 @@ The following documentation relates to the DevOps **Manage** stage:
| Manage Topics | Description |
|:--------------------------------------------------------------------------------------|:-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| [Authentication and<br/>Authorization](administration/auth/README.md) **(CORE ONLY)** | Supported authentication and authorization providers. |
| [GitLab Cycle Analytics](user/project/cycle_analytics.md) | Measure the time it takes to go from an [idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab) for each project you have. |
| [GitLab Value Stream Analytics](user/project/cycle_analytics.md) | Measure the time it takes to go from an [idea to production](https://about.gitlab.com/blog/2016/08/05/continuous-integration-delivery-and-deployment-with-gitlab/#from-idea-to-production-with-gitlab) for each project you have. |
| [Instance Statistics](user/instance_statistics/index.md) | Discover statistics on how many GitLab features you use and user activity. |
<div align="right">
......
......@@ -220,7 +220,7 @@ deployment will be recorded as a new environment named `production`.
NOTE: **Note:**
If your environment's name is `production` (all lowercase),
it will get recorded in [Cycle Analytics](../user/project/cycle_analytics.md).
it will get recorded in [Value Stream Analytics](../user/project/cycle_analytics.md).
### Configuring dynamic environments
......
......@@ -80,7 +80,7 @@ Complementary reads:
- [File uploads](uploads.md)
- [Auto DevOps development guide](auto_devops.md)
- [Mass Inserting Models](mass_insert.md)
- [Cycle Analytics development guide](cycle_analytics.md)
- [Value Stream Analytics development guide](value_stream_analytics.md)
- [Issue types vs first-class types](issue_types.md)
- [Application limits](application_limits.md)
- [Redis guidelines](redis.md)
......
This diff is collapsed.
......@@ -559,5 +559,5 @@ Let's suppose you want to add translations for a new language, let's say French.
```shell
git add locale/fr/ app/assets/javascripts/locale/fr/
git commit -m "Add French translations for Cycle Analytics page"
git commit -m "Add French translations for Value Stream Analytics page"
```
This diff is collapsed.
......@@ -36,7 +36,7 @@ identify improvements that might substantially accelerate your development cycle
Code Review Analytics can be used when:
- Your team agrees that code review is moving too slow.
- The [Cycle Analytics feature](cycle_analytics.md) shows that reviews are your team's most time-consuming step.
- The [Value Stream Analytics feature](value_stream_analytics.md) shows that reviews are your team's most time-consuming step.
You can use Code Review Analytics to see the types of work that are currently moving the slowest, and analyze the patterns
and trends between them. For example:
......
This diff is collapsed.
......@@ -16,13 +16,13 @@ Once enabled, click on **Analytics** from the top navigation bar.
From the centralized analytics workspace, the following analytics are available:
- [Code Review Analytics](code_review_analytics.md). **(STARTER)**
- [Cycle Analytics](cycle_analytics.md), enabled with the `cycle_analytics`
- [Value Stream Analytics](value_stream_analytics.md), enabled with the `cycle_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
- [Productivity Analytics](productivity_analytics.md), enabled with the `productivity_analytics`
[feature flag](../../development/feature_flags/development.md#enabling-a-feature-flag-in-development). **(PREMIUM)**
NOTE: **Note:**
Project-level Cycle Analytics are still available at a project's **Project > Cycle Analytics**.
Project-level Value Stream Analytics are still available at a project's **Project > Value Stream Analytics**.
## Other analytics tools
......
......@@ -7,7 +7,7 @@ Track development velocity with Productivity Analytics.
For many companies, the development cycle is a blackbox and getting an estimate of how
long, on average, it takes to deliver features is an enormous endeavor.
While [Cycle Analytics](../project/cycle_analytics.md) focuses on the entire
While [Value Stream Analytics](../project/cycle_analytics.md) focuses on the entire
Software Development Life Cycle (SDLC) process, Productivity Analytics provides a way for Engineering Management to drill down in a systematic way to uncover patterns and causes for success or failure at an individual, project or group level.
Productivity can slow down for many reasons ranging from degrading code base to quickly growing teams. In order to investigate, department or team leaders can start by visualizing the time it takes for merge requests to be merged.
......
This diff is collapsed.
......@@ -45,7 +45,7 @@ GitLab is a Git-based platform that integrates a great number of essential tools
- Building, testing, and deploying with built-in [Continuous Integration](../ci/README.md).
- Deploying personal and professional static websites with [GitLab Pages](project/pages/index.md).
- Integrating with Docker by using [GitLab Container Registry](packages/container_registry/index.md).
- Tracking the development lifecycle by using [GitLab Cycle Analytics](project/cycle_analytics.md).
- Tracking the development lifecycle by using [GitLab Value Stream Analytics](project/cycle_analytics.md).
With GitLab Enterprise Edition, you can also:
......
......@@ -166,10 +166,10 @@ Maintainers and Developers from pushing to a protected branch. Read through the
[Allowed to Merge and Allowed to Push settings](project/protected_branches.md#using-the-allowed-to-merge-and-allowed-to-push-settings)
to learn more.
### Cycle Analytics permissions
### Value Stream Analytics permissions
Find the current permissions on the Cycle Analytics dashboard on
the [documentation on Cycle Analytics permissions](analytics/cycle_analytics.md#permissions).
Find the current permissions on the Value Stream Analytics dashboard, as described in
[related documentation](analytics/value_stream_analytics.md#permissions).
### Issue Board permissions
......
---
redirect_to: '../analytics/cycle_analytics.md'
redirect_to: '../analytics/value_stream_analytics.md'
---
This document was moved to [another location](../analytics/cycle_analytics.md)
This document was moved to [another location](../analytics/value_stream_analytics.md)
......@@ -87,7 +87,7 @@ When you create a project in GitLab, you'll have access to a large number of
- [Wiki](wiki/index.md): document your GitLab project in an integrated Wiki.
- [Snippets](../snippets.md): store, share and collaborate on code snippets.
- [Cycle Analytics](cycle_analytics.md): review your development lifecycle.
- [Value Stream Analytics](cycle_analytics.md): review your development lifecycle.
- [Insights](insights/index.md): configure the Insights that matter for your projects. **(ULTIMATE)**
- [Security Dashboard](security_dashboard.md): Security Dashboard. **(ULTIMATE)**
- [Syntax highlighting](highlighting.md): an alternative to customize
......
......@@ -203,7 +203,7 @@ export default {
<template>
<div class="js-cycle-analytics">
<div class="page-title-holder d-flex align-items-center">
<h3 class="page-title">{{ __('Cycle Analytics') }}</h3>
<h3 class="page-title">{{ __('Value Stream Analytics') }}</h3>
</div>
<div class="mw-100">
<div
......@@ -239,7 +239,7 @@ export default {
</div>
<gl-empty-state
v-if="shouldRenderEmptyState"
:title="__('Cycle Analytics can help you determine your team’s velocity')"
:title="__('Value Stream Analytics can help you determine your team’s velocity')"
:description="
__(
'Start by choosing a group to see how your team is spending time. You can then drill down to the project level.',
......@@ -251,11 +251,11 @@ export default {
<gl-empty-state
v-if="hasNoAccessError"
class="js-empty-state"
:title="__('You don’t have access to Cycle Analytics for this group')"
:title="__('You don’t have access to Value Stream Analytics for this group')"
:svg-path="noAccessSvgPath"
:description="
__(
'Only \'Reporter\' roles and above on tiers Premium / Silver and above can see Cycle Analytics.',
'Only \'Reporter\' roles and above on tiers Premium / Silver and above can see Value Stream Analytics.',
)
"
/>
......
......@@ -14,7 +14,7 @@ export default {
},
setSelectedGroup(selectedGroup) {
this.selectedGroup = selectedGroup;
this.renderSelectedGroup(`/groups/${selectedGroup.path}/-/cycle_analytics`);
this.renderSelectedGroup(`/groups/${selectedGroup.path}/-/value_stream_analytics`);
},
setSelectedProjects(selectedProjects) {
this.selectedProjectIds = selectedProjects.map(value => value.id);
......
......@@ -119,7 +119,7 @@ export const receiveCycleAnalyticsDataError = ({ commit }, { response }) => {
commit(types.RECEIVE_CYCLE_ANALYTICS_DATA_ERROR, status);
if (status !== httpStatus.FORBIDDEN)
createFlash(__('There was an error while fetching cycle analytics data.'));
createFlash(__('There was an error while fetching value stream analytics data.'));
};
export const fetchCycleAnalyticsData = ({ dispatch }) => {
......@@ -147,7 +147,7 @@ export const requestSummaryData = ({ commit }) => commit(types.REQUEST_SUMMARY_D
export const receiveSummaryDataError = ({ commit }, error) => {
commit(types.RECEIVE_SUMMARY_DATA_ERROR, error);
createFlash(__('There was an error while fetching cycle analytics summary data.'));
createFlash(__('There was an error while fetching value stream analytics summary data.'));
};
export const receiveSummaryDataSuccess = ({ commit }, data) =>
......@@ -198,7 +198,7 @@ export const fetchGroupLabels = ({ dispatch, state }) => {
export const receiveGroupStagesAndEventsError = ({ commit }, error) => {
commit(types.RECEIVE_GROUP_STAGES_AND_EVENTS_ERROR, error);
createFlash(__('There was an error fetching cycle analytics stages.'));
createFlash(__('There was an error fetching value stream analytics stages.'));
};
export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch }, data) => {
......@@ -209,7 +209,7 @@ export const receiveGroupStagesAndEventsSuccess = ({ state, commit, dispatch },
dispatch('setSelectedStage', firstStage);
dispatch('fetchStageData', firstStage.slug);
} else {
createFlash(__('There was an error while fetching cycle analytics data.'));
createFlash(__('There was an error while fetching value stream analytics data.'));
}
};
......@@ -386,7 +386,7 @@ export const receiveDurationDataSuccess = ({ commit, state, dispatch }, data) =>
export const receiveDurationDataError = ({ commit }) => {
commit(types.RECEIVE_DURATION_DATA_ERROR);
createFlash(__('There was an error while fetching cycle analytics duration data.'));
createFlash(__('There was an error while fetching value stream analytics duration data.'));
};
export const fetchDurationData = ({ state, dispatch, getters }) => {
......@@ -430,7 +430,7 @@ export const receiveDurationMedianDataSuccess = ({ commit }, data) =>
export const receiveDurationMedianDataError = ({ commit }) => {
commit(types.RECEIVE_DURATION_MEDIAN_DATA_ERROR);
createFlash(__('There was an error while fetching cycle analytics duration median data.'));
createFlash(__('There was an error while fetching value stream analytics duration median data.'));
};
export const fetchDurationMedianData = ({ state, dispatch }) => {
......
......@@ -45,7 +45,7 @@ export const getLabelEventsIdentifiers = (events = []) =>
/**
* Checks if the specified stage is in memory or persisted to storage based on the id
*
* Default cycle analytics stages are initially stored in memory, when they are first
* Default value stream analytics stages are initially stored in memory, when they are first
* created the id for the stage is the name of the stage in lowercase. This string id
* is used to fetch stage data (events, median calculation)
*
......
......@@ -17,12 +17,13 @@ export default {
projectPackagesPath: '/api/:version/projects/:id/packages',
projectPackagePath: '/api/:version/projects/:id/packages/:package_id',
cycleAnalyticsTasksByTypePath: '/-/analytics/type_of_work/tasks_by_type',
cycleAnalyticsSummaryDataPath: '/-/analytics/cycle_analytics/summary',
cycleAnalyticsGroupStagesAndEventsPath: '/-/analytics/cycle_analytics/stages',
cycleAnalyticsStageEventsPath: '/-/analytics/cycle_analytics/stages/:stage_id/records',
cycleAnalyticsStageMedianPath: '/-/analytics/cycle_analytics/stages/:stage_id/median',
cycleAnalyticsStagePath: '/-/analytics/cycle_analytics/stages/:stage_id',
cycleAnalyticsDurationChartPath: '/-/analytics/cycle_analytics/stages/:stage_id/duration_chart',
cycleAnalyticsSummaryDataPath: '/-/analytics/value_stream_analytics/summary',
cycleAnalyticsGroupStagesAndEventsPath: '/-/analytics/value_stream_analytics/stages',
cycleAnalyticsStageEventsPath: '/-/analytics/value_stream_analytics/stages/:stage_id/records',
cycleAnalyticsStageMedianPath: '/-/analytics/value_stream_analytics/stages/:stage_id/median',
cycleAnalyticsStagePath: '/-/analytics/value_stream_analytics/stages/:stage_id',
cycleAnalyticsDurationChartPath:
'/-/analytics/value_stream_analytics/stages/:stage_id/duration_chart',
codeReviewAnalyticsPath: '/api/:version/analytics/code_review',
countriesPath: '/-/countries',
countryStatesPath: '/-/country_states',
......
- page_title _("Cycle Analytics")
- page_title _("Value Stream Analytics")
- initial_data = @request_params.valid? ? @request_params.to_data_attributes : {}
#js-cycle-analytics-app{ data: initial_data.merge({ empty_state_svg_path: image_path("illustrations/analytics/cycle-analytics-empty-chart.svg"),
......
......@@ -25,12 +25,12 @@
.nav-icon-container
= sprite_icon('repeat')
%span.nav-item-name
= _('Cycle Analytics')
= _('Value Stream Analytics')
%ul.sidebar-sub-level-items.is-fly-out-only
= nav_link(controller: :cycle_analytics, html_options: { class: "fly-out-top-item qa-sidebar-cycle-analytics-fly-out" } ) do
= link_to analytics_cycle_analytics_path do
%strong.fly-out-top-item-name
= _('Cycle Analytics')
= _('Value Stream Analytics')
= render_ce 'layouts/nav/sidebar/instance_statistics_links'
......
......@@ -6,8 +6,8 @@ namespace :analytics do
resource :productivity_analytics, only: :show, constraints: -> (req) { Feature.disabled?(:group_level_productivity_analytics) && Gitlab::Analytics.productivity_analytics_enabled? }
constraints(-> (req) { Gitlab::Analytics.cycle_analytics_enabled? }) do
resource :cycle_analytics, only: :show
namespace :cycle_analytics do
resource :cycle_analytics, only: :show, path: 'value_stream_analytics'
scope module: :cycle_analytics, as: 'cycle_analytics', path: 'value_stream_analytics' do
resources :stages, only: [:index, :create, :update, :destroy] do
member do
get :duration_chart
......@@ -15,8 +15,9 @@ namespace :analytics do
get :records
end
end
resource :summary, controller: :summary, only: [:show]
resource :summary, controller: :summary, only: :show
end
get '/cycle_analytics', to: redirect('-/analytics/value_stream_analytics')
end
constraints(::Constraints::FeatureConstrainer.new(Gitlab::Analytics::TASKS_BY_TYPE_CHART_FEATURE_FLAG)) do
......
......@@ -19,8 +19,8 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
get '/analytics', to: redirect('groups/%{group_id}/-/contribution_analytics')
resource :contribution_analytics, only: [:show]
resource :cycle_analytics, only: [:show]
namespace :cycle_analytics do
resource :cycle_analytics, only: [:show], path: 'value_stream_analytics'
scope module: :cycle_analytics, as: 'cycle_analytics', path: 'value_stream_analytics' do
scope :events, controller: 'events' do
get :issue
get :plan
......
......@@ -160,7 +160,7 @@ class Gitlab::Seeder::CustomizableCycleAnalytics
def merge_requests
@merge_requests ||= Array.new(MERGE_REQUEST_COUNT).map do |i|
opts = {
title: 'Customized Cycle Analytics merge_request',
title: 'Customized Value Stream Analytics merge_request',
description: "some description",
source_branch: "#{FFaker::Lorem.word}-#{i}-#{SecureRandom.hex(5)}",
target_branch: 'master'
......
......@@ -16,7 +16,7 @@ describe Analytics::AnalyticsController do
describe 'GET index' do
describe 'redirects to the first enabled analytics page' do
it 'redirects to cycle analytics' do
it 'redirects to value stream analytics' do
stub_feature_flags(Gitlab::Analytics::CYCLE_ANALYTICS_FEATURE_FLAG => true)
get :index
......
# frozen_string_literal: true
require 'spec_helper'
describe 'Group Cycle Analytics', :js do
describe 'Group Value Stream Analytics', :js do
let!(:user) { create(:user) }
let!(:group) { create(:group, name: "CA-test-group") }
let!(:project) { create(:project, :repository, namespace: group, group: group, name: "Cool fun project") }
......@@ -32,7 +32,7 @@ describe 'Group Cycle Analytics', :js do
it 'displays an empty state before a group is selected' do
element = page.find('.row.empty-state')
expect(element).to have_content("Cycle Analytics can help you determine your team’s velocity")
expect(element).to have_content("Value Stream Analytics can help you determine your team’s velocity")
expect(element.find('.svg-content img')['src']).to have_content('illustrations/analytics/cycle-analytics-empty-chart')
end
......@@ -78,7 +78,7 @@ describe 'Group Cycle Analytics', :js do
it 'displays empty text' do
[
'Cycle Analytics can help you determine your team’s velocity',
'Value Stream Analytics can help you determine your team’s velocity',
'Start by choosing a group to see how your team is spending time. You can then drill down to the project level.'
].each do |content|
expect(page).to have_content(content)
......
......@@ -21,7 +21,7 @@
},
{
"highlight": false,
"title": "Cycle Analytics"
"title": "Value Stream Analytics"
},
{
"highlight": false,
......
......@@ -424,12 +424,12 @@ describe('Cycle Analytics component', () => {
const defaultRequests = {
fetchSummaryData: {
status: defaultStatus,
endpoint: `/-/analytics/cycle_analytics/summary`,
endpoint: `/-/analytics/value_stream_analytics/summary`,
response: [...mockData.summaryData],
},
fetchGroupStagesAndEvents: {
status: defaultStatus,
endpoint: `/-/analytics/cycle_analytics/stages`,
endpoint: `/-/analytics/value_stream_analytics/stages`,
response: { ...mockData.customizableStagesAndEvents },
},
fetchGroupLabels: {
......@@ -448,19 +448,19 @@ describe('Cycle Analytics component', () => {
if (mockFetchDurationData) {
mock
.onGet(/analytics\/cycle_analytics\/stages\/\d+\/duration_chart/)
.onGet(/analytics\/value_stream_analytics\/stages\/\d+\/duration_chart/)
.reply(defaultStatus, [...mockData.rawDurationData]);
}
if (mockFetchStageMedian) {
mock
.onGet(/analytics\/cycle_analytics\/stages\/\d+\/median/)
.onGet(/analytics\/value_stream_analytics\/stages\/\d+\/median/)
.reply(defaultStatus, { value: null });
}
if (mockFetchStageData) {
mock
.onGet(/analytics\/cycle_analytics\/stages\/\d+\/records/)
.onGet(/analytics\/value_stream_analytics\/stages\/\d+\/records/)
.reply(defaultStatus, mockData.issueEvents);
}
......@@ -497,14 +497,14 @@ describe('Cycle Analytics component', () => {
overrides: {
fetchSummaryData: {
status: httpStatusCodes.NOT_FOUND,
endpoint: '/-/analytics/cycle_analytics/summary',
endpoint: '/-/analytics/value_stream_analytics/summary',
response: { response: { status: httpStatusCodes.NOT_FOUND } },
},
},
});
return selectGroupAndFindError(
'There was an error while fetching cycle analytics summary data.',
'There was an error while fetching value stream analytics summary data.',
);
});
......@@ -531,14 +531,14 @@ describe('Cycle Analytics component', () => {
mockRequestCycleAnalyticsData({
overrides: {
fetchGroupStagesAndEvents: {
endPoint: '/-/analytics/cycle_analytics/stages',
endPoint: '/-/analytics/value_stream_analytics/stages',
status: httpStatusCodes.NOT_FOUND,
response: { response: { status: httpStatusCodes.NOT_FOUND } },
},
},
});
return selectGroupAndFindError('There was an error fetching cycle analytics stages.');
return selectGroupAndFindError('There was an error fetching value stream analytics stages.');
});
it('will display an error if the fetchStageData request fails', () => {
......@@ -572,7 +572,7 @@ describe('Cycle Analytics component', () => {
return waitForPromises().catch(() => {
expect(findFlashError().innerText.trim()).toEqual(
'There was an error while fetching cycle analytics duration data.',
'There was an error while fetching value stream analytics duration data.',
);
});
});
......@@ -588,7 +588,7 @@ describe('Cycle Analytics component', () => {
return waitForPromises().catch(() => {
expect(findFlashError().innerText.trim()).toEqual(
'There was an error while fetching cycle analytics duration data.',
'There was an error while fetching value stream analytics duration data.',
);
});
});
......
......@@ -4,7 +4,7 @@ import { groupLabels } from '../mock_data';
const selectedLabel = groupLabels[groupLabels.length - 1];
describe('Cycle Analytics LabelsSelector', () => {
describe('Value Stream Analytics LabelsSelector', () => {
function createComponent({ props = {}, shallow = true } = {}) {
const func = shallow ? shallowMount : mount;
return func(LabelsSelector, {
......
......@@ -11,10 +11,10 @@ import { toYmd } from 'ee/analytics/shared/utils';
import { transformRawTasksByTypeData } from 'ee/analytics/cycle_analytics/utils';
const endpoints = {
customizableCycleAnalyticsStagesAndEvents: 'analytics/cycle_analytics/stages.json', // customizable stages and events endpoint
stageEvents: stage => `analytics/cycle_analytics/stages/${stage}/records.json`,
stageMedian: stage => `analytics/cycle_analytics/stages/${stage}/median.json`,
summaryData: 'analytics/cycle_analytics/summary.json',
customizableCycleAnalyticsStagesAndEvents: 'analytics/value_stream_analytics/stages.json', // customizable stages and events endpoint
stageEvents: stage => `analytics/value_stream_analytics/stages/${stage}/records.json`,
stageMedian: stage => `analytics/value_stream_analytics/stages/${stage}/median.json`,
summaryData: 'analytics/value_stream_analytics/summary.json',
};
export const groupLabels = mockLabels.map(({ title, ...rest }) => ({ ...rest, name: title }));
......
......@@ -22,20 +22,20 @@ import {
const stageData = { events: [] };
const error = new Error('Request failed with status code 404');
const flashErrorMessage = 'There was an error while fetching cycle analytics data.';
const flashErrorMessage = 'There was an error while fetching value stream analytics data.';
const selectedGroup = { fullPath: group.path };
const [selectedStage] = stages;
const selectedStageSlug = selectedStage.slug;
const endpoints = {
groupLabels: `/groups/${group.path}/-/labels`,
summaryData: '/analytics/cycle_analytics/summary',
durationData: /analytics\/cycle_analytics\/stages\/\d+\/duration_chart/,
stageData: /analytics\/cycle_analytics\/stages\/\d+\/records/,
stageMedian: /analytics\/cycle_analytics\/stages\/\d+\/median/,
baseStagesEndpoint: '/analytics/cycle_analytics/stages',
summaryData: '/analytics/value_stream_analytics/summary',
durationData: /analytics\/value_stream_analytics\/stages\/\d+\/duration_chart/,
stageData: /analytics\/value_stream_analytics\/stages\/\d+\/records/,
stageMedian: /analytics\/value_stream_analytics\/stages\/\d+\/median/,
baseStagesEndpoint: '/analytics/value_stream_analytics/stages',
};
const stageEndpoint = ({ stageId }) => `/-/analytics/cycle_analytics/stages/${stageId}`;
const stageEndpoint = ({ stageId }) => `/-/analytics/value_stream_analytics/stages/${stageId}`;
describe('Cycle analytics actions', () => {
let state;
......@@ -276,7 +276,7 @@ describe('Cycle analytics actions', () => {
state = { ...state, selectedGroup, startDate, endDate };
});
it(`dispatches actions for required cycle analytics data`, done => {
it(`dispatches actions for required value stream analytics analytics data`, done => {
testAction(
actions.fetchCycleAnalyticsData,
state,
......@@ -368,7 +368,9 @@ describe('Cycle analytics actions', () => {
commit: () => {},
})
.then(() => {
shouldFlashAMessage('There was an error while fetching cycle analytics summary data.');
shouldFlashAMessage(
'There was an error while fetching value stream analytics summary data.',
);
done();
})
.catch(done.fail);
......@@ -394,7 +396,7 @@ describe('Cycle analytics actions', () => {
commit: () => {},
})
.then(() => {
shouldFlashAMessage('There was an error fetching cycle analytics stages.');
shouldFlashAMessage('There was an error fetching value stream analytics stages.');
done();
})
.catch(done.fail);
......@@ -425,7 +427,9 @@ describe('Cycle analytics actions', () => {
{},
);
shouldFlashAMessage('There was an error while fetching cycle analytics duration data.');
shouldFlashAMessage(
'There was an error while fetching value stream analytics duration data.',
);
});
describe('with an existing error', () => {
......@@ -925,7 +929,9 @@ describe('Cycle analytics actions', () => {
commit: () => {},
});
shouldFlashAMessage('There was an error while fetching cycle analytics duration data.');
shouldFlashAMessage(
'There was an error while fetching value stream analytics duration data.',
);
});
});
......@@ -1149,7 +1155,7 @@ describe('Cycle analytics actions', () => {
});
shouldFlashAMessage(
'There was an error while fetching cycle analytics duration median data.',
'There was an error while fetching value stream analytics duration median data.',
);
});
});
......
......@@ -380,13 +380,13 @@ describe('Api', () => {
});
describe('cycleAnalyticsSummaryData', () => {
it('fetches cycle analytics summary data', done => {
it('fetches value stream analytics summary data', done => {
const response = [{ value: 0, title: 'New Issues' }, { value: 0, title: 'Deploys' }];
const params = {
...defaultParams,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/summary`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/summary`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsSummaryData(params)
......@@ -410,7 +410,7 @@ describe('Api', () => {
'cycle_analytics[created_after]': createdAfter,
'cycle_analytics[created_before]': createdBefore,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsGroupStagesAndEvents(groupId, params)
......@@ -432,7 +432,7 @@ describe('Api', () => {
const params = {
...defaultParams,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}/records`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}/records`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsStageEvents(groupId, stageId, params)
......@@ -454,7 +454,7 @@ describe('Api', () => {
const params = {
...defaultParams,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}/median`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}/median`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsStageMedian(groupId, stageId, params)
......@@ -480,7 +480,7 @@ describe('Api', () => {
end_event_identifier: 'issue_closed',
end_event_label_id: null,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages`;
mock.onPost(expectedUrl).reply(200, response);
Api.cycleAnalyticsCreateStage(groupId, customStage)
......@@ -502,7 +502,7 @@ describe('Api', () => {
name: 'nice-stage',
hidden: true,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}`;
mock.onPut(expectedUrl).reply(200, response);
Api.cycleAnalyticsUpdateStage(stageId, groupId, stageData)
......@@ -520,7 +520,7 @@ describe('Api', () => {
describe('cycleAnalyticsRemoveStage', () => {
it('deletes the specified data', done => {
const response = { id: stageId, hidden: true, custom: true };
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/${stageId}`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/${stageId}`;
mock.onDelete(expectedUrl).reply(200, response);
Api.cycleAnalyticsRemoveStage(stageId, groupId)
......@@ -541,7 +541,7 @@ describe('Api', () => {
const params = {
...defaultParams,
};
const expectedUrl = `${dummyUrlRoot}/-/analytics/cycle_analytics/stages/thursday/duration_chart`;
const expectedUrl = `${dummyUrlRoot}/-/analytics/value_stream_analytics/stages/thursday/duration_chart`;
mock.onGet(expectedUrl).reply(200, response);
Api.cycleAnalyticsDurationChart(stageId, params)
......
......@@ -140,7 +140,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
end
default_stages.each do |endpoint|
it "cycle_analytics/events/#{endpoint}.json" do
it "value_stream_analytics/events/#{endpoint}.json" do
get endpoint, params: { group_id: group, format: :json }
expect(response).to be_successful
......@@ -160,7 +160,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
sign_in(user)
end
it 'cycle_analytics/mock_data.json' do
it 'value_stream_analytics/mock_data.json' do
get(:show, params: {
group_id: group.name,
cycle_analytics: { start_date: 30 }
......@@ -194,21 +194,21 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
sign_in(user)
end
it 'analytics/cycle_analytics/stages.json' do
it 'analytics/value_stream_analytics/stages.json' do
get(:index, params: { group_id: group.name }, format: :json)
expect(response).to be_successful
end
Gitlab::Analytics::CycleAnalytics::DefaultStages.all.each do |stage|
it "analytics/cycle_analytics/stages/#{stage[:name]}/records.json" do
it "analytics/value_stream_analytics/stages/#{stage[:name]}/records.json" do
stage_id = group.cycle_analytics_stages.find_by(name: stage[:name]).id
get(:records, params: params.merge({ id: stage_id }), format: :json)
expect(response).to be_successful
end
it "analytics/cycle_analytics/stages/#{stage[:name]}/median.json" do
it "analytics/value_stream_analytics/stages/#{stage[:name]}/median.json" do
stage_id = group.cycle_analytics_stages.find_by(name: stage[:name]).id
get(:median, params: params.merge({ id: stage_id }), format: :json)
......@@ -216,13 +216,13 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
end
end
it "analytics/cycle_analytics/stages/label-based-stage/records.json" do
it "analytics/value_stream_analytics/stages/label-based-stage/records.json" do
get(:records, params: params.merge({ id: label_based_stage.id }), format: :json)
expect(response).to be_successful
end
it "analytics/cycle_analytics/stages/label-based-stage/median.json" do
it "analytics/value_stream_analytics/stages/label-based-stage/median.json" do
get(:median, params: params.merge({ id: label_based_stage.id }), format: :json)
expect(response).to be_successful
......@@ -243,7 +243,7 @@ describe 'Analytics (JavaScript fixtures)', :sidekiq_inline do
sign_in(user)
end
it 'analytics/cycle_analytics/summary.json' do
it 'analytics/value_stream_analytics/summary.json' do
get(:show, params: params, format: :json)
expect(response).to be_successful
......
# frozen_string_literal: true
require 'spec_helper'
describe 'cycle analytics events' do
describe 'value stream analytics events' do
let(:user) { create(:user) }
let(:group) { create(:group)}
let(:project) { create(:project, :repository, namespace: group, public_builds: false) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
describe 'GET /:namespace/-/cycle_analytics/events/:stage' do
describe 'GET /:namespace/-/value_stream_analytics/events/:stage' do
before do
stub_licensed_features(cycle_analytics_for_groups: true)
group.add_developer(user)
......
......@@ -31,7 +31,7 @@ describe 'Analytics' do
it 'succeeds' do
expect(Gitlab::Analytics).to receive(:cycle_analytics_enabled?).and_call_original
expect(get('/-/analytics/cycle_analytics')).to route_to('analytics/cycle_analytics#show')
expect(get('/-/analytics/value_stream_analytics')).to route_to('analytics/cycle_analytics#show')
end
end
......
......@@ -33,12 +33,12 @@ describe 'layouts/nav/sidebar/_analytics' do
expect(rendered).to match(/<use xlink:href=".+?icons-.+?#comment">/)
end
it 'has `Cycle Analytics` link' do
it 'has `Value Stream Analytics` link' do
stub_feature_flags(Gitlab::Analytics::CYCLE_ANALYTICS_FEATURE_FLAG => true)
render
expect(rendered).to have_content('Cycle Analytics')
expect(rendered).to have_content('Value Stream Analytics')
expect(rendered).to include(analytics_cycle_analytics_path)
expect(rendered).to match(/<use xlink:href=".+?icons-.+?#repeat">/)
end
......@@ -84,7 +84,7 @@ describe 'layouts/nav/sidebar/_analytics' do
disable_all_analytics_feature_flags
expect(rendered).not_to have_content('Productivity Analytics')
expect(rendered).not_to have_content('Cycle Analytics')
expect(rendered).not_to have_content('Value Stream Analytics')
end
context 'and user has access to instance statistics features' do
......
# frozen_string_literal: true
# This module represents the default Cycle Analytics stages that are currently provided by CE
# This module represents the default Value Stream Analytics stages that are currently provided by CE
# Each method returns a hash that can be used to build a new stage object.
#
# Example:
......
......@@ -50,7 +50,7 @@ module Gitlab
# Build a `SELECT` query. We find the first of the `end_time_attrs` that isn't `NULL` (call this end_time).
# Next, we find the first of the start_time_attrs that isn't `NULL` (call this start_time).
# We compute the (end_time - start_time) interval, and give it an alias based on the current
# cycle analytics stage.
# value stream analytics stage.
median_datetime(cte_table, interval_query(project_ids), name)
end
......
......@@ -5802,15 +5802,6 @@ msgstr ""
msgid "Customize your pipeline configuration."
msgstr ""
msgid "Cycle Analytics"
msgstr ""
msgid "Cycle Analytics can help you determine your team’s velocity"
msgstr ""
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
msgid "CycleAnalyticsEvent|Issue closed"
msgstr ""
......@@ -6714,15 +6705,15 @@ msgstr ""
msgid "Dismiss"
msgstr ""
msgid "Dismiss Cycle Analytics introduction box"
msgstr ""
msgid "Dismiss DevOps Score introduction"
msgstr ""
msgid "Dismiss Merge Request promotion"
msgstr ""
msgid "Dismiss Value Stream Analytics introduction box"
msgstr ""
msgid "Dismiss trial promotion"
msgstr ""
......@@ -10465,7 +10456,7 @@ msgstr ""
msgid "Interval Pattern"
msgstr ""
msgid "Introducing Cycle Analytics"
msgid "Introducing Value Stream Analytics"
msgstr ""
msgid "Introducing Your DevOps Score"
......@@ -13051,7 +13042,7 @@ msgstr ""
msgid "One or more of your personal access tokens will expire in %{days_to_expire} days or less."
msgstr ""
msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Cycle Analytics."
msgid "Only 'Reporter' roles and above on tiers Premium / Silver and above can see Value Stream Analytics."
msgstr ""
msgid "Only Project Members"
......@@ -19191,9 +19182,6 @@ msgstr ""
msgid "There was an error fetching configuration for charts"
msgstr ""
msgid "There was an error fetching cycle analytics stages."
msgstr ""
msgid "There was an error fetching data for the selected stage"
msgstr ""
......@@ -19209,6 +19197,9 @@ msgstr ""
msgid "There was an error fetching the Designs"
msgstr ""
msgid "There was an error fetching value stream analytics stages."
msgstr ""
msgid "There was an error gathering the chart data"
msgstr ""
......@@ -19251,16 +19242,16 @@ msgstr ""
msgid "There was an error when unsubscribing from this label."
msgstr ""
msgid "There was an error while fetching cycle analytics data."
msgid "There was an error while fetching value stream analytics data."
msgstr ""
msgid "There was an error while fetching cycle analytics duration data."
msgid "There was an error while fetching value stream analytics duration data."
msgstr ""
msgid "There was an error while fetching cycle analytics duration median data."
msgid "There was an error while fetching value stream analytics duration median data."
msgstr ""
msgid "There was an error while fetching cycle analytics summary data."
msgid "There was an error while fetching value stream analytics summary data."
msgstr ""
msgid "There was an error with the reCAPTCHA. Please solve the reCAPTCHA again."
......@@ -21106,6 +21097,15 @@ msgstr ""
msgid "Value"
msgstr ""
msgid "Value Stream Analytics"
msgstr ""
msgid "Value Stream Analytics can help you determine your team’s velocity"
msgstr ""
msgid "Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr ""
msgid "Variables"
msgstr ""
......@@ -21905,10 +21905,10 @@ msgstr ""
msgid "You don't have sufficient permission to perform this action."
msgstr ""
msgid "You don’t have access to Cycle Analytics for this group"
msgid "You don’t have access to Productivity Analytics in this group"
msgstr ""
msgid "You don’t have access to Productivity Analytics in this group"
msgid "You don’t have access to Value Stream Analytics for this group"
msgstr ""
msgid "You have been granted %{access_level} access to the %{source_link} %{source_type}."
......
......@@ -2,7 +2,7 @@
require 'spec_helper'
describe 'Cycle Analytics', :js do
describe 'Value Stream Analytics', :js do
let(:user) { create(:user) }
let(:guest) { create(:user) }
let(:project) { create(:project, :repository) }
......@@ -23,7 +23,7 @@ describe 'Cycle Analytics', :js do
end
it 'shows introductory message' do
expect(page).to have_content('Introducing Cycle Analytics')
expect(page).to have_content('Introducing Value Stream Analytics')
end
it 'shows pipeline summary' do
......@@ -38,7 +38,7 @@ describe 'Cycle Analytics', :js do
end
end
context "when there's cycle analytics data" do
context "when there's value stream analytics data" do
before do
allow_next_instance_of(Gitlab::ReferenceExtractor) do |instance|
allow(instance).to receive(:issues).and_return([issue])
......
......@@ -67,8 +67,8 @@ describe 'Project navbar' do
nav_sub_items: [
_('CI / CD Analytics'),
(_('Code Review') if Gitlab.ee?),
_('Cycle Analytics'),
_('Repository Analytics')
_('Repository Analytics'),
_('Value Stream Analytics')
]
},
{
......
......@@ -267,11 +267,11 @@ msgstr "Eventos de notificaciones personalizadas"
msgid "Custom notification levels are the same as participating levels. With custom notification levels you will also receive notifications for select events. To find out more, check out %{notification_link}."
msgstr "Los niveles de notificación personalizados son los mismos que los niveles participantes. Con los niveles de notificación personalizados, también recibirá notificaciones para eventos seleccionados. Para obtener más información, consulte %{notification_link}."
msgid "Cycle Analytics"
msgstr "Cycle Analytics"
msgid "Value Stream Analytics"
msgstr "Value Stream Analytics"
msgid "Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "Cycle Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."
msgid "Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project."
msgstr "Value Stream Analytics ofrece una visión general de cuánto tiempo tarda en pasar de idea a producción en su proyecto."
msgid "CycleAnalyticsStage|Code"
msgstr "Código"
......@@ -412,8 +412,8 @@ msgstr "Importar repositorio"
msgid "Interval Pattern"
msgstr "Patrón de intervalo"
msgid "Introducing Cycle Analytics"
msgstr "Introducción a Cycle Analytics"
msgid "Introducing Value Stream Analytics"
msgstr "Introducción a Value Stream Analytics"
msgid "Jobs for last month"
msgstr "Trabajos del mes pasado"
......
......@@ -16,8 +16,10 @@ describe('Cycle analytics banner', () => {
vm.$destroy();
});
it('should render cycle analytics information', () => {
expect(vm.$el.querySelector('h4').textContent.trim()).toEqual('Introducing Cycle Analytics');
it('should render value stream analytics information', () => {
expect(vm.$el.querySelector('h4').textContent.trim()).toEqual(
'Introducing Value Stream Analytics',
);
expect(
vm.$el
......@@ -25,7 +27,7 @@ describe('Cycle analytics banner', () => {
.textContent.trim()
.replace(/[\r\n]+/g, ' '),
).toContain(
'Cycle Analytics gives an overview of how much time it takes to go from idea to production in your project.',
'Value Stream Analytics gives an overview of how much time it takes to go from idea to production in your project.',
);
expect(vm.$el.querySelector('a').textContent.trim()).toEqual('Read more');
......
......@@ -2,12 +2,12 @@
require 'spec_helper'
describe 'cycle analytics events' do
describe 'value stream analytics events' do
let(:user) { create(:user) }
let(:project) { create(:project, :repository, public_builds: false) }
let(:issue) { create(:issue, project: project, created_at: 2.days.ago) }
describe 'GET /:namespace/:project/cycle_analytics/events/issues' do
describe 'GET /:namespace/:project/value_stream_analytics/events/issues' do
before do
project.add_developer(user)
......
......@@ -160,4 +160,31 @@ describe 'layouts/nav/sidebar/_project' do
end
end
end
describe 'value stream analytics entry' do
let(:read_cycle_analytics) { true }
before do
allow(view).to receive(:can?).with(nil, :read_cycle_analytics, project).and_return(read_cycle_analytics)
stub_feature_flags(analytics_pages_under_project_analytics_sidebar: { enabled: false, thing: project })
end
describe 'when value stream analytics is enabled' do
it 'shows the value stream analytics entry' do
render
expect(rendered).to have_link('Value Stream Analytics', href: project_cycle_analytics_path(project))
end
end
describe 'when value stream analytics is disabled' do
let(:read_cycle_analytics) { false }
it 'does not show the value stream analytics entry' do
render
expect(rendered).not_to have_link('Value Stream Analytics', href: project_cycle_analytics_path(project))
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