blob: e38e41737446cd341cc3ca4475fd5a4a2ccc66bc [file] [log] [blame]
[email protected]81702c82012-08-22 21:44:071// 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.
4
[email protected]10994d132013-06-11 07:16:185#include "base/strings/string_number_conversions.h"
[email protected]74ebfb12013-06-07 20:48:006#include "base/strings/utf_string_conversions.h"
[email protected]81702c82012-08-22 21:44:077#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"
[email protected]6e9def12014-03-27 20:23:2813#include "content/public/test/content_browser_test.h"
14#include "content/public/test/content_browser_test_utils.h"
[email protected]81702c82012-08-22 21:44:0715#include "content/public/test/test_utils.h"
[email protected]de7d61ff2013-08-20 11:30:4116#include "content/shell/browser/shell.h"
[email protected]81702c82012-08-22 21:44:0717#include "testing/gtest/include/gtest/gtest.h"
18
19namespace content {
20
21class DatabaseTest : public ContentBrowserTest {
22 public:
23 DatabaseTest() {}
24
25 void RunScriptAndCheckResult(Shell* shell,
26 const std::string& script,
27 const std::string& result) {
28 std::string data;
[email protected]b6987e02013-01-04 18:30:4329 ASSERT_TRUE(ExecuteScriptAndExtractString(
30 shell->web_contents(),
[email protected]06bc5d92013-01-02 22:44:1331 script,
32 &data));
[email protected]81702c82012-08-22 21:44:0733 ASSERT_EQ(data, result);
34 }
35
36 void Navigate(Shell* shell) {
37 NavigateToURL(shell, GetTestUrl("", "simple_database.html"));
38 }
39
40 void CreateTable(Shell* shell) {
41 RunScriptAndCheckResult(shell, "createTable()", "done");
42 }
43
44 void InsertRecord(Shell* shell, const std::string& data) {
45 RunScriptAndCheckResult(shell, "insertRecord('" + data + "')", "done");
46 }
47
48 void UpdateRecord(Shell* shell, int index, const std::string& data) {
49 RunScriptAndCheckResult(
[email protected]06bc5d92013-01-02 22:44:1350 shell,
51 "updateRecord(" + base::IntToString(index) + ", '" + data + "')",
52 "done");
[email protected]81702c82012-08-22 21:44:0753 }
54
55 void DeleteRecord(Shell* shell, int index) {
56 RunScriptAndCheckResult(
[email protected]06bc5d92013-01-02 22:44:1357 shell, "deleteRecord(" + base::IntToString(index) + ")", "done");
[email protected]81702c82012-08-22 21:44:0758 }
59
60 void CompareRecords(Shell* shell, const std::string& expected) {
61 RunScriptAndCheckResult(shell, "getRecords()", expected);
62 }
63
64 bool HasTable(Shell* shell) {
65 std::string data;
[email protected]b6987e02013-01-04 18:30:4366 CHECK(ExecuteScriptAndExtractString(
67 shell->web_contents(),
[email protected]06bc5d92013-01-02 22:44:1368 "getRecords()",
69 &data));
[email protected]81702c82012-08-22 21:44:0770 return data != "getRecords error: [object SQLError]";
71 }
72};
73
74// Insert records to the database.
75IN_PROC_BROWSER_TEST_F(DatabaseTest, InsertRecord) {
76 Navigate(shell());
77 CreateTable(shell());
78 InsertRecord(shell(), "text");
79 CompareRecords(shell(), "text");
80 InsertRecord(shell(), "text2");
81 CompareRecords(shell(), "text, text2");
82}
83
84// Update records in the database.
85IN_PROC_BROWSER_TEST_F(DatabaseTest, UpdateRecord) {
86 Navigate(shell());
87 CreateTable(shell());
88 InsertRecord(shell(), "text");
89 UpdateRecord(shell(), 0, "0");
90 CompareRecords(shell(), "0");
91
92 InsertRecord(shell(), "1");
93 InsertRecord(shell(), "2");
94 UpdateRecord(shell(), 1, "1000");
95 CompareRecords(shell(), "0, 1000, 2");
96}
97
98// Delete records in the database.
99IN_PROC_BROWSER_TEST_F(DatabaseTest, DeleteRecord) {
100 Navigate(shell());
101 CreateTable(shell());
102 InsertRecord(shell(), "text");
103 DeleteRecord(shell(), 0);
[email protected]007b3f82013-04-09 08:46:45104 CompareRecords(shell(), std::string());
[email protected]81702c82012-08-22 21:44:07105
106 InsertRecord(shell(), "0");
107 InsertRecord(shell(), "1");
108 InsertRecord(shell(), "2");
109 DeleteRecord(shell(), 1);
110 CompareRecords(shell(), "0, 2");
111}
112
113// Attempts to delete a nonexistent row in the table.
114IN_PROC_BROWSER_TEST_F(DatabaseTest, DeleteNonexistentRow) {
115 Navigate(shell());
116 CreateTable(shell());
117 InsertRecord(shell(), "text");
118
119 RunScriptAndCheckResult(
120 shell(), "deleteRecord(1)", "could not find row with index: 1");
121
122 CompareRecords(shell(), "text");
123}
124
125// Insert, update, and delete records in the database.
126IN_PROC_BROWSER_TEST_F(DatabaseTest, DatabaseOperations) {
127 Navigate(shell());
128 CreateTable(shell());
129
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())
135 expected += ", ";
136 expected += item;
137 }
138 CompareRecords(shell(), expected);
139
140 expected.clear();
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())
145 expected += ", ";
146 expected += item;
147 }
148 CompareRecords(shell(), expected);
149
150 for (int i = 0; i < 10; ++i)
151 DeleteRecord(shell(), 0);
152
[email protected]007b3f82013-04-09 08:46:45153 CompareRecords(shell(), std::string());
[email protected]81702c82012-08-22 21:44:07154
155 RunScriptAndCheckResult(
156 shell(), "deleteRecord(1)", "could not find row with index: 1");
157
[email protected]007b3f82013-04-09 08:46:45158 CompareRecords(shell(), std::string());
[email protected]81702c82012-08-22 21:44:07159}
160
161// Create records in the database and verify they persist after reload.
162IN_PROC_BROWSER_TEST_F(DatabaseTest, ReloadPage) {
163 Navigate(shell());
164 CreateTable(shell());
165 InsertRecord(shell(), "text");
166
167 WindowedNotificationObserver load_stop_observer(
168 NOTIFICATION_LOAD_STOP,
169 NotificationService::AllSources());
170 shell()->Reload();
171 load_stop_observer.Wait();
172
173 CompareRecords(shell(), "text");
174}
175
176// Attempt to read a database created in a regular browser from an off the
177// record browser.
178IN_PROC_BROWSER_TEST_F(DatabaseTest, OffTheRecordCannotReadRegularDatabase) {
179 Navigate(shell());
180 CreateTable(shell());
181 InsertRecord(shell(), "text");
182
183 Shell* otr = CreateOffTheRecordBrowser();
184 Navigate(otr);
185 ASSERT_FALSE(HasTable(otr));
186
187 CreateTable(otr);
[email protected]007b3f82013-04-09 08:46:45188 CompareRecords(otr, std::string());
[email protected]81702c82012-08-22 21:44:07189}
190
191// Attempt to read a database created in an off the record browser from a
192// regular browser.
193IN_PROC_BROWSER_TEST_F(DatabaseTest, RegularCannotReadOffTheRecordDatabase) {
194 Shell* otr = CreateOffTheRecordBrowser();
195 Navigate(otr);
196 CreateTable(otr);
197 InsertRecord(otr, "text");
198
199 Navigate(shell());
200 ASSERT_FALSE(HasTable(shell()));
201 CreateTable(shell());
[email protected]007b3f82013-04-09 08:46:45202 CompareRecords(shell(), std::string());
[email protected]81702c82012-08-22 21:44:07203}
204
205// Verify DB changes within first window are present in the second window.
206IN_PROC_BROWSER_TEST_F(DatabaseTest, ModificationPersistInSecondTab) {
207 Navigate(shell());
208 CreateTable(shell());
209 InsertRecord(shell(), "text");
210
211 Shell* shell2 = CreateBrowser();
212 Navigate(shell2);
213 UpdateRecord(shell2, 0, "0");
214
215 CompareRecords(shell(), "0");
216 CompareRecords(shell2, "0");
217}
218
219// Verify database modifications persist after restarting browser.
220IN_PROC_BROWSER_TEST_F(DatabaseTest, PRE_DatabasePersistsAfterRelaunch) {
221 Navigate(shell());
222 CreateTable(shell());
223 InsertRecord(shell(), "text");
224}
225
226IN_PROC_BROWSER_TEST_F(DatabaseTest, DatabasePersistsAfterRelaunch) {
227 Navigate(shell());
228 CompareRecords(shell(), "text");
229}
230
231// Verify OTR database is removed after OTR window closes.
232IN_PROC_BROWSER_TEST_F(DatabaseTest, PRE_OffTheRecordDatabaseNotPersistent) {
233 Shell* otr = CreateOffTheRecordBrowser();
234 Navigate(otr);
235 CreateTable(otr);
236 InsertRecord(otr, "text");
237}
238
239IN_PROC_BROWSER_TEST_F(DatabaseTest, OffTheRecordDatabaseNotPersistent) {
240 Shell* otr = CreateOffTheRecordBrowser();
241 Navigate(otr);
242 ASSERT_FALSE(HasTable(otr));
243}
244
245// Verify database modifications persist after crashing window.
246IN_PROC_BROWSER_TEST_F(DatabaseTest, ModificationsPersistAfterRendererCrash) {
247 Navigate(shell());
248 CreateTable(shell());
249 InsertRecord(shell(), "1");
250
251 CrashTab(shell()->web_contents());
252 Navigate(shell());
253 CompareRecords(shell(), "1");
254}
255
256// Test to check if database modifications are persistent across windows in
257// off the record window.
258IN_PROC_BROWSER_TEST_F(DatabaseTest, OffTheRecordDBPersistentAcrossWindows) {
259 Shell* otr1 = CreateOffTheRecordBrowser();
260 Navigate(otr1);
261 CreateTable(otr1);
262 InsertRecord(otr1, "text");
263
264 Shell* otr2 = CreateOffTheRecordBrowser();
265 Navigate(otr2);
266 CompareRecords(otr2, "text");
267}
268
269} // namespace content