summaryrefslogtreecommitdiffstats
path: root/content/browser/download/mhtml_generation_browsertest.cc
blob: f2ebfd87a9d275c58a6087062291758e37865a28 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/bind.h"
#include "base/callback.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/run_loop.h"
#include "content/public/browser/web_contents.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/content_browser_test_utils.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"

using testing::ContainsRegex;
using testing::HasSubstr;

namespace content {

class MHTMLGenerationTest : public ContentBrowserTest {
 public:
  MHTMLGenerationTest() : has_mhtml_callback_run_(false), file_size_(0) {}

 protected:
  void SetUp() override {
    ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    ASSERT_TRUE(embedded_test_server()->Start());
    ContentBrowserTest::SetUp();
  }

  void GenerateMHTML(const base::FilePath& path, const GURL& url) {
    NavigateToURL(shell(), url);

    base::RunLoop run_loop;
    shell()->web_contents()->GenerateMHTML(
        path, base::Bind(&MHTMLGenerationTest::MHTMLGenerated, this,
                         run_loop.QuitClosure()));

    // Block until the MHTML is generated.
    run_loop.Run();

    EXPECT_TRUE(has_mhtml_callback_run());
  }

  bool has_mhtml_callback_run() const { return has_mhtml_callback_run_; }
  int64 file_size() const { return file_size_; }

  base::ScopedTempDir temp_dir_;

 private:
  void MHTMLGenerated(base::Closure quit_closure, int64 size) {
    has_mhtml_callback_run_ = true;
    file_size_ = size;
    quit_closure.Run();
  }

  bool has_mhtml_callback_run_;
  int64 file_size_;
};

// Tests that generating a MHTML does create contents.
// Note that the actual content of the file is not tested, the purpose of this
// test is to ensure we were successful in creating the MHTML data from the
// renderer.
IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, GenerateMHTML) {
  base::FilePath path(temp_dir_.path());
  path = path.Append(FILE_PATH_LITERAL("test.mht"));

  GenerateMHTML(path, embedded_test_server()->GetURL("/simple_page.html"));
  ASSERT_FALSE(HasFailure());

  // Make sure the actual generated file has some contents.
  EXPECT_GT(file_size(), 0);  // Verify the size reported by the callback.
  int64 file_size;
  ASSERT_TRUE(base::GetFileSize(path, &file_size));
  EXPECT_GT(file_size, 100);  // Verify the actual file size.
}

IN_PROC_BROWSER_TEST_F(MHTMLGenerationTest, InvalidPath) {
  base::FilePath path(FILE_PATH_LITERAL("/invalid/file/path"));

  GenerateMHTML(path, embedded_test_server()->GetURL(
                          "/download/local-about-blank-subframes.html"));
  ASSERT_FALSE(HasFailure());  // No failures with the invocation itself?

  EXPECT_EQ(file_size(), -1);  // Expecting that the callback reported failure.
}

// Test suite that allows testing --site-per-process against cross-site frames.
// See http://dev.chromium.org/developers/design-documents/site-isolation.
class MHTMLGenerationSitePerProcessTest : public MHTMLGenerationTest {
 public:
  MHTMLGenerationSitePerProcessTest() {}

 protected:
  void SetUpCommandLine(base::CommandLine* command_line) override {
    MHTMLGenerationTest::SetUpCommandLine(command_line);

    // Append --site-per-process flag.
    content::IsolateAllSitesForTesting(command_line);
  }

  void SetUpOnMainThread() override {
    MHTMLGenerationTest::SetUpOnMainThread();

    host_resolver()->AddRule("*", "127.0.0.1");
    ASSERT_TRUE(embedded_test_server()->Start());
    content::SetupCrossSiteRedirector(embedded_test_server());
  }

 private:
  DISALLOW_COPY_AND_ASSIGN(MHTMLGenerationSitePerProcessTest);
};

// Test for crbug.com/538766.
// Disabled because the test will fail until the bug is fixed
// (but note that the test only fails with --site-per-process flag).
IN_PROC_BROWSER_TEST_F(MHTMLGenerationSitePerProcessTest,
                       DISABLED_GenerateMHTML) {
  base::FilePath path(temp_dir_.path());
  path = path.Append(FILE_PATH_LITERAL("test.mht"));

  GURL url(embedded_test_server()->GetURL(
      "a.com", "/frame_tree/page_with_one_frame.html"));
  GenerateMHTML(path, url);
  ASSERT_FALSE(HasFailure());

  std::string mhtml;
  ASSERT_TRUE(base::ReadFileToString(path, &mhtml));

  // Make sure the contents of both frames are present.
  EXPECT_THAT(mhtml, HasSubstr("This page has one cross-site iframe"));
  EXPECT_THAT(mhtml, HasSubstr("This page has no title"));  // From title1.html.

  // Make sure that URLs of both frames are present
  // (note that these are single-line regexes).
  EXPECT_THAT(
      mhtml,
      ContainsRegex("Content-Location:.*/frame_tree/page_with_one_frame.html"));
  EXPECT_THAT(mhtml, ContainsRegex("Content-Location:.*/title1.html"));
}

}  // namespace content