Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions node/clients/intsch/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ import { parseState } from '../../utils/searchState'
import {
filterUndefinedNonNull,
filterByAllowedIntelligentSearchQueryKeys,
shouldInjectDPPreview,
} from './utils'

export class Intsch extends JanusClient implements IIntelligentSearchClient {
Expand Down Expand Up @@ -171,6 +172,10 @@ export class Intsch extends JanusClient implements IIntelligentSearchClient {

const requestPath = `/api/intelligent-search/v1/product-search/${path}`

const dpPreview = shouldInjectDPPreview(this.context.production)
? 'true'
: undefined

const merged = filterUndefinedNonNull({
sc: params.salesChannel ? params.salesChannel : segmentParams?.sc,
regionId: params.regionId ?? segmentParams?.regionId,
Expand Down Expand Up @@ -208,6 +213,7 @@ export class Intsch extends JanusClient implements IIntelligentSearchClient {
: undefined,
simulationBehavior: params.simulationBehavior ?? undefined,
variant: params.variant,
dpPreview,
...parseState(searchState),
})

Expand Down Expand Up @@ -253,6 +259,10 @@ export class Intsch extends JanusClient implements IIntelligentSearchClient {

const facetsPath = `/api/intelligent-search/v1/facets/${path}`

const dpPreview = shouldInjectDPPreview(this.context.production)
? 'true'
: undefined

const merged = filterUndefinedNonNull({
sc: segmentParams?.sc,
regionId: params.regionId ?? segmentParams?.regionId,
Expand All @@ -272,6 +282,7 @@ export class Intsch extends JanusClient implements IIntelligentSearchClient {
locale: this.locale ?? segmentParams?.locale,
bgy_leap: leap ? 'true' : undefined,
variant: params.variant,
dpPreview,
...parseState(searchState),
} as Record<string, unknown>)

Expand Down
57 changes: 57 additions & 0 deletions node/clients/intsch/utils.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import {
filterByAllowedIntelligentSearchQueryKeys,
filterUndefinedNonNull,
shouldInjectDPPreview,
} from './utils'

describe('filterUndefinedNonNull', () => {
it('drops undefined and null values', () => {
expect(
filterUndefinedNonNull({ a: 1, b: undefined, c: null, d: 'x' })
).toEqual({ a: 1, d: 'x' })
})

it('keeps falsy-but-meaningful values (false, "", 0)', () => {
expect(filterUndefinedNonNull({ a: false, b: '', c: 0 })).toEqual({
a: false,
b: '',
c: 0,
})
})
})

describe('filterByAllowedIntelligentSearchQueryKeys', () => {
it('keeps known IS API query keys and drops unknown ones', () => {
const result = filterByAllowedIntelligentSearchQueryKeys({
query: 'shoes',
foo: 'bar',
regionId: 'r1',
})
expect(result).toEqual({ query: 'shoes', regionId: 'r1' })
})

it('accepts the DPT-67 dpPreview key on the allowlist', () => {
const result = filterByAllowedIntelligentSearchQueryKeys({
dpPreview: 'true',
ignored: 'value',
})
expect(result).toEqual({ dpPreview: 'true' })
})
})

/**
* DPT-67: production-driven QA mode. The storefront emits `dpPreview=true` on
* non-production workspaces so the IS API activates the Delivery Promises code
* path without the store having to flip `deliveryPromisesEnabled`. Production
* traffic must never carry the param — including named workspaces promoted to
* production, not just `master`.
*/
describe('shouldInjectDPPreview', () => {
it('returns true for a non-production (QA/dev) workspace', () => {
expect(shouldInjectDPPreview(false)).toBe(true)
})

it('returns false for a production workspace', () => {
expect(shouldInjectDPPreview(true)).toBe(false)
})
})
12 changes: 12 additions & 0 deletions node/clients/intsch/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,20 @@ export const INTELLIGENT_SEARCH_PRODUCT_QUERY_KEYS = new Set<string>([
'priceTables',
'simulationBehavior',
'variant',
'dpPreview',
])

/**
* Whether the IS API call should carry `dpPreview=true`. Non-production
* workspaces are treated as QA and get DP activated end-to-end without the
* store flipping `deliveryPromisesEnabled`. Production workspaces never carry
* the param — including named workspaces promoted to production, not just
* `master`.
*/
export function shouldInjectDPPreview(production: boolean): boolean {
return !production
}

export function filterByAllowedIntelligentSearchQueryKeys(
obj: Record<string, unknown>,
allowedKeys: Set<string> = INTELLIGENT_SEARCH_PRODUCT_QUERY_KEYS
Expand Down
Loading