테스트 통합 환경 설정 추가

This commit is contained in:
2026-05-29 15:58:33 +09:00
parent 00316ba013
commit ebfbf7b597
8 changed files with 182 additions and 25 deletions

View File

@@ -75,11 +75,14 @@ dependencies {
// file mimetype check
implementation("org.apache.tika:tika-core:3.2.0")
developmentOnly("org.springframework.boot:spring-boot-devtools")
runtimeOnly("com.h2database:h2")
runtimeOnly("com.mysql:mysql-connector-j")
testRuntimeOnly("com.h2database:h2")
testImplementation("org.springframework.boot:spring-boot-starter-test")
testImplementation("org.springframework.security:spring-security-test")
testImplementation("com.github.codemonstur:embedded-redis:1.4.3")
developmentOnly("org.springframework.boot:spring-boot-devtools")
}
allOpen {

View File

@@ -14,17 +14,24 @@ import java.io.FileInputStream
@Configuration
class AndroidPublisherConfig(
@Value("\${firebase.secret-key-path}")
private val secretKeyPath: String
private val secretKeyPath: String,
@Value("\${android-publisher.enabled:true}")
private val enabled: Boolean
) {
@Bean
fun androidPublisher(): AndroidPublisher {
val jsonFactory = GsonFactory.getDefaultInstance()
val httpTransport = NetHttpTransport()
val credential = GoogleCredentials.fromStream(FileInputStream(secretKeyPath))
val credential = if (enabled) {
HttpCredentialsAdapter(
GoogleCredentials.fromStream(FileInputStream(secretKeyPath))
.createScoped(listOf(AndroidPublisherScopes.ANDROIDPUBLISHER))
)
} else {
null
}
return AndroidPublisher.Builder(httpTransport, jsonFactory, HttpCredentialsAdapter(credential))
return AndroidPublisher.Builder(httpTransport, jsonFactory, credential)
.setApplicationName("소다라이브")
.build()
}

View File

@@ -4,11 +4,13 @@ import com.google.auth.oauth2.GoogleCredentials
import com.google.firebase.FirebaseApp
import com.google.firebase.FirebaseOptions
import org.springframework.beans.factory.annotation.Value
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty
import org.springframework.context.annotation.Configuration
import java.io.FileInputStream
import javax.annotation.PostConstruct
@Configuration
@ConditionalOnProperty(name = ["firebase.enabled"], havingValue = "true", matchIfMissing = true)
class FirebaseConfig(
@Value("\${firebase.secret-key-path}")
private val secretKeyPath: String

View File

@@ -27,15 +27,17 @@ class RedisConfig(
@Value("\${spring.redis.host}")
private val host: String,
@Value("\${spring.redis.port}")
private val port: Int
private val port: Int,
@Value("\${spring.redis.ssl-enabled:true}")
private val sslEnabled: Boolean
) {
@Bean(destroyMethod = "shutdown")
fun redissonClient(): RedissonClient {
val config = Config()
val scheme = if (sslEnabled) "rediss" else "redis"
config.useSingleServer()
.setAddress("rediss://$host:$port")
.setSslEnableEndpointIdentification(true)
.setSslTruststore(null)
.setAddress("$scheme://$host:$port")
.setSslEnableEndpointIdentification(sslEnabled)
.setDnsMonitoringInterval(30000)
.setConnectionMinimumIdleSize(0)
.setConnectionPoolSize(5)
@@ -44,12 +46,14 @@ class RedisConfig(
@Bean
fun redisConnectionFactory(): RedisConnectionFactory {
val clientConfiguration = LettuceClientConfiguration.builder()
val clientConfigurationBuilder = LettuceClientConfiguration.builder()
if (sslEnabled) {
clientConfigurationBuilder
.useSsl()
.disablePeerVerification()
.build()
}
return LettuceConnectionFactory(RedisStandaloneConfiguration(host, port), clientConfiguration)
return LettuceConnectionFactory(RedisStandaloneConfiguration(host, port), clientConfigurationBuilder.build())
}
@Bean

View File

@@ -0,0 +1,47 @@
package kr.co.vividnext.sodalive.support
import org.springframework.context.ApplicationContextInitializer
import org.springframework.context.ConfigurableApplicationContext
import redis.embedded.RedisServer
class EmbeddedRedisInitializer : ApplicationContextInitializer<ConfigurableApplicationContext> {
override fun initialize(applicationContext: ConfigurableApplicationContext) {
EmbeddedRedisHolder.start()
}
}
private object EmbeddedRedisHolder {
private const val PORT = 16379
private var redisServer: RedisServer? = null
private var shutdownHookRegistered = false
@Synchronized
fun start() {
if (redisServer != null) {
return
}
redisServer = RedisServer.newRedisServer()
.port(PORT)
.setting("bind 127.0.0.1")
.setting("daemonize no")
.setting("appendonly no")
.build()
.also { it.start() }
if (!shutdownHookRegistered) {
Runtime.getRuntime().addShutdownHook(
Thread {
stop()
}
)
shutdownHookRegistered = true
}
}
@Synchronized
fun stop() {
redisServer?.stop()
redisServer = null
}
}

View File

@@ -0,0 +1,31 @@
package kr.co.vividnext.sodalive.support
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.data.redis.core.StringRedisTemplate
import javax.persistence.EntityManager
@SpringBootTest
class SpringBootIntegrationSampleTest {
@Autowired
private lateinit var entityManager: EntityManager
@Autowired
private lateinit var stringRedisTemplate: StringRedisTemplate
@Test
fun shouldUseH2AndRedisInSpringBootIntegrationTest() {
val databaseResult = entityManager
.createNativeQuery("select 1")
.singleResult
val redisKey = "test:integration-sample"
stringRedisTemplate.opsForValue().set(redisKey, "ok")
val redisResult = stringRedisTemplate.opsForValue().get(redisKey)
assertEquals(1, (databaseResult as Number).toInt())
assertEquals("ok", redisResult)
}
}

View File

@@ -0,0 +1,2 @@
org.springframework.context.ApplicationContextInitializer=\
kr.co.vividnext.sodalive.support.EmbeddedRedisInitializer

View File

@@ -1,3 +1,6 @@
server:
env: test
logging:
level:
com:
@@ -5,23 +8,72 @@ logging:
util:
EC2MetadataUtils: error
weraser:
apiUrl: ""
apiKey: ""
payverse:
host: ""
inboundIp: ""
mid: ""
clientKey: ""
secretKey: ""
usdMid: ""
usdClientKey: ""
usdSecretKey: ""
jpyMid: ""
jpyClientKey: ""
jpySecretKey: ""
bootpay:
applicationId: ""
privateKey: ""
hectoApplicationId: ""
hectoPrivateKey: ""
apple:
iapVerifyUrl: https://buy.itunes.apple.com/verifyReceipt
iapVerifySandboxUrl: https://sandbox.itunes.apple.com/verifyReceipt
bundleId: ""
serviceId: ""
line:
channelId: ""
agora:
appId: ${AGORA_APP_ID}
appCertificate: ${AGORA_APP_CERTIFICATE}
appId: ""
appCertificate: ""
firebase:
enabled: false
secretKeyPath: ""
android-publisher:
enabled: false
google:
webClientId: ""
cloud:
naver:
papagoClientId: ""
papagoClientSecret: ""
aws:
credentials:
accessKey: ${APP_AWS_ACCESS_KEY}
secretKey: ${APP_AWS_SECRET_KEY}
accessKey: ""
secretKey: ""
s3:
bucket: ${S3_BUCKET}
contentBucket: ""
bucket: ""
contentCloudFront:
host: ""
privateKeyFilePath: ""
keyPairId: ""
cloudFront:
host: ${CLOUD_FRONT_HOST}
host: ""
sqs:
generateCouponUrl: ""
region:
static: ap-northeast-2
stack:
@@ -29,15 +81,24 @@ cloud:
jwt:
header: Authorization
token-validity-in-seconds: ${JWT_TOKEN_VALIDITY_TIME}
secret: ${JWT_SECRET}
token-validity-in-seconds: ${JWT_TOKEN_VALIDITY_TIME:360000000}
secret: ${JWT_SECRET:abcdefghijklmnopqrstuvwxyz1234567890}
spring:
redis:
host: localhost
port: 6379
port: 16379
ssl-enabled: false
datasource:
driver-class-name: org.h2.Driver
url: jdbc:h2:mem:sodalive-test;MODE=MySQL;DATABASE_TO_UPPER=false;NON_KEYWORDS=VALUE;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
username: sa
password:
jpa:
database: h2
database-platform: kr.co.vividnext.sodalive.support.H2MySqlFunctionDialect
hibernate:
ddl-auto: create-drop
properties: