diff --git a/ghost/portal/package.json b/ghost/portal/package.json index e7b8b33bc6..4cbf6df4fb 100644 --- a/ghost/portal/package.json +++ b/ghost/portal/package.json @@ -25,7 +25,8 @@ "@testing-library/user-event": "13.3.0", "react": "17.0.2", "react-dom": "17.0.2", - "react-scripts": "4.0.3" + "react-scripts": "4.0.3", + "uuid": "^8.3.2" }, "scripts": { "start": "BROWSER=none react-scripts start", diff --git a/ghost/portal/src/utils/fixtures.js b/ghost/portal/src/utils/fixtures.js index 178a96afde..8f8dfa2a85 100644 --- a/ghost/portal/src/utils/fixtures.js +++ b/ghost/portal/src/utils/fixtures.js @@ -1,371 +1,323 @@ -const prices = [ - { - id: '6086d2c776909b1a2382369a', - stripe_price_id: '7d6c89c0289ca1731226e86b95b5a162085b8561ca0d10d3a4f03afd3e3e6ba6', - stripe_product_id: '109c85c734fb9992e7bc30a26af66c22f5c94d8dc62e0a33cb797be902c06b2d', - active: 1, - nickname: 'Monthly', - currency: 'usd', - amount: 500, - type: 'recurring', - interval: 'month' - }, - { - id: '6086eff0823dd7240afc8083', - stripe_price_id: 'price_1IkXgCFToJelIqAsTP3V1paQ', - stripe_product_id: 'prod_JNGGBrrogUXcoM', - active: 1, - nickname: 'Yearly', - currency: 'usd', - amount: 5000, - type: 'recurring', - interval: 'year' - } -]; +import {v4 as uuidv4} from 'uuid'; -const products = [ - { - id: 'product_1', - name: 'Gold', - description: 'Get access to everything and lock in early adopter pricing for life + listen to my podcast', - monthlyPrice: { - id: '6085adc776909b1a2382369a', - stripe_price_id: '7d6c89c0289ca1731226e86b95b5a162085b8561ca0d10d3a4f03afd3e3e6ba6', - stripe_product_id: '109c85c734fb9992e7bc30a26af66c22f5c94d8dc62e0a33cb797be902c06b2d', - active: 1, - nickname: 'Monthly', - currency: 'usd', - amount: 2000, - type: 'recurring', - interval: 'month' - }, - yearlyPrice: { - id: '6086eff0823dd7345afc8083', - stripe_price_id: 'price_1IkXgCFToJelIqAsTP3V1paQ', - stripe_product_id: 'prod_JNGGBrrogUXcoM', - active: 1, - nickname: 'Yearly', - currency: 'usd', - amount: 17000, - type: 'recurring', - interval: 'year' - }, - // benefits: [] - benefits: [ - { - id: 'a1', - name: 'Limited early adopter pricing' - }, - { - id: 'a2', - name: 'Latest gear reviews' - }, - { - id: 'a3', - name: 'Weekly email newsletter' - }, - { - id: 'a4', - name: 'Listen to my podcast' - } - ] - }, - { - id: 'product_2', - name: 'Silver', - description: 'Access to all members articles and weekly podcast', - monthlyPrice: { - id: '6086d2c776909b111182369a', - stripe_price_id: '7d6c89c0289ca1731226e86b95b5a162085b8561ca0d10d3a4f03afd3e3e6ba6', - stripe_product_id: '109c85c734fb9992e7bc30a26af66c22f5c94d8dc62e0a33cb797be902c06b2d', - active: 1, - nickname: 'Monthly', - currency: 'usd', - amount: 1200, - type: 'recurring', - interval: 'month' - }, - yearlyPrice: { - id: '6086eff0823dd72402fc8012', - stripe_price_id: 'price_1IkXgCFToJelIqAsTP3V1paQ', - stripe_product_id: 'prod_JNGGBrrogUXcoM', - active: 1, - nickname: 'Yearly', - currency: 'usd', - amount: 12000, - type: 'recurring', - interval: 'year' - }, - benefits: [ - { - id: 'b1', - name: 'Limited early adopter pricing' - }, - { - id: 'b2', - name: 'Latest gear reviews' - }, - { - id: 'b3', - name: 'Weekly email newsletter' - } - ] - }, - { - id: 'product_3', - name: 'Bronze', - description: 'Access to all members articles', - monthlyPrice: { - id: '6086d2c776909b1a23823622', - stripe_price_id: '7d6c89c0289ca1731226e86b95b5a162085b8561ca0d10d3a4f03afd3e3e6ba6', - stripe_product_id: '109c85c734fb9992e7bc30a26af66c22f5c94d8dc62e0a33cb797be902c06b2d', - active: 1, - nickname: 'Monthly', - currency: 'usd', - amount: 700, - type: 'recurring', - interval: 'month' - }, - yearlyPrice: { - id: '6086eff0823dd7240afc8012', - stripe_price_id: 'price_1IkXgCFToJelIqAsTP3V1paQ', - stripe_product_id: 'prod_JNGGBrrogUXcoM', - active: 1, - nickname: 'Yearly', - currency: 'usd', - amount: 8000, - type: 'recurring', - interval: 'year' - }, - // benefits: [] - benefits: [ - { - id: 'c1', - name: 'Latest gear reviews' - }, - { - id: 'c2', - name: 'Weekly email newsletter' - } - ] - } -]; - -export const site = { - title: 'The Blueprint', - description: 'Thoughts, stories and ideas.', - logo: 'https://static.ghost.org/v4.0.0/images/ghost-orb-1.png', - icon: 'https://static.ghost.org/v4.0.0/images/ghost-orb-1.png', - accent_color: '#45C32E', - url: 'http://localhost:2368/', - plans: { - monthly: 5000, - yearly: 150000, - currency: 'USD' - }, - portal_products: ['product_1', 'product_2', 'product_3'], - // products: [products[0]], - products: products, - prices, - allow_self_signup: true, - members_signup_access: 'all', - free_price_name: 'Free', - free_price_description: 'Free preview', - is_stripe_configured: true, - portal_button: true, - portal_name: true, - portal_plans: ['free', 'monthly', 'yearly'], - portal_button_icon: 'icon-1', - portal_button_signup_text: 'Subscribe now', - portal_button_style: 'icon-and-text', - members_support_address: 'support@example.com' +export const sites = { + singleProduct: getSiteData({ + products: getProductsData({numOfProducts: 1}) + }) }; -export const member = { - free: { - uuid: 'd7d3b1a0-90f4-4b93-a51f-76b56213b535', - email: 'jamie@example.com', - name: 'Jamie Larson', - firstname: 'Jamie', - // avatar_image: 'https://gravatar.com/avatar/eb0ef27b5faa9528c900170cba4c11dc?s=250&', - avatar_image: '', - subscriptions: [], - paid: false - }, - alphaComplimentary: { - uuid: '7dcc8939-3be0-4ac8-a363-96d19f909de6', - email: 'jamie@example.com', - name: 'Jamie Larson', - firstname: 'Jamie', - // avatar_image: 'https://gravatar.com/avatar/eb0ef27b5faa9528c900170cba4c11dc?s=250&', - avatar_image: '', - subscriptions: [], - paid: true - }, - paid: { - uuid: '7dcc8939-3be0-4ac8-a363-96d19f909de6', - email: 'jamie@example.com', - name: 'Jamie Larson', - firstname: 'Jamie', - // avatar_image: 'https://gravatar.com/avatar/eb0ef27b5faa9528c900170cba4c11dc?s=250&', - avatar_image: '', - subscriptions: [{ - id: 'sub_HCLyRzHcGciDWJ', - customer: { - id: 'cus_HCLy4Y3eLt50YJ', - name: null, - email: 'jamie@example.com' - }, - plan: { - id: 'fd43b943666b97640188afb382cca39479de30f799985679dd7a71ad2925ac6c', - nickname: 'Yearly', - interval: 'year', - amount: 7000, - currency: 'USD' - }, - price: { - id: 'price_1IkXgCFToJelIqAsTP3V1paQ', - price_id: '6086eff0823dd7240afc8012', - nickname: 'Yearly', - currency: 'usd', - amount: 7000, - type: 'recurring', - interval: 'year', - product: { - id: 'prod_JNGGBrrogUXcoM', - name: 'Main Product', - product_id: '6086cd1b27c7d417b4a18eaf' - } - }, - status: 'active', - start_date: '2019-05-01T11:42:40.000Z', - default_payment_card_last4: '4242', - cancel_at_period_end: false, - current_period_end: '2021-06-05T11:42:40.000Z' - }], - paid: true - }, - complimentary: { - uuid: '67906ee2-c80f-4b61-9c9b-6b98c5d3a195', - email: 'jamie@example.com', - name: 'Jamie Larson', - firstname: 'Jamie', - // avatar_image: 'https://gravatar.com/avatar/76a4c5450dbb6fde8a293a811622aa6f?s=250&d=blank', - subscribed: true, - subscriptions: [{ - id: 'sub_HxAis4368CZIuX', - customer: { - id: 'cus_HxAiVNQ8C3MdAN', - name: null, - email: 'jamie@example.com' - }, - plan: { - id: 'd46f4d6de40f9bb47c86b8c9abb8285182f0b10f3ac05b5ba8633417ecac2746', - nickname: 'Complimentary', - amount: 0, - interval: 'year', - currency: 'USD' - }, - price: { - price_id: '6086eff0823dd7240afc8083', - nickname: 'Complimentary', - amount: 0, - interval: 'year', - type: 'recurring', - currency: 'USD', - product: { - id: 'prod_JNGGBrrogUXcoM', - name: 'Main Product', - product_id: '6086cd1b27c7d417b4a18eaf' - } - }, - status: 'active', - start_date: '2020-09-03T11:12:37.000Z', - default_payment_card_last4: null, - cancel_at_period_end: false, - current_period_end: '2021-09-03T11:12:37.000Z' - }], - paid: true - }, - preview: { - uuid: '7dcc8939-3be0-4ac8-a363-96d19f909de6', - email: 'jamie@example.com', - name: 'Jamie Larson', - firstname: 'Jamie', - // avatar_image: 'https://gravatar.com/avatar/eb0ef27b5faa9528c900170cba4c11dc?s=250&', - avatar_image: '', - subscriptions: [{ - id: 'sub_HCLyRzHcGciDWJ', - customer: { - id: 'cus_HCLy4Y3eLt50YJ', - name: null, - email: 'jamie@example.com' - }, - plan: { - id: 'fd43b943666b97640188afb382cca39479de30f799985679dd7a71ad2925ac6c', - nickname: 'Yearly', - interval: 'year', - amount: 500, - currency: 'USD' - }, - price: { - price_id: '6086ead8070218227791fe4f', - id: 'price_1IkXLAFToJelIqAseQdK4WSU', - nickname: 'Yearly', - currency: 'usd', - amount: 1500, - type: 'recurring', - interval: 'month', - product: { - id: 'prod_JNGGBrrogUXcoM', - name: 'Main Product', - product_id: '6086cd1b27c7d417b4a18eaf' - } - }, - status: 'active', - start_date: '2019-05-01T11:42:40.000Z', - default_payment_card_last4: '4242', - cancel_at_period_end: false, - current_period_end: '2021-06-05T11:42:40.000Z' - }], - paid: true - } -}; - -export const testSite = { - ...site, - products: products?.[0] ? [products[0]] : [], - allow_self_signup: true, - portal_plans: ['free', 'monthly', 'yearly'] -}; - -export const offer = { - id: '615fc537e1a950452c06e64d', - name: 'Black Friday', - code: 'black-friday', - display_title: 'Black Friday Special', - display_description: 'Black Friday Sale!', - type: 'percent', - cadence: 'month', - amount: 50, - duration: 'once', - duration_in_months: null, - currency_restriction: false, - currency: null, - status: 'active', - tier: { - id: '61233747fa18731c77a36691', - name: 'Basic' - } -}; - -export function generateAccountPlanFixture() { +function getSiteData({ + products = getProductsData({numOfProducts: 3}), + portalProducts = products.map(p => p.id), + portalPlans: portal_plans = ['free', 'monthly', 'yearly'] +} = {}) { return { - site: { - ...testSite, - products: products, - portal_products: ['product_2'] + title: 'The Blueprint', + description: 'Thoughts, stories and ideas.', + logo: 'https://static.ghost.org/v4.0.0/images/ghost-orb-1.png', + icon: 'https://static.ghost.org/v4.0.0/images/ghost-orb-1.png', + accent_color: '#45C32E', + url: 'https://portal.localhost', + plans: { + monthly: 5000, + yearly: 150000, + currency: 'USD' }, + products, + portal_products: portalProducts, + allow_self_signup: true, + members_signup_access: 'all', + free_price_name: 'Free', + free_price_description: 'Free preview', + is_stripe_configured: true, + portal_button: true, + portal_name: true, + portal_plans, + portal_button_icon: 'icon-1', + portal_button_signup_text: 'Subscribe now', + portal_button_style: 'icon-and-text', + members_support_address: 'support@example.com' + }; +} + +function getOfferData({ + name = 'Black Friday 2', + code = 'black-friday', + displayTitle = 'Black Friday Special', + displayDescription = 'Black Friday Sale!', + type = 'percent', + cadence = 'month', + amount = 50, + duration = 'once', + durationInMonths = null, + currencyRestruction = false, + currency = null, + status = 'active', + tierId = '' +} = {}) { + return { + id: `offer_${uuidv4()}`, + name, + code, + display_title: displayTitle, + display_description: displayDescription, + type, + cadence, + amount, + duration, + duration_in_months: durationInMonths, + currency_restriction: currencyRestruction, + currency, + status, + tier: { + id: `${tierId}`, + name: 'Basic' + } + }; +} + +function getMemberData({ + name = 'Jamie Larson', + email = 'jamie@example.com', + firstname = 'Jamie', + subscriptions = [], + paid = false, + avatarImage: avatar_image = '', + subscribed = true +} = {}) { + return { + uuid: `member_${uuidv4()}`, + email, + name, + firstname, + paid, + subscribed, + avatar_image, + subscriptions + }; +} + +function getProductsData({numOfProducts = 3} = {}) { + const products = [ + getProductData({ + name: 'Bronze', + description: 'Access to all members articles', + monthlyPrice: getPriceData({ + interval: 'month', + amount: 700 + }), + yearlyPrice: getPriceData({ + interval: 'month', + amount: 7000 + }), + numOfBenefits: 2 + }), + getProductData({ + name: 'Silver', + description: 'Access to all members articles and weekly podcast', + monthlyPrice: getPriceData({ + interval: 'month', + amount: 1200 + }), + yearlyPrice: getPriceData({ + interval: 'month', + amount: 12000 + }), + numOfBenefits: 3 + }), + getProductData({ + name: 'Gold', + description: 'Get access to everything and lock in early adopter pricing for life + listen to my podcast', + monthlyPrice: getPriceData({ + interval: 'month', + amount: 2000 + }), + yearlyPrice: getPriceData({ + interval: 'month', + amount: 17000 + }), + numOfBenefits: 4 + }) + ]; + return products.slice(0, numOfProducts); +} + +function getProductData({ + name = 'Basic', + description = '', + id = `product_${uuidv4()}`, + monthlyPrice = getPriceData(), + yearlyPrice = getPriceData({interval: 'year'}), + numOfBenefits = 2 +}) { + return { + id: id, + name: name, + description, + monthlyPrice, + yearlyPrice, + benefits: getBenefits({numOfBenefits}) + + }; +} + +function getBenefits({numOfBenefits}) { + const beenfits = [ + getBenefitData({name: 'Limited early adopter pricing'}), + getBenefitData({name: 'Latest gear reviews'}), + getBenefitData({name: 'Weekly email newsletter'}), + getBenefitData({name: 'Listen to my podcast'}) + ]; + return beenfits.slice(0, numOfBenefits); +} + +function getBenefitData({ + id = `benefit_${uuidv4()}`, + name = 'Benefit' +}) { + return { + id, + name + }; +} + +function getPriceData({ + interval = 'month', + amount = (interval === 'month' ? 500 : 5000), + nickname = interval === 'month' ? 'Monthly' : 'Yearly', + description = null, + currency = 'usd', + active = true, + id = `product_${uuidv4()}` +}) { + return { + id: id, + active, + nickname, + currency, + amount, + interval, + description, + stripe_price_id: `price_${uuidv4()}`, + stripe_product_id: `prod_${uuidv4()}`, + type: 'recurring' + }; +} + +function getSubscriptionData({ + id = `sub_${uuidv4()}`, + status = 'active', + currency = 'USD', + interval = 'month', + amount = (interval === 'month' ? 500 : 5000), + nickname = (interval === 'month' ? 'Monthly' : 'Yearly'), + cardLast4 = '4242', + priceId: price_id = `price_${uuidv4()}`, + startDate: start_date = '2021-10-05T03:18:30.000Z', + currentPeriodEnd: current_period_end = '2022-10-05T03:18:30.000Z', + cancelAtPeriodEnd: cancel_at_period_end = false +} = {}) { + return { + id, + customer: { + id: `cus_${uuidv4()}`, + name: 'Jamie', + email: 'jamie@example.com' + }, + plan: { + id: `price_${uuidv4()}`, + nickname, + amount, + interval, + currency + }, + status, + start_date, + default_payment_card_last4: cardLast4, + cancel_at_period_end, + cancellation_reason: null, + current_period_end, + price: { + id: `stripe_price_${uuidv4()}`, + price_id, + nickname, + amount, + interval, + type: 'recurring', + currency, + product: { + id: `stripe_prod_${uuidv4()}`, + product_id: `prod_${uuidv4()}` + } + } + }; +} + +export const testSite = getSiteData({ + products: getProductsData({numOfProducts: 1}) +}); + +export const site = getSiteData({}); +export const offer = getOfferData({}); +export const member = { + free: getMemberData(), + paid: getMemberData({ + paid: true, + subscriptions: [ + getSubscriptionData() + ] + }), + complimentary: getMemberData({ + paid: true, + subscriptions: [] + }), + complimentaryWithSubscription: getMemberData({ + paid: true, + subscriptions: [ + getSubscriptionData({ + amount: 0 + }) + ] + }), + preview: getMemberData({ + paid: true, + subscriptions: [ + getSubscriptionData({ + amount: 1500, + startDate: '2019-05-01T11:42:40.000Z', + currentPeriodEnd: '2021-06-05T11:42:40.000Z' + }) + ] + }) +}; +export function generateAccountPlanFixture() { + const products = getProductsData({numOfProducts: 3}); + return { + site: getSiteData({ + portalProducts: [products[1]] + }), member: member.paid }; } + +export function basic() { + const products = getProductsData(); + const siteData = getSiteData({ + products + }); + const defaultMemberPrice = products?.[0].monthlyPrice; + const memberData = getMemberData({ + paid: true, + subscriptions: [ + getSubscriptionData({ + priceId: defaultMemberPrice.id, + amount: defaultMemberPrice.amount, + currency: defaultMemberPrice.currency + }) + ] + }); + return { + site: siteData, + member: memberData + }; +} diff --git a/ghost/portal/yarn.lock b/ghost/portal/yarn.lock index 869f4af470..0fd652867e 100644 --- a/ghost/portal/yarn.lock +++ b/ghost/portal/yarn.lock @@ -11707,7 +11707,7 @@ uuid@^3.3.2, uuid@^3.4.0: resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== -uuid@^8.3.0: +uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==