-
Notifications
You must be signed in to change notification settings - Fork 290
Add remote enable/disable of gift card providers via info server #6032
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import { describe, expect, test } from '@jest/globals' | ||
|
|
||
| import type { NestedDisableMap } from '../actions/ExchangeInfoActions' | ||
| import { | ||
| asGiftCardInfo, | ||
| isGiftCardBrandDisabled, | ||
| isGiftCardProviderDisabled | ||
| } from '../actions/GiftCardInfoActions' | ||
|
|
||
| describe('asGiftCardInfo cleaner', () => { | ||
| test('defaults to an empty disable map when disablePlugins is missing', () => { | ||
| expect(asGiftCardInfo({})).toEqual({ disablePlugins: {} }) | ||
| }) | ||
|
|
||
| test('parses whole-provider and per-brand disable maps', () => { | ||
| const parsed = asGiftCardInfo({ | ||
| disablePlugins: { | ||
| bitrefill: true, | ||
| phaze: { '12345': true } | ||
| } | ||
| }) | ||
| expect(parsed.disablePlugins).toEqual({ | ||
| bitrefill: true, | ||
| phaze: { '12345': true } | ||
| }) | ||
| }) | ||
| }) | ||
|
|
||
| describe('isGiftCardProviderDisabled', () => { | ||
| test('true only when the provider is disabled as a whole', () => { | ||
| expect(isGiftCardProviderDisabled({ bitrefill: true }, 'bitrefill')).toBe( | ||
| true | ||
| ) | ||
| expect(isGiftCardProviderDisabled({}, 'bitrefill')).toBe(false) | ||
| // A per-brand map disables brands, not the whole provider | ||
| expect(isGiftCardProviderDisabled({ phaze: { '1': true } }, 'phaze')).toBe( | ||
| false | ||
| ) | ||
| }) | ||
| }) | ||
|
|
||
| describe('isGiftCardBrandDisabled', () => { | ||
| test('true when the whole provider is disabled', () => { | ||
| expect(isGiftCardBrandDisabled({ phaze: true }, 'phaze', '12345')).toBe( | ||
| true | ||
| ) | ||
| }) | ||
|
|
||
| test('true only for the specific disabled brand', () => { | ||
| const disablePlugins: NestedDisableMap = { phaze: { '12345': true } } | ||
| expect(isGiftCardBrandDisabled(disablePlugins, 'phaze', '12345')).toBe(true) | ||
| expect(isGiftCardBrandDisabled(disablePlugins, 'phaze', '99999')).toBe( | ||
| false | ||
| ) | ||
| }) | ||
|
|
||
| test('false when the provider is absent from the map', () => { | ||
| expect(isGiftCardBrandDisabled({}, 'phaze', '12345')).toBe(false) | ||
| }) | ||
| }) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,60 @@ | ||
| import { asMaybe, asObject } from 'cleaners' | ||
|
|
||
| import type { ThunkAction } from '../types/reduxTypes' | ||
| import { infoServerData } from '../util/network' | ||
| import { | ||
| asNestedDisableMap, | ||
| type NestedDisableMap | ||
| } from './ExchangeInfoActions' | ||
|
|
||
| // Remote enable/disable config for gift card providers, served by the info | ||
| // server as `giftCardInfo`. `disablePlugins` is a generic NestedDisableMap | ||
| // keyed by providerId, so it works for any present or future provider: | ||
| // { phaze: true } // disable the entire provider | ||
| // { phaze: { '12345': true } } // disable a single brand by productId | ||
| // { bitrefill: true } // webview provider: whole-provider only | ||
| export const asGiftCardInfo = asObject({ | ||
| disablePlugins: asMaybe(asNestedDisableMap, () => ({})) | ||
| }) | ||
|
|
||
| export type GiftCardInfo = ReturnType<typeof asGiftCardInfo> | ||
|
|
||
| export function updateGiftCardInfo(): ThunkAction<Promise<void>> { | ||
| return async dispatch => { | ||
| try { | ||
| // `giftCardInfo` is a forward-compatible read: the field arrives once the | ||
| // edge-info-server dependency that defines it is published and bumped. | ||
| // Until then the rollup omits it and we fall back to an empty config. | ||
| const rollup = infoServerData.rollup as | ||
| | { giftCardInfo?: unknown } | ||
| | undefined | ||
| const data = asGiftCardInfo(rollup?.giftCardInfo ?? {}) | ||
| dispatch({ type: 'UPDATE_GIFT_CARD_INFO', data }) | ||
| } catch (e: unknown) { | ||
| const message = e instanceof Error ? e.message : String(e) | ||
| console.warn(`Failed to get info server giftCardInfo: ${message}`) | ||
| } | ||
| } | ||
| } | ||
|
|
||
| /** True when the entire provider is remotely disabled. */ | ||
| export const isGiftCardProviderDisabled = ( | ||
| disablePlugins: NestedDisableMap, | ||
| pluginId: string | ||
| ): boolean => disablePlugins[pluginId] === true | ||
|
|
||
| /** | ||
| * True when a specific brand within a provider is remotely disabled — either | ||
| * because the whole provider is disabled, or because the brand is listed | ||
| * individually. | ||
| */ | ||
| export const isGiftCardBrandDisabled = ( | ||
| disablePlugins: NestedDisableMap, | ||
| pluginId: string, | ||
| brandId: string | ||
| ): boolean => { | ||
| const providerNode = disablePlugins[pluginId] | ||
| if (providerNode === true) return true | ||
| if (providerNode == null) return false | ||
| return providerNode[brandId] === true | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import type { GiftCardInfo } from '../actions/GiftCardInfoActions' | ||
| import type { Action } from '../types/reduxTypes' | ||
|
|
||
| export const initialState: GiftCardInfo = { | ||
| disablePlugins: {} | ||
| } | ||
|
|
||
| export const giftCardInfo = ( | ||
| state: GiftCardInfo = initialState, | ||
| action: Action | ||
| ): GiftCardInfo => { | ||
| switch (action.type) { | ||
| case 'UPDATE_GIFT_CARD_INFO': { | ||
| return { | ||
| ...state, | ||
| ...action.data | ||
| } | ||
| } | ||
| default: | ||
| return state | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.