mirror of
				https://gitlab.nic.cz/turris/reforis/foris-js.git
				synced 2025-11-03 23:00:31 +01:00 
			
		
		
		
	Extract reboot button from reForis.
* Add RebootButton tests. * RebootButton code review. * Update translations.
This commit is contained in:
		
							
								
								
									
										77
									
								
								src/common/RebootButton.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										77
									
								
								src/common/RebootButton.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,77 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
 | 
			
		||||
 *
 | 
			
		||||
 * This is free software, licensed under the GNU General Public License v3.
 | 
			
		||||
 * See /LICENSE for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React, { useState, useEffect } from "react";
 | 
			
		||||
import PropTypes from "prop-types";
 | 
			
		||||
 | 
			
		||||
import { useAPIPost } from "api/hooks";
 | 
			
		||||
import { API_STATE } from "api/utils";
 | 
			
		||||
import { ForisURLs } from "forisUrls";
 | 
			
		||||
 | 
			
		||||
import { Button } from "bootstrap/Button";
 | 
			
		||||
import {
 | 
			
		||||
    Modal, ModalHeader, ModalBody, ModalFooter,
 | 
			
		||||
} from "bootstrap/Modal";
 | 
			
		||||
import { useAlert } from "alertContext/AlertContext";
 | 
			
		||||
 | 
			
		||||
