- Добавил интеграционные тесты с помощью Testcontainers
- Убрал сохранение данных сессии в БД, с ним не работало тестирования логина пользователя. - Изменил стратегию генерации Id для сообщений с 'AUTO' на `IDENTITY`. Без этого ругалось на дублирования id при добавлении нового сообщения в тестах. https://www.youtube.com/watch?v=Lnc3o8cCwZY&list=PLU2ftbIeotGpAYRP9Iv2KLIwK36-o_qYk&index=26
This commit is contained in:
25
pom.xml
25
pom.xml
@@ -41,6 +41,26 @@
|
||||
<artifactId>spring-boot-starter-test</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>mysql</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.testcontainers</groupId>
|
||||
<artifactId>junit-jupiter</artifactId>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-testcontainers</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.security</groupId>
|
||||
<artifactId>spring-security-test</artifactId>
|
||||
<version>RELEASE</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-data-jpa</artifactId>
|
||||
@@ -81,12 +101,7 @@
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-validation</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.session</groupId>
|
||||
<artifactId>spring-session-jdbc</artifactId>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
|
||||
@@ -2,7 +2,6 @@ package net.sytes.kashey.sweater.config;
|
||||
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.springframework.security.config.Customizer;
|
||||
import org.springframework.security.config.annotation.method.configuration.EnableMethodSecurity;
|
||||
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
|
||||
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
|
||||
@@ -20,18 +19,19 @@ public class WebSecurityConfig {
|
||||
public PasswordEncoder passwordEncoder() {
|
||||
return new BCryptPasswordEncoder(8);
|
||||
}
|
||||
|
||||
@Bean
|
||||
public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception {
|
||||
http
|
||||
.authorizeHttpRequests((requests) -> requests
|
||||
.requestMatchers("/", "/registration","/static/**", "/activate/*").permitAll()
|
||||
.requestMatchers("/", "/registration", "/static/**", "/activate/*").permitAll()
|
||||
.anyRequest().authenticated()
|
||||
)
|
||||
.formLogin((form) -> form
|
||||
.loginPage("/login")
|
||||
.defaultSuccessUrl("/main", true)
|
||||
.permitAll()
|
||||
).rememberMe(Customizer.withDefaults())
|
||||
)
|
||||
.logout(LogoutConfigurer::permitAll);
|
||||
|
||||
return http.build();
|
||||
|
||||
@@ -7,7 +7,7 @@ import org.hibernate.validator.constraints.Length;
|
||||
@Entity
|
||||
public class Message {
|
||||
@Id
|
||||
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||
@GeneratedValue(strategy = GenerationType.IDENTITY)
|
||||
private Long id;
|
||||
|
||||
@NotBlank(message = "Please fill in the field.")
|
||||
|
||||
@@ -19,6 +19,3 @@ spring.mail.protocol=smtps
|
||||
mail.debug=true
|
||||
|
||||
recaptcha.secret=
|
||||
spring.session.jdbc.serialize=java
|
||||
spring.session.jdbc.initialize-schema=always
|
||||
spring.session.jdbc.table-name=SPRING_SESSION
|
||||
|
||||
@@ -1,48 +1,47 @@
|
||||
create table message
|
||||
CREATE TABLE IF NOT EXISTS message
|
||||
(
|
||||
id bigint not null,
|
||||
user_id bigint,
|
||||
filename varchar(255),
|
||||
tag varchar(255),
|
||||
text varchar(2048) not null,
|
||||
primary key (id)
|
||||
) engine = InnoDB;
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT,
|
||||
filename VARCHAR(255),
|
||||
tag VARCHAR(255),
|
||||
text VARCHAR(2048) NOT NULL
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
create table message_seq
|
||||
CREATE TABLE message_seq
|
||||
(
|
||||
next_val bigint
|
||||
) engine = InnoDB;
|
||||
next_val BIGINT
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
insert into message_seq
|
||||
values (1);
|
||||
INSERT INTO message_seq
|
||||
VALUES (1);
|
||||
|
||||
create table user_role
|
||||
CREATE TABLE user_role
|
||||
(
|
||||
user_id bigint not null,
|
||||
roles enum ('ADMIN','USER')
|
||||
) engine = InnoDB;
|
||||
user_id BIGINT NOT NULL,
|
||||
roles ENUM ('ADMIN','USER')
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
create table usr
|
||||
CREATE TABLE usr
|
||||
(
|
||||
enabled bit not null,
|
||||
id bigint not null,
|
||||
activation_code varchar(255),
|
||||
email varchar(255),
|
||||
password varchar(255) not null,
|
||||
username varchar(255) not null,
|
||||
primary key (id)
|
||||
) engine = InnoDB;
|
||||
enabled BIT NOT NULL,
|
||||
id BIGINT NOT NULL,
|
||||
activation_code VARCHAR(255),
|
||||
email VARCHAR(255),
|
||||
password VARCHAR(255) NOT NULL,
|
||||
username VARCHAR(255) NOT NULL,
|
||||
PRIMARY KEY (id)
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
create table usr_seq
|
||||
CREATE TABLE usr_seq
|
||||
(
|
||||
next_val bigint
|
||||
) engine = InnoDB;
|
||||
next_val BIGINT
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
insert into usr_seq
|
||||
values (1);
|
||||
INSERT INTO usr_seq
|
||||
VALUES (1);
|
||||
|
||||
alter table message
|
||||
add constraint message_user_fk foreign key (user_id) references usr (id);
|
||||
ALTER TABLE message
|
||||
ADD CONSTRAINT message_user_fk FOREIGN KEY (user_id) REFERENCES usr (id);
|
||||
|
||||
alter table user_role
|
||||
add constraint user_role_user_fk foreign key (user_id) references usr (id);
|
||||
ALTER TABLE user_role
|
||||
ADD CONSTRAINT user_role_user_fk FOREIGN KEY (user_id) REFERENCES usr (id);
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
<#import "parts/common.ftl" as com>
|
||||
<@com.page>
|
||||
<link href="/static/custom.css" rel="stylesheet">
|
||||
<link href="/static/custom.css" rel="stylesheet"/>
|
||||
<div class="input-group mb-3">
|
||||
<form method="get" action="/main" class="form-inline">
|
||||
<input type="text" name="tag" value="${tag}" placeholder="Tag to search">
|
||||
<input type="text" name="tag" value="${tag}" placeholder="Tag to search"/>
|
||||
<button type="submit" class="btn btn-primary ml-2">Search</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
<head>
|
||||
<title>Sweater</title>
|
||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous">
|
||||
<script src="https://www.google.com/recaptcha/api.js" async defer></script>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no"/>
|
||||
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@4.1.3/dist/css/bootstrap.min.css" integrity="sha384-MCw98/SFnGE8fJT3GXwEOngsV7Zt27NXFoaoApmYm81iuXoPkFOJwJ8ERdknLPMO" crossorigin="anonymous"/>
|
||||
<script src="https://www.google.com/recaptcha/api.js" async="async" defer="defer"></script>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<input type="text" class="form-control ${(tagError??)?string('is-invalid', '')}"
|
||||
value="<#if message??>${message.tag}</#if>" name="tag" placeholder="Tag">
|
||||
value="<#if message??>${message.tag}</#if>" name="tag" placeholder="Tag"/>
|
||||
<#if tagError??>
|
||||
<div class="invalid-feedback">
|
||||
${tagError}
|
||||
@@ -27,7 +27,7 @@
|
||||
</div>
|
||||
<div class="form-group">
|
||||
<div class="custom-file">
|
||||
<input type="file" name="file" id="customFile">
|
||||
<input type="file" name="file" id="customFile"/>
|
||||
<label class="custom-file-label" for="customFile">Choose file</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
<#include "security.ftl">
|
||||
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4">
|
||||
<div class="row row-cols-1 row-cols-md-3 g-4" id="message-list">
|
||||
<#list messages as message>
|
||||
<div class="col">
|
||||
<div class="card h-100"> <!-- h-100 делает карточки одинаковой высоты -->
|
||||
<div class="card h-100" data-id="${message.id}"> <!-- h-100 делает карточки одинаковой высоты -->
|
||||
<#if message.filename??>
|
||||
<img src="/img/${message.filename}" class="card-img-top">
|
||||
</#if>
|
||||
<div class="card-body">
|
||||
<span>${message.text}</span><br>
|
||||
<span>${message.text}</span><br/>
|
||||
<i>#${message.tag}</i>
|
||||
</div>
|
||||
<div class="card-footer d-flex justify-content-between">
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<#import "login.ftl" as l>
|
||||
|
||||
<nav class="navbar navbar-expand-lg bg-body-tertiary">
|
||||
<link href="/static/custom.css" rel="stylesheet">
|
||||
<link href="/static/custom.css" rel="stylesheet"/>
|
||||
<div class="container-fluid">
|
||||
<a class="navbar-brand" href="/">Sweater</a>
|
||||
<button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarSupportedContent"
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
<form action="/users" method="post" class="needs-validation" novalidate>
|
||||
<div class="form-group">
|
||||
<label for="username">Username:</label>
|
||||
<input type="text" class="form-control" id="username" name="username" value="${user.username}" required>
|
||||
<input type="text" class="form-control" id="username" name="username" value="${user.username}" required/>
|
||||
<div class="invalid-feedback">
|
||||
Please provide a username.
|
||||
</div>
|
||||
@@ -14,15 +14,15 @@
|
||||
<#list roles as role>
|
||||
<div class="form-check">
|
||||
<input class="form-check-input" type="checkbox" name="${role}"
|
||||
id="${role}" ${user.roles?seq_contains(role)?string("checked", "")}>
|
||||
id="${role}" ${user.roles?seq_contains(role)?string("checked", "")}/>
|
||||
<label class="form-check-label" for="${role}">
|
||||
${role}
|
||||
</label>
|
||||
</div>
|
||||
</#list>
|
||||
</div>
|
||||
<input type="hidden" value="${user.id}" name="userId">
|
||||
<input type="hidden" value="${_csrf.token}" name="_csrf">
|
||||
<input type="hidden" value="${user.id}" name="userId"/>
|
||||
<input type="hidden" value="${_csrf.token}" name="_csrf"/>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Save</button>
|
||||
</form>
|
||||
|
||||
80
src/test/java/net/sytes/kashey/sweater/LoginTest.java
Normal file
80
src/test/java/net/sytes/kashey/sweater/LoginTest.java
Normal file
@@ -0,0 +1,80 @@
|
||||
package net.sytes.kashey.sweater;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.testcontainers.containers.MySQLContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestBuilders.formLogin;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
|
||||
|
||||
@SpringBootTest
|
||||
@AutoConfigureMockMvc
|
||||
@Testcontainers
|
||||
@TestPropertySource("/application-test.properties")
|
||||
public class LoginTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
|
||||
@Container
|
||||
private static final MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
|
||||
.withDatabaseName("sweater_db_test")
|
||||
.withUsername("user")
|
||||
.withPassword("123456");
|
||||
|
||||
@DynamicPropertySource
|
||||
static void configureProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.datasource.url", mysql::getJdbcUrl);
|
||||
registry.add("spring.datasource.username", mysql::getUsername);
|
||||
registry.add("spring.datasource.password", mysql::getPassword);
|
||||
}
|
||||
|
||||
@Test
|
||||
void guestPageShouldContainLoginMessage() throws Exception {
|
||||
mockMvc.perform(get("/"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(content().string(containsString("Hello, guest")))
|
||||
.andExpect(content().string(containsString("Log in")));
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
void unauthorizedUserShouldBeRedirectedToLogin() throws Exception {
|
||||
mockMvc.perform(get("/main"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(redirectedUrl("http://localhost/login"));
|
||||
}
|
||||
|
||||
@Test
|
||||
@Sql(
|
||||
scripts = "/import.sql",
|
||||
config = @SqlConfig(encoding = "UTF-8")
|
||||
)
|
||||
void authorizedUserShouldBeRedirectedToMainPage() throws Exception {
|
||||
mockMvc.perform(formLogin().user("user").password("user"))
|
||||
.andExpect(status().is3xxRedirection())
|
||||
.andExpect(redirectedUrl("/main"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldReturnForbiddenWhenLoginWithInvalidCredentials() throws Exception {
|
||||
mockMvc.perform(post("/login").param("username", "Dummy"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isForbidden());
|
||||
}
|
||||
}
|
||||
102
src/test/java/net/sytes/kashey/sweater/MainControllerTest.java
Normal file
102
src/test/java/net/sytes/kashey/sweater/MainControllerTest.java
Normal file
@@ -0,0 +1,102 @@
|
||||
package net.sytes.kashey.sweater;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
|
||||
import org.springframework.boot.test.context.SpringBootTest;
|
||||
import org.springframework.security.test.context.support.WithUserDetails;
|
||||
import org.springframework.test.context.DynamicPropertyRegistry;
|
||||
import org.springframework.test.context.DynamicPropertySource;
|
||||
import org.springframework.test.context.TestPropertySource;
|
||||
import org.springframework.test.context.jdbc.Sql;
|
||||
import org.springframework.test.context.jdbc.SqlConfig;
|
||||
import org.springframework.test.web.servlet.MockMvc;
|
||||
import org.springframework.test.web.servlet.request.MockHttpServletRequestBuilder;
|
||||
import org.testcontainers.containers.MySQLContainer;
|
||||
import org.testcontainers.junit.jupiter.Container;
|
||||
import org.testcontainers.junit.jupiter.Testcontainers;
|
||||
|
||||
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.csrf;
|
||||
import static org.springframework.security.test.web.servlet.response.SecurityMockMvcResultMatchers.authenticated;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
|
||||
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.multipart;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
|
||||
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.xpath;
|
||||
|
||||
@SpringBootTest
|
||||
@Testcontainers
|
||||
@AutoConfigureMockMvc
|
||||
@WithUserDetails(value = "admin")
|
||||
@TestPropertySource("/application-test.properties")
|
||||
@Sql(
|
||||
scripts = {"/import.sql"},
|
||||
config = @SqlConfig(encoding = "UTF-8")
|
||||
|
||||
)
|
||||
public class MainControllerTest {
|
||||
|
||||
@Autowired
|
||||
private MockMvc mockMvc;
|
||||
@Container
|
||||
private static final MySQLContainer<?> mysql = new MySQLContainer<>("mysql:8.0")
|
||||
.withDatabaseName("sweater_db_test")
|
||||
.withUsername("user")
|
||||
.withPassword("123456");
|
||||
|
||||
@DynamicPropertySource
|
||||
static void configureProperties(DynamicPropertyRegistry registry) {
|
||||
registry.add("spring.datasource.url", mysql::getJdbcUrl);
|
||||
registry.add("spring.datasource.username", mysql::getUsername);
|
||||
registry.add("spring.datasource.password", mysql::getPassword);
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDisplayUsernameInNavbarWhenUserIsAuthenticated() throws Exception {
|
||||
|
||||
mockMvc.perform(get("/main"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(authenticated())
|
||||
.andExpect(xpath("/html/body/nav/div/div[2]").string("admin"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void shouldDisplayAllMessagesOnMainPage() throws Exception {
|
||||
|
||||
mockMvc.perform(get("/main"))
|
||||
.andDo(print())
|
||||
.andExpect(status().isOk())
|
||||
.andExpect(authenticated())
|
||||
.andExpect(xpath("//*[@id='message-list']/div").nodeCount(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
@WithUserDetails(value = "admin")
|
||||
void shouldFilterMessagesByTag() throws Exception {
|
||||
|
||||
mockMvc.perform(get("/main").param("tag", "my-tag"))
|
||||
.andDo(print())
|
||||
.andExpect(authenticated())
|
||||
.andExpect(xpath("//*[@id='message-list']/div").nodeCount(2))
|
||||
.andExpect(xpath("//*[@id='message-list']/div/div[@data-id='1']").exists())
|
||||
.andExpect(xpath("//*[@id='message-list']/div/div[@data-id='3']").exists());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAddNewMessageAndDisplayItOnMainPage() throws Exception {
|
||||
MockHttpServletRequestBuilder multipart = multipart("/main")
|
||||
.file("file", "123".getBytes())
|
||||
.param("text", "fifth")
|
||||
.param("tag", "new one")
|
||||
.with(csrf());
|
||||
|
||||
this.mockMvc.perform(multipart)
|
||||
.andDo(print())
|
||||
.andExpect(authenticated())
|
||||
.andExpect(xpath("//*[@id='message-list']/div").nodeCount(5))
|
||||
.andExpect(xpath("//*[@id='message-list']/div/div[@data-id='5']").exists())
|
||||
.andExpect(xpath("//*[@id='message-list']/div/div[@data-id='5']/div/span").string("fifth"))
|
||||
.andExpect(xpath("//*[@id='message-list']/div/div[@data-id='5']/div/i").string("#new one"));
|
||||
}
|
||||
}
|
||||
19
src/test/resources/application-test.properties
Normal file
19
src/test/resources/application-test.properties
Normal file
@@ -0,0 +1,19 @@
|
||||
spring.jpa.hibernate.ddl-auto=validate
|
||||
spring.jpa.show-sql=true
|
||||
spring.datasource.url=jdbc:mysql://${MYSQL_HOST:localhost}:3306/sweater_db_test
|
||||
spring.datasource.username=user
|
||||
spring.datasource.password=123456
|
||||
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
|
||||
spring.freemarker.expose-request-attributes=true
|
||||
spring.freemarker.expose-session-attributes=true
|
||||
spring.freemarker.suffix=.ftl
|
||||
upload.path=/home/kashey/soft/sweater/uploads
|
||||
hosting.path=http://localhost:8080
|
||||
spring.mail.host=smtp.yandex.ru
|
||||
spring.mail.username=username@yandex.ru
|
||||
spring.mail.password=pa$$word
|
||||
spring.mail.port=465
|
||||
spring.mail.protocol=smtps
|
||||
mail.debug=true
|
||||
|
||||
recaptcha.secret=
|
||||
49
src/test/resources/import.sql
Normal file
49
src/test/resources/import.sql
Normal file
@@ -0,0 +1,49 @@
|
||||
DROP TABLE IF EXISTS message;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS message
|
||||
(
|
||||
id BIGINT AUTO_INCREMENT PRIMARY KEY,
|
||||
user_id BIGINT,
|
||||
filename VARCHAR(255),
|
||||
tag VARCHAR(255),
|
||||
text VARCHAR(2048) NOT NULL
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS user_role
|
||||
(
|
||||
user_id BIGINT NOT NULL,
|
||||
roles ENUM ('ADMIN', 'USER')
|
||||
) ENGINE = InnoDB;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS usr
|
||||
(
|
||||
enabled bit not null,
|
||||
id bigint not null,
|
||||
activation_code varchar(255),
|
||||
email varchar(255),
|
||||
password varchar(255) not null,
|
||||
username varchar(255) not null,
|
||||
primary key (id)
|
||||
) engine = InnoDB;
|
||||
|
||||
DELETE
|
||||
FROM user_role;
|
||||
|
||||
DELETE
|
||||
FROM usr;
|
||||
|
||||
INSERT INTO usr (id, username, password, enabled)
|
||||
VALUES (1, 'admin', '$2a$12$.XB1cxFOs6F8vgouixcTP.TaY2GXwFspYHID12JpLwotvoYI0JwnC', true);
|
||||
|
||||
INSERT INTO usr (id, username, password, enabled)
|
||||
VALUES (2, 'user', '$2a$12$K3ShbpKTnDVozTH2HJ.mbu7jXoiy2oqAoVTEF0iRGFxUfJvse3oke', true);
|
||||
|
||||
INSERT INTO user_role (user_id, roles)
|
||||
VALUES (1, 'USER'),
|
||||
(1, 'ADMIN');
|
||||
|
||||
INSERT INTO message (text, tag, user_id)
|
||||
VALUES ('first', 'my-tag', 1),
|
||||
('second', 'more', 1),
|
||||
('third', 'my-tag', 1),
|
||||
('fourth', 'another', 2);
|
||||
Reference in New Issue
Block a user