earthengine-api 1.5.13rc0__py3-none-any.whl → 1.7.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of earthengine-api might be problematic. Click here for more details.

Files changed (102) hide show
  1. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/METADATA +3 -3
  2. earthengine_api-1.7.4.dist-info/RECORD +109 -0
  3. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/WHEEL +1 -1
  4. ee/__init__.py +29 -28
  5. ee/_arg_types.py +7 -6
  6. ee/_cloud_api_utils.py +95 -78
  7. ee/_helpers.py +17 -13
  8. ee/_state.py +105 -0
  9. ee/_utils.py +2 -1
  10. ee/apifunction.py +21 -19
  11. ee/apitestcase.py +33 -38
  12. ee/batch.py +87 -77
  13. ee/blob.py +10 -12
  14. ee/classifier.py +57 -59
  15. ee/cli/commands.py +178 -114
  16. ee/cli/eecli.py +1 -1
  17. ee/cli/utils.py +61 -42
  18. ee/clusterer.py +39 -41
  19. ee/collection.py +64 -54
  20. ee/computedobject.py +19 -16
  21. ee/confusionmatrix.py +9 -9
  22. ee/customfunction.py +13 -12
  23. ee/data.py +220 -322
  24. ee/daterange.py +10 -10
  25. ee/deprecation.py +21 -13
  26. ee/deserializer.py +25 -20
  27. ee/dictionary.py +11 -11
  28. ee/ee_array.py +22 -20
  29. ee/ee_date.py +23 -23
  30. ee/ee_list.py +15 -16
  31. ee/ee_number.py +11 -21
  32. ee/ee_string.py +24 -32
  33. ee/ee_types.py +4 -4
  34. ee/element.py +15 -15
  35. ee/encodable.py +7 -4
  36. ee/errormargin.py +4 -4
  37. ee/feature.py +68 -71
  38. ee/featurecollection.py +41 -40
  39. ee/filter.py +90 -92
  40. ee/function.py +8 -8
  41. ee/geometry.py +95 -93
  42. ee/image.py +238 -236
  43. ee/image_converter.py +4 -4
  44. ee/imagecollection.py +30 -27
  45. ee/join.py +13 -15
  46. ee/kernel.py +55 -57
  47. ee/mapclient.py +9 -9
  48. ee/model.py +29 -31
  49. ee/oauth.py +76 -63
  50. ee/pixeltype.py +6 -6
  51. ee/projection.py +5 -4
  52. ee/reducer.py +41 -41
  53. ee/serializer.py +14 -14
  54. ee/table_converter.py +7 -6
  55. ee/terrain.py +7 -9
  56. ee/tests/_cloud_api_utils_test.py +21 -6
  57. ee/tests/_helpers_test.py +57 -4
  58. ee/tests/_state_test.py +49 -0
  59. ee/tests/algorithms.json +85 -2
  60. ee/tests/apifunction_test.py +5 -5
  61. ee/tests/batch_test.py +135 -57
  62. ee/tests/blob_test.py +5 -5
  63. ee/tests/classifier_test.py +3 -3
  64. ee/tests/clusterer_test.py +3 -3
  65. ee/tests/collection_test.py +48 -13
  66. ee/tests/confusionmatrix_test.py +3 -3
  67. ee/tests/data_test.py +484 -55
  68. ee/tests/daterange_test.py +4 -4
  69. ee/tests/deprecation_test.py +6 -4
  70. ee/tests/deserializer_test.py +64 -5
  71. ee/tests/dictionary_test.py +12 -12
  72. ee/tests/ee_array_test.py +3 -3
  73. ee/tests/ee_date_test.py +4 -4
  74. ee/tests/ee_list_test.py +3 -3
  75. ee/tests/ee_number_test.py +75 -30
  76. ee/tests/ee_string_test.py +11 -3
  77. ee/tests/ee_test.py +40 -22
  78. ee/tests/element_test.py +2 -2
  79. ee/tests/errormargin_test.py +1 -1
  80. ee/tests/feature_test.py +10 -10
  81. ee/tests/featurecollection_test.py +3 -3
  82. ee/tests/filter_test.py +4 -4
  83. ee/tests/function_test.py +5 -5
  84. ee/tests/geometry_point_test.py +3 -3
  85. ee/tests/geometry_test.py +93 -52
  86. ee/tests/image_converter_test.py +1 -3
  87. ee/tests/image_test.py +3 -3
  88. ee/tests/imagecollection_test.py +3 -3
  89. ee/tests/join_test.py +3 -3
  90. ee/tests/kernel_test.py +7 -3
  91. ee/tests/model_test.py +17 -5
  92. ee/tests/oauth_test.py +189 -7
  93. ee/tests/pixeltype_test.py +6 -7
  94. ee/tests/projection_test.py +5 -6
  95. ee/tests/reducer_test.py +16 -3
  96. ee/tests/serializer_test.py +39 -12
  97. ee/tests/table_converter_test.py +51 -7
  98. ee/tests/terrain_test.py +11 -3
  99. earthengine_api-1.5.13rc0.dist-info/RECORD +0 -107
  100. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/entry_points.txt +0 -0
  101. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/licenses/LICENSE +0 -0
  102. {earthengine_api-1.5.13rc0.dist-info → earthengine_api-1.7.4.dist-info}/top_level.txt +0 -0
ee/tests/data_test.py CHANGED
@@ -2,7 +2,7 @@
2
2
  """Test for the ee.data module."""
3
3
 
4
4
  import json
5
- from typing import Any, Optional
5
+ from typing import Any
6
6
  from unittest import mock
7
7
 
8
8
  import googleapiclient
@@ -12,6 +12,7 @@ import requests
12
12
  import unittest
13
13
  import ee
14
14
  from ee import _cloud_api_utils
15
+ from ee import _state
15
16
  from ee import apitestcase
16
17
  from ee import featurecollection
17
18
  from ee import image
@@ -27,7 +28,7 @@ def NotFoundError() -> googleapiclient.errors.HttpError:
27
28
 
