1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "base/strings/string_number_conversions.h"
6 #include "base/strings/utf_string_conversions.h"
7 #include "content/public/browser/browser_context.h"
8 #include "content/public/browser/download_manager.h"
9 #include "content/public/browser/notification_service.h"
10 #include "content/public/browser/notification_types.h"
11 #include "content/public/browser/web_contents.h"
12 #include "content/public/test/browser_test_utils.h"
13 #include "content/public/test/test_utils.h"
14 #include "content/shell/shell.h"
15 #include "content/test/content_browser_test.h"
16 #include "content/test/content_browser_test_utils.h"
17 #include "content/test/net/url_request_mock_http_job.h"
18 #include "testing/gtest/include/gtest/gtest.h"
22 class DatabaseTest
: public ContentBrowserTest
{
26 void RunScriptAndCheckResult(Shell
* shell
,
27 const std::string
& script
,
28 const std::string
& result
) {
30 ASSERT_TRUE(ExecuteScriptAndExtractString(
31 shell
->web_contents(),
34 ASSERT_EQ(data
, result
);
37 void Navigate(Shell
* shell
) {
38 NavigateToURL(shell
, GetTestUrl("", "simple_database.html"));
41 void CreateTable(Shell
* shell
) {
42 RunScriptAndCheckResult(shell
, "createTable()", "done");
45 void InsertRecord(Shell
* shell
, const std::string
& data
) {
46 RunScriptAndCheckResult(shell
, "insertRecord('" + data
+ "')", "done");
49 void UpdateRecord(Shell
* shell
, int index
, const std::string
& data
) {
50 RunScriptAndCheckResult(
52 "updateRecord(" + base::IntToString(index
) + ", '" + data
+ "')",
56 void DeleteRecord(Shell
* shell
, int index
) {
57 RunScriptAndCheckResult(
58 shell
, "deleteRecord(" + base::IntToString(index
) + ")", "done");
61 void CompareRecords(Shell
* shell
, const std::string
& expected
) {
62 RunScriptAndCheckResult(shell
, "getRecords()", expected
);
65 bool HasTable(Shell
* shell
) {
67 CHECK(ExecuteScriptAndExtractString(
68 shell
->web_contents(),
71 return data
!= "getRecords error: [object SQLError]";
75 // Insert records to the database.
76 IN_PROC_BROWSER_TEST_F(DatabaseTest
, InsertRecord
) {
79 InsertRecord(shell(), "text");
80 CompareRecords(shell(), "text");
81 InsertRecord(shell(), "text2");
82 CompareRecords(shell(), "text, text2");
85 // Update records in the database.
86 IN_PROC_BROWSER_TEST_F(DatabaseTest
, UpdateRecord
) {
89 InsertRecord(shell(), "text");
90 UpdateRecord(shell(), 0, "0");
91 CompareRecords(shell(), "0");
93 InsertRecord(shell(), "1");
94 InsertRecord(shell(), "2");
95 UpdateRecord(shell(), 1, "1000");
96 CompareRecords(shell(), "0, 1000, 2");
99 // Delete records in the database.
100 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DeleteRecord
) {
102 CreateTable(shell());
103 InsertRecord(shell(), "text");
104 DeleteRecord(shell(), 0);
105 CompareRecords(shell(), std::string());
107 InsertRecord(shell(), "0");
108 InsertRecord(shell(), "1");
109 InsertRecord(shell(), "2");
110 DeleteRecord(shell(), 1);
111 CompareRecords(shell(), "0, 2");
114 // Attempts to delete a nonexistent row in the table.
115 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DeleteNonexistentRow
) {
117 CreateTable(shell());
118 InsertRecord(shell(), "text");
120 RunScriptAndCheckResult(
121 shell(), "deleteRecord(1)", "could not find row with index: 1");
123 CompareRecords(shell(), "text");
126 // Insert, update, and delete records in the database.
127 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DatabaseOperations
) {
129 CreateTable(shell());
131 std::string expected
;
132 for (int i
= 0; i
< 10; ++i
) {
133 std::string item
= base::IntToString(i
);
134 InsertRecord(shell(), item
);
135 if (!expected
.empty())
139 CompareRecords(shell(), expected
);
142 for (int i
= 0; i
< 10; ++i
) {
143 std::string item
= base::IntToString(i
* i
);
144 UpdateRecord(shell(), i
, item
);
145 if (!expected
.empty())
149 CompareRecords(shell(), expected
);
151 for (int i
= 0; i
< 10; ++i
)
152 DeleteRecord(shell(), 0);
154 CompareRecords(shell(), std::string());
156 RunScriptAndCheckResult(
157 shell(), "deleteRecord(1)", "could not find row with index: 1");
159 CompareRecords(shell(), std::string());
162 // Create records in the database and verify they persist after reload.
163 IN_PROC_BROWSER_TEST_F(DatabaseTest
, ReloadPage
) {
165 CreateTable(shell());
166 InsertRecord(shell(), "text");
168 WindowedNotificationObserver
load_stop_observer(
169 NOTIFICATION_LOAD_STOP
,
170 NotificationService::AllSources());
172 load_stop_observer
.Wait();
174 CompareRecords(shell(), "text");
177 // Attempt to read a database created in a regular browser from an off the
179 IN_PROC_BROWSER_TEST_F(DatabaseTest
, OffTheRecordCannotReadRegularDatabase
) {
181 CreateTable(shell());
182 InsertRecord(shell(), "text");
184 Shell
* otr
= CreateOffTheRecordBrowser();
186 ASSERT_FALSE(HasTable(otr
));
189 CompareRecords(otr
, std::string());
192 // Attempt to read a database created in an off the record browser from a
194 IN_PROC_BROWSER_TEST_F(DatabaseTest
, RegularCannotReadOffTheRecordDatabase
) {
195 Shell
* otr
= CreateOffTheRecordBrowser();
198 InsertRecord(otr
, "text");
201 ASSERT_FALSE(HasTable(shell()));
202 CreateTable(shell());
203 CompareRecords(shell(), std::string());
206 // Verify DB changes within first window are present in the second window.
207 IN_PROC_BROWSER_TEST_F(DatabaseTest
, ModificationPersistInSecondTab
) {
209 CreateTable(shell());
210 InsertRecord(shell(), "text");
212 Shell
* shell2
= CreateBrowser();
214 UpdateRecord(shell2
, 0, "0");
216 CompareRecords(shell(), "0");
217 CompareRecords(shell2
, "0");
220 // Verify database modifications persist after restarting browser.
221 IN_PROC_BROWSER_TEST_F(DatabaseTest
, PRE_DatabasePersistsAfterRelaunch
) {
223 CreateTable(shell());
224 InsertRecord(shell(), "text");
227 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DatabasePersistsAfterRelaunch
) {
229 CompareRecords(shell(), "text");
232 // Verify OTR database is removed after OTR window closes.
233 IN_PROC_BROWSER_TEST_F(DatabaseTest
, PRE_OffTheRecordDatabaseNotPersistent
) {
234 Shell
* otr
= CreateOffTheRecordBrowser();
237 InsertRecord(otr
, "text");
240 IN_PROC_BROWSER_TEST_F(DatabaseTest
, OffTheRecordDatabaseNotPersistent
) {
241 Shell
* otr
= CreateOffTheRecordBrowser();
243 ASSERT_FALSE(HasTable(otr
));
246 // Verify database modifications persist after crashing window.
247 IN_PROC_BROWSER_TEST_F(DatabaseTest
, ModificationsPersistAfterRendererCrash
) {
249 CreateTable(shell());
250 InsertRecord(shell(), "1");
252 CrashTab(shell()->web_contents());
254 CompareRecords(shell(), "1");
257 // Test to check if database modifications are persistent across windows in
258 // off the record window.
259 IN_PROC_BROWSER_TEST_F(DatabaseTest
, OffTheRecordDBPersistentAcrossWindows
) {
260 Shell
* otr1
= CreateOffTheRecordBrowser();
263 InsertRecord(otr1
, "text");
265 Shell
* otr2
= CreateOffTheRecordBrowser();
267 CompareRecords(otr2
, "text");
270 } // namespace content