DataStorageTests.java Source code

Java tutorial

Introduction

Here is the source code for DataStorageTests.java

Source

import Data.Storage;
import org.joda.time.DateTime;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import org.junit.Assert;
import org.junit.Test;

import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;

/**
 Copyright 2016 Alianza Inc.
    
 Licensed under the Apache License, Version 2.0 (the "License");
 you may not use this file except in compliance with the License.
 You may obtain a copy of the License at
    
 http://www.apache.org/licenses/LICENSE-2.0
    
 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
    
 */

public class DataStorageTests {

    private Storage storage;
    private JSONObject json;
    private String jsonString;
    private JSONArray jsonArray;
    private String xml;

    public DataStorageTests() throws JSONException {
        ArrayList<Object> list = new ArrayList<>();
        list.add("other test");
        list.add(10);
        list.add("false");
        list.add(new JSONObject("{'sub':'item'}"));
        jsonArray = new JSONArray("['other test', 10, false, {'sub':'item'}]");//list);
        jsonString = "{'test':{'other test': 'answer', 'next':{'subObject':true, 'lame':[{'again':'blah'}, {'number':34}, {'bool':false}]}}}";
        json = new JSONObject(jsonString);
        xml = "<test><next><subObject>true</subObject><lame><item><again>blah</again></item><item>"
                + "<number>34</number></item><item><bool>false</bool></item></lame></next><other_test>answer</other_test></test>";
    }

    public void setUpJson() throws JSONException {
        storage = new Storage(json);
    }

    public void setUpJsonArray() {
        storage = new Storage(jsonArray);
    }

    public void setUpXml() throws JSONException {
        storage = new Storage(xml);
    }

    public void setUpModel() {
        AccountModel accountModel = new AccountModel();
        accountModel.setAccountName("test Account");
        accountModel.setAccountNumber("123");
        accountModel.setBillingCycleDay(3);
        accountModel.setCustomField("amazing field!");

        storage = new Storage(accountModel);
    }

    @Test
    public void addJson() throws JSONException {
        setUpJson();
        Validator.validateJsonObjects(json, storage.toJson());
    }

    @Test
    public void addJsonArray() throws JSONException {
        storage = new Storage();
        storage.addJson(jsonArray);

        Validator.validateJsonArray(jsonArray, storage.toJsonArray());
    }

    @Test
    public void addXml() throws JSONException {
        setUpXml();
        JSONObject newJSON = new JSONObject(
                "{'test':{'other_test': 'answer', 'next':{'subObject':'true', 'lame':[{'again':'blah'}, {'number':'34'}, {'bool':'false'}]}}}");
        Validator.validateJsonObjects(newJSON, storage.toJson());
        Assert.assertEquals(xml, storage.toXml());
    }

    @Test
    public void addModel() throws JSONException {
        setUpModel();
        //xml of model
        String modelXml = "<accountName>test Account</accountName><billingCycleDay>3</billingCycleDay>"
                + "<accountNumber>123</accountNumber><customField>amazing field!</customField>";
        Assert.assertEquals(modelXml, storage.toXml());
    }

    @Test
    public void getByPathTypeJsonArray() {
        setUpJsonArray();
        String answer = "item";

        String found = storage.get(new String[] { "3", "sub" });
        Assert.assertEquals(answer, found);
    }

    @Test
    public void getByPathTypeJson() throws JSONException {
        Integer answer = 34;

        setUpJson();
        Integer found = storage.get(new String[] { "test", "next", "lame", "1", "number" });
        Assert.assertEquals(answer, found);
    }

    @Test
    public void getByPathTypeXml() throws JSONException {
        String answer = "34";
        setUpXml();
        String found = storage.get(new String[] { "test", "next", "lame", "1", "number" });
        Assert.assertEquals(answer, found);
    }

    @Test
    public void getByPathTypeModel() throws JSONException {
        int answer = 3;
        setUpModel();
        int found = storage.get(new String[] { "billingCycleDay" });
        Assert.assertEquals(answer, found);
    }

    @Test
    public void getJsonType() throws JSONException {
        setUpJson();

        JSONObject expectedJson = json.getJSONObject("test");
        JSONObject actualJson = storage.getAsDataStorage("test").toJson();

        Validator.validateJsonObjects(expectedJson, actualJson);
    }

    @Test
    public void getDouble() {
        Integer one = 1;
        Double half = 1.5;
        Integer twelve = 12;
        Double moreTwelv = 12.12;

        storage = new Storage();
        storage.put("I", one);
        storage.put("d", half);

        storage.put("j", "{'someI':12, 'somed':12.12}");

        Assert.assertEquals(one, storage.get("I"));
        Assert.assertEquals(half, storage.get("d"));
        Assert.assertEquals(moreTwelv, storage.<Integer>get(new String[] { "j", "somed" }));
        Assert.assertEquals(twelve, storage.get(new String[] { "j", "someI" }));
    }

