diff --git a/src/components/notifications/NotificationFormatSelector.jsx b/src/components/notifications/NotificationFormatSelector.jsx index dc2647c1..0a7a666b 100644 --- a/src/components/notifications/NotificationFormatSelector.jsx +++ b/src/components/notifications/NotificationFormatSelector.jsx @@ -3,7 +3,7 @@ import Form from "react-bootstrap/Form"; import Col from "react-bootstrap/Col"; import { stateProperty } from "../../forms"; -export function NotificationFormatSelector(component, name) { +export function NotificationFormatSelector(component, name, { lockPlainText = false } = {}) { return ( Notification Format @@ -11,8 +11,11 @@ export function NotificationFormatSelector(component, name) { as="select" size="sm" name={name} + data-testid="notification-format" onChange={(e) => component.handleChange(e)} - value={stateProperty(component, name)} + value={lockPlainText ? "txt" : stateProperty(component, name)} + className={lockPlainText ? "opacity-50" : ""} + disabled={lockPlainText} > diff --git a/src/components/notifications/WebHookNotificationMethod.jsx b/src/components/notifications/WebHookNotificationMethod.jsx index 4d99745b..69d12891 100644 --- a/src/components/notifications/WebHookNotificationMethod.jsx +++ b/src/components/notifications/WebHookNotificationMethod.jsx @@ -14,6 +14,7 @@ export class WebHookNotificationMethod extends Component { this.state = { format: "txt", method: "POST", + discord: false, ...props.initial, }; this.handleChange = handleChange.bind(this); @@ -32,27 +33,45 @@ export class WebHookNotificationMethod extends Component { <> {RequiredField(this, "URL Endpoint", "endpoint", { autoFocus: true })} - - HTTP Method - this.handleChange(e)} - value={stateProperty(this, "method")} - > - - - - - {NotificationFormatSelector(this, "format")} + + Discord + { + this.setState({ discord: e.target.checked }); + }} + /> + + + + + + HTTP Method + this.handleChange(e)} + value={this.state.discord ? "POST" : stateProperty(this, "method")} + disabled={this.state.discord} + className={this.state.discord ? "opacity-50" : ""} + > + + + + + {NotificationFormatSelector(this, "format", { lockPlainText: this.state.discord })} + {OptionalField( this, "Additional Headers", "headers", - { as: "textarea", rows: 5 }, + { as: "textarea", rows: 5, disabled: this.state.discord, className: this.state.discord ? "opacity-50" : "" }, "Enter one header per line in the format 'Header: Value'.", )} diff --git a/tests/components/notifications/WebHookNotificationMethod.test.jsx b/tests/components/notifications/WebHookNotificationMethod.test.jsx index 4fb0f75e..a4efe117 100644 --- a/tests/components/notifications/WebHookNotificationMethod.test.jsx +++ b/tests/components/notifications/WebHookNotificationMethod.test.jsx @@ -20,5 +20,47 @@ it("can set fields", async () => { method: "POST", format: "txt", headers: "some:header\nanother:header", + discord: false }); }); + +describe("Discord functionality", () => { + it("toggles Discord correctly and updates related fields", async () => { + let ref = React.createRef(); + const { getByTestId } = render(); + + // Fill endpoint first so validation passes + fireEvent.change(getByTestId("control-endpoint"), { + target: { value: "http://some-endpoint:12345" }, + }); + expect(ref.current.validate()).toBe(true); + + const discordCheckbox = getByTestId("discord"); + const methodSelect = getByTestId("http-method"); + const headersTextarea = getByTestId("control-headers"); + const formatSelect = getByTestId("notification-format"); + + // Initially, Discord unchecked + expect(discordCheckbox.checked).toBe(false); + expect(methodSelect.value).toBe("POST"); + expect(methodSelect.disabled).toBe(false); + expect(headersTextarea.disabled).toBe(false); + expect(formatSelect.value).toBe("txt"); + + // Toggle Discord ON + fireEvent.click(discordCheckbox); + + expect(discordCheckbox.checked).toBe(true); + expect(methodSelect.value).toBe("POST"); // HTTP method forced to POST + expect(methodSelect.disabled).toBe(true); // method disabled + expect(headersTextarea.disabled).toBe(true); // headers disabled + expect(formatSelect.value).toBe("txt"); // format locked to plain text + + // Toggle Discord OFF + fireEvent.click(discordCheckbox); + + expect(discordCheckbox.checked).toBe(false); + expect(methodSelect.disabled).toBe(false); + expect(headersTextarea.disabled).toBe(false); + }); +}); \ No newline at end of file