Skip to content

Commit

Permalink
add service /features api mock
Browse files Browse the repository at this point in the history
  • Loading branch information
giuseppedipinto committed Apr 23, 2024
1 parent 7f283d3 commit 5c73199
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 0 deletions.
1 change: 1 addition & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ const defaultConfig: IoDevServerConfig = {
},
service: {
response: {
featuredItemsResponseCode: 200,
institutionsResponseCode: 200
}
},
Expand Down
101 changes: 101 additions & 0 deletions src/features/services/payloads/get-featured-items.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import { nonEmptyArray } from "fp-ts";
import * as A from "fp-ts/Array";
import * as O from "fp-ts/lib/Option";
import { pipe } from "fp-ts/lib/function";
import { FeaturedItem } from "../../../../generated/definitions/services/FeaturedItem";
import { FeaturedItems } from "../../../../generated/definitions/services/FeaturedItems";
import ServicesDB from "../../../persistence/services";
import { getInstitutionsResponsePayload } from "./get-institutions";

/**
* Returns a random ordered array subset.
* @param array starting array of type T
* @param size array subset size (if `size` greater than `array`, it returns empty array subset)
* @returns
*/
const getRandomArraySubset = <T>(array: T[], size: number): T[] =>
pipe(
O.some(array),
O.fromPredicate(arr => O.isSome(arr) && size <= array.length),
O.fold(
() => [],
() => {
const remainingItems = [...array];
return pipe(
nonEmptyArray.range(1, size),
A.map(() => {
const randomIndex = Math.floor(
Math.random() * remainingItems.length
);
const selectedItem = remainingItems[randomIndex];
// eslint-disable-next-line functional/immutable-data
remainingItems.splice(randomIndex, 1);
return selectedItem;
})
);
}
)
);

export const getFeaturedItemsResponsePayload = (): FeaturedItems => {
// take some casual national service
const selectedNationalServices = getRandomArraySubset(
ServicesDB.getNationalServices(),
1
);
// take some casual special service
const selectedSpecialServices = getRandomArraySubset(
ServicesDB.getSpecialServices(),
3
);
// take some casual institutions
const featuredIntitutions = getRandomArraySubset(
Array.from(getInstitutionsResponsePayload().institutions),
1
);

/**
* Reduced national services to FeaturedService[] (add organization_name for layout testing purpose)
*/
const featuredNationalServices: FeaturedItem[] = pipe(
selectedNationalServices,
A.reduce([] as FeaturedItem[], (accumulator, service) => [
...accumulator,
{
id: service.service_id,
name: service.service_name,
version: service.version,
organization_name: service.organization_name
}
])
);

/**
* Reduce special services to FeaturedService[]
*/
const featuredSpecialServices: FeaturedItem[] = pipe(
selectedSpecialServices,
A.reduce([] as FeaturedItem[], (accumulator, service) => [
...accumulator,
{
id: service.service_id,
name: service.service_name,
version: service.version
}
])
);

// returns randomly ordered featured items
const featuredItems = pipe(
[
...featuredSpecialServices,
...featuredIntitutions,
...featuredNationalServices
],
arr => getRandomArraySubset(arr, arr.length)
);

return {
items: featuredItems
};
};
27 changes: 27 additions & 0 deletions src/features/services/routers/featured.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import * as O from "fp-ts/lib/Option";
import { pipe } from "fp-ts/lib/function";
import { ioDevServerConfig } from "../../../config";
import { addHandler } from "../../../payloads/response";
import { getFeaturedItemsResponsePayload } from "../payloads/get-featured-items";
import { addApiV2Prefix, serviceRouter } from "./router";

const serviceConfig = ioDevServerConfig.features.service;

// Retrieve featured items
addHandler(serviceRouter, "get", addApiV2Prefix("/featured"), (_, res) =>
pipe(
serviceConfig.response.featuredItemsResponseCode,
O.fromPredicate(statusCode => statusCode !== 200),
O.fold(
() =>
pipe(
O.of(getFeaturedItemsResponsePayload()),
O.fold(
() => res.status(404),
featuredItems => res.status(200).json(featuredItems)
)
),
statusCode => res.sendStatus(statusCode)
)
)
);
1 change: 1 addition & 0 deletions src/features/services/routers/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import "./featured";
import "./institutions";

export { serviceRouter } from "./router";
1 change: 1 addition & 0 deletions src/features/services/types/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export const ServiceConfiguration = t.interface({
// configure some API response error code
response: t.interface({
// 200 success with payload
featuredItemsResponseCode: HttpResponseCode,
institutionsResponseCode: HttpResponseCode
})
});
Expand Down
4 changes: 4 additions & 0 deletions src/persistence/services.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ const getAllServices = () => [
];

const getLocalServices = () => localServices.map(ls => ({ ...ls }));
const getNationalServices = () => nationalServices.map(ls => ({ ...ls }));
const getSpecialServices = () => specialServices.map(ls => ({ ...ls }));

const getPreference = (
serviceId: ServiceId
Expand Down Expand Up @@ -166,6 +168,8 @@ export default {
deleteServices,
getAllServices,
getLocalServices,
getNationalServices,
getSpecialServices,
getPreference,
getService,
getSummaries,
Expand Down

0 comments on commit 5c73199

Please sign in to comment.