    @Test
    public void getByPathJsonArrayType() throws JSONException {
        setUpJson();

        JSONArray expectedJson = new JSONArray("[{'again':'blah'}, {'number':34}, {'bool':false}]");
        JSONArray actualJson = storage.getAsDataStorage(new String[] { "test", "next", "lame" }).toJsonArray();

        Validator.validateJsonArray(expectedJson, actualJson);
    }

    @Test
    public void getJsonArrayArrayWithinArray() throws JSONException {
        JSONArray jsonArray = new JSONArray("[[[1,2]], [[{'test':'ok'}]], [true]]");
        storage = new Storage(jsonArray);

        Validator.validateJsonArray(jsonArray, storage.toJsonArray());

        Storage first = storage.getAsDataStorage(0);
        Validator.validateJsonArray(new JSONArray("[[1,2]]"), first.toJsonArray());

        Storage second = storage.getAsDataStorage(1);
        Validator.validateJsonArray(new JSONArray("[[{'test':'ok'}]]"), second.toJsonArray());

        first = storage.getAsDataStorage(new String[] { "0", "0" });
        Validator.validateJsonArray(new JSONArray("[1,2]"), first.toJsonArray());

        second = storage.getAsDataStorage(new String[] { "1", "0", "0" });
        Validator.validateJsonObjects(new JSONObject("{'test':'ok'}"), second.toJson());
    }

    @Test
    public void getByPathDataStorageType() throws JSONException {
        setUpJson();

        Storage expected = new Storage(
                "{'subObject':true, 'lame':[{'again':'blah'}, {'number':34.0}, {'bool':false}]}");
        Storage actual = storage.getAsDataStorage(new String[] { "test", "next" });

        Validator.validateJsonObjects(expected.toJson(), actual.toJson());
    }

    //"['other test', 10, false, {'sub':'item'}]"
    @Test
    public void getByIndexDataStorageType() throws JSONException {
        setUpJsonArray();

        JSONObject actual = storage.getAsDataStorage(3).toJson();
        Validator.validateJsonObjects(new JSONObject("{'sub':'item'}"), actual);

        Storage actualStorage = storage.getAsDataStorage(2);
        Assert.assertEquals(false, actualStorage.get(0));

        actualStorage = storage.getAsDataStorage(1);
        int result = actualStorage.get(0);
        Assert.assertEquals(10, result);

        actualStorage = storage.getAsDataStorage(0);
        Assert.assertEquals("other test", actualStorage.get(0));
    }

    @Test
    public void getByPathDataStorageTypeArray() throws JSONException {
        setUpJson();

        Storage expected = new Storage("[{'again':'blah'}, {'number':34.0}, {'bool':false}]");
        Storage actual = storage.getAsDataStorage(new String[] { "test", "next", "lame" });

        Validator.validateJsonObjects(expected.toJson(), actual.toJson());
    }

    @Test
    public void addDataStorageToDataStorage() throws JSONException {
        setUpJson();

        JSONObject otherJson = new JSONObject("{'added':{'other':{'layer':['item1', {'json':'embed'}, 12.12]}},"
                + jsonString.replaceFirst("\\{", ""));

        JSONObject add = new JSONObject("{'other':{'layer':['item1', {'json':'embed'}, 12.12]}}");
        storage.put("added", new Storage(add));

        Validator.validateJsonObjects(otherJson, storage.toJson());
    }

    @Test
    public void putJSONArray() throws JSONException {
        setUpJson();

        JSONArray array = new JSONArray("['item1', {'number2':'value'}, true, [1,2]]");
        storage.put("new array", new Storage(array));

        Validator.validateJsonArray(array, storage.toJson().getJSONArray("new array"));
    }

    @Test
    public void removeKeys() throws JSONException {
        JSONObject goodJson = new JSONObject(
                "{'test':[[[{'find':'object'}], 1, {'test':'text'}, [{'bottom':'text'}]]]}");
        JSONObject badJson = new JSONObject(
                "{'test':[{'map':{'myArrayList':[{'myMap':[{'find':'object'}]}, 1, {'test':'text'}, {'myMap':[{'bottom':'text'}]}]}}]}");
        storage = new Storage(badJson);

        Validator.validateJsonObjects(goodJson, storage.toJson());
    }

