package org.mongodb.morphia.mapping.lazy;


import org.junit.Assert;
import org.junit.Ignore;
import org.junit.Test;
import org.bson.types.ObjectId;
import org.mongodb.morphia.Key;
import org.mongodb.morphia.annotations.IdGetter;
import org.mongodb.morphia.annotations.Reference;
import org.mongodb.morphia.mapping.lazy.proxy.LazyReferenceFetchingException;
import org.mongodb.morphia.mapping.lazy.proxy.ProxiedEntityReference;
import org.mongodb.morphia.testutil.TestEntity;


public class TestLazySingleReference extends ProxyTestBase {
    @Ignore
    @Test
    public final void testCreateProxy() {

        if (!LazyFeatureDependencies.testDependencyFullFilled()) {
            return;
        }

        RootEntity root = new RootEntity();
        final ReferencedEntity referenced = new ReferencedEntity();

        root.r = referenced;
        root.r.setFoo("bar");

        getDs().save(referenced);
        getDs().save(root);

        root = getDs().get(root);

        assertNotFetched(root.r);
        Assert.assertEquals("bar", root.r.getFoo());
        assertFetched(root.r);
        Assert.assertEquals("bar", root.r.getFoo());

        // now remove it from DB
        getDs().delete(root.r);

        root = deserialize(root);
        assertNotFetched(root.r);

        try {
            // must fail
            root.r.getFoo();
            Assert.fail("Expected Exception did not happen");
        } catch (LazyReferenceFetchingException expected) {
            // fine
        }

    }

    @Test
    public final void testGetKeyWithoutFetching() {
        if (!LazyFeatureDependencies.testDependencyFullFilled()) {
            return;
        }

        RootEntity root = new RootEntity();
        final ReferencedEntity reference = new ReferencedEntity();

        root.r = reference;
        reference.setFoo("bar");

        final Key<ReferencedEntity> k = getDs().save(reference);
        final String keyAsString = k.getId().toString();
        getDs().save(root);

        root = getDs().get(root);

        final ReferencedEntity p = root.r;

        assertIsProxy(p);
        assertNotFetched(p);
        Assert.assertEquals(keyAsString, getDs().getKey(p).getId().toString());
        // still not fetched?
        assertNotFetched(p);
        p.getFoo();
        // should be fetched now.
        assertFetched(p);

    }

    @Test
    public final void testCallIdGetterWithoutFetching() {
        if (!LazyFeatureDependencies.testDependencyFullFilled()) {
            return;
        }

        RootEntity root = new RootEntity();
        final ReferencedEntity reference = new ReferencedEntity();
        ObjectId id = reference.getId();
        getDs().save(reference);

        root.r = reference;
        reference.setFoo("bar");
        getDs().save(root);

        root = getDs().get(root);

        final ReferencedEntity p = root.r;

        assertIsProxy(p);
        assertNotFetched(p);

        ObjectId idFromProxy = p.getId();
        Assert.assertEquals(id, idFromProxy);

        // Since getId() is annotated with @IdGetter, it should not cause the
        // referenced entity to be fetched
        assertNotFetched(p);

        p.getFoo();

        // Calling getFoo() should have caused the referenced entity to be fetched
        assertFetched(p);

    }

    @Test
    public final void testSameProxy() {
        if (!LazyFeatureDependencies.testDependencyFullFilled()) {
            return;
        }

        RootEntity root = new RootEntity();
        final ReferencedEntity reference = new ReferencedEntity();

        root.r = reference;
        root.secondReference = reference;
        reference.setFoo("bar");

        getDs().save(reference);
        getDs().save(root);

        root = getDs().get(root);
        Assert.assertSame(root.r, root.secondReference);
    }

    @Ignore
    @Test
    public final void testSerialization() {
        if (!LazyFeatureDependencies.testDependencyFullFilled()) {
            return;
        }

        RootEntity e1 = new RootEntity();
        final ReferencedEntity e2 = new ReferencedEntity();

        e1.r = e2;
        e2.setFoo("bar");

        getDs().save(e2);
        getDs().save(e1);

        e1 = deserialize(getDs().get(e1));

        assertNotFetched(e1.r);
        Assert.assertEquals("bar", e1.r.getFoo());
        assertFetched(e1.r);

        e1 = deserialize(e1);
        assertNotFetched(e1.r);
        Assert.assertEquals("bar", e1.r.getFoo());
        assertFetched(e1.r);

    }

