2323import org .junit .jupiter .api .Test ;
2424
2525import io .jooby .Context ;
26+ import io .jooby .Jooby ;
2627import io .jooby .ModelAndView ;
2728import io .jooby .Router ;
2829import io .jooby .TemplateEngine ;
@@ -35,13 +36,29 @@ class HtmxTemplateEngineTest {
3536 private HtmxTemplateEngine engine ;
3637 private Context ctx ;
3738 private Router router ;
39+ private Jooby app ;
3840
3941 @ BeforeEach
4042 void setUp () {
4143 engine = new HtmxTemplateEngine ();
4244 ctx = mock (Context .class );
4345 router = mock (Router .class );
46+ app = mock (Jooby .class );
47+
4448 when (ctx .getRouter ()).thenReturn (router );
49+ when (app .getRouter ()).thenReturn (router );
50+ }
51+
52+ // --- Lifecycle / Init Tests ---
53+
54+ @ Test
55+ void shouldThrowIllegalStateExceptionWhenNoOtherTemplateEnginesRegistered () {
56+ // Router only has the HtmxTemplateEngine registered, no underlying engines like Handlebars
57+ when (router .getTemplateEngines ()).thenReturn (List .of (engine ));
58+
59+ IllegalStateException ex = assertThrows (IllegalStateException .class , () -> engine .init (app ));
60+
61+ assertEquals ("No template engines registered" , ex .getMessage ());
4562 }
4663
4764 // --- Supports Tests ---
@@ -68,12 +85,17 @@ void shouldReturnNullForStandardModelAndView() throws Exception {
6885
6986 @ Test
7087 void shouldThrowIllegalStateExceptionWhenNoTemplateEngineFound () {
88+ // 1. Setup incompatible engine and initialize the HtmxTemplateEngine
89+ TemplateEngine incompatibleEngine = mock (TemplateEngine .class );
90+ when (router .getTemplateEngines ()).thenReturn (Arrays .asList (engine , incompatibleEngine ));
91+ engine .init (app ); // Cache the engines
92+
93+ // 2. Setup the HTMX view
7194 HtmxModelAndView <?> htmxView = mock (HtmxModelAndView .class );
7295 when (htmxView .getView ()).thenReturn ("missing.hbs" );
96+ when (incompatibleEngine .supports (htmxView )).thenReturn (false );
7397
74- // Router has no other engines registered
75- when (router .getTemplateEngines ()).thenReturn (List .of (engine ));
76-
98+ // 3. Execute and verify
7799 IllegalStateException ex =
78100 assertThrows (IllegalStateException .class , () -> engine .render (ctx , htmxView ));
79101
@@ -90,17 +112,18 @@ void shouldRenderMultipleTemplatesIntoCompositeOutput() throws Exception {
90112
91113 when (htmxView .iterator ()).thenReturn (views .iterator ());
92114
93- // 2. Mock a delegate Template Engine (e.g., Handlebars)
115+ // 2. Mock Delegate Engines
94116 TemplateEngine delegateEngine = mock (TemplateEngine .class );
95117 when (delegateEngine .supports (htmxView )).thenReturn (true );
96118
97- // Mock an incompatible engine to cover the "continue" branch inside resolveTemplateEngine
98119 TemplateEngine incompatibleEngine = mock (TemplateEngine .class );
99120 when (incompatibleEngine .supports (htmxView )).thenReturn (false );
100121
101- // Register engines. We include `engine` (this) to ensure the `!= this` branch is hit.
122+ // Register and initialize engines (HtmxTemplateEngine should remove itself from the cached
123+ // list)
102124 when (router .getTemplateEngines ())
103125 .thenReturn (Arrays .asList (engine , incompatibleEngine , delegateEngine ));
126+ engine .init (app );
104127
105128 // 3. Mock the Output Pipeline
106129 OutputFactory outputFactory = mock (OutputFactory .class );
0 commit comments