This repository has been archived by the owner on Jan 15, 2025. It is now read-only.
generated from pagopa/io-functions-template
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[#177017837] Added new api for retrieving eyca card (#25)
* added new api for retrieving eyca card
- Loading branch information
Showing
6 changed files
with
287 additions
and
11 deletions.
There are no files selected for viewing
This file contains 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 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,101 @@ | ||
/* tslint:disable: no-any */ | ||
|
||
import * as date_fns from "date-fns"; | ||
import { some } from "fp-ts/lib/Option"; | ||
import { none } from "fp-ts/lib/Option"; | ||
import { fromLeft, taskEither } from "fp-ts/lib/TaskEither"; | ||
import { FiscalCode } from "italia-ts-commons/lib/strings"; | ||
import { NonEmptyString } from "italia-ts-commons/lib/strings"; | ||
import { cgnActivatedDates, now } from "../../__mocks__/mock"; | ||
import { StatusEnum as ActivatedStatusEnum } from "../../generated/definitions/CardActivated"; | ||
import { | ||
CardPending, | ||
StatusEnum as PendingStatusEnum | ||
} from "../../generated/definitions/CardPending"; | ||
import { StatusEnum as RevokedStatusEnum } from "../../generated/definitions/CardRevoked"; | ||
import { EycaCardActivated } from "../../generated/definitions/EycaCardActivated"; | ||
import { EycaCardRevoked } from "../../generated/definitions/EycaCardRevoked"; | ||
import { UserEycaCard, UserEycaCardModel } from "../../models/user_eyca_card"; | ||
import { GetEycaStatusHandler } from "../handler"; | ||
|
||
const aFiscalCode = "RODFDS82S10H501T" as FiscalCode; | ||
const aUserEycaCardNumber = "AN_ID" as NonEmptyString; | ||
|
||
const aPendingEycaCard: CardPending = { | ||
status: PendingStatusEnum.PENDING | ||
}; | ||
|
||
const aUserEycaCard: UserEycaCard = { | ||
card: aPendingEycaCard, | ||
fiscalCode: aFiscalCode | ||
}; | ||
|
||
const aRevokedEycaCard: EycaCardRevoked = { | ||
...cgnActivatedDates, | ||
card_number: aUserEycaCardNumber, | ||
revocation_date: now, | ||
revocation_reason: "A motivation" as NonEmptyString, | ||
status: RevokedStatusEnum.REVOKED | ||
}; | ||
|
||
const findLastVersionByModelIdMock = jest | ||
.fn() | ||
.mockImplementation(() => taskEither.of(some(aUserEycaCard))); | ||
const userEycaCardModelMock = { | ||
findLastVersionByModelId: findLastVersionByModelIdMock | ||
}; | ||
|
||
const anActivatedEycaCard: EycaCardActivated = { | ||
activation_date: now, | ||
card_number: aUserEycaCardNumber, | ||
expiration_date: date_fns.addDays(now, 10), | ||
status: ActivatedStatusEnum.ACTIVATED | ||
}; | ||
|
||
const successImpl = async (userEycaCard: UserEycaCard) => { | ||
const handler = GetEycaStatusHandler(userEycaCardModelMock as any); | ||
const response = await handler({} as any, aFiscalCode); | ||
expect(response.kind).toBe("IResponseSuccessJson"); | ||
if (response.kind === "IResponseSuccessJson") { | ||
expect(response.value).toEqual({ | ||
...userEycaCard.card | ||
}); | ||
} | ||
}; | ||
describe("GetEycaCardStatusHandler", () => { | ||
it("should return an internal error when a query error occurs", async () => { | ||
findLastVersionByModelIdMock.mockImplementationOnce(() => | ||
fromLeft(new Error("Query Error")) | ||
); | ||
const handler = GetEycaStatusHandler(userEycaCardModelMock as any); | ||
const response = await handler({} as any, aFiscalCode); | ||
expect(response.kind).toBe("IResponseErrorInternal"); | ||
}); | ||
|
||
it("should return not found if no userEycaCard is found", async () => { | ||
findLastVersionByModelIdMock.mockImplementationOnce(() => | ||
taskEither.of(none) | ||
); | ||
const handler = GetEycaStatusHandler(userEycaCardModelMock as any); | ||
const response = await handler({} as any, aFiscalCode); | ||
expect(response.kind).toBe("IResponseErrorNotFound"); | ||
}); | ||
|
||
it("should return success if a pending userEycaCard is found", async () => { | ||
await successImpl(aUserEycaCard); | ||
}); | ||
|
||
it("should return success if a revoked userEycaCard is found", async () => { | ||
findLastVersionByModelIdMock.mockImplementationOnce(() => | ||
taskEither.of(some({ ...aUserEycaCard, card: aRevokedEycaCard })) | ||
); | ||
await successImpl({ ...aUserEycaCard, card: aRevokedEycaCard }); | ||
}); | ||
|
||
it("should return success if an activated userEycaCard is found", async () => { | ||
findLastVersionByModelIdMock.mockImplementationOnce(() => | ||
taskEither.of(some({ ...aUserEycaCard, card: anActivatedEycaCard })) | ||
); | ||
await successImpl({ ...aUserEycaCard, card: anActivatedEycaCard }); | ||
}); | ||
}); |
This file contains 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,20 @@ | ||
{ | ||
"bindings": [ | ||
{ | ||
"authLevel": "function", | ||
"type": "httpTrigger", | ||
"direction": "in", | ||
"name": "req", | ||
"route": "api/v1/cgn/eyca/status/{fiscalcode}", | ||
"methods": [ | ||
"get" | ||
] | ||
}, | ||
{ | ||
"type": "http", | ||
"direction": "out", | ||
"name": "res" | ||
} | ||
], | ||
"scriptFile": "../dist/GetEycaStatus/index.js" | ||
} |
This file contains 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,75 @@ | ||
import * as express from "express"; | ||
|
||
import { Context } from "@azure/functions"; | ||
import { fromOption } from "fp-ts/lib/Either"; | ||
import { identity } from "fp-ts/lib/function"; | ||
import { fromEither } from "fp-ts/lib/TaskEither"; | ||
import { ContextMiddleware } from "io-functions-commons/dist/src/utils/middlewares/context_middleware"; | ||
import { RequiredParamMiddleware } from "io-functions-commons/dist/src/utils/middlewares/required_param"; | ||
import { | ||
withRequestMiddlewares, | ||
wrapRequestHandler | ||
} from "io-functions-commons/dist/src/utils/request_middleware"; | ||
import { | ||
IResponseErrorInternal, | ||
IResponseErrorNotFound, | ||
IResponseSuccessJson, | ||
ResponseErrorInternal, | ||
ResponseErrorNotFound, | ||
ResponseSuccessJson | ||
} from "italia-ts-commons/lib/responses"; | ||
import { FiscalCode } from "italia-ts-commons/lib/strings"; | ||
|
||
import { EycaCard } from "../generated/definitions/EycaCard"; | ||
import { UserEycaCardModel } from "../models/user_eyca_card"; | ||
|
||
type ResponseTypes = | ||
| IResponseSuccessJson<EycaCard> | ||
| IResponseErrorNotFound | ||
| IResponseErrorInternal; | ||
|
||
type IGetEycaStatusHandler = ( | ||
context: Context, | ||
fiscalCode: FiscalCode | ||
) => Promise<ResponseTypes>; | ||
|
||
export function GetEycaStatusHandler( | ||
userEycaCardModel: UserEycaCardModel | ||
): IGetEycaStatusHandler { | ||
return async (_, fiscalCode) => { | ||
return userEycaCardModel | ||
.findLastVersionByModelId([fiscalCode]) | ||
.mapLeft<IResponseErrorInternal | IResponseErrorNotFound>(() => | ||
ResponseErrorInternal( | ||
"Error trying to retrieve user's EYCA Card status" | ||
) | ||
) | ||
.chain(maybeUserEycaCard => | ||
fromEither( | ||
fromOption( | ||
ResponseErrorNotFound( | ||
"Not Found", | ||
"User's EYCA Card status not found" | ||
) | ||
)(maybeUserEycaCard) | ||
) | ||
) | ||
.fold<ResponseTypes>(identity, userEycaCard => | ||
ResponseSuccessJson(userEycaCard.card) | ||
) | ||
.run(); | ||
}; | ||
} | ||
|
||
export function GetEycaStatus( | ||
userEycaCardModel: UserEycaCardModel | ||
): express.RequestHandler { | ||
const handler = GetEycaStatusHandler(userEycaCardModel); | ||
|
||
const middlewaresWrap = withRequestMiddlewares( | ||
ContextMiddleware(), | ||
RequiredParamMiddleware("fiscalcode", FiscalCode) | ||
); | ||
|
||
return wrapRequestHandler(middlewaresWrap(handler)); | ||
} |
This file contains 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,56 @@ | ||
import * as express from "express"; | ||
import * as winston from "winston"; | ||
|
||
import { Context } from "@azure/functions"; | ||
import { secureExpressApp } from "io-functions-commons/dist/src/utils/express"; | ||
import { AzureContextTransport } from "io-functions-commons/dist/src/utils/logging"; | ||
import { setAppContext } from "io-functions-commons/dist/src/utils/middlewares/context_middleware"; | ||
import createAzureFunctionHandler from "io-functions-express/dist/src/createAzureFunctionsHandler"; | ||
|
||
import { | ||
USER_EYCA_CARD_COLLECTION_NAME, | ||
UserEycaCardModel | ||
} from "../models/user_eyca_card"; | ||
import { getConfigOrThrow } from "../utils/config"; | ||
import { cosmosdbClient } from "../utils/cosmosdb"; | ||
import { GetEycaStatus } from "./handler"; | ||
|
||
// | ||
// CosmosDB initialization | ||
// | ||
|
||
const config = getConfigOrThrow(); | ||
|
||
const userEycaCardsContainer = cosmosdbClient | ||
.database(config.COSMOSDB_CGN_DATABASE_NAME) | ||
.container(USER_EYCA_CARD_COLLECTION_NAME); | ||
|
||
const userEycaCardModel = new UserEycaCardModel(userEycaCardsContainer); | ||
|
||
// tslint:disable-next-line: no-let | ||
let logger: Context["log"] | undefined; | ||
const contextTransport = new AzureContextTransport(() => logger, { | ||
level: "debug" | ||
}); | ||
winston.add(contextTransport); | ||
|
||
// Setup Express | ||
const app = express(); | ||
secureExpressApp(app); | ||
|
||
// Add express route | ||
app.get( | ||
"/api/v1/cgn/eyca/status/:fiscalcode", | ||
GetEycaStatus(userEycaCardModel) | ||
); | ||
|
||
const azureFunctionHandler = createAzureFunctionHandler(app); | ||
|
||
// Binds the express app to an Azure Function handler | ||
function httpStart(context: Context): void { | ||
logger = context.log; | ||
setAppContext(app, context); | ||
azureFunctionHandler(context); | ||
} | ||
|
||
export default httpStart; |
This file contains 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