Skip to content

Commit

Permalink
Merge branch '3.8.x' into 3.9.x
Browse files Browse the repository at this point in the history
  • Loading branch information
sdelamo committed Jul 11, 2023
2 parents d855b28 + f5463f8 commit 0aa0467
Show file tree
Hide file tree
Showing 28 changed files with 284 additions and 24 deletions.
2 changes: 1 addition & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ pluginManagement {
}

plugins {
id("io.micronaut.build.shared.settings") version "5.4.0"
id("io.micronaut.build.shared.settings") version "5.4.10"
}

rootProject.name = 'views-parent'
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package io.micronaut.doc.soy
package io.micronaut.docs.soy

import com.google.template.soy.SoyFileSet
import io.micronaut.context.annotation.Requires
Expand Down Expand Up @@ -45,4 +45,4 @@ class CustomSoyFileSetProvider implements SoyFileSetProvider {
builder.build()
}
}
//end::clazz[]
//end::clazz[]
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,9 @@ import spock.lang.Specification

import jakarta.inject.Inject

@Property(name = "micronaut.security.enabled", value = StringUtils.FALSE)
@Property(name = "spec.name", value = "soy")
@Property(name = "micronaut.views.velocity.enabled", value = StringUtils.FALSE)
@MicronautTest
class SoySpec extends Specification {
@Inject
Expand Down
4 changes: 3 additions & 1 deletion views-core/src/main/java/io/micronaut/views/ViewsFilter.java
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.micronaut.http.filter.ServerFilterChain;
import io.micronaut.http.filter.ServerFilterPhase;
import io.micronaut.views.exceptions.ViewNotFoundException;
import io.micronaut.views.exceptions.ViewRenderingException;
import io.micronaut.views.turbo.DefaultTurboFrameRenderer;
import io.micronaut.views.turbo.DefaultTurboStreamRenderer;
import io.micronaut.views.turbo.TurboFrame;
Expand All @@ -43,6 +44,7 @@
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import reactor.core.publisher.Flux;

import java.util.Optional;

/**
Expand Down Expand Up @@ -175,7 +177,7 @@ public final Publisher<MutableHttpResponse<?>> doFilter(HttpRequest<?> request,
response.contentType(type);
response.body(writable);
return Flux.just(response);
} catch (ViewNotFoundException e) {
} catch (ViewNotFoundException | ViewRenderingException e) {
return Flux.error(e);
}
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,26 +15,25 @@
*/
package io.micronaut.views.freemarker;

import freemarker.core.ParseException;
import freemarker.template.Configuration;
import freemarker.template.MalformedTemplateNameException;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.MalformedTemplateNameException;
import io.micronaut.core.annotation.NonNull;
import freemarker.core.ParseException;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
import io.micronaut.core.io.Writable;
import io.micronaut.core.util.ArgumentUtils;
import io.micronaut.http.HttpRequest;
import io.micronaut.views.ViewUtils;
import io.micronaut.views.ViewsConfiguration;
import io.micronaut.views.ViewsRenderer;
import io.micronaut.views.exceptions.ViewRenderingException;

import io.micronaut.core.annotation.Nullable;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

import java.io.IOException;
import java.util.Map;

/**
* Renders Views with FreeMarker Java template engine.
Expand Down Expand Up @@ -82,15 +81,20 @@ public Writable render(@NonNull String viewName,
@Nullable T data,
@Nullable HttpRequest<?> request) {
ArgumentUtils.requireNonNull("viewName", viewName);
Template template;
try {
// this has to fail fast to avoid a ReadTimeoutException from ViewsFilter call
template = freemarkerMicronautConfiguration.getTemplate(viewLocation(viewName));
} catch (IOException e) {
throw new ViewRenderingException(
"Error rendering Freemarker view [" + viewName + "]: " + e.getMessage(), e);
}
return (writer) -> {
Map<String, Object> context = ViewUtils.modelOf(data);
String location = viewLocation(viewName);
Template template = freemarkerMicronautConfiguration.getTemplate(location);
try {
template.process(context, writer);
template.process(ViewUtils.modelOf(data), writer);
} catch (TemplateException e) {
throw new ViewRenderingException(
"Error rendering Freemarker view [" + viewName + "]: " + e.getMessage(), e);
"Error rendering Freemarker view [" + viewName + "]: " + e.getMessage(), e);
}
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,12 +22,12 @@ import io.micronaut.http.MediaType
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.exceptions.HttpClientException
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.client.exceptions.ReadTimeoutException
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.views.ViewsFilter
import io.micronaut.views.freemarker.FreemarkerViewsRenderer
import io.micronaut.views.freemarker.FreemarkerViewsRendererConfigurationProperties
import spock.lang.AutoCleanup
import spock.lang.PendingFeature
import spock.lang.Shared
import spock.lang.Specification

Expand Down Expand Up @@ -194,15 +194,16 @@ class FreemarkerViewRendererSpec extends Specification {
rsp.body().contains("<h1>You are not logged in</h1>")
}

def "invoking /freemarker/invalid returns error"() {
def "invoking /freemarker/invalid throws HttpClientException that is not a read timeout"() {
when:
client.toBlocking().exchange('/freemarker/invalid', String)

then:
thrown(HttpClientException)
def e = thrown(HttpClientException)
// 'https://github.com/micronaut-projects/micronaut-views/issues/478'
!(e instanceof ReadTimeoutException)
}

@PendingFeature
def "invoking /freemarker/invalid returns HttpClientResponseException with 500 as status code"() {
when:
client.toBlocking().exchange('/freemarker/invalid', String)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

import java.io.IOException;

/**
* Renders Views with with Handlebars.java.
*
Expand Down Expand Up @@ -76,10 +78,15 @@ public Writable render(@NonNull String viewName,
@Nullable T data,
@Nullable HttpRequest<?> request) {
ArgumentUtils.requireNonNull("viewName", viewName);
String location = viewLocation(viewName);
Template template;
try {
template = handlebars.compile(location);
} catch (IOException e) {
throw new ViewRenderingException("Error rendering Handlebars view [" + viewName + "]: " + e.getMessage(), e);
}
return (writer) -> {
String location = viewLocation(viewName);
try {
Template template = handlebars.compile(location);
template.apply(data, writer);
} catch (Throwable e) {
throw new ViewRenderingException("Error rendering Handlebars view [" + viewName + "]: " + e.getMessage(), e);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,9 @@ public class HandlebarsController {
HttpResponse nullBody() {
HttpResponse.ok()
}

@View("badsyntax.hbs")
@Get("/badsyntax")
void badsyntax() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpStatus
import io.micronaut.http.MediaType
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.exceptions.HttpClientException
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.client.exceptions.ReadTimeoutException
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.views.ViewsFilter
import io.micronaut.views.handlebars.HandlebarsViewsRenderer
import spock.lang.AutoCleanup
import spock.lang.Issue
import spock.lang.Shared
import spock.lang.Specification

Expand Down Expand Up @@ -57,6 +60,16 @@ class HandlebarsViewsRendererSpec extends Specification {
noExceptionThrown()
}

@Issue('https://github.com/micronaut-projects/micronaut-views/issues/478')
def "invoking /handlebars/badsyntax throws HttpClientException that is not a read timeout"() {
when:
HttpResponse<String> rsp = client.toBlocking().exchange('/handlebars/badsyntax', String)

then:
def e = thrown(HttpClientException)
!(e instanceof ReadTimeoutException)
}

def "invoking /handlebars/home does not specify @View, thus, regular JSON rendering is used"() {
when:
HttpResponse<String> rsp = client.toBlocking().exchange('/handlebars/home', String)
Expand Down
13 changes: 13 additions & 0 deletions views-handlebars/src/test/resources/views/badsyntax.hbs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
{{#if loggedIn}}
<h1>username: <span>{{username}}</span></h1>
{{else}}
<h1>You are not logged in</h1>
{{/badsyntax}}
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -95,4 +95,9 @@ class JteController {
HttpResponse kteTemplate() {
return HttpResponse.ok(CollectionUtils.mapOf("loggedIn", true, "username", "sdelamo"));
}

@View("badsyntax.hbs")
@Get("/badsyntax")
void badsyntax() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,14 @@ import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpStatus
import io.micronaut.http.MediaType
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.exceptions.HttpClientException
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.client.exceptions.ReadTimeoutException
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.views.ViewsFilter
import io.micronaut.views.jte.JteViewsRenderer
import spock.lang.AutoCleanup
import spock.lang.Issue
import spock.lang.Shared
import spock.lang.Specification

Expand Down Expand Up @@ -52,6 +55,16 @@ abstract class JteViewRendererSpec extends Specification {
!jteBeans.empty
}

@Issue('https://github.com/micronaut-projects/micronaut-views/issues/478')
def "invoking /jte/badsyntax throws HttpClientException that is not a read timeout"() {
when:
HttpResponse<String> rsp = client.toBlocking().exchange('/jte/badsyntax', String)

then:
def e = thrown(HttpClientException)
!(e instanceof ReadTimeoutException)
}

def "invoking /jte/home does not specify @View, thus, regular JSON rendering is used"() {
when:
HttpResponse<String> rsp = client.toBlocking().exchange('/jte/home', String)
Expand Down
14 changes: 14 additions & 0 deletions views-jte/src/test/resources/views/badsyntax.jte
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
@param Boolean loggedIn
@param String username
<html>
<head>
<title>Home</title>
</head>
<body>
@if (loggedIn != null && loggedIn)
<h1>username: <span>${username}</span></h1>
@else
<h1>You are not logged in</h1>
@endif
</body>
</html>
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package io.micronaut.views.pebble;

import com.mitchellbosecke.pebble.PebbleEngine;
import com.mitchellbosecke.pebble.template.PebbleTemplate;
import io.micronaut.context.annotation.Requires;
import io.micronaut.core.annotation.NonNull;
import io.micronaut.core.annotation.Nullable;
Expand All @@ -25,6 +26,7 @@
import io.micronaut.http.HttpRequest;
import io.micronaut.views.ViewUtils;
import io.micronaut.views.ViewsRenderer;
import io.micronaut.views.exceptions.ViewRenderingException;
import jakarta.inject.Inject;
import jakarta.inject.Singleton;

Expand Down Expand Up @@ -93,7 +95,15 @@ public PebbleViewsRenderer(PebbleConfiguration configuration, PebbleEngine engin
public Writable render(@NonNull String name,
@Nullable T data,
@Nullable HttpRequest<?> request) {
return (writer) -> engine.getTemplate(name).evaluate(writer, ViewUtils.modelOf(data), request != null ? httpLocaleResolver.resolveOrDefault(request) : Locale.getDefault());
PebbleTemplate template;
try {
// this has to fail fast to avoid a ReadTimeoutException from ViewsFilter call
template = engine.getTemplate(name);
} catch (Exception e) {
throw new ViewRenderingException("Error rendering Pebble view [" + name + "]: " + e.getMessage(), e);
}
return writer -> template.evaluate(writer, ViewUtils.modelOf(data),
request != null ? httpLocaleResolver.resolveOrDefault(request) : Locale.getDefault());
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,4 +72,9 @@ public class PebbleController {
@Get("/i18n")
void i18n() {
}

@View("badsyntax.html")
@Get("/badsyntax")
void badsyntax() {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,20 @@
*/
package io.micronaut.docs


import io.micronaut.context.ApplicationContext
import io.micronaut.http.HttpResponse
import io.micronaut.http.HttpStatus
import io.micronaut.http.MediaType
import io.micronaut.http.client.HttpClient
import io.micronaut.http.client.exceptions.HttpClientException
import io.micronaut.http.client.exceptions.HttpClientResponseException
import io.micronaut.http.client.exceptions.ReadTimeoutException
import io.micronaut.runtime.server.EmbeddedServer
import io.micronaut.views.ViewsFilter
import io.micronaut.views.pebble.PebbleViewsRenderer
import spock.lang.AutoCleanup
import spock.lang.Issue
import spock.lang.Shared
import spock.lang.Specification
import spock.lang.Unroll
Expand Down Expand Up @@ -141,6 +145,16 @@ class PebbleViewsRendererSpec extends Specification {
rsp.body().contains("<h1>You are not logged in</h1>")
}

@Issue('https://github.com/micronaut-projects/micronaut-views/issues/478')
def "invoking /pebble/badsyntax throws HttpClientException that is not a read timeout"() {
when:
HttpResponse<String> rsp = client.toBlocking().exchange('/pebble/badsyntax', String)

then:
def e = thrown(HttpClientException)
!(e instanceof ReadTimeoutException)
}

def "invoking /text renders pebble text template from a controller returning a map"() {
when:
HttpResponse<String> rsp = client.toBlocking().exchange('/pebble/text', String)
Expand Down
11 changes: 11 additions & 0 deletions views-pebble/src/test/resources/views/badsyntax.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<!DOCTYPE html>
<html>
<head>
<title>Home</title>
</head>
<body>
{% block header %}
<h1> Introduction </h1>
{% endlock header %}
</body>
</html>
Loading

0 comments on commit 0aa0467

Please sign in to comment.