    @Test
    public void removeKeysEmbedded() throws JSONException {
        setUpJson();
        JSONObject badJson = new JSONObject("{\"addOns\":{  \n" + "      \"myArrayList\":[  \n" + "         {  \n"
                + "            \"map\":{  \n" + "               \"name\":\"mediaFriends\",\n"
                + "               \"enabledOnPartition\":true,\n" + "               \"fields\":{  \n"
                + "                  \"map\":{  \n" + "                     \"toNumber\":{  \n"
                + "                        \"myArrayList\":[]\n" + "                     },\n"
                + "                     \"enabled\":false\n" + "                  }\n" + "               }\n"
                + "            }\n" + "         }\n" + "      ]\n" + "   }}");
        JSONObject goodJson = new JSONObject(
                "{\"addOns\":[{\"name\":\"mediaFriends\",\"enabledOnPartition\":true,\"fields\":{\"toNumber\":[],\"enabled\":false}}]}");

        storage = new Storage(badJson);

        Validator.validateJsonObjects(badJson, storage.toJson());

        storage = new Storage(goodJson);

        Validator.validateJsonObjects(goodJson, storage.toJson());
    }

    @Test
    public void addAll() throws JSONException {
        String xmlData = "<xml>true</xml>";
        JSONObject jsonData = new JSONObject(
                "{'jsonParent':{'json':40}, 'array':[{'line':'one'}, {'next':'line'}]}");
        HashMap<String, Object> mapData = new HashMap<>();
        HashMap<String, Object> subMap = new HashMap<>();
        subMap.put("under", 12.5);
        mapData.put("map", "mapItem1");
        mapData.put("subItem", subMap);

        //start with a model added
        setUpModel();

        //add json
        storage.addJson(jsonData);

        //add xml
        storage.addXml(xmlData);

        //add map
        storage.addMap(mapData);

        //add an item
        storage.put("extra", "manual");

        //do many asserts, check each type is in there
        HashMap result = storage.toMap();
        Assert.assertEquals("true", result.get("xml"));

        Assert.assertEquals("line", storage.get(new String[] { "array", "1", "next" }));
        Double number = storage.get(new String[] { "subItem", "under" });
        Assert.assertEquals(new Double(12.5), number);
        Assert.assertTrue(new Boolean(storage.get("xml")));

        //get a json structure to make sure everything matches
        JSONObject expected = new JSONObject("{'xml':true, "
                + "'jsonParent':{'json':40}, 'array':[{'line':'one'}, {'next':'line'}]}," + "'map':'mapItem1',"
                + "'subItem':{'under':12.5}," + "'extra':'manual'," + "'accountName':'test Account',"
                + "'billingCycleDay':3," + "'accountNumber':'123'," + "'customField':'amazing field!'");

        Validator.validateJsonObjects(expected, storage.toJson());
    }

    @Test
    public void overwriteField() {
        HashMap<String, Object> preData = new HashMap<>();
        preData.put("key1", "item1");
        preData.put("key2", "item2");
        storage = new Storage(preData);

        HashMap<String, Object> data = new HashMap<>();
        data.put("key3", "item3");
        data.put("key2", "DUPLICATE");

        storage.addMap(data);

        Assert.assertEquals(storage.get("key2"), "DUPLICATE");
        Assert.assertEquals(storage.get("key1"), "item1");
        Assert.assertEquals(storage.get("key3"), "item3");
    }

    @Test
    public void putFieldFromPath() throws JSONException {
        setUpJson();
        String newValue = "REPLACED";
        String[] path = { "test", "next", "lame", "1", "number" };

        storage.put(path, newValue);

        Assert.assertEquals(newValue, storage.get(path));
    }

    @Test
    public void putFieldFromPathArray() throws JSONException {
        setUpJson();
        String newValue = "REPLACED";
        String[] path = { "test", "next", "lame", "1" };

        storage.put(path, newValue);

        Assert.assertEquals(newValue, storage.get(path));
    }

    @Test
    public void putNewFieldFromPath() throws JSONException {
        setUpJson();
        String newValue = "NEW ITEM";
        String[] path = { "test", "next", "lame", "1", "not there" };

        storage.put(path, newValue);

        Assert.assertEquals(newValue, storage.get(path));
    }

    @Test
    public void putNewFieldFromPathArray() throws JSONException {
        setUpJson();
        String newValue = "NEW ITEM";
        String[] path = { "test", "next", "lame", "2" };

        storage.put(path, newValue);

        Assert.assertEquals(newValue, storage.get(path));
    }

