Skip to content

Commit 75c9efe

Browse files
authored
Case-insensitive workflow filter (#790)
* Case-insensitive workflow filter
1 parent 4c9ec4e commit 75c9efe

File tree

9 files changed

+66
-15
lines changed

9 files changed

+66
-15
lines changed

src/main/scala/za/co/absa/hyperdrive/trigger/models/search/ContainsFilterAttributes.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,5 @@
1515

1616
package za.co.absa.hyperdrive.trigger.models.search
1717

18-
case class ContainsFilterAttributes(override val field: String, value: String) extends FilterAttributes
18+
case class ContainsFilterAttributes(override val field: String, value: String, isCaseSensitive: Boolean)
19+
extends FilterAttributes

src/main/scala/za/co/absa/hyperdrive/trigger/models/tables/tableExtensions/searchableTable/SearchableTableQuery.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,11 @@ trait SearchableTableQuery {
7575
fieldMapping: Map[String, Rep[_]]
7676
): Rep[Boolean] = {
7777
val tableField = fieldMapping(attributes.field).asInstanceOf[Rep[String]]
78-
tableField like s"%${attributes.value}%"
78+
if (attributes.isCaseSensitive) {
79+
tableField like s"%${attributes.value}%"
80+
} else {
81+
tableField.toLowerCase like s"%${attributes.value}%".toLowerCase
82+
}
7983
}
8084

8185
private def applyIntRangeFilter(

src/test/scala/za/co/absa/hyperdrive/trigger/models/tables/tableExtensions/searchableTable/SearchableTableQueryTest.scala

Lines changed: 43 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -49,8 +49,8 @@ class SearchableTableQueryTest
4949
import TestSearchableTableFieldNames._
5050
val containsFilterSeq = Some(
5151
Seq(
52-
ContainsFilterAttributes(field = stringField, value = "value"),
53-
ContainsFilterAttributes(field = stringField2, value = "str")
52+
ContainsFilterAttributes(field = stringField, value = "value", isCaseSensitive = true),
53+
ContainsFilterAttributes(field = stringField2, value = "str", isCaseSensitive = true)
5454
)
5555
)
5656
val intRangeFilterSeq = Some(Seq(IntRangeFilterAttributes(field = longField, start = Option(0), end = Option(1))))
@@ -83,7 +83,11 @@ class SearchableTableQueryTest
8383
}
8484

8585
"The contains filter" should "find values that contain the search string" in {
86-
val filter = ContainsFilterAttributes(field = TestSearchableTableFieldNames.stringField, value = "value")
86+
val filter = ContainsFilterAttributes(
87+
field = TestSearchableTableFieldNames.stringField,
88+
value = "value",
89+
isCaseSensitive = true
90+
)
8791
val searchRequest =
8892
TableSearchRequest(containsFilterAttributes = Some(Seq(filter)), sort = None, from = 0, size = 50)
8993

@@ -97,7 +101,42 @@ class SearchableTableQueryTest
97101

98102
it should "not find values that do not contain the search string" in {
99103
val filter =
100-
ContainsFilterAttributes(field = TestSearchableTableFieldNames.stringField, value = "not-matching-string")
104+
ContainsFilterAttributes(
105+
field = TestSearchableTableFieldNames.stringField,
106+
value = "not-matching-string",
107+
isCaseSensitive = true
108+
)
109+
val searchRequest =
110+
TableSearchRequest(containsFilterAttributes = Some(Seq(filter)), sort = None, from = 0, size = 50)
111+
112+
val result = await(db.run(underTest.search(searchRequest)))
113+
114+
result.total shouldBe 0
115+
}
116+
117+
it should "find values that contain the search string with disabled case sensitivity" in {
118+
val filter = ContainsFilterAttributes(
119+
field = TestSearchableTableFieldNames.stringField,
120+
value = "VaLuE",
121+
isCaseSensitive = false
122+
)
123+
val searchRequest =
124+
TableSearchRequest(containsFilterAttributes = Some(Seq(filter)), sort = None, from = 0, size = 50)
125+
126+
val result = await(db.run(underTest.search(searchRequest)))
127+
128+
val expected = TestSearchableData.testSearchableEntities.filter(_.stringValue.contains("value"))
129+
result.total should be > 0
130+
result.total shouldBe expected.size
131+
result.items should contain theSameElementsAs expected
132+
}
133+
134+
it should "not find values that do contain the search string and do not match case" in {
135+
val filter = ContainsFilterAttributes(
136+
field = TestSearchableTableFieldNames.stringField,
137+
value = "VaLuE",
138+
isCaseSensitive = true
139+
)
101140
val searchRequest =
102141
TableSearchRequest(containsFilterAttributes = Some(Seq(filter)), sort = None, from = 0, size = 50)
103142

src/test/scala/za/co/absa/hyperdrive/trigger/persistance/DagRunRepositoryTest.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -138,10 +138,10 @@ class DagRunRepositoryTest
138138
createTestData()
139139
val containsFilters = Some(
140140
Seq(
141-
ContainsFilterAttributes(field = "workflowName", value = "flow1"),
142-
ContainsFilterAttributes(field = "status", value = "Que"),
143-
ContainsFilterAttributes(field = "triggeredBy", value = TestData.triggeredBy),
144-
ContainsFilterAttributes(field = "projectName", value = "project")
141+
ContainsFilterAttributes(field = "workflowName", value = "flow1", isCaseSensitive = true),
142+
ContainsFilterAttributes(field = "status", value = "Que", isCaseSensitive = true),
143+
ContainsFilterAttributes(field = "triggeredBy", value = TestData.triggeredBy, isCaseSensitive = true),
144+
ContainsFilterAttributes(field = "projectName", value = "project", isCaseSensitive = true)
145145
)
146146
)
147147

src/test/scala/za/co/absa/hyperdrive/trigger/persistance/JobTemplateRepositoryPostgresTest.scala

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,9 @@ class JobTemplateRepositoryPostgresTest
122122
insertJobTemplates()
123123

124124
val containsFilterAttributes =
125-
Option(Seq(ContainsFilterAttributes(field = "name", value = TestData.jobTemplates.head.name)))
125+
Option(
126+
Seq(ContainsFilterAttributes(field = "name", value = TestData.jobTemplates.head.name, isCaseSensitive = true))
127+
)
126128
val searchRequest: TableSearchRequest = TableSearchRequest(
127129
containsFilterAttributes = containsFilterAttributes,
128130
sort = None,

src/test/scala/za/co/absa/hyperdrive/trigger/persistance/NotificationRuleRepositoryTest.scala

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -223,7 +223,8 @@ class NotificationRuleRepositoryTest
223223

224224
"searchJobTemplates" should "return notification rules sorted by workflow prefix" in {
225225
await(db.run(h2NotificationRuleTable.forceInsertAll(Seq(TestData.nr1, TestData.nr2, TestData.nr3))))
226-
val containsFilterAttributes = Option(Seq(ContainsFilterAttributes(field = "project", value = "proj")))
226+
val containsFilterAttributes =
227+
Option(Seq(ContainsFilterAttributes(field = "project", value = "proj", isCaseSensitive = true)))
227228
val searchRequest: TableSearchRequest = TableSearchRequest(
228229
containsFilterAttributes = containsFilterAttributes,
229230
sort = Option(SortAttributes(by = "workflowPrefix", order = 1)),
@@ -240,7 +241,8 @@ class NotificationRuleRepositoryTest
240241

241242
it should "return notification rules sorted by created" in {
242243
await(db.run(h2NotificationRuleTable.forceInsertAll(Seq(TestData.nr1, TestData.nr2, TestData.nr3))))
243-
val containsFilterAttributes = Option(Seq(ContainsFilterAttributes(field = "project", value = "proj")))
244+
val containsFilterAttributes =
245+
Option(Seq(ContainsFilterAttributes(field = "project", value = "proj", isCaseSensitive = true)))
244246
val searchRequest: TableSearchRequest = TableSearchRequest(
245247
containsFilterAttributes = containsFilterAttributes,
246248
sort = Option(SortAttributes(by = "created", order = 1)),

ui/src/app/components/common/datagrid/filters/string-filter/string-filter.component.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ export class StringFilterComponent implements ClrDatagridFilterInterface<any>, A
2828
@Input() removeFiltersSubject: Subject<any>;
2929
@Input() property: string;
3030
@Input() value: string = undefined;
31+
@Input() isCaseSensitive = true;
3132

3233
//clarity interface
3334
changes = new Subject<any>();
@@ -61,7 +62,7 @@ export class StringFilterComponent implements ClrDatagridFilterInterface<any>, A
6162
}
6263

6364
get state() {
64-
return new ContainsFilterAttributes(this.property, this.value);
65+
return new ContainsFilterAttributes(this.property, this.value, this.isCaseSensitive);
6566
}
6667

6768
modelChanged(value: string) {

ui/src/app/components/workflows/workflows-home/workflows-home.component.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,7 @@ <h3 class="modal-title">Upload workflow</h3>
138138
<ng-container>Workflow name</ng-container>
139139
<clr-dg-filter [clrDgFilter]="workflowNameFilter">
140140
<app-string-filter [value]="getFilter(workflowsHomeColumns.WORKFLOW_NAME)"
141+
[isCaseSensitive]="false"
141142
#workflowNameFilter
142143
[property]="workflowsHomeColumns.WORKFLOW_NAME"
143144
[removeFiltersSubject]="removeWorkflowFilterSubject">
@@ -151,6 +152,7 @@ <h3 class="modal-title">Upload workflow</h3>
151152
<clr-dg-filter [clrDgFilter]="workflowProjectFilter">
152153
<app-string-filter [removeFiltersSubject]="removeWorkflowFilterSubject"
153154
[value]="getFilter(workflowsHomeColumns.PROJECT_NAME)"
155+
[isCaseSensitive]="false"
154156
#workflowProjectFilter
155157
[property]="workflowsHomeColumns.PROJECT_NAME">
156158
</app-string-filter>

ui/src/app/models/search/containsFilterAttributes.model.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,5 @@
1616
import { FilterAttributes } from './filterAttributes.model';
1717

1818
export class ContainsFilterAttributes implements FilterAttributes {
19-
constructor(public field: string, public value: string) {}
19+
constructor(public field: string, public value: string, public isCaseSensitive: boolean) {}
2020
}

0 commit comments

Comments
 (0)