Skip to content

Commit ffed9fc

Browse files
committed
test/qg-264: добавлены тесты на скрипты черновиков форм карточки клиента и записи журнала
1 parent 7db9c29 commit ffed9fc

10 files changed

Lines changed: 175 additions & 104 deletions

File tree

app/src/main/resources/templates/therapist/clients/client-card-fragment.html

Lines changed: 49 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,59 +1,58 @@
1-
<script src="/js/form-drafts.js"></script>
2-
3-
<script th:inline="javascript">
4-
let serverState = /*[[${client}]]*/ null;
5-
let clientId = /*[[${clientId}]]*/ null;
6-
7-
let localStateKey = `qyoga.clientCardForm.${clientId || "new"}`;
8-
9-
let localState = localStorage.getItem(localStateKey) ? JSON.parse(localStorage.getItem(localStateKey)) : null;
10-
11-
let formData;
12-
if (serverState == null) {
13-
formData = localState || {version: 0};
14-
} else if (serverState.version === localState?.version) {
15-
formData = localState
16-
} else {
17-
formData = {...serverState}
18-
}
19-
20-
function clientCardData() {
21-
let hasUnsavedEdits = serverState != null && localState != null && !shallowEqual(serverState, localState);
22-
let newCardWasntSaved = serverState == null && localState != null;
23-
return {
24-
form: formData,
25-
serverState: serverState,
26-
hasUnsavedChanges: hasUnsavedEdits || newCardWasntSaved
27-
}
28-
}
29-
30-
function saveLocalState(formData) {
31-
localStorage.setItem(localStateKey, JSON.stringify(formData));
32-
}
33-
34-
function resetLocalState() {
35-
localStorage.removeItem(localStateKey);
36-
}
37-
38-
function isChanged(form, key) {
39-
return serverState != null && serverState[key] !== form[key];
40-
}
41-
42-
window.addEventListener("load", () => {
43-
document.querySelectorAll(".form-control").forEach(it => {
44-
it.setAttribute("x-model", "form." + it.name);
45-
it.setAttribute(":class", "isChanged(form, '" + it.name + "') ? 'border-warning' : ''");
46-
});
47-
});
48-
49-
</script>
50-
511
<div class="client__container" id="clientCardTab">
522
<form class="form__client-card" id="createClientForm" method="post" th:action="${formAction}"
533
th:fragment="createClientForm"
544
x-data="clientCardData()"
555
x-init="$watch('form', (form) => saveLocalState(form))">
566

7+
<script src="/js/form-drafts.js"></script>
8+
<script id="formDraft" th:inline="javascript">
9+
let serverState = /*[[${client}]]*/ null;
10+
let clientId = /*[[${clientId}]]*/ null;
11+
12+
let localStateKey = `qyoga.clientCardForm.${clientId || "new"}`;
13+
14+
let localState = localStorage.getItem(localStateKey) ? JSON.parse(localStorage.getItem(localStateKey)) : null;
15+
16+
let formData;
17+
if (serverState == null) {
18+
formData = localState || {version: 0};
19+
} else if (serverState.version === localState?.version) {
20+
formData = localState
21+
} else {
22+
formData = {...serverState}
23+
}
24+
25+
function clientCardData() {
26+
let hasUnsavedEdits = serverState != null && localState != null && !shallowEqual(serverState, localState);
27+
let newCardWasntSaved = serverState == null && localState != null;
28+
return {
29+
form: formData,
30+
serverState: serverState,
31+
hasUnsavedChanges: hasUnsavedEdits || newCardWasntSaved
32+
}
33+
}
34+
35+
function saveLocalState(formData) {
36+
localStorage.setItem(localStateKey, JSON.stringify(formData));
37+
}
38+
39+
function resetLocalState() {
40+
localStorage.removeItem(localStateKey);
41+
}
42+
43+
function isChanged(form, key) {
44+
return serverState != null && serverState[key] !== form[key];
45+
}
46+
47+
window.addEventListener("load", () => {
48+
document.querySelectorAll(".form-control").forEach(it => {
49+
it.setAttribute("x-model", "form." + it.name);
50+
it.setAttribute(":class", "isChanged(form, '" + it.name + "') ? 'border-warning' : ''");
51+
});
52+
});
53+
54+
</script>
55+
5756
<input
5857
name="version"
5958
th:value="${client?.version ?: 0}"

app/src/main/resources/templates/therapist/clients/journal-entry.html