28
29
 
29
30
  def NewFolderAsset(
30
- name: str, quota: Optional[dict[str, int]] = None
31
+ name: str, quota: dict[str, int] | None = None
31
32
  ) -> dict[str, Any]:
32
33
  return {
33
34
  'type': 'FOLDER',
@@ -49,22 +50,71 @@ class DataTest(unittest.TestCase):
49
50
 
50
51
  def tearDown(self):
51
52
  super().tearDown()
53
+ ee.data.reset()
52
54
  mock.patch.stopall()
53
55
 
54
- def testIsInitialized(self):
56
+ def test_is_initialized(self):
55
57
  self.assertFalse(ee.data.is_initialized())
56
58
  with apitestcase.UsingCloudApi():
57
59
  self.assertTrue(ee.data.is_initialized())
58
60
 
59
- def testSetMaxRetries_badValues(self):
61
+ @mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
62
+ def test_initialize(self, mock_install_cloud_api_resource):
63
+ ee.data.initialize()
64
+
65
+ self.assertTrue(ee.data.is_initialized())
66
+ mock_install_cloud_api_resource.assert_called_once()
67
+
68
+ @mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
69
+ def test_initialize_with_project(
70
+ self, unused_mock_install_cloud_api_resource
71
+ ):
72
+ ee.data.initialize(project='my-project')
73
+
74
+ self.assertTrue(ee.data.is_initialized())
75
+ self.assertEqual(
76
+ _state.get_state().cloud_api_user_project, 'my-project'
77
+ )
78
+
79
+ @mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
80
+ def test_initialize_with_no_project(
81
+ self, unused_mock_install_cloud_api_resource
82
+ ):
83
+ ee.data.initialize()
84
+
85
+ self.assertTrue(ee.data.is_initialized())
86
+ self.assertEqual(
87
+ _state.get_state().cloud_api_user_project, 'earthengine-legacy'
88
+ )
89
+
90
+ @mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
91
+ def test_initialize_with_credentials(
92
+ self, unused_mock_install_cloud_api_resource
93
+ ):
94
+ creds = mock.MagicMock()
95
+ ee.data.initialize(credentials=creds)
96
+
97
+ self.assertTrue(ee.data.is_initialized())
98
+ self.assertEqual(creds, _state.get_state().credentials)
99
+
100
+ @mock.patch.object(ee.data, '_install_cloud_api_resource', return_value=None)
101
+ def test_initialize_with_cloud_api_key(
102
+ self, unused_mock_install_cloud_api_resource
103
+ ):
104
+ cloud_api_key = 'a cloud api key'
105
+ ee.data.initialize(cloud_api_key=cloud_api_key)
106
+
107
+ self.assertTrue(ee.data.is_initialized())
108
+ self.assertEqual(cloud_api_key, _state.get_state().cloud_api_key)
109
+
110
+ def test_set_max_retries_bad_values(self):
60
111
  with self.assertRaises(ValueError):
61
112
  ee.data.setMaxRetries(-1)
62
113
  with self.assertRaises(ValueError):
63
114
  ee.data.setMaxRetries(100)
64
115
 
65
- def testSetMaxRetries(self):
116
+ def test_set_max_retries(self):
66
117
  mock_result = {'result': 5}
67
- original_max_retries = ee.data._max_retries
68
118
  ee.data.setMaxRetries(3)
69
119
  cloud_api_resource = mock.MagicMock()
70
120
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -79,9 +129,48 @@ class DataTest(unittest.TestCase):
79
129
  .compute()
80
130
  .execute.call_args.kwargs['num_retries'],
81
131
  )
82
- ee.data._max_retries = original_max_retries
83
132
 
84
- def testListOperations(self):
133
+ def test_set_cloud_api_key(self):
134
+ cloud_api_key = 'a cloud api key'
135
+ with mock.patch.object(
136
+ ee.data, '_install_cloud_api_resource', return_value=None
137
+ ) as mock_install_cloud_api_resource:
138
+ ee.data.setCloudApiKey(cloud_api_key)
139
+ self.assertEqual(cloud_api_key, _state.get_state().cloud_api_key)
140
+ mock_install_cloud_api_resource.assert_called_once()
141
+
142
+ def test_set_deadline(self):
143
+ deadline_ms = 12345
144
+ with mock.patch.object(
145
+ ee.data, '_install_cloud_api_resource', return_value=None
146
+ ) as mock_install_cloud_api_resource:
147
+ ee.data.setDeadline(deadline_ms)
148
+ self.assertEqual(deadline_ms, _state.get_state().deadline_ms)
149
+ mock_install_cloud_api_resource.assert_called_once()
150
+
151
+ def test_get_set_user_agent(self):
152
+ self.assertIsNone(ee.data.getUserAgent())
153
+ user_agent = 'user-agent'
154
+ ee.data.setUserAgent(user_agent)
155
+ self.assertEqual(user_agent, ee.data.getUserAgent())
156
+
157
+ def test_authorize_http_no_credentials(self):
158
+ self.assertIsNone(ee.data._get_state().credentials)
159
+ http = mock.MagicMock()
160
+ self.assertEqual(http, ee.data.authorizeHttp(http))
161
+
162
+ def test_authorize_http_with_credentials(self):
163
+ creds = mock.MagicMock()
164
+ ee.data._get_state().credentials = creds
165
+ http = mock.MagicMock()
166
+ with mock.patch.object(
167
+ ee.data.google_auth_httplib2, 'AuthorizedHttp'
168
+ ) as mock_authorized_http:
169
+ result = ee.data.authorizeHttp(http)
170
+ self.assertEqual(mock_authorized_http.return_value, result)
171
+ mock_authorized_http.assert_called_once_with(creds)
172
+
173
+ def test_list_operations(self):
85
174
  mock_http = mock.MagicMock(httplib2.Http)
86
175
  # Return in three groups.
87
176
  mock_http.request.side_effect = [
@@ -101,14 +190,120 @@ class DataTest(unittest.TestCase):
101
190
  'name': 'name3'
102
191
  }], ee.data.listOperations())
