<commit_before>from .helpers import *

from mock import patch

class TestClient(ClientTestCase):

    def test_users_me_not_authorized(self):
        res = {
            "errors": [
                { "message": "Not Authorized" }
            ]
        }
        responses.add(GET, 'http://app/users/me', status=401, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.NoAuthorizationError, self.client.users.me)

    def test_tasks_find_all_invalid_request(self):
        res = {
            "errors": [
                { "message": "workspace: Missing input" }
            ]
        }
        responses.add(GET, 'http://app/tasks', status=400, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.InvalidRequestError, self.client.tasks.find_all)

    def test_users_me_server_error(self):
        res = {
            "errors": [
                {
                    "message": "Server Error",
                    "phrase": "6 sad squid snuggle softly"
                }
            ]
        }
        responses.add(GET, 'http://app/users/me', status=500, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.ServerError, self.client.users.me)

    def test_users_find_by_id_not_found(self):
        res = {
            "errors": [
                { "message": "user: Unknown object: 1234124312341" }
            ]
        }
        responses.add(GET, 'http://app/users/1234', status=404, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.NotFoundError, self.client.users.find_by_id, (1234))

    def test_users_find_by_id_forbidden(self):
        res = {
            "errors": [
                { "message": "user: Forbidden" }
            ]
        }
        responses.add(GET, 'http://app/users/1234', status=403, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.ForbiddenError, self.client.users.find_by_id, (1234))

    @unittest.skip("pretty option not yet implemented")
    def test_option_pretty(self):
        res = {
            "data": { "email": "sanchez@...", "id": 999, "name": "<NAME>" }
        }
        responses.add(GET, 'http://app/users/me?opt_pretty', status=200, body=json.dumps(res), match_querystring=True)
        self.assertEqual(self.client.users.me(pretty=True), res['data'])

    @unittest.skip("fields option not yet implemented")
    def test_option_fields(self):
        res = {
            "data": { "name": "Make a list", "notes": "Check it twice!", "id": 1224 }
        }
        responses.add(GET, 'http://app/tasks/1224?opt_fields=name,notes', status=200, body=json.dumps(res), match_querystring=True)
        self.assertEqual(self.tasks.find_by_id.me(fields=('name','notes')), res['data'])

    @unittest.skip("expand option not yet implemented")
    def test_option_expand(self):
        res = {
            "data": {
                "id": 1001,
                "projects": [
                    {
                        "archived": false,
                        "created_at": "",
                        "followers": [],
                        "modified_at": "",
                        "notes": "",
                        "id": 1331,
                        "name": "Things to buy"
                    }
                ]
                # ...
            }
        }
        responses.add(PUT, 'http://app/tasks/1001', status=200, body=json.dumps(res), match_querystring=True)
        # -d "assignee=1234" \
        # -d "options.expand=%2Aprojects%2A"

    def test_pagination(self):
        res = {
            "data": [
                { "id": 1000, "name": "Task 1" }
            ],
            "next_page": {
                "offset": "<KEY>",
                "path": "/tasks?project=1337&limit=5&offset=<KEY>",
                "uri": "https://app.asana.com/api/1.0/tasks?project=1337&limit=5&offset=<KEY>"
            }
        }
        # responses.add(GET, 'http://app/tasks?project=1337&limit=5&offset=<KEY>', status=200, body=json.dumps(res), match_querystring=True)
        responses.add(GET, 'http://app/projects/1337/tasks?limit=5&offset=<KEY>', status=200, body=json.dumps(res), match_querystring=True)

        self.assertEqual(self.client.tasks.find_by_project(1337, { 'limit': 5, 'offset': '<KEY>'}), res['data'])

    def test_pagination_iterator(self):
        responses.add(GET, 'http://app/projects/1337/tasks?limit=2', status=200, body=json.dumps({ 'data': ['a', 'b'], 'next_page': { 'offset': 'a' } }), match_querystring=True)
        responses.add(GET, 'http://app/projects/1337/tasks?limit=2&offset=a', status=200, body=json.dumps({ 'data': ['c'], 'next_page': null }), match_querystring=True)

        iterator = self.client.tasks.find_by_project_iterator(1337, { 'limit': '2' })
        self.assertEqual(next(iterator), 'a')
        self.assertEqual(next(iterator), 'b')
        self.assertEqual(next(iterator), 'c')
        self.assertRaises(StopIteration, next, (iterator))

    @patch('time.sleep')
    def test_rate_limiting(self, time_sleep):
        res = [
            (429, { 'Retry-After': '10' }, '{}'),
            (200, {}, json.dumps({ 'data': 'me' }))
        ]
        responses.add_callback(responses.GET, 'http://app/users/me', callback=lambda r: res.pop(0), content_type='application/json')

        self.assertEqual(self.client.users.me(), 'me')
        self.assertEqual(len(responses.calls), 2)
        time_sleep.assert_called_once_with(10)
<commit_msg>Test case when rate limited twice in a row<commit_after>from .helpers import *

from mock import patch

