Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 18 additions & 4 deletions browser_tests/fixtures/data/cloudWorkspace.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import type { BillingStatusResponse as IngestBillingStatusResponse } from '@comfyorg/ingest-types'

import type {
BillingStatusResponse,
Member,
Plan,
WorkspaceWithRole
Expand Down Expand Up @@ -70,16 +71,29 @@ export const DEFAULT_TEAM_MEMBERS: Member[] = [

const TEAM_PLAN_SLUG = 'team-pro-monthly'

export const TEAM_BILLING_STATUS: BillingStatusResponse = {
export const TEAM_BILLING_STATUS = {
is_active: true,
subscription_status: 'active',
subscription_tier: 'PRO',
subscription_duration: 'MONTHLY',
plan_slug: TEAM_PLAN_SLUG,
billing_status: 'paid',
has_funds: true,
renewal_date: '2099-02-20T00:00:00Z'
}
renewal_date: '2099-02-20T00:00:00Z',
team_credit_stop: null
} satisfies IngestBillingStatusResponse

export const ENDED_STANDARD_BILLING_STATUS = {
billing_rail: 'stripe',
billing_status: 'inactive',
has_funds: true,
is_active: false,
plan_slug: 'standard-monthly',
subscription_duration: 'MONTHLY',
subscription_status: 'ended',
subscription_tier: 'STANDARD',
team_credit_stop: null
} satisfies IngestBillingStatusResponse & { billing_rail: 'stripe' }

export const TEAM_PRO_PLAN: Plan = {
slug: TEAM_PLAN_SLUG,
Expand Down
13 changes: 8 additions & 5 deletions browser_tests/fixtures/helpers/CloudWorkspaceMockHelper.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { Page, Route } from '@playwright/test'
import type { BillingStatusResponse } from '@comfyorg/ingest-types'

import type {
Member,
Expand Down Expand Up @@ -45,9 +46,10 @@ export class CloudWorkspaceMockHelper {

async setup(
members: Member[] = DEFAULT_TEAM_MEMBERS,
activeWorkspace: WorkspaceWithRole = TEAM_WORKSPACE
activeWorkspace: WorkspaceWithRole = TEAM_WORKSPACE,
billingStatus: BillingStatusResponse = TEAM_BILLING_STATUS
): Promise<MemberMockState> {
const state = await this.mockBoot(members, activeWorkspace)
const state = await this.mockBoot(members, activeWorkspace, billingStatus)
await new CloudAuthHelper(this.page).mockAuth()
await this.page.addInitScript((workspaceId) => {
localStorage.setItem('Comfy.userId', 'test-user-e2e')
Expand All @@ -58,7 +60,8 @@ export class CloudWorkspaceMockHelper {

private async mockBoot(
members: Member[],
activeWorkspace: WorkspaceWithRole
activeWorkspace: WorkspaceWithRole,
billingStatus: BillingStatusResponse
): Promise<MemberMockState> {
const state: MemberMockState = {
members: members.map((m) => ({ ...m })),
Expand Down Expand Up @@ -132,7 +135,7 @@ export class CloudWorkspaceMockHelper {
)

await page.route('**/api/billing/status', (r) =>
r.fulfill(jsonRoute(TEAM_BILLING_STATUS))
r.fulfill(jsonRoute(billingStatus))
)
await page.route('**/api/billing/balance', (r) =>
r.fulfill(
Expand All @@ -148,7 +151,7 @@ export class CloudWorkspaceMockHelper {
await page.route('**/api/billing/plans', (r) =>
r.fulfill(
jsonRoute({
current_plan_slug: TEAM_PRO_PLAN.slug,
current_plan_slug: billingStatus.plan_slug ?? TEAM_PRO_PLAN.slug,
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
plans: [TEAM_PRO_PLAN]
})
)
Expand Down
56 changes: 56 additions & 0 deletions browser_tests/tests/dialogs/endedSubscription.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { expect } from '@playwright/test'

import {
cloudAppFixture as test,
waitForCloudApp
} from '@e2e/fixtures/cloudAppFixture'
import {
DEFAULT_TEAM_MEMBERS,
ENDED_STANDARD_BILLING_STATUS,
TEAM_WORKSPACE
} from '@e2e/fixtures/data/cloudWorkspace'
import { CloudWorkspaceMockHelper } from '@e2e/fixtures/helpers/CloudWorkspaceMockHelper'
import { TestIds } from '@e2e/fixtures/selectors'

test.describe('Ended workspace subscription', { tag: '@cloud' }, () => {
test.describe.configure({ timeout: 60_000 })

test.beforeEach(async ({ page }) => {
await new CloudWorkspaceMockHelper(page).setup(
DEFAULT_TEAM_MEMBERS,
TEAM_WORKSPACE,
ENDED_STANDARD_BILLING_STATUS
)
await page.goto(process.env.PLAYWRIGHT_TEST_URL || 'http://localhost:8188')
await waitForCloudApp(page)

await page
.getByRole('button', { name: /^Settings/ })
.first()
.click()
const dialog = page.getByTestId(TestIds.dialogs.settings)
await expect(dialog).toBeVisible()
await dialog
.locator('nav')
.getByRole('button', { name: 'Workspace', exact: true })
.click()
})

test('shows subscribe prompt instead of stale paid plan metadata', async ({
page
}) => {
const content = page.getByTestId(TestIds.dialogs.settings).getByRole('main')

await expect(
content.getByRole('heading', {
name: 'This workspace is not on a subscription'
})
).toBeVisible()
await expect(
content.getByRole('button', { name: 'Subscribe Now' })
).toBeVisible()
await expect(
content.getByRole('heading', { name: 'Standard' })
).toHaveCount(0)
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -158,10 +158,10 @@ vi.mock('@/composables/billing/useBillingContext', () => ({
isActiveSubscription: computed(() => mockIsActiveSubscription.value),
isFreeTier: computed(() => false),
billingStatus: mockBillingStatus,
subscriptionStatus: mockSubscriptionStatus,
isTeamPlan: mockIsTeamPlan,
subscription: mockSubscription,
plans: mockPlans,
subscriptionStatus: mockSubscriptionStatus,
teamCreditStops: mockTeamCreditStops,
currentTeamCreditStop: mockCurrentTeamCreditStop,
isLoading: mockIsLoading,
Expand Down Expand Up @@ -534,6 +534,28 @@ describe('SubscriptionPanelContentWorkspace', () => {
).not.toBeInTheDocument()
})

it('shows subscribe prompt for an ended Standard plan in a Team workspace', () => {
mockIsActiveSubscription.value = false
mockSubscriptionStatus.value = 'ended'
mockBillingStatus.value = 'inactive'
mockSubscriptionTier.value = 'STANDARD'
mockPlanSlug.value = 'standard-monthly'
mockHasTeamPlan.value = false
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Outdated
renderComponent()

expect(
screen.getByRole('heading', {
name: 'This workspace is not on a subscription'
})
).toBeInTheDocument()
expect(
screen.getByRole('button', { name: 'Subscribe Now' })
).toBeInTheDocument()
expect(
screen.queryByRole('heading', { name: 'Standard' })
).not.toBeInTheDocument()
})

it.for(['paid', 'payment_failed', 'paused'] as BillingStatus[])(
'keeps a %s personal plan visible until it is terminal',
(billingStatus) => {
Expand Down
Loading