001// Generated by delombok at Sun Jul 30 17:21:56 UTC 2023
002package de.cuioss.test.jsf.util;
003
004import static de.cuioss.test.jsf.util.ConfigurationHelper.configureApplication;
005import static de.cuioss.test.jsf.util.ConfigurationHelper.configureComponents;
006import static de.cuioss.test.jsf.util.ConfigurationHelper.configureManagedBeans;
007import static de.cuioss.test.jsf.util.ConfigurationHelper.configureRequestConfig;
008import static de.cuioss.test.jsf.util.ConfigurationHelper.extractJsfTestConfiguration;
009import static de.cuioss.tools.string.MoreStrings.emptyToNull;
010import static org.junit.jupiter.api.Assertions.assertEquals;
011import static org.junit.jupiter.api.Assertions.assertNotNull;
012import static org.junit.jupiter.api.Assertions.assertTrue;
013import javax.faces.application.Application;
014import javax.faces.application.NavigationHandler;
015import javax.faces.context.ExternalContext;
016import javax.faces.context.FacesContext;
017import javax.faces.convert.EnumConverter;
018import javax.faces.convert.IntegerConverter;
019import javax.servlet.http.HttpServletResponse;
020import org.apache.myfaces.test.mock.MockExternalContext22;
021import org.apache.myfaces.test.mock.MockFacesContext;
022import org.apache.myfaces.test.mock.MockFacesContext22;
023import org.apache.myfaces.test.mock.MockHttpServletResponse;
024import org.junit.jupiter.api.BeforeEach;
025import de.cuioss.test.jsf.config.ApplicationConfigurator;
026import de.cuioss.test.jsf.config.BeanConfigurator;
027import de.cuioss.test.jsf.config.ComponentConfigurator;
028import de.cuioss.test.jsf.config.JsfTestConfiguration;
029import de.cuioss.test.jsf.config.RequestConfigurator;
030import de.cuioss.test.jsf.config.decorator.ApplicationConfigDecorator;
031import de.cuioss.test.jsf.config.decorator.BeanConfigDecorator;
032import de.cuioss.test.jsf.config.decorator.ComponentConfigDecorator;
033import de.cuioss.test.jsf.config.decorator.RequestConfigDecorator;
034import de.cuioss.test.valueobjects.util.IdentityResourceBundle;
035// owolff Base class for actual tests
036/**
037 * Base class for configuring the {@link FacesContext} provided by MyFaces-Test.
038 * The configuration is implemented using some kind of decorator pattern
039 * (roughly). The actual configuration relies on two sources:
040 * <ul>
041 * <li>It scans for the annotations of type {@link JsfTestConfiguration}
042 * instantiates the corresponding classes and configures the environment
043 * accordingly</li>
044 * <li>It checks whether the actual test-class implements one of
045 * {@link ApplicationConfigurator}, {@link BeanConfigurator},
046 * {@link RequestConfigurator} or {@link ComponentConfigurator} and calls the
047 * corresponding methods accordingly, <em>after</em> the configurator derived by
048 * the annotations</li>
049 * </ul>
050 * <p>
051 * The corresponding objects {@link ComponentConfigurator},
052 * {@link BeanConfigDecorator}, {@link RequestConfigDecorator} and
053 * {@link ApplicationConfigurator} can be accessed by the getter-methods, in
054 * case you need to configure elements for a certain test only.
055 * </p>
056 * <p>
057 * In addition there is a new way of dealing with localized messages for
058 * unit-tests. In essence there is the {@link IdentityResourceBundle}
059 * configured: This is helpful for tests where you want to ensure that a certain
060 * message key is used to create a message but do not want to test the actual
061 * ResourceBundle mechanism itself. It will always return the given key itself.
062 * As default this mechanism is active, you can change this by overwriting
063 * #isUseIdentityResouceBundle(). If it is active it is used as well for
064 * resolving the MessageBundle
065 * </p>
066 *
067 * @author Oliver Wolff
068 */
069@SuppressWarnings("squid:S2187")
070public class ConfigurableFacesTest {
071    /**
072     * "Location"
073     */
074    public static final String LOCATION_HEADER = "Location";
075    private ComponentConfigDecorator componentConfigDecorator;
076    private BeanConfigDecorator beanConfigDecorator;
077    private ApplicationConfigDecorator applicationConfigDecorator;
078    private RequestConfigDecorator requestConfigDecorator;
079    private ConfigurableApplication configurableApplication;
080    private final JsfRuntimeSetup runtimeSetup = new JsfRuntimeSetup();
081
082    /**
083     * See class documentation of {@link ConfigurableFacesTest} for details.
084     */
085    @BeforeEach
086    protected void setupAdditionalConfiguration() {
087        runtimeSetup.setUp();
088        configurableApplication = ConfigurableApplication.createWrapAndRegister((MockFacesContext) getFacesContext());
089        configurableApplication.setUseIdentityResouceBundle(isUseIdentityResourceBundle());
090        componentConfigDecorator = new ComponentConfigDecorator(getApplication(), getFacesContext());
091        beanConfigDecorator = new BeanConfigDecorator(getFacesContext());
092        applicationConfigDecorator = new ApplicationConfigDecorator(getApplication(), getFacesContext());
093        requestConfigDecorator = new RequestConfigDecorator((MockFacesContext22) getFacesContext(), (MockExternalContext22) getExternalContext());
094        final var annotations = extractJsfTestConfiguration(getClass());
095        configureApplication(this, applicationConfigDecorator, annotations);
096        configureComponents(this, componentConfigDecorator, annotations);
097        configureManagedBeans(this, beanConfigDecorator, annotations);
098        configureRequestConfig(this, requestConfigDecorator, annotations);
099        // Fix for invalid set converter Id at
100        // org.apache.myfaces.test.mock.MockApplication@91
101        componentConfigDecorator.registerConverter(IntegerConverter.class, IntegerConverter.CONVERTER_ID);
102        // Enum converter is currently omitted.
103        componentConfigDecorator.registerConverter(EnumConverter.class, EnumConverter.CONVERTER_ID);
104        componentConfigDecorator.registerConverter(EnumConverter.class, Enum.class);
105        // Enable CuiMockConfigurableNavigationHandler to be used
106        getApplicationConfigDecorator().getMockNavigationHandler();
107    }
108
109    protected FacesContext getFacesContext() {
110        return runtimeSetup.getFacesContext();
111    }
112
113    protected Application getApplication() {
114        return configurableApplication;
115    }
116
117    protected ExternalContext getExternalContext() {
118        return runtimeSetup.getExternalContext();
119    }
120
121    protected MockHttpServletResponse getResponse() {
122        return runtimeSetup.getResponse();
123    }
124
125    protected boolean isUseIdentityResourceBundle() {
126        return true;
127    }
128
129    /**
130     * Asserts whether a navigation was handled by calling
131     * {@link NavigationHandler#handleNavigation(javax.faces.context.FacesContext, String, String)}
132     *
133     * @param outcome must not be null
134     */
135    public void assertNavigatedWithOutcome(final String outcome) {
136        assertNotNull(emptyToNull(outcome), "Outcome must not be null");
137        assertTrue(getFacesContext().getExternalContext().isResponseCommitted(), "Response is not committed");
138        var handler = getApplicationConfigDecorator().getMockNavigationHandler();
139        assertTrue(handler.isHandleNavigationCalled(), "handleNavigation is not called");
140        assertEquals(outcome, handler.getCalledOutcome());
141    }
142
143    /**
144     * Asserts whether a navigation was initialized by calling
145     * {@link ExternalContext#redirect(String)}
146     *
147     * @param redirectUrl must not be null
148     */
149    public void assertRedirect(final String redirectUrl) {
150        assertNotNull("redirectUrl must not be null", emptyToNull(redirectUrl));
151        assertTrue(getFacesContext().getExternalContext().isResponseCommitted(), "Response is not committed");
152        var tempResponse = (HttpServletResponse) getExternalContext().getResponse();
153        assertTrue(tempResponse.containsHeader(LOCATION_HEADER), "Response must provide a header with the name " + LOCATION_HEADER);
154        assertEquals(redirectUrl, tempResponse.getHeader(LOCATION_HEADER));
155    }
156
157    @java.lang.SuppressWarnings("all")
158    @lombok.Generated
159    protected ComponentConfigDecorator getComponentConfigDecorator() {
160        return this.componentConfigDecorator;
161    }
162
163    @java.lang.SuppressWarnings("all")
164    @lombok.Generated
165    protected BeanConfigDecorator getBeanConfigDecorator() {
166        return this.beanConfigDecorator;
167    }
168
169    @java.lang.SuppressWarnings("all")
170    @lombok.Generated
171    protected ApplicationConfigDecorator getApplicationConfigDecorator() {
172        return this.applicationConfigDecorator;
173    }
174
175    @java.lang.SuppressWarnings("all")
176    @lombok.Generated
177    public RequestConfigDecorator getRequestConfigDecorator() {
178        return this.requestConfigDecorator;
179    }
180}