Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update movie-api with tests #10

Open
wants to merge 10 commits into
base: master
Choose a base branch
from
13 changes: 13 additions & 0 deletions movie-api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
<!-- spring security test -->
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>

<!-- JSON Web Token -->
<dependency>
Expand Down Expand Up @@ -89,6 +95,13 @@
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!-- h2 database -->
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
</dependencies>

<build>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,42 @@

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 {

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();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,14 @@
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface MovieRepository extends JpaRepository<Movie, String> {

List<Movie> findAllByOrderByTitle();

List<Movie> findByImdbContainingOrTitleContainingOrderByTitle(String imdb, String title);

Optional<Movie> findByImdb(String imdb);
}
Original file line number Diff line number Diff line change
Expand Up @@ -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";
}
20 changes: 20 additions & 0 deletions movie-api/src/main/resources/application-test.properties
Original file line number Diff line number Diff line change
@@ -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, '[email protected]', 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;

This file was deleted.

Original file line number Diff line number Diff line change
@@ -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);
}
}
Loading