Skip to content

Commit

Permalink
Add patients CRUD test
Browse files Browse the repository at this point in the history
  • Loading branch information
xamelon committed Dec 29, 2023
1 parent 3dd2e1b commit 98053d7
Show file tree
Hide file tree
Showing 9 changed files with 433 additions and 231 deletions.
36 changes: 20 additions & 16 deletions routes/ui/auth/tests/auth.test.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { describe, expect, test } from 'vitest'
import { describe, expect, test, beforeAll } from 'vitest'

beforeAll(async () => {
await http({method: "POST",
url: "/$sql",
body: ["truncate patient"]});
});

describe('Patient', async () => {
test('Create /Patient', async () => {
test('Create /Patient', async () => {

let resp;
let resp;

resp = await http({method: "POST",
url: "/$sql",
body: ["truncate patient"]})
resp = await http({method: "POST",
url: "/$sql",
body: ["truncate patient"]})

resp = await http({method: "GET",
url: "/Patient"});
resp = await http({method: "GET",
url: "/Patient"});

expect(resp.total).toBe(0);

resp = await http({method: "POST",
url: "/Patient",
body: {name: [{given: ["John"]}]}});
resp = await http({method: "POST",
url: "/Patient",
body: {name: [{given: ["John"]}]}});

resp = await http({method: "GET",
url: "/Patient"});
resp = await http({method: "GET",
url: "/Patient"});

expect(resp.total).toBe(1);
})
})
})
1 change: 1 addition & 0 deletions routes/ui/forms/responses_get.clj
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
(status-button nil)
(status-button "completed")
(status-button "in-progress")]])

[:turbo-frame {:id "search"}
[:form {:action "/ui/forms/responses/search"
:class "relative flex items-center md:mt-0 mb-0"}
Expand Down
3 changes: 2 additions & 1 deletion routes/ui/patients/:id_delete.clj
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
(box/set-header! "Content-Type" "text/vnd.turbo-stream.html; charset=utf-8")

(let [params (box/route-params)
result (box/delete {:id (:id params) :resourceType "Patient"})]
result (box/delete {:id (:id params) :resourceType "Patient"})
_ (m/set :result result)]
(when (= (:resourceType result) "Patient")
[:turbo-stream {:target (str "patient-" (:id result))
:action "remove"}]
Expand Down
4 changes: 3 additions & 1 deletion routes/ui/patients/edit_get.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@

(let [params (box/url-params)
patient (when (:patient-id params)
(box/read {:id (:patient-id params) :resourceType "Patient"}))]
(box/read {:id (:patient-id params) :resourceType "Patient"}))
_ (m/set :patient patient)
]
[:turbo-stream {:target "modal"
:action "update"}
[:template
Expand Down
3 changes: 2 additions & 1 deletion routes/ui/patients/save_post.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
:birthDate (get-in params [:birth-date])}
(:id params)
(assoc :id (:id params)))
saved-patient (box/create patient)]
saved-patient (box/create patient)
_ (m/set :saved-patient saved-patient)]

