com.restfb.util.InsightUtilsTest.java Source code

Java tutorial

Introduction

Here is the source code for com.restfb.util.InsightUtilsTest.java

Source

/**
 * Copyright (c) 2010-2016 Mark Allen, Norbert Bartels.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.restfb.util;

import static com.restfb.util.InsightUtils.*;
import static org.junit.Assert.assertEquals;

import com.restfb.*;
import com.restfb.json.JsonArray;
import com.restfb.json.JsonObject;
import com.restfb.util.InsightUtils.*;

import org.json.JSONException;
import org.junit.Assert;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.skyscreamer.jsonassert.JSONAssert;
import org.skyscreamer.jsonassert.JSONCompareMode;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;

/**
 * Unit tests that exercise {@link com.restfb.util.InsightUtils}.
 * 
 * @author Andrew Liles
 */
public class InsightUtilsTest {
    private static final String JSON_RESOURCES_PREFIX = "/json/insight/";
    private static Locale DEFAULT_LOCALE;
    private static final TimeZone UTC_TIMEZONE = TimeZone.getTimeZone("Etc/UTC");
    private static final TimeZone PST_TIMEZONE = TimeZone.getTimeZone("PST");
    private static SimpleDateFormat sdfUTC;
    private static SimpleDateFormat sdfPST;
    private static final String TEST_PAGE_OBJECT = "31698190356";
    private static Date d20101204_0000pst;
    private static Date d20101205_0000pst;
    private FacebookClient defaultNoAccessTokenClient;

    @BeforeClass
    public static void beforeClass() throws ParseException {
        for (Locale locale : Locale.getAvailableLocales()) {
            if (locale.toString().equals("en_US")) {
                DEFAULT_LOCALE = locale;
                break;
            }
        }
        Assert.assertNotNull(DEFAULT_LOCALE);
        sdfUTC = newSimpleDateFormat("yyyyMMdd_HHmm", DEFAULT_LOCALE, UTC_TIMEZONE);
        sdfPST = newSimpleDateFormat("yyyyMMdd_HHmm", DEFAULT_LOCALE, PST_TIMEZONE);
        d20101204_0000pst = sdfPST.parse("20101204_0000");
        d20101205_0000pst = sdfPST.parse("20101205_0000");
    }

    @Before
    public void before() {
        defaultNoAccessTokenClient = new DefaultFacebookClient(Version.LATEST);
    }

    @Test
    public void convertToMidnightInPacificTimeZone1() throws ParseException {
        Date d20030630_0221utc = sdfUTC.parse("20030630_0221");
        Date d20030629_0000pst = sdfPST.parse("20030629_0000");

        Date actual = convertToMidnightInPacificTimeZone(d20030630_0221utc);
        assertEquals(d20030629_0000pst, actual);
    }

    @Test
    public void convertToMidnightInPacificTimeZone2() throws ParseException {
        Date d20030630_1503utc = sdfUTC.parse("20030630_1503");
        Date d20030630_0000pst = sdfPST.parse("20030630_0000");

        Date actual = convertToMidnightInPacificTimeZone(d20030630_1503utc);
        assertEquals(d20030630_0000pst, actual);
    }

    @Test
    public void convertToMidnightInPacificTimeZoneSet1() throws ParseException {
        Date d20030630_0221utc = sdfUTC.parse("20030630_0221");
        Date d20030629_0000pst = sdfPST.parse("20030629_0000");
        Date d20030630_1503utc = sdfUTC.parse("20030630_1503");
        Date d20030630_0000pst = sdfPST.parse("20030630_0000");
        Set<Date> inputs = new HashSet<Date>();
        inputs.add(d20030630_0221utc);
        inputs.add(d20030630_1503utc);

        SortedSet<Date> actuals = convertToMidnightInPacificTimeZone(inputs);
        assertEquals(2, actuals.size());
        Iterator<Date> it = actuals.iterator();
        assertEquals(d20030629_0000pst, it.next());
        assertEquals(d20030630_0000pst, it.next());
    }

