diff --git a/pom.xml b/pom.xml
index e823d390..5b7359a3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -9,7 +9,7 @@
com.emobile
- SpringToDo
+ SpringToDo-hib
0.0.1-SNAPSHOT
SpringToDo
SpringToDo
@@ -40,11 +40,20 @@
org.springframework.boot
spring-boot-starter-security
-
- org.springframework.boot
- spring-boot-starter-jdbc
+ org.hibernate
+ hibernate-core
+ 6.6.1.Final
+
+
+
+
+
+
+
+
+
org.postgresql
postgresql
diff --git a/src/main/java/com/emobile/springtodo/aop/LazyLogger.java b/src/main/java/com/emobile/springtodo/aop/logger/LazyLogger.java
similarity index 85%
rename from src/main/java/com/emobile/springtodo/aop/LazyLogger.java
rename to src/main/java/com/emobile/springtodo/aop/logger/LazyLogger.java
index 4f5e8a6d..56039f72 100644
--- a/src/main/java/com/emobile/springtodo/aop/LazyLogger.java
+++ b/src/main/java/com/emobile/springtodo/aop/logger/LazyLogger.java
@@ -1,4 +1,4 @@
-package com.emobile.springtodo.aop;
+package com.emobile.springtodo.aop.logger;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
diff --git a/src/main/java/com/emobile/springtodo/aop/LazyLoggerAdvice.java b/src/main/java/com/emobile/springtodo/aop/logger/LazyLoggerAdvice.java
similarity index 98%
rename from src/main/java/com/emobile/springtodo/aop/LazyLoggerAdvice.java
rename to src/main/java/com/emobile/springtodo/aop/logger/LazyLoggerAdvice.java
index c1e94884..e98d50f5 100644
--- a/src/main/java/com/emobile/springtodo/aop/LazyLoggerAdvice.java
+++ b/src/main/java/com/emobile/springtodo/aop/logger/LazyLoggerAdvice.java
@@ -1,4 +1,4 @@
-package com.emobile.springtodo.aop;
+package com.emobile.springtodo.aop.logger;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
diff --git a/src/main/java/com/emobile/springtodo/aop/session/LazySession.java b/src/main/java/com/emobile/springtodo/aop/session/LazySession.java
new file mode 100644
index 00000000..587b6505
--- /dev/null
+++ b/src/main/java/com/emobile/springtodo/aop/session/LazySession.java
@@ -0,0 +1,17 @@
+package com.emobile.springtodo.aop.session;
+
+import com.emobile.springtodo.model.util.SessionAction;
+import com.emobile.springtodo.model.util.TransactionalType;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+@Target(ElementType.METHOD)
+@Retention(RetentionPolicy.RUNTIME)
+public @interface LazySession {
+ TransactionalType type() default TransactionalType.IGNORE;
+
+ SessionAction action() default SessionAction.CLOSE;
+}
diff --git a/src/main/java/com/emobile/springtodo/aop/session/LazySessionAdvice.java b/src/main/java/com/emobile/springtodo/aop/session/LazySessionAdvice.java
new file mode 100644
index 00000000..457b3d0b
--- /dev/null
+++ b/src/main/java/com/emobile/springtodo/aop/session/LazySessionAdvice.java
@@ -0,0 +1,56 @@
+package com.emobile.springtodo.aop.session;
+
+import com.emobile.springtodo.model.util.SessionAction;
+import com.emobile.springtodo.model.util.TransactionalType;
+import com.emobile.springtodo.util.SessionUtil;
+import lombok.RequiredArgsConstructor;
+import org.aspectj.lang.JoinPoint;
+import org.aspectj.lang.annotation.AfterReturning;
+import org.aspectj.lang.annotation.AfterThrowing;
+import org.aspectj.lang.annotation.Aspect;
+import org.aspectj.lang.annotation.Before;
+import org.hibernate.Transaction;
+import org.hibernate.resource.transaction.spi.TransactionStatus;
+import org.springframework.stereotype.Component;
+
+@RequiredArgsConstructor
+@Aspect
+@Component
+public class LazySessionAdvice {
+ private final SessionUtil sessionUtil;
+
+ @Before(value = "@annotation(param)")
+ public void beforeLazySession(LazySession param) {
+ if (param.type() == TransactionalType.AROUND) {
+ sessionUtil.getSession().beginTransaction();
+ }
+ }
+
+ @AfterThrowing(value = "@annotation(LazySession)")
+ public void afterThrowingLazySession(JoinPoint joinPoint) {
+ Transaction transaction = sessionUtil.getSession().getTransaction();
+ if (transaction != null) {
+ transaction.rollback();
+ }
+ sessionUtil.closeSession();
+ }
+
+ @AfterReturning(value = "@annotation(param)")
+ public void afterReturnLazySession(LazySession param) {
+ if (param.type() == TransactionalType.AROUND) {
+ sessionUtil.getSession().getTransaction().commit();
+ }
+ if (param.action() == SessionAction.CLOSE){
+ sessionUtil.closeSession();
+ }
+ if (param.action() == SessionAction.CHECK){
+ boolean oneOf = sessionUtil.getSession()
+ .getTransaction()
+ .getStatus()
+ .isOneOf(TransactionStatus.NOT_ACTIVE);
+ if (oneOf){
+ sessionUtil.closeSession();
+ }
+ }
+ }
+}
diff --git a/src/main/java/com/emobile/springtodo/config/AppConfig.java b/src/main/java/com/emobile/springtodo/config/AppConfig.java
index d5f1ebc2..a12682fd 100644
--- a/src/main/java/com/emobile/springtodo/config/AppConfig.java
+++ b/src/main/java/com/emobile/springtodo/config/AppConfig.java
@@ -1,20 +1,14 @@
package com.emobile.springtodo.config;
import com.emobile.springtodo.config.property.cache.AppCacheProperties;
-import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.datasource.DataSourceTransactionManager;
-import org.springframework.jdbc.datasource.DriverManagerDataSource;
-import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
-import javax.sql.DataSource;
import java.time.Clock;
/**
@@ -27,37 +21,6 @@
@EnableConfigurationProperties(AppCacheProperties.class)
@PropertySource("classpath:config/application.yml")
public class AppConfig {
- @Value("${spring.datasource.driver-class-name}")
- private String dataSourceDriverClassName;
- @Value("${spring.datasource.url}")
- private String dataSourceUrl;
- @Value("${spring.datasource.username}")
- private String dataSourceUsername;
- @Value("${spring.datasource.password}")
- private String dataSourcePassword;
-
- @Bean
- public DataSource dataSource() {
- DriverManagerDataSource dataSource = new DriverManagerDataSource();
-
- dataSource.setDriverClassName(dataSourceDriverClassName);
- dataSource.setUrl(dataSourceUrl);
- dataSource.setUsername(dataSourceUsername);
- dataSource.setPassword(dataSourcePassword);
-
- return dataSource;
- }
-
- @Bean
- public JdbcTemplate jdbcTemplate(DataSource dataSource) {
- return new JdbcTemplate(dataSource);
- }
-
- @Bean
- public PlatformTransactionManager txManager() {
- return new DataSourceTransactionManager(dataSource());
- }
-
@Bean
public Clock clock() {
return Clock.systemDefaultZone();
diff --git a/src/main/java/com/emobile/springtodo/config/HibernateConfig.java b/src/main/java/com/emobile/springtodo/config/HibernateConfig.java
new file mode 100644
index 00000000..b606790e
--- /dev/null
+++ b/src/main/java/com/emobile/springtodo/config/HibernateConfig.java
@@ -0,0 +1,50 @@
+package com.emobile.springtodo.config;
+
+import com.emobile.springtodo.model.entity.Task;
+import com.emobile.springtodo.model.entity.User;
+import org.hibernate.SessionFactory;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+
+@Configuration
+public class HibernateConfig {
+ @Value("${spring.datasource.driver-class-name}")
+ private String dataSourceDriverClassName;
+ @Value("${spring.datasource.url}")
+ private String dataSourceUrl;
+ @Value("${spring.datasource.username}")
+ private String dataSourceUsername;
+ @Value("${spring.datasource.password}")
+ private String dataSourcePassword;
+
+ @Bean
+ public SessionFactory sessionFactory() {
+ return new org.hibernate.cfg.Configuration()
+ .setProperty("hibernate.connection.driver_class", dataSourceDriverClassName)
+ .setProperty("hibernate.connection.url", dataSourceUrl)
+ .setProperty("hibernate.connection.username", dataSourceUsername)
+ .setProperty("hibernate.connection.password", dataSourcePassword)
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
+ .setProperty("hibernate.show_sql", "true")
+ .addAnnotatedClass(User.class)
+ .addAnnotatedClass(Task.class)
+ .buildSessionFactory();
+ }
+
+
+
+// @Bean
+// public PlatformTransactionManager transactionManager() {
+// JpaTransactionManager transactionManager = new JpaTransactionManager();
+// transactionManager.setEntityManagerFactory(entityManagerFactory().getObject());
+// return transactionManager;
+// }
+
+// @Bean
+// public HibernateTransactionManager transactionManager() {
+// HibernateTransactionManager txManager = new HibernateTransactionManager();
+// txManager.setSessionFactory(sessionFactory().getObject());
+// return txManager;
+// }
+}
diff --git a/src/main/java/com/emobile/springtodo/controller/AppController.java b/src/main/java/com/emobile/springtodo/controller/AppController.java
index aada94d0..d56fd369 100644
--- a/src/main/java/com/emobile/springtodo/controller/AppController.java
+++ b/src/main/java/com/emobile/springtodo/controller/AppController.java
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.tags.Tag;
diff --git a/src/main/java/com/emobile/springtodo/controller/AuthController.java b/src/main/java/com/emobile/springtodo/controller/AuthController.java
index 085dcef4..55a1f01a 100644
--- a/src/main/java/com/emobile/springtodo/controller/AuthController.java
+++ b/src/main/java/com/emobile/springtodo/controller/AuthController.java
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.mapper.UserMapper;
import com.emobile.springtodo.model.dto.user.UserSaveRequest;
import com.emobile.springtodo.model.dto.util.SimpleResponse;
diff --git a/src/main/java/com/emobile/springtodo/controller/TaskController.java b/src/main/java/com/emobile/springtodo/controller/TaskController.java
index 7a16fc42..af8a087f 100644
--- a/src/main/java/com/emobile/springtodo/controller/TaskController.java
+++ b/src/main/java/com/emobile/springtodo/controller/TaskController.java
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.mapper.TaskMapper;
import com.emobile.springtodo.model.dto.task.TaskInsertRequest;
import com.emobile.springtodo.model.dto.task.TaskListResponse;
diff --git a/src/main/java/com/emobile/springtodo/controller/UserController.java b/src/main/java/com/emobile/springtodo/controller/UserController.java
index 87c29f0a..909bfd6f 100644
--- a/src/main/java/com/emobile/springtodo/controller/UserController.java
+++ b/src/main/java/com/emobile/springtodo/controller/UserController.java
@@ -1,6 +1,6 @@
package com.emobile.springtodo.controller;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.mapper.UserMapper;
import com.emobile.springtodo.model.dto.user.UserInsertRequest;
import com.emobile.springtodo.model.dto.user.UserListResponse;
diff --git a/src/main/java/com/emobile/springtodo/controller/handler/ExceptionHandlerController.java b/src/main/java/com/emobile/springtodo/controller/handler/ExceptionHandlerController.java
index 01d93a9c..0246aa76 100644
--- a/src/main/java/com/emobile/springtodo/controller/handler/ExceptionHandlerController.java
+++ b/src/main/java/com/emobile/springtodo/controller/handler/ExceptionHandlerController.java
@@ -4,6 +4,7 @@
import com.emobile.springtodo.exception.DeleteEntityWithReferenceException;
import com.emobile.springtodo.exception.EntityNotFoundException;
import lombok.extern.slf4j.Slf4j;
+import org.hibernate.TransactionException;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
@@ -78,6 +79,22 @@ public ResponseEntity badRequest(
return buildResponse(HttpStatus.BAD_REQUEST, ex, webRequest);
}
+ /**
+ * ExceptionHandler for {@link TransactionException}.
+ *
+ * @param ex exception type of {@link TransactionException}.
+ * @param webRequest web request for exception description.
+ * @return {@link ResponseEntity} with {@link ErrorResponseBody}.
+ * @see #buildResponse(HttpStatus, Exception, WebRequest)
+ */
+ @ExceptionHandler(TransactionException.class)
+ public ResponseEntity badRequest(
+ TransactionException ex,
+ WebRequest webRequest
+ ) {
+ return buildResponse(HttpStatus.BAD_REQUEST, ex, webRequest);
+ }
+
/**
* ExceptionHandler for {@link EntityNotFoundException}.
*
diff --git a/src/main/java/com/emobile/springtodo/mapper/TaskMapper.java b/src/main/java/com/emobile/springtodo/mapper/TaskMapper.java
index 84977410..ccc8fa9a 100644
--- a/src/main/java/com/emobile/springtodo/mapper/TaskMapper.java
+++ b/src/main/java/com/emobile/springtodo/mapper/TaskMapper.java
@@ -6,6 +6,7 @@
import com.emobile.springtodo.model.dto.task.TaskSaveRequest;
import com.emobile.springtodo.model.entity.Task;
import org.mapstruct.Mapper;
+import org.mapstruct.Mapping;
import org.mapstruct.Named;
import org.mapstruct.ReportingPolicy;
@@ -45,8 +46,7 @@ public interface TaskMapper {
* @param model {@link Task} for mapping.
* @return mapped {@link TaskResponse}.
*/
-// @Mapping(target = "createdAt", qualifiedByName = "OffsetDateTimeToString")
-// @Mapping(target = "updatedAt", qualifiedByName = "OffsetDateTimeToString")
+ @Mapping(source = "author.id", target = "authorId")
TaskResponse modelToResponse(Task model);
diff --git a/src/main/java/com/emobile/springtodo/model/entity/Task.java b/src/main/java/com/emobile/springtodo/model/entity/Task.java
index 88ad60b8..36c61fc3 100644
--- a/src/main/java/com/emobile/springtodo/model/entity/Task.java
+++ b/src/main/java/com/emobile/springtodo/model/entity/Task.java
@@ -1,5 +1,15 @@
package com.emobile.springtodo.model.entity;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.JoinColumn;
+import jakarta.persistence.ManyToOne;
+import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
@@ -22,35 +32,54 @@
@Getter
@FieldNameConstants
@Builder
+@Entity
+@Table(name = "tasks")
public class Task implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* Long Task id.
*/
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = Fields.id)
private Long id;
/**
* Task name.
*/
+ @Column(name = Fields.name)
private String name;
/**
* Task description.
*/
+ @Column(name = Fields.description)
private String description;
/**
* Task {@link TaskStatus} status.
*/
+ @Enumerated(EnumType.STRING)
+ @Column(name = Fields.status)
private TaskStatus status;
/**
* Task creation time without timezone.
*/
+ @Column(name = "created_at")
private LocalDateTime createdAt;
/**
* Task update time without timezone.
*/
+ @Column(name = "updated_at")
private LocalDateTime updatedAt;
/**
- * The User id who owns the Task.
+ * The User who owns the Task.
*/
- private Long authorId;
+ @EqualsAndHashCode.Exclude
+ @ManyToOne
+ @JoinColumn(name = "author_id", referencedColumnName = "id")
+ private User author;
+
+ @EqualsAndHashCode.Include
+ public Long getAuthorId() {
+ return author.getId();
+ }
}
diff --git a/src/main/java/com/emobile/springtodo/model/entity/User.java b/src/main/java/com/emobile/springtodo/model/entity/User.java
index 9ab52043..0e93fe10 100644
--- a/src/main/java/com/emobile/springtodo/model/entity/User.java
+++ b/src/main/java/com/emobile/springtodo/model/entity/User.java
@@ -1,11 +1,22 @@
package com.emobile.springtodo.model.entity;
import com.emobile.springtodo.model.security.RoleType;
+import jakarta.persistence.Column;
+import jakarta.persistence.Entity;
+import jakarta.persistence.EnumType;
+import jakarta.persistence.Enumerated;
+import jakarta.persistence.GeneratedValue;
+import jakarta.persistence.GenerationType;
+import jakarta.persistence.Id;
+import jakarta.persistence.Index;
+import jakarta.persistence.OneToMany;
+import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.EqualsAndHashCode;
import lombok.Getter;
import lombok.NoArgsConstructor;
+import lombok.Setter;
import lombok.ToString;
import lombok.experimental.FieldNameConstants;
@@ -24,32 +35,53 @@
@Getter
@FieldNameConstants
@Builder
+@Entity
+@Table(name = "users",
+ indexes = {
+ @Index(columnList = User.Fields.username, unique = true),
+ @Index(columnList = User.Fields.email, unique = true)
+ })
public class User implements Serializable {
@Serial
private static final long serialVersionUID = 1L;
/**
* Long User id.
*/
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = Fields.id)
private Long id;
/**
* User name.
*/
+ @Column(name = Fields.username)
private String username;
/**
* User password.
*/
+ @Column(name = Fields.password)
private String password;
/**
* User email.
*/
+ @Column(name = Fields.email)
private String email;
/**
* User authorization role type.
*/
+ @Enumerated(EnumType.STRING)
+ @Column(name = Fields.role)
private RoleType role;
/**
* User tasks.
*/
+ @ToString.Exclude
+ @OneToMany(mappedBy = Task.Fields.author, orphanRemoval = true)
@Builder.Default
private List taskList = new ArrayList<>();
+//
+// @ToString.Include
+// public String getTaskListSize() {
+// return String.valueOf(taskList.size());
+// }
}
diff --git a/src/main/java/com/emobile/springtodo/model/util/PageInfo.java b/src/main/java/com/emobile/springtodo/model/util/PageInfo.java
index 46f65ff0..0836f048 100644
--- a/src/main/java/com/emobile/springtodo/model/util/PageInfo.java
+++ b/src/main/java/com/emobile/springtodo/model/util/PageInfo.java
@@ -33,5 +33,5 @@ public record PageInfo(
/**
* Minimum size of the number field.
*/
- private static final int MIN_NUMBER_SIZE = 1;
+ private static final int MIN_NUMBER_SIZE = 0;
}
diff --git a/src/main/java/com/emobile/springtodo/repository/CrudRepository.java b/src/main/java/com/emobile/springtodo/repository/CrudRepository.java
index 79cb3d45..e5c4f734 100644
--- a/src/main/java/com/emobile/springtodo/repository/CrudRepository.java
+++ b/src/main/java/com/emobile/springtodo/repository/CrudRepository.java
@@ -45,11 +45,9 @@ public interface CrudRepository {
T update(T model);
/**
- * Delete object with {@code T.id}
- * equals {@code id} from database.
+ * Delete object {@code model}.
*
- * @param id id of the object to be deleted
- * @return {@code true} if success
+ * @param model object to be deleted
*/
- boolean deleteById(Long id);
+ void deleteById(T model);//TODPO rename
}
diff --git a/src/main/java/com/emobile/springtodo/repository/TaskRepository.java b/src/main/java/com/emobile/springtodo/repository/TaskRepository.java
index a1b9b6ee..9d3e84c5 100644
--- a/src/main/java/com/emobile/springtodo/repository/TaskRepository.java
+++ b/src/main/java/com/emobile/springtodo/repository/TaskRepository.java
@@ -8,10 +8,8 @@
public interface TaskRepository extends CrudRepository {
/**
* Delete all {@link Task} objects in database.
- *
- * @return {@code true} if success
*/
- boolean deleteAll();
+ void deleteAll();
/**
* Delete all {@link Task} objects in database
diff --git a/src/main/java/com/emobile/springtodo/repository/impl/TaskRepositoryImpl.java b/src/main/java/com/emobile/springtodo/repository/impl/TaskRepositoryImpl.java
index d4821f6e..d19a530e 100644
--- a/src/main/java/com/emobile/springtodo/repository/impl/TaskRepositoryImpl.java
+++ b/src/main/java/com/emobile/springtodo/repository/impl/TaskRepositoryImpl.java
@@ -1,205 +1,71 @@
package com.emobile.springtodo.repository.impl;
-import com.emobile.springtodo.aop.LazyLogger;
-import com.emobile.springtodo.exception.NullResultSetException;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.model.entity.Task;
-import com.emobile.springtodo.model.entity.TaskStatus;
import com.emobile.springtodo.model.util.Page;
import com.emobile.springtodo.model.util.PageInfo;
import com.emobile.springtodo.repository.TaskRepository;
+import com.emobile.springtodo.util.SessionUtil;
import lombok.RequiredArgsConstructor;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
+import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
import java.util.Optional;
-import static com.emobile.springtodo.util.JdbcUtil.optionalExtractor;
-
-/**
- * Repository for working with entity {@link Task}.
- */
@RequiredArgsConstructor
@Repository
public class TaskRepositoryImpl implements TaskRepository {
- /**
- * For work with db.
- */
- private final JdbcTemplate jdbcTemplate;
+ private final SessionUtil sessionUtil;
- /**
- * Find all {@link Task} objects from db
- * with {@code pageNumber} and {@code pageSize} from {@code pageInfo}.
- * LIMIT - {@code pageSize}.
- * OFFSET - ({@code pageNumber} -1) * {@code pageSize}.
- *
- * @return {@link Page} with {@link Task} list.
- * @see #getMapper()
- */
@Override
@LazyLogger
- public Page findAll(PageInfo pageInfo) {
- final String sql = """
- SELECT * FROM tasks
- LIMIT ? OFFSET ?
- """;
- int beginInd = (pageInfo.pageNumber() - 1) * pageInfo.pageSize();
- return new Page<>(
- jdbcTemplate.query(sql,
- getMapper(),
- pageInfo.pageSize(),
- beginInd
- )
- );
+ public Page findAll(PageInfo pageinfo) {
+ int beginInd = pageinfo.pageNumber() * pageinfo.pageSize();
+ Query query = sessionUtil.getSession()
+ .createQuery("FROM Task", Task.class)
+ .setFirstResult(beginInd)
+ .setMaxResults(pageinfo.pageSize());
+ return new Page<>(query.getResultList());
}
- /**
- * Search object {@link Task} in db.
- *
- * @param id id searched {@link Task} object
- * @return {@link Optional} if exist, {@link Optional#empty()} if not
- * @see #getMapper()
- */
@Override
@LazyLogger
public Optional findById(Long id) {
- final String sql = """
- SELECT *
- FROM tasks
- WHERE id=?
- """;
- return jdbcTemplate.query(
- sql,
- optionalExtractor(getMapper()),
- id
+ return Optional.ofNullable(
+ sessionUtil.getSession().get(Task.class, id)
);
}
- /**
- * Save object model of type {@link Task}.
- *
- * @param model object of type {@link Task} to save
- * @return object of type {@link Task} that was saved
- * @throws NullResultSetException if returning value from db is null
- */
@Override
@LazyLogger
public Task save(Task model) {
- final String sql = """
- INSERT INTO tasks(name, description, status,
- created_at, updated_at, author_id)
- VALUES (?,?,?,?,?,?)
- RETURNING *
- """;
- return jdbcTemplate.query(sql,
- optionalExtractor(getMapper()),
- model.getName(),
- model.getDescription(),
- model.getStatus().name(),
- model.getCreatedAt(),
- model.getUpdatedAt(),
- model.getAuthorId()
- ).orElseThrow(NullResultSetException.create(
- "taskRepository save() query exception"
- ));
+ sessionUtil.getSession().persist(model);
+ return model;
}
- /**
- * Update object model of type {@link Task}
- * by {@code T.id} value.
- *
- * @param model object of type {@link Task} to update
- * @return object of type {@link Task} that was updated
- * @throws NullResultSetException if returning value from db is null
- */
@Override
@LazyLogger
public Task update(Task model) {
- final String sql = """
- UPDATE tasks
- SET name=?, description=?, status=?, updated_at=?, author_id =?
- WHERE id=?
- RETURNING *
- """;
- return jdbcTemplate.query(sql,
- optionalExtractor(getMapper()),
- model.getName(),
- model.getDescription(),
- model.getStatus().name(),
- model.getUpdatedAt(),
- model.getAuthorId(),
- model.getId()
- ).orElseThrow(NullResultSetException.create(
- "taskRepository update() query exception"
- ));
+ return sessionUtil.getSession().merge(model);
}
- /**
- * Delete object with {@code Task.id}
- * equals {@code id} from database.
- *
- * @param id id of the object to be deleted
- * @return {@code true} if success
- */
@Override
@LazyLogger
- public boolean deleteById(Long id) {
- final String sql = """
- DELETE
- FROM tasks
- WHERE id=?
- """;
- int result = jdbcTemplate.update(sql, id);
- return result != 0;
+ public void deleteById(Task model) {
+ sessionUtil.getSession().remove(model);
}
- /**
- * Delete all {@link Task} objects in database.
- *
- * @return {@code true} if success
- */
@Override
@LazyLogger
- public boolean deleteAll() {
- final String sql = "TRUNCATE tasks";
- int result = jdbcTemplate.update(sql);
- return result != 0;
+ public void deleteAll() {
+ sessionUtil.getSession()
+ .createQuery("DELETE FROM Task", Task.class)
+ .executeUpdate();
}
- /**
- * Delete all {@link Task} objects in database
- * for user with {@code userId}.
- *
- * @return {@code true} if success
- */
@Override
@LazyLogger
- public boolean deleteAllByUserId(Long userId) {
- final String sql = """
- DELETE
- FROM tasks
- WHERE author_id=?
- """;
- int result = jdbcTemplate.update(sql, userId);
- return result != 0;
- }
-
- /**
- * {@link Task} {@link RowMapper}.
- *
- * @return mapper for {@link Task} entity
- */
- private RowMapper getMapper() {
- return (rs, rn) -> Task.builder()
- .id(rs.getLong(Task.Fields.id))
- .name(rs.getString(Task.Fields.name))
- .description(rs.getString(Task.Fields.description))
- .status(TaskStatus.valueOf(rs.getString(Task.Fields.status)))
- .createdAt(rs.getTimestamp("created_at")
- .toLocalDateTime())
- .updatedAt(rs.getTimestamp("updated_at")
- .toLocalDateTime())
- .authorId(rs.getLong("author_id"))
- .build();
+ public boolean deleteAllByUserId(Long authorId) {
+ return false;
}
}
diff --git a/src/main/java/com/emobile/springtodo/repository/impl/UserRepositoryImpl.java b/src/main/java/com/emobile/springtodo/repository/impl/UserRepositoryImpl.java
index 1b8aad8d..91a08d0f 100644
--- a/src/main/java/com/emobile/springtodo/repository/impl/UserRepositoryImpl.java
+++ b/src/main/java/com/emobile/springtodo/repository/impl/UserRepositoryImpl.java
@@ -1,366 +1,125 @@
package com.emobile.springtodo.repository.impl;
-import com.emobile.springtodo.aop.LazyLogger;
-import com.emobile.springtodo.exception.NullResultSetException;
-import com.emobile.springtodo.model.entity.Task;
-import com.emobile.springtodo.model.entity.TaskStatus;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.model.entity.User;
-import com.emobile.springtodo.model.security.RoleType;
import com.emobile.springtodo.model.util.Page;
import com.emobile.springtodo.model.util.PageInfo;
import com.emobile.springtodo.repository.UserRepository;
+import com.emobile.springtodo.util.SessionUtil;
import lombok.RequiredArgsConstructor;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
+import org.hibernate.query.Query;
import org.springframework.stereotype.Repository;
-import java.sql.ResultSet;
-import java.sql.SQLException;
-import java.util.ArrayList;
-import java.util.List;
import java.util.Optional;
-import static com.emobile.springtodo.util.JdbcUtil.optionalExtractor;
-/**
- * Repository for working with entity {@link User}.
- */
@RequiredArgsConstructor
@Repository
public class UserRepositoryImpl implements UserRepository {
- /**
- * For work with db.
- */
- private final JdbcTemplate jdbcTemplate;
+ private final SessionUtil sessionUtil;
- /**
- * Find all {@link User} objects from db
- * with {@code pageNumber} and {@code pageSize} from {@code pageInfo}.
- * LIMIT - {@code pageSize}.
- * OFFSET - ({@code pageNumber} -1) * {@code pageSize}.
- *
- * @return {@link Page} with {@link User} list.
- * @see #getUserMapper()
- */
@Override
@LazyLogger
- public Page findAll(PageInfo pageInfo) {
- final String sql = """
- SELECT * FROM users
- LIMIT ? OFFSET ?
- """;
- int beginInd = (pageInfo.pageNumber() - 1) * pageInfo.pageSize();
- return new Page<>(
- jdbcTemplate.query(
- sql,
- getUserMapper(),
- pageInfo.pageSize(),
- beginInd
- )
- );
+ public Page findAll(PageInfo pageinfo) {
+ int beginInd = pageinfo.pageNumber() * pageinfo.pageSize();
+ Query query = sessionUtil.getSession()
+ .createQuery("FROM User", User.class)
+ .setFirstResult(beginInd)
+ .setMaxResults(pageinfo.pageSize());
+ return new Page<>(query.getResultList());
}
- /**
- * Search object {@link User} in db.
- *
- * @param id id searched {@link User} object
- * @return {@link Optional} if exist, {@link Optional#empty()} if not
- * @see #getUserTaskMapper()
- */
@Override
@LazyLogger
public Optional findById(Long id) {
- final String sql = """
- SELECT u.*, t.*
- FROM users u
- LEFT JOIN tasks t on u.id = t.author_id
- WHERE u.id= ?
- """;
- return jdbcTemplate.query(
- sql,
- optionalExtractor(getUserTaskMapper()),
- id
- );
+ Query query = sessionUtil.getSession()
+ .createQuery("FROM User u LEFT JOIN FETCH u.taskList WHERE u.id = :id", User.class)
+ .setParameter("id", id);
+ return Optional.ofNullable(query.uniqueResult());
}
- /**
- * Find {@link User}
- * with {@code User.username} equals {@code username}.
- *
- * @param username username searched {@link User}
- * @return {@link Optional} if exist, {@link Optional#empty()} if not
- */
@Override
@LazyLogger
- public Optional findByUsername(String username) {
- final String sql = """
- SELECT u.*, t.*
- FROM users u
- LEFT JOIN tasks t on u.id = t.author_id
- WHERE u.username= ?
- """;
- return jdbcTemplate.query(
- sql,
- optionalExtractor(getUserTaskMapper()),
- username
- );
+ public User save(User model) {
+ sessionUtil.getSession().persist(model);
+ return model;
}
- /**
- * Save object model of type {@link User}.
- *
- * @param model object of type {@link User} to save
- * @return object of type {@link User} that was saved
- * @throws NullResultSetException if returning value from db is null
- */
@Override
@LazyLogger
- public User save(User model) {
- final String sql = """
- INSERT INTO users(username, password, email, role)
- VALUES (?,?,?,?)
- RETURNING *
- """;
- return jdbcTemplate.query(sql,
- optionalExtractor(getUserMapper()),
- model.getUsername(),
- model.getPassword(),
- model.getEmail(),
- model.getRole().name())
- .orElseThrow(NullResultSetException.create(
- "userRepository save() query exception"
- ));
+ public User update(User model) {
+ return sessionUtil.getSession().merge(model);
}
- /**
- * Update object model of type {@link User}
- * by {@code T.id} value.
- *
- * @param model object of type {@link User} to update
- * @return object of type {@link User} that was updated
- * @throws NullResultSetException if returning value from db is null
- */
@Override
@LazyLogger
- public User update(User model) {
- final String sql = """
- UPDATE users
- SET username=?, password=?, email=?, role=?
- WHERE id=?
- RETURNING *
- """;
- return jdbcTemplate.query(sql,
- optionalExtractor(getUserMapper()),
- model.getUsername(),
- model.getPassword(),
- model.getEmail(),
- model.getRole().name(),
- model.getId())
- .orElseThrow(NullResultSetException.create(
- "userRepository update() query exception"
- ));
+ public void deleteById(User model) {
+ sessionUtil.getSession().remove(model);
}
- /**
- * Delete object with {@code User.id}
- * equals {@code id} from database.
- *
- * @param id id of the object to be deleted
- * @return {@code true} if success
- */
@Override
@LazyLogger
- public boolean deleteById(Long id) {
- final String sql = """
- DELETE
- FROM users
- WHERE id=?
- """;
- int result = jdbcTemplate.update(sql, id);
- return result != 0;
+ public Optional findByUsername(String username) {
+ Query query = sessionUtil.getSession()
+ .createQuery("FROM User WHERE username = :username", User.class)
+ .setParameter("username", username);
+ return Optional.ofNullable(query.uniqueResult());
}
- /**
- * Check duplicate {@code username}.
- * For save {@link User}.
- *
- * @param username username searched {@link User}
- * @return {@code true} if exist, {@code false} if not
- * @see #getExistsMapper()
- */
@Override
@LazyLogger
public boolean existsByUsername(String username) {
- final String sql = """
- SELECT EXISTS (SELECT *
- FROM users
- WHERE username = ?)
- AS result
- """;
- return jdbcTemplate.queryForObject(sql, getExistsMapper(), username);
+ return existsByField(User.Fields.username, username);
}
- /**
- * Check duplicate {@code username}.
- * For update {@link User}.
- *
- * @param username username searched {@link User}
- * @return {@code true} if exist, {@code false} if not
- * @see #getExistsMapper()
- */
@Override
@LazyLogger
public boolean existsByUsernameAndIdNot(String username, Long currentUserId) {
- final String sql = """
- SELECT EXISTS (SELECT *
- FROM users
- WHERE username = ?
- AND id != ?)
- AS result
- """;
- return jdbcTemplate.queryForObject(
- sql,
- getExistsMapper(),
- username,
- currentUserId
- );
+ return existsByField(User.Fields.username, username, currentUserId);
}
- /**
- * Check duplicate {@code email}.
- * For save {@link User}.
- *
- * @param email username searched {@link User}
- * @return {@code true} if exist, {@code false} if not
- * @see #getExistsMapper()
- */
@Override
@LazyLogger
public boolean existsByEmail(String email) {
- final String sql = """
- SELECT EXISTS (SELECT *
- FROM users
- WHERE email = ?)
- AS result
- """;
- return jdbcTemplate.queryForObject(sql, getExistsMapper(), email);
+ return existsByField(User.Fields.email, email);
}
- /**
- * Check duplicate {@code email}.
- * For update {@link User}.
- *
- * @param email username searched {@link User}
- * @return {@code true} if exist, {@code false} if not
- * @see #getExistsMapper()
- */
@Override
@LazyLogger
public boolean existsByEmailAndIdNot(String email, Long currentUserId) {
- final String sql = """
- SELECT EXISTS (SELECT *
- FROM users
- WHERE email = ?
- AND id != ?)
- AS result
- """;
- return jdbcTemplate.queryForObject(
- sql,
- getExistsMapper(),
- email,
- currentUserId
- );
- }
-
- /**
- * {@link User} {@link RowMapper}.
- *
- * @return mapper for {@link User} entity
- */
- private RowMapper getUserMapper() {
- return (rs, rn) -> User.builder()
- .id(rs.getLong(User.Fields.id))
- .username(rs.getString(User.Fields.username))
- .password(rs.getString(User.Fields.password))
- .email(rs.getString(User.Fields.email))
- .role(RoleType.valueOf(rs.getString(User.Fields.role)))
- .build();
- }
-
- /**
- * Грустно и костыльно, но работает.
- *
- * {code rs.getLong("author_id")} for wasNull() check.
- *
- * @return mapper for {@link User} with filled {@code taskList} fields
- * @see #fillUserFields(ResultSet, List)
- * @see #fillTaskFields(ResultSet)
- */
- private RowMapper getUserTaskMapper() {
- return (rs, rn) -> {
- List taskList = new ArrayList<>();
- User user = fillUserFields(rs, taskList);
- rs.getLong("author_id");
- if (!rs.wasNull()) {
- do {
- Task task = fillTaskFields(rs);
- taskList.add(task);
- } while (rs.next());
- }
- return user;
- };
- }
-
- /**
- * fill {@link User} entity.
- * {@code id} columnIndex - 1.
- *
- * @param rs resultSet for map
- * @param taskList list ref
- * @return {@link User} with filled fields
- * @throws SQLException if resultSet get exception
- */
- private User fillUserFields(ResultSet rs, List taskList) throws SQLException {
- return User.builder()
- .id(rs.getLong(1))
- .username(rs.getString(User.Fields.username))
- .password(rs.getString(User.Fields.password))
- .email(rs.getString(User.Fields.email))
- .role(RoleType.valueOf(rs.getString(User.Fields.role)))
- .taskList(taskList)
- .build();
+ return existsByField(User.Fields.email, email, currentUserId);
}
- /**
- * fill {@link Task} entity.
- * {@code id} columnIndex - 6.
- *
- * @param rs resultSet for map
- * @return {@link Task} with filled fields
- * @throws SQLException if resultSet get exception
- */
- private Task fillTaskFields(ResultSet rs) throws SQLException {
- return Task.builder()
- .id(rs.getLong(6))
- .name(rs.getString(Task.Fields.name))
- .description(rs.getString(Task.Fields.description))
- .status(TaskStatus.valueOf(rs.getString(Task.Fields.status)))
- .createdAt(rs.getTimestamp("created_at")
- .toLocalDateTime())
- .updatedAt(rs.getTimestamp("updated_at")
- .toLocalDateTime())
- .authorId(rs.getLong("author_id"))
- .build();
+ private boolean existsByField(String fieldName, Object value) {
+ try {
+ Query query = sessionUtil.getSession()
+ .createQuery(
+ "SELECT COUNT(u.id) FROM User u WHERE u." + fieldName + " = :value",
+ Long.class
+ )
+ .setParameter("value", value);
+ Long count = query.uniqueResult();
+ return count != null && count > 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
}
- /**
- * {@link RowMapper} for exist check.
- *
- * @return mapper for exist check
- */
- private RowMapper getExistsMapper() {
- return (resultSet, rowNum) ->
- resultSet.getString("result")
- .equals("t");
+ private boolean existsByField(String fieldName, Object value, Long currentUserId) {
+ try {
+ Query query = sessionUtil.getSession()
+ .createQuery(
+ "SELECT COUNT(u.id) FROM User u " +
+ "WHERE u." + fieldName + " = :value and u.id != :userId",
+ Long.class)
+ .setParameter("value", value)
+ .setParameter("userId", currentUserId);
+ Long count = query.uniqueResult();
+ return count != null && count > 0;
+ } catch (Exception e) {
+ e.printStackTrace();
+ return false;
+ }
}
}
diff --git a/src/main/java/com/emobile/springtodo/service/impl/TaskServiceImpl.java b/src/main/java/com/emobile/springtodo/service/impl/TaskServiceImpl.java
index 71594d79..7eb7696e 100644
--- a/src/main/java/com/emobile/springtodo/service/impl/TaskServiceImpl.java
+++ b/src/main/java/com/emobile/springtodo/service/impl/TaskServiceImpl.java
@@ -1,13 +1,18 @@
package com.emobile.springtodo.service.impl;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
+import com.emobile.springtodo.aop.session.LazySession;
+import com.emobile.springtodo.model.util.SessionAction;
+import com.emobile.springtodo.model.util.TransactionalType;
import com.emobile.springtodo.config.property.cache.AppCacheProperties;
import com.emobile.springtodo.exception.EntityNotFoundException;
import com.emobile.springtodo.model.entity.Task;
+import com.emobile.springtodo.model.entity.User;
import com.emobile.springtodo.model.security.AppUserDetails;
import com.emobile.springtodo.model.util.PageInfo;
import com.emobile.springtodo.repository.TaskRepository;
import com.emobile.springtodo.service.TaskService;
+import com.emobile.springtodo.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
@@ -18,7 +23,6 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
import java.text.MessageFormat;
import java.time.Clock;
@@ -42,6 +46,14 @@ public class TaskServiceImpl implements TaskService {
* {@link Task} Repository.
*/
private final TaskRepository taskRepository;
+ /**
+ * {@link User} Service.
+ * To fill author field.
+ *
+ * @see #enrich(Task)
+ * @see #enrich(Task, Task)
+ */
+ private final UserService userService;
/**
* Time management object.
*/
@@ -61,7 +73,7 @@ public void setSelf(TaskService self) {
*/
@Override
@Cacheable(AppCacheProperties.Types.TASKS)
- @Transactional(readOnly = true)
+ @LazySession
@LazyLogger
public List findAll(PageInfo pageInfo) {
return taskRepository.findAll(pageInfo).content();
@@ -76,7 +88,7 @@ public List findAll(PageInfo pageInfo) {
*/
@Override
@Cacheable(value = AppCacheProperties.Types.TASK_BY_ID, key = "#id")
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public Task findById(Long id) {
return taskRepository.findById(id).orElseThrow(
@@ -102,7 +114,7 @@ public Task findById(Long id) {
@CacheEvict(value = AppCacheProperties.Types.USER_BY_ID, key = "#result.authorId"),
@CacheEvict(value = AppCacheProperties.Types.USER_BY_NAME, allEntries = true)
})
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public Task save(Task model) {
model = enrich(model);
@@ -125,7 +137,7 @@ public Task save(Task model) {
@CacheEvict(value = AppCacheProperties.Types.USER_BY_ID, key = "#result.authorId"),
@CacheEvict(value = AppCacheProperties.Types.USER_BY_NAME, allEntries = true)
})
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public Task update(Long id, Task model) {
model = enrich(model, self.findById(id));
@@ -145,7 +157,7 @@ private Task enrich(Task model) {
.status(model.getStatus())
.createdAt(LocalDateTime.now(clock))
.updatedAt(LocalDateTime.now(clock))
- .authorId(getCurrentUserId())
+ .author(userService.findById(getCurrentUserId()))
.build();
}
@@ -180,7 +192,7 @@ private Task enrich(Task model, Task taskToUpdate) {
: model.getStatus())
.createdAt(taskToUpdate.getCreatedAt())
.updatedAt(LocalDateTime.now(clock))
- .authorId(taskToUpdate.getAuthorId())
+ .author(userService.findById(taskToUpdate.getAuthorId()))
.build();
}
@@ -197,11 +209,11 @@ private Task enrich(Task model, Task taskToUpdate) {
@CacheEvict(value = AppCacheProperties.Types.USER_BY_ID, allEntries = true),
@CacheEvict(value = AppCacheProperties.Types.USER_BY_NAME, allEntries = true)
})
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public void deleteById(Long id) {
- self.findById(id);
- taskRepository.deleteById(id);
+ Task task = self.findById(id);
+ taskRepository.deleteById(task);
}
/**
@@ -215,7 +227,7 @@ public void deleteById(Long id) {
@CacheEvict(value = AppCacheProperties.Types.USER_BY_ID, allEntries = true),
@CacheEvict(value = AppCacheProperties.Types.USER_BY_NAME, allEntries = true)
})
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public void deleteAll() {
taskRepository.deleteAll();
@@ -233,7 +245,7 @@ public void deleteAll() {
@CacheEvict(value = AppCacheProperties.Types.USER_BY_ID, key = "#userId"),
@CacheEvict(value = AppCacheProperties.Types.USER_BY_NAME, allEntries = true)
})
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public void deleteAllByUserId(Long userId) {
taskRepository.deleteAllByUserId(userId);
diff --git a/src/main/java/com/emobile/springtodo/service/impl/UserServiceImpl.java b/src/main/java/com/emobile/springtodo/service/impl/UserServiceImpl.java
index 23687951..546ef04e 100644
--- a/src/main/java/com/emobile/springtodo/service/impl/UserServiceImpl.java
+++ b/src/main/java/com/emobile/springtodo/service/impl/UserServiceImpl.java
@@ -1,14 +1,15 @@
package com.emobile.springtodo.service.impl;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
+import com.emobile.springtodo.aop.session.LazySession;
+import com.emobile.springtodo.model.util.SessionAction;
+import com.emobile.springtodo.model.util.TransactionalType;
import com.emobile.springtodo.config.property.cache.AppCacheProperties;
import com.emobile.springtodo.exception.AlreadyExitsException;
import com.emobile.springtodo.exception.EntityNotFoundException;
-import com.emobile.springtodo.model.entity.Task;
import com.emobile.springtodo.model.entity.User;
import com.emobile.springtodo.model.util.PageInfo;
import com.emobile.springtodo.repository.UserRepository;
-import com.emobile.springtodo.service.TaskService;
import com.emobile.springtodo.service.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.beans.factory.annotation.Autowired;
@@ -20,7 +21,6 @@
import org.springframework.context.annotation.Lazy;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
-import org.springframework.transaction.annotation.Transactional;
import java.text.MessageFormat;
import java.util.List;
@@ -42,11 +42,6 @@ public class UserServiceImpl implements UserService {
* {@link User} Repository.
*/
private final UserRepository userRepository;
- /**
- * {@link Task} Service.
- * To delete all task deleted user.
- */
- private final TaskService taskService;
/**
* Default PasswordEncoder.
* Needed to define and update the field password in {@link User}.
@@ -70,7 +65,7 @@ public void setSelf(UserService self) {
*/
@Override
@Cacheable(AppCacheProperties.Types.USERS)
- @Transactional(readOnly = true)
+ @LazySession
@LazyLogger
public List findAll(PageInfo pageInfo) {
return userRepository.findAll(pageInfo).content();
@@ -85,7 +80,7 @@ public List findAll(PageInfo pageInfo) {
*/
@Override
@Cacheable(value = AppCacheProperties.Types.USER_BY_ID, key = "#id")
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public User findById(Long id) {
return userRepository.findById(id).orElseThrow(
@@ -107,7 +102,7 @@ public User findById(Long id) {
*/
@Override
@Cacheable(value = AppCacheProperties.Types.USER_BY_NAME, key = "#username")
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public User findByUsername(String username) {
return userRepository.findByUsername(username).orElseThrow(
@@ -129,7 +124,7 @@ public User findByUsername(String username) {
@Override
@Cacheable(value = AppCacheProperties.Types.USER_BY_NAME, key = "#model.username")
@CacheEvict(value = AppCacheProperties.Types.USERS, allEntries = true)
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public User save(User model) {
model = enrich(model);
@@ -151,7 +146,7 @@ public User save(User model) {
@CachePut(value = AppCacheProperties.Types.USER_BY_NAME, key = "#result.username")
})
@CacheEvict(value = AppCacheProperties.Types.USERS, allEntries = true)
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public User update(Long id, User model) {
model = enrich(model, self.findById(id));
@@ -212,7 +207,7 @@ private User enrich(User model, User userToUpdate) {
* @param username username to check.
* @throws AlreadyExitsException if username already exist.
*/
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public void checkDuplicateUsername(String username) {
if (userRepository.existsByUsername(username)) {
@@ -234,7 +229,7 @@ public void checkDuplicateUsername(String username) {
* @throws AlreadyExitsException if username already exist
* excluding {@link User} with currentUserId.
*/
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public void checkDuplicateUsername(String username, Long currentUserId) {
if (userRepository.existsByUsernameAndIdNot(username, currentUserId)) {
@@ -254,7 +249,7 @@ public void checkDuplicateUsername(String username, Long currentUserId) {
* @param email email to check.
* @throws AlreadyExitsException if email already exist.
*/
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public void checkDuplicateEmail(String email) {
if (userRepository.existsByEmail(email)) {
@@ -276,7 +271,7 @@ public void checkDuplicateEmail(String email) {
* @throws AlreadyExitsException if email already exist
* excluding {@link User} with currentUserId.
*/
- @Transactional(readOnly = true)
+ @LazySession(action = SessionAction.CHECK)
@LazyLogger
public void checkDuplicateEmail(String email, Long currentUserId) {
if (userRepository.existsByEmailAndIdNot(email, currentUserId)) {
@@ -298,13 +293,14 @@ public void checkDuplicateEmail(String email, Long currentUserId) {
@Caching(evict = {
@CacheEvict(value = AppCacheProperties.Types.USER_BY_NAME, allEntries = true),
@CacheEvict(value = AppCacheProperties.Types.USER_BY_ID, key = "#id"),
- @CacheEvict(value = AppCacheProperties.Types.USERS, allEntries = true)
+ @CacheEvict(value = AppCacheProperties.Types.USERS, allEntries = true),
+ @CacheEvict(value = AppCacheProperties.Types.TASKS, allEntries = true),
+ @CacheEvict(value = AppCacheProperties.Types.TASK_BY_ID, allEntries = true)
})
- @Transactional
+ @LazySession(type = TransactionalType.AROUND)
@LazyLogger
public void deleteById(Long id) {
- self.findById(id);
- taskService.deleteAllByUserId(id);
- userRepository.deleteById(id);
+ User user = self.findById(id);
+ userRepository.deleteById(user);
}
}
diff --git a/src/main/java/com/emobile/springtodo/service/impl/security/SecurityServiceImpl.java b/src/main/java/com/emobile/springtodo/service/impl/security/SecurityServiceImpl.java
index d2818182..ae5dc875 100644
--- a/src/main/java/com/emobile/springtodo/service/impl/security/SecurityServiceImpl.java
+++ b/src/main/java/com/emobile/springtodo/service/impl/security/SecurityServiceImpl.java
@@ -1,6 +1,6 @@
package com.emobile.springtodo.service.impl.security;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.model.entity.User;
import com.emobile.springtodo.service.UserService;
import com.emobile.springtodo.service.security.SecurityService;
diff --git a/src/main/java/com/emobile/springtodo/service/impl/security/UserDetailsServiceImpl.java b/src/main/java/com/emobile/springtodo/service/impl/security/UserDetailsServiceImpl.java
index 071f0070..05272899 100644
--- a/src/main/java/com/emobile/springtodo/service/impl/security/UserDetailsServiceImpl.java
+++ b/src/main/java/com/emobile/springtodo/service/impl/security/UserDetailsServiceImpl.java
@@ -1,6 +1,6 @@
package com.emobile.springtodo.service.impl.security;
-import com.emobile.springtodo.aop.LazyLogger;
+import com.emobile.springtodo.aop.logger.LazyLogger;
import com.emobile.springtodo.model.entity.User;
import com.emobile.springtodo.model.security.AppUserDetails;
import com.emobile.springtodo.service.UserService;
diff --git a/src/main/java/com/emobile/springtodo/util/JdbcUtil.java b/src/main/java/com/emobile/springtodo/util/JdbcUtil.java
deleted file mode 100644
index 4f289500..00000000
--- a/src/main/java/com/emobile/springtodo/util/JdbcUtil.java
+++ /dev/null
@@ -1,26 +0,0 @@
-package com.emobile.springtodo.util;
-
-import org.springframework.jdbc.core.ResultSetExtractor;
-import org.springframework.jdbc.core.RowMapper;
-
-import java.util.Optional;
-
-public class JdbcUtil {
- private JdbcUtil() {
- throw new IllegalStateException("Utility class");
- }
-
- /**
- * Optional Extractor.
- *
- * @param mapper for map {@link T} entity
- * @param entity type for mapping
- * @return {@link Optional} mapped entity if ResultSet exist
- */
- public static ResultSetExtractor> optionalExtractor(
- RowMapper extends T> mapper) {
- return rs -> rs.next()
- ? Optional.of(mapper.mapRow(rs, 1))
- : Optional.empty();
- }
-}
diff --git a/src/main/java/com/emobile/springtodo/util/SessionUtil.java b/src/main/java/com/emobile/springtodo/util/SessionUtil.java
new file mode 100644
index 00000000..493dd718
--- /dev/null
+++ b/src/main/java/com/emobile/springtodo/util/SessionUtil.java
@@ -0,0 +1,30 @@
+package com.emobile.springtodo.util;
+
+import lombok.RequiredArgsConstructor;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.springframework.stereotype.Component;
+
+@RequiredArgsConstructor
+@Component
+public class SessionUtil {
+ private final SessionFactory sessionFactory;
+ private final ThreadLocal threadSession = new ThreadLocal<>();
+
+ public Session getSession() {
+ Session session = threadSession.get();
+ if (session == null) {
+ session = sessionFactory.openSession();
+ threadSession.set(session);
+ }
+ return session;
+ }
+
+ public void closeSession() {
+ Session session = threadSession.get();
+ threadSession.remove();
+ if (session != null && session.isOpen()) {
+ session.close();
+ }
+ }
+}
diff --git a/src/main/resources/config/application.yml b/src/main/resources/config/application.yml
index c2fee0c1..fccc94e2 100644
--- a/src/main/resources/config/application.yml
+++ b/src/main/resources/config/application.yml
@@ -6,6 +6,9 @@ spring:
url: ${SERVER_URL:jdbc:postgresql://localhost:5432/spring_todo_db}
username: ${SERVER_USERNAME:postgres}
password: ${SERVER_PASS:1322}
+ jpa:
+ show-sql: true
+ open-in-view: true
data:
redis:
port: ${REDIS_PORT:6379}
diff --git a/src/test/java/com/emobile/springtodo/SpringToDoApplicationTests.java b/src/test/java/com/emobile/springtodo/SpringToDoApplicationTests.java
index 17548caa..5fe400ae 100644
--- a/src/test/java/com/emobile/springtodo/SpringToDoApplicationTests.java
+++ b/src/test/java/com/emobile/springtodo/SpringToDoApplicationTests.java
@@ -1,5 +1,8 @@
package com.emobile.springtodo;
+import com.emobile.springtodo.model.entity.Task;
+import com.emobile.springtodo.model.entity.User;
+import org.hibernate.SessionFactory;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Primary;
@@ -21,4 +24,32 @@ public Clock fixedClock() {
return Clock.fixed(MILLENNIUM.toInstant(ZoneOffset.UTC), ZoneOffset.UTC);
}
}
+
+// @TestConfiguration
+// static class CustomHibernateConfiguration {
+// private final String dataSourceDriverClassName = "org.postgresql.Driver";
+// private final String dataSourceUrl = "jdbc:postgresql://localhost:5432/spring_todo_db";
+// private final String dataSourceUsername = "postgres";
+// private final String dataSourcePassword = "1322";
+//// @Bean
+//// @Primary
+//// public SessionUtil sessionUtil() {
+//// return new SessionUtil(sessionFactory());
+//// }
+//
+// @Bean
+// @Primary
+// public SessionFactory sessionFactory() {
+// return new org.hibernate.cfg.Configuration()
+// .setProperty("hibernate.connection.driver_class", dataSourceDriverClassName)
+// .setProperty("hibernate.connection.url", dataSourceUrl)
+// .setProperty("hibernate.connection.username", dataSourceUsername)
+// .setProperty("hibernate.connection.password", dataSourcePassword)
+// .setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
+// .setProperty("hibernate.show_sql", "true")
+// .addAnnotatedClass(User.class)
+// .addAnnotatedClass(Task.class)
+// .buildSessionFactory();
+// }
+// }
}
diff --git a/src/test/java/com/emobile/springtodo/controller/AuthControllerTest.java b/src/test/java/com/emobile/springtodo/controller/AuthControllerTest.java
index cd0ea37a..ba47a4e1 100644
--- a/src/test/java/com/emobile/springtodo/controller/AuthControllerTest.java
+++ b/src/test/java/com/emobile/springtodo/controller/AuthControllerTest.java
@@ -1,7 +1,9 @@
package com.emobile.springtodo.controller;
import com.redis.testcontainers.RedisContainer;
+import org.flywaydb.core.Flyway;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
@@ -50,6 +52,15 @@ static void configureProperties(DynamicPropertyRegistry registry) {
() -> REDIS_CONTAINER.getMappedPort(6379).toString());
}
+ @BeforeAll
+ static void beforeAll() {
+ POSTGRE_CONTAINER.start();
+ Flyway flyway = Flyway.configure()
+ .dataSource(POSTGRE_CONTAINER.getJdbcUrl(), POSTGRE_CONTAINER.getUsername(), POSTGRE_CONTAINER.getPassword())
+ .load();
+ flyway.migrate();
+ }
+
@AfterAll
static void afterAll() {
POSTGRE_CONTAINER.stop();
diff --git a/src/test/java/com/emobile/springtodo/controller/TaskControllerTest.java b/src/test/java/com/emobile/springtodo/controller/TaskControllerTest.java
index 4ebbb0ad..5f14b382 100644
--- a/src/test/java/com/emobile/springtodo/controller/TaskControllerTest.java
+++ b/src/test/java/com/emobile/springtodo/controller/TaskControllerTest.java
@@ -1,19 +1,24 @@
package com.emobile.springtodo.controller;
+import com.emobile.springtodo.model.entity.Task;
+import com.emobile.springtodo.model.entity.TaskStatus;
import com.emobile.springtodo.model.entity.User;
import com.emobile.springtodo.model.security.AppUserDetails;
import com.emobile.springtodo.model.security.RoleType;
+import com.emobile.springtodo.util.SessionUtil;
import com.redis.testcontainers.RedisContainer;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
+import org.flywaydb.core.Flyway;
+import org.flywaydb.core.internal.jdbc.JdbcTemplate;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.query.Query;
+import org.junit.jupiter.api.*;
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.data.redis.cache.RedisCacheManager;
import org.springframework.http.MediaType;
-import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.DynamicPropertyRegistry;
@@ -28,6 +33,7 @@
import java.time.Month;
import java.time.format.DateTimeFormatter;
import java.util.Collections;
+import java.util.List;
import static org.springframework.security.test.web.servlet.request.SecurityMockMvcRequestPostProcessors.user;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.delete;
@@ -43,14 +49,16 @@
@DisplayName("TaskControllerTest tests")
class TaskControllerTest {
private static final String URL_TEMPLATE = "/api/task";
+ private static final LocalDateTime MILLENNIUM = LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0, 0);
+ private static final LocalDateTime BEFORE_MILLENNIUM = MILLENNIUM.minusDays(5);
@Autowired
- JdbcTemplate jdbcTemplate;
+ private SessionFactory sessionFactory;
@Autowired
private MockMvc mockMvc;
@Autowired
private RedisCacheManager cacheManager;
- private static final LocalDateTime MILLENNIUM = LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0, 0);
- private static final LocalDateTime BEFORE_MILLENNIUM = MILLENNIUM.minusDays(5);
+ private Long existedId;
+ private Long existedUserId;
@Container
public static final PostgreSQLContainer> POSTGRE_CONTAINER =
@@ -73,6 +81,15 @@ static void configureProperties(DynamicPropertyRegistry registry) {
() -> REDIS_CONTAINER.getMappedPort(6379).toString());
}
+ @BeforeAll
+ static void beforeAll() {
+ POSTGRE_CONTAINER.start();
+ Flyway flyway = Flyway.configure()
+ .dataSource(POSTGRE_CONTAINER.getJdbcUrl(), POSTGRE_CONTAINER.getUsername(), POSTGRE_CONTAINER.getPassword())
+ .load();
+ flyway.migrate();
+ }
+
@AfterAll
static void afterAll() {
POSTGRE_CONTAINER.stop();
@@ -81,8 +98,34 @@ static void afterAll() {
@BeforeEach
void setUp() {
- jdbcTemplate.update("TRUNCATE users CASCADE");
cacheManager.getCacheNames().forEach(cacheName -> cacheManager.getCache(cacheName).clear());
+
+ Session session = sessionFactory.openSession();
+ Transaction transaction = session.beginTransaction();
+
+ session.createQuery("DELETE FROM Task").executeUpdate();
+ session.createQuery("DELETE FROM User").executeUpdate();
+
+ Task test1 = new Task();
+ Task test2 = new Task();
+ User testAuthor = new User(null, "user", "pass1",
+ "email1@co.m", RoleType.ROLE_USER, List.of(test1));
+ User testAuthor2 = new User(null, "user2", "pass1",
+ "email2@co.m", RoleType.ROLE_USER, List.of(test2));
+ test1 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor);
+ test2 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor2);
+
+ session.persist(testAuthor);
+ session.persist(testAuthor2);
+ session.persist(test1);
+ session.persist(test2);
+ existedId = test1.getId();
+ existedUserId = testAuthor.getId();
+
+ transaction.commit();
+ session.close();
}
@Test
@@ -90,7 +133,7 @@ void setUp() {
@DisplayName("getById test: get task data by id from anonymous user.")
void givenAnonymousUserWhenGetByIdUrlThenStatusUnauthorized()
throws Exception {
- String getByIdUrl = URL_TEMPLATE + "/1";
+ String getByIdUrl = URL_TEMPLATE + "/" + existedId;
mockMvc.perform(get(getByIdUrl))
.andExpect(status().isUnauthorized());
@@ -101,7 +144,7 @@ void givenAnonymousUserWhenGetByIdUrlThenStatusUnauthorized()
@DisplayName("getById test: get task data by not existed user id.")
void givenNotExistedUserIdWhenGetByIdUrlThenStatusNotFound()
throws Exception {
- String getByIdUrl = URL_TEMPLATE + "/1";
+ String getByIdUrl = URL_TEMPLATE + "/" + (existedId + 2);
mockMvc.perform(get(getByIdUrl))
.andExpect(status().isNotFound());
@@ -112,22 +155,14 @@ void givenNotExistedUserIdWhenGetByIdUrlThenStatusNotFound()
@DisplayName("getById test: get task data by existed user id.")
void givenExistedUserIdWhenGetByIdUrlThenUserResponse()
throws Exception {
- long expectedId = 1L;
- String getByIdUrl = URL_TEMPLATE + "/" + expectedId;
+ String getByIdUrl = URL_TEMPLATE + "/" + existedId;
String expectedName = "name";
- String expectedDescription = "description";
- String expectedStatus = "DONE";
- long expectedAuthorId = 2L;
- String sql = """
- INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_id)
- VALUES (?,?,?,?,?,?,?)
- """;
-
- setDefaultAuthorUser(expectedAuthorId);
- jdbcTemplate.update(sql,
- expectedId, expectedName, expectedDescription, expectedStatus,
- BEFORE_MILLENNIUM, MILLENNIUM, expectedAuthorId
- );
+ String expectedDescription = "des";
+ String expectedStatus = TaskStatus.TODO.name();
+ Long expectedAuthorId = sessionFactory.openSession()
+ .find(Task.class, existedId)
+ .getAuthor()
+ .getId();
mockMvc.perform(get(getByIdUrl))
.andExpect(jsonPath("$.id").isNumber())
@@ -137,7 +172,7 @@ INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_
.andExpect(jsonPath("$.createdAt").isString())
.andExpect(jsonPath("$.updatedAt").isString())
.andExpect(jsonPath("$.authorId").isNumber())
- .andExpect(jsonPath("$.id").value(expectedId))
+ .andExpect(jsonPath("$.id").value(existedId))
.andExpect(jsonPath("$.name").value(expectedName))
.andExpect(jsonPath("$.description").value(expectedDescription))
.andExpect(jsonPath("$.status").value(expectedStatus))
@@ -162,27 +197,18 @@ void givenAnonymousUserWhenSaveUrlThenStatusUnauthorized()
@DisplayName("save test: save task data by user id from auth user.")
void givenSaveJsonWhenSaveUrlThenStatusCreated()
throws Exception {
- long expectedId = 1L;
- String expectedName = "name";
+ String expectedName = "nameUpd";
String expectedDescription = "description";
String expectedStatus = "DONE";
- long expectedAuthorId = 2L;
String requestUserJson = """
{
- "name": "name",
+ "name": "nameUpd",
"description": "description",
"status": "DONE"
}""";
- User defaultUser = new User(
- expectedAuthorId,
- "username",
- "pass",
- "email@c.om",
- RoleType.ROLE_USER,
- Collections.emptyList()
- );
- AppUserDetails principal = new AppUserDetails(defaultUser);
- setDefaultAuthorUser(expectedAuthorId);
+ User user = sessionFactory.openSession()
+ .find(User.class, existedUserId);
+ AppUserDetails principal = new AppUserDetails(user);
mockMvc.perform(post(URL_TEMPLATE)
.with(user(principal))
@@ -196,7 +222,6 @@ void givenSaveJsonWhenSaveUrlThenStatusCreated()
.andExpect(jsonPath("$.createdAt").isString())
.andExpect(jsonPath("$.updatedAt").isString())
.andExpect(jsonPath("$.authorId").isNumber())
- .andExpect(jsonPath("$.id").value(expectedId))
.andExpect(jsonPath("$.name").value(expectedName))
.andExpect(jsonPath("$.description").value(expectedDescription))
.andExpect(jsonPath("$.status").value(expectedStatus))
@@ -204,7 +229,7 @@ void givenSaveJsonWhenSaveUrlThenStatusCreated()
.value(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(MILLENNIUM)))
.andExpect(jsonPath("$.updatedAt")
.value(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(MILLENNIUM)))
- .andExpect(jsonPath("$.authorId").value(expectedAuthorId))
+ .andExpect(jsonPath("$.authorId").value(existedUserId))
.andExpect(status().isCreated());
}
@@ -213,7 +238,7 @@ void givenSaveJsonWhenSaveUrlThenStatusCreated()
@DisplayName("update test: update task data by id from anonymous user.")
void givenAnonymousUserWhenUpdateUrlThenStatusUnauthorized()
throws Exception {
- String updateUrl = URL_TEMPLATE + "/1";
+ String updateUrl = URL_TEMPLATE + "/" + existedId;
mockMvc.perform(put(updateUrl))
.andExpect(status().isUnauthorized());
@@ -224,28 +249,16 @@ void givenAnonymousUserWhenUpdateUrlThenStatusUnauthorized()
@DisplayName("update test: update task data by user id from auth user.")
void givenInsertJsonWhenUpdateUrlThenTaskResponse()
throws Exception {
- long expectedId = 1L;
- String updateUrl = URL_TEMPLATE + "/" + expectedId;
- String expectedName = "name";
+ String updateUrl = URL_TEMPLATE + "/" + existedId;
+ String expectedName = "nameUpd";
String expectedDescription = "description";
- String expectedStatus = "DONE";
- long expectedAuthorId = 2L;
+ String expectedStatus = TaskStatus.TODO.name();
String requestUserJson = """
{
- "name": "name",
+ "name": "nameUpd",
"description": "description",
- "status": "DONE"
+ "status": "TODO"
}""";
- String sql = """
- INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_id)
- VALUES (?,?,?,?,?,?,?)
- """;
- setDefaultAuthorUser(expectedAuthorId);
-
- jdbcTemplate.update(sql,
- expectedId, expectedName, expectedDescription, expectedStatus,
- BEFORE_MILLENNIUM, MILLENNIUM, expectedAuthorId
- );
mockMvc.perform(put(updateUrl)
.contentType(MediaType.APPLICATION_JSON)
@@ -258,7 +271,7 @@ INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_
.andExpect(jsonPath("$.createdAt").isString())
.andExpect(jsonPath("$.updatedAt").isString())
.andExpect(jsonPath("$.authorId").isNumber())
- .andExpect(jsonPath("$.id").value(expectedId))
+ .andExpect(jsonPath("$.id").value(existedId))
.andExpect(jsonPath("$.name").value(expectedName))
.andExpect(jsonPath("$.description").value(expectedDescription))
.andExpect(jsonPath("$.status").value(expectedStatus))
@@ -266,7 +279,7 @@ INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_
.value(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(BEFORE_MILLENNIUM)))
.andExpect(jsonPath("$.updatedAt")
.value(DateTimeFormatter.ISO_LOCAL_DATE_TIME.format(MILLENNIUM)))
- .andExpect(jsonPath("$.authorId").value(expectedAuthorId))
+ .andExpect(jsonPath("$.authorId").value(existedUserId))
.andExpect(status().isOk());
}
@@ -275,7 +288,7 @@ INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_
@DisplayName("delete test: delete user data by id from anonymous user.")
void givenAnonymousUserWhenDeleteUrlThenStatusUnauthorized()
throws Exception {
- String deleteUrl = URL_TEMPLATE + "/1";
+ String deleteUrl = URL_TEMPLATE + "/" + existedId;
mockMvc.perform(delete(deleteUrl))
.andExpect(status().isUnauthorized());
@@ -286,7 +299,7 @@ void givenAnonymousUserWhenDeleteUrlThenStatusUnauthorized()
@DisplayName("delete test: delete user data by not existed id.")
void givenNotExistedUserIdWhenDeleteUrlThenStatusNotFound()
throws Exception {
- String deleteUrl = URL_TEMPLATE + "/1";
+ String deleteUrl = URL_TEMPLATE + "/" + (existedId + 2);
mockMvc.perform(delete(deleteUrl))
.andExpect(status().isNotFound());
@@ -297,38 +310,9 @@ void givenNotExistedUserIdWhenDeleteUrlThenStatusNotFound()
@DisplayName("delete test: delete user data by existed id from auth user.")
void givenExistedUserIdWhenDeleteUrlThenStatusNoContent()
throws Exception {
- long expectedId = 1L;
- String deleteUrl = URL_TEMPLATE + "/" + expectedId;
- String expectedName = "name";
- String expectedDescription = "description";
- String expectedStatus = "DONE";
- long expectedAuthorId = 2L;
- String sql = """
- INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_id)
- VALUES (?,?,?,?,?,?,?)
- """;
-
- setDefaultAuthorUser(expectedAuthorId);
- jdbcTemplate.update(sql,
- expectedId, expectedName, expectedDescription, expectedStatus,
- BEFORE_MILLENNIUM, MILLENNIUM, expectedAuthorId
- );
+ String deleteUrl = URL_TEMPLATE + "/" + existedId;
+
mockMvc.perform(delete(deleteUrl))
.andExpect(status().isNoContent());
}
-
- private void setDefaultAuthorUser(long expectedId) {
- String expectedUsername = "username";
- String expectedPass = "pass";
- String expectedEmail = "email@c.om";
- String expectedRole = "ROLE_USER";
- String sql = """
- INSERT INTO users(id, username, password, email, role)
- VALUES (?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- expectedId, expectedUsername, expectedPass,
- expectedEmail, expectedRole
- );
- }
}
diff --git a/src/test/java/com/emobile/springtodo/controller/UserControllerTest.java b/src/test/java/com/emobile/springtodo/controller/UserControllerTest.java
index db3bff9b..b5c1f599 100644
--- a/src/test/java/com/emobile/springtodo/controller/UserControllerTest.java
+++ b/src/test/java/com/emobile/springtodo/controller/UserControllerTest.java
@@ -1,16 +1,23 @@
package com.emobile.springtodo.controller;
+import com.emobile.springtodo.model.entity.Task;
+import com.emobile.springtodo.model.entity.TaskStatus;
+import com.emobile.springtodo.model.entity.User;
+import com.emobile.springtodo.model.security.RoleType;
+import com.emobile.springtodo.repository.impl.UserRepositoryImpl;
+import com.emobile.springtodo.util.SessionUtil;
import com.redis.testcontainers.RedisContainer;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
+import org.flywaydb.core.Flyway;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.query.Query;
+import org.junit.jupiter.api.*;
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.data.redis.cache.RedisCacheManager;
import org.springframework.http.MediaType;
-import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.test.context.support.WithAnonymousUser;
import org.springframework.security.test.context.support.WithMockUser;
@@ -23,6 +30,10 @@
import org.testcontainers.junit.jupiter.Testcontainers;
import org.testcontainers.utility.DockerImageName;
+import java.time.LocalDateTime;
+import java.time.Month;
+import java.util.List;
+
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
@@ -34,14 +45,18 @@
@DisplayName("UserControllerTest tests")
class UserControllerTest {
private static final String URL_TEMPLATE = "/api/user";
+ private static final LocalDateTime MILLENNIUM = LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0, 0);
+ private static final LocalDateTime BEFORE_MILLENNIUM = MILLENNIUM.minusDays(5);
@Autowired
- JdbcTemplate jdbcTemplate;
+ private SessionFactory sessionFactory;
@MockitoBean
PasswordEncoder passwordEncoder;
@Autowired
private MockMvc mockMvc;
@Autowired
private RedisCacheManager cacheManager;
+ private Long existedId;
+
@Container
public static final PostgreSQLContainer> POSTGRE_CONTAINER =
@@ -64,6 +79,15 @@ static void configureProperties(DynamicPropertyRegistry registry) {
() -> REDIS_CONTAINER.getMappedPort(6379).toString());
}
+ @BeforeAll
+ static void beforeAll() {
+ POSTGRE_CONTAINER.start();
+ Flyway flyway = Flyway.configure()
+ .dataSource(POSTGRE_CONTAINER.getJdbcUrl(), POSTGRE_CONTAINER.getUsername(), POSTGRE_CONTAINER.getPassword())
+ .load();
+ flyway.migrate();
+ }
+
@AfterAll
static void afterAll() {
POSTGRE_CONTAINER.stop();
@@ -72,8 +96,33 @@ static void afterAll() {
@BeforeEach
void setUp() {
- jdbcTemplate.update("TRUNCATE users CASCADE");
cacheManager.getCacheNames().forEach(cacheName -> cacheManager.getCache(cacheName).clear());
+
+ Session session = sessionFactory.openSession();
+ Transaction transaction = session.beginTransaction();
+
+ session.createQuery("DELETE FROM Task").executeUpdate();
+ session.createQuery("DELETE FROM User").executeUpdate();
+
+ Task test1 = new Task();
+ Task test2 = new Task();
+ User testAuthor = new User(null, "user", "pass1",
+ "email1@co.m", RoleType.ROLE_USER, List.of(test1));
+ User testAuthor2 = new User(null, "user2", "pass1",
+ "email2@co.m", RoleType.ROLE_USER, List.of(test2));
+ test1 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor);
+ test2 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor2);
+
+ session.persist(testAuthor);
+ session.persist(testAuthor2);
+ session.persist(test1);
+ session.persist(test2);
+ existedId = testAuthor.getId();
+
+ transaction.commit();
+ session.close();
}
@Test
@@ -81,7 +130,7 @@ void setUp() {
@DisplayName("getById test: get user data by id from anonymous user.")
void givenAnonymousUserWhenGetByIdUrlThenStatusUnauthorized()
throws Exception {
- String getByIdUrl = URL_TEMPLATE + "/1";
+ String getByIdUrl = URL_TEMPLATE + "/" + existedId;
mockMvc.perform(get(getByIdUrl))
.andExpect(status().isUnauthorized());
@@ -92,7 +141,7 @@ void givenAnonymousUserWhenGetByIdUrlThenStatusUnauthorized()
@DisplayName("getById test: get user data by not existed user id.")
void givenNotExistedUserIdWhenGetByIdUrlThenStatusNotFound()
throws Exception {
- String getByIdUrl = URL_TEMPLATE + "/1";
+ String getByIdUrl = URL_TEMPLATE + "/" + (existedId + 2);
mockMvc.perform(get(getByIdUrl))
.andExpect(status().isNotFound());
@@ -103,20 +152,11 @@ void givenNotExistedUserIdWhenGetByIdUrlThenStatusNotFound()
@DisplayName("getById test: get user data by existed user id.")
void givenExistedUserIdWhenGetByIdUrlThenUserResponse()
throws Exception {
- long expectedId = 1L;
- String getByIdUrl = URL_TEMPLATE + "/" + expectedId;
- String expectedUsername = "username";
- String expectedPass = "encodedPass";
- String expectedEmail = "email@c.om";
- String expectedRole = "ROLE_ADMIN";
- String sql = """
- INSERT INTO users(id, username, password, email, role)
- VALUES (?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- expectedId, expectedUsername, expectedPass,
- expectedEmail, expectedRole
- );
+ String getByIdUrl = URL_TEMPLATE + "/" + existedId;
+ String expectedUsername = "user";
+ String expectedPass = "pass1";
+ String expectedEmail = "email1@co.m";
+ String expectedRole = "ROLE_USER";
mockMvc.perform(get(getByIdUrl))
.andExpect(jsonPath("$.id").isNumber())
@@ -124,7 +164,7 @@ INSERT INTO users(id, username, password, email, role)
.andExpect(jsonPath("$.password").isString())
.andExpect(jsonPath("$.email").isString())
.andExpect(jsonPath("$.role").isString())
- .andExpect(jsonPath("$.id").value(expectedId))
+ .andExpect(jsonPath("$.id").value(existedId))
.andExpect(jsonPath("$.username").value(expectedUsername))
.andExpect(jsonPath("$.password").value(expectedPass))
.andExpect(jsonPath("$.email").value(expectedEmail))
@@ -137,7 +177,7 @@ INSERT INTO users(id, username, password, email, role)
@DisplayName("update test: update user data by id from anonymous user.")
void givenAnonymousUserWhenUpdateUrlThenStatusUnauthorized()
throws Exception {
- String updateUrl = URL_TEMPLATE + "/1";
+ String updateUrl = URL_TEMPLATE + "/" + existedId;
mockMvc.perform(put(updateUrl))
.andExpect(status().isUnauthorized());
@@ -148,29 +188,18 @@ void givenAnonymousUserWhenUpdateUrlThenStatusUnauthorized()
@DisplayName("update test: update user data by user id from auth user.")
void givenInsertJsonWhenUpdateUrlThenUserResponse()
throws Exception {
- long expectedId = 1L;
- String updateUrl = URL_TEMPLATE + "/" + expectedId;
- String oldUsername = "username";
- String oldPass = "password";
- String oldEmail = "email@c.om";
- String oldRole = "ROLE_ADMIN";
+ String updateUrl = URL_TEMPLATE + "/" + existedId;
+ String oldEmail = "email@co.m";
+ String oldRole = "ROLE_USER";
String expectedUsername = "user";
String expectedPass = "encodedPass";
String requestUserJson = """
{
"username": "user",
"password": "pass",
- "email" : "email@c.om",
- "roles": "ROLE_ADMIN"
+ "email" : "email@co.m",
+ "roles": "ROLE_USER"
}""";
- String sql = """
- INSERT INTO users(id, username, password, email, role)
- VALUES (?,?,?,?,?)
- """;//
- jdbcTemplate.update(sql,
- expectedId, oldUsername, oldPass,
- oldEmail, oldRole
- );
when(passwordEncoder.encode("pass"))
.thenReturn(expectedPass);
@@ -184,7 +213,7 @@ INSERT INTO users(id, username, password, email, role)
.andExpect(jsonPath("$.password").isString())
.andExpect(jsonPath("$.email").isString())
.andExpect(jsonPath("$.role").isString())
- .andExpect(jsonPath("$.id").value(expectedId))
+ .andExpect(jsonPath("$.id").value(existedId))
.andExpect(jsonPath("$.username").value(expectedUsername))
.andExpect(jsonPath("$.password").value(expectedPass))
.andExpect(jsonPath("$.email").value(oldEmail))
@@ -197,7 +226,7 @@ INSERT INTO users(id, username, password, email, role)
@DisplayName("delete test: delete user data by id from anonymous user.")
void givenAnonymousUserWhenDeleteUrlThenStatusUnauthorized()
throws Exception {
- String deleteUrl = URL_TEMPLATE + "/1";
+ String deleteUrl = URL_TEMPLATE + "/" + existedId;
mockMvc.perform(delete(deleteUrl))
.andExpect(status().isUnauthorized());
@@ -208,7 +237,7 @@ void givenAnonymousUserWhenDeleteUrlThenStatusUnauthorized()
@DisplayName("delete test: delete user data by not existed id.")
void givenNotExistedUserIdWhenDeleteUrlThenStatusNotFound()
throws Exception {
- String deleteUrl = URL_TEMPLATE + "/1";
+ String deleteUrl = URL_TEMPLATE + "/" + (existedId + 2);
mockMvc.perform(delete(deleteUrl))
.andExpect(status().isNotFound());
@@ -219,20 +248,8 @@ void givenNotExistedUserIdWhenDeleteUrlThenStatusNotFound()
@DisplayName("delete test: delete user data by existed id from auth user.")
void givenExistedUserIdWhenDeleteUrlThenStatusNoContent()
throws Exception {
- long expectedId = 1L;
- String deleteUrl = URL_TEMPLATE + "/" + expectedId;
- String expectedUsername = "username";
- String expectedPass = "encodedPass";
- String expectedEmail = "email@c.om";
- String expectedRole = "ROLE_ADMIN";
- String sql = """
- INSERT INTO users(id, username, password, email, role)
- VALUES (?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- expectedId, expectedUsername, expectedPass,
- expectedEmail, expectedRole
- );
+ String deleteUrl = URL_TEMPLATE + "/" + existedId;
+
mockMvc.perform(delete(deleteUrl))
.andExpect(status().isNoContent());
}
diff --git a/src/test/java/com/emobile/springtodo/repository/impl/TaskRepositoryImplTest.java b/src/test/java/com/emobile/springtodo/repository/impl/TaskRepositoryImplTest.java
index cd45bfda..fc4df98a 100644
--- a/src/test/java/com/emobile/springtodo/repository/impl/TaskRepositoryImplTest.java
+++ b/src/test/java/com/emobile/springtodo/repository/impl/TaskRepositoryImplTest.java
@@ -6,15 +6,17 @@
import com.emobile.springtodo.model.security.RoleType;
import com.emobile.springtodo.model.util.Page;
import com.emobile.springtodo.model.util.PageInfo;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
+import com.emobile.springtodo.util.SessionUtil;
+import org.flywaydb.core.Flyway;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.query.Query;
+import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
@@ -26,18 +28,17 @@
import java.util.List;
import java.util.Optional;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
-@DataJpaTest
-@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
+//@DataJpaTest
+//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
@Testcontainers
@DisplayName("TaskRepositoryImplTest Tests")
class TaskRepositoryImplTest {
private TaskRepositoryImpl repository;
- @Autowired
- private JdbcTemplate jdbcTemplate;
+ // @Autowired
+ private SessionUtil sessionUtil;
+ private static SessionFactory sessionFactory;
private static final LocalDateTime MILLENNIUM = LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0, 0);
private static final LocalDateTime BEFORE_MILLENNIUM = MILLENNIUM.minusDays(5);
@@ -46,11 +47,25 @@ class TaskRepositoryImplTest {
new PostgreSQLContainer<>("postgres:latest")
.withReuse(true);
- @DynamicPropertySource
- static void configureProperties(DynamicPropertyRegistry registry) {
- registry.add("spring.datasource.url", postgreContainer::getJdbcUrl);
- registry.add("spring.datasource.username", postgreContainer::getUsername);
- registry.add("spring.datasource.password", postgreContainer::getPassword);
+ @BeforeAll
+ static void beforeAll() {
+ postgreContainer.start();
+ Flyway flyway = Flyway.configure()
+ .dataSource(postgreContainer.getJdbcUrl(), postgreContainer.getUsername(), postgreContainer.getPassword())
+ .load();
+ flyway.migrate();
+
+ Configuration configuration = new Configuration()
+ .setProperty("hibernate.connection.url", postgreContainer.getJdbcUrl())
+ .setProperty("hibernate.connection.username", postgreContainer.getUsername())
+ .setProperty("hibernate.connection.password", postgreContainer.getPassword())
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
+ .setProperty("hibernate.hbm2ddl.auto", "create-drop")
+ .setProperty("hibernate.show_sql", "true")
+ .addAnnotatedClass(User.class)
+ .addAnnotatedClass(Task.class);
+
+ sessionFactory = configuration.buildSessionFactory();
}
@AfterAll
@@ -60,28 +75,42 @@ static void afterAll() {
@BeforeEach
void setUp() {
- repository = new TaskRepositoryImpl(jdbcTemplate);
- jdbcTemplate.update("TRUNCATE tasks CASCADE");
- jdbcTemplate.update("TRUNCATE users CASCADE");
+ sessionUtil = new SessionUtil(sessionFactory);
+ repository = new TaskRepositoryImpl(sessionUtil);
+
+ Session session = sessionFactory.openSession();
+ Transaction transaction = session.beginTransaction();
+
+ session.createQuery("DELETE FROM Task").executeUpdate();
+ session.createQuery("DELETE FROM User").executeUpdate();
+
+ transaction.commit();
+ session.close();
}
@Test
@DisplayName("findAll test: get all user data.")
void givenPageInfoWhenGetAllThenListUser() {
- PageInfo pageInfo = new PageInfo(5, 1);
- Task test1 = new Task(2L, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, 3L);
- Task test2 = new Task(4L, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, 2L);
+ Session session = sessionUtil.getSession();
+ PageInfo pageInfo = new PageInfo(5, 0);
+ Task test1 = new Task();
+ Task test2 = new Task();
+ User testAuthor = new User(null, "user", "pass1",
+ "email1@co.m", RoleType.ROLE_USER, List.of(test1));
+ User testAuthor2 = new User(null, "user2", "pass1",
+ "email2@co.m", RoleType.ROLE_USER, List.of(test2));
+ test1 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor);
+ test2 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor2);
Page expected = new Page<>(List.of(test1, test2));
- User testAuthor = new User(3L, "user", "pass1",
- "email1@co.m", RoleType.ROLE_USER, List.of());
- User testAuthor2 = new User(2L, "user2", "pass1",
- "email2@co.m", RoleType.ROLE_USER, List.of());
- addToDb(testAuthor);
- addToDb(testAuthor2);
- addToDb(test1);
- addToDb(test2);
+
+ session.beginTransaction();
+ session.persist(testAuthor);
+ session.persist(testAuthor2);
+ session.persist(test1);
+ session.persist(test2);
+ session.getTransaction().commit();
Page actual = repository.findAll(pageInfo);
@@ -91,13 +120,18 @@ void givenPageInfoWhenGetAllThenListUser() {
@Test
@DisplayName("findById test: get user data by id.")
void givenExistingIdWhenGetByIdThenUser() {
- Long taskId = 2L;
- Task test1 = new Task(taskId, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, 4L);
- User testAuthor = new User(4L, "user", "pass1",
- "email1@co.m", RoleType.ROLE_USER, List.of());
- addToDb(testAuthor);
- addToDb(test1);
+ Session session = sessionUtil.getSession();
+ Task test1 = new Task();
+ User testAuthor = new User(null, "user", "pass1",
+ "email1@co.m", RoleType.ROLE_USER, List.of(test1));
+ test1 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor);
+
+ session.beginTransaction();
+ session.persist(testAuthor);
+ session.persist(test1);
+ Long taskId = test1.getId();
+ session.getTransaction().commit();
Optional actual = repository.findById(taskId);
@@ -118,80 +152,43 @@ void givenNotExistingIdWhenGetByIdThenThrow() {
@Test
@DisplayName("update test: send task data to repository.")
void givenTaskWhenUpdateThenUpdatedTask() {
- Task test1 = new Task(2L, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, BEFORE_MILLENNIUM, 3L);
- Task expected = new Task(2L, "name2", "des2",
- TaskStatus.DONE, BEFORE_MILLENNIUM, MILLENNIUM, 3L);
- User testAuthor = new User(3L, "user", "pass1",
+ Session session = sessionUtil.getSession();
+ User testAuthor = new User(null, "user", "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of());
- addToDb(testAuthor);
- addToDb(test1);
+ Task test1 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, BEFORE_MILLENNIUM, testAuthor);
+
+ session.beginTransaction();
+ session.persist(testAuthor);
+ session.persist(test1);
+ Long taskId = test1.getId();
+ session.getTransaction().commit();
+
+ Task expected = new Task(taskId, "name2", "des2",
+ TaskStatus.DONE, BEFORE_MILLENNIUM, MILLENNIUM, testAuthor);
- repository.update(expected);
+ Task actual = repository.update(expected);
- assertTrue(existsInDb(expected));
+ session.find(Task.class, taskId);
+ assertEquals(expected, actual);
}
@Test
@DisplayName("delete test: delete task data message to repository.")
void givenTaskIdWhenDeleteThenVoid() {
- Long taskId = 2L;
- Task test1 = new Task(taskId, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, BEFORE_MILLENNIUM, 3L);
- User testAuthor = new User(3L, "user", "pass1",
+ Session session = sessionUtil.getSession();
+ User testAuthor = new User(null, "user", "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of());
- addToDb(testAuthor);
- addToDb(test1);
-
- repository.deleteById(taskId);
- assertFalse(existsInDb(test1));
- }
-
- private void addToDb(User user) {
- String sql = """
- INSERT INTO users(id, username, password, email, role)
- VALUES (?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- user.getId(), user.getUsername(), user.getPassword(),
- user.getEmail(), user.getRole().name()
- );
- }
-
- private void addToDb(Task task) {
- String sql = """
- INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_id)
- VALUES (?,?,?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- task.getId(), task.getName(), task.getDescription(),
- task.getStatus().name(), task.getCreatedAt(),
- task.getUpdatedAt(), task.getAuthorId()
- );
- }
+ Task test1 = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, BEFORE_MILLENNIUM, testAuthor);
+ session.beginTransaction();
+ session.persist(testAuthor);
+ session.persist(test1);
+ session.getTransaction().commit();
- private boolean existsInDb(Task task) {
- String sql = """
- SELECT EXISTS (SELECT *
- FROM tasks
- WHERE name = ?
- AND description = ?
- AND status = ?
- AND created_at = ?
- AND updated_at = ?
- AND author_id = ?)
- AS result
- """;
- return jdbcTemplate.queryForObject(sql, getExistsMapper(),
- task.getName(), task.getDescription(),
- task.getStatus().name(), task.getCreatedAt(),
- task.getUpdatedAt(), task.getAuthorId()
- );
- }
+ repository.deleteById(test1);
- private RowMapper getExistsMapper() {
- return (resultSet, rowNum) ->
- resultSet.getString("result")
- .equals("t");
+ Task actual = session.find(Task.class, test1.getId());
+ assertNull(actual);
}
}
diff --git a/src/test/java/com/emobile/springtodo/repository/impl/UserRepositoryImplTest.java b/src/test/java/com/emobile/springtodo/repository/impl/UserRepositoryImplTest.java
index d3a928cd..98ab8f3e 100644
--- a/src/test/java/com/emobile/springtodo/repository/impl/UserRepositoryImplTest.java
+++ b/src/test/java/com/emobile/springtodo/repository/impl/UserRepositoryImplTest.java
@@ -6,15 +6,25 @@
import com.emobile.springtodo.model.security.RoleType;
import com.emobile.springtodo.model.util.Page;
import com.emobile.springtodo.model.util.PageInfo;
-import org.junit.jupiter.api.AfterAll;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
+import com.emobile.springtodo.util.SessionUtil;
+import jakarta.persistence.EntityManager;
+import org.flywaydb.core.Flyway;
+import org.flywaydb.core.internal.jdbc.JdbcTemplate;
+import org.flywaydb.core.internal.jdbc.RowMapper;
+import org.hibernate.Session;
+import org.hibernate.SessionFactory;
+import org.hibernate.Transaction;
+import org.hibernate.annotations.NamedQuery;
+import org.hibernate.boot.MetadataSources;
+import org.hibernate.boot.registry.StandardServiceRegistry;
+import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
+import org.hibernate.cfg.Configuration;
+import org.hibernate.query.Query;
+import org.junit.jupiter.api.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
-import org.springframework.jdbc.core.JdbcTemplate;
-import org.springframework.jdbc.core.RowMapper;
+import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.DynamicPropertyRegistry;
import org.springframework.test.context.DynamicPropertySource;
import org.testcontainers.containers.PostgreSQLContainer;
@@ -26,18 +36,20 @@
import java.util.List;
import java.util.Optional;
-import static org.junit.jupiter.api.Assertions.assertEquals;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.junit.jupiter.api.Assertions.*;
-@DataJpaTest
-@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
+//@DataJpaTest
+//@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)
+//@SpringBootTest
@Testcontainers
@DisplayName("UserRepositoryImpl Tests")
class UserRepositoryImplTest {
+ // @Autowired
private UserRepositoryImpl repository;
- @Autowired
- private JdbcTemplate jdbcTemplate;
+ // @Autowired
+ private SessionUtil sessionUtil;
+ private static SessionFactory sessionFactory;
+
private static final LocalDateTime MILLENNIUM = LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0, 0);
private static final LocalDateTime BEFORE_MILLENNIUM = MILLENNIUM.minusDays(5);
@Container
@@ -52,6 +64,27 @@ static void configureProperties(DynamicPropertyRegistry registry) {
registry.add("spring.datasource.password", postgreContainer::getPassword);
}
+ @BeforeAll
+ static void beforeAll() {
+ postgreContainer.start();
+ Flyway flyway = Flyway.configure()
+ .dataSource(postgreContainer.getJdbcUrl(), postgreContainer.getUsername(), postgreContainer.getPassword())
+ .load();
+ flyway.migrate();
+
+ Configuration configuration = new Configuration()
+ .setProperty("hibernate.connection.url", postgreContainer.getJdbcUrl())
+ .setProperty("hibernate.connection.username", postgreContainer.getUsername())
+ .setProperty("hibernate.connection.password", postgreContainer.getPassword())
+ .setProperty("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect")
+ .setProperty("hibernate.hbm2ddl.auto", "create-drop")
+ .setProperty("hibernate.show_sql", "true")
+ .addAnnotatedClass(User.class)
+ .addAnnotatedClass(Task.class);
+
+ sessionFactory = configuration.buildSessionFactory();
+ }
+
@AfterAll
static void afterAll() {
postgreContainer.stop();
@@ -59,21 +92,39 @@ static void afterAll() {
@BeforeEach
void setUp() {
- repository = new UserRepositoryImpl(jdbcTemplate);
- jdbcTemplate.update("TRUNCATE users CASCADE");
+ sessionUtil = new SessionUtil(sessionFactory);
+ repository = new UserRepositoryImpl(sessionUtil);
+
+ Session session = sessionFactory.openSession();
+ Transaction transaction = session.beginTransaction();
+
+ session.createQuery("DELETE FROM Task").executeUpdate();
+ session.createQuery("DELETE FROM User").executeUpdate();
+
+ transaction.commit();
+ session.close();
+ }
+
+ @AfterEach
+ void after() {
+ sessionUtil.closeSession();
}
@Test
@DisplayName("findAll test: get all user data.")
void givenPageInfoWhenGetAllThenListUser() {
- PageInfo pageInfo = new PageInfo(5, 1);
- User test1 = new User(2L, "test1", "pass1",
+ PageInfo pageInfo = new PageInfo(5, 0);
+ User test1 = new User(null, "test1", "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of());
- User test2 = new User(3L, "test2", "pass2",
+ User test2 = new User(null, "test2", "pass2",
"email2@co.m", RoleType.ROLE_ADMIN, List.of());
Page expected = new Page<>(List.of(test1, test2));
- addToDb(test1);
- addToDb(test2);
+
+ Session session = sessionUtil.getSession();
+ Transaction transaction = session.beginTransaction();
+ sessionUtil.getSession().persist(test1);
+ sessionUtil.getSession().persist(test2);
+ transaction.commit();
Page actual = repository.findAll(pageInfo);
@@ -83,18 +134,24 @@ void givenPageInfoWhenGetAllThenListUser() {
@Test
@DisplayName("findById test: get user data by id.")
void givenExistingIdWhenGetByIdThenUser() {
- Long userId = 2L;
- Task testTask = new Task(2L, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, userId);
- User test1 = new User(userId, "test1", "pass1",
+ Session session = sessionUtil.getSession();
+ Transaction transaction = session.beginTransaction();
+ Task testTask = new Task();
+ User test1 = new User(null, "test1", "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of(testTask));
- addToDb(test1);
- addToDb(testTask);
+ testTask = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, test1);
+
+ sessionUtil.getSession().persist(test1);
+ sessionUtil.getSession().persist(testTask);
+ Long userId = test1.getId();
+ transaction.commit();
Optional actual = repository.findById(userId);
assertTrue(actual.isPresent());
assertEquals(test1, actual.get());
+ assertEquals(1, actual.get().getTaskList().size());
}
@Test
@@ -103,6 +160,7 @@ void givenNotExistingIdWhenGetByIdThenThrow() {
Long userId = 1L;
Optional actual = repository.findById(userId);
+ actual.ifPresent(System.out::println);
assertTrue(actual.isEmpty());
}
@@ -111,12 +169,17 @@ void givenNotExistingIdWhenGetByIdThenThrow() {
@DisplayName("findByUsername test: get user data by name.")
void givenExistingNameWhenGetByIdThenUser() {
String userUsername = "user";
- Task testTask = new Task(2L, "name", "des",
- TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, 2L);
- User test1 = new User(2L, userUsername, "pass1",
+ Task testTask = new Task();
+ User test1 = new User(null, userUsername, "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of(testTask));
- addToDb(test1);
- addToDb(testTask);
+ testTask = new Task(null, "name", "des",
+ TaskStatus.TODO, BEFORE_MILLENNIUM, MILLENNIUM, test1);
+
+ Session session = sessionUtil.getSession();
+ Transaction transaction = session.beginTransaction();
+ sessionUtil.getSession().persist(test1);
+ sessionUtil.getSession().persist(testTask);
+ transaction.commit();
Optional actual = repository.findByUsername(userUsername);
@@ -137,82 +200,64 @@ void givenNotExistingNameWhenGetByIdThenUser() {
@Test
@DisplayName("save test: send user data to repository.")
void givenUserWhenSendUserToDbThenSavedUser() {
+ Session session = sessionUtil.getSession();
User userToSave = new User(null, "user", "pass",
"email2@co.m", RoleType.ROLE_USER, List.of());
- repository.save(userToSave);
+ session.beginTransaction();
+ User actual = repository.save(userToSave);
+ session.getTransaction().commit();
- assertTrue(existsInDb(userToSave));
+ User inDb = session.find(User.class, actual.getId());
+
+ assertNotNull(actual);
+ assertNotNull(inDb);
+ assertEquals(inDb, actual);
+ assertSame(inDb, actual);
}
@Test
@DisplayName("update test: send user data to repository.")
void givenUserWhenUpdateThenUpdatedUser() {
- User test1 = new User(2L, "user", "pass1",
+ Session session = sessionUtil.getSession();
+ User test1 = new User(null, "user", "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of());
- User expected = new User(2L, "user", "pass",
- "email2@co.m", RoleType.ROLE_USER, List.of());
+
+ session.beginTransaction();
addToDb(test1);
+ Long userId = test1.getId();
+ session.getTransaction().commit();
- repository.update(expected);
+ User expected = new User(userId, "user", "pass",
+ "email2@co.m", RoleType.ROLE_USER, List.of());
- assertTrue(existsInDb(expected));
+ User actual = repository.update(expected);
+
+ session.find(User.class, userId);
+ assertEquals(expected, actual);
}
@Test
@DisplayName("delete test: delete user data message to repository.")
void givenUserIdWhenDeleteThenVoid() {
- Long userId = 1L;
- User test1 = new User(userId, "user", "pass1",
+ Session session = sessionUtil.getSession();
+ User test1 = new User(null, "user", "pass1",
"email1@co.m", RoleType.ROLE_USER, List.of());
- addToDb(test1);
+ session.beginTransaction();
+ session.persist(test1);
+ session.getTransaction().commit();
+
+ repository.deleteById(test1);
- repository.deleteById(userId);
- assertFalse(existsInDb(test1));
+ User actual = session.find(User.class, test1.getId());
+ assertNull(actual);
}
private void addToDb(User user) {
- String sql = """
- INSERT INTO users(id, username, password, email, role)
- VALUES (?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- user.getId(), user.getUsername(), user.getPassword(),
- user.getEmail(), user.getRole().name()
- );
+ sessionUtil.getSession().persist(user);
}
private void addToDb(Task task) {
- String sql = """
- INSERT INTO tasks(id, name, description, status, created_at, updated_at, author_id)
- VALUES (?,?,?,?,?,?,?)
- """;
- jdbcTemplate.update(sql,
- task.getId(), task.getName(), task.getDescription(),
- task.getStatus().name(), task.getCreatedAt(),
- task.getUpdatedAt(), task.getAuthorId()
- );
- }
-
- private boolean existsInDb(User user) {
- String sql = """
- SELECT EXISTS (SELECT *
- FROM users
- WHERE username = ?
- AND password = ?
- AND email = ?
- AND role = ?)
- AS result
- """;
- return jdbcTemplate.queryForObject(sql, getExistsMapper(),
- user.getUsername(), user.getPassword(),
- user.getEmail(), user.getRole().name()
- );
- }
-
- private RowMapper getExistsMapper() {
- return (resultSet, rowNum) ->
- resultSet.getString("result")
- .equals("t");
+ sessionUtil.getSession().persist(task);
}
}
diff --git a/src/test/java/com/emobile/springtodo/service/impl/TaskServiceImplTest.java b/src/test/java/com/emobile/springtodo/service/impl/TaskServiceImplTest.java
index 13eea52f..ba1cefa9 100644
--- a/src/test/java/com/emobile/springtodo/service/impl/TaskServiceImplTest.java
+++ b/src/test/java/com/emobile/springtodo/service/impl/TaskServiceImplTest.java
@@ -38,11 +38,13 @@
import static org.mockito.Mockito.when;
@ExtendWith(MockitoExtension.class)
-@DisplayName("UserServiceImplTest Tests")
+@DisplayName("TaskServiceImplTest Tests")
class TaskServiceImplTest {
private TaskServiceImpl taskService;
@Mock
private TaskRepository taskRepository;
+ @Mock
+ private UserServiceImpl userService;
private static final LocalDateTime MILLENNIUM = LocalDateTime.of(2000, Month.JANUARY, 1, 0, 0, 0);
private static final LocalDateTime BEFORE_MILLENNIUM = MILLENNIUM.minusDays(5);
private final Clock clock = Clock.fixed(MILLENNIUM.toInstant(ZoneOffset.UTC), ZoneOffset.UTC);
@@ -50,33 +52,41 @@ class TaskServiceImplTest {
@BeforeEach
void setUp() {
- taskService = new TaskServiceImpl(taskRepository, clock);
+ taskService = new TaskServiceImpl(taskRepository, userService, clock);
taskService.setSelf(taskService);
}
@Test
@DisplayName("findAll test: get all user data.")
- void givenWhenGetAllThenListUser() {
- List userList = new ArrayList<>(List.of(
+ void givenWhenGetAllThenListTask() {
+ List taskList = new ArrayList<>(List.of(
new Task(),
new Task()
));
PageInfo pageInfo = new PageInfo(0, 10);
when(taskRepository.findAll(pageInfo))
- .thenReturn(new Page<>(userList));
+ .thenReturn(new Page<>(taskList));
List actual = taskService.findAll(pageInfo);
- assertEquals(userList.size(), actual.size());
+ assertEquals(taskList.size(), actual.size());
verify(taskRepository, times(1))
.findAll(pageInfo);
}
@Test
- @DisplayName("findById test: get user data by id.")
- void givenExistingIdWhenGetByIdThenUser() {
- Long userId = 1L;
+ @DisplayName("findById test: get task data by id.")
+ void givenExistingIdWhenGetByIdThenTask() {
+ Long taskId = 1L;
+ User defaultUser = new User(
+ 2L,
+ "user",
+ "pass",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
Task defaultTask = new Task(
1L,
"name",
@@ -84,13 +94,13 @@ void givenExistingIdWhenGetByIdThenUser() {
TaskStatus.DONE,
LocalDateTime.of(2, 2, 2, 2, 2),
LocalDateTime.of(2, 2, 2, 2, 2),
- 2L
+ defaultUser
);
- when(taskRepository.findById(userId))
+ when(taskRepository.findById(taskId))
.thenReturn(Optional.of(defaultTask));
- Task actual = taskService.findById(userId);
+ Task actual = taskService.findById(taskId);
assertEquals(defaultTask, actual);
verify(taskRepository, times(1))
@@ -98,15 +108,15 @@ void givenExistingIdWhenGetByIdThenUser() {
}
@Test
- @DisplayName("findById test: try to get user data by not existing id.")
+ @DisplayName("findById test: try to get task data by not existing id.")
void givenNotExistingIdWhenGetByIdThenThrow() {
- Long userId = 1L;
+ Long taskId = 1L;
- when(taskRepository.findById(userId))
+ when(taskRepository.findById(taskId))
.thenReturn(Optional.empty());
assertThrows(EntityNotFoundException.class,
- () -> taskService.findById(userId),
+ () -> taskService.findById(taskId),
" index is incorrect."
);
verify(taskRepository, times(1))
@@ -114,9 +124,17 @@ void givenNotExistingIdWhenGetByIdThenThrow() {
}
@Test
- @DisplayName("save test: send user data to repository.")
- void givenUserWhenSendUserToDbThenSavedUser() {
+ @DisplayName("save test: send task data to repository.")
+ void givenTaskWhenSendTaskToDbThenSavedTask() {
Long userPrincipalId = 10L;
+ User defaultUser = new User(
+ userPrincipalId,
+ "username",
+ "password",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
Task taskToSave = new Task(
null,
"name",
@@ -133,15 +151,7 @@ void givenUserWhenSendUserToDbThenSavedUser() {
TaskStatus.DONE,
MILLENNIUM,
MILLENNIUM,
- userPrincipalId
- );
- User defaultUser = new User(
- userPrincipalId,
- "username",
- "password",
- "email",
- RoleType.ROLE_USER,
- Collections.emptyList()
+ defaultUser
);
AppUserDetails principal = new AppUserDetails(defaultUser);
Authentication auth =
@@ -154,6 +164,8 @@ void givenUserWhenSendUserToDbThenSavedUser() {
when(securityContext.getAuthentication()).thenReturn(auth);
when(taskRepository.save(expected))
.thenReturn(expected);
+ when(userService.findById(userPrincipalId))
+ .thenReturn(defaultUser);
Task actual = taskService.save(taskToSave);
@@ -163,9 +175,17 @@ void givenUserWhenSendUserToDbThenSavedUser() {
}
@Test
- @DisplayName("update test: with partially filled User data.")
- void givenPartiallyFilledUserUpdateThenUpdatedUser() {
- Long userId = 1L;
+ @DisplayName("update test: with partially filled Task data.")
+ void givenPartiallyFilledTaskUpdateThenUpdatedTask() {
+ Long taskId = 1L;
+ User defaultUser = new User(
+ 2L,
+ "user",
+ "pass",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
Task partiallyFilledTask = new Task(
null,
"name",
@@ -173,7 +193,7 @@ void givenPartiallyFilledUserUpdateThenUpdatedUser() {
TaskStatus.TODO,
null,
null,
- 2L
+ defaultUser
);
Task taskToUpdate = new Task(
1L,
@@ -182,7 +202,7 @@ void givenPartiallyFilledUserUpdateThenUpdatedUser() {
TaskStatus.DONE,
BEFORE_MILLENNIUM,
BEFORE_MILLENNIUM,
- 2L
+ defaultUser
);
Task expected = new Task(
1L,
@@ -191,16 +211,18 @@ void givenPartiallyFilledUserUpdateThenUpdatedUser() {
TaskStatus.TODO,
BEFORE_MILLENNIUM,
MILLENNIUM,
- 2L
+ defaultUser
);
- when(taskRepository.findById(userId))
+ when(taskRepository.findById(taskId))
.thenReturn(Optional.of(taskToUpdate));
when(taskRepository.update(expected))
.thenReturn(expected);
+ when(userService.findById(2L))
+ .thenReturn(defaultUser);
- Task actual = taskService.update(userId, partiallyFilledTask);
+ Task actual = taskService.update(taskId, partiallyFilledTask);
assertEquals(expected, actual);
verify(taskRepository, times(1))
@@ -210,9 +232,17 @@ void givenPartiallyFilledUserUpdateThenUpdatedUser() {
}
@Test
- @DisplayName("update test: with filled User data.")
- void givenFilledUserAndUserIdWhenUpdateThenUpdatedUser() {
- Long userId = 1L;
+ @DisplayName("update test: with filled Task data.")
+ void givenFilledTaskAndTaskIdWhenUpdateThenUpdatedTask() {
+ Long taskId = 1L;
+ User defaultUser = new User(
+ 2L,
+ "user",
+ "pass",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
Task taskToUpdate = new Task(
1L,
"name",
@@ -220,7 +250,7 @@ void givenFilledUserAndUserIdWhenUpdateThenUpdatedUser() {
TaskStatus.DONE,
BEFORE_MILLENNIUM,
BEFORE_MILLENNIUM,
- 2L
+ defaultUser
);
Task expected = new Task(
1L,
@@ -229,15 +259,17 @@ void givenFilledUserAndUserIdWhenUpdateThenUpdatedUser() {
TaskStatus.DONE,
BEFORE_MILLENNIUM,
MILLENNIUM,
- 2L
+ defaultUser
);
- when(taskRepository.findById(userId))
+ when(taskRepository.findById(taskId))
.thenReturn(Optional.of(expected));
when(taskRepository.update(expected))
.thenReturn(expected);
+ when(userService.findById(2L))
+ .thenReturn(defaultUser);
- Task actual = taskService.update(userId, taskToUpdate);
+ Task actual = taskService.update(taskId, taskToUpdate);
assertEquals(expected, actual);
verify(taskRepository, times(1))
@@ -247,10 +279,18 @@ void givenFilledUserAndUserIdWhenUpdateThenUpdatedUser() {
}
@Test
- @DisplayName("update test: try update with not existed user id.")
- void givenUserAndNotExistedUserIdWhenUpdateThenUpdatedUser() {
- Long notExistedUserId = 1L;
+ @DisplayName("update test: try update with not existed task id.")
+ void givenTaskAndNotExistedTaskIdWhenUpdateThenUpdatedTask() {
+ Long notExistedTaskId = 1L;
LocalDateTime creationTime = LocalDateTime.of(1999, Month.DECEMBER, 10, 0, 0, 0);
+ User defaultUser = new User(
+ 2L,
+ "user",
+ "pass",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
Task taskToUpdate = new Task(
1L,
"name",
@@ -258,15 +298,15 @@ void givenUserAndNotExistedUserIdWhenUpdateThenUpdatedUser() {
TaskStatus.DONE,
creationTime,
creationTime,
- 2L
+ defaultUser
);
- when(taskRepository.findById(notExistedUserId))
+ when(taskRepository.findById(notExistedTaskId))
.thenReturn(Optional.empty());
assertThrows(EntityNotFoundException.class,
- () -> taskService.update(notExistedUserId, taskToUpdate),
- "UserId is incorrect."
+ () -> taskService.update(notExistedTaskId, taskToUpdate),
+ "TaskId is incorrect."
);
verify(taskRepository, times(0))
.update(any());
@@ -275,32 +315,48 @@ void givenUserAndNotExistedUserIdWhenUpdateThenUpdatedUser() {
}
@Test
- @DisplayName("delete test: delete user data message to repository.")
- void givenExistedUserIdWhenDeleteThenVoid() {
+ @DisplayName("delete test: delete task data message to repository.")
+ void givenExistedTaskIdWhenDeleteThenVoid() {
Long existedTaskId = 1L;
-
+ User defaultUser = new User(
+ 2L,
+ "user",
+ "pass",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
+ Task expected = new Task(
+ 1L,
+ "name",
+ "description",
+ TaskStatus.DONE,
+ BEFORE_MILLENNIUM,
+ MILLENNIUM,
+ defaultUser
+ );
when(taskRepository.findById(existedTaskId))
- .thenReturn(Optional.of(new Task()));
+ .thenReturn(Optional.of(expected));
taskService.deleteById(existedTaskId);
verify(taskRepository, times(1))
.findById(existedTaskId);
verify(taskRepository, times(1))
- .deleteById(existedTaskId);
+ .deleteById(expected);
}
@Test
@DisplayName("delete test: delete task data message to repository.")
- void givenNotExistedUserIdWhenDeleteThenVoid() {
- Long notExistedUserId = 1L;
+ void givenNotExistedTaskIdWhenDeleteThenVoid() {
+ Long notExistedTaskId = 1L;
assertThrows(EntityNotFoundException.class,
- () -> taskService.deleteById(notExistedUserId),
- "UserId is incorrect."
+ () -> taskService.deleteById(notExistedTaskId),
+ "TaskId is incorrect."
);
verify(taskRepository, times(1))
- .findById(notExistedUserId);
+ .findById(notExistedTaskId);
verify(taskRepository, times(0))
- .deleteById(notExistedUserId);
+ .deleteById(any());
}
}
\ No newline at end of file
diff --git a/src/test/java/com/emobile/springtodo/service/impl/UserServiceImplTest.java b/src/test/java/com/emobile/springtodo/service/impl/UserServiceImplTest.java
index 45c0a174..fb382b0d 100644
--- a/src/test/java/com/emobile/springtodo/service/impl/UserServiceImplTest.java
+++ b/src/test/java/com/emobile/springtodo/service/impl/UserServiceImplTest.java
@@ -7,12 +7,14 @@
import com.emobile.springtodo.model.util.PageInfo;
import com.emobile.springtodo.repository.UserRepository;
import com.emobile.springtodo.service.TaskService;
+import com.emobile.springtodo.util.SessionUtil;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
import org.mockito.junit.jupiter.MockitoExtension;
+import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import java.util.ArrayList;
@@ -34,14 +36,12 @@ class UserServiceImplTest {
@Mock
private UserRepository userRepository;
@Mock
- private TaskService taskService;
- @Mock
private PasswordEncoder passwordEncoder;
@BeforeEach
void setUp() {
- userService = new UserServiceImpl(userRepository, taskService, passwordEncoder);
+ userService = new UserServiceImpl(userRepository, passwordEncoder);
userService.setSelf(userService);
}
@@ -274,15 +274,23 @@ void givenUserAndNotExistedUserIdWhenUpdateThenUpdatedUser() {
@DisplayName("delete test: delete user data message to repository.")
void givenExistedUserIdWhenDeleteThenVoid() {
Long existedUserId = 1L;
+ User defaultUser = new User(
+ 1L,
+ "user",
+ "pass",
+ "email",
+ RoleType.ROLE_USER,
+ Collections.emptyList()
+ );
when(userRepository.findById(existedUserId))
- .thenReturn(Optional.of(new User()));
+ .thenReturn(Optional.of(defaultUser));
userService.deleteById(existedUserId);
verify(userRepository, times(1))
.findById(existedUserId);
verify(userRepository, times(1))
- .deleteById(existedUserId);
+ .deleteById(defaultUser);
}
@Test
@@ -297,6 +305,6 @@ void givenNotExistedUserIdWhenDeleteThenVoid() {
verify(userRepository, times(1))
.findById(notExistedUserId);
verify(userRepository, times(0))
- .deleteById(notExistedUserId);
+ .deleteById(any());
}
}