License Management Test
This test retrieves plans, creates checkout session, and updates license Essential changes have been made to linkStripeCustomer & updatePlan functions to support the test Modified "test:self:ci" to include 'licensing' instead of 'license' Modified environment.ts to include STRIPE_SECRET_KEY
This commit is contained in:
parent
87c1726eec
commit
e05821d6d7
|
@ -17,7 +17,7 @@
|
||||||
"test:notify": "node scripts/testResultsWebhook",
|
"test:notify": "node scripts/testResultsWebhook",
|
||||||
"test:cloud:prod": "yarn run test --testPathIgnorePatterns=\\.integration\\.",
|
"test:cloud:prod": "yarn run test --testPathIgnorePatterns=\\.integration\\.",
|
||||||
"test:cloud:qa": "yarn run test",
|
"test:cloud:qa": "yarn run test",
|
||||||
"test:self:ci": "yarn run test --testPathIgnorePatterns=\\.integration\\. \\.cloud\\. \\.license\\.",
|
"test:self:ci": "yarn run test --testPathIgnorePatterns=\\.integration\\. \\.cloud\\. \\.licensing\\.",
|
||||||
"serve:test:self:ci": "start-server-and-test dev:built http://localhost:4001/health test:self:ci",
|
"serve:test:self:ci": "start-server-and-test dev:built http://localhost:4001/health test:self:ci",
|
||||||
"serve": "start-server-and-test dev:built http://localhost:4001/health",
|
"serve": "start-server-and-test dev:built http://localhost:4001/health",
|
||||||
"dev:built": "cd ../ && yarn dev:built"
|
"dev:built": "cd ../ && yarn dev:built"
|
||||||
|
|
|
@ -99,9 +99,15 @@ export default class LicenseAPI extends BaseAPI {
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async updatePlan(opts: APIRequestOpts = { status: 200 }) {
|
async updatePlan(
|
||||||
|
priceId: string,
|
||||||
|
opts: APIRequestOpts = { status: 200 }
|
||||||
|
) {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.put(`/api/license/plan`)
|
return this.client.put(`/api/license/plan`,
|
||||||
|
{
|
||||||
|
body: { priceId },
|
||||||
|
})
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,18 @@ export default class StripeAPI extends BaseAPI {
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
async linkStripeCustomer(opts: APIRequestOpts = { status: 200 }) {
|
async linkStripeCustomer(
|
||||||
|
accountId: string,
|
||||||
|
stripeCustomerId: string,
|
||||||
|
opts: APIRequestOpts = { status: 200 }) {
|
||||||
return this.doRequest(() => {
|
return this.doRequest(() => {
|
||||||
return this.client.post(`/api/stripe/link`)
|
return this.client.post(`/api/stripe/link`, {
|
||||||
|
body: {
|
||||||
|
accountId,
|
||||||
|
stripeCustomerId
|
||||||
|
},
|
||||||
|
internal: true,
|
||||||
|
})
|
||||||
}, opts)
|
}, opts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,113 @@
|
||||||
|
import TestConfiguration from "../../config/TestConfiguration"
|
||||||
|
import * as fixtures from "../../fixtures"
|
||||||
|
import {Hosting, PlanType} from "@budibase/types"
|
||||||
|
|
||||||
|
describe("license management", () => {
|
||||||
|
const config = new TestConfiguration()
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await config.beforeAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
afterAll(async () => {
|
||||||
|
await config.afterAll()
|
||||||
|
})
|
||||||
|
|
||||||
|
it("retrieves plans, creates checkout session, and updates license", async () => {
|
||||||
|
// Create cloud account
|
||||||
|
const createAccountRequest = fixtures.accounts.generateAccount({
|
||||||
|
hosting: Hosting.CLOUD,
|
||||||
|
})
|
||||||
|
const [createAccountRes, account] =
|
||||||
|
await config.accountsApi.accounts.create(createAccountRequest, {
|
||||||
|
autoVerify: true,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Self response has free license
|
||||||
|
await config.doInNewState(async () => {
|
||||||
|
await config.loginAsAccount(createAccountRequest)
|
||||||
|
const [selfRes, selfBody] = await config.api.accounts.self()
|
||||||
|
expect(selfBody.license.plan.type).toBe(PlanType.FREE)
|
||||||
|
})
|
||||||
|
|
||||||
|
// Retrieve plans
|
||||||
|
const [plansRes, planBody] = await config.api.licenses.getPlans()
|
||||||
|
|
||||||
|
// Select priceId from premium plan
|
||||||
|
let premiumPriceId = null
|
||||||
|
let businessPriceId = ''
|
||||||
|
for (const plan of planBody) {
|
||||||
|
if (plan.type === PlanType.PREMIUM) {
|
||||||
|
premiumPriceId = plan.prices[0].priceId
|
||||||
|
}
|
||||||
|
if (plan.type === PlanType.BUSINESS) {
|
||||||
|
businessPriceId = plan.prices[0].priceId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create checkout session for price
|
||||||
|
const checkoutSessionRes = await config.api.stripe.createCheckoutSession(
|
||||||
|
premiumPriceId
|
||||||
|
)
|
||||||
|
const checkoutSessionUrl = checkoutSessionRes[1].url
|
||||||
|
expect(checkoutSessionUrl).toContain("checkout.stripe.com")
|
||||||
|
|
||||||
|
// Create stripe customer
|
||||||
|
const stripe = require('stripe')(process.env.STRIPE_SECRET_KEY)
|
||||||
|
const customer = await stripe.customers.create({
|
||||||
|
email: createAccountRequest.email
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create payment method
|
||||||
|
const paymentMethod = await stripe.paymentMethods.create({
|
||||||
|
type: 'card',
|
||||||
|
card: {
|
||||||
|
token: 'tok_visa' // Test Visa Card
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Attach payment method to customer
|
||||||
|
await stripe.paymentMethods.attach(paymentMethod.id, {
|
||||||
|
customer: customer.id,
|
||||||
|
})
|
||||||
|
|
||||||
|
// Update customer
|
||||||
|
await stripe.customers.update(customer.id, {
|
||||||
|
invoice_settings: {
|
||||||
|
default_payment_method: paymentMethod.id,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
// Create subscription for premium plan
|
||||||
|
const subscription = await stripe.subscriptions.create({
|
||||||
|
customer: customer.id,
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
price: premiumPriceId,
|
||||||
|
quantity: 1,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
default_payment_method: paymentMethod.id,
|
||||||
|
collection_method: 'charge_automatically',
|
||||||
|
})
|
||||||
|
|
||||||
|
await config.doInNewState(async () => {
|
||||||
|
// License updated from Free to Premium
|
||||||
|
await config.loginAsAccount(createAccountRequest)
|
||||||
|
await config.api.stripe.linkStripeCustomer(account.accountId, customer.id)
|
||||||
|
const [_, selfBodyPremium] = await config.api.accounts.self()
|
||||||
|
expect(selfBodyPremium.license.plan.type).toBe(PlanType.PREMIUM)
|
||||||
|
|
||||||
|
// Create portal session - Check URL
|
||||||
|
const [portalRes, portalSessionBody] = await config.api.stripe.createPortalSession(customer.id)
|
||||||
|
expect(portalSessionBody.url).toContain("billing.stripe.com")
|
||||||
|
|
||||||
|
// Update subscription from premium to business license
|
||||||
|
await config.api.licenses.updatePlan(businessPriceId)
|
||||||
|
|
||||||
|
// License updated to Business
|
||||||
|
const [selfRes, selfBodyBusiness] = await config.api.accounts.self()
|
||||||
|
expect(selfBodyBusiness.license.plan.type).toBe(PlanType.BUSINESS)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
|
@ -28,6 +28,7 @@ const env = {
|
||||||
MARIADB_DB: process.env.MARIADB_DB,
|
MARIADB_DB: process.env.MARIADB_DB,
|
||||||
MARIADB_USER: process.env.MARIADB_USER,
|
MARIADB_USER: process.env.MARIADB_USER,
|
||||||
MARIADB_PASSWORD: process.env.MARIADB_PASSWORD,
|
MARIADB_PASSWORD: process.env.MARIADB_PASSWORD,
|
||||||
|
STRIPE_SECRET_KEY: process.env.STRIPE_SECRET_KEY,
|
||||||
}
|
}
|
||||||
|
|
||||||
export = env
|
export = env
|
||||||
|
|
Loading…
Reference in New Issue