    @Test
    public void convertToUnixTimeAtPacificTimeZoneMidnightOneDayLater1() throws ParseException {
        // From http://developers.facebook.com/docs/reference/fql/insights/
        // Example: To obtain data for the 24-hour period starting on
        // September 15th at 00:00 (i.e. 12:00 midnight) and ending on
        // September 16th at 00:00 (i.e. 12:00 midnight),
        // specify 1284620400 as the end_time and 86400 as the period.

        Date d20100916_1800utc = sdfUTC.parse("20100915_1200");

        long actual = convertToUnixTimeAtPacificTimeZoneMidnightOneDayLater(d20100916_1800utc);
        assertEquals(1284620400L, actual);
    }

    @Test
    public void convertToUnixTimeAtPacificTimeZoneMidnightOneDayLater2() throws ParseException {
        // in this test we are still in the previous PST day - the difference is 7
        // hours from UTC to PST

        Date d20100917_0659utc = sdfUTC.parse("20100916_0659");

        long actual = convertToUnixTimeAtPacificTimeZoneMidnightOneDayLater(d20100917_0659utc);
        assertEquals(1284620400L, actual);

        Date d20100917_0700utc = sdfUTC.parse("20100916_0700");

        actual = convertToUnixTimeAtPacificTimeZoneMidnightOneDayLater(d20100917_0700utc);
        assertEquals(1284620400L + (60 * 60 * 24), actual);
    }

    @Test
    public void convertToUnixTimeOneDayLater1() throws ParseException {
        Object[][] testset = {
                // 3 summertime:
                { "2010-09-15", 1284620400L }, { "2010-09-16", 1284706800L }, { "2010-09-17", 1284793200L },
                // 3 wintertime:
                { "2010-12-15", 1292486400L }, { "2010-12-16", 1292572800L }, { "2010-12-17", 1292659200L },
                // 3 across the DST switch in 2011 in the US was Sunday 6 Nov
                { "2011-11-05", 1320562800L }, { "2011-11-06", 1320649200L }, { "2011-11-07", 1320739200L } };
        SimpleDateFormat sdfPST2 = newSimpleDateFormat("yyyy-MM-dd", DEFAULT_LOCALE, PST_TIMEZONE);
        for (Object[] test : testset) {
            Date d = sdfPST2.parse((String) test[0]);
            long expectedUnixDate = (Long) test[1];
            assertEquals("On date " + test[0], expectedUnixDate, convertToUnixTimeOneDayLater(d));
        }
    }

    @Test
    public void createBaseQuery0metrics() {
        Set<String> metrics = Collections.emptySet();
        assertEquals("SELECT metric, value FROM insights WHERE object_id='31698190356' AND "
                + "period=604800 AND end_time=", createBaseQuery(Period.WEEK, TEST_PAGE_OBJECT, metrics));

        // what about all empties/nulls in the list?
        metrics = new LinkedHashSet<String>();
        metrics.add(null);
        metrics.add("");
        metrics.add("");
        assertEquals("SELECT metric, value FROM insights WHERE object_id='31698190356' AND "
                + "period=604800 AND end_time=", createBaseQuery(Period.WEEK, TEST_PAGE_OBJECT, metrics));
    }

