Properly report initial clin information
Includes fixed up state machine test as well as adds some missing dependencies
This commit is contained in:
parent
81054b2ff0
commit
ea040a914e
1
Pipfile
1
Pipfile
@ -36,6 +36,7 @@ transitions = "*"
|
||||
azure-mgmt-consumption = "*"
|
||||
adal = "*"
|
||||
azure-identity = "*"
|
||||
azure-keyvault = "*"
|
||||
|
||||
[dev-packages]
|
||||
bandit = "*"
|
||||
|
82
Pipfile.lock
generated
82
Pipfile.lock
generated
@ -1,7 +1,7 @@
|
||||
{
|
||||
"_meta": {
|
||||
"hash": {
|
||||
"sha256": "3760f0b1df1156211d671afa2eb417b7bf980aa33d2f74d390e8eed6a3ce8c8b"
|
||||
"sha256": "4dbb023bcb860eb6dc56e1c201c91f272e1e67ad03e5e5eeb3a7a7fdff350eed"
|
||||
},
|
||||
"pipfile-spec": 6,
|
||||
"requires": {
|
||||
@ -26,10 +26,10 @@
|
||||
},
|
||||
"alembic": {
|
||||
"hashes": [
|
||||
"sha256:3b0cb1948833e062f4048992fbc97ecfaaaac24aaa0d83a1202a99fb58af8c6d"
|
||||
"sha256:d412982920653db6e5a44bfd13b1d0db5685cbaaccaf226195749c706e1e862a"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.2"
|
||||
"version": "==1.3.3"
|
||||
},
|
||||
"amqp": {
|
||||
"hashes": [
|
||||
@ -68,6 +68,28 @@
|
||||
"index": "pypi",
|
||||
"version": "==1.2.0"
|
||||
},
|
||||
"azure-keyvault": {
|
||||
"hashes": [
|
||||
"sha256:76f75cb83929f312a08616d426ad6f597f1beae180131cf445876fb88f2c8ef1",
|
||||
"sha256:e85f5bd6cb4f10b3248b99bbf02e3acc6371d366846897027d4153f18025a2d7"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"azure-keyvault-keys": {
|
||||
"hashes": [
|
||||
"sha256:2983fa42e20a0e6bf6b87976716129c108e613e0292d34c5b0f0c8dc1d488e89",
|
||||
"sha256:38c27322637a2c52620a8b96da1942ad6a8d22d09b5a01f6fa257f7a51e52ed0"
|
||||
],
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"azure-keyvault-secrets": {
|
||||
"hashes": [
|
||||
"sha256:2eae9264a8f6f59277e1a9bfdbc8b0a15969ee5a80d8efe403d7744805b4a481",
|
||||
"sha256:97a602406a833e8f117c540c66059c818f4321a35168dd17365fab1e4527d718"
|
||||
],
|
||||
"version": "==4.0.0"
|
||||
},
|
||||
"azure-mgmt-authorization": {
|
||||
"hashes": [
|
||||
"sha256:31e875a34ac2c5d6fefe77b4a8079a8b2bdbe9edb957e47e8b44222fb212d6a7",
|
||||
@ -232,6 +254,14 @@
|
||||
],
|
||||
"version": "==2.8"
|
||||
},
|
||||
"dataclasses": {
|
||||
"hashes": [
|
||||
"sha256:3459118f7ede7c8bea0fe795bff7c6c2ce287d01dd226202f7c9ebc0610a7836",
|
||||
"sha256:494a6dcae3b8bcf80848eea2ef64c0cc5cd307ffc263e17cdf42f3e5420808e6"
|
||||
],
|
||||
"markers": "python_version < '3.7'",
|
||||
"version": "==0.7"
|
||||
},
|
||||
"flask": {
|
||||
"hashes": [
|
||||
"sha256:13f9f196f330c7c2c5d7a5cf91af894110ca0215ac051b5844701f2bfd934d52",
|
||||
@ -325,9 +355,9 @@
|
||||
},
|
||||
"mako": {
|
||||
"hashes": [
|
||||
"sha256:a36919599a9b7dc5d86a7a8988f23a9a3a3d083070023bab23d64f7f1d1e0a4b"
|
||||
"sha256:2984a6733e1d472796ceef37ad48c26f4a984bb18119bb2dbc37a44d8f6e75a4"
|
||||
],
|
||||
"version": "==1.1.0"
|
||||
"version": "==1.1.1"
|
||||
},
|
||||
"markupsafe": {
|
||||
"hashes": [
|
||||
@ -584,10 +614,10 @@
|
||||
},
|
||||
"sqlalchemy": {
|
||||
"hashes": [
|
||||
"sha256:bfb8f464a5000b567ac1d350b9090cf081180ec1ab4aa87e7bca12dab25320ec"
|
||||
"sha256:64a7b71846db6423807e96820993fa12a03b89127d278290ca25c0b11ed7b4fb"
|
||||
],
|
||||
"index": "pypi",
|
||||
"version": "==1.3.12"
|
||||
"version": "==1.3.13"
|
||||
},
|
||||
"sqlalchemy-json": {
|
||||
"hashes": [
|
||||
@ -620,10 +650,10 @@
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293",
|
||||
"sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"
|
||||
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
|
||||
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
|
||||
],
|
||||
"version": "==1.25.7"
|
||||
"version": "==1.25.8"
|
||||
},
|
||||
"vine": {
|
||||
"hashes": [
|
||||
@ -657,10 +687,10 @@
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:57147f6b0403b59f33fd357f169f860e031303415aeb7d04ede4839d23905ab8",
|
||||
"sha256:7ae5ccaca427bafa9760ac3cd8f8c244bfc259794b5b6bb9db4dda2241575d09"
|
||||
"sha256:b338014b9bc7102ca69e0fb96ed07215a8954d2989bc5d83658494ab2ba634af",
|
||||
"sha256:e013e7800f60ec4dde789ebf4e9f7a54236e4bbf5df2a1a4e20ce9e1d9609d67"
|
||||
],
|
||||
"version": "==2.0.0"
|
||||
"version": "==2.0.1"
|
||||
}
|
||||
},
|
||||
"develop": {
|
||||
@ -671,6 +701,14 @@
|
||||
],
|
||||
"version": "==1.4.3"
|
||||
},
|
||||
"appnope": {
|
||||
"hashes": [
|
||||
"sha256:5b26757dc6f79a3b7dc9fab95359328d5747fcb2409d331ea66d0272b90ab2a0",
|
||||
"sha256:8b995ffe925347a2138d7ac0fe77155e4311a0ea6d6da4f5128fe4b3cbe5ed71"
|
||||
],
|
||||
"markers": "sys_platform == 'darwin'",
|
||||
"version": "==0.1.0"
|
||||
},
|
||||
"argh": {
|
||||
"hashes": [
|
||||
"sha256:a9b3aaa1904eeb78e32394cd46c6f37ac0fb4af6dc488daa58971bdc7d7fcaf3",
|
||||
@ -1062,11 +1100,11 @@
|
||||
},
|
||||
"pexpect": {
|
||||
"hashes": [
|
||||
"sha256:2094eefdfcf37a1fdbfb9aa090862c1a4878e5c7e0e7e7088bdb511c558e5cd1",
|
||||
"sha256:9e2c1fd0e6ee3a49b28f95d4b33bc389c89b20af6a1255906e90ff1262ce62eb"
|
||||
"sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937",
|
||||
"sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"
|
||||
],
|
||||
"markers": "sys_platform != 'win32'",
|
||||
"version": "==4.7.0"
|
||||
"version": "==4.8.0"
|
||||
},
|
||||
"pickleshare": {
|
||||
"hashes": [
|
||||
@ -1325,10 +1363,10 @@
|
||||
},
|
||||
"urllib3": {
|
||||
"hashes": [
|
||||
"sha256:a8a318824cc77d1fd4b2bec2ded92646630d7fe8619497b142c84a9e6f5a7293",
|
||||
"sha256:f3c5fd51747d450d4dcf6f923c81f78f811aab8205fda64b0aba34a4e48b0745"
|
||||
"sha256:2f3db8b19923a873b3e5256dc9c2dedfa883e33d87c690d9c7913e1f40673cdc",
|
||||
"sha256:87716c2d2a7121198ebcb7ce7cccf6ce5e9ba539041cfbaeecfb641dc0bf6acc"
|
||||
],
|
||||
"version": "==1.25.7"
|
||||
"version": "==1.25.8"
|
||||
},
|
||||
"watchdog": {
|
||||
"hashes": [
|
||||
@ -1359,10 +1397,10 @@
|
||||
},
|
||||
"zipp": {
|
||||
"hashes": [
|
||||
"sha256:57147f6b0403b59f33fd357f169f860e031303415aeb7d04ede4839d23905ab8",
|
||||
"sha256:7ae5ccaca427bafa9760ac3cd8f8c244bfc259794b5b6bb9db4dda2241575d09"
|
||||
"sha256:b338014b9bc7102ca69e0fb96ed07215a8954d2989bc5d83658494ab2ba634af",
|
||||
"sha256:e013e7800f60ec4dde789ebf4e9f7a54236e4bbf5df2a1a4e20ce9e1d9609d67"
|
||||
],
|
||||
"version": "==2.0.0"
|
||||
"version": "==2.0.1"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -327,12 +327,12 @@ class TaskOrderBillingCreationCSPPayload(BaseCSPPayload):
|
||||
|
||||
class TaskOrderBillingCreationCSPResult(AliasModel):
|
||||
task_order_billing_verify_url: str
|
||||
retry_after: int
|
||||
task_order_retry_after: int
|
||||
|
||||
class Config:
|
||||
fields = {
|
||||
"task_order_billing_verify_url": "Location",
|
||||
"retry_after": "Retry-After",
|
||||
"task_order_retry_after": "Retry-After",
|
||||
}
|
||||
|
||||
|
||||
@ -358,11 +358,11 @@ class TaskOrderBillingVerificationCSPResult(AliasModel):
|
||||
|
||||
|
||||
class BillingInstructionCSPPayload(BaseCSPPayload):
|
||||
amount: float
|
||||
start_date: str
|
||||
end_date: str
|
||||
clin_type: str
|
||||
task_order_id: str
|
||||
initial_clin_amount: float
|
||||
initial_clin_start_date: str
|
||||
initial_clin_end_date: str
|
||||
initial_clin_type: str
|
||||
initial_task_order_id: str
|
||||
billing_account_name: str
|
||||
billing_profile_name: str
|
||||
|
||||
@ -646,19 +646,76 @@ class MockCloudProvider(CloudProviderInterface):
|
||||
self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION)
|
||||
self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION)
|
||||
|
||||
return {
|
||||
"id": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB/billingRoleAssignments/40000000-aaaa-bbbb-cccc-100000000000_0a5f4926-e3ee-4f47-a6e3-8b0a30a40e3d",
|
||||
"name": "40000000-aaaa-bbbb-cccc-100000000000_0a5f4926-e3ee-4f47-a6e3-8b0a30a40e3d",
|
||||
return BillingProfileTenantAccessCSPResult(
|
||||
**{
|
||||
"id": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB/billingRoleAssignments/40000000-aaaa-bbbb-cccc-100000000000_0a5f4926-e3ee-4f47-a6e3-8b0a30a40e3d",
|
||||
"name": "40000000-aaaa-bbbb-cccc-100000000000_0a5f4926-e3ee-4f47-a6e3-8b0a30a40e3d",
|
||||
"properties": {
|
||||
"createdOn": "2020-01-14T14:39:26.3342192+00:00",
|
||||
"createdByPrincipalId": "82e2b376-3297-4096-8743-ed65b3be0b03",
|
||||
"principalId": "0a5f4926-e3ee-4f47-a6e3-8b0a30a40e3d",
|
||||
"principalTenantId": "60ff9d34-82bf-4f21-b565-308ef0533435",
|
||||
"roleDefinitionId": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB/billingRoleDefinitions/40000000-aaaa-bbbb-cccc-100000000000",
|
||||
"scope": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB",
|
||||
},
|
||||
"type": "Microsoft.Billing/billingRoleAssignments",
|
||||
}
|
||||
).dict()
|
||||
|
||||
def create_task_order_billing_creation(self, payload: TaskOrderBillingCreationCSPPayload):
|
||||
self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION)
|
||||
self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION)
|
||||
self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION)
|
||||
|
||||
return TaskOrderBillingCreationCSPResult(**{"Location": "https://somelocation", "Retry-After": "10"}).dict()
|
||||
|
||||
def create_task_order_billing_verification(self, payload: TaskOrderBillingVerificationCSPPayload):
|
||||
self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION)
|
||||
self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION)
|
||||
self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION)
|
||||
|
||||
return TaskOrderBillingVerificationCSPResult(**{
|
||||
"id": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/XC36-GRNZ-BG7-TGB",
|
||||
"name": "XC36-GRNZ-BG7-TGB",
|
||||
"properties": {
|
||||
"createdOn": "2020-01-14T14:39:26.3342192+00:00",
|
||||
"createdByPrincipalId": "82e2b376-3297-4096-8743-ed65b3be0b03",
|
||||
"principalId": "0a5f4926-e3ee-4f47-a6e3-8b0a30a40e3d",
|
||||
"principalTenantId": "60ff9d34-82bf-4f21-b565-308ef0533435",
|
||||
"roleDefinitionId": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB/billingRoleDefinitions/40000000-aaaa-bbbb-cccc-100000000000",
|
||||
"scope": "/providers/Microsoft.Billing/billingAccounts/7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31/billingProfiles/KQWI-W2SU-BG7-TGB",
|
||||
"address": {
|
||||
"addressLine1": "123 S Broad Street, Suite 2400",
|
||||
"city": "Philadelphia",
|
||||
"companyName": "Promptworks",
|
||||
"country": "US",
|
||||
"postalCode": "19109",
|
||||
"region": "PA"
|
||||
},
|
||||
"currency": "USD",
|
||||
"displayName": "First Portfolio Billing Profile",
|
||||
"enabledAzurePlans": [
|
||||
{
|
||||
"productId": "DZH318Z0BPS6",
|
||||
"skuId": "0001",
|
||||
"skuDescription": "Microsoft Azure Plan"
|
||||
}
|
||||
],
|
||||
"hasReadAccess": True,
|
||||
"invoiceDay": 5,
|
||||
"invoiceEmailOptIn": False
|
||||
},
|
||||
"type": "Microsoft.Billing/billingRoleAssignments",
|
||||
}
|
||||
"type": "Microsoft.Billing/billingAccounts/billingProfiles"
|
||||
}).dict()
|
||||
|
||||
def create_billing_instruction(self, payload: BillingInstructionCSPPayload):
|
||||
self._maybe_raise(self.NETWORK_FAILURE_PCT, self.NETWORK_EXCEPTION)
|
||||
self._maybe_raise(self.SERVER_FAILURE_PCT, self.SERVER_EXCEPTION)
|
||||
self._maybe_raise(self.UNAUTHORIZED_RATE, self.AUTHORIZATION_EXCEPTION)
|
||||
|
||||
return BillingInstructionCSPResult(**{
|
||||
"name": "TO1:CLIN001",
|
||||
"properties": {
|
||||
"amount": 1000.0,
|
||||
"endDate": "2020-03-01T00:00:00+00:00",
|
||||
"startDate": "2020-01-01T00:00:00+00:00"
|
||||
},
|
||||
"type": "Microsoft.Billing/billingAccounts/billingProfiles/billingInstructions"
|
||||
}).dict()
|
||||
|
||||
def create_or_update_user(self, auth_credentials, user_info, csp_role_id):
|
||||
self._authorize(auth_credentials)
|
||||
@ -1150,13 +1207,13 @@ class AzureCloudProvider(CloudProviderInterface):
|
||||
|
||||
request_body = {
|
||||
"properties": {
|
||||
"amount": payload.amount,
|
||||
"startDate": payload.start_date,
|
||||
"endDate": payload.end_date,
|
||||
"amount": payload.initial_clin_amount,
|
||||
"startDate": payload.initial_clin_start_date,
|
||||
"endDate": payload.initial_clin_end_date,
|
||||
}
|
||||
}
|
||||
|
||||
url = f"https://management.azure.com/providers/Microsoft.Billing/billingAccounts/{payload.billing_account_name}/billingProfiles/{payload.billing_profile_name}/instructions/{payload.task_order_id}:CLIN00{payload.clin_type}?api-version=2019-10-01-preview"
|
||||
url = f"https://management.azure.com/providers/Microsoft.Billing/billingAccounts/{payload.billing_account_name}/billingProfiles/{payload.billing_profile_name}/instructions/{payload.initial_task_order_id}:CLIN00{payload.initial_clin_type}?api-version=2019-10-01-preview"
|
||||
|
||||
auth_header = {
|
||||
"Authorization": f"Bearer {sp_token}",
|
||||
|
@ -67,7 +67,6 @@ class PortfolioStateMachine(
|
||||
def __repr__(self):
|
||||
return f"<PortfolioStateMachine(state='{self.current_state.name}', portfolio='{self.portfolio.name}'"
|
||||
|
||||
|
||||
@reconstructor
|
||||
def attach_machine(self):
|
||||
"""
|
||||
@ -112,7 +111,9 @@ class PortfolioStateMachine(
|
||||
if create_trigger:
|
||||
self.trigger(create_trigger, **kwargs)
|
||||
else:
|
||||
app.logger.info(f"could not locate 'create trigger' for {self.__repr__()}")
|
||||
app.logger.info(
|
||||
f"could not locate 'create trigger' for {self.__repr__()}"
|
||||
)
|
||||
self.fail_stage(stage)
|
||||
|
||||
elif state_obj.is_CREATED:
|
||||
@ -143,8 +144,11 @@ class PortfolioStateMachine(
|
||||
try:
|
||||
payload_data = payload_data_cls(**payload)
|
||||
except PydanticValidationError as exc:
|
||||
app.logger.error(f"Payload Validation Error in {self.__repr__()}:", exc_info=1)
|
||||
app.logger.error(
|
||||
f"Payload Validation Error in {self.__repr__()}:", exc_info=1
|
||||
)
|
||||
app.logger.info(exc.json())
|
||||
print(exc.json())
|
||||
app.logger.info(payload)
|
||||
self.fail_stage(stage)
|
||||
|
||||
@ -161,7 +165,10 @@ class PortfolioStateMachine(
|
||||
func_name = f"create_{stage}"
|
||||
response = getattr(self.csp, func_name)(payload_data)
|
||||
except (ConnectionException, UnknownServerException) as exc:
|
||||
app.logger.error(f"CSP api call. Caught exception for {self.__repr__()}. Retry attempt {attempt}", exc_info=1)
|
||||
app.logger.error(
|
||||
f"CSP api call. Caught exception for {self.__repr__()}. Retry attempt {attempt}",
|
||||
exc_info=1,
|
||||
)
|
||||
continue
|
||||
else:
|
||||
break
|
||||
@ -198,12 +205,16 @@ class PortfolioStateMachine(
|
||||
dc = cls(**stage_data)
|
||||
if getattr(dc, "get_creds", None) is not None:
|
||||
new_creds = dc.get_creds()
|
||||
print("creds to report")
|
||||
print(new_creds)
|
||||
# TODO: how/where to store these
|
||||
# TODO: credential schema
|
||||
# self.store_creds(self.portfolio, new_creds)
|
||||
|
||||
except PydanticValidationError as exc:
|
||||
app.logger.error(f"Payload Validation Error in {self.__repr__()}:", exc_info=1)
|
||||
app.logger.error(
|
||||
f"Payload Validation Error in {self.__repr__()}:", exc_info=1
|
||||
)
|
||||
app.logger.info(exc.json())
|
||||
app.logger.info(payload)
|
||||
|
||||
|
@ -404,11 +404,11 @@ def test_create_billing_instruction(mock_azure: AzureCloudProvider):
|
||||
payload = BillingInstructionCSPPayload(
|
||||
**dict(
|
||||
creds=creds,
|
||||
amount=1000.00,
|
||||
start_date="2020/1/1",
|
||||
end_date="2020/3/1",
|
||||
clin_type="1",
|
||||
task_order_id="TO1",
|
||||
initial_clin_amount=1000.00,
|
||||
initial_clin_start_date="2020/1/1",
|
||||
initial_clin_end_date="2020/3/1",
|
||||
initial_clin_type="1",
|
||||
initial_task_order_id="TO1",
|
||||
billing_account_name="7c89b735-b22b-55c0-ab5a-c624843e8bf6:de4416ce-acc6-44b1-8122-c87c4e903c91_2019-05-31",
|
||||
billing_profile_name="KQWI-W2SU-BG7-TGB",
|
||||
)
|
||||
|
@ -4,16 +4,19 @@ import re
|
||||
from tests.factories import (
|
||||
PortfolioFactory,
|
||||
PortfolioStateMachineFactory,
|
||||
TaskOrderFactory,
|
||||
CLINFactory,
|
||||
)
|
||||
|
||||
from atst.models import FSMStates, PortfolioStateMachine
|
||||
from atst.models import FSMStates, PortfolioStateMachine, TaskOrder
|
||||
from atst.models.mixins.state_machines import AzureStages, StageStates, compose_state
|
||||
from atst.models.portfolio import Portfolio
|
||||
from atst.domain.csp import get_stage_csp_class
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def portfolio():
|
||||
portfolio = PortfolioFactory.create()
|
||||
portfolio = CLINFactory.create().task_order.portfolio
|
||||
return portfolio
|
||||
|
||||
|
||||
@ -77,7 +80,7 @@ def test_state_machine_initialization(portfolio):
|
||||
assert ["reset", "fail", create_trigger] == started_triggers
|
||||
|
||||
|
||||
def test_fsm_transition_start(portfolio):
|
||||
def test_fsm_transition_start(portfolio: Portfolio):
|
||||
sm: PortfolioStateMachine = PortfolioStateMachineFactory.create(portfolio=portfolio)
|
||||
assert sm.portfolio
|
||||
assert sm.state == FSMStates.UNSTARTED
|
||||
@ -88,6 +91,16 @@ def test_fsm_transition_start(portfolio):
|
||||
sm.start()
|
||||
assert sm.state == FSMStates.STARTED
|
||||
|
||||
expected_states = [
|
||||
FSMStates.TENANT_CREATED,
|
||||
FSMStates.BILLING_PROFILE_CREATION_CREATED,
|
||||
FSMStates.BILLING_PROFILE_VERIFICATION_CREATED,
|
||||
FSMStates.BILLING_PROFILE_TENANT_ACCESS_CREATED,
|
||||
FSMStates.TASK_ORDER_BILLING_CREATION_CREATED,
|
||||
FSMStates.TASK_ORDER_BILLING_VERIFICATION_CREATED,
|
||||
FSMStates.BILLING_INSTRUCTION_CREATED,
|
||||
]
|
||||
|
||||
# Should source all creds for portfolio? might be easier to manage than per-step specific ones
|
||||
creds = {"username": "mock-cloud", "password": "shh"}
|
||||
if portfolio.csp_data is not None:
|
||||
@ -95,19 +108,21 @@ def test_fsm_transition_start(portfolio):
|
||||
else:
|
||||
csp_data = {}
|
||||
|
||||
# ppoc = portfolio.owner
|
||||
# user_id = f"{ppoc.first_name[0]}{ppoc.last_name}".lower()
|
||||
user_id = "abcdefg"
|
||||
ppoc = portfolio.owner
|
||||
user_id = f"{ppoc.first_name[0]}{ppoc.last_name}".lower()
|
||||
domain_name = re.sub("[^0-9a-zA-Z]+", "", portfolio.name).lower()
|
||||
|
||||
initial_task_order: TaskOrder = portfolio.task_orders[0]
|
||||
initial_clin = initial_task_order.sorted_clins[0]
|
||||
|
||||
portfolio_data = {
|
||||
"user_id": user_id,
|
||||
"password": "jklfsdNCVD83nklds2#202",
|
||||
"domain_name": domain_name,
|
||||
"first_name": "john", # ppoc.first_name,
|
||||
"last_name": "doe", # ppoc.last_name,
|
||||
"first_name": ppoc.first_name,
|
||||
"last_name": ppoc.last_name,
|
||||
"country_code": "US",
|
||||
"password_recovery_email_address": "email@example.com", # ppoc.email,
|
||||
"password_recovery_email_address": ppoc.email,
|
||||
"address": {
|
||||
"company_name": "",
|
||||
"address_line_1": "",
|
||||
@ -117,26 +132,24 @@ def test_fsm_transition_start(portfolio):
|
||||
"postal_code": "",
|
||||
},
|
||||
"billing_profile_display_name": "My Billing Profile",
|
||||
"initial_clin_amount": initial_clin.obligated_amount,
|
||||
"initial_clin_start_date": initial_clin.start_date.strftime("%Y/%m/%d"),
|
||||
"initial_clin_end_date": initial_clin.end_date.strftime("%Y/%m/%d"),
|
||||
"initial_clin_type": initial_clin.number,
|
||||
"initial_task_order_id": initial_task_order.number,
|
||||
}
|
||||
|
||||
config = {"billing_account_name": "billing_account_name"}
|
||||
|
||||
collected_data = dict(
|
||||
list(csp_data.items()) + list(portfolio_data.items()) + list(config.items())
|
||||
)
|
||||
sm.trigger_next_transition(creds=creds, csp_data=collected_data)
|
||||
for expected_state in expected_states:
|
||||
print(expected_state)
|
||||
collected_data = dict(
|
||||
list(csp_data.items()) + list(portfolio_data.items()) + list(config.items())
|
||||
)
|
||||
sm.trigger_next_transition(creds=creds, csp_data=collected_data)
|
||||
assert sm.state == expected_state
|
||||
if portfolio.csp_data is not None:
|
||||
csp_data = portfolio.csp_data
|
||||
else:
|
||||
csp_data = {}
|
||||
|
||||
assert sm.state == FSMStates.TENANT_CREATED
|
||||
assert portfolio.csp_data.get("tenant_id", None) is not None
|
||||
#print(portfolio.csp_data.keys())
|
||||
if portfolio.csp_data is not None:
|
||||
csp_data = portfolio.csp_data
|
||||
else:
|
||||
csp_data = {}
|
||||
collected_data = dict(
|
||||
list(csp_data.items()) + list(portfolio_data.items()) + list(config.items())
|
||||
)
|
||||
sm.trigger_next_transition(creds=creds, csp_data=collected_data)
|
||||
assert sm.state == FSMStates.BILLING_PROFILE_CREATION_CREATED
|
||||
|
||||
#print(portfolio.csp_data.keys())
|
||||
|
@ -66,6 +66,12 @@ def mock_requests():
|
||||
return Mock(spec=requests)
|
||||
|
||||
|
||||
def mock_secrets():
|
||||
from azure.keyvault import secrets
|
||||
|
||||
return Mock(spec=secrets)
|
||||
|
||||
|
||||
class MockAzureSDK(object):
|
||||
def __init__(self):
|
||||
from msrestazure.azure_cloud import AZURE_PUBLIC_CLOUD
|
||||
@ -78,6 +84,7 @@ class MockAzureSDK(object):
|
||||
self.graphrbac = mock_graphrbac()
|
||||
self.credentials = mock_credentials()
|
||||
self.policy = mock_policy()
|
||||
self.secrets = mock_secrets()
|
||||
self.requests = mock_requests()
|
||||
# may change to a JEDI cloud
|
||||
self.cloud = AZURE_PUBLIC_CLOUD
|
||||
|
Loading…
x
Reference in New Issue
Block a user