diff --git a/spa/src/pages/Connections/GHCloudConnections/index.tsx b/spa/src/pages/Connections/GHCloudConnections/index.tsx
index 1983b3442..ceef92608 100644
--- a/spa/src/pages/Connections/GHCloudConnections/index.tsx
+++ b/spa/src/pages/Connections/GHCloudConnections/index.tsx
@@ -19,26 +19,30 @@ const containerStyles = xcss({
type GitHubCloudConnectionsProps = {
ghCloudSubscriptions: GhCloudSubscriptions;
+ refetch: () => void;
};
const GitHubCloudConnections = ({
ghCloudSubscriptions,
+ refetch,
}: GitHubCloudConnectionsProps) => {
const [isModalOpened, setIsModalOpened] = useState(false);
const [subscriptionForModal, setSubscriptionForModal] = useState(undefined);
const [selectedModal, setSelectedModal] = useState("BACKFILL");
- const openedModal = () => {
+ const openedModal = (refetch: () => void) => {
switch (selectedModal) {
case "BACKFILL":
return ();
case "DISCONNECT_SUBSCRIPTION":
return ;
// TODO: Create modals for GHE later
case "DISCONNECT_SERVER":
@@ -64,7 +68,7 @@ const GitHubCloudConnections = ({
{
- isModalOpened && subscriptionForModal && openedModal()
+ isModalOpened && subscriptionForModal && openedModal(refetch)
}
>
diff --git a/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.test.tsx b/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.test.tsx
index b28e1cadd..9dfe713a3 100644
--- a/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.test.tsx
+++ b/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.test.tsx
@@ -3,6 +3,9 @@ import { render, screen } from "@testing-library/react";
import { BrowserRouter } from "react-router-dom";
import userEvent from "@testing-library/user-event";
import DisconnectSubscriptionModal from "./DisconnectSubscriptionModal";
+import SubscriptionManager from "../../../services/subscription-manager";
+
+jest.mock("../../../services/subscription-manager");
const sampleSubscription = {
app_slug: "string",
@@ -29,11 +32,12 @@ const sampleSubscription = {
html_url: "html_url"
};
const isModalOpened = jest.fn();
+const refetch = jest.fn();
-test("Disconnect subscription Modal", async () => {
+test("Clicking cancel in disconnect subscription Modal", async () => {
render(
-
+
);
@@ -43,4 +47,27 @@ test("Disconnect subscription Modal", async () => {
await userEvent.click(screen.getByText("Cancel"));
expect(isModalOpened).toBeCalled();
+ expect(refetch).not.toBeCalled();
+});
+
+test("Clicking Disconnect in disconnect subscription Modal", async () => {
+ jest.mocked(SubscriptionManager).deleteSubscription = jest.fn().mockReturnValue(Promise.resolve(true));
+
+ render(
+
+
+
+ );
+
+ expect(screen.getByText("Disconnect sample?")).toBeInTheDocument();
+ const text = screen.getByTestId("disconnect-content");
+ expect(text.textContent).toBe("Are you sure you want to disconnect your organization sample? This means that you will have to redo the backfill of historical data if you ever want to reconnect");
+
+ await userEvent.click(screen.getByText("Disconnect"));
+ /**
+ * Called twice, once when the loading is set to true,
+ * and later after getting the response from the API request
+ */
+ expect(isModalOpened).toBeCalledTimes(2);
+ expect(refetch).toBeCalled();
});
diff --git a/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.tsx b/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.tsx
index c0c3f88e4..05c12cbc6 100644
--- a/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.tsx
+++ b/spa/src/pages/Connections/Modals/DisconnectSubscriptionModal.tsx
@@ -1,18 +1,30 @@
+import { useState } from "react";
+import { AxiosError } from "axios";
import Modal, { ModalBody, ModalFooter, ModalHeader, ModalTitle } from "@atlaskit/modal-dialog";
-import Button from "@atlaskit/button";
+import Button, { LoadingButton } from "@atlaskit/button";
import { SuccessfulConnection } from "../../../../../src/rest-interfaces";
+import SubscriptionManager from "../../../services/subscription-manager";
/**
* NOTE: While testing in dev mode, please disable the React.StrictMode first,
* otherwise this modal won't show up.
*/
-const DisconnectSubscriptionModal = ({ subscription, setIsModalOpened }: {
+const DisconnectSubscriptionModal = ({ subscription, setIsModalOpened, refetch }: {
subscription: SuccessfulConnection,
- setIsModalOpened: (x: boolean) => void
+ setIsModalOpened: (x: boolean) => void,
+ refetch: () => void
}) => {
- const disconnect = () => {
- // TODO: API call to disconnect this subscription
- console.log("Disconnect", subscription.account.login);
+ const [isLoading, setIsLoading] = useState(false);
+
+ const disconnect = async () => {
+ setIsLoading(true);
+ const response: boolean | AxiosError = await SubscriptionManager.deleteSubscription(subscription.subscriptionId);
+ if (response instanceof AxiosError) {
+ // TODO: Handle the error once we have the designs
+ console.error("Error", response);
+ } else {
+ await refetch();
+ }
setIsModalOpened(false);
};
@@ -31,10 +43,20 @@ const DisconnectSubscriptionModal = ({ subscription, setIsModalOpened }: {
-
-
>
diff --git a/spa/src/pages/Connections/Modals/RestartBackfillModal.test.tsx b/spa/src/pages/Connections/Modals/RestartBackfillModal.test.tsx
index e79e2fd62..4a6959e0f 100644
--- a/spa/src/pages/Connections/Modals/RestartBackfillModal.test.tsx
+++ b/spa/src/pages/Connections/Modals/RestartBackfillModal.test.tsx
@@ -29,11 +29,12 @@ const sampleSubscription = {
html_url: "html_url"
};
const isModalOpened = jest.fn();
+const refetch = jest.fn();
test("Restart backfill Modal", async () => {
render(
-
+
);
diff --git a/spa/src/pages/Connections/Modals/RestartBackfillModal.tsx b/spa/src/pages/Connections/Modals/RestartBackfillModal.tsx
index f8f4e36e1..959005315 100644
--- a/spa/src/pages/Connections/Modals/RestartBackfillModal.tsx
+++ b/spa/src/pages/Connections/Modals/RestartBackfillModal.tsx
@@ -10,9 +10,10 @@ import { DatePicker } from "@atlaskit/datetime-picker";
* NOTE: While testing in dev mode, please disable the React.StrictMode first,
* otherwise this modal won't show up.
*/
-const RestartBackfillModal = ({ subscription, setIsModalOpened }: {
+const RestartBackfillModal = ({ subscription, setIsModalOpened, refetch }: {
subscription: SuccessfulConnection,
- setIsModalOpened: (x: boolean) => void
+ setIsModalOpened: (x: boolean) => void,
+ refetch: () => void,
}) => {
const [restartFromDateCheck, setRestartFromDateCheck] = useState(false);
const [backfillDate, setBackfillDate] = useState("");
@@ -30,9 +31,10 @@ const RestartBackfillModal = ({ subscription, setIsModalOpened }: {
setTimeout(() => setIsDisabled(false), 10);
}, []);
- const backfill = () => {
+ const backfill = async () => {
// TODO: API call to disconnect this subscription
console.log("Backfill for", subscription.account.login, restartFromDateCheck, backfillDate);
+ await refetch();
setIsModalOpened(false);
};
diff --git a/spa/src/pages/Connections/index.tsx b/spa/src/pages/Connections/index.tsx
index 905091c9b..6b02c82bd 100644
--- a/spa/src/pages/Connections/index.tsx
+++ b/spa/src/pages/Connections/index.tsx
@@ -1,29 +1,28 @@
import { useEffect, useState } from "react";
-import ApiRequest from "../../api";
import SyncHeader from "../../components/SyncHeader";
import Step from "../../components/Step";
import { Wrapper } from "../../common/Wrapper";
import GitHubCloudConnections from "./GHCloudConnections";
import GitHubEnterpriseConnections from "./GHEnterpriseConnections";
import { GHSubscriptions } from "../../rest-interfaces";
-import { reportError } from "../../utils";
import SkeletonForLoading from "./SkeletonForLoading";
import { useNavigate } from "react-router-dom";
+import SubscriptionManager from "../../services/subscription-manager";
+import { AxiosError } from "axios";
const Connections = () => {
const navigate = useNavigate();
const [isLoading, setIsLoading] = useState(false);
- const [ghSubscriptions, setSubscriptions] = useState(null);
+ const [subscriptions, setSubscriptions] = useState(null);
const fetchGHSubscriptions = async () => {
- try {
- setIsLoading(true);
- const { data } = await ApiRequest.subscriptions.getSubscriptions();
- setSubscriptions(data);
- } catch (e) {
- reportError(e, { path: "Fetching subscriptions" });
- } finally {
- setIsLoading(false);
+ setIsLoading(true);
+ const response = await SubscriptionManager.getSubscriptions();
+ if (response instanceof AxiosError) {
+ // TODO: Handle the error once we have the designs
+ console.error("Error", response);
}
+ setSubscriptions(response as GHSubscriptions);
+ setIsLoading(false);
};
useEffect(() => {
fetchGHSubscriptions();
@@ -31,10 +30,10 @@ const Connections = () => {
// If there are no connections then go back to the start page
useEffect(() => {
- if (!ghSubscriptions?.ghCloudSubscriptions && ghSubscriptions?.ghEnterpriseServers && ghSubscriptions.ghEnterpriseServers?.length === 0) {
+ if (!subscriptions?.ghCloudSubscriptions && subscriptions?.ghEnterpriseServers && subscriptions.ghEnterpriseServers?.length === 0) {
navigate("/spa");
}
- }, [ghSubscriptions, navigate]);
+ }, [subscriptions, navigate]);
return (
@@ -42,14 +41,14 @@ const Connections = () => {
{
isLoading ? : <>
{
- ghSubscriptions?.ghCloudSubscriptions &&
-
+ subscriptions?.ghCloudSubscriptions &&
+
}
{
- ghSubscriptions?.ghEnterpriseServers && ghSubscriptions.ghEnterpriseServers?.length > 0 &&
-
+ subscriptions?.ghEnterpriseServers && subscriptions.ghEnterpriseServers?.length > 0 &&
+
}
>
diff --git a/spa/src/services/subscription-manager/index.ts b/spa/src/services/subscription-manager/index.ts
new file mode 100644
index 000000000..4c2dcd62c
--- /dev/null
+++ b/spa/src/services/subscription-manager/index.ts
@@ -0,0 +1,47 @@
+import Api from "../../api";
+import { AxiosError } from "axios";
+import { reportError } from "../../utils";
+import { GHSubscriptions } from "../../../../src/rest-interfaces";
+
+async function getSubscriptions(): Promise {
+ try {
+ const response= await Api.subscriptions.getSubscriptions();
+ const status = response.status === 200;
+ if(!status) {
+ reportError(
+ { message: "Response status for getting subscriptions is not 204", status: response.status },
+ { path: "getSubscriptions" }
+ );
+ }
+
+ return response.data;
+ } catch (e: unknown) {
+ reportError(new Error("Unable to delete subscription", { cause: e }), { path: "getSubscriptions" });
+ return e as AxiosError;
+ }
+}
+
+async function deleteSubscription(subscriptionId: number): Promise {
+ try {
+ const response= await Api.subscriptions.deleteSubscription(subscriptionId);
+ const ret = response.status === 204;
+ if(!ret) {
+ reportError(
+ { message: "Response status for deleting subscription is not 204", status: response.status },
+ { path: "deleteSubscription" }
+ );
+ }
+
+ return ret;
+ } catch (e: unknown) {
+ reportError(new Error("Unable to delete subscription", { cause: e }), { path: "deleteSubscription" });
+ return e as AxiosError;
+ }
+}
+
+export default {
+ getSubscriptions,
+ deleteSubscription,
+};
+
+