103
192
 
104
- def testListOperationsEmptyList(self):
193
+ def test_list_operations_empty_list(self):
105
194
  # Empty lists don't appear at all in the result.
106
195
  mock_http = mock.MagicMock(httplib2.Http)
107
196
  mock_http.request.return_value = (httplib2.Response({'status': 200}), b'{}')
108
197
  with apitestcase.UsingCloudApi(mock_http=mock_http):
109
198
  self.assertEqual([], ee.data.listOperations())
110
199
 
111
- def testCreateAsset(self):
200
+ def test_get_operation(self):
201
+ cloud_api_resource = mock.MagicMock()
202
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
203
+ name = 'projects/test-project/operations/foo'
204
+ cloud_api_resource.projects().operations().get.execute.return_value = {
205
+ 'name': name,
206
+ 'done': False,
207
+ }
208
+ ee.data.getOperation(name)
209
+ cloud_api_resource.projects().operations().get.assert_called_once_with(
210
+ name=name
211
+ )
212
+
213
+ def test_get_task_status(self):
214
+ cloud_api_resource = mock.MagicMock()
215
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
216
+ cloud_api_resource.projects().operations().get.return_value.execute.return_value = {
217
+ 'name': 'projects/earthengine-legacy/operations/foo',
218
+ 'done': False,
219
+ 'metadata': {'state': 'RUNNING'},
220
+ }
221
+ result = ee.data.getTaskStatus('foo')
222
+ cloud_api_resource.projects().operations().get.assert_called_once_with(
223
+ name='projects/earthengine-legacy/operations/foo'
224
+ )
225
+ self.assertEqual(
226
+ result,
227
+ [{
228
+ 'id': 'foo',
229
+ 'state': 'RUNNING',
230
+ 'name': 'projects/earthengine-legacy/operations/foo',
231
+ }],
232
+ )
233
+
234
+ def test_get_task_status_with_not_found(self):
235
+ cloud_api_resource = mock.MagicMock()
236
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
237
+ cloud_api_resource.projects().operations().get.return_value.execute.side_effect = [
238
+ {
239
+ 'name': 'projects/earthengine-legacy/operations/foo',
240
+ 'done': False,
241
+ 'metadata': {'state': 'RUNNING'},
242
+ },
243
+ NotFoundError(),
244
+ {
245
+ 'name': 'projects/earthengine-legacy/operations/bar',
246
+ 'done': True,
247
+ 'metadata': {'state': 'SUCCEEDED'},
248
+ },
249
+ ]
250
+ result = ee.data.getTaskStatus(['foo', 'missing', 'bar'])
251
+ cloud_api_resource.projects().operations().get.assert_has_calls([
252
+ mock.call(name='projects/earthengine-legacy/operations/foo'),
253
+ mock.call().execute(num_retries=5),
254
+ mock.call(name='projects/earthengine-legacy/operations/missing'),
255
+ mock.call().execute(num_retries=5),
256
+ mock.call(name='projects/earthengine-legacy/operations/bar'),
257
+ mock.call().execute(num_retries=5),
258
+ ])
259
+ self.assertEqual(
260
+ 3,
261
+ cloud_api_resource.projects()
262
+ .operations()
263
+ .get.return_value.execute.call_count,
264
+ )
265
+ self.assertEqual(
266
+ result,
267
+ [
268
+ {
269
+ 'id': 'foo',
270
+ 'state': 'RUNNING',
271
+ 'name': 'projects/earthengine-legacy/operations/foo',
272
+ },
273
+ {
274
+ 'id': 'missing',
275
+ 'state': 'UNKNOWN',
276
+ 'name': 'projects/earthengine-legacy/operations/missing',
277
+ },
278
+ {
279
+ 'id': 'bar',
280
+ 'state': 'COMPLETED',
281
+ 'name': 'projects/earthengine-legacy/operations/bar',
282
+ },
283
+ ],
284
+ )
285
+
286
+ def test_cancel_operation(self):
287
+ cloud_api_resource = mock.MagicMock()
288
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
289
+ cancel_mock = cloud_api_resource.projects().operations().cancel
290
+ cancel_mock.execute.return_value = {}
291
+ ee.data.cancelOperation('projects/test-project/operations/foo')
292
+ cancel_mock.assert_called_once_with(
293
+ name='projects/test-project/operations/foo', body={}
294
+ )
295
+
296
+ def test_cancel_task(self):
297
+ cloud_api_resource = mock.MagicMock()
298
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
299
+ cancel_mock = cloud_api_resource.projects().operations().cancel
300
+ cancel_mock.execute.return_value = {}
301
+ ee.data.cancelTask('foo')
302
+ cancel_mock.assert_called_once_with(
303
+ name='projects/earthengine-legacy/operations/foo', body={}
304
+ )
305
+
306
+ def test_create_asset(self):
112
307
  cloud_api_resource = mock.MagicMock()
