Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/**
* Copyright 2005-2026 Qlik
*<p>
* The content of this file is subject to the terms of the Apache 2.0 open
* source license available at https://www.opensource.org/licenses/apache-2.0
*<p>
* Restlet is a registered trademark of QlikTech International AB.
*/
package org.restlet.ext.freemarker;

import static org.junit.jupiter.api.Assertions.assertDoesNotThrow;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import java.io.IOException;
import java.util.Date;
import org.junit.jupiter.api.Test;
import org.restlet.Context;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.Restlet;
import org.restlet.data.Reference;
import org.restlet.representation.StringRepresentation;

class ContextTemplateLoaderTestCase {

/** Context whose dispatcher records the last URI it received. */
private static class CapturingContext extends Context {
String lastRequestedUri;

CapturingContext() {
setClientDispatcher(
new Restlet() {
@Override
public void handle(Request request, Response response) {
lastRequestedUri = request.getResourceRef().toString();
response.setEntity(new StringRepresentation("template content"));
}
});
}
}

/** Representation that tracks whether release() was called. */
private static class TrackingRepresentation extends StringRepresentation {
boolean released = false;

TrackingRepresentation() {
super("content");
}

@Override
public void release() {
released = true;
super.release();
}
}

@Test
void findTemplateSource_nullContext_returnsNull() throws IOException {
ContextTemplateLoader loader = new ContextTemplateLoader(null, "clap://test");
assertNull(loader.findTemplateSource("test.ftl"));
}

@Test
void findTemplateSource_baseUriWithTrailingSlash_buildsCorrectUri() throws IOException {
CapturingContext ctx = new CapturingContext();
ContextTemplateLoader loader = new ContextTemplateLoader(ctx, "clap://test/");
loader.findTemplateSource("hello.ftl");
assertEquals("clap://test/hello.ftl", ctx.lastRequestedUri);
}

@Test
void findTemplateSource_baseUriWithoutTrailingSlash_buildsCorrectUri() throws IOException {
CapturingContext ctx = new CapturingContext();
ContextTemplateLoader loader = new ContextTemplateLoader(ctx, "clap://test");
loader.findTemplateSource("hello.ftl");
assertEquals("clap://test/hello.ftl", ctx.lastRequestedUri);
}

@Test
void constructor_withReference_usesReferenceToString() throws IOException {
CapturingContext ctx = new CapturingContext();
Reference ref = new Reference("clap://test/");
ContextTemplateLoader loader = new ContextTemplateLoader(ctx, ref);
loader.findTemplateSource("hello.ftl");
assertEquals("clap://test/hello.ftl", ctx.lastRequestedUri);
}

@Test
void closeTemplateSource_withRepresentation_callsRelease() {
ContextTemplateLoader loader = new ContextTemplateLoader(null, "clap://test");
TrackingRepresentation rep = new TrackingRepresentation();
loader.closeTemplateSource(rep);
assertTrue(rep.released);
}

@Test
void closeTemplateSource_withNonRepresentation_doesNotThrow() {
ContextTemplateLoader loader = new ContextTemplateLoader(null, "clap://test");
assertDoesNotThrow(() -> loader.closeTemplateSource("notARepresentation"));
}

@Test
void getLastModified_withModificationDate_returnsTimestamp() {
ContextTemplateLoader loader = new ContextTemplateLoader(null, "clap://test");
Date now = new Date();
StringRepresentation rep = new StringRepresentation("content");
rep.setModificationDate(now);
assertEquals(now.getTime(), loader.getLastModified(rep));
}

@Test
void getLastModified_withNullModificationDate_returnsMinusOne() {
ContextTemplateLoader loader = new ContextTemplateLoader(null, "clap://test");
StringRepresentation rep = new StringRepresentation("content");
assertEquals(-1L, loader.getLastModified(rep));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,21 @@
package org.restlet.ext.freemarker;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertTrue;

import freemarker.template.Configuration;
import freemarker.template.Template;
import java.io.File;
import java.io.FileWriter;
import java.nio.file.Files;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.restlet.data.MediaType;
import org.restlet.engine.io.IoUtils;
import org.restlet.representation.StringRepresentation;
import org.restlet.representation.Variant;

/**
* Unit test for the FreeMarker extension.
Expand All @@ -37,7 +43,7 @@ void testTemplate() throws Exception {
fw.write("Value=${value}");
fw.close();

final Configuration fmc = new Configuration();
final Configuration fmc = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
fmc.setDirectoryForTemplateLoading(testDir);
final Map<String, Object> map = Map.of("value", "myValue");

Expand All @@ -49,4 +55,76 @@ void testTemplate() throws Exception {
// Clean-up
IoUtils.delete(testDir, true);
}

@Test
void testTemplateRepresentationConstructors() {
// Constructor with Template object (null template)
TemplateRepresentation tr =
new TemplateRepresentation((Template) null, MediaType.TEXT_PLAIN);
assertNull(tr.getTemplate());
assertNull(tr.getDataModel());

// setDataModel and setTemplate
tr.setDataModel("myModel");
assertEquals("myModel", tr.getDataModel());
tr.setTemplate(null);
assertNull(tr.getTemplate());

// Constructor with template name + config: template not found → null
Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
tr = new TemplateRepresentation("nonexistent.ftl", cfg, MediaType.TEXT_PLAIN);
assertNull(tr.getTemplate());

// Constructor with template name + config + data model
tr =
new TemplateRepresentation(
"nonexistent.ftl", cfg, Map.of("k", "v"), MediaType.TEXT_PLAIN);
assertEquals(Map.of("k", "v"), tr.getDataModel());

// Constructor with Representation + config (no directory set → template loading fails)
StringRepresentation rep = new StringRepresentation("Hello ${name}");
rep.setCharacterSet(org.restlet.data.CharacterSet.UTF_8);
TemplateRepresentation tr2 = new TemplateRepresentation(rep, cfg, MediaType.TEXT_PLAIN);
assertNotNull(tr2); // The template is loaded inline from the representation

// setDataModel with a Resolver (anonymous class, since Resolver is abstract)
tr = new TemplateRepresentation((Template) null, MediaType.TEXT_PLAIN);
tr.setDataModel(
new org.restlet.util.Resolver<>() {
@Override
public Object resolve(String name) {
return "resolved-" + name;
}
});
assertNotNull(tr.getDataModel());

// static getTemplate(config, name) — name not found returns null (already tested above via
// constructor)
assertNull(TemplateRepresentation.getTemplate(cfg, "nonexistent.ftl"));
}

@Test
void testTemplateRepresentationWriteNullTemplate() throws Exception {
// write() with null template should log a warning and not throw
TemplateRepresentation tr =
new TemplateRepresentation((Template) null, MediaType.TEXT_PLAIN);
java.io.StringWriter sw = new java.io.StringWriter();
tr.write(sw); // must not throw
assertEquals("", sw.toString());
}

@Test
void testFreemarkerConverterScore() {
FreemarkerConverter converter = new FreemarkerConverter();

assertEquals(-1.0f, converter.score(null, new Variant(MediaType.TEXT_PLAIN), null));
assertEquals(-1.0f, converter.score("hello", new Variant(MediaType.TEXT_PLAIN), null));
assertEquals(-1.0f, converter.score(new StringRepresentation("x"), String.class, null));
assertTrue(converter.getObjectClasses(new Variant(MediaType.TEXT_PLAIN)).isEmpty());
assertTrue(converter.getVariants(String.class).isEmpty());
assertNull(converter.toObject(null, String.class, null));
assertNull(
converter.toRepresentation(
"notATemplate", new Variant(MediaType.TEXT_PLAIN), null));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ private static class User {
private final Date createAt;

@Since(2.0)
private Date lastLogin;
private final Date lastLogin;

private final String loginId;

Expand Down
6 changes: 6 additions & 0 deletions org.restlet.ext.jaas/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@
<artifactId>org.restlet</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${lib-junit-version}</version>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,111 @@
/**
* Copyright 2005-2026 Qlik
*<p>
* The content of this file is subject to the terms of the Apache 2.0 open
* source license available at https://www.opensource.org/licenses/apache-2.0
*<p>
* Restlet is a registered trademark of QlikTech International AB.
*/
package org.restlet.ext.jaas;

import static org.junit.jupiter.api.Assertions.assertArrayEquals;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNull;
import static org.junit.jupiter.api.Assertions.assertThrows;

import javax.security.auth.callback.NameCallback;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.restlet.Request;
import org.restlet.Response;
import org.restlet.data.ChallengeResponse;
import org.restlet.data.ChallengeScheme;
import org.restlet.data.Method;
import org.restlet.data.Reference;

/** Unit tests for {@link ChallengeCallbackHandler}. */
class ChallengeCallbackHandlerTestCase {

private Request request;
private Response response;
private ChallengeCallbackHandler handler;

@BeforeEach
void setUp() {
request = new Request(Method.GET, new Reference("http://localhost/test"));
response = new Response(request);
handler = new ChallengeCallbackHandler(request, response);
}

@Test
void testConstructor() {
assertEquals(request, handler.getRequest());
assertEquals(response, handler.getResponse());
}

@Test
void testSetRequest() {
Request newRequest = new Request(Method.POST, new Reference("http://localhost/other"));
handler.setRequest(newRequest);
assertEquals(newRequest, handler.getRequest());
}

@Test
void testSetResponse() {
Response newResponse = new Response(request);
handler.setResponse(newResponse);
assertEquals(newResponse, handler.getResponse());
}

@Test
void testHandleNameCallback() throws UnsupportedCallbackException {
request.setChallengeResponse(
new ChallengeResponse(ChallengeScheme.HTTP_BASIC, "john", "secret"));

NameCallback nameCallback = new NameCallback("Username:");
handler.handle(new javax.security.auth.callback.Callback[] {nameCallback});

assertEquals("john", nameCallback.getName());
}

@Test
void testHandlePasswordCallback() throws UnsupportedCallbackException {
request.setChallengeResponse(
new ChallengeResponse(ChallengeScheme.HTTP_BASIC, "john", "secret"));

PasswordCallback passwordCallback = new PasswordCallback("Password:", false);
handler.handle(new javax.security.auth.callback.Callback[] {passwordCallback});

assertArrayEquals("secret".toCharArray(), passwordCallback.getPassword());
}

@Test
void testHandleNullCallbacks() throws UnsupportedCallbackException {
handler.handle((javax.security.auth.callback.Callback[]) null);
}

@Test
void testHandleEmptyCallbacks() throws UnsupportedCallbackException {
handler.handle(new javax.security.auth.callback.Callback[] {});
}

@Test
void testHandleUnsupportedCallback() {
javax.security.auth.callback.Callback unsupported =
new javax.security.auth.callback.Callback() {};
assertThrows(
UnsupportedCallbackException.class,
() -> handler.handle(new javax.security.auth.callback.Callback[] {unsupported}));
}

@Test
void testHandleNameCallbackWithoutChallengeResponse() {
assertNull(request.getChallengeResponse());
NameCallback nameCallback = new NameCallback("Username:");
assertThrows(
UnsupportedCallbackException.class,
() -> handler.handle(new javax.security.auth.callback.Callback[] {nameCallback}));
}
}
Loading
Loading