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/content_browser_test.h"
14 #include "content/public/test/content_browser_test_utils.h"
15 #include "content/public/test/test_utils.h"
16 #include "content/shell/browser/shell.h"
17 #include "testing/gtest/include/gtest/gtest.h"
21 class DatabaseTest
: public ContentBrowserTest
{
25 void RunScriptAndCheckResult(Shell
* shell
,
26 const std::string
& script
,
27 const std::string
& result
) {
29 ASSERT_TRUE(ExecuteScriptAndExtractString(
30 shell
->web_contents(),
33 ASSERT_EQ(data
, result
);
36 void Navigate(Shell
* shell
) {
37 NavigateToURL(shell
, GetTestUrl("", "simple_database.html"));
40 void CreateTable(Shell
* shell
) {
41 RunScriptAndCheckResult(shell
, "createTable()", "done");
44 void InsertRecord(Shell
* shell
, const std::string
& data
) {
45 RunScriptAndCheckResult(shell
, "insertRecord('" + data
+ "')", "done");
48 void UpdateRecord(Shell
* shell
, int index
, const std::string
& data
) {
49 RunScriptAndCheckResult(
51 "updateRecord(" + base::IntToString(index
) + ", '" + data
+ "')",
55 void DeleteRecord(Shell
* shell
, int index
) {
56 RunScriptAndCheckResult(
57 shell
, "deleteRecord(" + base::IntToString(index
) + ")", "done");
60 void CompareRecords(Shell
* shell
, const std::string
& expected
) {
61 RunScriptAndCheckResult(shell
, "getRecords()", expected
);
64 bool HasTable(Shell
* shell
) {
66 CHECK(ExecuteScriptAndExtractString(
67 shell
->web_contents(),
70 return data
!= "getRecords error: [object SQLError]";
74 // Insert records to the database.
75 IN_PROC_BROWSER_TEST_F(DatabaseTest
, InsertRecord
) {
78 InsertRecord(shell(), "text");
79 CompareRecords(shell(), "text");
80 InsertRecord(shell(), "text2");
81 CompareRecords(shell(), "text, text2");
84 // Update records in the database.
85 IN_PROC_BROWSER_TEST_F(DatabaseTest
, UpdateRecord
) {
88 InsertRecord(shell(), "text");
89 UpdateRecord(shell(), 0, "0");
90 CompareRecords(shell(), "0");
92 InsertRecord(shell(), "1");
93 InsertRecord(shell(), "2");
94 UpdateRecord(shell(), 1, "1000");
95 CompareRecords(shell(), "0, 1000, 2");
98 // Delete records in the database.
99 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DeleteRecord
) {
101 CreateTable(shell());
102 InsertRecord(shell(), "text");
103 DeleteRecord(shell(), 0);
104 CompareRecords(shell(), std::string());
106 InsertRecord(shell(), "0");
107 InsertRecord(shell(), "1");
108 InsertRecord(shell(), "2");
109 DeleteRecord(shell(), 1);
110 CompareRecords(shell(), "0, 2");
113 // Attempts to delete a nonexistent row in the table.
114 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DeleteNonexistentRow
) {
116 CreateTable(shell());
117 InsertRecord(shell(), "text");
119 RunScriptAndCheckResult(
120 shell(), "deleteRecord(1)", "could not find row with index: 1");
122 CompareRecords(shell(), "text");
125 // Insert, update, and delete records in the database.
126 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DatabaseOperations
) {
128 CreateTable(shell());
130 std::string expected
;
131 for (int i
= 0; i
< 10; ++i
) {
132 std::string item
= base::IntToString(i
);
133 InsertRecord(shell(), item
);
134 if (!expected
.empty())
138 CompareRecords(shell(), expected
);
141 for (int i
= 0; i
< 10; ++i
) {
142 std::string item
= base::IntToString(i
* i
);
143 UpdateRecord(shell(), i
, item
);
144 if (!expected
.empty())
148 CompareRecords(shell(), expected
);
150 for (int i
= 0; i
< 10; ++i
)
151 DeleteRecord(shell(), 0);
153 CompareRecords(shell(), std::string());
155 RunScriptAndCheckResult(
156 shell(), "deleteRecord(1)", "could not find row with index: 1");
158 CompareRecords(shell(), std::string());
161 // Create records in the database and verify they persist after reload.
162 IN_PROC_BROWSER_TEST_F(DatabaseTest
, ReloadPage
) {
164 CreateTable(shell());
165 InsertRecord(shell(), "text");
167 WindowedNotificationObserver
load_stop_observer(
168 NOTIFICATION_LOAD_STOP
,
169 NotificationService::AllSources());
171 load_stop_observer
.Wait();
173 CompareRecords(shell(), "text");
176 // Attempt to read a database created in a regular browser from an off the
178 IN_PROC_BROWSER_TEST_F(DatabaseTest
, OffTheRecordCannotReadRegularDatabase
) {
180 CreateTable(shell());
181 InsertRecord(shell(), "text");
183 Shell
* otr
= CreateOffTheRecordBrowser();
185 ASSERT_FALSE(HasTable(otr
));
188 CompareRecords(otr
, std::string());
191 // Attempt to read a database created in an off the record browser from a
193 IN_PROC_BROWSER_TEST_F(DatabaseTest
, RegularCannotReadOffTheRecordDatabase
) {
194 Shell
* otr
= CreateOffTheRecordBrowser();
197 InsertRecord(otr
, "text");
200 ASSERT_FALSE(HasTable(shell()));
201 CreateTable(shell());
202 CompareRecords(shell(), std::string());
205 // Verify DB changes within first window are present in the second window.
206 IN_PROC_BROWSER_TEST_F(DatabaseTest
, ModificationPersistInSecondTab
) {
208 CreateTable(shell());
209 InsertRecord(shell(), "text");
211 Shell
* shell2
= CreateBrowser();
213 UpdateRecord(shell2
, 0, "0");
215 CompareRecords(shell(), "0");
216 CompareRecords(shell2
, "0");
219 // Verify database modifications persist after restarting browser.
220 IN_PROC_BROWSER_TEST_F(DatabaseTest
, PRE_DatabasePersistsAfterRelaunch
) {
222 CreateTable(shell());
223 InsertRecord(shell(), "text");
226 IN_PROC_BROWSER_TEST_F(DatabaseTest
, DatabasePersistsAfterRelaunch
) {
228 CompareRecords(shell(), "text");
231 // Verify OTR database is removed after OTR window closes.
232 IN_PROC_BROWSER_TEST_F(DatabaseTest
, PRE_OffTheRecordDatabaseNotPersistent
) {
233 Shell
* otr
= CreateOffTheRecordBrowser();
236 InsertRecord(otr
, "text");
239 IN_PROC_BROWSER_TEST_F(DatabaseTest
, OffTheRecordDatabaseNotPersistent
) {
240 Shell
* otr
= CreateOffTheRecordBrowser();
242 ASSERT_FALSE(HasTable(otr
));
245 // Verify database modifications persist after crashing window.
246 IN_PROC_BROWSER_TEST_F(DatabaseTest
, ModificationsPersistAfterRendererCrash
) {
248 CreateTable(shell());
249 InsertRecord(shell(), "1");
251 CrashTab(shell()->web_contents());
253 CompareRecords(shell(), "1");
256 // Test to check if database modifications are persistent across windows in
257 // off the record window.
258 IN_PROC_BROWSER_TEST_F(DatabaseTest
, OffTheRecordDBPersistentAcrossWindows
) {
259 Shell
* otr1
= CreateOffTheRecordBrowser();
262 InsertRecord(otr1
, "text");
264 Shell
* otr2
= CreateOffTheRecordBrowser();
266 CompareRecords(otr2
, "text");
269 } // namespace content