    @Test
    public void putJsonString() {
        storage = new Storage();

        storage.put("one", "{'item':'value', 'next':{'more':[1,2]}}");
        storage.put("two", "['this', ['value1', {'things':true}]]");
        storage.put("three", "string");

        int value = storage.get(new String[] { "one", "next", "more", "1" });
        Assert.assertEquals(2, value);
        Assert.assertEquals(true, storage.get(new String[] { "two", "1", "1", "things" }));
        Assert.assertEquals("string", storage.get("three"));
    }

    @Test
    public void removeField() throws JSONException {
        setUpJson();
        JSONObject local = new JSONObject(json);
        local.remove("next");
        storage.remove("next");

        Validator.validateJsonObjects(local, storage.toJson());
    }

    @Test
    public void findPath() throws JSONException {
        setUpJson();
        String[] path = { "test", "next", "lame", "1", "number" };

        ArrayList<String[]> jsonPath = storage.findPaths("number");

        Assert.assertEquals(1, jsonPath.size());
        Assert.assertArrayEquals(path, jsonPath.get(0));
    }

    @Test
    public void removeFieldFromPath() throws JSONException {
        setUpJson();
        String[] path = { "test", "next", "lame", "1", "number" };
        JSONObject local = new JSONObject(jsonString);
        local.getJSONObject("test").getJSONObject("next").getJSONArray("lame").getJSONObject(1).remove("number");
        storage.remove(path);

        Validator.validateJsonObjects(local, storage.toJson());
    }

    @Test
    public void removeFieldFromPathArray() throws JSONException {
        setUpJson();
        String[] path = { "test", "next", "lame", "1" };
        JSONObject local = new JSONObject(
                ("{'test':{'other test': 'answer', 'next':{'subObject':true, 'lame':[{'again':'blah'},{},{'bool':false}]}}}"));
        storage.remove(path);

        Validator.validateJsonObjects(local, storage.toJson());
    }

    @Test
    public void jsonString() throws JSONException {
        JSONObject json = new JSONObject(
                "{'test':[1, {'user':0}, {'me':'user'}], 'object':'test', 'test':{'bool':true}}");
        storage = new Storage("{'test':[1, {'user':0}, {'me':'user'}], 'object':'test', 'test':{'bool':true}}");

        Validator.validateJsonObjects(json, storage.toJson());
    }

    @Test
    public void equals() {
        Storage match1 = new Storage();
        Storage match2 = new Storage();

        Assert.assertTrue(match1.equals(match2));

        match1.put("item", "first");
        match2.put("item", "first");

        match1.put("item2", "second");
        match2.put("item2", "second");

        HashMap<String, String> test = new HashMap<>();
        test.put("extra", "item");
        HashMap<String, String> test2 = new HashMap<>();
        test2.put("extra", "item");

        match1.put("sub", test);
        match2.put("sub", test2);
        Assert.assertTrue(match2.equals(match1));

        match1.put("badData", "noMatch");
        Assert.assertFalse(match1.equals(match2));

        match1.remove("badData");
        Assert.assertTrue(match1.equals(match2));

        match2.put(new String[] { "sub", "extra" }, "item_bad");

        Assert.assertFalse(match1.equals(match2));

        Assert.assertFalse(match1.equals("not dataStorage"));
    }

    @Test
    public void getArray() {
        ArrayList<Object> items = new ArrayList<>();
        HashMap<String, String> sub = new HashMap<>();

        sub.put("test", "inner");
        items.add("one");
        items.add(3);
        items.add(sub);

        Storage storage = new Storage(items);
        storage.put("test", sub);
        ;
        storage.put("arrays", items);
        storage.put("other", "nonsense");

        Assert.assertEquals(items.toArray()[0].toString(), storage.toArray().toArray()[0].toString());
        Assert.assertEquals(items.toArray()[1].toString(), storage.toArray().toArray()[1].toString());
        Assert.assertEquals("inner", storage.get(new String[] { "2", "test" }));
    }

    @Test
    public void putDataStorage() {
        storage = new Storage();
        Storage temp = new Storage("{\"l1\":\"value\",\"l2\":\"TEN\"}");
        storage.put("test", temp);

        Assert.assertEquals("value", storage.get(new String[] { "test", "l1" }));
    }

    @Test
    public void dataStorageHashMap() {
        HashMap<String, String> stringHash = new HashMap<>();
        stringHash.put("test", "one");
        stringHash.put("test2", "two");
        stringHash.put("last", "test");
        storage = new Storage(stringHash);

        Assert.assertEquals("one", storage.get("test"));
        Assert.assertEquals("two", storage.get("test2"));
        Assert.assertEquals("test", storage.get("last"));
    }