113
308
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
114
309
  mock_result = {
@@ -129,7 +324,7 @@ class DataTest(unittest.TestCase):
129
324
  asset = mock_create_asset.call_args.kwargs['body']
130
325
  self.assertEqual(asset, {'type': 'FOLDER'})
131
326
 
132
- def testCreateAssetWithV1AlphaParams(self):
327
+ def test_create_asset_with_v1alpha_params(self):
133
328
  cloud_api_resource = mock.MagicMock()
134
329
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
135
330
  mock_result = {
@@ -186,7 +381,7 @@ class DataTest(unittest.TestCase):
186
381
  {'uris': ['gs://my-bucket/path']},
187
382
  )
188
383
 
189
- def testCreateFolder(self):
384
+ def test_create_folder(self):
190
385
  cloud_api_resource = mock.MagicMock()
191
386
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
192
387
  mock_result = {
@@ -207,7 +402,15 @@ class DataTest(unittest.TestCase):
207
402
  asset = mock_create_asset.call_args.kwargs['body']
208
403
  self.assertEqual(asset, {'type': 'FOLDER'})
209
404
 
210
- def testCreateAssets(self):
405
+ @mock.patch.object(ee.data, 'createAsset')
406
+ def test_create_asset_home(self, mock_create_asset):
407
+ ee.data.createAssetHome('users/test')
408
+ mock_create_asset.assert_called_once_with({
409
+ 'name': 'projects/earthengine-legacy/assets/users/test',
410
+ 'type': 'FOLDER',
411
+ })
412
+
413
+ def test_create_assets(self):
211
414
  cloud_api_resource = mock.MagicMock()
212
415
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
213
416
  asset_name = 'projects/some-project/assets/some-asset'
@@ -223,14 +426,14 @@ class DataTest(unittest.TestCase):
223
426
  prettyPrint=False,
224
427
  )
225
428
 
226
- def testCreateAssets_empty(self):
429
+ def test_create_assets_empty(self):
227
430
  cloud_api_resource = mock.MagicMock()
228
431
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
229
432
  ee.data.create_assets([], 'FOLDER', False)
230
433
  mock_create_asset = cloud_api_resource.projects().assets().create
231
434
  mock_create_asset.assert_not_called()
232
435
 
233
- def testCreateAssets_noOpIfAssetExists(self):
436
+ def test_create_assets_no_op_if_asset_exists(self):
234
437
  cloud_api_resource = mock.MagicMock()
235
438
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
236
439
  asset_name = 'projects/some-project/assets/some-asset'
@@ -241,7 +444,7 @@ class DataTest(unittest.TestCase):
241
444
  mock_create_asset = cloud_api_resource.projects().assets().create
242
445
  mock_create_asset.assert_not_called()
243
446
 
244
- def testCreateAssets_withParents(self):
447
+ def test_create_assets_with_parents(self):
245
448
  cloud_api_resource = mock.MagicMock()
246
449
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
247
450
  asset_name = 'projects/some-project/assets/foo/bar'
@@ -267,7 +470,7 @@ class DataTest(unittest.TestCase):
267
470
  mock.call().execute(num_retries=5),
268
471
  ])
269
472
 
270
- def testStartIngestion(self):
473
+ def test_start_ingestion(self):
271
474
  cloud_api_resource = mock.MagicMock()
272
475
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
273
476
  mock_result = {'name': 'operations/ingestion', 'done': False}
@@ -297,7 +500,69 @@ class DataTest(unittest.TestCase):
297
500
  )
298
501
  self.assertTrue(import_args['overwrite'])
299
502
 
300
- def testSetAssetProperties(self):
503
+ def test_start_table_ingestion(self):
504
+ cloud_api_resource = mock.MagicMock()
505
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
506
+ mock_result = {'name': 'operations/ingestion', 'done': False}
507
+ cloud_api_resource.projects().table().import_.return_value.execute.return_value = (
508
+ mock_result
509
+ )
510
+ params = {
511
+ 'id': 'users/test/table',
512
+ 'sources': [{'uris': ['gs://bucket/file.shp'], 'charset': 'UTF-8'}],
513
+ }
514
+ result = ee.data.startTableIngestion('request_id', params, True)
515
+ self.assertEqual(result['id'], 'ingestion')
516
+ self.assertEqual(result['name'], 'operations/ingestion')
517
+
518
+ mock_import = cloud_api_resource.projects().table().import_
519
+ mock_import.assert_called_once()
520
+ call_kwargs = mock_import.call_args.kwargs
521
+ self.assertEqual(call_kwargs['project'], 'projects/earthengine-legacy')
522
+ body = call_kwargs['body']
523
+ self.assertEqual(
524
+ body['tableManifest'],
525
+ {
526
+ 'name': 'projects/earthengine-legacy/assets/users/test/table',
527
+ 'sources': [
528
+ {'uris': ['gs://bucket/file.shp'], 'charset': 'UTF-8'}
529
+ ],
530
+ },
531
+ )
532
+ self.assertEqual(body['requestId'], 'request_id')
533
+ self.assertTrue(body['overwrite'])
534
+
535
+ def test_start_external_image_ingestion(self):
536
+ cloud_api_resource = mock.MagicMock()
537
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
538
+ cloud_api_resource.projects().image().importExternal.return_value.execute.return_value = (
539
+ {}
540
+ )
541
+ manifest = {
542
+ 'id': 'users/test/image',
543
+ 'tilesets': [{'sources': [{'uris': ['gs://bucket/file.tif']}]}],
544
+ }
545
+ result = ee.data.startExternalImageIngestion(manifest, True)
546
+ expected_name = 'projects/earthengine-legacy/assets/users/test/image'
547
+ self.assertEqual(result['name'], expected_name)
548
+
549
+ mock_import_external = (
550
+ cloud_api_resource.projects().image().importExternal
551
+ )
552
+ mock_import_external.assert_called_once()
553
+ call_kwargs = mock_import_external.call_args.kwargs
554
+ self.assertEqual(call_kwargs['project'], 'projects/earthengine-legacy')
555
+ body = call_kwargs['body']
556
+ self.assertEqual(
557
+ body['imageManifest'],
558
+ {
559
+ 'name': expected_name,
560
+ 'tilesets': [{'sources': [{'uris': ['gs://bucket/file.tif']}]}],
561
+ },
562
+ )
563
+ self.assertTrue(body['overwrite'])
564
+
565
+ def test_set_asset_properties(self):
301
566
  mock_http = mock.MagicMock(httplib2.Http)
302
567
  with apitestcase.UsingCloudApi(mock_http=mock_http), mock.patch.object(
303
568
  ee.data, 'updateAsset', autospec=True) as mock_update_asset:
@@ -315,10 +580,22 @@ class DataTest(unittest.TestCase):
315
580
  update_mask = mock_update_asset.call_args[0][2]