(if (= (:resourceType saved-patient) "Patient")
[:<>
Expand Down
120 changes: 77 additions & 43 deletions routes/ui/patients/search_get.clj
Original file line number Diff line number Diff line change
@@ -1,54 +1,88 @@
(box/set-header! "Content-Type" "text/vnd.turbo-stream.html; charset=utf-8")

(let [params (box/url-params)
_ (m/set :params params)
patients (->> (box/sql ["select resource || jsonb_build_object('id', id) resource from Patient
where resource::text ilike ?" (str "%" (:query params) "%")])
(mapv :resource))
_ (m/set :patients patients)
]

[:turbo-stream {:target "patients"
:action "update"}
(into [:template]
(map (fn [p]
[:div {:class "contents"
:id (str "patient-" (:id p))}
[:div
{:class "px-4 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"}
[:h2
{:class "font-medium text-gray-800 dark:text-white"}
(str (get-in p [:name 0 :given 0]) ", "
(get-in p [:name 0 :family]))]]
[:div
{:class "px-12 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"}
(when-let [birth-date (get-in p [:birthDate])]
[:div
{:class
"inline px-3 py-1 text-sm font-normal rounded-full text-emerald-500 gap-x-2 bg-emerald-100/60 dark:bg-gray-800"}
birth-date])]
[:div
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"}

patients* (cond->> patients
(not-empty (:gender params))
(filter (fn [p] (= (:gender params) (:gender p)))))
_ (m/set :patients patients*)
encode-params (fn [qparams]
(->> qparams
(map (fn [[k v]] (str (name k) "=" v)))
(clojure.string/join "&")))]
[:<>
(when (:gender params)
(let [inactive-class "px-5 py-2 text-xs font-medium text-gray-600 transition-colors duration-200 sm:text-sm dark:bg-gray-800 dark:text-gray-300"
active-class (str inactive-class " bg-gray-100")

status-button (fn [gender]
[:a
{:class (if (= (:gender params) (not-empty gender)) active-class inactive-class)
:data-turbo-action "advance"
:href (str "/ui/patients?" (cond-> params
(not-empty gender)
(assoc :gender gender)

(empty? gender)
(dissoc :gender)

:true
encode-params))}
(or (some-> gender not-empty clojure.string/capitalize) "View all")])]
[:turbo-stream {:target "gender-filter"
:action "update"}
[:template
(status-button "")
(status-button "male")
(status-button "female")]])
)

[:turbo-stream {:target "patients"
:action "update"}
(into [:template]
(map (fn [p]
[:div {:class "contents"
:id (str "patient-" (:id p))}
[:div
{:class "px-4 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"}
[:h2
{:class "font-medium text-gray-800 dark:text-white"}
(str (get-in p [:name 0 :given 0]) ", "
(get-in p [:name 0 :family]))]]
[:div
{:class "px-12 py-4 text-sm font-medium whitespace-nowrap flex items-center border-b"}
(when-let [birth-date (get-in p [:birthDate])]
[:div
[:h4 {:class "text-gray-700 dark:text-gray-200"} (get-in p [:gender])]]]
[:div
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"}
[:form {:action "/ui/patients/edit"
:class "mb-0"}
[:input {:type "hidden"
:name "patient-id"
:value (:id p)}]
[:button
{:class
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100"}
[:i.fas.fa-pencil]]]
[:a
{:class
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100"
:href (str "/ui/patients/" (str (:id p)))
:data-turbo-method "DELETE"
:data-turbo-confirm "Do you want to delete patient?"}
[:i.fas.fa-trash]]]]) patients))
"inline px-3 py-1 text-sm font-normal rounded-full text-emerald-500 gap-x-2 bg-emerald-100/60 dark:bg-gray-800"}
birth-date])]
[:div
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"}
[:div
[:h4 {:class "text-gray-700 dark:text-gray-200"} (get-in p [:gender])]]]
[:div
{:class "px-4 py-4 text-sm whitespace-nowrap flex items-center border-b"}
[:form {:action "/ui/patients/edit"
:class "mb-0"}
[:input {:type "hidden"
:name "patient-id"
:value (:id p)}]
[:button
{:class
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100"}
[:i.fas.fa-pencil]]]
[:a
{:class
"px-3 py-2 text-gray-500 transition-colors duration-200 rounded-lg dark:text-gray-300 hover:bg-gray-100"
:href (str "/ui/patients/" (str (:id p)))
:data-turbo-method "DELETE"
:data-turbo-confirm "Do you want to delete patient?"}
[:i.fas.fa-trash]]]]) patients*))


]
]]
)
134 changes: 134 additions & 0 deletions routes/ui/patients/tests/patients.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { describe, expect, test, afterAll, beforeAll } from 'vitest'

beforeAll(async () => {
console.log("Delete all: ");

await http({method: "POST",
url: "/$sql",
body: ["truncate patient"]});

await http({method: "POST",
url: "/Patient",
body: {id: "pt-1",
name: [{given: ["Paul"], family: "Mask"}]}})

});

afterAll(async () => {
await http({method: "POST",
url: "/$sql",
body: ["truncate patient"]});
});

describe('Patient grid', async () => {
let resp;
test("patient grid", async () => {
resp = await http({method: "GET",
url: "/ui/patients/search",
headers: {"X-Aidbox-Dev": "model"}
});

console.log(resp);

expect(resp).toEqual({
params: {},
patients: expect.arrayContaining(
[{id: "pt-1",
name: [{family: "Mask", given: ["Paul"]}]}]
)});
});

test("search should return empty list", async () => {
resp = await http({method: "GET",
url: "/ui/patients/search?query=tahto",
headers: {"X-Aidbox-Dev": "model"}});
expect(resp).toEqual({
params: {query: "tahto"},
patients: [],
});

});

test("search should return one patient", async () => {
resp = await http({method: "GET",
url: "/ui/patients/search?query=paul",
headers: {"X-Aidbox-Dev": "model"}});
expect(resp).toEqual({
params: {query: "paul"},
patients: [{id: "pt-1",
name: [{family: "Mask", given: ["Paul"]}]}],
});
})

});

describe('patient form', async () => {
let resp;

test("add patient should open empty form", async () => {
resp = await http({method: "GET",
url: "/ui/patients/edit",
headers: {"X-Aidbox-Dev": "model"}});

expect(resp.patient).toBeNull();
});

test("edit patient should open filled form", async () => {
resp = await http({method: "GET",
url: "/ui/patients/edit?patient-id=pt-1",
headers: {"X-Aidbox-Dev": "model"}});

expect(resp.patient).toMatchObject({
id: "pt-1",
name: [{given: ["Paul"], family: "Mask"}]
});
});

test("save patient should return new patient", async () => {
var formData = new FormData();
formData.append("id", "pt-1");
formData.append("given", "Pasha"),
formData.append("family", "Mask");
formData.append("gender", "male");

resp = await http({method: "POST",
url: "/ui/patients/save",
body: formData,
headers: {
"content-type": "multipart/form-data",
"x-aidbox-dev": "model",
}});

expect(resp).toMatchObject({
"saved-patient": {
id: "pt-1",
name: [{given: ["Pasha"], family: "Mask"}],
gender: "male",

}});

});
});

describe("delete patient", async () => {
let resp;

test("delete patient", async () => {
resp = await http({method: "DELETE",
url: "/ui/patients/pt-1",
headers: {"x-aidbox-dev": "model"}});

expect(resp.result).toMatchObject({
id: "pt-1",
});
});

test("patient grid should not include deleted patient", async () => {
resp = await http({method: "GET",
url: "/ui/patients/search?query=Mask",
headers: {"x-aidbox-dev": "model"}});

expect(resp.patients).toEqual([]);

});
});
Loading

0 comments on commit 98053d7

Please sign in to comment.