Files
gen1recomp/tests/engine/discord_join_requested.lua
T
2026-08-28 10:14:44 -04:00

150 lines
4.5 KiB
Lua

-- Unit coverage for event:discord.join_requested (DiscordPresence Ask-to-Join).
-- Mods subscribe through Runtime; the engine emits before it hands the code
-- to the launcher's online client.
package.path = "./?.lua;./?/init.lua;" .. package.path
local T = require("tests.modkit")
local Runtime = require("src.mods.Runtime")
local Events = require("src.mods.Events")
local DiscordPresence = require("src.core.DiscordPresence")
local joined = {}
local savedClient = package.loaded["src.online.Client"]
package.loaded["src.online.Client"] = {
joinRoom = function(code, as)
joined[#joined + 1] = { code = code, as = as }
end,
}
local function freshGame(withLauncher)
local items = {}
local game = {
returned = nil,
stack = {
items = items,
top = function(self) return self.items[#self.items] end,
push = function(self, screen) self.items[#self.items + 1] = screen end,
},
}
if withLauncher ~= false then
game.returnToLauncher = function(opts) game.returned = opts end
end
return game
end
local bus = Events.new()
local savedEvents, savedHooks = Runtime.events, Runtime.hooks
Runtime.events = bus
local function listen()
local seen = {}
bus:on("discord.join_requested", function(ev)
seen[#seen + 1] = ev
end, 0, "discord_join_test")
return seen
end
do
local game = freshGame()
local st = DiscordPresence._state
st.game = game
st.activity = "exploring"
local seen = listen()
joined = {}
DiscordPresence.handleJoinRequest("m:HOST01")
T.eq(#seen, 1, "match join emits discord.join_requested")
T.eq(seen[1].code, "HOST01", "payload carries the match code")
T.eq(seen[1].kind, "m", "payload carries kind tag m")
T.eq(game.returned and game.returned.tab, "online",
"a running game returns to the launcher's online tab")
T.eq(game.returned and game.returned.joinCode, "HOST01",
"the launcher is handed the code")
T.eq(#joined, 1, "the online client is asked to join the room")
T.eq(joined[1].code, "HOST01", "...with the code")
T.eq(joined[1].as, "player", "...as a player")
T.eq(game.stack:top(), nil, "no in-game link screen is pushed any more")
bus:removeOwner("discord_join_test")
end
do
local st = DiscordPresence._state
st.game = nil -- the launcher, with no game booted
st.activity = "menu"
local seen = listen()
joined = {}
DiscordPresence.handleJoinRequest("t:TOUR99")
T.eq(#seen, 1, "a tournament secret still emits discord.join_requested")
T.eq(seen[1].kind, "t", "payload carries kind tag t")
T.eq(joined[1] and joined[1].code, "TOUR99", "it joins that room code")
bus:removeOwner("discord_join_test")
end
do
local game = freshGame()
local st = DiscordPresence._state
st.game = game
st.activity = "exploring"
local seen = listen()
joined = {}
DiscordPresence.handleJoinRequest("PLAIN42")
T.eq(#seen, 1, "plain secret still emits discord.join_requested")
T.eq(seen[1].kind, "m", "plain secret defaults to match kind")
T.eq(seen[1].code, "PLAIN42", "plain secret is the whole code")
T.eq(joined[1] and joined[1].code, "PLAIN42", "and it joins that room")
bus:removeOwner("discord_join_test")
end
do
local game = freshGame(false) -- a build with no returnToLauncher
local st = DiscordPresence._state
st.game = game
st.activity = "exploring"
local seen = listen()
joined = {}
DiscordPresence.handleJoinRequest("m:NOWAY")
T.eq(#seen, 1, "the event still fires so a mod can act on it")
T.eq(#joined, 0, "a game that cannot reach the launcher joins nothing")
bus:removeOwner("discord_join_test")
end
do
local game = freshGame()
local st = DiscordPresence._state
st.game = game
st.activity = "battle"
local seen = listen()
joined = {}
DiscordPresence.handleJoinRequest("m:NOPE")
T.eq(#seen, 0, "battle activity suppresses join dispatch")
T.eq(#joined, 0, "battle activity joins no room")
bus:removeOwner("discord_join_test")
end
do
local game = freshGame()
game.stack:push({ stage = true, net = {} }) -- already in a link session
local st = DiscordPresence._state
st.game = game
st.activity = "exploring"
local seen = listen()
joined = {}
DiscordPresence.handleJoinRequest("m:NOPE")
T.eq(#seen, 0, "active link session suppresses join dispatch")
T.eq(#joined, 0, "active link session joins no room")
T.eq(#game.stack.items, 1, "active link session is not replaced")
bus:removeOwner("discord_join_test")
end
DiscordPresence._state.game = nil
DiscordPresence._state.activity = "menu"
Runtime.events, Runtime.hooks = savedEvents, savedHooks
package.loaded["src.online.Client"] = savedClient
T.finish("discord_join_requested")