Lines changed: 50 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,3 @@
1-
2-
<script th:inline="javascript">
3-
let serverState = /*[[${entry}]]*/ null;
4-
let clientId = /*[[${client.id}]]*/ null;
5-
let entryId = /*[[${entryId}]]*/ null;
6-
let entryDate = /*[[${#temporals.format((entry?.date ?: entryDate), T(pro.qyoga.l10n.DateFormatsKt).RUSSIAN_DATE_FORMAT_PATTERN)}]]*/ null;
7-
8-
let localStateKey = `qyoga.journalEntryForm.${clientId}.${entryId || "new"}`;
9-
10-
let localState = localStorage.getItem(localStateKey) ? JSON.parse(localStorage.getItem(localStateKey)) : null;
11-
12-
let formData;
13-
if (serverState == null) {
14-
formData = localState || {version: 0, date: entryDate};
15-
} else if (serverState.version === localState?.version) {
16-
formData = localState
17-
} else {
18-
formData = {...serverState}
19-
}
20-
21-
function entryData() {
22-
let hasUnsavedEdits = serverState != null && localState != null && !shallowEqual(serverState, localState);
23-
let newCardWasntSaved = serverState == null && localState != null;
24-
return {
25-
form: formData,
26-
serverState: serverState,
27-
hasUnsavedChanges: hasUnsavedEdits || newCardWasntSaved
28-
}
29-
}
30-
31-
function saveLocalState(formData) {
32-
localStorage.setItem(localStateKey, JSON.stringify(formData));
33-
}
34-
35-
function resetLocalState() {
36-
localStorage.removeItem(localStateKey);
37-
}
38-
39-
function isChanged(form, key) {
40-
return serverState != null && serverState[key] !== form[key];
41-
}
42-
43-
window.addEventListener("htmx:afterSettle", () => {
44-
document.querySelectorAll(".form-control").forEach(it => {
45-
it.setAttribute("x-model", "form." + it.name);
46-
it.setAttribute(":class", "isChanged(form, '" + it.name + "') ? 'border-warning' : ''");
47-
});
48-
});
49-
50-
</script>
51-
521
<div id="createJournalEntryTabContent">
532
<style>
543
/* For medium screens and larger */
@@ -75,6 +24,56 @@
7524
x-data="entryData()"
7625
x-init="$watch('form', (form) => saveLocalState(form))">
7726

27+
<script id="formDraft" th:inline="javascript">
28+
let serverState = /*[[${entry}]]*/ null;
29+
let clientId = /*[[${client.id}]]*/ null;
30+
let entryId = /*[[${entryId}]]*/ null;
31+
let entryDate = /*[[${#temporals.format((entry?.date ?: entryDate), T(pro.qyoga.l10n.DateFormatsKt).RUSSIAN_DATE_FORMAT_PATTERN)}]]*/ null;
32+
33+
let localStateKey = `qyoga.journalEntryForm.${clientId}.${entryId || "new"}`;
34+
35+
let localState = localStorage.getItem(localStateKey) ? JSON.parse(localStorage.getItem(localStateKey)) : null;
36+
37+
let formData;
38+
if (serverState == null) {
39+
formData = localState || {version: 0, date: entryDate};
40+
} else if (serverState.version === localState?.version) {
41+
formData = localState
42+
} else {
43+
formData = {...serverState}
44+
}
45+
46+
function entryData() {
47+
let hasUnsavedEdits = serverState != null && localState != null && !shallowEqual(serverState, localState);
48+
let newCardWasntSaved = serverState == null && localState != null;
49+
return {
50+
form: formData,
51+
serverState: serverState,
52+
hasUnsavedChanges: hasUnsavedEdits || newCardWasntSaved
53+
}
54+
}
55+
56+
function saveLocalState(formData) {
57+
localStorage.setItem(localStateKey, JSON.stringify(formData));
58+
}
59+
60+
function resetLocalState() {
61+
localStorage.removeItem(localStateKey);
62+
}
63+
64+
function isChanged(form, key) {
65+
return serverState != null && serverState[key] !== form[key];
66+
}
67+
68+
window.addEventListener("htmx:afterSettle", () => {
69+
document.querySelectorAll(".form-control").forEach(it => {
70+
it.setAttribute("x-model", "form." + it.name);
71+
it.setAttribute(":class", "isChanged(form, '" + it.name + "') ? 'border-warning' : ''");
72+
});
73+
});
74+
75+
</script>
76+
7877
<input
7978
name="version"
8079
th:value="${entry?.version ?: 0}"

app/src/test/kotlin/pro/qyoga/tests/cases/app/therapist/clients/journal/CreateJournalEntryPageTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ class CreateJournalEntryPageTest : QYogaAppIntegrationBaseTest() {
3838
val document = therapist.clientJournal.getCreateJournalEntryPage(client.id)
3939

4040
// Проверка
41-
document shouldBePage CreateJournalEntryPage(client.id)
41+
document shouldBePage CreateJournalEntryPage(client.id, LocalDate.now())
4242
}
4343

4444
@Test