RebootButton.propTypes = {
 | 
			
		||||
    forisFormSize: PropTypes.bool,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export function RebootButton(props) {
 | 
			
		||||
    const [triggered, setTriggered] = useState(false);
 | 
			
		||||
    const [modalShown, setModalShown] = useState(false);
 | 
			
		||||
    const [triggerRebootStatus, triggerReboot] = useAPIPost(ForisURLs.reboot);
 | 
			
		||||
 | 
			
		||||
    const [setAlert] = useAlert();
 | 
			
		||||
    useEffect(() => {
 | 
			
		||||
        if (triggerRebootStatus.state === API_STATE.ERROR) {
 | 
			
		||||
            setAlert(_("Reboot request failed."));
 | 
			
		||||
        }
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    function rebootHandler() {
 | 
			
		||||
        setTriggered(true);
 | 
			
		||||
        triggerReboot();
 | 
			
		||||
        setModalShown(false);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return (
 | 
			
		||||
        <>
 | 
			
		||||
            <RebootModal shown={modalShown} setShown={setModalShown} onReboot={rebootHandler} />
 | 
			
		||||
            <Button
 | 
			
		||||
                className="btn-danger"
 | 
			
		||||
                loading={triggered}
 | 
			
		||||
                disabled={triggered}
 | 
			
		||||
                onClick={() => setModalShown(true)}
 | 
			
		||||
 | 
			
		||||
                {...props}
 | 
			
		||||
            >
 | 
			
		||||
                {_("Reboot")}
 | 
			
		||||
            </Button>
 | 
			
		||||
        </>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
RebootModal.propTypes = {
 | 
			
		||||
    shown: PropTypes.bool.isRequired,
 | 
			
		||||
    setShown: PropTypes.func.isRequired,
 | 
			
		||||
    onReboot: PropTypes.func.isRequired,
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function RebootModal({ shown, setShown, onReboot }) {
 | 
			
		||||
    return (
 | 
			
		||||
        <Modal shown={shown} setShown={setShown}>
 | 
			
		||||
            <ModalHeader setShown={setShown} title={_("Reboot confirmation")} />
 | 
			
		||||
            <ModalBody><p>{_("Are you sure you want to restart the router?")}</p></ModalBody>
 | 
			
		||||
            <ModalFooter>
 | 
			
		||||
                <Button onClick={() => setShown(false)}>{_("Cancel")}</Button>
 | 
			
		||||
                <Button className="btn-danger" onClick={onReboot}>{_("Confirm reboot")}</Button>
 | 
			
		||||
            </ModalFooter>
 | 
			
		||||
        </Modal>
 | 
			
		||||
    );
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										55
									
								
								src/common/__tests__/RebootButton.test.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										55
									
								
								src/common/__tests__/RebootButton.test.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,55 @@
 | 
			
		||||
/*
 | 
			
		||||
 * Copyright (C) 2019 CZ.NIC z.s.p.o. (http://www.nic.cz/)
 | 
			
		||||
 *
 | 
			
		||||
 * This is free software, licensed under the GNU General Public License v3.
 | 
			
		||||
 * See /LICENSE for more information.
 | 
			
		||||
 */
 | 
			
		||||
 | 
			
		||||
import React from "react";
 | 
			
		||||
 | 
			
		||||
import { fireEvent, getByText, queryByText, render, wait } from "customTestRender";
 | 
			
		||||
import mockAxios from "jest-mock-axios";
 | 
			
		||||
import { mockJSONError } from "testUtils/network";
 | 
			
		||||
import { mockSetAlert } from "testUtils/alertContextMock";
 | 
			
		||||
 | 
			
		||||
import { RebootButton } from "../RebootButton";
 | 
			
		||||
 | 
			
		||||
describe("<RebootButton/>", () => {
 | 
			
		||||
    let componentContainer;
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
        const { container } = render(<>
 | 
			
		||||
            <div id="modal-container"/>
 | 
			
		||||
            <RebootButton/>
 | 
			
		||||
        </>);
 | 
			
		||||
        componentContainer = container;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("Render.", () => {
 | 
			
		||||
        expect(componentContainer)
 | 
			
		||||
            .toMatchSnapshot();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("Render modal.", () => {
 | 
			
		||||
        expect(queryByText(componentContainer, "Confirm reboot"))
 | 
			
		||||
            .toBeNull();
 | 
			
		||||
        fireEvent.click(getByText(componentContainer, "Reboot"));
 | 
			
		||||
        expect(componentContainer)
 | 
			
		||||
            .toMatchSnapshot();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("Confirm reboot.", () => {
 | 
			
		||||
        fireEvent.click(getByText(componentContainer, "Reboot"));
 | 
			
		||||
        fireEvent.click(getByText(componentContainer, "Confirm reboot"));
 | 
			
		||||
        expect(mockAxios.post)
 | 
			
		||||
            .toHaveBeenCalledWith("/reforis/api/reboot", undefined, expect.anything());
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it("Hold error.", async () => {
 | 
			
		||||
        fireEvent.click(getByText(componentContainer, "Reboot"));
 | 
			
		||||
        fireEvent.click(getByText(componentContainer, "Confirm reboot"));
 | 
			
		||||
        mockJSONError();
 | 
			
		||||
        await wait(() => expect(mockSetAlert)
 | 
			
		||||
            .toBeCalledWith("Reboot triggering was failed."));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
});
 | 
			
		||||
							
								
								
									
										94
									
								
								src/common/__tests__/__snapshots__/RebootButton.test.js.snap
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										94
									
								
								src/common/__tests__/__snapshots__/RebootButton.test.js.snap
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,94 @@
 | 
			
		||||
// Jest Snapshot v1, https://goo.gl/fbAQLP
 | 
			
		||||
 | 
			
		||||
exports[`<RebootButton/> Render modal. 1`] = `
 | 
			
		||||
<div>
 | 
			
		||||
  <div
 | 
			
		||||
    id="modal-container"
 | 
			
		||||
  >
 | 
			
		||||
    <div
 | 
			
		||||
      class="modal fade show"
 | 
			
		||||
      role="dialog"
 | 
			
		||||
    >
 | 
			
		||||
      <div
 | 
			
		||||
        class="modal-dialog modal-dialog-centered"
 | 
			
		||||
        role="document"
 | 
			
		||||
      >
 | 
			
		||||
        <div
 | 
			
		||||
          class="modal-content"
 | 
			
		||||
        >
 | 
			
		||||
          <div
 | 
			
		||||
            class="modal-header"
 | 
			
		||||
          >
 | 
			
		||||
            <h5
 | 
			
		||||
              class="modal-title"
 | 
			
		||||
            >
 | 
			
		||||
              Reboot confirmation
 | 
			
		||||
            </h5>
 | 
			
		||||
            <button
 | 
			
		||||
              class="close"
 | 
			
		||||
              type="button"
 | 
			
		||||
            >
 | 
			
		||||
              <span
 | 
			
		||||
                aria-hidden="true"
 | 
			
		||||
              >
 | 
			
		||||
                ×
 | 
			
		||||
              </span>
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            class="modal-body"
 | 
			
		||||
          >
 | 
			
		||||
            <p>
 | 
			
		||||
              Are you sure you want to restart the router?
 | 
			
		||||
            </p>
 | 
			
		||||
          </div>
 | 
			
		||||
          <div
 | 
			
		||||
            class="modal-footer"
 | 
			
		||||
          >
 | 
			
		||||
            <button
 | 
			
		||||
              class="btn btn-primary "
 | 
			
		||||
              type="button"
 | 
			
		||||
            >
 | 
			
		||||
               
 | 
			
		||||
               
 | 
			
		||||
              Cancel
 | 
			
		||||
            </button>
 | 
			
		||||
            <button
 | 
			
		||||
              class="btn btn-danger"
 | 
			
		||||
              type="button"
 | 
			
		||||
            >
 | 
			
		||||
               
 | 
			
		||||
               
 | 
			
		||||
              Confirm reboot
 | 
			
		||||
            </button>
 | 
			
		||||
          </div>
 | 
			
		||||
        </div>
 | 
			
		||||
      </div>
 | 
			
		||||
    </div>
 | 
			
		||||
  </div>
 | 
			
		||||
  <button
 | 
			
		||||
    class="btn btn-danger"
 | 
			
		||||
    type="button"
 | 
			
		||||
  >
 | 
			
		||||
     
 | 
			
		||||
     
 | 
			
		||||
    Reboot
 | 
			
		||||
  </button>
 | 
			
		||||
</div>
 | 
			
		||||
`;
 | 
			
		||||
 | 
			
		||||
exports[`<RebootButton/> Render. 1`] = `
 | 
			
		||||
<div>
 | 
			
		||||
  <div
 | 
			
		||||
    id="modal-container"
 | 
			
		||||
  />
 | 
			
		||||
  <button
 | 
			
		||||
    class="btn btn-danger"
 | 
			
		||||
    type="button"
 | 
			
		||||
  >
 | 
			
		||||
     
 | 
			
		||||
     
 | 
			
		||||
    Reboot
 | 
			
		||||
  </button>
 | 
			
		||||
</div>
 | 
			
		||||
`;
 | 
			
		||||
@@ -11,6 +11,7 @@ export const ForisURLs = {
 | 
			
		||||
    login: `${REFORIS_URL_PREFIX}/login`,
 | 
			
		||||
    static: `${REFORIS_URL_PREFIX}/static/reforis`,
 | 
			
		||||
    wifi: `${REFORIS_URL_PREFIX}/network-settings/wifi`,
 | 
			
		||||
 | 
			
		||||
    packageManagement: {
 | 
			
		||||
        updateSettings: `${REFORIS_URL_PREFIX}/package-management/update-settings`,
 | 
			
		||||
        updates: `${REFORIS_URL_PREFIX}/package-management/updates`,
 | 
			
		||||
@@ -21,4 +22,7 @@ export const ForisURLs = {
 | 
			
		||||
    notificationsSettings: "/administration/notifications-settings",
 | 
			
		||||
 | 
			
		||||
    luci: "/cgi-bin/luci",
 | 
			
		||||
 | 
			
		||||
    // API
 | 
			
		||||
    reboot: `${REFORIS_URL_PREFIX}/api/reboot`,
 | 
			
		||||
};
 | 
			
		||||
 
 | 
			
		||||
@@ -43,6 +43,9 @@ export {
 | 
			
		||||
    ModalHeader,
 | 
			
		||||
} from "bootstrap/Modal";
 | 
			
		||||
 | 
			
		||||
// Common
 | 
			
		||||
export { RebootButton } from "common/RebootButton";
 | 
			
		||||
 | 
			
		||||
// Form
 | 
			
		||||
export { ForisForm } from "form/components/ForisForm";
 | 
			
		||||
export { SubmitButton, STATES as SUBMIT_BUTTON_STATES } from "form/components/SubmitButton";
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user