Bug 40876: Apply 'exact' to all attributes when column filtering
If you select an option in a column filter, the "exact" behaviour will
only apply to the first attribute mapped to this column
eg. on the patron search we have "Libraries" mapped to library.name and
library.library_id. If you select Centerville/CPL, the generated q
parameter will be {name: CPL, id: {like: "%CPL%"}}
This is caused by:
if (value.match(/^\^(.*)\$$/)) {
value = value.replace(/^\^/, "").replace(/\$$/, "");
On the second parameter we have lost the ^$ markers
Moving it out of the loop fixes the problem (and does not impact the
other behaviours: we search the same value for all the attributes
Test plan:
Create a library with code=CPLL and use if for a patron
Go to http://localhost:8081/cgi-bin/koha/members/members-home.pl
Click search
Select "Centerville" in the "Libraries" column filter
=> Without this patch you get the patrons from CPL and CPLL
=> With this patch applied only patrons from CPL are listed
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
Signed-off-by: Lucas Gass <lucas@bywatersolutions.com>
(cherry picked from commit 9e437a4089)
Signed-off-by: Paul Derscheid <paul.derscheid@lmscloud.de>
This commit is contained in:
parent
cfa17e1bc5
commit
66e8f837dd
|
|
@ -493,18 +493,20 @@ function _dt_default_ajax(params) {
|
|||
function build_query(col, value) {
|
||||
var parts = [];
|
||||
var attributes = col.data.split(":");
|
||||
|
||||
let criteria = options.criteria;
|
||||
if (value.match(/^\^(.*)\$$/)) {
|
||||
value = value.replace(/^\^/, "").replace(/\$$/, "");
|
||||
criteria = "exact";
|
||||
} else {
|
||||
// escape SQL LIKE special characters %
|
||||
value = value.replace(/(\%|\\)/g, "\\$1");
|
||||
}
|
||||
|
||||
for (var i = 0; i < attributes.length; i++) {
|
||||
var part = {};
|
||||
var attr = attributes[i];
|
||||
let default_build = true;
|
||||
let criteria = options.criteria;
|
||||
if (value.match(/^\^(.*)\$$/)) {
|
||||
value = value.replace(/^\^/, "").replace(/\$$/, "");
|
||||
criteria = "exact";
|
||||
} else {
|
||||
// escape SQL LIKE special characters %
|
||||
value = value.replace(/(\%|\\)/g, "\\$1");
|
||||
}
|
||||
|
||||
let built_value;
|
||||
if (col.type == "date") {
|
||||
|
|
|
|||
|
|
@ -180,4 +180,94 @@ describe("Filters", () => {
|
|||
).should("have.value", null);
|
||||
});
|
||||
});
|
||||
|
||||
describe("Exact search for all attributes", () => {
|
||||
// In this case the library column is bind to library.name and library.library_id
|
||||
it("From the form", () => {
|
||||
cy.task("buildSampleObjects", {
|
||||
object: "patron",
|
||||
count: RESTdefaultPageSize,
|
||||
values: {},
|
||||
}).then(patrons => {
|
||||
// Needs more properties to not explode
|
||||
// account_balace: balance_str.escapeHtml(...).format_price is not a function
|
||||
patrons = patrons.map(p => ({ ...p, account_balance: 0 }));
|
||||
|
||||
cy.intercept("GET", "/api/v1/patrons*", {
|
||||
statusCode: 200,
|
||||
body: patrons,
|
||||
headers: {
|
||||
"X-Base-Total-Count": baseTotalCount,
|
||||
"X-Total-Count": baseTotalCount,
|
||||
},
|
||||
}).as("searchPatrons");
|
||||
|
||||
cy.visit("/cgi-bin/koha/members/members-home.pl");
|
||||
|
||||
cy.window().then(win => {
|
||||
win.categories_map = patrons.reduce((map, p) => {
|
||||
map[p.category_id.toLowerCase()] = p.category_id;
|
||||
return map;
|
||||
}, {});
|
||||
});
|
||||
|
||||
cy.get("form.patron_search_form .branchcode_filter").select(
|
||||
"CPL"
|
||||
);
|
||||
cy.get("form.patron_search_form input[type='submit']").click();
|
||||
|
||||
cy.wait("@searchPatrons").then(interception => {
|
||||
const q = interception.request.query.q;
|
||||
expect(q).to.equal(
|
||||
'[{"library.name":"CPL"},{"me.library_id":"CPL"}]'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
it("From the column filter", () => {
|
||||
cy.task("buildSampleObjects", {
|
||||
object: "patron",
|
||||
count: RESTdefaultPageSize,
|
||||
values: {},
|
||||
}).then(patrons => {
|
||||
// Needs more properties to not explode
|
||||
// account_balace: balance_str.escapeHtml(...).format_price is not a function
|
||||
patrons = patrons.map(p => ({ ...p, account_balance: 0 }));
|
||||
|
||||
cy.intercept("GET", "/api/v1/patrons*", {
|
||||
statusCode: 200,
|
||||
body: patrons,
|
||||
headers: {
|
||||
"X-Base-Total-Count": baseTotalCount,
|
||||
"X-Total-Count": baseTotalCount,
|
||||
},
|
||||
}).as("searchPatrons");
|
||||
|
||||
cy.visit("/cgi-bin/koha/members/members-home.pl");
|
||||
|
||||
cy.window().then(win => {
|
||||
win.categories_map = patrons.reduce((map, p) => {
|
||||
map[p.category_id.toLowerCase()] = p.category_id;
|
||||
return map;
|
||||
}, {});
|
||||
});
|
||||
|
||||
cy.get("form.patron_search_form input[type='submit']").click();
|
||||
|
||||
cy.wait("@searchPatrons");
|
||||
|
||||
cy.get(
|
||||
`#${table_id} thead tr th[data-filter='libraries'] select`
|
||||
).select("^CPL$");
|
||||
|
||||
cy.wait("@searchPatrons").then(interception => {
|
||||
const q = interception.request.query.q;
|
||||
expect(q).to.equal(
|
||||
'[{"library.name":"CPL"},{"me.library_id":"CPL"}]'
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue