diff --git a/adapters/out-persistence/src/test/kotlin/com/pokit/out/persistence/content/impl/ContentAdapterTest.kt b/adapters/out-persistence/src/test/kotlin/com/pokit/out/persistence/content/impl/ContentAdapterTest.kt index 53ea0ef4..5c1477c7 100644 --- a/adapters/out-persistence/src/test/kotlin/com/pokit/out/persistence/content/impl/ContentAdapterTest.kt +++ b/adapters/out-persistence/src/test/kotlin/com/pokit/out/persistence/content/impl/ContentAdapterTest.kt @@ -4,6 +4,7 @@ import com.pokit.bookmark.BookmarkFixture import com.pokit.category.CategoryFixture import com.pokit.category.model.Category import com.pokit.category.model.CategoryImage +import com.pokit.category.model.OpenType import com.pokit.content.ContentFixture import com.pokit.log.model.LogType import com.pokit.log.model.UserLog @@ -156,7 +157,8 @@ class ContentAdapterTest( val anotherCategory = Category( userId = savedUser.id, categoryName = "다른 카테고리", - categoryImage = savedAnotherImage.toDomain() + categoryImage = savedAnotherImage.toDomain(), + openType = OpenType.PUBLIC ) val savedAnotherCategory = categoryRepository.save(CategoryEntity.of(anotherCategory)) diff --git a/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/category/CategoryFixture.kt b/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/category/CategoryFixture.kt index 57f58179..186a60c1 100644 --- a/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/category/CategoryFixture.kt +++ b/adapters/out-persistence/src/testFixtures/kotlin/com/pokit/category/CategoryFixture.kt @@ -3,25 +3,30 @@ package com.pokit.category import com.pokit.category.model.Category import com.pokit.category.model.CategoryImage import com.pokit.category.model.CategoryStatus +import com.pokit.category.model.OpenType class CategoryFixture { companion object { fun getCategory(userId: Long, image: CategoryImage) = Category( userId = userId, categoryName = "스포츠/레저", - categoryImage = image + categoryImage = image, + openType = OpenType.PUBLIC ) fun getCategory(userId: Long) = Category( + categoryId = 1L, userId = userId, categoryName = "스포츠/레저", - categoryImage = CategoryImage(1, "www.s3.com") + categoryImage = CategoryImage(1, "www.s3.com"), + openType = OpenType.PUBLIC ) fun getUnCategorized(userId: Long, image: CategoryImage) = Category( userId = userId, categoryName = CategoryStatus.UNCATEGORIZED.displayName, - categoryImage = image + categoryImage = image, + openType = OpenType.PUBLIC ) } } diff --git a/adapters/out-web/src/main/kotlin/com/pokit/alert/config/FirebaseConfig.kt b/adapters/out-web/src/main/kotlin/com/pokit/alert/config/FirebaseConfig.kt new file mode 100644 index 00000000..91e676f0 --- /dev/null +++ b/adapters/out-web/src/main/kotlin/com/pokit/alert/config/FirebaseConfig.kt @@ -0,0 +1,23 @@ +package com.pokit.alert.config + +import com.google.auth.oauth2.GoogleCredentials +import com.google.firebase.FirebaseApp +import com.google.firebase.FirebaseOptions +import org.springframework.context.annotation.Bean +import org.springframework.context.annotation.Configuration +import org.springframework.core.io.ClassPathResource + +@Configuration +class FirebaseConfig { + @Bean + fun firebaseApp(): FirebaseApp { + val resource = ClassPathResource("google-services.json") + val serviceAccount = resource.inputStream + + val options = FirebaseOptions.builder() + .setCredentials(GoogleCredentials.fromStream(serviceAccount)) + .build() + + return FirebaseApp.initializeApp(options) + } +} diff --git a/adapters/out-web/src/main/kotlin/com/pokit/alert/impl/FcmSender.kt b/adapters/out-web/src/main/kotlin/com/pokit/alert/impl/FcmSender.kt new file mode 100644 index 00000000..574aeeb8 --- /dev/null +++ b/adapters/out-web/src/main/kotlin/com/pokit/alert/impl/FcmSender.kt @@ -0,0 +1,43 @@ +package com.pokit.alert.impl + +import com.google.firebase.messaging.FirebaseMessaging +import com.google.firebase.messaging.FirebaseMessagingException +import com.google.firebase.messaging.Message +import com.google.firebase.messaging.Notification +import com.pokit.alert.model.AlertBatch +import com.pokit.alert.port.out.AlertSender +import io.github.oshai.kotlinlogging.KotlinLogging +import org.springframework.stereotype.Component + +@Component +class FcmSender : AlertSender { + private val logger = KotlinLogging.logger { } + + companion object { + const val IMAGE_PATH = "https://pokit-storage.s3.ap-northeast-2.amazonaws.com/logo/pokit.png" // 앱 로고 + const val title = "잊지 말고 링크를 확인하세요!" + const val body = "저장하신 링크가 기다리고 있어요.\n잊지 말고 링크를 확인하세요!" + } + + override fun send(tokens: List) { + val notification = Notification.builder() + .setTitle(title) + .setBody(body) + .setImage(IMAGE_PATH) + .build() + val messages = tokens.map { + Message.builder() + .setNotification(notification) + .setToken(it) + .build() + } + + try { + messages.forEach { + FirebaseMessaging.getInstance().sendAsync(it) + } + } catch (e: FirebaseMessagingException) { + logger.warn { "Failed To Send Message : ${e.message}" } + } + } +} diff --git a/application/src/main/kotlin/com/pokit/alert/port/out/AlertSender.kt b/application/src/main/kotlin/com/pokit/alert/port/out/AlertSender.kt new file mode 100644 index 00000000..63b87f9f --- /dev/null +++ b/application/src/main/kotlin/com/pokit/alert/port/out/AlertSender.kt @@ -0,0 +1,7 @@ +package com.pokit.alert.port.out + +import com.pokit.alert.model.AlertBatch + +interface AlertSender { + fun send(tokens: List) +} diff --git a/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt b/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt index 3c133047..07b28b47 100644 --- a/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt +++ b/application/src/test/kotlin/com/pokit/content/port/service/ContentServiceTest.kt @@ -84,13 +84,17 @@ class ContentServiceTest : BehaviorSpec({ categoryPort.loadByIdAndUserId(invalidCommand.categoryId, user.id) } returns null + every { + bookmarkPort.isBookmarked(content.id, user.id) + } returns true + When("저장 요청이 들어오면") { val content = contentService.create(user, command) Then("저장 후 저장 된 컨텐츠를 반환한다.") { content.data shouldBe command.data content.title shouldBe command.title content.memo shouldBe command.memo - content.categoryId shouldBe command.categoryId + content.category.categoryId shouldBe command.categoryId content.alertYn shouldBe command.alertYn } } @@ -108,7 +112,7 @@ class ContentServiceTest : BehaviorSpec({ modifiedContent.data shouldBe command.data modifiedContent.title shouldBe command.title modifiedContent.memo shouldBe command.memo - modifiedContent.categoryId shouldBe command.categoryId + modifiedContent.category.categoryId shouldBe command.categoryId modifiedContent.alertYn shouldBe command.alertYn } } diff --git a/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt b/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt index 05a2c920..6e5f506b 100644 --- a/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt +++ b/application/src/test/kotlin/com/pokit/user/port/service/UserServiceTest.kt @@ -1,6 +1,7 @@ package com.pokit.user.port.service import com.pokit.category.CategoryFixture +import com.pokit.category.model.Category import com.pokit.category.model.CategoryImage import com.pokit.category.port.out.CategoryImagePort import com.pokit.category.port.out.CategoryPort @@ -33,6 +34,7 @@ class UserServiceTest : BehaviorSpec({ every { userPort.persist(any(User::class)) } returns modifieUser every { categoryImagePort.loadById(1) } returns image every { categoryPort.persist(unCategorized) } returns unCategorized + every { categoryPort.persist(any(Category::class)) } returns unCategorized When("수정하려는 정보를 받으면") { val response = userService.signUp(user, request)