Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: running paid subscription e2e tests on both self-hosted and home-server setup #2355

Merged
merged 4 commits into from Jul 14, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
36 changes: 12 additions & 24 deletions packages/snjs/mocha/files.test.js
@@ -1,5 +1,4 @@
import * as Factory from './lib/factory.js'
import * as Events from './lib/Events.js'
import * as Utils from './lib/Utils.js'
import * as Files from './lib/Files.js'

Expand Down Expand Up @@ -39,7 +38,7 @@ describe('files', function () {
})

if (subscription) {
await context.publicMockSubscriptionPurchaseEvent()
await context.activatePaidSubscriptionForUser()
}
}

Expand All @@ -48,7 +47,7 @@ describe('files', function () {
localStorage.clear()
})

it('should create valet token from server - @paidfeature', async function () {
it('should create valet token from server', async function () {
await setup({ fakeCrypto: true, subscription: true })

const remoteIdentifier = Utils.generateUuid()
Expand All @@ -66,34 +65,23 @@ describe('files', function () {
expect(isClientDisplayableError(tokenOrError)).to.equal(true)
})

it('should not create valet token from server when user has an expired subscription - @paidfeature', async function () {
it('should not create valet token from server when user has an expired subscription', async function () {
await setup({ fakeCrypto: true, subscription: false })

await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: context.email,
subscriptionId: subscriptionId++,
subscriptionName: 'PLUS_PLAN',
subscriptionExpiresAt: (new Date().getTime() - 3_600_000) * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 1,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.0,
})
const dateAnHourBefore = new Date()
dateAnHourBefore.setHours(dateAnHourBefore.getHours() - 1)

await Factory.sleep(2)
await context.activatePaidSubscriptionForUser({
expiresAt: dateAnHourBefore,
})

const remoteIdentifier = Utils.generateUuid()
const tokenOrError = await application.apiService.createUserFileValetToken(remoteIdentifier, 'write')

expect(isClientDisplayableError(tokenOrError)).to.equal(true)
})

it('creating two upload sessions successively should succeed - @paidfeature', async function () {
it('creating two upload sessions successively should succeed', async function () {
await setup({ fakeCrypto: true, subscription: true })

const firstToken = await application.apiService.createUserFileValetToken(Utils.generateUuid(), 'write')
Expand All @@ -107,7 +95,7 @@ describe('files', function () {
expect(secondSession.uploadId).to.be.ok
})

it('should encrypt and upload small file - @paidfeature', async function () {
it('should encrypt and upload small file', async function () {
await setup({ fakeCrypto: false, subscription: true })

const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
Expand All @@ -120,7 +108,7 @@ describe('files', function () {
expect(downloadedBytes).to.eql(buffer)
})

it('should encrypt and upload big file - @paidfeature', async function () {
it('should encrypt and upload big file', async function () {
await setup({ fakeCrypto: false, subscription: true })

const response = await fetch('/packages/snjs/mocha/assets/two_mb_file.md')
Expand All @@ -133,7 +121,7 @@ describe('files', function () {
expect(downloadedBytes).to.eql(buffer)
})

it('should delete file - @paidfeature', async function () {
it('should delete file', async function () {
await setup({ fakeCrypto: false, subscription: true })

const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
Expand Down
53 changes: 36 additions & 17 deletions packages/snjs/mocha/lib/AppContext.js
Expand Up @@ -3,6 +3,7 @@ import * as Applications from './Applications.js'
import * as Utils from './Utils.js'
import * as Defaults from './Defaults.js'
import * as Events from './Events.js'
import * as HomeServer from './HomeServer.js'
import { createNotePayload } from './Items.js'

UuidGenerator.SetGenerator(new FakeWebCrypto().generateUUID)
Expand Down Expand Up @@ -597,23 +598,41 @@ export class AppContext {
console.warn('Anticipating a console error with message:', message)
}

async publicMockSubscriptionPurchaseEvent() {
await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: this.email,
subscriptionId: GlobalSubscriptionIdCounter++,
subscriptionName: 'PRO_PLAN',
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 1,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.0,
})
async activatePaidSubscriptionForUser(options = {}) {
const dateInAnHour = new Date()
dateInAnHour.setHours(dateInAnHour.getHours() + 1)

options.expiresAt = options.expiresAt || dateInAnHour
options.subscriptionPlanName = options.subscriptionPlanName || 'PRO_PLAN'

try {
await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: this.email,
subscriptionId: GlobalSubscriptionIdCounter++,
subscriptionName: options.subscriptionPlanName,
subscriptionExpiresAt: options.expiresAt.getTime() * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 1,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.0,
})

await Utils.sleep(2)
} catch (error) {
console.warn(`Mock events service not available. You are probalby running a test suite for home server: ${error.message}`)
}

try {
await HomeServer.activatePremiumFeatures(this.email, options.subscriptionPlanName, options.expiresAt)

await Utils.sleep(2)
await Utils.sleep(1)
} catch (error) {
console.warn(`Home server not available. You are probalby running a test suite for self hosted setup: ${error.message}`)
}
}
}
6 changes: 1 addition & 5 deletions packages/snjs/mocha/lib/Events.js
@@ -1,7 +1,7 @@
import * as Defaults from './Defaults.js'

export async function publishMockedEvent(eventType, eventPayload) {
const response = await fetch(`${Defaults.getDefaultMockedEventServiceUrl()}/events`, {
await fetch(`${Defaults.getDefaultMockedEventServiceUrl()}/events`, {
method: 'POST',
headers: {
Accept: 'application/json',
Expand All @@ -12,8 +12,4 @@ export async function publishMockedEvent(eventType, eventPayload) {
eventPayload,
}),
})

if (!response.ok) {
console.error(`Failed to publish mocked event: ${response.status} ${response.statusText}`)
}
}
16 changes: 16 additions & 0 deletions packages/snjs/mocha/lib/HomeServer.js
@@ -0,0 +1,16 @@
import * as Defaults from './Defaults.js'

export async function activatePremiumFeatures(username, subscriptionPlanName, endsAt) {
await fetch(`${Defaults.getDefaultHost()}/e2e/activate-premium`, {
method: 'POST',
headers: {
Accept: 'application/json',
'Content-Type': 'application/json',
},
body: JSON.stringify({
username,
subscriptionPlanName,
endsAt,
}),
})
}
72 changes: 7 additions & 65 deletions packages/snjs/mocha/settings.test.js
Expand Up @@ -134,50 +134,19 @@ describe('settings service', function () {
expect(settings.getSettingValue(SettingName.create(SettingName.NAMES.MfaSecret).getValue())).to.not.be.ok
})

it('reads a subscription setting - @paidfeature', async () => {
await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: context.email,
subscriptionId: subscriptionId++,
subscriptionName: 'PRO_PLAN',
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 1,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.0,
})

await Factory.sleep(2)
it('reads a subscription setting', async () => {
await context.activatePaidSubscriptionForUser()

const setting = await application.settings.getSubscriptionSetting(
SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue(),
SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
)
expect(setting).to.be.a('string')
})

it('persist irreplaceable subscription settings between subsequent subscriptions - @paidfeature', async () => {
it('persist irreplaceable subscription settings between subsequent subscriptions', async () => {
await reInitializeApplicationWithRealCrypto()

await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: context.email,
subscriptionId: subscriptionId,
subscriptionName: 'PRO_PLAN',
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 1,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.0,
})
await Factory.sleep(1)
await context.activatePaidSubscriptionForUser()

const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
const buffer = new Uint8Array(await response.arrayBuffer())
Expand All @@ -189,42 +158,15 @@ describe('settings service', function () {
const limitSettingBefore = await application.settings.getSubscriptionSetting(
SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue(),
)
expect(limitSettingBefore).to.equal('107374182400')

const usedSettingBefore = await application.settings.getSubscriptionSetting(
SettingName.create(SettingName.NAMES.FileUploadBytesUsed).getValue(),
)
expect(usedSettingBefore).to.equal('196')

await Events.publishMockedEvent('SUBSCRIPTION_EXPIRED', {
userEmail: context.email,
subscriptionId: subscriptionId++,
subscriptionName: 'PRO_PLAN',
timestamp: Date.now(),
offline: false,
totalActiveSubscriptionsCount: 1,
userExistingSubscriptionsCount: 1,
billingFrequency: 12,
payAmount: 59.0,
})
await Factory.sleep(1)
await context.activatePaidSubscriptionForUser()

await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: context.email,
subscriptionId: subscriptionId++,
subscriptionName: 'PRO_PLAN',
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: false,
totalActiveSubscriptionsCount: 2,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.0,
})
await Factory.sleep(1)
await context.activatePaidSubscriptionForUser()

const limitSettingAfter = await application.settings.getSubscriptionSetting(
SettingName.create(SettingName.NAMES.FileUploadBytesLimit).getValue(),
Expand Down
25 changes: 5 additions & 20 deletions packages/snjs/mocha/subscriptions.test.js
Expand Up @@ -32,25 +32,10 @@ describe('subscriptions', function () {
password: context.password,
})

await Events.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
userEmail: context.email,
subscriptionId: subscriptionId++,
subscriptionName: 'PRO_PLAN',
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
timestamp: Date.now(),
offline: false,
discountCode: null,
limitedDiscountPurchased: false,
newSubscriber: true,
totalActiveSubscriptionsCount: 1,
userRegisteredAt: 1,
billingFrequency: 12,
payAmount: 59.00
})
await Factory.sleep(2)
await context.activatePaidSubscriptionForUser()
})

it('should invite a user by email to a shared subscription - @paidfeature', async () => {
it('should invite a user by email to a shared subscription', async () => {
await subscriptionManager.inviteToSubscription('test@test.te')

const existingInvites = await subscriptionManager.listSubscriptionInvitations()
Expand All @@ -60,7 +45,7 @@ describe('subscriptions', function () {
expect(newlyCreatedInvite.status).to.equal('sent')
})

it('should not invite a user by email if the limit of shared subscription is breached - @paidfeature', async () => {
it('should not invite a user by email if the limit of shared subscription is breached', async () => {
await subscriptionManager.inviteToSubscription('test1@test.te')
await subscriptionManager.inviteToSubscription('test2@test.te')
await subscriptionManager.inviteToSubscription('test3@test.te')
Expand All @@ -78,7 +63,7 @@ describe('subscriptions', function () {
expect(existingInvites.length).to.equal(5)
})

it('should cancel a user invitation to a shared subscription - @paidfeature', async () => {
it('should cancel a user invitation to a shared subscription', async () => {
await subscriptionManager.inviteToSubscription('test@test.te')
await subscriptionManager.inviteToSubscription('test2@test.te')

Expand All @@ -97,7 +82,7 @@ describe('subscriptions', function () {
expect(existingInvites.filter(invite => invite.status === 'canceled').length).to.equal(1)
})

it('should invite a user by email if the limit of shared subscription is restored - @paidfeature', async () => {
it('should invite a user by email if the limit of shared subscription is restored', async () => {
await subscriptionManager.inviteToSubscription('test1@test.te')
await subscriptionManager.inviteToSubscription('test2@test.te')
await subscriptionManager.inviteToSubscription('test3@test.te')
Expand Down
6 changes: 1 addition & 5 deletions packages/snjs/mocha/test.html
Expand Up @@ -27,16 +27,12 @@

const urlParams = new URLSearchParams(window.location.search);
const bail = urlParams.get('bail') === 'false' ? false : true;
const skipPaidFeatures = urlParams.get('skip_paid_features') === 'true' ? true : false;

mocha.setup({
ui: 'bdd',
timeout: 5000,
bail: bail,
});
if (skipPaidFeatures) {
mocha.grep('@paidfeature').invert();
}
</script>

<script type="module">
Expand Down Expand Up @@ -81,4 +77,4 @@
<div id="mocha"></div>
</body>

</html>
</html>
2 changes: 1 addition & 1 deletion packages/snjs/mocha/vaults/files.test.js
Expand Up @@ -25,7 +25,7 @@ describe('shared vault files', function () {
await context.register()

vaults = context.vaults
await context.publicMockSubscriptionPurchaseEvent()
await context.activatePaidSubscriptionForUser()
})

describe('private vaults', () => {
Expand Down