Skip to content

Commit

Permalink
Ensure Error Response on Invalid Value in FHIR Search
Browse files Browse the repository at this point in the history
In the default lenient handling, invalid search values were ignored.
This is not the intended behaviour. Only unknown search parameters
should be ignored, but not invalid values.
  • Loading branch information
alexanderkiel committed Dec 10, 2021
1 parent 8d265e1 commit 40b6279
Show file tree
Hide file tree
Showing 6 changed files with 135 additions and 13 deletions.
2 changes: 1 addition & 1 deletion modules/db/src/blaze/db/api_spec.clj
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
:args (s/cat :node-or-db (s/or :node :blaze.db/node :db :blaze.db/db)
:type :fhir.type/name
:clauses :blaze.db.query/clauses)
:ret :blaze.db/query)
:ret (s/or :query :blaze.db/query :anomaly ::anom/anomaly))



Expand Down
9 changes: 5 additions & 4 deletions modules/db/src/blaze/db/node.clj
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,11 @@
(batch-db/->TypeQuery (codec/tid type) (seq clauses))))

(-compile-type-query-lenient [_ type clauses]
(if-let [clauses (seq (resolve-search-params search-param-registry type
clauses true))]
(batch-db/->TypeQuery (codec/tid type) clauses)
(batch-db/->EmptyTypeQuery (codec/tid type))))
(when-ok [clauses (resolve-search-params search-param-registry type clauses
true)]
(if-let [clauses (seq clauses)]
(batch-db/->TypeQuery (codec/tid type) clauses)
(batch-db/->EmptyTypeQuery (codec/tid type)))))

(-compile-system-query [_ clauses]
(when-ok [clauses (resolve-search-params search-param-registry "Resource"
Expand Down
32 changes: 27 additions & 5 deletions modules/db/test/blaze/db/api_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2888,7 +2888,12 @@
(given (d/compile-type-query node "Patient" [["foo" "bar"]
["active" "true"]])
::anom/category := ::anom/not-found
::anom/message := "The search-param with code `foo` and type `Patient` was not found.")))))
::anom/message := "The search-param with code `foo` and type `Patient` was not found."))

(testing "invalid date"
(given (d/compile-type-query node "Patient" [["birthdate" "invalid"]])
::anom/category := ::anom/incorrect
::anom/message := "Invalid date-time value `invalid` in search parameter `birthdate`.")))))


(deftest compile-type-query-lenient-test
Expand All @@ -2897,21 +2902,38 @@
@(d/transact node [[:put {:fhir/type :fhir/Patient :id "0" :active true}]])

(testing "the patient can be found"
(given @(->> (d/compile-type-query-lenient node "Patient" [["active" "true"]])
(given @(->> (d/compile-type-query-lenient
node "Patient" [["active" "true"]])
(d/execute-query (d/db node))
(d/pull-many node))
[0 :fhir/type] := :fhir/Patient
[0 :id] := "0"))

(testing "an unknown search-param is ignored"
(let [clauses [["foo" "bar"] ["active" "true"]]
query (d/compile-type-query-lenient node "Patient" clauses)]
(let [query (d/compile-type-query-lenient
node "Patient" [["foo" "bar"] ["active" "true"]])]
(given @(d/pull-many node (d/execute-query (d/db node) query))
[0 :fhir/type] := :fhir/Patient
[0 :id] := "0")

(testing "the clause [\"foo\" \"bar\"] was not used"
(is (= [["active" "true"]] (d/query-clauses query)))))))))
(is (= [["active" "true"]] (d/query-clauses query)))))

(testing "one unknown search parameter will result in an empty query"
(let [query (d/compile-type-query-lenient
node "Patient" [["foo" "bar"]])]
(given @(d/pull-many node (d/execute-query (d/db node) query))
[0 :fhir/type] := :fhir/Patient
[0 :id] := "0")

(testing "the clause [\"foo\" \"bar\"] was not used"
(is (empty? (d/query-clauses query)))))))

(testing "invalid date"
(given (d/compile-type-query-lenient
node "Patient" [["birthdate" "invalid"]])
::anom/category := ::anom/incorrect
::anom/message := "Invalid date-time value `invalid` in search parameter `birthdate`.")))))



Expand Down
4 changes: 2 additions & 2 deletions modules/interaction/src/blaze/interaction/search_type.clj
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
:clauses clauses})

:else
(let [query (d/compile-type-query-lenient db type clauses)]
(when-ok [query (d/compile-type-query-lenient db type clauses)]
{:handles (execute-query db query page-id)
:clauses (d/query-clauses query)})))

