/*
* JBoss, Home of Professional Open Source
* Copyright 2013, Red Hat, Inc. and individual contributors
* by the @authors tag. See the copyright.txt in the distribution for a
* full listing of individual contributors.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This software 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, write to the Free
* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
* 02110-1301 USA, or see the FSF site: http://www.fsf.org.
*/
package org.ajax4jsf.javascript;
import static org.easymock.EasyMock.capture;
import static org.easymock.EasyMock.eq;
import static org.easymock.EasyMock.expectLastCall;
import static org.easymock.EasyMock.isNull;
import static org.junit.Assert.assertThat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.TreeMap;
import java.util.TreeSet;
import javax.faces.context.ResponseWriter;
import junit.framework.TestCase;
import org.easymock.Capture;
import org.easymock.CaptureType;
import org.hamcrest.CoreMatchers;
import org.jboss.test.faces.mock.MockFacesEnvironment;
import org.junit.Test;
/**
* @author shura
*/
public class ScriptUtilsTest extends TestCase {
/**
* @param name
*/
public ScriptUtilsTest(String name) {
super(name);
}
private static enum TestEnum {
A,
B,
C;
@Override
public String toString() {
return "TestEnum: " + super.toString();
}
}
public static class ReferencedBean {
private String name;
private ReferenceHolderBean parent;
public ReferencedBean(String name, ReferenceHolderBean parent) {
super();
this.name = name;
this.parent = parent;
}
public ReferenceHolderBean getParent() {
return parent;
}
public String getName() {
return name;
}
}
public static class ReferenceHolderBean {
private String name;
private Object reference;
public ReferenceHolderBean(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public Object getReference() {
return reference;
}
public void setReference(Object reference) {
this.reference = reference;
}
}
private static String dehydrate(String s) {
return s != null ? s.replaceAll("\\s", "") : s;
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testStringToScript() {
Object obj = "f \b\r\t\f\n\"'\\/ oo ]&<>-";
assertEquals("\"f \\b\\r\\t\\f\\n\\\"'\\\\\\/ oo \\u005D\\u0026\\u003C\\u003E\\u002D\"",
ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testArrayToScript() {
int[] obj = { 1, 2, 3, 4, 5 };
assertEquals("[1,2,3,4,5] ", ScriptUtils.toScript(obj));
}
public void testSqlDate() {
java.sql.Time obj = new java.sql.Time(1);
String timeString = ScriptUtils.toScript(obj);
timeString = ScriptUtils.toScript(obj);
timeString = ScriptUtils.toScript(obj);
timeString = ScriptUtils.toScript(obj);
timeString = ScriptUtils.toScript(obj);
assertNotNull(timeString);
assertFalse(timeString.contains("year"));
java.sql.Date obj1 = new java.sql.Date(1);
String dateString = ScriptUtils.toScript(obj1);
assertNotNull(dateString);
assertFalse(dateString.contains("seconds"));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testTwoDimentionalArrayToScript() {
int[][] obj = { { 1, 2 }, { 3, 4 } };
assertEquals("[[1,2] ,[3,4] ] ", ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testTwoDimentionalStringArrayToScript() {
String[][] obj = { { "one", "two" }, { "three", "four" } };
assertEquals("[[\"one\",\"two\"] ,[\"three\",\"four\"] ] ", ScriptUtils.toScript(obj));
Map<String, Object> map = new TreeMap<String, Object>();
map.put("a", obj);
map.put("b", "c");
assertEquals("{\"a\":[[\"one\",\"two\"] ,[\"three\",\"four\"] ] ,\"b\":\"c\"} ", ScriptUtils.toScript(map));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testListToScript() {
List<Integer> obj = new ArrayList<Integer>();
obj.add(new Integer(1));
obj.add(new Integer(2));
obj.add(new Integer(3));
obj.add(new Integer(4));
obj.add(new Integer(5));
assertEquals("[1,2,3,4,5] ", ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testSetToScript() {
Set<Integer> obj = new TreeSet<Integer>();
obj.add(new Integer(1));
obj.add(new Integer(2));
obj.add(new Integer(3));
obj.add(new Integer(4));
obj.add(new Integer(5));
assertEquals("[1,2,3,4,5] ", ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testObjectArrayToScript() {
Bean[] obj = { new Bean(1, true, "foo"), new Bean(2, false, "bar") };
assertEquals("[{\"bool\":true,\"foo\":\"foo\",\"integer\":1} ,{\"bool\":false,\"foo\":\"bar\",\"integer\":2} ] ",
ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testObjectListToScript() {
Bean[] array = { new Bean(1, true, "foo"), new Bean(2, false, "bar") };
List<Bean> obj = Arrays.asList(array);
assertEquals("[{\"bool\":true,\"foo\":\"foo\",\"integer\":1} ,{\"bool\":false,\"foo\":\"bar\",\"integer\":2} ] ",
ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#toScript(java.lang.Object)}.
*/
public void testMapToScript() {
TreeMap<String, String> obj = new TreeMap<String, String>();
obj.put("a", "foo");
obj.put("b", "bar");
obj.put("c", "baz");
assertEquals("{\"a\":\"foo\",\"b\":\"bar\",\"c\":\"baz\"} ", ScriptUtils.toScript(obj));
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#addEncodedString(java.lang.StringBuffer, java.lang.Object)}.
*
* @throws Exception
*/
public void testAddEncodedString() throws Exception {
StringBuilder buff = new StringBuilder();
ScriptUtils.appendEncodedString(buff, "foo");
assertEquals("\"foo\"", buff.toString());
}
/**
* Test method for {@link org.richfaces.javascript.ScriptUtils#addEncoded(java.lang.StringBuffer, java.lang.Object)}.
*
* @throws Exception
*/
public void testAddEncoded() throws Exception {
StringBuilder buff = new StringBuilder();
ScriptUtils.appendEncoded(buff, "foo");
assertEquals("foo", buff.toString());
}
/**
* Test method for {@link ScriptUtils#toScript(Object)}
*/
public void testNull() throws Exception {
assertEquals("null", ScriptUtils.toScript(null));
}
/**
* Test method for {@link ScriptUtils#toScript(Object)}
*/
public void testScriptString() throws Exception {
assertEquals("alert(x<y);", ScriptUtils.toScript(new JSLiteral("alert(x<y);")));
}
/**
* Test method for {@link ScriptUtils#toScript(Object)}
*/
public void testEnum() throws Exception {
assertEquals("\"TestEnum: B\"", ScriptUtils.toScript(TestEnum.B));
}
public void testCharacter() throws Exception {
assertEquals("\"N\"", ScriptUtils.toScript('N'));
}
private void assertCaptureEquals(Capture<? extends Object> capture, String expected) {
StringBuilder sb = new StringBuilder();
List<? extends Object> list = capture.getValues();
for (Object o : list) {
assertNotNull(o);
sb.append(o);
}
assertEquals(expected, sb.toString().trim());
}
/**
* Test method for {@link ScriptUtils#writeToStream(javax.faces.context.ResponseWriter, Object)}
*/
public void testWriteToStream() throws Exception {
MockFacesEnvironment environment = MockFacesEnvironment.createEnvironment();
ResponseWriter mockWriter = environment.createMock(ResponseWriter.class);
Capture<? extends Object> capture = new Capture<Object>(CaptureType.ALL) {
/**
*
*/
private static final long serialVersionUID = -4915440411892856583L;
@Override
public void setValue(Object value) {
if (value instanceof char[]) {
char[] cs = (char[]) value;
super.setValue(new String(cs, 0, 1));
} else {
super.setValue(value);
}
}
};
mockWriter.writeText(capture(capture), (String) isNull());
expectLastCall().anyTimes();
mockWriter.writeText((char[]) capture(capture), eq(0), eq(1));
expectLastCall().anyTimes();
environment.replay();
ScriptUtils.writeToStream(mockWriter, Collections.singletonMap("delay", Integer.valueOf(1500)));
environment.verify();
assertCaptureEquals(capture, "{\"delay\":1500}");
environment.release();
}
/**
* @author shura
*/
public static class Bean {
private boolean bool;
private Object foo;
private int integer;
public Bean() {
}
/**
* @param ineger
* @param bool
* @param foo
*/
public Bean(int ineger, boolean bool, Object foo) {
this.integer = ineger;
this.bool = bool;
this.foo = foo;
}
/**
* @return the bool
*/
public boolean isBool() {
return this.bool;
}
/**
* @param bool the bool to set
*/
public void setBool(boolean bool) {
this.bool = bool;
}
/**
* @return the ineger
*/
public int getInteger() {
return this.integer;
}
/**
* @param ineger the ineger to set
*/
public void setInteger(int ineger) {
this.integer = ineger;
}
/**
* @return the foo
*/
public Object getFoo() {
return this.foo;
}
/**
* @param foo the foo to set
*/
public void setFoo(Object foo) {
this.foo = foo;
}
}
public void testCircularReferenceBeans() throws Exception {
ReferenceHolderBean parent = new ReferenceHolderBean("parent");
ReferencedBean child = new ReferencedBean("child", parent);
assertEquals(dehydrate("{\"name\": \"child\", \"parent\": {\"name\": \"parent\", \"reference\": null}}"),
dehydrate(ScriptUtils.toScript(child)));
}
public void testCircularReferenceViaProperty() throws Exception {
ReferenceHolderBean parent = new ReferenceHolderBean("parent");
ReferencedBean child = new ReferencedBean("child", parent);
parent.setReference(child);
assertEquals(dehydrate("{\"name\": \"parent\", \"reference\": {\"name\": \"child\", \"parent\": null}}"),
dehydrate(ScriptUtils.toScript(parent)));
}
public void testCircularReferenceViaArray() throws Exception {
ReferenceHolderBean parent = new ReferenceHolderBean("parent");
ReferencedBean child = new ReferencedBean("child", parent);
parent.setReference(new Object[] { child });
assertEquals(dehydrate("{\"name\": \"parent\", \"reference\": [{\"name\": \"child\", \"parent\": null}]}"),
dehydrate(ScriptUtils.toScript(parent)));
}
public void testCircularReferenceViaCollection() throws Exception {
ReferenceHolderBean parent = new ReferenceHolderBean("parent");
ReferencedBean child = new ReferencedBean("child", parent);
Collection<Object> set = new ArrayList<Object>();
set.add(child);
parent.setReference(set);
assertEquals(dehydrate("{\"name\": \"parent\", \"reference\": [{\"name\": \"child\", \"parent\": null}]}"),
dehydrate(ScriptUtils.toScript(parent)));
}
public void testCircularReferenceViaMap() throws Exception {
ReferenceHolderBean parent = new ReferenceHolderBean("parent");
ReferencedBean child = new ReferencedBean("child", parent);
Map<String, Object> map = new HashMap<String, Object>();
map.put("key", child);
parent.setReference(map);
assertEquals(dehydrate("{\"name\": \"parent\", \"reference\": {\"key\": {\"name\": \"child\", \"parent\": null}}}"),
dehydrate(ScriptUtils.toScript(parent)));
}
@Test
public void testEscapeStringForCSSSelector() throws Exception {
assertNull(ScriptUtils.escapeCSSMetachars(null));
assertEquals("", ScriptUtils.escapeCSSMetachars(""));
assertEquals("test", ScriptUtils.escapeCSSMetachars("test"));
assertEquals("test\\.string", ScriptUtils.escapeCSSMetachars("test.string"));
assertEquals("test\\.\\=string", ScriptUtils.escapeCSSMetachars("test.=string"));
assertEquals("some\\.test\\=string", ScriptUtils.escapeCSSMetachars("some.test=string"));
assertEquals("\\#test", ScriptUtils.escapeCSSMetachars("#test"));
assertEquals("\\#\\=test", ScriptUtils.escapeCSSMetachars("#=test"));
assertEquals("test\\#", ScriptUtils.escapeCSSMetachars("test#"));
assertEquals("test\\#\\=", ScriptUtils.escapeCSSMetachars("test#="));
}
@Test
public void testTimezoneSerialization() throws Exception {
TimeZone utcPlusTwoTZ = TimeZone.getTimeZone("GMT+02:00");
String serializedUTCPlusTwoTZ = dehydrate(ScriptUtils.toScript(utcPlusTwoTZ));
assertThat(serializedUTCPlusTwoTZ, CoreMatchers.containsString("\"DSTSavings\":0"));
assertThat(serializedUTCPlusTwoTZ, CoreMatchers.containsString("\"ID\":\"GMT+02:00\""));
assertThat(serializedUTCPlusTwoTZ, CoreMatchers.containsString("\"rawOffset\":7200000"));
TimeZone pstTimeZone = TimeZone.getTimeZone("PST");
String serializedPSTTimeZone = dehydrate(ScriptUtils.toScript(pstTimeZone));
assertThat(serializedPSTTimeZone, CoreMatchers.containsString("\"ID\":\"PST\""));
assertThat(serializedPSTTimeZone, CoreMatchers.containsString("\"rawOffset\":-28800000"));
TimeZone sfTimeZone = TimeZone.getTimeZone("America/New_York");
String serializedSFTimeZone = dehydrate(ScriptUtils.toScript(sfTimeZone));
assertThat(serializedSFTimeZone, CoreMatchers.containsString("\"ID\":\"America\\/New_York\""));
assertThat(serializedSFTimeZone, CoreMatchers.containsString("\"rawOffset\":-18000000"));
}
@Test
public void testGetMD5scriptHash() throws Exception {
String testString = "Some string to hash";
String expectedMD5hash = "7624f3fd394f02f0ff8c53fac249129a";
String computedMD5hash = ScriptUtils.getMD5scriptHash(testString);
assertEquals(expectedMD5hash, computedMD5hash);
}
}