001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.wicket.util.tester;
018
019import static org.junit.jupiter.api.Assertions.assertEquals;
020
021import java.io.IOException;
022import java.util.Locale;
023
024import org.apache.wicket.Component;
025import org.apache.wicket.Page;
026import org.apache.wicket.ThreadContext;
027import org.apache.wicket.behavior.AbstractAjaxBehavior;
028import org.apache.wicket.markup.IMarkupFragment;
029import org.apache.wicket.mock.MockApplication;
030import org.apache.wicket.protocol.http.WebApplication;
031import org.apache.wicket.request.mapper.parameter.PageParameters;
032import org.junit.jupiter.api.AfterEach;
033import org.junit.jupiter.api.BeforeEach;
034
035/**
036 * Base class for tests which require comparing wicket response with a file.
037 * <p>
038 * To create/replace the expected result file with the new content, define the system property like
039 * -Dwicket.replace.expected.results=true
040 */
041public abstract class WicketTestCase
042{
043        /** */
044        public WicketTester tester;
045
046        /**
047         */
048        @BeforeEach
049        public void commonBefore()
050        {
051                // make sure no leaked threadlocals are present
052                ThreadContext.detach();
053
054                WebApplication application = newApplication();
055                tester = newWicketTester(application);
056        }
057
058        /**
059         * @return the application that should be used for the test
060         */
061        protected WebApplication newApplication()
062        {
063                return new MockApplication();
064        }
065
066        /**
067         * In case you need to subclass WicketTester and want to be independent on possible changes in
068         * setUp().
069         *
070         * @param app
071         * @return WIcketTester
072         */
073        protected WicketTester newWicketTester(final WebApplication app)
074        {
075                return new WicketTester(app) {
076                        @Override
077                        protected Locale servletRequestLocale() {
078                                return Locale.US;
079                        }
080                };
081        }
082
083        /**
084         *
085         */
086        @AfterEach
087        public void commonAfter()
088        {
089                tester.destroy();
090        }
091
092        /**
093         * Use <code>-Dwicket.replace.expected.results=true</code> to automatically replace the expected
094         * output file.
095         *
096         * @param <T>
097         *
098         * @param pageClass
099         * @param filename
100         * @throws Exception
101         */
102        protected <T extends Page> void executeTest(final Class<T> pageClass, final String filename)
103                throws Exception
104        {
105                tester.executeTest(getClass(), pageClass, filename);
106        }
107
108        /**
109         * Use <code>-Dwicket.replace.expected.results=true</code> to automatically replace the expected
110         * output file.
111         *
112         * @param page
113         * @param filename
114         * @throws Exception
115         */
116        protected void executeTest(final Page page, final String filename) throws Exception
117        {
118                tester.executeTest(getClass(), page, filename);
119        }
120
121        /**
122         * Use <code>-Dwicket.replace.expected.results=true</code> to automatically replace the expected
123         * output file.
124         *
125         * @param <T>
126         *
127         * @param pageClass
128         * @param parameters
129         * @param filename
130         * @throws Exception
131         */
132        protected <T extends Page> void executeTest(final Class<T> pageClass,
133                PageParameters parameters, final String filename) throws Exception
134        {
135                tester.executeTest(getClass(), pageClass, parameters, filename);
136        }
137
138        /**
139         *
140         * @param component
141         * @param filename
142         * @throws Exception
143         */
144        protected void executeListener(final Component component, final String filename)
145                throws Exception
146        {
147                tester.executeListener(getClass(), component, filename);
148        }
149
150        /**
151         *
152         * @param behavior
153         * @param filename
154         * @throws Exception
155         */
156        protected void executeBehavior(final AbstractAjaxBehavior behavior, final String filename)
157                throws Exception
158        {
159                tester.executeBehavior(getClass(), behavior, filename);
160        }
161
162        /**
163         * Returns the current Maven build directory taken from the <tt>basedir</tt> system property, or
164         * null if not set
165         *
166         * @return path with a trailing slash
167         */
168        public String getBasedir()
169        {
170                return WicketTester.getBasedir();
171        }
172
173        /**
174         * Compare the markup provided with the file content
175         *
176         * @param markup
177         * @param filename
178         * @param scopeClass
179         * @throws IOException
180         */
181        protected final void compareMarkupWithFile(IMarkupFragment markup, String filename, Class<?> scopeClass)
182                throws IOException
183        {
184                String doc = markup.toString(true);
185                DiffUtil.validatePage(doc, scopeClass, filename, true);
186        }
187
188        /**
189         * Compare the markup provided with the String
190         *
191         * @param markup
192         * @param testMarkup
193         */
194        protected final void compareMarkupWithString(IMarkupFragment markup, String testMarkup) {
195                testMarkup = testMarkup.replaceAll("\r", "");
196                testMarkup = testMarkup.replaceAll("\n", "");
197                testMarkup = testMarkup.replaceAll("\t", "");
198
199                String doc = markup.toString(true);
200                doc = doc.replaceAll("\n", "");
201                doc = doc.replaceAll("\r", "");
202                doc = doc.replaceAll("\t", "");
203                assertEquals(doc, testMarkup);
204        }
205}