    @Test
    public void hasPathTest() throws JSONException {
        setUpJson();

        Assert.assertTrue(storage.has(new String[] { "test" }));
        Assert.assertTrue(storage.has(new String[] { "test", "other test" }));
        Assert.assertTrue(storage.has(new String[] { "test", "next", "subObject" }));
        Assert.assertTrue(storage.has(new String[] { "test", "next", "lame", "0", "again" }));
        Assert.assertTrue(storage.has(new String[] { "test", "next", "lame", "2", "bool" }));

        Assert.assertFalse(storage.has(new String[] { "false" }));
        Assert.assertFalse(storage.has(new String[] { "test", "false" }));
        Assert.assertFalse(storage.has(new String[] { "test", "next", "false" }));
        Assert.assertFalse(storage.has(new String[] { "test", "next", "lame", "20", "again" }));
        Assert.assertFalse(storage.has(new String[] { "test", "next", "lame", "false", "again" }));
        Assert.assertFalse(storage.has(new String[] { "test", "next", "lame", "2", "false" }));
    }

    @Test
    public void dateTest() {
        storage = new Storage("{'lower':{}}");
        ZonedDateTime now = ZonedDateTime.now();
        Date dNow = new Date();
        String dNowString = dNow.toString();
        String dateNow = now.toString().split("T")[0];

        storage.put("date", now);
        storage.put(new String[] { "lower", "date" }, now);
        storage.put(new String[] { "lower", "otherDate" }, dNow);

        Assert.assertEquals(dateNow, storage.get("date"));
        Assert.assertEquals(dateNow, storage.get(new String[] { "lower", "date" }));
        Assert.assertEquals(dNowString, storage.getString(new String[] { "lower", "otherDate" }));

        // for testing the parsing of an object with date time objects
        class Inner {
            public ZonedDateTime getDate() {
                return now;
            }

            public Date getOtherDate() {
                return dNow;
            }
        }

        class Top {
            public ZonedDateTime getDate() {
                return now;
            }

            public Inner getInner() {
                return new Inner();
            }
        }

        Top test = new Top();
        storage = new Storage(test);

        Assert.assertEquals(dateNow, storage.get("date"));
        Assert.assertEquals(dateNow, storage.get(new String[] { "inner", "date" }));
        Assert.assertEquals(dNowString, storage.get(new String[] { "inner", "otherDate" }));

        storage = new Storage();
        storage.addModel(test);

        Assert.assertEquals(dateNow, storage.get("date"));
        Assert.assertEquals(dateNow, storage.get(new String[] { "inner", "date" }));
        Assert.assertEquals(dNowString, storage.get(new String[] { "inner", "otherDate" }));

        storage.put("test", test);

        Assert.assertEquals(dateNow, storage.get(new String[] { "test", "date" }));
        Assert.assertEquals(dateNow, storage.get(new String[] { "test", "inner", "date" }));
        Assert.assertEquals(dNowString, storage.get(new String[] { "test", "inner", "otherDate" }));

        //array list of objects that have DateTime
        ArrayList<Top> list = new ArrayList<>();
        list.add(new Top());
        list.add(new Top());

        storage = new Storage(list);

        Assert.assertEquals(dateNow, storage.get(new String[] { "0", "date" }));
        Assert.assertEquals(dateNow, storage.get(new String[] { "1", "inner", "date" }));
        Assert.assertEquals(dNowString, storage.get(new String[] { "0", "inner", "otherDate" }));
        Assert.assertEquals("{\"date\":\"" + dateNow + "\",\"otherDate\":\"" + dNowString + "\"}",
                storage.getAsDataStorage(new String[] { "1", "inner" }).toString());
    }

    @Test
    public void dateContainers() {
        storage = new Storage();
        ArrayList dateArray = new ArrayList();
        HashMap dateMap = new HashMap();
        DateTime now = DateTime.now();
        String dateString = now.toString().split("T")[0];

        dateArray.add(now);
        dateMap.put("date", now);

        storage.addArray(dateArray);
        storage.addMap(dateMap);

        Assert.assertEquals(dateString, storage.get(new String[] { "0" }));
        Assert.assertEquals(dateString, storage.get(new String[] { "date" }));

        storage = new Storage(dateArray);
        Assert.assertEquals(dateString, storage.get(new String[] { "0" }));

        storage = new Storage(dateMap);
        Assert.assertEquals(dateString, storage.get(new String[] { "date" }));
    }

