diff --git a/.code-samples.meilisearch.yaml b/.code-samples.meilisearch.yaml index b5b82ec5..f6423f99 100644 --- a/.code-samples.meilisearch.yaml +++ b/.code-samples.meilisearch.yaml @@ -640,3 +640,28 @@ webhooks_patch_1: |- Webhook updated_webhook = this.client.updateWebhook(webhook.getUuid(), webhookReq2); webhooks_delete_1: |- this.client.deleteWebhook("WEBHOOK_UUID"); + + +post_render_template_1: |- + Map features = new HashMap<>(); + features.put("renderRoute", true); + client.experimentalFeatures(features); + + Map template = new HashMap<>(); + template.put("kind", "inlineDocumentTemplate"); + template.put("inline", "Product {{doc.name}} is a {{doc.color}} {{doc.category}}."); + + Map product = new HashMap<>(); + product.put("name", "Nike Air Max"); + product.put("color", "Black"); + product.put("category", "Shoes"); + + Map input = new HashMap<>(); + input.put("kind", "inlineDocument"); + input.put("inline", product); + + RenderTemplateRequest request = new RenderTemplateRequest() + .setTemplate(template) + .setInput(input); + + client.renderTemplate(request); diff --git a/src/main/java/com/meilisearch/sdk/Client.java b/src/main/java/com/meilisearch/sdk/Client.java index 37e250eb..3f4bfed5 100644 --- a/src/main/java/com/meilisearch/sdk/Client.java +++ b/src/main/java/com/meilisearch/sdk/Client.java @@ -482,6 +482,18 @@ public void experimentalFeatures(Map features) { this.config.httpClient.patch("/experimental-features", features, Void.class); } + /** + * Renders a template using the experimental render-template route. + * + * @param request Render template request body + * @return Rendered template result + * @throws MeilisearchException if an error occurs + */ + public RenderTemplateResult renderTemplate(RenderTemplateRequest request) + throws MeilisearchException { + return this.config.httpClient.post("/render-template", request, RenderTemplateResult.class); + } + public String generateTenantToken(String apiKeyUid, Map searchRules) throws MeilisearchException { return this.generateTenantToken(apiKeyUid, searchRules, new TenantTokenOptions()); diff --git a/src/main/java/com/meilisearch/sdk/RenderTemplateRequest.java b/src/main/java/com/meilisearch/sdk/RenderTemplateRequest.java new file mode 100644 index 00000000..1ab79b1d --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/RenderTemplateRequest.java @@ -0,0 +1,30 @@ +package com.meilisearch.sdk; + +import java.util.Map; +import lombok.AccessLevel; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import lombok.experimental.Accessors; +import org.json.JSONObject; + +@Builder +@AllArgsConstructor(access = AccessLevel.PACKAGE) +@Getter +@Setter +@Accessors(chain = true) +public class RenderTemplateRequest { + private Map template; + private Map input; + + public RenderTemplateRequest() {} + + @Override + public String toString() { + JSONObject jsonObject = new JSONObject(); + jsonObject.put("template", this.template); + jsonObject.putOpt("input", this.input); + return jsonObject.toString(); + } +} diff --git a/src/main/java/com/meilisearch/sdk/model/RenderTemplateResult.java b/src/main/java/com/meilisearch/sdk/model/RenderTemplateResult.java new file mode 100644 index 00000000..4d521a06 --- /dev/null +++ b/src/main/java/com/meilisearch/sdk/model/RenderTemplateResult.java @@ -0,0 +1,15 @@ +package com.meilisearch.sdk.model; + +import lombok.Getter; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@ToString +public class RenderTemplateResult { + private Object template; + private Object rendered; + + public RenderTemplateResult() {} +} diff --git a/src/test/java/com/meilisearch/sdk/RenderTemplateRequestTest.java b/src/test/java/com/meilisearch/sdk/RenderTemplateRequestTest.java new file mode 100644 index 00000000..73399d53 --- /dev/null +++ b/src/test/java/com/meilisearch/sdk/RenderTemplateRequestTest.java @@ -0,0 +1,148 @@ +package com.meilisearch.sdk; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +import com.meilisearch.sdk.http.request.BasicRequest; +import com.meilisearch.sdk.http.request.HttpMethod; +import com.meilisearch.sdk.http.request.HttpRequest; +import com.meilisearch.sdk.json.GsonJsonHandler; +import java.util.Collections; +import java.util.HashMap; +import java.util.Map; +import org.json.JSONObject; +import org.junit.jupiter.api.Test; + +class RenderTemplateRequestTest { + @Test + void toStringWithTemplateAndInput() { + Map template = new HashMap<>(); + template.put("kind", "inlineDocumentTemplate"); + template.put("inline", "Product {{doc.name}} is a {{doc.color}} {{doc.category}}."); + + Map product = new HashMap<>(); + product.put("name", "Nike Air Max"); + product.put("color", "Black"); + product.put("category", "Shoes"); + + Map input = new HashMap<>(); + input.put("kind", "inlineDocument"); + input.put("inline", product); + + RenderTemplateRequest request = + new RenderTemplateRequest().setTemplate(template).setInput(input); + + JSONObject json = new JSONObject(request.toString()); + + assertThat( + json.getJSONObject("template").getString("kind"), + is(equalTo("inlineDocumentTemplate"))); + assertThat( + json.getJSONObject("template").getString("inline"), + is(equalTo("Product {{doc.name}} is a {{doc.color}} {{doc.category}}."))); + + assertThat(json.getJSONObject("input").getString("kind"), is(equalTo("inlineDocument"))); + assertThat( + json.getJSONObject("input").getJSONObject("inline").getString("name"), + is(equalTo("Nike Air Max"))); + assertThat( + json.getJSONObject("input").getJSONObject("inline").getString("color"), + is(equalTo("Black"))); + assertThat( + json.getJSONObject("input").getJSONObject("inline").getString("category"), + is(equalTo("Shoes"))); + } + + @Test + void toStringWithoutInput() { + Map template = new HashMap<>(); + template.put("kind", "inlineDocumentTemplate"); + template.put("inline", "Hello {{doc.name}}"); + + RenderTemplateRequest request = new RenderTemplateRequest().setTemplate(template); + + JSONObject json = new JSONObject(request.toString()); + + assertThat(json.has("template"), is(true)); + assertThat(json.has("input"), is(false)); + assertThat( + json.getJSONObject("template").getString("kind"), + is(equalTo("inlineDocumentTemplate"))); + assertThat( + json.getJSONObject("template").getString("inline"), + is(equalTo("Hello {{doc.name}}"))); + } + + @Test + void requestSerializerWithTemplateAndInput() { + Map template = new HashMap<>(); + template.put("kind", "inlineDocumentTemplate"); + template.put("inline", "Product {{doc.name}} is a {{doc.color}} {{doc.category}}."); + + Map product = new HashMap<>(); + product.put("name", "Nike Air Max"); + product.put("color", "Black"); + product.put("category", "Shoes"); + + Map input = new HashMap<>(); + input.put("kind", "inlineDocument"); + input.put("inline", product); + + RenderTemplateRequest request = + new RenderTemplateRequest().setTemplate(template).setInput(input); + + BasicRequest basicRequest = new BasicRequest(new GsonJsonHandler()); + HttpRequest httpRequest = + basicRequest.create( + HttpMethod.POST, "/render-template", Collections.emptyMap(), request); + + JSONObject json = new JSONObject(httpRequest.getContent()); + + assertThat(httpRequest.getMethod(), is(equalTo(HttpMethod.POST))); + assertThat(httpRequest.getPath(), is(equalTo("/render-template"))); + assertThat( + json.getJSONObject("template").getString("kind"), + is(equalTo("inlineDocumentTemplate"))); + assertThat(json.getJSONObject("input").getString("kind"), is(equalTo("inlineDocument"))); + assertThat( + json.getJSONObject("input").getJSONObject("inline").getString("name"), + is(equalTo("Nike Air Max"))); + } + + @Test + void requestSerializerWithoutInput() { + Map template = new HashMap<>(); + template.put("kind", "inlineDocumentTemplate"); + template.put("inline", "Hello {{doc.name}}"); + + RenderTemplateRequest request = new RenderTemplateRequest().setTemplate(template); + + BasicRequest basicRequest = new BasicRequest(new GsonJsonHandler()); + HttpRequest httpRequest = + basicRequest.create( + HttpMethod.POST, "/render-template", Collections.emptyMap(), request); + + JSONObject json = new JSONObject(httpRequest.getContent()); + + assertThat(httpRequest.getMethod(), is(equalTo(HttpMethod.POST))); + assertThat(httpRequest.getPath(), is(equalTo("/render-template"))); + assertThat(json.has("template"), is(true)); + assertThat(json.has("input"), is(false)); + } + + @Test + void gettersAndSetters() { + Map template = new HashMap<>(); + template.put("kind", "inlineDocumentTemplate"); + + Map input = new HashMap<>(); + input.put("kind", "inlineDocument"); + + RenderTemplateRequest request = + RenderTemplateRequest.builder().template(template).input(input).build(); + + assertThat(request.getTemplate(), is(equalTo(template))); + assertThat(request.getInput(), is(equalTo(input))); + } +} diff --git a/src/test/java/com/meilisearch/sdk/model/RenderTemplateResultTest.java b/src/test/java/com/meilisearch/sdk/model/RenderTemplateResultTest.java new file mode 100644 index 00000000..f9ccde0a --- /dev/null +++ b/src/test/java/com/meilisearch/sdk/model/RenderTemplateResultTest.java @@ -0,0 +1,48 @@ +package com.meilisearch.sdk.model; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.equalTo; +import static org.hamcrest.Matchers.is; + +import com.meilisearch.sdk.json.JacksonJsonHandler; +import java.util.List; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class RenderTemplateResultTest { + @Test + void deserializesWithJacksonJsonHandler() throws Exception { + RenderTemplateResult result = + new JacksonJsonHandler() + .decode( + "{\"template\":\"Hello {{doc.name}}\",\"rendered\":\"Hello Movindu\"}", + RenderTemplateResult.class); + + assertThat(result.getTemplate(), is(equalTo("Hello {{doc.name}}"))); + assertThat(result.getRendered(), is(equalTo("Hello Movindu"))); + } + + @Test + void deserializesStructuredRenderedValueWithJacksonJsonHandler() throws Exception { + RenderTemplateResult result = + new JacksonJsonHandler() + .decode( + "{" + + "\"template\":\"{{ doc }}\"," + + "\"rendered\":{" + + "\"title\":\"Ariel\"," + + "\"tags\":[\"movie\",\"classic\"]" + + "}" + + "}", + RenderTemplateResult.class); + + assertThat(result.getTemplate(), is(equalTo("{{ doc }}"))); + + Map rendered = (Map) result.getRendered(); + assertThat(rendered.get("title"), is(equalTo("Ariel"))); + + List tags = (List) rendered.get("tags"); + assertThat(tags.get(0), is(equalTo("movie"))); + assertThat(tags.get(1), is(equalTo("classic"))); + } +}