Expand Down Expand Up @@ -193,7 +193,7 @@
:clauses clauses})

:else
(let [query (d/compile-type-query-lenient db type clauses)]
(when-ok [query (d/compile-type-query-lenient db type clauses)]
{:total (count (d/execute-query db query))
:clauses (d/query-clauses query)})))

Expand Down
34 changes: 34 additions & 0 deletions modules/interaction/test/blaze/interaction/search_type_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -456,6 +456,40 @@
(is (= #fhir/uri"base-url-113047/Patient?active=true&_summary=count&_count=50&__t=1"
(link-url body "self")))))))))))

(testing "on invalid date-time"
(testing "returns error"
(with-handler [handler]
[]
(testing "normal result"
(let [{:keys [status body]}
@(handler
{::reitit/match observation-match
;; the date is already URl decoded and so contains a space instead of a plus
:params {"date" "2021-12-09T00:00:00 01:00"}})]

(is (= 400 status))

(given body
:fhir/type := :fhir/OperationOutcome
[:issue 0 :severity] := #fhir/code"error"
[:issue 0 :code] := #fhir/code"invalid"
[:issue 0 :diagnostics] := "Invalid date-time value `2021-12-09T00:00:00 01:00` in search parameter `date`.")))

(testing "summary result"
(let [{:keys [status body]}
@(handler
{::reitit/match observation-match
;; the date is already URl decoded and so contains a space instead of a plus
:params {"date" "2021-12-09T00:00:00 01:00" "_summary" "count"}})]

(is (= 400 status))

(given body
:fhir/type := :fhir/OperationOutcome
[:issue 0 :severity] := #fhir/code"error"
[:issue 0 :code] := #fhir/code"invalid"
[:issue 0 :diagnostics] := "Invalid date-time value `2021-12-09T00:00:00 01:00` in search parameter `date`."))))))

(testing "on invalid token"
(testing "returns error"
(with-handler [handler]
Expand Down
67 changes: 66 additions & 1 deletion modules/interaction/test/blaze/interaction/transaction_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,8 @@
[["/Observation"
{:name :Observation/type
:fhir.resource/type "Observation"
:get {:middleware [[wrap-db node]]
:handler (wrap-params search-type-handler)}
:post create-handler}]
["/Patient"
{:name :Patient/type
Expand Down Expand Up @@ -1774,4 +1776,67 @@

(testing "entry response"
(given response
:status := "200"))))))))
:status := "200")))))

(testing "with date-time search param value"
(with-handler [handler]
[[[:create
{:fhir/type :fhir/Observation :id "0"
:effective #fhir/dateTime"2021-12-08T00:00:00+01:00"}]
[:create
{:fhir/type :fhir/Observation :id "1"
:effective #fhir/dateTime"2021-12-09T00:00:00+01:00"}]]]

(let [{:keys [status] {[{:keys [resource response]}] :entry} :body}
@(handler
{:body
{:fhir/type :fhir/Bundle
:type #fhir/code"batch"
:entry
[{:fhir/type :fhir.Bundle/entry
:request
{:fhir/type :fhir.Bundle.entry/request
:method #fhir/code"GET"
:url #fhir/uri"Observation?date=lt2021-12-08T10:00:00%2B01:00"}}]}})]

(testing "response status"
(is (= 200 status)))

(testing "entry resource"
(given resource
:fhir/type := :fhir/Bundle
:type := #fhir/code"searchset"
:total := #fhir/unsignedInt 1
[:entry count] := 1))

(testing "entry response"
(given response
:status := "200")))

(testing "without encoding of the plus in the timezone"
(let [{:keys [status] {[{:keys [response]}] :entry} :body}
@(handler
{:body
{:fhir/type :fhir/Bundle
:type #fhir/code"batch"
:entry
[{:fhir/type :fhir.Bundle/entry
:request
{:fhir/type :fhir.Bundle.entry/request
:method #fhir/code"GET"
:url #fhir/uri"Observation?date=lt2021-12-09T00:00:00+01:00"}}]}})]

(testing "response status"
(is (= 200 status)))

(testing "returns error"
(testing "with status"
(is (= "400" (:status response))))

(testing "with outcome"
(given (:outcome response)
:fhir/type := :fhir/OperationOutcome
[:issue 0 :severity] := #fhir/code"error"
[:issue 0 :code] := #fhir/code"invalid"
[:issue 0 :diagnostics] := "Invalid date-time value `2021-12-09T00:00:00 01:00` in search parameter `date`."
[:issue 0 :expression 0] := "Bundle.entry[0]"))))))))))

0 comments on commit 40b6279

Please sign in to comment.