Commit 457ffd5a authored by Enrique Alcántara's avatar Enrique Alcántara

Merge branch 'jj-repo-integrations-link-experiment' into 'master'

Configure integrations link experiment (repo_integrations_link) [RUN ALL RSPEC] [RUN AS-IF-FOSS]

See merge request gitlab-org/gitlab!54652
parents 7953be84 6f412407
import { omitBy, isUndefined } from 'lodash'; import { omitBy, isUndefined, get } from 'lodash';
const standardContext = { ...window.gl?.snowplowStandardContext }; const standardContext = { ...window.gl?.snowplowStandardContext };
...@@ -30,11 +30,17 @@ const createEventPayload = (el, { suffix = '' } = {}) => { ...@@ -30,11 +30,17 @@ const createEventPayload = (el, { suffix = '' } = {}) => {
let value = el.dataset.trackValue || el.value || undefined; let value = el.dataset.trackValue || el.value || undefined;
if (el.type === 'checkbox' && !el.checked) value = false; if (el.type === 'checkbox' && !el.checked) value = false;
let context = el.dataset.trackContext;
if (el.dataset.trackExperiment) {
const data = get(window, ['gon', 'global', 'experiment', el.dataset.trackExperiment]);
if (data) context = { schema: 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0', data };
}
const data = { const data = {
label: el.dataset.trackLabel, label: el.dataset.trackLabel,
property: el.dataset.trackProperty, property: el.dataset.trackProperty,
value, value,
context: el.dataset.trackContext, context,
}; };
return { return {
......
...@@ -25,6 +25,10 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp ...@@ -25,6 +25,10 @@ class ApplicationExperiment < Gitlab::Experiment # rubocop:disable Gitlab/Namesp
)) ))
end end
def exclude!
@excluded = true
end
def rollout_strategy def rollout_strategy
# no-op override in inherited class as desired # no-op override in inherited class as desired
end end
......
...@@ -41,7 +41,8 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -41,7 +41,8 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
contribution_guide_anchor_data, contribution_guide_anchor_data,
autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout), autodevops_anchor_data(show_auto_devops_callout: show_auto_devops_callout),
kubernetes_cluster_anchor_data, kubernetes_cluster_anchor_data,
gitlab_ci_anchor_data gitlab_ci_anchor_data,
integrations_anchor_data
].compact.reject(&:is_link).sort_by.with_index { |item, idx| [item.class_modifier ? 0 : 1, idx] } ].compact.reject(&:is_link).sort_by.with_index { |item, idx| [item.class_modifier ? 0 : 1, idx] }
end end
...@@ -57,7 +58,8 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -57,7 +58,8 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
license_anchor_data, license_anchor_data,
changelog_anchor_data, changelog_anchor_data,
contribution_guide_anchor_data, contribution_guide_anchor_data,
gitlab_ci_anchor_data gitlab_ci_anchor_data,
integrations_anchor_data
].compact.reject { |item| item.is_link } ].compact.reject { |item| item.is_link }
end end
...@@ -422,6 +424,25 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated ...@@ -422,6 +424,25 @@ class ProjectPresenter < Gitlab::View::Presenter::Delegated
private private
def integrations_anchor_data
experiment(:repo_integrations_link, project: project) do |e|
e.exclude! unless can?(current_user, :admin_project, project)
e.use {} # nil control
e.try do
label = statistic_icon('settings') + _('Configure Integrations')
AnchorData.new(false, label, project_settings_integrations_path(project), nil, nil, nil, {
'track-event': 'click',
'track-experiment': e.name
})
end
e.run # call run so the return value will be the AnchorData (or nil)
e.track(:view, value: project.id) # track an event for the view, with project id
end
end
def cicd_missing? def cicd_missing?
current_user && can_current_user_push_code? && repository.gitlab_ci_yml.blank? && !auto_devops_enabled? current_user && can_current_user_push_code? && repository.gitlab_ci_yml.blank? && !auto_devops_enabled?
end end
......
---
name: repo_integrations_link
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/54652/
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/285154
milestone: '13.10'
type: experiment
group: group::adoption
default_enabled: false
...@@ -7736,6 +7736,9 @@ msgstr "" ...@@ -7736,6 +7736,9 @@ msgstr ""
msgid "Configure Gitaly timeouts." msgid "Configure Gitaly timeouts."
msgstr "" msgstr ""
msgid "Configure Integrations"
msgstr ""
msgid "Configure Let's Encrypt" msgid "Configure Let's Encrypt"
msgstr "" msgstr ""
......
...@@ -82,6 +82,10 @@ RSpec.describe ApplicationExperiment, :experiment do ...@@ -82,6 +82,10 @@ RSpec.describe ApplicationExperiment, :experiment do
end end
end end
it "can exclude from within the block" do
expect(described_class.new('namespaced/stub') { |e| e.exclude! }).to be_excluded
end
describe "tracking events", :snowplow do describe "tracking events", :snowplow do
it "doesn't track if we shouldn't track" do it "doesn't track if we shouldn't track" do
allow(subject).to receive(:should_track?).and_return(false) allow(subject).to receive(:should_track?).and_return(false)
......
...@@ -183,6 +183,7 @@ describe('Tracking', () => { ...@@ -183,6 +183,7 @@ describe('Tracking', () => {
<input class="dropdown" data-track-event="toggle_dropdown"/> <input class="dropdown" data-track-event="toggle_dropdown"/>
<div data-track-event="nested_event"><span class="nested"></span></div> <div data-track-event="nested_event"><span class="nested"></span></div>
<input data-track-eventbogus="click_bogusinput" data-track-label="_label_" value="_value_"/> <input data-track-eventbogus="click_bogusinput" data-track-label="_label_" value="_value_"/>
<input data-track-event="click_input3" data-track-experiment="example" value="_value_"/>
`); `);
}); });
...@@ -242,6 +243,22 @@ describe('Tracking', () => { ...@@ -242,6 +243,22 @@ describe('Tracking', () => {
expect(eventSpy).toHaveBeenCalledWith('_category_', 'nested_event', {}); expect(eventSpy).toHaveBeenCalledWith('_category_', 'nested_event', {});
}); });
it('brings in experiment data if linked to an experiment', () => {
const data = {
variant: 'candidate',
experiment: 'repo_integrations_link',
key: '2bff73f6bb8cc11156c50a8ba66b9b8b',
};
window.gon.global = { experiment: { example: data } };
document.querySelector('[data-track-event="click_input3"]').click();
expect(eventSpy).toHaveBeenCalledWith('_category_', 'click_input3', {
value: '_value_',
context: { schema: 'iglu:com.gitlab/gitlab_experiment/jsonschema/1-0-0', data },
});
});
}); });
describe('tracking page loaded events', () => { describe('tracking page loaded events', () => {
......
...@@ -602,6 +602,38 @@ RSpec.describe ProjectPresenter do ...@@ -602,6 +602,38 @@ RSpec.describe ProjectPresenter do
end end
end end
describe 'experiment(:repo_integrations_link)' do
context 'when enabled' do
before do
stub_experiments(repo_integrations_link: :candidate)
end
it 'includes a button to configure integrations for maintainers' do
project.add_maintainer(user)
expect(empty_repo_statistics_buttons.map(&:label)).to include(
a_string_including('Configure Integration')
)
end
it 'does not include a button if not a maintainer' do
expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
a_string_including('Configure Integration')
)
end
end
context 'when disabled' do
it 'does not include a button' do
project.add_maintainer(user)
expect(empty_repo_statistics_buttons.map(&:label)).not_to include(
a_string_including('Configure Integration')
)
end
end
end
context 'for a developer' do context 'for a developer' do
before do before do
project.add_developer(user) project.add_developer(user)
......
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