-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds GetServicesForRecipient function (#2)
- Loading branch information
Showing
8 changed files
with
1,602 additions
and
34 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -43,3 +43,5 @@ __pycache__/ | |
*$py.class | ||
|
||
coverage | ||
|
||
yarn-error.log |
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 @@ | ||
declare module "jest-mock-express"; |
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,110 @@ | ||
// tslint:disable:no-any | ||
|
||
import { none, some } from "fp-ts/lib/Option"; | ||
|
||
import { right } from "fp-ts/lib/Either"; | ||
import { NonNegativeNumber } from "italia-ts-commons/lib/numbers"; | ||
import { | ||
FiscalCode, | ||
NonEmptyString, | ||
OrganizationFiscalCode | ||
} from "italia-ts-commons/lib/strings"; | ||
|
||
import { response as MockResponse } from "jest-mock-express"; | ||
|
||
import * as middlewares from "io-functions-commons/dist/src/utils/request_middleware"; | ||
|
||
import { | ||
NewService, | ||
RetrievedService, | ||
Service, | ||
toAuthorizedCIDRs, | ||
toAuthorizedRecipients | ||
} from "io-functions-commons/dist/src/models/service"; | ||
|
||
import { MaxAllowedPaymentAmount } from "io-functions-commons/dist/generated/definitions/MaxAllowedPaymentAmount"; | ||
|
||
import { | ||
GetServicesForRecipient, | ||
GetServicesForRecipientHandler | ||
} from "../handler"; | ||
|
||
afterEach(() => { | ||
jest.resetAllMocks(); | ||
jest.restoreAllMocks(); | ||
}); | ||
|
||
const anOrganizationFiscalCode = "01234567890" as OrganizationFiscalCode; | ||
const aFiscalCode = "SPNDNL80R13D000X" as FiscalCode; | ||
|
||
const aService: Service = { | ||
authorizedCIDRs: toAuthorizedCIDRs([]), | ||
authorizedRecipients: toAuthorizedRecipients([]), | ||
departmentName: "MyDeptName" as NonEmptyString, | ||
isVisible: true, | ||
maxAllowedPaymentAmount: 0 as MaxAllowedPaymentAmount, | ||
organizationFiscalCode: anOrganizationFiscalCode, | ||
organizationName: "MyOrgName" as NonEmptyString, | ||
serviceId: "MySubscriptionId" as NonEmptyString, | ||
serviceName: "MyServiceName" as NonEmptyString | ||
}; | ||
|
||
const aNewService: NewService = { | ||
...aService, | ||
id: "123" as NonEmptyString, | ||
kind: "INewService", | ||
version: 1 as NonNegativeNumber | ||
}; | ||
|
||
const aRetrievedService: RetrievedService = { | ||
...aNewService, | ||
_self: "123", | ||
_ts: 123, | ||
kind: "IRetrievedService" | ||
}; | ||
|
||
const someRetrievedServices: ReadonlyArray<any> = [ | ||
aRetrievedService, | ||
{ ...aRetrievedService, id: "124" } | ||
]; | ||
|
||
describe("GetServicesByRecipientHandler", () => { | ||
it("should get id of the services that notified an existing recipient", async () => { | ||
const mockIterator = { | ||
executeNext: jest.fn() | ||
}; | ||
mockIterator.executeNext.mockImplementationOnce(() => | ||
Promise.resolve(right(some(someRetrievedServices))) | ||
); | ||
mockIterator.executeNext.mockImplementationOnce(() => | ||
Promise.resolve(right(none)) | ||
); | ||
|
||
const senderServiceModelMock = { | ||
findSenderServicesForRecipient: jest.fn(() => mockIterator) | ||
}; | ||
|
||
const getSenderServiceHandler = GetServicesForRecipientHandler( | ||
senderServiceModelMock as any | ||
); | ||
const response = await getSenderServiceHandler(aFiscalCode); | ||
await response.apply(MockResponse()); | ||
|
||
expect( | ||
senderServiceModelMock.findSenderServicesForRecipient | ||
).toHaveBeenCalledWith(aFiscalCode); | ||
expect(response.kind).toBe("IResponseSuccessJsonIterator"); | ||
expect(mockIterator.executeNext).toHaveBeenCalledTimes(2); | ||
}); | ||
}); | ||
|
||
describe("GetServicesByRecipient", () => { | ||
// tslint:disable-next-line:no-duplicate-string | ||
it("should set up authentication middleware", async () => { | ||
const withRequestMiddlewaresSpy = jest | ||
.spyOn(middlewares, "withRequestMiddlewares") | ||
.mockReturnValueOnce(jest.fn()); | ||
GetServicesForRecipient({} as any); | ||
expect(withRequestMiddlewaresSpy).toHaveBeenCalledTimes(1); | ||
}); | ||
}); |
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": "v1/profiles/{fiscalcode}/sender-services", | ||
"methods": [ | ||
"get" | ||
] | ||
}, | ||
{ | ||
"type": "http", | ||
"direction": "out", | ||
"name": "res" | ||
} | ||
], | ||
"scriptFile": "../dist/GetServicesForRecipient/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,63 @@ | ||
import * as express from "express"; | ||
|
||
import { FiscalCode } from "italia-ts-commons/lib/strings"; | ||
|
||
import { mapResultIterator } from "io-functions-commons/dist/src/utils/documentdb"; | ||
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 { | ||
IResponseErrorQuery, | ||
IResponseSuccessJsonIterator, | ||
ResponseJsonIterator | ||
} from "io-functions-commons/dist/src/utils/response"; | ||
|
||
import { SenderServiceModel } from "io-functions-commons/dist/src/models/sender_service"; | ||
|
||
import { ServiceTuple } from "io-functions-commons/dist/generated/definitions/ServiceTuple"; | ||
|
||
type IGetSenderServicesHandlerRet = | ||
| IResponseSuccessJsonIterator<ServiceTuple> | ||
| IResponseErrorQuery; | ||
|
||
type IGetSenderServicesHandler = ( | ||
fiscalCode: FiscalCode | ||
) => Promise<IGetSenderServicesHandlerRet>; | ||
|
||
/** | ||
* Returns the serviceId for all the Services that have sent | ||
* at least one notification to the recipient with the provided fiscalCode. | ||
*/ | ||
export function GetServicesForRecipientHandler( | ||
senderServiceModel: SenderServiceModel | ||
): IGetSenderServicesHandler { | ||
return async fiscalCode => { | ||
const retrievedServicesIterator = senderServiceModel.findSenderServicesForRecipient( | ||
fiscalCode | ||
); | ||
const senderServicesIterator = mapResultIterator( | ||
retrievedServicesIterator, | ||
service => ({ | ||
service_id: service.serviceId, | ||
version: service.version | ||
}) | ||
); | ||
return ResponseJsonIterator(senderServicesIterator); | ||
}; | ||
} | ||
|
||
/** | ||
* Wraps a GetSenderServices handler inside an Express request handler. | ||
*/ | ||
export function GetServicesForRecipient( | ||
senderServiceModel: SenderServiceModel | ||
): express.RequestHandler { | ||
const handler = GetServicesForRecipientHandler(senderServiceModel); | ||
|
||
const middlewaresWrap = withRequestMiddlewares( | ||
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,70 @@ | ||
import { Context } from "@azure/functions"; | ||
|
||
import * as cors from "cors"; | ||
import * as express from "express"; | ||
import * as winston from "winston"; | ||
|
||
import { DocumentClient as DocumentDBClient } from "documentdb"; | ||
|
||
import { | ||
SENDER_SERVICE_COLLECTION_NAME, | ||
SenderServiceModel | ||
} from "io-functions-commons/dist/src/models/sender_service"; | ||
import * as documentDbUtils from "io-functions-commons/dist/src/utils/documentdb"; | ||
import { getRequiredStringEnv } from "io-functions-commons/dist/src/utils/env"; | ||
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 { GetServicesForRecipient } from "./handler"; | ||
|
||
// Setup Express | ||
const app = express(); | ||
secureExpressApp(app); | ||
|
||
// Set up CORS (free access to the API from browser clients) | ||
app.use(cors()); | ||
|
||
const cosmosDbUri = getRequiredStringEnv("CUSTOMCONNSTR_COSMOSDB_URI"); | ||
const cosmosDbKey = getRequiredStringEnv("CUSTOMCONNSTR_COSMOSDB_KEY"); | ||
const cosmosDbName = getRequiredStringEnv("COSMOSDB_NAME"); | ||
|
||
const documentDbDatabaseUrl = documentDbUtils.getDatabaseUri(cosmosDbName); | ||
const senderServicesCollectionUrl = documentDbUtils.getCollectionUri( | ||
documentDbDatabaseUrl, | ||
SENDER_SERVICE_COLLECTION_NAME | ||
); | ||
|
||
const documentClient = new DocumentDBClient(cosmosDbUri, { | ||
masterKey: cosmosDbKey | ||
}); | ||
|
||
const senderServiceModel = new SenderServiceModel( | ||
documentClient, | ||
senderServicesCollectionUrl | ||
); | ||
|
||
app.get( | ||
"/api/v1/profiles/:fiscalcode/sender-services", | ||
GetServicesForRecipient(senderServiceModel) | ||
); | ||
|
||
const azureFunctionHandler = createAzureFunctionHandler(app); | ||
|
||
// tslint:disable-next-line: no-let | ||
let logger: Context["log"] | undefined; | ||
const contextTransport = new AzureContextTransport(() => logger, { | ||
level: "debug" | ||
}); | ||
winston.add(contextTransport); | ||
|
||
// 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
Oops, something went wrong.