blob: c9aaf047a0883b1b469e550124698ced800d29ae [file] [log] [blame]
package org.codehaus.jackson.map.ser;
import org.codehaus.jackson.map.BaseMapTest;
import java.io.*;
import java.util.*;
import org.codehaus.jackson.annotate.*;
import org.codehaus.jackson.map.*;
import org.codehaus.jackson.map.annotate.JsonView;
/**
* Unit tests for verifying JSON view functionality: ability to declaratively
* suppress subset of properties from being serialized.
*/
public class TestViews
extends BaseMapTest
{
/*
/**********************************************************
/* Helper types
/**********************************************************
*/
// Classes that represent views
static class ViewA { }
static class ViewAA extends ViewA { }
static class ViewB { }
static class ViewBB extends ViewB { }
static class Bean
{
@JsonView(ViewA.class)
public String a = "1";
@JsonView({ViewAA.class, ViewB.class})
public String aa = "2";
@JsonView(ViewB.class)
public String getB() { return "3"; }
}
/**
* Bean with mix of explicitly annotated
* properties, and implicit ones that may or may
* not be included in views.
*/
static class MixedBean
{
@JsonView(ViewA.class)
public String a = "1";
public String getB() { return "2"; }
}
/**
* As indicated by [JACKSON-261], @JsonView should imply
* that associated element (method, field) is to be considered
* a property
*/
static class ImplicitBean {
@SuppressWarnings("unused")
@JsonView(ViewA.class)
private int a = 1;
}
static class VisibilityBean {
@JsonProperty protected String id = "id";
@JsonView(ViewA.class)
public String value = "x";
}
/*
/**********************************************************
/* Unit tests
/**********************************************************
*/
@SuppressWarnings("unchecked")
public void testSimple() throws IOException
{
StringWriter sw = new StringWriter();
ObjectMapper mapper = new ObjectMapper();
// Ok, first, using no view whatsoever; all 3
Bean bean = new Bean();
Map<String,Object> map = writeAndMap(mapper, bean);
assertEquals(3, map.size());
// Then with "ViewA", just one property
sw = new StringWriter();
mapper.writerWithView(ViewA.class).writeValue(sw, bean);
map = mapper.readValue(sw.toString(), Map.class);
assertEquals(1, map.size());
assertEquals("1", map.get("a"));
// "ViewAA", 2 properties
sw = new StringWriter();
mapper.writerWithView(ViewAA.class).writeValue(sw, bean);
map = mapper.readValue(sw.toString(), Map.class);
assertEquals(2, map.size());
assertEquals("1", map.get("a"));
assertEquals("2", map.get("aa"));
// "ViewB", 2 prop2
String json = mapper.writerWithView(ViewB.class).writeValueAsString(bean);
map = mapper.readValue(json, Map.class);
assertEquals(2, map.size());
assertEquals("2", map.get("aa"));
assertEquals("3", map.get("b"));
// and "ViewBB", 2 as well
json = mapper.writerWithView(ViewBB.class).writeValueAsString(bean);
map = mapper.readValue(json, Map.class);
assertEquals(2, map.size());
assertEquals("2", map.get("aa"));
assertEquals("3", map.get("b"));
}
/**
* Unit test to verify implementation of [JACKSON-232], to
* allow "opt-in" handling for JSON Views: that is, that
* default for properties is to exclude unless included in
* a view.
*/
@SuppressWarnings("unchecked")
public void testDefaultExclusion() throws IOException
{
MixedBean bean = new MixedBean();
StringWriter sw = new StringWriter();
ObjectMapper mapper = new ObjectMapper();
// default setting: both fields will get included
mapper.writerWithView(ViewA.class).writeValue(sw, bean);
Map<String,Object> map = mapper.readValue(sw.toString(), Map.class);
assertEquals(2, map.size());
assertEquals("1", map.get("a"));
assertEquals("2", map.get("b"));
// but can also change (but not necessarily on the fly...)
mapper = new ObjectMapper();
mapper.configure(SerializationConfig.Feature.DEFAULT_VIEW_INCLUSION, false);
// with this setting, only explicit inclusions count:
String json = mapper.writerWithView(ViewA.class).writeValueAsString(bean);
map = mapper.readValue(json, Map.class);
assertEquals(1, map.size());
assertEquals("1", map.get("a"));
assertNull(map.get("b"));
}
/**
* As per [JACKSON-261], @JsonView annotation should imply that associated
* method/field does indicate a property.
*/
public void testImplicitAutoDetection() throws Exception
{
assertEquals("{\"a\":1}", serializeAsString(new ImplicitBean()));
}
public void testVisibility() throws Exception
{
ObjectMapper mapper = new ObjectMapper();
VisibilityBean bean = new VisibilityBean();
// Without view setting, should only see "id"
String json = mapper.writerWithView(Object.class).writeValueAsString(bean);
//json = mapper.writeValueAsString(bean);
assertEquals("{\"id\":\"id\"}", json);
}
}