diff --git a/.gitignore b/.gitignore
index 44dfdf0..19b2b43 100644
--- a/.gitignore
+++ b/.gitignore
@@ -27,4 +27,5 @@ labs-in-progress/
.coverage
tests/python/htmlcov/
-shared/bicep/modules/**/*.json
\ No newline at end of file
+shared/bicep/modules/**/*.json
+main.json
\ No newline at end of file
diff --git a/infrastructure/afd-apim/create.ipynb b/infrastructure/afd-apim/create.ipynb
index 1030b70..0998fdd 100644
--- a/infrastructure/afd-apim/create.ipynb
+++ b/infrastructure/afd-apim/create.ipynb
@@ -57,9 +57,9 @@
"if use_ACA:\n",
" utils.print_info('ACA APIs will be created.')\n",
"\n",
- " aca_backend_1_policy_xml = utils.read_policy_xml(ACA_BACKEND_1_XML_POLICY_PATH)\n",
- " aca_backend_2_policy_xml = utils.read_policy_xml(ACA_BACKEND_2_XML_POLICY_PATH)\n",
- " aca_backend_pool_policy_xml = utils.read_policy_xml(ACA_BACKEND_POOL_XML_POLICY_PATH)\n",
+ " aca_backend_1_policy_xml = utils.read_policy_xml(BACKEND_XML_POLICY_PATH).format(backend_id = 'aca-backend-1')\n",
+ " aca_backend_2_policy_xml = utils.read_policy_xml(BACKEND_XML_POLICY_PATH).format(backend_id = 'aca-backend-2')\n",
+ " aca_backend_pool_policy_xml = utils.read_policy_xml(BACKEND_XML_POLICY_PATH).format(backend_id = 'aca-backend-pool')\n",
"\n",
" # Hello World (ACA Backend 1)\n",
" api_hwaca_1_get = GET_APIOperation('This is a GET for Hello World on ACA Backend 1')\n",
diff --git a/infrastructure/afd-apim/main.bicep b/infrastructure/afd-apim/main.bicep
index 4918a19..ad4fc96 100644
--- a/infrastructure/afd-apim/main.bicep
+++ b/infrastructure/afd-apim/main.bicep
@@ -226,7 +226,7 @@ module backendPoolModule '../../shared/bicep/modules/apim/v1/backend-pool.bicep'
// 8. APIM APIs
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in apis: if(length(apis) > 0) {
- name: '${api.name}-${resourceSuffix}'
+ name: 'api-${api.name}'
params: {
apimName: apimName
appInsightsInstrumentationKey: appInsightsInstrumentationKey
diff --git a/infrastructure/apim-aca/create.ipynb b/infrastructure/apim-aca/create.ipynb
index 6ee828a..1ede262 100644
--- a/infrastructure/apim-aca/create.ipynb
+++ b/infrastructure/apim-aca/create.ipynb
@@ -46,9 +46,9 @@
"\n",
"# Policies\n",
"hello_world_policy_xml = utils.read_policy_xml(HELLO_WORLD_XML_POLICY_PATH)\n",
- "aca_backend_1_policy_xml = utils.read_policy_xml(ACA_BACKEND_1_XML_POLICY_PATH)\n",
- "aca_backend_2_policy_xml = utils.read_policy_xml(ACA_BACKEND_2_XML_POLICY_PATH)\n",
- "aca_backend_pool_policy_xml = utils.read_policy_xml(ACA_BACKEND_POOL_XML_POLICY_PATH)\n",
+ "aca_backend_1_policy_xml = utils.read_policy_xml(BACKEND_XML_POLICY_PATH).format(backend_id = 'aca-backend-1')\n",
+ "aca_backend_2_policy_xml = utils.read_policy_xml(BACKEND_XML_POLICY_PATH).format(backend_id = 'aca-backend-2')\n",
+ "aca_backend_pool_policy_xml = utils.read_policy_xml(BACKEND_XML_POLICY_PATH).format(backend_id = 'aca-backend-pool')\n",
"\n",
"# Hello World (Root)\n",
"api_hwroot_get = GET_APIOperation('This is a GET for Hello World in the root', hello_world_policy_xml)\n",
diff --git a/infrastructure/apim-aca/main.bicep b/infrastructure/apim-aca/main.bicep
index 406b57e..469da37 100644
--- a/infrastructure/apim-aca/main.bicep
+++ b/infrastructure/apim-aca/main.bicep
@@ -134,7 +134,7 @@ module backendPoolModule '../../shared/bicep/modules/apim/v1/backend-pool.bicep'
// 7. APIM APIs
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [
for api in apis: if (length(apis) > 0) {
- name: '${api.name}-${resourceSuffix}'
+ name: 'api-${api.name}'
params: {
apimName: apimName
appInsightsInstrumentationKey: appInsightsInstrumentationKey
diff --git a/infrastructure/simple-apim/main.bicep b/infrastructure/simple-apim/main.bicep
index b2af5e2..048d3bd 100644
--- a/infrastructure/simple-apim/main.bicep
+++ b/infrastructure/simple-apim/main.bicep
@@ -49,7 +49,7 @@ module apimModule '../../shared/bicep/modules/apim/v1/apim.bicep' = {
// 4. APIM APIs
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in apis: if(length(apis) > 0) {
- name: '${api.name}-${resourceSuffix}'
+ name: 'api-${api.name}'
params: {
apimName: apimName
appInsightsInstrumentationKey: appInsightsInstrumentationKey
diff --git a/samples/authX-pro/create.ipynb b/samples/authX-pro/create.ipynb
index 635779f..f069ac8 100644
--- a/samples/authX-pro/create.ipynb
+++ b/samples/authX-pro/create.ipynb
@@ -126,8 +126,9 @@
" hr_member_role_id = '{{HRMemberRoleId}}'\n",
")\n",
"\n",
+ "hr_product_name = 'hr'\n",
"products: List[Product] = [\n",
- " Product('hr', 'Human Resources', 'Product for Human Resources APIs providing access to employee data, organizational structure, benefits information, and HR management services. Includes JWT-based authentication for HR members.', 'published', False, False, hr_product_xml)\n",
+ " Product(hr_product_name, 'Human Resources', 'Product for Human Resources APIs providing access to employee data, organizational structure, benefits information, and HR management services. Includes JWT-based authentication for HR members.', 'published', False, False, hr_product_xml)\n",
"]\n",
"\n",
"# 6) Define the APIs and their operations and policies\n",
@@ -136,13 +137,13 @@
"hremployees_api_path = f'/{api_prefix}employees'\n",
"hremployees_get = GET_APIOperation('Gets the employees', utils.read_policy_xml('./hr_get.xml'))\n",
"hremployees_post = POST_APIOperation('Creates a new employee', utils.read_policy_xml('./hr_post.xml'))\n",
- "hremployees = API(f'{api_prefix}Employees', 'Employees Pro', hremployees_api_path, 'This is a Human Resources API for employee information', utils.read_policy_xml(DEFAULT_XML_POLICY_PATH), operations = [hremployees_get, hremployees_post], tags = tags, productNames = ['hr'])\n",
+ "hremployees = API(f'{api_prefix}Employees', 'Employees Pro', hremployees_api_path, 'This is a Human Resources API for employee information', utils.read_policy_xml(DEFAULT_XML_POLICY_PATH), operations = [hremployees_get, hremployees_post], tags = tags, productNames = [hr_product_name])\n",
"\n",
"# Benefits (HR)\n",
"hrbenefits_api_path = f'/{api_prefix}benefits'\n",
"hrbenefits_get = GET_APIOperation('Gets employee benefits', utils.read_policy_xml('./hr_get.xml'))\n",
"hrbenefits_post = POST_APIOperation('Creates employee benefits', utils.read_policy_xml('./hr_post.xml'))\n",
- "hrbenefits = API(f'{api_prefix}Benefits', 'Benefits Pro', hrbenefits_api_path, 'This is a Human Resources API for employee benefits', utils.read_policy_xml(DEFAULT_XML_POLICY_PATH), operations = [hrbenefits_get, hrbenefits_post], tags = tags, productNames = ['hr'])\n",
+ "hrbenefits = API(f'{api_prefix}Benefits', 'Benefits Pro', hrbenefits_api_path, 'This is a Human Resources API for employee benefits', utils.read_policy_xml(DEFAULT_XML_POLICY_PATH), operations = [hrbenefits_get, hrbenefits_post], tags = tags, productNames = [hr_product_name])\n",
"\n",
"# APIs Array\n",
"apis: List[API] = [hremployees, hrbenefits]\n",
@@ -171,7 +172,8 @@
"bicep_parameters = {\n",
" 'apis': {'value': [api.to_dict() for api in apis]},\n",
" 'namedValues': {'value': [nv.to_dict() for nv in nvs]},\n",
- " 'policyFragments': {'value': [pf.to_dict() for pf in pfs]}\n",
+ " 'policyFragments': {'value': [pf.to_dict() for pf in pfs]},\n",
+ " 'products': {'value': [product.to_dict() for product in products]}\n",
"}\n",
"\n",
"# 2) Infrastructure must be in place before samples can be layered on top\n",
diff --git a/samples/authX-pro/main.bicep b/samples/authX-pro/main.bicep
index d5f3377..322675d 100644
--- a/samples/authX-pro/main.bicep
+++ b/samples/authX-pro/main.bicep
@@ -78,7 +78,8 @@ module productHr '../../shared/bicep/modules/apim/v1/product.bicep' = [for produ
]
}]
-// APIM APIs
+// APIM APIs (deployed after products are ready to avoid race conditions)
+@batchSize(1) // Deploy APIs sequentially to avoid race conditions
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in apis: {
name: 'api-${api.name}'
params:{
@@ -90,7 +91,8 @@ module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in a
}
dependsOn: [
namedValue // ensure all named values are created before APIs
- productHr // ensure products are created before APIs that reference them
+ policyFragment // ensure all policy fragments are created before APIs
+ productHr // ensure all products are fully created before APIs
]
}]
diff --git a/samples/authX/hr_product.xml b/samples/authX/hr_product.xml
deleted file mode 100644
index e1be748..0000000
--- a/samples/authX/hr_product.xml
+++ /dev/null
@@ -1,31 +0,0 @@
-
-
-
-
-
-
- {jwt_signing_key}
-
-
-
- {hr_member_role_id}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/authX/main.bicep b/samples/authX/main.bicep
index 8c516cf..f2651ad 100644
--- a/samples/authX/main.bicep
+++ b/samples/authX/main.bicep
@@ -34,7 +34,7 @@ resource apimService 'Microsoft.ApiManagement/service@2024-06-01-preview' existi
// APIM Named Values
module namedValue '../../shared/bicep/modules/apim/v1/named-value.bicep' = [for nv in namedValues: if (!empty(namedValues)) {
- name: nv.name
+ name: 'nv-${nv.name}'
params: {
apimName: apimName
namedValueName: nv.name
@@ -45,7 +45,7 @@ module namedValue '../../shared/bicep/modules/apim/v1/named-value.bicep' = [for
// APIM APIs
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in apis: if(!empty(apis)) {
- name: '${api.name}-${resourceSuffix}'
+ name: 'api-${api.name}'
params: {
apimName: apimName
appInsightsInstrumentationKey: appInsightsInstrumentationKey
diff --git a/samples/general/create.ipynb b/samples/general/create.ipynb
index d5fdf03..7ce247c 100644
--- a/samples/general/create.ipynb
+++ b/samples/general/create.ipynb
@@ -46,7 +46,7 @@
"# 1) User-defined parameters (change these as needed)\n",
"rg_location = 'eastus2'\n",
"index = 1\n",
- "deployment = INFRASTRUCTURE.AFD_APIM_PE\n",
+ "deployment = INFRASTRUCTURE.SIMPLE_APIM\n",
"tags = ['general']\n",
"\n",
"# 2) Service-defined parameters (please do not change these)\n",
diff --git a/samples/general/main.bicep b/samples/general/main.bicep
index 1e222a8..4a51c99 100644
--- a/samples/general/main.bicep
+++ b/samples/general/main.bicep
@@ -32,7 +32,7 @@ resource apimService 'Microsoft.ApiManagement/service@2024-06-01-preview' existi
// APIM APIs
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [for api in apis: if(!empty(apis)) {
- name: '${api.name}-${resourceSuffix}'
+ name: 'api-${api.name}'
params: {
apimName: apimName
appInsightsInstrumentationKey: appInsightsInstrumentationKey
diff --git a/samples/load-balancing/main.bicep b/samples/load-balancing/main.bicep
index 599b29c..1900ddf 100644
--- a/samples/load-balancing/main.bicep
+++ b/samples/load-balancing/main.bicep
@@ -197,7 +197,7 @@ module backendPoolModule4 '../../shared/bicep/modules/apim/v1/backend-pool.bicep
// APIM APIs
module apisModule '../../shared/bicep/modules/apim/v1/api.bicep' = [
for api in apis: if (!empty(apis)) {
- name: '${api.name}-${resourceSuffix}'
+ name: 'api-${api.name}'
params: {
apimName: apimName
appInsightsInstrumentationKey: appInsightsInstrumentationKey
diff --git a/shared/apim-policies/aca-backend-2.xml b/shared/apim-policies/aca-backend-2.xml
deleted file mode 100644
index 4c86d0b..0000000
--- a/shared/apim-policies/aca-backend-2.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/shared/apim-policies/aca-backend-pool.xml b/shared/apim-policies/aca-backend-pool.xml
deleted file mode 100644
index 49a4e9f..0000000
--- a/shared/apim-policies/aca-backend-pool.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/shared/apim-policies/aca-backend-1.xml b/shared/apim-policies/backend.xml
similarity index 83%
rename from shared/apim-policies/aca-backend-1.xml
rename to shared/apim-policies/backend.xml
index 03e81ec..1da050d 100644
--- a/shared/apim-policies/aca-backend-1.xml
+++ b/shared/apim-policies/backend.xml
@@ -4,7 +4,7 @@
-
+
diff --git a/shared/apim-policies/fragments/pf-authz-match-all.xml b/shared/apim-policies/fragments/pf-authz-match-all.xml
new file mode 100644
index 0000000..5711225
--- /dev/null
+++ b/shared/apim-policies/fragments/pf-authz-match-all.xml
@@ -0,0 +1,26 @@
+
+
+
+
+ ("authz_roles", "").ToString().Split(',');
+ var jwtRoles = jwt.Claims.GetValueOrDefault("roles", new string[0]);
+
+ // Check if ALL required role GUIDs are present in the JWT
+ return !requiredRoleGuids.All(requiredRole => jwtRoles.Contains(requiredRole.Trim()));
+ }">
+
+
+ Access denied - not all required roles found
+
+
+
+
+
diff --git a/shared/apim-policies/fragments/pf-authz-match-any.xml b/shared/apim-policies/fragments/pf-authz-match-any.xml
index de4899c..79a0a64 100644
--- a/shared/apim-policies/fragments/pf-authz-match-any.xml
+++ b/shared/apim-policies/fragments/pf-authz-match-any.xml
@@ -3,8 +3,7 @@
- "jwt": The parsed JWT token which should already be set by the pf-authx fragment.
- "authz_roles": A csv of allowed role GUIDs to check against. Any match will grant access.
- - This fragment only blocks access (returns 403) when no roles match. If roles match, processing
-continues normally.
+ - This fragment only blocks access (returns 403) when no roles match. If roles match, processing continues normally.
-->
diff --git a/shared/bicep/modules/apim/v1/api.bicep b/shared/bicep/modules/apim/v1/api.bicep
index b2a92e3..da6980d 100644
--- a/shared/bicep/modules/apim/v1/api.bicep
+++ b/shared/bicep/modules/apim/v1/api.bicep
@@ -149,11 +149,24 @@ resource apiDiagnostics 'Microsoft.ApiManagement/service/apis/diagnostics@2024-0
} }
}
+// Product associations are handled directly in this module with proper dependency management // to prevent race conditions while keeping the architecture simple
+// Reference existing products for association (with explicit dependency timing)
+resource apimProducts 'Microsoft.ApiManagement/service/products@2024-06-01-preview' existing = [for productName in productNames: {
+ name: productName
+ parent: apimService
+}]
+
+// Create product-API associations with proper dependency management
// https://learn.microsoft.com/azure/templates/microsoft.apimanagement/service/products/apis
-resource apiProductAssociation 'Microsoft.ApiManagement/service/products/apis@2024-05-01' = [for productName in productNames: {
- name: '${apimName}/${productName}/${api.name}'
+resource apiProductAssociation 'Microsoft.ApiManagement/service/products/apis@2024-06-01-preview' = [for (productName, index) in productNames: {
+ name: apimApi.name
+ parent: apimProducts[index]
dependsOn: [
- apimApi
+ apimProducts[index] // Ensure the specific product exists and is ready
+ apiPolicy // Ensure API policy is applied if present
+ apiOperation // Ensure all operations are created
+ apiOperationPolicy // Ensure all operation policies are applied
+ apiDiagnostics // Ensure diagnostics are configured if present
]
}]
@@ -174,10 +187,10 @@ output apiDisplayName string = apimApi.properties.displayName
@description('The path of the created API.')
output apiPath string = apimApi.properties.path
-// @description('Array of product names this API is associated with.')
-// output associatedProducts string[] = productNames
+@description('Array of product names this API is associated with.')
+output associatedProducts array = productNames
-// @description('Number of products this API is associated with.')
-// output productAssociationCount int = length(productNames)
+@description('Number of products this API is associated with.')
+output productAssociationCount int = length(productNames)
//output subscriptionPrimaryKey string = apimSubscription.listSecrets().primaryKey
diff --git a/shared/python/apimtypes.py b/shared/python/apimtypes.py
index 8850acd..e608856 100644
--- a/shared/python/apimtypes.py
+++ b/shared/python/apimtypes.py
@@ -16,9 +16,7 @@
DEFAULT_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/default.xml'
HELLO_WORLD_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/hello-world.xml'
REQUEST_HEADERS_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/request-headers.xml'
-ACA_BACKEND_1_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/aca-backend-1.xml'
-ACA_BACKEND_2_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/aca-backend-2.xml'
-ACA_BACKEND_POOL_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/aca-backend-pool.xml'
+BACKEND_XML_POLICY_PATH = f'{SHARED_XML_POLICY_BASE_PATH}/backend.xml'
SUBSCRIPTION_KEY_PARAMETER_NAME = 'api_key'
SLEEP_TIME_BETWEEN_REQUESTS_MS = 50
diff --git a/tests/python/test_apimrequests.py b/tests/python/test_apimrequests.py
index 60f5bda..f427004 100644
--- a/tests/python/test_apimrequests.py
+++ b/tests/python/test_apimrequests.py
@@ -1,8 +1,8 @@
import pytest
import requests
from unittest.mock import patch, MagicMock
-from shared.python.apimrequests import ApimRequests
-from shared.python.apimtypes import HTTP_VERB, SUBSCRIPTION_KEY_PARAMETER_NAME
+from apimrequests import ApimRequests
+from apimtypes import SUBSCRIPTION_KEY_PARAMETER_NAME
# Sample values for tests
default_url = "https://example.com/apim/"
@@ -35,10 +35,10 @@ def test_init_no_key():
assert apim.headers["Accept"] == "application/json"
@pytest.mark.http
-@patch("shared.python.apimrequests.requests.request")
-@patch("shared.python.apimrequests.utils.print_message")
-@patch("shared.python.apimrequests.utils.print_info")
-@patch("shared.python.apimrequests.utils.print_error")
+@patch("apimrequests.requests.request")
+@patch("apimrequests.utils.print_message")
+@patch("apimrequests.utils.print_info")
+@patch("apimrequests.utils.print_error")
def test_single_get_success(mock_print_error, mock_print_info, mock_print_message, mock_request, apim):
mock_response = MagicMock()
mock_response.status_code = 200
@@ -55,10 +55,10 @@ def test_single_get_success(mock_print_error, mock_print_info, mock_print_messag
mock_print_error.assert_not_called()
@pytest.mark.http
-@patch("shared.python.apimrequests.requests.request")
-@patch("shared.python.apimrequests.utils.print_message")
-@patch("shared.python.apimrequests.utils.print_info")
-@patch("shared.python.apimrequests.utils.print_error")
+@patch("apimrequests.requests.request")
+@patch("apimrequests.utils.print_message")
+@patch("apimrequests.utils.print_info")
+@patch("apimrequests.utils.print_error")
def test_single_get_error(mock_print_error, mock_print_info, mock_print_message, mock_request, apim):
mock_request.side_effect = requests.exceptions.RequestException("fail")
result = apim.singleGet(default_path, printResponse=True)
@@ -66,10 +66,10 @@ def test_single_get_error(mock_print_error, mock_print_info, mock_print_message,
mock_print_error.assert_called_once()
@pytest.mark.http
-@patch("shared.python.apimrequests.requests.request")
-@patch("shared.python.apimrequests.utils.print_message")
-@patch("shared.python.apimrequests.utils.print_info")
-@patch("shared.python.apimrequests.utils.print_error")
+@patch("apimrequests.requests.request")
+@patch("apimrequests.utils.print_message")
+@patch("apimrequests.utils.print_info")
+@patch("apimrequests.utils.print_error")
def test_single_post_success(mock_print_error, mock_print_info, mock_print_message, mock_request, apim):
mock_response = MagicMock()
mock_response.status_code = 201
@@ -86,9 +86,9 @@ def test_single_post_success(mock_print_error, mock_print_info, mock_print_messa
mock_print_error.assert_not_called()
@pytest.mark.http
-@patch("shared.python.apimrequests.requests.Session")
-@patch("shared.python.apimrequests.utils.print_message")
-@patch("shared.python.apimrequests.utils.print_info")
+@patch("apimrequests.requests.Session")
+@patch("apimrequests.utils.print_message")
+@patch("apimrequests.utils.print_info")
def test_multi_get_success(mock_print_info, mock_print_message, mock_session, apim):
mock_sess = MagicMock()
mock_response = MagicMock()
@@ -110,9 +110,9 @@ def test_multi_get_success(mock_print_info, mock_print_message, mock_session, ap
mock_print_code.assert_called()
@pytest.mark.http
-@patch("shared.python.apimrequests.requests.Session")
-@patch("shared.python.apimrequests.utils.print_message")
-@patch("shared.python.apimrequests.utils.print_info")
+@patch("apimrequests.requests.Session")
+@patch("apimrequests.utils.print_message")
+@patch("apimrequests.utils.print_info")
def test_multi_get_error(mock_print_info, mock_print_message, mock_session, apim):
mock_sess = MagicMock()
mock_sess.request.side_effect = requests.exceptions.RequestException("fail")
@@ -134,8 +134,8 @@ def make_apim():
@pytest.mark.http
def test_single_post_error():
apim = make_apim()
- with patch("shared.python.apimrequests.requests.request") as mock_request, \
- patch("shared.python.apimrequests.utils.print_error") as mock_print_error:
+ with patch("apimrequests.requests.request") as mock_request, \
+ patch("apimrequests.utils.print_error") as mock_print_error:
import requests
mock_request.side_effect = requests.RequestException("fail")
result = apim.singlePost(path, data={"foo": "bar"}, printResponse=True)
@@ -145,7 +145,7 @@ def test_single_post_error():
@pytest.mark.http
def test_multi_get_non_json():
apim = make_apim()
- with patch("shared.python.apimrequests.requests.Session") as mock_session:
+ with patch("apimrequests.requests.Session") as mock_session:
mock_sess = MagicMock()
mock_response = MagicMock()
mock_response.status_code = 200
@@ -161,7 +161,7 @@ def test_multi_get_non_json():
@pytest.mark.http
def test_request_header_merging():
apim = make_apim()
- with patch("shared.python.apimrequests.requests.request") as mock_request:
+ with patch("apimrequests.requests.request") as mock_request:
mock_response = MagicMock()
mock_response.status_code = 200
mock_response.headers = {"Content-Type": "application/json"}
@@ -189,7 +189,7 @@ def test_print_response_code_edge():
class DummyResponse:
status_code = 302
reason = "Found"
- with patch("shared.python.apimrequests.utils.print_val") as mock_print_val:
+ with patch("apimrequests.utils.print_val") as mock_print_val:
apim._print_response_code(DummyResponse())
mock_print_val.assert_called_with("Response status", "302")
diff --git a/tests/python/test_apimtypes.py b/tests/python/test_apimtypes.py
index ffa0a74..63e7bb7 100644
--- a/tests/python/test_apimtypes.py
+++ b/tests/python/test_apimtypes.py
@@ -1,8 +1,9 @@
"""
Unit tests for apimtypes.py.
"""
+
import pytest
-from shared.python import apimtypes
+import apimtypes
# ------------------------------
@@ -279,14 +280,6 @@ def test_api_missing_fields():
policyXml = EXAMPLE_POLICY_XML
)
- # with pytest.raises(TypeError):
- # apimtypes.API(
- # name = EXAMPLE_NAME,
- # displayName = EXAMPLE_DISPLAY_NAME,
- # path = EXAMPLE_PATH,
- # description = EXAMPLE_DESCRIPTION
- # )
-
# ------------------------------
# ENUMS
diff --git a/tests/python/test_utils.py b/tests/python/test_utils.py
index b94ed4e..1226c67 100644
--- a/tests/python/test_utils.py
+++ b/tests/python/test_utils.py
@@ -2,9 +2,8 @@
from apimtypes import INFRASTRUCTURE
import os
import builtins
-from io import StringIO
-from unittest.mock import patch, MagicMock, mock_open
-from shared.python import utils
+from unittest.mock import MagicMock, mock_open
+import utils
from apimtypes import INFRASTRUCTURE
# ------------------------------