def test_validation_business_endpoint_without_authentication(self): client_with_auth = Client( self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) client_with_auth.validation.rules.store(self.owner, rule_to_post) rule_name = 'content-movie-validation' client_without_auth = Client( 'http://registry.sandbox.eu-west-1.palettedev.aws.pikselpalette.com/services/testmock', auth_type=auth.AuthType.NO_AUTH) validation_endpoint = client_without_auth.validation.business( '/$service/$owner/$ref$params') response = validation_endpoint.store(service='v', owner=self.owner, content=content_to_validate, ref=rule_name, params={'validation': 'full'}) assert_that(response.status, 200) client_with_auth.validation.rules.delete(self.owner, 'testmock:%s' % rule_name)
def setUp(self): self.mock = mocking.bootstrap_mock() self.client_with_auth = Client( 'http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)]) self.client_without_auth = Client( 'http://mock-registry/services/testmock', adapters=[('http://', self.mock)], auth_type=auth.AuthType.NO_AUTH)
def test_given_assets_with_pagination_then(self): assets_ids, content_name = self._create_ids_and_content(5) content = content_template % content_name assets = assets_template % assets_ids client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) content_endpoint = client.metadata.contents assets_endpoint = client.metadata.assets content_endpoint.store(self.owner, content) assets_endpoint.store(self.owner, assets) # Getting content stored previously, sometimes is empty sleep(3) query_string = 'perPage=2&withContentRef=testmock:%s' % content_name content_pages = [ response for response in assets_endpoint.browse(self.owner, query_string=query_string) ] assert_that(content_pages[0].resources, has_length(2)) assert_that(content_pages[1].resources, has_length(2)) assert_that(content_pages[2].resources, has_length(1)) # Clean up content_endpoint.delete(self.owner, 'testmock:' + content_name) for name in assets_ids: assets_endpoint.delete(self.owner, 'testmock:' + name)
def test_given_assets_with_errors_then_store_should_raise_an_error(self): client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) assets_endpoint = client.metadata.assets with pytest.raises(HttpError): assets_endpoint.store(self.owner, assets_with_errors)
def test_can_post_and_retrieve_json_payload(self): random_name = 'aSampleProfile-' + str(uuid.uuid4()) profile = profile_template % random_name client = Client(self.registry, user_id=' the_user_id', application_id='the_application_id ', correlation_id=' ', grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) profile_endpoint = client.flow.profiles store_result = profile_endpoint.store(self.owner, profile) read_result = profile_endpoint.read(self.owner, store_result.resources[0]['ref']) delete_result = profile_endpoint.delete( self.owner, store_result.resources[0]['ref']) assert_that(store_result.status, 201) assert_that(delete_result.status, 204) assert_that(read_result.resources[0]['name'], random_name) read_result_object = read_result.to_object() assert_that(read_result_object[0].name, random_name) assert_that(read_result_object[0].secrets.awsKey1, 'awsKeyValue1') assert_that(read_result_object[0].secrets.ftpKey1, 'ftpKeyValue1')
def test_init(self): client = Client(registry_url="https://registry.sequoia.piksel.com", client_id="foo", client_secret="bar") assert client._client_id == "foo" assert client._client_secret == "bar" assert client._token is None assert client._owner is None assert len(client._services) == 0
def setUp(self): TokenCache._token_storage = {} self.mock = mocking.bootstrap_mock() self.client = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)])
def test_given_assets_with_errors_then_store_should_raise_an_error(self): client = Client( 'https://registry-sandbox.sequoia.piksel.com/services/testmock', grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) assets_endpoint = client.metadata.assets with pytest.raises(HttpError): assets_endpoint.store('testmock', assets_with_errors)
def test_given_wrong_registry_url_should_raise_an_error(self): with pytest.raises(HttpError) as e: Client( 'https://registry.sandbox.eu-west-1.palettedev.aws.pikselpalette.com/service/testmock', grant_client_id=self.config.ingest.username, grant_client_secret=self.config.ingest.password) assert e.value.message['statusCode'] == 404
def test_refresh_sequoia_token(self): """ When you perform a query against Sequoia and your token has expired or it's been invalidated, a new token is taken and used to perform your query. """ assets_ids, content_name = self._create_ids_and_content(5) content = content_template % content_name assets = assets_template % assets_ids client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) content_endpoint = client.metadata.contents assets_endpoint = client.metadata.assets content_endpoint.store(self.owner, content) assets_endpoint.store(self.owner, assets) sleep(1) response = assets_endpoint.browse( self.owner, criteria.Criteria().add( criterion=criteria.StringExpressionFactory.field( "contentRef").equal_to('testmock:%s' % content_name))) assert_that(response.resources, has_length(5)) # Revoke the token (not using clientsdk) token_previous = client._auth.session.access_token import base64, requests my_auth_creds = base64.b64encode('{}:{}'.format( self.config.sequoia.username, self.config.sequoia.password).encode('ascii')).decode('ascii') url = "https://identity.sandbox.eu-west-1.palettedev.aws.pikselpalette.com/oauth/revoke" payload = 'token=' + token_previous headers = { 'authorization': 'Basic ' + my_auth_creds, 'Content-Type': 'application/x-www-form-urlencoded' } response = requests.request("POST", url, headers=headers, data=payload) assert_that(response.status_code, is_(200)) # Query again sleep(10) response = assets_endpoint.browse( self.owner, criteria.Criteria().add( criterion=criteria.StringExpressionFactory.field( "contentRef").equal_to('testmock:%s' % content_name))) assert_that(response.resources, has_length(5)) token_current = client._auth.session.access_token print('*********') print('TOKEN OLD (revoked): ' + token_previous) print('TOKEN NEW (updated): ' + token_current) print('*********') # assert_that(token_previous, is_not(equal_to(token_current))) # Clean up content_endpoint.delete(self.owner, 'testmock:' + content_name) for name in assets_ids: assets_endpoint.delete(self.owner, 'testmock:' + name)
def test_flow_execution_progress_business_endpoint_when_flow_execution_not_found_raise_an_error( self): ref = 'flow-execution-that-not-exists' client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) with pytest.raises(HttpError): client.workflow.business('/$service/$owner:$ref').browse( service='flow-execution-progress', owner=self.owner, ref=ref)
def test_create_endpoint_proxy_with_dictionary_notation( self, mock_oauth2_session, mock_registry, mock_http_executor): mock_http_executor.return_value = mock_http_executor endpoint_proxy = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[ ('http://', self.mock) ])['service-with-dash']['resource-with-dash'] assert_that(endpoint_proxy.resource, equal_to('resource-with-dash'))
def test_retry_when_empty_then_browse_with_content_ref_should_not_retrieve_assets( self): self._configure_logging() unique_name = str(uuid.uuid4()) import backoff client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password, user_agent='backoff_test') contents_endpoint = client.metadata.contents categories_endpoint = client.metadata.categories content = content_template_unique % (unique_name, unique_name, unique_name) categories = category_template_unique % (unique_name, unique_name) contents_result = contents_endpoint.store(self.owner, content) categories_result = categories_endpoint.store(self.owner, categories) sleep(1) response = contents_endpoint.browse( self.owner, criteria.Criteria().add_criterion( criteria.StringExpressionFactory.field('ref'). equal_to(f'testmock:{unique_name}')).add_inclusion( criteria.Inclusion.resource('categories')).add_inclusion( criteria.Inclusion.resource('assets')), backoff_strategy={ 'wait_gen': backoff.expo, 'max_tries': 3, # 'max_time': 10, 'retry_http_status_codes': '404', 'retry_when_empty_result': { 'contents': True, 'assets': True, 'categories': True } }) from pprint import pformat logging.info(pformat(response.resources)) assert len(response.resources) == 1 assert len(response.linked('categories').resources) == 2 assert len(response.linked('assets').resources) == 0 # This test returns the data it has found after retrying the query as there's no assets and they are required categories_endpoint.delete(self.owner, categories_result.resources[0]['ref']) categories_endpoint.delete(self.owner, categories_result.resources[1]['ref']) contents_endpoint.delete(self.owner, contents_result.resources[0]['ref'])
def test_create_client_with_correlation_id(self, mock_oauth2_session, mock_registry, mock_http_executor): mock_http_executor.return_value = mock_http_executor client = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)], correlation_id="user_id/application_id/1234567890") assert_that(client._correlation_id, equal_to('user_id/application_id/1234567890'))
async def test_update_services_error_getting_registry_list(self): wrong_response = Mock(spec=Response) wrong_response.json.return_value = {"foo": "bar"} responses = [ # Error raised establishing connection with registry OSError() ] with patch.object(httpx.AsyncClient, "request", new_callable=AsyncMock, side_effect=responses), pytest.raises( DiscoveryServicesError ): sequoia_client = Client(registry_url="", client_id="", client_secret="") await sequoia_client.update_services()
def test_create_service_proxy_with_dictionary_notation( self, mock_oauth2_session, mock_registry, mock_http_executor): mock_http_executor.return_value = mock_http_executor mock_registry.return_value.__getitem__.side_effect = [ mock_registry, 'service-with-dash' ] service_proxy = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock) ])['service-with-dash'] assert_that(service_proxy._service, equal_to('service-with-dash')) assert_that(service_proxy._http, equal_to(mock_http_executor))
def test_validation_business_endpoint_without_authentication_when_rule_not_exists_raise_error( self): rule = 'rule-not-exists' client = Client( 'http://registry.sandbox.eu-west-1.palettedev.aws.pikselpalette.com/services/testmock', auth_type=auth.AuthType.NO_AUTH) with pytest.raises(HttpError): client.validation.business('/$service/$owner/$ref').browse( service='v', owner='test', content=content_to_validate, ref=rule)
def test_given_asset_with_different_version_then_update_should_raise_an_error( self): client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) assets_endpoint = client.metadata.assets assets_endpoint.store(self.owner, asset_to_store) with pytest.raises(NotMatchingVersion) as e: assets_endpoint.update( self.owner, asset, 'testmock:016b9e5f-c184-48ea-a5e2-6e6bc2d62791', 'e3706cb187f8decf810f8a3645c4e178aa65b0d1') assert e.value.message == 'Document cannot be updated. Version does not match.'
def test_given_no_assets_then_browse_with_content_ref_should_not_retrieve_assets( self): client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) assets_endpoint = client.metadata.assets response = assets_endpoint.browse( self.owner, criteria.Criteria().add( criterion=criteria.StringExpressionFactory.field( 'contentRef').equal_to('testmock:nonExistingContent'))) assert len(response.resources) == 0
def test_create_client_generate_correlation_id_with_autogenerated_transaction_id( self, mock_oauth2_session, mock_registry, mock_http_executor, mock_uuid): mock_http_executor.return_value = mock_http_executor mock_uuid.return_value = '0987654321' client = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)], user_id='user_id', application_id='application_id') assert_that(client._correlation_id, equal_to('user_id/application_id/0987654321'))
def test_create_client_should_prioritizise_correlation_id_over_arguments_to_build_it( self, mock_oauth2_session, mock_registry, mock_http_executor): mock_http_executor.return_value = mock_http_executor client = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)], correlation_id="user_id/application_id/1234567890", user_id='another_user_id', application_id='another_application_id', transaction_id='another_transaction_id') assert_that(client._correlation_id, equal_to('user_id/application_id/1234567890'))
def test_returns_mocked_profile(self): mocking.add_get_mapping_for(self.mock, 'workflow', 'valid_workflow_profile_response') mocking.add_get_mapping_for(self.mock, 'descriptor', 'valid_workflow_profile_response') self.client = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)], model_resolution='all') under_test = self.client.workflow.profiles response = under_test.read('testmock', 'testmock:profile-1') assert_that(response.resources[0]['title'], 'profile-1')
async def test_update_services_wrong_response_getting_service_description(self, response_registry_list_services): wrong_response = Mock(spec=Response) wrong_response.json.return_value = {"foo": "bar"} responses = [ # Registry's list of services response_registry_list_services, # Wrong response from service description wrong_response, ] with patch.object(httpx.AsyncClient, "request", new_callable=AsyncMock, side_effect=responses), pytest.raises( DiscoveryResourcesError ): sequoia_client = Client(registry_url="", client_id="", client_secret="") await sequoia_client.update_services() await sequoia_client.resources("metadata")
def test_retry_when_empty_then_browse_with_content_ref_should_not_retrieve_assets( self): self._configure_logging() unique_name = str(uuid.uuid4()) import backoff client = Client( self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password, user_agent='backoff_test', backoff_strategy={ 'wait_gen': backoff.expo, # 'max_tries': 3, 'max_time': 10, 'retry_http_status_codes': '404' }) contents_endpoint = client.metadata.contents categories_endpoint = client.metadata.categories content = content_template_unique % (unique_name, unique_name, unique_name) categories = category_template_unique % (unique_name, unique_name) contents_endpoint.store(self.owner, content) categories_endpoint.store(self.owner, categories) sleep(1) response = contents_endpoint.browse( self.owner, criteria.Criteria().add_criterion( criteria.StringExpressionFactory.field('ref'). equal_to(f'testmock:{unique_name}')).add_inclusion( criteria.Inclusion.resource('categories')).add_inclusion( criteria.Inclusion.resource('assets')), retry_when_empty_result={ 'contents': True, 'assets': True, 'categories': True }) from pprint import pprint pprint(response.resources) assert len(response.resources) == 1 assert len(response.resources[0]['categoryRefs']) == 2
def test_can_delete_and_manage_empty_payload(self): random_name = 'aSampleProfile-' + str(uuid.uuid4()) profile = profile_template % random_name client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) profile_endpoint = client.flow.profiles store_result = profile_endpoint.store(self.owner, profile) read_result = profile_endpoint.read(self.owner, store_result.resources[0]['ref']) delete_result = profile_endpoint.delete( self.owner, store_result.resources[0]['ref']) assert_that(store_result.status, 201) assert_that(delete_result.status, 204) assert_that(delete_result.result, none()) assert_that(read_result.resources[0]['name'], random_name)
def test_fetch_token_given_there_is_an_error_fetching_the_token_then_client_error_is_raised( self): mocking.add_post_mapping_for(self.mock, 'identity', 'error_identity_response') with pytest.raises(error.AuthorisationError) as client_error: Client("http://mock-registry/services/testmock", grant_client_id="piksel-workflow", grant_client_secret="blablabla", adapters=[("http://", self.mock)]) assert_that(client_error.value.cause, instance_of(InvalidGrantError)) assert_that( client_error.value.args[0], '(invalid_grant) The provided authorization grant (e.g., authorization code, resource owner' ' credentials) or refresh token is invalid, expired, revoked, does not match the redirection URI ' 'used in the authorization request, or was issued to another client.' )
def test_given_assets_then_browse_with_query_string_should_retrieve_assets( self): assets_ids, content_name = self._create_ids_and_content(5) content = content_template % content_name assets = assets_template % assets_ids client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) content_endpoint = client.metadata.contents assets_endpoint = client.metadata.assets content_endpoint.store(self.owner, content) assets_endpoint.store(self.owner, assets) sleep(1) response = assets_endpoint.browse( self.owner, query_string='withContentRef=testmock:%s' % content_name) assert_that(response.resources, has_length(5)) # Clean up content_endpoint.delete(self.owner, 'testmock:' + content_name) for name in assets_ids: assets_endpoint.delete(self.owner, 'testmock:' + name)
def test_browse_assets_with_model_query_string_returns_mocked_assets(self): mocking.add_get_mapping_for_url( self.mock, 'data/assets\?withContentRef=theContentRef&owner=testmock', 'valid_metadata_assets_response') mocking.add_get_mapping_for_url(self.mock, 'descriptor', 'workflow_descriptor_raw') self.client = Client('http://mock-registry/services/testmock', grant_client_id='piksel-workflow', grant_client_secret='blablabla', adapters=[('http://', self.mock)], model_resolution='all') under_test = self.client.metadata.assets response = under_test.browse( 'testmock', query_string='withContentRef=theContentRef') assert_that(response.resources, has_length(4)) assert_that(response.resources[0]['name'], '016b9e5f-c184-48ea-a5e2-6e6bc2d62791') assert_that(response.model[0]['name'], '016b9e5f-c184-48ea-a5e2-6e6bc2d62791')
def test_can_post_and_retrieve_linked_content(self): client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password, model_resolution='direct') contents_endpoint = client.metadata.contents categories_endpoint = client.metadata.categories store_content = None store_category = None try: store_content = contents_endpoint.store( self.owner, content_with_category_template) store_category = categories_endpoint.store(self.owner, category_template) sleep(1) result = contents_endpoint.browse( self.owner, criteria.Criteria().add( inclusion=criteria.Inclusion.resource('categories')).add( criterion=criteria.StringExpressionFactory.field('ref') .equal_to(store_content.resources[0]['ref']))) finally: if store_content: delete_result = contents_endpoint.delete( self.owner, store_content.resources[0]['ref']) if store_category: delete_result = categories_endpoint.delete( self.owner, store_category.resources[0]['ref']) assert_that(result.model, has_length(1)) assert_that(result.status, 201) assert_that(result.model[0]['name'], 'a_test_content_linked_to_categories') assert_that(result.model[0]['categories'], has_length(1)) assert_that(result.model[0]['categories'][0]['ref'], 'testmock:genre_animation')
def test_given_assets_then_browse_with_content_ref_should_retrieve_assets( self): assets_ids, content_name = self._create_ids_and_content(5) content = content_template % content_name assets = assets_template % assets_ids client = Client(self.registry, grant_client_id=self.config.sequoia.username, grant_client_secret=self.config.sequoia.password) content_endpoint = client.metadata.contents assets_endpoint = client.metadata.assets content_endpoint.store(self.owner, content) assets_endpoint.store(self.owner, assets) sleep(1) response = assets_endpoint.browse( self.owner, criteria.Criteria().add( criterion=criteria.StringExpressionFactory.field( "contentRef").equal_to('testmock:%s' % content_name))) assert_that(response.resources, has_length(5)) # Clean up content_endpoint.delete(self.owner, 'testmock:' + content_name) for name in assets_ids: assets_endpoint.delete(self.owner, 'testmock:' + name)