Skip to content

Commit

Permalink
template-engine: must initialize flash attributes only when there is …
Browse files Browse the repository at this point in the history
…one flash cookie

- fix #3607
  • Loading branch information
jknack committed Jan 5, 2025
1 parent d6222a0 commit 033c502
Show file tree
Hide file tree
Showing 6 changed files with 107 additions and 1 deletion.
7 changes: 7 additions & 0 deletions jooby/src/main/java/io/jooby/Context.java
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,13 @@ public interface Context extends Registry {
*/
@NonNull FlashMap flash();

/**
* Flash map or null when no flash cookie exists.
*
* @return Flash map or null when no flash cookie exists.
*/
@Nullable FlashMap flashOrNull();

/**
* Get a flash attribute.
*
Expand Down
6 changes: 6 additions & 0 deletions jooby/src/main/java/io/jooby/DefaultContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,12 @@ default boolean matches(String pattern) {
FlashMap.NAME, key -> FlashMap.create(this, getRouter().getFlashCookie().clone()));
}

@Nullable @Override
default FlashMap flashOrNull() {
var flashCookie = cookie(getRouter().getFlashCookie().getName());
return flashCookie.isMissing() ? null : flash();
}

/**
* Get a flash attribute.
*
Expand Down
5 changes: 5 additions & 0 deletions jooby/src/main/java/io/jooby/ForwardingContext.java
Original file line number Diff line number Diff line change
Expand Up @@ -673,6 +673,11 @@ public FlashMap flash() {
return ctx.flash();
}

@Nullable @Override
public FlashMap flashOrNull() {
return ctx.flashOrNull();
}

@NonNull @Override
public Value flash(@NonNull String name) {
return ctx.flash(name);
Expand Down
2 changes: 1 addition & 1 deletion jooby/src/main/java/io/jooby/TemplateEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ public interface TemplateEngine extends MessageEncoder {
@Override
default DataBuffer encode(@NonNull Context ctx, @NonNull Object value) throws Exception {
// initialize flash and session attributes (if any)
ctx.flash();
ctx.flashOrNull();
ctx.sessionOrNull();

ctx.setDefaultResponseType(MediaType.html);
Expand Down
36 changes: 36 additions & 0 deletions jooby/src/test/java/io/jooby/Issue3607.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package io.jooby;

import static org.mockito.Mockito.*;

import org.junit.jupiter.api.Test;

import io.jooby.buffer.DataBuffer;
import io.jooby.buffer.DefaultDataBufferFactory;

public class Issue3607 {

private static class TemplateEngineImpl implements TemplateEngine {
@Override
public DataBuffer render(Context ctx, ModelAndView<?> modelAndView) throws Exception {
// do nothing
return DefaultDataBufferFactory.sharedInstance.wrap(new byte[0]);
}
}

@Test
public void shouldNotGenerateEmptyFlashMap() throws Exception {
var ctx = mock(Context.class);

var templateEngine = new TemplateEngineImpl();
templateEngine.encode(ctx, ModelAndView.map("index.html"));

verify(ctx, times(1)).flashOrNull();
verify(ctx, times(1)).sessionOrNull();
verify(ctx, times(1)).setDefaultResponseType(MediaType.html);
}
}
52 changes: 52 additions & 0 deletions tests/src/test/java/io/jooby/i3607/Issue3607.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Jooby https://jooby.io
* Apache License Version 2.0 https://jooby.io/LICENSE.txt
* Copyright 2014 Edgar Espina
*/
package io.jooby.i3607;

import static org.junit.jupiter.api.Assertions.*;

import java.util.Map;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean;

import io.jooby.FlashMap;
import io.jooby.ModelAndView;
import io.jooby.junit.ServerTest;
import io.jooby.junit.ServerTestRunner;
import io.jooby.pebble.PebbleModule;

public class Issue3607 {
@ServerTest
public void shouldNotGenerateEmptyFlashMap(ServerTestRunner runner) throws InterruptedException {
var latch = new CountDownLatch(1);
var mustBeNull = new AtomicBoolean(false);
runner
.define(
app -> {
app.install(new PebbleModule());
app.use(
next ->
ctx -> {
ctx.onComplete(
done -> {
mustBeNull.set(!done.getAttributes().containsKey(FlashMap.NAME));
latch.countDown();
});
return next.apply(ctx);
});
app.get("/3607", ctx -> ModelAndView.map("index.pebble", Map.of("name", "Pebble")));
})
.ready(
client -> {
client.get(
"/3607",
rsp -> {
assertEquals("Hello Pebble!", rsp.body().string().trim());
});
});
latch.await();
assertTrue(mustBeNull.get(), "Flash map must be null");
}
}

0 comments on commit 033c502

Please sign in to comment.