package jp.sf.amateras.mirage.example.page;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.when;

import java.util.ArrayList;
import java.util.List;

import jp.sf.amateras.mirage.example.entity.Book;
import jp.sf.amateras.mirage.test.MirageTestContext;
import jp.sf.amateras.mirage.test.MockSqlManager;

import org.apache.click.Context;
import org.apache.click.MockContext;
import org.apache.click.servlet.MockRequest;
import org.junit.Before;
import org.junit.Test;

public class BookListPageTest {

	private BookListPage page;

	private static Book newBook(Long id){
		Book book = new Book();
		book.setId(id);
		return  book;
	}

	private static Book newBook(Long id, boolean checked){
		Book book = new Book();
		book.setId(id);
		book.setCheck(checked);
		return  book;
	}

	@Before
	public void setUp(){
		MirageTestContext.initMirageTestContext();
		MockContext.initContext();

		page = spy(new BookListPage());
		when(page.getSqlManager()).thenReturn(new MockSqlManager());
	}

	@Test
	public void testOnInit() {
		List<Book> bookList = new ArrayList<Book>();
		bookList.add(newBook(new Long(1)));
		bookList.add(newBook(new Long(2)));

		MirageTestContext.addResult(bookList);

		page.onInit();

		@SuppressWarnings("unchecked")
		List<Object> rowList = page.table.getRowList();

		assertEquals(2, rowList.size());
		assertEquals(new Long(1), ((Book) rowList.get(0)).getId());
		assertEquals(new Long(2), ((Book) rowList.get(1)).getId());

		MirageTestContext.verifySqlCount(1);

		MirageTestContext.verifySqlByRegexp(0, "SELECT .* FROM BOOK ORDER BY ID DESC");
		MirageTestContext.verifySqlParameterCount(0, 0);
	}

	@Test
	public void testOnInit_SubmitClicked() {
		MockContext context = (MockContext) Context.getThreadLocalContext();
		MockRequest request = (MockRequest) context.getRequest();
		request.setParameter("submit", "true");
		request.setParameter("keyword", "keyword");

		page.onInit();

		MirageTestContext.verifySqlCount(1);

		MirageTestContext.verifySqlByRegexp(0, "SELECT .* FROM BOOK " +
				"WHERE NAME LIKE \\? OR AUTHOR LIKE \\? OR PUBLISHER LIKE \\? " +
				"ORDER BY ID DESC");

		MirageTestContext.verifySqlParameterCount(0, 3);
		MirageTestContext.verifySqlParameter(0, 0, "%keyword%");
		MirageTestContext.verifySqlParameter(0, 1, "%keyword%");
		MirageTestContext.verifySqlParameter(0, 2, "%keyword%");
	}

	@Test
	public void testDoDelete() {
		page.delete.setParameter("id", "1");

		page.onInit();
		page.doDelete();

		MirageTestContext.verifySqlCount(2);

		MirageTestContext.verifySqlByRegexp(0,
				"SELECT .* FROM BOOK ORDER BY ID DESC");
		MirageTestContext.verifySqlParameterCount(0, 0);

		MirageTestContext.verifySql(1,
				"DELETE FROM BOOK WHERE ID=?");
		MirageTestContext.verifySqlParameterCount(1, 1);
		MirageTestContext.verifySqlParameter(1, 0, new Long(1));
	}

	@Test
	public void testDoBatchDelete() {
		List<Book> bookList = new ArrayList<Book>();
		bookList.add(newBook(new Long(1), true));
		bookList.add(newBook(new Long(2), false));
		bookList.add(newBook(new Long(3), true));

		MirageTestContext.addResult(bookList);

		page.onInit();
		page.doBatchDelete();

		MirageTestContext.verifySqlCount(3);

		MirageTestContext.verifySqlByRegexp(0, "SELECT .* FROM BOOK ORDER BY ID DESC");
		MirageTestContext.verifySqlParameterCount(0, 0);

		MirageTestContext.verifySql(1, "DELETE FROM BOOK WHERE ID=?");
		MirageTestContext.verifySqlParameterCount(1, 1);
		MirageTestContext.verifySqlParameter(1, 0, new Long(1));

		MirageTestContext.verifySql(2, "DELETE FROM BOOK WHERE ID=?");
		MirageTestContext.verifySqlParameterCount(2, 1);
		MirageTestContext.verifySqlParameter(2, 0, new Long(3));
	}
}
