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
cf07b5d1
Commit
cf07b5d1
authored
Dec 16, 2021
by
Eugie Limpin
Committed by
Mayra Cabrera
Dec 16, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
EE-only: Open account validation modal
parent
bb074096
Changes
13
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
215 additions
and
7 deletions
+215
-7
app/views/projects/pipelines/show.html.haml
app/views/projects/pipelines/show.html.haml
+1
-2
ee/app/assets/javascripts/billings/components/cc_validation_required_alert.vue
...ipts/billings/components/cc_validation_required_alert.vue
+16
-0
ee/app/assets/javascripts/credit_card_validation_required_alert.js
...sets/javascripts/credit_card_validation_required_alert.js
+5
-1
ee/app/controllers/projects/pipelines/email_campaigns_controller.rb
...trollers/projects/pipelines/email_campaigns_controller.rb
+32
-0
ee/app/helpers/ee/ci/pipelines_helper.rb
ee/app/helpers/ee/ci/pipelines_helper.rb
+1
-0
ee/app/views/projects/pipelines/_cc_validation_required_alert.html.haml
...rojects/pipelines/_cc_validation_required_alert.html.haml
+3
-0
ee/config/routes/pipelines.rb
ee/config/routes/pipelines.rb
+2
-0
ee/lib/gitlab/email/message/account_validation.rb
ee/lib/gitlab/email/message/account_validation.rb
+1
-1
ee/spec/features/projects/pipelines/pipeline_spec.rb
ee/spec/features/projects/pipelines/pipeline_spec.rb
+25
-0
ee/spec/frontend/billings/components/cc_validation_required_alert_spec.js
.../billings/components/cc_validation_required_alert_spec.js
+39
-2
ee/spec/helpers/ee/ci/pipelines_helper_spec.rb
ee/spec/helpers/ee/ci/pipelines_helper_spec.rb
+10
-0
ee/spec/mailers/emails/in_product_marketing_spec.rb
ee/spec/mailers/emails/in_product_marketing_spec.rb
+1
-1
ee/spec/requests/projects/pipelines/email_campaigns_controller_spec.rb
...sts/projects/pipelines/email_campaigns_controller_spec.rb
+79
-0
No files found.
app/views/projects/pipelines/show.html.haml
View file @
cf07b5d1
...
...
@@ -10,8 +10,7 @@
.js-pipeline-container
{
data:
{
controller_action:
"#{controller.action_name}"
}
}
#js-pipeline-header-vue
.pipeline-header-container
{
data:
{
full_path:
@project
.
full_path
,
pipeline_iid:
@pipeline
.
iid
,
pipeline_id:
@pipeline
.
id
,
pipelines_path:
project_pipelines_path
(
@project
)
}
}
-
if
Gitlab
.
com?
&&
show_cc_validation_alert?
(
@pipeline
)
#js-cc-validation-required-alert
=
render_if_exists
'projects/pipelines/cc_validation_required_alert'
,
pipeline:
@pipeline
-
if
@pipeline
.
commit
.
present?
=
render
"projects/pipelines/info"
,
commit:
@pipeline
.
commit
...
...
ee/app/assets/javascripts/billings/components/cc_validation_required_alert.vue
View file @
cf07b5d1
<
script
>
import
{
GlAlert
,
GlSprintf
,
GlLink
}
from
'
@gitlab/ui
'
;
import
{
s__
}
from
'
~/locale
'
;
import
Tracking
from
'
~/tracking
'
;
import
AccountVerificationModal
from
'
./account_verification_modal.vue
'
;
const
i18n
=
{
...
...
@@ -28,12 +29,18 @@ export default {
GlLink
,
AccountVerificationModal
,
},
mixins
:
[
Tracking
.
mixin
()],
props
:
{
customMessage
:
{
type
:
String
,
default
:
null
,
required
:
false
,
},
isFromAccountValidationEmail
:
{
type
:
Boolean
,
default
:
false
,
required
:
false
,
},
},
data
()
{
return
{
...
...
@@ -48,11 +55,20 @@ export default {
return
gon
.
subscriptions_url
;
},
},
mounted
()
{
if
(
this
.
isFromAccountValidationEmail
)
{
this
.
showModal
();
}
},
methods
:
{
showModal
()
{
this
.
$refs
.
modal
.
show
();
},
handleSuccessfulVerification
()
{
if
(
this
.
isFromAccountValidationEmail
)
{
this
.
track
(
'
successful_validation
'
,
{
label
:
'
account_validation_email
'
});
}
this
.
$refs
.
modal
.
hide
();
this
.
shouldRenderSuccess
=
true
;
this
.
$emit
(
'
verifiedCreditCard
'
);
...
...
ee/app/assets/javascripts/credit_card_validation_required_alert.js
View file @
cf07b5d1
...
...
@@ -11,7 +11,11 @@ export default (containerId = 'js-cc-validation-required-alert') => {
return
new
Vue
({
el
,
render
(
createElement
)
{
return
createElement
(
CreditCardValidationRequiredAlert
);
return
createElement
(
CreditCardValidationRequiredAlert
,
{
props
:
{
isFromAccountValidationEmail
:
'
openValidateAccountModal
'
in
el
.
dataset
,
},
});
},
});
};
ee/app/controllers/projects/pipelines/email_campaigns_controller.rb
0 → 100644
View file @
cf07b5d1
# frozen_string_literal: true
module
Projects
module
Pipelines
class
EmailCampaignsController
<
Projects
::
Pipelines
::
ApplicationController
before_action
:check_if_gl_com_or_dev
feature_category
:navigation
def
validate_account
track_email_cta_click
session
[
:start_account_validation
]
=
true
redirect_to
project_pipeline_path
(
project
,
pipeline
)
end
private
def
track_email_cta_click
::
Gitlab
::
Tracking
.
event
(
self
.
class
.
name
,
'cta_clicked'
,
label:
'account_validation_email'
,
project:
project
,
user:
current_user
,
namespace:
project
.
root_namespace
)
end
end
end
end
ee/app/helpers/ee/ci/pipelines_helper.rb
View file @
cf07b5d1
...
...
@@ -4,6 +4,7 @@ module EE
module
Ci
module
PipelinesHelper
def
show_cc_validation_alert?
(
pipeline
)
return
false
unless
::
Gitlab
.
dev_env_or_com?
return
false
if
pipeline
.
user
.
blank?
||
current_user
!=
pipeline
.
user
pipeline
.
user_not_verified?
&&
!
pipeline
.
user
.
has_required_credit_card_to_run_pipelines?
(
pipeline
.
project
)
...
...
ee/app/views/projects/pipelines/_cc_validation_required_alert.html.haml
0 → 100644
View file @
cf07b5d1
-
return
unless
show_cc_validation_alert?
(
pipeline
)
-
open_validate_account_modal
=
session
.
delete
(
:start_account_validation
)
#js-cc-validation-required-alert
{
data:
{
open_validate_account_modal:
open_validate_account_modal
}
}
ee/config/routes/pipelines.rb
View file @
cf07b5d1
...
...
@@ -6,4 +6,6 @@ resources :pipelines, only: [] do
get
:licenses
get
:codequality_report
end
get
'validate_account'
,
action: :validate_account
,
controller:
'pipelines/email_campaigns'
end
ee/lib/gitlab/email/message/account_validation.rb
View file @
cf07b5d1
...
...
@@ -44,7 +44,7 @@ module Gitlab
end
def
cta_link
url
=
project_pipeline_url
(
pipeline
.
project
,
pipeline
)
url
=
project_pipeline_
validate_account_
url
(
pipeline
.
project
,
pipeline
)
case
format
when
:html
...
...
ee/spec/features/projects/pipelines/pipeline_spec.rb
View file @
cf07b5d1
...
...
@@ -316,6 +316,31 @@ RSpec.describe 'Pipeline', :js do
end
end
describe
'GET /:project/-/pipelines/:id/validate_account'
do
let
(
:pipeline
)
{
create
(
:ci_pipeline
,
:failed
,
project:
project
,
user:
user
,
failure_reason:
'user_not_verified'
)
}
let
(
:ultimate_plan
)
{
create
(
:ultimate_plan
)
}
before
do
allow
(
Gitlab
).
to
receive
(
:com?
)
{
true
}
create
(
:gitlab_subscription
,
:active_trial
,
namespace:
namespace
,
hosted_plan:
ultimate_plan
)
end
it
'redirects to pipeline page with account validation modal opened'
do
visit
project_pipeline_validate_account_path
(
project
,
pipeline
)
expect
(
page
).
to
have_current_path
(
pipeline_path
(
pipeline
))
account_validation_alert_content
=
'User validation required'
expect
(
page
).
to
have_content
(
account_validation_alert_content
)
expect
(
page
).
to
have_selector
(
"#credit-card-verification-modal"
)
# ensure account validation modal is only opened when redirected from /validate_account
visit
current_path
expect
(
page
).
not_to
have_selector
(
"#credit-card-verification-modal"
)
end
end
private
def
create_link
(
source_pipeline
,
pipeline
)
...
...
ee/spec/frontend/billings/components/cc_validation_required_alert_spec.js
View file @
cf07b5d1
import
{
GlAlert
,
GlSprintf
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
}
from
'
@vue/test-utils
'
;
import
{
mockTracking
,
unmockTracking
}
from
'
helpers/tracking_helper
'
;
import
AccountVerificationModal
from
'
ee/billings/components/account_verification_modal.vue
'
;
import
CreditCardValidationRequiredAlert
from
'
ee/billings/components/cc_validation_required_alert.vue
'
;
import
{
TEST_HOST
}
from
'
helpers/test_constants
'
;
import
{
stubComponent
}
from
'
helpers/stub_component
'
;
describe
(
'
CreditCardValidationRequiredAlert
'
,
()
=>
{
let
showSpy
;
let
trackingSpy
;
let
wrapper
;
const
createComponent
=
(
data
=
{})
=>
{
const
createComponent
=
({
data
=
{},
props
=
{}
}
=
{})
=>
{
showSpy
=
jest
.
fn
();
return
shallowMount
(
CreditCardValidationRequiredAlert
,
{
propsData
:
{
...
props
,
},
stubs
:
{
GlSprintf
,
AccountVerificationModal
:
stubComponent
(
AccountVerificationModal
,
{
methods
:
{
show
:
showSpy
,
hide
:
jest
.
fn
()
},
}),
},
data
()
{
return
data
;
...
...
@@ -21,6 +33,8 @@ describe('CreditCardValidationRequiredAlert', () => {
const
findGlAlert
=
()
=>
wrapper
.
findComponent
(
GlAlert
);
beforeEach
(()
=>
{
trackingSpy
=
mockTracking
(
undefined
,
undefined
,
jest
.
spyOn
);
window
.
gon
=
{
subscriptions_url
:
TEST_HOST
,
payment_form_url
:
TEST_HOST
,
...
...
@@ -31,6 +45,7 @@ describe('CreditCardValidationRequiredAlert', () => {
});
afterEach
(()
=>
{
unmockTracking
();
wrapper
.
destroy
();
});
...
...
@@ -47,7 +62,7 @@ describe('CreditCardValidationRequiredAlert', () => {
});
it
(
'
renders the success alert instead of danger
'
,
()
=>
{
wrapper
=
createComponent
({
shouldRenderSuccess
:
true
});
wrapper
=
createComponent
({
data
:
{
shouldRenderSuccess
:
true
}
});
expect
(
findGlAlert
().
attributes
(
'
variant
'
)).
toBe
(
'
success
'
);
});
...
...
@@ -64,4 +79,26 @@ describe('CreditCardValidationRequiredAlert', () => {
expect
(
wrapper
.
emitted
(
'
dismiss
'
)).
toBeDefined
();
});
it
(
'
does not open the modal on mount
'
,
()
=>
{
expect
(
showSpy
).
not
.
toHaveBeenCalled
();
});
describe
(
'
when isFromAccountValidationEmail prop is true
'
,
()
=>
{
beforeEach
(()
=>
{
wrapper
=
createComponent
({
props
:
{
isFromAccountValidationEmail
:
true
}
});
});
it
(
'
opens the modal on mount
'
,
()
=>
{
expect
(
showSpy
).
toHaveBeenCalled
();
});
it
(
'
sends successful verification event
'
,
()
=>
{
wrapper
.
findComponent
(
AccountVerificationModal
).
vm
.
$emit
(
'
success
'
);
expect
(
trackingSpy
).
toHaveBeenCalledWith
(
undefined
,
'
successful_validation
'
,
{
label
:
'
account_validation_email
'
,
});
});
});
});
ee/spec/helpers/ee/ci/pipelines_helper_spec.rb
View file @
cf07b5d1
...
...
@@ -40,5 +40,15 @@ RSpec.describe EE::Ci::PipelinesHelper do
it
{
is_expected
.
to
be_falsy
}
end
context
'when not in dev env or com'
do
let
(
:pipeline
)
{
instance_double
(
Ci
::
Pipeline
)
}
before
do
allow
(
Gitlab
).
to
receive
(
:dev_env_or_com?
)
{
false
}
end
it
{
is_expected
.
to
be_falsy
}
end
end
end
ee/spec/mailers/emails/in_product_marketing_spec.rb
View file @
cf07b5d1
...
...
@@ -22,7 +22,7 @@ RSpec.describe Emails::InProductMarketing do
it
'has the correct subject and content'
do
message
=
Gitlab
::
Email
::
Message
::
AccountValidation
.
new
(
pipeline
)
cta_url
=
project_pipeline_url
(
pipeline
.
project
,
pipeline
)
cta_url
=
project_pipeline_
validate_account_
url
(
pipeline
.
project
,
pipeline
)
cta2_url
=
'https://docs.gitlab.com/runner/install/'
aggregate_failures
do
...
...
ee/spec/requests/projects/pipelines/email_campaigns_controller_spec.rb
0 → 100644
View file @
cf07b5d1
# frozen_string_literal: true
require
'spec_helper'
RSpec
.
describe
Projects
::
Pipelines
::
EmailCampaignsController
do
let_it_be
(
:user
)
{
create
(
:user
)
}
let
(
:dev_env_or_com
)
{
true
}
subject
(
:request
)
do
get
project_pipeline_validate_account_path
(
project
,
pipeline
)
end
before
do
allow
(
Gitlab
).
to
receive
(
:dev_env_or_com?
)
{
dev_env_or_com
}
end
describe
'GET #validate_account'
,
:snowplow
do
context
'when user has access to the pipeline'
do
let_it_be
(
:group
)
{
create
(
:group
)
}
let_it_be
(
:project
)
{
create
(
:project
,
group:
group
)
}
let_it_be
(
:pipeline
)
{
create
(
:ci_pipeline
,
project:
project
,
user:
user
)
}
before
do
group
.
add_developer
(
user
)
sign_in
(
user
)
request
end
it
'emits a snowplow event'
do
expect_snowplow_event
(
category:
described_class
.
name
,
action:
'cta_clicked'
,
label:
'account_validation_email'
,
project:
project
,
user:
user
,
namespace:
group
)
end
it
'sets session[:start_account_validation] to true'
do
expect
(
session
[
:start_account_validation
]).
to
eq
(
true
)
end
it
'redirects to the pipeline show page'
do
expect
(
response
).
to
redirect_to
(
project_pipeline_path
(
project
,
pipeline
))
end
context
'when not in .com or dev env'
do
let
(
:dev_env_or_com
)
{
false
}
it
'returns 404'
do
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
end
end
context
'when user does not have access to the pipeline'
do
let_it_be
(
:project
)
{
create
(
:project
,
:private
)
}
let_it_be
(
:pipeline
)
{
create
(
:ci_pipeline
,
project:
project
)
}
before
do
sign_in
(
user
)
request
end
it
'returns :not_found'
do
expect
(
response
).
to
have_gitlab_http_status
(
:not_found
)
end
it
'does not set session[:start_account_validation]'
do
expect
(
session
[
:start_account_validation
]).
to
be_nil
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