    @Test
    public final void testShortcutInterface() {
        if (!LazyFeatureDependencies.testDependencyFullFilled()) {
            return;
        }

        RootEntity root = new RootEntity();
        final ReferencedEntity reference = new ReferencedEntity();
        final ReferencedEntity second = new ReferencedEntity();

        root.r = reference;
        root.secondReference = second;
        reference.setFoo("bar");

        final Key<ReferencedEntity> k = getDs().save(reference);
        getDs().save(second);
        final Object key = k.getId();
        getDs().save(root);

        root = getDs().get(root);

        ReferencedEntity referenced = root.r;

        assertIsProxy(referenced);
        assertNotFetched(referenced);
        Assert.assertEquals(key, ((ProxiedEntityReference) referenced).__getKey().getId());
        // still not fetched?
        assertNotFetched(referenced);
        assertNotFetched(root.secondReference);
        referenced.getFoo();
        // should be fetched now.
        assertFetched(referenced);
        assertNotFetched(root.secondReference);
        root.secondReference.getFoo();
        assertFetched(root.secondReference);

        root = getDs().get(root);
        assertNotFetched(root.r);
        assertNotFetched(root.secondReference);
        getDs().save(root);
        assertNotFetched(root.r);
        assertNotFetched(root.secondReference);
    }

    public static class RootEntity extends TestEntity {
        @Reference(lazy = true)
        private ReferencedEntity r;
        @Reference(lazy = true)
        private ReferencedEntity secondReference;

    }

    public static class ReferencedEntity extends TestEntity {
        private String foo;

        @Override
        @IdGetter
        public ObjectId getId() {
            return super.getId();
        }

        public String getFoo() {
            return foo;
        }

        public void setFoo(final String string) {
            foo = string;
        }
    }

}

@@ -52,20 +52,27 @@
 org.
-junit.Assert
+bson.types.ObjectId
 ;%0Aim
@@ -86,22 +86,22 @@
 g.junit.
-Ignore
+Assert
 ;%0Aimport
@@ -121,40 +121,8 @@
 st;%0A
-import org.bson.types.ObjectId;%0A
 impo
@@ -252,86 +252,8 @@
 ce;%0A
-import org.mongodb.morphia.mapping.lazy.proxy.LazyReferenceFetchingException;%0A
 impo
@@ -432,976 +432,8 @@
 se %7B
-%0A    @Ignore%0A    @Test%0A    public final void testCreateProxy() %7B%0A%0A        if (!LazyFeatureDependencies.testDependencyFullFilled()) %7B%0A            return;%0A        %7D%0A%0A        RootEntity root = new RootEntity();%0A        final ReferencedEntity referenced = new ReferencedEntity();%0A%0A        root.r = referenced;%0A        root.r.setFoo(%22bar%22);%0A%0A        getDs().save(referenced);%0A        getDs().save(root);%0A%0A        root = getDs().get(root);%0A%0A        assertNotFetched(root.r);%0A        Assert.assertEquals(%22bar%22, root.r.getFoo());%0A        assertFetched(root.r);%0A        Assert.assertEquals(%22bar%22, root.r.getFoo());%0A%0A        // now remove it from DB%0A        getDs().delete(root.r);%0A%0A        root = deserialize(root);%0A        assertNotFetched(root.r);%0A%0A        try %7B%0A            // must fail%0A            root.r.getFoo();%0A            Assert.fail(%22Expected Exception did not happen%22);%0A        %7D catch (LazyReferenceFetchingException expected) %7B%0A            // fine%0A        %7D%0A%0A    %7D
 %0A%0A  
@@ -2759,681 +2759,8 @@
  %7D%0A%0A
-    @Ignore%0A    @Test%0A    public final void testSerialization() %7B%0A        if (!LazyFeatureDependencies.testDependencyFullFilled()) %7B%0A            return;%0A        %7D%0A%0A        RootEntity e1 = new RootEntity();%0A        final ReferencedEntity e2 = new ReferencedEntity();%0A%0A        e1.r = e2;%0A        e2.setFoo(%22bar%22);%0A%0A        getDs().save(e2);%0A        getDs().save(e1);%0A%0A        e1 = deserialize(getDs().get(e1));%0A%0A        assertNotFetched(e1.r);%0A        Assert.assertEquals(%22bar%22, e1.r.getFoo());%0A        assertFetched(e1.r);%0A%0A        e1 = deserialize(e1);%0A        assertNotFetched(e1.r);%0A        Assert.assertEquals(%22bar%22, e1.r.getFoo());%0A        assertFetched(e1.r);%0A%0A    %7D%0A%0A
     

remove outdated tests