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.attachment;
16  
17  import java.io.File;
18  import java.net.URL;
19  import java.util.ArrayList;
20  import java.util.Collection;
21  import java.util.List;
22  
23  import org.apache.commons.io.FileUtils;
24  import org.htmlunit.MockWebConnection;
25  import org.htmlunit.Page;
26  import org.htmlunit.SimpleWebTestCase;
27  import org.htmlunit.WebClient;
28  import org.htmlunit.html.HtmlAnchor;
29  import org.htmlunit.html.HtmlPage;
30  import org.htmlunit.junit.BrowserRunner;
31  import org.htmlunit.util.MimeType;
32  import org.htmlunit.util.NameValuePair;
33  import org.junit.Test;
34  import org.junit.runner.RunWith;
35  
36  /**
37   * Tests for {@link DownloadingAttachmentHandler}.
38   *
39   * @author Marek Andreansky
40   * @author Ronald Brill
41   */
42  @RunWith(BrowserRunner.class)
43  public class DownloadingAttachmentHandlerTest extends SimpleWebTestCase {
44  
45      /**
46       * @throws Exception if an error occurs
47       */
48      @Test
49      public void basic() throws Exception {
50          final String content1 = DOCTYPE_HTML
51              + "<html><body>\n"
52              + "<form method='POST' name='form' action='" + URL_SECOND + "'>\n"
53              + "<input type='submit' value='ok'>\n"
54              + "</form>\n"
55              + "<a href='#' onclick='document.form.submit()'>click me</a>\n"
56              + "</body></html>";
57          final String content2 = "download file contents";
58  
59          final File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
60          final File downloadFolder = new File(tmpFolder, "downloading-attachment-test");
61  
62          try {
63              FileUtils.forceMkdir(downloadFolder);
64  
65              assertEquals(0, FileUtils.listFiles(downloadFolder, null, false).size());
66  
67              final WebClient client = getWebClient();
68              client.setAttachmentHandler(new DownloadingAttachmentHandler(downloadFolder.toPath()));
69  
70              final List<NameValuePair> headers = new ArrayList<>();
71              headers.add(new NameValuePair("Content-Disposition", "attachment"));
72  
73              final MockWebConnection conn = new MockWebConnection();
74              conn.setResponse(URL_FIRST, content1);
75              conn.setResponse(URL_SECOND, content2, 200, "OK", MimeType.TEXT_HTML, headers);
76              client.setWebConnection(conn);
77  
78              final HtmlPage result = client.getPage(URL_FIRST);
79              final HtmlAnchor anchor = result.getAnchors().get(0);
80              final Page clickResult = anchor.click();
81              assertEquals(result, clickResult);
82  
83              Collection<File> files = FileUtils.listFiles(downloadFolder, null, false);
84              assertEquals(1, files.size());
85              assertEquals("download", files.iterator().next().getName());
86  
87              anchor.click();
88              files = FileUtils.listFiles(downloadFolder, null, false);
89              assertEquals(2, files.size());
90  
91              // be order agnostic
92              assertTrue(files.removeIf(f -> f.getName().equals("download")));
93              assertTrue(files.removeIf(f -> f.getName().equals("download(1)")));
94              assertEquals(0, files.size());
95          }
96          finally {
97              FileUtils.deleteDirectory(downloadFolder);
98          }
99      }
100 
101     /**
102      * @throws Exception if an error occurs
103      */
104     @Test
105     public void basicFileNameFromUrl() throws Exception {
106         final String content1 = DOCTYPE_HTML
107             + "<html><body>\n"
108             + "<form method='POST' name='form' action='" + URL_SECOND + "test.txt'>\n"
109             + "<input type='submit' value='ok'>\n"
110             + "</form>\n"
111             + "<a href='#' onclick='document.form.submit()'>click me</a>\n"
112             + "</body></html>";
113         final String content2 = "download file contents";
114 
115         final File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
116         final File downloadFolder = new File(tmpFolder, "downloading-attachment-test");
117 
118         try {
119             FileUtils.forceMkdir(downloadFolder);
120 
121             assertEquals(0, FileUtils.listFiles(downloadFolder, null, false).size());
122 
123             final WebClient client = getWebClient();
124             client.setAttachmentHandler(new DownloadingAttachmentHandler(downloadFolder.toPath()));
125 
126             final List<NameValuePair> headers = new ArrayList<>();
127             headers.add(new NameValuePair("Content-Disposition", "attachment"));
128 
129             final MockWebConnection conn = new MockWebConnection();
130             conn.setResponse(URL_FIRST, content1);
131             conn.setResponse(new URL(URL_SECOND, "test.txt"), content2, 200, "OK", MimeType.TEXT_HTML, headers);
132             client.setWebConnection(conn);
133 
134             final HtmlPage result = client.getPage(URL_FIRST);
135             final HtmlAnchor anchor = result.getAnchors().get(0);
136             final Page clickResult = anchor.click();
137             assertEquals(result, clickResult);
138 
139             Collection<File> files = FileUtils.listFiles(downloadFolder, null, false);
140             assertEquals(1, files.size());
141             assertEquals("test.txt", files.iterator().next().getName());
142 
143             anchor.click();
144             files = FileUtils.listFiles(downloadFolder, null, false);
145             assertEquals(2, files.size());
146 
147             // be order agnostic
148             assertTrue(files.removeIf(f -> f.getName().equals("test.txt")));
149             assertTrue(files.removeIf(f -> f.getName().equals("test(1).txt")));
150             assertEquals(0, files.size());
151         }
152         finally {
153             FileUtils.deleteDirectory(downloadFolder);
154         }
155     }
156 
157     /**
158      * @throws Exception if an error occurs
159      */
160     @Test
161     public void basicFileNameFromHeader() throws Exception {
162         final String content1 = DOCTYPE_HTML
163             + "<html><body>\n"
164             + "<form method='POST' name='form' action='" + URL_SECOND + "test.txt'>\n"
165             + "<input type='submit' value='ok'>\n"
166             + "</form>\n"
167             + "<a href='#' onclick='document.form.submit()'>click me</a>\n"
168             + "</body></html>";
169         final String content2 = "download file contents";
170 
171         final File tmpFolder = new File(System.getProperty("java.io.tmpdir"));
172         final File downloadFolder = new File(tmpFolder, "downloading-attachment-test");
173         FileUtils.deleteDirectory(downloadFolder);
174 
175         try {
176             FileUtils.forceMkdir(downloadFolder);
177 
178             assertEquals(0, FileUtils.listFiles(downloadFolder, null, false).size());
179 
180             final WebClient client = getWebClient();
181             client.setAttachmentHandler(new DownloadingAttachmentHandler(downloadFolder.toPath()));
182 
183             final List<NameValuePair> headers = new ArrayList<>();
184             headers.add(new NameValuePair("Content-Disposition", "attachment; filename=sample.pdf"));
185 
186             final MockWebConnection conn = new MockWebConnection();
187             conn.setResponse(URL_FIRST, content1);
188             conn.setResponse(new URL(URL_SECOND, "test.txt"), content2, 200, "OK", MimeType.TEXT_HTML, headers);
189             client.setWebConnection(conn);
190 
191             final HtmlPage result = client.getPage(URL_FIRST);
192             final HtmlAnchor anchor = result.getAnchors().get(0);
193             final Page clickResult = anchor.click();
194             assertEquals(result, clickResult);
195 
196             Collection<File> files = FileUtils.listFiles(downloadFolder, null, false);
197             assertEquals(1, files.size());
198             assertEquals("sample.pdf", files.iterator().next().getName());
199 
200             anchor.click();
201             files = FileUtils.listFiles(downloadFolder, null, false);
202             assertEquals(2, files.size());
203 
204             // be order agnostic
205             assertTrue(files.removeIf(f -> f.getName().equals("sample.pdf")));
206             assertTrue(files.removeIf(f -> f.getName().equals("sample(1).pdf")));
207             assertEquals(0, files.size());
208         }
209         finally {
210             FileUtils.deleteDirectory(downloadFolder);
211         }
212     }
213 }