"""Functional tests for endpoint to get list of products for account. GET /vendor//products GET /subaccount/subaccount_id>/products """ import json from unittest.mock import MagicMock, patch from owsrequest import flask_request from product.constants import error from product.constants import header from tests.testutils import db @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_vendor_default_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, client, test_vendor, context): """Test get products for a given vendor is successful.""" db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == 5 for item in response_json['items']: assert item['vendor_id'] == test_vendor assert 'product_id' in item assert item['status'] == 'label_processing' @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_vendor_all_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products for a given vendor is successful.""" db.insert_vw_product() mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products?status=all' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == 6 for item in response_json['items']: assert item['vendor_id'] == test_vendor assert 'product_id' in item @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_fails_for_invalid_account_type_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products raises error if no account is provided.""" db.insert_vw_product() mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format('junk', test_vendor)) assert server_response.status_code == 400 @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_vendor_with_specified_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products for a vendor for a specified status is successful.""" db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products?status=in_content' server_response = client.get( request_url.format(header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == 1 for item in response_json['items']: assert item['vendor_id'] == test_vendor assert 'product_id' in item assert item['status'] == 'in_content' @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_vendor_paged_items_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products are paginated for specific offset and limit.""" offset = 1 limit = 2 total = 5 db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products?page_offset={}&page_limit={}' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor, offset, limit)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == limit assert response_json.get('pagination') == { 'offset': offset, 'limit': limit, 'total_records': total, 'type': 'standard'} @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_subaccount_default_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_subaccount, client, context): """Test get products for a given subaccount is successful.""" db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_SUBACCOUNT, test_subaccount)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 for item in response_json['items']: assert item['subaccount_id'] == test_subaccount assert 'product_id' in item assert item['status'] == 'label_processing' @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_subaccount_with_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_subaccount, client, context): """Test get products for a subaccount with given status is successful.""" db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products?status=in_content' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_SUBACCOUNT, test_subaccount)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 for item in response_json['items']: assert item['subaccount_id'] == test_subaccount assert 'product_id' in item assert item['status'] == 'in_content' @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_account_paged_items( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products are paginated for specific offset and limit.""" offset = 1 limit = 2 total = 5 db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products?page_offset={}&page_limit={}' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor, offset, limit)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == limit assert response_json.get('pagination') == { 'offset': offset, 'limit': limit, 'total_records': total, 'type': 'standard'} @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_with_invalid_account_type( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products with invalid account type in route.""" request_url = '/{}/{}/products' mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = True server_response = client.get( request_url.format('junk', test_vendor)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 400 assert response_json['code'] == error.ERROR_CODE_BAD_REQUEST assert response_json['message'] == error.ERROR_MESSAGE_INVALID_ACCOUNT @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_vendor_default_status_valid_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, client, valid_headers, context): """Test get products for given vendor is successful with valid headers.""" db.insert_vw_product() mock_is_jwt_identity_authorized.return_value = True vendor_id = valid_headers[header.GRASS_ACCOUNT_ID] request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, vendor_id), headers=valid_headers) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == 3 for item in response_json['items']: assert item['vendor_id'] == valid_headers[header.GRASS_ACCOUNT_ID] assert 'product_id' in item assert item['status'] == 'label_processing' assert item['subaccount_id'] is not None @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_vendor_route_and_header_mismatched( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, valid_headers, monkeypatch, fixture_subaccount_ownership_failure, context): """Test get products fails when account in route doesn't match headers.""" monkeypatch.setattr( flask_request, 'verify_grass_ownership', value=MagicMock( return_value=fixture_subaccount_ownership_failure)) db.insert_vw_product() mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor), headers=valid_headers) assert server_response.status_code == 403 @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_fails_invalid_account_type( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, not_valid_headers, context): """Test get products fails with junk in Grass headers.""" db.insert_vw_product() not_valid_headers[header.GRASS_ACCOUNT_TYPE] = 'junk' mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor), headers=not_valid_headers) assert server_response.status_code == 403 @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_fails_with_one_missing_header( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, not_valid_headers, context): """Test get products fails when one Grass header is missing.""" db.insert_vw_product() del not_valid_headers[header.GRASS_ACCOUNT_TYPE] mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor), headers=not_valid_headers) assert server_response.status_code == 400 @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_subccount_default_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_subaccount, client, context): """Test get products for a given subaccount is successful.""" db.insert_vw_product() mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_SUBACCOUNT, test_subaccount)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == 2 for item in response_json['items']: assert item['subaccount_id'] == test_subaccount assert 'product_id' in item assert item['status'] == 'label_processing' @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_for_subaccount_with_specified_status_no_headers( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_subaccount, client, context): """Test get products for a subaccount for a status is successful.""" db.insert_vw_product() mock_is_jwt_identity_authorized.return_value = True request_url = '/{}/{}/products?status=in_content' server_response = client.get( request_url.format( header.GRASS_ACCOUNT_TYPE_SUBACCOUNT, test_subaccount)) response_json = json.loads(server_response.data.decode('utf-8')) assert server_response.status_code == 200 assert len(response_json['items']) == 1 for item in response_json['items']: assert item['subaccount_id'] == test_subaccount assert 'product_id' in item assert item['status'] == 'in_content' @patch('product.handlers.g') @patch('product.utils.handler_util.is_jwt_identity_authorized') @db.test_schema def test_get_products_fails_for_invalid_jwt_token( mock_is_jwt_identity_authorized, mock_g: MagicMock, test_vendor, client, context): """Test get products raises error if invalid jwt token is provided.""" db.insert_vw_product() mock_g.request_context.jwt_identity_id = 'dummy_token' mock_is_jwt_identity_authorized.return_value = False request_url = '/{}/{}/products' server_response = client.get(request_url.format( header.GRASS_ACCOUNT_TYPE_VENDOR, test_vendor)) assert server_response.status_code == 403