diff --git a/connect_ext_ppr/errors.py b/connect_ext_ppr/errors.py index 7429456..a5e8486 100644 --- a/connect_ext_ppr/errors.py +++ b/connect_ext_ppr/errors.py @@ -103,8 +103,9 @@ class ExtensionValidationError(ExtensionErrorBase): 0: "{validation_error}", # PPR Schema validation 1: "{field}: {id} not found.", 2: "{field}: This values {values} are invalid.", - 3: "At least one choice needs to be specified.", + 3: "At least one {field} needs to be specified.", 4: "Cannot applied PPR to {entity} {values}.", 5: "Transition not allowed: can not set {field_name} from `{source}` to" " '{target}', allowed {field_name} sources for '{target}' are '{allowed}'.", + 6: "Pricing batches invalid: {ids}.", } diff --git a/connect_ext_ppr/models/deployment.py b/connect_ext_ppr/models/deployment.py index 4d82a02..50f5ec6 100644 --- a/connect_ext_ppr/models/deployment.py +++ b/connect_ext_ppr/models/deployment.py @@ -72,6 +72,7 @@ class DeploymentRequest(Model): foreign_keys="DeploymentRequest.deployment_id", innerjoin=True, ) + marketplaces = relationship('MarketplaceConfiguration', backref='deployment_request', lazy=True) @transition('status', target=STATUSES.aborting, sources=[STATUSES.pending, STATUSES.processing]) def aborting(self, by): @@ -100,8 +101,9 @@ class MarketplaceConfiguration(Model): id = db.Column(db.Integer(), primary_key=True, autoincrement=True) marketplace = db.Column(db.String(16)) deployment_id = db.Column(db.ForeignKey(Deployment.id), nullable=True) - deployment_request = db.Column(db.ForeignKey(DeploymentRequest.id), nullable=True) + deployment_request_id = db.Column(db.ForeignKey(DeploymentRequest.id), nullable=True) ppr_id = db.Column(db.String, db.ForeignKey(PPRVersion.id)) + pricelist_id = db.Column(db.String(32), nullable=True) active = db.Column(db.Boolean(), default=True) ppr = relationship('PPRVersion', foreign_keys='MarketplaceConfiguration.ppr_id') diff --git a/connect_ext_ppr/schemas.py b/connect_ext_ppr/schemas.py index 80415f9..e408603 100644 --- a/connect_ext_ppr/schemas.py +++ b/connect_ext_ppr/schemas.py @@ -210,6 +210,7 @@ class MarketplaceSchema(NonNullSchema): external_id: Optional[str] ppr: Optional[PPRVersionReferenceSchema] + pricelist: Optional[PrimaryKeyReference] class TaskSchema(NonNullSchema): @@ -220,9 +221,14 @@ class TaskSchema(NonNullSchema): error_message: Optional[str] +class MarketplaceConfigSchema(NonNullSchema): + id: str + pricelist: Optional[PrimaryKeyReference] + + class DeploymentRequestCreateSchema(NonNullSchema): deployment: PrimaryKeyReference ppr: PrimaryKeyReference manually: bool delegate_l2: Optional[bool] - marketplaces: ChoicesSchema + marketplaces: Optional[List[MarketplaceConfigSchema]] diff --git a/connect_ext_ppr/service.py b/connect_ext_ppr/service.py index f7b206e..215a69b 100644 --- a/connect_ext_ppr/service.py +++ b/connect_ext_ppr/service.py @@ -329,14 +329,11 @@ def add_new_deployment_request(db, dr_data, deployment, account_id, logger): db.flush() db.refresh(deployment_request) - marketplaces = [m.id for m in dr_data.marketplaces.choices] - if dr_data.marketplaces.all: - marketplaces = [m.marketplace for m in deployment.marketplaces] - - for m_id in marketplaces: + for mp_data in dr_data.marketplaces: mc = MarketplaceConfiguration( - deployment_request=deployment_request.id, - marketplace=m_id, + deployment_request=deployment_request, + marketplace=mp_data.id, + pricelist_id=mp_data.pricelist.id if mp_data.pricelist else None, ) db.add(mc) @@ -412,11 +409,11 @@ def deactivate_marketplaces(installation, listings, config, logger): update(MarketplaceConfiguration) .where( MarketplaceConfiguration.marketplace == marketplace_id, - MarketplaceConfiguration.deployment_request.in_( + MarketplaceConfiguration.deployment_request_id.in_( [dr.id for dr in deployments_requests], )) .values(active=False) - .returning(MarketplaceConfiguration.deployment_request) + .returning(MarketplaceConfiguration.deployment_request_id) ) result = db.execute(stmt) diff --git a/connect_ext_ppr/utils.py b/connect_ext_ppr/utils.py index 9670b49..13cdc35 100644 --- a/connect_ext_ppr/utils.py +++ b/connect_ext_ppr/utils.py @@ -35,6 +35,7 @@ MarketplaceSchema, PPRVersionReferenceSchema, PPRVersionSchema, + PrimaryKeyReference, ProductReferenceSchema, ProductSchema, TaskSchema, @@ -605,7 +606,7 @@ def process_ppr(wb, product, config_json, items): return ws_list, summary -def get_marketplace_schema(marketplace, ppr): +def get_marketplace_schema(marketplace, ppr, pricelist_id): mp_schema = MarketplaceSchema( id=marketplace['id'], name=marketplace['name'], @@ -614,6 +615,8 @@ def get_marketplace_schema(marketplace, ppr): ) if ppr: mp_schema.ppr = PPRVersionReferenceSchema(id=ppr.id, version=ppr.version) + if pricelist_id: + mp_schema.pricelist = PrimaryKeyReference(id=pricelist_id) return mp_schema diff --git a/connect_ext_ppr/validator.py b/connect_ext_ppr/validator.py index 851c31e..bd004e9 100644 --- a/connect_ext_ppr/validator.py +++ b/connect_ext_ppr/validator.py @@ -1,3 +1,4 @@ +from connect.client import R from fastapi import status from connect_ext_ppr.errors import ExtensionValidationError @@ -28,11 +29,19 @@ def validate_ppr_version_belongs_to_deployment(ppr, deployment): ) -def validate_dr_marketplaces(dr_marketplaces, dep_marketplaces): +def validate_dr_marketplaces(client, product_id, dr_marketplaces, dep_marketplaces): """ Validates that all the DR's marketplaces belong to the associated deployment """ - diff = list(set(dr_marketplaces) - set(dep_marketplaces)) + if not dr_marketplaces: + raise ExtensionValidationError.VAL_003( + format_kwargs={'field': 'marketplace'}, + ) + + mp_configs = {mp.id: mp for mp in dr_marketplaces} + dep_ids = {mp.marketplace for mp in dep_marketplaces} + + diff = list(mp_configs.keys() - dep_ids) if diff: diff.sort() raise ExtensionValidationError.VAL_002( @@ -43,6 +52,37 @@ def validate_dr_marketplaces(dr_marketplaces, dep_marketplaces): status_code=status.HTTP_400_BAD_REQUEST, ) + validate_pricelist_ids(client, product_id, mp_configs) + + +def validate_pricelist_ids(client, product_id, mp_configs): + rql_filters = [] + pricelist_ids = set() + for mp_id, config in mp_configs.items(): + if config.pricelist: + pricelist_ids.add(config.pricelist.id) + rql_filters.append( + R().stream.context.marketplace.id.eq(mp_id) + & R().id.eq(config.pricelist.id), + ) + + if not pricelist_ids: + return + + batches = client('pricing').batches.filter( + R(_op=R.OR, _children=rql_filters), + R().stream.context.product.id.eq(product_id), + R().status.eq('published'), + R().test.ne(True), + ) + + invalid_ids = pricelist_ids - {b['id'] for b in batches} + + if invalid_ids: + raise ExtensionValidationError.VAL_006(format_kwargs={ + 'ids': ', '.join(sorted(invalid_ids)), + }) + def validate_marketplaces_ppr(ppr, dr_marketplaces, dep_marketplaces): """ @@ -50,9 +90,10 @@ def validate_marketplaces_ppr(ppr, dr_marketplaces, dep_marketplaces): """ dep_mkplc_map = {m.marketplace: m for m in dep_marketplaces} mkplcs_w_erros = [] - for marketplace in dr_marketplaces: - if dep_mkplc_map[marketplace].ppr_id and dep_mkplc_map[marketplace].ppr_id > ppr.id: - mkplcs_w_erros.append(marketplace) + for mp_data in dr_marketplaces: + mp_id = mp_data.id + if dep_mkplc_map[mp_id].ppr_id and dep_mkplc_map[mp_id].ppr_id > ppr.id: + mkplcs_w_erros.append(mp_id) if mkplcs_w_erros: raise ExtensionValidationError.VAL_004( diff --git a/connect_ext_ppr/webapp.py b/connect_ext_ppr/webapp.py index 722a255..c421505 100644 --- a/connect_ext_ppr/webapp.py +++ b/connect_ext_ppr/webapp.py @@ -164,13 +164,14 @@ def add_dep_request( active=True, deployment_id=deployment.id, ) - dr_marketplaces = [m.id for m in deployment_request.marketplaces.choices] + validate_dr_marketplaces( - dr_marketplaces, - [m.marketplace for m in dep_marketplaces], + client=client, + product_id=deployment.product_id, + dr_marketplaces=deployment_request.marketplaces, + dep_marketplaces=dep_marketplaces, ) - - validate_marketplaces_ppr(ppr, dr_marketplaces, dep_marketplaces) + validate_marketplaces_ppr(ppr, deployment_request.marketplaces, dep_marketplaces) instance = add_new_deployment_request( db, deployment_request, deployment, account_id, logger, @@ -265,14 +266,16 @@ def get_deployment_request( def list_deployment_request_tasks( self, depl_req_id: str, + pagination_params: PaginationParams = Depends(), + response: Response = None, db: VerboseBaseSession = Depends(get_db), installation: dict = Depends(get_installation), ): dr = get_deployment_request_by_id(depl_req_id, db, installation) if dr: task_list = [] - tasks = db.query(Task).filter_by(deployment_request_id=dr.id).order_by(Task.id) - for task in tasks: + qs = db.query(Task).filter_by(deployment_request_id=dr.id).order_by(Task.id) + for task in apply_pagination(qs, db, pagination_params, response): task_list.append(get_task_schema(task)) return task_list @@ -294,19 +297,24 @@ def list_deployment_request_marketplaces( dr = get_deployment_request_by_id(depl_req_id, db, installation) marketplaces_list = [] - marketplaces = db.query(MarketplaceConfiguration).options( + + mp_configs = db.query(MarketplaceConfiguration).options( selectinload(MarketplaceConfiguration.ppr), - ).filter_by(deployment_request=dr.id) - marketplaces = m_filter.filter(marketplaces) - marketplaces = m_filter.sort(marketplaces) - marketplaces = apply_pagination(marketplaces, db, pagination_params, response) + ).filter_by(deployment_request_id=dr.id) + mp_configs = m_filter.filter(mp_configs) + mp_configs = m_filter.sort(mp_configs) + mp_configs = apply_pagination(mp_configs, db, pagination_params, response) - marketplaces_pprs = {m.marketplace: m.ppr for m in marketplaces} - marketplaces_data = get_marketplaces(client, list(marketplaces_pprs.keys())) + mp_configs = {m.marketplace: m for m in mp_configs} + marketplaces_data = get_marketplaces(client, list(mp_configs.keys())) for marketplace in marketplaces_data: marketplaces_list.append( - get_marketplace_schema(marketplace, marketplaces_pprs.get(marketplace['id'])), + get_marketplace_schema( + marketplace, + mp_configs[marketplace['id']].ppr, + mp_configs[marketplace['id']].pricelist_id, + ), ) return marketplaces_list @@ -694,7 +702,11 @@ def get_marketplaces_by_deployment( response_list = [] for mkplc_config in mkplc_configs: m_data = filter_object_list_by_id(marketplaces, mkplc_config.marketplace) - response_list.append(get_marketplace_schema(m_data, mkplc_config.ppr)) + response_list.append(get_marketplace_schema( + m_data, + mkplc_config.ppr, + mkplc_config.pricelist_id, + )) return response_list @router.get( diff --git a/tests/api/test_deployment_requests.py b/tests/api/test_deployment_requests.py index fd14246..3383520 100644 --- a/tests/api/test_deployment_requests.py +++ b/tests/api/test_deployment_requests.py @@ -2,6 +2,7 @@ from datetime import datetime import pytest +from connect.client import R from sqlalchemy import null from connect_ext_ppr.models.deployment import DeploymentRequest, MarketplaceConfiguration @@ -400,28 +401,47 @@ def test_create_deployment_request( ppr_version_factory, installation, api_client, + connect_client, + client_mocker_factory, ): hub_data = { 'id': 'HB-0000-0001', 'name': 'Another Hub for the best', } - mocker.patch('connect_ext_ppr.webapp.get_client_object', side_effect=[hub_data]) dep = deployment_factory(account_id=installation['owner']['id'], hub_id=hub_data['id']) ppr = ppr_version_factory(deployment=dep) marketplace_config_factory(deployment=dep, marketplace_id='MP-124') marketplace_config_factory(deployment=dep, marketplace_id='MP-123', ppr_id=ppr.id) + marketplace_config_factory(deployment=dep, marketplace_id='MP-234', ppr_id=ppr.id) + + mocker.patch('connect_ext_ppr.webapp.get_client_object', side_effect=[hub_data]) + client_mocker = client_mocker_factory(base_url=connect_client.endpoint) + client_mocker('pricing').batches.filter( + R( + _op=R.OR, + _children=[ + R().stream.context.marketplace.id.eq('MP-234') + & R().id.eq('BAT-111'), + ], + ), + R().stream.context.product.id.eq(dep.product_id), + R().status.eq('published'), + R().test.ne(True), + ).mock( + return_value=[{'id': 'BAT-111'}], + ) body = { 'deployment': {'id': dep.id}, 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': { - 'choices': [{'id': 'MP-123'}], - 'all': False, - }, + 'marketplaces': [ + {'id': 'MP-123'}, + {'id': 'MP-234', 'pricelist': {'id': 'BAT-111'}}, + ], } with mocker.patch( @@ -464,7 +484,16 @@ def test_create_deployment_request( assert dbsession.query(MarketplaceConfiguration).filter_by( marketplace='MP-123', - deployment_request=deployment_request.id, + deployment_request=deployment_request, + ).filter( + MarketplaceConfiguration.deployment_id.is_(null()), + MarketplaceConfiguration.ppr_id.is_(null()), + ).count() == 1 + + assert dbsession.query(MarketplaceConfiguration).filter_by( + marketplace='MP-234', + deployment_request=deployment_request, + pricelist_id='BAT-111', ).filter( MarketplaceConfiguration.deployment_id.is_(null()), MarketplaceConfiguration.ppr_id.is_(null()), @@ -506,10 +535,7 @@ def test_create_deployment_request_without_delegation_to_l2( 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': False, - 'marketplaces': { - 'choices': [{'id': 'MP-123'}], - 'all': False, - }, + 'marketplaces': [{'id': 'MP-123'}], } with mocker.patch( 'connect_ext_ppr.webapp.ConnectExtensionXvsWebApplication.thread_pool.submit', @@ -523,7 +549,7 @@ def test_create_deployment_request_without_delegation_to_l2( deployment_request = dbsession.query(DeploymentRequest).first() - assert response.status_code == 201, response.json() + assert response.status_code == 201, response.content data = response.json() events = data.pop('events') assert data == { @@ -557,40 +583,25 @@ def test_create_deployment_request_without_delegation_to_l2( assert tasks[1].type == Task.TYPES.apply_and_delegate -@pytest.mark.parametrize( - 'marketplaces_dict', - ( - {'choices': [], 'all': True}, - {'all': True}, - ), -) -def test_create_deployment_request_with_all_marketplaces( +def test_create_deployment_request_invalid_deployment( mocker, - dbsession, deployment_factory, - marketplace_config_factory, ppr_version_factory, installation, api_client, - marketplaces_dict, ): - hub_data = { - 'id': 'HB-0000-0001', - 'name': 'Another Hub for the best', - } - mocker.patch('connect_ext_ppr.webapp.get_client_object', side_effect=[hub_data]) - - dep = deployment_factory(account_id=installation['owner']['id'], hub_id=hub_data['id']) + deployment_factory(account_id=installation['owner']['id']) + dep = deployment_factory(account_id='PA-123-456') ppr = ppr_version_factory(deployment=dep) - marketplace_config_factory(deployment=dep, marketplace_id='MP-124') - marketplace_config_factory(deployment=dep, marketplace_id='MP-123', ppr_id=ppr.id) - body = { 'deployment': {'id': dep.id}, - 'ppr': {'id': ppr.id}, + 'ppr': { + 'id': ppr.id, + }, 'manually': True, - 'marketplaces': marketplaces_dict, + 'delegate_l2': True, + 'marketplaces': [], } with mocker.patch( 'connect_ext_ppr.webapp.ConnectExtensionXvsWebApplication.thread_pool.submit', @@ -602,51 +613,20 @@ def test_create_deployment_request_with_all_marketplaces( json=body, ) - deployment_request = dbsession.query(DeploymentRequest).first() - - assert response.status_code == 201, response.json() - data = response.json() - events = data.pop('events') - assert data == { - 'id': deployment_request.id, - 'deployment': { - 'id': dep.id, - 'product': { - 'id': dep.product.id, - 'name': dep.product.name, - 'icon': dep.product.logo, - }, - 'hub': hub_data, - }, - 'ppr': { - 'id': ppr.id, - 'version': ppr.version, - }, - 'status': DeploymentRequest.STATUSES.pending.value, - 'manually': True, - 'delegate_l2': False, - } - assert list(events.keys()) == ['created'] - assert list(events['created'].keys()) == ['at', 'by'] - assert events['created']['by'] == installation['owner']['id'] - - assert dbsession.query(MarketplaceConfiguration).filter_by( - deployment_request=deployment_request.id, - ).filter( - MarketplaceConfiguration.deployment_id.is_(null()), - MarketplaceConfiguration.marketplace.in_(['MP-123', 'MP-124']), - ).count() == 2 + assert response.status_code == 400 + assert response.json()['error_code'] == 'VAL_001' + assert response.json()['errors'] == [f'deployment: {dep.id} not found.'] -def test_create_deployment_request_invalid_deployment( +def test_create_deployment_request_invalid_ppr( deployment_factory, ppr_version_factory, installation, api_client, ): - deployment_factory(account_id=installation['owner']['id']) - dep = deployment_factory(account_id='PA-123-456') - ppr = ppr_version_factory(deployment=dep) + dep = deployment_factory(account_id=installation['owner']['id']) + other_dep = deployment_factory(account_id='PA-123-456') + ppr = ppr_version_factory(deployment=other_dep) body = { 'deployment': {'id': dep.id}, @@ -655,7 +635,7 @@ def test_create_deployment_request_invalid_deployment( }, 'manually': True, 'delegate_l2': True, - 'marketplaces': {'all': True}, + 'marketplaces': [], } response = api_client.post( @@ -666,27 +646,56 @@ def test_create_deployment_request_invalid_deployment( assert response.status_code == 400 assert response.json()['error_code'] == 'VAL_001' - assert response.json()['errors'] == [f'deployment: {dep.id} not found.'] + assert response.json()['errors'] == [f'ppr: {ppr.id} not found.'] -def test_create_deployment_request_invalid_ppr( +def test_create_deployment_request_invalid_pricelist( deployment_factory, ppr_version_factory, + marketplace_config_factory, installation, api_client, + connect_client, + client_mocker_factory, ): dep = deployment_factory(account_id=installation['owner']['id']) - other_dep = deployment_factory(account_id='PA-123-456') - ppr = ppr_version_factory(deployment=other_dep) + ppr = ppr_version_factory(deployment=dep) + marketplace_config_factory(deployment=dep, marketplace_id='MP-123', ppr_id=ppr.id) + marketplace_config_factory(deployment=dep, marketplace_id='MP-234', ppr_id=ppr.id) body = { 'deployment': {'id': dep.id}, 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': {'all': True}, + 'marketplaces': [ + {'id': 'MP-123', 'pricelist': {'id': 'BAT-123'}}, + {'id': 'MP-234', 'pricelist': {'id': 'BAT-234'}}, + ], } + client_mocker = client_mocker_factory(base_url=connect_client.endpoint) + client_mocker('pricing').batches.filter( + R( + _op=R.OR, + _children=[ + ( + R().stream.context.marketplace.id.eq('MP-123') + & R().id.eq('BAT-123') + ), + ( + R().stream.context.marketplace.id.eq('MP-234') + & R().id.eq('BAT-234') + ), + ], + ), + R().stream.context.product.id.eq(dep.product_id), + R().status.eq('published'), + R().test.ne(True), + ).mock( + return_value=[{'id': 'BAT-123'}], + ) + response = api_client.post( '/api/deployments/requests', installation=installation, @@ -694,8 +703,8 @@ def test_create_deployment_request_invalid_ppr( ) assert response.status_code == 400 - assert response.json()['error_code'] == 'VAL_001' - assert response.json()['errors'] == [f'ppr: {ppr.id} not found.'] + assert response.json()['error_code'] == 'VAL_006' + assert response.json()['errors'] == ['Pricing batches invalid: BAT-234.'] def test_create_deployment_invalid_marketplace( @@ -726,10 +735,12 @@ def test_create_deployment_invalid_marketplace( 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': { - 'choices': [{'id': 'MP-125'}, {'id': 'MP-123'}, {'id': 'MP-126'}, {'id': 'MP-127'}], - 'all': False, - }, + 'marketplaces': [ + {'id': 'MP-125'}, + {'id': 'MP-123'}, + {'id': 'MP-126'}, + {'id': 'MP-127'}, + ], } response = api_client.post( '/api/deployments/requests', @@ -744,9 +755,9 @@ def test_create_deployment_invalid_marketplace( ] -@pytest.mark.parametrize('choices', ([], None)) +@pytest.mark.parametrize('marketplaces', ([], None)) def test_create_deployment_invalid_all_false_w_empty_choices( - choices, + marketplaces, mocker, deployment_factory, marketplace_config_factory, @@ -773,10 +784,7 @@ def test_create_deployment_invalid_all_false_w_empty_choices( 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': { - 'choices': choices, - 'all': False, - }, + 'marketplaces': marketplaces, } response = api_client.post( '/api/deployments/requests', @@ -786,10 +794,10 @@ def test_create_deployment_invalid_all_false_w_empty_choices( assert response.status_code == 400 assert response.json()['error_code'] == 'VAL_003' - assert response.json()['errors'] == ['At least one choice needs to be specified.'] + assert response.json()['errors'] == ['At least one marketplace needs to be specified.'] -def test_create_deployment_invalid_all_false_wo_choices( +def test_create_deployment_invalid_all_false_wo_marketplaces( mocker, deployment_factory, marketplace_config_factory, @@ -816,9 +824,7 @@ def test_create_deployment_invalid_all_false_wo_choices( 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': { - 'all': False, - }, + 'marketplaces': [], } response = api_client.post( '/api/deployments/requests', @@ -828,7 +834,7 @@ def test_create_deployment_invalid_all_false_wo_choices( assert response.status_code == 400 assert response.json()['error_code'] == 'VAL_003' - assert response.json()['errors'] == ['At least one choice needs to be specified.'] + assert response.json()['errors'] == ['At least one marketplace needs to be specified.'] def test_create_deployment_invalid_ppr_for_marketplace( @@ -860,10 +866,11 @@ def test_create_deployment_invalid_ppr_for_marketplace( 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': { - 'choices': [{'id': 'MP-123'}, {'id': 'MP-126'}, {'id': 'MP-124'}], - 'all': False, - }, + 'marketplaces': [ + {'id': 'MP-123'}, + {'id': 'MP-126'}, + {'id': 'MP-124'}, + ], } response = api_client.post( '/api/deployments/requests', @@ -908,10 +915,9 @@ def test_create_deployment_request_w_open_request( 'ppr': {'id': ppr.id}, 'manually': True, 'delegate_l2': True, - 'marketplaces': { - 'choices': [{'id': 'MP-123'}], - 'all': False, - }, + 'marketplaces': [ + {'id': 'MP-123'}, + ], } response = api_client.post( '/api/deployments/requests', @@ -951,7 +957,12 @@ def test_list_deployment_request_marketplaces( dr1 = deployment_request_factory(deployment=dep1) marketplace_config_factory(deployment_request=dr1, marketplace_id=m1['id']) - marketplace_config_factory(deployment_request=dr1, marketplace_id=m2['id'], ppr_id=ppr.id) + marketplace_config_factory( + deployment_request=dr1, + marketplace_id=m2['id'], + ppr_id=ppr.id, + pricelist_id='BAT-123', + ) marketplace_config_factory(deployment_request=dr1, marketplace_id='MP-12345') marketplace_config_factory(deployment=dep1, marketplace_id=m1['id']) @@ -966,6 +977,7 @@ def test_list_deployment_request_marketplaces( } for m in marketplaces ] expected_response[1]['ppr'] = {'id': ppr.id, 'version': ppr.version} + expected_response[1]['pricelist'] = {'id': 'BAT-123'} response = api_client.get( f'/api/deployments/requests/{dr1.id}/marketplaces', diff --git a/tests/api/test_deployments.py b/tests/api/test_deployments.py index 81e1200..741a18a 100644 --- a/tests/api/test_deployments.py +++ b/tests/api/test_deployments.py @@ -274,7 +274,12 @@ def test_get_deployments_marketplaces( deployment = deployment_factory(account_id=installation['owner']['id']) another_dep = deployment_factory(account_id='PA-123-123') ppr = ppr_version_factory(deployment=deployment) - marketplace_config_factory(deployment=deployment, marketplace_id=m1['id'], ppr_id=ppr.id) + marketplace_config_factory( + deployment=deployment, + marketplace_id=m1['id'], + ppr_id=ppr.id, + pricelist_id='BAT-921', + ) marketplace_config_factory(deployment=deployment, marketplace_id=m2['id']) marketplace_config_factory(deployment=deployment, marketplace_id='MP-657', active=False) marketplace_config_factory(deployment=another_dep, marketplace_id=m3['id']) @@ -295,6 +300,7 @@ def test_get_deployments_marketplaces( ] expected_response[0].update({'ppr': {'id': ppr.id, 'version': ppr.version}}) + expected_response[0].update({'pricelist': {'id': 'BAT-921'}}) assert response.json() == expected_response diff --git a/tests/conftest.py b/tests/conftest.py index bcbb160..e4b1483 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -145,6 +145,7 @@ def deployment(dbsession, product_factory): @pytest.fixture def deployment_factory(dbsession, product_factory): def _build_deployment( + id=None, product_id=None, account_id='PA-000-000', vendor_id='VA-000-000', @@ -155,6 +156,7 @@ def _build_deployment( product_id = product.id dep = Deployment( + id=id, product_id=product_id, account_id=account_id, vendor_id=vendor_id, @@ -302,17 +304,19 @@ def _build_mc( deployment=None, deployment_request=None, ppr_id=None, + pricelist_id=None, active=True, ): mp = MarketplaceConfiguration( marketplace=marketplace_id, ppr_id=ppr_id, + pricelist_id=pricelist_id, active=active, ) if deployment: mp.deployment_id = deployment.id else: - mp.deployment_request = deployment_request.id + mp.deployment_request_id = deployment_request.id dbsession.add(mp) dbsession.commit() dbsession.refresh(mp) @@ -329,7 +333,7 @@ def file(file_factory): def connect_client(): return ConnectClient( 'ApiKey fake_api_key', - endpoint='https://localhost/public/v1', + endpoint='https://example.org/public/v1', ) @@ -337,7 +341,7 @@ def connect_client(): def async_connect_client(): return AsyncConnectClient( 'ApiKey fake_api_key', - endpoint='https://localhost/public/v1', + endpoint='https://example.org/public/v1', ) diff --git a/tests/models/test_deployment.py b/tests/models/test_deployment.py index 33d029a..43aa62d 100644 --- a/tests/models/test_deployment.py +++ b/tests/models/test_deployment.py @@ -2,7 +2,11 @@ from sqlalchemy.exc import IntegrityError from connect_ext_ppr.db import VerboseSessionError -from connect_ext_ppr.models.deployment import Deployment, DeploymentRequest +from connect_ext_ppr.models.deployment import ( + Deployment, + DeploymentRequest, + MarketplaceConfiguration, +) from connect_ext_ppr.models.replicas import Product from connect_ext_ppr.models.task import Task @@ -165,44 +169,61 @@ def test_generate_all_next_verbose_id( index += 1 -def test_list_deployment_request_marketplaces_filters( - mocker, +def test_create_marketplace_configuration_deployment( + dbsession, deployment_factory, - deployment_request_factory, - installation, - api_client, - marketplace, - marketplace_config_factory, - ppr_version_factory, ): - m1 = marketplace - marketplaces = [m1] + dep = deployment_factory() + mp_conf = MarketplaceConfiguration( + deployment=dep, + marketplace='US', + ) + + dbsession.commit() + + assert mp_conf.id + assert mp_conf.deployment_id == dep.id + assert mp_conf.deployment_request is None + assert mp_conf.active + assert mp_conf.ppr_id is None + assert mp_conf.pricelist_id is None + - mocker.patch( - 'connect_ext_ppr.webapp.get_marketplaces', - return_value=marketplaces, +def test_create_marketplace_configuration_deployment_req( + dbsession, + deployment_request_factory, +): + dep_req = deployment_request_factory() + mp_conf = MarketplaceConfiguration( + deployment_request=dep_req, + marketplace='US', ) - dep1 = deployment_factory(account_id=installation['owner']['id']) - ppr = ppr_version_factory(deployment=dep1) - dr1 = deployment_request_factory(deployment=dep1) + dbsession.commit() - marketplace_config_factory(deployment_request=dr1, marketplace_id=m1['id']) - marketplace_config_factory(deployment_request=dr1, marketplace_id='MP-12344', ppr_id=ppr.id) - marketplace_config_factory(deployment_request=dr1, marketplace_id='MP-12345') + assert mp_conf.id + assert mp_conf.deployment_request_id == dep_req.id + assert mp_conf.deployment_id is None + assert mp_conf.active + assert mp_conf.ppr_id is None + assert mp_conf.pricelist_id is None - marketplace_config_factory(deployment=dep1, marketplace_id=m1['id']) - marketplace_config_factory(deployment=dep1, marketplace_id='MP-12344') - marketplace_config_factory(deployment=dep1, marketplace_id='MP-124-114') - response = api_client.get( - f"/api/deployments/requests/{dr1.id}/marketplaces?marketplace={m1['id']}", - installation=installation, +def test_create_marketplace_configuration_with_pricelist( + dbsession, + deployment_request_factory, +): + dep_req = deployment_request_factory() + mp_conf = MarketplaceConfiguration( + deployment_request=dep_req, + marketplace='US', + pricelist_id='BAT-1233-1233-1233', ) - assert response.status_code == 200 - assert response.json() == [{ - 'id': m1['id'], - 'name': m1['name'], - 'icon': m1['icon'], - }], response.json() + dbsession.commit() + + assert mp_conf.id + assert mp_conf.deployment_request_id == dep_req.id + assert mp_conf.deployment_id is None + assert mp_conf.active + assert mp_conf.pricelist_id == 'BAT-1233-1233-1233' diff --git a/tests/test_events.py b/tests/test_events.py index f5be7de..0780ffa 100644 --- a/tests/test_events.py +++ b/tests/test_events.py @@ -124,27 +124,27 @@ def test_handle_listing_processing_unlisted( assert dbsession.query(MarketplaceConfiguration).filter_by( active=True, - deployment_request=dep1_dr1.id, + deployment_request_id=dep1_dr1.id, ).count() == 2 assert dbsession.query(MarketplaceConfiguration).filter_by( marketplace=marketplace['id'], active=False, - deployment_request=dep1_dr2.id, + deployment_request_id=dep1_dr2.id, ).count() == 1 assert dbsession.query(MarketplaceConfiguration).filter_by( active=True, - deployment_request=dep1_dr2.id, + deployment_request_id=dep1_dr2.id, ).count() == 1 assert dbsession.query(MarketplaceConfiguration).filter_by( marketplace=marketplace['id'], active=False, - deployment_request=dep2_dr1.id, + deployment_request_id=dep2_dr1.id, ).count() == 1 assert dbsession.query(MarketplaceConfiguration).filter_by( active=True, - deployment_request=dep2_dr1.id, + deployment_request_id=dep2_dr1.id, ).count() == 1 @@ -212,17 +212,17 @@ def test_handle_listing_processing_unlisted_no_marketplace_removal_in_dr( assert dbsession.query(MarketplaceConfiguration).filter_by( active=True, - deployment_request=dep1_dr1.id, + deployment_request_id=dep1_dr1.id, ).count() == 2 assert dbsession.query(MarketplaceConfiguration).filter_by( marketplace=marketplace['id'], active=True, - deployment_request=dep1_dr2.id, + deployment_request_id=dep1_dr2.id, ).count() == 1 assert dbsession.query(MarketplaceConfiguration).filter_by( active=True, - deployment_request=dep1_dr2.id, + deployment_request_id=dep1_dr2.id, ).count() == 2 diff --git a/tests/test_utils.py b/tests/test_utils.py index a05c130..416a1ed 100644 --- a/tests/test_utils.py +++ b/tests/test_utils.py @@ -23,6 +23,15 @@ def test_fail_get_all_info_exc(mocker, connect_client): + mocker.patch( + 'connect_ext_ppr.utils.get_listings', + return_value=[ + { + 'product': {'id': 'P-1'}, + 'contract': {'marketplace': {'id': 'MP-1'}}, + }, + ], + ) mocker.patch( 'connect_ext_ppr.utils.get_marketplaces', side_effect=ClientError(),