package org.mongodb.morphia.query;

import java.util.List;

import org.bson.types.ObjectId;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.TestBase;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import org.mongodb.morphia.annotations.Index;
import org.mongodb.morphia.annotations.Indexes;

public class TestMaxMin extends TestBase {

    @Entity("IndexedEntity")
    @Indexes({
            @Index("testField"),
            @Index("testField, id")
    })
    private static class IndexedEntity {

        @Id
        private ObjectId id;
        private String testField;

        private IndexedEntity(String testField) {
            this.testField = testField;
        }

        private IndexedEntity() {
        }
    }

    @Override
    @Before
    public void setUp() {
        super.setUp();
        getMorphia().map(IndexedEntity.class);
        getDs().ensureIndexes();
    }

    @Test
    public void testMax() {
        final IndexedEntity a = new IndexedEntity("a");
        final IndexedEntity b = new IndexedEntity("b");
        final IndexedEntity c = new IndexedEntity("c");

        Datastore ds = getDs();

        ds.save(a);
        ds.save(b);
        ds.save(c);

        Assert.assertEquals("last", b.id, ds.createQuery(IndexedEntity.class).order("-id").max("testField", "c").get().id);
    }

    @Test
    public void testMaxCompoundIndex() {
        final IndexedEntity a1 = new IndexedEntity("a");
        final IndexedEntity a2 = new IndexedEntity("a");
        final IndexedEntity b1 = new IndexedEntity("b");
        final IndexedEntity b2 = new IndexedEntity("b");
        final IndexedEntity c1 = new IndexedEntity("c");
        final IndexedEntity c2 = new IndexedEntity("c");

        Datastore ds = getDs();

        ds.save(a1);
        ds.save(a2);
        ds.save(b1);
        ds.save(b2);
        ds.save(c1);
        ds.save(c2);

        List<IndexedEntity> l = ds.createQuery(IndexedEntity.class).order("testField, id").max("testField", "b").max("id", b2.id).asList();

        Assert.assertEquals("size", 3, l.size());
        Assert.assertEquals("item", b1.id, l.get(2).id);
    }

    @Test
    public void testMin() {
        final IndexedEntity a = new IndexedEntity("a");
        final IndexedEntity b = new IndexedEntity("b");
        final IndexedEntity c = new IndexedEntity("c");

        Datastore ds = getDs();

        ds.save(a);
        ds.save(b);
        ds.save(c);

        Assert.assertEquals("last", b.id, ds.createQuery(IndexedEntity.class).order("id").min("testField", "b").get().id);
    }

    @Test
    public void testMinCompoundIndex() {
        final IndexedEntity a1 = new IndexedEntity("a");
        final IndexedEntity a2 = new IndexedEntity("a");
        final IndexedEntity b1 = new IndexedEntity("b");
        final IndexedEntity b2 = new IndexedEntity("b");
        final IndexedEntity c1 = new IndexedEntity("c");
        final IndexedEntity c2 = new IndexedEntity("c");

        Datastore ds = getDs();

        ds.save(a1);
        ds.save(a2);
        ds.save(b1);
        ds.save(b2);
        ds.save(c1);
        ds.save(c2);

        List<IndexedEntity> l = ds.createQuery(IndexedEntity.class).order("testField, id").min("testField", "b").min("id", b1.id).asList();

        Assert.assertEquals("size", 4, l.size());
        Assert.assertEquals("item", b1.id, l.get(0).id);
    }

}

@@ -40,24 +40,35 @@
 ort 
-java.util.List;%0A
+com.mongodb.MongoException;
 %0Aimp
@@ -429,16 +429,40 @@
 dexes;%0A%0A
+import java.util.List;%0A%0A
 public c
@@ -601,24 +601,25 @@
 %22testField, 
+_
 id%22)%0A    %7D)%0A
@@ -2154,16 +2154,17 @@
 %22).max(%22
+_
 id%22, b2.
@@ -3395,16 +3395,17 @@
 %22).min(%22
+_
 id%22, b1.
@@ -3533,10 +3533,205 @@
 %0A    %7D%0A%0A
+    @Test(expected = MongoException.class)%0A    public void testExceptionForIndexMismatch() throws Exception %7B%0A        getDs().createQuery(IndexedEntity.class).min(%22doesNotExist%22, 1).get();%0A    %7D%0A
 %7D%0A

Update tests to expect mongo to validate against the index.