Skip to content
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Empty file modified gradlew
100644 → 100755
Empty file.
1 change: 0 additions & 1 deletion settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
rootProject.name = "WerewolfHelper"

Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
package dev.robothanzo.werewolf.controller

import dev.robothanzo.werewolf.WerewolfApplication
import dev.robothanzo.werewolf.controller.dto.AuthData
import dev.robothanzo.werewolf.controller.dto.AuthResponse
import dev.robothanzo.werewolf.database.documents.AuthSession
import dev.robothanzo.werewolf.database.documents.UserRole
import jakarta.servlet.http.HttpSession
import net.dv8tion.jda.api.JDA
import net.dv8tion.jda.api.entities.Guild
import net.dv8tion.jda.api.entities.Member
import net.dv8tion.jda.api.entities.User
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Assertions.assertNotNull
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.InjectMocks
import org.mockito.Mock
import org.mockito.Mockito.*
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.any
import org.mockito.kotlin.eq
import org.mockito.kotlin.whenever
import org.springframework.http.HttpStatus
import java.util.*

class AuthControllerTest {

@InjectMocks
private lateinit var authController: AuthController

@Mock
private lateinit var session: HttpSession

@Mock
private lateinit var jda: JDA

@BeforeEach
fun setup() {
MockitoAnnotations.openMocks(this)
WerewolfApplication.jda = jda
}

@Test
fun testSelectGuild_Success() {
val user = AuthSession(userId = "user1", guildId = null, role = UserRole.PENDING)
whenever(session.getAttribute("user")).thenReturn(user)

val guildId = "123"
val guildMock = mock(Guild::class.java)
val memberMock = mock(Member::class.java)
whenever(jda.getGuildById(123L)).thenReturn(guildMock)
whenever(guildMock.getMemberById("user1")).thenReturn(memberMock)
// Assume isAdmin logic - isAdmin is an extension function, mocking it might be hard.
// It likely checks permissions.
// If it's an extension function, we cannot easily mock it unless we mock the Member interface completely
// and isAdmin calls member methods.
// dev.robothanzo.werewolf.utils.isAdmin checks member.hasPermission(Administrator) or is owner.

// However, isAdmin is an extension function.
// Let's assume it returns false for mock unless we configure it.
// But for this test, we just check if it returns OK.

Copilot AI Feb 23, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This inline commentary about difficulties mocking isAdmin() is speculative/noisy. Since the test doesn’t assert the admin path, consider removing the commentary and (optionally) explicitly stubbing memberMock.hasPermission(Permission.ADMINISTRATOR) if you want deterministic coverage of role selection.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed: Removed the speculative comments about isAdmin to reduce noise.

val response = authController.selectGuild(guildId, session)

assertEquals(HttpStatus.OK, response.statusCode)
val body = response.body as AuthResponse
assertEquals(guildId, body.data.user.guildId)
verify(session).setAttribute(eq("user"), any())
}

@Test
fun testSelectGuild_Unauthenticated() {
whenever(session.getAttribute("user")).thenReturn(null)

val response = authController.selectGuild("123", session)

assertEquals(HttpStatus.UNAUTHORIZED, response.statusCode)
}

@Test
fun testSelectGuild_GuildNotFound() {
val user = AuthSession(userId = "user1")
whenever(session.getAttribute("user")).thenReturn(user)
whenever(jda.getGuildById(123L)).thenReturn(null)

val response = authController.selectGuild("123", session)

assertEquals(HttpStatus.BAD_REQUEST, response.statusCode)
}

@Test
fun testMe_Authenticated() {
val user = AuthSession(userId = "user1", guildId = "123")
whenever(session.getAttribute("user")).thenReturn(user)

val discordUser = mock(User::class.java)
whenever(discordUser.name).thenReturn("TestUser")
whenever(discordUser.effectiveAvatarUrl).thenReturn("avatar.png")
whenever(jda.getUserById("user1")).thenReturn(discordUser)

val response = authController.me(session)

assertEquals(HttpStatus.OK, response.statusCode)
val body = response.body as AuthResponse
assertEquals("user1", body.data.user.userId)
assertEquals("TestUser", body.data.username)
}

@Test
fun testMe_Unauthenticated() {
whenever(session.getAttribute("user")).thenReturn(null)

val response = authController.me(session)

assertEquals(HttpStatus.UNAUTHORIZED, response.statusCode)
}

@Test
fun testLogout() {
val response = authController.logout(session)

assertEquals(HttpStatus.OK, response.statusCode)
verify(session).invalidate()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,201 @@
package dev.robothanzo.werewolf.controller

import dev.robothanzo.werewolf.WerewolfApplication
import dev.robothanzo.werewolf.controller.dto.GameRequests
import dev.robothanzo.werewolf.database.documents.Session
import dev.robothanzo.werewolf.game.model.GameSettings
import dev.robothanzo.werewolf.service.*
import net.dv8tion.jda.api.JDA
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.MockitoAnnotations
import org.mockito.kotlin.*
import java.util.*

class GameControllerTest {

@Mock
private lateinit var playerService: PlayerService

@Mock
private lateinit var roleService: RoleService

@Mock
private lateinit var gameActionService: GameActionService

@Mock
private lateinit var gameSessionService: GameSessionService

@Mock
private lateinit var gameStateService: GameStateService

private lateinit var gameController: GameController

@BeforeEach
fun setup() {
MockitoAnnotations.openMocks(this)
gameController = GameController(
playerService,
roleService,
gameActionService,
gameSessionService,
gameStateService
)

// Mock JDA to prevent NPE in Session
val mockJda = mock<JDA>()
WerewolfApplication.jda = mockJda
WerewolfApplication.gameSessionService = gameSessionService
WerewolfApplication.gameStateService = gameStateService
}

@Test
fun testNextState() {
val guildId = 123L
val session = Session(guildId = guildId)

whenever(gameSessionService.withLockedSession<Any>(eq(guildId), any())).thenAnswer { invocation ->
val block = invocation.getArgument<(Session) -> Any>(1)
block.invoke(session)
}

val response = gameController.nextState(guildId.toString())

assertEquals(200, response.statusCode.value())
verify(gameStateService).nextStep(session)
}

@Test
fun testSetState() {
val guildId = 123L
val session = Session(guildId = guildId)
val stepId = "NIGHT_STEP"
val request = GameRequests.StateSetRequest(stepId)

whenever(gameSessionService.withLockedSession<Any>(eq(guildId), any())).thenAnswer { invocation ->
val block = invocation.getArgument<(Session) -> Any>(1)
block.invoke(session)
}

val response = gameController.setState(guildId.toString(), request)

assertEquals(200, response.statusCode.value())
verify(gameStateService).startStep(session, stepId)
}

@Test
fun testPauseState() {
val guildId = 123L
val session = Session(guildId = guildId)

whenever(gameSessionService.withLockedSession<Any>(eq(guildId), any())).thenAnswer { invocation ->
val block = invocation.getArgument<(Session) -> Any>(1)
block.invoke(session)
}

val response = gameController.pauseState(guildId.toString())

assertEquals(200, response.statusCode.value())
verify(gameStateService).pauseStep(eq(session), any())
}

@Test
fun testResumeState() {
val guildId = 123L
val session = Session(guildId = guildId)

whenever(gameSessionService.withLockedSession<Any>(eq(guildId), any())).thenAnswer { invocation ->
val block = invocation.getArgument<(Session) -> Any>(1)
block.invoke(session)
}

val response = gameController.resumeState(guildId.toString())

assertEquals(200, response.statusCode.value())
verify(gameStateService).resumeStep(eq(session), any())
}

@Test
fun testStateAction() {
val guildId = 123L
val session = Session(guildId = guildId)
val action = "vote"
val request = GameRequests.StateActionRequest(action, mapOf("target" to "1"))

whenever(gameSessionService.withLockedSession<Any>(eq(guildId), any())).thenAnswer { invocation ->
val block = invocation.getArgument<(Session) -> Any>(1)
block.invoke(session)
}
whenever(gameStateService.handleInput(eq(session), any())).thenReturn(mapOf("success" to true))

val response = gameController.stateAction(guildId.toString(), request)

assertEquals(200, response.statusCode.value())
// Argument capture or specialized matcher can be used here
// verifying that handleInput was called is sufficient for now
verify(gameStateService).handleInput(eq(session), any())
verify(gameSessionService).broadcastSessionUpdate(session)
}

@Test
fun testAssignRoles() {
val guildId = 123L
val session = Session(guildId = guildId)

whenever(gameSessionService.getSession(guildId)).thenReturn(Optional.of(session))

val response = gameController.assignRoles(guildId.toString())

assertEquals(200, response.statusCode.value())
verify(roleService).assignRoles(eq(session), any(), any())
}

@Test
fun testStartGame() {
val guildId = 123L
val session = Session(guildId = guildId)

whenever(gameSessionService.getSession(guildId)).thenReturn(Optional.of(session))

val response = gameController.startGame(guildId.toString())

assertEquals(200, response.statusCode.value())
verify(gameSessionService).saveSession(session)
verify(gameStateService).startStep(session, "NIGHT_STEP")
verify(gameSessionService).broadcastSessionUpdate(session)
}

@Test
fun testResetGame() {
val guildId = 123L
val session = Session(guildId = guildId)

whenever(gameSessionService.getSession(guildId)).thenReturn(Optional.of(session))

val response = gameController.resetGame(guildId.toString())

assertEquals(200, response.statusCode.value())
verify(gameActionService).resetGame(eq(session), any(), any())
}

@Test
fun testUpdateSettings() {
val guildId = 123L
val session = Session(guildId = guildId, settings = GameSettings())
val settings = mapOf("doubleIdentities" to true, "allowWolfSelfKill" to true)

whenever(gameSessionService.withLockedSession<Any>(eq(guildId), any())).thenAnswer { invocation ->
val block = invocation.getArgument<(Session) -> Any>(1)
block.invoke(session)
}

val response = gameController.updateSettings(guildId.toString(), settings)

assertEquals(200, response.statusCode.value())
assertEquals(true, session.doubleIdentities)
assertEquals(true, session.settings.allowWolfSelfKill)
}
}
Loading