Skip to content

Add mParticle template targeting to tests - #1809

Merged
zaraGNM merged 16 commits into
mainfrom
mParticle-attributes
Sep 15, 2026
Merged

zaraGNM merged 16 commits into
mainfrom
mParticle-attributes

Conversation

@zaraGNM

@zaraGNM zaraGNM commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

What does this change?

This PR Introduces support for mParticle template personalisation in both Banners and epics. It allows for substitution of user attributes from mParticle profiles into banner and epic content, based on templates defined in A/B test configurations.

The changes:

  • Added support for mParticleTemplates in both banner and epic A/B test schemas (bannerTestFromToolSchema and epicTestFromToolSchema) and their corresponding props, allowing tests to specify which mParticle user attributes should be substituted into content.
  • Implemented helper functions in mParticleTemplates.ts to check for required user attributes (matchesMParticleTemplates) and to substitute attribute values into banner and epic content (substituteMParticleTemplate, substituteMParticleTemplateInBannerVariant, substituteMParticleTemplateInEpicVariant).
  • Modified banner and epic routers to perform template substitution at request time, injecting personalised content into the response if the user profile contains the necessary attributes.
  • Added unit tests for the template substitution logic, covering edge cases such as missing attributes and multiple substitutions.
    Added unit tests for template matching and substitution, covering missing profiles, missing attributes, multiple substitutions, and regular tests that do not require mParticle attributes.

Why are we doing this PR?

Currently, Banner and Epic tests can't use mParticle attributes to personalise their content. Adding mParticle templates means we can personalise content using a user's mParticle attributes, such as first name or previous contribution amount.

How to test?

Tested locally using a stubbed mParticle profile.

  • Add a test mParticle profile containing the required user attribute.
  • Run SDC with MPARTICLE_STUB_PROFILE=true so it uses the test profile instead of the mParticle API.
  • Run dotcom rendering against the local SDC instance.
  • Create an RRCP Banner and Epic named MPARTICLE_ATTRIBUTES_ containing an mParticle template and check that the template is replaced with the value from the test profile.
  • Check that the mParticle attribute is used when selecting the variant.
  • Create a regular Banner and Epic test without MPARTICLE_ATTRIBUTES_ in the name and check that the mParticle menu is not available and mParticle attributes are not required for variant selection.

How can we measure success?

For this PR it is being able to select Banner and Epic variants based on whether a user has the required mParticle attributes, and correctly substitute those attributes into the content.

The wider goal is to enable personalised messaging for users with the right mParticle attributes, and measure the impact through conversion rate and LTV3 per impression.

Screenshots

Banner:

image

Epic:

image

Accessibility

@zaraGNM zaraGNM added the feature Departmental tracking: work on a new feature label Aug 19, 2026
@github-actions

github-actions Bot commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Comment thread src/server/api/bannerRouter.ts Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Unresolved moderate issues remain in profile gating and template matching and substitution.

Get a fresh assessment by requesting another Copilot review.

Pull request overview

Adds mParticle attribute targeting and template substitution for Banner and Epic A/B tests.

Changes:

  • Extends schemas and props with mParticle template configuration.
  • Adds profile matching and content substitution helpers.
  • Integrates targeting and substitution into selection and routers with unit tests.
File summaries
File Reviewed changes
src/shared/types/props/epic.ts Adds mParticle template props.
src/shared/types/props/banner.ts Adds mParticle template props.
src/shared/types/abTests/epic.ts Extends Epic test schema.
src/shared/types/abTests/banner.ts Extends Banner test schema.
src/server/tests/headers/headerSelection.test.ts Updates profile fixtures.
src/server/tests/epics/epicSelection.ts Adds Epic template targeting.
src/server/tests/banners/bannerSelection.ts Adds Banner template targeting.
src/server/lib/targeting.test.ts Updates targeting fixtures.
src/server/lib/mParticleTemplates.ts Implements matching and substitution.
src/server/lib/mParticleTemplates.test.ts Tests template behavior.
src/server/lib/mParticle.ts Supports optional profile attributes.
src/server/api/epicRouter.ts Substitutes Epic content in responses.
src/server/api/bannerRouter.ts Substitutes Banner content in responses.
Review details

Suppressed comments (2)

src/server/lib/mParticleTemplates.ts:24

  • Eligibility checks attribute keys case-sensitively, but substitution deliberately resolves them case-insensitively. For example, a configured FIRST_NAME with a profile key first_name is rejected before the substitution that would have succeeded. Use the same case-insensitive key lookup for matching.
    for (const template of mParticleTemplates) {
        if (!mParticleProfile.user_attributes || !(template in mParticleProfile.user_attributes)) {
            return false;

src/server/lib/mParticleTemplates.ts:74

  • The spread preserves user-visible fields such as cta.text, custom secondary-CTA text, and newsletter successDescription without substitution. Templates placed in any of those EpicVariant fields will therefore remain in the response; the variant helper needs to transform those nested content fields too.
    return {
        ...epicVariant,
        heading: updatedHeading,
        paragraphs: updatedParagraphs,
        highlightedText: updatedHighlightedText,
    };
  • Files reviewed: 13/13 changed files
  • Comments generated: 5
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/server/api/bannerRouter.ts Outdated
Comment thread src/server/api/epicRouter.ts Outdated
Comment thread src/server/lib/mParticleTemplates.ts Outdated
Comment thread src/server/lib/mParticleTemplates.ts
Comment thread src/server/lib/mParticleTemplates.ts
Comment thread src/server/lib/mParticleTemplates.ts Outdated

@tomrf1 tomrf1 left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

great!

@zaraGNM
zaraGNM marked this pull request as ready for review September 15, 2026 15:00
@zaraGNM
zaraGNM requested a review from a team as a code owner September 15, 2026 15:00
@zaraGNM
zaraGNM merged commit 5afa41c into main Sep 15, 2026
8 checks passed
@zaraGNM
zaraGNM deleted the mParticle-attributes branch September 15, 2026 15:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

feature Departmental tracking: work on a new feature

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants