001/*
002 * acme4j - Java ACME client
003 *
004 * Copyright (C) 2016 Richard "Shred" Körber
005 *   http://acme4j.shredzone.org
006 *
007 * Licensed under the Apache License, Version 2.0 (the "License");
008 * you may not use this file except in compliance with the License.
009 *
010 * This program is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
013 */
014package org.shredzone.acme4j;
015
016import static org.assertj.core.api.Assertions.assertThat;
017import static org.junit.jupiter.api.Assertions.assertThrows;
018
019import java.io.ByteArrayInputStream;
020import java.io.ByteArrayOutputStream;
021import java.io.ObjectInputStream;
022import java.io.ObjectOutputStream;
023import java.net.URL;
024import java.nio.charset.StandardCharsets;
025
026import org.junit.jupiter.api.Test;
027import org.shredzone.acme4j.toolbox.TestUtils;
028
029/**
030 * Unit tests for {@link AcmeResource}.
031 */
032public class AcmeResourceTest {
033
034    /**
035     * Test constructors and setters
036     */
037    @Test
038    public void testConstructor() throws Exception {
039        var login = TestUtils.login();
040        var location = new URL("http://example.com/acme/resource");
041
042        assertThrows(NullPointerException.class, () -> new DummyResource(null, null));
043
044        var resource = new DummyResource(login, location);
045        assertThat(resource.getLogin()).isEqualTo(login);
046        assertThat(resource.getLocation()).isEqualTo(location);
047    }
048
049    /**
050     * Test if {@link AcmeResource} is properly serialized.
051     */
052    @Test
053    public void testSerialization() throws Exception {
054        var login = TestUtils.login();
055        var location = new URL("http://example.com/acme/resource");
056
057        // Create a Challenge for testing
058        var challenge = new DummyResource(login, location);
059        assertThat(challenge.getLogin()).isEqualTo(login);
060
061        // Serialize it
062        byte[] serialized;
063        try (var baos = new ByteArrayOutputStream()) {
064            try (var out = new ObjectOutputStream(baos)) {
065                out.writeObject(challenge);
066            }
067            serialized = baos.toByteArray();
068        }
069
070        // Make sure there is no PrivateKey in the stream
071        var str = new String(serialized, StandardCharsets.ISO_8859_1);
072        assertThat(str).as("serialized stream contains a PrivateKey")
073                .doesNotContain("Ljava/security/PrivateKey");
074
075        // Deserialize to new object
076        DummyResource restored;
077        try (var bais = new ByteArrayInputStream(serialized);
078                var in = new ObjectInputStream(bais)) {
079            var obj = in.readObject();
080            assertThat(obj).isInstanceOf(DummyResource.class);
081            restored = (DummyResource) obj;
082        }
083        assertThat(restored).isNotSameAs(challenge);
084
085        // Make sure the restored object is not attached to a login
086        assertThrows(IllegalStateException.class, restored::getLogin);
087
088        // Rebind to login
089        restored.rebind(login);
090
091        // Make sure the new login is set
092        assertThat(restored.getLogin()).isEqualTo(login);
093    }
094
095    /**
096     * Test if a rebind attempt fails.
097     */
098    @Test
099    public void testRebind() {
100        assertThrows(IllegalStateException.class, () -> {
101            var login = TestUtils.login();
102            var location = new URL("http://example.com/acme/resource");
103
104            var resource = new DummyResource(login, location);
105            assertThat(resource.getLogin()).isEqualTo(login);
106
107            var login2 = TestUtils.login();
108            resource.rebind(login2); // fails to rebind to another login
109        });
110    }
111
112    /**
113     * Minimum implementation of {@link AcmeResource}.
114     */
115    private static class DummyResource extends AcmeResource {
116        private static final long serialVersionUID = 7188822681353082472L;
117        public DummyResource(Login login, URL location) {
118            super(login, location);
119        }
120    }
121
122}