Add latest changes from gitlab-org/gitlab@master
This commit is contained in:
parent
90cd393409
commit
43b35a88ca
|
@ -1 +1 @@
|
|||
01edc18bdf95883cc78040c0fdbfd7766de01e1a
|
||||
9a0283f5d3f930bc3c73e14ed1eb127f1321849f
|
||||
|
|
|
@ -204,19 +204,12 @@ export default {
|
|||
:class="{ 'pr-sm-8': sidebarStatus }"
|
||||
>
|
||||
<div
|
||||
class="gl-display-flex gl-justify-content-space-between gl-align-items-baseline gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid flex-column flex-sm-row"
|
||||
class="gl-display-flex gl-justify-content-space-between gl-align-items-center gl-px-1 py-3 py-md-4 gl-border-b-1 gl-border-b-gray-100 gl-border-b-solid gl-flex-direction-column gl-sm-flex-direction-row"
|
||||
>
|
||||
<div
|
||||
data-testid="alert-header"
|
||||
class="gl-display-flex gl-align-items-center gl-justify-content-center"
|
||||
>
|
||||
<div
|
||||
class="gl-display-inline-flex gl-align-items-center gl-justify-content-space-between"
|
||||
>
|
||||
<gl-badge class="gl-mr-3">
|
||||
<strong>{{ s__('AlertManagement|Alert') }}</strong>
|
||||
</gl-badge>
|
||||
</div>
|
||||
<div data-testid="alert-header">
|
||||
<gl-badge class="gl-mr-3">
|
||||
<strong>{{ s__('AlertManagement|Alert') }}</strong>
|
||||
</gl-badge>
|
||||
<span>
|
||||
<gl-sprintf :message="reportedAtMessage">
|
||||
<template #when>
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Projects::ProductAnalyticsController < Projects::ApplicationController
|
||||
before_action :feature_enabled!
|
||||
before_action :authorize_read_product_analytics!
|
||||
before_action :tracker_variables, only: [:setup, :test]
|
||||
|
||||
def index
|
||||
@events = product_analytics_events.order_by_time.page(params[:page])
|
||||
end
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
def test
|
||||
@event = product_analytics_events.try(:first)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def product_analytics_events
|
||||
@project.product_analytics_events
|
||||
end
|
||||
|
||||
def tracker_variables
|
||||
# We use project id as Snowplow appId
|
||||
@project_id = @project.id.to_s
|
||||
|
||||
# Snowplow remembers values like appId and platform between reloads.
|
||||
# That is why we have to rename the tracker with a random integer.
|
||||
@random = rand(999999)
|
||||
|
||||
# Generate random platform every time a tracker is rendered.
|
||||
@platform = %w(web mob app)[(@random % 3)]
|
||||
end
|
||||
|
||||
def feature_enabled!
|
||||
render_404 unless Feature.enabled?(:product_analytics, @project, default_enabled: false)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ProductAnalyticsHelper
|
||||
def product_analytics_tracker_url
|
||||
ProductAnalytics::Tracker::URL
|
||||
end
|
||||
|
||||
def product_analytics_tracker_collector_url
|
||||
ProductAnalytics::Tracker::COLLECTOR_URL
|
||||
end
|
||||
end
|
|
@ -421,6 +421,10 @@ module ProjectsHelper
|
|||
nav_tabs << :operations
|
||||
end
|
||||
|
||||
if can_view_product_analytics?(current_user, project)
|
||||
nav_tabs << :product_analytics
|
||||
end
|
||||
|
||||
tab_ability_map.each do |tab, ability|
|
||||
if can?(current_user, ability, project)
|
||||
nav_tabs << tab
|
||||
|
@ -479,6 +483,11 @@ module ProjectsHelper
|
|||
end
|
||||
end
|
||||
|
||||
def can_view_product_analytics?(current_user, project)
|
||||
Feature.enabled?(:product_analytics, project) &&
|
||||
can?(current_user, :read_product_analytics, project)
|
||||
end
|
||||
|
||||
def search_tab_ability_map
|
||||
@search_tab_ability_map ||= tab_ability_map.merge(
|
||||
blobs: :download_code,
|
||||
|
@ -738,6 +747,7 @@ module ProjectsHelper
|
|||
user
|
||||
gcp
|
||||
logs
|
||||
product_analytics
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -19,4 +19,8 @@ class ProductAnalyticsEvent < ApplicationRecord
|
|||
scope :timerange, ->(duration, today = Time.zone.today) {
|
||||
where('collector_tstamp BETWEEN ? AND ? ', today - duration + 1, today + 1)
|
||||
}
|
||||
|
||||
def as_json_wo_empty
|
||||
as_json.compact
|
||||
end
|
||||
end
|
||||
|
|
|
@ -340,6 +340,10 @@ class Project < ApplicationRecord
|
|||
has_many :webide_pipelines, -> { webide_source }, class_name: 'Ci::Pipeline', inverse_of: :project
|
||||
has_many :reviews, inverse_of: :project
|
||||
|
||||
# Can be too many records. We need to implement delete_all in batches.
|
||||
# Issue https://gitlab.com/gitlab-org/gitlab/-/issues/228637
|
||||
has_many :product_analytics_events, dependent: :destroy # rubocop:disable Cop/ActiveRecordDependent
|
||||
|
||||
accepts_nested_attributes_for :variables, allow_destroy: true
|
||||
accepts_nested_attributes_for :project_feature, update_only: true
|
||||
accepts_nested_attributes_for :project_setting, update_only: true
|
||||
|
|
|
@ -264,6 +264,7 @@ class ProjectPolicy < BasePolicy
|
|||
enable :metrics_dashboard
|
||||
enable :read_confidential_issues
|
||||
enable :read_package
|
||||
enable :read_product_analytics
|
||||
end
|
||||
|
||||
# We define `:public_user_access` separately because there are cases in gitlab-ee
|
||||
|
|
|
@ -252,6 +252,12 @@
|
|||
%span
|
||||
= _('Error Tracking')
|
||||
|
||||
- if project_nav_tab?(:product_analytics)
|
||||
= nav_link(controller: :product_analytics) do
|
||||
= link_to project_product_analytics_path(@project), title: _('Product Analytics') do
|
||||
%span
|
||||
= _('Product Analytics')
|
||||
|
||||
- if project_nav_tab? :serverless
|
||||
= nav_link(controller: :functions) do
|
||||
= link_to project_serverless_functions_path(@project), title: _('Serverless') do
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
.mb-3
|
||||
%ul.nav-links
|
||||
= nav_link(path: 'product_analytics#index') do
|
||||
= link_to _('Events'), project_product_analytics_path(@project)
|
||||
= nav_link(path: 'product_analytics#test') do
|
||||
= link_to _('Test'), test_project_product_analytics_path(@project)
|
||||
= nav_link(path: 'product_analytics#setup') do
|
||||
= link_to _('Setup'), setup_project_product_analytics_path(@project)
|
|
@ -0,0 +1,10 @@
|
|||
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
|
||||
p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
|
||||
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
|
||||
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","<%= product_analytics_tracker_url -%>","snowplow<%= @random -%>"));
|
||||
snowplow<%= @random -%>("newTracker", "sp", "<%= product_analytics_tracker_collector_url -%>", {
|
||||
appId: "<%= @project_id -%>",
|
||||
platform: "<%= @platform -%>",
|
||||
eventMethod: "get"
|
||||
});
|
||||
snowplow<%= @random -%>('trackPageView');
|
|
@ -0,0 +1,16 @@
|
|||
- page_title 'Product Analytics'
|
||||
|
||||
= render 'links'
|
||||
|
||||
- if @events.any?
|
||||
%p
|
||||
- if @events.total_count > @events.size
|
||||
= _('Number of events for this project: %{total_count}.') % { total_count: number_with_delimiter(@events.total_count) }
|
||||
%ol
|
||||
- @events.each do |event|
|
||||
%li
|
||||
%code= event.as_json_wo_empty
|
||||
- else
|
||||
.empty-state
|
||||
.text-content
|
||||
= _('There are currently no events.')
|
|
@ -0,0 +1,9 @@
|
|||
= render "links"
|
||||
%p
|
||||
= _('Copy the code below to implement tracking in your application:')
|
||||
|
||||
%pre
|
||||
= render "tracker"
|
||||
|
||||
%p.hint
|
||||
= _('A platform value can be web, mob or app.')
|
|
@ -0,0 +1,14 @@
|
|||
= render 'links'
|
||||
|
||||
%p
|
||||
= _('This page sends a payload. Go back to the events page to see a newly created event.')
|
||||
|
||||
- if @event
|
||||
%p
|
||||
= _('Last item before this page loaded in your browser:')
|
||||
|
||||
%code
|
||||
= @event.as_json_wo_empty
|
||||
|
||||
:javascript
|
||||
#{render 'tracker'}
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Fix dependency proxy not working with object storage
|
||||
merge_request: 37878
|
||||
author:
|
||||
type: fixed
|
|
@ -306,6 +306,13 @@ constraints(::Constraints::ProjectUrlConstrainer.new) do
|
|||
resources :projects, only: :index
|
||||
end
|
||||
|
||||
resources :product_analytics, only: [:index] do
|
||||
collection do
|
||||
get :setup
|
||||
get :test
|
||||
end
|
||||
end
|
||||
|
||||
resources :error_tracking, only: [:index], controller: :error_tracking do
|
||||
collection do
|
||||
get ':issue_id/details',
|
||||
|
|
|
@ -145,6 +145,10 @@ See [database guidelines](database/index.md).
|
|||
|
||||
- [Refactoring guidelines](refactoring_guide/index.md)
|
||||
|
||||
## Deprecation guides
|
||||
|
||||
- [Deprecation guidelines](deprecation_guidelines/index.md)
|
||||
|
||||
## Documentation guides
|
||||
|
||||
- [Writing documentation](documentation/index.md)
|
||||
|
|
|
@ -0,0 +1,23 @@
|
|||
# Deprecation guidelines
|
||||
|
||||
This page includes information about how and when to remove or make breaking
|
||||
changes to GitLab features.
|
||||
|
||||
## Terminology
|
||||
|
||||
It's important to understand the difference between **deprecation** and
|
||||
**removal**:
|
||||
|
||||
**Deprecation** is the process of flagging/marking/announcing that a feature
|
||||
will be removed in a future version of GitLab.
|
||||
|
||||
**Removal** is the process of actually removing a feature that was previously
|
||||
deprecated.
|
||||
|
||||
## When can a feature be deprecated?
|
||||
|
||||
A feature can be deprecated at any time, provided there is a viable alternative.
|
||||
|
||||
## When can a feature be removed/changed?
|
||||
|
||||
See our [Release and Maintenance policy](../../policy/maintenance.md).
|
|
@ -16,6 +16,7 @@ your applications:
|
|||
- Manage your infrastructure with [Infrastructure as Code](../user/infrastructure/index.md) approaches.
|
||||
- Discover and view errors generated by your applications with [Error Tracking](error_tracking.md).
|
||||
- Handle incidents in your applications and services with [Incident Management](incident_management/index.md).
|
||||
- See how your application is used and analyze events with [Product Analytics](product_analytics.md).
|
||||
- Create, toggle, and remove [Feature Flags](feature_flags.md). **(PREMIUM)**
|
||||
- [Trace](tracing.md) the performance and health of a deployed application. **(ULTIMATE)**
|
||||
- Change the [settings of the Monitoring Dashboard](metrics/dashboards/settings.md).
|
||||
|
|
|
@ -0,0 +1,82 @@
|
|||
---
|
||||
stage: Monitor
|
||||
group: APM
|
||||
info: To determine the technical writer assigned to the Stage/Group associated with this page, see https://about.gitlab.com/handbook/engineering/ux/technical-writing/#designated-technical-writers
|
||||
---
|
||||
|
||||
# Product Analytics **(CORE)**
|
||||
|
||||
> - [Introduced](https://gitlab.com/gitlab-org/gitlab/-/issues/225167) in GitLab 13.3.
|
||||
> - It's deployed behind a feature flag, disabled by default.
|
||||
> - It's disabled on GitLab.com.
|
||||
> - It's able to be enabled or disabled per-project.
|
||||
> - It's not recommended for production use.
|
||||
> - To use it in GitLab self-managed instances, ask a GitLab administrator to enable it.
|
||||
|
||||
GitLab allows you to go from planning an application to getting feedback. Feedback
|
||||
is not just observability, but also knowing how people use your product.
|
||||
Product Analytics uses events sent from your application to know how they are using it.
|
||||
It's based on [Snowplow](https://github.com/snowplow/snowplow), the best open-source
|
||||
event tracker. With Product Analytics, you can receive and analyze the Snowplow data
|
||||
inside GitLab.
|
||||
|
||||
## Enable or disable Product Analytics
|
||||
|
||||
Product Analytics is under development and not ready for production use. It's
|
||||
deployed behind a feature flag that's **disabled by default**.
|
||||
[GitLab administrators with access to the GitLab Rails console](../administration/feature_flags.md)
|
||||
can enable it for your instance. Product Analytics can be enabled or disabled per-project.
|
||||
|
||||
To enable it:
|
||||
|
||||
```ruby
|
||||
# Instance-wide
|
||||
Feature.enable(:product_analytics)
|
||||
# or by project
|
||||
Feature.enable(:product_analytics, Project.find(<project id>))
|
||||
```
|
||||
|
||||
To disable it:
|
||||
|
||||
```ruby
|
||||
# Instance-wide
|
||||
Feature.disable(:product_analytics)
|
||||
# or by project
|
||||
Feature.disable(:product_analytics, Project.find(<project id>))
|
||||
```
|
||||
|
||||
## Access Product Analytics
|
||||
|
||||
After enabling the feature flag for Product Analytics, you can access the
|
||||
user interface:
|
||||
|
||||
1. Sign in to GitLab as a user with Reporter or greater
|
||||
[permissions](../user/permissions.md).
|
||||
1. Navigate to **{cloud-gear}** **Operations > TODO HERE**
|
||||
|
||||
The user interface contains:
|
||||
|
||||
- An Events page that shows the recent events and a total count.
|
||||
- A test page that sends a sample event.
|
||||
- A setup page containing the code to implement in your application.
|
||||
|
||||
## Rate limits for Product Analytics
|
||||
|
||||
While Product Analytics is under development, it's rate-limited to
|
||||
**100 events per minute** per project. This limit prevents the events table in the
|
||||
database from growing too quickly.
|
||||
|
||||
## Data storage for Product Analytics
|
||||
|
||||
Product Analytics stores events are stored in GitLab database.
|
||||
|
||||
CAUTION: **Caution:**
|
||||
This data storage is experimental, and GitLab is likely to remove this data during
|
||||
future development.
|
||||
|
||||
## Event collection
|
||||
|
||||
Events are collected by [Rails collector](https://gitlab.com/gitlab-org/gitlab/-/merge_requests/36443),
|
||||
allowing GitLab to ship the feature fast. Due to scalability issue, GitLab plans
|
||||
to switch to a separate application, such as
|
||||
[snowplow-go-collector](https://gitlab.com/gitlab-org/snowplow-go-collector), for event collection.
|
Binary file not shown.
Before Width: | Height: | Size: 377 KiB |
|
@ -4,14 +4,10 @@ type: index, reference
|
|||
|
||||
# Merge requests
|
||||
|
||||
Merge requests allow you to visualize and collaborate on the proposed changes
|
||||
to source code that exist as commits on a given Git branch.
|
||||
A Merge Request (**MR**) is a _request_ to _merge_ one branch into another.
|
||||
|
||||
![Merge request view](img/merge_request.png)
|
||||
|
||||
A Merge Request (**MR**) is the basis of GitLab as a code collaboration and version
|
||||
control platform. It's exactly as the name implies: a _request_ to _merge_ one
|
||||
branch into another.
|
||||
Use merge requests to visualize and collaborate on proposed changes
|
||||
to source code.
|
||||
|
||||
## Use cases
|
||||
|
||||
|
|
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ProductAnalytics
|
||||
class Tracker
|
||||
# The file is located in the /public directory
|
||||
URL = Gitlab.config.gitlab.url + '/-/sp.js'
|
||||
|
||||
# The collector URL minus protocol and /i
|
||||
COLLECTOR_URL = Gitlab.config.gitlab.url.sub(/\Ahttps?\:\/\//, '') + '/-/collector'
|
||||
end
|
||||
end
|
|
@ -1127,6 +1127,9 @@ msgstr ""
|
|||
msgid "A plain HTML site that uses Netlify for CI/CD instead of GitLab, but still with all the other great GitLab features."
|
||||
msgstr ""
|
||||
|
||||
msgid "A platform value can be web, mob or app."
|
||||
msgstr ""
|
||||
|
||||
msgid "A project boilerplate for Salesforce App development with Salesforce Developer tools."
|
||||
msgstr ""
|
||||
|
||||
|
@ -6779,6 +6782,9 @@ msgstr ""
|
|||
msgid "Copy source branch name"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy the code below to implement tracking in your application:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Copy token"
|
||||
msgstr ""
|
||||
|
||||
|
@ -13728,6 +13734,9 @@ msgstr ""
|
|||
msgid "Last edited by %{name}"
|
||||
msgstr ""
|
||||
|
||||
msgid "Last item before this page loaded in your browser:"
|
||||
msgstr ""
|
||||
|
||||
msgid "Last name"
|
||||
msgstr ""
|
||||
|
||||
|
@ -16322,6 +16331,9 @@ msgstr ""
|
|||
msgid "Number of employees"
|
||||
msgstr ""
|
||||
|
||||
msgid "Number of events for this project: %{total_count}."
|
||||
msgstr ""
|
||||
|
||||
msgid "Number of files touched"
|
||||
msgstr ""
|
||||
|
||||
|
@ -17824,6 +17836,9 @@ msgstr ""
|
|||
msgid "Proceed"
|
||||
msgstr ""
|
||||
|
||||
msgid "Product Analytics"
|
||||
msgstr ""
|
||||
|
||||
msgid "Productivity"
|
||||
msgstr ""
|
||||
|
||||
|
@ -21747,6 +21762,9 @@ msgstr ""
|
|||
msgid "Settings to prevent self-approval across all projects in the instance. Only an administrator can modify these settings."
|
||||
msgstr ""
|
||||
|
||||
msgid "Setup"
|
||||
msgstr ""
|
||||
|
||||
msgid "Severity"
|
||||
msgstr ""
|
||||
|
||||
|
@ -23891,6 +23909,9 @@ msgstr ""
|
|||
msgid "The vulnerability is no longer detected. Verify the vulnerability has been remediated before changing its status."
|
||||
msgstr ""
|
||||
|
||||
msgid "There are currently no events."
|
||||
msgstr ""
|
||||
|
||||
msgid "There are no %{replicableTypeName} to show"
|
||||
msgstr ""
|
||||
|
||||
|
@ -24497,6 +24518,9 @@ msgstr ""
|
|||
msgid "This page is unavailable because you are not allowed to read information across multiple projects."
|
||||
msgstr ""
|
||||
|
||||
msgid "This page sends a payload. Go back to the events page to see a newly created event."
|
||||
msgstr ""
|
||||
|
||||
msgid "This pipeline does not use the %{codeStart}needs%{codeEnd} keyword and can't be represented as a directed acyclic graph."
|
||||
msgstr ""
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,74 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe Projects::ProductAnalyticsController do
|
||||
let_it_be(:project) { create(:project) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before(:all) do
|
||||
project.add_maintainer(user)
|
||||
end
|
||||
|
||||
before do
|
||||
sign_in(user)
|
||||
stub_feature_flags(product_analytics: true)
|
||||
end
|
||||
|
||||
describe 'GET #index' do
|
||||
it 'renders index with 200 status code' do
|
||||
get :index, params: project_params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template(:index)
|
||||
end
|
||||
|
||||
context 'with an anonymous user' do
|
||||
before do
|
||||
sign_out(user)
|
||||
end
|
||||
|
||||
it 'redirects to sign-in page' do
|
||||
get :index, params: project_params
|
||||
|
||||
expect(response).to redirect_to(new_user_session_path)
|
||||
end
|
||||
end
|
||||
|
||||
context 'feature flag disabled' do
|
||||
before do
|
||||
stub_feature_flags(product_analytics: false)
|
||||
end
|
||||
|
||||
it 'returns not found' do
|
||||
get :index, params: project_params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:not_found)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #test' do
|
||||
it 'renders test with 200 status code' do
|
||||
get :test, params: project_params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template(:test)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'GET #setup' do
|
||||
it 'renders setup with 200 status code' do
|
||||
get :setup, params: project_params
|
||||
|
||||
expect(response).to have_gitlab_http_status(:ok)
|
||||
expect(response).to render_template(:setup)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def project_params(opts = {})
|
||||
opts.reverse_merge(namespace_id: project.namespace, project_id: project)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,29 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Product Analytics > Events' do
|
||||
let_it_be(:project) { create(:project_empty_repo) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
let(:event) { create(:product_analytics_event, project: project) }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'shows no events message' do
|
||||
visit(project_product_analytics_path(project))
|
||||
|
||||
expect(page).to have_content('There are currently no events')
|
||||
end
|
||||
|
||||
it 'shows events' do
|
||||
event
|
||||
|
||||
visit(project_product_analytics_path(project))
|
||||
|
||||
expect(page).to have_content('dvce_created_tstamp')
|
||||
expect(page).to have_content(event.event_id)
|
||||
end
|
||||
end
|
|
@ -0,0 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Product Analytics > Setup' do
|
||||
let_it_be(:project) { create(:project_empty_repo) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'shows the setup instructions' do
|
||||
visit(setup_project_product_analytics_path(project))
|
||||
|
||||
expect(page).to have_content('Copy the code below to implement tracking in your application')
|
||||
end
|
||||
end
|
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
RSpec.describe 'Product Analytics > Test' do
|
||||
let_it_be(:project) { create(:project_empty_repo) }
|
||||
let_it_be(:user) { create(:user) }
|
||||
|
||||
before do
|
||||
project.add_maintainer(user)
|
||||
sign_in(user)
|
||||
end
|
||||
|
||||
it 'says it sends a payload' do
|
||||
visit(test_project_product_analytics_path(project))
|
||||
|
||||
expect(page).to have_content('This page sends a payload.')
|
||||
end
|
||||
|
||||
it 'shows the last event if there is one' do
|
||||
event = create(:product_analytics_event, project: project)
|
||||
|
||||
visit(test_project_product_analytics_path(project))
|
||||
|
||||
expect(page).to have_content(event.event_id)
|
||||
end
|
||||
end
|
|
@ -518,6 +518,7 @@ project:
|
|||
- build_report_results
|
||||
- vulnerability_statistic
|
||||
- vulnerability_historical_statistics
|
||||
- product_analytics_events
|
||||
award_emoji:
|
||||
- awardable
|
||||
- user
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "spec_helper"
|
||||
|
||||
RSpec.describe ProductAnalytics::Tracker do
|
||||
it { expect(described_class::URL).to eq('http://localhost/-/sp.js') }
|
||||
it { expect(described_class::COLLECTOR_URL).to eq('localhost/-/collector') }
|
||||
end
|
|
@ -67,6 +67,7 @@ RSpec.shared_context 'project navbar structure' do
|
|||
_('Incidents'),
|
||||
_('Environments'),
|
||||
_('Error Tracking'),
|
||||
_('Product Analytics'),
|
||||
_('Serverless'),
|
||||
_('Logs'),
|
||||
_('Kubernetes')
|
||||
|
|
Loading…
Reference in New Issue