fix(web): review fixes — EPG switch gating, edit route key, stronger PUT assertion (#146)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+1
-1
@@ -2859,7 +2859,7 @@ function ScreenContent({
|
||||
}
|
||||
|
||||
if (route.id === 'editChannel') {
|
||||
return <ChannelEditScreen />;
|
||||
return <ChannelEditScreen key={window.location.pathname} />;
|
||||
}
|
||||
|
||||
if (route.id === 'guide') {
|
||||
|
||||
@@ -34,6 +34,14 @@ const channel = {
|
||||
showInEpg: true
|
||||
};
|
||||
|
||||
// The PUT body is the GET response minus the read-only id / playoutCount fields.
|
||||
function expectedPutBody(overrides: Record<string, unknown> = {}): Record<string, unknown> {
|
||||
const { id, playoutCount, ...rest } = channel;
|
||||
void id;
|
||||
void playoutCount;
|
||||
return { ...rest, ...overrides };
|
||||
}
|
||||
|
||||
function json(body: unknown, status = 200): Response {
|
||||
return new Response(JSON.stringify(body), {
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
@@ -115,14 +123,34 @@ describe('ChannelEditScreen', () => {
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
await waitFor(() => expect(puts).toHaveLength(1));
|
||||
expect(puts[0]).toMatchObject({ name: 'Renamed', number: '5', playoutSource: 'Generated' });
|
||||
// Read-only fields are not part of the PUT contract.
|
||||
expect(puts[0]).not.toHaveProperty('id');
|
||||
expect(puts[0]).not.toHaveProperty('playoutCount');
|
||||
|
||||
expect(puts[0]).toEqual(expectedPutBody({ name: 'Renamed' }));
|
||||
|
||||
expect(await screen.findByText('Channel saved')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('forces showInEpg off in the PUT body when Enabled is turned off', async () => {
|
||||
const puts: unknown[] = [];
|
||||
mockApi({ onPut: (body) => puts.push(body) });
|
||||
render(<ChannelEditScreen />);
|
||||
|
||||
await screen.findByDisplayValue('Cartoons');
|
||||
|
||||
// The General pane renders exactly two switches, in document order: Enabled, then Show in EPG.
|
||||
const [enabledSwitch, showInEpgSwitch] = screen.getAllByRole('switch');
|
||||
fireEvent.click(enabledSwitch);
|
||||
|
||||
expect(showInEpgSwitch).toHaveAttribute('aria-checked', 'false');
|
||||
expect(showInEpgSwitch).toHaveAttribute('aria-disabled', 'true');
|
||||
|
||||
const saveButton = await screen.findByRole('button', { name: 'Save changes' });
|
||||
fireEvent.click(saveButton);
|
||||
|
||||
await waitFor(() => expect(puts).toHaveLength(1));
|
||||
|
||||
expect(puts[0]).toEqual(expectedPutBody({ isEnabled: false, showInEpg: false }));
|
||||
});
|
||||
|
||||
it('shows an error state when the channel is not found', async () => {
|
||||
mockApi({ channelStatus: 404 });
|
||||
render(<ChannelEditScreen />);
|
||||
|
||||
@@ -252,10 +252,19 @@ function GeneralPane({
|
||||
/>
|
||||
</Row>
|
||||
<Row help="Whether this channel is served to clients." label="Enabled">
|
||||
<Switch checked={draft.isEnabled} onChange={(next) => set({ isEnabled: next })} size="sm" />
|
||||
<Switch
|
||||
checked={draft.isEnabled}
|
||||
onChange={(next) => set(next ? { isEnabled: next } : { isEnabled: next, showInEpg: false })}
|
||||
size="sm"
|
||||
/>
|
||||
</Row>
|
||||
<Row help="Include this channel in the XMLTV guide." label="Show in EPG">
|
||||
<Switch checked={draft.showInEpg} onChange={(next) => set({ showInEpg: next })} size="sm" />
|
||||
<Switch
|
||||
checked={draft.showInEpg}
|
||||
disabled={!draft.isEnabled}
|
||||
onChange={(next) => set({ showInEpg: next })}
|
||||
size="sm"
|
||||
/>
|
||||
</Row>
|
||||
</Card>
|
||||
</Pane>
|
||||
|
||||
Reference in New Issue
Block a user