Skip to content

Commit

Permalink
Integrate BeaconSignPage to BeaconNotification
Browse files Browse the repository at this point in the history
  • Loading branch information
ryutamago committed Sep 15, 2023
1 parent 2f351d6 commit b81ab3b
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 260 deletions.
3 changes: 1 addition & 2 deletions src/Router.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,9 +59,8 @@ const MemoizedRouter = React.memo(() => {
<Route path="/*" element={<Navigate to="/home" />} />
</Routes>
{dynamicModal.content}
{beaconNotificationModal}
</DynamicModalContext.Provider>

{beaconNotificationModal}
</HashRouter>
);
});
Expand Down
37 changes: 37 additions & 0 deletions src/components/SendFlow/Beacon/BeaconSignPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import { ImplicitOperations } from "../../sendForm/types";

import BeaconTezSignPage from "./TezSignPage";
import ContractCallSignPage from "./ContractCallSignPage";
import DelegationSignPage from "./DelegationSignPage";
import UndelegationSignPage from "./UndelegationSignPage";

export type BeaconSignPageProps = {
operation: ImplicitOperations;
onBeaconSuccess: (hash: string) => Promise<void>;
};

const BeaconSignPage: React.FC<BeaconSignPageProps> = ({ operation, onBeaconSuccess }) => {
const operationType = operation.operations[0].type;

switch (operationType) {
case "tez": {
return <BeaconTezSignPage operation={operation} onBeaconSuccess={onBeaconSuccess} />;
}
case "contract_call": {
return <ContractCallSignPage operation={operation} onBeaconSuccess={onBeaconSuccess} />;
}
case "delegation": {
return <DelegationSignPage operation={operation} onBeaconSuccess={onBeaconSuccess} />;
}
case "undelegation": {
return <UndelegationSignPage operation={operation} onBeaconSuccess={onBeaconSuccess} />;
}
case "fa1.2":
case "fa2":
case "contract_origination":
// this line will not reach, but better safe than sorry
throw new Error("Unsupported operation type");
}
};

export default BeaconSignPage;
2 changes: 1 addition & 1 deletion src/components/SendFlow/Undelegation/SignPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const SignPage: React.FC<SignPageProps> = props => {
<FormLabel>From</FormLabel>
<AddressTile address={signer.address} />

<Flex mt="12px" alignItems="center" justifyContent="end" px={1}>
<Flex mt="12px" alignItems="center" justifyContent="end" px="4px">
<SignPageFee fee={fee} />
</Flex>

Expand Down
156 changes: 3 additions & 153 deletions src/utils/beacon/BeaconNotification/BeaconRequestNotification.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,21 +2,14 @@ import {
BeaconMessageType,
BeaconRequestOutputMessage,
NetworkType,
OperationRequestOutput,
PermissionRequestOutput,
PermissionScope,
} from "@airgap/beacon-wallet";
import { Modal } from "@chakra-ui/react";
import { BeaconNotification } from ".";
import {
mockBeaconDelegate,
objectOperationBatchRequest,
objectOperationDelegationRequest,
objectOperationRequest,
} from "../../../mocks/beacon";
import { mockImplicitAccount } from "../../../mocks/factories";
import { dispatchMockAccounts, fillPassword, mockEstimatedFee } from "../../../mocks/helpers";
import { fireEvent, render, screen, waitFor, within } from "../../../mocks/testUtils";
import { dispatchMockAccounts, mockEstimatedFee } from "../../../mocks/helpers";
import { fireEvent, render, screen, waitFor } from "../../../mocks/testUtils";
import { walletClient } from "../beacon";
import { executeOperations } from "../../tezos";

Expand All @@ -34,7 +27,7 @@ const BATCH_OP_HASH = { opHash: "bar" };

const fixture = (message: BeaconRequestOutputMessage, onSuccess: () => void) => (
<Modal isOpen={true} onClose={() => {}}>
<BeaconNotification message={message} onSuccess={() => {}} />
<BeaconNotification message={message} onClose={() => {}} />
</Modal>
);

Expand Down Expand Up @@ -83,149 +76,6 @@ describe("<BeaconRequestNotification />", () => {
});
});

describe("Operation request (case simple tez transaction)", () => {
const message: OperationRequestOutput = {
...objectOperationRequest,
sourceAddress: mockImplicitAccount(2).address.pkh,
};

it("should display operations request with parameters displayed", async () => {
render(fixture(message, () => {}));
expect(screen.getByRole("dialog", { name: "Send" })).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByRole("button", { name: /preview/i })).toBeEnabled();
});
expect(screen.getByLabelText("Parameter")).toHaveTextContent(
`{ "entrypoint": "fulfill_ask", "value": { "prim": "Pair", "args": [ { "int": "1232832" }, { "prim": "None" } ] } }`
);
});

