Skip to content

Commit

Permalink
fix(api-elasticsearch): filtering via startsWith and notStartsWith (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
brunozoric committed Oct 13, 2023
1 parent 80fefae commit 6b74895
Show file tree
Hide file tree
Showing 6 changed files with 125 additions and 3 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export class ElasticsearchQueryBuilderOperatorNotStartsWithPlugin extends Elasti
params: ElasticsearchQueryBuilderArgsPlugin
): void {
const { value, basePath } = params;
if (value === "" || value === null || value === undefined) {
return;
}
query.must_not.push({
match_phrase_prefix: {
[basePath]: value
Expand Down
3 changes: 3 additions & 0 deletions packages/api-elasticsearch/src/plugins/operator/startsWith.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ export class ElasticsearchQueryBuilderOperatorStartsWithPlugin extends Elasticse
params: ElasticsearchQueryBuilderArgsPlugin
): void {
const { value, basePath } = params;
if (value === "" || value === null || value === undefined) {
return;
}
query.filter.push({
match_phrase_prefix: {
[basePath]: value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,18 @@ interface ExecuteFilterParams {
const executeFilter = (params: ExecuteFilterParams) => {
const { value, filter } = params;

/**
* We need to check if the filter can be used.
* If it cannot, we will just return true.
*/
const canUse = filter.plugin.canUse({
value,
compareValue: filter.compareValue
});
if (!canUse) {
return true;
}

const matched = filter.plugin.matches({
value,
compareValue: filter.compareValue
Expand Down
90 changes: 90 additions & 0 deletions packages/api-headless-cms/__tests__/contentAPI/filtering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1926,4 +1926,94 @@ describe("filtering", () => {
}
});
});

it("should filter via startsWith", async () => {
const { apple, banana, strawberry } = await setupFruits();
const { listFruits } = useFruitReadHandler({
...readOpts
});

const [filteredResponse] = await listFruits({
where: {
name_startsWith: "ap"
}
});
expect(filteredResponse).toMatchObject({
data: {
listFruits: {
data: [apple],
meta: {
totalCount: 1,
hasMoreItems: false,
cursor: null
},
error: null
}
}
});

const [response] = await listFruits({
where: {
name_startsWith: ""
}
});
expect(response).toMatchObject({
data: {
listFruits: {
data: [banana, strawberry, apple],
meta: {
totalCount: 3,
hasMoreItems: false,
cursor: null
},
error: null
}
}
});
});

it("should filter via not_startsWith", async () => {
const { apple, banana, strawberry } = await setupFruits();
const { listFruits } = useFruitReadHandler({
...readOpts
});

const [filteredResponse] = await listFruits({
where: {
name_not_startsWith: "ap"
}
});
expect(filteredResponse).toMatchObject({
data: {
listFruits: {
data: [banana, strawberry],
meta: {
totalCount: 2,
hasMoreItems: false,
cursor: null
},
error: null
}
}
});

const [response] = await listFruits({
where: {
name_not_startsWith: ""
}
});
expect(response).toMatchObject({
data: {
listFruits: {
data: [banana, strawberry, apple],
meta: {
totalCount: 3,
hasMoreItems: false,
cursor: null
},
error: null
}
}
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface ValueFilterPluginParamsMatches {

export interface ValueFilterPluginParams {
operation: string;
canUse?: (params: ValueFilterPluginParamsMatchesParams) => boolean;
matches: ValueFilterPluginParamsMatches;
}
export class ValueFilterPlugin extends Plugin {
Expand All @@ -27,6 +28,13 @@ export class ValueFilterPlugin extends Plugin {
this._params = params;
}

public canUse(params: ValueFilterPluginParamsMatchesParams): boolean {
if (!this._params.canUse) {
return true;
}
return this._params.canUse(params);
}

public matches(params: ValueFilterPluginParamsMatchesParams): boolean {
if (!this._params || !this._params.matches) {
throw new WebinyError(`Missing "matches" in the plugin.`, "MATCHES_ERROR", {
Expand Down
12 changes: 9 additions & 3 deletions packages/db-dynamodb/src/plugins/filters/startsWith.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@ import { ValueFilterPlugin } from "../definitions/ValueFilterPlugin";

const plugin = new ValueFilterPlugin({
operation: "startsWith",
canUse: ({ compareValue }) => {
if (compareValue === "" || compareValue === null || compareValue === undefined) {
return false;
}
return true;
},
matches: ({ value, compareValue }) => {
/**
* We do "case-insensitive" comparison.
Expand All @@ -10,9 +16,9 @@ const plugin = new ValueFilterPlugin({

if (typeof value !== "string") {
if (Array.isArray(value) === true) {
return value.some((v: string) =>
v.toLowerCase().startsWith(compareValueInLowerCase)
);
return value.some((v: string) => {
return v.toLowerCase().startsWith(compareValueInLowerCase);
});
}
return false;
}
Expand Down

0 comments on commit 6b74895

Please sign in to comment.