From 5be27325a98e8108ebdde61673e3493c68b5f1b6 Mon Sep 17 00:00:00 2001 From: Pierre Brisorgueil Date: Tue, 4 Aug 2026 17:22:02 +0200 Subject: [PATCH] fix(public): make slug-collision precedence fixture self-contained The "slug-collision precedence" describe block built its fixture input as `[...originalGuides, appGuidePath, reverseGuideRelPath]`, spreading the real on-disk guide list. That implicitly assumed at most one real guide per slug (the framework's own modules/home/). A consumer shipping a second real guide at the same slug from its own module lands at the same precedence tier as the fixture and silently wins the same-tier tiebreak, defeating the test. The block now fully controls its own input: the two framework sample guides these fixtures collide against are listed explicitly by their known real path instead of spread from originalGuides. Closes #4012 --- .../tests/public.docs.integration.tests.js | 22 ++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/modules/public/tests/public.docs.integration.tests.js b/modules/public/tests/public.docs.integration.tests.js index 88102ce61..9965e4913 100644 --- a/modules/public/tests/public.docs.integration.tests.js +++ b/modules/public/tests/public.docs.integration.tests.js @@ -171,7 +171,27 @@ describe('Public docs integration tests — slug-collision precedence:', () => { fs.writeFileSync(reverseFixtureAbsPath, '# App Quickstart\n\nApplication-level quickstart guide.\n'); reverseGuideRelPath = path.relative(process.cwd(), reverseFixtureAbsPath); - config.files.guides = [...originalGuides, appGuidePath, reverseGuideRelPath]; + // The block fully controls its own input — no `...originalGuides` spread. + // Spreading the real on-disk `config.files.guides` implicitly assumed at + // most one real guide per slug (the framework's own `modules/home/`); a + // downstream consumer shipping a second real guide at the same slug from + // its own (non-core) module lands at the SAME precedence tier as this + // fixture and silently wins the same-tier tiebreak, defeating the test + // (#4012). The two framework sample guides these fixtures collide + // against are listed explicitly instead, by their known real path — both + // cross-tier assertions below need a framework guide actually present + // (as the silently-losing incumbent for "welcome", the explicitly + // overridden incumbent for "quickstart"), so removing the spread can't + // also drop them. + const frameworkWelcomeGuide = 'modules/home/doc/guides/00-welcome.md'; + const frameworkQuickstartGuide = 'modules/home/doc/guides/01-quickstart.md'; + + config.files.guides = [ + frameworkWelcomeGuide, + frameworkQuickstartGuide, + appGuidePath, + reverseGuideRelPath, + ]; }); afterAll(async () => {