View Javadoc
1   /*
2    * Copyright (c) 2002-2025 Gargoyle Software Inc.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * https://www.apache.org/licenses/LICENSE-2.0
8    *
9    * Unless required by applicable law or agreed to in writing, software
10   * distributed under the License is distributed on an "AS IS" BASIS,
11   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   * See the License for the specific language governing permissions and
13   * limitations under the License.
14   */
15  package org.htmlunit.html;
16  
17  import java.io.ByteArrayOutputStream;
18  import java.io.IOException;
19  import java.io.InputStream;
20  import java.io.ObjectOutputStream;
21  import java.net.URL;
22  
23  import org.apache.commons.io.IOUtils;
24  import org.htmlunit.HttpHeader;
25  import org.htmlunit.WebClient;
26  import org.htmlunit.WebResponse;
27  import org.htmlunit.WebServerTestCase;
28  import org.htmlunit.platform.image.ImageData;
29  import org.htmlunit.platform.image.ImageIOImageData;
30  import org.junit.jupiter.api.AfterEach;
31  import org.junit.jupiter.api.Assertions;
32  import org.junit.jupiter.api.Test;
33  
34  /**
35   * Tests for {@link HtmlImage}.
36   *
37   * @author Knut Johannes Dahle
38   * @author Ahmed Ashour
39   * @author Marc Guillemot
40   * @author Lukas Botsch
41   */
42  public class HtmlImageDownloadTest extends WebServerTestCase {
43      private static final String BASE_FILE_PATH = "src/test/resources/org/htmlunit/html";
44  
45      /**
46       * Constructor.
47       * @throws Exception if an exception occurs
48       */
49      public HtmlImageDownloadTest() throws Exception {
50          startWebServer(BASE_FILE_PATH);
51      }
52  
53      /**
54       * @throws Exception if the test fails
55       */
56      @Test
57      public void imageHeight() throws Exception {
58          final HtmlImage htmlImage = getHtmlElementToTest("image1");
59          assertEquals("Image height", 612, htmlImage.getHeight());
60      }
61  
62      /**
63       * @throws Exception if the test fails
64       */
65      @Test
66      public void imageWidth() throws Exception {
67          final HtmlImage htmlImage = getHtmlElementToTest("image1");
68          assertEquals("Image width", 879, htmlImage.getWidth());
69      }
70  
71      /**
72       * @throws Exception if the test fails
73       */
74      @Test
75      public void imageFileSize() throws Exception {
76          final HtmlImage htmlImage = getHtmlElementToTest("image1");
77          try (InputStream in = htmlImage.getWebResponse(true).getContentAsStream()) {
78              assertEquals("Image filesize", 140144,
79                      IOUtils.toByteArray(in).length);
80          }
81      }
82  
83      /**
84       * @throws Exception if the test fails
85       */
86      @Test
87      public void getImageData() throws Exception {
88          final HtmlImage htmlImage = getHtmlElementToTest("image1");
89          assertNotNull("ImageData should not be null", htmlImage.getImageData());
90          assertNotNull("ImageReader should not be null", ((ImageIOImageData) htmlImage.getImageData()).getImageReader());
91      }
92  
93      /**
94       * @throws Exception if the test fails
95       */
96      @Test
97      public void getImageDataNoneSupportedImage() throws Exception {
98          final HtmlImage htmlImage = getHtmlElementToTest("image1");
99          final String url = "/HtmlImageDownloadTest.html";
100         htmlImage.setAttribute("src", url);
101         try {
102             htmlImage.getImageData();
103             Assertions.fail("it was not an image!");
104         }
105         catch (final IOException expected) {
106         }
107     }
108 
109     /**
110      * @throws Exception if the test fails
111      */
112     @Test
113     public void getWebResponse() throws Exception {
114         final HtmlImage htmlImage = getHtmlElementToTest("image1");
115         final URL url = htmlImage.getPage().getUrl();
116         // per default images are not downloaded
117         assertNull(htmlImage.getWebResponse(false));
118         final WebResponse resp = htmlImage.getWebResponse(true);
119         assertNotNull(resp);
120         assertEquals(url.toExternalForm(), resp.getWebRequest().getAdditionalHeaders().get(HttpHeader.REFERER));
121     }
122 
123     /**
124      * The image should be redownloaded when the src attribute changes.
125      * @throws Exception if the test fails
126      */
127     @Test
128     public void redownloadOnSrcAttributeChanged() throws Exception {
129         final HtmlImage htmlImage = getHtmlElementToTest("image1");
130 
131         final ImageData imageData = htmlImage.getImageData();
132 
133         htmlImage.setAttribute("src", htmlImage.getSrcAttribute() + "#changed");
134 
135         assertFalse("Src attribute changed but ImageData was not reloaded",
136                 imageData.equals(htmlImage.getImageData()));
137     }
138 
139     /**
140      * Common code for the tests to load the test page and fetch the HtmlImage object.
141      * @param id value of image id attribute
142      * @return the found HtmlImage
143      * @throws Exception if an error occurs
144      */
145     private HtmlImage getHtmlElementToTest(final String id) throws Exception {
146         final String url = URL_FIRST + "HtmlImageDownloadTest.html";
147         final WebClient client = getWebClient();
148         final HtmlPage page = client.getPage(url);
149         return (HtmlImage) page.getElementById(id);
150     }
151 
152     /**
153      * {@inheritDoc}
154      */
155     @Override
156     @AfterEach
157     public void tearDown() throws Exception {
158         Thread.sleep(100);
159         super.tearDown();
160     }
161 
162     /**
163      * @throws Exception if the test fails
164      */
165     @Test
166     public void serialize() throws Exception {
167         final HtmlImage htmlImage = getHtmlElementToTest("image1");
168         htmlImage.getImageData();
169 
170         try (ByteArrayOutputStream baos = new ByteArrayOutputStream()) {
171             try (ObjectOutputStream out = new ObjectOutputStream(baos)) {
172                 out.writeObject(htmlImage);
173             }
174         }
175     }
176 
177 }