From 0b7969e7c1c96f826586501ff03cfca3e8130980 Mon Sep 17 00:00:00 2001 From: Lindsey Volta Date: Thu, 4 Sep 2025 19:44:11 +0000 Subject: [PATCH 1/4] remove events from reserved events list --- .../EventBuilder/ValidateEvent/handlers/formatCheckLib.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) 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", From 51e96f73dcad396834e4c3a7ee4d1a7576335d07 Mon Sep 17 00:00:00 2001 From: Lindsey Volta Date: Mon, 8 Sep 2025 19:25:05 +0000 Subject: [PATCH 2/4] add stream identifier to event --- src/components/ga4/EventBuilder/event.ts | 22 +++++++++--- .../ga4/EventBuilder/index.spec.tsx | 4 +-- src/components/ga4/EventBuilder/index.tsx | 34 +++++++++++++++---- 3 files changed, 47 insertions(+), 13 deletions(-) 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..7cdf67d40 100644 --- a/src/components/ga4/EventBuilder/index.spec.tsx +++ b/src/components/ga4/EventBuilder/index.spec.tsx @@ -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,7 +208,7 @@ 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"/) }) }) }) diff --git a/src/components/ga4/EventBuilder/index.tsx b/src/components/ga4/EventBuilder/index.tsx index aa185437d..8c4f37aba 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) { @@ -273,12 +278,23 @@ const EventBuilder: React.FC = () => { { - setUseFirebase(e.target.checked) + onChange={e => { + 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) => { From f5c5a0c49bafd4fe2fe53c90ae505d8ca73e6519 Mon Sep 17 00:00:00 2001 From: Lindsey Volta Date: Mon, 8 Sep 2025 20:08:21 +0000 Subject: [PATCH 3/4] add test, cleanup deprecated method use in test file --- .../ga4/EventBuilder/index.spec.tsx | 27 ++++++++++++++++--- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/src/components/ga4/EventBuilder/index.spec.tsx b/src/components/ga4/EventBuilder/index.spec.tsx index 7cdf67d40..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, @@ -213,4 +213,23 @@ describe("Event Builder", () => { }) }) }) + 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() + }) + }) }) From 01a99b19bf9d0a72b970152ee8782dd1afb1e265 Mon Sep 17 00:00:00 2001 From: Lindsey Volta Date: Tue, 9 Sep 2025 20:45:16 +0000 Subject: [PATCH 4/4] fix code formatting --- src/components/ga4/EventBuilder/index.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/ga4/EventBuilder/index.tsx b/src/components/ga4/EventBuilder/index.tsx index 8c4f37aba..34fed9eaa 100644 --- a/src/components/ga4/EventBuilder/index.tsx +++ b/src/components/ga4/EventBuilder/index.tsx @@ -278,7 +278,7 @@ const EventBuilder: React.FC = () => { { + onChange={e => { const newUseFirebase = e.target.checked setUseFirebase(newUseFirebase)