diff --git a/ui/src/Stores/AlertStore.js b/ui/src/Stores/AlertStore.js index eb0b1a972..e6025abb5 100644 --- a/ui/src/Stores/AlertStore.js +++ b/ui/src/Stores/AlertStore.js @@ -46,8 +46,11 @@ function DecodeLocationSearch(searchString) { if (parsed.q === "") { params.q = []; } else if (Array.isArray(parsed.q)) { - // filter out empty strings, so 'q=' doesn't end up [""] but rather [] - params.q = parsed.q.filter(v => v !== ""); + // first filter out duplicates + // then filter out empty strings, so 'q=' doesn't end up [""] but rather [] + params.q = parsed.q + .filter((v, i) => parsed.q.indexOf(v) === i) + .filter(v => v !== ""); } else { params.q = [parsed.q]; } diff --git a/ui/src/Stores/AlertStore.test.js b/ui/src/Stores/AlertStore.test.js index 3f82a11a1..210ccba93 100644 --- a/ui/src/Stores/AlertStore.test.js +++ b/ui/src/Stores/AlertStore.test.js @@ -181,6 +181,13 @@ describe("DecodeLocationSearch", () => { }); }); + it("no value q[]=&q[]= search param is decoded correctly", () => { + expect(DecodeLocationSearch("?q=")).toMatchObject({ + defaultsUsed: false, + params: { q: [] } + }); + }); + it("single value q=foo search param is decoded correctly", () => { expect(DecodeLocationSearch("?q=foo")).toMatchObject({ defaultsUsed: false, @@ -201,6 +208,20 @@ describe("DecodeLocationSearch", () => { params: { q: ["foo", "bar"] } }); }); + + it("multi value q[]=foo&q[]=bar&q[]=foo search param is decoded correctly", () => { + expect(DecodeLocationSearch("?q[]=foo&q[]=bar&q[]=foo")).toMatchObject({ + defaultsUsed: false, + params: { q: ["foo", "bar"] } + }); + }); + + it("multi value q[]=foo&q[]=&q[]=foo search param is decoded correctly", () => { + expect(DecodeLocationSearch("?q[]=foo&q[]=&q[]=foo")).toMatchObject({ + defaultsUsed: false, + params: { q: ["foo"] } + }); + }); }); describe("UpdateLocationSearch", () => {