app/src/testFixtures/kotlin/pro/qyoga/tests/assertions/ClientMatchers.kt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import pro.qyoga.core.clients.cards.dtos.ClientCardDto
55
import pro.qyoga.core.clients.cards.model.Client
66
import pro.qyoga.core.clients.cards.model.PhoneNumber
77
import pro.qyoga.core.clients.cards.model.toE164Format
8+
import pro.qyoga.core.clients.cards.model.toUIFormat
89

910

1011
infix fun Client.shouldMatch(clientCardDto: ClientCardDto) {
@@ -19,4 +20,18 @@ infix fun Client.shouldMatch(clientCardDto: ClientCardDto) {
1920
distributionSource?.comment shouldBe clientCardDto.distributionSourceComment
2021
complaints shouldBe clientCardDto.complaints
2122
anamnesis shouldBe clientCardDto.anamnesis
23+
}
24+
25+
infix fun ClientCardDto.shouldMatch(client: Client) {
26+
firstName shouldBe client.firstName
27+
lastName shouldBe client.lastName
28+
middleName shouldBe client.middleName
29+
birthDate shouldBe client.birthDate
30+
phoneNumber shouldBe client.phoneNumber.toUIFormat()
31+
email shouldBe client.email
32+
address shouldBe client.address
33+
distributionSource?.type shouldBe client.distributionSource?.type
34+
distributionSource?.comment shouldBe client.distributionSource?.comment
35+
complaints shouldBe client.complaints
36+
anamnesis shouldBe client.anamnesis
2237
}

app/src/test/kotlin/pro/qyoga/tests/assertions/JournalEntryMatchers.kt renamed to app/src/testFixtures/kotlin/pro/qyoga/tests/assertions/JournalEntryMatchers.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,10 @@ infix fun JournalEntry.shouldMatch(editJournalEntryRq: EditJournalEntryRq) {
1010
date shouldBe editJournalEntryRq.date
1111
therapeuticTask.resolveOrThrow().name shouldBe editJournalEntryRq.therapeuticTaskName
1212
entryText shouldBe editJournalEntryRq.journalEntryText
13+
}
14+
15+
infix fun EditJournalEntryRq.shouldMatch(journalEntry: JournalEntry) {
16+
date shouldBe journalEntry.date
17+
therapeuticTaskName shouldBe journalEntry.therapeuticTask.resolveOrThrow().name
18+
journalEntryText shouldBe journalEntryText
1319
}

app/src/testFixtures/kotlin/pro/qyoga/tests/pages/therapist/clients/card/ClientForm.kt

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
package pro.qyoga.tests.pages.therapist.clients.card
22

33
import io.kotest.matchers.shouldBe
4+
import pro.qyoga.core.clients.cards.dtos.ClientCardDto
45
import pro.qyoga.core.clients.cards.model.Client
56
import pro.qyoga.core.clients.cards.model.DistributionSourceType
67
import pro.qyoga.core.clients.cards.model.toUIFormat
78
import pro.qyoga.l10n.russianDateFormat
89
import pro.qyoga.tests.assertions.PageMatcher
910
import pro.qyoga.tests.assertions.SelectorOnlyComponent
11+
import pro.qyoga.tests.assertions.shouldMatch
1012
import pro.qyoga.tests.platform.html.*
1113
import pro.qyoga.tests.platform.html.Input.Companion.email
1214
import pro.qyoga.tests.platform.html.Input.Companion.hidden
1315
import pro.qyoga.tests.platform.html.Input.Companion.tel
1416
import pro.qyoga.tests.platform.html.Input.Companion.text
17+
import java.util.*
1518

1619
abstract class ClientForm(action: FormAction) : QYogaForm("createClientForm", action) {
1720

@@ -32,6 +35,12 @@ abstract class ClientForm(action: FormAction) : QYogaForm("createClientForm", ac
3235
val version = hidden("version", false)
3336
val submit = Button("confirmButton", "Сохранить")
3437

38+
object FormDraftScript : Script("formDraft") {
39+
val clientId = Variable("clientId")
40+
val serverState = Variable("serverState")
41+
override val vars = listOf(clientId, serverState)
42+
}
43+
3544
override val components: List<Component> = listOf(
3645
firstName,
3746
lastName,
@@ -67,6 +76,14 @@ object EditClientForm : ClientForm(FormAction.classicPost("/therapist/clients/{i
6776
element.select(distributionSourceComment.selector())
6877
.`val`() shouldBe (client.distributionSource?.comment ?: "")
6978
element.select(complaints.selector()).text() shouldBe (client.complaints ?: "")
79+
FormDraftScript.clientId.value(
80+
element.select(FormDraftScript.selector()).single(),
81+
UUID::class
82+
) shouldBe client.id
83+
FormDraftScript.serverState.value(
84+
element.select(FormDraftScript.selector()).single(),
85+
ClientCardDto::class
86+
)!! shouldMatch client
7087
}
7188

7289
}

app/src/testFixtures/kotlin/pro/qyoga/tests/pages/therapist/clients/journal/entry/CreateJournalEntryPage.kt

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import java.time.LocalDate
1010
import java.util.*
1111

1212

13-
class CreateJournalEntryPage(val clientId: UUID) : QYogaPage {
13+
class CreateJournalEntryPage(val clientId: UUID, private val today: LocalDate) : QYogaPage {
1414

1515
override val path: String = CreateJournalEntryPageController.CREATE_JOURNAL_PAGE_URL
1616

@@ -20,6 +20,12 @@ class CreateJournalEntryPage(val clientId: UUID) : QYogaPage {
2020
element shouldHaveComponent CreateJournalEntryForm
2121
CreateJournalEntryForm.actionParam(element, "clientId")?.let { UUID.fromString(it) } shouldBe clientId
2222
CreateJournalEntryForm.dateInput.value(element) shouldBe russianDateFormat.format(LocalDate.now())
23+
JournalEntryFrom.FormDraftScript.clientId.value(
24+
element.select(JournalEntryFrom.FormDraftScript.selector()).single(), UUID::class
25+
) shouldBe clientId
26+
JournalEntryFrom.FormDraftScript.entryDate.value(
27+
element.select(JournalEntryFrom.FormDraftScript.selector()).single(), String::class
28+
) shouldBe (today.format(russianDateFormat))
2329
}
2430

2531
}

app/src/testFixtures/kotlin/pro/qyoga/tests/pages/therapist/clients/journal/entry/EditJournalEntryPage.kt

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,16 @@ import io.kotest.matchers.Matcher
44
import io.kotest.matchers.shouldBe
55
import org.jsoup.nodes.Element
66
import pro.azhidkov.platform.spring.sdj.ergo.hydration.resolveOrThrow
7+
import pro.qyoga.core.clients.journals.dtos.EditJournalEntryRq
78
import pro.qyoga.core.clients.journals.model.JournalEntry
89
import pro.qyoga.l10n.russianDateFormat
910
import pro.qyoga.tests.assertions.PageMatcher
1011
import pro.qyoga.tests.assertions.alwaysSuccess
1112
import pro.qyoga.tests.assertions.shouldBeComponent
13+
import pro.qyoga.tests.assertions.shouldMatch
14+
import pro.qyoga.tests.pages.therapist.clients.journal.entry.JournalEntryFrom.FormDraftScript
1215
import pro.qyoga.tests.platform.html.Component
16+
import java.util.*
1317

1418

1519
object EditJournalEntryPage : Component {
@@ -28,6 +32,14 @@ object EditJournalEntryPage : Component {
2832
EditJournalEntryForm.dateInput.value(element) shouldBe russianDateFormat.format(entry.date)
2933
EditJournalEntryForm.therapeuticTaskNameInput.value(element) shouldBe entry.therapeuticTask.resolveOrThrow().name
3034
EditJournalEntryForm.entryTextInput.value(element) shouldBe entry.entryText
35+
val scriptElement = element.select(FormDraftScript.selector()).single()
36+
FormDraftScript.clientId.value(scriptElement, UUID::class) shouldBe entry.clientRef.id
37+
FormDraftScript.entryId.value(scriptElement, Long::class) shouldBe entry.id
38+
FormDraftScript.entryDate.value(
39+
scriptElement,
40+
String::class
41+
) shouldBe (entry.date.format(russianDateFormat))
42+
FormDraftScript.serverState.value(scriptElement, EditJournalEntryRq::class)!! shouldMatch entry
3143
}
3244

3345
}

app/src/testFixtures/kotlin/pro/qyoga/tests/pages/therapist/clients/journal/entry/JournalEntryFrom.kt

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,14 @@ abstract class JournalEntryFrom(action: FormAction) : QYogaForm("journalEntryFro
1212

1313
private val addButton = Button("confirmButton", "Сохранить")
1414

15+
object FormDraftScript : Script("formDraft") {
16+
val clientId = Variable("clientId")
17+
val entryId = Variable("entryId")
18+
val entryDate = Variable("entryDate")
19+
val serverState = Variable("serverState")
20+
override val vars = listOf(clientId, serverState, entryId, entryDate)
21+
}
22+
1523
companion object {
1624
const val DUPLICATED_DATE_MESSAGE = "div.invalid-feedback:contains(Запись за эту дату уже существует)"
1725
}
@@ -20,7 +28,8 @@ abstract class JournalEntryFrom(action: FormAction) : QYogaForm("journalEntryFro
2028
dateInput,
2129
therapeuticTaskNameInput,
2230
entryTextInput,
23-
addButton
31+
addButton,
32+
FormDraftScript
2433
)
2534

2635
}

0 commit comments

Comments
 (0)