def test_refresh_token_failing_raises_unauthorized(self):
        def build_expires_at(dt):
            return (
                dt - datetime.datetime(1970, 1, 1)
            ).total_seconds()

        # dates
        now = datetime.datetime.now()
        one_day_delta = datetime.timedelta(days=1)

        expired_yesterday = build_expires_at(now - one_day_delta)

        # set access_token.expires_at to yesterday
        self.request.user.token['expires_at'] = expired_yesterday

        # mock the refresh token endpoint, return 401
        responses.add(
            responses.POST,
            api_client.REQUEST_TOKEN_URL,
            status=401,
            content_type='application/json'
        )

        # test
        conn = api_client.get_connection(self.request)
        self.assertRaises(
            Unauthorized, conn.test.get
        )
    def test_token_refreshed_automatically(self):
        """
        Test that if I call the /test/ endpoint with an
        expired access token, the module should automatically:

        - request a new access token
        - update request.user.token to the new token
        - finally request /test/ with the new valid token
        """
        def build_expires_at(dt):
            return (
                dt - datetime.datetime(1970, 1, 1)
            ).total_seconds()

        # dates
        now = datetime.datetime.now()
        one_day_delta = datetime.timedelta(days=1)

        expired_yesterday = build_expires_at(now - one_day_delta)
        expires_tomorrow = build_expires_at(now + one_day_delta)

        # set access_token.expires_at to yesterday
        self.request.user.token['expires_at'] = expired_yesterday
        expired_token = self.request.user.token

        # mock the refresh token endpoint, return a new token
        new_token = generate_tokens(expires_at=expires_tomorrow)
        responses.add(
            responses.POST,
            api_client.REQUEST_TOKEN_URL,
            body=json.dumps(new_token),
            status=200,
            content_type='application/json'
        )

        # mock the /test/ endpoint, return valid body
        expected_response = {'success': True}
        responses.add(
            responses.GET,
            self.test_endpoint,
            body=json.dumps(expected_response),
            status=200,
            content_type='application/json'
        )

        # test
        conn = api_client.get_connection(self.request)
        result = conn.test.get()

        self.assertDictEqual(result, expected_response)
        self.assertDictEqual(self.request.user.token, new_token)
        self.assertNotEqual(
            expired_token['access_token'],
            new_token['access_token']
        )
    def test_invalid_access_token_raises_unauthorized(self):
        # mock the response, return 401
        responses.add(
            responses.GET,
            self.test_endpoint,
            status=401,
            content_type='application/json'
        )

        conn = api_client.get_connection(self.request)
        self.assertRaises(
            Unauthorized, conn.test.get
        )
    def test_with_valid_access_token(self):
        # mock the response, return valid body
        expected_response = {'success': True}

        responses.add(
            responses.GET,
            self.test_endpoint,
            body=json.dumps(expected_response),
            status=200,
            content_type='application/json'
        )

        # should return the same generated body
        conn = api_client.get_connection(self.request)
        result = conn.test.get()

        self.assertDictEqual(result, expected_response)