316
581
  self.assertSetEqual(
317
582
  set(update_mask),
318
- set(['properties.\"mYPropErTy\"',
319
- 'properties.\"system:time_start\"']))
583
+ {'properties.\"mYPropErTy\"',
584
+ 'properties.\"system:time_start\"'})
585
+
586
+ def test_update_asset(self):
587
+ cloud_api_resource = mock.MagicMock()
588
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
589
+ asset_id = 'users/test/asset'
590
+ asset = {'properties': {'foo': 'bar'}}
591
+ update_mask = ['properties.foo']
592
+ ee.data.updateAsset(asset_id, asset, update_mask)
593
+ cloud_api_resource.projects().assets().patch.assert_called_once_with(
594
+ name='projects/earthengine-legacy/assets/users/test/asset',
595
+ body={'updateMask': {'paths': update_mask}, 'asset': asset},
596
+ )
320
597
 
321
- def testListAssets(self):
598
+ def test_list_assets(self):
322
599
  cloud_api_resource = mock.MagicMock()
323
600
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
324
601
  mock_result = {'assets': [{'path': 'id1', 'type': 'type1'}]}
@@ -330,7 +607,7 @@ class DataTest(unittest.TestCase):
330
607
  ).execute.assert_called_once()
331
608
  self.assertEqual(mock_result, actual_result)
332
609
 
333
- def testListAssetsWithPageSize(self):
610
+ def test_list_assets_with_page_size(self):
334
611
  mock_http = mock.MagicMock(httplib2.Http)
335
612
  ok_resp = httplib2.Response({'status': 200})
336
613
  page = (
@@ -347,7 +624,7 @@ class DataTest(unittest.TestCase):
347
624
  }
348
625
  self.assertEqual(expected_result, actual_result)
349
626
 
350
- def testListAssetsMultiplePages(self):
627
+ def test_list_assets_multiple_pages(self):
351
628
  mock_http = mock.MagicMock(httplib2.Http)
352
629
  ok_resp = httplib2.Response({'status': 200})
353
630
  page1 = (
@@ -373,7 +650,7 @@ class DataTest(unittest.TestCase):
373
650
  }
374
651
  self.assertEqual(expected_result, actual_result)
375
652
 
376
- def testListImages(self):
653
+ def test_list_images(self):
377
654
  cloud_api_resource = mock.MagicMock()
378
655
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
379
656
  mock_result = {'assets': [{'path': 'id1', 'type': 'type1'}]}
@@ -388,7 +665,7 @@ class DataTest(unittest.TestCase):
388
665
  'type': 'type1'
389
666
  }]}, actual_result)
390
667
 
391
- def testListImagesWithPageSize(self):
668
+ def test_list_images_with_page_size(self):
392
669
  mock_http = mock.MagicMock(httplib2.Http)
393
670
  ok_resp = httplib2.Response({'status': 200})
394
671
  page = (
@@ -405,7 +682,7 @@ class DataTest(unittest.TestCase):
405
682
  }
406
683
  self.assertEqual(expected_result, actual_result)
407
684
 
408
- def testListImagesMultiplePages(self):
685
+ def test_list_images_multiple_pages(self):
409
686
  mock_http = mock.MagicMock(httplib2.Http)
410
687
  ok_resp = httplib2.Response({'status': 200})
411
688
  page1 = (
@@ -431,7 +708,7 @@ class DataTest(unittest.TestCase):
431
708
  }
432
709
  self.assertEqual(expected_result, actual_result)
433
710
 
434
- def testListBuckets(self):
711
+ def test_list_buckets(self):
435
712
  cloud_api_resource = mock.MagicMock()
436
713
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
437
714
  mock_result = {'assets': [{'name': 'id1', 'type': 'FOLDER'}]}
@@ -441,7 +718,17 @@ class DataTest(unittest.TestCase):
441
718
  cloud_api_resource.projects().listAssets().execute.assert_called_once()
442
719
  self.assertEqual(mock_result, actual_result)
443
720
 
444
- def testSimpleGetListViaCloudApi(self):
721
+ def test_get_asset_roots(self):
722
+ with mock.patch.object(
723
+ ee.data,
724
+ 'listBuckets',
725
+ return_value={'assets': [{'name': 'id1', 'type': 'FOLDER'}]},
726
+ ) as mock_list_buckets:
727
+ result = ee.data.getAssetRoots()
728
+ mock_list_buckets.assert_called_once()
729
+ self.assertEqual([{'id': 'id1', 'type': 'Folder'}], result)
730
+
731
+ def test_simple_get_list_via_cloud_api(self):
445
732
  cloud_api_resource = mock.MagicMock()
446
733
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
447
734
  mock_result = {'assets': [{'name': 'id1', 'type': 'IMAGE_COLLECTION'}]}
@@ -458,7 +745,7 @@ class DataTest(unittest.TestCase):
458
745
  **expected_params)
459
746
  self.assertEqual(expected_result, actual_result)
460
747
 
461
- def testGetListAssetRootViaCloudApi(self):
748
+ def test_get_list_asset_root_via_cloud_api(self):
462
749
  cloud_api_resource = mock.MagicMock()
463
750
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
464
751
  mock_result = {'assets': [{'name': 'id1', 'type': 'IMAGE_COLLECTION'}]}
@@ -478,7 +765,7 @@ class DataTest(unittest.TestCase):
478
765
  **expected_params)
479
766
  self.assertEqual(expected_result, actual_result)
480
767
 
481
- def testGetListAssetRootViaCloudApiNoSlash(self):
768
+ def test_get_list_asset_root_via_cloud_api_no_slash(self):
482
769
  cloud_api_resource = mock.MagicMock()
483
770
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
484
771
  mock_result = {'assets': [{'name': 'id1', 'type': 'IMAGE_COLLECTION'}]}
@@ -498,7 +785,7 @@ class DataTest(unittest.TestCase):
498
785
  **expected_params)
499
786
  self.assertEqual(expected_result, actual_result)
500
787
 
501
- def testComplexGetListViaCloudApi(self):
788
+ def test_complex_get_list_via_cloud_api(self):
502
789
  cloud_api_resource = mock.MagicMock()
