Merge pull request #17230 from overleaf/mf-tear-down-inr-2

[web] Tear down INR split test

GitOrigin-RevId: 90c6ab4666d9281e804b279d697d6c14ffd682d2
This commit is contained in:
M Fahru
2024-02-22 09:05:02 +00:00
committed by Copybot
parent 23281255a1
commit dc9b0aa8a5
18 changed files with 233 additions and 228 deletions
@@ -363,28 +363,14 @@ async function projectListPage(req, res, next) {
'writefull-integration'
)
let showInrGeoBanner, inrGeoBannerSplitTestName
let inrGeoBannerVariant = 'default'
let showInrGeoBanner = false
let recommendedCurrency
if (usersBestSubscription?.type === 'free') {
const { countryCode } = await GeoIpLookup.promises.getCurrencyCode(req.ip)
// Split test is kept active, but all users geolocated in India can
// now use the INR currency (See #13507)
const { variant: inrGeoPricingVariant } =
await SplitTestHandler.promises.getAssignment(req, res, 'geo-pricing-inr')
if (countryCode === 'IN') {
inrGeoBannerSplitTestName =
inrGeoPricingVariant === 'inr'
? 'geo-banners-inr-2'
: 'geo-banners-inr-1'
const geoBannerAssignment = await SplitTestHandler.promises.getAssignment(
req,
res,
inrGeoBannerSplitTestName
)
showInrGeoBanner = true
inrGeoBannerVariant = geoBannerAssignment.variant
}
}
@@ -437,8 +423,6 @@ async function projectListPage(req, res, next) {
showWritefullPromoBanner,
recommendedCurrency,
showInrGeoBanner,
inrGeoBannerVariant,
inrGeoBannerSplitTestName,
projectDashboardReact: true, // used in navbar
groupSsoSetupSuccess,
groupSubscriptionsPendingEnrollment:
@@ -38,8 +38,10 @@ async function plansPage(req, res) {
if (GeoIpLookup.isValidCurrencyParam(queryCurrency)) {
currency = queryCurrency
}
const { recommendedCurrency, countryCode, geoPricingINRTestVariant } =
await _getRecommendedCurrency(req, res)
const { recommendedCurrency, countryCode } = await _getRecommendedCurrency(
req,
res
)
if (recommendedCurrency && currency == null) {
currency = recommendedCurrency
}
@@ -65,24 +67,6 @@ async function plansPage(req, res) {
usage: getDefault('usage', 'usage', 'enterprise'),
}
let showInrGeoBanner, inrGeoBannerSplitTestName
let inrGeoBannerVariant = 'default'
if (countryCode === 'IN') {
inrGeoBannerSplitTestName =
geoPricingINRTestVariant === 'inr'
? 'geo-banners-inr-2'
: 'geo-banners-inr-1'
const geoBannerAssignment = await SplitTestHandler.promises.getAssignment(
req,
res,
inrGeoBannerSplitTestName
)
inrGeoBannerVariant = geoBannerAssignment.variant
if (inrGeoBannerVariant !== 'default') {
showInrGeoBanner = true
}
}
// annual plans with the free trial option split test - nudge variant
const annualTrialsAssignment = await SplitTestHandler.promises.getAssignment(
req,
@@ -93,13 +77,8 @@ async function plansPage(req, res) {
const plansPageViewSegmentation = {
currency: recommendedCurrency,
countryCode,
'geo-pricing-inr-group': geoPricingINRTestVariant,
'geo-pricing-inr-page': currency === 'INR' ? 'inr' : 'default',
'annual-trials': annualTrialsAssignment.variant,
}
if (inrGeoBannerSplitTestName) {
plansPageViewSegmentation[inrGeoBannerSplitTestName] = inrGeoBannerVariant
}
AnalyticsManager.recordEventForSession(
req.session,
@@ -122,7 +101,7 @@ async function plansPage(req, res) {
groupPlanModalDefaults,
initialLocalizedGroupPrice:
SubscriptionHelper.generateInitialLocalizedGroupPrice(currency),
showInrGeoBanner,
showInrGeoBanner: countryCode === 'IN',
annualTrialsAssignment: annualTrialsAssignment?.variant,
})
}
@@ -233,8 +212,10 @@ async function userSubscriptionPage(req, res) {
async function interstitialPaymentPage(req, res) {
const user = SessionManager.getSessionUser(req.session)
const { recommendedCurrency, countryCode, geoPricingINRTestVariant } =
await _getRecommendedCurrency(req, res)
const { recommendedCurrency, countryCode } = await _getRecommendedCurrency(
req,
res
)
const hasSubscription =
await LimitationsManager.promises.userHasV1OrV2Subscription(user)
@@ -244,24 +225,6 @@ async function interstitialPaymentPage(req, res) {
if (hasSubscription) {
res.redirect('/user/subscription?hasSubscription=true')
} else {
let showInrGeoBanner, inrGeoBannerSplitTestName
let inrGeoBannerVariant = 'default'
if (countryCode === 'IN') {
inrGeoBannerSplitTestName =
geoPricingINRTestVariant === 'inr'
? 'geo-banners-inr-2'
: 'geo-banners-inr-1'
const geoBannerAssignment = await SplitTestHandler.promises.getAssignment(
req,
res,
inrGeoBannerSplitTestName
)
inrGeoBannerVariant = geoBannerAssignment.variant
if (inrGeoBannerVariant !== 'default') {
showInrGeoBanner = true
}
}
// annual plans with the free trial option split test - nudge variant
const annualTrialsAssignment =
await SplitTestHandler.promises.getAssignment(req, res, 'annual-trials')
@@ -269,14 +232,8 @@ async function interstitialPaymentPage(req, res) {
const paywallPlansPageViewSegmentation = {
currency: recommendedCurrency,
countryCode,
'geo-pricing-inr-group': geoPricingINRTestVariant,
'geo-pricing-inr-page': recommendedCurrency === 'INR' ? 'inr' : 'default',
'annual-trials': annualTrialsAssignment.variant,
}
if (inrGeoBannerSplitTestName) {
paywallPlansPageViewSegmentation[inrGeoBannerSplitTestName] =
inrGeoBannerVariant
}
AnalyticsManager.recordEventForSession(
req.session,
'paywall-plans-page-view',
@@ -304,7 +261,7 @@ async function interstitialPaymentPage(req, res) {
recommendedCurrency,
interstitialPaymentConfig,
showSkipLink,
showInrGeoBanner,
showInrGeoBanner: countryCode === 'IN',
})
}
}
@@ -621,14 +578,6 @@ async function _getRecommendedCurrency(req, res) {
const currencyLookup = await GeoIpLookup.promises.getCurrencyCode(ip)
const countryCode = currencyLookup.countryCode
let recommendedCurrency = currencyLookup.currencyCode
// for #12703
// Split test is kept active, but all users geolocated in India can
// now use the INR currency (See #13507)
const assignmentINR = await SplitTestHandler.promises.getAssignment(
req,
res,
'geo-pricing-inr'
)
if (['BRL', 'MXN', 'COP', 'CLP', 'PEN'].includes(recommendedCurrency)) {
recommendedCurrency = GeoIpLookup.DEFAULT_CURRENCY_CODE
@@ -637,7 +586,6 @@ async function _getRecommendedCurrency(req, res) {
return {
recommendedCurrency,
countryCode,
geoPricingINRTestVariant: assignmentINR?.variant,
}
}
@@ -29,8 +29,6 @@ block append meta
meta(name="ol-showWritefullPromoBanner" data-type="boolean" content=showWritefullPromoBanner)
meta(name="ol-groupsAndEnterpriseBannerVariant" data-type="string" content=groupsAndEnterpriseBannerVariant)
meta(name="ol-showInrGeoBanner" data-type="boolean" content=showInrGeoBanner)
meta(name="ol-inrGeoBannerVariant" data-type="string" content=inrGeoBannerVariant)
meta(name="ol-inrGeoBannerSplitTestName" data-type="string" content=inrGeoBannerSplitTestName)
meta(name="ol-recommendedCurrency" data-type="string" content=recommendedCurrency)
meta(name="ol-groupSubscriptionsPendingEnrollment" data-type="json" content=groupSubscriptionsPendingEnrollment)
meta(name="ol-hasIndividualRecurlySubscription" data-type="boolean" content=hasIndividualRecurlySubscription)
@@ -18,7 +18,8 @@ block content
.plans
.container
if showInrGeoBanner
div.alert.alert-success.text-centered !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
div.notification.notification-type-success.text-centered
div.notification-content !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
.row
.col-md-12
@@ -18,7 +18,8 @@ block content
.plans
.container
if showInrGeoBanner
div.alert.alert-success.text-centered !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
div.notification.notification-type-success.text-centered
div.notification-content !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
.row
.col-md-12
@@ -18,7 +18,8 @@ block content
.plans
.container
if showInrGeoBanner
div.alert.alert-success.text-centered !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
div.notification.notification-type-success.text-centered
div.notification-content !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
.row
.col-md-12
@@ -16,7 +16,8 @@ block content
.plans
.container(ng-cloak)
if showInrGeoBanner
div.alert.alert-success.text-centered !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
div.notification.notification-type-success.text-centered
div.notification-content !{translate("inr_discount_offer_plans_page_banner", {flag: '🇮🇳'})}
.row
.col-md-12
@@ -578,8 +578,6 @@
"increased_compile_timeout": "",
"inr_discount_modal_info": "",
"inr_discount_modal_title": "",
"inr_discount_offer": "",
"inr_discount_offer_green_banner": "",
"insert": "",
"insert_column_left": "",
"insert_column_right": "",
@@ -1,35 +1,12 @@
import { useCallback, useEffect, useRef, useState } from 'react'
import { Trans, useTranslation } from 'react-i18next'
import { useTranslation } from 'react-i18next'
import usePersistedState from '../../../../../shared/hooks/use-persisted-state'
import Notification from '../notification'
import * as eventTracking from '../../../../../infrastructure/event-tracking'
import { Modal, Button } from 'react-bootstrap'
import AccessibleModal from '../../../../../shared/components/accessible-modal'
import getMeta from '@/utils/meta'
interface VariantContents {
default: string
'green-banner': string
modal: string
}
const contentLookup: VariantContents = {
default: 'blue',
'green-banner': 'green',
modal: 'modal',
}
type INRBannerProps = {
variant: keyof VariantContents
splitTestName: string
}
export default function INRBanner({ variant, splitTestName }: INRBannerProps) {
export default function INRBanner() {
const { t } = useTranslation()
const newNotificationStyle = getMeta(
'ol-newNotificationStyle',
false
) as boolean
const [dismissedUntil, setDismissedUntil] = usePersistedState<
Date | undefined
>(`has_dismissed_inr_banner_until`)
@@ -44,38 +21,41 @@ export default function INRBanner({ variant, splitTestName }: INRBannerProps) {
}
if (!viewEventSent.current) {
eventTracking.sendMB('promo-prompt', {
location: variant === 'modal' ? 'dashboard-modal' : 'dashboard-banner',
name: splitTestName,
content: contentLookup[variant],
location: 'dashboard-modal',
name: 'geo-pricing',
content: 'modal',
country: 'IN',
})
viewEventSent.current = true
}
}, [dismissedUntil, splitTestName, variant])
}, [dismissedUntil])
const handleClick = useCallback(() => {
eventTracking.sendMB('promo-click', {
location: variant === 'modal' ? 'dashboard-modal' : 'dashboard-banner',
name: splitTestName,
content: contentLookup[variant],
location: 'dashboard-modal',
name: 'geo-pricing',
content: 'modal',
type: 'click',
country: 'IN',
})
setShowModal(false)
window.open('/user/subscription/plans')
}, [splitTestName, variant])
}, [])
const bannerDismissed = useCallback(() => {
eventTracking.sendMB('promo-dismiss', {
location: variant === 'modal' ? 'dashboard-modal' : 'dashboard-banner',
name: splitTestName,
content: contentLookup[variant],
location: 'dashboard-modal',
name: 'geo-pricing',
content: 'modal',
type: 'click',
country: 'IN',
})
const until = new Date()
until.setDate(until.getDate() + 30) // 30 days
setDismissedUntil(until)
}, [setDismissedUntil, splitTestName, variant])
}, [setDismissedUntil])
const handleHide = useCallback(() => {
setShowModal(false)
@@ -84,99 +64,47 @@ export default function INRBanner({ variant, splitTestName }: INRBannerProps) {
const handleMaybeLater = useCallback(() => {
eventTracking.sendMB('promo-click', {
location: variant === 'modal' ? 'dashboard-modal' : 'dashboard-banner',
name: splitTestName,
content: contentLookup[variant],
location: 'dashboard-modal',
name: 'geo-pricing',
content: 'modal',
type: 'pause',
country: 'IN',
})
setShowModal(false)
const until = new Date()
until.setDate(until.getDate() + 1) // 1 day
setDismissedUntil(until)
}, [setDismissedUntil, splitTestName, variant])
}, [setDismissedUntil])
if (dismissedUntil && new Date(dismissedUntil) > new Date()) {
return null
}
if (variant === 'default') {
return (
<Notification
bsStyle="info"
onDismiss={bannerDismissed}
body={
<Trans
i18nKey="inr_discount_offer"
components={[<b />]} // eslint-disable-line react/jsx-key
return (
<AccessibleModal show={showModal} onHide={handleHide} backdrop="static">
<Modal.Header closeButton>
<Modal.Title>{t('inr_discount_modal_title')}</Modal.Title>
</Modal.Header>
<Modal.Body className="modal-body-share">
<p>
<img
alt={t('inr_discount_modal_title')}
src="/img/subscriptions/inr-discount-modal.png"
style={{
width: '100%',
}}
/>
}
action={
<Button
bsStyle={newNotificationStyle ? null : 'info'}
bsSize="sm"
className={newNotificationStyle ? 'btn-secondary' : 'pull-right'}
onClick={handleClick}
>
{t('get_discounted_plan')}
</Button>
}
/>
)
} else if (variant === 'green-banner') {
return (
<Notification
bsStyle="success"
onDismiss={bannerDismissed}
body={
<Trans
i18nKey="inr_discount_offer_green_banner"
components={[<b />, <br />]} // eslint-disable-line react/jsx-key
values={{ flag: '🇮🇳' }}
shouldUnescape
tOptions={{ interpolation: { escapeValue: true } }}
/>
}
action={
<Button
bsStyle={newNotificationStyle ? null : 'success'}
bsSize="sm"
className={newNotificationStyle ? 'btn-secondary' : 'pull-right'}
onClick={handleClick}
>
{t('get_discounted_plan')} ₹
</Button>
}
/>
)
} else if (variant === 'modal') {
return (
<AccessibleModal show={showModal} onHide={handleHide}>
<Modal.Header closeButton>
<Modal.Title>{t('inr_discount_modal_title')}</Modal.Title>
</Modal.Header>
<Modal.Body className="modal-body-share">
<p>
<img
alt={t('inr_discount_modal_title')}
src="/img/subscriptions/inr-discount-modal.png"
style={{
width: '100%',
}}
/>
</p>
<p>{t('inr_discount_modal_info')}</p>
</Modal.Body>
<Modal.Footer>
<Button bsStyle="default" onClick={handleMaybeLater}>
{t('maybe_later')}
</Button>
<Button type="button" bsStyle="primary" onClick={handleClick}>
{t('get_discounted_plan')}
</Button>
</Modal.Footer>
</AccessibleModal>
)
} else {
return null
}
</p>
<p>{t('inr_discount_modal_info')}</p>
</Modal.Body>
<Modal.Footer>
<Button bsStyle="default" onClick={handleMaybeLater}>
{t('maybe_later')}
</Button>
<Button type="button" bsStyle="primary" onClick={handleClick}>
{t('get_discounted_plan')}
</Button>
</Modal.Footer>
</AccessibleModal>
)
}
@@ -44,11 +44,6 @@ function UserNotifications() {
)
const showInrGeoBanner = getMeta('ol-showInrGeoBanner', false)
const inrGeoBannerVariant = getMeta('ol-inrGeoBannerVariant', 'default')
const inrGeoBannerSplitTestName = getMeta(
'ol-inrGeoBannerSplitTestName',
'unassigned'
)
const writefullIntegrationSplitTestEnabled = isSplitTestEnabled(
'writefull-integration'
)
@@ -105,15 +100,8 @@ function UserNotifications() {
<Institution />
<ConfirmEmail />
<ReconfirmationInfo />
{!showInrGeoBanner && !showWritefull && !dismissedWritefull && (
<GroupsAndEnterpriseBanner />
)}
{showInrGeoBanner && (
<INRBanner
variant={inrGeoBannerVariant}
splitTestName={inrGeoBannerSplitTestName}
/>
)}
{!showWritefull && !dismissedWritefull && <GroupsAndEnterpriseBanner />}
{showInrGeoBanner && <INRBanner />}
{writefullIntegrationSplitTestEnabled || user?.writefull?.enabled ? (
<WritefullPremiumPromoBanner
show={showWritefull}
@@ -0,0 +1,10 @@
import INRBanner from '@/features/project-list/components/notifications/ads/inr-banner'
export const Default = () => {
return <INRBanner />
}
export default {
title: 'Project List / INR Banner',
component: INRBanner,
}
-1
View File
@@ -701,7 +701,6 @@
"increased_compile_timeout": "Forlænget kompileringstidsgrænse",
"indvidual_plans": "Individuelle abonnementer",
"info": "Info",
"inr_discount_offer": "Gode nyheder! Du kan nu bruge rupier ₹ til at betale for et Overleaf abonnement, hvilket giver dig en <0>70% rabat</0> på vores Premium-funktioner.",
"insert_figure": "Indsæt figur",
"insert_from_another_project": "Indsæt fra andet projekt",
"insert_from_project_files": "Indsæt fra projektfiler",
-1
View File
@@ -719,7 +719,6 @@
"increased_compile_timeout": "Zeitlimit beim Kompilieren erhöhen",
"indvidual_plans": "Einzelnutzer-Abonnements",
"info": "Info",
"inr_discount_offer": "Gute Nachrichten! Du kannst jetzt für dein Overleaf-Abonnement in Rupees ₹ bezahlen und so einen <0>70% Rabatt</0> auf unsere Premiumfunktionen erhalten.",
"insert_figure": "Abbildung einfügen",
"insert_from_another_project": "Von einem anderen Projekt einfügen",
"insert_from_project_files": "Von Projektdateien einfügen",
-2
View File
@@ -845,8 +845,6 @@
"info": "Info",
"inr_discount_modal_info": "Get document history, track changes, additional collaborators, and more at Purchasing Power Parity prices.",
"inr_discount_modal_title": "70% off all Overleaf premium plans for users in India",
"inr_discount_offer": "Good news! You can now use Rupees ₹ to pay for an Overleaf subscription, giving you a <0>70% discount</0> on our premium features.",
"inr_discount_offer_green_banner": "__flag__ <0>Big news!</0> You qualify for a <0>70% discount</0> on our premium plans because you’re in India. <1/>Get additional collaborators, document history, track changes, and more.",
"inr_discount_offer_plans_page_banner": "__flag__ <b>Great news!</b> We’ve applied a <b>70% discount</b> discount to premium plans for our users in India. Check out the new lower prices below.",
"insert": "Insert",
"insert_column_left": "Insert column left",
-2
View File
@@ -855,8 +855,6 @@
"info": "信息",
"inr_discount_modal_info": "以平价获取文档历史记录、跟踪更改、更多协作者等功能。",
"inr_discount_modal_title": "面向印度用户的所有 Overleaf 高级计划七折优惠",
"inr_discount_offer": "好消息! 您现在可以使用卢比 ₹ 来支付 Overleaf 订阅费用,从而在使用我们的高级功能时享受<0>70% 的折扣</0>。",
"inr_discount_offer_green_banner": "__flag__ <0>好消息!</0>由于您在印度,因此您有资格享受我们的高级计划的<0>70% 折扣</0>。 &lt;1/&gt;获取其他协作者、文档历史记录、跟踪更改等。",
"inr_discount_offer_plans_page_banner": "__flag__ <b>好消息!</b>我们已为印度用户的高级计划提供<b>70% 折扣</b>折扣。 查看下面的最新低价。",
"insert": "插入",
"insert_column_left": "在左边插入列",
@@ -0,0 +1,84 @@
import INRBanner from '@/features/project-list/components/notifications/ads/inr-banner'
import customLocalStorage from '@/infrastructure/local-storage'
import { fireEvent, render, screen } from '@testing-library/react'
import { expect } from 'chai'
describe('<INRBanner />', function () {
beforeEach(function () {
customLocalStorage.clear()
})
it('renders correctly', async function () {
render(<INRBanner />)
await screen.findByRole('dialog')
await screen.findByText(
'70% off all Overleaf premium plans for users in India'
)
await screen.findByText(
'Get document history, track changes, additional collaborators, and more at Purchasing Power Parity prices.'
)
await screen.findByRole('button', { name: 'Maybe later' })
await screen.findByRole('button', { name: 'Get discounted plan' })
})
it('dismisses the modal when the "Maybe later" button is clicked', async function () {
render(<INRBanner />)
await screen.findByRole('dialog')
fireEvent.click(screen.getByRole('button', { name: 'Maybe later' }))
expect(screen.queryByRole('dialog')).to.be.null
const dismissedUntil = customLocalStorage.getItem(
'has_dismissed_inr_banner_until'
)
expect(dismissedUntil).to.not.be.null
const nowPlus2Days = new Date()
nowPlus2Days.setDate(nowPlus2Days.getDate() + 2)
// check if dismissal date is around 1 days after the dismissal via "Maybe later" button
expect(new Date(dismissedUntil)).to.be.greaterThan(new Date())
expect(new Date(dismissedUntil)).to.be.lessThan(nowPlus2Days)
})
it('dismisses the modal when close button is clicked', async function () {
render(<INRBanner />)
await screen.findByRole('dialog')
fireEvent.click(screen.getByRole('button', { name: /close/i }))
expect(screen.queryByRole('dialog')).to.be.null
const dismissedUntil = customLocalStorage.getItem(
'has_dismissed_inr_banner_until'
)
expect(dismissedUntil).to.not.be.null
const nowPlus29Days = new Date()
nowPlus29Days.setDate(nowPlus29Days.getDate() + 29)
const nowPlus31Days = new Date()
nowPlus31Days.setDate(nowPlus31Days.getDate() + 31)
// check if dismissal date is around 30 days after the dismissal via close button
expect(new Date(dismissedUntil)).to.be.greaterThan(nowPlus29Days)
expect(new Date(dismissedUntil)).to.be.lessThan(nowPlus31Days)
})
it('hides the modal when user visits while current date is less than local storage date', function () {
const until = new Date()
until.setDate(until.getDate() + 30) // 30 days
customLocalStorage.setItem('has_dismissed_inr_banner_until', until)
render(<INRBanner />)
expect(screen.queryByRole('dialog')).to.be.null
})
})
@@ -126,6 +126,14 @@ describe('ProjectListController', function () {
getUserSubscription: sinon.stub().resolves({}),
},
}
this.GeoIpLookup = {
promises: {
getCurrencyCode: sinon.stub().resolves({
countryCode: 'US',
currencyCode: 'USD',
}),
},
}
this.ProjectListController = SandboxedModule.require(MODULE_PATH, {
requires: {
@@ -155,6 +163,7 @@ describe('ProjectListController', function () {
this.UserPrimaryEmailCheckHandler,
'../Notifications/NotificationsBuilder': this.NotificationBuilder,
'../Subscription/SubscriptionLocator': this.SubscriptionLocator,
'../../infrastructure/GeoIpLookup': this.GeoIpLookup,
},
})
@@ -310,6 +319,38 @@ describe('ProjectListController', function () {
this.ProjectListController.projectListPage(this.req, this.res)
})
it('should show INR Banner for Indian users with free account', function (done) {
// usersBestSubscription is only available when saas feature is present
this.Features.hasFeature.withArgs('saas').returns(true)
this.SubscriptionViewModelBuilder.promises.getBestSubscription.resolves({
type: 'free',
})
this.GeoIpLookup.promises.getCurrencyCode.resolves({
countryCode: 'IN',
})
this.res.render = (pageName, opts) => {
expect(opts.showInrGeoBanner).to.be.true
done()
}
this.ProjectListController.projectListPage(this.req, this.res)
})
it('should not show INR Banner for Indian users with premium account', function (done) {
// usersBestSubscription is only available when saas feature is present
this.Features.hasFeature.withArgs('saas').returns(true)
this.SubscriptionViewModelBuilder.promises.getBestSubscription.resolves({
type: 'individual',
})
this.GeoIpLookup.promises.getCurrencyCode.resolves({
countryCode: 'IN',
})
this.res.render = (pageName, opts) => {
expect(opts.showInrGeoBanner).to.be.false
done()
}
this.ProjectListController.projectListPage(this.req, this.res)
})
describe('With Institution SSO feature', function () {
beforeEach(function (done) {
this.institutionEmail = 'test@overleaf.com'
@@ -268,6 +268,20 @@ describe('SubscriptionController', function () {
this.SubscriptionController.plansPage(this.req, this.res)
})
})
describe('showInrGeoBanner data', function () {
it('should return true for Indian Users', function (done) {
this.res.render = (page, opts) => {
page.should.equal('subscriptions/plans')
opts.showInrGeoBanner.should.equal(true)
done()
}
this.GeoIpLookup.promises.getCurrencyCode.resolves({
countryCode: 'IN',
})
this.SubscriptionController.plansPage(this.req, this.res)
})
})
})
describe('interstitialPaymentPage', function () {
@@ -301,6 +315,20 @@ describe('SubscriptionController', function () {
this.SubscriptionController.interstitialPaymentPage(this.req, this.res)
})
})
describe('showInrGeoBanner data', function () {
it('should return true for Indian users', function (done) {
this.res.render = (page, opts) => {
page.should.equal('subscriptions/interstitial-payment')
opts.showInrGeoBanner.should.equal(true)
done()
}
this.GeoIpLookup.promises.getCurrencyCode.resolves({
countryCode: 'IN',
})
this.SubscriptionController.interstitialPaymentPage(this.req, this.res)
})
})
})
describe('successfulSubscription', function () {