mirror of https://github.com/shred/acme4j
Increase unit test coverage
parent
b3fc9a732c
commit
0a288fa290
|
@ -17,7 +17,9 @@ import java.io.IOException;
|
|||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
@ -162,7 +164,7 @@ public class Challenge extends AcmeResource {
|
|||
* JSON map containing the challenge data
|
||||
*/
|
||||
public void unmarshall(Map<String, Object> map) {
|
||||
String type = map.get(KEY_TYPE).toString();
|
||||
String type = (String) map.get(KEY_TYPE);
|
||||
if (type == null) {
|
||||
throw new IllegalArgumentException("map does not contain a type");
|
||||
}
|
||||
|
@ -187,6 +189,22 @@ public class Challenge extends AcmeResource {
|
|||
return (T) data.get(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an {@link URL} value from the challenge state.
|
||||
*
|
||||
* @param key
|
||||
* Key
|
||||
* @return Value, or {@code null} if not set
|
||||
*/
|
||||
protected URL getUrl(String key) {
|
||||
try {
|
||||
String value = get(key);
|
||||
return value != null ? new URL(value) : null;
|
||||
} catch (MalformedURLException ex) {
|
||||
throw new AcmeProtocolException(key + ": invalid URL", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback that is invoked when the challenge is supposed to compute its
|
||||
* authorization data.
|
||||
|
|
|
@ -13,11 +13,9 @@
|
|||
*/
|
||||
package org.shredzone.acme4j.challenge;
|
||||
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
|
||||
import org.shredzone.acme4j.Session;
|
||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||
|
||||
/**
|
||||
* Implements the {@value TYPE} challenge.
|
||||
|
@ -45,11 +43,7 @@ public class OutOfBand01Challenge extends Challenge {
|
|||
* challenge.
|
||||
*/
|
||||
public URL getValidationUrl() {
|
||||
try {
|
||||
return new URL((String) get("href"));
|
||||
} catch (MalformedURLException ex) {
|
||||
throw new AcmeProtocolException("Invalid validation URL", ex);
|
||||
}
|
||||
return getUrl("href");
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -49,6 +49,13 @@ public class HttpConnector {
|
|||
USER_AGENT = agent.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the default User-Agent to be used.
|
||||
*/
|
||||
public static String defaultUserAgent() {
|
||||
return USER_AGENT;
|
||||
}
|
||||
|
||||
/**
|
||||
* Opens a {@link HttpURLConnection} to the given {@link URI}.
|
||||
*
|
||||
|
@ -58,11 +65,24 @@ public class HttpConnector {
|
|||
*/
|
||||
public HttpURLConnection openConnection(URI uri) throws IOException {
|
||||
HttpURLConnection conn = (HttpURLConnection) uri.toURL().openConnection();
|
||||
configure(conn);
|
||||
return conn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Configures the new {@link HttpURLConnection}.
|
||||
* <p>
|
||||
* This implementation sets reasonable timeouts, forbids caching, and sets an user
|
||||
* agent.
|
||||
*
|
||||
* @param conn
|
||||
* {@link HttpURLConnection} to configure.
|
||||
*/
|
||||
protected void configure(HttpURLConnection conn) {
|
||||
conn.setConnectTimeout(TIMEOUT);
|
||||
conn.setReadTimeout(TIMEOUT);
|
||||
conn.setUseCaches(false);
|
||||
conn.setRequestProperty("User-Agent", USER_AGENT);
|
||||
return conn;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -122,6 +122,19 @@ public class AcmeResourceTest {
|
|||
assertThat(restored.getSession(), is(session));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a rebind attempt fails.
|
||||
*/
|
||||
@Test(expected = IllegalStateException.class)
|
||||
public void testRebind() throws Exception {
|
||||
Session session = TestUtils.session();
|
||||
AcmeResource resource = new DummyResource(session);
|
||||
assertThat(resource.getSession(), is(session));
|
||||
|
||||
Session session2 = TestUtils.session();
|
||||
resource.rebind(session2); // fails to rebind to another session
|
||||
}
|
||||
|
||||
/**
|
||||
* Minimum implementation of {@link AcmeResource}.
|
||||
*/
|
||||
|
|
|
@ -195,4 +195,12 @@ public class CertificateTest {
|
|||
provider.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that numeric revocation reasons are correctly translated.
|
||||
*/
|
||||
@Test
|
||||
public void testRevocationReason() {
|
||||
assertThat(RevocationReason.code(1), is(RevocationReason.KEY_COMPROMISE));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,8 +24,10 @@ import java.io.IOException;
|
|||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
import java.net.HttpURLConnection;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.net.URL;
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
|
@ -98,7 +100,7 @@ public class ChallengeTest {
|
|||
* Test that after unmarshalling, the challenge properties are set correctly.
|
||||
*/
|
||||
@Test
|
||||
public void testUnmarshall() throws URISyntaxException {
|
||||
public void testUnmarshall() throws URISyntaxException, MalformedURLException {
|
||||
Challenge challenge = new Challenge(session);
|
||||
|
||||
// Test default values
|
||||
|
@ -115,6 +117,17 @@ public class ChallengeTest {
|
|||
assertThat(challenge.getStatus(), is(Status.VALID));
|
||||
assertThat(challenge.getLocation(), is(new URI("http://example.com/challenge/123")));
|
||||
assertThat(challenge.getValidated(), is(TimestampParser.parse("2015-12-12T17:19:36.336785823Z")));
|
||||
assertThat((String) challenge.get("type"), is("generic-01"));
|
||||
assertThat(challenge.getUrl("uri"), is(new URL("http://example.com/challenge/123")));
|
||||
assertThat(challenge.get("not-present"), is(nullValue()));
|
||||
assertThat(challenge.getUrl("not-present-url"), is(nullValue()));
|
||||
|
||||
try {
|
||||
challenge.getUrl("type");
|
||||
fail("bad URL is not detected");
|
||||
} catch (AcmeProtocolException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -267,6 +280,65 @@ public class ChallengeTest {
|
|||
provider.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that null is handled properly.
|
||||
*/
|
||||
@Test
|
||||
public void testNullChallenge() throws Exception {
|
||||
try {
|
||||
Challenge.bind(session, null);
|
||||
fail("locationUri accepts null");
|
||||
} catch (NullPointerException ex) {
|
||||
// expected
|
||||
}
|
||||
|
||||
try {
|
||||
Challenge.bind(null, locationUri);
|
||||
fail("session accepts null");
|
||||
} catch (NullPointerException ex) {
|
||||
// expected
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an exception is thrown on a bad location URI.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBadBind() throws Exception {
|
||||
TestableConnectionProvider provider = new TestableConnectionProvider() {
|
||||
@Override
|
||||
public void sendRequest(URI uri, Session session) {
|
||||
assertThat(uri, is(locationUri));
|
||||
}
|
||||
|
||||
@Override
|
||||
public int accept(int... httpStatus) throws AcmeException {
|
||||
assertThat(httpStatus, isIntArrayContainingInAnyOrder(
|
||||
HttpURLConnection.HTTP_OK, HttpURLConnection.HTTP_ACCEPTED));
|
||||
return HttpURLConnection.HTTP_ACCEPTED;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, Object> readJsonResponse() {
|
||||
return getJsonAsMap("updateRegistrationResponse");
|
||||
}
|
||||
};
|
||||
|
||||
Session session = provider.createSession();
|
||||
Challenge.bind(session, locationUri);
|
||||
|
||||
provider.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that unmarshalling something different like a challenge fails.
|
||||
*/
|
||||
@Test(expected = IllegalArgumentException.class)
|
||||
public void testBadUnmarshall() {
|
||||
Challenge challenge = new Challenge(session);
|
||||
challenge.unmarshall(TestUtils.getJsonAsMap("updateRegistrationResponse"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that challenge serialization works correctly.
|
||||
*/
|
||||
|
|
|
@ -23,6 +23,7 @@ import org.junit.BeforeClass;
|
|||
import org.junit.Test;
|
||||
import org.shredzone.acme4j.Session;
|
||||
import org.shredzone.acme4j.Status;
|
||||
import org.shredzone.acme4j.exception.AcmeProtocolException;
|
||||
import org.shredzone.acme4j.util.ClaimBuilder;
|
||||
import org.shredzone.acme4j.util.TestUtils;
|
||||
|
||||
|
@ -62,4 +63,14 @@ public class HttpChallengeTest {
|
|||
+ KEY_AUTHORIZATION + "\"}").allowingExtraUnexpectedFields());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that an exception is thrown if there is no token.
|
||||
*/
|
||||
@Test(expected = AcmeProtocolException.class)
|
||||
public void testNoTokenSet() {
|
||||
Http01Challenge challenge = new Http01Challenge(session);
|
||||
challenge.unmarshall(TestUtils.getJsonAsMap("httpNoTokenChallenge"));
|
||||
challenge.getToken();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@ package org.shredzone.acme4j.connector;
|
|||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.net.HttpURLConnection;
|
||||
|
@ -29,6 +31,24 @@ import org.junit.experimental.categories.Category;
|
|||
*/
|
||||
public class HttpConnectorTest {
|
||||
|
||||
/**
|
||||
* Test if a HTTP connection can be opened.
|
||||
* <p>
|
||||
* This is just a mock to check that the parameters are properly set.
|
||||
*/
|
||||
@Test
|
||||
public void testMockOpenConnection() throws IOException, URISyntaxException {
|
||||
HttpURLConnection conn = mock(HttpURLConnection.class);
|
||||
|
||||
HttpConnector connector = new HttpConnector();
|
||||
connector.configure(conn);
|
||||
|
||||
verify(conn).setConnectTimeout(anyInt());
|
||||
verify(conn).setReadTimeout(anyInt());
|
||||
verify(conn).setUseCaches(false);
|
||||
verify(conn).setRequestProperty("User-Agent", HttpConnector.defaultUserAgent());
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if a HTTP connection can be opened.
|
||||
* <p>
|
||||
|
@ -45,4 +65,14 @@ public class HttpConnectorTest {
|
|||
assertThat(conn.getResponseCode(), is(HttpURLConnection.HTTP_OK));
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests that the user agent is correct.
|
||||
*/
|
||||
@Test
|
||||
public void testUserAgent() {
|
||||
String userAgent = HttpConnector.defaultUserAgent();
|
||||
assertThat(userAgent.contains("acme4j/"), is(true));
|
||||
assertThat(userAgent.contains("Java/"), is(true));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -0,0 +1,64 @@
|
|||
/*
|
||||
* acme4j - Java ACME client
|
||||
*
|
||||
* Copyright (C) 2016 Richard "Shred" Körber
|
||||
* http://acme4j.shredzone.org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
package org.shredzone.acme4j.exception;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeAgreementRequiredException}.
|
||||
*/
|
||||
public class AcmeAgreementRequiredExceptionTest {
|
||||
|
||||
/**
|
||||
* Test that parameters are correctly returned.
|
||||
*/
|
||||
@Test
|
||||
public void testAcmeAgreementRequiredException() {
|
||||
String type = "urn:ietf:params:acme:error:agreementRequired";
|
||||
String detail = "Agreement is required";
|
||||
URI agreementUri = URI.create("http://example.com/agreement.pdf");
|
||||
URI instanceUri = URI.create("http://example.com/howToAgree.html");
|
||||
|
||||
AcmeAgreementRequiredException ex
|
||||
= new AcmeAgreementRequiredException(type, detail, agreementUri, instanceUri);
|
||||
|
||||
assertThat(ex.getType(), is(type));
|
||||
assertThat(ex.getMessage(), is(detail));
|
||||
assertThat(ex.getAgreementUri(), is(agreementUri));
|
||||
assertThat(ex.getInstance(), is(instanceUri));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that optional parameters are null-safe.
|
||||
*/
|
||||
@Test
|
||||
public void testNullAcmeAgreementRequiredException() {
|
||||
String type = "urn:ietf:params:acme:error:agreementRequired";
|
||||
String detail = "Agreement is required";
|
||||
|
||||
AcmeAgreementRequiredException ex
|
||||
= new AcmeAgreementRequiredException(type, detail, null, null);
|
||||
|
||||
assertThat(ex.getType(), is(type));
|
||||
assertThat(ex.getMessage(), is(detail));
|
||||
assertThat(ex.getAgreementUri(), nullValue());
|
||||
assertThat(ex.getInstance(), nullValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* acme4j - Java ACME client
|
||||
*
|
||||
* Copyright (C) 2016 Richard "Shred" Körber
|
||||
* http://acme4j.shredzone.org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
package org.shredzone.acme4j.exception;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeConflictException}.
|
||||
*/
|
||||
public class AcmeConflictExceptionTest {
|
||||
|
||||
@Test
|
||||
public void testAcmeConflictException() {
|
||||
String msg = "Account already exists";
|
||||
URI locationUri = URI.create("http://example.com/location/123");
|
||||
|
||||
AcmeConflictException ex
|
||||
= new AcmeConflictException(msg, locationUri);
|
||||
|
||||
assertThat(ex.getMessage(), is(msg));
|
||||
assertThat(ex.getLocation(), is(locationUri));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,53 @@
|
|||
/*
|
||||
* acme4j - Java ACME client
|
||||
*
|
||||
* Copyright (C) 2016 Richard "Shred" Körber
|
||||
* http://acme4j.shredzone.org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
package org.shredzone.acme4j.exception;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeException}.
|
||||
*/
|
||||
public class AcmeExceptionTest {
|
||||
|
||||
@Test
|
||||
public void testAcmeException() {
|
||||
AcmeException ex = new AcmeException();
|
||||
assertThat(ex.getMessage(), nullValue());
|
||||
assertThat(ex.getCause(), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testMessageAcmeException() {
|
||||
String message = "Failure";
|
||||
AcmeException ex = new AcmeException(message);
|
||||
assertThat(ex.getMessage(), is(message));
|
||||
assertThat(ex.getCause(), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCausedAcmeException() {
|
||||
String message = "Failure";
|
||||
IOException cause = new IOException("No network");
|
||||
|
||||
AcmeException ex = new AcmeException(message, cause);
|
||||
assertThat(ex.getMessage(), is(message));
|
||||
assertThat(ex.getCause(), is((Throwable) cause));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
/*
|
||||
* acme4j - Java ACME client
|
||||
*
|
||||
* Copyright (C) 2016 Richard "Shred" Körber
|
||||
* http://acme4j.shredzone.org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
package org.shredzone.acme4j.exception;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeNetworkException}.
|
||||
*/
|
||||
public class AcmeNetworkExceptionTest {
|
||||
|
||||
@Test
|
||||
public void testAcmeNetworkException() {
|
||||
IOException cause = new IOException("Network not reachable");
|
||||
|
||||
AcmeNetworkException ex = new AcmeNetworkException(cause);
|
||||
|
||||
assertThat(ex.getMessage(), notNullValue());
|
||||
assertThat(ex.getCause(), is((Throwable) cause));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* acme4j - Java ACME client
|
||||
*
|
||||
* Copyright (C) 2016 Richard "Shred" Körber
|
||||
* http://acme4j.shredzone.org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
package org.shredzone.acme4j.exception;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeProtocolException}.
|
||||
*/
|
||||
public class AcmeProtocolExceptionTest {
|
||||
|
||||
@Test
|
||||
public void testAcmeProtocolException() {
|
||||
String msg = "Bad content";
|
||||
AcmeProtocolException ex = new AcmeProtocolException(msg);
|
||||
assertThat(ex, is(instanceOf(RuntimeException.class)));
|
||||
assertThat(ex.getMessage(), is(msg));
|
||||
assertThat(ex.getCause(), nullValue());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testCausedAcmeProtocolException() {
|
||||
String message = "Bad content";
|
||||
NumberFormatException cause = new NumberFormatException("Not a number: abc");
|
||||
AcmeProtocolException ex = new AcmeProtocolException(message, cause);
|
||||
assertThat(ex.getMessage(), is(message));
|
||||
assertThat(ex.getCause(), is((Throwable) cause));
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* acme4j - Java ACME client
|
||||
*
|
||||
* Copyright (C) 2016 Richard "Shred" Körber
|
||||
* http://acme4j.shredzone.org
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*/
|
||||
package org.shredzone.acme4j.exception;
|
||||
|
||||
import static org.hamcrest.Matchers.*;
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
import java.net.URI;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Date;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* Unit tests for {@link AcmeRateLimitExceededException}.
|
||||
*/
|
||||
public class AcmeRateLimitExceededExceptionTest {
|
||||
|
||||
/**
|
||||
* Test that parameters are correctly returned.
|
||||
*/
|
||||
@Test
|
||||
public void testAcmeRateLimitExceededException() {
|
||||
String type = "urn:ietf:params:acme:error:rateLimited";
|
||||
String detail = "Too many requests per minute";
|
||||
Date retryAfter = new Date(System.currentTimeMillis() + 60 * 1000L);
|
||||
Collection<URI> documents = Arrays.asList(
|
||||
URI.create("http://example.com/doc1.html"),
|
||||
URI.create("http://example.com/doc2.html"));
|
||||
|
||||
AcmeRateLimitExceededException ex
|
||||
= new AcmeRateLimitExceededException(type, detail, retryAfter, documents);
|
||||
|
||||
assertThat(ex.getType(), is(type));
|
||||
assertThat(ex.getMessage(), is(detail));
|
||||
assertThat(ex.getRetryAfter(), is(retryAfter));
|
||||
assertThat(ex.getDocuments(), containsInAnyOrder(documents.toArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that optional parameters are null-safe.
|
||||
*/
|
||||
@Test
|
||||
public void testNullAcmeRateLimitExceededException() {
|
||||
String type = "urn:ietf:params:acme:error:rateLimited";
|
||||
String detail = "Too many requests per minute";
|
||||
|
||||
AcmeRateLimitExceededException ex
|
||||
= new AcmeRateLimitExceededException(type, detail, null, null);
|
||||
|
||||
assertThat(ex.getType(), is(type));
|
||||
assertThat(ex.getMessage(), is(detail));
|
||||
assertThat(ex.getRetryAfter(), nullValue());
|
||||
assertThat(ex.getDocuments(), nullValue());
|
||||
}
|
||||
|
||||
}
|
|
@ -13,9 +13,12 @@
|
|||
*/
|
||||
package org.shredzone.acme4j.util;
|
||||
|
||||
import static org.hamcrest.Matchers.is;
|
||||
import static org.junit.Assert.*;
|
||||
import static org.shredzone.acme4j.util.TimestampParser.parse;
|
||||
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Calendar;
|
||||
import java.util.Date;
|
||||
|
@ -99,6 +102,17 @@ public class TimestampParserTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that constructor is private.
|
||||
*/
|
||||
@Test
|
||||
public void testPrivateConstructor() throws Exception {
|
||||
Constructor<TimestampParser> constructor = TimestampParser.class.getDeclaredConstructor();
|
||||
assertThat(Modifier.isPrivate(constructor.getModifiers()), is(true));
|
||||
constructor.setAccessible(true);
|
||||
constructor.newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Matches the given time.
|
||||
*/
|
||||
|
|
|
@ -218,6 +218,12 @@ httpChallenge = \
|
|||
"token": "rSoI9JpyvFi-ltdnBW0W1DjKstzG7cHixjzcOjwzAEQ" \
|
||||
}
|
||||
|
||||
httpNoTokenChallenge = \
|
||||
{ \
|
||||
"type":"http-01", \
|
||||
"status":"pending" \
|
||||
}
|
||||
|
||||
tlsSniChallenge = \
|
||||
{ \
|
||||
"type":"tls-sni-01", \
|
||||
|
|
|
@ -20,6 +20,9 @@ import java.io.ByteArrayInputStream;
|
|||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.KeyPair;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
|
@ -57,13 +60,9 @@ public class CertificateUtilsTest {
|
|||
@Test
|
||||
public void testReadWriteX509Certificate() throws IOException, CertificateException {
|
||||
// Read a demonstration certificate
|
||||
X509Certificate original;
|
||||
try (InputStream cert = getClass().getResourceAsStream("/cert.pem")) {
|
||||
original = (X509Certificate) certificateFactory.generateCertificate(cert);
|
||||
}
|
||||
assertThat(original, is(notNullValue()));
|
||||
X509Certificate original = createCertificate();
|
||||
|
||||
// Write to StringWriter
|
||||
// Write to Byte Array
|
||||
byte[] pem;
|
||||
try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
|
||||
CertificateUtils.writeX509Certificate(original, out);
|
||||
|
@ -83,6 +82,43 @@ public class CertificateUtilsTest {
|
|||
assertThat(original.getEncoded(), is(equalTo(written.getEncoded())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if
|
||||
* {@link CertificateUtils#writeX509CertificateChain(java.io.Writer, X509Certificate, X509Certificate...)}
|
||||
* writes a correct chain.
|
||||
*/
|
||||
@Test
|
||||
public void testWriteX509CertificateChain() throws IOException, CertificateException {
|
||||
X509Certificate leaf = createCertificate();
|
||||
X509Certificate chain1 = createCertificate();
|
||||
X509Certificate chain2 = createCertificate();
|
||||
|
||||
String out;
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(1));
|
||||
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf, chain1);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(2));
|
||||
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf, chain1, chain2);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(3));
|
||||
|
||||
try (StringWriter w = new StringWriter()) {
|
||||
CertificateUtils.writeX509CertificateChain(w, leaf, chain1, null, chain2);
|
||||
out = w.toString();
|
||||
}
|
||||
assertThat(countCertificates(out), is(3));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test if {@link CertificateUtils#createTlsSniCertificate(KeyPair, String)} creates a
|
||||
* good certificate.
|
||||
|
@ -155,6 +191,48 @@ public class CertificateUtilsTest {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a test certificates.
|
||||
*/
|
||||
private X509Certificate createCertificate() throws IOException, CertificateException {
|
||||
X509Certificate original;
|
||||
try (InputStream cert = getClass().getResourceAsStream("/cert.pem")) {
|
||||
original = (X509Certificate) certificateFactory.generateCertificate(cert);
|
||||
}
|
||||
assertThat(original, is(notNullValue()));
|
||||
return original;
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that constructor is private.
|
||||
*/
|
||||
@Test
|
||||
public void testPrivateConstructor() throws Exception {
|
||||
Constructor<CertificateUtils> constructor = CertificateUtils.class.getDeclaredConstructor();
|
||||
assertThat(Modifier.isPrivate(constructor.getModifiers()), is(true));
|
||||
constructor.setAccessible(true);
|
||||
constructor.newInstance();
|
||||
}
|
||||
|
||||
/**
|
||||
* Counts number of certificates in a PEM string.
|
||||
*
|
||||
* @param str
|
||||
* String containing certificates in PEM format
|
||||
* @return Number of certificates found
|
||||
*/
|
||||
private int countCertificates(String str) {
|
||||
int count = 0;
|
||||
int pos = 0;
|
||||
while (true) {
|
||||
pos = str.indexOf("-----BEGIN CERTIFICATE-----", pos);
|
||||
if (pos < 0) break;
|
||||
count++;
|
||||
pos++;
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
/**
|
||||
* Extracts all DNSName SANs from a certificate.
|
||||
*
|
||||
|
|
|
@ -19,6 +19,8 @@ import static org.junit.Assert.assertThat;
|
|||
import java.io.IOException;
|
||||
import java.io.StringReader;
|
||||
import java.io.StringWriter;
|
||||
import java.lang.reflect.Constructor;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
import java.security.interfaces.ECPublicKey;
|
||||
|
@ -131,4 +133,15 @@ public class KeyPairUtilsTest {
|
|||
assertThat(pair.getPrivate().getEncoded(), is(equalTo(readPair.getPrivate().getEncoded())));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test that constructor is private.
|
||||
*/
|
||||
@Test
|
||||
public void testPrivateConstructor() throws Exception {
|
||||
Constructor<KeyPairUtils> constructor = KeyPairUtils.class.getDeclaredConstructor();
|
||||
assertThat(Modifier.isPrivate(constructor.getModifiers()), is(true));
|
||||
constructor.setAccessible(true);
|
||||
constructor.newInstance();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue