Максим спасибо за дто, спасибо за знания. Часть проги работает, права дальше будет сложнее(

This commit is contained in:
Николай 2023-04-18 19:11:40 +04:00
parent e7fc79a52b
commit 0d47401bda
23 changed files with 584 additions and 82 deletions

View File

@ -15,9 +15,16 @@ jar {
enabled = false
}
dependencies {
implementation(project(':front'))
implementation 'org.springframework.boot:spring-boot-starter-web'
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-devtools'
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
implementation 'org.webjars:bootstrap:5.1.3'
implementation 'org.webjars:jquery:3.6.0'
implementation 'org.webjars:font-awesome:6.1.0'
implementation 'com.h2database:h2:2.1.210'
implementation 'org.hibernate.validator:hibernate-validator'
implementation 'org.springdoc:springdoc-openapi-ui:1.6.5'

View File

@ -1,2 +1 @@
rootProject.name = 'app'
include 'front'

View File

@ -2,12 +2,13 @@ package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.CreatorMangaDto;
import com.LabWork.app.MangaStore.service.CreatorService;
import com.LabWork.app.WebConfiguration;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/creator")
@RequestMapping(WebConfiguration.REST_API + "/creator")
public class CreatorController {
private final CreatorService creatorService;
@ -20,12 +21,12 @@ public class CreatorController {
return new CreatorMangaDto(creatorService.findCreator(id));
}
@GetMapping
/* @GetMapping
public List<CreatorMangaDto> getCreators() {
return creatorService.findAllCreators().stream()
.map(CreatorMangaDto::new)
.toList();
}
}*/
@PostMapping
public CreatorMangaDto createCreator(@RequestParam("creatorName") String creatorName,

View File

@ -0,0 +1,63 @@
package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.CreatorMangaDto;
import com.LabWork.app.MangaStore.service.CreatorService;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/creator")
public class CreatorMvcController {
private final CreatorService creatorService;
public CreatorMvcController(CreatorService creatorService) {
this.creatorService = creatorService;
}
@GetMapping
public String getCreators(Model model) {
model.addAttribute("creators",
creatorService.findAllCreators().stream()
.map(CreatorMangaDto::new)
.toList());
return "creator";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editCreator(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("CreatorMangaDto", new CreatorMangaDto());
} else {
model.addAttribute("creatorId", id);
model.addAttribute("CreatorMangaDto", new CreatorMangaDto(creatorService.findCreator(id)));
}
return "creator-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveCreator(@PathVariable(required = false) Long id,
@ModelAttribute @Valid CreatorMangaDto creatorMangaDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "creator-edit";
}
if (id == null || id <= 0) {
creatorService.addCreator(creatorMangaDto.getCreatorName(), creatorMangaDto.getHashedPassword());
} else {
creatorService.updateCreator(id, creatorMangaDto.getCreatorName(), creatorMangaDto.getHashedPassword());
}
return "redirect:/creator";
}
@PostMapping("/delete/{id}")
public String deleteCreator(@PathVariable Long id) {
creatorService.deleteCreator(id);
return "redirect:/creator";
}
}

View File

@ -5,13 +5,14 @@ import com.LabWork.app.MangaStore.model.Dto.MangaReaderDto;
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
import com.LabWork.app.MangaStore.service.MangaService;
import com.LabWork.app.WebConfiguration;
import jakarta.validation.Valid;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/manga")
@RequestMapping(WebConfiguration.REST_API + "/manga")
public class MangaController {
private final MangaService mangaService;

View File

@ -4,12 +4,13 @@ package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
import com.LabWork.app.MangaStore.service.ReaderService;
import com.LabWork.app.WebConfiguration;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/reader")
@RequestMapping(WebConfiguration.REST_API + "/reader")
public class ReaderController {
private final ReaderService readerService;

View File

@ -0,0 +1,63 @@
package com.LabWork.app.MangaStore.controller;
import com.LabWork.app.MangaStore.model.Dto.ReaderMangaDto;
import com.LabWork.app.MangaStore.service.ReaderService;
import jakarta.validation.Valid;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.*;
@Controller
@RequestMapping("/reader")
public class ReaderMvcController {
private final ReaderService readerService;
public ReaderMvcController(ReaderService readerService) {
this.readerService = readerService;
}
@GetMapping
public String getReaders(Model model) {
model.addAttribute("readers",
readerService.findAllReaders().stream()
.map(ReaderMangaDto::new)
.toList());
return "reader";
}
@GetMapping(value = {"/edit", "/edit/{id}"})
public String editReader(@PathVariable(required = false) Long id,
Model model) {
if (id == null || id <= 0) {
model.addAttribute("ReaderMangaDto", new ReaderMangaDto());
} else {
model.addAttribute("readerId", id);
model.addAttribute("ReaderMangaDto", new ReaderMangaDto(readerService.findReader(id)));
}
return "reader-edit";
}
@PostMapping(value = {"", "/{id}"})
public String saveReader(@PathVariable(required = false) Long id,
@ModelAttribute @Valid ReaderMangaDto readerMangaDto,
BindingResult bindingResult,
Model model) {
if (bindingResult.hasErrors()) {
model.addAttribute("errors", bindingResult.getAllErrors());
return "reader-edit";
}
if (id == null || id <= 0) {
readerService.addReader(readerMangaDto.getReaderName(), readerMangaDto.getHashedPassword());
} else {
readerService.updateReader(id, readerMangaDto.getReaderName(), readerMangaDto.getHashedPassword());
}
return "redirect:/reader";
}
@PostMapping("/delete/{id}")
public String deleteReader(@PathVariable Long id) {
readerService.deleteReader(id);
return "redirect:/reader";
}
}

View File

@ -6,10 +6,13 @@ import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
import java.util.List;
public class CreatorMangaDto {
private final long id;
private final String creatorName;
private final String hashedPassword;
private final List<MangaDto> mangas;
private long id;
private String creatorName;
private String hashedPassword;
private List<MangaDto> mangas;
public CreatorMangaDto() {
}
public CreatorMangaDto(Creator creator) {
this.id = creator.getId();
@ -33,4 +36,16 @@ public class CreatorMangaDto {
}
public List<MangaDto> getMangas() { return mangas; }
public void setCreatorName(String creatorName) {
this.creatorName = creatorName;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
public void setMangas(List<MangaDto> mangas) {
this.mangas = mangas;
}
}

View File

@ -3,20 +3,24 @@ package com.LabWork.app.MangaStore.model.Dto;
import com.LabWork.app.MangaStore.model.Default.Creator;
import com.LabWork.app.MangaStore.model.Default.Manga;
import com.LabWork.app.MangaStore.model.Default.Reader;
import com.LabWork.app.MangaStore.model.Dto.SupportDto.MangaDto;
import com.LabWork.app.MangaStore.model.Dto.SupportDto.ReaderDto;
import java.nio.charset.StandardCharsets;
import java.util.List;
public class MangaReaderDto {
private final Long id;
private Long id;
private final Long creatorId;
private final String mangaName;
private final Integer chapterCount;
private final List<ReaderDto> readers;
private Long creatorId;
private String mangaName;
private Integer chapterCount;
private List<ReaderDto> readers;
private String image;
public MangaReaderDto() {
}
public MangaReaderDto(Manga manga, List<Reader> listReader) {
this.id = manga.getId();
this.creatorId = manga.getCreator().getId();
@ -52,4 +56,21 @@ public class MangaReaderDto {
return creatorId;
}
public void setImage(String image) {
this.image = image;
}
public void setMangaName(String mangaName) {
this.mangaName = mangaName;
}
public void setReaders(List<ReaderDto> readers) {
this.readers = readers;
}
public void setChapterCount(Integer chapterCount) {
this.chapterCount = chapterCount;
}
public void setCreatorIdString(Long creatorId) {this.creatorId = creatorId;}
}

View File

@ -14,6 +14,9 @@ public class ReaderMangaDto {
private List<MangaDto> mangas;
public ReaderMangaDto() {
}
public ReaderMangaDto(Reader reader) {
this.id = reader.getId();
this.readerName = reader.getReaderName();
@ -33,4 +36,16 @@ public class ReaderMangaDto {
public List<MangaDto> getMangas() { return mangas; }
public void setReaderName(String readerName) {
this.readerName = readerName;
}
public void setHashedPassword(String hashedPassword) {
this.hashedPassword = hashedPassword;
}
public void setMangas(List<MangaDto> mangas) {
this.mangas = mangas;
}
}

View File

@ -3,11 +3,8 @@ package com.LabWork.app.MangaStore.service;
import com.LabWork.app.MangaStore.model.Default.Creator;
import com.LabWork.app.MangaStore.model.Default.Manga;
import com.LabWork.app.MangaStore.model.Default.Reader;
import com.LabWork.app.MangaStore.service.Exception.MangaNotFoundException;
import com.LabWork.app.MangaStore.service.Repository.CreatorRepository;
import com.LabWork.app.MangaStore.service.Exception.CreatorNotFoundException;
import com.LabWork.app.MangaStore.service.Repository.MangaRepository;
import com.LabWork.app.MangaStore.service.Repository.ReaderRepository;
import com.LabWork.app.MangaStore.util.validation.ValidatorUtil;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

View File

@ -6,25 +6,26 @@ import org.springframework.boot.web.servlet.server.ConfigurableServletWebServerF
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpStatus;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistration;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import org.springframework.web.servlet.config.annotation.*;
@Configuration
public class WebConfiguration implements WebMvcConfigurer {
public static final String REST_API = "/api";
@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**").allowedMethods("*");
}
@Override
public void configurePathMatch(PathMatchConfigurer configurer) {
configurer.setUseTrailingSlashMatch(true);
}
@Override
public void addViewControllers(ViewControllerRegistry registry) {
ViewControllerRegistration registration = registry.addViewController("/notFound");
registration.setViewName("forward:/index.html");
registration.setStatusCode(HttpStatus.OK);
// Alternative way (404 error hits the console):
// > registry.addViewController("/notFound").setViewName("forward:/index.html");
}
}

View File

@ -1,5 +1,5 @@
spring.main.banner-mode=off
#server.port=8080
server.port=8079
spring.datasource.url=jdbc:h2:file:./data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa

View File

@ -0,0 +1,107 @@
html,
body {
background-color: #000000;
color: #ffffff;
padding: 0;
margin: 0;
font-family: sans-serif;
line-height: 1.15;
height: 100%;
}
header {
background-color: #3c3c3c;
color: #ffffff;
}
header a {
color: #ffffff;
text-decoration: none;
margin: 0 0.5em;
}
header a:hover {
text-decoration: underline;
}
#logo {
margin-left: 0.5em;
}
article a {
color: #ffffff;
text-decoration: none;
margin: 0.5em 0.5em;
}
header a:hover {
text-decoration: underline;
}
h2 {
font-size: 1.25em;
}
h3 {
font-size: 1.1em;
}
footer {
background-color: #9c9c9c;
color: #ffffff;
height: 32px;
padding: 0.5em;
}
.manga_pages{
display: flex;
flex-direction: column;
align-items: center;
}
.catalog_wrapper{
display: flex;
width: 73%;
flex-direction: column;
}
.catalog_article{
display: flex;
}
.poster{
width:140px;
}
th {
border: 0px solid rgb(255, 255, 255);
}
.added_manga{
display: flex;
flex-direction: column;
}
@media (min-width: 992px) {
.manga_pages img{
max-width: 900px;
width: auto;
height: auto;
}
}
.flex_grow {
flex-grow: 1;
display: flex;
align-items: center;
}
@media (min-width: 1024px){
.article_1 {
max-width: -webkit-calc(1600px + (100vw/64*7)*2);
max-width: -moz-calc(1600px + (100vw/64*7)*2);
max-width: calc(1600px + (100vw/64*7)*2);
padding-left: -webkit-calc(100vw/64*7);
padding-left: -moz-calc(100vw/64*7);
padding-left: calc(100vw/64*7);
padding-right: -webkit-calc(100vw/64*7);
padding-right: -moz-calc(100vw/64*7);
padding-right: calc(100vw/64*7);
}
}
.registration_div {
width: 100%;
height: 100%;
}
.slideshow{
height: 250px;
width: auto;/*maintain aspect ratio*/
max-width:180px;
border-radius: 7%;
}

View File

@ -0,0 +1,4 @@
<svg xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 448 512"><!--! Font Awesome Pro 6.1.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2022 Fonticons, Inc. -->
<path d="M448 48V384c-63.09 22.54-82.34 32-119.5 32c-62.82 0-86.6-32-149.3-32C158.6 384 142.6 387.6 128 392.2v-64C142.6 323.6 158.6 320 179.2 320c62.73 0 86.51 32 149.3 32C348.9 352 364.1 349 384 342.7v-208C364.1 141 348.9 144 328.5 144c-62.82 0-86.6-32-149.3-32C128.4 112 104.3 132.6 64 140.7v307.3C64 465.7 49.67 480 32 480S0 465.7 0 448V63.1C0 46.33 14.33 32 31.1 32S64 46.33 64 63.1V76.66C104.3 68.63 128.4 48 179.2 48c62.73 0 86.51 32 149.3 32C365.7 80 384.9 70.54 448 48z"/>
</svg>

After

Width:  |  Height:  |  Size: 727 B

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/creator/{id}(id=${id})}" th:object="${CreatorMangaDto}" method="post">
<div class="mb-3">
<label for="creatorName" class="form-label">creatorName</label>
<input id="creatorName" type='text' value class="form-control" th:field="${CreatorMangaDto.creatorName}" required="true"/>
</div>
<div class="mb-3">
<label for="hashedPassword" class="form-label">hashedPassword</label>
<input id="hashedPassword" type='text' value class="form-control" th:field="${CreatorMangaDto.hashedPassword}" required="true"/>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/creator}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div class="container" id="root-div" layout:fragment="content">
<div class="content">
<h1>Creator</h1>
<a class="btn btn-success"
th:href="@{/creator/edit}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
<div class="row table-responsive text-white">
<table class="table mt-3 text-white">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">CreatorName</th>
<th scope="col">Password</th>
<th scope="col">Mangas</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="creator, iterator: ${creators}">
<td th:text="${creator.id}"/>
<td th:text="${creator.creatorName}"/>
<td th:text="${creator.hashedPassword}"/>
<td>
<select className="form-select" aria-label="Default select example">
<option th:each="manga, iterator: ${creator.mangas}" th:text="${manga.mangaName}"/>
</select>
</td>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/creator/edit/{id}(id=${creator.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${creator.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/creator/delete/{id}(id=${creator.id})}" method="post">
<button th:id="'remove-' + ${creator.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

View File

@ -0,0 +1,49 @@
<!DOCTYPE html>
<html lang="ru"
xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout">
<head>
<meta charset="UTF-8"/>
<title>IP Example</title>
<meta name="viewport" content="width=device-width, initial-scale=1"/>
<link rel="icon" href="/favicon.svg">
<script type="text/javascript" src="/webjars/bootstrap/5.1.3/js/bootstrap.bundle.min.js"></script>
<link rel="stylesheet" href="/webjars/bootstrap/5.1.3/css/bootstrap.min.css"/>
<link rel="stylesheet" href="/webjars/font-awesome/6.1.0/css/all.min.css"/>
<link rel="stylesheet" href="/css/style.css"/>
</head>
<body>
<nav class="navbar navbar-expand-lg navbar-dark">
<div class="container-fluid">
<a class="navbar-brand" href="/">
<i class="fa-solid fa-font-awesome"></i>
IP Example
</a>
<button class="navbar-toggler" type="button"
data-bs-toggle="collapse" data-bs-target="#navbarNav"
aria-controls="navbarNav" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<a class="nav-link" href="/">Index</a>
<a class="nav-link" th:href="@{/creator}">Creator</a>
<a class="nav-link" href="/reader">Reader</a>
<a class="nav-link" href="/creatorAction">CreatorAction</a>
<a class="nav-link" href="/readerAction">ReaderAction</a>
<a class="nav-link" href="/catalog">Catalog</a>
<a class="nav-link" href="/mangaPage">MangaPage</a>
<a class="nav-link" href="/swagger-ui/index.html" target="_blank">Документация REST API</a>
<a class="nav-link" href="/h2-console/" target="_blank">Консоль H2</a>
</ul>
</div>
</div>
</nav>
<div class="container-fluid">
<div class="container container-padding" layout:fragment="content">
</div>
</div>
</body>
<th:block layout:fragment="scripts">
</th:block>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div><span th:text="${error}"></span></div>
<a href="/">На главную</a>
</div>
</body>
</html>

View File

@ -0,0 +1,13 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div>It's works!</div>
<a href="123">ERROR</a>
</div>
</body>
</html>

View File

@ -0,0 +1,31 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div layout:fragment="content">
<div th:text="${errors}" class="margin-bottom alert-danger"></div>
<form action="#" th:action="@{/reader/{id}(id=${id})}" th:object="${ReaderMangaDto}" method="post">
<div class="mb-3">
<label for="readerName" class="form-label">readerName</label>
<input id="readerName" type='text' value class="form-control" th:field="${ReaderMangaDto.readerName}" required="true"/>
</div>
<div class="mb-3">
<label for="hashedPassword" class="form-label">hashedPassword</label>
<input id="hashedPassword" type='text' value class="form-control" th:field="${ReaderMangaDto.hashedPassword}" required="true"/>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary button-fixed">
<span th:if="${id == null}">Добавить</span>
<span th:if="${id != null}">Обновить</span>
</button>
<a class="btn btn-secondary button-fixed" th:href="@{/reader}">
Назад
</a>
</div>
</form>
</div>
</body>
</html>

View File

@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="~{default}">
<head>
</head>
<body>
<div class="container" id="root-div" layout:fragment="content">
<div class="content">
<h1>Reader</h1>
<a class="btn btn-success"
th:href="@{/reader/edit}">
<i class="fa-solid fa-plus"></i> Добавить
</a>
<div class="row table-responsive text-white">
<table class="table mt-3 text-white">
<thead>
<tr>
<th scope="col">#</th>
<th scope="col">ReaderName</th>
<th scope="col">Password</th>
<th scope="col">Mangas</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
<tr th:each="reader, iterator: ${readers}">
<td th:text="${reader.id}"/>
<td th:text="${reader.readerName}"/>
<td th:text="${reader.hashedPassword}"/>
<td>
<select className="form-select" aria-label="Default select example">
<option th:each="manga, iterator: ${reader.mangas}" th:text="${manga.mangaName}"/>
</select>
</td>
<td style="width: 10%">
<div class="btn-group" role="group" aria-label="Basic example">
<a class="btn btn-warning button-fixed button-sm"
th:href="@{/reader/edit/{id}(id=${reader.id})}">
<i class="fa fa-pencil" aria-hidden="true"></i> Изменить
</a>
<button type="button" class="btn btn-danger button-fixed button-sm"
th:attr="onclick=|confirm('Удалить запись?') && document.getElementById('remove-${reader.id}').click()|">
<i class="fa fa-trash" aria-hidden="true"></i> Удалить
</button>
</div>
<form th:action="@{/reader/delete/{id}(id=${reader.id})}" method="post">
<button th:id="'remove-' + ${reader.id}" type="submit" style="display: none">
Удалить
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
</body>
</html>

View File

@ -1,62 +1,12 @@
package com.LabWork.app;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class AppApplicationTests {
/* @Autowired
MethodService methodService;
@Test
void testMethodSumInt() {
final String res = methodService.Sum(1, 2, "int");
Assertions.assertEquals(3, Integer.parseInt(res));
public static void main(String[] args) {
SpringApplication.run(AppApplicationTests.class, args);
}
@Test
void testMethodSumString() {
final String res = methodService.Sum("1", "2", "string");
Assertions.assertEquals("12", res);
}
@Test
void testMethodMinusInt() {
final String res = methodService.Difference(1, 2, "int");
Assertions.assertEquals(-1, Integer.parseInt(res));
}
@Test
void testMethodMinusString() {
final String res = methodService.Difference("214324", "4", "string");
Assertions.assertEquals("2132", res);
}
@Test
void testMethodMultInt() {
final String res = methodService.Multiplication(1, 2, "int");
Assertions.assertEquals(2, Integer.parseInt(res));
}
@Test
void testMethodMultString() {
final String res = methodService.Multiplication("1", "2", "string");
Assertions.assertEquals("11", res);
}
@Test
void testMethodContainsInt() {
final String res = methodService.Contains(123, 2, "int");
Assertions.assertEquals(61, Integer.parseInt(res));
}
@Test
void testMethodContainsString() {
final String res = methodService.Contains("1", "2", "string");
Assertions.assertEquals("false", res);
}*/
}