Beispiel #1
0
 def post(self):
     cache = RedisCacheFactory().create(name=app.config.get('REDIS_CACHE_NAME'),
                                        redis_host=app.config.get('REDIS_HOST'))
     post_data = request.get_json()
     url_str = post_data.get('url')
     custom_str = post_data.get('custom')
     auth_header = request.headers.get('Authorization')
     user_id = get_user_id(auth_header)
     if user_id is None:
         return response(message='Invalid credentials!', status=HTTPStatus.UNAUTHORIZED)
     crud = URLCrud(SequentialEncoder())
     try:
         url, representation = crud.create_url(user_id, url_str, custom_str)
     except ValueError:
         return response(status=HTTPStatus.BAD_REQUEST, message='url is not formatted correctly!')
     cache[representation] = url.id, url_str
     return response(
         data={
             'id': url.id,
             'original_url': url_str,
             'short_uri': f'r/{representation}'
         },
         message='URL shortened successfully!',
         status=HTTPStatus.CREATED
     )
Beispiel #2
0
 def setUp(self):
     self.app = create_app(TestConfig)
     self.app_context = self.app.app_context()
     self.app_context.push()
     db.create_all()
     URLLog.query.delete()
     URL.query.delete()
     User.query.delete()
     self.user = UserCRUD(SimpleUserFactory()).create_user('*****@*****.**', '12341234')
     self.crud = URLCrud(SequentialEncoder())
Beispiel #3
0
 def get(self, short_representation):
     cache = RedisCacheFactory().create(name=app.config.get('REDIS_CACHE_NAME'),
                                        redis_host=app.config.get('REDIS_HOST'))
     crud = URLCrud(SequentialEncoder())
     url_id, url = cache[short_representation]
     if url is None:
         url_object = crud.retrieve_url(short_representation)
         if not url_object:
             return response(status=HTTPStatus.NOT_FOUND, message='URL not available')
         url_id, url = url_object.id, url_object.url
         cache[short_representation] = url
     submit_url_log.delay(url_id=url_id, user_agent=request.headers.get('User-Agent'))
     return response(status=HTTPStatus.MOVED_PERMANENTLY, headers={'Location': url})
 def create_app(self):
     self.app = create_app(TestConfig)
     self.app_context = self.app.app_context()
     self.app_context.push()
     db.create_all()
     URLLog.query.delete()
     URL.query.delete()
     User.query.delete()
     self.user = UserCRUD(SimpleUserFactory()).create_user('*****@*****.**', '12341234')
     self.url, _ = URLCrud(SequentialEncoder()).create_url(self.user.id, 'http://foo.bar.com')
     self.crud = URLLogsCrudFactory()
     return self.app
class TestAuthViews(TestCase):
    def create_app(self):
        self.app = create_app(TestConfig)
        self.app_context = self.app.app_context()
        self.app_context.push()
        URLLog.query.delete()
        URL.query.delete()
        User.query.delete()
        db.create_all()
        self.user = UserCRUD(SimpleUserFactory()).create_user(
            '*****@*****.**', '12341234')
        self.crud = URLCrud(SequentialEncoder())
        submit_url_log.delay = submit_url_log
        return self.app

    def setUp(self) -> None:
        response = self.client.post('/auth/login',
                                    json={
                                        'email': '*****@*****.**',
                                        'password': '******'
                                    })
        self.token = response.json['data']['auth_token']

    def test_url_shortener_get_redirects_to_correct_link(self):
        url, representation = self.crud.create_url(self.user.id,
                                                   'https://foo.bar.com')
        response = self.client.get(f'/r/{representation}')
        self.assertEqual(301, response.status_code)
        self.assertEqual(response.headers['Location'], 'https://foo.bar.com')

    def test_url_shortener_create_url_log_correctly(self):
        url, representation = self.crud.create_url(self.user.id,
                                                   'https://foo.bar.com')
        response = self.client.get(
            f'/r/{representation}',
            headers={
                'User-Agent':
                'Mozilla/5.0 (Linux; Android 7.0; SM-G892A Build/NRD90M; wv)'
                'AppleWebKit/537.36 (KHTML, like Gecko)'
                'Version/4.0 Chrome/60.0.3112.107 Mobile Safari/537.36'
            })
        url_log: URLLog = URLLog.query.filter(
            URLLog.url_id == url.id).one_or_none()
        self.assertEqual(url.id, url_log.url_id)
        self.assertEqual('Chrome', url_log.browser)
        self.assertEqual('Linux', url_log.os)
        self.assertEqual('Android', url_log.platform)

    def test_url_shortener_get_returns_404_for_unavailable__or_invalid_url(
            self):
        response = self.client.get('/r/unavailable')
        self.assertEqual(404, response.status_code)
        response = self.client.get('/r/in.vali.d')
        self.assertEqual(404, response.status_code)

    def test_url_shortener_post_returns_401_for_unauthorized_users(self):
        response = self.client.post('/urls', json={'url': 'https://foo.com'})
        self.assertEqual(401, response.status_code)

    def test_url_shortener_post_returns_401_for_bad_token(self):
        response = self.client.post(
            '/urls',
            json={'url': 'bad.url'},
            headers={'Authorization': f'Bearer BADTOKEN'})
        self.assertEqual(401, response.status_code)

    def test_url_shortener_post_returns_400_for_bad_urls(self):
        response = self.client.post(
            '/urls',
            json={'url': 'bad.url'},
            headers={'Authorization': f'Bearer {self.token}'})
        self.assertEqual(400, response.status_code)

    def test_url_shortener_works_correctly_given_token_and_correct_url(self):
        response = self.client.post(
            '/urls',
            json={'url': 'https://foo.bar.com?var=3&another_var=2'},
            headers={'Authorization': f'Bearer {self.token}'})
        self.assertEqual('https://foo.bar.com?var=3&another_var=2',
                         response.json['data']['original_url'])
        self.assertTrue('short_uri' in response.json['data'])
        short_uri = response.json['data']['short_uri']
        response = self.client.get(f'{short_uri}')
        self.assertEqual(301, response.status_code)
        self.assertEqual(response.headers['Location'],
                         'https://foo.bar.com?var=3&another_var=2')

    def test_url_shortener_uses_cache_if_exists(self):
        short_uri = self.client.post(
            '/urls',
            json={
                'url': 'https://foo.bar.com?var=3&another_var=2'
            },
            headers={
                'Authorization': f'Bearer {self.token}'
            }).json['data']['short_uri']
        url = URL.query.one_or_none()
        url.url = 'something_different'
        db.session.commit()
        response = self.client.get(f'{short_uri}')
        self.assertEqual(301, response.status_code)
        self.assertEqual(response.headers['Location'],
                         'https://foo.bar.com?var=3&another_var=2')
