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