A @DoNotHydrate annotation for toHydratedString

This is needed for a soon-to-be-submitted CL that changes
all Refs to Keys and therefore removes the logic in
toHydratedString that doesn't expand Keys. We need to be
able to tag types as unexpandable to avoid cycles. It
would be better to tag fields, not types, but that is a
much harder change and not currently needed by the use
case of the following CL, so for now this suffices.

While I am in here, add tests for all of the features
of toHydratedString.

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=131618634
This commit is contained in:
cgoldfeder 2016-08-29 11:56:35 -07:00 committed by Ben McIlwain
parent d77dced024
commit 8059ab5c90
2 changed files with 129 additions and 1 deletions

View file

@ -19,12 +19,22 @@ import static com.google.common.collect.Maps.newHashMap;
import static com.google.common.collect.Sets.newHashSet;
import static com.google.common.truth.Truth.assertThat;
import static google.registry.model.ImmutableObject.cloneEmptyToNull;
import static google.registry.testing.DatastoreHelper.persistActiveContact;
import static google.registry.testing.DatastoreHelper.persistResource;
import static google.registry.util.DateTimeUtils.START_OF_TIME;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Iterables;
import com.googlecode.objectify.Key;
import com.googlecode.objectify.ObjectifyService;
import com.googlecode.objectify.Ref;
import com.googlecode.objectify.annotation.Entity;
import com.googlecode.objectify.annotation.Id;
import google.registry.model.ImmutableObject.DoNotHydrate;
import google.registry.model.domain.ReferenceUnion;
import google.registry.testing.AppEngineRule;
import google.registry.util.CidrAddressBlock;
import java.util.ArrayDeque;
import java.util.Arrays;
@ -33,6 +43,8 @@ import java.util.List;
import java.util.Map;
import java.util.Set;
import org.joda.time.DateTime;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
@ -41,6 +53,17 @@ import org.junit.runners.JUnit4;
@RunWith(JUnit4.class)
public class ImmutableObjectTest {
@Rule
public final AppEngineRule appEngine = AppEngineRule.builder()
.withDatastore()
.build();
@Before
public void register() {
ObjectifyService.register(HydratableObject.class);
ObjectifyService.register(UnhydratableObject.class);
}
/** Simple subclass of ImmutableObject. */
public static class SimpleObject extends ImmutableObject {
String a;
@ -232,4 +255,95 @@ public class ImmutableObjectTest {
assertThat(cloned.heterogenousMap).containsEntry("a", new SimpleObject("", ""));
assertThat(cloned.heterogenousMap).containsEntry("b", "");
}
/** Subclass of ImmutableObject with keys to other objects. */
public static class RootObject extends ImmutableObject {
Ref<HydratableObject> hydratable;
Ref<UnhydratableObject> unhydratable;
Key<HydratableObject> key;
Map<String, Ref<?>> map;
Set<Ref<?>> set;
ReferenceUnion<?> referenceUnion;
}
/** Hydratable subclass of ImmutableObject. */
@Entity
public static class HydratableObject extends ImmutableObject {
@Id
long id = 1;
String value;
}
/** Unhydratable subclass of SimpleObject. */
@Entity
@DoNotHydrate
public static class UnhydratableObject extends ImmutableObject {
@Id
long id = 1;
String value;
}
@Test
public void testToHydratedString_skipsDoNotHydrate() {
HydratableObject hydratable = new HydratableObject();
hydratable.value = "expected";
UnhydratableObject unhydratable = new UnhydratableObject();
unhydratable.value = "unexpected";
RootObject root = new RootObject();
root.hydratable = Ref.create(persistResource(hydratable));
root.unhydratable = Ref.create(persistResource(unhydratable));
assertThat(root.toHydratedString()).contains("expected");
assertThat(root.toHydratedString()).doesNotContain("unexpected");
}
@Test
public void testToHydratedString_skipsKeys() {
HydratableObject hydratable = new HydratableObject();
hydratable.value = "unexpected";
RootObject root = new RootObject();
root.key = Key.create(persistResource(hydratable));
assertThat(root.toHydratedString()).doesNotContain("unexpected");
}
@Test
public void testToHydratedString_expandsMaps() {
HydratableObject hydratable = new HydratableObject();
hydratable.value = "expected";
UnhydratableObject unhydratable = new UnhydratableObject();
unhydratable.value = "unexpected";
RootObject root = new RootObject();
root.map = ImmutableMap.<String, Ref<?>>of(
"hydratable", Ref.create(persistResource(hydratable)),
"unhydratable", Ref.create(persistResource(unhydratable)));
assertThat(root.toHydratedString()).contains("expected");
assertThat(root.toHydratedString()).doesNotContain("unexpected");
}
@Test
public void testToHydratedString_expandsCollections() {
HydratableObject hydratable = new HydratableObject();
hydratable.value = "expected";
UnhydratableObject unhydratable = new UnhydratableObject();
unhydratable.value = "unexpected";
RootObject root = new RootObject();
root.set = ImmutableSet.<Ref<?>>of(
Ref.create(persistResource(hydratable)),
Ref.create(persistResource(unhydratable)));
assertThat(root.toHydratedString()).contains("expected");
assertThat(root.toHydratedString()).doesNotContain("unexpected");
}
@Test
public void testToHydratedString_expandsReferenceUnions() {
RootObject root = new RootObject();
root.referenceUnion = ReferenceUnion.create(Ref.create(persistActiveContact("expected")));
assertThat(root.toHydratedString()).contains("expected");
}
}