Skip to content

Commit

Permalink
Fix subscriptions record migration
Browse files Browse the repository at this point in the history
  • Loading branch information
shepherd-l committed Sep 12, 2024
1 parent 0f60a67 commit 6e61697
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 34 deletions.
92 changes: 69 additions & 23 deletions __test__/unit/services/indexedDb.test.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { DUMMY_EXTERNAL_ID, DUMMY_ONESIGNAL_ID } from '../../support/constants';
import {
LegacyModelName,
ModelName,
} from '../../../src/core/models/SupportedModels';
import IndexedDb from '../../../src/shared/services/IndexedDb';
import Random from '../../support/utils/Random';
import { SubscriptionType } from '../../../src/core/models/SubscriptionModels';

require('fake-indexeddb/auto');

Expand Down Expand Up @@ -128,12 +130,26 @@ describe('migrations', () => {
expect(result).toEqual({ modelId: '1' });
});

test('migrates emailSubscriptions records into subscriptions', async () => {
test('migrates v5 email, push, sms subscriptions records to v6 subscriptions record', async () => {
const dbName = 'testDbV5upgradeToV6' + Random.getRandomString(10);
const db = newOSIndexedDb(dbName, 5);
await db.put(LegacyModelName.EmailSubscriptions, {
modelId: '1',
modelName: LegacyModelName.EmailSubscriptions,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.Email,
});
await db.put(LegacyModelName.PushSubscriptions, {
modelId: '2',
modelName: LegacyModelName.PushSubscriptions,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.ChromePush,
});
await db.put(LegacyModelName.SmsSubscriptions, {
modelId: '3',
modelName: LegacyModelName.SmsSubscriptions,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.SMS,
});
db.close();

Expand All @@ -144,38 +160,53 @@ describe('migrations', () => {
modelId: '1',
modelName: ModelName.Subscriptions,
externalId: undefined,
onesignalId: undefined,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.Email,
},
]);
});

test('migrates pushSubscriptions records into subscriptions', async () => {
const dbName = 'testDbV5upgradeToV6' + Random.getRandomString(10);
const db = newOSIndexedDb(dbName, 5);
await db.put(LegacyModelName.PushSubscriptions, {
modelId: '1',
modelName: LegacyModelName.PushSubscriptions,
});
db.close();

const db2 = newOSIndexedDb(dbName, 6);
const result = await db2.getAll(ModelName.Subscriptions);
expect(result).toEqual([
{
modelId: '1',
modelId: '2',
modelName: ModelName.Subscriptions,
externalId: undefined,
onesignalId: undefined,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.ChromePush,
},
{
modelId: '3',
modelName: ModelName.Subscriptions,
externalId: undefined,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.SMS,
},
]);
});

test('migrates smsSubscriptions records into subscriptions', async () => {
test('migrates v5 email, push, sms subscriptions records of logged in user to v6 subscriptions record with external id', async () => {
const dbName = 'testDbV5upgradeToV6' + Random.getRandomString(10);
const db = newOSIndexedDb(dbName, 5);
await db.put(LegacyModelName.SmsSubscriptions, {
await db.put(LegacyModelName.EmailSubscriptions, {
modelId: '1',
modelName: LegacyModelName.EmailSubscriptions,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.Email,
});
await db.put(LegacyModelName.PushSubscriptions, {
modelId: '2',
modelName: LegacyModelName.PushSubscriptions,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.ChromePush,
});
await db.put(LegacyModelName.SmsSubscriptions, {
modelId: '3',
modelName: LegacyModelName.SmsSubscriptions,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.SMS,
});
// user is logged in
await db.put(ModelName.Identity, {
modelId: '4',
modelName: ModelName.Identity,
onesignalId: DUMMY_ONESIGNAL_ID,
externalId: DUMMY_EXTERNAL_ID,
});
db.close();

Expand All @@ -185,8 +216,23 @@ describe('migrations', () => {
{
modelId: '1',
modelName: ModelName.Subscriptions,
externalId: undefined,
onesignalId: undefined,
externalId: DUMMY_EXTERNAL_ID,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.Email,
},
{
modelId: '2',
modelName: ModelName.Subscriptions,
externalId: DUMMY_EXTERNAL_ID,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.ChromePush,
},
{
modelId: '3',
modelName: ModelName.Subscriptions,
externalId: DUMMY_EXTERNAL_ID,
onesignalId: DUMMY_ONESIGNAL_ID,
type: SubscriptionType.SMS,
},
]);
});
Expand Down
40 changes: 29 additions & 11 deletions src/shared/services/IndexedDb.ts
Original file line number Diff line number Diff line change
Expand Up @@ -265,31 +265,49 @@ export default class IndexedDb {
const newTableName = ModelName.Subscriptions;
db.createObjectStore(newTableName, { keyPath: 'modelId' });

let currentExternalId: string;
const identityCursor = transaction
.objectStore(ModelName.Identity)
.openCursor();
identityCursor.onsuccess = () => {
if (identityCursor.result) {
currentExternalId = identityCursor.result.value.externalId;
}
};
identityCursor.onerror = () => {
// If there is an error getting old records nothing we can do but
// move on. Old table will stay around so an attempt could be made
// later.
console.error(
'Could not find ' + ModelName.Identity + ' records',
identityCursor.error,
);
};

Object.values(LegacyModelName).forEach((oldTableName) => {
const cursor = transaction.objectStore(oldTableName).openCursor();
cursor.onsuccess = () => {
if (!cursor.result) {
const legacyCursor = transaction.objectStore(oldTableName).openCursor();
legacyCursor.onsuccess = () => {
if (!legacyCursor.result) {
// Delete old table once we have gone through all records
db.deleteObjectStore(oldTableName);
return;
}
const oldValue = cursor.result.value;
const oldValue = legacyCursor.result.value;

transaction.objectStore(newTableName).put({
modelId: oldValue.modelId,
...oldValue,
modelName: ModelName.Subscriptions,
onesignalId: oldValue.onesignalId,
externalId: oldValue.externalId,
data: oldValue.data,
externalId: currentExternalId,
});
cursor.result.continue();
legacyCursor.result.continue();
};
cursor.onerror = () => {
legacyCursor.onerror = () => {
// If there is an error getting old records nothing we can do but
// move on. Old table will stay around so an attempt could be made
// later.
console.error(
'Could not migrate ' + oldTableName + ' records',
cursor.error,
legacyCursor.error,
);
};
});
Expand Down

0 comments on commit 6e61697

Please sign in to comment.