diff --git a/movie-api/pom.xml b/movie-api/pom.xml
index 61d57cf..ed01682 100644
--- a/movie-api/pom.xml
+++ b/movie-api/pom.xml
@@ -40,6 +40,12 @@
org.springframework.boot
spring-boot-starter-validation
+
+
+ org.springframework.security
+ spring-security-test
+ test
+
@@ -89,6 +95,13 @@
spring-boot-starter-test
test
+
+
+
+ com.h2database
+ h2
+ runtime
+
diff --git a/movie-api/src/main/java/com/ivanfranchin/movieapi/MovieApiApplication.java b/movie-api/src/main/java/com/ivanfranchin/movieapi/MovieApiApplication.java
index 9d9e341..b2a25c2 100644
--- a/movie-api/src/main/java/com/ivanfranchin/movieapi/MovieApiApplication.java
+++ b/movie-api/src/main/java/com/ivanfranchin/movieapi/MovieApiApplication.java
@@ -2,6 +2,13 @@
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Scope;
+
+import com.ivanfranchin.movieapi.model.Movie;
+import com.ivanfranchin.movieapi.model.User;
+import com.ivanfranchin.movieapi.rest.dto.LoginRequest;
+import com.ivanfranchin.movieapi.rest.dto.SignUpRequest;
@SpringBootApplication
public class MovieApiApplication {
@@ -9,4 +16,28 @@ public class MovieApiApplication {
public static void main(String[] args) {
SpringApplication.run(MovieApiApplication.class, args);
}
+
+ @Bean
+ @Scope(value = "prototype")
+ User getUser() {
+ return new User();
+ }
+
+ @Bean
+ @Scope(value = "prototype")
+ Movie getMovie() {
+ return new Movie();
+ }
+
+ @Bean
+ @Scope(value = "prototype")
+ LoginRequest getLoginRequest() {
+ return new LoginRequest();
+ }
+
+ @Bean
+ @Scope(value = "prototype")
+ SignUpRequest getSignUpRequest() {
+ return new SignUpRequest();
+ }
}
diff --git a/movie-api/src/main/java/com/ivanfranchin/movieapi/repository/MovieRepository.java b/movie-api/src/main/java/com/ivanfranchin/movieapi/repository/MovieRepository.java
index bea6ff8..4b63fe6 100644
--- a/movie-api/src/main/java/com/ivanfranchin/movieapi/repository/MovieRepository.java
+++ b/movie-api/src/main/java/com/ivanfranchin/movieapi/repository/MovieRepository.java
@@ -5,6 +5,7 @@
import org.springframework.stereotype.Repository;
import java.util.List;
+import java.util.Optional;
@Repository
public interface MovieRepository extends JpaRepository {
@@ -12,4 +13,6 @@ public interface MovieRepository extends JpaRepository {
List findAllByOrderByTitle();
List findByImdbContainingOrTitleContainingOrderByTitle(String imdb, String title);
+
+ Optional findByImdb(String imdb);
}
diff --git a/movie-api/src/main/java/com/ivanfranchin/movieapi/security/WebSecurityConfig.java b/movie-api/src/main/java/com/ivanfranchin/movieapi/security/WebSecurityConfig.java
index f43cedc..ba50090 100644
--- a/movie-api/src/main/java/com/ivanfranchin/movieapi/security/WebSecurityConfig.java
+++ b/movie-api/src/main/java/com/ivanfranchin/movieapi/security/WebSecurityConfig.java
@@ -59,6 +59,6 @@ public PasswordEncoder passwordEncoder() {
return new BCryptPasswordEncoder();
}
- public static final String ADMIN = "ADMIN";
- public static final String USER = "USER";
+ public static final String ADMIN = "ROLE_ADMIN";
+ public static final String USER = "ROLE_USER";
}
diff --git a/movie-api/src/main/resources/application-test.properties b/movie-api/src/main/resources/application-test.properties
new file mode 100644
index 0000000..c1c3e9e
--- /dev/null
+++ b/movie-api/src/main/resources/application-test.properties
@@ -0,0 +1,20 @@
+## H2 Test Database creds
+spring.datasource.url=jdbc:h2:mem:testdb
+spring.datasource.driverClassName=org.h2.Driver
+spring.datasource.username=sa
+spring.datasource.password=password
+spring.datasource.initialization-mode=always
+spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
+spring.h2.console.enabled=true
+spring.jpa.hibernate.ddl-auto=create-drop
+spring.jpa.show-sql =true
+
+
+# SQL scripts
+sql.script.insert.user=INSERT INTO users (id, email, image_url, name, password, provider, provider_id, role, username) \
+ VALUES (11, 'kane@test.com', NULL, 'kane', '@kien12a99', 'LOCAL', 1, 'USER', 'Kane');
+sql.script.delete.users=DELETE FROM users
+
+sql.script.insert.movie=INSERT INTO movies (imdb, title, poster) \
+ values ('tt01171998', 'No home away', 'cudayanh1');
+sql.script.delete.movies=DELETE FROM movies;
\ No newline at end of file
diff --git a/movie-api/src/test/java/com/ivanfranchin/movieapi/MovieApiApplicationTests.java b/movie-api/src/test/java/com/ivanfranchin/movieapi/MovieApiApplicationTests.java
deleted file mode 100644
index 2e6ca23..0000000
--- a/movie-api/src/test/java/com/ivanfranchin/movieapi/MovieApiApplicationTests.java
+++ /dev/null
@@ -1,14 +0,0 @@
-package com.ivanfranchin.movieapi;
-
-import org.junit.jupiter.api.Disabled;
-import org.junit.jupiter.api.Test;
-import org.springframework.boot.test.context.SpringBootTest;
-
-@Disabled
-@SpringBootTest
-class MovieApiApplicationTests {
-
- @Test
- void contextLoads() {
- }
-}
diff --git a/movie-api/src/test/java/com/ivanfranchin/movieapi/movie/MovieControllerTest.java b/movie-api/src/test/java/com/ivanfranchin/movieapi/movie/MovieControllerTest.java
new file mode 100644
index 0000000..66a42b3
--- /dev/null
+++ b/movie-api/src/test/java/com/ivanfranchin/movieapi/movie/MovieControllerTest.java
@@ -0,0 +1,184 @@
+package com.ivanfranchin.movieapi.movie;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.http.MediaType;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.hamcrest.CoreMatchers.*; // is()
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ivanfranchin.movieapi.model.Movie;
+import com.ivanfranchin.movieapi.repository.MovieRepository;
+import com.ivanfranchin.movieapi.service.MovieService;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceContext;
+
+@TestPropertySource("/application-test.properties")
+@AutoConfigureMockMvc(addFilters = false)
+@SpringBootTest
+@Transactional
+public class MovieControllerTest {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ private static MockHttpServletRequest mockHttpRequest;
+
+ @Mock
+ private MovieService movieService;
+
+ @Autowired
+ private MovieRepository movieRepository;
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Autowired
+ private Movie movie;
+
+ @Autowired
+ private JdbcTemplate jdbc;
+
+ @Value("${sql.script.insert.movie}")
+ private String sqlInsertMovie;
+
+ @Value("${sql.script.delete.movies}")
+ private String sqlDeleteMovie;
+
+ @Value("${sql.script.insert.user}")
+ private String sqlInsertUser;
+
+ @Value("${sql.script.delete.users}")
+ private String sqlDeleteUser;
+
+ public static final MediaType APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON;
+
+ @BeforeAll
+ static void setupMock() {
+ mockHttpRequest = new MockHttpServletRequest();
+
+ mockHttpRequest.setParameter("imdb", "tt0163111");
+ mockHttpRequest.setParameter("title", "today, now");
+ mockHttpRequest.setParameter("poster", "admin");
+ }
+
+ @BeforeEach
+ void setupDbBeforeTransactions() throws Exception {
+ jdbc.execute(sqlInsertMovie);
+ jdbc.execute(sqlInsertUser);
+ }
+
+ @Test
+ void getNumberOfMoviesHttpRequest() throws Exception {
+ mockMvc.perform(MockMvcRequestBuilders.get("/public/numberOfMovies"))
+ .andExpect(status().isOk()).andExpect(jsonPath("$", is(11)));
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void getMovieByTextHttpRequest() throws Exception {
+ String text = "home";
+ mockMvc.perform(MockMvcRequestBuilders.get("/api/movies").param("text", text))
+ .andExpect(status().isOk())
+ .andDo(print())
+ .andExpect(jsonPath("$").isArray());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void createInvalidMovieHttpRequest() throws Exception {
+ String blankImdb = "";
+ mockMvc.perform(MockMvcRequestBuilders.post("/api/movies")
+ .contentType(MediaType.APPLICATION_JSON)
+ .param("imdb", blankImdb)
+ .param("title", "test title")
+ .param("poster", "Me"))
+ .andExpect(status().isBadRequest())
+ .andDo(print());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void createMovieHttpRequest() throws Exception {
+ String imdb = "tt0163111";
+ String title = "today, now";
+ String poster = "admin";
+
+ movie.setImdb(imdb);
+ movie.setTitle(title);
+ movie.setPoster(poster);
+
+ assertFalse(movieRepository.findByImdb(imdb).isPresent(), "should return false");
+
+ mockMvc.perform(MockMvcRequestBuilders.post("/api/movies")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(movie)))
+ .andExpect(status().isCreated())
+ .andExpect(content().contentType(APPLICATION_JSON_UTF8))
+ .andExpect(jsonPath("$.imdb", is(imdb)))
+ .andExpect(jsonPath("$.title", is(title)))
+ .andExpect(jsonPath("$.poster", is(poster)))
+ .andExpect(jsonPath("$.createdAt", is(notNullValue())))
+ .andDo(print());
+
+ assertTrue(movieRepository.findByImdb(imdb).isPresent(), "should return true");
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void deleteNonExistingMovieByImdbHttpRequest() throws Exception {
+ String imdb = "nonPresentImdb";
+
+ assertFalse(movieRepository.findByImdb(imdb).isPresent());
+
+ mockMvc.perform(MockMvcRequestBuilders.delete("/api/movies/{imdb}", imdb))
+ .andExpect(status().is4xxClientError())
+ .andDo(print());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void deleteMovieByImdbHttpRequest() throws Exception {
+ String imdb = "tt01171998";
+
+ assertTrue(movieRepository.findByImdb(imdb).isPresent(), "should return true");
+
+ mockMvc.perform(MockMvcRequestBuilders.delete("/api/movies/{imdb}", imdb))
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.imdb", is(imdb)))
+ .andExpect(jsonPath("$.title", is("No home away")))
+ .andExpect(jsonPath("$.poster", is("cudayanh1")))
+ // .andExpect(jsonPath("$.createdAt", is(notNullValue()))) // ? not sure why createdAt sometimes returns null
+ .andDo(print());
+
+ assertFalse(movieRepository.findByImdb(imdb).isPresent(), "should return false");
+ }
+
+ @AfterEach
+ void setupDbAfterTransactions() throws Exception {
+ jdbc.execute(sqlDeleteMovie);
+ jdbc.execute(sqlDeleteUser);
+ }
+}
diff --git a/movie-api/src/test/java/com/ivanfranchin/movieapi/movie/MovieServiceTest.java b/movie-api/src/test/java/com/ivanfranchin/movieapi/movie/MovieServiceTest.java
new file mode 100644
index 0000000..35f0dd3
--- /dev/null
+++ b/movie-api/src/test/java/com/ivanfranchin/movieapi/movie/MovieServiceTest.java
@@ -0,0 +1,100 @@
+package com.ivanfranchin.movieapi.movie;
+
+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 java.util.List;
+import java.util.Optional;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.TestPropertySource;
+
+import com.ivanfranchin.movieapi.model.Movie;
+import com.ivanfranchin.movieapi.repository.MovieRepository;
+import com.ivanfranchin.movieapi.service.MovieService;
+
+@TestPropertySource("/application-test.properties")
+@SpringBootTest
+public class MovieServiceTest {
+
+ @Autowired
+ private JdbcTemplate jdbc;
+
+ @Autowired
+ private MovieService movieService;
+
+ @Autowired
+ private MovieRepository movieRepository;
+
+ @Value("${sql.script.insert.movie}")
+ private String sqlInsertMovie;
+
+ @Value("${sql.script.delete.movies}")
+ private String sqlDeleteMovie;
+
+ @BeforeEach
+ void setupDbBeforeTransactions() throws Exception {
+ jdbc.execute(sqlInsertMovie);
+ }
+
+ @Test
+ void isMovieNullCheck() throws Exception {
+ Movie movie = movieService.validateAndGetMovie("tt01171998");
+ assertEquals("tt01171998", movie.getImdb() ,"should return true for movie has `imdb: tt01171998`");
+ }
+
+ @Test
+ void createMovieService() throws Exception {
+ Movie movie = new Movie("tt01171999", "be strong", "Jane");
+
+ movieService.saveMovie(movie);
+
+ Movie movieToCheck = movieService.validateAndGetMovie("tt01171999");
+
+ assertEquals("tt01171999", movieToCheck.getImdb());
+ }
+
+ @Test
+ void getMoviesService() throws Exception {
+ List movies = movieService.getMovies();
+ // there are 10 movies already persisted in db
+ // NOTE: TRUE if run for just this single case, otherwise FALSE
+ // assertEquals(11, movies.size(), "should return movies.size() == 11");
+
+ // NOTE: TRUE if run concurrently with other test cases, otherwise FALSE
+ assertEquals(1, movies.size(), "should return movies.size() == 11");
+ }
+
+ @Test
+ void getMoviesServiceContainGivenText() throws Exception {
+ List movies = movieService.getMoviesContainingText("home");
+ assertTrue(movies.size() > 0, "should return true for movies.size() > 0");
+ assertFalse(movies.size() > 1, "should return for movies.size() > 1");
+ assertTrue(movies.size() == 1, "should return for movies.size() == 1");
+ }
+
+ @Test
+ void deleteMovieService() throws Exception {
+ Optional movie = movieRepository.findByImdb("tt01171998");
+
+ assertTrue(Optional.of(movie).isPresent(), "should return true");
+
+ movieService.deleteMovie(movie.get());
+
+ movie = movieRepository.findByImdb("tt01171998");
+
+ assertFalse(movie.isPresent(), "should return false");
+ }
+
+ @AfterEach
+ void setupDbAfterTransactions() throws Exception {
+ jdbc.execute(sqlDeleteMovie);
+ }
+}
diff --git a/movie-api/src/test/java/com/ivanfranchin/movieapi/user/UserControllerTest.java b/movie-api/src/test/java/com/ivanfranchin/movieapi/user/UserControllerTest.java
new file mode 100644
index 0000000..9f309f9
--- /dev/null
+++ b/movie-api/src/test/java/com/ivanfranchin/movieapi/user/UserControllerTest.java
@@ -0,0 +1,216 @@
+package com.ivanfranchin.movieapi.user;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeAll;
+import org.junit.jupiter.api.BeforeEach;
+import org.junit.jupiter.api.Test;
+import org.mockito.Mock;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.boot.test.mock.mockito.MockBean;
+import org.springframework.http.MediaType;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.mock.web.MockHttpServletRequest;
+import org.springframework.security.oauth2.jwt.JwtDecoder;
+import org.springframework.security.test.context.support.WithMockUser;
+import org.springframework.test.context.TestPropertySource;
+import org.springframework.test.web.servlet.MockMvc;
+import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
+import org.springframework.transaction.annotation.Transactional;
+
+import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
+import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;
+import static org.hamcrest.CoreMatchers.*; // is()
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.ivanfranchin.movieapi.model.User;
+import com.ivanfranchin.movieapi.repository.UserRepository;
+import com.ivanfranchin.movieapi.rest.dto.LoginRequest;
+import com.ivanfranchin.movieapi.rest.dto.SignUpRequest;
+import com.ivanfranchin.movieapi.service.UserService;
+
+import jakarta.persistence.EntityManager;
+import jakarta.persistence.PersistenceContext;
+
+
+@TestPropertySource("/application-test.properties")
+@AutoConfigureMockMvc(addFilters = false)
+@SpringBootTest
+@Transactional
+public class UserControllerTest {
+
+ @PersistenceContext
+ private EntityManager entityManager;
+
+ private static MockHttpServletRequest mockHttpRequest;
+
+ @Mock
+ UserService userService;
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Autowired
+ private MockMvc mockMvc;
+
+ @Autowired
+ private ObjectMapper objectMapper;
+
+ @Autowired
+ private LoginRequest loginRequest;
+
+ @Autowired
+ private SignUpRequest signUpRequest;
+
+ @Autowired
+ private JdbcTemplate jdbc;
+
+ @Autowired
+ private User user;
+
+ @MockBean
+ private JwtDecoder jwtDecoder;
+
+ @Value("${sql.script.insert.user}")
+ private String sqlInsertUser;
+
+ @Value("${sql.script.delete.users}")
+ private String sqlDeleteUser;
+
+ public static final MediaType APPLICATION_JSON_UTF8 = MediaType.APPLICATION_JSON;
+
+ @BeforeAll
+ static void setupMock() {
+ mockHttpRequest = new MockHttpServletRequest();
+
+ mockHttpRequest.setParameter("username", "Jane");
+ mockHttpRequest.setParameter("email", "jane@test.com");
+ }
+
+ @BeforeEach
+ void setupDbBeforeTransactions() throws Exception {
+ jdbc.execute(sqlInsertUser);
+ }
+
+ @Test
+ void getNumberOfUsersHttpRequest() throws Exception {
+ mockMvc.perform(MockMvcRequestBuilders.get("/public/numberOfUsers"))
+ .andExpect(status().isOk()).andExpect(jsonPath("$", is(3)));
+ }
+
+ @Test
+ void testAuthenticateUserHttpRequest() throws Exception {
+ signUpRequest.setEmail("jane@test.com");
+ signUpRequest.setUsername("jane");
+ signUpRequest.setName("Jane");
+ signUpRequest.setPassword("jane");
+
+ assertFalse(userRepository.findByUsername("jane").isPresent(), "should return false");
+
+ mockMvc.perform(MockMvcRequestBuilders.post("/auth/signup")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(signUpRequest)))
+ .andExpect(status().is2xxSuccessful())
+ .andExpect(jsonPath("$.accessToken", is(notNullValue())))
+ .andDo(print());
+
+ assertTrue(userRepository.findByUsername("jane").isPresent(), "should return true");
+ }
+
+ @Test
+ void testSignupAuthenticatedUserHttpRequest() throws Exception {
+ String username = "admin";
+ String password = "admin";
+
+ loginRequest.setUsername(username);
+ loginRequest.setPassword(password);
+
+ assertTrue(userRepository.findByUsername(username).isPresent(), "should return true");
+
+ mockMvc.perform(MockMvcRequestBuilders.post("/auth/authenticate")
+ .contentType(MediaType.APPLICATION_JSON)
+ .content(objectMapper.writeValueAsString(loginRequest))
+ )
+ .andExpect(status().isOk())
+ .andExpect(jsonPath("$.accessToken", is(notNullValue())))
+ .andDo(print());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void getNonExistingUserByUsernameHttpRequest() throws Exception {
+ String nonExistingUsername = "Kaneee";
+
+ assertFalse(userRepository.findByUsername(nonExistingUsername).isPresent(), "should return true");
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/api/users/{username}", nonExistingUsername))
+ .andExpect(status().is4xxClientError())
+ .andDo(print());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void getUserByUsernameHttpRequest() throws Exception {
+ user.setEmail("jane@test.com");
+ user.setUsername("jane");
+ user.setName("Jane");
+ user.setPassword("password");
+ user.setRole("USER");
+
+ entityManager.persist(user);
+ entityManager.flush();
+
+ assertTrue(userRepository.findByUsername("jane").isPresent(), "should return true");
+
+ mockMvc.perform(MockMvcRequestBuilders.get("/api/users/{username}", "jane"))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(APPLICATION_JSON_UTF8))
+ .andExpect(jsonPath("$.id", is(3)))
+ .andExpect(jsonPath("$.username", is("jane")))
+ .andExpect(jsonPath("$.name", is( "Jane")))
+ .andExpect(jsonPath("$.email", is("jane@test.com")))
+ .andExpect(jsonPath("$.role", is("USER")))
+ .andDo(print());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void deleteNonExistingUserByUsernameHttpRequest() throws Exception {
+ String nonExistingUsername = "Kaneeee";
+
+ assertTrue(userRepository.findByUsername("Kane").isPresent(), "should return true for existing username");
+
+ mockMvc.perform(MockMvcRequestBuilders.delete("/api/users/{username}", nonExistingUsername))
+ .andExpect(status().is4xxClientError())
+ .andDo(print());
+ }
+
+ @Test
+ @WithMockUser(username = "admin", password = "admin", roles = "ADMIN")
+ void deleteUserByUsernameHttpRequest() throws Exception {
+ String username = "Kane";
+
+ assertTrue(userRepository.findByUsername(username).isPresent(), "should return true");
+
+ mockMvc.perform(MockMvcRequestBuilders.delete("/api/users/{username}", username))
+ .andExpect(status().isOk())
+ .andExpect(content().contentType(APPLICATION_JSON_UTF8))
+ .andExpect(jsonPath("$.id", is(11)))
+ .andExpect(jsonPath("$.username", is("Kane")))
+ .andExpect(jsonPath("$.name", is( "kane")))
+ .andExpect(jsonPath("$.email", is("kane@test.com")))
+ .andExpect(jsonPath("$.role", is("USER")))
+ .andDo(print());
+
+ assertFalse(userRepository.findByUsername(username).isPresent(), "should return false");
+ }
+
+ @AfterEach
+ void setupDbAfterTransactions() throws Exception {
+ jdbc.execute(sqlDeleteUser);
+ }
+}
diff --git a/movie-api/src/test/java/com/ivanfranchin/movieapi/user/UserServiceTest.java b/movie-api/src/test/java/com/ivanfranchin/movieapi/user/UserServiceTest.java
new file mode 100644
index 0000000..c3b6717
--- /dev/null
+++ b/movie-api/src/test/java/com/ivanfranchin/movieapi/user/UserServiceTest.java
@@ -0,0 +1,97 @@
+package com.ivanfranchin.movieapi.user;
+
+import org.junit.jupiter.api.AfterEach;
+import org.junit.jupiter.api.BeforeEach;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.boot.test.context.SpringBootTest;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.test.context.TestPropertySource;
+import org.junit.jupiter.api.Test;
+
+import java.util.Optional;
+
+import static org.junit.jupiter.api.Assertions.*;
+
+import com.ivanfranchin.movieapi.model.User;
+import com.ivanfranchin.movieapi.repository.UserRepository;
+import com.ivanfranchin.movieapi.security.oauth2.OAuth2Provider;
+import com.ivanfranchin.movieapi.service.UserService;
+
+
+@TestPropertySource("/application-test.properties")
+@SpringBootTest
+public class UserServiceTest {
+
+ @Autowired
+ private JdbcTemplate jdbc;
+
+ @Autowired
+ private UserRepository userRepository;
+
+ @Autowired
+ private UserService userService;
+
+ @Value("${sql.script.insert.user}")
+ private String sqlInsertUser;
+
+ @Value("${sql.script.delete.users}")
+ private String sqlDeleteUser;
+
+ @BeforeEach
+ public void setupDbBeforeTransactions() {
+ jdbc.execute(sqlInsertUser);
+ }
+
+ @Test
+ void getUserServiceByUsername() throws Exception {
+ assertTrue(userService.hasUserWithUsername("Kane"), "a user named 'Kane' should be created by @setupDbBeforeTransaction");
+ }
+
+ @Test
+ void getUserServiceByInvalidUsername() throws Exception {
+ assertFalse(userService.hasUserWithUsername("nonExistedUsername"), "should return false for a user with email 'nonExists@test.com'");
+ }
+
+ @Test
+ void getUserServiceByEmail() throws Exception {
+ Optional user = userService.getUserByEmail("kane@test.com");
+ assertTrue(user.isPresent(), "should return true for user with `email: cudayanh1@test.com`");
+ }
+
+ @Test
+ void getUserServiceByInvalidEmail() throws Exception {
+ Optional user = userService.getUserByEmail("kane1111@test.com");
+ assertFalse(user.isPresent(), "should return false for user with `email: cudayanh1111@test.com`");
+ }
+
+ @Test
+ void createUserService() throws Exception {
+ User user = new User("Jane", "@kien12a9", "jane",
+ "jane@test.com", "USER", "", OAuth2Provider.LOCAL, "2");
+
+ userService.saveUser(user);
+
+ Optional userToCheck = userRepository.findByUsername("Jane");
+
+ assertTrue(userToCheck.isPresent(), "should return true for a user with `username: Jane`");
+ }
+
+ @Test
+ void deleteUserService() throws Exception {
+ Optional user = userRepository.findByUsername("Kane");
+
+ assertTrue(user.isPresent(), "should return true for a user named `Kane`");
+
+ userService.deleteUser(user.get());
+
+ user = userRepository.findByUsername("Kane");
+
+ assertFalse(user.isPresent(), "should return false for deleted user named `Kane`");
+ }
+
+ @AfterEach
+ public void setupDbAfterTransactions() {
+ jdbc.execute(sqlDeleteUser);
+ }
+}