@@ -253,6 +253,88 @@ def test_with_custom_nick(eggdrop_config, eggdrop_proc, mock_ircd, tcl_bridge):
253253If you don't call ` render() ` , the ` eggdrop_proc ` fixture renders with
254254defaults from ` EggdropConfig.context() ` .
255255
256+ ` render() ` only takes effect * before* the proc fixture evaluates. If your
257+ test parameter list pulls in ` eggdrop_proc ` directly, the proc has already
258+ spawned by the time the test body runs. To customise after the dataclass
259+ exists but before the bot starts, take ` eggdrop_config ` + `request:
260+ pytest.FixtureRequest`, render, then lazy-load the rest:
261+
262+ ``` python
263+ def test_loads_my_userfile (eggdrop_config , request : pytest.FixtureRequest):
264+ eggdrop_config.render(... )
265+ eggdrop_config.userfile_path.write_text(... ) # tweak files post-render
266+ proc = request.getfixturevalue(" eggdrop_proc" )
267+ bridge = request.getfixturevalue(" tcl_bridge" )
268+ ```
269+
270+ ### Pre-populating the userfile
271+
272+ Two template variables (rendered by ` templates/userfile.j2 ` ) inject
273+ already-formatted ban-record lines into the userfile that's written
274+ before the bot starts:
275+
276+ - ` userfile_ban_lines ` — list of strings, written under ` *ban - - ` .
277+ - ` userfile_chan_ban_lines ` — dict of ` chan-name → list of strings ` ,
278+ each list written under ` ::<chan-name> bans ` . The channel must be
279+ configured before the userfile is read; the default eggdrop.conf
280+ ` channels ` list handles this for ` #test ` automatically (see
281+ ` chanprog.c:452 ` for the order: conf load → HOOK_REHASH →
282+ ` readuserfile ` ).
283+
284+ Build the strings with ` support.userfile_helpers.format_userfile_ban ` ,
285+ which takes every field as a required keyword argument (` mask ` , ` perm ` ,
286+ ` sticky ` , ` expire ` , ` added ` , ` lastactive ` , ` creator ` , ` desc ` ) and
287+ hex-escapes ` : ` / ` \\ ` in the mask per ` src/misc.c:str_escape ` . The
288+ template itself is a flat iteration; all formatting lives in Python.
289+
290+ ``` python
291+ from support.userfile_helpers import format_userfile_ban
292+
293+ eggdrop_config.render(
294+ userfile_ban_lines = [
295+ format_userfile_ban(
296+ mask = " a:storedacct" , perm = True , sticky = False , expire = 0 ,
297+ added = 1700000000 , lastactive = 0 , creator = " owner" ,
298+ desc = " from disk" ,
299+ ),
300+ ],
301+ userfile_chan_ban_lines = {
302+ " #test" : [
303+ format_userfile_ban(
304+ mask = " ~a:chanonlyacct" , perm = True , sticky = False , expire = 0 ,
305+ added = 1700000000 , lastactive = 0 , creator = " owner" ,
306+ desc = " per-chan" ,
307+ ),
308+ ],
309+ },
310+ )
311+ ```
312+
313+ The chanfile is rendered from ` templates/chanfile.j2 ` . Pass
314+ ` chanfile_channels=[{"name": "#chan", "options": "..."}] ` if you need
315+ to register channels at chanfile-load time (rather than via
316+ ` channels ` in the conf). Default is empty — most tests use the
317+ conf-level ` channel add ` instead.
318+
319+ ### Selecting which modules to load
320+
321+ The ` modules ` template variable controls the ` loadmodule ` lines and gates
322+ the server-related conf block (` set net-type ` , ` server add ` , `set
323+ msg-rate` , ...) on whether ` server` is in the list. Default is the full
324+ chain needed for IRC behaviour: `[ "pbkdf2", "channels", "server", "ctcp",
325+ "irc", "console", "notes"] `.
326+
327+ Override to test channels-mod-only scenarios (e.g. behaviour when
328+ server.mod is absent — irc.mod and ctcp.mod will fail to load alongside
329+ since they ` module_depend ` on server):
330+
331+ ``` python
332+ eggdrop_config.render(modules = [" pbkdf2" , " channels" , " console" , " notes" ])
333+ ```
334+
335+ ` extra_modules ` still appends in addition to ` modules ` , so it's the right
336+ knob for opting into share/transfer/etc. without changing the base list.
337+
256338## Layout
257339
258340```
0 commit comments