[UX] #599 separate database preparation from settings
This commit is contained in:
@@ -31,6 +31,11 @@ public class SettingController {
|
||||
model.addAttribute("runtimeErrorTitle", error.title());
|
||||
model.addAttribute("runtimeErrorMessage", error.message());
|
||||
}
|
||||
return "settings";
|
||||
}
|
||||
|
||||
@GetMapping("/settings/database")
|
||||
public String databaseSettings(Model model) {
|
||||
try {
|
||||
model.addAttribute("schemaPreflight", backofficeSchemaService.preflight());
|
||||
} catch (DataAccessException exception) {
|
||||
@@ -38,7 +43,7 @@ public class SettingController {
|
||||
model.addAttribute("schemaPreflightErrorTitle", error.title());
|
||||
model.addAttribute("schemaPreflightErrorMessage", error.message());
|
||||
}
|
||||
return "settings";
|
||||
return "settings-database";
|
||||
}
|
||||
|
||||
@PostMapping("/settings/ords")
|
||||
@@ -51,8 +56,16 @@ public class SettingController {
|
||||
return "redirect:/settings";
|
||||
}
|
||||
|
||||
@PostMapping("/settings/schema/initialize")
|
||||
public String initializeSchema(RedirectAttributes redirectAttributes) {
|
||||
@PostMapping("/settings/database/initialize")
|
||||
public String initializeSchema(
|
||||
@RequestParam String confirmation,
|
||||
RedirectAttributes redirectAttributes
|
||||
) {
|
||||
if (!"DB 준비 실행".equals(confirmation)) {
|
||||
redirectAttributes.addFlashAttribute(
|
||||
"error", "DB 지원 DDL을 실행하려면 확인 문구 ‘DB 준비 실행’을 정확히 입력하세요.");
|
||||
return "redirect:/settings/database";
|
||||
}
|
||||
var results = backofficeSchemaService.initializeSchema();
|
||||
long failures = results.stream()
|
||||
.filter(result -> "FAILED".equalsIgnoreCase(result.status()))
|
||||
@@ -63,6 +76,6 @@ public class SettingController {
|
||||
} else {
|
||||
redirectAttributes.addFlashAttribute("message", "백오피스 지원 테이블 DDL을 실행했습니다.");
|
||||
}
|
||||
return "redirect:/settings";
|
||||
return "redirect:/settings/database";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -358,6 +358,57 @@ body {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.back-link {
|
||||
color: var(--rw-primary);
|
||||
display: inline-block;
|
||||
font-size: .86rem;
|
||||
font-weight: 800;
|
||||
margin-bottom: .6rem;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.settings-database-link {
|
||||
align-items: center;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 1rem;
|
||||
justify-content: space-between;
|
||||
}
|
||||
|
||||
.settings-database-link h2,
|
||||
.settings-danger-zone h2 {
|
||||
font-size: 1rem;
|
||||
font-weight: 800;
|
||||
margin: .3rem 0;
|
||||
}
|
||||
|
||||
.settings-database-link p {
|
||||
color: var(--rw-muted);
|
||||
margin: 0;
|
||||
max-width: 52rem;
|
||||
}
|
||||
|
||||
.settings-danger-zone {
|
||||
background: #fff8e8;
|
||||
border-color: #e7d29c;
|
||||
}
|
||||
|
||||
.settings-impact-list {
|
||||
color: var(--rw-muted);
|
||||
margin: .75rem 0 1rem;
|
||||
padding-left: 1.25rem;
|
||||
}
|
||||
|
||||
.settings-impact-list li + li {
|
||||
margin-top: .3rem;
|
||||
}
|
||||
|
||||
.settings-confirm-form {
|
||||
align-items: end;
|
||||
grid-template-columns: minmax(220px, 1fr) auto;
|
||||
max-width: 46rem;
|
||||
}
|
||||
|
||||
.content-band h2,
|
||||
.section-heading h2 {
|
||||
font-size: 1rem;
|
||||
@@ -1587,6 +1638,10 @@ body {
|
||||
}
|
||||
|
||||
@media (max-width: 640px) {
|
||||
.settings-confirm-form {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
.effective-tabs {
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
104
src/main/resources/templates/settings-database.html
Normal file
104
src/main/resources/templates/settings-database.html
Normal file
@@ -0,0 +1,104 @@
|
||||
<!doctype html>
|
||||
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/layout :: head('DB 준비 상태')}"></head>
|
||||
<body>
|
||||
<nav th:replace="~{fragments/layout :: nav}"></nav>
|
||||
<main class="container py-4 settings-page">
|
||||
<div class="page-title">
|
||||
<a class="back-link" href="/settings">← 연결 설정으로 돌아가기</a>
|
||||
<h1>DB 준비 상태</h1>
|
||||
<p class="context-summary">DB에 영향을 주는 지원 DDL과 VPD·ORDS runtime 준비 상태를 확인합니다.</p>
|
||||
<details class="explanation-details">
|
||||
<summary>실행 전 반드시 확인할 내용</summary>
|
||||
<p><strong>지원 테이블 생성/확인</strong>은 현재 연결 사용자의 백오피스 메타데이터를 생성하거나 보강합니다. VPD context, ORDS enablement, grant는 여기서 실행하지 않으며, 아래 sqlcl preview 순서를 따릅니다.</p>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
<div class="alert alert-success" th:if="${message}" th:text="${message}"></div>
|
||||
<div class="alert alert-danger" th:if="${error}" th:text="${error}"></div>
|
||||
<div class="alert alert-warning" th:if="${schemaPreflightErrorMessage}">
|
||||
<strong th:text="${schemaPreflightErrorTitle}">DB 준비 상태 확인 불가</strong>
|
||||
<div th:text="${schemaPreflightErrorMessage}">DB 연결을 확인하세요.</div>
|
||||
</div>
|
||||
|
||||
<section class="content-band" th:if="${schemaPreflight}">
|
||||
<div class="section-heading">
|
||||
<div>
|
||||
<span class="architecture-kicker">읽기 전용 점검</span>
|
||||
<h2>현재 DB 준비 상태</h2>
|
||||
<p class="section-subtitle">현재 연결 사용자 기준으로 메타데이터, VPD runtime, ORDS runtime, grant 상태를 점검합니다.</p>
|
||||
</div>
|
||||
<a class="btn btn-sm rw-btn-secondary" href="/operation-status">운영 상태 보기</a>
|
||||
</div>
|
||||
<div class="schema-summary">
|
||||
<div><span>현재 연결 사용자</span><strong th:text="${schemaPreflight.currentUser()}">ADMIN</strong></div>
|
||||
<div><span>권장 ORDS schema</span><strong th:text="${schemaPreflight.recommendedOrdsSchema()}">CB_ORDS</strong></div>
|
||||
<div><span>OK</span><strong th:text="${schemaPreflight.okCount()}">0</strong></div>
|
||||
<div><span>WARN</span><strong th:text="${schemaPreflight.warnCount()}">0</strong></div>
|
||||
<div><span>MISSING</span><strong th:text="${schemaPreflight.missingCount()}">0</strong></div>
|
||||
<div><span>ERROR</span><strong th:text="${schemaPreflight.errorCount()}">0</strong></div>
|
||||
</div>
|
||||
<div class="table-responsive mt-3">
|
||||
<table class="table table-sm align-middle schema-preflight-table">
|
||||
<thead><tr><th>Layer</th><th>Item</th><th>Type</th><th>Status</th><th>Detail</th><th>Next Action</th></tr></thead>
|
||||
<tbody>
|
||||
<tr th:each="check : ${schemaPreflight.checks()}">
|
||||
<td th:text="${check.layer()}">Backoffice Metadata</td>
|
||||
<td><code th:text="${check.itemName()}">CB_APP_USER</code></td>
|
||||
<td th:text="${check.objectType()}">TABLE</td>
|
||||
<td><span class="badge" th:classappend="${check.ok()} ? ' text-bg-success' : (${check.warning()} ? ' text-bg-warning' : (${check.missing()} ? ' text-bg-secondary' : ' text-bg-danger'))" th:text="${check.status()}">OK</span></td>
|
||||
<td th:text="${check.detail()}">존재합니다.</td>
|
||||
<td><span class="badge" th:classappend="${check.sqlclRequired()} ? ' text-bg-warning' : ' text-bg-info'" th:text="${check.sqlclRequired()} ? 'sqlcl 필요' : '앱 실행 가능'">앱 실행 가능</span><div class="mt-1" th:text="${check.nextAction()}">조치 없음</div></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="content-band" th:if="${schemaPreflight}">
|
||||
<h2>실행 전 SQL 확인</h2>
|
||||
<div class="schema-preview-grid mt-3">
|
||||
<details><summary>앱에서 실행하는 지원 DDL</summary><pre class="schema-sql-preview" th:text="${schemaPreflight.appDdlPreview()}">CREATE TABLE ...</pre></details>
|
||||
<details><summary>sqlcl로 실행할 VPD/ORDS runtime 순서</summary><pre class="schema-sql-preview" th:text="${schemaPreflight.sqlclScript()}">@sql/adb/...</pre></details>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="content-band settings-danger-zone">
|
||||
<div class="section-heading">
|
||||
<div>
|
||||
<span class="architecture-kicker">영향 있는 작업</span>
|
||||
<h2>지원 테이블 생성/확인</h2>
|
||||
<p class="section-subtitle">현재 연결 사용자에 백오피스 지원 테이블, 시퀀스, 컬럼을 생성하거나 보강합니다. VPD·ORDS runtime은 실행하지 않습니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
<ul class="settings-impact-list">
|
||||
<li>실행 대상과 SQL은 위 preview에서 먼저 확인합니다.</li>
|
||||
<li>운영 데이터 백업과 DB 권한을 확인한 뒤 실행합니다.</li>
|
||||
<li>실행 결과는 이 화면에 남고, 실패한 SQL을 개별 확인할 수 있습니다.</li>
|
||||
</ul>
|
||||
<form method="post" action="/settings/database/initialize" class="form-grid settings-confirm-form">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<label>
|
||||
확인 문구 입력
|
||||
<input class="form-control" name="confirmation" placeholder="DB 준비 실행" required autocomplete="off">
|
||||
<span class="form-hint">실행하려면 <code>DB 준비 실행</code>을 정확히 입력하세요.</span>
|
||||
</label>
|
||||
<button class="btn btn-outline-danger" type="submit">지원 DDL 실행</button>
|
||||
</form>
|
||||
<div class="table-responsive mt-3" th:if="${schemaResults}">
|
||||
<table class="table table-sm align-middle">
|
||||
<thead><tr><th>Object</th><th>Action</th><th>Status</th><th>Message</th><th>SQL</th></tr></thead>
|
||||
<tbody>
|
||||
<tr th:each="result : ${schemaResults}">
|
||||
<td><code th:text="${result.objectName()}">object</code></td><td th:text="${result.action()}">TABLE</td>
|
||||
<td><span class="badge" th:classappend="${result.status() == 'CREATED' || result.status() == 'MERGED' || result.status() == 'UPDATED'} ? ' text-bg-success' : (${result.status() == 'EXISTS'} ? ' text-bg-secondary' : ' text-bg-danger')" th:text="${result.status()}">CREATED</span></td>
|
||||
<td th:text="${result.message()}">생성했습니다.</td>
|
||||
<td><details th:if="${result.sqlText()}"><summary>보기</summary><pre class="table-pre" th:text="${result.sqlText()}">CREATE TABLE ...</pre></details><span class="text-muted" th:unless="${result.sqlText()}">-</span></td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
@@ -1,15 +1,15 @@
|
||||
<!doctype html>
|
||||
<html lang="ko" xmlns:th="http://www.thymeleaf.org">
|
||||
<head th:replace="~{fragments/layout :: head('설정')}"></head>
|
||||
<head th:replace="~{fragments/layout :: head('연결 설정')}"></head>
|
||||
<body>
|
||||
<nav th:replace="~{fragments/layout :: nav}"></nav>
|
||||
<main class="container py-4">
|
||||
<main class="container py-4 settings-page">
|
||||
<div class="page-title">
|
||||
<h1>설정</h1>
|
||||
<p class="context-summary">ORDS 연결값과 백오피스 DB 준비 상태를 확인합니다.</p>
|
||||
<h1>연결 설정</h1>
|
||||
<p class="context-summary">백오피스가 ORDS를 호출할 주소를 관리합니다. DB 지원 DDL은 별도 안전 화면에서 실행합니다.</p>
|
||||
<details class="explanation-details">
|
||||
<summary>설정 화면의 범위 보기</summary>
|
||||
<p>백오피스에서 사용하는 외부 연동 값을 관리합니다. DB 준비 상태에서는 메타데이터, VPD runtime, ORDS runtime, grant를 연결 사용자 기준으로 점검합니다.</p>
|
||||
<summary>이 화면에서 바꾸는 범위 보기</summary>
|
||||
<p>여기서는 ORDS Base URL만 저장합니다. VPD runtime, grant, 지원 테이블 생성처럼 DB에 영향을 주는 작업은 <strong>DB 준비 상태</strong>에서 별도로 확인·실행합니다.</p>
|
||||
</details>
|
||||
</div>
|
||||
|
||||
@@ -19,151 +19,32 @@
|
||||
<strong th:text="${runtimeErrorTitle}">DB 준비 필요</strong>
|
||||
<div th:text="${runtimeErrorMessage}">지원 테이블을 생성하세요.</div>
|
||||
</div>
|
||||
<div class="alert alert-warning" th:if="${schemaPreflightErrorMessage}">
|
||||
<strong th:text="${schemaPreflightErrorTitle}">DB 준비 상태 확인 불가</strong>
|
||||
<div th:text="${schemaPreflightErrorMessage}">DB 연결을 확인하세요.</div>
|
||||
</div>
|
||||
|
||||
<section class="content-band">
|
||||
<h2>ORDS</h2>
|
||||
<div class="section-heading">
|
||||
<div>
|
||||
<span class="architecture-kicker">ORDS 연결</span>
|
||||
<h2>ORDS Base URL</h2>
|
||||
<p class="section-subtitle">저장 후 권한 결과 확인과 연동 도구가 이 주소를 사용합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
<form method="post" action="/settings/ords" class="form-grid">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<label class="span-2">
|
||||
Base URL
|
||||
<input class="form-control" name="ordsBaseUrl" th:value="${ordsBaseUrl}" required>
|
||||
<input class="form-control" name="ordsBaseUrl" th:value="${ordsBaseUrl}" required inputmode="url" autocomplete="url">
|
||||
</label>
|
||||
<button class="btn rw-btn-primary" type="submit">저장</button>
|
||||
<button class="btn rw-btn-primary" type="submit">연결 주소 저장</button>
|
||||
</form>
|
||||
</section>
|
||||
|
||||
<section class="content-band mt-3" th:if="${schemaPreflight}">
|
||||
<div class="section-heading">
|
||||
<section class="content-band settings-database-link">
|
||||
<div>
|
||||
<h2>DB 준비 상태</h2>
|
||||
<p>현재 연결 사용자 기준으로 백오피스 메타데이터, VPD runtime, ORDS runtime, grant 상태를 점검합니다.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="schema-summary">
|
||||
<div>
|
||||
<span>현재 연결 사용자</span>
|
||||
<strong th:text="${schemaPreflight.currentUser()}">ADMIN</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>권장 ORDS parsing schema</span>
|
||||
<strong th:text="${schemaPreflight.recommendedOrdsSchema()}">CB_ORDS</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>OK</span>
|
||||
<strong th:text="${schemaPreflight.okCount()}">0</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>WARN</span>
|
||||
<strong th:text="${schemaPreflight.warnCount()}">0</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>MISSING</span>
|
||||
<strong th:text="${schemaPreflight.missingCount()}">0</strong>
|
||||
</div>
|
||||
<div>
|
||||
<span>ERROR</span>
|
||||
<strong th:text="${schemaPreflight.errorCount()}">0</strong>
|
||||
</div>
|
||||
</div>
|
||||
<div class="alert alert-info mt-3 mb-3" th:if="${schemaPreflight.hasActionNeeded()}">
|
||||
앱에서 실행 가능한 항목은 아래 `지원 테이블 생성/확인` 버튼으로 보강하고, `sqlcl 필요` 항목은 preview 순서대로 DB 권한을 가진 세션에서 실행하세요.
|
||||
</div>
|
||||
<div class="table-responsive">
|
||||
<table class="table table-sm align-middle schema-preflight-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Layer</th>
|
||||
<th>Item</th>
|
||||
<th>Type</th>
|
||||
<th>Status</th>
|
||||
<th>Detail</th>
|
||||
<th>Next Action</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="check : ${schemaPreflight.checks()}">
|
||||
<td th:text="${check.layer()}">Backoffice Metadata</td>
|
||||
<td><code th:text="${check.itemName()}">CB_APP_USER</code></td>
|
||||
<td th:text="${check.objectType()}">TABLE</td>
|
||||
<td>
|
||||
<span class="badge"
|
||||
th:classappend="${check.ok()} ? ' text-bg-success' : (${check.warning()} ? ' text-bg-warning' : (${check.missing()} ? ' text-bg-secondary' : ' text-bg-danger'))"
|
||||
th:text="${check.status()}">OK</span>
|
||||
</td>
|
||||
<td th:text="${check.detail()}">존재합니다.</td>
|
||||
<td>
|
||||
<span class="badge" th:classappend="${check.sqlclRequired()} ? ' text-bg-warning' : ' text-bg-info'"
|
||||
th:text="${check.sqlclRequired()} ? 'sqlcl 필요' : '앱 실행 가능'">앱 실행 가능</span>
|
||||
<div class="mt-1" th:text="${check.nextAction()}">조치 없음</div>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="content-band mt-3" th:if="${schemaPreflight}">
|
||||
<h2>SQL Preview</h2>
|
||||
<p class="text-muted mb-3">
|
||||
앱 버튼이 실행할 SQL과 sqlcl로 실행할 runtime 준비 순서를 구분해서 확인합니다.
|
||||
</p>
|
||||
<div class="schema-preview-grid">
|
||||
<details open>
|
||||
<summary>앱에서 실행하는 지원 DDL</summary>
|
||||
<pre class="schema-sql-preview" th:text="${schemaPreflight.appDdlPreview()}">CREATE TABLE ...</pre>
|
||||
</details>
|
||||
<details>
|
||||
<summary>sqlcl로 실행할 VPD/ORDS runtime 순서</summary>
|
||||
<pre class="schema-sql-preview" th:text="${schemaPreflight.sqlclScript()}">@sql/adb/...</pre>
|
||||
</details>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="content-band mt-3">
|
||||
<h2>DB 스키마 초기화</h2>
|
||||
<p class="text-muted mb-3">
|
||||
현재 연결된 DB 사용자에 백오피스 지원 테이블, 시퀀스, 컬럼을 생성하거나 보강합니다. VPD context, ORDS enablement, grant는 sqlcl preview 순서를 사용하세요.
|
||||
</p>
|
||||
<form method="post" action="/settings/schema/initialize" class="inline-form">
|
||||
<input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}">
|
||||
<button class="btn btn-outline-primary" type="submit">지원 테이블 생성/확인</button>
|
||||
</form>
|
||||
<div class="table-responsive mt-3" th:if="${schemaResults}">
|
||||
<table class="table table-sm align-middle">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Object</th>
|
||||
<th>Action</th>
|
||||
<th>Status</th>
|
||||
<th>Message</th>
|
||||
<th>SQL</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr th:each="result : ${schemaResults}">
|
||||
<td><code th:text="${result.objectName()}">object</code></td>
|
||||
<td th:text="${result.action()}">TABLE</td>
|
||||
<td>
|
||||
<span class="badge"
|
||||
th:classappend="${result.status() == 'CREATED' || result.status() == 'MERGED' || result.status() == 'UPDATED'} ? ' text-bg-success' : (${result.status() == 'EXISTS'} ? ' text-bg-secondary' : ' text-bg-danger')"
|
||||
th:text="${result.status()}">CREATED</span>
|
||||
</td>
|
||||
<td th:text="${result.message()}">생성했습니다.</td>
|
||||
<td>
|
||||
<details th:if="${result.sqlText()}">
|
||||
<summary>보기</summary>
|
||||
<pre class="table-pre" th:text="${result.sqlText()}">CREATE TABLE ...</pre>
|
||||
</details>
|
||||
<span class="text-muted" th:unless="${result.sqlText()}">-</span>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
<span class="architecture-kicker">DB 준비 · 별도 화면</span>
|
||||
<h2>지원 테이블과 VPD runtime 상태를 확인해야 하나요?</h2>
|
||||
<p>현재 연결 사용자, 메타데이터, VPD runtime, ORDS runtime, grant 상태를 점검합니다. 지원 DDL 실행은 확인 문구 입력이 필요합니다.</p>
|
||||
</div>
|
||||
<a class="btn rw-btn-secondary" href="/settings/database">DB 준비 상태 열기</a>
|
||||
</section>
|
||||
</main>
|
||||
</body>
|
||||
|
||||
@@ -113,6 +113,23 @@ class GuidedFlowTemplateTest {
|
||||
.contains("기술 태그 비교 예시");
|
||||
}
|
||||
|
||||
@Test
|
||||
void connectionSettingsAreSeparatedFromDatabasePreparation() throws IOException {
|
||||
String settings = template("settings.html");
|
||||
String database = template("settings-database.html");
|
||||
|
||||
assertThat(settings)
|
||||
.contains("연결 설정")
|
||||
.contains("/settings/database")
|
||||
.doesNotContain("action=\"/settings/database/initialize\"");
|
||||
assertThat(database)
|
||||
.contains("DB 준비 상태")
|
||||
.contains("/settings/database/initialize")
|
||||
.contains("확인 문구 입력")
|
||||
.contains("DB 준비 실행")
|
||||
.doesNotContain("action=\"/settings/schema/initialize\"");
|
||||
}
|
||||
|
||||
@Test
|
||||
void effectiveMatrixStartsWithOneUserAndKeepsGroupAndRoleAsSecondaryViews() throws IOException {
|
||||
String html = template("effective-matrix.html");
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
package com.cloudhandson.vpdbackoffice.web;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.thymeleaf.context.Context;
|
||||
import org.thymeleaf.spring6.SpringTemplateEngine;
|
||||
import org.thymeleaf.templateresolver.FileTemplateResolver;
|
||||
|
||||
class SettingsTemplateRenderTest {
|
||||
|
||||
@Test
|
||||
void rendersConnectionAndDatabasePreparationPagesSeparately() {
|
||||
var resolver = new FileTemplateResolver();
|
||||
resolver.setPrefix(Path.of("src/main/resources/templates").toAbsolutePath() + "/");
|
||||
resolver.setSuffix(".html");
|
||||
resolver.setTemplateMode("HTML");
|
||||
resolver.setCacheable(false);
|
||||
var engine = new SpringTemplateEngine();
|
||||
engine.setTemplateResolver(resolver);
|
||||
|
||||
var context = new Context(Locale.KOREAN);
|
||||
context.setVariable("_csrf", new CsrfFixture("_csrf", "test-token"));
|
||||
context.setVariable("ordsBaseUrl", "https://ords.example.test/ords");
|
||||
|
||||
String connection = engine.process("settings", context);
|
||||
String database = engine.process("settings-database", context);
|
||||
|
||||
assertThat(connection)
|
||||
.contains("ORDS Base URL")
|
||||
.contains("/settings/database")
|
||||
.doesNotContain("/settings/database/initialize");
|
||||
assertThat(database)
|
||||
.contains("DB 준비 상태")
|
||||
.contains("/settings/database/initialize")
|
||||
.contains("DB 준비 실행");
|
||||
}
|
||||
|
||||
private record CsrfFixture(String parameterName, String token) {
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user