001/*
002 * acme4j - Java ACME client
003 *
004 * Copyright (C) 2015 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.toolbox;
015
016import static org.assertj.core.api.Assertions.assertThat;
017
018import java.io.IOException;
019import java.time.Duration;
020import java.time.ZoneId;
021import java.time.ZonedDateTime;
022import java.util.Arrays;
023import java.util.Collections;
024import java.util.Map;
025
026import org.jose4j.json.JsonUtil;
027import org.jose4j.lang.JoseException;
028import org.junit.jupiter.api.Test;
029
030/**
031 * Unit test for {@link JSONBuilder}.
032 */
033public class JSONBuilderTest {
034
035    /**
036     * Test that an empty JSON builder is empty.
037     */
038    @Test
039    public void testEmpty() {
040        var cb = new JSONBuilder();
041        assertThat(cb.toString()).isEqualTo("{}");
042    }
043
044    /**
045     * Test basic data types. Also test that methods return {@code this}, and that
046     * existing keys are replaced.
047     */
048    @Test
049    public void testBasics() {
050        JSONBuilder res;
051
052        var cb = new JSONBuilder();
053        res = cb.put("fooStr", "String");
054        assertThat(res).isSameAs(cb);
055
056        res = cb.put("fooInt", 123);
057        assertThat(res).isSameAs(cb);
058
059        res = cb.put("fooInt", 456);
060        assertThat(res).isSameAs(cb);
061
062        assertThat(cb.toString()).isEqualTo("{\"fooStr\":\"String\",\"fooInt\":456}");
063
064        var map = cb.toMap();
065        assertThat(map.keySet()).hasSize(2);
066        assertThat(map).extracting("fooInt").isEqualTo(456);
067        assertThat(map).extracting("fooStr").isEqualTo("String");
068
069        var json = cb.toJSON();
070        assertThat(json.keySet()).hasSize(2);
071        assertThat(json.get("fooInt").asInt()).isEqualTo(456);
072        assertThat(json.get("fooStr").asString()).isEqualTo("String");
073    }
074
075    /**
076     * Test date type.
077     */
078    @Test
079    public void testDate() {
080        var date = ZonedDateTime.of(2016, 6, 1, 5, 13, 46, 0, ZoneId.of("GMT+2")).toInstant();
081        var duration = Duration.ofMinutes(5);
082
083        var cb = new JSONBuilder();
084        cb.put("fooDate", date);
085        cb.put("fooDuration", duration);
086        cb.put("fooNull", (Object) null);
087
088        assertThat(cb.toString()).isEqualTo("{\"fooDate\":\"2016-06-01T03:13:46Z\",\"fooDuration\":300,\"fooNull\":null}");
089    }
090
091    /**
092     * Test base64 encoding.
093     */
094    @Test
095    public void testBase64() {
096        var data = "abc123".getBytes();
097
098        JSONBuilder res;
099
100        var cb = new JSONBuilder();
101        res = cb.putBase64("foo", data);
102        assertThat(res).isSameAs(cb);
103        assertThat(cb.toString()).isEqualTo("{\"foo\":\"YWJjMTIz\"}");
104    }
105
106    /**
107     * Test JWK.
108     */
109    @Test
110    public void testKey() throws IOException, JoseException {
111        var keyPair = TestUtils.createKeyPair();
112
113        JSONBuilder res;
114
115        var cb = new JSONBuilder();
116        res = cb.putKey("foo", keyPair.getPublic());
117        assertThat(res).isSameAs(cb);
118
119        var json = JsonUtil.parseJson(cb.toString());
120        assertThat(json).containsKey("foo");
121
122        var jwk = (Map<String, String>) json.get("foo");
123        assertThat(jwk.keySet()).hasSize(3);
124        assertThat(jwk).extracting("n").isEqualTo(TestUtils.N);
125        assertThat(jwk).extracting("e").isEqualTo(TestUtils.E);
126        assertThat(jwk).extracting("kty").isEqualTo(TestUtils.KTY);
127    }
128
129    /**
130     * Test sub claims (objects).
131     */
132    @Test
133    public void testObject() {
134        var cb = new JSONBuilder();
135        var sub = cb.object("sub");
136        assertThat(sub).isNotSameAs(cb);
137
138        assertThat(cb.toString()).isEqualTo("{\"sub\":{}}");
139
140        cb.put("foo", 123);
141        sub.put("foo", 456);
142
143        assertThat(cb.toString()).isEqualTo("{\"sub\":{\"foo\":456},\"foo\":123}");
144    }
145
146    /**
147     * Test arrays.
148     */
149    @Test
150    public void testArray() {
151        JSONBuilder res;
152
153        var cb1 = new JSONBuilder();
154        res = cb1.array("ar", Collections.emptyList());
155        assertThat(res).isSameAs(cb1);
156        assertThat(cb1.toString()).isEqualTo("{\"ar\":[]}");
157
158        var cb2 = new JSONBuilder();
159        res = cb2.array("ar", Collections.singletonList(123));
160        assertThat(res).isSameAs(cb2);
161        assertThat(cb2.toString()).isEqualTo("{\"ar\":[123]}");
162
163        var cb3 = new JSONBuilder();
164        res = cb3.array("ar", Arrays.asList(123, "foo", 456));
165        assertThat(res).isSameAs(cb3);
166        assertThat(cb3.toString()).isEqualTo("{\"ar\":[123,\"foo\",456]}");
167    }
168
169}