Skip to content

Commit

Permalink
chore: remove SUBSCRIBE_TO_ALL_PRODUCTS ff (#23418)
Browse files Browse the repository at this point in the history
Co-authored-by: github-actions <41898282+github-actions[bot]@users.noreply.github.com>
  • Loading branch information
2 people authored and thmsobrmlr committed Jul 3, 2024
1 parent 34cb6c4 commit be7260a
Show file tree
Hide file tree
Showing 67 changed files with 274 additions and 445 deletions.
28 changes: 4 additions & 24 deletions cypress/e2e/billingUpgradeCTA.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,40 +10,20 @@ describe('Billing Upgrade CTA', () => {

it('Check that events are being sent on each page visit', () => {
cy.visit('/organization/billing')
cy.get('[data-attr=product_analytics-upgrade-cta] .LemonButton__content').should('have.text', 'Subscribe')
cy.get('[data-attr=billing-page-core-upgrade-cta] .LemonButton__content').should('have.text', 'Upgrade now')
cy.window().then((win) => {
const events = (win as any)._cypress_posthog_captures

const matchingEvents = events.filter((event) => event.event === 'billing CTA shown')
// One for each product card
expect(matchingEvents.length).to.equal(4)
expect(matchingEvents.length).to.equal(1)
})

// Mock billing response with subscription
cy.intercept('/api/billing/', { fixture: 'api/billing/billing.json' })
cy.reload()

cy.get('[data-attr=session_replay-upgrade-cta] .LemonButton__content').should('have.text', 'Subscribe')
cy.intercept('POST', '**/e/?compression=gzip-js*').as('capture3')
cy.window().then((win) => {
const events = (win as any)._cypress_posthog_captures

const matchingEvents = events.filter((event) => event.event === 'billing CTA shown')
expect(matchingEvents.length).to.equal(3)
})

cy.intercept('/api/billing/', { fixture: 'api/billing/billing-unsubscribed.json' })
// Navigate to the onboarding billing step
cy.visit('/products')
cy.get('[data-attr=product_analytics-onboarding-card]').click()
cy.get('[data-attr=onboarding-breadcrumbs] > :nth-child(5)').click()

cy.intercept('POST', '**/e/?compression=gzip-js*').as('capture4')
cy.window().then((win) => {
const events = (win as any)._cypress_posthog_captures

const matchingEvents = events.filter((event) => event.event === 'billing CTA shown')
expect(matchingEvents.length).to.equal(3)
})
cy.get('[data-attr=billing-page-core-upgrade-cta] .LemonButton__content').should('not.exist')
cy.get('[data-attr=manage-billing]').should('have.text', 'Manage card details and view past invoices')
})
})
1 change: 1 addition & 0 deletions cypress/fixtures/api/billing/billing.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"customer_id": "cus_Pg7PIL8MsKi6bx",
"deactivated": false,
"has_active_subscription": true,
"subscription_level": "custom",
"billing_period": {
"current_period_start": "2024-03-07T23:21:20Z",
"current_period_end": "2024-04-07T23:21:20Z",
Expand Down
2 changes: 1 addition & 1 deletion ee/api/billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class BillingViewset(TeamAndOrgViewSetMixin, viewsets.GenericViewSet):
def list(self, request: Request, *args: Any, **kwargs: Any) -> Response:
license = get_cached_instance_license()
if license and not license.is_v2_license:
raise NotFound("Billing V2 is not supported for this license type")
raise NotFound("Billing is not supported for this license type")

org = self._get_org()

Expand Down
2 changes: 1 addition & 1 deletion ee/api/test/test_billing.py
Original file line number Diff line number Diff line change
Expand Up @@ -280,7 +280,7 @@ def test_billing_fails_for_old_license_type(self):

res = self.client.get("/api/billing")
assert res.status_code == 404
assert res.json()["detail"] == "Billing V2 is not supported for this license type"
assert res.json()["detail"] == "Billing is not supported for this license type"

@patch("ee.api.billing.requests.get")
@freeze_time("2022-01-01")
Expand Down
206 changes: 174 additions & 32 deletions ee/clickhouse/views/test/__snapshots__/test_clickhouse_experiments.ambr
Original file line number Diff line number Diff line change
Expand Up @@ -441,26 +441,97 @@
# ---
# name: ClickhouseTestFunnelExperimentResults.test_experiment_flow_with_event_results_for_three_test_variants.1
'''
/* celery:posthog.tasks.tasks.sync_insight_caching_state */
SELECT team_id,
date_diff('second', max(timestamp), now()) AS age
FROM events
WHERE timestamp > date_sub(DAY, 3, now())
AND timestamp < now()
GROUP BY team_id
ORDER BY age;
/* user_id:0 request:_snapshot_ */
SELECT array(replaceRegexpAll(JSONExtractRaw(properties, '$feature/a-b-test'), '^"|"$', '')) AS value,
count(*) as count
FROM events e
WHERE team_id = 2
AND event IN ['$pageleave', '$pageview']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-06 00:00:00', 'UTC')
GROUP BY value
ORDER BY count DESC, value DESC
LIMIT 26
OFFSET 0
'''
# ---
# name: ClickhouseTestFunnelExperimentResults.test_experiment_flow_with_event_results_for_three_test_variants.2
'''
/* celery:posthog.tasks.tasks.sync_insight_caching_state */
SELECT team_id,
date_diff('second', max(timestamp), now()) AS age
FROM events
WHERE timestamp > date_sub(DAY, 3, now())
AND timestamp < now()
GROUP BY team_id
ORDER BY age;
/* user_id:0 request:_snapshot_ */
SELECT countIf(steps = 1) step_1,
countIf(steps = 2) step_2,
avg(step_1_average_conversion_time_inner) step_1_average_conversion_time,
median(step_1_median_conversion_time_inner) step_1_median_conversion_time,
prop
FROM
(SELECT aggregation_target,
steps,
avg(step_1_conversion_time) step_1_average_conversion_time_inner,
median(step_1_conversion_time) step_1_median_conversion_time_inner ,
prop
FROM
(SELECT aggregation_target,
steps,
max(steps) over (PARTITION BY aggregation_target,
prop) as max_steps,
step_1_conversion_time ,
prop
FROM
(SELECT *,
if(latest_0 <= latest_1
AND latest_1 <= latest_0 + INTERVAL 14 DAY, 2, 1) AS steps ,
if(isNotNull(latest_1)
AND latest_1 <= latest_0 + INTERVAL 14 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time,
prop
FROM
(SELECT aggregation_target, timestamp, step_0,
latest_0,
step_1,
min(latest_1) over (PARTITION by aggregation_target,
prop
ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_1 ,
if(has([[''], ['test_1'], ['test'], ['control'], ['unknown_3'], ['unknown_2'], ['unknown_1'], ['test_2']], prop), prop, ['Other']) as prop
FROM
(SELECT *,
if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) as prop
FROM
(SELECT e.timestamp as timestamp,
pdi.person_id as aggregation_target,
pdi.person_id as person_id,
if(event = '$pageview', 1, 0) as step_0,
if(step_0 = 1, timestamp, null) as latest_0,
if(event = '$pageleave', 1, 0) as step_1,
if(step_1 = 1, timestamp, null) as latest_1,
array(replaceRegexpAll(JSONExtractRaw(properties, '$feature/a-b-test'), '^"|"$', '')) AS prop_basic,
prop_basic as prop,
argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) over (PARTITION by aggregation_target) as prop_vals
FROM events e
INNER JOIN
(SELECT distinct_id,
argMax(person_id, version) as person_id
FROM person_distinct_id2
WHERE team_id = 2
AND distinct_id IN
(SELECT distinct_id
FROM events
WHERE team_id = 2
AND event IN ['$pageleave', '$pageview']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-06 00:00:00', 'UTC') )
GROUP BY distinct_id
HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id
WHERE team_id = 2
AND event IN ['$pageleave', '$pageview']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-06 00:00:00', 'UTC')
AND (step_0 = 1
OR step_1 = 1) )))
WHERE step_0 = 1 ))
GROUP BY aggregation_target,
steps,
prop
HAVING steps = max_steps)
GROUP BY prop
'''
# ---
# name: ClickhouseTestFunnelExperimentResults.test_experiment_flow_with_event_results_for_three_test_variants.3
Expand Down Expand Up @@ -584,26 +655,97 @@
# ---
# name: ClickhouseTestFunnelExperimentResults.test_experiment_flow_with_event_results_with_hogql_aggregation.1
'''
/* celery:posthog.tasks.tasks.sync_insight_caching_state */
SELECT team_id,
date_diff('second', max(timestamp), now()) AS age
FROM events
WHERE timestamp > date_sub(DAY, 3, now())
AND timestamp < now()
GROUP BY team_id
ORDER BY age;
/* user_id:0 request:_snapshot_ */
SELECT array(replaceRegexpAll(JSONExtractRaw(properties, '$feature/a-b-test'), '^"|"$', '')) AS value,
count(*) as count
FROM events e
WHERE team_id = 2
AND event IN ['$pageleave', '$pageview']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-06 00:00:00', 'UTC')
GROUP BY value
ORDER BY count DESC, value DESC
LIMIT 26
OFFSET 0
'''
# ---
# name: ClickhouseTestFunnelExperimentResults.test_experiment_flow_with_event_results_with_hogql_aggregation.2
'''
/* celery:posthog.tasks.tasks.sync_insight_caching_state */
SELECT team_id,
date_diff('second', max(timestamp), now()) AS age
FROM events
WHERE timestamp > date_sub(DAY, 3, now())
AND timestamp < now()
GROUP BY team_id
ORDER BY age;
/* user_id:0 request:_snapshot_ */
SELECT countIf(steps = 1) step_1,
countIf(steps = 2) step_2,
avg(step_1_average_conversion_time_inner) step_1_average_conversion_time,
median(step_1_median_conversion_time_inner) step_1_median_conversion_time,
prop
FROM
(SELECT aggregation_target,
steps,
avg(step_1_conversion_time) step_1_average_conversion_time_inner,
median(step_1_conversion_time) step_1_median_conversion_time_inner ,
prop
FROM
(SELECT aggregation_target,
steps,
max(steps) over (PARTITION BY aggregation_target,
prop) as max_steps,
step_1_conversion_time ,
prop
FROM
(SELECT *,
if(latest_0 <= latest_1
AND latest_1 <= latest_0 + INTERVAL 14 DAY, 2, 1) AS steps ,
if(isNotNull(latest_1)
AND latest_1 <= latest_0 + INTERVAL 14 DAY, dateDiff('second', toDateTime(latest_0), toDateTime(latest_1)), NULL) step_1_conversion_time,
prop
FROM
(SELECT aggregation_target, timestamp, step_0,
latest_0,
step_1,
min(latest_1) over (PARTITION by aggregation_target,
prop
ORDER BY timestamp DESC ROWS BETWEEN UNBOUNDED PRECEDING AND 0 PRECEDING) latest_1 ,
if(has([['test'], ['control'], ['']], prop), prop, ['Other']) as prop
FROM
(SELECT *,
if(notEmpty(arrayFilter(x -> notEmpty(x), prop_vals)), prop_vals, ['']) as prop
FROM
(SELECT e.timestamp as timestamp,
replaceRegexpAll(nullIf(nullIf(JSONExtractRaw(properties, '$account_id'), ''), 'null'), '^"|"$', '') as aggregation_target,
pdi.person_id as person_id,
if(event = '$pageview', 1, 0) as step_0,
if(step_0 = 1, timestamp, null) as latest_0,
if(event = '$pageleave', 1, 0) as step_1,
if(step_1 = 1, timestamp, null) as latest_1,
array(replaceRegexpAll(JSONExtractRaw(properties, '$feature/a-b-test'), '^"|"$', '')) AS prop_basic,
prop_basic as prop,
argMinIf(prop, timestamp, notEmpty(arrayFilter(x -> notEmpty(x), prop))) over (PARTITION by aggregation_target) as prop_vals
FROM events e
INNER JOIN
(SELECT distinct_id,
argMax(person_id, version) as person_id
FROM person_distinct_id2
WHERE team_id = 2
AND distinct_id IN
(SELECT distinct_id
FROM events
WHERE team_id = 2
AND event IN ['$pageleave', '$pageview']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-06 00:00:00', 'UTC') )
GROUP BY distinct_id
HAVING argMax(is_deleted, version) = 0) AS pdi ON e.distinct_id = pdi.distinct_id
WHERE team_id = 2
AND event IN ['$pageleave', '$pageview']
AND toTimeZone(timestamp, 'UTC') >= toDateTime('2020-01-01 00:00:00', 'UTC')
AND toTimeZone(timestamp, 'UTC') <= toDateTime('2020-01-06 00:00:00', 'UTC')
AND (step_0 = 1
OR step_1 = 1) )))
WHERE step_0 = 1 ))
GROUP BY aggregation_target,
steps,
prop
HAVING steps = max_steps)
GROUP BY prop
'''
# ---
# name: ClickhouseTestFunnelExperimentResults.test_experiment_flow_with_event_results_with_hogql_aggregation.3
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
Diff not rendered.
43 changes: 6 additions & 37 deletions frontend/src/lib/components/PayGateMini/PayGateButton.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
import { LemonButton } from '@posthog/lemon-ui'
import { useValues } from 'kea'
import { FEATURE_FLAGS } from 'lib/constants'
import { featureFlagLogic, FeatureFlagsSet } from 'lib/logic/featureFlagLogic'
import { urls } from 'scenes/urls'

import { BillingFeatureType, BillingProductV2AddonType, BillingProductV2Type, BillingType } from '~/types'
import { BillingFeatureType, BillingProductV2AddonType, BillingProductV2Type } from '~/types'

interface PayGateButtonProps {
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null
productWithFeature: BillingProductV2AddonType | BillingProductV2Type
featureInfo: BillingFeatureType
onCtaClick: () => void
billing: BillingType | null
isAddonProduct?: boolean
scrollToProduct: boolean
}
Expand All @@ -21,28 +17,18 @@ export const PayGateButton = ({
productWithFeature,
featureInfo,
onCtaClick,
billing,
isAddonProduct,
scrollToProduct = true,
}: PayGateButtonProps): JSX.Element => {
const { featureFlags } = useValues(featureFlagLogic)
return (
<LemonButton
to={getCtaLink(
gateVariant,
productWithFeature,
featureInfo,
featureFlags,
billing?.subscription_level,
isAddonProduct,
scrollToProduct
)}
to={getCtaLink(gateVariant, productWithFeature, featureInfo, isAddonProduct, scrollToProduct)}
disableClientSideRouting={gateVariant === 'add-card' && !isAddonProduct}
type="primary"
center
onClick={onCtaClick}
>
{getCtaLabel(gateVariant, billing, featureFlags)}
{getCtaLabel(gateVariant)}
</LemonButton>
)
}
Expand All @@ -51,17 +37,10 @@ const getCtaLink = (
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null,
productWithFeature: BillingProductV2AddonType | BillingProductV2Type,
featureInfo: BillingFeatureType,
featureFlags: FeatureFlagsSet,
subscriptionLevel?: BillingType['subscription_level'],
isAddonProduct?: boolean,
scrollToProduct: boolean = true
): string | undefined => {
if (
gateVariant === 'add-card' &&
!isAddonProduct &&
featureFlags[FEATURE_FLAGS.SUBSCRIBE_TO_ALL_PRODUCTS] === 'test' &&
subscriptionLevel === 'free'
) {
if (gateVariant === 'add-card' && !isAddonProduct) {
return `/api/billing/activate?products=all_products:&redirect_path=${urls.organizationBilling()}&intent_product=${
productWithFeature.type
}`
Expand All @@ -75,19 +54,9 @@ const getCtaLink = (
return undefined
}

const getCtaLabel = (
gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null,
billing: BillingType | null,
featureFlags: FeatureFlagsSet
): string => {
if (
gateVariant === 'add-card' &&
featureFlags[FEATURE_FLAGS.SUBSCRIBE_TO_ALL_PRODUCTS] === 'test' &&
billing?.subscription_level === 'free'
) {
const getCtaLabel = (gateVariant: 'add-card' | 'contact-sales' | 'move-to-cloud' | null): string => {
if (gateVariant === 'add-card') {
return 'Upgrade now'
} else if (gateVariant === 'add-card') {
return billing?.has_active_subscription ? 'Upgrade now' : 'Subscribe now'
} else if (gateVariant === 'contact-sales') {
return 'Contact sales'
}
Expand Down
Loading

0 comments on commit be7260a

Please sign in to comment.