mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #10793 from overleaf/mj-split-test-cleanup
Split test clean-up GitOrigin-RevId: 7dd6178487022cbefcbc85797dacc3f3fbfa17e2
This commit is contained in:
parent
f6c1e2738d
commit
38cc3394e3
27 changed files with 53 additions and 622 deletions
|
@ -552,24 +552,6 @@ const ProjectController = {
|
|||
}
|
||||
)
|
||||
},
|
||||
primaryEmailCheckActive(cb) {
|
||||
SplitTestHandler.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'primary-email-check',
|
||||
(err, assignment) => {
|
||||
if (err) {
|
||||
logger.warn(
|
||||
{ err },
|
||||
'failed to get "primary-email-check" split test assignment'
|
||||
)
|
||||
cb(null, false)
|
||||
} else {
|
||||
cb(null, assignment.variant === 'active')
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
survey(cb) {
|
||||
SurveyHandler.getSurvey(userId, (err, survey) => {
|
||||
if (err) {
|
||||
|
@ -591,14 +573,12 @@ const ProjectController = {
|
|||
notifications,
|
||||
user,
|
||||
userEmailsData,
|
||||
primaryEmailCheckActive,
|
||||
groupsAndEnterpriseBannerAssignment,
|
||||
userIsMemberOfGroupSubscription,
|
||||
} = results
|
||||
|
||||
if (
|
||||
user &&
|
||||
primaryEmailCheckActive &&
|
||||
UserPrimaryEmailCheckHandler.requiresPrimaryEmailCheck(user)
|
||||
) {
|
||||
return res.redirect('/user/emails/primary-email-check')
|
||||
|
@ -997,37 +977,6 @@ const ProjectController = {
|
|||
}
|
||||
)
|
||||
},
|
||||
dictionaryEditorAssignment(cb) {
|
||||
SplitTestHandler.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'dictionary-editor',
|
||||
{},
|
||||
(error, assignment) => {
|
||||
// do not fail editor load if assignment fails
|
||||
if (error) {
|
||||
cb(null, { variant: 'default' })
|
||||
} else {
|
||||
cb(null, assignment)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
interstitialPaymentFromPaywallAssignment(cb) {
|
||||
SplitTestHandler.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'interstitial-payment-from-paywall',
|
||||
(error, assignment) => {
|
||||
// do not fail editor load if assignment fails
|
||||
if (error) {
|
||||
cb(null, { variant: 'default' })
|
||||
} else {
|
||||
cb(null, assignment)
|
||||
}
|
||||
}
|
||||
)
|
||||
},
|
||||
latexLogParserAssignment(cb) {
|
||||
SplitTestHandler.getAssignment(
|
||||
req,
|
||||
|
@ -1043,25 +992,6 @@ const ProjectController = {
|
|||
}
|
||||
)
|
||||
},
|
||||
compileTimeWarningAssignment: [
|
||||
'user',
|
||||
(results, cb) => {
|
||||
if (results.user?.features?.compileTimeout <= 60) {
|
||||
SplitTestHandler.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'compile-time-warning',
|
||||
{},
|
||||
() => {
|
||||
// do not fail editor load if assignment fails
|
||||
cb()
|
||||
}
|
||||
)
|
||||
} else {
|
||||
cb()
|
||||
}
|
||||
},
|
||||
],
|
||||
linkSharingUpgradePromptAssignment(cb) {
|
||||
SplitTestHandler.getAssignment(
|
||||
req,
|
||||
|
@ -1152,7 +1082,6 @@ const ProjectController = {
|
|||
brandVariation,
|
||||
newSourceEditorAssignment,
|
||||
pdfjsAssignment,
|
||||
dictionaryEditorAssignment,
|
||||
editorLeftMenuAssignment,
|
||||
}
|
||||
) => {
|
||||
|
@ -1251,10 +1180,6 @@ const ProjectController = {
|
|||
: ['all']
|
||||
const galileoPromptWords = req.query?.galileoPromptWords || ''
|
||||
|
||||
const dictionaryEditorEnabled =
|
||||
!Features.hasFeature('saas') ||
|
||||
dictionaryEditorAssignment?.variant === 'enabled'
|
||||
|
||||
// Persistent upgrade prompts
|
||||
// in header & in share project modal
|
||||
const showUpgradePrompt =
|
||||
|
@ -1329,7 +1254,6 @@ const ProjectController = {
|
|||
wsUrl,
|
||||
showSupport: Features.hasFeature('support'),
|
||||
pdfjsVariant: pdfjsAssignment.variant,
|
||||
dictionaryEditorEnabled,
|
||||
debugPdfDetach,
|
||||
showNewSourceEditorOption,
|
||||
showSymbolPalette,
|
||||
|
|
|
@ -124,26 +124,8 @@ async function projectListReactPage(req, res, next) {
|
|||
logger.err({ err: error, userId }, 'Failed to load the active survey')
|
||||
}
|
||||
|
||||
try {
|
||||
const assignment = await SplitTestHandler.promises.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'primary-email-check'
|
||||
)
|
||||
const primaryEmailCheckActive = assignment.variant === 'active'
|
||||
|
||||
if (
|
||||
user &&
|
||||
primaryEmailCheckActive &&
|
||||
UserPrimaryEmailCheckHandler.requiresPrimaryEmailCheck(user)
|
||||
) {
|
||||
return res.redirect('/user/emails/primary-email-check')
|
||||
}
|
||||
} catch (error) {
|
||||
logger.warn(
|
||||
{ err: error },
|
||||
'failed to get "primary-email-check" split test assignment'
|
||||
)
|
||||
if (user && UserPrimaryEmailCheckHandler.requiresPrimaryEmailCheck(user)) {
|
||||
return res.redirect('/user/emails/primary-email-check')
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -43,22 +43,7 @@ module.exports = HomeController = {
|
|||
|
||||
async home(req, res) {
|
||||
if (Features.hasFeature('homepage') && homepageExists) {
|
||||
try {
|
||||
const homeRegistration = await SplitTestHandler.promises.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'home-registration'
|
||||
)
|
||||
const removeRegistration = homeRegistration.variant
|
||||
return res.render('external/home/v2', {
|
||||
removeRegistration,
|
||||
})
|
||||
} catch (err) {
|
||||
logger.error({ err }, err.message)
|
||||
return res.render('external/home/v2', {
|
||||
removeRegistration: 'default',
|
||||
})
|
||||
}
|
||||
return res.render('external/home/v2')
|
||||
} else {
|
||||
return res.redirect('/login')
|
||||
}
|
||||
|
|
|
@ -80,17 +80,6 @@ async function plansPage(req, res) {
|
|||
|
||||
AnalyticsManager.recordEventForSession(req.session, 'plans-page-view')
|
||||
|
||||
const standardPlanNameAssignment =
|
||||
await SplitTestHandler.promises.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'standard-plan-name'
|
||||
)
|
||||
|
||||
const useNewPlanName =
|
||||
standardPlanNameAssignment &&
|
||||
standardPlanNameAssignment.variant === 'new-plan-name'
|
||||
|
||||
const template = newPlansPageVariantV2
|
||||
? 'subscriptions/plans-marketing-v2'
|
||||
: 'subscriptions/plans-marketing'
|
||||
|
@ -108,7 +97,6 @@ async function plansPage(req, res) {
|
|||
groupPlanModalOptions,
|
||||
groupPlanModalDefaults,
|
||||
newPlansPageVariantV2,
|
||||
useNewPlanName,
|
||||
initialLocalizedGroupPrice:
|
||||
SubscriptionHelper.generateInitialLocalizedGroupPrice(
|
||||
recommendedCurrency
|
||||
|
@ -151,13 +139,6 @@ async function paymentPage(req, res) {
|
|||
if (recommendedCurrency && currency == null) {
|
||||
currency = recommendedCurrency
|
||||
}
|
||||
const assignment = await SplitTestHandler.promises.getAssignment(
|
||||
req,
|
||||
res,
|
||||
'payment-page'
|
||||
)
|
||||
const useUpdatedPaymentPage =
|
||||
assignment && assignment.variant === 'updated-payment-page'
|
||||
|
||||
const refreshedPaymentPageAssignment =
|
||||
await SplitTestHandler.promises.getAssignment(
|
||||
|
@ -177,9 +158,7 @@ async function paymentPage(req, res) {
|
|||
|
||||
const template = useRefreshedPaymentPage
|
||||
? 'subscriptions/new-refreshed'
|
||||
: useUpdatedPaymentPage
|
||||
? 'subscriptions/new-updated'
|
||||
: 'subscriptions/new'
|
||||
: 'subscriptions/new-updated'
|
||||
|
||||
res.render(template, {
|
||||
title: 'subscribe',
|
||||
|
|
|
@ -7,7 +7,6 @@ const UserDeleter = require('./UserDeleter')
|
|||
const UserGetter = require('./UserGetter')
|
||||
const UserUpdater = require('./UserUpdater')
|
||||
const Analytics = require('../Analytics/AnalyticsManager')
|
||||
const SplitTestHandler = require('../SplitTests/SplitTestHandler')
|
||||
const UserOnboardingEmailManager = require('./UserOnboardingEmailManager')
|
||||
const UserPostRegistrationAnalyticsManager = require('./UserPostRegistrationAnalyticsManager')
|
||||
const OError = require('@overleaf/o-error')
|
||||
|
@ -38,13 +37,8 @@ async function _addAffiliation(user, affiliationOptions) {
|
|||
|
||||
async function recordRegistrationEvent(user) {
|
||||
try {
|
||||
const homeRegistrationAssignment =
|
||||
await SplitTestHandler.promises.getAssignmentForUser(
|
||||
user._id,
|
||||
'home-registration'
|
||||
)
|
||||
const segmentation = {
|
||||
'home-registration': homeRegistrationAssignment.variant,
|
||||
'home-registration': 'default',
|
||||
}
|
||||
if (user.thirdPartyIdentifiers && user.thirdPartyIdentifiers.length > 0) {
|
||||
segmentation.provider = user.thirdPartyIdentifiers[0].providerId
|
||||
|
|
|
@ -6,8 +6,12 @@ function requiresPrimaryEmailCheck({
|
|||
lastPrimaryEmailCheck,
|
||||
signUpDate,
|
||||
}) {
|
||||
const hasExpired = date =>
|
||||
Date.now() - date.getTime() > Settings.primary_email_check_expiration
|
||||
const hasExpired = date => {
|
||||
if (!date) {
|
||||
return true
|
||||
}
|
||||
return Date.now() - date.getTime() > Settings.primary_email_check_expiration
|
||||
}
|
||||
|
||||
const primaryEmailConfirmedAt = emails.find(
|
||||
emailEntry => emailEntry.email === email
|
||||
|
|
|
@ -117,15 +117,14 @@ aside#left-menu.full-size(
|
|||
value=language.code
|
||||
)= language.name
|
||||
|
||||
if dictionaryEditorEnabled
|
||||
.form-controls(ng-controller="DictionaryModalController")
|
||||
label #{translate("dictionary")}
|
||||
button.btn.btn-secondary.btn-xs(ng-click="openModal()") #{translate("edit")}
|
||||
.form-controls(ng-controller="DictionaryModalController")
|
||||
label #{translate("dictionary")}
|
||||
button.btn.btn-secondary.btn-xs(ng-click="openModal()") #{translate("edit")}
|
||||
|
||||
dictionary-modal(
|
||||
handle-hide="handleHide"
|
||||
show="show"
|
||||
)
|
||||
dictionary-modal(
|
||||
handle-hide="handleHide"
|
||||
show="show"
|
||||
)
|
||||
|
||||
.form-controls
|
||||
label(for="autoComplete") #{translate("auto_complete")}
|
||||
|
|
|
@ -28,7 +28,6 @@ meta(name="ol-galileoFeatures" data-type="json" content=galileoFeatures)
|
|||
meta(name="ol-detachRole" data-type="string" content=detachRole)
|
||||
meta(name="ol-allowedImageNames" data-type="json" content=allowedImageNames)
|
||||
meta(name="ol-languages" data-type="json" content=languages)
|
||||
meta(name="ol-dictionaryEditorEnabled" data-type="boolean" content=dictionaryEditorEnabled)
|
||||
meta(name="ol-editorThemes" data-type="json" content=editorThemes)
|
||||
meta(name="ol-legacyEditorThemes" data-type="json" content=legacyEditorThemes)
|
||||
meta(name="ol-showUpgradePrompt" data-type="boolean" content=showUpgradePrompt)
|
||||
|
|
|
@ -206,10 +206,7 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
|
|||
.best-value
|
||||
strong #{translate('best_value')}
|
||||
.card-header
|
||||
if (useNewPlanName)
|
||||
h2 #{translate("standard")}
|
||||
else
|
||||
h2 #{translate("collaborator")}
|
||||
h2 #{translate("standard")}
|
||||
h5.tagline #{translate("tagline_collaborator")}
|
||||
.circle
|
||||
+price_collaborator
|
||||
|
|
|
@ -1,357 +0,0 @@
|
|||
extends ../layout
|
||||
|
||||
include ./_new_mixins
|
||||
|
||||
block append meta
|
||||
meta(name="ol-countryCode" content=countryCode)
|
||||
meta(name="ol-recurlyApiKey" content=settings.apis.recurly.publicKey)
|
||||
meta(name="ol-recommendedCurrency" content=String(currency).slice(0,3))
|
||||
|
||||
block head-scripts
|
||||
script(type="text/javascript", nonce=scriptNonce, src="https://js.recurly.com/v4/recurly.js")
|
||||
|
||||
block content
|
||||
main.content.content-alt#main-content
|
||||
.container(ng-controller="NewSubscriptionController" ng-cloak)
|
||||
.row.card-group
|
||||
.col-md-5.col-md-push-4
|
||||
.card.card-highlighted.card-border(ng-hide="threeDSecureFlow")
|
||||
.alert.alert-danger(ng-show="recurlyLoadError")
|
||||
strong #{translate('payment_provider_unreachable_error')}
|
||||
.page-header(ng-hide="recurlyLoadError")
|
||||
.row
|
||||
.col-xs-9
|
||||
h2 {{planName}}
|
||||
.col-xs-3
|
||||
div.dropdown.changePlanButton.pull-right(ng-cloak, dropdown)
|
||||
a.btn.btn-default.dropdown-toggle(
|
||||
href="#",
|
||||
data-toggle="dropdown",
|
||||
dropdown-toggle
|
||||
)
|
||||
| {{currencyCode}} ({{allCurrencies[currencyCode]['symbol']}})
|
||||
span.caret
|
||||
ul.dropdown-menu(role="menu")
|
||||
li(ng-repeat="(currency, value) in availableCurrencies")
|
||||
a(
|
||||
ng-click="changeCurrency(currency)",
|
||||
) {{currency}} ({{value['symbol']}})
|
||||
.row(ng-if="planCode == 'student-annual' || planCode == 'student-monthly' || planCode == 'student_free_trial_7_days'")
|
||||
.col-xs-12
|
||||
p.student-disclaimer #{translate('student_disclaimer')}
|
||||
|
||||
hr.thin
|
||||
.row
|
||||
.col-md-12.text-center
|
||||
div(ng-if="trialLength")
|
||||
span !{translate("first_few_days_free", {trialLen:'{{trialLength}}'})}
|
||||
span(ng-if="coupon.discountMonths && coupon.discountRate") - {{coupon.discountMonths}} #{translate("month")}s {{coupon.discountRate}}% Off
|
||||
|
||||
div(ng-if="recurlyPrice")
|
||||
- var priceVars = { price: "{{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.total }}"};
|
||||
span(ng-if="!coupon.singleUse && monthlyBilling")
|
||||
| !{translate("x_price_per_month", priceVars, ['strong'] )}
|
||||
span(ng-if="!coupon.singleUse && !monthlyBilling")
|
||||
| !{translate("x_price_per_year", priceVars, ['strong'] )}
|
||||
span(ng-if="coupon.singleUse && monthlyBilling")
|
||||
| !{translate("x_price_for_first_month", priceVars, ['strong'] )}
|
||||
span(ng-if="coupon.singleUse && !monthlyBilling")
|
||||
| !{translate("x_price_for_first_year", priceVars, ['strong'] )}
|
||||
|
||||
div(ng-if="coupon && coupon.normalPrice")
|
||||
- var noDiscountPriceAngularExp = "{{ availableCurrencies[currencyCode]['symbol']}}{{coupon.normalPrice | number:2 }}";
|
||||
span.small(ng-if="!coupon.singleUse && monthlyBilling")
|
||||
| !{translate("normally_x_price_per_month", { price: noDiscountPriceAngularExp } )}
|
||||
span.small(ng-if="!coupon.singleUse && !monthlyBilling")
|
||||
| !{translate("normally_x_price_per_year", { price: noDiscountPriceAngularExp } )}
|
||||
span.small(ng-if="coupon.singleUse && monthlyBilling")
|
||||
| !{translate("then_x_price_per_month", { price: noDiscountPriceAngularExp } )}
|
||||
span.small(ng-if="coupon.singleUse && !monthlyBilling")
|
||||
| !{translate("then_x_price_per_year", { price: noDiscountPriceAngularExp } )}
|
||||
|
||||
.row(ng-hide="recurlyLoadError")
|
||||
div()
|
||||
.col-md-12()
|
||||
form(
|
||||
name="simpleCCForm"
|
||||
novalidate
|
||||
)
|
||||
|
||||
div.payment-method-toggle
|
||||
a.payment-method-toggle-switch(
|
||||
href
|
||||
ng-click="setPaymentMethod('credit_card');"
|
||||
ng-class="paymentMethod.value === 'credit_card' ? 'payment-method-toggle-switch-selected' : ''"
|
||||
)
|
||||
i.fa.fa-cc-mastercard.fa-2x(aria-hidden="true")
|
||||
span
|
||||
i.fa.fa-cc-visa.fa-2x(aria-hidden="true")
|
||||
span
|
||||
i.fa.fa-cc-amex.fa-2x(aria-hidden="true")
|
||||
span.sr-only Pay with Mastercard, Visa, or Amex
|
||||
a.payment-method-toggle-switch(
|
||||
href
|
||||
ng-click="setPaymentMethod('paypal');"
|
||||
ng-class="paymentMethod.value === 'paypal' ? 'payment-method-toggle-switch-selected' : ''"
|
||||
)
|
||||
i.fa.fa-cc-paypal.fa-2x(aria-hidden="true")
|
||||
span.sr-only Pay with PayPal
|
||||
|
||||
.alert.alert-warning.small(ng-show="genericError")
|
||||
strong {{genericError}}
|
||||
|
||||
.alert.alert-warning.small(ng-show="couponError")
|
||||
strong {{couponError}}
|
||||
|
||||
div(ng-show="paymentMethod.value === 'credit_card'")
|
||||
.row
|
||||
.col-xs-6
|
||||
.form-group(ng-class="validation.errorFields.first_name || inputHasError(simpleCCForm.firstName) ? 'has-error' : ''")
|
||||
label(for="first-name") #{translate('first_name')}
|
||||
input#first-name.form-control(
|
||||
type="text"
|
||||
maxlength='255'
|
||||
data-recurly="first_name"
|
||||
name="firstName"
|
||||
ng-model="data.first_name"
|
||||
required
|
||||
)
|
||||
span.input-feedback-message(ng-if="simpleCCForm.firstName.$error.required") #{translate('this_field_is_required')}
|
||||
.col-xs-6
|
||||
.form-group(ng-class="validation.errorFields.last_name || inputHasError(simpleCCForm.lastName)? 'has-error' : ''")
|
||||
label(for="last-name") #{translate('last_name')}
|
||||
input#last-name.form-control(
|
||||
type="text"
|
||||
maxlength='255'
|
||||
data-recurly="last_name"
|
||||
name="lastName"
|
||||
ng-model="data.last_name"
|
||||
required
|
||||
)
|
||||
span.input-feedback-message(ng-if="simpleCCForm.lastName.$error.required") #{translate('this_field_is_required')}
|
||||
|
||||
.form-group(ng-class="validation.errorFields.number ? 'has-error' : ''")
|
||||
label(for="card-no") #{translate("credit_card_number")}
|
||||
div#card-no(
|
||||
type="text"
|
||||
name="ccNumber"
|
||||
data-recurly='number'
|
||||
)
|
||||
|
||||
.row
|
||||
.col-xs-3
|
||||
.form-group.has-feedback(ng-class="validation.errorFields.month ? 'has-error' : ''")
|
||||
label(for="month").capitalised #{translate("month")}
|
||||
div(
|
||||
type="number"
|
||||
name="month"
|
||||
data-recurly="month"
|
||||
)
|
||||
.col-xs-3
|
||||
.form-group.has-feedback(ng-class="validation.errorFields.year ? 'has-error' : ''")
|
||||
label(for="year").capitalised #{translate("year")}
|
||||
div(
|
||||
type="number"
|
||||
name="year"
|
||||
data-recurly="year"
|
||||
)
|
||||
|
||||
.col-xs-6
|
||||
.form-group.has-feedback(ng-class="validation.errorFields.cvv ? 'has-error' : ''")
|
||||
label #{translate("security_code")}
|
||||
div(
|
||||
type="number"
|
||||
ng-model="data.cvv"
|
||||
data-recurly="cvv"
|
||||
name="cvv"
|
||||
cc-format-sec-code
|
||||
)
|
||||
.form-control-feedback
|
||||
a.form-helper(
|
||||
href
|
||||
tabindex="-1"
|
||||
tooltip-template="'cvv-tooltip-tpl.html'"
|
||||
tooltip-trigger="mouseenter"
|
||||
tooltip-append-to-body="true"
|
||||
) ?
|
||||
|
||||
div
|
||||
.row
|
||||
.col-xs-12
|
||||
.form-group(ng-class="validation.errorFields.address1 || inputHasError(simpleCCForm.address1) ? 'has-error' : ''")
|
||||
label(for="address-line-1") #{translate('address_line_1')}
|
||||
input#address-line-1.form-control(
|
||||
type="text"
|
||||
maxlength="50"
|
||||
data-recurly="address1"
|
||||
name="address1"
|
||||
ng-model="data.address1"
|
||||
required
|
||||
)
|
||||
span.input-feedback-message(ng-if="simpleCCForm.address1.$error.required") #{translate('this_field_is_required')}
|
||||
|
||||
.row
|
||||
.col-xs-12
|
||||
.form-group.has-feedback(ng-class="validation.errorFields.address2 ? 'has-error' : ''")
|
||||
label(for="address-line-2") #{translate('address_line_2')}
|
||||
input#address-line-2.form-control(
|
||||
type="text"
|
||||
maxlength="50"
|
||||
data-recurly="address2"
|
||||
name="address2"
|
||||
ng-model="data.address2"
|
||||
)
|
||||
|
||||
.row
|
||||
.col-xs-4
|
||||
.form-group(ng-class="validation.errorFields.postal_code || inputHasError(simpleCCForm.postalCode) ? 'has-error' : ''")
|
||||
label(for="postal-code") #{translate('postal_code')}
|
||||
input#postal-code.form-control(
|
||||
type="text"
|
||||
maxlength="20"
|
||||
data-recurly="postal_code"
|
||||
name="postalCode"
|
||||
ng-model="data.postal_code"
|
||||
required
|
||||
)
|
||||
span.input-feedback-message(ng-if="simpleCCForm.postalCode.$error.required") #{translate('this_field_is_required')}
|
||||
|
||||
.col-xs-8
|
||||
.form-group(ng-class="validation.errorFields.country || inputHasError(simpleCCForm.country) ? 'has-error' : ''")
|
||||
label(for="country") #{translate('country')}
|
||||
select#country.form-control(
|
||||
data-recurly="country"
|
||||
ng-model="data.country"
|
||||
name="country"
|
||||
ng-change="updateCountry()"
|
||||
ng-selected="{{country.code == data.country}}"
|
||||
ng-model-options="{ debounce: 200 }"
|
||||
required
|
||||
)
|
||||
option(value='', disabled) #{translate("country")}
|
||||
option(value='-', disabled) --------------
|
||||
option(ng-repeat="country in countries" ng-bind-html="country.name" value="{{country.code}}")
|
||||
span.input-feedback-message(ng-if="simpleCCForm.country.$error.required") #{translate('this_field_is_required')}
|
||||
|
||||
.form-group
|
||||
.checkbox
|
||||
label
|
||||
input(
|
||||
type="checkbox"
|
||||
ng-model="ui.addCompanyDetails"
|
||||
)
|
||||
|
|
||||
| #{translate("add_company_details")}
|
||||
|
||||
.form-group(ng-show="ui.addCompanyDetails")
|
||||
label(for="company-name") #{translate("company_name")}
|
||||
input#company-name.form-control(
|
||||
type="text"
|
||||
name="companyName"
|
||||
ng-model="data.company"
|
||||
)
|
||||
|
||||
.form-group(ng-show="ui.addCompanyDetails && taxes.length")
|
||||
label(for="vat-number") #{translate("vat_number")}
|
||||
input#vat-number.form-control(
|
||||
type="text"
|
||||
name="vatNumber"
|
||||
ng-model="data.vat_number"
|
||||
ng-blur="applyVatNumber()"
|
||||
)
|
||||
|
||||
if (showCouponField)
|
||||
.form-group
|
||||
label(for="coupon-code") #{translate('coupon_code')}
|
||||
input#coupon-code.form-control(
|
||||
type="text"
|
||||
ng-blur="applyCoupon()"
|
||||
ng-model="data.coupon"
|
||||
)
|
||||
|
||||
p(ng-if="paymentMethod.value === 'paypal'") #{translate("paypal_upgrade")}
|
||||
|
||||
div.price-breakdown(
|
||||
ng-show="taxes.length"
|
||||
)
|
||||
- var priceBreakdownVars = { total: "{{ availableCurrencies[currencyCode]['symbol'] }}{{ recurlyPrice.total }}", subtotal: "{{availableCurrencies[currencyCode]['symbol']}}{{ recurlyPrice.subtotal }}", tax: "{{availableCurrencies[currencyCode]['symbol']}}{{ recurlyPrice.tax }}" };
|
||||
hr.thin
|
||||
span
|
||||
| Total:
|
||||
|
|
||||
span(ng-if="!coupon.singleUse && monthlyBilling")
|
||||
| !{translate("x_price_per_month_tax", priceBreakdownVars, ['strong'] )}
|
||||
span(ng-if="!coupon.singleUse && !monthlyBilling")
|
||||
| !{translate("x_price_per_year_tax", priceBreakdownVars, ['strong'] )}
|
||||
span(ng-if="coupon.singleUse && monthlyBilling")
|
||||
| !{translate("x_price_for_first_month_tax", priceBreakdownVars, ['strong'] )}
|
||||
span(ng-if="coupon.singleUse && !monthlyBilling")
|
||||
| !{translate("x_price_for_first_year_tax", priceBreakdownVars, ['strong'] )}
|
||||
hr.thin
|
||||
|
||||
div.payment-submit
|
||||
button.btn.btn-primary.btn-block(
|
||||
ng-click="submit()"
|
||||
ng-disabled="processing || !isFormValid(simpleCCForm);"
|
||||
)
|
||||
span(ng-show="processing")
|
||||
i.fa.fa-spinner.fa-spin(aria-hidden="true")
|
||||
span.sr-only #{translate('processing')}
|
||||
|
|
||||
span(ng-if="paymentMethod.value === 'credit_card'")
|
||||
| {{ trialLength ? '#{translate("upgrade_cc_btn")}' : '#{translate("upgrade_now")}'}}
|
||||
span(ng-if="paymentMethod.value !== 'credit_card'") #{translate("upgrade_paypal_btn")}
|
||||
|
||||
p.tos-agreement-notice !{translate("by_subscribing_you_agree_to_our_terms_of_service", {}, [{name: 'a', attrs: {href: '/legal#Terms', target:'_blank', rel:'noopener noreferrer'}}])}
|
||||
|
||||
div.three-d-secure-container.card.card-highlighted.card-border(ng-show="threeDSecureFlow")
|
||||
.alert.alert-info.small(aria-live="assertive")
|
||||
strong #{translate('card_must_be_authenticated_by_3dsecure')}
|
||||
div.three-d-secure-recurly-container
|
||||
|
||||
|
||||
|
||||
.col-md-3.col-md-pull-4
|
||||
.card.card-first
|
||||
.paymentPageFeatures
|
||||
h3 #{translate("unlimited_projects")}
|
||||
p #{translate("create_unlimited_projects")}
|
||||
|
||||
h3
|
||||
if plan.features.collaborators == -1
|
||||
- var collaboratorCount = 'Unlimited'
|
||||
else
|
||||
- var collaboratorCount = plan.features.collaborators
|
||||
if plan.features.collaborators == 1
|
||||
| #{translate("collabs_per_proj_single", {collabcount:collaboratorCount})}
|
||||
else
|
||||
| #{translate("collabs_per_proj", {collabcount:collaboratorCount})}
|
||||
p #{translate("work_on_single_version")}. #{translate("view_collab_edits_in_real_time")}
|
||||
|
||||
h3 #{translate("full_doc_history")}
|
||||
p.track-changes-example
|
||||
| #{translate("see_what_has_been")} #[span.added #{translate("added")}]
|
||||
| #{translate("and")} #[span.removed #{translate("removed")}].
|
||||
p
|
||||
| #{translate("restore_to_any_older_version")}.
|
||||
|
||||
h3 #{translate("sync_to_dropbox")}
|
||||
p
|
||||
| #{translate("acces_work_from_anywhere")}.
|
||||
| #{translate("work_offline_and_sync_with_dropbox")}.
|
||||
|
||||
hr
|
||||
|
||||
p.small.text-center(ng-non-bindable) !{translate("cancel_anytime", { appName:'{{settings.appName}}' })}
|
||||
|
||||
script(type="text/javascript", nonce=scriptNonce).
|
||||
ga('send', 'event', 'pageview', 'payment_form', "#{plan_code}")
|
||||
|
||||
script(
|
||||
type="text/ng-template"
|
||||
id="cvv-tooltip-tpl.html"
|
||||
)
|
||||
p !{translate("for_visa_mastercard_and_discover", {}, ['strong', 'strong', 'strong'])}
|
||||
p !{translate("for_american_express", {}, ['strong', 'strong', 'strong'])}
|
||||
|
||||
+studentCheckModal
|
|
@ -51,10 +51,7 @@ div.modal.fade(tabindex="-1" role="dialog" data-ol-group-plan-modal)
|
|||
value=plan_code.code
|
||||
data-ol-group-plan-code=plan_code.code
|
||||
)
|
||||
if (useNewPlanName && plan_code.code === 'collaborator')
|
||||
span Standard
|
||||
else
|
||||
span #{plan_code.display}
|
||||
span #{plan_code.display}
|
||||
.form-group
|
||||
label(for='size')
|
||||
| Number of users
|
||||
|
|
|
@ -245,10 +245,7 @@ mixin allCardsAndControls(controlsRowSpaced, listLocation)
|
|||
.best-value
|
||||
strong #{translate('best_value')}
|
||||
.card-header
|
||||
if (useNewPlanName)
|
||||
h2 #{translate("standard")}
|
||||
else
|
||||
h2 #{translate("collaborator")}
|
||||
h2 #{translate("standard")}
|
||||
.card-byline
|
||||
h5.tagline #{translate("tagline_collaborator")}
|
||||
.circle
|
||||
|
|
|
@ -5,11 +5,7 @@ mixin table_premium
|
|||
th
|
||||
th #{translate("free")}
|
||||
th #{translate("personal")}
|
||||
th
|
||||
if (useNewPlanName)
|
||||
| #{translate("standard")}
|
||||
else
|
||||
| #{translate("collaborator")}
|
||||
th #{translate("standard")}
|
||||
.outer.outer-top
|
||||
.outer-content
|
||||
.best-value
|
||||
|
|
|
@ -2,7 +2,6 @@ import { useCallback } from 'react'
|
|||
import { useTranslation } from 'react-i18next'
|
||||
import { Alert, Button, Modal } from 'react-bootstrap'
|
||||
import Icon from '../../../shared/components/icon'
|
||||
import SplitTestBadge from '../../../shared/components/split-test-badge'
|
||||
import Tooltip from '../../../shared/components/tooltip'
|
||||
import useAsync from '../../../shared/hooks/use-async'
|
||||
import { postJSON } from '../../../infrastructure/fetch-json'
|
||||
|
@ -38,17 +37,7 @@ export default function DictionaryModalContent({
|
|||
return (
|
||||
<>
|
||||
<Modal.Header closeButton>
|
||||
<Modal.Title>
|
||||
{t('edit_dictionary')}{' '}
|
||||
<SplitTestBadge
|
||||
splitTestName="dictionary-editor"
|
||||
displayOnVariants={['enabled']}
|
||||
tooltip={{
|
||||
placement: 'bottom',
|
||||
className: 'tooltip-wide',
|
||||
}}
|
||||
/>
|
||||
</Modal.Title>
|
||||
<Modal.Title>{t('edit_dictionary')}</Modal.Title>
|
||||
</Modal.Header>
|
||||
|
||||
<Modal.Body>
|
||||
|
|
|
@ -1,19 +1,11 @@
|
|||
import { useState } from 'react'
|
||||
import { Button } from 'react-bootstrap'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import getMeta from '../../../../utils/meta'
|
||||
import DictionaryModal from '../../../dictionary/components/dictionary-modal'
|
||||
|
||||
export default function SettingsDictionary() {
|
||||
const { t } = useTranslation()
|
||||
const [showModal, setShowModal] = useState(false)
|
||||
const dictionaryEditorEnabled = getMeta(
|
||||
'ol-dictionaryEditorEnabled'
|
||||
) as boolean
|
||||
|
||||
if (!dictionaryEditorEnabled) {
|
||||
return null
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="form-group left-menu-setting">
|
||||
|
|
|
@ -5,7 +5,6 @@ import { Button } from 'react-bootstrap'
|
|||
import PdfLogEntry from './pdf-log-entry'
|
||||
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
|
||||
import StopOnFirstErrorBadge from '../../../shared/components/stop-on-first-error-badge'
|
||||
|
||||
function PdfPreviewError({ error }) {
|
||||
const { t } = useTranslation()
|
||||
|
@ -254,7 +253,6 @@ function TimedOutLogEntry() {
|
|||
/>,
|
||||
]}
|
||||
/>{' '}
|
||||
<StopOnFirstErrorBadge placement="bottom" />
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
|
|
|
@ -4,7 +4,6 @@ import { Button } from 'react-bootstrap'
|
|||
import PdfLogEntry from './pdf-log-entry'
|
||||
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
|
||||
import StopOnFirstErrorBadge from '../../../shared/components/stop-on-first-error-badge'
|
||||
|
||||
export default function StopOnFirstErrorPrompt() {
|
||||
const { t } = useTranslation()
|
||||
|
@ -22,7 +21,6 @@ export default function StopOnFirstErrorPrompt() {
|
|||
return (
|
||||
<PdfLogEntry
|
||||
headerTitle={t('stop_on_first_error_enabled_title')}
|
||||
headerIcon={<StopOnFirstErrorBadge placement="right" />}
|
||||
formattedContent={
|
||||
<>
|
||||
<Trans
|
||||
|
|
|
@ -6,7 +6,6 @@ import PreviewLogEntryHeader from './preview-log-entry-header'
|
|||
import Icon from '../../../shared/components/icon'
|
||||
import { useDetachCompileContext as useCompileContext } from '../../../shared/context/detach-compile-context'
|
||||
import { useStopOnFirstError } from '../../../shared/hooks/use-stop-on-first-error'
|
||||
import StopOnFirstErrorBadge from '../../../shared/components/stop-on-first-error-badge'
|
||||
|
||||
function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
|
||||
const { t } = useTranslation()
|
||||
|
@ -54,7 +53,6 @@ function PreviewLogsPaneMaxEntries({ totalEntries, entriesShown, hasErrors }) {
|
|||
),
|
||||
}}
|
||||
/>{' '}
|
||||
<StopOnFirstErrorBadge placement="bottom" />
|
||||
</p>
|
||||
<p>{t('log_entry_maximum_entries_see_full_logs')}</p>
|
||||
</>
|
||||
|
|
|
@ -1,33 +0,0 @@
|
|||
import Tooltip from './tooltip'
|
||||
|
||||
type Props = {
|
||||
placement: string
|
||||
}
|
||||
|
||||
export default function StopOnFirstErrorBadge({ placement }: Props) {
|
||||
const content = (
|
||||
<>
|
||||
We are testing the “Stop on first error” compilation mode.
|
||||
<br />
|
||||
Click to give feedback
|
||||
</>
|
||||
)
|
||||
|
||||
return (
|
||||
<Tooltip
|
||||
id="stop-on-first-error-badge"
|
||||
description={content}
|
||||
overlayProps={{ placement, delayHide: 100 }}
|
||||
tooltipProps={{ className: 'tooltip-wide' }}
|
||||
>
|
||||
<a
|
||||
href="https://forms.gle/7M8821o5RDZrFKoF6"
|
||||
target="_blank"
|
||||
rel="noopener noreferrer"
|
||||
className="badge info-badge"
|
||||
>
|
||||
<span className="sr-only">{content}</span>
|
||||
</a>
|
||||
</Tooltip>
|
||||
)
|
||||
}
|
|
@ -27,8 +27,8 @@ import { useIdeContext } from './ide-context'
|
|||
import { useProjectContext } from './project-context'
|
||||
import { useEditorContext } from './editor-context'
|
||||
import { buildFileList } from '../../features/pdf-preview/util/file-list'
|
||||
import { useSplitTestContext } from './split-test-context'
|
||||
import { useLayoutContext } from './layout-context'
|
||||
import { useUserContext } from './user-context'
|
||||
|
||||
export const LocalCompileContext = createContext()
|
||||
|
||||
|
@ -86,10 +86,10 @@ export function LocalCompileProvider({ children }) {
|
|||
|
||||
const { _id: projectId, rootDocId } = useProjectContext()
|
||||
|
||||
const { splitTestVariants } = useSplitTestContext()
|
||||
|
||||
const { pdfPreviewOpen } = useLayoutContext()
|
||||
|
||||
const { features } = useUserContext()
|
||||
|
||||
// whether a compile is in progress
|
||||
const [compiling, setCompiling] = useState(false)
|
||||
|
||||
|
@ -279,8 +279,7 @@ export function LocalCompileProvider({ children }) {
|
|||
}, [compiledOnce, currentDoc, compiler])
|
||||
|
||||
useEffect(() => {
|
||||
const compileTimeWarningEnabled =
|
||||
splitTestVariants['compile-time-warning'] === 'show-upgrade-prompt'
|
||||
const compileTimeWarningEnabled = features?.compileTimeout <= 60
|
||||
|
||||
if (compileTimeWarningEnabled && compiling && isProjectOwner) {
|
||||
const timeout = window.setTimeout(() => {
|
||||
|
@ -291,7 +290,7 @@ export function LocalCompileProvider({ children }) {
|
|||
window.clearTimeout(timeout)
|
||||
}
|
||||
}
|
||||
}, [compiling, isProjectOwner, splitTestVariants])
|
||||
}, [compiling, isProjectOwner, features])
|
||||
|
||||
// handle the data returned from a compile request
|
||||
// note: this should _only_ run when `data` changes,
|
||||
|
|
|
@ -22,6 +22,7 @@ UserContext.Provider.propTypes = {
|
|||
mendeley: PropTypes.boolean,
|
||||
zotero: PropTypes.boolean,
|
||||
references: PropTypes.boolean,
|
||||
compileTimeout: PropTypes.number,
|
||||
}),
|
||||
refProviders: PropTypes.shape({
|
||||
mendeley: PropTypes.any,
|
||||
|
|
|
@ -1,36 +1,15 @@
|
|||
const UserHelper = require('./helpers/UserHelper')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const { expect } = require('chai')
|
||||
const SplitTestManager = require('../../../app/src/Features/SplitTests/SplitTestManager')
|
||||
const Features = require('../../../app/src/infrastructure/Features')
|
||||
|
||||
// While the split test is in progress this must be appended to URLs during tests
|
||||
const SPLIT_TEST_QUERY = '?primary-email-check=active'
|
||||
|
||||
describe('PrimaryEmailCheck', function () {
|
||||
let userHelper
|
||||
|
||||
// Create the primary-email-check split test because this is now required for the query string override to work. See
|
||||
// https://github.com/overleaf/internal/pull/7545#discussion_r848575736
|
||||
before(async function () {
|
||||
if (!Features.hasFeature('saas')) {
|
||||
this.skip()
|
||||
}
|
||||
|
||||
await SplitTestManager.createSplitTest({
|
||||
name: 'primary-email-check',
|
||||
configuration: {
|
||||
active: true,
|
||||
analyticsEnabled: true,
|
||||
phase: 'release',
|
||||
variants: [
|
||||
{
|
||||
name: 'active',
|
||||
rolloutPercent: 0,
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(async function () {
|
||||
|
@ -43,13 +22,13 @@ describe('PrimaryEmailCheck', function () {
|
|||
describe('redirections', function () {
|
||||
describe('when the user has signed up recently', function () {
|
||||
it("shouldn't be redirected from project list to the primary email check page", async function () {
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
const response = await userHelper.fetch('/project')
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should be redirected from the primary email check page to the project list', async function () {
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY
|
||||
'/user/emails/primary-email-check'
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
|
@ -67,13 +46,13 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it("shouldn't be redirected from project list to the primary email check page", async function () {
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
const response = await userHelper.fetch('/project')
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should be redirected from the primary email check page to the project list', async function () {
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY
|
||||
'/user/emails/primary-email-check'
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
|
@ -98,13 +77,13 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it("shouldn't be redirected from project list to the primary email check page", async function () {
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
const response = await userHelper.fetch('/project')
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
it('should be redirected from the primary email check page to the project list', async function () {
|
||||
const response = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY
|
||||
'/user/emails/primary-email-check'
|
||||
)
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
|
@ -122,7 +101,7 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it('should be redirected from project list to the primary email check page', async function () {
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
const response = await userHelper.fetch('/project')
|
||||
expect(response.status).to.equal(302)
|
||||
expect(response.headers.get('location')).to.equal(
|
||||
UserHelper.url('/user/emails/primary-email-check').toString()
|
||||
|
@ -149,7 +128,7 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
checkResponse = await userHelper.fetch(
|
||||
'/user/emails/primary-email-check' + SPLIT_TEST_QUERY,
|
||||
'/user/emails/primary-email-check',
|
||||
{ method: 'POST' }
|
||||
)
|
||||
})
|
||||
|
@ -162,7 +141,7 @@ describe('PrimaryEmailCheck', function () {
|
|||
})
|
||||
|
||||
it("shouldn't be redirected from project list to the primary email check page any longer", async function () {
|
||||
const response = await userHelper.fetch('/project' + SPLIT_TEST_QUERY)
|
||||
const response = await userHelper.fetch('/project')
|
||||
expect(response.status).to.equal(200)
|
||||
})
|
||||
|
||||
|
|
|
@ -73,6 +73,7 @@ describe('Sessions', function () {
|
|||
// set up second session for this user
|
||||
this.user2 = new User()
|
||||
this.user2.email = this.user1.email
|
||||
this.user2.emails = this.user1.emails
|
||||
this.user2.password = this.user1.password
|
||||
})
|
||||
|
||||
|
@ -197,9 +198,11 @@ describe('Sessions', function () {
|
|||
// set up second session for this user
|
||||
this.user2 = new User()
|
||||
this.user2.email = this.user1.email
|
||||
this.user2.emails = this.user1.emails
|
||||
this.user2.password = this.user1.password
|
||||
this.user3 = new User()
|
||||
this.user3.email = this.user1.email
|
||||
this.user3.emails = this.user1.emails
|
||||
this.user3.password = this.user1.password
|
||||
})
|
||||
|
||||
|
@ -321,9 +324,11 @@ describe('Sessions', function () {
|
|||
// set up second session for this user
|
||||
this.user2 = new User()
|
||||
this.user2.email = this.user1.email
|
||||
this.user2.emails = this.user1.emails
|
||||
this.user2.password = this.user1.password
|
||||
this.user3 = new User()
|
||||
this.user3.email = this.user1.email
|
||||
this.user3.emails = this.user1.emails
|
||||
this.user3.password = this.user1.password
|
||||
async.series([this.user2.login.bind(this.user2)], done)
|
||||
})
|
||||
|
|
|
@ -19,6 +19,7 @@ class User {
|
|||
{
|
||||
email: options.email || `acceptance-test-${count}@example.com`,
|
||||
createdAt: new Date(),
|
||||
confirmedAt: options.confirmedAt,
|
||||
},
|
||||
]
|
||||
this.email = this.emails[0].email
|
||||
|
|
|
@ -105,6 +105,9 @@ export function EditorProviders({
|
|||
metadataManager,
|
||||
}
|
||||
|
||||
// Add details for useUserContext
|
||||
window.metaAttributesCache.set('ol-user', { ...user, features })
|
||||
|
||||
return (
|
||||
<SplitTestProvider>
|
||||
<IdeProvider ide={window._ide}>
|
||||
|
|
|
@ -71,6 +71,9 @@ describe('ProjectController', function () {
|
|||
this.EditorController = { renameProject: sinon.stub() }
|
||||
this.InactiveProjectManager = { reactivateProjectIfRequired: sinon.stub() }
|
||||
this.ProjectUpdateHandler = { markAsOpened: sinon.stub() }
|
||||
this.UserPrimaryEmailCheckHandler = {
|
||||
requiresPrimaryEmailCheck: sinon.stub().returns(false),
|
||||
}
|
||||
this.ProjectGetter = {
|
||||
findAllUsersProjects: sinon.stub(),
|
||||
getProject: sinon.stub(),
|
||||
|
@ -193,6 +196,8 @@ describe('ProjectController', function () {
|
|||
},
|
||||
'../Institutions/InstitutionsFeatures': this.InstitutionsFeatures,
|
||||
'../Survey/SurveyHandler': this.SurveyHandler,
|
||||
'../User/UserPrimaryEmailCheckHandler':
|
||||
this.UserPrimaryEmailCheckHandler,
|
||||
'./ProjectAuditLogHandler': this.ProjectAuditLogHandler,
|
||||
},
|
||||
})
|
||||
|
|
|
@ -275,7 +275,7 @@ describe('SubscriptionController', function () {
|
|||
describe('with a valid plan code', function () {
|
||||
it('should render the new subscription page', function (done) {
|
||||
this.res.render = (page, opts) => {
|
||||
page.should.equal('subscriptions/new')
|
||||
page.should.equal('subscriptions/new-updated')
|
||||
done()
|
||||
}
|
||||
this.SubscriptionController.paymentPage(this.req, this.res)
|
||||
|
|
Loading…
Reference in a new issue