From e601439421f1179fd339a2f7d103b65c2c70cac6 Mon Sep 17 00:00:00 2001
From: Mike Hearn
Date: Wed, 7 Aug 2024 11:31:54 +0200
Subject: [PATCH 01/16] ReactJS: don't crash if a props object returns null
from a property.
---
.../views/react/IntrospectableToPolyglotObject.java | 2 +-
.../micronaut/views/react/ReactViewRenderSpec.groovy | 4 +++-
.../views/react/SandboxReactRenderSpec.groovy | 2 +-
.../test/java/io/micronaut/views/react/SomeBean.java | 10 +++++++++-
views-react/src/test/js/components/App.js | 4 +++-
5 files changed, 17 insertions(+), 5 deletions(-)
diff --git a/views-react/src/main/java/io/micronaut/views/react/IntrospectableToPolyglotObject.java b/views-react/src/main/java/io/micronaut/views/react/IntrospectableToPolyglotObject.java
index fb0da8369..4945da088 100644
--- a/views-react/src/main/java/io/micronaut/views/react/IntrospectableToPolyglotObject.java
+++ b/views-react/src/main/java/io/micronaut/views/react/IntrospectableToPolyglotObject.java
@@ -42,7 +42,7 @@ class ProxyObjectWithIntrospectableSupport implements ProxyObject {
@Override
public Object getMember(String key) {
Object result = map.get(key);
- if (BeanIntrospector.SHARED.findIntrospection(result.getClass()).isPresent()) {
+ if (result != null && BeanIntrospector.SHARED.findIntrospection(result.getClass()).isPresent()) {
return new ProxyObjectWithIntrospectableSupport(context, BeanMap.of(result));
} else {
return context.asValue(result);
diff --git a/views-react/src/test/groovy/io/micronaut/views/react/ReactViewRenderSpec.groovy b/views-react/src/test/groovy/io/micronaut/views/react/ReactViewRenderSpec.groovy
index bdc52ea3e..090a0c193 100644
--- a/views-react/src/test/groovy/io/micronaut/views/react/ReactViewRenderSpec.groovy
+++ b/views-react/src/test/groovy/io/micronaut/views/react/ReactViewRenderSpec.groovy
@@ -15,7 +15,7 @@ class ReactViewRenderSpec extends Specification {
void "views can be rendered with basic props"() {
when:
- Writable writable = renderer.render("App", ["name": "Mike"], null)
+ Writable writable = renderer.render("App", ["name": "Mike", "someNull": null, "obj": new SomeBean("foo", null)], null)
String result = new StringWriter().with {
writable.writeTo(it)
it.toString()
@@ -23,6 +23,8 @@ class ReactViewRenderSpec extends Specification {
then:
result.contains("Hello there")
+ result.contains("Reading a property works: foo")
+ result.contains("Reading a null works:
")
result.contains("\"name\":\"Mike\"")
}
diff --git a/views-react/src/test/groovy/io/micronaut/views/react/SandboxReactRenderSpec.groovy b/views-react/src/test/groovy/io/micronaut/views/react/SandboxReactRenderSpec.groovy
index 07f5868c1..fcd683204 100644
--- a/views-react/src/test/groovy/io/micronaut/views/react/SandboxReactRenderSpec.groovy
+++ b/views-react/src/test/groovy/io/micronaut/views/react/SandboxReactRenderSpec.groovy
@@ -20,7 +20,7 @@ class SandboxReactRenderSpec extends Specification {
@FailsWith(BeanInstantiationException)
void "views can be rendered with sandboxing enabled"() {
given:
- def props = ["name": "Mike", "obj": new SomeBean("bar")]
+ def props = ["name": "Mike", "obj": new SomeBean("bar", null)]
when:
Writable writable = renderer.render("App", props, null)
diff --git a/views-react/src/test/java/io/micronaut/views/react/SomeBean.java b/views-react/src/test/java/io/micronaut/views/react/SomeBean.java
index ab3c01635..9434e6268 100644
--- a/views-react/src/test/java/io/micronaut/views/react/SomeBean.java
+++ b/views-react/src/test/java/io/micronaut/views/react/SomeBean.java
@@ -1,6 +1,7 @@
package io.micronaut.views.react;
import io.micronaut.core.annotation.Introspected;
+import io.micronaut.core.annotation.Nullable;
import org.graalvm.polyglot.HostAccess;
/**
@@ -9,13 +10,20 @@
@Introspected
public class SomeBean {
private final String foo;
+ private final @Nullable String bar;
- SomeBean(String foo) {
+ SomeBean(String foo, String bar) {
this.foo = foo;
+ this.bar = bar;
}
@HostAccess.Export
public String getFoo() {
return foo;
}
+
+ @HostAccess.Export
+ public String getBar() {
+ return bar;
+ }
}
diff --git a/views-react/src/test/js/components/App.js b/views-react/src/test/js/components/App.js
index 60e3ba70b..d6bb9803a 100644
--- a/views-react/src/test/js/components/App.js
+++ b/views-react/src/test/js/components/App.js
@@ -1,7 +1,7 @@
// App.js
import React from 'react';
-function App({name, url, triggerSandbox}) {
+function App({name, obj, url, triggerSandbox}) {
if (triggerSandbox) {
// Verify that we aren't able to access host types due to the sandbox.
Java.type("java.lang.System");
@@ -16,6 +16,8 @@ function App({name, url, triggerSandbox}) {
Hello there {name}, I'm saying hi from SSR React!
URL is {url}
+ Reading a property works: {obj.foo}
+ Reading a null works: {obj.bar}