503
790
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
504
791
  mock_result = {
@@ -527,7 +814,7 @@ class DataTest(unittest.TestCase):
527
814
  **expected_params)
528
815
  self.assertEqual(expected_result, actual_result)
529
816
 
530
- def testGetMapId(self):
817
+ def test_get_map_id(self):
531
818
  cloud_api_resource = mock.MagicMock()
532
819
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
533
820
  mock_result = {
@@ -544,7 +831,7 @@ class DataTest(unittest.TestCase):
544
831
  self.assertEqual('', actual_result['token'])
545
832
  self.assertIsInstance(actual_result['tile_fetcher'], ee.data.TileFetcher)
546
833
 
547
- def testGetMapId_withWorkloadTag(self):
834
+ def test_get_map_id_with_workload_tag(self):
548
835
  with ee.data.workloadTagContext('mapid-tag'):
549
836
  cloud_api_resource = mock.MagicMock()
550
837
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -561,7 +848,7 @@ class DataTest(unittest.TestCase):
561
848
  cloud_api_resource.projects().maps().create.call_args_list[1]
562
849
  .kwargs['workloadTag'])
563
850
 
564
- def testGetDownloadId(self):
851
+ def test_get_download_id(self):
565
852
  cloud_api_resource = mock.MagicMock()
566
853
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
567
854
  mock_result = {'name': 'projects/earthengine-legacy/thumbnails/DOCID'}
@@ -579,7 +866,7 @@ class DataTest(unittest.TestCase):
579
866
  'token': ''
580
867
  }, actual_result)
581
868
 
582
- def testGetDownloadId_withWorkloadTag(self):
869
+ def test_get_download_id_with_workload_tag(self):
583
870
  with ee.data.workloadTagContext('downloadid-tag'):
584
871
  cloud_api_resource = mock.MagicMock()
585
872
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -595,7 +882,7 @@ class DataTest(unittest.TestCase):
595
882
  cloud_api_resource.projects().thumbnails().create.call_args
596
883
  .kwargs['workloadTag'])
597
884
 
598
- def testGetDownloadId_withBandList(self):
885
+ def test_get_download_id_with_band_list(self):
599
886
  cloud_api_resource = mock.MagicMock()
600
887
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
601
888
  mock_result = {'name': 'projects/earthengine-legacy/thumbnails/DOCID'}
@@ -614,14 +901,14 @@ class DataTest(unittest.TestCase):
614
901
  'token': ''
615
902
  }, actual_result)
616
903
 
617
- def testGetDownloadId_withImageID(self):
904
+ def test_get_download_id_with_image_id(self):
618
905
  cloud_api_resource = mock.MagicMock()
619
906
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
620
907
  with self.assertRaisesRegex(ee.ee_exception.EEException,
621
908
  '^Image ID string is not supported.'):
622
909
  ee.data.getDownloadId({'id': 'my-image', 'name': 'dummy'})
623
910
 
624
- def testGetDownloadId_withSerializedImage(self):
911
+ def test_get_download_id_with_serialized_image(self):
625
912
  cloud_api_resource = mock.MagicMock()
626
913
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
627
914
  with self.assertRaisesRegex(ee.ee_exception.EEException,
@@ -631,7 +918,7 @@ class DataTest(unittest.TestCase):
631
918
  'name': 'dummy'
632
919
  })
633
920
 
634
- def testGetThumbId(self):
921
+ def test_get_thumb_id(self):
635
922
  cloud_api_resource = mock.MagicMock()
636
923
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
637
924
  mock_result = {'name': 'projects/earthengine-legacy/thumbnails/DOCID'}
@@ -649,7 +936,7 @@ class DataTest(unittest.TestCase):
649
936
  'token': ''
650
937
  }, actual_result)
651
938
 
652
- def testGetThumbId_withWorkloadTag(self):
939
+ def test_get_thumb_id_with_workload_tag(self):
653
940
  with ee.data.workloadTagContext('thumbid-tag'):
654
941
  cloud_api_resource = mock.MagicMock()
655
942
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -662,7 +949,7 @@ class DataTest(unittest.TestCase):
662
949
  cloud_api_resource.projects().thumbnails().create.call_args
663
950
  .kwargs['workloadTag'])
664
951
 
665
- def testGetTableDownloadId(self):
952
+ def test_get_table_download_id(self):
666
953
  cloud_api_resource = mock.MagicMock()
667
954
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
668
955
  mock_result = {'name': 'projects/earthengine-legacy/table/DOCID'}
@@ -680,7 +967,7 @@ class DataTest(unittest.TestCase):
680
967
  'token': ''
681
968
  }, actual_result)
682
969
 
683
- def testGetTableDownloadId_withWorkloadTag(self):
970
+ def test_get_table_download_id_with_workload_tag(self):
684
971
  with ee.data.workloadTagContext('tableid-tag'):
685
972
  cloud_api_resource = mock.MagicMock()
686
973
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
@@ -696,7 +983,7 @@ class DataTest(unittest.TestCase):
696
983
  cloud_api_resource.projects().tables().create.call_args
697
984
  .kwargs['workloadTag'])
698
985
 
699
- def testCloudProfilingEnabled(self):
986
+ def test_cloud_profiling_enabled(self):
700
987
  seen = []
701
988
 
702
989
  def ProfileHook(profile_id):
@@ -707,11 +994,11 @@ class DataTest(unittest.TestCase):
707
994
  ee.data.listImages({'parent': 'projects/earthengine-public/assets/q'})
708
995
  self.assertEqual(['someProfileId'], seen)
709
996
 
710
- def testCloudProfilingDisabled(self):
997
+ def test_cloud_profiling_disabled(self):
711
998
  with apitestcase.UsingCloudApi(), DoCloudProfileStubHttp(self, False):
712
999
  ee.data.listImages({'parent': 'projects/earthengine-public/assets/q'})
713
1000
 
714
- def testCloudErrorTranslation(self):
1001
+ def test_cloud_error_translation(self):
715
1002
  mock_http = mock.MagicMock(httplib2.Http)
