com.liferay.frontend.js.loader.modules.extender.internal.JSLoaderModulesServletTest.java Source code

Java tutorial

Introduction

Here is the source code for com.liferay.frontend.js.loader.modules.extender.internal.JSLoaderModulesServletTest.java

Source

/**
 * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
 *
 * This library 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 library 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.
 */

package com.liferay.frontend.js.loader.modules.extender.internal;

import aQute.bnd.osgi.Constants;

import aQute.lib.converter.Converter;

import com.liferay.frontend.js.loader.modules.extender.internal.npm.NPMRegistryImpl;
import com.liferay.frontend.js.loader.modules.extender.npm.NPMRegistry;
import com.liferay.petra.string.StringPool;
import com.liferay.portal.kernel.test.ReflectionTestUtil;
import com.liferay.portal.kernel.util.Portal;
import com.liferay.portal.kernel.util.PortalUtil;
import com.liferay.portal.util.PortalImpl;

import java.net.URL;

import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;

import javax.servlet.ServletContext;

import org.json.JSONException;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import org.osgi.framework.Bundle;
import org.osgi.framework.ServiceReference;
import org.osgi.framework.Version;
import org.osgi.framework.wiring.BundleCapability;
import org.osgi.framework.wiring.BundleWire;
import org.osgi.framework.wiring.BundleWiring;
import org.osgi.service.component.ComponentContext;

import org.powermock.api.mockito.PowerMockito;
import org.powermock.modules.junit4.PowerMockRunner;

import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.mock.web.MockHttpServletResponse;
import org.springframework.mock.web.MockServletConfig;
import org.springframework.mock.web.MockServletContext;

/**
 * @author Raymond Aug
 */
@RunWith(PowerMockRunner.class)
public class JSLoaderModulesServletTest extends PowerMockito {

    @Before
    public void setUp() {
        _portal = PortalUtil.getPortal();

        _portalUtil.setPortal(new PortalImpl() {

            @Override
            public String getPathContext() {
                return StringPool.BLANK;
            }

        });
    }

    @After
    public void tearDown() {
        _portalUtil.setPortal(_portal);
    }

    @Test
    public void testBasicOutput() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet();

        MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
        MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

        jsLoaderModulesServlet.service(mockHttpServletRequest, mockHttpServletResponse);

