fix(docs-infra): do not break when cookies are disabled in the browser (#35557)
Whenever cookies are disabled in the browser, `window.localStorage` is not avaialable to the app (i.e. even trying to access `window.localStorage` throws an error). To avoid breaking the app, we use a no-op `Storage` implementation if `window.localStorage` is not available. (This is similar to #33829, but for `localStorage` instead of `sessionStorage`.) Fixes #35555 PR Close #35557
This commit is contained in:
parent
9c01ca42d3
commit
975a11b37f
|
@ -111,6 +111,22 @@ describe('NotificationComponent', () => {
|
|||
expect(getItemSpy).toHaveBeenCalledWith('aio-notification/survey-january-2018');
|
||||
expect(component.showNotification).toBe('hide');
|
||||
});
|
||||
|
||||
it('should not break when cookies are disabled in the browser', () => {
|
||||
configTestingModule();
|
||||
|
||||
// Simulate `window.localStorage` being inaccessible, when cookies are disabled.
|
||||
const mockWindow: MockWindow = TestBed.inject(WindowToken);
|
||||
Object.defineProperty(mockWindow, 'localStorage', {
|
||||
get() { throw new Error('The operation is insecure'); },
|
||||
});
|
||||
|
||||
expect(() => createComponent()).not.toThrow();
|
||||
expect(component.showNotification).toBe('show');
|
||||
|
||||
component.dismiss();
|
||||
expect(component.showNotification).toBe('hide');
|
||||
});
|
||||
});
|
||||
|
||||
@Component({
|
||||
|
|
|
@ -20,7 +20,7 @@ const LOCAL_STORAGE_NAMESPACE = 'aio-notification/';
|
|||
]
|
||||
})
|
||||
export class NotificationComponent implements OnInit {
|
||||
private get localStorage() { return this.window.localStorage; }
|
||||
private storage: Storage;
|
||||
|
||||
@Input() dismissOnContentClick: boolean;
|
||||
@Input() notificationId: string;
|
||||
|
@ -31,12 +31,27 @@ export class NotificationComponent implements OnInit {
|
|||
showNotification: 'show'|'hide';
|
||||
|
||||
constructor(
|
||||
@Inject(WindowToken) private window: Window,
|
||||
@Inject(WindowToken) window: Window,
|
||||
@Inject(CurrentDateToken) private currentDate: Date
|
||||
) {}
|
||||
) {
|
||||
try {
|
||||
this.storage = window.localStorage;
|
||||
} catch {
|
||||
// When cookies are disabled in the browser, even trying to access
|
||||
// `window.localStorage` throws an error. Use a no-op storage.
|
||||
this.storage = {
|
||||
length: 0,
|
||||
clear: () => undefined,
|
||||
getItem: () => null,
|
||||
key: () => null,
|
||||
removeItem: () => undefined,
|
||||
setItem: () => undefined
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
ngOnInit() {
|
||||
const previouslyHidden = this.localStorage.getItem(LOCAL_STORAGE_NAMESPACE + this.notificationId) === 'hide';
|
||||
const previouslyHidden = this.storage.getItem(LOCAL_STORAGE_NAMESPACE + this.notificationId) === 'hide';
|
||||
const expired = this.currentDate > new Date(this.expirationDate);
|
||||
this.showNotification = previouslyHidden || expired ? 'hide' : 'show';
|
||||
}
|
||||
|
@ -48,7 +63,7 @@ export class NotificationComponent implements OnInit {
|
|||
}
|
||||
|
||||
dismiss() {
|
||||
this.localStorage.setItem(LOCAL_STORAGE_NAMESPACE + this.notificationId, 'hide');
|
||||
this.storage.setItem(LOCAL_STORAGE_NAMESPACE + this.notificationId, 'hide');
|
||||
this.showNotification = 'hide';
|
||||
this.dismissed.next();
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue