def test_update_rec_index_0(caplog): """test method.""" bdb = BukuDb() res = bdb.update_rec(index=0, url='http://example.com') assert not res assert caplog.records[0].getMessage() == 'All URLs cannot be same' assert caplog.records[0].levelname == 'ERROR'
def test_get_default_dbdir(self): dbdir_expected = TEST_TEMP_DBDIR_PATH dbdir_local_expected = os.path.join( os.path.expanduser("~"), ".local", "share", "buku" ) dbdir_relative_expected = os.path.abspath(".") # desktop linux self.assertEqual(dbdir_expected, BukuDb.get_default_dbdir()) # desktop generic os.environ.pop("XDG_DATA_HOME") self.assertEqual(dbdir_local_expected, BukuDb.get_default_dbdir()) # no desktop # -- home is defined differently on various platforms. # -- keep a copy and set it back once done originals = {} for env_var in ["HOME", "HOMEPATH", "HOMEDIR"]: try: originals[env_var] = os.environ.pop(env_var) except KeyError: pass self.assertEqual(dbdir_relative_expected, BukuDb.get_default_dbdir()) for key, value in list(originals.items()): os.environ[key] = value
def test_add_rec_add_invalid_url(caplog, url): """test method.""" bdb = BukuDb() res = bdb.add_rec(url=url) assert res == -1 caplog.records[0].levelname == 'ERROR' caplog.records[0].getMessage() == 'Invalid URL'
def test_get_dbdir_path(self): dbdir_expected = TEST_TEMP_DBDIR_PATH dbdir_local_expected = join(expanduser('~'), '.local', 'share', 'buku') dbdir_relative_expected = join('.', 'buku') # desktop linux self.assertEqual(dbdir_expected, BukuDb.get_dbdir_path()) # desktop generic os.environ.pop('XDG_DATA_HOME') self.assertEqual(dbdir_local_expected, BukuDb.get_dbdir_path()) # no desktop # -- home is defined differently on various platforms. # -- keep a copy and set it back once done originals = {} for env_var in ['HOME', 'HOMEPATH', 'HOMEDIR']: try: originals[env_var] = os.environ.pop(env_var) except KeyError: pass self.assertEqual(dbdir_relative_expected, BukuDb.get_dbdir_path()) for key, value in originals.items(): os.environ[key] = value
def test_add_rec_exec_arg(kwargs, exp_arg): """test func.""" bdb = BukuDb() bdb.cur = mock.Mock() bdb.get_rec_id = mock.Mock(return_value=-1) bdb.add_rec(**kwargs) assert bdb.cur.execute.call_args[0][1] == exp_arg
def test_search_by_tag_query(caplog, tags_to_search, exp_query, exp_arguments): """test that the correct query and argments are constructed""" bdb = BukuDb() bdb.search_by_tag(tags_to_search) exp_log = 'query: "{}", args: {}'.format(exp_query, exp_arguments) assert caplog.records[-1].getMessage() == exp_log assert caplog.records[-1].levelname == 'DEBUG'
def test_update_rec_update_all_bookmark( caplog, tmp_path, setup, read_in_retval, exp_res, record_tuples ): """test method.""" with mock.patch("buku.read_in", return_value=read_in_retval): bdb = BukuDb(tmp_path / "tmp.db") res = bdb.update_rec(index=0, tags_in="tags1") assert (res, caplog.record_tuples) == (exp_res, record_tuples)
def test_update_rec_invalid_tag(caplog, invalid_tag): """test method.""" url = 'http://example.com' bdb = BukuDb() res = bdb.update_rec(index=1, url=url, tags_in=invalid_tag) assert not res assert caplog.records[0].getMessage() == 'Please specify a tag' assert caplog.records[0].levelname == 'ERROR'
def test_update_rec_exec_arg(caplog, kwargs, exp_query, exp_arguments): """test method.""" bdb = BukuDb() res = bdb.update_rec(**kwargs) assert res exp_log = 'query: "{}", args: {}'.format(exp_query, exp_arguments) assert caplog.records[-1].getMessage() == exp_log assert caplog.records[-1].levelname == 'DEBUG'
def setUp(self): os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH # start every test from a clean state if exists(TEST_TEMP_DBFILE_PATH): os.remove(TEST_TEMP_DBFILE_PATH) self.bookmarks = TEST_BOOKMARKS self.bdb = BukuDb()
def test_compactdb(setup): bdb = BukuDb() # adding bookmarks for bookmark in TEST_BOOKMARKS: bdb.add_rec(*bookmark) # manually deleting 2nd index from db, calling compactdb bdb.cur.execute("DELETE FROM bookmarks WHERE id = ?", (2,)) bdb.compactdb(2) # asserting bookmarks have correct indices assert bdb.get_rec_by_id(1) == ( 1, "http://slashdot.org", "SLASHDOT", ",news,old,", "News for old nerds, stuff that doesn't matter", 0, ) assert bdb.get_rec_by_id(2) == ( 2, "http://example.com/", "test", ",es,est,tes,test,", "a case for replace_tag test", 0, ) assert bdb.get_rec_by_id(3) is None
def test_get_bookmark_index(self): bdb = BukuDb() for idx, bookmark in enumerate(self.bookmarks): # adding bookmark from self.bookmarks to database bdb.add_bookmark(*bookmark) # asserting index is in order idx_from_db = bdb.get_bookmark_index(bookmark[0]) self.assertEqual(idx + 1, idx_from_db) # asserting -1 is returned for nonexistent url idx_from_db = bdb.get_bookmark_index("http://nonexistent.url") self.assertEqual(-1, idx_from_db)
def test_close_quit(self): bdb = BukuDb() # quitting with no args try: bdb.close_quit() except SystemExit as err: self.assertEqual(err.args[0], 0) # quitting with custom arg try: bdb.close_quit(1) except SystemExit as err: self.assertEqual(err.args[0], 1)
def test_update_rec_update_all_bookmark(caplog, read_in_retval): """test method.""" caplog.set_level(logging.DEBUG) with mock.patch('buku.read_in', return_value=read_in_retval): bdb = BukuDb() res = bdb.update_rec(index=0, tags_in='tags1') assert res if read_in_retval == 'y' else not res if read_in_retval == 'y': assert caplog.records[0].getMessage() == \ "update_rec query: " \ "\"UPDATE bookmarks SET tags = ?\", args: [',tags1,']" else: assert not caplog.records
def test_add_bookmark(self): bdb = BukuDb() for bookmark in self.bookmarks: # adding bookmark from self.bookmarks to database bdb.add_bookmark(*bookmark) # retrieving bookmark from database index = bdb.get_bookmark_index(bookmark[0]) from_db = bdb.get_bookmark_by_index(index) self.assertIsNotNone(from_db) # comparing data for pair in zip(from_db[1:], bookmark): self.assertEqual(*pair)
def test_list_tags(capsys, setup): bdb = BukuDb() # adding bookmarks bdb.add_rec("http://one.com", "", parse_tags(['cat,ant,bee,1']), "") bdb.add_rec("http://two.com", "", parse_tags(['Cat,Ant,bee,1']), "") bdb.add_rec("http://three.com", "", parse_tags(['Cat,Ant,3,Bee,2']), "") # listing tags, asserting output out, err = capsys.readouterr() prompt(bdb, None, True, subprompt=True) out, err = capsys.readouterr() assert out == " 1. 1 (2)\n 2. 2 (1)\n 3. 3 (1)\n 4. ant (3)\n 5. bee (3)\n 6. cat (3)\n\n" assert err == ''
def test_delete_rec_range_and_big_int(setup, low, high): """test delete rec, range and big integer.""" bdb = BukuDb() index = 0 is_range = True # Fill bookmark for bookmark in TEST_BOOKMARKS: bdb.add_rec(*bookmark) db_len = len(TEST_BOOKMARKS) res = bdb.delete_rec(index=index, low=low, high=high, is_range=is_range) if high > db_len and low > db_len: assert not res return assert res
def test_bookmark_model_view(tmp_path, client, disable_favicon): test_db = tmp_path / 'test.db' bukudb = BukuDb(dbfile=test_db.as_posix()) inst = BookmarkModelView(bukudb) model = Namespace(description='randomdesc', id=1, tags='tags1', title='Example Domain', url='http://example.com') current_app.config['BUKUSERVER_DISABLE_FAVICON'] = disable_favicon img_html = '' if not disable_favicon: img_html = \ '<img src="http://www.google.com/s2/favicons?domain=example.com"/> ' res = inst._list_entry(None, model, 'Entry') exp_res = \ ( '<a href="http://example.com">Example Domain</a><br/>' '<a href="http://example.com">http://example.com</a><br/>' '<a class="btn btn-default" ' 'href="/bookmark/?flt2_url_netloc_match=example.com">netloc:example.com</a>' '<a class="btn btn-default" href="/bookmark/?flt2_tags_contain=tags1">tags1</a>' '<br/>randomdesc') exp_res = ''.join([img_html, exp_res]) assert str(res) == exp_res
def create_app(config_filename=None): """create app.""" app = Flask(__name__) bukudb = BukuDb() app.app_context().push() setattr(flask.g, 'bukudb', bukudb) @app.shell_context_processor def shell_context(): """Shell context definition.""" return {'app': app, 'bukudb': bukudb} # routing app.add_url_rule('/api/tags', 'get_tags', get_tags, methods=['GET']) app.add_url_rule('/api/tags/<tag>', 'update_tag', update_tag, methods=['PUT']) app.add_url_rule('/api/bookmarks', 'bookmarks', bookmarks, methods=['GET', 'POST', 'DELETE']) app.add_url_rule('/api/bookmarks/refresh', 'refresh_bookmarks', refresh_bookmarks, methods=['POST']) app.add_url_rule('/api/bookmarks/<id>', 'bookmark_api', refresh_bookmarks, methods=['GET', 'PUT', 'DELETE']) app.add_url_rule('/api/bookmarks/<id>/refresh', 'refresh_bookmark', refresh_bookmark, methods=['POST']) app.add_url_rule('/api/bookmarks/<id>/tiny', 'get_tiny_url', get_tiny_url, methods=['GET']) app.add_url_rule('/api/bookmarks/<id>/long', 'get_long_url', get_long_url, methods=['GET']) app.add_url_rule( '/api/bookmarks/<starting_id>/<ending_id>', 'bookmark_range_operations', bookmark_range_operations, methods=['GET', 'PUT', 'DELETE']) app.add_url_rule('/api/bookmarks/search', 'search_bookmarks', search_bookmarks, methods=['GET', 'DELETE']) return app
def update_tag(tag): res = None if request.method in ('PUT', 'POST'): new_tags = request.form.getlist('tags') result_flag = getattr(flask.g, 'bukudb', BukuDb()).replace_tag(tag, new_tags) op_text = 'replace tag [{}] with [{}]'.format(tag, ', '.join(new_tags)) if request.method == 'PUT' and result_flag and request.path.startswith( '/api/'): res = jsonify( response.response_template['success']), status.HTTP_200_OK, { 'ContentType': 'application/json' } elif request.method == 'PUT' and request.path.startswith('/api/'): res = jsonify(response.response_template['failure'] ), status.HTTP_400_BAD_REQUEST, { 'ContentType': 'application/json' } elif request.method == 'POST' and result_flag: flash(Markup('Success {}'.format(op_text)), 'success') res = redirect(url_for('get_tags-html')) elif request.method == 'POST': flash(Markup('Failed {}'.format(op_text)), 'danger') res = redirect(url_for('get_tags-html')) else: abort(400, description="Unknown Condition") return res
def bookmark_api(id): res = None try: id = int(id) except ValueError: return jsonify(response.response_template['failure']), status.HTTP_400_BAD_REQUEST, \ {'ContentType': 'application/json'} bukudb = getattr(flask.g, 'bukudb', BukuDb()) bookmark_form = forms.CreateBookmarksForm() is_html_post_request = request.method == 'POST' and not request.path.startswith('/api/') if request.method == 'GET': bookmark = bukudb.get_rec_by_id(id) if bookmark is not None: result = { 'url': bookmark[1], 'title': bookmark[2], 'tags': list([_f for _f in bookmark[3].split(',') if _f]), 'description': bookmark[4] } if request.path.startswith('/api/'): res = jsonify(result) else: bookmark_form.url.data = result['url'] bookmark_form.title.data = result['title'] bookmark_form.tags.data = bookmark[3] bookmark_form.description.data = result['description'] res = render_template( 'bukuserver/bookmark_edit.html', result=result, bookmark_form=bookmark_form, bookmark_id=bookmark[0] ) else: res = jsonify(response.response_template['failure']), status.HTTP_400_BAD_REQUEST, \ {'ContentType': 'application/json'} elif request.method == 'PUT' or is_html_post_request: if request.method == 'PUT': result_flag = bukudb.update_rec( id, request.form['url'], request.form.get('title'), request.form['tags'], request.form['description']) if result_flag and not is_html_post_request: res = jsonify(response.response_template['success']), status.HTTP_200_OK, {'ContentType': 'application/json'} elif not result_flag and not is_html_post_request: res = jsonify(response.response_template['failure']), status.HTTP_400_BAD_REQUEST, {'ContentType': 'application/json'} elif is_html_post_request: result_flag = bukudb.update_rec( id, bookmark_form.url.data, bookmark_form.title.data, bookmark_form.tags.data, bookmark_form.description.data) if result_flag: flash(Markup('Success edit bookmark, id:{}'.format(id)), 'success') else: flash(Markup('Failed edit bookmark, id:{}'.format(id)), 'danger') res = redirect(url_for('bookmarks-html')) else: abort(400, description="Unknown Condition") else: result_flag = bukudb.delete_rec(id) if result_flag: res = jsonify(response.response_template['success']), status.HTTP_200_OK, {'ContentType': 'application/json'} else: res = jsonify(response.response_template['failure']), status.HTTP_400_BAD_REQUEST, {'ContentType': 'application/json'} return res
def test_delete_rec_on_empty_database(setup, index, is_range, low, high): """test delete rec, on empty database.""" bdb = BukuDb() with mock.patch('builtins.input', return_value='y'): res = bdb.delete_rec(index, is_range, low, high) if (is_range and any([low == 0, high == 0])) or (not is_range and index == 0): assert res # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH return if is_range and low > 1 and high > 1: assert not res # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH
def test_update_rec_invalid_tag(caplog, invalid_tag): """test method.""" url = 'http://example.com' bdb = BukuDb() res = bdb.update_rec(index=1, url=url, tags_in=invalid_tag) assert not res try: assert caplog.records[0].getMessage() == 'Please specify a tag' assert caplog.records[0].levelname == 'ERROR' except IndexError as e: if (sys.version_info.major, sys.version_info.minor) == (3, 4): print('caplog records: {}'.format(caplog.records)) for idx, record in enumerate(caplog.records): print('idx:{};{};message:{};levelname:{}'.format( idx, record, record.getMessage(), record.levelname)) else: raise e
def test_delete_bookmark(self): bdb = BukuDb() # adding bookmark and getting index bdb.add_bookmark(*self.bookmarks[0]) index = bdb.get_bookmark_index(self.bookmarks[0][0]) # deleting bookmark bdb.delete_bookmark(index) # asserting it doesn't exist from_db = bdb.get_bookmark_by_index(index) self.assertIsNone(from_db)
def test_refreshdb(self): bdb = BukuDb() bdb.add_bookmark("https://www.google.com/ncr", "?") bdb.refreshdb(1) from_db = bdb.get_bookmark_by_index(1) self.assertEqual(from_db[2], "Google")
def test_search_by_tag_query(caplog, tags_to_search, exp_query, exp_arguments): """test that the correct query and argments are constructed""" bdb = BukuDb() bdb.search_by_tag(tags_to_search) exp_log = 'query: "{}", args: {}'.format(exp_query, exp_arguments) try: assert caplog.records[-1].getMessage() == exp_log assert caplog.records[-1].levelname == 'DEBUG' except IndexError as e: # TODO: fix test if (sys.version_info.major, sys.version_info.minor) in [(3, 4), (3, 5), (3, 6)]: print('caplog records: {}'.format(caplog.records)) for idx, record in enumerate(caplog.records): print('idx:{};{};message:{};levelname:{}'.format( idx, record, record.getMessage(), record.levelname)) else: raise e
def get_tags(): """get tags.""" tags = getattr(flask.g, 'bukudb', BukuDb()).get_tag_all() result = {'tags': tags[0]} if request.path.startswith('/api/'): res = jsonify(result) else: res = render_template('bukuserver/tags.html', result=result) return res
def test_update_rec_exec_arg(caplog, kwargs, exp_query, exp_arguments): """test method.""" bdb = BukuDb() res = bdb.update_rec(**kwargs) assert res exp_log = 'query: "{}", args: {}'.format(exp_query, exp_arguments) try: assert caplog.records[-1].getMessage() == exp_log assert caplog.records[-1].levelname == 'DEBUG' except IndexError as e: # TODO: fix test if (sys.version_info.major, sys.version_info.minor) in [(3, 4), (3, 5), (3, 6)]: print('caplog records: {}'.format(caplog.records)) for idx, record in enumerate(caplog.records): print('idx:{};{};message:{};levelname:{}'.format( idx, record, record.getMessage(), record.levelname)) else: raise e
def test_add_and_retrieve_bookmark(self): URL = 'http://slashdot.org' TITLE = 'SLASHDOT' TAGS = ['old', 'news'] DESC = "News for old nerds, stuff that doesn't matter" # start from clean slate if exists(TEST_TEMP_DBFILE_PATH): os.remove(TEST_TEMP_DBFILE_PATH) bdb = BukuDb() bdb.add_bookmark(URL, tag_manual=parse_tags(TAGS), title_manual=TITLE, desc=DESC) index = bdb.get_bookmark_index(URL) self.assertEqual(1, index)
def test_initdb(self): if exists(TEST_TEMP_DBFILE_PATH): os.remove(TEST_TEMP_DBFILE_PATH) self.assertIs(False, exists(TEST_TEMP_DBFILE_PATH)) conn, curr = BukuDb.initdb() self.assertIsInstance(conn, sqlite3.Connection) self.assertIsInstance(curr, sqlite3.Cursor) self.assertIs(True, exists(TEST_TEMP_DBFILE_PATH)) curr.close() conn.close()
def tag_detail(tag): bukudb = BukuDb() if request.method == 'GET': tags = bukudb.get_tag_all() if tag not in tags[1]: raise exceptions.NotFound() res = dict(name=tag, usage_count=tags[1][tag]) elif request.method == 'PUT': res = None try: new_tags = request.data.get('tags').split(',') except AttributeError as e: raise exceptions.ParseError(detail=str(e)) result_flag = bukudb.replace_tag(tag, new_tags) if result_flag: res = response.response_template['success'], status.HTTP_200_OK else: res = response.response_template['failure'], status.HTTP_400_BAD_REQUEST return res
def test_print_rec_hypothesis(caplog, setup, index, low, high, is_range): """test when index, low or high is less than 0.""" # setup caplog.handler.records.clear() caplog.records.clear() bdb = BukuDb() # clear all record first before testing bdb.delete_rec_all() bdb.add_rec("http://one.com", "", parse_tags(['cat,ant,bee,1']), "") db_len = 1 bdb.print_rec(index=index, low=low, high=high, is_range=is_range) check_print = False err_msg = ['Actual log:'] err_msg.extend( ['{}:{}'.format(x.levelname, x.getMessage()) for x in caplog.records]) if index < 0 or (0 <= index <= db_len and not is_range): check_print = True # negative index/range on is_range elif (is_range and any([low < 0, high < 0])): assert any([x.levelname == "ERROR" for x in caplog.records]), \ '\n'.join(err_msg) assert any([x.getMessage() == "Negative range boundary" for x in caplog.records]), \ '\n'.join(err_msg) elif is_range: check_print = True else: assert any([x.levelname == "ERROR" for x in caplog.records]), \ '\n'.join(err_msg) assert any([x.getMessage().startswith("No matching index") for x in caplog.records]), \ '\n'.join(err_msg) if check_print: assert not any([x.levelname == "ERROR" for x in caplog.records]), \ '\n'.join(err_msg) # teardown bdb.delete_rec(index=1) caplog.handler.records.clear() caplog.records.clear()
def refresh_bookmarks(): res = None if request.method == 'POST': print(request.form['index']) print(request.form['threads']) result_flag = getattr(flask.g, 'bukudb', BukuDb()).refreshdb(request.form['index'], request.form['threads']) if result_flag: res = jsonify(response.response_template['success']), status.HTTP_200_OK, {'ContentType': 'application/json'} else: res = jsonify(response.response_template['failure']), status.HTTP_400_BAD_REQUEST, {'ContentType': 'application/json'} return res
def create_app(config_filename=None): """create app.""" app = FlaskAPI(__name__) per_page = int(os.getenv('BUKUSERVER_PER_PAGE', str(views.DEFAULT_PER_PAGE))) per_page = per_page if per_page > 0 else views.DEFAULT_PER_PAGE app.config['BUKUSERVER_PER_PAGE'] = per_page url_render_mode = os.getenv('BUKUSERVER_URL_RENDER_MODE', views.DEFAULT_URL_RENDER_MODE) if url_render_mode not in ('full', 'netloc'): url_render_mode = views.DEFAULT_URL_RENDER_MODE app.config['BUKUSERVER_URL_RENDER_MODE'] = url_render_mode app.config['SECRET_KEY'] = os.getenv('BUKUSERVER_SECRET_KEY') or os.urandom(24) app.config['BUKUSERVER_DB_FILE'] = os.getenv('BUKUSERVER_DB_FILE') bukudb = BukuDb(dbfile=app.config['BUKUSERVER_DB_FILE']) app.app_context().push() setattr(flask.g, 'bukudb', bukudb) @app.shell_context_processor def shell_context(): """Shell context definition.""" return {'app': app, 'bukudb': bukudb} app.jinja_env.filters['netloc'] = lambda x: urlparse(x).netloc # pylint: disable=no-member Bootstrap(app) admin = Admin( app, name='Buku Server', template_mode='bootstrap3', index_view=views.CustomAdminIndexView( template='bukuserver/home.html', url='/' ) ) # routing # api app.add_url_rule('/api/tags', 'get_tags', tag_list, methods=['GET']) app.add_url_rule('/api/tags/<tag>', 'update_tag', tag_detail, methods=['GET', 'PUT']) app.add_url_rule('/api/network_handle', 'networkk_handle', network_handle_detail, methods=['POST']) app.add_url_rule('/api/bookmarks', 'bookmarks', bookmarks, methods=['GET', 'POST', 'DELETE']) app.add_url_rule('/api/bookmarks/refresh', 'refresh_bookmarks', refresh_bookmarks, methods=['POST']) app.add_url_rule('/api/bookmarks/<id>', 'bookmark_api', bookmark_api, methods=['GET', 'PUT', 'DELETE']) app.add_url_rule('/api/bookmarks/<id>/refresh', 'refresh_bookmark', refresh_bookmark, methods=['POST']) app.add_url_rule('/api/bookmarks/<id>/tiny', 'get_tiny_url', get_tiny_url, methods=['GET']) app.add_url_rule('/api/bookmarks/<id>/long', 'get_long_url', get_long_url, methods=['GET']) app.add_url_rule( '/api/bookmarks/<starting_id>/<ending_id>', 'bookmark_range_operations', bookmark_range_operations, methods=['GET', 'PUT', 'DELETE']) app.add_url_rule('/api/bookmarks/search', 'search_bookmarks', search_bookmarks, methods=['GET', 'DELETE']) # non api admin.add_view(views.BookmarkModelView( bukudb, 'Bookmarks', page_size=per_page, url_render_mode=url_render_mode)) admin.add_view(views.TagModelView( bukudb, 'Tags', page_size=per_page)) admin.add_view(views.StatisticView( bukudb, 'Statistic', endpoint='statistic')) return app
def test_bookmark_model_view(tmp_path, client, disable_favicon): logging.debug('client: %s', client) test_db = tmp_path / 'test.db' bukudb = BukuDb(dbfile=test_db.as_posix()) inst = BookmarkModelView(bukudb) model = Namespace(description='randomdesc', id=1, tags='tags1', title='Example Domain', url='http://example.com') current_app.config['BUKUSERVER_DISABLE_FAVICON'] = disable_favicon assert inst._list_entry(None, model, 'Entry')
def test_print_rec_hypothesis(caplog, setup, index, low, high, is_range): """test when index, low or high is less than 0.""" # setup caplog.handler.records.clear() caplog.records.clear() bdb = BukuDb() # clear all record first before testing bdb.delete_rec_all() bdb.add_rec("http://one.com", "", parse_tags(['cat,ant,bee,1']), "") db_len = 1 bdb.print_rec(index=index, low=low, high=high, is_range=is_range) check_print = False err_msg = ['Actual log:'] err_msg.extend(['{}:{}'.format(x.levelname, x.getMessage()) for x in caplog.records]) if index < 0 or (0 <= index <= db_len and not is_range): check_print = True # negative index/range on is_range elif (is_range and any([low < 0, high < 0])): assert any([x.levelname == "ERROR" for x in caplog.records]), \ '\n'.join(err_msg) assert any([x.getMessage() == "Negative range boundary" for x in caplog.records]), \ '\n'.join(err_msg) elif is_range: check_print = True else: assert any([x.levelname == "ERROR" for x in caplog.records]), \ '\n'.join(err_msg) assert any([x.getMessage().startswith("No matching index") for x in caplog.records]), \ '\n'.join(err_msg) if check_print: assert not any([x.levelname == "ERROR" for x in caplog.records]), \ '\n'.join(err_msg) # teardown bdb.delete_rec(index=1) caplog.handler.records.clear() caplog.records.clear()
def test_list_tags(capsys, setup): bdb = BukuDb() # adding bookmarks bdb.add_bookmark("http://one.com", "", parse_tags(['cat,ant,bee,1']), "") bdb.add_bookmark("http://two.com", "", parse_tags(['Cat,Ant,bee,1']), "") bdb.add_bookmark("http://three.com", "", parse_tags(['Cat,Ant,3,Bee,2']), "") # listing tags, asserting output out, err = capsys.readouterr() bdb.list_tags() out, err = capsys.readouterr() assert out == " 1. 1\n 2. 2\n 3. 3\n 4. Ant\n 5. ant\n 6. bee\n 7. Bee\n 8. Cat\n 9. cat\n" assert err == ''
def test_delete_rec_on_non_interger(index, low, high, is_range): """test delete rec on non integer arg.""" bdb = BukuDb() for bookmark in TEST_BOOKMARKS: bdb.add_rec(*bookmark) db_len = len(TEST_BOOKMARKS) if is_range and not (isinstance(low, int) and isinstance(high, int)): with pytest.raises(TypeError): bdb.delete_rec(index=index, low=low, high=high, is_range=is_range) return elif not is_range and not isinstance(index, int): res = bdb.delete_rec(index=index, low=low, high=high, is_range=is_range) assert not res assert len(bdb.get_rec_all()) == db_len else: assert bdb.delete_rec(index=index, low=low, high=high, is_range=is_range)
def test_compactdb(setup): bdb = BukuDb() # adding bookmarks for bookmark in TEST_BOOKMARKS: bdb.add_bookmark(*bookmark) # manually deleting 2nd index from db, calling compactdb bdb.cur.execute('DELETE FROM bookmarks WHERE id = ?', (2,)) bdb.compactdb(2) # asserting bookmarks have correct indices assert bdb.get_bookmark_by_index(1) == (1, 'http://slashdot.org', 'SLASHDOT', ',news,old,', "News for old nerds, stuff that doesn't matter") assert bdb.get_bookmark_by_index(2) == (2, 'https://test.com:8080', 'test', ',es,est,tes,test,', 'a case for replace_tag test') assert bdb.get_bookmark_by_index(3) is None
def test_update_bookmark(self): bdb = BukuDb() old_values = self.bookmarks[0] new_values = self.bookmarks[1] # adding bookmark and getting index bdb.add_bookmark(*old_values) index = bdb.get_bookmark_index(old_values[0]) # updating with new values bdb.update_bookmark(index, *new_values) # retrieving bookmark from database from_db = bdb.get_bookmark_by_index(index) self.assertIsNotNone(from_db) # checking if values are updated for pair in zip(from_db[1:], new_values): self.assertEqual(*pair)
def test_print_bookmark(capsys, caplog, setup): bdb = BukuDb() out, err = capsys.readouterr() # calling with nonexistent index bdb.print_bookmark(1) out, err = capsys.readouterr() for record in caplog.records: assert record.levelname == "ERROR" assert record.getMessage() == "No matching index" assert (out, err) == ('', '') # adding bookmarks bdb.add_bookmark("http://full-bookmark.com", "full", parse_tags(['full,bookmark']), "full bookmark") bdb.add_bookmark("http://blank-title.com", "", parse_tags(['blank,title']), "blank title") bdb.add_bookmark("http://empty-tags.com", "empty tags", parse_tags(['']), "empty tags") bdb.add_bookmark("http://all-empty.com", "", parse_tags(['']), "all empty") out, err = capsys.readouterr() # printing first bookmark bdb.print_bookmark(1) out, err = capsys.readouterr() assert out == "\x1b[1m\x1b[93m1. \x1b[0m\x1b[92mhttp://full-bookmark.com\x1b[0m\n \x1b[91m>\x1b[0m full\n \x1b[91m+\x1b[0m full bookmark\n \x1b[91m#\x1b[0m bookmark,full\n\n" assert err == '' # printing all bookmarks bdb.print_bookmark(0) out, err = capsys.readouterr() assert out == "\x1b[1m\x1b[93m1. \x1b[0m\x1b[92mhttp://full-bookmark.com\x1b[0m\n \x1b[91m>\x1b[0m full\n \x1b[91m+\x1b[0m full bookmark\n \x1b[91m#\x1b[0m bookmark,full\n\n\x1b[1m\x1b[93m2. \x1b[0m\x1b[92mhttp://blank-title.com\x1b[0m\n \x1b[91m+\x1b[0m blank title\n \x1b[91m#\x1b[0m blank,title\n\n\x1b[1m\x1b[93m3. \x1b[0m\x1b[92mhttp://empty-tags.com\x1b[0m\n \x1b[91m>\x1b[0m empty tags\n \x1b[91m+\x1b[0m empty tags\n\n\x1b[1m\x1b[93m4. \x1b[0m\x1b[92mhttp://all-empty.com\x1b[0m\n \x1b[91m+\x1b[0m all empty\n\n" assert err == '' # printing all bookmarks with empty fields bdb.print_bookmark(0, empty=True) out, err = capsys.readouterr() assert out == "\x1b[1m3 records found\x1b[21m\n\n\x1b[1m\x1b[93m2. \x1b[0m\x1b[92mhttp://blank-title.com\x1b[0m\n \x1b[91m+\x1b[0m blank title\n \x1b[91m#\x1b[0m blank,title\n\n\x1b[1m\x1b[93m3. \x1b[0m\x1b[92mhttp://empty-tags.com\x1b[0m\n \x1b[91m>\x1b[0m empty tags\n \x1b[91m+\x1b[0m empty tags\n\n\x1b[1m\x1b[93m4. \x1b[0m\x1b[92mhttp://all-empty.com\x1b[0m\n \x1b[91m+\x1b[0m all empty\n\n" assert err == ''
class TestBukuDb(unittest.TestCase): def setUp(self): os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH # start every test from a clean state if exists(TEST_TEMP_DBFILE_PATH): os.remove(TEST_TEMP_DBFILE_PATH) self.bookmarks = TEST_BOOKMARKS self.bdb = BukuDb() def tearDown(self): os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH # @unittest.skip('skipping') @pytest.mark.non_tox def test_get_default_dbdir(self): dbdir_expected = TEST_TEMP_DBDIR_PATH dbdir_local_expected = os.path.join(os.path.expanduser('~'), '.local', 'share', 'buku') dbdir_relative_expected = os.path.abspath('.') # desktop linux self.assertEqual(dbdir_expected, BukuDb.get_default_dbdir()) # desktop generic os.environ.pop('XDG_DATA_HOME') self.assertEqual(dbdir_local_expected, BukuDb.get_default_dbdir()) # no desktop # -- home is defined differently on various platforms. # -- keep a copy and set it back once done originals = {} for env_var in ['HOME', 'HOMEPATH', 'HOMEDIR']: try: originals[env_var] = os.environ.pop(env_var) except KeyError: pass self.assertEqual(dbdir_relative_expected, BukuDb.get_default_dbdir()) for key, value in list(originals.items()): os.environ[key] = value # # not sure how to test this in nondestructive manner # def test_move_legacy_dbfile(self): # self.fail() # @unittest.skip('skipping') def test_initdb(self): if exists(TEST_TEMP_DBFILE_PATH): os.remove(TEST_TEMP_DBFILE_PATH) self.assertIs(False, exists(TEST_TEMP_DBFILE_PATH)) conn, curr = BukuDb.initdb() self.assertIsInstance(conn, sqlite3.Connection) self.assertIsInstance(curr, sqlite3.Cursor) self.assertIs(True, exists(TEST_TEMP_DBFILE_PATH)) curr.close() conn.close() # @unittest.skip('skipping') def test_get_rec_by_id(self): for bookmark in self.bookmarks: # adding bookmark from self.bookmarks self.bdb.add_rec(*bookmark) # the expected bookmark expected = (1, 'http://slashdot.org', 'SLASHDOT', ',news,old,', "News for old nerds, stuff that doesn't matter", 0) bookmark_from_db = self.bdb.get_rec_by_id(1) # asserting bookmark matches expected self.assertEqual(expected, bookmark_from_db) # asserting None returned if index out of range self.assertIsNone(self.bdb.get_rec_by_id(len(self.bookmarks[0]) + 1)) # @unittest.skip('skipping') def test_get_rec_id(self): for idx, bookmark in enumerate(self.bookmarks): # adding bookmark from self.bookmarks to database self.bdb.add_rec(*bookmark) # asserting index is in order idx_from_db = self.bdb.get_rec_id(bookmark[0]) self.assertEqual(idx + 1, idx_from_db) # asserting -1 is returned for nonexistent url idx_from_db = self.bdb.get_rec_id("http://nonexistent.url") self.assertEqual(-1, idx_from_db) # @unittest.skip('skipping') def test_add_rec(self): for bookmark in self.bookmarks: # adding bookmark from self.bookmarks to database self.bdb.add_rec(*bookmark) # retrieving bookmark from database index = self.bdb.get_rec_id(bookmark[0]) from_db = self.bdb.get_rec_by_id(index) self.assertIsNotNone(from_db) # comparing data for pair in zip(from_db[1:], bookmark): self.assertEqual(*pair) # TODO: tags should be passed to the api as a sequence... # @unittest.skip('skipping') def test_update_rec(self): old_values = self.bookmarks[0] new_values = self.bookmarks[1] # adding bookmark and getting index self.bdb.add_rec(*old_values) index = self.bdb.get_rec_id(old_values[0]) # updating with new values self.bdb.update_rec(index, *new_values) # retrieving bookmark from database from_db = self.bdb.get_rec_by_id(index) self.assertIsNotNone(from_db) # checking if values are updated for pair in zip(from_db[1:], new_values): self.assertEqual(*pair) # @unittest.skip('skipping') def test_append_tag_at_index(self): for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) # tags to add old_tags = self.bdb.get_rec_by_id(1)[3] new_tags = ",foo,bar,baz" self.bdb.append_tag_at_index(1, new_tags) # updated list of tags from_db = self.bdb.get_rec_by_id(1)[3] # checking if new tags were added to the bookmark self.assertTrue(split_and_test_membership(new_tags, from_db)) # checking if old tags still exist self.assertTrue(split_and_test_membership(old_tags, from_db)) # @unittest.skip('skipping') def test_append_tag_at_all_indices(self): for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) # tags to add new_tags = ",foo,bar,baz" # record of original tags for each bookmark old_tagsets = {i: self.bdb.get_rec_by_id(i)[3] for i in inclusive_range(1, len(self.bookmarks))} with mock.patch('builtins.input', return_value='y'): self.bdb.append_tag_at_index(0, new_tags) # updated tags for each bookmark from_db = [(i, self.bdb.get_rec_by_id(i)[3]) for i in inclusive_range(1, len(self.bookmarks))] for index, tagset in from_db: # checking if new tags added to bookmark self.assertTrue(split_and_test_membership(new_tags, tagset)) # checking if old tags still exist for boomark self.assertTrue(split_and_test_membership(old_tagsets[index], tagset)) # @unittest.skip('skipping') def test_delete_tag_at_index(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) get_tags_at_idx = lambda i: self.bdb.get_rec_by_id(i)[3] # list of two-tuples, each containg bookmark index and corresponding tags tags_by_index = [(i, get_tags_at_idx(i)) for i in inclusive_range(1, len(self.bookmarks))] for i, tags in tags_by_index: # get the first tag from the bookmark to_delete = re.match(',.*?,', tags).group(0) self.bdb.delete_tag_at_index(i, to_delete) # get updated tags from db from_db = get_tags_at_idx(i) self.assertNotIn(to_delete, from_db) # @unittest.skip('skipping') @pytest.mark.slowtest def test_refreshdb(self): self.bdb.add_rec("https://www.google.com/ncr", "?") self.bdb.refreshdb(1, 1) from_db = self.bdb.get_rec_by_id(1) self.assertEqual(from_db[2], "Google") # @unittest.skip('skipping') def test_searchdb(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) get_first_tag = lambda x: ''.join(x[2].split(',')[:2]) for i, bookmark in enumerate(self.bookmarks): tag_search = get_first_tag(bookmark) # search by the domain name for url url_search = re.match('https?://(.*)?\..*', bookmark[0]).group(1) title_search = bookmark[1] # Expect a five-tuple containing all bookmark data # db index, URL, title, tags, description expected = [(i + 1,) + tuple(bookmark)] # search db by tag, url (domain name), and title for keyword in (tag_search, url_search, title_search): with mock.patch('buku.prompt'): # search by keyword results = self.bdb.searchdb([keyword]) self.assertEqual(results, expected) # @unittest.skip('skipping') def test_search_by_tag(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) with mock.patch('buku.prompt'): get_first_tag = lambda x: ''.join(x[2].split(',')[:2]) for i in range(len(self.bookmarks)): # search for bookmark with a tag that is known to exist results = self.bdb.search_by_tag(get_first_tag(self.bookmarks[i])) # Expect a five-tuple containing all bookmark data # db index, URL, title, tags, description expected = [(i + 1,) + tuple(self.bookmarks[i])] self.assertEqual(results, expected) def test_search_by_multiple_tags_search_any(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) new_bookmark = ['https://newbookmark.com', 'New Bookmark', parse_tags(['test,old,new']), 'additional bookmark to test multiple tag search'] self.bdb.add_rec(*new_bookmark) with mock.patch('buku.prompt'): # search for bookmarks matching ANY of the supplied tags results = self.bdb.search_by_tag('test, old') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (1, 'http://slashdot.org', 'SLASHDOT', parse_tags([',news,old,']), "News for old nerds, stuff that doesn't matter"), (3, 'https://test.com:8080', 'test', parse_tags([',test,tes,est,es,']), "a case for replace_tag test"), (4, 'https://newbookmark.com', 'New Bookmark', parse_tags([',test,old,new,']), 'additional bookmark to test multiple tag search') ] self.assertEqual(results, expected) def test_search_by_multiple_tags_search_all(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) new_bookmark = ['https://newbookmark.com', 'New Bookmark', parse_tags(['test,old,new']), 'additional bookmark to test multiple tag search'] self.bdb.add_rec(*new_bookmark) with mock.patch('buku.prompt'): # search for bookmarks matching ALL of the supplied tags results = self.bdb.search_by_tag('test + old') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (4, 'https://newbookmark.com', 'New Bookmark', parse_tags([',test,old,new,']), 'additional bookmark to test multiple tag search') ] self.assertEqual(results, expected) def test_search_by_tags_enforces_space_seprations_search_all(self): bookmark1 = ['https://bookmark1.com', 'Bookmark One', parse_tags(['tag, two,tag+two']), "test case for bookmark with '+' in tag"] bookmark2 = ['https://bookmark2.com', 'Bookmark Two', parse_tags(['tag,two, tag-two']), "test case for bookmark with hyphenated tag"] self.bdb.add_rec(*bookmark1) self.bdb.add_rec(*bookmark2) with mock.patch('buku.prompt'): # check that space separation for ' + ' operator is enforced results = self.bdb.search_by_tag('tag+two') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (1, 'https://bookmark1.com', 'Bookmark One', parse_tags([',tag,two,tag+two,']), "test case for bookmark with '+' in tag") ] self.assertEqual(results, expected) results = self.bdb.search_by_tag('tag + two') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (1, 'https://bookmark1.com', 'Bookmark One', parse_tags([',tag,two,tag+two,']), "test case for bookmark with '+' in tag"), (2, 'https://bookmark2.com', 'Bookmark Two', parse_tags([',tag,two,tag-two,']), "test case for bookmark with hyphenated tag"), ] self.assertEqual(results, expected) def test_search_by_tags_exclusion(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) new_bookmark = ['https://newbookmark.com', 'New Bookmark', parse_tags(['test,old,new']), 'additional bookmark to test multiple tag search'] self.bdb.add_rec(*new_bookmark) with mock.patch('buku.prompt'): # search for bookmarks matching ANY of the supplied tags # while excluding bookmarks from results that match a given tag results = self.bdb.search_by_tag('test, old - est') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (1, 'http://slashdot.org', 'SLASHDOT', parse_tags([',news,old,']), "News for old nerds, stuff that doesn't matter"), (4, 'https://newbookmark.com', 'New Bookmark', parse_tags([',test,old,new,']), 'additional bookmark to test multiple tag search') ] self.assertEqual(results, expected) def test_search_by_tags_enforces_space_seprations_exclusion(self): bookmark1 = ['https://bookmark1.com', 'Bookmark One', parse_tags(['tag, two,tag+two']), "test case for bookmark with '+' in tag"] bookmark2 = ['https://bookmark2.com', 'Bookmark Two', parse_tags(['tag,two, tag-two']), "test case for bookmark with hyphenated tag"] bookmark3 = ['https://bookmark3.com', 'Bookmark Three', parse_tags(['tag, tag three']), "second test case for bookmark with hyphenated tag"] self.bdb.add_rec(*bookmark1) self.bdb.add_rec(*bookmark2) self.bdb.add_rec(*bookmark3) with mock.patch('buku.prompt'): # check that space separation for ' - ' operator is enforced results = self.bdb.search_by_tag('tag-two') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (2, 'https://bookmark2.com', 'Bookmark Two', parse_tags([',tag,two,tag-two,']), "test case for bookmark with hyphenated tag"), ] self.assertEqual(results, expected) results = self.bdb.search_by_tag('tag - two') # Expect a list of five-element tuples containing all bookmark data # db index, URL, title, tags, description expected = [ (3, 'https://bookmark3.com', 'Bookmark Three', parse_tags([',tag,tag three,']), "second test case for bookmark with hyphenated tag"), ] self.assertEqual(results, expected) # @unittest.skip('skipping') def test_search_and_open_in_broswer_by_range(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) # simulate user input, select range of indices 1-3 index_range = '1-%s' % len(self.bookmarks) with mock.patch('builtins.input', side_effect=[index_range]): with mock.patch('buku.browse') as mock_browse: try: # search the db with keywords from each bookmark # searching using the first tag from bookmarks get_first_tag = lambda x: x[2].split(',')[1] results = self.bdb.searchdb([get_first_tag(bm) for bm in self.bookmarks]) prompt(self.bdb, results) except StopIteration: # catch exception thrown by reaching the end of the side effect iterable pass # collect arguments passed to browse arg_list = [args[0] for args, _ in mock_browse.call_args_list] # expect a list of one-tuples that are bookmark URLs expected = [x[0] for x in self.bookmarks] # checking if browse called with expected arguments self.assertEqual(arg_list, expected) # @unittest.skip('skipping') def test_search_and_open_all_in_browser(self): # adding bookmarks for bookmark in self.bookmarks: self.bdb.add_rec(*bookmark) # simulate user input, select 'a' to open all bookmarks in results with mock.patch('builtins.input', side_effect=['a']): with mock.patch('buku.browse') as mock_browse: try: # search the db with keywords from each bookmark # searching using the first tag from bookmarks get_first_tag = lambda x: x[2].split(',')[1] results = self.bdb.searchdb([get_first_tag(bm) for bm in self.bookmarks[:2]]) prompt(self.bdb, results) except StopIteration: # catch exception thrown by reaching the end of the side effect iterable pass # collect arguments passed to browse arg_list = [args[0] for args, _ in mock_browse.call_args_list] # expect a list of one-tuples that are bookmark URLs expected = [x[0] for x in self.bookmarks][:2] # checking if browse called with expected arguments self.assertEqual(arg_list, expected) # @unittest.skip('skipping') def test_delete_rec(self): # adding bookmark and getting index self.bdb.add_rec(*self.bookmarks[0]) index = self.bdb.get_rec_id(self.bookmarks[0][0]) # deleting bookmark self.bdb.delete_rec(index) # asserting it doesn't exist from_db = self.bdb.get_rec_by_id(index) self.assertIsNone(from_db) # @unittest.skip('skipping') def test_delete_rec_yes(self): # checking that "y" response causes delete_rec to return True with mock.patch('builtins.input', return_value='y'): self.assertTrue(self.bdb.delete_rec(0)) # @unittest.skip('skipping') def test_delete_rec_no(self): # checking that non-"y" response causes delete_rec to return None with mock.patch('builtins.input', return_value='n'): self.assertFalse(self.bdb.delete_rec(0)) # @unittest.skip('skipping') def test_cleardb(self): # adding bookmarks self.bdb.add_rec(*self.bookmarks[0]) # deleting all bookmarks with mock.patch('builtins.input', return_value='y'): self.bdb.cleardb() # assert table has been dropped with self.assertRaises(sqlite3.OperationalError) as ctx_man: self.bdb.get_rec_by_id(0) err_msg = str(ctx_man.exception) self.assertEqual(err_msg, 'no such table: bookmarks') # @unittest.skip('skipping') def test_replace_tag(self): indices = [] for bookmark in self.bookmarks: # adding bookmark, getting index self.bdb.add_rec(*bookmark) index = self.bdb.get_rec_id(bookmark[0]) indices += [index] # replacing tags with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("news", ["__01"]) with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("zażółć", ["__02,__03"]) # replacing tag which is also a substring of other tag with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("es", ["__04"]) # removing tags with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("gęślą") with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("old") # removing non-existent tag with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("_") # removing nonexistent tag which is also a substring of other tag with mock.patch('builtins.input', return_value='y'): self.bdb.replace_tag("e") for url, title, _, _ in self.bookmarks: # retrieving from db index = self.bdb.get_rec_id(url) from_db = self.bdb.get_rec_by_id(index) # asserting tags were replaced if title == "SLASHDOT": self.assertEqual(from_db[3], parse_tags(["__01"])) elif title == "ZAŻÓŁĆ": self.assertEqual(from_db[3], parse_tags(["__02,__03,jaźń"])) elif title == "test": self.assertEqual(from_db[3], parse_tags(["test,tes,est,__04"])) # def test_browse_by_index(self): # self.fail() # @unittest.skip('skipping') def test_close_quit(self): # quitting with no args try: self.bdb.close_quit() except SystemExit as err: self.assertEqual(err.args[0], 0) # quitting with custom arg try: self.bdb.close_quit(1) except SystemExit as err: self.assertEqual(err.args[0], 1)
def test_replace_tag(self): bdb = BukuDb() indices = [] for bookmark in self.bookmarks: # adding bookmark, getting index bdb.add_bookmark(*bookmark) index = bdb.get_bookmark_index(bookmark[0]) indices += [index] # replacing tags bdb.replace_tag("news", ["__01"]) bdb.replace_tag("zażółć", ["__02,__03"]) # replacing tag which is also a substring of other tag bdb.replace_tag("es", ["__04"]) # removing tags bdb.replace_tag("gęślą") bdb.replace_tag("old") # removing nonexistent tag bdb.replace_tag("_") # removing nonexistent tag which is also a substring of other tag bdb.replace_tag("e") for url, title, _, _ in self.bookmarks: # retrieving from db index = bdb.get_bookmark_index(url) from_db = bdb.get_bookmark_by_index(index) # asserting tags were replaced if title == "SLASHDOT": self.assertEqual(from_db[3], parse_tags(["__01"])) elif title == "ZAŻÓŁĆ": self.assertEqual(from_db[3], parse_tags(["__02,__03,jaźń"])) elif title == "test": self.assertEqual(from_db[3], parse_tags(["test,tes,est,__04"]))
def test_delete_rec_range_and_delay_commit(setup, low, high, delay_commit, input_retval): """test delete rec, range and delay commit.""" bdb = BukuDb() bdb_dc = BukuDb() # instance for delay_commit check. index = 0 is_range = True # Fill bookmark for bookmark in TEST_BOOKMARKS: bdb.add_rec(*bookmark) db_len = len(TEST_BOOKMARKS) # use normalized high and low variable n_low, n_high = normalize_range(db_len=db_len, low=low, high=high) exp_res = True if n_high > db_len and n_low <= db_len: exp_db_len = db_len - (db_len + 1 - n_low) elif n_high == n_low and n_low > db_len: exp_db_len = db_len exp_res = False elif n_high == n_low and n_low <= db_len: exp_db_len = db_len - 1 else: exp_db_len = db_len - (n_high + 1 - n_low) with mock.patch('builtins.input', return_value=input_retval): res = bdb.delete_rec( index=index, low=low, high=high, is_range=is_range, delay_commit=delay_commit) if n_low < 0: assert not res assert len(bdb_dc.get_rec_all()) == db_len # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH return elif (low == 0 or high == 0) and input_retval != 'y': assert not res assert len(bdb_dc.get_rec_all()) == db_len # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH return elif (low == 0 or high == 0) and input_retval == 'y': assert res == exp_res with pytest.raises(sqlite3.OperationalError): bdb.get_rec_all() # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH return elif n_low > db_len and n_low > 0: assert not res assert len(bdb_dc.get_rec_all()) == db_len # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH return assert res == exp_res assert len(bdb.get_rec_all()) == exp_db_len if delay_commit: assert len(bdb_dc.get_rec_all()) == db_len else: assert len(bdb_dc.get_rec_all()) == exp_db_len # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH
def test_delete_rec_index_and_delay_commit(index, delay_commit, input_retval): """test delete rec, index and delay commit.""" bdb = BukuDb() bdb_dc = BukuDb() # instance for delay_commit check. # Fill bookmark for bookmark in TEST_BOOKMARKS: bdb.add_rec(*bookmark) db_len = len(TEST_BOOKMARKS) n_index = index if index.bit_length() > 63: with pytest.raises(OverflowError): bdb.delete_rec(index=index, delay_commit=delay_commit) return with mock.patch('builtins.input', return_value=input_retval): res = bdb.delete_rec(index=index, delay_commit=delay_commit) if n_index < 0: assert not res elif n_index > db_len: assert not res assert len(bdb.get_rec_all()) == db_len elif index == 0 and input_retval != 'y': assert not res assert len(bdb.get_rec_all()) == db_len else: assert res assert len(bdb.get_rec_all()) == db_len - 1 if delay_commit: assert len(bdb_dc.get_rec_all()) == db_len else: assert len(bdb_dc.get_rec_all()) == db_len - 1 # teardown os.environ['XDG_DATA_HOME'] = TEST_TEMP_DIR_PATH
def index(self): bukudb = BukuDb() global STATISTIC_DATA statistic_data = STATISTIC_DATA if not statistic_data or request.method == 'POST': all_bookmarks = bukudb.get_rec_all() netloc = [urlparse(x[1]).netloc for x in all_bookmarks] tag_set = [x[3] for x in all_bookmarks] tag_items = [] for tags in tag_set: tag_items.extend([x.strip() for x in tags.split(',') if x.strip()]) tag_counter = Counter(tag_items) title_items = [x[2] for x in all_bookmarks] title_counter = Counter(title_items) statistic_datetime = arrow.now() STATISTIC_DATA = { 'datetime': statistic_datetime, 'netloc': netloc, 'tag_counter': tag_counter, 'title_counter': title_counter, } else: netloc = statistic_data['netloc'] statistic_datetime = statistic_data['datetime'] tag_counter = statistic_data['tag_counter'] title_counter = statistic_data['title_counter'] netloc_counter = Counter(netloc) unique_netloc_len = len(set(netloc)) colors = [ "#F7464A", "#46BFBD", "#FDB45C", "#FEDCBA", "#ABCDEF", "#DDDDDD", "#ABCABC", "#4169E1", "#C71585", "#FF4500", "#FEDCBA", "#46BFBD"] show_netloc_table = False if unique_netloc_len > len(colors): max_netloc_item = len(colors) netloc_colors = colors show_netloc_table = True else: netloc_colors = colors[:unique_netloc_len] max_netloc_item = unique_netloc_len most_common_netlocs = netloc_counter.most_common(max_netloc_item) most_common_netlocs = [ [val[0], val[1], netloc_colors[idx]] for idx, val in enumerate(most_common_netlocs)] unique_tag_len = len(tag_counter) show_tag_rank_table = False if unique_tag_len > len(colors): max_tag_item = len(colors) tag_colors = colors show_tag_rank_table = True else: tag_colors = colors[:unique_tag_len] max_tag_item = unique_tag_len most_common_tags = tag_counter.most_common(max_tag_item) most_common_tags = [ [val[0], val[1], tag_colors[idx]] for idx, val in enumerate(most_common_tags)] unique_title_len = len(title_counter) show_title_rank_table = False if unique_title_len > len(colors): max_title_item = len(colors) title_colors = colors show_title_rank_table = True else: title_colors = colors[:unique_title_len] max_title_item = unique_title_len most_common_titles = title_counter.most_common(max_title_item) most_common_titles = [ [val[0], val[1], title_colors[idx]] for idx, val in enumerate(most_common_titles)] return self.render( 'bukuserver/statistic.html', most_common_netlocs=most_common_netlocs, netloc_counter=netloc_counter, show_netloc_table=show_netloc_table, most_common_tags=most_common_tags, tag_counter=tag_counter, show_tag_rank_table=show_tag_rank_table, most_common_titles=most_common_titles, title_counter=title_counter, show_title_rank_table=show_title_rank_table, datetime=statistic_datetime, datetime_text=statistic_datetime.humanize(arrow.now(), granularity='second'), )