From d1876c88aa0689510936cd77ce1c1ae183a1efef Mon Sep 17 00:00:00 2001 From: Stefan Kalscheuer Date: Tue, 20 Nov 2018 13:50:28 +0100 Subject: [PATCH] Add unit tests for secret metadata models and fixed JSON property name --- .../model/response/MetadataResponse.java | 3 +- .../response/embedded/SecretMetadata.java | 2 +- .../model/response/MetadataResponseTest.java | 100 ++++++++++++++++++ .../model/response/SecretResponseTest.java | 89 ++++++++++++++-- 4 files changed, 184 insertions(+), 10 deletions(-) create mode 100644 src/test/java/de/stklcode/jvault/connector/model/response/MetadataResponseTest.java diff --git a/src/main/java/de/stklcode/jvault/connector/model/response/MetadataResponse.java b/src/main/java/de/stklcode/jvault/connector/model/response/MetadataResponse.java index 9f00c07..24fc801 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/response/MetadataResponse.java +++ b/src/main/java/de/stklcode/jvault/connector/model/response/MetadataResponse.java @@ -49,7 +49,8 @@ public class MetadataResponse extends VaultDataResponse { /** * Get the actual metadata. - * @return + * + * @return Metadata. */ public SecretMetadata getMetadata() { return metadata; diff --git a/src/main/java/de/stklcode/jvault/connector/model/response/embedded/SecretMetadata.java b/src/main/java/de/stklcode/jvault/connector/model/response/embedded/SecretMetadata.java index f1d2f02..0f2e518 100644 --- a/src/main/java/de/stklcode/jvault/connector/model/response/embedded/SecretMetadata.java +++ b/src/main/java/de/stklcode/jvault/connector/model/response/embedded/SecretMetadata.java @@ -40,7 +40,7 @@ public final class SecretMetadata { @JsonProperty("current_version") private Integer currentVersion; - @JsonProperty("max_version") + @JsonProperty("max_versions") private Integer maxVersions; @JsonProperty("oldest_version") diff --git a/src/test/java/de/stklcode/jvault/connector/model/response/MetadataResponseTest.java b/src/test/java/de/stklcode/jvault/connector/model/response/MetadataResponseTest.java new file mode 100644 index 0000000..f0a59a9 --- /dev/null +++ b/src/test/java/de/stklcode/jvault/connector/model/response/MetadataResponseTest.java @@ -0,0 +1,100 @@ +/* + * Copyright 2016-2018 Stefan Kalscheuer + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package de.stklcode.jvault.connector.model.response; + +import com.fasterxml.jackson.databind.ObjectMapper; +import de.stklcode.jvault.connector.exception.InvalidResponseException; +import org.junit.jupiter.api.Test; + +import java.io.IOException; +import java.util.List; +import java.util.Map; + +import static org.hamcrest.MatcherAssert.assertThat; +import static org.hamcrest.Matchers.*; +import static org.junit.jupiter.api.Assertions.fail; + +/** + * JUnit Test for {@link MetadataResponse} model. + * + * @author Stefan Kalscheuer + * @since 0.8 + */ +public class MetadataResponseTest { + private static final String V1_TIME = "2018-03-22T02:24:06.945319214Z"; + private static final String V3_TIME = "2018-03-22T02:36:43.986212308Z"; + private static final String V2_TIME = "2018-03-22T02:36:33.954880664Z"; + private static final Integer CURRENT_VERSION = 3; + private static final Integer MAX_VERSIONS = 0; + private static final Integer OLDEST_VERSION = 1; + + private static final String META_JSON = "{\n" + + " \"data\": {\n" + + " \"created_time\": \"" + V1_TIME + "\",\n" + + " \"current_version\": " + CURRENT_VERSION + ",\n" + + " \"max_versions\": " + MAX_VERSIONS + ",\n" + + " \"oldest_version\": " + OLDEST_VERSION + ",\n" + + " \"updated_time\": \"" + V3_TIME + "\",\n" + + " \"versions\": {\n" + + " \"1\": {\n" + + " \"created_time\": \"" + V1_TIME + "\",\n" + + " \"deletion_time\": \"" + V2_TIME + "\",\n" + + " \"destroyed\": true\n" + + " },\n" + + " \"2\": {\n" + + " \"created_time\": \"" + V2_TIME + "\",\n" + + " \"deletion_time\": \"\",\n" + + " \"destroyed\": false\n" + + " },\n" + + " \"3\": {\n" + + " \"created_time\": \"" + V3_TIME + "\",\n" + + " \"deletion_time\": \"\",\n" + + " \"destroyed\": false\n" + + " }\n" + + " }\n" + + " }\n" + + "}"; + + /** + * Test creation from JSON value as returned by Vault (JSON example copied from Vault documentation). + */ + @Test + public void jsonRoundtrip() { + try { + MetadataResponse res = new ObjectMapper().readValue(META_JSON, MetadataResponse.class); + assertThat("Parsed response is NULL", res, is(notNullValue())); + assertThat("Parsed metadatra is NULL", res.getMetadata(), is(notNullValue())); + assertThat("Incorrect created time", res.getMetadata().getCreatedTimeString(), is(V1_TIME)); + assertThat("Parting created time failed", res.getMetadata().getCreatedTime(), is(notNullValue())); + assertThat("Incorrect current version", res.getMetadata().getCurrentVersion(), is(CURRENT_VERSION)); + assertThat("Incorrect max versions", res.getMetadata().getMaxVersions(), is(MAX_VERSIONS)); + assertThat("Incorrect oldest version", res.getMetadata().getOldestVersion(), is(OLDEST_VERSION)); + assertThat("Incorrect updated time", res.getMetadata().getUpdatedTimeString(), is(V3_TIME)); + assertThat("Parting updated time failed", res.getMetadata().getUpdatedTime(), is(notNullValue())); + assertThat("Incorrect number of versions", res.getMetadata().getVersions().size(), is(3)); + assertThat("Incorrect version 1 delete time", res.getMetadata().getVersions().get(1).getDeletionTimeString(), is(V2_TIME)); + assertThat("Parsion version delete time failed", res.getMetadata().getVersions().get(1).getDeletionTime(), is(notNullValue())); + assertThat("Incorrect version 1 destroyed state", res.getMetadata().getVersions().get(1).isDestroyed(), is(true)); + assertThat("Incorrect version 2 created time", res.getMetadata().getVersions().get(2).getCreatedTimeString(), is(V2_TIME)); + assertThat("Parsion version created failed", res.getMetadata().getVersions().get(2).getCreatedTime(), is(notNullValue())); + assertThat("Incorrect version 3 destroyed state", res.getMetadata().getVersions().get(3).isDestroyed(), is(false)); + + } catch (IOException e) { + fail("MetadataResoponse deserialization failed: " + e.getMessage()); + } + } +} diff --git a/src/test/java/de/stklcode/jvault/connector/model/response/SecretResponseTest.java b/src/test/java/de/stklcode/jvault/connector/model/response/SecretResponseTest.java index 310aa97..f23c59c 100644 --- a/src/test/java/de/stklcode/jvault/connector/model/response/SecretResponseTest.java +++ b/src/test/java/de/stklcode/jvault/connector/model/response/SecretResponseTest.java @@ -53,6 +53,8 @@ public class SecretResponseTest { private static final String SECRET_DATA_V1 = "yes"; private static final String SECRET_DATA_K2 = "value"; private static final String SECRET_DATA_V2 = "world"; + private static final String SECRET_META_CREATED = "2018-03-22T02:24:06.945319214Z"; + private static final String SECRET_META_DELETED = "2018-03-23T03:25:07.056420325Z"; private static final List SECRET_WARNINGS = null; private static final String SECRET_JSON = "{\n" + " \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" + @@ -65,6 +67,44 @@ public class SecretResponseTest { " },\n" + " \"warnings\": " + SECRET_WARNINGS + "\n" + "}"; + private static final String SECRET_JSON_V2 = "{\n" + + " \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" + + " \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" + + " \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" + + " \"renewable\": " + SECRET_RENEWABLE + ",\n" + + " \"data\": {\n" + + " \"data\": {\n" + + " \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" + + " \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" + + " },\n" + + " \"metadata\": {\n" + + " \"created_time\": \"" + SECRET_META_CREATED + "\",\n" + + " \"deletion_time\": \"\",\n" + + " \"destroyed\": false,\n" + + " \"version\": 1\n" + + " }\n" + + " },\n" + + " \"warnings\": " + SECRET_WARNINGS + "\n" + + "}"; + private static final String SECRET_JSON_V2_2 = "{\n" + + " \"request_id\": \"" + SECRET_REQUEST_ID + "\",\n" + + " \"lease_id\": \"" + SECRET_LEASE_ID + "\",\n" + + " \"lease_duration\": " + SECRET_LEASE_DURATION + ",\n" + + " \"renewable\": " + SECRET_RENEWABLE + ",\n" + + " \"data\": {\n" + + " \"data\": {\n" + + " \"" + SECRET_DATA_K1 + "\": \"" + SECRET_DATA_V1 + "\",\n" + + " \"" + SECRET_DATA_K2 + "\": \"" + SECRET_DATA_V2 + "\"\n" + + " },\n" + + " \"metadata\": {\n" + + " \"created_time\": \"" + SECRET_META_CREATED + "\",\n" + + " \"deletion_time\": \"" + SECRET_META_DELETED + "\",\n" + + " \"destroyed\": true,\n" + + " \"version\": 2\n" + + " }\n" + + " },\n" + + " \"warnings\": " + SECRET_WARNINGS + "\n" + + "}"; static { @@ -118,16 +158,49 @@ public class SecretResponseTest { @Test public void jsonRoundtrip() { try { - SecretResponse res = new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class); - assertThat("Parsed response is NULL", res, is(notNullValue())); - assertThat("Incorrect lease ID", res.getLeaseId(), is(SECRET_LEASE_ID)); - assertThat("Incorrect lease duration", res.getLeaseDuration(), is(SECRET_LEASE_DURATION)); - assertThat("Incorrect renewable status", res.isRenewable(), is(SECRET_RENEWABLE)); - assertThat("Incorrect warnings", res.getWarnings(), is(SECRET_WARNINGS)); - assertThat("Response does not contain correct data", res.get(SECRET_DATA_K1), is(SECRET_DATA_V1)); - assertThat("Response does not contain correct data", res.get(SECRET_DATA_K2), is(SECRET_DATA_V2)); + assertSecretData(new ObjectMapper().readValue(SECRET_JSON, SecretResponse.class)); + } catch (IOException e) { + fail("SecretResponse deserialization failed: " + e.getMessage()); + } + + // KV v2 secret. + try { + SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2, SecretResponse.class); + assertSecretData(res); + assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue())); + assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED)); + assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue())); + assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(emptyString())); + assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(nullValue())); + assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(false)); + assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(1)); + } catch (IOException e) { + fail("SecretResponse deserialization failed: " + e.getMessage()); + } + + // Deleted KV v2 secret. + try { + SecretResponse res = new ObjectMapper().readValue(SECRET_JSON_V2_2, SecretResponse.class); + assertSecretData(res); + assertThat("SecretResponse does not contain metadata", res.getMetadata(), is(notNullValue())); + assertThat("Incorrect creation date string", res.getMetadata().getCreatedTimeString(), is(SECRET_META_CREATED)); + assertThat("Creation date parsing failed", res.getMetadata().getCreatedTime(), is(notNullValue())); + assertThat("Incorrect deletion date string", res.getMetadata().getDeletionTimeString(), is(SECRET_META_DELETED)); + assertThat("Incorrect deletion date", res.getMetadata().getDeletionTime(), is(notNullValue())); + assertThat("Secret destroyed when not expected", res.getMetadata().isDestroyed(), is(true)); + assertThat("Incorrect secret version", res.getMetadata().getVersion(), is(2)); } catch (IOException e) { fail("SecretResponse deserialization failed: " + e.getMessage()); } } + + private void assertSecretData(SecretResponse res) { + assertThat("Parsed response is NULL", res, is(notNullValue())); + assertThat("Incorrect lease ID", res.getLeaseId(), is(SECRET_LEASE_ID)); + assertThat("Incorrect lease duration", res.getLeaseDuration(), is(SECRET_LEASE_DURATION)); + assertThat("Incorrect renewable status", res.isRenewable(), is(SECRET_RENEWABLE)); + assertThat("Incorrect warnings", res.getWarnings(), is(SECRET_WARNINGS)); + assertThat("Response does not contain correct data", res.get(SECRET_DATA_K1), is(SECRET_DATA_V1)); + assertThat("Response does not contain correct data", res.get(SECRET_DATA_K2), is(SECRET_DATA_V2)); + } }