From 9fc6fd7b67ec9a2add25a43eae19f72898c05390 Mon Sep 17 00:00:00 2001 From: hitnik Date: Wed, 18 Aug 2021 20:14:22 +0300 Subject: [PATCH] get_long_url_from_db --- app/__init__.py | 1 + app/config.py | 4 +++ app/db.py | 26 +++++++++++++-- app/{main.py => utils.py} | 29 +++++++++++++--- main.py | 10 ++++++ tests/__init__.py | 1 + tests/conftest.py | 2 +- tests/test_db.py | 70 ++++++++++++++++++++------------------- tests/test_utils.py | 21 ++++++++++++ 9 files changed, 121 insertions(+), 43 deletions(-) create mode 100644 app/config.py rename app/{main.py => utils.py} (62%) create mode 100644 main.py create mode 100644 tests/test_utils.py diff --git a/app/__init__.py b/app/__init__.py index e69de29..c7df41c 100644 --- a/app/__init__.py +++ b/app/__init__.py @@ -0,0 +1 @@ +import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__))) \ No newline at end of file diff --git a/app/config.py b/app/config.py new file mode 100644 index 0000000..606e1b3 --- /dev/null +++ b/app/config.py @@ -0,0 +1,4 @@ +import os + +SCHEME = os.environ.get("API_SCHEME", "http") +NETLOC = os.environ.get("API_NETLOC", "ex.com") \ No newline at end of file diff --git a/app/db.py b/app/db.py index f7198c3..6a62f7d 100644 --- a/app/db.py +++ b/app/db.py @@ -153,8 +153,22 @@ def get_short_url(short): short = cur.execute(sql, (short,)).fetchone() return short +def get_short_url_by_long(long_id): + """ get short_url instance by long id -def get_long_url(id): + Args: + long_id (int): long id + + Returns: + [tuple]: short_url instance + """ + sql = "SELECT * FROM short_urls WHERE long_id = ?;" + with db_manager() as db: + cur = db.cursor() + short = cur.execute(sql, (long_id,)).fetchone() + return short + +def get_long_url_from_db(id=None, url=None): """ get long_url instance by id Args: @@ -163,10 +177,16 @@ def get_long_url(id): Returns: [tuple]: long_url instance """ - sql = "SELECT * FROM long_urls WHERE id = ?;" + + sql_id = "SELECT * FROM long_urls WHERE id = ?;" + sql_url = "SELECT * FROM long_urls WHERE long_url = ?;" + instance = None with db_manager() as db: cur = db.cursor() - instance = cur.execute(sql, (id,)).fetchone() + if id and not url: + instance = cur.execute(sql_id, (id,)).fetchone() + elif url and not id: + instance = cur.execute(sql_url, (url,)).fetchone() return instance diff --git a/app/main.py b/app/utils.py similarity index 62% rename from app/main.py rename to app/utils.py index d378149..c462a5a 100644 --- a/app/main.py +++ b/app/utils.py @@ -1,5 +1,9 @@ import argparse import textwrap +from db import ( short_url_exist, get_short_url, + get_long_url_from_db, long_url_exist, + get_short_url_by_long + ) def parser(): @@ -23,10 +27,25 @@ def parser(): help="""Use this argument and cpecify short URL, if you want to use custom short_url.""" ) - return parser + return parser -if __name__ == '__main__': - parser = parser() - args = parser.parse_args() - print(args) +class Shortener: + + + @staticmethod + def get_long_url(short): + if short_url_exist(short): + short_inst = get_short_url(short) + long_inst = get_long_url_from_db(id=short_inst[1]) + return long_inst[1] + else: + raise Exception("This short URL does not exist") + + + @staticmethod + def gen_short_url(long): + if long_url_exist(long): + long_inst = get_long_url_from_db(url=long) + short_inst = get_short_url_by_long(long_inst[0]) + return short_inst[2] diff --git a/main.py b/main.py new file mode 100644 index 0000000..f969440 --- /dev/null +++ b/main.py @@ -0,0 +1,10 @@ + + + +from app.utils import parser + + +if __name__ == '__main__': + parser = parser() + args = parser.parse_args() + print(args) diff --git a/tests/__init__.py b/tests/__init__.py index e69de29..c7df41c 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -0,0 +1 @@ +import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__))) \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py index 9e90302..bed232c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -2,7 +2,7 @@ import tempfile import pytest from app.db import init_db -from app.main import parser +from app.utils import parser @pytest.fixture diff --git a/tests/test_db.py b/tests/test_db.py index 536a6b5..5043389 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -1,8 +1,10 @@ from app.db import ( init_db, close_db, get_db, insert_long_url, insert_short_url, - long_url_exist, get_short_url, short_url_exist, get_long_url + long_url_exist, get_short_url, short_url_exist, get_long_url_from_db, + get_short_url_by_long ) from unittest import mock +from contextlib import contextmanager script = """ INSERT INTO long_urls (id, long_url) @@ -14,7 +16,13 @@ (1, 1, 'goo.gl'), (2, 2, 'yu.tu'); """ - +@contextmanager +def manager_mock(db_mock, init_db, db_manager): + with mock.patch(init_db) as get_db: + get_db.return_value = db_mock + with mock.patch(db_manager) as manager: + manager.return_value = db_mock + yield lambda : manager def test_init_db(db_path): db = init_db(db_path) @@ -44,47 +52,41 @@ def test_get_db(db_path): def test_long_url_exist(db_mock): db_mock.executescript(script) - with mock.patch('app.db.get_db') as get_db: - get_db.return_value = db_mock - with mock.patch('app.db.db_manager') as manager: - manager.return_value = db_mock - assert long_url_exist('') is False - assert long_url_exist('https://www.youtube.com') is True + with manager_mock(db_mock, 'app.db.get_db', 'app.db.db_manager'): + assert long_url_exist('') is False + assert long_url_exist('https://www.youtube.com') is True def test_insert(db_mock): - with mock.patch('app.db.get_db') as get_db: - get_db.return_value = db_mock - with mock.patch('app.db.db_manager') as manager: - manager.return_value = db_mock - assert insert_long_url('www.test.ru') == 1 - assert insert_short_url('short.ru/a23', 1) == 1 + with manager_mock(db_mock, 'app.db.get_db', 'app.db.db_manager'): + assert insert_long_url('www.test.ru') == 1 + assert insert_short_url('short.ru/a23', 1) == 1 def test_get_short_url(db_mock): - with mock.patch('app.db.get_db') as get_db: - get_db.return_value = db_mock - with mock.patch('app.db.db_manager') as manager: - manager.return_value = db_mock - db_mock.executescript(script) - assert type(get_short_url('goo.gl')) == tuple - assert get_short_url('goo.gl')[0] == 1 + db_mock.executescript(script) + with manager_mock(db_mock, 'app.db.get_db', 'app.db.db_manager'): + assert type(get_short_url('goo.gl')) == tuple + assert get_short_url('goo.gl')[0] == 1 def test_short_url_exist(db_mock): db_mock.executescript(script) - with mock.patch('app.db.get_db') as get_db: - get_db.return_value = db_mock - with mock.patch('app.db.db_manager') as manager: - manager.return_value = db_mock - assert short_url_exist('') is False - assert short_url_exist('goo.gl') is True + with manager_mock(db_mock, 'app.db.get_db', 'app.db.db_manager'): + assert short_url_exist('') is False + assert short_url_exist('goo.gl') is True def test_get_long_url(db_mock): - with mock.patch('app.db.get_db') as get_db: - get_db.return_value = db_mock - with mock.patch('app.db.db_manager') as manager: - manager.return_value = db_mock - db_mock.executescript(script) - assert type(get_long_url(1)) == tuple - assert get_long_url(1)[0] == 1 \ No newline at end of file + db_mock.executescript(script) + with manager_mock(db_mock, 'app.db.get_db', 'app.db.db_manager'): + assert get_long_url_from_db() is None + assert type(get_long_url_from_db(id=1)) == tuple + assert get_long_url_from_db(id=1)[0] == 1 + assert type(get_long_url_from_db(url='https://www.google.com/')) == tuple + assert get_long_url_from_db(url='https://www.google.com/')[0] == 1 + +def test_get_short_by_long(db_mock): + db_mock.executescript(script) + with manager_mock(db_mock, 'app.db.get_db', 'app.db.db_manager'): + assert type(get_short_url_by_long(1)) == tuple + assert get_short_url_by_long(2)[0] == 2 diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..8649456 --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,21 @@ +from app.utils import Shortener +from tests.test_db import script, manager_mock +import pytest +from unittest import mock + + +def test_get_long_url(db_mock): + db_mock.executescript(script) + with manager_mock(db_mock, 'db.get_db', 'db.db_manager'): + with pytest.raises(Exception, match=r".* URL does .*"): + Shortener.get_long_url('raise') + inst = Shortener.get_long_url('goo.gl') + assert type(inst) is str + assert inst == 'https://www.google.com/' + +def test_get_long_url(db_mock): + db_mock.executescript(script) + with manager_mock(db_mock, 'db.get_db', 'db.db_manager'): + inst = Shortener.gen_short_url('https://www.google.com/') + assert type(inst) is str + assert inst == 'goo.gl'