apitestcase.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315
  1. #!/usr/bin/env python
  2. """A TestCase that initializes the library with standard API methods."""
  3. import contextlib
  4. import json
  5. import os
  6. from . import _cloud_api_utils
  7. import unittest
  8. import ee
  9. # Cached algorithms list
  10. _algorithms_cache = None
  11. def GetAlgorithms():
  12. """Returns a static version of the ListAlgorithms call.
  13. After ApiTestCase.setUp is called, ee.data.getAlgorithms() is patched to use
  14. this data. This function may be called explicitly if the test data is needed
  15. at a time before the test case has started executing.
  16. """
  17. global _algorithms_cache
  18. if _algorithms_cache is not None:
  19. return _algorithms_cache
  20. algorithms_path = os.path.join(
  21. os.path.dirname(os.path.realpath(__file__)),
  22. "tests/algorithms.json")
  23. with open(algorithms_path, encoding='utf-8') as algorithms_file:
  24. algorithms = json.load(algorithms_file)
  25. _algorithms_cache = _cloud_api_utils.convert_algorithms(algorithms)
  26. return _algorithms_cache
  27. class ApiTestCase(unittest.TestCase):
  28. def setUp(self):
  29. super(ApiTestCase, self).setUp()
  30. self.InitializeApi()
  31. def InitializeApi(self, should_mock=True):
  32. """Initializes the library with standard API methods.
  33. This is normally invoked during setUp(), but subclasses may invoke
  34. it manually instead if they prefer.
  35. Args:
  36. should_mock: Whether or not to mock the various functions.
  37. """
  38. self.last_download_call = None
  39. self.last_thumb_call = None
  40. self.last_table_call = None
  41. self.last_mapid_call = None
  42. ee.Reset()
  43. ee.data._install_cloud_api_resource = lambda: None
  44. ee.data.getAlgorithms = GetAlgorithms
  45. if should_mock:
  46. ee.data.computeValue = lambda x: {'value': 'fakeValue'}
  47. ee.data.getMapId = self._MockMapId
  48. ee.data.getDownloadId = self._MockDownloadUrl
  49. ee.data.getThumbId = self._MockThumbUrl
  50. ee.data.getTableDownloadId = self._MockTableDownload
  51. ee.Initialize(None, '')
  52. # We are mocking the url here so the unit tests are happy.
  53. def _MockMapId(self, params):
  54. self.last_mapid_call = {'url': '/mapid', 'data': params}
  55. return {'mapid': 'fakeMapId', 'token': 'fakeToken'}
  56. def _MockDownloadUrl(self, params):
  57. self.last_download_call = {'url': '/download', 'data': params}
  58. return {'docid': '1', 'token': '2'}
  59. def _MockThumbUrl(self, params, thumbType=None): # pylint: disable=invalid-name,unused-argument
  60. # Hang on to the call arguments.
  61. self.last_thumb_call = {'url': '/thumb', 'data': params}
  62. return {'thumbid': '3', 'token': '4'}
  63. def _MockTableDownload(self, params):
  64. self.last_table_call = {'url': '/table', 'data': params}
  65. return {'docid': '5', 'token': '6'}
  66. @contextlib.contextmanager
  67. def UsingCloudApi(cloud_api_resource=None, mock_http=None):
  68. """Returns a context manager under which the Cloud API is enabled."""
  69. old_cloud_api_resource = ee.data._cloud_api_resource
  70. try:
  71. if cloud_api_resource is None:
  72. discovery_doc_path = os.path.join(
  73. os.path.dirname(os.path.realpath(__file__)),
  74. "tests/cloud_api_discovery_document.json")
  75. with open(discovery_doc_path) as discovery_doc_file:
  76. discovery_doc_str = discovery_doc_file.read()
  77. cloud_api_resource = (
  78. _cloud_api_utils.build_cloud_resource_from_document(
  79. json.loads(discovery_doc_str),
  80. http_transport=mock_http,
  81. headers_supplier=ee.data._make_request_headers,
  82. response_inspector=ee.data._handle_profiling_response))
  83. ee.data._cloud_api_resource = cloud_api_resource
  84. yield
  85. finally:
  86. ee.data._cloud_api_resource = old_cloud_api_resource
  87. # A sample of encoded EE API JSON, used by SerializerTest and DeserializerTest.
  88. ENCODED_JSON_SAMPLE = {
  89. 'type': 'CompoundValue',
  90. 'scope': [
  91. ['0', {
  92. 'type': 'Invocation',
  93. 'functionName': 'Date',
  94. 'arguments': {
  95. 'value': 1234567890000
  96. }
  97. }],
  98. ['1', {
  99. 'type': 'LineString',
  100. 'coordinates': [[1, 2], [3, 4]],
  101. 'crs': {
  102. 'type': 'name',
  103. 'properties': {
  104. 'name': 'SR-ORG:6974'
  105. }
  106. }
  107. }],
  108. ['2', {
  109. 'evenOdd': True,
  110. 'type': 'Polygon',
  111. 'coordinates': [
  112. [[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
  113. [[5, 6], [7, 6], [7, 8], [5, 8]],
  114. [[1, 1], [2, 1], [2, 2], [1, 2]]
  115. ]
  116. }],
  117. ['3', {
  118. 'type': 'Bytes',
  119. 'value': 'aGVsbG8='
  120. }],
  121. ['4', {
  122. 'type': 'Invocation',
  123. 'functionName': 'String.cat',
  124. 'arguments': {
  125. 'string1': 'x',
  126. 'string2': 'y'
  127. }
  128. }],
  129. ['5', {
  130. 'type': 'Dictionary',
  131. 'value': {
  132. 'foo': 'bar',
  133. 'baz': {'type': 'ValueRef', 'value': '4'}
  134. }
  135. }],
  136. ['6', {
  137. 'type': 'Function',
  138. 'argumentNames': ['x', 'y'],
  139. 'body': {'type': 'ArgumentRef', 'value': 'y'}
  140. }],
  141. ['7', [
  142. None,
  143. True,
  144. 5,
  145. 7,
  146. 3.4,
  147. 112233445566778899,
  148. 'hello',
  149. {'type': 'ValueRef', 'value': '0'},
  150. {'type': 'ValueRef', 'value': '1'},
  151. {'type': 'ValueRef', 'value': '2'},
  152. {'type': 'ValueRef', 'value': '3'},
  153. {'type': 'ValueRef', 'value': '5'},
  154. {'type': 'ValueRef', 'value': '4'},
  155. {'type': 'ValueRef', 'value': '6'}
  156. ]]
  157. ],
  158. 'value': {'type': 'ValueRef', 'value': '7'}
  159. }
  160. # A sample of encoded EE API JSON for the Cloud API, used by SerializerTest.
  161. ENCODED_CLOUD_API_JSON_SAMPLE = {
  162. 'values': {
  163. '0': {
  164. 'arrayValue': {
  165. 'values': [
  166. {'constantValue': None},
  167. {'constantValue': True},
  168. {'constantValue': 5},
  169. {'constantValue': 7},
  170. {'constantValue': 3.4},
  171. {'integerValue': '112233445566778899'},
  172. {'constantValue': 'hello'},
  173. {'functionInvocationValue': {
  174. 'functionName': 'Date',
  175. 'arguments': {'value': {'constantValue': 1234567890000}}
  176. }},
  177. {'functionInvocationValue': {
  178. 'functionName': 'GeometryConstructors.LineString',
  179. 'arguments': {
  180. 'crs': {'functionInvocationValue': {
  181. 'functionName': 'Projection',
  182. 'arguments': {
  183. 'crs': {'constantValue': 'SR-ORG:6974'}}
  184. }},
  185. 'coordinates': {'arrayValue': {'values': [
  186. {'valueReference': '1'},
  187. {'constantValue': [3, 4]}
  188. ]}}
  189. }}},
  190. {'functionInvocationValue': {
  191. 'functionName': 'GeometryConstructors.Polygon',
  192. 'arguments': {
  193. 'coordinates': {'arrayValue': {'values': [
  194. {'arrayValue': {'values': [
  195. {'valueReference': '2'},
  196. {'constantValue': [10, 0]},
  197. {'constantValue': [10, 10]},
  198. {'constantValue': [0, 10]},
  199. {'valueReference': '2'}]}},
  200. {'constantValue':
  201. [[5, 6], [7, 6], [7, 8], [5, 8]]},
  202. {'arrayValue': {'values': [
  203. {'constantValue': [1, 1]},
  204. {'constantValue': [2, 1]},
  205. {'constantValue': [2, 2]},
  206. {'valueReference': '1'}]}}
  207. ]}},
  208. 'evenOdd': {'constantValue': True}}}},
  209. {'bytesValue': 'aGVsbG8='},
  210. {'dictionaryValue': {
  211. 'values': {
  212. 'baz': {'valueReference': '3'},
  213. 'foo': {'constantValue': 'bar'},
  214. }
  215. }},
  216. {'valueReference': '3'},
  217. {'functionDefinitionValue': {
  218. 'argumentNames': ['x', 'y'],
  219. 'body': '4'}
  220. }
  221. ]}},
  222. '1': {'constantValue': [1, 2]},
  223. '2': {'constantValue': [0, 0]},
  224. '3': {'functionInvocationValue': {
  225. 'functionName': 'String.cat',
  226. 'arguments': {
  227. 'string1': {'constantValue': 'x'},
  228. 'string2': {'constantValue': 'y'}
  229. }}},
  230. '4': {'argumentReference': 'y'},
  231. },
  232. 'result': '0'
  233. }
  234. ENCODED_CLOUD_API_JSON_SAMPLE_PRETTY = {
  235. 'arrayValue': {
  236. 'values': [
  237. {'constantValue': None},
  238. {'constantValue': True},
  239. {'constantValue': 5},
  240. {'constantValue': 7},
  241. {'constantValue': 3.4},
  242. {'integerValue': '112233445566778899'},
  243. {'constantValue': 'hello'},
  244. {'functionInvocationValue': {
  245. 'functionName': 'Date',
  246. 'arguments': {'value': {'constantValue': 1234567890000}}
  247. }},
  248. {'functionInvocationValue': {
  249. 'functionName': 'GeometryConstructors.LineString',
  250. 'arguments': {
  251. 'crs': {'functionInvocationValue': {
  252. 'functionName': 'Projection',
  253. 'arguments': {
  254. 'crs': {'constantValue': 'SR-ORG:6974'}}
  255. }},
  256. 'coordinates': {'constantValue': [[1, 2], [3, 4]]}
  257. }}},
  258. {'functionInvocationValue': {
  259. 'functionName': 'GeometryConstructors.Polygon',
  260. 'arguments': {
  261. 'coordinates': {
  262. 'constantValue':
  263. [[[0, 0], [10, 0], [10, 10], [0, 10], [0, 0]],
  264. [[5, 6], [7, 6], [7, 8], [5, 8]],
  265. [[1, 1], [2, 1], [2, 2], [1, 2]]]},
  266. 'evenOdd': {'constantValue': True}}}},
  267. {'bytesValue': 'aGVsbG8='},
  268. {'dictionaryValue': {
  269. 'values': {
  270. 'baz': {'functionInvocationValue': {
  271. 'functionName': 'String.cat',
  272. 'arguments': {
  273. 'string1': {'constantValue': 'x'},
  274. 'string2': {'constantValue': 'y'}
  275. }}},
  276. 'foo': {'constantValue': 'bar'},
  277. }}},
  278. {'functionInvocationValue': {
  279. 'functionName': 'String.cat',
  280. 'arguments': {
  281. 'string1': {'constantValue': 'x'},
  282. 'string2': {'constantValue': 'y'}
  283. }}},
  284. {'functionDefinitionValue': {
  285. 'argumentNames': ['x', 'y'],
  286. 'body': {'argumentReference': 'y'}}
  287. }
  288. ]}}