mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-10 10:06:15 -08:00
fix(settings): keep the parental lock switch on the saved state and roll back to the recovered value
The Settings switch snaps back to the saved state when clicked and follows it once the PIN action succeeds, so a cancelled or refused PIN no longer leaves it showing the opposite state. A failed switch write is undone to the value read after the settings retry instead of the hard-coded inverse. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
ed48e7fd2b
commit
8d11f674cf
6 files changed
+129
-5
No files matched your search
@@ -19,7 +19,7 @@
|
||||
data-test-id="parental-lock-enabled"
|
||||
[checked]="enabled()"
|
||||
[disabled]="busy()"
|
||||
(change)="toggleEnabled.emit($event.checked)"
|
||||
(change)="onToggleEnabled($event)"
|
||||
[attr.aria-label]="'SETTINGS.PARENTAL_LOCK.ENABLE' | translate"
|
||||
></mat-slide-toggle>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
import { TestBed } from '@angular/core/testing';
|
||||
import { MatSlideToggle } from '@angular/material/slide-toggle';
|
||||
import { By } from '@angular/platform-browser';
|
||||
import { NoopAnimationsModule } from '@angular/platform-browser/animations';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { SettingsParentalLockSectionComponent } from './settings-parental-section.component';
|
||||
|
||||
describe('SettingsParentalLockSectionComponent', () => {
|
||||
it('keeps the enable switch on the saved state until the PIN action succeeds', async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [
|
||||
SettingsParentalLockSectionComponent,
|
||||
NoopAnimationsModule,
|
||||
TranslateModule.forRoot(),
|
||||
],
|
||||
}).compileComponents();
|
||||
const fixture = TestBed.createComponent(
|
||||
SettingsParentalLockSectionComponent
|
||||
);
|
||||
fixture.componentRef.setInput('enabled', false);
|
||||
fixture.componentRef.setInput('unlocked', false);
|
||||
fixture.componentRef.setInput('hasPin', false);
|
||||
fixture.componentRef.setInput('relockMinutes', 15);
|
||||
fixture.componentRef.setInput('relockOptions', [0, 15]);
|
||||
fixture.detectChanges();
|
||||
const requested = jest.fn();
|
||||
fixture.componentInstance.toggleEnabled.subscribe(requested);
|
||||
const toggle = fixture.debugElement.query(By.directive(MatSlideToggle))
|
||||
.componentInstance as MatSlideToggle;
|
||||
const button = fixture.nativeElement.querySelector(
|
||||
'[data-test-id="parental-lock-enabled"] button'
|
||||
) as HTMLButtonElement;
|
||||
|
||||
// The set-PIN prompt is then cancelled: `enabled` never changes.
|
||||
button.click();
|
||||
fixture.detectChanges();
|
||||
|
||||
expect(requested).toHaveBeenCalledWith(true);
|
||||
expect(toggle.checked).toBe(false);
|
||||
|
||||
// The PIN was set: the switch follows the saved state.
|
||||
fixture.componentRef.setInput('enabled', true);
|
||||
fixture.detectChanges();
|
||||
expect(toggle.checked).toBe(true);
|
||||
});
|
||||
});
|
||||
@@ -3,7 +3,10 @@ import { MatButtonModule } from '@angular/material/button';
|
||||
import { MatFormFieldModule } from '@angular/material/form-field';
|
||||
import { MatIconModule } from '@angular/material/icon';
|
||||
import { MatSelectModule } from '@angular/material/select';
|
||||
import { MatSlideToggleModule } from '@angular/material/slide-toggle';
|
||||
import {
|
||||
MatSlideToggleChange,
|
||||
MatSlideToggleModule,
|
||||
} from '@angular/material/slide-toggle';
|
||||
import { TranslateModule } from '@ngx-translate/core';
|
||||
import { ParentalLockRelockMinutes } from '@iptvnator/shared/interfaces';
|
||||
|
||||
@@ -36,6 +39,18 @@ export class SettingsParentalLockSectionComponent {
|
||||
readonly lockNow = output<void>();
|
||||
readonly unlock = output<void>();
|
||||
|
||||
/**
|
||||
* The switch only REQUESTS the change: enabling and disabling both go
|
||||
* through the PIN, which may be cancelled. It is put back to the saved
|
||||
* state at once and follows `enabled()` when the action succeeds;
|
||||
* otherwise the slide toggle would keep showing the state it flipped to
|
||||
* (`[checked]` is not re-applied while the bound value is unchanged).
|
||||
*/
|
||||
onToggleEnabled(event: MatSlideToggleChange): void {
|
||||
event.source.checked = this.enabled();
|
||||
this.toggleEnabled.emit(event.checked);
|
||||
}
|
||||
|
||||
relockLabelKey(minutes: ParentalLockRelockMinutes): string {
|
||||
return minutes === 0
|
||||
? 'SETTINGS.PARENTAL_LOCK.RELOCK_NEVER'
|
||||
|
||||
Reference in new issue
Block a user