snapshot of https://github.com/jitsi/jitsi-meet.git @ fd1749dd28f4138aa80234fc7f311b19aaffa0e7 (2026-09-15)
Some checks failed
Prosody Plugin Tests / test (push) Failing after 10m11s
Close stale issues and PRs / stale (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-15 15:56:32 +05:00
commit 1d2bfcac0c
3159 changed files with 464524 additions and 0 deletions

View File

@@ -0,0 +1,273 @@
-- Unit tests for mod_jibri_session.lua
-- Run with busted from resources/prosody-plugins/:
-- busted spec/lua/
--
-- Stubs every Prosody dependency so no Prosody installation is needed.
-- The module is loaded once; the hooked attachJibriSessionId function is
-- extracted and called directly in each test.
-- cjson is required by the module under test — skip gracefully if absent.
local ok_json, json = pcall(require, 'cjson')
if not ok_json then
describe("mod_jibri_session", function()
it("skipped — lua-cjson not installed", function()
pending("lua-cjson is required: luarocks install lua-cjson")
end)
end)
return
end
-- ---------------------------------------------------------------------------
-- Shared mutable mock state — reset in before_each
-- ---------------------------------------------------------------------------
local mock = {
room_from_jid = nil, -- returned by get_room_from_jid; nil = "not found"
rewrite_jid = nil, -- if set, room_jid_match_rewrite returns this; else identity
last_room_jid = nil, -- records the jid passed to get_room_from_jid
}
local util_stub = {
room_jid_match_rewrite = function(jid)
return mock.rewrite_jid or jid
end,
get_room_from_jid = function(jid)
mock.last_room_jid = jid
return mock.room_from_jid
end,
}
-- Capture the hook function installed by the module at load time.
local hooked_fn = nil
local mod_stub = { host = 'test.example.com' }
function mod_stub:require(name) -- luacheck: ignore 212
if name == 'util' then return util_stub end
return {}
end
function mod_stub:hook(event, fn) -- luacheck: ignore 212
if event == 'pre-iq/full' then hooked_fn = fn end
end
function mod_stub:log() end -- luacheck: ignore 212
_G.module = mod_stub
-- ---------------------------------------------------------------------------
-- Load the module under test
-- ---------------------------------------------------------------------------
local ok_mod, load_err = pcall(dofile, 'mod_jibri_session.lua')
if not ok_mod then
describe("mod_jibri_session", function()
it("skipped — failed to load module", function()
pending(tostring(load_err):match("([^\n]+)") or tostring(load_err))
end)
end)
return
end
assert(hooked_fn, "mod_jibri_session did not hook 'pre-iq/full'")
-- ---------------------------------------------------------------------------
-- Test helpers
-- ---------------------------------------------------------------------------
local JIBRI_NS = 'http://jitsi.org/protocol/jibri'
local function make_jibri_elem(attrs)
local e = { name = 'jibri', attr = attrs or {} }
function e:up() return self end
return e
end
local function make_iq(jibri_elem)
local s = { name = 'iq', attr = {} }
function s:get_child(tag, ns)
if tag == 'jibri' and ns == JIBRI_NS then return jibri_elem end
return nil
end
function s:up() return self end
return s
end
local function make_event(stanza, origin)
return { stanza = stanza, origin = origin }
end
local function decoded_app_data(jibri_elem)
return json.decode(jibri_elem.attr.app_data)
end
-- ---------------------------------------------------------------------------
-- Tests
-- ---------------------------------------------------------------------------
describe("mod_jibri_session", function()
before_each(function()
mock.room_from_jid = nil
mock.rewrite_jid = nil
mock.last_room_jid = nil
end)
-- -----------------------------------------------------------------------
describe("non-matching stanzas pass through unchanged", function()
it("ignores a non-IQ stanza", function()
local s = { name = 'message', attr = {} }
function s:get_child() return nil end
assert.has_no.errors(function() hooked_fn(make_event(s)) end)
end)
it("ignores an IQ with no jibri child", function()
local s = { name = 'iq', attr = {} }
function s:get_child() return nil end
assert.has_no.errors(function() hooked_fn(make_event(s)) end)
end)
it("ignores a jibri IQ with action 'stop'", function()
local jibri = make_jibri_elem({ action = 'stop' })
hooked_fn(make_event(make_iq(jibri)))
assert.is_nil(jibri.attr.app_data)
end)
it("ignores a jibri IQ with no action attribute", function()
local jibri = make_jibri_elem({})
hooked_fn(make_event(make_iq(jibri)))
assert.is_nil(jibri.attr.app_data)
end)
end)
-- -----------------------------------------------------------------------
-- Client → jicofo pass: no `room` attribute on the jibri element.
-- The module reads initiator identity from the XMPP session (event.origin).
-- -----------------------------------------------------------------------
describe("client-to-jicofo pass (no room attr on jibri element)", function()
it("sets initiator.id from jitsi_meet_context_user.id", function()
local jibri = make_jibri_elem({ action = 'start' })
local session = { jitsi_meet_context_user = { id = 'user-abc' } }
hooked_fn(make_event(make_iq(jibri), session))
assert.equal('user-abc', decoded_app_data(jibri).file_recording_metadata.initiator.id)
end)
it("falls back to granted_jitsi_meet_context_user_id when context_user is nil", function()
local jibri = make_jibri_elem({ action = 'start' })
local session = { granted_jitsi_meet_context_user_id = 'granted-id-xyz' }
hooked_fn(make_event(make_iq(jibri), session))
assert.equal('granted-id-xyz', decoded_app_data(jibri).file_recording_metadata.initiator.id)
end)
it("sets initiator.group from jitsi_meet_context_group", function()
local jibri = make_jibri_elem({ action = 'start' })
local session = {
jitsi_meet_context_user = { id = 'user-1' },
jitsi_meet_context_group = 'group-A',
}
hooked_fn(make_event(make_iq(jibri), session))
assert.equal('group-A', decoded_app_data(jibri).file_recording_metadata.initiator.group)
end)
it("falls back to granted_jitsi_meet_context_group_id when context_group is nil", function()
local jibri = make_jibri_elem({ action = 'start' })
local session = {
jitsi_meet_context_user = { id = 'user-1' },
granted_jitsi_meet_context_group_id = 'granted-group-B',
}
hooked_fn(make_event(make_iq(jibri), session))
assert.equal('granted-group-B', decoded_app_data(jibri).file_recording_metadata.initiator.group)
end)
it("does not modify app_data when origin (session) is nil", function()
local jibri = make_jibri_elem({ action = 'start' })
hooked_fn(make_event(make_iq(jibri), nil))
assert.is_nil(jibri.attr.app_data)
end)
it("preserves pre-existing top-level app_data keys", function()
local existing = json.encode({ custom_key = 'custom_value' })
local jibri = make_jibri_elem({ action = 'start', app_data = existing })
local session = { jitsi_meet_context_user = { id = 'user-1' } }
hooked_fn(make_event(make_iq(jibri), session))
local data = decoded_app_data(jibri)
assert.equal('custom_value', data.custom_key)
assert.equal('user-1', data.file_recording_metadata.initiator.id)
end)
it("preserves pre-existing file_recording_metadata fields", function()
local existing = json.encode({
file_recording_metadata = { existing_field = 'existing_value' }
})
local jibri = make_jibri_elem({ action = 'start', app_data = existing })
local session = { jitsi_meet_context_user = { id = 'user-1' } }
hooked_fn(make_event(make_iq(jibri), session))
local data = decoded_app_data(jibri)
assert.equal('existing_value', data.file_recording_metadata.existing_field)
assert.equal('user-1', data.file_recording_metadata.initiator.id)
end)
end)
-- -----------------------------------------------------------------------
-- Jicofo → jibri pass: `room` attribute present on the jibri element.
-- The module looks up the room and attaches its meetingId as session_id.
-- -----------------------------------------------------------------------
describe("jicofo-to-jibri pass (room attr present on jibri element)", function()
it("sets conference_details.session_id from room meetingId", function()
mock.room_from_jid = { _data = { meetingId = 'meeting-123' } }
local jibri = make_jibri_elem({ action = 'start', room = 'room@conference.example.com' })
hooked_fn(make_event(make_iq(jibri)))
assert.equal('meeting-123',
decoded_app_data(jibri).file_recording_metadata.conference_details.session_id)
end)
it("does not modify app_data when room is not found", function()
mock.room_from_jid = nil
local jibri = make_jibri_elem({ action = 'start', room = 'missing@conference.example.com' })
hooked_fn(make_event(make_iq(jibri)))
assert.is_nil(jibri.attr.app_data)
end)
it("preserves pre-existing top-level app_data keys", function()
mock.room_from_jid = { _data = { meetingId = 'meeting-456' } }
local existing = json.encode({ custom_key = 'custom_value' })
local jibri = make_jibri_elem({
action = 'start',
room = 'room@conference.example.com',
app_data = existing,
})
hooked_fn(make_event(make_iq(jibri)))
local data = decoded_app_data(jibri)
assert.equal('custom_value', data.custom_key)
assert.equal('meeting-456', data.file_recording_metadata.conference_details.session_id)
end)
it("passes the room JID through room_jid_match_rewrite before lookup", function()
mock.rewrite_jid = 'rewritten@conference.example.com'
mock.room_from_jid = { _data = { meetingId = 'meeting-789' } }
local jibri = make_jibri_elem({
action = 'start',
room = 'original@conference.sub.example.com',
})
hooked_fn(make_event(make_iq(jibri)))
assert.equal('rewritten@conference.example.com', mock.last_room_jid)
end)
end)
-- -----------------------------------------------------------------------
describe("malformed app_data", function()
it("silently ignores invalid JSON in app_data (cjson.safe: returns nil, no throw)", function()
local raw = '{not valid json{{'
local jibri = make_jibri_elem({ action = 'start', app_data = raw })
local session = { jitsi_meet_context_user = { id = 'user-1' } }
assert.has_no.errors(function() hooked_fn(make_event(make_iq(jibri), session)) end)
assert.equal(raw, jibri.attr.app_data) -- unchanged: module returned early
end)
end)
end) -- mod_jibri_session