Beispiel #1
0
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'
Beispiel #2
0
    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
Beispiel #3
0
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'
Beispiel #4
0
    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
Beispiel #5
0
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
Beispiel #6
0
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'
Beispiel #7
0
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'
Beispiel #8
0
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'
Beispiel #9
0
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'
Beispiel #10
0
    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
Beispiel #11
0
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)
Beispiel #12
0
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'
Beispiel #13
0
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'
Beispiel #14
0
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'
Beispiel #15
0
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'
Beispiel #16
0
    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()
Beispiel #17
0
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
Beispiel #18
0
    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)
Beispiel #19
0
 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)
Beispiel #20
0
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
Beispiel #21
0
    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)
Beispiel #22
0
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 == ''
Beispiel #23
0
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
Beispiel #24
0
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
Beispiel #25
0
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
Beispiel #26
0
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
Beispiel #27
0
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
Beispiel #28
0
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
Beispiel #29
0
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
Beispiel #30
0
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
Beispiel #31
0
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
Beispiel #32
0
 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)
Beispiel #33
0
    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")
Beispiel #34
0
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
Beispiel #35
0
    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()
Beispiel #36
0
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
Beispiel #37
0
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
Beispiel #38
0
    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)
Beispiel #39
0
 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()
Beispiel #40
0
 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()
Beispiel #41
0
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
Beispiel #42
0
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()
Beispiel #43
0
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
Beispiel #44
0
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
Beispiel #45
0
 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)
Beispiel #46
0
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')
Beispiel #47
0
    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")
Beispiel #48
0
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()
Beispiel #49
0
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 == ''
Beispiel #50
0
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)
Beispiel #51
0
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
Beispiel #52
0
    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)
Beispiel #53
0
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 == ''
Beispiel #54
0
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)
Beispiel #55
0
    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"]))
Beispiel #56
0
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
Beispiel #57
0
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
Beispiel #58
0
    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'),
        )