        Assert.assertNotNull(mockHttpServletResponse.getContentAsString());
        Assert.assertEquals(Details.CONTENT_TYPE, mockHttpServletResponse.getContentType());
    }

    @Test
    public void testMultipleModulesOutput() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet(
                Collections.<String, Object>singletonMap("applyVersioning", Boolean.TRUE));

        JSLoaderModulesTracker jsLoaderModulesTracker = jsLoaderModulesServlet.getJSLoaderModulesTracker();

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/config1.js"));

        jsLoaderModulesTracker.addingService(serviceReference);

        serviceReference = buildServiceReference("foo", new Version("13.2.23"), true, 0,
                getResource("dependencies/config2.js"));

        jsLoaderModulesTracker.addingService(serviceReference);

        MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
        MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

        jsLoaderModulesServlet.service(mockHttpServletRequest, mockHttpServletResponse);

        String content = mockHttpServletResponse.getContentAsString();

        content = content.replace('"', '\'');

        assertContains("'test': '/test-1.0.0'", content);
        assertContains("'test@1.0.0': '/test-1.0.0'", content);
        assertContains("'test/some.es':{'dependencies':['exports','test@1.0.0/other.es']}", content);
        assertContains("'test@1.0.0/some.es':{'dependencies':['exports'," + "'test@1.0.0/other.es']}", content);
        assertContains("'foo': '/foo-13.2.23'", content);
        assertContains("'foo@13.2.23': '/foo-13.2.23'", content);
        assertContains(
                "'foo/foo.es':{'dependencies':['exports','foo@13.2.23/fum.es'," + "'jquery@2.15.3/jquery.js']}",
                content);
        assertContains("'foo@13.2.23/foo.es':{'dependencies':['exports',"
                + "'foo@13.2.23/fum.es','jquery@2.15.3/jquery.js']}", content);
    }

    @Test
    public void testMultipleVersionsModuleOutput() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet(
                Collections.<String, Object>singletonMap("applyVersioning", Boolean.TRUE));

        JSLoaderModulesTracker jsLoaderModulesTracker = jsLoaderModulesServlet.getJSLoaderModulesTracker();

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/config1.js"));

        jsLoaderModulesTracker.addingService(serviceReference);

        serviceReference = buildServiceReference("test", new Version("1.2.0"), true, 0,
                getResource("dependencies/config1.js"));

        jsLoaderModulesTracker.addingService(serviceReference);

        MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
        MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

        jsLoaderModulesServlet.service(mockHttpServletRequest, mockHttpServletResponse);

        String content = mockHttpServletResponse.getContentAsString();

        content = content.replace('"', '\'');

        assertContains("'test': '/test-1.2.0'", content);
        assertContains("'test@1.2.0': '/test-1.2.0'", content);
        assertContains("'test@1.0.0': '/test-1.0.0'", content);
        assertContains("'test/some.es':{'dependencies':['exports','test@1.2.0/other.es']}", content);
        assertNotContains("'test/some.es':{'dependencies':['exports','test@1.0.0/other.es']}", content);
        assertContains("'test@1.2.0/some.es':{'dependencies':['exports'," + "'test@1.2.0/other.es']}", content);
        assertContains("'test@1.0.0/some.es':{'dependencies':['exports'," + "'test@1.0.0/other.es']}", content);
    }

    @Test
    public void testSingleModuleOutput() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet(
                Collections.<String, Object>singletonMap("applyVersioning", Boolean.TRUE));

        JSLoaderModulesTracker jsLoaderModulesTracker = jsLoaderModulesServlet.getJSLoaderModulesTracker();

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/config1.js"));

        jsLoaderModulesTracker.addingService(serviceReference);

        MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
        MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

        jsLoaderModulesServlet.service(mockHttpServletRequest, mockHttpServletResponse);

        String content = mockHttpServletResponse.getContentAsString();

        content = content.replace('"', '\'');

        assertContains("'test': '/test-1.0.0'", content);
        assertContains("'test@1.0.0': '/test-1.0.0'", content);
        assertContains("'test/some.es':{'dependencies':['exports','test@1.0.0/other.es']}", content);
        assertContains("'test/other.es':{'dependencies':['exports']}", content);
        assertContains("'test@1.0.0/some.es':{'dependencies':['exports'," + "'test@1.0.0/other.es']}", content);
        assertContains("'test@1.0.0/other.es':{'dependencies':['exports']}", content);
    }

    @Test(expected = JSONException.class)
    public void testSingleModuleOutputEmptyConfiguration() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet();

        JSLoaderModulesTracker jsLoaderModulesTracker = jsLoaderModulesServlet.getJSLoaderModulesTracker();

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/empty.js"));

        jsLoaderModulesTracker.addingService(serviceReference);
    }

    @Test
    public void testSingleModuleOutputIdempotent() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet(
                Collections.<String, Object>singletonMap("applyVersioning", Boolean.TRUE));

        JSLoaderModulesTracker jsLoaderModulesTracker = jsLoaderModulesServlet.getJSLoaderModulesTracker();

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/config1.js"));

        jsLoaderModulesTracker.addingService(serviceReference);
        jsLoaderModulesTracker.addingService(serviceReference);

        MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
        MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

        jsLoaderModulesServlet.service(mockHttpServletRequest, mockHttpServletResponse);

        String content = mockHttpServletResponse.getContentAsString();

        content = content.replace('"', '\'');

        assertOccurrences("'test': '/test-1.0.0'", content, 1);
        assertOccurrences("'test@1.0.0': '/test-1.0.0'", content, 1);
        assertOccurrences("'test/some.es':{'dependencies':['exports','test@1.0.0/other.es']}", content, 1);
        assertOccurrences("'test/other.es':{'dependencies':['exports']}", content, 1);
        assertOccurrences("'test@1.0.0/some.es':{'dependencies':['exports'," + "'test@1.0.0/other.es']}", content,
                1);
        assertOccurrences("'test@1.0.0/other.es':{'dependencies':['exports']}", content, 1);
    }

    @Test(expected = JSONException.class)
    public void testSingleModuleOutputMalformedConfiguration() throws Exception {

        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet();

        JSLoaderModulesTracker jsLoaderModulesTracker = new JSLoaderModulesTracker();

        jsLoaderModulesTracker.setDetails(Converter.cnv(Details.class, new HashMap<>()));

        jsLoaderModulesServlet.setJSLoaderModulesTracker(jsLoaderModulesTracker);

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/malformed.js"));

        jsLoaderModulesTracker.addingService(serviceReference);
    }

    @Test
    public void testUnversionedModuleOutput() throws Exception {
        JSLoaderModulesServlet jsLoaderModulesServlet = buildJSLoaderModulesServlet(
                Collections.<String, Object>singletonMap("apply-versioning", Boolean.FALSE));

        JSLoaderModulesTracker jsLoaderModulesTracker = jsLoaderModulesServlet.getJSLoaderModulesTracker();

        ServiceReference<ServletContext> serviceReference = buildServiceReference("test", new Version("1.0.0"),
                true, 0, getResource("dependencies/config1.js"));

        jsLoaderModulesServlet.setJSLoaderModulesTracker(jsLoaderModulesTracker);

        jsLoaderModulesTracker.addingService(serviceReference);

        MockHttpServletRequest mockHttpServletRequest = new MockHttpServletRequest();
        MockHttpServletResponse mockHttpServletResponse = new MockHttpServletResponse();

        jsLoaderModulesServlet.service(mockHttpServletRequest, mockHttpServletResponse);

        String content = mockHttpServletResponse.getContentAsString();

        content = content.replace('"', '\'');

        assertContains("'test': '/test-1.0.0'", content);
        assertContains("'test@1.0.0': '/test-1.0.0'", content);
        assertContains("'test/some.es':{'dependencies':['exports','test/other.es']}", content);
        assertNotContains("'test/some.es':{'dependencies':['exports','test@1.0.0/other.es']}", content);
        assertContains("'test/other.es':{'dependencies':['exports']}", content);
        assertNotContains("'test@1.0.0/some.es':{'dependencies':['exports'," + "'test@1.0.0/other.es']}", content);
        assertNotContains("'test@1.0.0/other.es':{'dependencies':['exports']}", content);
    }

    protected void assertContains(String expected, String content) {
        Assert.assertTrue("Does not contain <" + expected + ">", content.contains(expected));
    }

    protected void assertNotContains(String expected, String content) {
        Assert.assertFalse("Contains <" + expected + ">", content.contains(expected));
    }

    protected void assertOccurrences(String expected, String content, int occurences) {

        int count = 0;

        for (int i = content.indexOf(expected); i != -1; i = content.indexOf(expected, i + 1)) {

            count++;
        }

        Assert.assertEquals(occurences, count);
    }

    protected JSLoaderModulesServlet buildJSLoaderModulesServlet() throws Exception {

        return buildJSLoaderModulesServlet(Collections.<String, Object>emptyMap());
    }

    protected JSLoaderModulesServlet buildJSLoaderModulesServlet(Map<String, Object> properties) throws Exception {

        JSLoaderModulesServlet jsLoaderModulesServlet = new JSLoaderModulesServlet();

        ReflectionTestUtil.setFieldValue(jsLoaderModulesServlet, "_portal", PortalUtil.getPortal());

        jsLoaderModulesServlet.activate(mock(ComponentContext.class), properties);

        MockServletContext mockServletContext = new MockServletContext();

        mockServletContext.setContextPath("/loader");

        jsLoaderModulesServlet.init(new MockServletConfig(mockServletContext));

        jsLoaderModulesServlet.setDetails(Converter.cnv(Details.class, properties));

        JSLoaderModulesTracker jsLoaderModulesTracker = new JSLoaderModulesTracker();

        jsLoaderModulesTracker.setDetails(Converter.cnv(Details.class, properties));

        jsLoaderModulesServlet.setJSLoaderModulesTracker(jsLoaderModulesTracker);

        NPMRegistry npmRegistry = new NPMRegistryImpl();

        jsLoaderModulesServlet.setNPMRegistry(npmRegistry);

        return jsLoaderModulesServlet;
    }

    protected ServiceReference<ServletContext> buildServiceReference(String bsn, Version version,
            boolean capability, int ranking, URL url) {

        Bundle bundle = mock(Bundle.class);

        mockBundle(bundle, bsn, version, url, capability);

        TestServiceReference mockServiceReference = new TestServiceReference(bundle,
                new String[] { ServletContext.class.getName() }, _counter.incrementAndGet(), ranking);

        mockServiceReference.setProperties(Collections.<String, Object>singletonMap("osgi.web.contextpath",
                "/" + bsn + "-" + version.toString()));

        return mockServiceReference;
    }

    protected URL getResource(String name) {
        Class<?> clazz = getClass();

        return clazz.getResource(name);
    }

    protected void mockBundle(Bundle bundle, String bsn, Version version, URL url, boolean capability) {

        doReturn(url).when(bundle).getEntry(Details.CONFIG_JSON);

        doReturn(new Hashtable<String, String>()).when(bundle).getHeaders();

        doReturn(bsn).when(bundle).getSymbolicName();

        doReturn(version).when(bundle).getVersion();

        doReturn(mockBundleWiring(bsn, capability)).when(bundle).adapt(BundleWiring.class);
    }

    protected BundleCapability mockBundleCapability(String bsn) {
        BundleCapability bundleCapability = mock(BundleCapability.class);

        doReturn(Collections.<String, Object>singletonMap(Details.OSGI_WEBRESOURCE, bsn)).when(bundleCapability)
                .getAttributes();

        return bundleCapability;
    }

    protected BundleWire mockBundleWire() {
        BundleWire bundleWire = mock(BundleWire.class);

        doReturn(mockJQueryBundleCapability()).when(bundleWire).getCapability();

        return bundleWire;
    }

    protected BundleWiring mockBundleWiring(String bsn, boolean capability) {
        BundleWiring bundleWiring = mock(BundleWiring.class);

        List<BundleCapability> bundleCapabilities = Collections.emptyList();

        if (capability) {
            bundleCapabilities = Arrays.asList(mockBundleCapability(bsn));
        }

        doReturn(bundleCapabilities).when(bundleWiring).getCapabilities(Details.OSGI_WEBRESOURCE);

        List<BundleWire> bundleWires = Collections.emptyList();

        if (capability) {
            bundleWires = Arrays.asList(mockBundleWire());
        }

        doReturn(bundleWires).when(bundleWiring).getRequiredWires(Details.OSGI_WEBRESOURCE);

        return bundleWiring;
    }

    protected BundleCapability mockJQueryBundleCapability() {
        BundleCapability bundleCapability = mock(BundleCapability.class);

        Map<String, Object> properties = new HashMap<>();

        properties.put(Details.OSGI_WEBRESOURCE, "jquery");
        properties.put(Constants.VERSION_ATTRIBUTE, new Version("2.15.3"));

        doReturn(properties).when(bundleCapability).getAttributes();

        return bundleCapability;
    }

    private final AtomicInteger _counter = new AtomicInteger(0);
    private Portal _portal;
    private final PortalUtil _portalUtil = new PortalUtil();

    private static class TestServiceReference implements ServiceReference<ServletContext> {

        public TestServiceReference(Bundle bundle, String[] objectClasses, int id, int ranking) {

            _bundle = bundle;
            _objectClasses = objectClasses;
            _id = id;
            _ranking = ranking;

            _properties.put("objectClass", objectClasses);
            _properties.put("service.id", _id);
            _properties.put("service.ranking", _ranking);
        }

        @Override
        public int compareTo(Object object) {
            TestServiceReference testServiceReference = (TestServiceReference) object;

            if (_ranking != testServiceReference._ranking) {
                if (_ranking < testServiceReference._ranking) {
                    return -1;
                }

                return 1;
            }

            if (_id == testServiceReference._id) {
                return 0;
            }

            if (_id < testServiceReference._id) {
                return 1;
            }

            return -1;
        }

        @Override
        public Bundle getBundle() {
            return _bundle;
        }

        @Override
        public Object getProperty(String key) {
            return _properties.get(key);
        }

        @Override
        public String[] getPropertyKeys() {
            Set<String> keys = _properties.keySet();

            return keys.toArray(new String[keys.size()]);
        }

        @Override
        public Bundle[] getUsingBundles() {
            return null;
        }

        @Override
        public boolean isAssignableTo(Bundle bundle, String className) {
            return false;
        }

        public void setProperties(Map<String, Object> properties) {
            _properties.putAll(properties);

            _properties.put("objectClass", _objectClasses);
            _properties.put("service.id", _id);
            _properties.put("service.ranking", _ranking);
        }

        private final Bundle _bundle;
        private int _id;
        private final String[] _objectClasses;
        private final Map<String, Object> _properties = new HashMap<>();
        private final int _ranking;

    }

}