1#!/usr/bin/env python
2#
3# Copyright 2014 Google Inc. All Rights Reserved.
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9#      http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""Tests for errors handling
18"""
19from __future__ import absolute_import
20
21__author__ = "afshar@google.com (Ali Afshar)"
22
23
24import unittest2 as unittest
25import httplib2
26
27
28from googleapiclient.errors import HttpError
29
30
31JSON_ERROR_CONTENT = b"""
32{
33 "error": {
34  "errors": [
35   {
36    "domain": "global",
37    "reason": "required",
38    "message": "country is required",
39    "locationType": "parameter",
40    "location": "country"
41   }
42  ],
43  "code": 400,
44  "message": "country is required",
45  "details": "error details"
46 }
47}
48"""
49
50
51def fake_response(data, headers, reason="Ok"):
52    response = httplib2.Response(headers)
53    response.reason = reason
54    return response, data
55
56
57class Error(unittest.TestCase):
58    """Test handling of error bodies."""
59
60    def test_json_body(self):
61        """Test a nicely formed, expected error response."""
62        resp, content = fake_response(
63            JSON_ERROR_CONTENT,
64            {"status": "400", "content-type": "application/json"},
65            reason="Failed",
66        )
67        error = HttpError(resp, content, uri="http://example.org")
68        self.assertEqual(
69            str(error),
70            '<HttpError 400 when requesting http://example.org returned "country is required". Details: "error details">',
71        )
72
73    def test_bad_json_body(self):
74        """Test handling of bodies with invalid json."""
75        resp, content = fake_response(
76            b"{", {"status": "400", "content-type": "application/json"}, reason="Failed"
77        )
78        error = HttpError(resp, content)
79        self.assertEqual(str(error), '<HttpError 400 "Failed">')
80
81    def test_with_uri(self):
82        """Test handling of passing in the request uri."""
83        resp, content = fake_response(
84            b"{",
85            {"status": "400", "content-type": "application/json"},
86            reason="Failure",
87        )
88        error = HttpError(resp, content, uri="http://example.org")
89        self.assertEqual(
90            str(error),
91            '<HttpError 400 when requesting http://example.org returned "Failure">',
92        )
93
94    def test_missing_message_json_body(self):
95        """Test handling of bodies with missing expected 'message' element."""
96        resp, content = fake_response(
97            b"{}",
98            {"status": "400", "content-type": "application/json"},
99            reason="Failed",
100        )
101        error = HttpError(resp, content)
102        self.assertEqual(str(error), '<HttpError 400 "Failed">')
103
104    def test_non_json(self):
105        """Test handling of non-JSON bodies"""
106        resp, content = fake_response(b"}NOT OK", {"status": "400"})
107        error = HttpError(resp, content)
108        self.assertEqual(str(error), '<HttpError 400 "Ok">')
109
110    def test_missing_reason(self):
111        """Test an empty dict with a missing resp.reason."""
112        resp, content = fake_response(b"}NOT OK", {"status": "400"}, reason=None)
113        error = HttpError(resp, content)
114        self.assertEqual(str(error), '<HttpError 400 "">')
115