Add VKey to String and String to VKey methods (#1396)

* Add stringify and parse methods to SerializeUTils

* Improve comments and test cases

* Fix comments and test strings

* Fix dependency warning
This commit is contained in:
Rachel Guan 2021-11-02 13:25:35 -04:00 committed by GitHub
parent 230daeeab7
commit adb82565db
6 changed files with 325 additions and 1 deletions

View file

@ -22,7 +22,9 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import javax.annotation.Nullable;
import org.apache.commons.codec.binary.Base64;
/** Utilities for easy serialization with informative error messages. */
public final class SerializeUtils {
@ -47,7 +49,7 @@ public final class SerializeUtils {
}
/**
* Turns a byte array into an object.
* Turns a byte string into an object.
*
* @return deserialized object or {@code null} if {@code objectBytes} is {@code null}
*/
@ -71,4 +73,19 @@ public final class SerializeUtils {
}
private SerializeUtils() {}
/** Turns an object into an encoded string that can be used safely as a URI query parameter. */
public static String stringify(Serializable object) {
checkNotNull(object, "Object cannot be null");
return Base64.encodeBase64URLSafeString(SerializeUtils.serialize(object));
}
/** Turns a string encoded by stringify() into an object. */
@Nullable
public static <T> T parse(Class<T> type, String objectString) {
checkNotNull(type, "Class type is not specified");
checkNotNull(objectString, "Object string cannot be null");
return SerializeUtils.deserialize(type, Base64.decodeBase64(objectString));
}
}

View file

@ -16,9 +16,12 @@ package google.registry.util;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.util.SerializeUtils.deserialize;
import static google.registry.util.SerializeUtils.parse;
import static google.registry.util.SerializeUtils.serialize;
import static google.registry.util.SerializeUtils.stringify;
import static org.junit.jupiter.api.Assertions.assertThrows;
import java.io.Serializable;
import org.junit.jupiter.api.Test;
/** Unit tests for {@link SerializeUtils}. */
@ -61,4 +64,51 @@ class SerializeUtilsTest {
() -> deserialize(String.class, new byte[] {(byte) 0xff}));
assertThat(thrown).hasMessageThat().contains("Unable to deserialize: objectBytes=FF");
}
@Test
void testStringify_string_returnsBase64EncodedString() {
assertThat(stringify("foo")).isEqualTo("rO0ABXQAA2Zvbw");
}
@Test
void testParse_stringClass_returnsObject() {
assertThat(parse(String.class, "rO0ABXQAA2Zvbw")).isEqualTo("foo");
}
@Test
void testStringifyParse_stringValue_maintainsValue() {
assertThat(parse(Serializable.class, stringify("hello"))).isEqualTo("hello");
}
@Test
void testStringifyParse_longValue_maintainsValue() {
assertThat(parse(Serializable.class, stringify((long) 12345))).isEqualTo((long) 12345);
}
@Test
void testStringify_nullValue_throwsException() {
NullPointerException thrown = assertThrows(NullPointerException.class, () -> stringify(null));
assertThat(thrown).hasMessageThat().contains("Object cannot be null");
}
@Test
void testParse_nullClass_throwsException() {
NullPointerException thrown =
assertThrows(NullPointerException.class, () -> parse(null, "test"));
assertThat(thrown).hasMessageThat().contains("Class type is not specified");
}
@Test
void testParse_invalidBase64String_throwsException() {
IllegalArgumentException thrown =
assertThrows(IllegalArgumentException.class, () -> parse(String.class, "abcde:atest"));
assertThat(thrown).hasMessageThat().contains("Unable to deserialize");
}
@Test
void testParse_nullObjectStringValue_throwsException() {
NullPointerException thrown =
assertThrows(NullPointerException.class, () -> parse(String.class, null));
assertThat(thrown).hasMessageThat().contains("Object string cannot be null");
}
}