mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-15 05:36:17 -08:00
fix(settings): build bulk lock drafts only from a readable lock store
The Xtream and M3U management dialogs offer lock toggles, and the Stalker lock dialog opens, only once the lock store has been read. A draft built from the empty fail-closed snapshot would otherwise replace the real locks with nothing on Save if storage recovered in between. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ceb0653415
commit
ed48e7fd2b
7 files changed
+94
-5
No files matched your search
+23
-2
@@ -47,7 +47,11 @@ describe('GroupsViewComponent', () => {
|
||||
let fixture: ComponentFixture<GroupsViewComponent>;
|
||||
let component: GroupsViewComponent;
|
||||
let dialog: { open: jest.Mock };
|
||||
let parentalLock: { requestUnlock: jest.Mock };
|
||||
let parentalLock: {
|
||||
requestUnlock: jest.Mock;
|
||||
ensureLocksReadable: jest.Mock;
|
||||
lockedGroupTitles: jest.Mock;
|
||||
};
|
||||
|
||||
const sportsCenter = createChannel(
|
||||
'sports-1',
|
||||
@@ -104,7 +108,11 @@ describe('GroupsViewComponent', () => {
|
||||
beforeEach(async () => {
|
||||
localStorage.removeItem(GROUP_CHANNEL_SORT_STORAGE_KEY);
|
||||
|
||||
parentalLock = { requestUnlock: jest.fn().mockResolvedValue(true) };
|
||||
parentalLock = {
|
||||
requestUnlock: jest.fn().mockResolvedValue(true),
|
||||
ensureLocksReadable: jest.fn().mockResolvedValue(true),
|
||||
lockedGroupTitles: jest.fn(() => ['News']),
|
||||
};
|
||||
|
||||
dialog = {
|
||||
open: jest.fn(),
|
||||
@@ -537,6 +545,19 @@ describe('GroupsViewComponent', () => {
|
||||
]);
|
||||
});
|
||||
|
||||
it('opens the manage-groups dialog without lock toggles while the lock store is unreadable', async () => {
|
||||
fixture.componentRef.setInput('playlistId', 'playlist-a');
|
||||
fixture.componentRef.setInput('lockedGroupTitles', []);
|
||||
fixture.detectChanges();
|
||||
parentalLock.ensureLocksReadable.mockResolvedValue(false);
|
||||
dialog.open.mockReturnValue({ afterClosed: () => of(undefined) });
|
||||
|
||||
await component.openGroupManagement();
|
||||
|
||||
const data = dialog.open.mock.calls[0][1].data;
|
||||
expect(data.lockedGroupTitles).toBeUndefined();
|
||||
});
|
||||
|
||||
it('drops the manage-groups result once another playlist is open', async () => {
|
||||
const hiddenGroupTitlesChanged = jest.fn();
|
||||
const lockedGroupTitlesChanged = jest.fn();
|
||||
|
||||
+11
-1
@@ -556,7 +556,17 @@ export class GroupsViewComponent {
|
||||
count,
|
||||
})
|
||||
);
|
||||
const lockedGroupTitles = this.lockedGroupTitles();
|
||||
// Lock toggles only from a lock store that was read: a draft built
|
||||
// from the empty fail-closed snapshot would, if storage recovered by
|
||||
// Save, replace the real locks with nothing. Hidden groups stay
|
||||
// editable either way.
|
||||
const lockedGroupTitles =
|
||||
this.lockedGroupTitles() !== null &&
|
||||
playlistId &&
|
||||
(await this.parentalLock.ensureLocksReadable()) &&
|
||||
this.playlistId() === playlistId
|
||||
? this.parentalLock.lockedGroupTitles(playlistId)
|
||||
: null;
|
||||
const dialogRef = this.dialog.open(GroupManagementDialogComponent, {
|
||||
data: {
|
||||
groups,
|
||||
|
||||
Reference in new issue
Block a user