Skip to content

Commit 7c78fc7

Browse files
committed
Use response.ok, which is handled in tests, fixed some errors
1 parent 274386f commit 7c78fc7

File tree

7 files changed

+80
-84
lines changed

7 files changed

+80
-84
lines changed

src/app/helpers/tag-manager.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
import accountsModel from '~/models/accounts-model';
33
const tagManagerID = 'GTM-W6N7PB';
44

5-
window.dataLayer = window.dataLayer || [];
5+
window.dataLayer ||= [];
66

7-
window.oxDLF = window.oxDLF || [];
7+
window.oxDLF ||= [];
88

99
// eslint-disable-next-line max-params
1010
(function (w, d, s, l, i) {

src/app/models/accounts-model.ts

Lines changed: 17 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import settings from '~/helpers/window-settings';
22

33
const accountsUrl = `${settings().accountHref}/api/user`;
44

5-
function cached<T>(fn: () => T) {
5+
function cached<T>(fn: () => T, invalidateFn: () => void) {
66
let valid = false;
77
let cachedResult: T | null = null;
88
const cachedFn = function () {
@@ -14,32 +14,12 @@ function cached<T>(fn: () => T) {
1414
};
1515

1616
cachedFn.invalidate = () => {
17+
invalidateFn();
1718
valid = false;
1819
};
1920
return cachedFn;
2021
}
2122

22-
export type SfUserModel = {
23-
id: number;
24-
uuid: string;
25-
first_name: string;
26-
last_name: string;
27-
email: string;
28-
school_name: string;
29-
self_reported_role: string;
30-
self_reported_school: string;
31-
is_not_gdpr_location: boolean;
32-
salesforce_contact_id: string;
33-
is_instructor_verification_stale: boolean;
34-
faculty_status: string;
35-
contact_infos: {
36-
type: string;
37-
value: string;
38-
is_verified: boolean;
39-
is_guessed_preferred: boolean;
40-
}[];
41-
};
42-
4323
export default {
4424
load: cached(() => {
4525
// Uncomment ONLY to TEST
@@ -82,34 +62,23 @@ export default {
8262
// ]
8363
// });
8464
// eslint-disable-next-line no-unreachable
85-
return fetch(accountsUrl, {credentials: 'include'}).then(
65+
window._OX_USER_PROMISE ||= fetch(accountsUrl, { credentials: 'include' }).then(
8666
(response) => {
87-
if (response.status === 403) {
88-
return {};
67+
if (response.ok) {
68+
return response.json().catch((error) => {
69+
throw new Error(`Failed to parse user JSON: ${error.message}`);
70+
});
71+
} else {
72+
throw new Error(`Failed to load user: HTTP ${response.status} status code`);
8973
}
90-
return response.json().then(
91-
(result) => {
92-
if (
93-
'dataLayer' in window &&
94-
window.dataLayer instanceof Array
95-
) {
96-
window.dataLayer.push({
97-
// eslint-disable-next-line camelcase
98-
faculty_status: result.faculty_status
99-
});
100-
}
101-
return result as SfUserModel;
102-
},
103-
(err: unknown) => {
104-
console.warn('No JSON in Accounts response');
105-
return {err};
106-
}
107-
);
108-
},
109-
(err: unknown) => {
110-
console.warn('"Error fetching user info"');
111-
return {err};
11274
}
11375
);
114-
})
76+
return window._OX_USER_PROMISE.then((user) => {
77+
window.dataLayer ||= [];
78+
window.dataLayer.push({
79+
faculty_status: user.faculty_status
80+
});
81+
return user;
82+
});
83+
}, () => { window._OX_USER_PROMISE = undefined; })
11584
};

src/app/models/usermodel.ts

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import {useState, useEffect} from 'react';
22
import isEqual from 'lodash/isEqual';
33
import throttle from 'lodash/throttle';
4-
import accountsModel, {SfUserModel} from './accounts-model';
4+
import accountsModel from './accounts-model';
5+
import type {AccountsUserModel} from '../../typings/accounts';
56

67
export type UserModelType = {
78
id: number;
@@ -22,12 +23,12 @@ export type UserModelType = {
2223
self_reported_school: string;
2324
is_not_gdpr_location: boolean;
2425
salesforce_contact_id: string;
25-
accountsModel: SfUserModel;
26+
accountsModel: AccountsUserModel;
2627
};
2728

2829
// eslint-disable-next-line complexity
29-
function oldUserModel(sfUserModel: SfUserModel) {
30-
if (!('id' in sfUserModel)) {
30+
function oldUserModel(accountsUserModel: AccountsUserModel) {
31+
if (!('id' in accountsUserModel)) {
3132
return {};
3233
}
3334
const findPreferredEmail = (
@@ -45,21 +46,21 @@ function oldUserModel(sfUserModel: SfUserModel) {
4546
return a;
4647
}).value;
4748
const isStudent = ['student', 'unknown_role'].includes(
48-
sfUserModel.self_reported_role
49+
accountsUserModel.self_reported_role
4950
);
5051
const isVerificationStale =
51-
!isStudent && sfUserModel.is_instructor_verification_stale;
52+
!isStudent && accountsUserModel.is_instructor_verification_stale;
5253
const isVerificationPending =
5354
!isStudent &&
54-
['pending_faculty'].includes(sfUserModel.faculty_status) &&
55+
['pending_faculty'].includes(accountsUserModel.faculty_status) &&
5556
!isVerificationStale;
5657
const groups = (function () {
5758
const result = [];
5859

5960
if (isStudent) {
6061
result.push('Student');
6162
}
62-
if (sfUserModel.faculty_status === 'confirmed_faculty') {
63+
if (accountsUserModel.faculty_status === 'confirmed_faculty') {
6364
result.push('Faculty');
6465
}
6566
return result;
@@ -69,44 +70,44 @@ function oldUserModel(sfUserModel: SfUserModel) {
6970
const pendingInstructorAccess = [
7071
'rejected_by_sheerid',
7172
'pending_faculty'
72-
].includes(sfUserModel.faculty_status);
73-
const incompleteSignup = sfUserModel.faculty_status === 'incomplete_signup';
74-
const emailUnverified = !sfUserModel.contact_infos.some(
73+
].includes(accountsUserModel.faculty_status);
74+
const incompleteSignup = accountsUserModel.faculty_status === 'incomplete_signup';
75+
const emailUnverified = !accountsUserModel.contact_infos.some(
7576
(i) => i.is_verified
7677
);
77-
const instructorEligible = sfUserModel.faculty_status === 'no_faculty_info';
78+
const instructorEligible = accountsUserModel.faculty_status === 'no_faculty_info';
7879

7980
/* eslint camelcase: 0 */
8081
return {
81-
id: sfUserModel.id,
82-
accounts_id: sfUserModel.id,
83-
uuid: sfUserModel.uuid,
84-
email: sfUserModel.contact_infos.length
85-
? findPreferredEmail(sfUserModel.contact_infos)
82+
id: accountsUserModel.id,
83+
accounts_id: accountsUserModel.id,
84+
uuid: accountsUserModel.uuid,
85+
email: accountsUserModel.contact_infos.length
86+
? findPreferredEmail(accountsUserModel.contact_infos)
8687
: undefined,
87-
first_name: sfUserModel.first_name,
88+
first_name: accountsUserModel.first_name,
8889
groups,
89-
last_name: sfUserModel.last_name,
90+
last_name: accountsUserModel.last_name,
9091
instructorEligible,
9192
pending_verification: isVerificationPending,
9293
stale_verification: isVerificationStale,
9394
incompleteSignup,
9495
pendingInstructorAccess,
9596
emailUnverified,
96-
username: sfUserModel.id,
97-
self_reported_role: sfUserModel.self_reported_role,
98-
self_reported_school: sfUserModel.self_reported_school,
99-
is_not_gdpr_location: sfUserModel.is_not_gdpr_location,
100-
salesforce_contact_id: sfUserModel.salesforce_contact_id,
101-
accountsModel: sfUserModel
97+
username: accountsUserModel.id,
98+
self_reported_role: accountsUserModel.self_reported_role,
99+
self_reported_school: accountsUserModel.self_reported_school,
100+
is_not_gdpr_location: accountsUserModel.is_not_gdpr_location,
101+
salesforce_contact_id: accountsUserModel.salesforce_contact_id,
102+
accountsModel: accountsUserModel
102103
} as const;
103104
}
104105

105106
const userModel = {
106107
load() {
107108
return accountsModel
108109
.load()
109-
?.then((sfModel) => oldUserModel(sfModel as SfUserModel));
110+
?.then((accountsUserModel) => oldUserModel(accountsUserModel as AccountsUserModel));
110111
}
111112
};
112113

src/app/pages/details/common/get-this-title-files/give-before-pdf/give-before-pdf.tsx

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -87,11 +87,10 @@ function GiveBeforePdfAfterConditionals({
8787
});
8888

8989
React.useEffect(() => {
90-
if ('dataLayer' in window) {
91-
(window.dataLayer as Array<object>).push({
92-
event: 'optimize.giveBeforePdf'
93-
});
94-
}
90+
window.dataLayer ||= [];
91+
window.dataLayer.push({
92+
event: 'optimize.giveBeforePdf'
93+
});
9594
});
9695

9796
const closeAfterDelay = React.useCallback(

src/index.html

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
<script>
2828
window._OX_USER_PROMISE ||= fetch('/accounts/api/user?always_200=true', { credentials: 'include' }).then(
2929
(response) => {
30-
if (response.status === 200) {
30+
if (response.ok) {
3131
return response.json().catch((error) => {
3232
throw new Error(`Failed to parse user JSON: ${error.message}`);
3333
});
@@ -46,7 +46,7 @@
4646
method: 'PUT',
4747
}).then(
4848
(response) => {
49-
if (response.status === 200) {
49+
if (response.ok) {
5050
window.location.reload();
5151
} else {
5252
throw new Error(`Failed to save cookie consent: HTTP ${response.status} status code`);
@@ -57,7 +57,6 @@
5757
};
5858

5959
document.addEventListener('cookieyes_banner_load', async(eventData) => {
60-
const user = userResponse.status === 200 ? await userResponse.json() : undefined;
6160
const userConsentPreferences = user?.consent_preferences;
6261

6362
if (userConsentPreferences) {

src/typings/accounts.d.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
export type AccountsUserModel = {
2+
id: number;
3+
uuid: string;
4+
first_name: string;
5+
last_name: string;
6+
email: string;
7+
school_name: string;
8+
self_reported_role: string;
9+
self_reported_school: string;
10+
is_not_gdpr_location: boolean;
11+
salesforce_contact_id: string;
12+
is_instructor_verification_stale: boolean;
13+
faculty_status: string;
14+
contact_infos: {
15+
type: string;
16+
value: string;
17+
is_verified: boolean;
18+
is_guessed_preferred: boolean;
19+
}[];
20+
};

src/typings/global.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import type { AccountsUserModel } from './accounts';
2+
3+
declare global {
4+
interface Window {
5+
_OX_USER_PROMISE?: Promise<AccountsUserModel>;
6+
dataLayer?: object[];
7+
}
8+
}

0 commit comments

Comments
 (0)