716
1003
  mock_http.request.return_value = (httplib2.Response({'status': 400}),
717
1004
  b'{"error": {"message": "errorly"} }')
@@ -719,7 +1006,7 @@ class DataTest(unittest.TestCase):
719
1006
  with self.assertRaisesRegex(ee.ee_exception.EEException, '^errorly$'):
720
1007
  ee.data.listImages({'parent': 'projects/earthengine-public/assets/q'})
721
1008
 
722
- def testListFeatures(self):
1009
+ def test_list_features(self):
723
1010
  cloud_api_resource = mock.MagicMock()
724
1011
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
725
1012
  mock_result = {
@@ -746,9 +1033,53 @@ class DataTest(unittest.TestCase):
746
1033
  ).execute.assert_called_once()
747
1034
  self.assertEqual(mock_result, actual_result)
748
1035
 
749
- @mock.patch.object(ee.data, '_tile_base_url', new='base_url')
750
- def testGetFeatureViewTilesKey(self):
1036
+ def test_get_pixels(self):
1037
+ cloud_api_resource_raw = mock.MagicMock()
1038
+ with apitestcase.UsingCloudApi(
1039
+ cloud_api_resource_raw=cloud_api_resource_raw
1040
+ ):
1041
+ assets = cloud_api_resource_raw.projects().assets()
1042
+ mock_result = b'pixel data'
1043
+ assets.getPixels.return_value.execute.return_value = mock_result
1044
+ asset_id = 'users/foo/bar'
1045
+ params = {'assetId': asset_id}
1046
+ result = ee.data.getPixels(params)
1047
+ self.assertEqual(mock_result, result)
1048
+ assets.getPixels.assert_called_once_with(
1049
+ name='projects/earthengine-legacy/assets/users/foo/bar',
1050
+ body={'fileFormat': 'AUTO_JPEG_PNG'},
1051
+ )
1052
+
1053
+ def test_compute_pixels(self):
1054
+ cloud_api_resource_raw = mock.MagicMock()
1055
+ with apitestcase.UsingCloudApi(
1056
+ cloud_api_resource_raw=cloud_api_resource_raw
1057
+ ):
1058
+ mock_result = b'pixel data'
1059
+ (
1060
+ cloud_api_resource_raw.projects()
1061
+ .image()
1062
+ .computePixels.return_value.execute.return_value
1063
+ ) = mock_result
1064
+ expression = ee.Image(1)
1065
+ params = {'expression': expression}
1066
+ result = ee.data.computePixels(params)
1067
+ self.assertEqual(mock_result, result)
1068
+ (
1069
+ cloud_api_resource_raw.projects()
1070
+ .image()
1071
+ .computePixels.assert_called_once_with(
1072
+ project='projects/earthengine-legacy',
1073
+ body={
1074
+ 'expression': ee.serializer.encode(expression),
1075
+ 'fileFormat': 'AUTO_JPEG_PNG',
1076
+ },
1077
+ )
1078
+ )
1079
+
1080
+ def test_get_feature_view_tiles_key(self):
751
1081
  cloud_api_resource = mock.MagicMock()
1082
+ _state.get_state().tile_base_url = 'base_url'
752
1083
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
753
1084
  mock_name = 'projects/projectfoo/featureView/tiles-key-foo'
754
1085
  mock_result = {'name': mock_name}
@@ -769,7 +1100,7 @@ class DataTest(unittest.TestCase):
769
1100
  f'base_url/{_cloud_api_utils.VERSION}/{mock_name}/tiles/7/5/6',
770
1101
  actual_result['formatTileUrl'](5, 6, 7))
771
1102
 
772
- def testGetProjectConfig(self) -> None:
1103
+ def test_get_project_config(self) -> None:
773
1104
  cloud_api_resource = mock.MagicMock()
774
1105
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
775
1106
  mock_result = {'fake-project-config-value': 1}
@@ -780,20 +1111,43 @@ class DataTest(unittest.TestCase):
780
1111
  cloud_api_resource.projects().getConfig().execute.assert_called_once()
781
1112
  self.assertEqual(mock_result, actual_result)
782
1113
 
783
- def testUpdateProjectConfig(self) -> None:
1114
+ def test_update_project_config(self) -> None:
784
1115
  cloud_api_resource = mock.MagicMock()
785
1116
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
786
1117
  mock_result = {'fake-project-config-value': 1}
787
1118
  cloud_api_resource.projects().updateConfig().execute.return_value = (
788
1119
  mock_result
789
1120
  )
1121
+ project_config = {'maxConcurrentExports': 2}
790
1122
  actual_result = ee.data.updateProjectConfig(
791
- {'maxConcurrentExports': 2}, ['max_concurrent_exports']
1123
+ project_config, ['max_concurrent_exports']
1124
+ )
1125
+ cloud_api_resource.projects().updateConfig.assert_called_with(
1126
+ name='projects/earthengine-legacy/config',
1127
+ body=project_config,
1128
+ updateMask='max_concurrent_exports',
792
1129
  )
793
1130
  cloud_api_resource.projects().updateConfig().execute.assert_called_once()
794
1131
  self.assertEqual(mock_result, actual_result)
795
1132
 
796
- def testWorkloadTag(self):
1133
+ def test_update_project_config_no_mask(self) -> None:
1134
+ cloud_api_resource = mock.MagicMock()
1135
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
1136
+ mock_result = {'fake-project-config-value': 1}
1137
+ cloud_api_resource.projects().updateConfig().execute.return_value = (
1138
+ mock_result
1139
+ )
1140
+ project_config = {'maxConcurrentExports': 2}
1141
+ actual_result = ee.data.updateProjectConfig(project_config)
1142
+ cloud_api_resource.projects().updateConfig.assert_called_with(
1143
+ name='projects/earthengine-legacy/config',
1144
+ body=project_config,
1145
+ updateMask='max_concurrent_exports',
1146
+ )
1147
+ cloud_api_resource.projects().updateConfig().execute.assert_called_once()
1148
+ self.assertEqual(mock_result, actual_result)
1149
+
1150
+ def test_workload_tag(self):
797
1151
  self.assertEqual('', ee.data.getWorkloadTag())
