def test_status(): collection = Collection(id='C333666999-EOSDIS') job_id = '21469294-d6f7-42cc-89f2-c81990a5d7f4' exp_job = expected_job(collection.id, job_id) expected_status = { 'status': exp_job['status'], 'message': exp_job['message'], 'progress': exp_job['progress'], 'created_at': dateutil.parser.parse(exp_job['createdAt']), 'updated_at': dateutil.parser.parse(exp_job['updatedAt']), 'request': exp_job['request'], 'num_input_granules': exp_job['numInputGranules'] } responses.add(responses.GET, expected_status_url(job_id), status=200, json=exp_job) actual_status = Client(should_validate_auth=False).status(job_id) assert len(responses.calls) == 1 assert responses.calls[0].request is not None assert urllib.parse.unquote( responses.calls[0].request.url) == expected_status_url(job_id) assert actual_status == expected_status
def test_request_spatial_bounding_box(west, south, east, north): spatial = BBox(west, south, east, north) request = Request( collection=Collection('foobar'), spatial=spatial, ) if request.is_valid(): assert request.spatial is not None w, s, e, n = request.spatial assert w == west assert s == south assert e == east assert n == north assert south < north assert south >= -90.0 assert north >= -90.0 assert south <= 90.0 assert north <= 90.0 assert west >= -180.0 assert east >= -180.0 assert west <= 180.0 assert east <= 180.0
def test_with_invalid_request(): collection = Collection(id='C333666999-EOSDIS') request = Request(collection=collection, spatial=BBox(-190, -100, 100, 190)) with pytest.raises(Exception): Client(should_validate_auth=False).submit(request)
def test_request_temporal_range(key_a, key_b, datetime_a, datetime_b): temporal = {key_a: datetime_a, key_b: datetime_b} request = Request(collection=Collection('foobar'), temporal=temporal) if request.is_valid(): assert request.temporal is not None assert 'start' in request.temporal or 'stop' in request.temporal if 'start' in request.temporal and 'stop' in request.temporal: assert request.temporal['start'] < request.temporal['stop']
def test_request_has_variables(variables, expected): collection = Collection('foobar') request = Request(collection=collection, variables=variables) responses.add( responses.GET, expected_submit_url(collection.id, expected), status=200, json=expected_job(collection.id, 'abcd-1234'), ) Client(should_validate_auth=False).submit(request)
def test_stac_catalog_url(mocker): job_id = '1234' collection = Collection(id='C1940468263-POCLOUD') expected_json = expected_job(collection.id, job_id) result_json_mock = mocker.Mock(return_value=expected_json) mocker.patch('harmony.harmony.Client.result_json', result_json_mock) expected_stac_catalog_url = f'https://harmony.uat.earthdata.nasa.gov/stac/{job_id}/' client = Client(should_validate_auth=False) actual_stac_catalog_url = client.stac_catalog_url(job_id) assert actual_stac_catalog_url == expected_stac_catalog_url
def test_request_has_query_param(param, expected): collection = Collection('foobar') request = Request(collection=collection, **param) responses.add( responses.GET, expected_submit_url(collection.id), status=200, json=expected_job(collection.id, 'abcd-1234'), ) Client(should_validate_auth=False).submit(request) assert len(responses.calls) == 1 assert urllib.parse.unquote( responses.calls[0].request.url).index(expected) >= 0
def test_result_urls(mocker, show_progress): collection = Collection(id='C1940468263-POCLOUD') job_id = '1234' expected_json = expected_job(collection.id, job_id) expected_urls = [ 'https://harmony.uat.earthdata.nasa.gov/service-results/fake.tif' ] result_json_mock = mocker.Mock(return_value=expected_json) mocker.patch('harmony.harmony.Client.result_json', result_json_mock) client = Client(should_validate_auth=False) actual_urls = client.result_urls(job_id, show_progress=show_progress) assert actual_urls == expected_urls assert result_json_mock.called_with(client, job_id, show_progress)
def test_result_urls(mocker, show_progress, link_type): collection = Collection(id='C1940468263-POCLOUD') job_id = '1234' expected_json = expected_job(collection.id, job_id, link_type) expected_urls = [fake_data_url(link_type)] result_json_mock = mocker.Mock(return_value=expected_json) mocker.patch('harmony.harmony.Client.result_json', result_json_mock) client = Client(should_validate_auth=False) actual_urls = client.result_urls(job_id, show_progress=show_progress, link_type=link_type) assert actual_urls == expected_urls assert result_json_mock.called_with(client, job_id, show_progress)
def test_with_bounding_box(): collection = Collection(id='C1940468263-POCLOUD') request = Request(collection=collection, spatial=BBox(-107, 40, -105, 42)) job_id = '21469294-d6f7-42cc-89f2-c81990a5d7f4' responses.add(responses.GET, expected_submit_url(collection.id), status=200, json=expected_job(collection.id, job_id)) actual_job_id = Client(should_validate_auth=False).submit(request) assert len(responses.calls) == 1 assert responses.calls[0].request is not None assert urllib.parse.unquote( responses.calls[0].request.url) == expected_full_submit_url(request) assert actual_job_id == job_id
def test_progress(): collection = Collection(id='C333666999-EOSDIS') job_id = '21469294-d6f7-42cc-89f2-c81990a5d7f4' exp_job = expected_job(collection.id, job_id) expected_progress = int(exp_job['progress']), exp_job['status'] responses.add(responses.GET, expected_status_url(job_id), status=200, json=exp_job) actual_progress = Client(should_validate_auth=False).progress(job_id) assert len(responses.calls) == 1 assert responses.calls[0].request is not None assert urllib.parse.unquote( responses.calls[0].request.url) == expected_status_url(job_id) assert actual_progress == expected_progress
def test_with_temporal_range(): collection = Collection(id='C1234-TATOOINE') request = Request( collection=collection, temporal={ 'start': dt.datetime(2010, 12, 1), 'stop': dt.datetime(2010, 12, 31) }, ) job_id = '1234abcd-deed-9876-c001-f00dbad' responses.add(responses.GET, expected_submit_url(collection.id), status=200, json=expected_job(collection.id, job_id)) actual_job_id = Client(should_validate_auth=False).submit(request) assert len(responses.calls) == 1 assert responses.calls[0].request is not None assert urllib.parse.unquote( responses.calls[0].request.url) == expected_full_submit_url(request) assert actual_job_id == job_id
def test_when_multiple_submits_it_only_authenticates_once(): collection = Collection(id='C1940468263-POCLOUD') request = Request(collection=collection, spatial=BBox(-107, 40, -105, 42)) job_id = '3141592653-abcd-1234' auth_url = 'https://harmony.uat.earthdata.nasa.gov/jobs' responses.add(responses.GET, auth_url, status=200) responses.add(responses.GET, expected_submit_url(collection.id), status=200, json=expected_job(collection.id, job_id)) client = Client() client.submit(request) client.submit(request) assert len(responses.calls) == 3 assert responses.calls[0].request.url == auth_url assert urllib.parse.unquote(responses.calls[0].request.url) == auth_url assert urllib.parse.unquote( responses.calls[1].request.url) == expected_full_submit_url(request) assert urllib.parse.unquote( responses.calls[2].request.url) == expected_full_submit_url(request)
def test_with_bounding_box_and_temporal_range(): collection = Collection(id='C333666999-EOSDIS') request = Request( collection=collection, spatial=BBox(-107, 40, -105, 42), temporal={ 'start': dt.datetime(2001, 1, 1), 'stop': dt.datetime(2003, 3, 31) }, ) job_id = '1234abcd-1234-9876-6666-999999abcd' responses.add(responses.GET, expected_submit_url(collection.id), status=200, json=expected_job(collection.id, job_id)) actual_job_id = Client(should_validate_auth=False).submit(request) assert len(responses.calls) == 1 assert responses.calls[0].request is not None assert urllib.parse.unquote( responses.calls[0].request.url) == expected_full_submit_url(request) assert actual_job_id == job_id
def test_with_shapefile(): collection = Collection(id='C333666999-EOSDIS') request = Request( collection=collection, shape='./examples/asf_example.json', spatial=BBox(-107, 40, -105, 42), ) job_id = '1234abcd-1234-9876-6666-999999abcd' responses.add(responses.POST, expected_submit_url(collection.id), status=200, json=expected_job(collection.id, job_id)) actual_job_id = Client(should_validate_auth=False).submit(request) assert len(responses.calls) == 1 post_request = responses.calls[0].request post_body = post_request.body.decode('utf-8') assert post_request is not None # GeoJSON is present in the submit body assert 'FeatureCollection' in post_body assert 'Content-Type: application/geo+json' in post_body # Submit URL has no query params assert urllib.parse.unquote(post_request.url) == expected_submit_url( collection.id) # Would-be query params are in the POST body assert 'Content-Disposition: form-data; name="forceAsync"\r\n\r\ntrue' in post_body assert 'Content-Disposition: form-data; name="subset"\r\n\r\nlat(40:42)' in post_body assert 'Content-Disposition: form-data; name="subset"\r\n\r\nlon(-107:-105)' in post_body assert actual_job_id == job_id
def test_request_spatial_error_messages(key, value, message): request = Request(Collection('foo'), **{key: value}) messages = request.error_messages() assert not request.is_valid() assert message in messages
def test_request_has_collection_with_id(): collection = Collection('foobar') request = Request(collection) assert request.collection.id == 'foobar'
def test_request_shape_file_error_message(key, value, messages): request = Request(Collection('foo'), **{key: value}) assert not request.is_valid() assert request.error_messages() == messages
def test_request_valid_shape(): request = Request(Collection('foo'), shape='./examples/asf_example.json') messages = request.error_messages() assert request.is_valid() assert messages == []
def test_request_with_only_a_collection(): request = Request(collection=Collection('foobar')) assert request.is_valid()