/** * Copyright (c) 2013-2016, The SeedStack authors <http://seedstack.org> * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ package org.seedstack.seed.rest.jersey2.internal; import com.google.common.collect.Sets; import com.google.inject.Injector; import com.sun.org.apache.xpath.internal.operations.String; import io.nuun.kernel.api.annotations.Ignore; import mockit.Deencapsulation; import mockit.Expectations; import mockit.Mock; import mockit.MockUp; import mockit.Mocked; import mockit.NonStrictExpectations; import mockit.Tested; import mockit.Verifications; import mockit.integration.junit4.JMockit; import org.glassfish.hk2.api.DynamicConfiguration; import org.glassfish.hk2.api.Factory; import org.glassfish.hk2.api.ServiceLocator; import org.glassfish.hk2.utilities.binding.BindingBuilder; import org.glassfish.hk2.utilities.binding.ServiceBindingBuilder; import org.glassfish.jersey.internal.inject.Injections; import org.junit.Test; import org.junit.runner.RunWith; import org.jvnet.hk2.guice.bridge.api.GuiceBridge; import org.jvnet.hk2.guice.bridge.api.GuiceIntoHK2Bridge; import org.seedstack.seed.SeedException; import javax.servlet.ServletContext; import javax.ws.rs.Path; import javax.ws.rs.ext.Provider; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.Assert.fail; @RunWith(JMockit.class) public class GuiceComponentProviderTest { @Tested private GuiceComponentProvider underTest; @Mocked private ServiceLocator serviceLocator; @Mocked private ServletContext servletContext; @Mocked private Injector injector; @Mocked private GuiceIntoHK2Bridge guiceIntoHK2Bridge; @Mocked private ServiceBindingBuilder bindingBuilder; @Mocked private DynamicConfiguration dynamicConfiguration; @Test public void testInitializeSaveTheServiceLocator() throws Exception { givenServiceLocator(); underTest.initialize(serviceLocator); ServiceLocator initializedServiceLocator = Deencapsulation.getField(underTest, ServiceLocator.class); assertThat(initializedServiceLocator).isEqualTo(serviceLocator); } @Test public void testGetTheInjector() throws Exception { givenServiceLocator(); underTest.initialize(serviceLocator); Injector initializedInjector = Deencapsulation.getField(underTest, Injector.class); assertThat(initializedInjector).isEqualTo(injector); } private void givenServiceLocator() { new NonStrictExpectations() {{ serviceLocator.getService(ServletContext.class); result = servletContext; servletContext.getAttribute(Injector.class.getName()); result = injector; serviceLocator.getService(GuiceIntoHK2Bridge.class); result = guiceIntoHK2Bridge; }}; } @Test public void testMissingServletContext() throws Exception { givenMissingServletContext(); try { underTest.initialize(serviceLocator); fail(); } catch (SeedException e) { assertThat(e.getErrorCode()).isEqualTo(Jersey2ErrorCode.MISSING_SERVLET_CONTEXT); } } private void givenMissingServletContext() { new NonStrictExpectations() {{ serviceLocator.getService(ServletContext.class); result = null; }}; } @Test public void testMissingInjector() throws Exception { givenServletContextAndMissingInjector(); try { underTest.initialize(serviceLocator); fail(); } catch (SeedException e) { assertThat(e.getErrorCode()).isEqualTo(Jersey2ErrorCode.MISSING_INJECTOR); } } private void givenServletContextAndMissingInjector() { new NonStrictExpectations() {{ serviceLocator.getService(ServletContext.class); result = servletContext; servletContext.getAttribute(Injector.class.getName()); result = null; }}; } @Test public void testPrepareHK2Bridge(@Mocked final GuiceBridge guiceBridge) throws Exception { givenServiceLocator(); new Expectations() {{ serviceLocator.getService(GuiceIntoHK2Bridge.class); result = guiceIntoHK2Bridge; }}; underTest.initialize(serviceLocator); new Verifications() {{ guiceBridge.initializeGuiceBridge(serviceLocator); serviceLocator.getService(GuiceIntoHK2Bridge.class); guiceIntoHK2Bridge.bridgeGuiceInjector(injector); }}; } @Test public void testDoNotBindNonResourceClasses() throws Exception { boolean isBound = underTest.bind(String.class, null); assertThat(isBound).isFalse(); } @Test public void testBindResourceClasses() throws Exception { givenServiceLocator(); givenInjections(); underTest.initialize(serviceLocator); @Ignore @Path("/") class MyResource { } boolean isBound = underTest.bind(MyResource.class, null); assertThat(isBound).isTrue(); } @Ignore @Provider interface MyProvider { } class MyProviderImpl implements MyProvider { } @Test public void testBind() throws Exception { givenServiceLocator(); givenInjections(); underTest.initialize(serviceLocator); underTest.bind(MyProvider.class, Sets.newHashSet(MyProviderImpl.class)); new Verifications() {{ bindingBuilder.to(MyProvider.class); bindingBuilder.to(MyProviderImpl.class); }}; } private void givenInjections() { new MockUp<Injections>() { @Mock DynamicConfiguration getConfiguration(final ServiceLocator locator) { return dynamicConfiguration; } @Mock <T> ServiceBindingBuilder<T> newFactoryBinder(final Factory<T> factory) { return bindingBuilder; } @Mock void addBinding(final BindingBuilder<?> builder, final DynamicConfiguration configuration) {} }; } }