diff --git a/src/main/kotlin/com/project/movienight/adapters/web/FilmLibraryController.kt b/src/main/kotlin/com/project/movienight/adapters/web/FilmLibraryController.kt index fa95bad..5a9f002 100644 --- a/src/main/kotlin/com/project/movienight/adapters/web/FilmLibraryController.kt +++ b/src/main/kotlin/com/project/movienight/adapters/web/FilmLibraryController.kt @@ -92,12 +92,14 @@ class FilmLibraryController( fun removeFilm( @PathVariable userId: UUID, @PathVariable filmId: UUID, - ) = removeFilmFromLibraryUseCase.removeFilm( - RemoveFilmFromLibraryCommand( - userId = userId, - filmId = filmId, - ), - ) + ) { + removeFilmFromLibraryUseCase.removeFilm( + RemoveFilmFromLibraryCommand( + userId = userId, + filmId = filmId, + ), + ) + } @GetMapping("/available-films") fun getAvailableFilms( diff --git a/src/main/resources/db/migration/V1__init.sql b/src/main/resources/db/migration/V1__init.sql index 11017d1..900f6b5 100644 --- a/src/main/resources/db/migration/V1__init.sql +++ b/src/main/resources/db/migration/V1__init.sql @@ -1,7 +1,10 @@ CREATE TABLE IF NOT EXISTS public.users ( id UUID PRIMARY KEY, name VARCHAR(255) NOT NULL, - email VARCHAR(320) NOT NULL UNIQUE + email VARCHAR(320) NOT NULL UNIQUE, + provider VARCHAR(64), + provider_id VARCHAR(255), + created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ); CREATE TABLE IF NOT EXISTS public.films ( diff --git a/src/test/kotlin/com/project/movienight/adapters/persistence/entity/UserEntityMappingTest.kt b/src/test/kotlin/com/project/movienight/adapters/persistence/entity/UserEntityMappingTest.kt index bec7f20..cdf0c42 100644 --- a/src/test/kotlin/com/project/movienight/adapters/persistence/entity/UserEntityMappingTest.kt +++ b/src/test/kotlin/com/project/movienight/adapters/persistence/entity/UserEntityMappingTest.kt @@ -9,17 +9,17 @@ import kotlin.test.assertEquals import kotlin.test.assertNull class UserEntityMappingTest { - @Test fun `toDomain maps UserEntity correctly`() { - val entity = UserEntity( - id = UUID.randomUUID(), - name = "John Pork", - email = "john@email.com", - provider = "GOOGLE", - providerId = "google1234", - createdAt = LocalDateTime.now(), - ) + val entity = + UserEntity( + id = UUID.randomUUID(), + name = "John Pork", + email = "john@email.com", + provider = "GOOGLE", + providerId = "google1234", + createdAt = LocalDateTime.now(), + ) val user = entity.toDomain() assertEquals(entity.id, user.id) @@ -30,12 +30,13 @@ class UserEntityMappingTest { @Test fun `toEntity maps User with OAuth provider`() { - val user = User( - id = UUID.randomUUID(), - name = "Jane", - email = "jane@mail.com", - library = null - ) + val user = + User( + id = UUID.randomUUID(), + name = "Jane", + email = "jane@mail.com", + library = null, + ) val entity = user.toEntity(AuthProvider.YANDEX, "yandex456") @@ -48,12 +49,13 @@ class UserEntityMappingTest { @Test fun `toEntity maps User without OAuth provider`() { - val user = User( - id = UUID.randomUUID(), - name = "Bob", - email = "bob@mail.com", - library = null - ) + val user = + User( + id = UUID.randomUUID(), + name = "Bob", + email = "bob@mail.com", + library = null, + ) val entity = user.toEntity() @@ -63,12 +65,13 @@ class UserEntityMappingTest { @Test fun `mapping is reversible for basic fields`() { - val original = User( - id = UUID.randomUUID(), - name = "Alice", - email = "alice@email.com", - library = null - ) + val original = + User( + id = UUID.randomUUID(), + name = "Alice", + email = "alice@email.com", + library = null, + ) val mapped = original.toEntity().toDomain() @@ -76,6 +79,4 @@ class UserEntityMappingTest { assertEquals(original.name, mapped.name) assertEquals(original.email, mapped.email) } - - } diff --git a/src/test/kotlin/com/project/movienight/adapters/web/FilmControllerSearchTest.kt b/src/test/kotlin/com/project/movienight/adapters/web/FilmControllerSearchTest.kt new file mode 100644 index 0000000..dd6bd33 --- /dev/null +++ b/src/test/kotlin/com/project/movienight/adapters/web/FilmControllerSearchTest.kt @@ -0,0 +1,77 @@ +package com.project.movienight.adapters.web + +import com.project.movienight.application.ports.input.CreateFilmUseCase +import com.project.movienight.application.ports.input.DeleteFilmUseCase +import com.project.movienight.application.ports.input.EditFilmUseCase +import com.project.movienight.application.ports.input.GetAllFilmsUseCase +import com.project.movienight.application.ports.input.GetFilmByIdUseCase +import com.project.movienight.application.ports.input.SearchFilmByTitleUseCase +import com.project.movienight.domain.model.Film +import io.mockk.every +import io.mockk.mockk +import io.mockk.verify +import org.junit.jupiter.api.BeforeEach +import org.junit.jupiter.api.Test +import org.springframework.test.web.servlet.MockMvc +import org.springframework.test.web.servlet.get +import org.springframework.test.web.servlet.setup.MockMvcBuilders +import java.util.UUID + +class FilmControllerSearchTest { + private lateinit var mockMvc: MockMvc + private lateinit var searchFilmByTitleUseCase: SearchFilmByTitleUseCase + + @BeforeEach + fun setup() { + searchFilmByTitleUseCase = mockk() + + val controller = + FilmController( + createFilmUseCase = mockk(), + editFilmUseCase = mockk(), + deleteFilmUseCase = mockk(), + getFilmByIdUseCase = mockk(), + getAllFilmsUseCase = mockk(), + searchFilmByTitleUseCase = searchFilmByTitleUseCase, + ) + + mockMvc = MockMvcBuilders.standaloneSetup(controller).build() + } + + @Test + fun `search returns film when title exists`() { + val title = "Inception" + val film = Film(id = UUID.randomUUID(), title = title, description = "A dream heist") + + every { searchFilmByTitleUseCase.searchByTitle(title) } returns film + + mockMvc + .get("/api/films/search") { + param("title", title) + }.andExpect { + status { isOk() } + jsonPath("$.id") { value(film.id.toString()) } + jsonPath("$.title") { value(title) } + jsonPath("$.description") { value("A dream heist") } + } + + verify(exactly = 1) { searchFilmByTitleUseCase.searchByTitle(title) } + } + + @Test + fun `search returns empty body when title is missing`() { + val title = "Unknown Title" + + every { searchFilmByTitleUseCase.searchByTitle(title) } returns null + + mockMvc + .get("/api/films/search") { + param("title", title) + }.andExpect { + status { isOk() } + content { string("") } + } + + verify(exactly = 1) { searchFilmByTitleUseCase.searchByTitle(title) } + } +}