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
c35a9bab
Commit
c35a9bab
authored
Feb 01, 2021
by
GitLab Bot
Browse files
Options
Browse Files
Download
Plain Diff
Automatic merge of gitlab-org/gitlab master
parents
9ce5b1c2
27b43a19
Changes
22
Hide whitespace changes
Inline
Side-by-side
Showing
22 changed files
with
351 additions
and
80 deletions
+351
-80
GITALY_SERVER_VERSION
GITALY_SERVER_VERSION
+1
-1
app/controllers/groups/email_campaigns_controller.rb
app/controllers/groups/email_campaigns_controller.rb
+61
-0
app/helpers/in_product_marketing_helper.rb
app/helpers/in_product_marketing_helper.rb
+2
-27
changelogs/unreleased/kassio-manage-import-gmau-metrics.yml
changelogs/unreleased/kassio-manage-import-gmau-metrics.yml
+5
-0
config/routes/group.rb
config/routes/group.rb
+1
-0
ee/app/controllers/ee/projects/issues_controller.rb
ee/app/controllers/ee/projects/issues_controller.rb
+5
-3
ee/changelogs/unreleased/299462-create-issue-from-vulnerability-details-edited-text-is-discarde.yml
...ue-from-vulnerability-details-edited-text-is-discarde.yml
+5
-0
ee/config/feature_flags/development/repository_push_audit_event.yml
...feature_flags/development/repository_push_audit_event.yml
+3
-3
ee/spec/controllers/projects/issues_controller_spec.rb
ee/spec/controllers/projects/issues_controller_spec.rb
+10
-1
ee/spec/frontend/security_configuration/sast/components/analyzer_configuration_spec.js
...figuration/sast/components/analyzer_configuration_spec.js
+1
-1
ee/spec/frontend/security_configuration/sast/components/app_spec.js
...ontend/security_configuration/sast/components/app_spec.js
+38
-35
ee/spec/frontend/security_configuration/sast/components/configuration_form_spec.js
..._configuration/sast/components/configuration_form_spec.js
+1
-1
ee/spec/frontend/security_configuration/sast/components/dynamic_fields_spec.js
...rity_configuration/sast/components/dynamic_fields_spec.js
+1
-1
ee/spec/frontend/security_configuration/sast/components/utils_spec.js
...tend/security_configuration/sast/components/utils_spec.js
+1
-1
ee/spec/frontend/security_configuration/sast/helpers.js
ee/spec/frontend/security_configuration/sast/helpers.js
+1
-0
ee/spec/frontend/security_configuration/sast/mock_data.js
ee/spec/frontend/security_configuration/sast/mock_data.js
+47
-0
lib/gitlab/usage_data.rb
lib/gitlab/usage_data.rb
+13
-0
spec/frontend/__helpers__/graphql_helpers.js
spec/frontend/__helpers__/graphql_helpers.js
+14
-0
spec/frontend/__helpers__/graphql_helpers_spec.js
spec/frontend/__helpers__/graphql_helpers_spec.js
+23
-0
spec/frontend/vue_shared/security_reports/security_reports_app_spec.js
.../vue_shared/security_reports/security_reports_app_spec.js
+4
-6
spec/lib/gitlab/usage_data_spec.rb
spec/lib/gitlab/usage_data_spec.rb
+23
-0
spec/requests/groups/email_campaigns_controller_spec.rb
spec/requests/groups/email_campaigns_controller_spec.rb
+91
-0
No files found.
GITALY_SERVER_VERSION
View file @
c35a9bab
e342c59d0c6575245a335bbe9dfe95d9a06b3a2f
9ed0124f6cdfc359521feae325420549781d883e
app/controllers/groups/email_campaigns_controller.rb
0 → 100644
View file @
c35a9bab
# frozen_string_literal: true
class
Groups::EmailCampaignsController
<
Groups
::
ApplicationController
include
InProductMarketingHelper
include
Gitlab
::
Tracking
::
ControllerConcern
EMAIL_CAMPAIGNS_SCHEMA_URL
=
'iglu:com.gitlab/email_campaigns/jsonschema/1-0-0'
feature_category
:navigation
before_action
:check_params
def
index
track_click
redirect_to
redirect_link
end
private
def
track_click
data
=
{
namespace_id:
group
.
id
,
track:
@track
,
series:
@series
,
subject_line:
subject_line
(
@track
,
@series
)
}
track_self_describing_event
(
EMAIL_CAMPAIGNS_SCHEMA_URL
,
data:
data
)
end
def
redirect_link
case
@track
when
:create
create_track_url
when
:verify
project_pipelines_url
(
group
.
projects
.
first
)
when
:trial
'https://about.gitlab.com/free-trial/'
when
:team
group_group_members_url
(
group
)
end
end
def
create_track_url
[
new_project_url
,
new_project_url
(
anchor:
'import_project'
),
help_page_url
(
'user/project/repository/repository_mirroring'
)
][
@series
]
end
def
check_params
@track
=
params
[
:track
]
&
.
to_sym
@series
=
params
[
:series
]
&
.
to_i
track_valid
=
@track
.
in?
(
Namespaces
::
InProductMarketingEmailsService
::
TRACKS
.
keys
)
series_valid
=
@series
.
in?
(
0
..
Namespaces
::
InProductMarketingEmailsService
::
INTERVAL_DAYS
.
size
-
1
)
render_404
unless
track_valid
&&
series_valid
end
end
app/helpers/in_product_marketing_helper.rb
View file @
c35a9bab
...
@@ -187,9 +187,9 @@ module InProductMarketingHelper
...
@@ -187,9 +187,9 @@ module InProductMarketingHelper
def
cta_link
(
track
,
series
,
group
,
format:
nil
)
def
cta_link
(
track
,
series
,
group
,
format:
nil
)
case
format
case
format
when
:html
when
:html
link_to
in_product_marketing_cta_text
(
track
,
series
),
in_product_marketing_cta_link
(
track
,
series
,
group
),
target:
'_blank'
,
rel:
'noopener noreferrer'
link_to
in_product_marketing_cta_text
(
track
,
series
),
group_email_campaigns_url
(
group
,
track:
track
,
series:
series
),
target:
'_blank'
,
rel:
'noopener noreferrer'
else
else
[
in_product_marketing_cta_text
(
track
,
series
),
in_product_marketing_cta_link
(
track
,
series
,
group
)].
join
(
' >> '
)
[
in_product_marketing_cta_text
(
track
,
series
),
group_email_campaigns_url
(
group
,
track:
track
,
series:
series
)].
join
(
' >> '
)
end
end
end
end
...
@@ -260,31 +260,6 @@ module InProductMarketingHelper
...
@@ -260,31 +260,6 @@ module InProductMarketingHelper
}[
track
][
series
]
}[
track
][
series
]
end
end
def
in_product_marketing_cta_link
(
track
,
series
,
group
)
{
create:
[
new_project_url
,
new_project_url
(
anchor:
'import_project'
),
help_page_url
(
'user/project/repository/repository_mirroring'
)
],
verify:
[
project_pipelines_url
(
group
.
projects
.
first
),
project_pipelines_url
(
group
.
projects
.
first
),
project_pipelines_url
(
group
.
projects
.
first
)
],
trial:
[
'https://about.gitlab.com/free-trial/'
,
'https://about.gitlab.com/free-trial/'
,
'https://about.gitlab.com/free-trial/'
],
team:
[
group_group_members_url
(
group
),
group_group_members_url
(
group
),
group_group_members_url
(
group
)
]
}[
track
][
series
]
end
def
project_link
(
format
)
def
project_link
(
format
)
link
(
s_
(
'InProductMarketing|create a project'
),
help_page_url
(
'gitlab-basics/create-project'
),
format
)
link
(
s_
(
'InProductMarketing|create a project'
),
help_page_url
(
'gitlab-basics/create-project'
),
format
)
end
end
...
...
changelogs/unreleased/kassio-manage-import-gmau-metrics.yml
0 → 100644
View file @
c35a9bab
---
title
:
Add the Manage::Import total GMAU metric
merge_request
:
51496
author
:
type
:
added
config/routes/group.rb
View file @
c35a9bab
...
@@ -111,6 +111,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
...
@@ -111,6 +111,7 @@ constraints(::Constraints::GroupUrlConstrainer.new) do
resources
:container_registries
,
only:
[
:index
,
:show
],
controller:
'registry/repositories'
resources
:container_registries
,
only:
[
:index
,
:show
],
controller:
'registry/repositories'
resource
:dependency_proxy
,
only:
[
:show
,
:update
]
resource
:dependency_proxy
,
only:
[
:show
,
:update
]
resources
:email_campaigns
,
only: :index
end
end
scope
(
path:
'*id'
,
scope
(
path:
'*id'
,
...
...
ee/app/controllers/ee/projects/issues_controller.rb
View file @
c35a9bab
...
@@ -66,10 +66,12 @@ module EE
...
@@ -66,10 +66,12 @@ module EE
end
end
def
vulnerability_issue_build_parameters
def
vulnerability_issue_build_parameters
issue
=
params
[
:issue
]
{
{
title:
_
(
"Investigate vulnerability: %{title}"
)
%
{
title:
vulnerability
.
title
}
,
title:
issue
.
fetch
(
:title
,
_
(
"Investigate vulnerability: %{title}"
)
%
{
title:
vulnerability
.
title
})
,
description:
render_vulnerability_description
,
description:
issue
.
fetch
(
:description
,
render_vulnerability_description
)
,
confidential:
true
confidential:
issue
.
fetch
(
:confidential
,
true
)
}
}
end
end
...
...
ee/changelogs/unreleased/299462-create-issue-from-vulnerability-details-edited-text-is-discarde.yml
0 → 100644
View file @
c35a9bab
---
title
:
Fixed bug that overwrote issue description changes from vulnerabilities
merge_request
:
52376
author
:
type
:
fixed
ee/config/feature_flags/development/repository_push_audit_event.yml
View file @
c35a9bab
---
---
name
:
repository_push_audit_event
name
:
repository_push_audit_event
introduced_by_url
:
introduced_by_url
:
https://gitlab.com/gitlab-org/gitlab/-/merge_requests/15667
rollout_issue_url
:
rollout_issue_url
:
milestone
:
milestone
:
'
12.3'
type
:
development
type
:
development
group
:
group
:
group::compliance
default_enabled
:
false
default_enabled
:
false
ee/spec/controllers/projects/issues_controller_spec.rb
View file @
c35a9bab
...
@@ -112,6 +112,15 @@ RSpec.describe Projects::IssuesController do
...
@@ -112,6 +112,15 @@ RSpec.describe Projects::IssuesController do
expect
(
project
.
issues
.
last
.
vulnerability_links
.
first
.
vulnerability
).
to
eq
(
vulnerability
)
expect
(
project
.
issues
.
last
.
vulnerability_links
.
first
.
vulnerability
).
to
eq
(
vulnerability
)
end
end
it
'overwrites the default fields'
do
send_request
issue
=
project
.
issues
.
last
expect
(
issue
.
title
).
to
eq
(
'Title'
)
expect
(
issue
.
description
).
to
eq
(
'Description'
)
expect
(
issue
.
confidential
).
to
be
false
end
context
'when vulnerability already has a linked issue'
do
context
'when vulnerability already has a linked issue'
do
render_views
render_views
...
@@ -131,7 +140,7 @@ RSpec.describe Projects::IssuesController do
...
@@ -131,7 +140,7 @@ RSpec.describe Projects::IssuesController do
post
:create
,
params:
{
post
:create
,
params:
{
namespace_id:
project
.
namespace
.
to_param
,
namespace_id:
project
.
namespace
.
to_param
,
project_id:
project
,
project_id:
project
,
issue:
{
title:
'Title'
,
description:
'Description'
},
issue:
{
title:
'Title'
,
description:
'Description'
,
confidential:
'false'
},
vulnerability_id:
vulnerability
.
id
vulnerability_id:
vulnerability
.
id
}
}
end
end
...
...
ee/spec/frontend/security_configuration/sast/components/analyzer_configuration_spec.js
View file @
c35a9bab
import
{
mount
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
AnalyzerConfiguration
from
'
ee/security_configuration/sast/components/analyzer_configuration.vue
'
;
import
AnalyzerConfiguration
from
'
ee/security_configuration/sast/components/analyzer_configuration.vue
'
;
import
DynamicFields
from
'
ee/security_configuration/sast/components/dynamic_fields.vue
'
;
import
DynamicFields
from
'
ee/security_configuration/sast/components/dynamic_fields.vue
'
;
import
{
makeAnalyzerEntities
,
makeEntities
,
makeSastCiConfiguration
}
from
'
./helpers
'
;
import
{
makeAnalyzerEntities
,
makeEntities
,
makeSastCiConfiguration
}
from
'
.
.
/helpers
'
;
describe
(
'
AnalyzerConfiguration component
'
,
()
=>
{
describe
(
'
AnalyzerConfiguration component
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
...
...
ee/spec/frontend/security_configuration/sast/components/app_spec.js
View file @
c35a9bab
import
{
merge
}
from
'
lodash
'
;
import
Vue
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
{
GlLink
,
GlLoadingIcon
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
GlLink
,
GlLoadingIcon
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
SASTConfigurationApp
from
'
ee/security_configuration/sast/components/app.vue
'
;
import
SASTConfigurationApp
from
'
ee/security_configuration/sast/components/app.vue
'
;
import
ConfigurationForm
from
'
ee/security_configuration/sast/components/configuration_form.vue
'
;
import
ConfigurationForm
from
'
ee/security_configuration/sast/components/configuration_form.vue
'
;
import
{
makeSastCiConfiguration
}
from
'
./helpers
'
;
import
{
stripTypenames
}
from
'
helpers/graphql_helpers
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
sastCiConfigurationQuery
from
'
ee/security_configuration/sast/graphql/sast_ci_configuration.query.graphql
'
;
import
{
sastCiConfigurationQueryResponse
}
from
'
../mock_data
'
;
Vue
.
use
(
VueApollo
);
const
sastDocumentationPath
=
'
/help/sast
'
;
const
sastDocumentationPath
=
'
/help/sast
'
;
const
projectPath
=
'
namespace/project
'
;
const
projectPath
=
'
namespace/project
'
;
...
@@ -10,29 +18,29 @@ const projectPath = 'namespace/project';
...
@@ -10,29 +18,29 @@ const projectPath = 'namespace/project';
describe
(
'
SAST Configuration App
'
,
()
=>
{
describe
(
'
SAST Configuration App
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
const
createComponent
=
({
const
pendingHandler
=
()
=>
new
Promise
(()
=>
{});
stubs
=
{},
const
successHandler
=
async
()
=>
sastCiConfigurationQueryResponse
;
loading
=
true
,
const
failureHandler
=
async
()
=>
({
errors
:
[{
message
:
'
some error
'
}]
});
hasLoadingError
=
false
,
const
createMockApolloProvider
=
(
handler
)
=>
sastCiConfiguration
=
null
,
createMockApollo
([[
sastCiConfigurationQuery
,
handler
]]);
}
=
{})
=>
{
wrapper
=
shallowMount
(
SASTConfigurationApp
,
{
const
createComponent
=
(
options
)
=>
{
mocks
:
{
$apollo
:
{
loading
}
},
wrapper
=
shallowMount
(
stubs
,
SASTConfigurationApp
,
provide
:
{
merge
(
sastDocumentationPath
,
{
projectPath
,
// Use a function reference here so it's lazily initialized, and can
},
// be replaced with other handlers in certain tests without
// While setting data is usually frowned upon, it is the documented way
// initialising twice.
// of mocking GraphQL response data:
apolloProvider
:
()
=>
createMockApolloProvider
(
successHandler
),
// https://docs.gitlab.com/ee/development/fe_guide/graphql.html#testing
provide
:
{
data
()
{
sastDocumentationPath
,
return
{
projectPath
,
hasLoadingError
,
}
,
sastCiConfiguration
,
}
,
};
options
,
}
,
)
,
}
);
);
};
};
const
findHeader
=
()
=>
wrapper
.
find
(
'
header
'
);
const
findHeader
=
()
=>
wrapper
.
find
(
'
header
'
);
...
@@ -98,7 +106,7 @@ describe('SAST Configuration App', () => {
...
@@ -98,7 +106,7 @@ describe('SAST Configuration App', () => {
describe
(
'
when loading
'
,
()
=>
{
describe
(
'
when loading
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
createComponent
({
createComponent
({
loading
:
true
,
apolloProvider
:
createMockApolloProvider
(
pendingHandler
)
,
});
});
});
});
...
@@ -118,8 +126,7 @@ describe('SAST Configuration App', () => {
...
@@ -118,8 +126,7 @@ describe('SAST Configuration App', () => {
describe
(
'
when loading failed
'
,
()
=>
{
describe
(
'
when loading failed
'
,
()
=>
{
beforeEach
(()
=>
{
beforeEach
(()
=>
{
createComponent
({
createComponent
({
loading
:
false
,
apolloProvider
:
createMockApolloProvider
(
failureHandler
),
hasLoadingError
:
true
,
});
});
});
});
...
@@ -137,14 +144,8 @@ describe('SAST Configuration App', () => {
...
@@ -137,14 +144,8 @@ describe('SAST Configuration App', () => {
});
});
describe
(
'
when loaded
'
,
()
=>
{
describe
(
'
when loaded
'
,
()
=>
{
let
sastCiConfiguration
;
beforeEach
(()
=>
{
beforeEach
(()
=>
{
sastCiConfiguration
=
makeSastCiConfiguration
();
createComponent
();
createComponent
({
loading
:
false
,
sastCiConfiguration
,
});
});
});
it
(
'
does not display a loading spinner
'
,
()
=>
{
it
(
'
does not display a loading spinner
'
,
()
=>
{
...
@@ -156,7 +157,9 @@ describe('SAST Configuration App', () => {
...
@@ -156,7 +157,9 @@ describe('SAST Configuration App', () => {
});
});
it
(
'
passes the sastCiConfiguration to the sastCiConfiguration prop
'
,
()
=>
{
it
(
'
passes the sastCiConfiguration to the sastCiConfiguration prop
'
,
()
=>
{
expect
(
findConfigurationForm
().
props
(
'
sastCiConfiguration
'
)).
toBe
(
sastCiConfiguration
);
expect
(
findConfigurationForm
().
props
(
'
sastCiConfiguration
'
)).
toEqual
(
stripTypenames
(
sastCiConfigurationQueryResponse
.
data
.
project
.
sastCiConfiguration
),
);
});
});
it
(
'
does not display an alert message
'
,
()
=>
{
it
(
'
does not display an alert message
'
,
()
=>
{
...
...
ee/spec/frontend/security_configuration/sast/components/configuration_form_spec.js
View file @
c35a9bab
...
@@ -8,7 +8,7 @@ import ExpandableSection from 'ee/security_configuration/sast/components/expanda
...
@@ -8,7 +8,7 @@ import ExpandableSection from 'ee/security_configuration/sast/components/expanda
import
configureSastMutation
from
'
ee/security_configuration/sast/graphql/configure_sast.mutation.graphql
'
;
import
configureSastMutation
from
'
ee/security_configuration/sast/graphql/configure_sast.mutation.graphql
'
;
import
{
redirectTo
}
from
'
~/lib/utils/url_utility
'
;
import
{
redirectTo
}
from
'
~/lib/utils/url_utility
'
;
import
*
as
Sentry
from
'
~/sentry/wrapper
'
;
import
*
as
Sentry
from
'
~/sentry/wrapper
'
;
import
{
makeEntities
,
makeSastCiConfiguration
}
from
'
./helpers
'
;
import
{
makeEntities
,
makeSastCiConfiguration
}
from
'
.
.
/helpers
'
;
jest
.
mock
(
'
~/lib/utils/url_utility
'
,
()
=>
({
jest
.
mock
(
'
~/lib/utils/url_utility
'
,
()
=>
({
redirectTo
:
jest
.
fn
(),
redirectTo
:
jest
.
fn
(),
...
...
ee/spec/frontend/security_configuration/sast/components/dynamic_fields_spec.js
View file @
c35a9bab
import
{
shallowMount
,
mount
}
from
'
@vue/test-utils
'
;
import
{
shallowMount
,
mount
}
from
'
@vue/test-utils
'
;
import
DynamicFields
from
'
ee/security_configuration/sast/components/dynamic_fields.vue
'
;
import
DynamicFields
from
'
ee/security_configuration/sast/components/dynamic_fields.vue
'
;
import
{
makeEntities
}
from
'
./helpers
'
;
import
{
makeEntities
}
from
'
.
.
/helpers
'
;
describe
(
'
DynamicFields component
'
,
()
=>
{
describe
(
'
DynamicFields component
'
,
()
=>
{
let
wrapper
;
let
wrapper
;
...
...
ee/spec/frontend/security_configuration/sast/components/utils_spec.js
View file @
c35a9bab
...
@@ -4,7 +4,7 @@ import {
...
@@ -4,7 +4,7 @@ import {
toSastCiConfigurationEntityInput
,
toSastCiConfigurationEntityInput
,
toSastCiConfigurationAnalyzerEntityInput
,
toSastCiConfigurationAnalyzerEntityInput
,
}
from
'
ee/security_configuration/sast/components/utils
'
;
}
from
'
ee/security_configuration/sast/components/utils
'
;
import
{
makeEntities
,
makeAnalyzerEntities
}
from
'
./helpers
'
;
import
{
makeEntities
,
makeAnalyzerEntities
}
from
'
.
.
/helpers
'
;
describe
(
'
isValidConfigurationEntity
'
,
()
=>
{
describe
(
'
isValidConfigurationEntity
'
,
()
=>
{
const
validEntities
=
makeEntities
(
3
);
const
validEntities
=
makeEntities
(
3
);
...
...
ee/spec/frontend/security_configuration/sast/
components/
helpers.js
→
ee/spec/frontend/security_configuration/sast/helpers.js
View file @
c35a9bab
...
@@ -15,6 +15,7 @@ export const makeEntities = (count, changes) =>
...
@@ -15,6 +15,7 @@ export const makeEntities = (count, changes) =>
label
:
`label
${
i
}
`
,
label
:
`label
${
i
}
`
,
type
:
'
string
'
,
type
:
'
string
'
,
value
:
`value
${
i
}
`
,
value
:
`value
${
i
}
`
,
size
:
`MEDIUM`
,
...
changes
,
...
changes
,
}));
}));
...
...
ee/spec/frontend/security_configuration/sast/mock_data.js
0 → 100644
View file @
c35a9bab
import
{
makeEntities
}
from
'
./helpers
'
;
export
const
sastCiConfigurationQueryResponse
=
{
data
:
{
project
:
{
sastCiConfiguration
:
{
global
:
{
nodes
:
makeEntities
(
2
,
{
__typename
:
'
SastCiConfigurationEntity
'
}),
__typename
:
'
SastCiConfigurationEntityConnection
'
,
},
pipeline
:
{
nodes
:
makeEntities
(
2
,
{
__typename
:
'
SastCiConfigurationEntity
'
}),
__typename
:
'
SastCiConfigurationEntityConnection
'
,
},
analyzers
:
{
nodes
:
[
{
description
:
'
Ruby on Rails
'
,
enabled
:
false
,
label
:
'
Brakeman
'
,
name
:
'
brakeman
'
,
variables
:
{
nodes
:
makeEntities
(
2
,
{
__typename
:
'
SastCiConfigurationEntity
'
}),
__typename
:
'
SastCiConfigurationEntityConnection
'
,
},
__typename
:
'
SastCiConfigurationAnalyzersEntity
'
,
},
{
description
:
'
Python
'
,
enabled
:
false
,
label
:
'
Bandit
'
,
name
:
'
bandit
'
,
variables
:
{
nodes
:
[],
__typename
:
'
SastCiConfigurationEntityConnection
'
,
},
__typename
:
'
SastCiConfigurationAnalyzersEntity
'
,
},
],
__typename
:
'
SastCiConfigurationAnalyzersEntityConnection
'
,
},
__typename
:
'
SastCiConfiguration
'
,
},
__typename
:
'
Project
'
,
},
},
};
lib/gitlab/usage_data.rb
View file @
c35a9bab
...
@@ -582,6 +582,7 @@ module Gitlab
...
@@ -582,6 +582,7 @@ module Gitlab
users_created:
count
(
::
User
.
where
(
time_period
),
start:
user_minimum_id
,
finish:
user_maximum_id
),
users_created:
count
(
::
User
.
where
(
time_period
),
start:
user_minimum_id
,
finish:
user_maximum_id
),
omniauth_providers:
filtered_omniauth_provider_names
.
reject
{
|
name
|
name
==
'group_saml'
},
omniauth_providers:
filtered_omniauth_provider_names
.
reject
{
|
name
|
name
==
'group_saml'
},
user_auth_by_provider:
distinct_count_user_auth_by_provider
(
time_period
),
user_auth_by_provider:
distinct_count_user_auth_by_provider
(
time_period
),
unique_users_all_imports:
unique_users_all_imports
(
time_period
),
bulk_imports:
{
bulk_imports:
{
gitlab:
distinct_count
(
::
BulkImport
.
where
(
time_period
,
source_type: :gitlab
),
:user_id
)
gitlab:
distinct_count
(
::
BulkImport
.
where
(
time_period
,
source_type: :gitlab
),
:user_id
)
},
},
...
@@ -903,6 +904,18 @@ module Gitlab
...
@@ -903,6 +904,18 @@ module Gitlab
distinct_count
(
::
Project
.
imported_from
(
from
).
where
(
time_period
).
where
.
not
(
import_type:
nil
),
:creator_id
)
# rubocop: disable CodeReuse/ActiveRecord
distinct_count
(
::
Project
.
imported_from
(
from
).
where
(
time_period
).
where
.
not
(
import_type:
nil
),
:creator_id
)
# rubocop: disable CodeReuse/ActiveRecord
end
end
# rubocop:disable CodeReuse/ActiveRecord
def
unique_users_all_imports
(
time_period
)
project_imports
=
distinct_count
(
::
Project
.
where
(
time_period
).
where
.
not
(
import_type:
nil
),
:creator_id
)
bulk_imports
=
distinct_count
(
::
BulkImport
.
where
(
time_period
),
:user_id
)
jira_issue_imports
=
distinct_count
(
::
JiraImportState
.
where
(
time_period
),
:user_id
)
csv_issue_imports
=
distinct_count
(
Issues
::
CsvImport
.
where
(
time_period
),
:user_id
)
group_imports
=
distinct_count
(
::
GroupImportState
.
where
(
time_period
),
:user_id
)
project_imports
+
bulk_imports
+
jira_issue_imports
+
csv_issue_imports
+
group_imports
end
# rubocop:enable CodeReuse/ActiveRecord
# rubocop:disable CodeReuse/ActiveRecord
# rubocop:disable CodeReuse/ActiveRecord
def
distinct_count_user_auth_by_provider
(
time_period
)
def
distinct_count_user_auth_by_provider
(
time_period
)
counts
=
auth_providers_except_ldap
.
each_with_object
({})
do
|
provider
,
hash
|
counts
=
auth_providers_except_ldap
.
each_with_object
({})
do
|
provider
,
hash
|
...
...
spec/frontend/__helpers__/graphql_helpers.js
0 → 100644
View file @
c35a9bab
/**
* Returns a clone of the given object with all __typename keys omitted,
* including deeply nested ones.
*
* Only works with JSON-serializable objects.
*
* @param {object} An object with __typename keys (e.g., a GraphQL response)
* @returns {object} A new object with no __typename keys
*/
export
const
stripTypenames
=
(
object
)
=>
{
return
JSON
.
parse
(
JSON
.
stringify
(
object
,
(
key
,
value
)
=>
(
key
===
'
__typename
'
?
undefined
:
value
)),
);
};
spec/frontend/__helpers__/graphql_helpers_spec.js
0 → 100644
View file @
c35a9bab
import
{
stripTypenames
}
from
'
./graphql_helpers
'
;
describe
(
'
stripTypenames
'
,
()
=>
{
it
.
each
`
input | expected
${{}}
|
$
{{}}
$
{{
__typename
:
'
Foo
'
}
} |
${{}}
$
{{
bar
:
'
bar
'
,
__typename
:
'
Foo
'
}
} |
${{
bar
:
'
bar
'
}
}
${{
bar
:
{
__typename
:
'
Bar
'
}
, __typename: 'Foo' }} |
${{
bar
:
{}
}}
$
{{
bar
:
[{
__typename
:
'
Bar
'
}],
__typename
:
'
Foo
'
}
} |
${{
bar
:
[{}]
}
}
${[]}
|
${[]}
${[{
__typename
:
'
Foo
'
}]}
|
${[{}]}
${[{
bar
:
[{
a
:
1
,
__typename
:
'
Bar
'
}]
}]}
|
${[{
bar
:
[{
a
:
1
}]
}]}
`
(
'
given $input returns $expected, with all __typename keys removed
'
,
({
input
,
expected
})
=>
{
const
actual
=
stripTypenames
(
input
);
expect
(
actual
).
toEqual
(
expected
);
expect
(
input
).
not
.
toBe
(
actual
);
});
it
(
'
given null returns null
'
,
()
=>
{
expect
(
stripTypenames
(
null
)).
toEqual
(
null
);
});
});
spec/frontend/vue_shared/security_reports/security_reports_app_spec.js
View file @
c35a9bab
import
{
mount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
mount
}
from
'
@vue/test-utils
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
MockAdapter
from
'
axios-mock-adapter
'
;
import
{
merge
}
from
'
lodash
'
;
import
{
merge
}
from
'
lodash
'
;
import
Vue
from
'
vue
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
Vuex
from
'
vuex
'
;
import
Vuex
from
'
vuex
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
import
createMockApollo
from
'
helpers/mock_apollo_helper
'
;
...
@@ -26,8 +27,8 @@ import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/quer
...
@@ -26,8 +27,8 @@ import securityReportDownloadPathsQuery from '~/vue_shared/security_reports/quer
jest
.
mock
(
'
~/flash
'
);
jest
.
mock
(
'
~/flash
'
);
const
localVue
=
createLocalVue
(
);
Vue
.
use
(
VueApollo
);
local
Vue
.
use
(
Vuex
);
Vue
.
use
(
Vuex
);
const
SAST_COMPARISON_PATH
=
'
/sast.json
'
;
const
SAST_COMPARISON_PATH
=
'
/sast.json
'
;
const
SECRET_SCANNING_COMPARISON_PATH
=
'
/secret_detection.json
'
;
const
SECRET_SCANNING_COMPARISON_PATH
=
'
/secret_detection.json
'
;
...
@@ -47,7 +48,6 @@ describe('Security reports app', () => {
...
@@ -47,7 +48,6 @@ describe('Security reports app', () => {
SecurityReportsApp
,
SecurityReportsApp
,
merge
(
merge
(
{
{
localVue
,
propsData
:
{
...
props
},
propsData
:
{
...
props
},
stubs
:
{
stubs
:
{
HelpIcon
:
true
,
HelpIcon
:
true
,
...
@@ -64,8 +64,6 @@ describe('Security reports app', () => {
...
@@ -64,8 +64,6 @@ describe('Security reports app', () => {
Promise
.
resolve
({
data
:
securityReportDownloadPathsQueryNoArtifactsResponse
});
Promise
.
resolve
({
data
:
securityReportDownloadPathsQueryNoArtifactsResponse
});
const
failureHandler
=
()
=>
Promise
.
resolve
({
errors
:
[{
message
:
'
some error
'
}]
});
const
failureHandler
=
()
=>
Promise
.
resolve
({
errors
:
[{
message
:
'
some error
'
}]
});
const
createMockApolloProvider
=
(
handler
)
=>
{
const
createMockApolloProvider
=
(
handler
)
=>
{
localVue
.
use
(
VueApollo
);
const
requestHandlers
=
[[
securityReportDownloadPathsQuery
,
handler
]];
const
requestHandlers
=
[[
securityReportDownloadPathsQuery
,
handler
]];
return
createMockApollo
(
requestHandlers
);
return
createMockApollo
(
requestHandlers
);
...
...
spec/lib/gitlab/usage_data_spec.rb
View file @
c35a9bab
...
@@ -228,6 +228,29 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
...
@@ -228,6 +228,29 @@ RSpec.describe Gitlab::UsageData, :aggregate_failures do
)
)
end
end
it
'includes import gmau usage data'
do
for_defined_days_back
do
user
=
create
(
:user
)
group
=
create
(
:group
)
group
.
add_owner
(
user
)
create
(
:project
,
import_type: :github
,
creator_id:
user
.
id
)
create
(
:jira_import_state
,
:finished
,
project:
create
(
:project
,
creator_id:
user
.
id
))
create
(
:issue_csv_import
,
user:
user
)
create
(
:group_import_state
,
group:
group
,
user:
user
)
create
(
:bulk_import
,
user:
user
)
end
expect
(
described_class
.
usage_activity_by_stage_manage
({})).
to
include
(
unique_users_all_imports:
10
)
expect
(
described_class
.
usage_activity_by_stage_manage
(
described_class
.
last_28_days_time_period
)).
to
include
(
unique_users_all_imports:
5
)
end
it
'includes imports usage data'
do
it
'includes imports usage data'
do
for_defined_days_back
do
for_defined_days_back
do
user
=
create
(
:user
)
user
=
create
(
:user
)
...
...
spec/requests/groups/email_campaigns_controller_spec.rb
0 → 100644
View file @
c35a9bab
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Groups
::
EmailCampaignsController
do
include
InProductMarketingHelper
using
RSpec
::
Parameterized
::
TableSyntax
describe
'GET #index'
,
:snowplow
do
let_it_be
(
:group
)
{
create
(
:group
)
}
let_it_be
(
:project
)
{
create
(
:project
,
group:
group
)
}
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:track
)
{
'create'
}
let
(
:series
)
{
'0'
}
before
do
sign_in
(
user
)
group
.
add_developer
(
user
)
allow
(
Gitlab
::
Tracking
).
to
receive
(
:self_describing_event
)
end
subject
(
:get_index
)
do
get
group_email_campaigns_url
(
group
,
track:
track
,
series:
series
)
response
end
RSpec
::
Matchers
.
define
:track_event
do
|*
args
|
match
do
expect
(
Gitlab
::
Tracking
).
to
have_received
(
:self_describing_event
).
with
(
described_class
::
EMAIL_CAMPAIGNS_SCHEMA_URL
,
data:
{
namespace_id:
group
.
id
,
track:
track
.
to_sym
,
series:
series
.
to_i
,
subject_line:
subject_line
(
track
.
to_sym
,
series
.
to_i
)
}
)
end
match_when_negated
do
expect
(
Gitlab
::
Tracking
).
not_to
have_received
(
:self_describing_event
)
end
end
context
'track parameter'
do
where
(
:track
,
:valid
)
do
'create'
|
true
'verify'
|
true
'trial'
|
true
'team'
|
true
'xxxx'
|
false
nil
|
false
end
with_them
do
it
do
if
valid
is_expected
.
to
track_event
is_expected
.
to
have_gitlab_http_status
(
:redirect
)
else
is_expected
.
not_to
track_event
is_expected
.
to
have_gitlab_http_status
(
:not_found
)
end
end
end
end
context
'series parameter'
do
where
(
:series
,
:valid
)
do
'0'
|
true
'1'
|
true
'2'
|
true
'-1'
|
false
'3'
|
false
nil
|
false
end
with_them
do
it
do
if
valid
is_expected
.
to
track_event
is_expected
.
to
have_gitlab_http_status
(
:redirect
)
else
is_expected
.
not_to
track_event
is_expected
.
to
have_gitlab_http_status
(
:not_found
)
end
end
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