feat(snjs): add e2e test for subsequent subscriptions settings persistance
This commit is contained in:
@@ -1,5 +1,7 @@
|
|||||||
import * as Factory from './lib/factory.js'
|
import * as Factory from './lib/factory.js'
|
||||||
import * as Utils from './lib/Utils.js'
|
import * as Utils from './lib/Utils.js'
|
||||||
|
import * as Files from './lib/Files.js'
|
||||||
|
|
||||||
chai.use(chaiAsPromised)
|
chai.use(chaiAsPromised)
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
@@ -52,38 +54,6 @@ describe('files', function () {
|
|||||||
localStorage.clear()
|
localStorage.clear()
|
||||||
})
|
})
|
||||||
|
|
||||||
const uploadFile = async (fileService, buffer, name, ext, chunkSize) => {
|
|
||||||
const operation = await fileService.beginNewFileUpload(buffer.byteLength)
|
|
||||||
|
|
||||||
let chunkId = 1
|
|
||||||
for (let i = 0; i < buffer.length; i += chunkSize) {
|
|
||||||
const readUntil = i + chunkSize > buffer.length ? buffer.length : i + chunkSize
|
|
||||||
const chunk = buffer.slice(i, readUntil)
|
|
||||||
const isFinalChunk = readUntil === buffer.length
|
|
||||||
|
|
||||||
const error = await fileService.pushBytesForUpload(operation, chunk, chunkId++, isFinalChunk)
|
|
||||||
if (error) {
|
|
||||||
throw new Error('Could not upload file chunk')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const file = await fileService.finishUpload(operation, name, ext)
|
|
||||||
|
|
||||||
return file
|
|
||||||
}
|
|
||||||
|
|
||||||
const downloadFile = async (fileService, itemManager, remoteIdentifier) => {
|
|
||||||
const file = itemManager.getItems(ContentType.File).find((file) => file.remoteIdentifier === remoteIdentifier)
|
|
||||||
|
|
||||||
let receivedBytes = new Uint8Array()
|
|
||||||
|
|
||||||
await fileService.downloadFile(file, (decryptedBytes) => {
|
|
||||||
receivedBytes = new Uint8Array([...receivedBytes, ...decryptedBytes])
|
|
||||||
})
|
|
||||||
|
|
||||||
return receivedBytes
|
|
||||||
}
|
|
||||||
|
|
||||||
it('should create valet token from server', async function () {
|
it('should create valet token from server', async function () {
|
||||||
await setup({ fakeCrypto: true, subscription: true })
|
await setup({ fakeCrypto: true, subscription: true })
|
||||||
const remoteIdentifier = Utils.generateUuid()
|
const remoteIdentifier = Utils.generateUuid()
|
||||||
@@ -141,9 +111,9 @@ describe('files', function () {
|
|||||||
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||||
|
|
||||||
const file = await uploadFile(fileService, buffer, 'my-file', 'md', 1000)
|
const file = await Files.uploadFile(fileService, buffer, 'my-file', 'md', 1000)
|
||||||
|
|
||||||
const downloadedBytes = await downloadFile(fileService, itemManager, file.remoteIdentifier)
|
const downloadedBytes = await Files.downloadFile(fileService, itemManager, file.remoteIdentifier)
|
||||||
|
|
||||||
expect(downloadedBytes).to.eql(buffer)
|
expect(downloadedBytes).to.eql(buffer)
|
||||||
})
|
})
|
||||||
@@ -154,9 +124,9 @@ describe('files', function () {
|
|||||||
const response = await fetch('/packages/snjs/mocha/assets/two_mb_file.md')
|
const response = await fetch('/packages/snjs/mocha/assets/two_mb_file.md')
|
||||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||||
|
|
||||||
const file = await uploadFile(fileService, buffer, 'my-file', 'md', 100000)
|
const file = await Files.uploadFile(fileService, buffer, 'my-file', 'md', 100000)
|
||||||
|
|
||||||
const downloadedBytes = await downloadFile(fileService, itemManager, file.remoteIdentifier)
|
const downloadedBytes = await Files.downloadFile(fileService, itemManager, file.remoteIdentifier)
|
||||||
|
|
||||||
expect(downloadedBytes).to.eql(buffer)
|
expect(downloadedBytes).to.eql(buffer)
|
||||||
})
|
})
|
||||||
@@ -167,7 +137,7 @@ describe('files', function () {
|
|||||||
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||||
const buffer = new Uint8Array(await response.arrayBuffer())
|
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||||
|
|
||||||
const file = await uploadFile(fileService, buffer, 'my-file', 'md', 1000)
|
const file = await Files.uploadFile(fileService, buffer, 'my-file', 'md', 1000)
|
||||||
|
|
||||||
const error = await fileService.deleteFile(file)
|
const error = await fileService.deleteFile(file)
|
||||||
|
|
||||||
|
|||||||
31
packages/snjs/mocha/lib/Files.js
Normal file
31
packages/snjs/mocha/lib/Files.js
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
export async function uploadFile(fileService, buffer, name, ext, chunkSize) {
|
||||||
|
const operation = await fileService.beginNewFileUpload(buffer.byteLength)
|
||||||
|
|
||||||
|
let chunkId = 1
|
||||||
|
for (let i = 0; i < buffer.length; i += chunkSize) {
|
||||||
|
const readUntil = i + chunkSize > buffer.length ? buffer.length : i + chunkSize
|
||||||
|
const chunk = buffer.slice(i, readUntil)
|
||||||
|
const isFinalChunk = readUntil === buffer.length
|
||||||
|
|
||||||
|
const error = await fileService.pushBytesForUpload(operation, chunk, chunkId++, isFinalChunk)
|
||||||
|
if (error) {
|
||||||
|
throw new Error('Could not upload file chunk')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const file = await fileService.finishUpload(operation, name, ext)
|
||||||
|
|
||||||
|
return file
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function downloadFile(fileService, itemManager, remoteIdentifier) {
|
||||||
|
const file = itemManager.getItems(ContentType.File).find((file) => file.remoteIdentifier === remoteIdentifier)
|
||||||
|
|
||||||
|
let receivedBytes = new Uint8Array()
|
||||||
|
|
||||||
|
await fileService.downloadFile(file, (decryptedBytes) => {
|
||||||
|
receivedBytes = new Uint8Array([...receivedBytes, ...decryptedBytes])
|
||||||
|
})
|
||||||
|
|
||||||
|
return receivedBytes
|
||||||
|
}
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
import * as Factory from './lib/factory.js'
|
import * as Factory from './lib/factory.js'
|
||||||
|
import * as Files from './lib/Files.js'
|
||||||
|
|
||||||
chai.use(chaiAsPromised)
|
chai.use(chaiAsPromised)
|
||||||
const expect = chai.expect
|
const expect = chai.expect
|
||||||
|
|
||||||
describe('settings service', function () {
|
describe('settings service', function () {
|
||||||
|
this.timeout(Factory.TwentySecondTimeout)
|
||||||
|
|
||||||
const validSetting = SettingName.GoogleDriveBackupFrequency
|
const validSetting = SettingName.GoogleDriveBackupFrequency
|
||||||
const fakePayload = 'Im so meta even this acronym'
|
const fakePayload = 'Im so meta even this acronym'
|
||||||
const updatedFakePayload = 'is meta'
|
const updatedFakePayload = 'is meta'
|
||||||
|
|
||||||
let application
|
let application
|
||||||
let context
|
let context
|
||||||
|
let user
|
||||||
|
|
||||||
beforeEach(async function () {
|
beforeEach(async function () {
|
||||||
context = await Factory.createAppContextWithFakeCrypto()
|
context = await Factory.createAppContextWithFakeCrypto()
|
||||||
@@ -17,13 +22,31 @@ describe('settings service', function () {
|
|||||||
|
|
||||||
application = context.application
|
application = context.application
|
||||||
|
|
||||||
await Factory.registerUserToApplication({
|
const registerResponse = await Factory.registerUserToApplication({
|
||||||
application: context.application,
|
application: context.application,
|
||||||
email: context.email,
|
email: context.email,
|
||||||
password: context.password,
|
password: context.password,
|
||||||
})
|
})
|
||||||
|
user = registerResponse.user
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const reInitializeApplicationWithRealCrypto = async () => {
|
||||||
|
await Factory.safeDeinit(application)
|
||||||
|
|
||||||
|
context = await Factory.createAppContextWithRealCrypto()
|
||||||
|
|
||||||
|
await context.launch()
|
||||||
|
|
||||||
|
application = context.application
|
||||||
|
|
||||||
|
const registerResponse = await Factory.registerUserToApplication({
|
||||||
|
application: context.application,
|
||||||
|
email: context.email,
|
||||||
|
password: context.password,
|
||||||
|
})
|
||||||
|
user = registerResponse.user
|
||||||
|
}
|
||||||
|
|
||||||
afterEach(async function () {
|
afterEach(async function () {
|
||||||
await Factory.safeDeinit(application)
|
await Factory.safeDeinit(application)
|
||||||
})
|
})
|
||||||
@@ -108,4 +131,63 @@ describe('settings service', function () {
|
|||||||
const setting = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
|
const setting = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
|
||||||
expect(setting).to.be.a('string')
|
expect(setting).to.be.a('string')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('persist irreplaceable subscription settings between subsequent subscriptions', async () => {
|
||||||
|
await reInitializeApplicationWithRealCrypto()
|
||||||
|
|
||||||
|
await Factory.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
|
||||||
|
userEmail: context.email,
|
||||||
|
subscriptionId: 1,
|
||||||
|
subscriptionName: 'PRO_PLAN',
|
||||||
|
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
offline: false,
|
||||||
|
})
|
||||||
|
await Factory.sleep(1)
|
||||||
|
|
||||||
|
const response = await fetch('/packages/snjs/mocha/assets/small_file.md')
|
||||||
|
const buffer = new Uint8Array(await response.arrayBuffer())
|
||||||
|
|
||||||
|
await Files.uploadFile(application.fileService, buffer, 'my-file', 'md', 1000)
|
||||||
|
|
||||||
|
await Factory.publishMockedEvent('FILE_UPLOADED', {
|
||||||
|
userUuid: user.uuid,
|
||||||
|
fileByteSize: 123,
|
||||||
|
filePath: 'foobar',
|
||||||
|
fileName: 'barbuzz',
|
||||||
|
})
|
||||||
|
await Factory.sleep(1)
|
||||||
|
|
||||||
|
const limitSettingBefore = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
|
||||||
|
expect(limitSettingBefore).to.equal('107374182400')
|
||||||
|
|
||||||
|
const usedSettingBefore = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_USED')
|
||||||
|
expect(usedSettingBefore).to.equal('123')
|
||||||
|
|
||||||
|
|
||||||
|
await Factory.publishMockedEvent('SUBSCRIPTION_EXPIRED', {
|
||||||
|
userEmail: context.email,
|
||||||
|
subscriptionId: 1,
|
||||||
|
subscriptionName: 'PRO_PLAN',
|
||||||
|
timestamp: Date.now(),
|
||||||
|
offline: false,
|
||||||
|
})
|
||||||
|
await Factory.sleep(1)
|
||||||
|
|
||||||
|
await Factory.publishMockedEvent('SUBSCRIPTION_PURCHASED', {
|
||||||
|
userEmail: context.email,
|
||||||
|
subscriptionId: 2,
|
||||||
|
subscriptionName: 'PRO_PLAN',
|
||||||
|
subscriptionExpiresAt: (new Date().getTime() + 3_600_000) * 1_000,
|
||||||
|
timestamp: Date.now(),
|
||||||
|
offline: false,
|
||||||
|
})
|
||||||
|
await Factory.sleep(1)
|
||||||
|
|
||||||
|
const limitSettingAfter = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_LIMIT')
|
||||||
|
expect(limitSettingAfter).to.equal(limitSettingBefore)
|
||||||
|
|
||||||
|
const usedSettingAfter = await application.settings.getSubscriptionSetting('FILE_UPLOAD_BYTES_USED')
|
||||||
|
expect(usedSettingAfter).to.equal(usedSettingBefore)
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user