/* * Copyright (c) 2009, SQL Power Group Inc. * * This file is part of SQL Power Library. * * SQL Power Library is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 3 of the License, or * (at your option) any later version. * * SQL Power Library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package ca.sqlpower.dao.json; import java.io.ByteArrayInputStream; import junit.framework.TestCase; import org.json.JSONException; import org.json.JSONObject; import ca.sqlpower.dao.MessageSender; import ca.sqlpower.dao.SPPersistenceException; import ca.sqlpower.dao.SPPersister.DataType; import ca.sqlpower.dao.SPPersister.SPPersistMethod; public class SPJSONPersisterTest extends TestCase { private SPJSONPersister persister; public void testBegin() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { assertEquals(content.getString(SPJSONPersister.METHOD), SPPersistMethod.begin.getCode()); } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); } public void testCommit() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { String method = content.getString(SPJSONPersister.METHOD); if (!method.equals(SPPersistMethod.begin.getCode())) { assertEquals(method, SPPersistMethod.commit.getCode()); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); try { persister.commit(); fail("Expected SPPersistenceException to be thrown"); } catch (SPPersistenceException e) { if (!e.getMessage().equals("Commit attempted while not in a transaction")) { throw e; } } persister.begin(); persister.commit(); } public void testPersistObject() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { if (content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.persistObject.getCode())) { assertEquals(content.getString(SPJSONPersister.PARENT_UUID), "parent"); assertEquals(content.getString("uuid"), "uuid"); assertEquals(content.getString("type"), "type"); assertEquals(content.getInt("index"), 0); } else if (!content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.commit.getCode()) && !content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.begin.getCode())) { fail(); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.persistObject("parent", "type", "uuid", 0); persister.commit(); } public void testChangeProperty() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { if (content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.changeProperty.getCode())) { assertEquals(content.getString(SPJSONPersister.PROPERTY_NAME), "property"); assertEquals(content.getString("type"), DataType.STRING.name()); assertEquals(content.getString("oldValue"), "old"); assertEquals(content.getString(SPJSONPersister.NEW_VALUE), "new"); } else if (!content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.commit.getCode()) && !content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.begin.getCode())) { fail(); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.persistProperty("uuid", "property", DataType.STRING, "old", "new"); persister.commit(); } public void testPersistImagePropertyConditional() throws Exception { final String binaryDataBase64 = "AQIDBAUGBwgJCg=="; final byte[] binaryData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { if (content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.changeProperty.getCode())) { assertEquals(content.getString(SPJSONPersister.PROPERTY_NAME), "property"); assertEquals(content.getString("type"), DataType.PNG_IMG.name()); assertSame(content.get("oldValue"), JSONObject.NULL); assertEquals(content.getString(SPJSONPersister.NEW_VALUE), binaryDataBase64); } else if (!content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.commit.getCode()) && !content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.begin.getCode())) { fail("Unexpected method \""+content.getString(SPJSONPersister.METHOD)+"\""); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.persistProperty("uuid", "property", DataType.PNG_IMG, null, new ByteArrayInputStream(binaryData)); persister.commit(); } public void testPersistImagePropertyUnconditional() throws Exception { final String binaryDataBase64 = "AQIDBAUGBwgJCg=="; final byte[] binaryData = new byte[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { if (content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.persistProperty.getCode())) { assertEquals(content.getString(SPJSONPersister.PROPERTY_NAME), "property"); assertEquals(content.getString("type"), DataType.PNG_IMG.name()); assertEquals(content.getString(SPJSONPersister.NEW_VALUE), binaryDataBase64); } else if (!content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.commit.getCode()) && !content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.begin.getCode())) { fail("Unexpected method \""+content.getString(SPJSONPersister.METHOD)+"\""); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.persistProperty("uuid", "property", DataType.PNG_IMG, new ByteArrayInputStream(binaryData)); persister.commit(); } public void testPersistProperty() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { if (content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.persistProperty.getCode())) { assertEquals(content.getString(SPJSONPersister.PROPERTY_NAME), "property"); assertEquals(content.getString("type"), DataType.STRING.name()); assertEquals(content.getString(SPJSONPersister.NEW_VALUE), "new"); } else if (!content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.commit.getCode()) && !content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.begin.getCode())) { fail(); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.persistProperty("uuid", "property", DataType.STRING, "new"); persister.commit(); } public void testRemoveObject() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { if (content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.removeObject.getCode())) { assertEquals(content.getString(SPJSONPersister.PARENT_UUID), "parent"); assertEquals(content.getString("uuid"), "uuid"); } else if (!content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.commit.getCode()) && !content.getString(SPJSONPersister.METHOD).equals(SPPersistMethod.begin.getCode())) { fail(); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.removeObject("parent", "uuid"); persister.commit(); } public void testRollback() throws Exception { MessageSender<JSONObject> messagePasser = new MessageSender<JSONObject>() { public void send(JSONObject content) throws SPPersistenceException { try { String method = content.getString(SPJSONPersister.METHOD); if (!method.equals(SPPersistMethod.begin.getCode())) { assertEquals(method, SPPersistMethod.rollback.getCode()); } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } }; persister = new SPJSONPersister(messagePasser); persister.begin(); persister.rollback(); try { persister.commit(); fail("Expected SPPersistenceException to be thrown"); } catch (SPPersistenceException e) { if (!e.getMessage().equals("Commit attempted while not in a transaction")) { throw e; } } } private class TestingMessageSender implements MessageSender<JSONObject> { private boolean commitCalled = false; public void send(JSONObject content) throws SPPersistenceException { try { String method = content.getString(SPJSONPersister.METHOD); if (!method.equals(SPPersistMethod.commit.getCode())) { assertEquals("SPJSONPersister sent calls to the message sender in a transaction before commit got called!", true, commitCalled); } else { commitCalled = true; } } catch (JSONException e) { throw new RuntimeException(e); } } public void flush() throws SPPersistenceException { // no-op } public void clear() { // no op } } public void testTransactionOnlyCommitSendsMessages() throws Exception { TestingMessageSender messageSender = new TestingMessageSender(); persister = new SPJSONPersister(messageSender); persister.begin(); persister.persistObject(SPJSONPersister.PARENT_UUID, "type", "uuid", 0); persister.persistProperty("uuid", SPJSONPersister.PROPERTY_NAME, DataType.STRING, "old"); persister.persistProperty("uuid", SPJSONPersister.PROPERTY_NAME, DataType.STRING, "old", "new"); persister.removeObject(SPJSONPersister.PARENT_UUID, "uuid"); messageSender.commitCalled = true; persister.commit(); } }