Skip to content

Commit d3f2407

Browse files
committed
update subscription tests
1 parent 786f22f commit d3f2407

File tree

8 files changed

+85
-71
lines changed

8 files changed

+85
-71
lines changed

__test__/unit/models/deliveryPlatformKind.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import { DeliveryPlatformKind } from '../../../src/shared/models/DeliveryPlatfor
33
describe('DeliveryPlatformKind', () => {
44
test('delivery platform constants should be correct', async () => {
55
expect(DeliveryPlatformKind.ChromeLike).toBe(5);
6-
expect(DeliveryPlatformKind.SafariLegacy).toBe(7);
76
expect(DeliveryPlatformKind.Firefox).toBe(8);
87
expect(DeliveryPlatformKind.Email).toBe(11);
98
expect(DeliveryPlatformKind.Edge).toBe(12);

src/global.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ declare global {
99
OneSignal: _OneSignal;
1010
OneSignalDeferred?: OneSignalDeferredLoadedCallback[];
1111
__oneSignalSdkLoadCount?: number;
12-
safari?: {};
12+
safari?: {
13+
pushNotification?: {};
14+
};
1315
}
1416
}

src/page/userModel/FuturePushSubscriptionRecord.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -37,10 +37,7 @@ export default class FuturePushSubscriptionRecord implements Serializable {
3737
}
3838

3939
private _getToken(subscription: RawPushSubscription): string | undefined {
40-
if (subscription.w3cEndpoint) {
41-
return subscription.w3cEndpoint.toString();
42-
}
43-
return subscription.safariDeviceToken;
40+
return subscription.w3cEndpoint?.toString();
4441
}
4542

4643
serialize() {

src/page/utils/BrowserSupportsPush.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,16 @@
66
// Checks if the browser supports push notifications by checking if specific
77
// classes and properties on them exist
88
export function isPushNotificationsSupported() {
9-
return supportsVapidPush();
9+
return supportsVapidPush() || supportsSafariLegacyPush();
10+
}
11+
12+
// Allow app to run with legacy safari push notifications. If safari version is newer then
13+
// the subscription will ported in SubscriptionManager _updatePushSubscriptionModelWithRawSubscription
14+
export function supportsSafariLegacyPush(): boolean {
15+
return (
16+
typeof window.safari !== 'undefined' &&
17+
typeof window.safari.pushNotification !== 'undefined'
18+
);
1019
}
1120

1221
// Does the browser support the standard Push API

src/shared/helpers/EventHelper.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ export default class EventHelper {
2727
}
2828

2929
static async checkAndTriggerSubscriptionChanged() {
30-
console.log('checkAndTriggerSubscriptionChanged');
3130
OneSignalUtils.logMethodCall('checkAndTriggerSubscriptionChanged');
3231
const context: ContextSWInterface = OneSignal.context;
3332
// isPushEnabled = subscribed && is not opted out
Lines changed: 68 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
import { APP_ID, DUMMY_EXTERNAL_ID } from '__test__/support/constants';
22
import TestContext from '__test__/support/environment/TestContext';
33
import { TestEnvironment } from '__test__/support/environment/TestEnvironment';
4-
import { setupSubModelStore } from '__test__/support/environment/TestEnvironmentHelpers';
54
import {
6-
createUserFn,
7-
setCreateUserResponse,
8-
} from '__test__/support/helpers/requests';
5+
mockUserAgent,
6+
setupSubModelStore,
7+
} from '__test__/support/environment/TestEnvironmentHelpers';
98
import {
109
getSubscriptionFn,
1110
MockServiceWorker,
1211
} from '__test__/support/mocks/MockServiceWorker';
12+
import BrowserUserAgent from '__test__/support/models/BrowserUserAgent';
13+
import { SubscriptionType } from 'src/core/types/subscription';
14+
import UserDirector from 'src/onesignal/UserDirector';
1315
import ContextSW from '../models/ContextSW';
1416
import { RawPushSubscription } from '../models/RawPushSubscription';
17+
import Database from '../services/Database';
1518
import { IDManager } from './IDManager';
1619
import {
1720
SubscriptionManager,
@@ -29,19 +32,24 @@ const getRawSubscription = (): RawPushSubscription => {
2932
rawSubscription.w3cAuth = 'auth';
3033
rawSubscription.w3cP256dh = 'p256dh';
3134
rawSubscription.w3cEndpoint = new URL('https://example.com/endpoint');
35+
// @ts-expect-error - legacy property
3236
rawSubscription.safariDeviceToken = 'safariDeviceToken';
3337
return rawSubscription;
3438
};
3539

40+
const createUserOnServerSpy = vi
41+
.spyOn(UserDirector, 'createUserOnServer')
42+
.mockResolvedValue();
43+
3644
describe('SubscriptionManager', () => {
3745
beforeEach(async () => {
3846
vi.resetModules();
3947
await TestEnvironment.initialize();
48+
await Database.clear();
4049
});
4150

4251
describe('updatePushSubscriptionModelWithRawSubscription', () => {
4352
test('should create the push subscription model if it does not exist', async () => {
44-
setCreateUserResponse();
4553
const context = new ContextSW(TestContext.getFakeMergedConfig());
4654
const subscriptionManager = new SubscriptionManager(context, subConfig);
4755
const rawSubscription = getRawSubscription();
@@ -55,17 +63,15 @@ describe('SubscriptionManager', () => {
5563
token: rawSubscription.w3cEndpoint?.toString(),
5664
});
5765

66+
// @ts-expect-error - private method
5867
await subscriptionManager._updatePushSubscriptionModelWithRawSubscription(
5968
rawSubscription,
6069
);
6170

6271
subModels = await OneSignal.coreDirector.subscriptionModelStore.list();
6372
expect(subModels.length).toBe(1);
6473

65-
const id = subModels[0].id;
66-
expect(IDManager.isLocalId(id)).toBe(true);
6774
expect(subModels[0].toJSON()).toEqual({
68-
id,
6975
device_model: '',
7076
device_os: 56,
7177
enabled: true,
@@ -77,28 +83,7 @@ describe('SubscriptionManager', () => {
7783
web_p256: rawSubscription.w3cP256dh,
7884
});
7985

80-
await vi.waitUntil(() => createUserFn.mock.calls.length > 0);
81-
expect(createUserFn).toHaveBeenCalledWith({
82-
identity: {},
83-
properties: {
84-
language: 'en',
85-
timezone_id: 'America/Los_Angeles',
86-
},
87-
refresh_device_metadata: true,
88-
subscriptions: [
89-
{
90-
device_model: '',
91-
device_os: 56,
92-
enabled: true,
93-
notification_types: 1,
94-
sdk: '1',
95-
token: rawSubscription.w3cEndpoint?.toString(),
96-
type: 'ChromePush',
97-
web_auth: rawSubscription.w3cAuth,
98-
web_p256: rawSubscription.w3cP256dh,
99-
},
100-
],
101-
});
86+
expect(createUserOnServerSpy).toHaveBeenCalled();
10287
});
10388

10489
test('should create user if push subscription model does not have an id', async () => {
@@ -110,9 +95,6 @@ describe('SubscriptionManager', () => {
11095
getSubscriptionFn.mockResolvedValue({
11196
endpoint: rawSubscription.w3cEndpoint?.toString(),
11297
});
113-
setCreateUserResponse({
114-
externalId: 'some-external-id',
115-
});
11698

11799
const context = new ContextSW(TestContext.getFakeMergedConfig());
118100
const subscriptionManager = new SubscriptionManager(context, subConfig);
@@ -128,38 +110,17 @@ describe('SubscriptionManager', () => {
128110
onesignalId: identityModel.onesignalId,
129111
});
130112

113+
// @ts-expect-error - private method
131114
await subscriptionManager._updatePushSubscriptionModelWithRawSubscription(
132115
rawSubscription,
133116
);
134117

135118
// should not call generatePushSubscriptionModelSpy
136119
expect(generatePushSubscriptionModelSpy).not.toHaveBeenCalled();
137-
138-
expect(createUserFn).toHaveBeenCalledWith({
139-
identity: {
140-
external_id: 'some-external-id',
141-
},
142-
properties: {
143-
language: 'en',
144-
timezone_id: 'America/Los_Angeles',
145-
},
146-
refresh_device_metadata: true,
147-
subscriptions: [
148-
{
149-
device_model: '',
150-
device_os: 56,
151-
enabled: true,
152-
notification_types: 1,
153-
sdk: '1',
154-
token: rawSubscription.w3cEndpoint?.toString(),
155-
type: 'ChromePush',
156-
},
157-
],
158-
});
120+
expect(createUserOnServerSpy).toHaveBeenCalled();
159121
});
160122

161123
test('should update the push subscription model if it already exists', async () => {
162-
setCreateUserResponse();
163124
const context = new ContextSW(TestContext.getFakeMergedConfig());
164125
const subscriptionManager = new SubscriptionManager(context, subConfig);
165126
const rawSubscription = getRawSubscription();
@@ -176,6 +137,7 @@ describe('SubscriptionManager', () => {
176137
pushModel.web_auth = 'old-web-auth';
177138
pushModel.web_p256 = 'old-web-p256';
178139

140+
// @ts-expect-error - private method
179141
await subscriptionManager._updatePushSubscriptionModelWithRawSubscription(
180142
rawSubscription,
181143
);
@@ -188,10 +150,60 @@ describe('SubscriptionManager', () => {
188150
expect(updatedPushModel.web_auth).toBe(rawSubscription.w3cAuth);
189151
expect(updatedPushModel.web_p256).toBe(rawSubscription.w3cP256dh);
190152
});
153+
154+
test('should port legacy safari push to new format', async () => {
155+
const rawSubscription = getRawSubscription();
156+
getSubscriptionFn.mockResolvedValue({
157+
endpoint: rawSubscription.w3cEndpoint?.toString(),
158+
});
159+
160+
const context = new ContextSW(TestContext.getFakeMergedConfig());
161+
const subscriptionManager = new SubscriptionManager(context, subConfig);
162+
163+
// setting up legacy push model
164+
await OneSignal.database.setTokenAndId({
165+
token: 'old-token',
166+
});
167+
const pushModel = await setupSubModelStore({
168+
id: '123',
169+
token: 'old-token',
170+
onesignalId: DUMMY_EXTERNAL_ID,
171+
});
172+
pushModel.type = SubscriptionType.SafariLegacyPush;
173+
174+
// mock agent to safari with vapid push support
175+
mockUserAgent({
176+
userAgent: BrowserUserAgent.SafariSupportedMac121,
177+
});
178+
179+
// @ts-expect-error - private method
180+
await subscriptionManager._updatePushSubscriptionModelWithRawSubscription(
181+
rawSubscription,
182+
);
183+
184+
// should update push model with new token, type, web_auth, and web_p256
185+
const updatedPushModel =
186+
(await OneSignal.coreDirector.getPushSubscriptionModel())!;
187+
expect(updatedPushModel.type).toBe(SubscriptionType.SafariPush);
188+
expect(updatedPushModel.token).toBe(
189+
rawSubscription.w3cEndpoint!.toString(),
190+
);
191+
expect(updatedPushModel.web_auth).toBe(rawSubscription.w3cAuth);
192+
expect(updatedPushModel.web_p256).toBe(rawSubscription.w3cP256dh);
193+
});
191194
});
192195
});
193196

194197
Object.defineProperty(global.navigator, 'serviceWorker', {
195198
value: new MockServiceWorker(),
196199
writable: true,
197200
});
201+
202+
Object.defineProperty(global, 'PushSubscriptionOptions', {
203+
value: {
204+
prototype: {
205+
applicationServerKey: 'test',
206+
},
207+
},
208+
writable: true,
209+
});

src/shared/managers/SubscriptionManager.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import PushPermissionNotGrantedError, {
1515
PushPermissionNotGrantedErrorReason,
1616
} from '../errors/PushPermissionNotGrantedError';
1717
import ServiceWorkerRegistrationError from '../errors/ServiceWorkerRegistrationError';
18+
import Environment from '../helpers/Environment';
1819
import { ServiceWorkerActiveState } from '../helpers/ServiceWorkerHelper';
1920
import Log from '../libraries/Log';
2021
import { ContextSWInterface } from '../models/ContextSW';
@@ -153,11 +154,7 @@ export class SubscriptionManager {
153154
private async _updatePushSubscriptionModelWithRawSubscription(
154155
rawPushSubscription: RawPushSubscription,
155156
) {
156-
console.log('updatePushSubscriptionModelWithRawSubscription', {
157-
rawPushSubscription,
158-
});
159157
const pushModel = await OneSignal.coreDirector.getPushSubscriptionModel();
160-
console.log('pushModel', { pushModel });
161158

162159
// EventHelper checkAndTriggerSubscriptionChanged is called before this function when permission is granted and so
163160
// it will save the push token/id to the database so we don't need to save the token afer generating
@@ -176,12 +173,11 @@ export class SubscriptionManager {
176173

177174
// for legacy safari push, switch to new format (e.g. old token 'ebsm3...' to -> https://web.push.apple.com/... with populated web_auth and web_p256)
178175
if (pushModel.type === SubscriptionType.SafariLegacyPush) {
179-
if (!window.Notification) return;
176+
if (!Environment.useSafariVapidPush()) return;
180177
await Database.setTokenAndId({
181178
token: serializedSubscriptionRecord.token,
182179
id: pushModel.id,
183180
});
184-
pushModel.setProperty('type', SubscriptionType.SafariPush);
185181
}
186182

187183
// update existing push subscription model

vitest.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { defineConfig } from 'vitest/config';
44
export default defineConfig({
55
define: {
66
__API_ORIGIN__: JSON.stringify('onesignal.com'),
7-
__API_TYPE__: JSON.stringify('staging'),
7+
__API_TYPE__: JSON.stringify('production'),
88
__BUILD_ORIGIN__: JSON.stringify('onesignal.com'),
99
__BUILD_TYPE__: JSON.stringify('production'),
1010
__IS_HTTPS__: JSON.stringify(true),

0 commit comments

Comments
 (0)