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
091ea700
Commit
091ea700
authored
Aug 04, 2021
by
Angelo Gulina
Committed by
Vitaly Slobodin
Aug 04, 2021
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
[CI Minutes] Show the banner after successful purchase
parent
061963f3
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
106 additions
and
37 deletions
+106
-37
ee/app/assets/javascripts/subscriptions/buy_minutes/components/app.vue
.../javascripts/subscriptions/buy_minutes/components/app.vue
+1
-0
ee/app/assets/javascripts/subscriptions/buy_minutes/components/checkout/confirm_order.vue
...iptions/buy_minutes/components/checkout/confirm_order.vue
+5
-3
ee/app/assets/javascripts/subscriptions/buy_minutes/utils.js
ee/app/assets/javascripts/subscriptions/buy_minutes/utils.js
+2
-1
ee/app/assets/javascripts/subscriptions/graphql/queries/state.query.graphql
...scripts/subscriptions/graphql/queries/state.query.graphql
+1
-0
ee/spec/frontend/subscriptions/buy_minutes/components/checkout/confirm_order_spec.js
...ons/buy_minutes/components/checkout/confirm_order_spec.js
+95
-32
ee/spec/frontend/subscriptions/buy_minutes/mock_data.js
ee/spec/frontend/subscriptions/buy_minutes/mock_data.js
+1
-0
ee/spec/frontend/subscriptions/buy_minutes/utils_spec.js
ee/spec/frontend/subscriptions/buy_minutes/utils_spec.js
+1
-0
ee/spec/frontend/vue_shared/purchase_flow/spec_helper.js
ee/spec/frontend/vue_shared/purchase_flow/spec_helper.js
+0
-1
No files found.
ee/app/assets/javascripts/subscriptions/buy_minutes/components/app.vue
View file @
091ea700
...
...
@@ -10,6 +10,7 @@ import Checkout from './checkout.vue';
import
OrderSummary
from
'
./order_summary.vue
'
;
export
default
{
name
:
'
BuyCIMinutesApp
'
,
components
:
{
Checkout
,
GlEmptyState
,
...
...
ee/app/assets/javascripts/subscriptions/buy_minutes/components/checkout/confirm_order.vue
View file @
091ea700
...
...
@@ -30,13 +30,16 @@ export default {
},
confirmOrderParams
:
{
query
:
stateQuery
,
skip
()
{
return
!
this
.
isActive
;
},
update
(
data
)
{
const
{
customer
}
=
data
;
return
{
setup_for_company
:
data
.
isSetupForCompany
,
selected_group
:
data
.
subscription
.
namespaceId
,
new_user
:
data
.
isNewUser
,
redirect_after_success
:
data
.
redirectAfterSuccess
,
customer
:
{
country
:
customer
.
country
,
address_1
:
customer
.
address1
,
...
...
@@ -58,7 +61,6 @@ export default {
methods
:
{
confirmOrder
()
{
this
.
isLoading
=
true
;
return
Api
.
confirmOrder
(
this
.
confirmOrderParams
)
.
then
(({
data
})
=>
{
if
(
data
.
location
)
{
...
...
@@ -82,7 +84,7 @@ export default {
};
</
script
>
<
template
>
<div
v-if=
"isActive"
class=
"full-width gl-mb-7"
>
<div
v-if=
"isActive"
class=
"full-width gl-mb-7"
data-testid=
"confirm-order-root"
>
<gl-button
:disabled=
"isLoading"
variant=
"success"
category=
"primary"
@
click=
"confirmOrder"
>
<gl-loading-icon
v-if=
"isLoading"
inline
size=
"sm"
/>
{{
isLoading
?
$options
.
i18n
.
confirming
:
$options
.
i18n
.
confirm
}}
...
...
ee/app/assets/javascripts/subscriptions/buy_minutes/utils.js
View file @
091ea700
...
...
@@ -11,7 +11,7 @@ function arrayToGraphqlArray(arr, typename) {
}
export
function
writeInitialDataToApolloCache
(
apolloProvider
,
dataset
)
{
const
{
groupData
,
namespaceId
}
=
dataset
;
const
{
groupData
,
namespaceId
,
redirectAfterSuccess
}
=
dataset
;
// eslint-disable-next-line @gitlab/require-i18n-strings
const
namespaces
=
arrayToGraphqlArray
(
JSON
.
parse
(
groupData
),
'
Namespace
'
);
...
...
@@ -23,6 +23,7 @@ export function writeInitialDataToApolloCache(apolloProvider, dataset) {
isSetupForCompany
:
false
,
selectedPlanId
:
null
,
namespaces
,
redirectAfterSuccess
,
subscription
:
{
quantity
:
1
,
namespaceId
,
...
...
ee/app/assets/javascripts/subscriptions/graphql/queries/state.query.graphql
View file @
091ea700
...
...
@@ -8,6 +8,7 @@ query State {
fullName
@client
isSetupForCompany
@client
selectedPlanId
@client
redirectAfterSuccess
@client
customer
@client
{
country
address1
...
...
ee/spec/frontend/subscriptions/buy_minutes/components/checkout/confirm_order_spec.js
View file @
091ea700
import
{
GlButton
,
GlLoadingIcon
}
from
'
@gitlab/ui
'
;
import
{
shallowMount
,
createLocalVue
}
from
'
@vue/test-utils
'
;
import
{
createLocalVue
,
shallowMount
}
from
'
@vue/test-utils
'
;
import
VueApollo
from
'
vue-apollo
'
;
import
Api
from
'
ee/api
'
;
import
ConfirmOrder
from
'
ee/subscriptions/buy_minutes/components/checkout/confirm_order.vue
'
;
import
{
STEPS
}
from
'
ee/subscriptions/constants
'
;
import
ConfirmOrder
from
'
ee/subscriptions/new/components/checkout/confirm_order.vue
'
;
import
createStore
from
'
ee/subscriptions/new/store
'
;
import
stateQuery
from
'
ee/subscriptions/graphql/queries/state.query.graphql
'
;
import
{
GENERAL_ERROR_MESSAGE
}
from
'
ee/vue_shared/purchase_flow/constants
'
;
import
{
stateData
as
initialStateData
}
from
'
ee_jest/subscriptions/buy_minutes/mock_data
'
;
import
{
createMockApolloProvider
}
from
'
ee_jest/vue_shared/purchase_flow/spec_helper
'
;
import
{
extendedWrapper
}
from
'
helpers/vue_test_utils_helper
'
;
import
flash
from
'
~/flash
'
;
import
*
as
UrlUtility
from
'
~/lib/utils/url_utility
'
;
jest
.
mock
(
'
~/lib/utils/url_utility
'
);
jest
.
mock
(
'
~/flash
'
);
jest
.
mock
(
'
ee/api.js
'
);
describe
(
'
Confirm Order
'
,
()
=>
{
const
localVue
=
createLocalVue
();
localVue
.
use
(
VueApollo
);
const
flushPromises
=
()
=>
new
Promise
(
setImmediate
);
describe
(
'
Confirm Order
'
,
()
=>
{
let
mockApolloProvider
;
let
wrapper
;
jest
.
mock
(
'
ee/api.js
'
);
const
store
=
createStore
();
function
createComponent
(
options
=
{})
{
return
shallowMount
(
ConfirmOrder
,
{
localVue
,
store
,
...
options
,
});
}
const
findRootElement
=
()
=>
wrapper
.
findByTestId
(
'
confirm-order-root
'
);
const
findConfirmButton
=
()
=>
wrapper
.
find
(
GlButton
);
const
findLoadingIcon
=
()
=>
wrapper
.
find
(
GlLoadingIcon
);
const
localVue
=
createLocalVue
();
localVue
.
use
(
VueApollo
);
const
createComponent
=
(
options
=
{})
=>
{
wrapper
=
extendedWrapper
(
shallowMount
(
ConfirmOrder
,
{
localVue
,
...
options
,
}),
);
};
afterEach
(()
=>
{
wrapper
.
destroy
();
});
...
...
@@ -39,8 +44,8 @@ describe('Confirm Order', () => {
describe
(
'
Active
'
,
()
=>
{
describe
(
'
when receiving proper step data
'
,
()
=>
{
beforeEach
(()
=>
{
const
mockApolloProvider
=
createMockApolloProvider
(
STEPS
,
3
);
wrapper
=
createComponent
({
apolloProvider
:
mockApolloProvider
});
mockApolloProvider
=
createMockApolloProvider
(
STEPS
,
3
);
createComponent
({
apolloProvider
:
mockApolloProvider
});
});
it
(
'
button should be visible
'
,
()
=>
{
...
...
@@ -58,15 +63,38 @@ describe('Confirm Order', () => {
describe
(
'
Clicking the button
'
,
()
=>
{
beforeEach
(()
=>
{
const
mockApolloProvider
=
createMockApolloProvider
(
STEPS
,
3
);
wrapper
=
createComponent
({
apolloProvider
:
mockApolloProvider
});
mockApolloProvider
=
createMockApolloProvider
([]);
mockApolloProvider
.
clients
.
defaultClient
.
cache
.
writeQuery
({
query
:
stateQuery
,
data
:
{
...
initialStateData
,
stepList
:
STEPS
,
activeStep
:
STEPS
[
3
]
},
});
createComponent
({
apolloProvider
:
mockApolloProvider
});
Api
.
confirmOrder
=
jest
.
fn
().
mockReturnValue
(
new
Promise
(
jest
.
fn
()));
findConfirmButton
().
vm
.
$emit
(
'
click
'
);
});
it
(
'
calls the confirmOrder API method
'
,
()
=>
{
expect
(
Api
.
confirmOrder
).
toHaveBeenCalled
();
it
(
'
calls the confirmOrder API method with the correct params
'
,
()
=>
{
expect
(
Api
.
confirmOrder
).
toHaveBeenCalledTimes
(
1
);
expect
(
Api
.
confirmOrder
.
mock
.
calls
[
0
][
0
]).
toMatchObject
({
setup_for_company
:
true
,
selected_group
:
null
,
new_user
:
false
,
redirect_after_success
:
'
/path/to/redirect/
'
,
customer
:
{
country
:
null
,
address_1
:
null
,
address_2
:
null
,
city
:
null
,
state
:
null
,
zip_code
:
null
,
company
:
null
,
},
subscription
:
{
plan_id
:
null
,
payment_method_id
:
null
,
quantity
:
1
,
},
});
});
it
(
'
shows the text "Confirming..."
'
,
()
=>
{
...
...
@@ -78,11 +106,44 @@ describe('Confirm Order', () => {
});
});
describe
(
'
Order confirmation
'
,
()
=>
{
describe
(
'
when the confirmation succeeds
'
,
()
=>
{
const
location
=
'
group/location/path
'
;
beforeEach
(()
=>
{
mockApolloProvider
=
createMockApolloProvider
(
STEPS
,
3
);
createComponent
({
apolloProvider
:
mockApolloProvider
});
});
it
(
'
should redirect to the location
'
,
async
()
=>
{
Api
.
confirmOrder
=
jest
.
fn
().
mockResolvedValueOnce
({
data
:
{
location
}
});
findConfirmButton
().
vm
.
$emit
(
'
click
'
);
await
flushPromises
();
expect
(
UrlUtility
.
redirectTo
).
toHaveBeenCalledTimes
(
1
);
expect
(
UrlUtility
.
redirectTo
).
toHaveBeenCalledWith
(
location
);
});
it
(
'
shows an error
'
,
async
()
=>
{
const
errors
=
'
an error
'
;
Api
.
confirmOrder
=
jest
.
fn
().
mockResolvedValueOnce
({
data
:
{
errors
}
});
findConfirmButton
().
vm
.
$emit
(
'
click
'
);
await
flushPromises
();
expect
(
flash
.
mock
.
calls
[
0
][
0
]).
toMatchObject
({
message
:
GENERAL_ERROR_MESSAGE
,
captureError
:
true
,
error
:
new
Error
(
JSON
.
stringify
(
errors
)),
});
});
});
});
describe
(
'
when failing to receive step data
'
,
()
=>
{
beforeEach
(()
=>
{
const
mockApolloProvider
=
createMockApolloProvider
([]);
mockApolloProvider
=
createMockApolloProvider
([]);
createComponent
({
apolloProvider
:
mockApolloProvider
});
mockApolloProvider
.
clients
.
defaultClient
.
clearStore
();
wrapper
=
createComponent
({
apolloProvider
:
mockApolloProvider
});
});
afterEach
(()
=>
{
...
...
@@ -96,16 +157,18 @@ describe('Confirm Order', () => {
error
:
expect
.
any
(
Error
),
});
});
it
(
'
does not render the root element
'
,
()
=>
{
expect
(
findRootElement
().
exists
()).
toBe
(
false
);
});
});
});
describe
(
'
Inactive
'
,
()
=>
{
beforeEach
(()
=>
{
const
mockApolloProvider
=
createMockApolloProvider
(
STEPS
,
1
);
wrapper
=
createComponent
({
apolloProvider
:
mockApolloProvider
});
});
it
(
'
does not show buttons
'
,
()
=>
{
mockApolloProvider
=
createMockApolloProvider
(
STEPS
,
1
);
createComponent
({
apolloProvider
:
mockApolloProvider
});
it
(
'
button should not be visible
'
,
()
=>
{
expect
(
findConfirmButton
().
exists
()).
toBe
(
false
);
});
});
...
...
ee/spec/frontend/subscriptions/buy_minutes/mock_data.js
View file @
091ea700
...
...
@@ -28,6 +28,7 @@ export const stateData = {
namespaceId
:
null
,
__typename
:
'
Subscription
'
,
},
redirectAfterSuccess
:
'
/path/to/redirect/
'
,
selectedPlanId
:
null
,
paymentMethod
:
{
id
:
null
,
...
...
ee/spec/frontend/subscriptions/buy_minutes/utils_spec.js
View file @
091ea700
...
...
@@ -9,6 +9,7 @@ const DEFAULT_DATA = {
newUser
:
false
,
fullName
:
null
,
setupForCompany
:
false
,
redirectAfterSuccess
:
null
,
};
describe
(
'
utils
'
,
()
=>
{
...
...
ee/spec/frontend/vue_shared/purchase_flow/spec_helper.js
View file @
091ea700
...
...
@@ -14,6 +14,5 @@ export function createMockApolloProvider(stepList, initialStepIndex = 0, additio
query
:
activeStepQuery
,
data
:
{
activeStep
:
stepList
[
initialStepIndex
]
},
});
return
mockApollo
;
}
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