    @Test
    public void xmlArray() throws JSONException {
        String xmlData1 = "<test1><list><node>some data</node><node>some more data</node><node><layer>too far</layer></node></list></test1>";
        String xmlData1Test = "<test1><list><item>some data</item><item>some more data</item><item><layer>too far</layer></item></list></test1>";

        String xmlData2 = "<test2><item></item><item></item></test2>";

        String asJson = "{'test1':{'list':['some data', 'some more data', {'layer':'too far'}]}}, 'test2':['','']}";
        storage = new Storage(xmlData1 + xmlData2);
        Assert.assertEquals(xmlData2 + xmlData1Test, storage.toXml());
        Validator.validateJsonObjects(new JSONObject(asJson), storage.toJson());
    }

    @Test
    public void xmlEmptyTags() throws JSONException {
        String xmlData = "<test1></test1><test2><inner></inner><data>the saved data</data></test2>";
        String xmlDataTest = "<test2><data>the saved data</data><inner></inner></test2><test1></test1>";
        String asJson = "{'test1': '', 'test2':{'inner':'', 'data':'the saved data'}}";

        storage = new Storage(xmlData);
        Assert.assertEquals(xmlDataTest, storage.toXml());
        Validator.validateJsonObjects(new JSONObject(asJson), storage.toJson());

        String notXml = "<some:random:data>";
        storage.put("string", notXml);
        Assert.assertEquals(notXml, storage.get("string"));
    }

    @Test
    public void xmlHandling() {
        String html = "<head>\n" + "<title>       </title>\n" + "<style type=\"text/css\">\n"
                + "h1  {text-align:center;\n" + "    font-family:Arial, Helvetica, Sans-Serif;\n" + "    }\n" + "\n"
                + "p   {text-indent:20px;\n" + "    }\n" + "</style>\n" + "</head>\n"
                + "<TEST:body bgcolor=\"#ffffcc\" text=\"#000000\">\n" + "<h1>Hello, World!</h1>\n"
                + "<p>this world doesn't care</p>\n" + "</TEST:body>\n";

        String expectedHtml = "<head><style type=\"text/css\">\n" + "h1  {text-align:center;\n"
                + "    font-family:Arial, Helvetica, Sans-Serif;\n" + "    }\n" + "\n" + "p   {text-indent:20px;\n"
                + "    }\n"
                + "</style><title>       </title></head><TEST:body bgcolor=\"#ffffcc\" text=\"#000000\"><p>this world doesn't care</p><h1>Hello, World!</h1></TEST:body>";

        String expectedjson = "{\"head\":{\"style_Attributes\":{\"type\":\"text/css\"},\"style\":\"\\n"
                + "h1  {text-align:center;\\n" + "    font-family:Arial, Helvetica, Sans-Serif;\\n" + "    }\\n"
                + "\\n" + "p   {text-indent:20px;\\n" + "    }\\n"
                + "\",\"title\":\"       \"},\"TEST:body_Attributes\":{\"bgcolor\":\"#ffffcc\",\"text\":\"#000000\"},\"TEST:body\":{\"p\":\"this world doesn't care\",\"h1\":\"Hello, World!\"}}";

        storage = new Storage(html);

        Assert.assertEquals(expectedHtml, storage.toXml());
        storage.put("htmlData", html);
        Assert.assertEquals(expectedjson, storage.getAsDataStorage("htmlData").toString());

        html = "<!DOCTYPE html>" + html;
        storage = new Storage(html);

        Assert.assertEquals(expectedHtml, storage.toXml());
        storage.put("htmlData", html);
        Assert.assertEquals(expectedjson, storage.getAsDataStorage("htmlData").toString());
        storage = new Storage();
        storage.addXml(html);

        Assert.assertEquals(expectedHtml, storage.toXml());
    }

    @Test
    public void htmlHandling() {
        String htmlData = "<html>\n" + "    <head>\n" + "        <title>The resource cannot be found.</title>\n"
                + "    </head>\n" + "    <body bgcolor=\"white\">\n" + "        <span>\n"
                + "            <H1>Server Error in '/' Application.\n" + "                <hr/>\n"
                + "            </H1>\n" + "            <h2:main>\n"
                + "                <i>The resource cannot be found.</i> \n" + "            </h2:main>\n"
                + "        </span>\n"
                + "        <font face=\"Arial, Helvetica, Geneva, SunSans-Regular, sans-serif \">\n"
                + "            <b> Description: </b>HTTP 404. The resource you are looking for (or one of its dependencies) could have been removed, had its name changed, or is temporarily unavailable. ;Please review the following URL and make sure that it is spelled correctly.\n"
                + "            \n" + "            <br>\n" + "            <br>\n"
                + "            <b> Requested URL: </b>/HolidayService_v2/HolidayService.asmx\n"
                + "            <br>\n" + "            <br>\n" + "            <hr/>\n"
                + "            <b>Version Information:</b>Microsoft .NET Framework Version:2.0.50727.5485; ASP.NET Version:2.0.50727.5491\n"
                + "\n" + "            \n" + "        </font>\n" + "\n" + "    \n" + "    </body>\n" + "\n"
                + "</html>";

        storage = new Storage(htmlData);
        Assert.assertEquals(storage.get("html"), htmlData);

        storage.put("moreHtml", htmlData);
        Assert.assertEquals(storage.get("moreHtml"), htmlData);

        String htmlDataExtra = "<!DOCTYPE html>" + htmlData;
        storage = new Storage(htmlDataExtra);

        Assert.assertEquals(htmlData, storage.get("html"));

        storage.put("moreHtml", htmlDataExtra);
        Assert.assertEquals(htmlData, storage.get("moreHtml"));
    }

