diff --git a/src/main/java/com/demo/sqlite/dtos/ProductOrderDTO.java b/src/main/java/com/demo/sqlite/dtos/ProductOrderDTO.java index 212c5a0..0b934b5 100644 --- a/src/main/java/com/demo/sqlite/dtos/ProductOrderDTO.java +++ b/src/main/java/com/demo/sqlite/dtos/ProductOrderDTO.java @@ -24,7 +24,7 @@ public ProductOrderDTO(Integer quantity, Stock.builder() .code(code) .description(description) - .category_id(category) + .categoryId(category) .status(status) .build(); } diff --git a/src/main/java/com/demo/sqlite/dtos/ShoppingCartJoined.java b/src/main/java/com/demo/sqlite/dtos/ShoppingCartJoined.java index 04b6170..1102db7 100644 --- a/src/main/java/com/demo/sqlite/dtos/ShoppingCartJoined.java +++ b/src/main/java/com/demo/sqlite/dtos/ShoppingCartJoined.java @@ -27,7 +27,7 @@ public ShoppingCartJoined(int id, int quantityCart, .code(code) .description(description) .quantity(quantityStock) - .category_id(category) + .categoryId(category) .price(price) .status(status) .build(); diff --git a/src/main/java/com/demo/sqlite/dtos/StockResponseDTO.java b/src/main/java/com/demo/sqlite/dtos/StockResponseDTO.java index 90a641c..469a6cb 100644 --- a/src/main/java/com/demo/sqlite/dtos/StockResponseDTO.java +++ b/src/main/java/com/demo/sqlite/dtos/StockResponseDTO.java @@ -47,8 +47,8 @@ public static StockResponseDTO from(Stock stock, Category category) { stock.getQuantity(), stock.getPrice(), stock.getStatus(), - stock.getCreated_by(), - stock.getUpdated_by() + stock.getCreatedBy(), + stock.getUpdatedBy() ); } diff --git a/src/main/java/com/demo/sqlite/models/Client.java b/src/main/java/com/demo/sqlite/models/Client.java index 1e53813..a2e4a7a 100644 --- a/src/main/java/com/demo/sqlite/models/Client.java +++ b/src/main/java/com/demo/sqlite/models/Client.java @@ -1,10 +1,7 @@ package com.demo.sqlite.models; import com.demo.sqlite.dtos.ClientSignupRequestDTO; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -23,10 +20,12 @@ public class Client { private String surnames; private String direction; private String state; - private String postal_code; + @Column(name = "postal_code") + private String postalCode; private String phone; private String email; - private String password_hash; + @Column(name = "password_hash") + private String passwordHash; public static Client fromSignupDTO(ClientSignupRequestDTO clientSignupDTO, String passwordHash) { return Client.builder() @@ -34,10 +33,10 @@ public static Client fromSignupDTO(ClientSignupRequestDTO clientSignupDTO, Strin .surnames(clientSignupDTO.getSurnames()) .direction(clientSignupDTO.getDirection()) .state(clientSignupDTO.getState()) - .postal_code(clientSignupDTO.getPostal_code()) + .postalCode(clientSignupDTO.getPostal_code()) .phone(clientSignupDTO.getPhone()) .email(clientSignupDTO.getEmail()) - .password_hash(passwordHash) + .passwordHash(passwordHash) .build(); } diff --git a/src/main/java/com/demo/sqlite/models/Employee.java b/src/main/java/com/demo/sqlite/models/Employee.java index ded4c51..699d4cc 100644 --- a/src/main/java/com/demo/sqlite/models/Employee.java +++ b/src/main/java/com/demo/sqlite/models/Employee.java @@ -1,10 +1,7 @@ package com.demo.sqlite.models; import com.demo.sqlite.dtos.EmployeeSignupRequestDTO; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -22,14 +19,15 @@ public class Employee { private String name; private String surnames; private String email; - private String password_hash; + @Column(name = "password_hash") + private String passwordHash; public static Employee fromSignupDTO(EmployeeSignupRequestDTO signupDTO, String passwordHash) { return Employee.builder() .name(signupDTO.getName()) .surnames(signupDTO.getSurnames()) .email(signupDTO.getEmail()) - .password_hash(passwordHash) + .passwordHash(passwordHash) .build(); } diff --git a/src/main/java/com/demo/sqlite/models/Order.java b/src/main/java/com/demo/sqlite/models/Order.java index 328e938..bda7d8e 100644 --- a/src/main/java/com/demo/sqlite/models/Order.java +++ b/src/main/java/com/demo/sqlite/models/Order.java @@ -1,9 +1,6 @@ package com.demo.sqlite.models; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -20,8 +17,11 @@ public class Order { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; - private int client_id; - private String payment_method; - private Timestamp created_at; + @Column(name = "client_id") + private int clientId; + @Column(name = "payment_method") + private String paymentMethod; + @Column(name = "created_at") + private Timestamp createdAt; } diff --git a/src/main/java/com/demo/sqlite/models/OrderDetails.java b/src/main/java/com/demo/sqlite/models/OrderDetails.java index 7fb04b7..27ff668 100644 --- a/src/main/java/com/demo/sqlite/models/OrderDetails.java +++ b/src/main/java/com/demo/sqlite/models/OrderDetails.java @@ -1,9 +1,6 @@ package com.demo.sqlite.models; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -18,8 +15,10 @@ public class OrderDetails { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; - private int order_id; - private int product_code; + @Column(name = "order_id") + private int orderId; + @Column(name = "product_code") + private int productCode; private int quantity; private double price; } diff --git a/src/main/java/com/demo/sqlite/models/ShoppingCart.java b/src/main/java/com/demo/sqlite/models/ShoppingCart.java index 0538f86..1d51f38 100644 --- a/src/main/java/com/demo/sqlite/models/ShoppingCart.java +++ b/src/main/java/com/demo/sqlite/models/ShoppingCart.java @@ -1,9 +1,6 @@ package com.demo.sqlite.models; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -18,7 +15,9 @@ public class ShoppingCart { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id; - private int product_code; + @Column(name = "product_code") + private int productCode; private int quantity; - private int client_id; + @Column(name = "client_id") + private int clientId; } diff --git a/src/main/java/com/demo/sqlite/models/Stock.java b/src/main/java/com/demo/sqlite/models/Stock.java index abac993..ba4e548 100644 --- a/src/main/java/com/demo/sqlite/models/Stock.java +++ b/src/main/java/com/demo/sqlite/models/Stock.java @@ -2,10 +2,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; -import jakarta.persistence.Entity; -import jakarta.persistence.GeneratedValue; -import jakarta.persistence.GenerationType; -import jakarta.persistence.Id; +import jakarta.persistence.*; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Data; @@ -24,28 +21,32 @@ public class Stock { private String description; @JsonIgnore private byte[] image; - private int category_id; + @Column(name = "category_id") + private int categoryId; private int quantity; private double price; private String status; - private int created_by; - private int updated_by; + @Column(name = "created_by") + private int createdBy; + @Column(name = "updated_by") + private int updatedBy; + public Stock(Integer code, String description, - int category_id, + int categoryId, Integer quantity, Double price, String status, - Integer created_by, - Integer updated_by) { + int createdBy, + int updatedBy) { this.code = code; this.description = description; - this.category_id = category_id; + this.categoryId = categoryId; this.quantity = quantity; this.price = price; this.status = status; - this.created_by = created_by; - this.updated_by = updated_by; + this.createdBy = createdBy; + this.updatedBy = updatedBy; } } diff --git a/src/main/java/com/demo/sqlite/repositories/ClientRepository.java b/src/main/java/com/demo/sqlite/repositories/ClientRepository.java index 49c4ca7..df5acc4 100644 --- a/src/main/java/com/demo/sqlite/repositories/ClientRepository.java +++ b/src/main/java/com/demo/sqlite/repositories/ClientRepository.java @@ -10,7 +10,7 @@ @Repository public interface ClientRepository extends CrudRepository { - @Query(value = "SELECT u FROM clients u WHERE u.email = :email AND u.password_hash = :password_hash") + @Query(value = "SELECT u FROM clients u WHERE u.email = :email AND u.passwordHash = :password_hash") Optional findClientByEmailAndPassword(@Param("email") String email, @Param("password_hash") String passwordHash); @Query(value = "SELECT u.id FROM clients u WHERE u.email = :email") diff --git a/src/main/java/com/demo/sqlite/repositories/EmployeeRepository.java b/src/main/java/com/demo/sqlite/repositories/EmployeeRepository.java index 7b89a1c..577ebdc 100644 --- a/src/main/java/com/demo/sqlite/repositories/EmployeeRepository.java +++ b/src/main/java/com/demo/sqlite/repositories/EmployeeRepository.java @@ -10,7 +10,7 @@ @Repository public interface EmployeeRepository extends CrudRepository { - @Query(value = "SELECT u FROM employees u WHERE u.email = :email AND u.password_hash = :password_hash") + @Query(value = "SELECT u FROM employees u WHERE u.email = :email AND u.passwordHash = :password_hash") Optional findEmployeeByEmailAndPassword(@Param("email") String email, @Param("password_hash") String passwordHash); @Query(value = "SELECT u.id FROM employees u WHERE u.email = :email") Optional existEmail(@Param("email") String email); diff --git a/src/main/java/com/demo/sqlite/repositories/OrderDetailsRepository.java b/src/main/java/com/demo/sqlite/repositories/OrderDetailsRepository.java index 1a4f84b..c0776f6 100644 --- a/src/main/java/com/demo/sqlite/repositories/OrderDetailsRepository.java +++ b/src/main/java/com/demo/sqlite/repositories/OrderDetailsRepository.java @@ -12,8 +12,8 @@ @Repository public interface OrderDetailsRepository extends CrudRepository { - @Query(value = "SELECT new com.demo.sqlite.dtos.ProductOrderDTO(u.quantity, u.price, s.code, s.description, s.category_id, s.status)" + - " FROM order_details u JOIN stock s ON u.product_code = s.code WHERE u.order_id = :order_id") + @Query(value = "SELECT new com.demo.sqlite.dtos.ProductOrderDTO(u.quantity, u.price, s.code, s.description, s.categoryId, s.status)" + + " FROM order_details u JOIN stock s ON u.productCode = s.code WHERE u.orderId = :order_id") List findByOrderId(@Param("order_id") Integer order_id); } diff --git a/src/main/java/com/demo/sqlite/repositories/OrdersRepository.java b/src/main/java/com/demo/sqlite/repositories/OrdersRepository.java index 1b36a21..24e9278 100644 --- a/src/main/java/com/demo/sqlite/repositories/OrdersRepository.java +++ b/src/main/java/com/demo/sqlite/repositories/OrdersRepository.java @@ -12,10 +12,10 @@ @Repository public interface OrdersRepository extends CrudRepository { - @Query(value = "SELECT u FROM orders u WHERE u.client_id = :client_id") + @Query(value = "SELECT u FROM orders u WHERE u.clientId = :client_id") List findByClientId(@Param("client_id") Integer clientId); - @Query(value = "SELECT u FROM orders u WHERE u.id = :id AND u.client_id = :client_id ") + @Query(value = "SELECT u FROM orders u WHERE u.id = :id AND u.clientId = :client_id ") Optional findByIdAndClientId(@Param("client_id") Integer clientId, @Param("id") Integer id); } diff --git a/src/main/java/com/demo/sqlite/repositories/ShoppingCartRepository.java b/src/main/java/com/demo/sqlite/repositories/ShoppingCartRepository.java index f896860..2df71af 100644 --- a/src/main/java/com/demo/sqlite/repositories/ShoppingCartRepository.java +++ b/src/main/java/com/demo/sqlite/repositories/ShoppingCartRepository.java @@ -14,12 +14,12 @@ public interface ShoppingCartRepository extends CrudRepository { @Query(value = "SELECT new com.demo.sqlite.dtos.ShoppingCartJoined(u.id, u.quantity," + - " s.code, s.description, s.quantity, s.category_id, s.price, s.status)" + - " FROM shopping_cart u JOIN stock s ON u.product_code = s.code WHERE u.client_id = :client_id") + " s.code, s.description, s.quantity, s.categoryId, s.price, s.status)" + + " FROM shopping_cart u JOIN stock s ON u.productCode = s.code WHERE u.clientId = :client_id") List filterByClientId(@Param("client_id") Integer clientId); @Modifying - @Query(value = "DELETE FROM shopping_cart u WHERE u.id = :cart_id AND u.client_id = :client_id") + @Query(value = "DELETE FROM shopping_cart u WHERE u.id = :cart_id AND u.clientId = :client_id") Integer deleteByIdAndClientId(@Param("cart_id") Integer cartId, @Param("client_id") Integer clientId); } diff --git a/src/main/java/com/demo/sqlite/repositories/StockRepository.java b/src/main/java/com/demo/sqlite/repositories/StockRepository.java index b9b873a..5e1834d 100644 --- a/src/main/java/com/demo/sqlite/repositories/StockRepository.java +++ b/src/main/java/com/demo/sqlite/repositories/StockRepository.java @@ -15,12 +15,12 @@ public interface StockRepository extends CrudRepository { @Query(value = "SELECT new com.demo.sqlite.dtos.StockResponseDTO(u.code, u.description, s.id,s.category, s.description," + - " u.quantity, u.price, u.status, u.created_by, u.updated_by) FROM stock u JOIN categories s ON u.category_id = s.id" + + " u.quantity, u.price, u.status, u.createdBy, u.updatedBy) FROM stock u JOIN categories s ON u.categoryId = s.id" + " WHERE (:phrase IS NULL OR u.description LIKE %:phrase%)") Page filterByPhraseAndPagination(@Param("phrase") String phrase, Pageable pageable); @Query(value = "SELECT new com.demo.sqlite.dtos.StockResponseDTO(u.code, u.description, s.id,s.category, s.description," + - " u.quantity, u.price, u.status, u.created_by, u.updated_by) FROM stock u JOIN categories s ON u.category_id = s.id" + + " u.quantity, u.price, u.status, u.createdBy, u.updatedBy) FROM stock u JOIN categories s ON u.categoryId = s.id" + " WHERE u.code = :code") Optional findStockResponseDTOById(@Param("code") Integer code); diff --git a/src/main/java/com/demo/sqlite/services/OrdersService.java b/src/main/java/com/demo/sqlite/services/OrdersService.java index f695984..469c946 100644 --- a/src/main/java/com/demo/sqlite/services/OrdersService.java +++ b/src/main/java/com/demo/sqlite/services/OrdersService.java @@ -37,9 +37,9 @@ public Optional orderDetails(int clientId, int orderId) .sum(); return OrderResultResponseDTO.builder() .id(value.getId()) - .paymentMethod(value.getPayment_method()) + .paymentMethod(value.getPaymentMethod()) .total(total) - .createdAt(value.getCreated_at()) + .createdAt(value.getCreatedAt()) .products(products) .build(); }); diff --git a/src/main/java/com/demo/sqlite/services/ShoppingCartService.java b/src/main/java/com/demo/sqlite/services/ShoppingCartService.java index 5aaad1a..865bd3d 100644 --- a/src/main/java/com/demo/sqlite/services/ShoppingCartService.java +++ b/src/main/java/com/demo/sqlite/services/ShoppingCartService.java @@ -68,9 +68,9 @@ public Optional addCartProduct(int clientId, int productCode, int if (product.getQuantity() >= quantity) { ShoppingCart saved = shoppingCartRepository.save( ShoppingCart.builder() - .product_code(productCode) + .productCode(productCode) .quantity(quantity) - .client_id(clientId) + .clientId(clientId) .build() ); return Optional.of(saved); @@ -99,15 +99,15 @@ public Order buyCart(int clientId, String paymentMethod) throws ValidationError shoppingCartJList.stream().map(ShoppingCartJoined::getId).toList(); Order newOrder = Order.builder() - .payment_method(paymentMethod) - .client_id(clientId) - .created_at(new Timestamp(System.currentTimeMillis())) + .paymentMethod(paymentMethod) + .clientId(clientId) + .createdAt(new Timestamp(System.currentTimeMillis())) .build(); Order orderSaved = orderRepository.save(newOrder); List orderDetailsList = shoppingCartJList.stream().map(cart -> OrderDetails.builder() - .order_id(orderSaved.getId()) - .product_code(cart.getStock().getCode()) + .orderId(orderSaved.getId()) + .productCode(cart.getStock().getCode()) .quantity(cart.getQuantity()) .price(cart.getStock().getPrice()) .build() diff --git a/src/main/java/com/demo/sqlite/services/StockService.java b/src/main/java/com/demo/sqlite/services/StockService.java index 6aa3a65..70f68f9 100644 --- a/src/main/java/com/demo/sqlite/services/StockService.java +++ b/src/main/java/com/demo/sqlite/services/StockService.java @@ -45,12 +45,12 @@ public Stock addProduct(String description, int categoryId, String status, Stock newStock = Stock.builder() .description(description) - .category_id(categoryId) + .categoryId(categoryId) .status(status) .price(price) .quantity(quantity) - .updated_by(clientId) - .created_by(clientId) + .createdBy(clientId) + .updatedBy(clientId) .build(); imageOpt.ifPresent(newStock::setImage); return stockRepository.save(newStock); @@ -67,11 +67,11 @@ public Optional updateProduct(int code, String description, in return stockOptional.map(stock -> { stock.setDescription(description); - stock.setCategory_id(categoryId); + stock.setCategoryId(categoryId); stock.setStatus(status); stock.setPrice(price); stock.setQuantity(quantity); - stock.setUpdated_by(clientId); + stock.setUpdatedBy(clientId); imageOpt.ifPresent(stock::setImage); stockRepository.save(stock); return StockResponseDTO.from(stock, optionalCategory.get()); diff --git a/src/test/java/com/demo/sqlite/SQLiteDemo/SqLiteDemoApplicationTests.java b/src/test/java/com/demo/sqlite/SQLiteDemo/SqLiteDemoApplicationTests.java deleted file mode 100644 index abfcedb..0000000 --- a/src/test/java/com/demo/sqlite/SQLiteDemo/SqLiteDemoApplicationTests.java +++ /dev/null @@ -1,13 +0,0 @@ -//package com.demo.sqlite.SQLiteDemo; -// -//import org.junit.jupiter.api.Test; -//import org.springframework.boot.test.context.SpringBootTest; -// -//@SpringBootTest -//class SqLiteDemoApplicationTests { -// -// @Test -// void contextLoads() { -// } -// -//} diff --git a/src/test/java/com/demo/sqlite/TestingWebApplicationTest.java b/src/test/java/com/demo/sqlite/TestingWebApplicationTest.java new file mode 100644 index 0000000..7663ec6 --- /dev/null +++ b/src/test/java/com/demo/sqlite/TestingWebApplicationTest.java @@ -0,0 +1,28 @@ +package com.demo.sqlite; + +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; +import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.test.web.servlet.MockMvc; + +import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.redirectedUrl; +import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status; + +@SpringBootTest +@AutoConfigureMockMvc +class TestingWebApplicationTest { + + @Autowired + private MockMvc mockMvc; + + @Test + public void testRedirection() throws Exception { + mockMvc.perform(get("/")) + .andExpect(status().is3xxRedirection()) + .andExpect(redirectedUrl("/swagger-ui/index.html")); + } + + +} diff --git a/src/test/java/com/demo/sqlite/repositories/ClientRepositoryTest.java b/src/test/java/com/demo/sqlite/repositories/ClientRepositoryTest.java new file mode 100644 index 0000000..e575b21 --- /dev/null +++ b/src/test/java/com/demo/sqlite/repositories/ClientRepositoryTest.java @@ -0,0 +1,63 @@ +package com.demo.sqlite.repositories; + +import com.demo.sqlite.models.Client; +import org.junit.jupiter.api.Test; +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.test.context.ActiveProfiles; +import org.springframework.test.context.ContextConfiguration; +import org.springframework.test.context.TestPropertySource; + +import java.util.Optional; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +@TestPropertySource(locations = "classpath:application-test.properties") +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +@ContextConfiguration(classes = TestConfig.class) +@ActiveProfiles("test") +public class ClientRepositoryTest { + + @Autowired + private ClientRepository clientRepository; + + private static final String TEST_EMAIL = "john@example.com"; + private static final String TEST_PASSWORD_HASH = "2689367B205C16CE32ED4200942B8B8B1E262DFC70D9BC9FBC77C49699A4F1DF"; + private static final String INVALID_EMAIL = "invalid_email@com"; + + private static final String INVALID_PASSWORD_HASH = "invalid_password_hash"; + + @Test + public void testFindExistingClientByEmailAndPassword() { + Optional clientFounded = + clientRepository.findClientByEmailAndPassword(TEST_EMAIL, TEST_PASSWORD_HASH); + assertTrue(clientFounded.isPresent()); + assertEquals(clientFounded.get().getEmail(), TEST_EMAIL); + assertEquals(clientFounded.get().getPasswordHash(), TEST_PASSWORD_HASH); + } + + @Test + public void testFindNonExistingClientByEmailAndPassword() { + Optional clientFounded = + clientRepository.findClientByEmailAndPassword(INVALID_EMAIL, INVALID_PASSWORD_HASH); + assertTrue(clientFounded.isEmpty()); + } + + @Test + public void testIfExistsEmailWhenEmailExists() { + Optional optionalID = clientRepository.existEmail(TEST_EMAIL); + assertTrue(optionalID.isPresent()); + assertEquals(optionalID.get(), 1); + } + + @Test + public void testIfExistsEmailWhenEmailDoesNotExists() { + Optional optionalID = clientRepository.existEmail(INVALID_EMAIL); + assertTrue(optionalID.isEmpty()); + } + + +} \ No newline at end of file diff --git a/src/test/java/com/demo/sqlite/repositories/TestConfig.java b/src/test/java/com/demo/sqlite/repositories/TestConfig.java new file mode 100644 index 0000000..0e69343 --- /dev/null +++ b/src/test/java/com/demo/sqlite/repositories/TestConfig.java @@ -0,0 +1,56 @@ +package com.demo.sqlite.repositories; + +import com.zaxxer.hikari.HikariDataSource; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.boot.test.context.TestConfiguration; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Profile; + +import javax.sql.DataSource; +import java.io.BufferedReader; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.sql.Connection; +import java.sql.Statement; + +@TestConfiguration +public class TestConfig { + + @Value("${spring.datasource.driver-class-name}") + private String driverClassName; + @Value("${spring.datasource.url}") + private String dataSourceUrl; + + @Bean + @Profile("test") + public DataSource dataSource() { + HikariDataSource dataSource = new HikariDataSource(); + dataSource.setDriverClassName(driverClassName); + dataSource.setJdbcUrl(dataSourceUrl); + dataSource.setMaximumPoolSize(10); + dataSource.setConnectionTimeout(60000); + dataSource.setConnectionTestQuery("SELECT name FROM sqlite_master limit 0;"); + initialize(dataSource); + return dataSource; + } + + public void initialize(DataSource dataSource) { + try (Connection connection = dataSource.getConnection()) { + Statement statement = connection.createStatement(); + InputStream inputStream = this.getClass().getResourceAsStream("/tables-sqlite.sql"); + BufferedReader reader = new BufferedReader(new InputStreamReader(inputStream)); + String line; + StringBuilder script = new StringBuilder(); + while ((line = reader.readLine()) != null) { + script.append(line).append("\n"); + } + reader.close(); + statement.executeUpdate(script.toString()); + statement.close(); + } catch (Exception e) { + e.printStackTrace(); + } + + } + +} \ No newline at end of file diff --git a/src/test/java/com/demo/sqlite/security/JWTCoderTest.java b/src/test/java/com/demo/sqlite/security/JWTCoderTest.java new file mode 100644 index 0000000..0ca5d78 --- /dev/null +++ b/src/test/java/com/demo/sqlite/security/JWTCoderTest.java @@ -0,0 +1,33 @@ +package com.demo.sqlite.security; + +import io.jsonwebtoken.Claims; +import org.junit.jupiter.api.Test; + +import java.util.Arrays; +import java.util.List; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; + +public class JWTCoderTest { + + private static final String TEST_SUBJECT = "testSubject"; + private static final List TEST_ROLES = Arrays.asList("role1", "role2"); + private static final int TEST_USER_ID = 123; + + @Test + public void testGenerateJWT() { + String jwt = JWTCoder.generateJWT(TEST_SUBJECT, TEST_ROLES, TEST_USER_ID); + assertNotNull(jwt); + } + + @Test + public void testParseJWT() { + String jwt = JWTCoder.generateJWT(TEST_SUBJECT, TEST_ROLES, TEST_USER_ID); + Claims claims = JWTCoder.parseJWT(jwt); + assertNotNull(claims); + assertEquals(TEST_SUBJECT, claims.getSubject()); + assertEquals(TEST_USER_ID, claims.get("userId", Integer.class)); + assertEquals(TEST_ROLES, claims.get("roles", List.class)); + } +} \ No newline at end of file diff --git a/src/test/java/com/demo/sqlite/services/StockServiceTest.java b/src/test/java/com/demo/sqlite/services/StockServiceTest.java new file mode 100644 index 0000000..e108f99 --- /dev/null +++ b/src/test/java/com/demo/sqlite/services/StockServiceTest.java @@ -0,0 +1,237 @@ +package com.demo.sqlite.services; + +import com.demo.sqlite.dtos.StockResponseDTO; +import com.demo.sqlite.exceptions.ValidationError; +import com.demo.sqlite.models.Category; +import com.demo.sqlite.models.Stock; +import com.demo.sqlite.repositories.CategoryRepository; +import com.demo.sqlite.repositories.StockRepository; +import lombok.AllArgsConstructor; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.ArgumentMatcher; +import org.mockito.InjectMocks; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; + +import java.util.Arrays; +import java.util.List; +import java.util.Optional; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.*; + +@ExtendWith(MockitoExtension.class) +class StockServiceTest { + + @Mock + private StockRepository stockRepository; + + @Mock + private CategoryRepository categoryRepository; + + @InjectMocks + private StockService stockService; + + private final String SEARCH_PHRASE = "searchPhrase"; + + private final Pageable pagination = PageRequest.of(0, 10); + + private Stock stock1; + private Stock stock2; + private Category category1; + private Category category2; + private List stockResponseDTOList; + + @BeforeEach + public void init() { + stock1 = Stock.builder() + .code(1) + .description("description 1") + .quantity(15) + .categoryId(1) + .price(25) + .status("active") + .image(new byte[]{10, 20}) + .createdBy(5) + .updatedBy(6) + .build(); + stock2 = Stock.builder() + .code(2) + .description("description 2") + .quantity(100) + .categoryId(2) + .price(120) + .status("active") + .build(); + category1 = Category.builder() + .id(1) + .category("category 1") + .description("description 1") + .build(); + category2 = Category.builder() + .id(2) + .category("category 2") + .description("description 2") + .build(); + stockResponseDTOList = List.of( + StockResponseDTO.from(stock1, category1), + StockResponseDTO.from(stock2, category2) + ); + } + + @Test + void testGetAllStocksWhenNoFoundStocks() { + // Mocking data + when(stockRepository.filterByPhraseAndPagination(SEARCH_PHRASE, pagination)).thenReturn(Page.empty()); + + // Test + List result = stockService.getAllStocks(SEARCH_PHRASE, pagination); + + // Assertion + assertTrue(result.isEmpty()); + verify(stockRepository, times(1)).filterByPhraseAndPagination(SEARCH_PHRASE, pagination); + } + + @Test + void testGetAllStocksWhenFoundStocks() { + Page stockResponseDTOS = new PageImpl<>(stockResponseDTOList); + // Mocking data + when(stockRepository.filterByPhraseAndPagination(SEARCH_PHRASE, pagination)).thenReturn(stockResponseDTOS); + + // Test + List result = stockService.getAllStocks(SEARCH_PHRASE, pagination); + + // Assertion + assertThat(result.size()).isEqualTo(2); + assertEquals(result, stockResponseDTOList); + verify(stockRepository, times(1)).filterByPhraseAndPagination(SEARCH_PHRASE, pagination); + } + + @Test + void testFindImageByCodeWhenFoundImage() { + // Mocking data + int imageCode = 123; + byte[] expectedImage = {10, 20}; + when(stockRepository.findImageByCode(imageCode)).thenReturn(Optional.of(expectedImage)); + + // Test + Optional result = stockService.findImageByCode(imageCode); + + // Assertion + assertTrue(result.isPresent()); + assertEquals(expectedImage, result.get()); + verify(stockRepository, times(1)).findImageByCode(imageCode); + } + + @Test + void testFindImageByCodeWhenNoFoundImage() { + // Mocking data + int imageCode = 123; + when(stockRepository.findImageByCode(imageCode)).thenReturn(Optional.empty()); + + // Test + Optional result = stockService.findImageByCode(imageCode); + + // Assertion + assertTrue(result.isEmpty()); + verify(stockRepository, times(1)).findImageByCode(imageCode); + } + + @AllArgsConstructor + public static class StockMatcher implements ArgumentMatcher { + + private Stock expectedStock; + + @Override + public boolean matches(Stock actualStock) { + // Perform specific checks on the fields of the Stock object + return expectedStock.getPrice() == actualStock.getPrice() && + expectedStock.getStatus().equals(actualStock.getStatus()) && + expectedStock.getDescription().equals(actualStock.getDescription()) && + expectedStock.getQuantity() == actualStock.getQuantity() && + Arrays.equals(expectedStock.getImage(), actualStock.getImage()) && + expectedStock.getCategoryId() == actualStock.getCategoryId(); + } + } + + @Test + void testAddProduct() throws ValidationError { + int clientId = 15; + // Mocking data + when(categoryRepository.findById(eq(stock1.getCategoryId()))).thenReturn(Optional.of(category1)); + when(stockRepository.save(argThat(new StockMatcher(stock1)))).thenReturn(stock1); + + // Test + Stock result = stockService.addProduct( + stock1.getDescription(), + stock1.getCategoryId(), + stock1.getStatus(), + stock1.getPrice(), + stock1.getQuantity(), + clientId, + Optional.ofNullable(stock1.getImage())); + + // Assertion + assertEquals(stock1, result); + verify(categoryRepository, times(1)).findById(stock1.getCategoryId()); + verify(stockRepository, times(1)).save(any(Stock.class)); + } + +// +// @Test +// void testUpdateProduct() throws ValidationError { +// // Mocking data +// Category category = new Category(); +// when(categoryRepository.findById(anyInt())).thenReturn(Optional.of(category)); +// Stock stock = new Stock(); +// when(stockRepository.findById(anyInt())).thenReturn(Optional.of(stock)); +// StockResponseDTO expectedResponse = new StockResponseDTO(); +// when(stockRepository.save(any(Stock.class))).thenReturn(stock); +// +// // Test +// Optional result = stockService.updateProduct(123, "new description", 1, "new status", 20.0, 10, 1, Optional.empty()); +// +// // Assertion +// assertTrue(result.isPresent()); +// assertEquals(expectedResponse, result.get()); +// verify(categoryRepository, times(1)).findById(anyInt()); +// verify(stockRepository, times(1)).findById(anyInt()); +// verify(stockRepository, times(1)).save(any(Stock.class)); +// } +// +// @Test +// void testFindStockByCode() { +// // Mocking data +// StockResponseDTO expectedResponse = new StockResponseDTO(); +// when(stockRepository.findStockResponseDTOById(anyInt())).thenReturn(Optional.of(expectedResponse)); +// +// // Test +// Optional result = stockService.findStockByCode(123); +// +// // Assertion +// assertTrue(result.isPresent()); +// assertEquals(expectedResponse, result.get()); +// verify(stockRepository, times(1)).findStockResponseDTOById(anyInt()); +// } +// +// @Test +// void testDeleteProduct() { +// // Mocking data +// doNothing().when(stockRepository).deleteById(anyInt()); +// +// // Test +// boolean result = stockService.deleteProduct(123); +// +// // Assertion +// assertTrue(result); +// verify(stockRepository, times(1)).deleteById(anyInt()); +// } +} \ No newline at end of file diff --git a/src/test/java/com/demo/sqlite/utils/JWTCoderTest.java b/src/test/java/com/demo/sqlite/utils/JWTCoderTest.java deleted file mode 100644 index ad4c8cc..0000000 --- a/src/test/java/com/demo/sqlite/utils/JWTCoderTest.java +++ /dev/null @@ -1,22 +0,0 @@ -package com.demo.sqlite.utils; - -import com.demo.sqlite.security.JWTCoder; -import io.jsonwebtoken.Claims; -import org.junit.jupiter.api.Test; - -import java.util.Collections; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -//@SpringBootTest -public class JWTCoderTest { - - @Test - public void testAdd() { - String jwt = JWTCoder.generateJWT("admin", Collections.singletonList("admin"), 1); - System.out.println(jwt); - Claims claims = JWTCoder.parseJWT(jwt); - System.out.println(claims); -// assertEquals(5, result); - } -} \ No newline at end of file diff --git a/src/test/resources/application-test.properties b/src/test/resources/application-test.properties new file mode 100644 index 0000000..8f231a5 --- /dev/null +++ b/src/test/resources/application-test.properties @@ -0,0 +1,42 @@ +spring.application.name=${APPLICATION_NAME:SQLiteDemo} +server.port=${HTTP_SERVER_PORT:8080} + +server.servlet.context-path=/ecommerce/api/v1 +# The default domain for generating ObjectNames must be specified. Otherwise when multiple Spring Boot applications start in the same servlet container +# all would be created with the same name (com.zaxxer.hikari:name=dataSource,type=HikariDataSource) for example +spring.jmx.default-domain=${spring.application.name} + +# datasource +spring.jpa.database-platform=org.hibernate.community.dialect.SQLiteDialect +sqlitedb.path=ecommerce-test.db +spring.datasource.url=jdbc:sqlite::memory: +spring.datasource.driver-class-name=org.sqlite.JDBC +spring.jpa.show-sql=true +spring.jpa.hibernate.ddl-auto=none +spring.jooq.sql-dialect=org.hibernate.community.dialect.SQLiteDialect +spring.datasource.type=com.zaxxer.hikari.HikariDataSource +spring.datasource.hikari.poolName=${spring.application.name} + +# 10 minutes +spring.datasource.hikari.maxLifetime=600000 +# 5 minutes +spring.datasource.hikari.idleTimeout=300000 +spring.datasource.hikari.minimumIdle=10 +spring.datasource.hikari.maximumPoolSize=50 +spring.datasource.hikari.connection-test-query=${JDBC_CONNECTION_TEST_QUERY:SELECT name FROM sqlite_master limit 0;} + +#log4j.logger.org.springframework.web=DEBUG + +#Swagger +springdoc.swagger-ui.path=/swagger-ui.html +springdoc.api-docs.path=/api-docs +springdoc.show-actuator=true +springdoc.swagger-ui.disable-swagger-default-url=true + +spring.servlet.multipart.enabled=true +spring.servlet.multipart.max-file-size=10MB +spring.servlet.multipart.max-request-size=10MB + +debug=false +#hibernate.globally_quoted_identifiers=true +