/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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. */ package org.apache.shindig.social.opensocial.util; import org.apache.shindig.social.JsonLibTestsGuiceModule; import org.apache.shindig.social.core.model.ActivityImpl; import org.apache.shindig.social.core.model.AddressImpl; import org.apache.shindig.social.core.model.ListFieldImpl; import org.apache.shindig.social.core.model.MediaItemImpl; import org.apache.shindig.social.core.model.NameImpl; import org.apache.shindig.social.core.model.PersonImpl; import org.apache.shindig.social.core.util.BeanJsonLibConversionException; import org.apache.shindig.social.core.util.BeanJsonLibConverter; import org.apache.shindig.social.opensocial.model.Activity; import org.apache.shindig.social.opensocial.model.Address; import org.apache.shindig.social.opensocial.model.ListField; import org.apache.shindig.social.opensocial.model.MediaItem; import org.apache.shindig.social.opensocial.model.Name; import org.apache.shindig.social.opensocial.model.Person; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.inject.Guice; import com.google.inject.Injector; import junit.framework.TestCase; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.Map.Entry; public class BeanJsonLibConverterTest extends TestCase { private static final Log log = LogFactory.getLog(BeanJsonLibConverterTest.class); // taken from opensocial-reference/person.js private static final String[] PERSON_FIELDS = { "id", "name", "nickname", "thumbnailUrl", "profileUrl", "currentLocation", "addresses", "emails", "phoneNumbers", "aboutMe", "status", "profileSong", "profileVideo", "gender", "sexualOrientation", "relationshipStatus", "age", "dateOfBirth", "bodyType", "ethnicity", "smoker", "drinker", "children", "pets", "livingArrangement", "timeZone", "languagesSpoken", "jobs", "jobInterests", "schools", "interests", "urls", "music", "movies", "tvShows", "books", "activities", "sports", "heroes", "quotes", "cars", "food", "turnOns", "turnOffs", "tags", "romance", "scaredOf", "happiestWhen", "fashion", "humor", "lookingFor", "religion", "politicalViews", "hasApp", "networkPresence" }; // taken from opensocial-reference/name.js private static final String[] NAME_FIELDS = { "familyName", "givenName", "additionalName", "honorificPrefix", "honorificSuffix", "formatted" }; private Person johnDoe; private Activity activity; private BeanJsonLibConverter beanJsonConverter; private ApiValidator apiValidator; // set to true to get loging output at info level private boolean outputInfo = false; @Override public void setUp() throws Exception { super.setUp(); johnDoe = new PersonImpl("johnDoeId", "Johnny", new NameImpl("John Doe")); johnDoe.setPhoneNumbers(Lists.<ListField>newArrayList( new ListFieldImpl("home", "+33H000000000"), new ListFieldImpl("mobile", "+33M000000000"), new ListFieldImpl("work", "+33W000000000"))); johnDoe.setAddresses(Lists.<Address>newArrayList(new AddressImpl("My home address"))); johnDoe.setEmails(Lists.<ListField>newArrayList(new ListFieldImpl("work", "john.doe@work.bar"), new ListFieldImpl("home", "john.doe@home.bar"))); activity = new ActivityImpl("activityId", johnDoe.getId()); activity.setMediaItems(Lists.<MediaItem>newArrayList(new MediaItemImpl("image/jpg", MediaItem.Type.IMAGE, "http://foo.bar"))); Injector injector = Guice.createInjector(new JsonLibTestsGuiceModule()); beanJsonConverter = injector.getInstance(BeanJsonLibConverter.class); apiValidator = new ApiValidator(); } public static class SpecialPerson extends PersonImpl { public static final String[] OPTIONALFIELDS = {}; public static final String[] NULLFIELDS = { "jobInterests", "nickname", "romance", "religion", "timeZone", "relationshipStatus", "tags", "networkPresence", "books", "quotes", "phoneNumbers", "languagesSpoken", "activities", "jobs", "dateOfBirth", "profileVideo", "bodyType", "urls", "schools", "music", "addresses", "livingArrangement", "thumbnailUrl", "humor", "sports", "scaredOf", "movies", "age", "pets", "hasApp", "turnOffs", "gender", "fashion", "drinker", "aboutMe", "children", "sexualOrientation", "heroes", "profileSong", "lookingFor", "cars", "turnOns", "tvShows", "profileUrl", "status", "currentLocation", "smoker", "happiestWhen", "ethnicity", "food", "emails", "politicalViews", "interests", "familyName", "honorificSuffix", "additionalName", "honorificPrefix", "givenName" }; private String newfield; public SpecialPerson() { super(); } public SpecialPerson(String id, String name, String newfield) { super(id, name, new NameImpl(name)); this.newfield = newfield; } public String getNewfield() { return newfield; } public void setNewfield(String newfield) { this.newfield = newfield; } } public void testToJsonOnInheritedClass() throws Exception { SpecialPerson cassie = new SpecialPerson("5", "robot", "nonsense"); String result = beanJsonConverter.convertToString(cassie); validatePerson(result, "5", "robot", SpecialPerson.OPTIONALFIELDS, SpecialPerson.NULLFIELDS); String[] optional = {}; String[] nullfields = {}; Map<String, Object> special = apiValidator.validate(result, new String[] { "newfield" }, optional, nullfields); assertNotNull(special.get("newfield")); assertEquals(String.class, special.get("newfield").getClass()); assertEquals("nonsense", special.get("newfield")); // convert back into an object Tree SpecialPerson parseCassie = beanJsonConverter.convertToObject(result, SpecialPerson.class); assertNotNull(parseCassie); assertEquals(cassie.getId(), parseCassie.getId()); assertEquals(cassie.getNewfield(), parseCassie.getNewfield()); Name name = parseCassie.getName(); Name cassieName = cassie.getName(); assertNotNull(name); assertEquals(cassieName.getFormatted(), name.getFormatted()); assertEquals(cassieName.getAdditionalName(), name.getAdditionalName()); assertEquals(cassieName.getFamilyName(), name.getFamilyName()); assertEquals(cassieName.getGivenName(), name.getGivenName()); assertEquals(cassieName.getHonorificPrefix(), name.getHonorificPrefix()); assertEquals(cassieName.getHonorificSuffix(), name.getHonorificSuffix()); } /** * @param result * @throws ApiValidatorExpcetion */ private void validatePerson(String result, String id, String name, String[] optional, String[] nullfields) throws ApiValidatorExpcetion { Map<String, Object> standard = apiValidator.validate(result, PERSON_FIELDS, optional, nullfields); assertNotNull(standard.get("id")); assertEquals(String.class, standard.get("id").getClass()); assertEquals(id, standard.get("id")); assertNotNull(standard.get("name")); Map<String, Object> nameJSON = apiValidator.validateObject(standard.get("name"), NAME_FIELDS, optional, nullfields); ApiValidator.dump(nameJSON); assertNotNull(nameJSON.get("formatted")); assertEquals(String.class, nameJSON.get("formatted").getClass()); assertEquals(name, nameJSON.get("formatted")); // additional name assertNull(nameJSON.get("additionalName")); } public void testPersonToJson() throws Exception { String result = beanJsonConverter.convertToString(johnDoe); if (outputInfo) { log.info("JSON (" + result + ")"); } Person parsedPerson = beanJsonConverter.convertToObject(result, Person.class); assertEquals(johnDoe.getId(), parsedPerson.getId()); assertEquals(johnDoe.getName().getFormatted(), parsedPerson.getName().getFormatted()); List<Address> addresses = parsedPerson.getAddresses(); if (outputInfo) { for (Object o : addresses) { log.info("Address " + o); } } assertEquals(1, addresses.size()); Address address = addresses.get(0); String formatted = address.getFormatted(); assertNotNull(formatted); assertEquals(johnDoe.getAddresses().get(0).getFormatted(), parsedPerson .getAddresses().get(0).getFormatted()); assertEquals(3, parsedPerson.getPhoneNumbers().size()); for (int i = 0; i < johnDoe.getPhoneNumbers().size(); i++) { ListField expectedPhone = johnDoe.getPhoneNumbers().get(i); ListField actualPhone = parsedPerson.getPhoneNumbers().get(i); assertEquals(expectedPhone.getType(), actualPhone.getType()); assertEquals(expectedPhone.getValue(), actualPhone.getValue()); } assertEquals(2, parsedPerson.getEmails().size()); for (int i = 0; i < johnDoe.getEmails().size(); i++) { ListField expectedEmail = johnDoe.getEmails().get(i); ListField actualEmail = parsedPerson.getEmails().get(i); assertEquals(expectedEmail.getType(), actualEmail.getType()); assertEquals(expectedEmail.getValue(), actualEmail.getValue()); } } public void testActivityToJson() throws Exception { String result = beanJsonConverter.convertToString(activity); if (outputInfo) { log.info("JSON (" + result + ")"); } Activity parsedActivity = beanJsonConverter.convertToObject(result, Activity.class); assertEquals(activity.getUserId(), parsedActivity.getUserId()); assertEquals(activity.getId(), parsedActivity.getId()); assertEquals(1, parsedActivity.getMediaItems().size()); MediaItem expectedItem = activity.getMediaItems().get(0); MediaItem actualItem = parsedActivity.getMediaItems().get(0); assertEquals(expectedItem.getUrl(), actualItem.getUrl()); assertEquals(expectedItem.getMimeType(), actualItem.getMimeType()); assertEquals(expectedItem.getType().toString(), actualItem.getType().toString()); } public void testMapsToJson() throws Exception { Map<String, Map<String, String>> map = Maps.newHashMap(); Map<String, String> item1Map = Maps.newHashMap(); item1Map.put("value", "1"); // Null values shouldn't cause exceptions item1Map.put("value2", null); map.put("item1", item1Map); Map<String, String> item2Map = Maps.newHashMap(); item2Map.put("value", "2"); map.put("item2", item2Map); String result = beanJsonConverter.convertToString(map); if (outputInfo) { log.info("JSON (" + result + ")"); } // there is introspection that can tell jsonobject -> bean converter what a // map should contain, so we have to tell it beanJsonConverter.addMapping("item1", Map.class); beanJsonConverter.addMapping("item2", Map.class); Map<?, ?> parsedMap = beanJsonConverter.convertToObject(result, Map.class); if (outputInfo) { log.info("Dumping Map (" + parsedMap + ")"); } ApiValidator.dump(parsedMap); assertEquals("1", ((Map<?, ?>) parsedMap.get("item1")).get("value")); assertEquals("2", ((Map<?, ?>) parsedMap.get("item2")).get("value")); } public void testListsToJson() throws Exception { Map<String, String> item1Map = Maps.newHashMap(); item1Map.put("value", "1"); Map<String, String> item2Map = Maps.newHashMap(); item2Map.put("value", "2"); // put the list into a container before serializing, top level lists dont // appear // to be allowed in json // just check that the list is in the holder correctly List<Map<String, String>> list = Lists.newArrayList(); list.add(item1Map); list.add(item2Map); String result = beanJsonConverter.convertToString(list); if (outputInfo) { log.info("JSON (" + result + ")"); } Map<?, ?>[] parsedList = beanJsonConverter.convertToObject(result, Map[].class); assertEquals("1", parsedList[0].get("value")); assertEquals("2", parsedList[1].get("value")); } public void testArrayToJson() throws Exception { String[] colors = { "blue", "green", "aquamarine" }; String result = beanJsonConverter.convertToString(colors); if (outputInfo) { log.info("JSON (" + result + ")"); } String[] parsedColors = beanJsonConverter.convertToObject(result, String[].class); assertEquals(colors.length, parsedColors.length); assertEquals(colors[0], parsedColors[0]); assertEquals(colors[1], parsedColors[1]); assertEquals(colors[2], parsedColors[2]); } public void testJsonToActivity() throws Exception { String jsonActivity = "{userId : 5, id : 6, mediaItems : [" + "{url : 'hello', mimeType : 'mimey', type : 'VIDEO'}" + "]}"; Activity result = beanJsonConverter.convertToObject(jsonActivity, Activity.class); assertEquals("5", result.getUserId()); assertEquals("6", result.getId()); assertEquals(1, result.getMediaItems().size()); MediaItem actualItem = result.getMediaItems().get(0); assertEquals("hello", actualItem.getUrl()); assertEquals("mimey", actualItem.getMimeType()); assertEquals("video", actualItem.getType().toString()); } @SuppressWarnings("unchecked") public void testJsonToMap() throws Exception { String jsonActivity = "{count : 0, favoriteColor : 'yellow'}"; Map<String, Object> data = Maps.newHashMap(); data = beanJsonConverter.convertToObject(jsonActivity, (Class<Map<String, Object>>) data .getClass()); assertEquals(2, data.size()); for (Entry<String, Object> entry : data.entrySet()) { String key = entry.getKey(); Object value = entry.getValue(); if (key.equals("count")) { assertEquals(0, value); } else if (key.equals("favoriteColor")) { assertEquals("yellow", value); } } } public void testEmptyObject() { assertEquals("{}", beanJsonConverter.convertToString("")); assertEquals(0, beanJsonConverter.convertToObject("", Map.class).size()); assertEquals(0, beanJsonConverter.convertToObject("[]", String[].class).length); assertEquals(2, beanJsonConverter.convertToObject("[\"a\",\"b\"]", String[].class).length); } public void testException() { // a bit brain dead, but makes certain the exception is available in all forms assertNotNull(new BeanJsonLibConversionException()); assertNotNull(new BeanJsonLibConversionException("message")); assertNotNull(new BeanJsonLibConversionException(new Exception())); assertNotNull(new BeanJsonLibConversionException("message", new Exception())); } }