def test_table_no_exceptions_chromium_db_copy(create_chromium_data): with tempfile.TemporaryDirectory() as tempdir: expected_record = { 'id': 88, 'url': 'https://www.google.com/search?q=chrome+linux+profile+data&oq=chrome+linux+profile+data&aqs=chrome..69i57j33l4.3443j0j7&sourceid=chrome&ie=UTF-8', 'title': 'chrome linux profile data - Google Search', 'visit_count': 1, 'typed_count': 0, 'last_visit_time': 13204503690648295, 'hidden': 0, 'last_visit_readable': '2388-06-07 16:41:30', } chromium_db_path = create_chromium_data table_obj = Table( table='urls', path=chromium_db_path, browser='chrome', filename='History', profile='Profile 1', copies_subpath=tempdir, ) table_obj.make_records_yielder() records = list(table_obj.records_yielder) assert len(records) == 1 assert records[0]['id'] == 88 assert expected_record.keys() == records[0].keys() del table_obj
def non_pytest_test_suite_no_such_table(test_suite): for test_case in test_suite: table_obj = Table(*test_case) try: table_obj.make_records_yielder() except InvalidTableError: print('Passed.')
def test_check_if_empty_db_false(create_chromium_data): not_empty_table = Table( table='urls', path=create_chromium_data, browser=None, filename='anything', profile=None, ) not_empty_table._connect() assert not_empty_table.check_if_db_empty() == False
def test_create_db_copy_invalid_parameter_names(create_mozilla_data): table = Table( table='moz_places', path=create_mozilla_data, browser=None, filename=None, profile=None, copies_subpath='.', ) with pytest.raises(TypeError): table._create_db_copy()
def test_connect_FileNotFoundError(tests_root): invalid_path = str(Path(tests_root, 'invalid0', 'invalid1', 'invalid2')) table = Table( table='some_table', path=invalid_path, browser='mozilla', filename='anything', profile='test', ) excep = table._connect() assert isinstance(excep, FileNotFoundError)
def test_TableAccessError_invalid_table(create_mozilla_data): table_obj = Table( table='invalid_tablename', path=create_mozilla_data, browser='firefox', filename='places.sqlite', profile='test_profile2', copies_subpath=None, ) with pytest.raises(TableAccessError): table_obj.make_records_yielder()
def test_TableAccessError_nondb_mozilla(create_fake_non_db_file): table_obj = Table( table='moz_places', path=create_fake_non_db_file, browser='firefox', filename='places.sqlite', profile='test_profile2', copies_subpath=None, ) with pytest.raises(TableAccessError): table_obj.make_records_yielder()
def test_spaces_in_table_name(create_fake_non_db_file): table_obj = Table( table='nonexistent table', path=create_fake_non_db_file, browser='chrome', filename='History', profile='Profile 1', copies_subpath=None, ) with pytest.raises(ValueError): table_obj.make_records_yielder()
def test_invalid_filepath_error_mozilla_1(create_invalid_filepath): table_obj = Table( table='moz_places', path=create_invalid_filepath, browser='firefox', filename='non_db_dummy_file_for_testing.txt', profile='test_profile2', copies_subpath=None, ) with pytest.raises(sqlite3.OperationalError) as excep: table_obj.make_records_yielder() assert str(excep) == 'unable to open database file'
def test_create_db_copy_invalid_FileNotFoundError(create_invalid_filepath): with tempfile.TemporaryDirectory() as tempdir: table = Table( table='some_table', path=create_invalid_filepath, browser='mozilla', filename='anything', profile='test', copies_subpath=tempdir, ) excep = table._create_db_copy() assert isinstance(excep, FileNotFoundError)
def non_pytest_test_DatabaseLockedError(test_suite): for test_case in test_suite: db_file_path_uri_mode = f'file:{test_case.path}?mode=ro' conn = sqlite3.connect(f'{test_case.path}', isolation_level='EXCLUSIVE') # conn.row_factory = sqlite3.Row' cur = conn.cursor() yield_records = cur.execute(f'SELECT * FROM {test_case.table}') pprint(list(yield_records)) # with sqlite3.connect(f'{test_case.path}') as conn2: # conn table_obj = Table(*test_case) table_obj._connect()
def test_browser_access_single_profile_file_table_with_timestamp(tests_root): profile_rootpath = Path(tests_root, 'firefox_databases') profile_path = Path( profile_rootpath, 't87e6f86.test_profile1', 'places.sqlite', ) browser_name = 'firefox' table_name = 'moz_places' profile_name = 'test_profile1' file_name = 'places.sqlite' moz_places_records_yielder = make_browser_records_yielder( browser=browser_name, profile_root=profile_rootpath, filename=file_name, tablename=table_name, profiles=[profile_name], ) browser_profile1_records = [ record for record in moz_places_records_yielder ] sort_by_id = lambda item: item['url'] browser_profile1_records.sort(key=sort_by_id) profile1_table = Table( table=table_name, path=profile_path, browser=browser_name, filename=file_name, profile=profile_name, ) profile1_table.make_records_yielder() table_profile1_records = list(profile1_table.records_yielder) table_profile1_records.sort(key=sort_by_id) table_profile1_records_urls = [ record['url'] for record in table_profile1_records ] browser_profile1_records_urls = [ record['url'] for record in browser_profile1_records ] assert table_profile1_records_urls == browser_profile1_records_urls assert len(table_profile1_records) == len(browser_profile1_records) assert check_records_unique_with_field(records=table_profile1_records, field='id') assert check_records_unique_with_field(records=browser_profile1_records, field='id') assert sorted(table_profile1_records_urls) == sorted( browser_profile1_records_urls)
def test_make_records_yielder_invalid_FileNotFoundError( create_invalid_filepath): with tempfile.TemporaryDirectory() as tempdir: table = Table( table='some_table', path=create_invalid_filepath, browser='mozilla', filename='anything', profile='test', copies_subpath=tempdir, ) records_yielder, excep = table.make_records_yielder() assert records_yielder is None assert isinstance(excep, FileNotFoundError)
def test_table_no_exceptions_mozilla_timestamp_field(create_mozilla_data): mozilla_db_path = create_mozilla_data table_obj = Table( table='moz_places', path=mozilla_db_path, browser='firefox', filename='places.sqlite', profile='test_profile0', copies_subpath=None, ) table_obj.make_records_yielder() records = list(table_obj.records_yielder) assert len(records) == 3 assert [record['id'] for record in records] == [13, 1, 1] assert any([key.endswith('_readable') for key in records[0].keys()])
def test_table_mozilla_table_no_timestamp_field(create_mozilla_data): mozilla_db_path = Path(create_mozilla_data) table_obj = Table( table='moz_origins', path=mozilla_db_path, browser='firefox', filename='places.sqlite', profile='test_profile1', copies_subpath=None, ) table_obj.make_records_yielder() records = list(table_obj.records_yielder) assert len(records) == 1 assert records[0]['id'] == 1 assert not all([key.endswith('_readable') for key in records[0].keys()])
def test_browser_access_two_profiles_same_file_table(tests_root): profile_rootpath = Path(tests_root, 'firefox_databases') browser_name = 'firefox' profiles = ['test_profile1', 'test_profile2'] file_name = 'places.sqlite' table_name = 'moz_places' moz_places_records_yielder = make_browser_records_yielder( browser=browser_name, profile_root=profile_rootpath, filename=file_name, tablename=table_name, profiles=profiles, ) profile_1_2_records_using_browser = [ record for record in moz_places_records_yielder ] sort_by_url = lambda item: item['url'] profile_1_2_records_using_browser.sort(key=sort_by_url) profile1_table = Table( table='moz_places', path=Path( profile_rootpath, 't87e6f86.test_profile1', 'places.sqlite', ), browser='mozilla', filename='places.sqlite', profile='test_profile1', ) profile1_table.make_records_yielder() profile1_records = list(profile1_table.records_yielder) profile2_table = Table( table='moz_places', path=Path( profile_rootpath, 'z786c76dv78.test_profile2', 'places.sqlite', ), browser='mozilla', filename='places.sqlite', profile='test_profile2', ) profile2_table.make_records_yielder() profile2_records = list(profile2_table.records_yielder) profile_1_2_records_using_tables = [*profile1_records, *profile2_records] profile_1_2_records_using_tables.sort(key=sort_by_url) table_records_urls = [ record['url'] for record in profile_1_2_records_using_tables ] browser_records_urls = [ record['url'] for record in profile_1_2_records_using_browser ] assert table_records_urls == browser_records_urls
def access_table(self, file, tables, non_null_fields=None): """ Accepts name of file containing the tables and list of table names and creates corresponding Table objects. Accessed via the tables attribute. """ error_msgs = [] current_batch = [Table(table, path.joinpath(file), self.browser, file, profile, copies_subpath=self.copies_subpath) for profile, path in self.paths.items() for table in tables ] for table in current_batch: table_yielder, exception_raised = table.make_records_yielder(raise_exceptions=False) # exception is returned here. if exception_raised: error_msgs.append(exception_raised) else: self.tables.append(table) try: self.profiles.add(table.profile) except AttributeError: self.profiles = set() self.profiles.add(table.profile) try: self.error_msgs.extend(error_msgs) except AttributeError: if error_msgs: error_msgs = exceph.exceptions_log_deduplicator(exceptions_log=error_msgs) self._errors_display(error_msgs=error_msgs)
def test_check_if_empty_db_true(create_chromium_data): with tempfile.TemporaryDirectory() as tmpdir: dbname = 'empty.sqlite' dbpath = str(Path(tmpdir, dbname)) conn = sqlite3.connect(dbpath) conn.close() empty_ = Table( table='nonexistent_table', path=dbpath, browser=None, filename=dbname, profile=None, ) empty_._connect() assert empty_.check_if_db_empty() == True empty_._connection.close()
def non_pytest_test_InvalidFileError(test_suite): for test_case in test_suite: table_obj = Table(*test_case) try: table_obj.make_records_yielder() except InvalidFileError as excep: print('Expected exception raised: InvalidFileError', excep, '--', test_case.browser, test_case.profile, test_case.filename, test_case.table) else: print('Expected exception InvalidFileError NOT raised: .', '--', test_case.browser, test_case.profile, test_case.filename, test_case.table) raise Exception finally: print()
def test_browser_access_two_profiles_same_file_table(tests_root): profile_rootpath = Path(tests_root, 'chrome_databases') browser_name = 'chrome' table_name = 'urls' file_name = 'History' urls_records_yielder = make_browser_records_yielder( browser=browser_name, profile_root=profile_rootpath, filename=file_name, tablename=table_name, profiles=['Profile 1', 'Profile 2'], ) profile_1_2_records_using_browser = [ record for record in urls_records_yielder ] sort_by_url = lambda item: item['url'] profile_1_2_records_using_browser.sort(key=sort_by_url) profile1_table = Table( table=table_name, path=Path( profile_rootpath, 'Profile 1', file_name, ), browser=browser_name, filename=file_name, profile='Profile 1', ) profile1_table.make_records_yielder() profile1_records = list(profile1_table.records_yielder) profile2_table = Table( table=table_name, path=Path( profile_rootpath, 'Profile 2', 'History', ), browser=browser_name, filename=file_name, profile='Profile 2', ) profile2_table.make_records_yielder() profile2_records = list(profile2_table.records_yielder) profile_1_2_records_using_tables = [*profile1_records, *profile2_records] profile_1_2_records_using_tables.sort(key=sort_by_url) table_records_urls = [ record['url'] for record in profile_1_2_records_using_tables ] browser_records_urls = [ record['url'] for record in profile_1_2_records_using_browser ] assert table_records_urls == browser_records_urls
def make_browser_records_yielder(browser: Text, profile_root: PathInfo, filename: Text, tablename: Text, profiles: Optional[Iterable[Text]] = None, fieldnames: Optional[Iterable[Text]] = None, copies_subpath: Optional[PathInfo] = None ) -> Generator[Mapping[Text, Text], None, None]: """ Creates a generator of browser database records. :param browser: browser name :param profile_root: path to directory/folder where the browser stores all of its profiles :param profiles: list of profile, default is all profiles :param fieldnames: Optional list of fieldnames for which data is to be retrieved. :param copies_subpath: path where a copy of the database files is created, and read from,instead of the original files. :return: Generator of records """ paths = make_browser_paths(browser, profile_root, profiles) for profile_name, profile_path in paths.items(): filepath = Path(profile_path, filename) profile_name = Path(profile_path).name table_obj = Table(table=tablename, path=filepath, browser=browser, filename=filename, profile=profile_name, copies_subpath=copies_subpath, ) additional_info = {'browser': browser, 'profile': profile_name, 'file': filename, 'table': tablename, } table_obj.make_records_yielder() if fieldnames: for record in table_obj.records_yielder: record = {field_name: field_value for field_name, field_value in record.items() if field_name in fieldnames} record.update(additional_info) yield record else: for record in table_obj.records_yielder: record.update(additional_info) yield record
def test_create_db_copy(create_mozilla_data): with tempfile.TemporaryDirectory() as tempdir: table = Table( table='moz_places', path=create_mozilla_data, browser='mozilla', filename='anything', profile='test', copies_subpath=tempdir, ) filename = Path(create_mozilla_data).name expected_dst = Path(table.copies_subpath, 'AppData', 'Profile Copies', table.browser, table.profile, filename).expanduser() table._create_db_copy() assert table.path == expected_dst assert filecmp.cmp(expected_dst, table.path)
def test_check_if_timestamp_field_needed(field_names): expected_output = {field_names[1]: 'last_visit_readable'} cursor_desc_mimic = [[field, None, None, None] for field in field_names] CursorDescription = namedtuple('CursorDescription', 'description') cursor_mimic = CursorDescription(description=cursor_desc_mimic) actual_output = Table._check_if_timestamp_field_needed(Table, cursor=cursor_mimic) assert expected_output == actual_output
def non_pytest_test_InvalidPathError(test_suite): for test_case in test_suite: table_obj = Table(*test_case) try: table_obj.make_records_yielder() pass except InvalidPathError as excep: print(f'Expected Exception raised', excep, '--', test_case.browser, test_case.profile, test_case.filename, test_case.table) except Exception as excep: raise excep else: print(f'Expected Exception NOT raised', '--', test_case.browser, test_case.profile, test_case.filename, test_case.table) raise Exception('Expected exception not raised.') finally: print()
def make_test_table_obj(self): return Table( table=self.test_data.table, path=self.test_data.path, browser=self.test_data.browser, filename=self.test_data.filename, profile=self.test_data.profile, copies_subpath=self.test_data.copies_subpath, )
def test_browser_access_single_profile_file_table_without_timestamp( tests_root): profile_rootpath = Path(tests_root, 'chrome_databases') profile_path = Path( profile_rootpath, 'Profile 1', 'History', ) browser_name = 'chrome' table_name = 'keyword_search_terms' profile_name = 'Profile 1' file_name = 'History' urls_records_yielder = make_browser_records_yielder( browser=browser_name, profile_root=profile_rootpath, filename=file_name, tablename=table_name, profiles=[profile_name], ) browser_profile1_records = [record for record in urls_records_yielder] sort_by_id = lambda item: item['url_id'] browser_profile1_records.sort(key=sort_by_id) profile1_table = Table( table=table_name, path=profile_path, browser=browser_name, filename=file_name, profile=profile_name, ) profile1_table.make_records_yielder() table_profile1_records = list(profile1_table.records_yielder) table_profile1_records.sort(key=sort_by_id) table_profile1_records_ids = [ record['url_id'] for record in table_profile1_records ] browser_profile1_records_ids = [ record['url_id'] for record in browser_profile1_records ] assert table_profile1_records_ids == browser_profile1_records_ids
def test_InvalidPathError(test_case): table_obj = Table(*test_case) with pytest.raises(OSError) as excep: table_obj.make_records_yielder()
def simply_run(test_suite): for test_case in test_suite: table_obj = Table(*test_case) table_obj.make_records_yielder()
def test_InvalidFileError(test_case): table_obj = Table(*test_case) with pytest.raises(InvalidFileError): table_obj.make_records_yielder()
for test_case in test_suite: table_obj = Table(*test_case) table_obj.make_records_yielder() if __name__ == '__main__': non_pytest_test_InvalidFileError( test_suite=test_cases_exception_InvalidFileError) quit() # simply_run(test_suite=test_cases_exception_InvalidFileError) fx_false_file = Table( table='moz_places', path=Path( project_root, 'tests/data/browser_profiles_for_testing/AppData/Roaming/Mozilla/' 'Firefox/Profiles/udd5sttq.test_profile2/non_db_dummy_file_for_testing.txt' ), browser='firefox', filename='non_db_dummy_file_for_testing.txt', profile='test_profile2', copies_subpath=None, ) # fx_false_file.make_records_yielder() chrome_false_file = Table( table='urls', path=Path( project_root, 'tests/data/browser_profiles_for_testing/AppData/Local/Google/Chrome/User Data/Profile 1/History_false_filename' ), browser='chrome',