    @Test
    public void addAttributes() {
        //not supporting attributes in an xml array
        String attributeJSON = "{\"other\":\"more value\",\"top\":{\"next\":\"value\",\"next_Attributes\":{\"attribute\":\"two\"},\"space\":{\"sub\":\"blank\",\"sub_Attributes\":{\"details\":\"data\"}}},\"array\":[\"one\",\"two\"],\"other_Attributes\":{\"details\":\"data\",\"attribute\":\"one\"}}";
        HashMap<String, String> otherAttr = new HashMap<>();
        HashMap<String, String> topAttr = new HashMap<>();
        otherAttr.put("details", "data");
        otherAttr.put("attribute", "one");
        topAttr.put("attribute", "two");
        storage = new Storage();
        storage.addXml(
                "<top><next>value</next><space><sub></sub></space></top><other>more value</other><array><item>one</item><item attr=\"extra\">two</item></array>");

        storage.putAttribute(new String[] { "other" }, "attribute", otherAttr.get("attribute"));
        storage.putAttribute(new String[] { "top", "next" }, "attribute", topAttr.get("attribute"));
        storage.putAttribute(new String[] { "other" }, "details", otherAttr.get("details"));
        storage.put(new String[] { "top", "space", "sub" }, "blank");
        storage.putAttribute(new String[] { "top", "space", "sub" }, "details", otherAttr.get("details"));
        storage.putAttribute(new String[] { "array", "0" }, "details", otherAttr.get("details")); //will not add anything

        Assert.assertEquals(otherAttr, storage.getAttributes(new String[] { "other" }));
        Assert.assertEquals(topAttr, storage.getAttributes(new String[] { "top", "next" }));
        Assert.assertEquals("data", storage.getAttribute(new String[] { "top", "space", "sub" }, "details"));
        Assert.assertEquals("data", storage.getAttribute(new String[] { "other" }, "details"));

        Assert.assertEquals(attributeJSON, storage.toJson().toString());
    }

    @Test
    public void addPath() throws JSONException {
        storage = new Storage();
        String test = "testData";
        String[] path = { "created", "path", "here" };
        String[] arrayPath = { "0", "layer1", "2", "0" };
        JSONObject testItem = new JSONObject("{'created':{'path':{'here':'" + test + "'}}}");
        JSONArray testArray = new JSONArray("[{'layer1':[null,null,['" + test + "']]}]");

        storage.put(path, test);

        Assert.assertEquals(test, storage.get(path));
        Assert.assertEquals(testItem.toString(), storage.toString());

        storage = new Storage();
        storage.put(arrayPath, test);

        Assert.assertEquals(test, storage.get(arrayPath));
        Assert.assertEquals(testArray.toString(), storage.toJsonArray().toString());

        storage = new Storage("{'created':{}}");
        storage.put(path, test);

        Assert.assertEquals(test, storage.get(path));
        Assert.assertEquals(testItem.toString(), storage.toString());

        storage = new Storage("[{'layer1':[]}]");
        storage.put(arrayPath, test);

        Assert.assertEquals(test, storage.get(arrayPath));
        Assert.assertEquals(testArray.toString(), storage.toJsonArray().toString());

        storage = new Storage("[{'layer1':[null, null]}]");
        storage.put(arrayPath, test);

        Assert.assertEquals(test, storage.get(arrayPath));
        Assert.assertEquals(testArray.toString(), storage.toJsonArray().toString());

        storage = new Storage("[{'layer1':[0, 1, null]}]");
        storage.put(arrayPath, test);
        storage.put(new String[] { "0", "layer1", "0" }, (Object) null);
        storage.put(new String[] { "0", "layer1", "1" }, (Object) null);

        Assert.assertEquals(test, storage.get(arrayPath));
        Assert.assertEquals(testArray.toString(), storage.toJsonArray().toString());
    }

