Skip to content
This repository has been archived by the owner on Jan 23, 2024. It is now read-only.

Commit

Permalink
fix: default organizer bug in managed event type (calcom#11921)
Browse files Browse the repository at this point in the history
  • Loading branch information
Udit-takkar authored Nov 22, 2023
1 parent b762f60 commit f65c7e4
Show file tree
Hide file tree
Showing 13 changed files with 69 additions and 12 deletions.
2 changes: 2 additions & 0 deletions apps/web/components/eventtype/EventTeamTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,8 @@ const ChildrenEventTypesList = ({
<div>
<Label>{t("assign_to")}</Label>
<ChildrenEventTypeSelect
aria-label="assignment-dropdown"
data-testid="assignment-dropdown"
onChange={(options) => {
onChange &&
onChange(
Expand Down
2 changes: 1 addition & 1 deletion apps/web/playwright/fixtures/regularBookings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -204,7 +204,7 @@ export function createBookingPageFixture(page: Page) {
placeholder?: string
) => {
await page.getByTestId("add-field").click();
await page.locator("#test-field-type > .bg-default > div > div:nth-child(2)").first().click();
await page.getByTestId("test-field-type").click();
await page.getByTestId(`select-option-${questionType}`).click();
await page.getByLabel("Identifier").dblclick();
await page.getByLabel("Identifier").fill(identifier);
Expand Down
2 changes: 1 addition & 1 deletion apps/web/playwright/integrations-stripe.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,7 +267,7 @@ test.describe("Stripe integration", () => {
await page.getByTestId("price-input-stripe").fill("200");

// Select currency in dropdown
await page.locator(".text-black > .bg-default > div > div:nth-child(2)").first().click();
await page.getByTestId("stripe-currency-select").click();
await page.locator("#react-select-2-input").fill("mexi");
await page.locator("#react-select-2-option-81").click();

Expand Down
32 changes: 30 additions & 2 deletions apps/web/playwright/managed-event-types.e2e.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
import { expect } from "@playwright/test";
import type { Page } from "@playwright/test";

import { test } from "./lib/fixtures";
import { selectFirstAvailableTimeSlotNextMonth, bookTimeSlot } from "./lib/testUtils";
import { localize } from "./lib/testUtils";

test.afterEach(({ users }) => users.deleteAll());

Expand Down Expand Up @@ -69,15 +72,34 @@ test.describe("Managed Event Types tests", () => {
await page.goto("/event-types");
await page.getByTestId("event-types").locator('a[title="managed"]').click();
await page.getByTestId("vertical-tab-assignment").click();
await page.locator('[class$="control"]').filter({ hasText: "Select..." }).click();
await page.getByTestId("assignment-dropdown").click();

await page.getByTestId(`select-option-${memberUser.id}`).click();
await page.locator('[type="submit"]').click();
await page.getByTestId("toast-success").waitFor();
});

await adminUser.logout();
await test.step("Managed event type can use Organizer's default app as location", async () => {
await page.getByTestId("vertical-tab-event_setup_tab_title").click();

await page.locator("#location-select").click();
const optionText = (await localize("en"))("organizer_default_conferencing_app");
await page.locator(`text=${optionText}`).click();
await page.locator("[data-testid=update-eventtype]").click();
await page.getByTestId("toast-success").waitFor();
await page.waitForLoadState("networkidle");

await page.getByTestId("vertical-tab-assignment").click();
await gotoBookingPage(page);
await selectFirstAvailableTimeSlotNextMonth(page);
await bookTimeSlot(page);

await expect(page.getByTestId("success-page")).toBeVisible();
});

await test.step("Managed event type has locked fields for added member", async () => {
await adminUser.logout();

// Coming back as member user to see if there is a managed event present after assignment
await memberUser.apiLogin();
await page.goto("/event-types");
Expand All @@ -91,3 +113,9 @@ test.describe("Managed Event Types tests", () => {
});
});
});

async function gotoBookingPage(page: Page) {
const previewLink = await page.getByTestId("preview-button").getAttribute("href");

await page.goto(previewLink ?? "");
}
6 changes: 3 additions & 3 deletions apps/web/playwright/payment-apps.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ test.describe("Payment app", () => {

await page.goto(`event-types/${paymentEvent.id}?tabName=apps`);
await page.locator("#event-type-form").getByRole("switch").click();
await page.locator(".text-black > .bg-default > div > div:nth-child(2)").first().click();
await page.getByTestId("stripe-currency-select").click();
await page.getByTestId("select-option-usd").click();

await page.getByTestId("price-input-stripe").click();
Expand Down Expand Up @@ -123,10 +123,10 @@ test.describe("Payment app", () => {
await page.getByPlaceholder("Price").click();
await page.getByPlaceholder("Price").fill("150");

await page.locator(".text-black > .bg-default > div > div:nth-child(2)").first().click();
await page.getByTestId("paypal-currency-select").click();
await page.locator("#react-select-2-option-13").click();

await page.locator(".mb-1 > .bg-default > div > div:nth-child(2)").first().click();
await page.getByTestId("paypal-payment-option-select").click();

await page.getByText("$MXNCurrencyMexican pesoPayment option").click();
await page.getByTestId("update-eventtype").click();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
</label>
<Select
variant="default"
data-testid="paypal-currency-select"
options={currencyOptions}
value={selectedCurrency}
className="text-black"
Expand All @@ -111,6 +112,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
Payment option
</label>
<Select<Option>
data-testid="paypal-payment-option-select"
defaultValue={
paymentOptionSelectValue
? { ...paymentOptionSelectValue, label: t(paymentOptionSelectValue.label) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
{t("currency")}
</label>
<Select
data-testid="currency-select-stripe"
data-testid="stripe-currency-select"
variant="default"
options={currencyOptions}
value={selectedCurrency}
Expand All @@ -119,6 +119,7 @@ const EventTypeAppCard: EventTypeAppCardComponent = function EventTypeAppCard({
Payment option
</label>
<Select<Option>
data-testid="stripe-payment-option-select"
defaultValue={
paymentOptionSelectValue
? { ...paymentOptionSelectValue, label: t(paymentOptionSelectValue.label) }
Expand Down
5 changes: 4 additions & 1 deletion packages/features/bookings/lib/handleNewBooking.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1001,8 +1001,11 @@ async function handler(
const attendeeTimezone = attendeeInfoOnReschedule ? attendeeInfoOnReschedule.timeZone : reqBody.timeZone;

const tAttendees = await getTranslation(attendeeLanguage ?? "en", "common");

const isManagedEventType = !!eventType.parentId;

// use host default
if (isTeamEventType && locationBodyString === OrganizerDefaultConferencingAppType) {
if ((isManagedEventType || isTeamEventType) && locationBodyString === OrganizerDefaultConferencingAppType) {
const metadataParseResult = userMetadataSchema.safeParse(organizerUser.metadata);
const organizerMetadata = metadataParseResult.success ? metadataParseResult.data : undefined;
if (organizerMetadata?.defaultConferencingApp?.appSlug) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ export const ChildrenEventTypeSelect = ({
{children.created && children.owner.username && (
<Tooltip content={t("preview")}>
<Button
data-testid="preview-button"
color="secondary"
target="_blank"
variant="icon"
Expand Down
1 change: 1 addition & 0 deletions packages/features/form-builder/FormBuilder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,7 @@ function FieldEditDialog({
<DialogHeader title={t("add_a_booking_question")} subtitle={t("booking_questions_description")} />
<SelectField
defaultValue={fieldTypesConfigMap.text}
data-testid="test-field-type"
id="test-field-type"
isDisabled={
fieldForm.getValues("editable") === "system" ||
Expand Down
2 changes: 1 addition & 1 deletion packages/ui/components/form/select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export type SelectProps<
Option,
IsMulti extends boolean = false,
Group extends GroupBase<Option> = GroupBase<Option>
> = Props<Option, IsMulti, Group> & { variant?: "default" | "checkbox" };
> = Props<Option, IsMulti, Group> & { variant?: "default" | "checkbox"; "data-testid"?: string };

export const Select = <
Option,
Expand Down
20 changes: 19 additions & 1 deletion packages/ui/components/form/select/components.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import type { GroupBase, InputProps, OptionProps } from "react-select";
import type { GroupBase, InputProps, OptionProps, ControlProps } from "react-select";
import { components as reactSelectComponents } from "react-select";

import { classNames } from "@calcom/lib";

import { UpgradeTeamsBadge, UpgradeOrgsBadge } from "../../badge";
import { Check } from "../../icon";
import type { SelectProps } from "./Select";

export const InputComponent = <
Option,
Expand Down Expand Up @@ -60,6 +61,23 @@ export const OptionComponent = <
);
};

export const ControlComponent = <
Option,
IsMulti extends boolean,
Group extends GroupBase<Option> = GroupBase<Option>
>(
controlProps: ControlProps<Option, IsMulti, Group> & {
selectProps: SelectProps<Option, IsMulti, Group>;
}
) => {
const dataTestId = controlProps.selectProps["data-testid"] ?? "select-control";
return (
<span data-testid={dataTestId}>
<reactSelectComponents.Control {...controlProps} />
</span>
);
};

// We need to override this component if we need a icon - we can't simpily override styles
type IconLeadingProps = {
icon: React.ReactNode;
Expand Down
3 changes: 2 additions & 1 deletion packages/ui/components/form/select/selectTheme.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { GroupBase, SelectComponentsConfig, MenuPlacement } from "react-select";

import { InputComponent, OptionComponent } from "./components";
import { InputComponent, OptionComponent, ControlComponent } from "./components";

export const getReactSelectProps = <
Option,
Expand All @@ -18,6 +18,7 @@ export const getReactSelectProps = <
components: {
Input: InputComponent,
Option: OptionComponent,
Control: ControlComponent,
...components,
},
unstyled: true,
Expand Down

0 comments on commit f65c7e4

Please sign in to comment.