test("User previews then submits operation, and operation hash is sent via Beacon", async () => {
render(fixture(message, () => {}));
expect(screen.getByRole("dialog", { name: "Send" })).toBeInTheDocument();

await waitFor(() => {
expect(screen.getByRole("button", { name: /preview/i })).toBeEnabled();
});
screen.getByRole("button", { name: /preview/i }).click();
await waitFor(() => {
expect(screen.getByRole("dialog", { name: "Recap" })).toBeInTheDocument();
});

fillPassword("mockPass");
await waitFor(() => {
expect(screen.getByRole("button", { name: /submit transaction/i })).toBeEnabled();
});
screen.getByRole("button", { name: /submit transaction/i }).click();

await waitFor(() => {
expect(screen.getByText(/operation submitted/i)).toBeInTheDocument();
});

expect(walletClient.respond).toHaveBeenCalledWith({
id: objectOperationRequest.id,
transactionHash: BATCH_OP_HASH.opHash,
type: "operation_response",
});
});
});

describe("Operation request (case delegation)", () => {
const message: OperationRequestOutput = {
...objectOperationDelegationRequest,
sourceAddress: mockImplicitAccount(2).address.pkh,
};

it("should display delegation request", async () => {
render(fixture(message, () => {}));
expect(screen.getByRole("dialog", { name: /delegation/i })).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByRole("button", { name: /preview/i })).toBeEnabled();
});
await waitFor(() => {
expect(screen.getByTestId("real-address-input-baker")).toHaveAttribute(
"value",
mockBeaconDelegate
);
});
});

test("User previews then submits Delegation, and operation hash is sent via Beacon", async () => {
render(fixture(message, () => {}));
expect(screen.getByRole("dialog", { name: /delegation/i })).toBeInTheDocument();
await waitFor(() => {
expect(screen.getByRole("button", { name: /preview/i })).toBeEnabled();
});
screen.getByRole("button", { name: /preview/i }).click();
await waitFor(() => {
expect(screen.getByRole("dialog", { name: "Recap" })).toBeInTheDocument();
});

fillPassword("mockPass");
await waitFor(() => {
expect(screen.getByRole("button", { name: /submit transaction/i })).toBeEnabled();
});
screen.getByRole("button", { name: /submit transaction/i }).click();

await waitFor(() => {
expect(screen.getByText(/operation submitted/i)).toBeInTheDocument();
});

expect(walletClient.respond).toHaveBeenCalledWith({
id: objectOperationDelegationRequest.id,
transactionHash: BATCH_OP_HASH.opHash,
type: "operation_response",
});
});
});

test("User previews then submits Batches, and operation hash is sent via Beacon", async () => {
const message: OperationRequestOutput = {
...objectOperationBatchRequest,
sourceAddress: mockImplicitAccount(2).address.pkh,
};
render(fixture(message, () => {}));
const modal = screen.getByRole("dialog", { name: /recap/i });
const { getByRole, getByLabelText } = within(modal);
await waitFor(() => {
expect(getByRole("button", { name: /preview/i })).toBeEnabled();
});

expect(screen.getByText(/transaction details/i)).toBeInTheDocument();

const txsAmount = getByLabelText(/transactions-amount/i);
expect(txsAmount).toHaveTextContent("3");

const previewBtn = screen.getByRole("button", { name: /preview/i });
fireEvent.click(previewBtn);

await waitFor(() => {
expect(screen.getByLabelText(/password/i)).toBeInTheDocument();
});
fillPassword("mockPass");

const submit = screen.getByRole("button", {
name: /submit transaction/i,
});

await waitFor(() => {
expect(submit).toBeEnabled();
});

fireEvent.click(submit);

await waitFor(() => {
expect(screen.getByText(/Operation Submitted/i)).toBeInTheDocument();
});
expect(screen.getByTestId(/tzkt-link/i)).toHaveProperty("href", "https://tzkt.io/bar");

expect(walletClient.respond).toHaveBeenCalledWith({
id: objectOperationBatchRequest.id,
transactionHash: BATCH_OP_HASH.opHash,
type: "operation_response",
});
});

test("Unhandled Beacon request display an error", async () => {
const message = {
type: BeaconMessageType.BlockchainRequest,
Expand Down
Loading

0 comments on commit b81ab3b

Please sign in to comment.