Skip to content

Commit

Permalink
feat(Bonus Pagamenti Digitali): [#175883590] Satispay and Bancomatpay…
Browse files Browse the repository at this point in the history
… selector (#2429)

* [#175883590] add missing selectors & refactoring

* [#175883590] add test

* [#175883590] update comments

* [#175883590] test fix changelog

* [#175883590] test

* [#175883590] fix changelog

Co-authored-by: Matteo Boschi <[email protected]>
  • Loading branch information
fabriziofff and Undermaken authored Nov 26, 2020
1 parent 9e51f3a commit 1e22fb0
Show file tree
Hide file tree
Showing 8 changed files with 172 additions and 85 deletions.
7 changes: 5 additions & 2 deletions scripts/changelog/ts/__tests__/changelog.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,9 +75,12 @@ describe("Test pivotal Utility", () => {
const eitherScope = getStoryChangelogScope(clashScopeLabelStory);
expect(eitherScope.isLeft()).toBeTruthy();
});
it("getStoryChangelogScope on a story with scope label not allowed should return Left,Error", () => {
it("getStoryChangelogScope on a story with scope label not allowed should return Right,none", () => {
const eitherScope = getStoryChangelogScope(scopeLabelNotAllowedStory);
expect(eitherScope.isLeft()).toBeTruthy();
expect(eitherScope.isRight()).toBeTruthy();
if (eitherScope.isRight()) {
expect(eitherScope.value).toBe(none);
}
});
it("getStoryChangelogScope on a story with a scope labels and belonging to a project that assigns a scope should return Left,Error", () => {
const eitherScope = getStoryChangelogScope(bonusVacanzeStoryWithScopeLabel);
Expand Down
3 changes: 2 additions & 1 deletion scripts/changelog/ts/changelog.ts
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ export const getStoryChangelogScope = (
// search for scope labels associated with the story
const maybeChangelogScopeTag = story.labels
.filter(l => l.name.match(regex))
.map(l => l.name.match(regex)!.pop());
.map(l => l.name.match(regex)!.pop())
.filter(tag => tag && allowedScope.has(tag));

// multiple scope labels found on the story
if (maybeChangelogScopeTag.length > 1) {
Expand Down
4 changes: 2 additions & 2 deletions ts/features/wallet/component/WalletV2PreviewCards.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import * as React from "react";
import { connect } from "react-redux";
import { Dispatch } from "redux";
import { GlobalState } from "../../../store/reducers/types";
import { bancomatSelector } from "../../../store/reducers/wallet/wallets";
import { bancomatListSelector } from "../../../store/reducers/wallet/wallets";
import BancomatWalletPreview from "../bancomat/component/BancomatWalletPreview";

type Props = ReturnType<typeof mapDispatchToProps> &
Expand Down Expand Up @@ -36,7 +36,7 @@ const WalletV2PreviewCards: React.FunctionComponent<Props> = props => (
const mapDispatchToProps = (_: Dispatch) => ({});

const mapStateToProps = (state: GlobalState) => ({
bancomatList: bancomatSelector(state)
bancomatList: bancomatListSelector(state)
});

export default connect(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { getType } from "typesafe-actions";
import { Action } from "../../../../../../store/actions/types";
import {
BancomatPaymentMethod,
enhanceBancomat,
RawBancomatPaymentMethod
} from "../../../../../../types/pagopa";
import { enhanceBancomat } from "../../../../../../utils/paymentMethod";
import { getValueOrElse } from "../../../../../bonus/bpd/model/RemoteValue";
import { abiSelector } from "../../../store/abi";
import { addBancomatToWallet, walletAddBancomatStart } from "../actions";
Expand Down
86 changes: 69 additions & 17 deletions ts/store/reducers/wallet/__tests__/wallets.test.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
import { Either } from "fp-ts/lib/Either";
import { Errors } from "io-ts";
import * as pot from "italia-ts-commons/lib/pot";
import { remoteUndefined } from "../../../../features/bonus/bpd/model/RemoteValue";
import {
isRawCreditCard,
PatchedWalletV2ListResponse
} from "../../../../types/pagopa";
import { walletsV2_2, walletsV2_1 } from "../__mocks__/wallets";
import { walletsV2_2, walletsV2_1, walletsV2_3 } from "../__mocks__/wallets";
import { toIndexed } from "../../../helpers/indexer";
import {
bancomatSelector,
bancomatListSelector,
bPayListSelector,
creditCardListSelector,
creditCardWalletV1Selector,
pagoPaCreditCardWalletV1Selector
pagoPaCreditCardWalletV1Selector,
satispayListSelector
} from "../wallets";
import { GlobalState } from "../../types";
import { convertWalletV2toWalletV1 } from "../../../../utils/walletv2";
Expand Down Expand Up @@ -51,7 +56,7 @@ describe("walletV2 selectors", () => {
});

it("should return bancomat", () => {
const maybeBancomat = bancomatSelector(globalState);
const maybeBancomat = bancomatListSelector(globalState);
expect(pot.isSome(maybeBancomat)).toBeTruthy();
const hpans = [
"a591ab131bd9492e6df0357f1ac52785a96ddc8e772baddbb02e2169af9474f4",
Expand Down Expand Up @@ -82,23 +87,70 @@ describe("walletV2 selectors", () => {

it("should return empty list since there is no method compliant with pagoPa", () => {
const maybeWallets = PatchedWalletV2ListResponse.decode(walletsV2_2);
const indexedWallets = toIndexed(
(maybeWallets.value as PatchedWalletV2ListResponse).data!.map(
convertWalletV2toWalletV1
),
w => w.idWallet
);
const globalState = ({
wallet: {
wallets: {
walletById: pot.some(indexedWallets)
}
}
} as any) as GlobalState;
const globalState = mockWalletState(maybeWallets);
const maybePagoPaCC = pagoPaCreditCardWalletV1Selector(globalState);
expect(pot.isSome(maybePagoPaCC)).toBeTruthy();
if (pot.isSome(maybePagoPaCC)) {
expect(maybePagoPaCC.value.length).toEqual(0);
}
});
it("should filter credit card and return one", () => {
const maybeWallets = PatchedWalletV2ListResponse.decode(walletsV2_3);
const globalState = mockWalletState(maybeWallets);
const potCreditCard = creditCardListSelector(globalState);
expect(pot.isSome(potCreditCard)).toBeTruthy();
expect(pot.getOrElse(potCreditCard, undefined)).toBeDefined();
if (pot.isSome(potCreditCard)) {
expect(potCreditCard.value.length).toEqual(1);
}
});
it("should filter bancomat and return one", () => {
const maybeWallets = PatchedWalletV2ListResponse.decode(walletsV2_3);
const globalState = mockWalletState(maybeWallets);
const potBancomat = bancomatListSelector(globalState);
expect(pot.isSome(potBancomat)).toBeTruthy();
expect(pot.getOrElse(potBancomat, undefined)).toBeDefined();
if (pot.isSome(potBancomat)) {
expect(potBancomat.value.length).toEqual(1);
}
});
it("should filter BPay and return one", () => {
const maybeWallets = PatchedWalletV2ListResponse.decode(walletsV2_3);
const globalState = mockWalletState(maybeWallets);
const potBPay = bPayListSelector(globalState);
expect(pot.isSome(potBPay)).toBeTruthy();
expect(pot.getOrElse(potBPay, undefined)).toBeDefined();
if (pot.isSome(potBPay)) {
expect(potBPay.value.length).toEqual(1);
}
});
it("should filter satispay and return one", () => {
const maybeWallets = PatchedWalletV2ListResponse.decode(walletsV2_3);
const globalState = mockWalletState(maybeWallets);
const potSatispay = satispayListSelector(globalState);
expect(pot.isSome(potSatispay)).toBeTruthy();
expect(pot.getOrElse(potSatispay, undefined)).toBeDefined();
if (pot.isSome(potSatispay)) {
expect(potSatispay.value.length).toEqual(1);
}
});
});

const mockWalletState = (
walletResponse: Either<Errors, PatchedWalletV2ListResponse>
) => {
const indexedWallets = toIndexed(
(walletResponse.value as PatchedWalletV2ListResponse).data!.map(
convertWalletV2toWalletV1
),
w => w.idWallet
);
return {
wallet: {
abi: remoteUndefined,
wallets: {
walletById: pot.some(indexedWallets)
}
}
} as GlobalState;
};
65 changes: 50 additions & 15 deletions ts/store/reducers/wallet/wallets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,23 @@ import { getValueOrElse } from "../../../features/bonus/bpd/model/RemoteValue";
import { abiSelector } from "../../../features/wallet/onboarding/store/abi";
import {
BancomatPaymentMethod,
enhancePaymentMethod,
BPayPaymentMethod,
CreditCardPaymentMethod,
isBancomat,
isBPay,
isCreditCard,
isRawCreditCard,
isSatispay,
PaymentMethod,
RawCreditCardPaymentMethod,
RawPaymentMethod,
SatispayPaymentMethod,
Wallet
} from "../../../types/pagopa";

import { PotFromActions } from "../../../types/utils";
import { isDefined } from "../../../utils/guards";
import { enhancePaymentMethod } from "../../../utils/paymentMethod";
import { Action } from "../../actions/types";
import { paymentUpdateWalletPsp } from "../../actions/wallet/payment";
import {
Expand Down Expand Up @@ -95,7 +101,7 @@ export const getFavoriteWallet = (state: GlobalState) =>
/**
* @deprecated Using API v2 this selector is deprecated
* If you are searching for credit card or bancomat use {@link creditCardWalletV1Selector}
* - {@link pagoPaCreditCardWalletV1Selector} {@link bancomatSelector} instead
* - {@link pagoPaCreditCardWalletV1Selector} {@link bancomatListSelector} instead
*/
export const walletsSelector = createSelector(
getWallets,
Expand Down Expand Up @@ -142,15 +148,55 @@ export const paymentMethodsSelector = createSelector(
)
);

export const rawCreditCardListSelector = createSelector(
[paymentMethodsSelector],
(
paymentMethods: pot.Pot<ReadonlyArray<RawPaymentMethod>, Error>
): ReadonlyArray<RawCreditCardPaymentMethod> =>
pot.getOrElse(
pot.map(paymentMethods, w => w.filter(isRawCreditCard)),
[]
)
);

/**
* Return a bancomat list enhanced with the additional abi information
* Return a bancomat list enhanced with the additional abi information in the wallet
*/
export const bancomatSelector = createSelector(
export const bancomatListSelector = createSelector(
[paymentMethodsSelector],
(paymentMethodPot): pot.Pot<ReadonlyArray<BancomatPaymentMethod>, Error> =>
pot.map(paymentMethodPot, paymentMethod => paymentMethod.filter(isBancomat))
);

/**
* Return a credit card list in the wallet
*/
export const creditCardListSelector = createSelector(
[paymentMethodsSelector],
(paymentMethodPot): pot.Pot<ReadonlyArray<CreditCardPaymentMethod>, Error> =>
pot.map(paymentMethodPot, paymentMethod =>
paymentMethod.filter(isCreditCard)
)
);

/**
* Return a satispay list in the wallet
*/
export const satispayListSelector = createSelector(
[paymentMethodsSelector],
(paymentMethodPot): pot.Pot<ReadonlyArray<SatispayPaymentMethod>, Error> =>
pot.map(paymentMethodPot, paymentMethod => paymentMethod.filter(isSatispay))
);

/**
* Return a BPay list in the wallet
*/
export const bPayListSelector = createSelector(
[paymentMethodsSelector],
(paymentMethodPot): pot.Pot<ReadonlyArray<BPayPaymentMethod>, Error> =>
pot.map(paymentMethodPot, paymentMethod => paymentMethod.filter(isBPay))
);

/**
* Get the list of credit cards using the info contained in v2 (Walletv2) to distinguish
*/
Expand All @@ -167,17 +213,6 @@ export const creditCardWalletV1Selector = createSelector(
)
);

export const creditCardSelector = createSelector(
[paymentMethodsSelector],
(
paymentMethods: pot.Pot<ReadonlyArray<RawPaymentMethod>, Error>
): ReadonlyArray<RawCreditCardPaymentMethod> =>
pot.getOrElse(
pot.map(paymentMethods, w => w.filter(isRawCreditCard)),
[]
)
);

/**
* Get the list of credit cards usable as payment instrument in pagoPA
* using the info contained in v2 (Walletv2) to distinguish
Expand Down
37 changes: 0 additions & 37 deletions ts/types/pagopa.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,12 @@ import { BPayInfo as BPayInfoPagoPa } from "../../definitions/pagopa/walletv2/BP
import { CardInfo } from "../../definitions/pagopa/walletv2/CardInfo";
import { SatispayInfo as SatispayInfoPagoPa } from "../../definitions/pagopa/walletv2/SatispayInfo";
import { WalletTypeEnum } from "../../definitions/pagopa/walletv2/WalletV2";
import { IndexedById } from "../store/helpers/indexer";
import {
CreditCardCVC,
CreditCardExpirationMonth,
CreditCardExpirationYear,
CreditCardPan
} from "../utils/input";
import {
getImageFromPaymentMethod,
getTitleFromBancomat,
getTitleFromPaymentMethod
} from "../utils/paymentMethod";

/**
* Union of all possible credit card types
Expand Down Expand Up @@ -256,37 +250,6 @@ export const isBPay = (
pm: PaymentMethod | undefined
): pm is BPayPaymentMethod => (pm === undefined ? false : pm.kind === "BPay");

export const enhanceBancomat = (
bancomat: RawBancomatPaymentMethod,
abiList: IndexedById<Abi>
): BancomatPaymentMethod => ({
...bancomat,
abiInfo: bancomat.info.issuerAbiCode
? abiList[bancomat.info.issuerAbiCode]
: undefined,
caption: getTitleFromBancomat(bancomat, abiList),
icon: getImageFromPaymentMethod(bancomat)
});

export const enhancePaymentMethod = (
pm: RawPaymentMethod,
abiList: IndexedById<Abi>
): PaymentMethod => {
switch (pm.kind) {
// bancomat need a special handling, we need to include the abi
case "Bancomat":
return enhanceBancomat(pm, abiList);
case "CreditCard":
case "BPay":
case "Satispay":
return {
...pm,
caption: getTitleFromPaymentMethod(pm, abiList),
icon: getImageFromPaymentMethod(pm)
};
}
};

/**
* A refined Wallet
*/
Expand Down
Loading

0 comments on commit 1e22fb0

Please sign in to comment.