class TestClient(ClientTestCase):

    def test_users_me_not_authorized(self):
        res = {
            "errors": [
                { "message": "Not Authorized" }
            ]
        }
        responses.add(GET, 'http://app/users/me', status=401, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.NoAuthorizationError, self.client.users.me)

    def test_tasks_find_all_invalid_request(self):
        res = {
            "errors": [
                { "message": "workspace: Missing input" }
            ]
        }
        responses.add(GET, 'http://app/tasks', status=400, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.InvalidRequestError, self.client.tasks.find_all)

    def test_users_me_server_error(self):
        res = {
            "errors": [
                {
                    "message": "Server Error",
                    "phrase": "6 sad squid snuggle softly"
                }
            ]
        }
        responses.add(GET, 'http://app/users/me', status=500, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.ServerError, self.client.users.me)

    def test_users_find_by_id_not_found(self):
        res = {
            "errors": [
                { "message": "user: Unknown object: 1234124312341" }
            ]
        }
        responses.add(GET, 'http://app/users/1234', status=404, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.NotFoundError, self.client.users.find_by_id, (1234))

    def test_users_find_by_id_forbidden(self):
        res = {
            "errors": [
                { "message": "user: Forbidden" }
            ]
        }
        responses.add(GET, 'http://app/users/1234', status=403, body=json.dumps(res), match_querystring=True)
        self.assertRaises(asana.error.ForbiddenError, self.client.users.find_by_id, (1234))

    @unittest.skip("pretty option not yet implemented")
    def test_option_pretty(self):
        res = {
            "data": { "email": "sanchez@...", "id": 999, "name": "<NAME>" }
        }
        responses.add(GET, 'http://app/users/me?opt_pretty', status=200, body=json.dumps(res), match_querystring=True)
        self.assertEqual(self.client.users.me(pretty=True), res['data'])

    @unittest.skip("fields option not yet implemented")
    def test_option_fields(self):
        res = {
            "data": { "name": "Make a list", "notes": "Check it twice!", "id": 1224 }
        }
        responses.add(GET, 'http://app/tasks/1224?opt_fields=name,notes', status=200, body=json.dumps(res), match_querystring=True)
        self.assertEqual(self.tasks.find_by_id.me(fields=('name','notes')), res['data'])

    @unittest.skip("expand option not yet implemented")
    def test_option_expand(self):
        res = {
            "data": {
                "id": 1001,
                "projects": [
                    {
                        "archived": false,
                        "created_at": "",
                        "followers": [],
                        "modified_at": "",
                        "notes": "",
                        "id": 1331,
                        "name": "Things to buy"
                    }
                ]
                # ...
            }
        }
        responses.add(PUT, 'http://app/tasks/1001', status=200, body=json.dumps(res), match_querystring=True)
        # -d "assignee=1234" \
        # -d "options.expand=%2Aprojects%2A"

    def test_pagination(self):
        res = {
            "data": [
                { "id": 1000, "name": "Task 1" }
            ],
            "next_page": {
                "offset": "<KEY>",
                "path": "/tasks?project=1337&limit=5&offset=<KEY>",
                "uri": "https://app.asana.com/api/1.0/tasks?project=1337&limit=5&offset=<KEY>"
            }
        }
        # responses.add(GET, 'http://app/tasks?project=1337&limit=5&offset=<KEY>', status=200, body=json.dumps(res), match_querystring=True)
        responses.add(GET, 'http://app/projects/1337/tasks?limit=5&offset=<KEY>', status=200, body=json.dumps(res), match_querystring=True)

        self.assertEqual(self.client.tasks.find_by_project(1337, { 'limit': 5, 'offset': '<KEY>'}), res['data'])

    def test_pagination_iterator(self):
        responses.add(GET, 'http://app/projects/1337/tasks?limit=2', status=200, body=json.dumps({ 'data': ['a', 'b'], 'next_page': { 'offset': 'a' } }), match_querystring=True)
        responses.add(GET, 'http://app/projects/1337/tasks?limit=2&offset=a', status=200, body=json.dumps({ 'data': ['c'], 'next_page': null }), match_querystring=True)

        iterator = self.client.tasks.find_by_project_iterator(1337, { 'limit': '2' })
        self.assertEqual(next(iterator), 'a')
        self.assertEqual(next(iterator), 'b')
        self.assertEqual(next(iterator), 'c')
        self.assertRaises(StopIteration, next, (iterator))

    @patch('time.sleep')
    def test_rate_limiting(self, time_sleep):
        res = [
            (429, { 'Retry-After': '10' }, '{}'),
            (200, {}, json.dumps({ 'data': 'me' }))
        ]
        responses.add_callback(responses.GET, 'http://app/users/me', callback=lambda r: res.pop(0), content_type='application/json')

        self.assertEqual(self.client.users.me(), 'me')
        self.assertEqual(len(responses.calls), 2)
        time_sleep.assert_called_once_with(10)

    @patch('time.sleep')
    def test_rate_limited_twice(self, time_sleep):
        res = [
            (429, { 'Retry-After': '10' }, '{}'),
            (429, { 'Retry-After': '1' }, '{}'),
            (200, {}, json.dumps({ 'data': 'me' }))
        ]
        responses.add_callback(responses.GET, 'http://app/users/me', callback=lambda r: res.pop(0), content_type='application/json')

        self.assertEqual(self.client.users.me(), 'me')
        self.assertEqual(len(responses.calls), 3)
        time_sleep.assert_called_twice()

{'fraction_non_alphanumeric': 0.1624816636465614, 'fraction_numerical': 0.027784968504616446, 'mean_word_length': 2.238334730371612, 'pattern_counts': {'":': 72, '<': 17, '<?xml version=': 0, '>': 17, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1265281', 'n_tokens_mistral': 3897, 'n_tokens_neox': 3630, 'n_words': 556}