com.scvngr.levelup.core.net.RequestUtilsTest.java Source code

Java tutorial

Introduction

Here is the source code for com.scvngr.levelup.core.net.RequestUtilsTest.java

Source

/*
 * Copyright (C) 2014 SCVNGR, Inc. d/b/a LevelUp
 *
 * 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.
 */
package com.scvngr.levelup.core.net;

import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.os.Build;
import android.support.annotation.NonNull;
import android.test.mock.MockContext;
import android.test.mock.MockPackageManager;
import android.test.suitebuilder.annotation.SmallTest;

import com.scvngr.levelup.core.R;
import com.scvngr.levelup.core.test.SupportAndroidTestCase;
import com.scvngr.levelup.core.util.CoreLibConstants;
import com.scvngr.levelup.core.util.NullUtils;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.HashMap;
import java.util.Locale;
import java.util.Map;

/**
 * Tests {@link com.scvngr.levelup.core.net.RequestUtils}.
 */
public final class RequestUtilsTest extends SupportAndroidTestCase {
    @NonNull
    private static final String TEST_PACKAGE_NAME = "com.example.test";
    @NonNull
    private static final String TEST_VERSION_NAME = "2.4.6";

    /**
     * Eventually non-null; initialized in {@link #setUp()}.
     */
    @SuppressWarnings("null")
    @NonNull
    private Context mMockContext;

    @Override
    protected void setUp() throws Exception {
        super.setUp();
        mMockContext = new RequestUtilsMockContext(getContext(), new RequestUtilsMockPackageManager());
    }

    /**
     * Tests {@link com.scvngr.levelup.core.net.RequestUtils#getDefaultRequestHeaders(android.content.Context)} when a
     * {@link android.content.pm.PackageManager.NameNotFoundException} is not thrown.
     */
    @SmallTest
    public void testGetDefaultRequestHeaders() {
        final Map<String, String> headers = RequestUtils.getDefaultRequestHeaders(mMockContext);
        assertTrue("Device model header is present", headers.containsKey("X-Device-Model"));
        assertEquals("Accept header is set for JSON", //
                RequestUtils.HEADER_CONTENT_TYPE_JSON, headers.get(RequestUtils.HEADER_ACCEPT));
        assertEquals("User-Agent header matches RequestUtils.getUserAgent()",
                RequestUtils.getUserAgent(mMockContext), headers.get("User-Agent"));
    }

    @SmallTest
    public void testGetUserAgent() {
        assertTrue(RequestUtils.getUserAgent(mMockContext)
                .contains(TEST_PACKAGE_NAME + "/" + TEST_VERSION_NAME + getDeviceSpecificUserAgentString()));
        assertTrue(RequestUtils.getUserAgent(mMockContext).contains("LevelUpSdk/" + CoreLibConstants.SDK_VERSION));
        /*
         * Ensure we're not using properties that come back null in our User-Agent (like
         * applicationInfo.name). This is a mocked context so it's not an ideal test, but there's
         * not a great way to unit-test real-world values.
         */
        assertFalse("User-Agent should not have 'null' for any of its properties",
                RequestUtils.getUserAgent(mMockContext).contains("null"));
    }

    /**
     * Test {@link com.scvngr.levelup.core.net.RequestUtils#addApiKeyToRequestQueryParams}.
     */
    @SmallTest
    public void testAddApiKeyToRequestQueryParams() {
        final Map<String, String> expected = new HashMap<String, String>();
        final Map<String, String> params = new HashMap<String, String>();
        final Context context = NullUtils.nonNullContract(getContext());

        expected.put(RequestUtils.PARAM_API_KEY, context.getString(R.string.levelup_api_key));

        RequestUtils.addApiKeyToRequestQueryParams(context, params);
        assertEquals(expected.toString(), params.toString());
    }

    /**
     * Test {@link com.scvngr.levelup.core.net.RequestUtils#addApiKeyToRequestBody}.
     *
     * @throws org.json.JSONException from {@link org.json.JSONObject#put}
     */
    @SmallTest
    public void testAddApiKeyToRequestBody() throws JSONException {
        final JSONObject object = new JSONObject();
        final JSONObject expected = new JSONObject();
        final Context context = NullUtils.nonNullContract(getContext());

        expected.put(RequestUtils.PARAM_API_KEY, context.getString(R.string.levelup_api_key));

        RequestUtils.addApiKeyToRequestBody(context, object);
        assertEquals(expected.toString(), object.toString());
    }

    /**
     * Test {@link com.scvngr.levelup.core.net.RequestUtils#addDeviceIdToRequestBody}.
     *
     * @throws org.json.JSONException from {@link org.json.JSONObject#getString}
     */
    @SmallTest
    public void testAddDeviceIdToRequestBody() throws JSONException {
        final JSONObject object = new JSONObject();
        final Context context = NullUtils.nonNullContract(getContext());
        RequestUtils.addDeviceIdToRequestBody(context, object);

        assertTrue(object.has(RequestUtils.PARAM_DEVICE_IDENTIFIER));
        assertEquals(RequestUtils.getDeviceId(context), object.getString(RequestUtils.PARAM_DEVICE_IDENTIFIER));
    }

    /**
     * Helper method to get the device specific portion of the user agent screen.
     *
     * @return device specific part of the user agent string
     */
    private static String getDeviceSpecificUserAgentString() {
        return String.format(Locale.US, " (Linux; U; Android %s; %s/%s; %s)", Build.VERSION.RELEASE, Build.BRAND,
                Build.PRODUCT, Locale.getDefault().toString());
    }

    /**
     * Mock Context to return a fake PackageManager.
     */
    public static final class RequestUtilsMockContext extends MockContext {

        @NonNull
        private final RequestUtilsMockPackageManager mMgr;
        @NonNull
        private final Context mContext;

        /**
         * Constructor.
         *
         * @param context the context.
         * @param mgr the fake package manager to return
         */
        public RequestUtilsMockContext(@NonNull final Context context,
                @NonNull final RequestUtilsMockPackageManager mgr) {
            mContext = context;
            mMgr = mgr;
        }

        @Override
        public PackageManager getPackageManager() {
            return mMgr;
        }

        @Override
        public String getPackageName() {
            return TEST_PACKAGE_NAME;
        }

        @Override
        public SharedPreferences getSharedPreferences(final String name, final int mode) {
            throw new UnsupportedOperationException();
        }

        @Override
        public Context getApplicationContext() {
            return mContext.getApplicationContext();
        }

        @Override
        public Resources getResources() {
            return mContext.getResources();
        }
    }

    /**
     * Fakes the PackageManager API for getting package data.
     */
    public static final class RequestUtilsMockPackageManager extends MockPackageManager {
        @Override
        public PackageInfo getPackageInfo(final String packageName, final int flags) throws NameNotFoundException {
            final PackageInfo info = new PackageInfo();
            info.versionName = TEST_VERSION_NAME;

            return info;
        }
    }
}