798
1152
  ee.data.setDefaultWorkloadTag(None)
799
1153
  self.assertEqual('', ee.data.getWorkloadTag())
@@ -851,13 +1205,13 @@ class DataTest(unittest.TestCase):
851
1205
  ee.data.resetWorkloadTag(True)
852
1206
  self.assertEqual('', ee.data.getWorkloadTag())
853
1207
 
854
- def testResetWorkloadTagOptParams(self):
1208
+ def test_reset_workload_tag_opt_params(self):
855
1209
  ee.data.setDefaultWorkloadTag('reset-me')
856
1210
  self.assertEqual('reset-me', ee.data.getWorkloadTag())
857
1211
  ee.data.resetWorkloadTag(opt_resetDefault=True)
858
1212
  self.assertEqual('', ee.data.getWorkloadTag())
859
1213
 
860
- def testGetAssetRootQuota_V1Alpha(self):
1214
+ def test_get_asset_root_quota_v1alpha(self):
861
1215
  cloud_api_resource = mock.MagicMock()
862
1216
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
863
1217
  fake_asset = {
@@ -881,7 +1235,7 @@ class DataTest(unittest.TestCase):
881
1235
  }
882
1236
  self.assertEqual(expected, quota)
883
1237
 
884
- def testGetAssetRootQuota(self):
1238
+ def test_get_asset_root_quota(self):
885
1239
  cloud_api_resource = mock.MagicMock()
886
1240
  with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
887
1241
  fake_asset = {
@@ -905,6 +1259,81 @@ class DataTest(unittest.TestCase):
905
1259
  }
906
1260
  self.assertEqual(expected, quota)
907
1261
 
1262
+ def test_get_asset_root_quota_not_root(self):
1263
+ cloud_api_resource = mock.MagicMock()
1264
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
1265
+ asset_id = 'users/test/asset'
1266
+ fake_asset = {
1267
+ 'type': 'IMAGE',
1268
+ 'name': 'projects/earthengine-legacy/assets/users/test/asset',
1269
+ }
1270
+ cloud_api_resource.projects().assets().get().execute.return_value = (
1271
+ fake_asset
1272
+ )
1273
+ with self.assertRaisesRegex(
1274
+ ee.ee_exception.EEException, f'{asset_id} is not a root folder.'
1275
+ ):
1276
+ ee.data.getAssetRootQuota(asset_id)
1277
+
1278
+ def test_get_iam_policy(self):
1279
+ cloud_api_resource = mock.MagicMock()
1280
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
1281
+ asset_id = 'users/test/asset'
1282
+ ee.data.getIamPolicy(asset_id)
1283
+ cloud_api_resource.projects().assets().getIamPolicy.assert_called_once_with(
1284
+ resource='projects/earthengine-legacy/assets/users/test/asset',
1285
+ body={},
1286
+ prettyPrint=False,
1287
+ )
1288
+
1289
+ def test_get_asset_acl(self):
1290
+ asset_id = 'users/test/asset'
1291
+ policy = {'bindings': [{'role': 'roles/viewer', 'members': ['allUsers']}]}
1292
+ acl = {'readers': ['allUsers']}
1293
+ with mock.patch.object(
1294
+ ee.data, 'getIamPolicy', return_value=policy
1295
+ ) as mock_get_iam_policy, mock.patch.object(
1296
+ ee.data._cloud_api_utils, 'convert_iam_policy_to_acl', return_value=acl
1297
+ ) as mock_convert:
1298
+ result = ee.data.getAssetAcl(asset_id)
1299
+ mock_get_iam_policy.assert_called_once_with(asset_id)
1300
+ mock_convert.assert_called_once_with(policy)
1301
+ self.assertEqual(acl, result)
1302
+
1303
+ def test_set_asset_acl(self):
1304
+ asset_id = 'users/test/asset'
1305
+ acl_update_dict = {'readers': ['allUsers']}
1306
+ acl_update_str = '{"readers": ["allUsers"]}'
1307
+ policy = {'bindings': [{'role': 'roles/viewer', 'members': ['allUsers']}]}
1308
+ with mock.patch.object(
1309
+ ee.data._cloud_api_utils,
1310
+ 'convert_acl_to_iam_policy',
1311
+ return_value=policy,
1312
+ ) as mock_convert, mock.patch.object(
1313
+ ee.data, 'setIamPolicy'
1314
+ ) as mock_set_iam_policy:
1315
+ ee.data.setAssetAcl(asset_id, acl_update_dict)
1316
+ mock_convert.assert_called_once_with(acl_update_dict)
1317
+ mock_set_iam_policy.assert_called_once_with(asset_id, policy)
1318
+
1319
+ mock_convert.reset_mock()
1320
+ mock_set_iam_policy.reset_mock()
1321
+ ee.data.setAssetAcl(asset_id, acl_update_str)
1322
+ mock_convert.assert_called_once_with(acl_update_dict)
1323
+ mock_set_iam_policy.assert_called_once_with(asset_id, policy)
1324
+
1325
+ def test_set_iam_policy(self):
1326
+ cloud_api_resource = mock.MagicMock()
1327
+ with apitestcase.UsingCloudApi(cloud_api_resource=cloud_api_resource):
1328
+ asset_id = 'users/test/asset'
1329
+ policy = {'bindings': [{'role': 'roles/viewer', 'members': ['allUsers']}]}
1330
+ ee.data.setIamPolicy(asset_id, policy)
1331
+ cloud_api_resource.projects().assets().setIamPolicy.assert_called_once_with(
1332
+ resource='projects/earthengine-legacy/assets/users/test/asset',
1333
+ body={'policy': policy},
1334
+ prettyPrint=False,
1335
+ )
1336
+
908
1337
 
909
1338
  def DoCloudProfileStubHttp(test, expect_profiling):
910
1339