Skip to content

Commit

Permalink
v6 - Removing Card 'showBrandsUnderCardNumber' property (#2441)
Browse files Browse the repository at this point in the history
  • Loading branch information
ribeiroguilherme authored Nov 23, 2023
1 parent b58aea2 commit 09ec83b
Show file tree
Hide file tree
Showing 22 changed files with 73 additions and 305 deletions.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -8,24 +8,17 @@ fixture`Cards - Available brands on Card Component`.page(CARDS_URL).beforeEach(a
cardComponent = new CardComponent('.card-field');
});

test('#1 Available brands dont show underneath Card Number field if property `showBrandsUnderCardNumber` is set to false', async t => {
// Wait for field to appear in DOM
await cardComponent.numHolder();
const brandsInsidePaymentMethod = Selector('.adyen-checkout__card__brands');
await t.expect(brandsInsidePaymentMethod.find('img').count).eql(0);
}).clientScripts('./availableBrands.disabled.clientScripts.js');

/**
* NOTE: this test ALWAYS fails if other test files are run i.e. only if this fixture is run in isolation does this test pass
* So it is a false negative from TestCafe.
*/
test('#2 Available brands show underneath Card Number field by default', async t => {
test('#1 Available brands show underneath Card Number field by default', async t => {
await cardComponent.numHolder();
const brandsInsidePaymentMethod = Selector('.adyen-checkout__card__brands');
await t.expect(brandsInsidePaymentMethod.find('img').count).eql(10);
}).clientScripts('./availableBrands.clientScripts.js');

test('#3 Available brands show underneath Card Number field but with excluded brands missing', async t => {
test('#2 Available brands show underneath Card Number field but with excluded brands missing', async t => {
await cardComponent.numHolder();
const brandsInsidePaymentMethod = Selector('.adyen-checkout__card__brands');
await t.expect(brandsInsidePaymentMethod.find('img').count).eql(7);
Expand Down
4 changes: 1 addition & 3 deletions packages/lib/src/components/Card/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ export class CardElement extends UIElement<CardConfiguration> {

protected static defaultProps = {
onBinLookup: () => {},
showBrandsUnderCardNumber: true,
showFormInstruction: true,
_disableClickToPay: false
};
Expand Down Expand Up @@ -134,8 +133,7 @@ export class CardElement extends UIElement<CardConfiguration> {
}

public onBrand = event => {
this.eventEmitter.emit('brand', { ...event, brand: event.brand === 'card' ? null : event.brand });
if (this.props.onBrand) this.props.onBrand(event);
this.props.onBrand?.(event);
};

processBinLookupResponse(binLookupResponse: BinLookupResponse, isReset = false) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,7 @@ const cardInputRequiredProps = {
clientKey: 'xxxx',
loadingContext: 'test',
resources: global.resources,
brandsIcons: [],
showBrandsUnderCardNumber: true
brandsIcons: []
};

const getWrapper = ui => {
Expand All @@ -54,22 +53,7 @@ describe('CardInput', () => {
});

describe('CardInput - Brands beneath Card Number field', () => {
test('should not render brands if property `showBrandsUnderCardNumber` is set to false', () => {
const wrapper = getWrapper(<CardInput {...cardInputRequiredProps} showBrandsUnderCardNumber={false} />);
expect(wrapper.find('span.adyen-checkout__card__brands').exists()).toBeFalsy();
});

test('should render brands if property `showBrandsUnderCardNumber` is set', () => {
const brandsIcons = [
{ name: 'visa', icon: 'visa.png' },
{ name: 'mc', icon: 'mc.png' }
];
const wrapper = getWrapper(<CardInput {...cardInputRequiredProps} showBrandsUnderCardNumber brandsIcons={brandsIcons} />);
expect(wrapper.find('.adyen-checkout__card__brands__brand-wrapper')).toHaveLength(2);
expect(wrapper.find('.adyen-checkout__card__brands__brand-wrapper--disabled')).toHaveLength(0);
});

test('should render brands if property `showBrandsUnderCardNumber` is not set', () => {
test('should render brands under Card number field', () => {
const brandsIcons = [
{ name: 'visa', icon: 'visa.png' },
{ name: 'mc', icon: 'mc.png' }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ export default function CardFields({
expiryDatePolicy,
onFocusField,
showBrandIcon,
showBrandsUnderCardNumber,
valid,
showContextualElement
}: CardFieldsProps) {
Expand Down Expand Up @@ -62,7 +61,7 @@ export default function CardFields({
dualBrandingSelected={dualBrandingSelected}
/>

{showBrandsUnderCardNumber && <AvailableBrands activeBrand={brand} brands={allowedBrands} />}
<AvailableBrands activeBrand={brand} brands={allowedBrands} />

<div
className={classNames('adyen-checkout__card__exp-cvc adyen-checkout__field-wrapper', {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ export const CardFieldsWrapper = ({
positionHolderNameOnTop,
// For CardFields > CardNumber
showBrandIcon,
showBrandsUnderCardNumber,
showContextualElement,
//
iOSFocusedField,
Expand All @@ -86,7 +85,6 @@ export const CardFieldsWrapper = ({

<CardFields
showBrandIcon={showBrandIcon}
showBrandsUnderCardNumber={showBrandsUnderCardNumber}
showContextualElement={showContextualElement}
brand={sfpState.brand}
brandsIcons={brandsIcons}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ export interface CardFieldsProps {
expiryDatePolicy?: DatePolicyType;
onFocusField?: any;
showBrandIcon?: boolean;
showBrandsUnderCardNumber: boolean;
valid?: any;
showContextualElement?: boolean;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ export default {
enableStoreDetails: false,
hasCVC: true,
showBrandIcon: true,
showBrandsUnderCardNumber: true,
positionHolderNameOnTop: false,
billingAddressRequired: false,
billingAddressMode: AddressModeOptions.full,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,6 @@ export interface CardInputProps {
positionHolderNameOnTop?: boolean;
resources: Resources;
setComponentRef?: (ref) => void;
showBrandsUnderCardNumber: boolean;
showBrandIcon?: boolean;
showFormInstruction?: boolean;
showInstallmentAmounts?: boolean;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ export const extractPropsForCardFields = (props: CardInputProps) => {
positionHolderNameOnTop: props.positionHolderNameOnTop,
// Extract props for CardFields > CardNumber
showBrandIcon: props.showBrandIcon,
showBrandsUnderCardNumber: props.showBrandsUnderCardNumber,
showContextualElement: props.showContextualElement,
// Extract props for StoredCardFields
lastFour: props.lastFour,
Expand Down
6 changes: 0 additions & 6 deletions packages/lib/src/components/Card/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,6 @@ export interface CardConfiguration extends UIElementProps {
/** List of brands accepted by the component */
brands?: string[];

/**
* Show/hide available card brands under the Card number field
* @defaultValue `false`
*/
showBrandsUnderCardNumber?: boolean;

/**
* Position holder name above card number field (instead of having it after the security code field)
* @defaultValue `false`
Expand Down

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,31 +1,47 @@
import { h } from 'preact';
import { mount } from 'enzyme';
import { render, screen } from '@testing-library/preact';
import PaymentMethodBrands from './PaymentMethodBrands';
import CompactView from './CompactView';
import PaymentMethodIcon from '../PaymentMethodIcon';

const brands = [
{ name: 'visa', icon: 'visa.png' },
{ name: 'mc', icon: 'mc.png' },
{ name: 'amex', icon: 'amex.png' },
{ name: 'discovery', icon: 'discovery.png' },
{ name: 'vpay', icon: 'vpay.png' },
{ name: 'maestro', icon: 'maestro.png' }
];

describe('PaymentMethodBrands', () => {
test('should render compact view if prop is set', () => {
const wrapper = mount(<PaymentMethodBrands brands={brands} isPaymentMethodSelected={false} isCompactView />);
expect(wrapper.find(CompactView)).toHaveLength(1);
test('should not render anything if payment method is selected', () => {
const brands = [{ name: 'visa', icon: 'visa.png' }];
const { container } = render(<PaymentMethodBrands brands={brands} isPaymentMethodSelected={true} />);

expect(container).toBeEmptyDOMElement();
});

test('should render compact view if prop is not', () => {
const wrapper = mount(<PaymentMethodBrands brands={brands} isPaymentMethodSelected />);
expect(wrapper.find(CompactView)).toHaveLength(1);
test('should render three brands', () => {
const brands = [
{ name: 'visa', icon: 'visa.png' },
{ name: 'mc', icon: 'mc.png' },
{ name: 'amex', icon: 'amex.png' }
];

render(<PaymentMethodBrands brands={brands} isPaymentMethodSelected={false} />);

screen.getByAltText('VISA');
screen.getByAltText('MasterCard');
screen.getByAltText('American Express');

expect(screen.queryByText(/\+/)).toBeNull();
});

test('should not render compact view if prop is set to false', () => {
const wrapper = mount(<PaymentMethodBrands brands={brands} isPaymentMethodSelected isCompactView={false} />);
expect(wrapper.find(PaymentMethodIcon)).toHaveLength(6);
test('should render three brands AND number of left over brands', () => {
const brands = [
{ name: 'visa', icon: 'visa.png' },
{ name: 'mc', icon: 'mc.png' },
{ name: 'amex', icon: 'amex.png' },
{ name: 'discovery', icon: 'discovery.png' },
{ name: 'vpay', icon: 'vpay.png' },
{ name: 'maestro', icon: 'maestro.png' }
];

render(<PaymentMethodBrands brands={brands} isPaymentMethodSelected={false} />);

screen.getByAltText('VISA');
screen.getByAltText('MasterCard');
screen.getByAltText('American Express');

screen.getByText('+3');
});
});
Original file line number Diff line number Diff line change
@@ -1,41 +1,36 @@
import { h } from 'preact';
import PaymentMethodIcon from '../PaymentMethodIcon';
import { BrandConfiguration } from '../../../../Card/types';
import CompactView from './CompactView';
import PaymentMethodIcon from '../PaymentMethodIcon';
import { getFullBrandName } from '../../../../Card/components/CardInput/utils';

const prepareVisibleBrands = (allowedBrands: Array<BrandConfiguration>) => {
const visibleBrands = allowedBrands.length <= 4 ? allowedBrands : allowedBrands.slice(0, 3);
return {
visibleBrands,
leftBrandsAmount: allowedBrands.length - visibleBrands.length
};
};

interface PaymentMethodBrandsProps {
brands: Array<BrandConfiguration>;
excludedUIBrands?: Array<string>; // A list of brands that can never appear in the UI
excludedUIBrands?: Array<string>;
isPaymentMethodSelected: boolean;
activeBrand?: string;
isCompactView?: boolean;
}

const PaymentMethodBrands = ({
activeBrand,
brands,
excludedUIBrands = [],
isPaymentMethodSelected,
isCompactView = true
}: PaymentMethodBrandsProps) => {
// A set of brands filtered to exclude those that can never appear in the UI
const PaymentMethodBrands = ({ brands, excludedUIBrands = [], isPaymentMethodSelected }: PaymentMethodBrandsProps) => {
if (isPaymentMethodSelected) {
return null;
}

const allowedBrands = brands.filter(brand => !excludedUIBrands?.includes(brand.name));
const { visibleBrands, leftBrandsAmount } = prepareVisibleBrands(allowedBrands);

if (isCompactView) {
return <CompactView allowedBrands={allowedBrands} isPaymentMethodSelected={isPaymentMethodSelected} />;
}
return (
<span className="adyen-checkout__payment-method__brands">
{allowedBrands.map(brand => (
<PaymentMethodIcon
key={brand.name}
altDescription={getFullBrandName(brand.name)}
type={brand.name}
src={brand.icon}
disabled={activeBrand && activeBrand !== brand.name}
/>
{visibleBrands.map(brand => (
<PaymentMethodIcon key={brand.name} altDescription={getFullBrandName(brand.name)} type={brand.name} src={brand.icon} />
))}
{leftBrandsAmount !== 0 && <span className="adyen-checkout__payment-method__brand-number">+{leftBrandsAmount}</span>}
</span>
);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ const paymentMethod = {
props: {
type: 'mytype'
},
eventEmitter: { on: jest.fn(), off: jest.fn() },
render: jest.fn()
};

Expand Down
Loading

0 comments on commit 09ec83b

Please sign in to comment.