    @Test
    public void getArrayAsDataStorage() throws JSONException {
        JSONArray array = new JSONArray("[{\"inner\":{\"data\":\"value\"}}]");
        storage = new Storage();

        storage.put("genericArray", array);
        Storage stowArray = storage.getAsDataStorage("genericArray");
        Assert.assertEquals("did not convert correctly", "{\"0\":{\"inner\":{\"data\":\"value\"}}}",
                stowArray.toString());
    }

    @Test
    public void removeFromStorage() {
        String[] lowestPath = { "top", "next", "level1", "level2", "level3", "level4", "last" };
        String[] abovePath = { "top", "next", "level1", "level2", "level3", "level4" };
        String xmlItem = "<top><next><level1><level2><level3><level4><last>data</last></level4></level3></level2></level1></next></top>";

        storage = new Storage(xmlItem);
        storage.remove(abovePath);
        Assert.assertEquals(storage.toString(), "{\"top\":{\"next\":{\"level1\":{\"level2\":{\"level3\":{}}}}}}");

        storage = new Storage(xmlItem);
        storage.remove(lowestPath);
        Assert.assertEquals(storage.toString(),
                "{\"top\":{\"next\":{\"level1\":{\"level2\":{\"level3\":{\"level4\":{}}}}}}}");
    }

    @Test
    public void xmlChangeArray() {
        String list = "{'master':['key1','key2'], 'other':'value'}";
        storage = new Storage(list);
        Assert.assertEquals("<other>value</other><master><item>key1</item><item>key2</item></master>",
                storage.toXml());

        storage.setXmlArrayKey("list");
        Assert.assertEquals("<other>value</other><master><list>key1</list><list>key2</list></master>",
                storage.toXml());

        storage.setXmlArrayKey("stupid");
        String itemList = storage.toXml();

        storage.setXmlArrayKey("item");
        storage = new Storage();
        storage.putString("Test", itemList);

        Assert.assertEquals(
                "<Test><other>value</other><master><stupid>key1</stupid><stupid>key2</stupid></master></Test>",
                storage.toXml());
    }

    @Test
    public void xmlError() {
        String data = "<polycomConfig xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"polycomConfig.xsd\">\n"
                + "    <tcpIpApp.sntp tcpIpApp.sntp.daylightSavings.stop.dayOfWeek=\"1\" tcpIpApp.sntp.daylightSavings.stop.time=\"2\" tcpIpApp.sntp.daylightSavings.stop.date=\"11\" tcpIpApp.sntp.daylightSavings.stop.month=\"11\" tcpIpApp.sntp.address=\"us.pool.ntp.org\" tcpIpApp.sntp.daylightSavings.start.dayOfWeek=\"1\" tcpIpApp.sntp.daylightSavings.start.time=\"2\" tcpIpApp.sntp.daylightSavings.start.date=\"3\" tcpIpApp.sntp.daylightSavings.start.month=\"3\" tcpIpApp.sntp.daylightSavings.fixedDayEnable=\"1\" tcpIpApp.sntp.daylightSavings.enable=\"1\" tcpIpApp.sntp.gmtOffset.overrideDHCP=\"1\" tcpIpApp.sntp.gmtOffset=\"-25200\" tcpIpApp.sntp.resyncPeriod=\"86400\" />\n"
                + "</tcpIpApp>\n" + "undefined</polycomConfig>";

        storage = new Storage(data);
        Assert.assertEquals(data, storage.get("data"));
    }

    @Test
    public void nullArrayModelError() {
        TestArray obj = new TestArray();
        TestArray model = new TestArray();
        TestArray more = new TestArray();
        Storage expectedJson = new Storage(
                "{'sub':{'number':3,'name':'the name','things':[{'name':'values'}]},'name':'my Test'}");

        more.setName("values");
        more.setNumber(null);
        model.setName("the name");
        model.setNumber(null);
        model.setThings(new TestArray[] { more });
        model.setNumber(3);
        obj.setName("my Test");
        obj.setSub(model);

        storage = new Storage(obj);
        Assert.assertEquals(expectedJson, storage);
    }

    class TestArray {
        private String name;
        private TestArray[] things;
        private TestArray sub;
        private Integer number;

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public TestArray[] getThings() {
            return things;
        }

        public void setThings(TestArray[] things) {
            this.things = things;
        }

        public Integer getNumber() {
            return number;
        }

        public void setNumber(Integer number) {
            this.number = number;
        }

        public TestArray getSub() {
            return sub;
        }

        public void setSub(TestArray sub) {
            this.sub = sub;
        }
    }
}