Skip to content

Commit

Permalink
fix(api): add missing plugins (#265)
Browse files Browse the repository at this point in the history
* add missing plugins

* style: resolve style guide violations

---------

Co-authored-by: oXtxNt9U <[email protected]>
  • Loading branch information
oXtxNt9U and oXtxNt9U authored Oct 5, 2023
1 parent b0dc608 commit 1d7f9aa
Show file tree
Hide file tree
Showing 4 changed files with 167 additions and 0 deletions.
22 changes: 22 additions & 0 deletions packages/api-http/source/plugins/comma-separated-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import Hapi from "@hapi/hapi";

export const commaArrayQuery = {
name: "comma-array-query",
onRequest(request: Hapi.Request, h: Hapi.ResponseToolkit): Hapi.Lifecycle.ReturnValue {
const query = {};
const separator = ",";

for (const [key, value] of Object.entries(request.query as { [key: string]: string })) {
query[key] = value.includes(separator) ? value.split(separator) : value;
}

request.query = query;
return h.continue;
},

register(server: Hapi.Server): void {
server.ext("onRequest", this.onRequest);
},

version: "1.0.0",
};
20 changes: 20 additions & 0 deletions packages/api-http/source/plugins/dot-separated-query.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Hapi from "@hapi/hapi";
import { set } from "@mainsail/utils";

export const dotSeparatedQuery = {
name: "dot-separated-query",
onRequest(request: Hapi.Request, h: Hapi.ResponseToolkit): Hapi.Lifecycle.ReturnValue {
const query = {};
for (const [key, value] of Object.entries(request.query)) {
set(query, key, value);
}
request.query = query;
return h.continue;
},

register(server: Hapi.Server): void {
server.ext("onRequest", this.onRequest);
},

version: "1.0.0",
};
4 changes: 4 additions & 0 deletions packages/api-http/source/plugins/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { commaArrayQuery } from "./comma-separated-query";
import { dotSeparatedQuery } from "./dot-separated-query";
import { hapiAjv } from "./hapi-ajv";
import { pagination } from "./pagination";
import { rateLimit } from "./rate-limit";
Expand All @@ -20,6 +22,8 @@ export const preparePlugins = (config) => [
},
plugin: rateLimit,
},
{ plugin: commaArrayQuery },
{ plugin: dotSeparatedQuery },
{
options: {
query: {
Expand Down
121 changes: 121 additions & 0 deletions packages/api-http/source/schemas/schemas.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
import Joi from "joi";
import { describe, Sandbox } from "../../../test-framework";
import * as schemas from "./schemas";

describe<{}>("Schemas", ({ it, assert }) => {
describe("createRangeCriteriaSchema", () => {
it("should be valid", () => {
const schema = schemas.createRangeCriteriaSchema(Joi.number().integer().min(1));

const result = schema.validate({ from: 1, to: 2 });

assert.equal(result, {
value: {
from: 1,
to: 2,
},
});
});

it("should be invalid if from doesn't satisfy condition", () => {
const schema = schemas.createRangeCriteriaSchema(Joi.number().integer().min(1));

const result = schema.validate({ from: 0, to: 2 });

assert.equal(result.error!.message, '"from" must be greater than or equal to 1');
});

it("should be invalid if to doesn't satisfy condition", () => {
const schema = schemas.createRangeCriteriaSchema(Joi.number().integer().min(1));

const result = schema.validate({ from: 1, to: 0 });

assert.equal(result.error!.message, '"to" must be greater than or equal to 1');
});
});

describe("createSortingSchema", () => {
const testCriteriaSchemaObject = {
username: Joi.string().max(256),
};

it("should use asc direction if direction is not present", () => {
const sortingSchema = schemas.createSortingSchema(testCriteriaSchemaObject);

const result = sortingSchema.validate({ orderBy: "username" });

assert.equal(result, {
value: {
orderBy: [
{
property: "username",
direction: "asc",
},
],
},
});
});

it("should use given direction", () => {
const sortingSchema = schemas.createSortingSchema(testCriteriaSchemaObject);

const result = sortingSchema.validate({ orderBy: "username:desc" });

assert.equal(result, {
value: {
orderBy: [
{
property: "username",
direction: "desc",
},
],
},
});
});

it("should return empty order if orderBy is empty string", () => {
const sortingSchema = schemas.createSortingSchema(testCriteriaSchemaObject);

const result = sortingSchema.validate({ orderBy: "" });

assert.equal(result, {
value: {
orderBy: [],
},
});
});

it("should contain error if direction is unknown", () => {
const sortingSchema = schemas.createSortingSchema(testCriteriaSchemaObject);

const result = sortingSchema.validate({ orderBy: "username:invalid" });

assert.equal(result.error!.message, "Unexpected orderBy direction 'invalid' for property 'username'");
});

it("should contain error if property is unknown", () => {
const sortingSchema = schemas.createSortingSchema(testCriteriaSchemaObject);

const result = sortingSchema.validate({ orderBy: "invalid:asc" });

assert.equal(result.error!.message, "Unknown orderBy property 'invalid'");
});

it("should return orderBy if property is defined in wildcardPaths", () => {
const sortingSchema = schemas.createSortingSchema(testCriteriaSchemaObject, ["invalid"]);

const result = sortingSchema.validate({ orderBy: "invalid.username:asc" });

assert.equal(result, {
value: {
orderBy: [
{
property: "invalid.username",
direction: "asc",
},
],
},
});
});
});
});

0 comments on commit 1d7f9aa

Please sign in to comment.