    @Test
    public void createBaseQuery1metric() {
        Set<String> metrics = Collections.singleton("page_active_users");
        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_active_users') AND period=604800 AND end_time=",
                createBaseQuery(Period.WEEK, TEST_PAGE_OBJECT, metrics));
    }

    @Test
    public void createBaseQuery3metrics() {
        Set<String> metrics = new LinkedHashSet<String>();
        metrics.add("page_comment_removes");
        metrics.add("page_active_users");
        metrics.add("page_like_adds_source_unique");
        assertEquals("SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                + "('page_comment_removes','page_active_users','page_like_adds_source_unique') AND period=86400 AND end_time=",
                createBaseQuery(Period.DAY, TEST_PAGE_OBJECT, metrics));
    }

    @Test
    public void createBaseQuery4metrics() {
        // are null/empty metrics removed from the list?
        Set<String> metrics = new LinkedHashSet<String>();
        metrics.add("");
        metrics.add("page_comment_removes");
        metrics.add("");
        metrics.add("page_like_adds_source_unique");
        metrics.add(null);
        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_comment_removes','page_like_adds_source_unique') AND period=86400 AND end_time=",
                createBaseQuery(Period.DAY, TEST_PAGE_OBJECT, metrics));
    }

    @Test
    public void buildQueries1() throws ParseException {
        long t20101205_0000 = 1291536000L;
        assertEquals(t20101205_0000, convertToUnixTimeAtPacificTimeZoneMidnightOneDayLater(d20101204_0000pst));
        assertEquals(t20101205_0000, d20101205_0000pst.getTime() / 1000L);

        List<Date> datesByQueryIndex = new ArrayList<Date>();
        datesByQueryIndex.add(d20101204_0000pst);

        String baseQuery = "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                + "('page_active_users') AND period=604800 AND end_time=";

        Map<String, String> fqlByQueryIndex = buildQueries(baseQuery, datesByQueryIndex);
        assertEquals(1, fqlByQueryIndex.size());

        String fql = fqlByQueryIndex.values().iterator().next();
        Assert.assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN ('page_active_users') AND period=604800 AND end_time="
                        + t20101205_0000,
                fql);
    }

    @Test
    public void prepareQueries30() throws Exception {
        // produce a set of days in UTC timezone from 1st Nov 9am to 30th Nov 9am
        // inclusive
        Date d20101101_0900utc = sdfUTC.parse("20101101_0900");
        Calendar c = new GregorianCalendar();
        c.setTimeZone(UTC_TIMEZONE);
        c.setTime(d20101101_0900utc);
        Set<Date> utcDates = new TreeSet<Date>();
        for (int dayNum = 1; dayNum <= 30; dayNum++) {
            utcDates.add(c.getTime());
            c.add(Calendar.DAY_OF_MONTH, 1);
        }
        assertEquals(30, utcDates.size());

        // convert into PST and convert into a list
        List<Date> datesByQueryIndex = new ArrayList<Date>(convertToMidnightInPacificTimeZone(utcDates));
        assertEquals(30, datesByQueryIndex.size());

        // Mon Nov 01 00:00:00 2010 PST
        long day0 = sdfPST.parse("20101101_0000").getTime() / 1000L + 60 * 60 * 24;
        // Sat Nov 06 00:00:00 2010 PST
        long day5 = sdfPST.parse("20101106_0000").getTime() / 1000L + 60 * 60 * 24;

        // Sun Nov 07 00:00:00 2010 PST
        // //////////// NOTE 7 Nov 2010 was when Summer time turned into Winter time
        long day6 = sdfPST.parse("20101107_0000").getTime() / 1000L + 60 * 60 * 24;

        // Mon Nov 08 00:00:00 2010 PST
        long day7 = sdfPST.parse("20101108_0000").getTime() / 1000L + 60 * 60 * 24;
        // Tue Nov 30 00:00:00 2010 PST
        long day29 = sdfPST.parse("20101130_0000").getTime() / 1000L + 60 * 60 * 24;

        String baseQuery = "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                + "('page_active_users','page_audio_plays') AND period=86400 AND end_time=";

        Map<String, String> fqlByQueryIndex = buildQueries(baseQuery, datesByQueryIndex);
        assertEquals(30, fqlByQueryIndex.size());

        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_active_users','page_audio_plays') AND period=86400 AND end_time=" + day0,
                fqlByQueryIndex.get("0"));
        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_active_users','page_audio_plays') AND period=86400 AND end_time=" + day5,
                fqlByQueryIndex.get("5"));
        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_active_users','page_audio_plays') AND period=86400 AND end_time=" + day6,
                fqlByQueryIndex.get("6"));
        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_active_users','page_audio_plays') AND period=86400 AND end_time=" + day7,
                fqlByQueryIndex.get("7"));
        assertEquals(
                "SELECT metric, value FROM insights WHERE object_id='31698190356' AND metric IN "
                        + "('page_active_users','page_audio_plays') AND period=86400 AND end_time=" + day29,
                fqlByQueryIndex.get("29"));
    }

    @Test(expected = IllegalArgumentException.class)
    public void executeInsightQueriesByDate_badArgs1() {
        executeInsightQueriesByDate(null, TEST_PAGE_OBJECT, Collections.singleton("page_active_users"), Period.DAY,
                Collections.singleton(d20101205_0000pst));
    }

    @Test(expected = IllegalArgumentException.class)
    public void executeInsightQueriesByDate_badArgs2() {
        executeInsightQueriesByDate(defaultNoAccessTokenClient, "", Collections.singleton("page_active_users"),
                Period.DAY, Collections.singleton(d20101205_0000pst));
    }

    @Test(expected = IllegalArgumentException.class)
    public void executeInsightQueriesByDate_badArgs3() {
        executeInsightQueriesByDate(defaultNoAccessTokenClient, TEST_PAGE_OBJECT,
                Collections.singleton("page_active_users"), null, Collections.singleton(d20101205_0000pst));
    }

    @Test(expected = IllegalArgumentException.class)
    public void executeInsightQueriesByDate_badArgs4() {
        executeInsightQueriesByDate(defaultNoAccessTokenClient, TEST_PAGE_OBJECT,
                Collections.singleton("page_active_users"), Period.DAY, new HashSet<Date>());
    }

    @Test(expected = IllegalArgumentException.class)
    public void executeInsightQueriesByDate_badArgs5() {
        executeInsightQueriesByDate(defaultNoAccessTokenClient, TEST_PAGE_OBJECT, new HashSet<String>(), Period.DAY,
                Collections.singleton(d20101205_0000pst));
    }

    @Test
    public void executeInsightQueriesByDate1() throws IOException, JSONException {
        // note that the query that is passed to the FacebookClient WebRequestor is
        // ignored,
        // so arguments of executeInsightQueriesByDate:
        // (String pageObjectId, Set<String> metrics, Period period)
        // are effectively ignored. In this test we are validating the
        // WebRequestor's json
        // is properly processed
        SortedMap<Date, JsonArray> results = executeInsightQueriesByDate(
                createFixedResponseFacebookClient("multiResponse_2metrics_1date.json"), TEST_PAGE_OBJECT,
                toStringSet("page_fans", "page_fans_gender"), Period.DAY, Collections.singleton(d20101205_0000pst));
        Assert.assertNotNull(results);
        assertEquals(1, results.size());
        JsonArray ja = results.get(d20101205_0000pst);
        Assert.assertNotNull(ja);
        // not ideal that this test requires on a stable JsonArray.toString()
        String expectedJson = "[{\"metric\":\"page_fans\",\"value\":3777},{\"metric\":\"page_fans_gender\",\"value\":{\"U\":58,\"F\":1656,\"M\":2014}}]";
        JSONAssert.assertEquals(expectedJson, ja.toString(), JSONCompareMode.NON_EXTENSIBLE);
    }

    @Test
    public void executeInsightQueriesByDate2() throws IOException, ParseException, JSONException {
        // note that the query that is passed to the FacebookClient WebRequestor is
        // ignored,
        // so arguments of executeInsightQueriesByDate:
        // (String pageObjectId, Set<String> metrics, Period period)
        // are effectively ignored. In this test we are validating the
        // WebRequestor's json
        // is properly processed

        Date d20030629_0000pst = sdfPST.parse("20030629_0000");
        Date d20030630_0000pst = sdfPST.parse("20030630_0000");
        Date d20030701_0000pst = sdfPST.parse("20030701_0000");
        Date d20030702_0000pst = sdfPST.parse("20030702_0000");
        // intentionally using (chaotic) HashSet to ensure implementation is
        // tolerant of that collection
        Set<Date> periodEndDates = new HashSet<Date>();
        periodEndDates.add(d20030629_0000pst);
        periodEndDates.add(d20030630_0000pst);
        periodEndDates.add(d20030701_0000pst);
        periodEndDates.add(d20030702_0000pst);

        SortedMap<Date, JsonArray> results = executeInsightQueriesByDate(
                createFixedResponseFacebookClient("multiResponse_2metrics_4dates.json"), TEST_PAGE_OBJECT,
                toStringSet("page_active_users", "page_tab_views_login_top_unique"), Period.DAY, periodEndDates);
        Assert.assertNotNull(results);
        assertEquals(4, results.size());
        // not ideal that this test requires on a stable JsonArray.toString()

        String expectedString;
        String actualString;

        expectedString = new JsonArray(
                "[{\"metric\":\"page_active_users\",\"value\":761},{\"metric\":\"page_tab_views_login_top_unique\",\"value\":{\"photos\":2,\"app_4949752878\":3,\"wall\":30}}]")
                        .toString();
        actualString = results.get(d20030629_0000pst).toString();
        JSONAssert.assertEquals(expectedString, actualString, JSONCompareMode.NON_EXTENSIBLE);

        expectedString = new JsonArray(
                "[{\"metric\":\"page_active_users\",\"value\":705},{\"metric\":\"page_tab_views_login_top_unique\",\"value\":{\"app_4949752878\":1,\"photos\":1,\"app_2373072738\":2,\"wall\":23}}]")
                        .toString();
        actualString = results.get(d20030630_0000pst).toString();
        JSONAssert.assertEquals(expectedString, actualString, JSONCompareMode.NON_EXTENSIBLE);

        expectedString = new JsonArray(
                "[{\"metric\":\"page_active_users\",\"value\":582},{\"metric\":\"page_tab_views_login_top_unique\",\"value\":{\"app_4949752878\":1,\"wall\":12}}]")
                        .toString();
        actualString = results.get(d20030701_0000pst).toString();
        JSONAssert.assertEquals(expectedString, actualString, JSONCompareMode.NON_EXTENSIBLE);

        expectedString = new JsonArray(
                "[{\"metric\":\"page_active_users\",\"value\":125},{\"metric\":\"page_tab_views_login_top_unique\",\"value\":{\"photos\":1,\"wall\":11}}]")
                        .toString();
        actualString = results.get(d20030702_0000pst).toString();
        JSONAssert.assertEquals(expectedString, actualString, JSONCompareMode.NON_EXTENSIBLE);
    }

    @Test
    public void executeInsightQueriesByMetricByDate1() throws IOException {
        // note that the query that is passed to the FacebookClient WebRequestor is
        // ignored,
        // so arguments of executeInsightQueriesByDate:
        // (String pageObjectId, Set<String> metrics, Period period)
        // are effectively ignored. In this test we are validating the
        // WebRequestor's json
        // is properly processed
        SortedMap<String, SortedMap<Date, Object>> results = executeInsightQueriesByMetricByDate(
                createFixedResponseFacebookClient("multiResponse_2metrics_1date.json"), TEST_PAGE_OBJECT,
                toStringSet("page_fans", "page_fans_gender"), Period.DAY, Collections.singleton(d20101205_0000pst));
        Assert.assertNotNull(results);
        assertEquals(2, results.size());

        SortedMap<Date, Object> metricResult = results.get("page_fans");
        assertEquals(1, metricResult.size());
        assertEquals(3777, metricResult.get(d20101205_0000pst));

        metricResult = results.get("page_fans_gender");
        assertEquals(1, metricResult.size());
        Object metricValue = metricResult.get(d20101205_0000pst);
        Assert.assertTrue(metricValue instanceof JsonObject);
        JsonObject o = (JsonObject) metricValue;
        assertEquals(58, o.getInt("U"));
        assertEquals(1656, o.getInt("F"));
        assertEquals(2014, o.getInt("M"));
    }

    @Test
    public void executeInsightQueriesByMetricByDate2() throws IOException, ParseException {
        // note that the query that is passed to the FacebookClient WebRequestor is
        // ignored,
        // so arguments of executeInsightQueriesByDate:
        // (String pageObjectId, Set<String> metrics, Period period)
        // are effectively ignored. In this test we are validating the
        // WebRequestor's json
        // is properly processed
        Date d20030629_0000pst = sdfPST.parse("20030629_0000");
        Date d20030630_0000pst = sdfPST.parse("20030630_0000");
        Date d20030701_0000pst = sdfPST.parse("20030701_0000");
        Date d20030702_0000pst = sdfPST.parse("20030702_0000");
        // intentionally using (chaotic) HashSet to ensure implementation is
        // tolerant of that collection
        Set<Date> periodEndDates = new HashSet<Date>();
        periodEndDates.add(d20030629_0000pst);
        periodEndDates.add(d20030630_0000pst);
        periodEndDates.add(d20030701_0000pst);
        periodEndDates.add(d20030702_0000pst);

        SortedMap<String, SortedMap<Date, Object>> results = executeInsightQueriesByMetricByDate(
                createFixedResponseFacebookClient("multiResponse_2metrics_4dates.json"), TEST_PAGE_OBJECT,
                toStringSet("page_active_users", "page_tab_views_login_top_unique"), Period.DAY, periodEndDates);
        Assert.assertNotNull(results);
        assertEquals(2, results.size());

        SortedMap<Date, Object> metricResult = results.get("page_active_users");
        assertEquals(4, metricResult.size());
        // {"name":0,"fql_result_set":[{"metric":"page_active_users","value":761},{"metric":"page_tab_views_login_top_unique","value":{"wall":30,"app_4949752878":3,"photos":2}}]},
        // here we validate the date map is sorted, so the results will come out in
        // a predictable order
        Iterator<Object> itValues = metricResult.values().iterator();
        assertEquals(761, itValues.next());
        assertEquals(705, itValues.next());
        assertEquals(582, itValues.next());
        assertEquals(125, itValues.next());

        metricResult = results.get("page_tab_views_login_top_unique");
        assertEquals(4, metricResult.size());
        JsonObject o = (JsonObject) metricResult.get(d20030629_0000pst);
        assertEquals(3, o.length());
        assertEquals(2, o.getInt("photos"));
        assertEquals(3, o.getInt("app_4949752878"));
        assertEquals(30, o.getInt("wall"));

        o = (JsonObject) metricResult.get(d20030630_0000pst);
        assertEquals(4, o.length());
        assertEquals(1, o.getInt("photos"));
        assertEquals(1, o.getInt("app_4949752878"));
        assertEquals(2, o.getInt("app_2373072738"));
        assertEquals(23, o.getInt("wall"));

        o = (JsonObject) metricResult.get(d20030701_0000pst);
        assertEquals(2, o.length());
        assertEquals(1, o.getInt("app_4949752878"));
        assertEquals(12, o.getInt("wall"));

        o = (JsonObject) metricResult.get(d20030702_0000pst);
        assertEquals(2, o.length());
        assertEquals(1, o.getInt("photos"));
        assertEquals(11, o.getInt("wall"));
    }

    @Test
    public void periodLengths() {
        assertEquals(86400, Period.DAY.getPeriodLength());
        assertEquals(604800, Period.WEEK.getPeriodLength());
        assertEquals(2419200, Period.DAYS_28.getPeriodLength());
        assertEquals(2592000, Period.MONTH.getPeriodLength());
        assertEquals(0, Period.LIFETIME.getPeriodLength());
    }

    /**
     * As there is no easy constructor for making a SimpleDateFormat specifying both a Locale and Timezone a utility is
     * provided here
     * 
     * @param pattern
     * @param locale
     * @param timezone
     * @return
     */
    public static SimpleDateFormat newSimpleDateFormat(String pattern, Locale locale, TimeZone timezone) {
        SimpleDateFormat sdf = new SimpleDateFormat(pattern, locale);
        sdf.setTimeZone(timezone);
        return sdf;
    }

    private static FacebookClient createFixedResponseFacebookClient(String pathToJson) throws IOException {
        WebRequestor wr = new ClasspathWebRequestor(JSON_RESOURCES_PREFIX + pathToJson);
        String jsonBody = wr.executeGet(null).getBody();
        Assert.assertTrue("path to json not found:" + JSON_RESOURCES_PREFIX + pathToJson,
                (jsonBody != null) && (jsonBody.length() > 0));
        return new DefaultFacebookClient(null, wr, new DefaultJsonMapper(), Version.LATEST);
    }

    private static Set<String> toStringSet(String... metrics) {
        return new LinkedHashSet<String>(Arrays.asList(metrics));
    }
}