diff --git a/src/components/ga4/EventBuilder/ValidateEvent/handlers/formatCheckLib.ts b/src/components/ga4/EventBuilder/ValidateEvent/handlers/formatCheckLib.ts index b6a72d53a..1fade516e 100644 --- a/src/components/ga4/EventBuilder/ValidateEvent/handlers/formatCheckLib.ts +++ b/src/components/ga4/EventBuilder/ValidateEvent/handlers/formatCheckLib.ts @@ -5,12 +5,11 @@ import {eventDefinitions} from "../schemas/eventTypes/eventDefinitions" import {InstanceId} from "../../types" const RESERVED_EVENT_NAMES = [ - "ad_activeview", "ad_click", "ad_exposure", "ad_impression", "ad_query", + "ad_activeview", "ad_click", "ad_exposure", "ad_query", "adunit_exposure", "app_clear_data", "app_install", "app_update", "app_remove", "error", "first_open", "first_visit", "in_app_purchase", "notification_dismiss", "notification_foreground", "notification_open", - "notification_receive", "os_update", "screen_view", "session_start", - "user_engagement" + "notification_receive", "os_update", "session_start", "user_engagement" ] const RESERVED_USER_PROPERTY_NAMES = [ "first_open_time", "first_visit_time", "last_deep_link_referrer", "user_id", diff --git a/src/components/ga4/EventBuilder/event.ts b/src/components/ga4/EventBuilder/event.ts index 5704422b4..89e812e52 100644 --- a/src/components/ga4/EventBuilder/event.ts +++ b/src/components/ga4/EventBuilder/event.ts @@ -40,12 +40,14 @@ const eventFor = ( type: EventType, categories: Category[], parameters: Parameter[], - firstItem?: Parameter[] + firstItem?: Parameter[], + clients: ("web" | "app")[] = ["web", "app"] ) => ({ type, categories, parameters, items: firstItem === undefined ? undefined : [firstItem], + clients, }) const custom_event = eventFor(EventType.CustomEvent, [Category.Custom], [], []) @@ -60,7 +62,9 @@ const ad_impression = eventFor( stringParam("ad_unit_name", "Banner_03"), stringParam("currency", "USD"), numberParam("value", 3.99), - ] + ], + undefined, + ["app"] ) const add_payment_info = eventFor( @@ -306,7 +310,9 @@ const screen_view = eventFor( [ stringParam("screen_class", "MainActivity"), stringParam("screen_name", "About"), - ] + ], + undefined, + ["app"] ) const search = eventFor( @@ -598,5 +604,11 @@ const events = Object.values(EventType).map(eventType => suggestedEventFor(eventType) ) -export const eventsForCategory = (category: Category) => - events.filter(event => event.categories.find(c => c === category)) +export const eventsForCategory = (category: Category, useFirebase?: boolean) => { + const client = useFirebase ? "app" : "web" + return events.filter( + (event: any) => + event.categories.find((c: any) => c === category) && + event.clients.includes(client) + ) +} diff --git a/src/components/ga4/EventBuilder/index.spec.tsx b/src/components/ga4/EventBuilder/index.spec.tsx index 16596010a..f856c8242 100644 --- a/src/components/ga4/EventBuilder/index.spec.tsx +++ b/src/components/ga4/EventBuilder/index.spec.tsx @@ -49,7 +49,7 @@ describe("Event Builder", () => { const { wrapped } = withProviders(, { isLoggedIn: false }) const { findByLabelText, findByTestId } = renderer.render(wrapped) - await renderer.act(async () => { + await React.act(async () => { // Choose the second view in the list const clientToggle = await findByTestId("use firebase") clientToggle.click() @@ -94,7 +94,7 @@ describe("Event Builder", () => { exact: false, }) - await renderer.act(async () => { + await React.act(async () => { await userEvent.type(apiSecret, "my_secret", { delay: 1 }) await userEvent.type(firebaseAppId, "my_firebase_app_id", { delay: 1, @@ -145,7 +145,7 @@ describe("Event Builder", () => { wrapped ) - await renderer.act(async () => { + await React.act(async () => { // Choose the second view in the list const clientToggle = await findByTestId("use firebase") clientToggle.click() @@ -166,7 +166,7 @@ describe("Event Builder", () => { exact: false, }) - await renderer.act(async () => { + await React.act(async () => { await userEvent.type(apiSecret, "my_secret", { delay: 1 }) await userEvent.type(measurementId, "my_measurement_id", { delay: 1, @@ -187,7 +187,7 @@ describe("Event Builder", () => { const enInput = within(eventName).getByRole("combobox") //eventCategory.focus() - renderer.fireEvent.change(enInput, { target: { value: "select_content" } }) + renderer.fireEvent.change(enInput, { target: { value: "campaign_details" } }) await userEvent.type( timestampMicros, @@ -208,9 +208,28 @@ describe("Event Builder", () => { expect(payload).toHaveTextContent(/"user_id":"my_user_id"/) expect(payload).toHaveTextContent(/"timestamp_micros":"1234"/) expect(payload).toHaveTextContent(/"non_personalized_ads":true/) - expect(payload).toHaveTextContent(/"name":"select_content"/) + expect(payload).toHaveTextContent(/"name":"campaign_details"/) }) }) }) }) + describe("for firebase switch", () => { + test("app only event ad_impression is not available", async () => { + const { wrapped } = withProviders(, { isLoggedIn: false }) + const { findByTestId } = renderer.render(wrapped) + + await React.act(async () => { + const clientToggle = await findByTestId("use firebase") + clientToggle.click() + }) + + const eventName = await findByTestId(Label.EventName) + const enInput = within(eventName).getByRole("combobox") + eventName.focus() + renderer.fireEvent.change(enInput, { target: { value: "ad" } }) + + const adImpression = renderer.screen.queryByText("ad_impression") + expect(adImpression).toBeNull() + }) + }) }) diff --git a/src/components/ga4/EventBuilder/index.tsx b/src/components/ga4/EventBuilder/index.tsx index aa185437d..34fed9eaa 100644 --- a/src/components/ga4/EventBuilder/index.tsx +++ b/src/components/ga4/EventBuilder/index.tsx @@ -226,6 +226,11 @@ const EventBuilder: React.FC = () => { setNonPersonalizedAds, } = useInputs(categories) + const eventOptions = React.useMemo( + () => eventsForCategory(category, useFirebase), + [category, useFirebase] + ) + const formatPayload = React.useCallback( () => { try { if (inputPayload) { @@ -274,11 +279,22 @@ const EventBuilder: React.FC = () => { data-testid="use firebase" checked={useFirebase} onChange={e => { - setUseFirebase(e.target.checked) + const newUseFirebase = e.target.checked + setUseFirebase(newUseFirebase) if (!e.target.checked) { setUseTextBox(false) } + + // Always reset the event type when the client changes. + const newOptions = eventsForCategory(category, newUseFirebase) + if (newOptions.length > 0) { + setType(newOptions[0].type) + } else { + // If the new client has no events for this category, switch to Custom. + setCategory(Category.Custom) + setType(EventType.CustomEvent) + } }} name="use firebase" color="primary" @@ -446,9 +462,15 @@ const EventBuilder: React.FC = () => { value={category} onChange={(_event, value) => { setCategory(value as Category) - const events = eventsForCategory(value as Category) - if (events.length > 0) { - setType(events[0].type) + const newOptions = eventsForCategory( + value as Category, + useFirebase + ) + if (newOptions.length > 0) { + setType(newOptions[0].type) + } else { + setCategory(Category.Custom) + setType(EventType.CustomEvent) } }} renderInput={params => ( @@ -483,7 +505,7 @@ const EventBuilder: React.FC = () => { autoComplete autoHighlight autoSelect - options={eventsForCategory(category).map(e => e.type)} + options={eventOptions.map(e => e.type)} getOptionLabel={eventType => eventType} value={type} onChange={(_event, value) => {