mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
fix(server-storage): offline recheck checks only the instance; sign-out always navigates
The recheck on going offline ran a full refresh: when /instance answered but /user-state kept failing, each failed read set the page offline again and started the next one at once, bypassing the retry interval. It now checks the instance only; reads wait for the retry. Sign-out navigates to sign-in itself, also when the page is signed out already: a guard (unsaved Settings) may have cancelled the redirect the first time, and the state change that drives it does not repeat. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
cfda131c41
commit
52d733e1c7
3 files changed
+55
-4
No files matched your search
@@ -1,6 +1,6 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { MatSnackBar } from '@angular/material/snack-bar';
|
||||
import { provideRouter } from '@angular/router';
|
||||
import { provideRouter, Router } from '@angular/router';
|
||||
import { TranslateService } from '@ngx-translate/core';
|
||||
import { PlaylistStorageBackend } from '../playlist-storage-backend';
|
||||
import { RuntimeCapabilitiesService } from '../runtime-capabilities.service';
|
||||
@@ -187,6 +187,21 @@ describe('ServerStorageSession', () => {
|
||||
delete (document as { visibilityState?: unknown }).visibilityState;
|
||||
});
|
||||
|
||||
it('goes to sign-in on every sign-out, also when already signed out', async () => {
|
||||
const { session } = setup('none');
|
||||
await session.start();
|
||||
const navigate = jest
|
||||
.spyOn(TestBed.inject(Router), 'navigateByUrl')
|
||||
.mockResolvedValue(false);
|
||||
|
||||
session.signOut();
|
||||
// A guard kept the page (unsaved Settings); the user signs out again.
|
||||
session.signOut();
|
||||
|
||||
expect(navigate).toHaveBeenCalledTimes(2);
|
||||
expect(navigate).toHaveBeenLastCalledWith('/server-sign-in');
|
||||
});
|
||||
|
||||
describe('after losing the server', () => {
|
||||
const answer = (body: unknown) => ({
|
||||
status: 200,
|
||||
@@ -226,6 +241,30 @@ describe('ServerStorageSession', () => {
|
||||
);
|
||||
});
|
||||
|
||||
it('checks only the instance at once when it goes offline', async () => {
|
||||
const { session, status } = setup('none');
|
||||
await session.start();
|
||||
// The instance answers, its user data does not.
|
||||
fetchMock.mockImplementation(async (url: string) =>
|
||||
url.endsWith('/instance')
|
||||
? answer({ instanceId: 'i-1' })
|
||||
: { status: 503, ok: false, headers: new Headers() }
|
||||
);
|
||||
fetchMock.mockClear();
|
||||
|
||||
status.reportOffline();
|
||||
TestBed.tick();
|
||||
for (let turn = 0; turn < 10; turn += 1) {
|
||||
await Promise.resolve();
|
||||
}
|
||||
|
||||
expect(status.isVerified()).toBe(true);
|
||||
// A failing read waits for the retry interval, not a loop.
|
||||
expect(fetchMock.mock.calls.map(([url]) => url)).toEqual([
|
||||
'/api/v1/instance',
|
||||
]);
|
||||
});
|
||||
|
||||
it('reloads when another instance answers at the address', async () => {
|
||||
const { session, status } = setup('none');
|
||||
const reload = jest
|
||||
|
||||
@@ -74,8 +74,14 @@ export class ServerStorageSession {
|
||||
effect(() => {
|
||||
// Gone offline, the token and writes wait for the instance
|
||||
// check: after a blip it passes at once, not at the next retry.
|
||||
if (this.status.state() === 'offline') {
|
||||
untracked(() => void this.refresh());
|
||||
// Only the check: a read failing on its own waits for the retry.
|
||||
if (
|
||||
this.status.state() === 'offline' &&
|
||||
!this.config.startedOffline
|
||||
) {
|
||||
untracked(
|
||||
() => void this.ensureVerified().catch(() => undefined)
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -164,6 +170,9 @@ export class ServerStorageSession {
|
||||
signOut(): void {
|
||||
clearServerAccessToken();
|
||||
this.status.reportUnauthorized();
|
||||
// Also when signed out already: a guard (unsaved Settings) may have
|
||||
// kept the page here the first time.
|
||||
void this.router.navigateByUrl(SERVER_SIGN_IN_PATH);
|
||||
}
|
||||
|
||||
private listen(): void {
|
||||
|
||||
Reference in new issue
Block a user