Files
cal.diy/apps/web/components/apps/InstallAppButtonChild.test.tsx
T
Pedro CastroandUdit Takkar 3ebac0194e fix: block Google Meet installation without Google Calendar dependency (#25513)
* fix: block Google Meet installation without Google Calendar dependency

  - Prevent users from installing Google Meet when Google Calendar is not connected
  - Update AppDependencyComponent to show error state for unmet dependencies
  - Fix InstallAppButtonChild to respect disabled prop from dependencies check
  - Ensure consistent dependency validation across App Store and app detail pages

  Fixes #25497

* test: add unit tests for dependency validation
- Add tests for AppDependencyComponent (8 tests)
- Add tests for InstallAppButtonChild (5 tests)
- Cover dependency blocking behavior
- Test visual state changes (bg-error/bg-subtle)

* test: resolve type-check error in InstallAppButtonChild tests

- Add complete MockCredential type definition
- Create factory function to generate typed mock credentials
- Eliminate code duplication across test cases

* fix: remove redundant disabled prop assignment

Disabled state is already passed through via props.disableInstall
which gets converted to props.disabled in InstallAppButtonWithoutPlanCheck.
This change addresses the review comment to avoid unnecessary duplication

---------

Co-authored-by: Udit Takkar <53316345+Udit-takkar@users.noreply.github.com>
2025-12-09 17:56:20 +00:00

104 lines
3.1 KiB
TypeScript

import { render, screen } from "@testing-library/react";
import { vi } from "vitest";
import { InstallAppButtonChild } from "./InstallAppButtonChild";
// Mock credential type
type MockCredential = {
id: number;
delegatedToId: string;
userId: number;
user: { email: string };
key: { access_token: string };
invalid: boolean;
teamId: null;
team: null;
delegationCredentialId: string;
type:
| `${string}_calendar`
| `${string}_messaging`
| `${string}_payment`
| `${string}_video`
| `${string}_other`
| `${string}_automation`
| `${string}_analytics`
| `${string}_crm`
| `${string}_other_calendar`;
appId: string;
};
// Factory function to create mock credentials
const createMockCredential = (overrides: Partial<MockCredential> = {}): MockCredential => ({
id: 1,
type: "google_calendar" as const,
userId: 1,
delegatedToId: "delegation-123",
teamId: null,
team: null,
user: { email: "test@example.com" },
key: { access_token: "mock_token_123" },
delegationCredentialId: "delegation-123",
appId: "google-calendar",
invalid: false,
...overrides,
});
// Mock the useLocale hook
vi.mock("@calcom/lib/hooks/useLocale", () => ({
useLocale: () => ({
t: (key: string) => {
const translations = {
install_app: "Install App",
install_another: "Install Another",
start_paid_trial: "Start Free Trial",
subscribe: "Subscribe",
};
return translations[key as keyof typeof translations] || key;
},
}),
}));
describe("InstallAppButtonChild", () => {
afterEach(() => {
vi.clearAllMocks();
});
it("is disabled when credentials exist and multiInstall is false", () => {
const mockCredentials = [createMockCredential()];
render(<InstallAppButtonChild multiInstall={false} credentials={mockCredentials} />);
const button = screen.getByTestId("install-app-button");
expect(button).toBeDisabled();
});
it("is enabled when credentials exist and multiInstall is true", () => {
const mockCredentials = [createMockCredential()];
render(<InstallAppButtonChild multiInstall={true} credentials={mockCredentials} />);
const button = screen.getByTestId("install-app-button");
expect(button).not.toBeDisabled();
});
it("is disabled when disabled prop is true regardless of credentials", () => {
render(<InstallAppButtonChild disabled={true} multiInstall={true} credentials={[]} />);
const button = screen.getByTestId("install-app-button");
expect(button).toBeDisabled();
});
it("combines disabled prop with credential logic correctly", () => {
const mockCredentials = [createMockCredential()];
render(<InstallAppButtonChild disabled={true} multiInstall={false} credentials={mockCredentials} />);
const button = screen.getByTestId("install-app-button");
expect(button).toBeDisabled();
});
it("is enabled when no blocking conditions exist", () => {
render(<InstallAppButtonChild multiInstall={false} credentials={[]} disabled={false} />);
const button = screen.getByTestId("install-app-button");
expect(button).not.toBeDisabled();
});
});