## Description - Locator fixes for cy tests - Missing saga for discard and merge - New component for hot keys Fixes https://github.com/appsmithorg/appsmith/issues/37821 Fixes https://github.com/appsmithorg/appsmith/issues/37822 Fixes https://github.com/appsmithorg/appsmith/issues/37824 ## Automation /ok-to-test tags="@tag.Git" ### 🔍 Cypress test results <!-- This is an auto-generated comment: Cypress test results --> > [!TIP] > 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉 > Workflow run: <https://github.com/appsmithorg/appsmith/actions/runs/12649057943> > Commit: 94c57d0a2398fca8e6cbb4be573586aa98dffbe1 > <a href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=12649057943&attempt=1" target="_blank">Cypress dashboard</a>. > Tags: `@tag.Git` > Spec: > <hr>Tue, 07 Jan 2025 10:42:55 UTC <!-- end of auto-generated comment: Cypress test results --> ## Communication Should the DevRel and Marketing teams inform users about this change? - [ ] Yes - [ ] No <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit ## Release Notes - **New Features** - Added repository limit error modal to handle scenarios when repository limits are reached. - Introduced Git hot keys for quick access to Git operations. - Enhanced Git synchronization functionality with new merge and discard change capabilities. - Integrated feature flag handling in test suites for Git-related functionalities. - **Improvements** - Standardized test identifiers across Git-related components. - Refined Git modal interactions and state management. - Updated locator references for more consistent testing. - Improved user feedback with success notifications for branch deletions. - **Bug Fixes** - Resolved issues with branch switching and URL handling. - Improved error handling in Git synchronization processes. - **Testing** - Updated Cypress test suites with new feature flag interceptors. - Enhanced test coverage for Git operations and modal interactions. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
163 lines
5.4 KiB
TypeScript
163 lines
5.4 KiB
TypeScript
import React from "react";
|
|
import { render, screen, fireEvent } from "@testing-library/react";
|
|
import "@testing-library/jest-dom";
|
|
import AnalyticsUtil from "ee/utils/AnalyticsUtil";
|
|
import DisconnectModal from "./DisconnectModalView";
|
|
|
|
jest.mock("ee/utils/AnalyticsUtil", () => ({
|
|
logEvent: jest.fn(),
|
|
}));
|
|
|
|
describe("DisconnectModal", () => {
|
|
const defaultProps = {
|
|
closeDisconnectModal: jest.fn(),
|
|
disconnect: jest.fn(),
|
|
disconnectArtifactName: "TestApp",
|
|
isDisconnectLoading: false,
|
|
isDisconnectModalOpen: true,
|
|
toggleSettingsModal: jest.fn(),
|
|
};
|
|
|
|
afterEach(() => {
|
|
jest.clearAllMocks();
|
|
});
|
|
|
|
it("should render the modal when isModalOpen is true", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
expect(screen.getByTestId("t--git-disconnect-modal")).toBeInTheDocument();
|
|
});
|
|
|
|
it("should not render the modal when isModalOpen is false", () => {
|
|
render(<DisconnectModal {...defaultProps} isDisconnectModalOpen={false} />);
|
|
expect(
|
|
screen.queryByTestId("t--git-disconnect-modal"),
|
|
).not.toBeInTheDocument();
|
|
});
|
|
|
|
it("should display the correct modal header", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
expect(screen.getByText("Revoke access to TestApp")).toBeInTheDocument();
|
|
});
|
|
|
|
it("should display the correct instruction text", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
expect(
|
|
screen.getByText("Type “TestApp” in the input box to revoke access."),
|
|
).toBeInTheDocument();
|
|
});
|
|
|
|
it("should update appName state when input changes", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const input = screen.getByLabelText("Application name");
|
|
|
|
fireEvent.change(input, { target: { value: "TestApp" } });
|
|
expect(input).toHaveValue("TestApp");
|
|
});
|
|
|
|
it("should enable Revoke button when appName matches disconnectAppName", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const input = screen.getByLabelText("Application name");
|
|
const revokeButton = screen.getByTestId(
|
|
"t--git-disconnect-modal-revoke-btn",
|
|
);
|
|
|
|
expect(revokeButton).toBeDisabled();
|
|
|
|
fireEvent.change(input, { target: { value: "TestApp" } });
|
|
expect(revokeButton).toBeEnabled();
|
|
});
|
|
|
|
it("should disable Revoke button when appName does not match disconnectAppName", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const input = screen.getByLabelText("Application name");
|
|
const revokeButton = screen.getByTestId(
|
|
"t--git-disconnect-modal-revoke-btn",
|
|
);
|
|
|
|
fireEvent.change(input, { target: { value: "WrongAppName" } });
|
|
expect(revokeButton).toBeDisabled();
|
|
});
|
|
|
|
it("should call onBackClick when Go Back button is clicked", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const goBackButton = screen.getByTestId("t--git-disconnect-modal-back-btn");
|
|
|
|
fireEvent.click(goBackButton);
|
|
expect(defaultProps.closeDisconnectModal).toHaveBeenCalledTimes(1);
|
|
expect(defaultProps.toggleSettingsModal).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("should call onDisconnect when Revoke button is clicked", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const input = screen.getByLabelText("Application name");
|
|
const revokeButton = screen.getByTestId(
|
|
"t--git-disconnect-modal-revoke-btn",
|
|
);
|
|
|
|
fireEvent.change(input, { target: { value: "TestApp" } });
|
|
fireEvent.click(revokeButton);
|
|
|
|
expect(defaultProps.disconnect).toHaveBeenCalledTimes(1);
|
|
});
|
|
|
|
it("should disable Revoke button when isRevoking is true", () => {
|
|
const { rerender } = render(<DisconnectModal {...defaultProps} />);
|
|
const input = screen.getByLabelText("Application name");
|
|
const revokeButton = screen.getByTestId(
|
|
"t--git-disconnect-modal-revoke-btn",
|
|
);
|
|
|
|
fireEvent.change(input, { target: { value: "TestApp" } });
|
|
expect(revokeButton).toBeEnabled();
|
|
|
|
fireEvent.click(revokeButton);
|
|
// Rerender to reflect state change
|
|
rerender(<DisconnectModal {...defaultProps} isDisconnectLoading />);
|
|
|
|
expect(defaultProps.disconnect).toHaveBeenCalledTimes(1);
|
|
expect(revokeButton).toBeDisabled();
|
|
});
|
|
|
|
it("should log analytics event on input blur", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const input = screen.getByLabelText("Application name");
|
|
|
|
fireEvent.change(input, { target: { value: "SomeValue" } });
|
|
fireEvent.blur(input);
|
|
|
|
expect(AnalyticsUtil.logEvent).toHaveBeenCalledWith(
|
|
"GS_MATCHING_REPO_NAME_ON_GIT_DISCONNECT_MODAL",
|
|
{
|
|
value: "SomeValue",
|
|
expecting: "TestApp",
|
|
},
|
|
);
|
|
});
|
|
|
|
it("should display callout with non-reversible message and learn more link", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
expect(
|
|
screen.getByText(
|
|
"This action is non-reversible. Please proceed with caution.",
|
|
),
|
|
).toBeInTheDocument();
|
|
const learnMoreLink = screen.getByText("Learn more").parentElement;
|
|
|
|
expect(learnMoreLink).toBeInTheDocument();
|
|
expect(learnMoreLink).toHaveAttribute(
|
|
"href",
|
|
"https://docs.appsmith.com/advanced-concepts/version-control-with-git/disconnect-the-git-repository",
|
|
);
|
|
});
|
|
|
|
it("should not call onDisconnect when Revoke button is clicked and appName does not match", () => {
|
|
render(<DisconnectModal {...defaultProps} />);
|
|
const revokeButton = screen.getByTestId(
|
|
"t--git-disconnect-modal-revoke-btn",
|
|
);
|
|
|
|
fireEvent.click(revokeButton);
|
|
expect(defaultProps.disconnect).not.toHaveBeenCalled();
|
|
});
|
|
});
|