Beispiel #6
0
class TestUserCRUD(TestCase):
    def setUp(self):
        self.app = create_app(TestConfig)
        self.app_context = self.app.app_context()
        self.app_context.push()
        db.create_all()
        URLLog.query.delete()
        URL.query.delete()
        User.query.delete()
        self.user = UserCRUD(SimpleUserFactory()).create_user('*****@*****.**', '12341234')
        self.crud = URLCrud(SequentialEncoder())

    def test_create_url_raises_error_for_incorrectly_formatted_url(self):
        self.assertRaises(ValueError, self.crud.create_url, self.user.id, 'foobar')
        self.assertRaises(ValueError, self.crud.create_url, self.user.id, 'foo.bar.com')

    def test_create_url_generates_different_representation_for_the_same_url_each_time(self):
        _, representation_1 = self.crud.create_url(self.user.id, 'http://foo.bar.com')
        _, representation_2 = self.crud.create_url(self.user.id, 'http://foo.bar.com')
        self.assertNotEqual(representation_1, representation_2)

    def test_create_url_uses_custom_representation_if_not_already_used(self):
        _, representation = self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom')
        self.assertEqual('custom', representation)

    def test_create_url_uses_similar_custom_representation_in_case_of_conflict_in_order(self):
        _, representation_1 = self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom')
        for i in range(10):
            _, representation_i = self.crud.create_url(self.user.id, 'http://foo.bar.com',
                                                       custom_representation='custom')
            self.assertEqual(representation_i, f'custom{i}')
        _, representation_00 = self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom')
        self.assertEqual('custom00', representation_00)

    def test_create_url_uses_similar_custom_representation_in_case_of_conflict_without_order(self):
        self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom')
        self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom0')
        self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom2')
        _, representation = self.crud.create_url(self.user.id, 'http://foo.bar.com', custom_representation='custom')
        self.assertEqual('custom1', representation)

    def test_create_url_raises_value_error_given_invalid_custom_string(self):
        self.assertRaises(ValueError, self.crud.create_url, self.user.id, 'http://foo.bar.com', '!nv^l!d')

    def test_retrieve_url_finds_the_correct_url_given_short_representation(self):
        url_normal, representation_normal = self.crud.create_url(self.user.id, 'http://foo.bar.com')
        url_custom, representation_custom = self.crud.create_url(self.user.id, 'http://foo.bar.com',
                                                                 custom_representation='custom')
        retrieved_url_normal = self.crud.retrieve_url(representation_normal)
        retrieved_url_custom = self.crud.retrieve_url(representation_custom)

        self.assertEqual(url_normal, retrieved_url_normal)
        self.assertEqual(url_custom, retrieved_url_custom)

    def test_retrieve_url_returns_none_given_unavailable_representation(self):
        retrieved_url_unavailable = self.crud.retrieve_url('unavailable')
        self.assertIsNone(retrieved_url_unavailable)

    def test_retrieve_url_returns_none_given_invalid_representation(self):
        retrieved_url_invalid = self.crud.retrieve_url('!nv^lID')
        self.assertIsNone(retrieved_url_invalid)

    def tearDown(self) -> None:
        URL.query.delete()
        User.query.delete()