database_browsertest.cc revision 5821806d5e7f356e8fa4b058a389a808ea183019
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. 4 5#include "base/string_number_conversions.h" 6#include "base/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" 19 20namespace content { 21 22class DatabaseTest : public ContentBrowserTest { 23 public: 24 DatabaseTest() {} 25 26 void RunScriptAndCheckResult(Shell* shell, 27 const std::string& script, 28 const std::string& result) { 29 std::string data; 30 ASSERT_TRUE(ExecuteJavaScriptAndExtractString( 31 shell->web_contents()->GetRenderViewHost(), L"", 32 ASCIIToWide(script), &data)); 33 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( 50 shell, "updateRecord(" + base::IntToString(index) + ", '" + data + "')", 51 "done"); 52 } 53 54 void DeleteRecord(Shell* shell, int index) { 55 RunScriptAndCheckResult( 56 shell, "deleteRecord(" + base::IntToString(index) + ")", "done"); 57 } 58 59 void CompareRecords(Shell* shell, const std::string& expected) { 60 RunScriptAndCheckResult(shell, "getRecords()", expected); 61 } 62 63 bool HasTable(Shell* shell) { 64 std::string data; 65 CHECK(ExecuteJavaScriptAndExtractString( 66 shell->web_contents()->GetRenderViewHost(), L"", 67 ASCIIToWide("getRecords()"), &data)); 68 return data != "getRecords error: [object SQLError]"; 69 } 70}; 71 72// Insert records to the database. 73IN_PROC_BROWSER_TEST_F(DatabaseTest, InsertRecord) { 74 Navigate(shell()); 75 CreateTable(shell()); 76 InsertRecord(shell(), "text"); 77 CompareRecords(shell(), "text"); 78 InsertRecord(shell(), "text2"); 79 CompareRecords(shell(), "text, text2"); 80} 81 82// Update records in the database. 83IN_PROC_BROWSER_TEST_F(DatabaseTest, UpdateRecord) { 84 Navigate(shell()); 85 CreateTable(shell()); 86 InsertRecord(shell(), "text"); 87 UpdateRecord(shell(), 0, "0"); 88 CompareRecords(shell(), "0"); 89 90 InsertRecord(shell(), "1"); 91 InsertRecord(shell(), "2"); 92 UpdateRecord(shell(), 1, "1000"); 93 CompareRecords(shell(), "0, 1000, 2"); 94} 95 96// Delete records in the database. 97IN_PROC_BROWSER_TEST_F(DatabaseTest, DeleteRecord) { 98 Navigate(shell()); 99 CreateTable(shell()); 100 InsertRecord(shell(), "text"); 101 DeleteRecord(shell(), 0); 102 CompareRecords(shell(), ""); 103 104 InsertRecord(shell(), "0"); 105 InsertRecord(shell(), "1"); 106 InsertRecord(shell(), "2"); 107 DeleteRecord(shell(), 1); 108 CompareRecords(shell(), "0, 2"); 109} 110 111// Attempts to delete a nonexistent row in the table. 112IN_PROC_BROWSER_TEST_F(DatabaseTest, DeleteNonexistentRow) { 113 Navigate(shell()); 114 CreateTable(shell()); 115 InsertRecord(shell(), "text"); 116 117 RunScriptAndCheckResult( 118 shell(), "deleteRecord(1)", "could not find row with index: 1"); 119 120 CompareRecords(shell(), "text"); 121} 122 123// Insert, update, and delete records in the database. 124IN_PROC_BROWSER_TEST_F(DatabaseTest, DatabaseOperations) { 125 Navigate(shell()); 126 CreateTable(shell()); 127 128 std::string expected; 129 for (int i = 0; i < 10; ++i) { 130 std::string item = base::IntToString(i); 131 InsertRecord(shell(), item); 132 if (!expected.empty()) 133 expected += ", "; 134 expected += item; 135 } 136 CompareRecords(shell(), expected); 137 138 expected.clear(); 139 for (int i = 0; i < 10; ++i) { 140 std::string item = base::IntToString(i * i); 141 UpdateRecord(shell(), i, item); 142 if (!expected.empty()) 143 expected += ", "; 144 expected += item; 145 } 146 CompareRecords(shell(), expected); 147 148 for (int i = 0; i < 10; ++i) 149 DeleteRecord(shell(), 0); 150 151 CompareRecords(shell(), ""); 152 153 RunScriptAndCheckResult( 154 shell(), "deleteRecord(1)", "could not find row with index: 1"); 155 156 CompareRecords(shell(), ""); 157} 158 159// Create records in the database and verify they persist after reload. 160IN_PROC_BROWSER_TEST_F(DatabaseTest, ReloadPage) { 161 Navigate(shell()); 162 CreateTable(shell()); 163 InsertRecord(shell(), "text"); 164 165 WindowedNotificationObserver load_stop_observer( 166 NOTIFICATION_LOAD_STOP, 167 NotificationService::AllSources()); 168 shell()->Reload(); 169 load_stop_observer.Wait(); 170 171 CompareRecords(shell(), "text"); 172} 173 174// Attempt to read a database created in a regular browser from an off the 175// record browser. 176IN_PROC_BROWSER_TEST_F(DatabaseTest, OffTheRecordCannotReadRegularDatabase) { 177 Navigate(shell()); 178 CreateTable(shell()); 179 InsertRecord(shell(), "text"); 180 181 Shell* otr = CreateOffTheRecordBrowser(); 182 Navigate(otr); 183 ASSERT_FALSE(HasTable(otr)); 184 185 CreateTable(otr); 186 CompareRecords(otr, ""); 187} 188 189// Attempt to read a database created in an off the record browser from a 190// regular browser. 191IN_PROC_BROWSER_TEST_F(DatabaseTest, RegularCannotReadOffTheRecordDatabase) { 192 Shell* otr = CreateOffTheRecordBrowser(); 193 Navigate(otr); 194 CreateTable(otr); 195 InsertRecord(otr, "text"); 196 197 Navigate(shell()); 198 ASSERT_FALSE(HasTable(shell())); 199 CreateTable(shell()); 200 CompareRecords(shell(), ""); 201} 202 203// Verify DB changes within first window are present in the second window. 204IN_PROC_BROWSER_TEST_F(DatabaseTest, ModificationPersistInSecondTab) { 205 Navigate(shell()); 206 CreateTable(shell()); 207 InsertRecord(shell(), "text"); 208 209 Shell* shell2 = CreateBrowser(); 210 Navigate(shell2); 211 UpdateRecord(shell2, 0, "0"); 212 213 CompareRecords(shell(), "0"); 214 CompareRecords(shell2, "0"); 215} 216 217// Verify database modifications persist after restarting browser. 218IN_PROC_BROWSER_TEST_F(DatabaseTest, PRE_DatabasePersistsAfterRelaunch) { 219 Navigate(shell()); 220 CreateTable(shell()); 221 InsertRecord(shell(), "text"); 222} 223 224IN_PROC_BROWSER_TEST_F(DatabaseTest, DatabasePersistsAfterRelaunch) { 225 Navigate(shell()); 226 CompareRecords(shell(), "text"); 227} 228 229// Verify OTR database is removed after OTR window closes. 230IN_PROC_BROWSER_TEST_F(DatabaseTest, PRE_OffTheRecordDatabaseNotPersistent) { 231 Shell* otr = CreateOffTheRecordBrowser(); 232 Navigate(otr); 233 CreateTable(otr); 234 InsertRecord(otr, "text"); 235} 236 237IN_PROC_BROWSER_TEST_F(DatabaseTest, OffTheRecordDatabaseNotPersistent) { 238 Shell* otr = CreateOffTheRecordBrowser(); 239 Navigate(otr); 240 ASSERT_FALSE(HasTable(otr)); 241} 242 243// Verify database modifications persist after crashing window. 244IN_PROC_BROWSER_TEST_F(DatabaseTest, ModificationsPersistAfterRendererCrash) { 245 Navigate(shell()); 246 CreateTable(shell()); 247 InsertRecord(shell(), "1"); 248 249 CrashTab(shell()->web_contents()); 250 Navigate(shell()); 251 CompareRecords(shell(), "1"); 252} 253 254// Test to check if database modifications are persistent across windows in 255// off the record window. 256IN_PROC_BROWSER_TEST_F(DatabaseTest, OffTheRecordDBPersistentAcrossWindows) { 257 Shell* otr1 = CreateOffTheRecordBrowser(); 258 Navigate(otr1); 259 CreateTable(otr1); 260 InsertRecord(otr1, "text"); 261 262 Shell* otr2 = CreateOffTheRecordBrowser(); 263 Navigate(otr2); 264 CompareRecords(otr2, "text"); 265} 266 267} // namespace content 268