cumulusci-plus 5.0.35__py3-none-any.whl → 5.0.43__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- cumulusci/__about__.py +1 -1
- cumulusci/cli/task.py +9 -10
- cumulusci/cli/tests/test_org.py +5 -0
- cumulusci/cli/tests/test_task.py +34 -0
- cumulusci/core/config/__init__.py +1 -0
- cumulusci/core/config/org_config.py +2 -1
- cumulusci/core/config/project_config.py +12 -0
- cumulusci/core/config/scratch_org_config.py +12 -0
- cumulusci/core/config/tests/test_config.py +1 -0
- cumulusci/core/dependencies/base.py +4 -0
- cumulusci/cumulusci.yml +18 -1
- cumulusci/schema/cumulusci.jsonschema.json +5 -0
- cumulusci/tasks/apex/testrunner.py +7 -4
- cumulusci/tasks/bulkdata/tests/test_select_utils.py +20 -0
- cumulusci/tasks/metadata_etl/__init__.py +2 -0
- cumulusci/tasks/metadata_etl/applications.py +256 -0
- cumulusci/tasks/metadata_etl/tests/test_applications.py +710 -0
- cumulusci/tasks/salesforce/insert_record.py +18 -19
- cumulusci/tasks/salesforce/tests/test_enable_prediction.py +4 -2
- cumulusci/tasks/salesforce/tests/test_update_external_auth_identity_provider.py +927 -0
- cumulusci/tasks/salesforce/tests/test_update_external_credential.py +523 -8
- cumulusci/tasks/salesforce/tests/test_update_record.py +512 -0
- cumulusci/tasks/salesforce/update_external_auth_identity_provider.py +551 -0
- cumulusci/tasks/salesforce/update_external_credential.py +89 -4
- cumulusci/tasks/salesforce/update_record.py +217 -0
- cumulusci/tasks/sfdmu/sfdmu.py +14 -1
- cumulusci/tasks/utility/credentialManager.py +58 -12
- cumulusci/tasks/utility/secretsToEnv.py +2 -2
- cumulusci/tasks/utility/tests/test_credentialManager.py +586 -0
- cumulusci/tasks/utility/tests/test_secretsToEnv.py +42 -15
- cumulusci/utils/yaml/cumulusci_yml.py +1 -0
- {cumulusci_plus-5.0.35.dist-info → cumulusci_plus-5.0.43.dist-info}/METADATA +6 -7
- {cumulusci_plus-5.0.35.dist-info → cumulusci_plus-5.0.43.dist-info}/RECORD +37 -31
- {cumulusci_plus-5.0.35.dist-info → cumulusci_plus-5.0.43.dist-info}/WHEEL +1 -1
- {cumulusci_plus-5.0.35.dist-info → cumulusci_plus-5.0.43.dist-info}/entry_points.txt +0 -0
- {cumulusci_plus-5.0.35.dist-info → cumulusci_plus-5.0.43.dist-info}/licenses/AUTHORS.rst +0 -0
- {cumulusci_plus-5.0.35.dist-info → cumulusci_plus-5.0.43.dist-info}/licenses/LICENSE +0 -0
|
@@ -109,7 +109,7 @@ class TestExternalCredentialParameter:
|
|
|
109
109
|
assert param.auth_provider == "MyAuthProvider"
|
|
110
110
|
result = param.get_external_credential_parameter()
|
|
111
111
|
assert result["parameterType"] == "AuthProvider"
|
|
112
|
-
assert result["
|
|
112
|
+
assert result["authProvider"] == "MyAuthProvider"
|
|
113
113
|
assert result["parameterName"] == "AuthProvider"
|
|
114
114
|
|
|
115
115
|
def test_parameter_with_auth_provider_url(self):
|
|
@@ -231,7 +231,9 @@ class TestTransformExternalCredentialParameter:
|
|
|
231
231
|
auth_provider="MY_AUTH_PROVIDER"
|
|
232
232
|
)
|
|
233
233
|
result = param.get_external_credential_parameter()
|
|
234
|
-
assert
|
|
234
|
+
assert (
|
|
235
|
+
result["authProvider"] == "MY_AUTH_PROVIDER"
|
|
236
|
+
) # Transform doesn't apply to authProvider field
|
|
235
237
|
|
|
236
238
|
def test_transform_parameter_missing_env(self):
|
|
237
239
|
"""Test parameter transformation with missing environment variable"""
|
|
@@ -507,6 +509,23 @@ class TestUpdateExternalCredential:
|
|
|
507
509
|
@responses.activate
|
|
508
510
|
def test_update_external_credential_with_namespace(self):
|
|
509
511
|
"""Test update of external credential with namespace"""
|
|
512
|
+
# Mock SF API version discovery
|
|
513
|
+
responses.add(
|
|
514
|
+
method="GET",
|
|
515
|
+
url="https://test.salesforce.com/services/data",
|
|
516
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
517
|
+
status=200,
|
|
518
|
+
)
|
|
519
|
+
|
|
520
|
+
# Mock installed packages query
|
|
521
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
522
|
+
responses.add(
|
|
523
|
+
method="GET",
|
|
524
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
525
|
+
json={"size": 0, "records": []},
|
|
526
|
+
status=200,
|
|
527
|
+
)
|
|
528
|
+
|
|
510
529
|
task = create_task(
|
|
511
530
|
UpdateExternalCredential,
|
|
512
531
|
{
|
|
@@ -517,7 +536,6 @@ class TestUpdateExternalCredential:
|
|
|
517
536
|
)
|
|
518
537
|
|
|
519
538
|
ext_cred_id = "0XE1234567890ABC"
|
|
520
|
-
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
521
539
|
|
|
522
540
|
# Mock query for external credential ID
|
|
523
541
|
responses.add(
|
|
@@ -556,7 +574,7 @@ class TestUpdateExternalCredential:
|
|
|
556
574
|
)
|
|
557
575
|
|
|
558
576
|
task()
|
|
559
|
-
assert len(responses.calls) == 3
|
|
577
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
560
578
|
|
|
561
579
|
@responses.activate
|
|
562
580
|
def test_update_external_credential_add_new_parameter(self):
|
|
@@ -758,6 +776,23 @@ class TestUpdateExternalCredential:
|
|
|
758
776
|
@responses.activate
|
|
759
777
|
def test_update_external_credential_no_existing_parameters(self):
|
|
760
778
|
"""Test update when external credential has no existing parameters"""
|
|
779
|
+
# Mock SF API version discovery
|
|
780
|
+
responses.add(
|
|
781
|
+
method="GET",
|
|
782
|
+
url="https://test.salesforce.com/services/data",
|
|
783
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
784
|
+
status=200,
|
|
785
|
+
)
|
|
786
|
+
|
|
787
|
+
# Mock installed packages query
|
|
788
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
789
|
+
responses.add(
|
|
790
|
+
method="GET",
|
|
791
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
792
|
+
json={"size": 0, "records": []},
|
|
793
|
+
status=200,
|
|
794
|
+
)
|
|
795
|
+
|
|
761
796
|
task = create_task(
|
|
762
797
|
UpdateExternalCredential,
|
|
763
798
|
{
|
|
@@ -767,7 +802,6 @@ class TestUpdateExternalCredential:
|
|
|
767
802
|
)
|
|
768
803
|
|
|
769
804
|
ext_cred_id = "0XE1234567890ABC"
|
|
770
|
-
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
771
805
|
|
|
772
806
|
# Mock query for external credential ID
|
|
773
807
|
responses.add(
|
|
@@ -794,11 +828,28 @@ class TestUpdateExternalCredential:
|
|
|
794
828
|
)
|
|
795
829
|
|
|
796
830
|
task()
|
|
797
|
-
assert len(responses.calls) == 3
|
|
831
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
798
832
|
|
|
799
833
|
@responses.activate
|
|
800
834
|
def test_update_external_credential_with_multiple_parameters(self):
|
|
801
835
|
"""Test update with multiple parameters"""
|
|
836
|
+
# Mock SF API version discovery
|
|
837
|
+
responses.add(
|
|
838
|
+
method="GET",
|
|
839
|
+
url="https://test.salesforce.com/services/data",
|
|
840
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
841
|
+
status=200,
|
|
842
|
+
)
|
|
843
|
+
|
|
844
|
+
# Mock installed packages query
|
|
845
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
846
|
+
responses.add(
|
|
847
|
+
method="GET",
|
|
848
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
849
|
+
json={"size": 0, "records": []},
|
|
850
|
+
status=200,
|
|
851
|
+
)
|
|
852
|
+
|
|
802
853
|
auth_header = HttpHeader(name="Authorization", value="Bearer token123")
|
|
803
854
|
jwt_claim = ExtParameter(name="sub", value='{"sub":"user"}')
|
|
804
855
|
task = create_task(
|
|
@@ -814,7 +865,6 @@ class TestUpdateExternalCredential:
|
|
|
814
865
|
)
|
|
815
866
|
|
|
816
867
|
ext_cred_id = "0XE1234567890ABC"
|
|
817
|
-
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
818
868
|
|
|
819
869
|
# Mock query for external credential ID
|
|
820
870
|
responses.add(
|
|
@@ -853,7 +903,7 @@ class TestUpdateExternalCredential:
|
|
|
853
903
|
)
|
|
854
904
|
|
|
855
905
|
task()
|
|
856
|
-
assert len(responses.calls) == 3
|
|
906
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
857
907
|
|
|
858
908
|
@responses.activate
|
|
859
909
|
def test_update_external_credential_with_sequence_number(self):
|
|
@@ -910,3 +960,468 @@ class TestUpdateExternalCredential:
|
|
|
910
960
|
|
|
911
961
|
task()
|
|
912
962
|
assert len(responses.calls) == 3
|
|
963
|
+
|
|
964
|
+
@responses.activate
|
|
965
|
+
def test_auth_provider_removes_external_auth_identity_provider(self):
|
|
966
|
+
"""Test that adding AuthProvider removes ExternalAuthIdentityProvider"""
|
|
967
|
+
# Mock SF API version discovery
|
|
968
|
+
responses.add(
|
|
969
|
+
method="GET",
|
|
970
|
+
url="https://test.salesforce.com/services/data",
|
|
971
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
972
|
+
status=200,
|
|
973
|
+
)
|
|
974
|
+
|
|
975
|
+
# Mock installed packages query
|
|
976
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
977
|
+
responses.add(
|
|
978
|
+
method="GET",
|
|
979
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
980
|
+
json={"size": 0, "records": []},
|
|
981
|
+
status=200,
|
|
982
|
+
)
|
|
983
|
+
|
|
984
|
+
task = create_task(
|
|
985
|
+
UpdateExternalCredential,
|
|
986
|
+
{
|
|
987
|
+
"name": "testExtCred",
|
|
988
|
+
"parameters": [{"auth_provider": "MyAuthProvider"}],
|
|
989
|
+
},
|
|
990
|
+
)
|
|
991
|
+
|
|
992
|
+
ext_cred_id = "0XE1234567890ABC"
|
|
993
|
+
|
|
994
|
+
# Mock query for external credential ID
|
|
995
|
+
responses.add(
|
|
996
|
+
method="GET",
|
|
997
|
+
url=f"{tooling_url}/query/?q=SELECT+Id+FROM+ExternalCredential+WHERE+DeveloperName%3D%27testExtCred%27+LIMIT+1",
|
|
998
|
+
json={"size": 1, "records": [{"Id": ext_cred_id}]},
|
|
999
|
+
status=200,
|
|
1000
|
+
)
|
|
1001
|
+
|
|
1002
|
+
# Mock get external credential object with ExternalAuthIdentityProvider
|
|
1003
|
+
responses.add(
|
|
1004
|
+
method="GET",
|
|
1005
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1006
|
+
json={
|
|
1007
|
+
"Metadata": {
|
|
1008
|
+
"externalCredentialParameters": [
|
|
1009
|
+
{
|
|
1010
|
+
"parameterType": "ExternalAuthIdentityProvider",
|
|
1011
|
+
"parameterName": "ExternalAuthIdentityProvider",
|
|
1012
|
+
"externalAuthIdentityProvider": "OldProvider",
|
|
1013
|
+
"authProvider": None,
|
|
1014
|
+
"certificate": None,
|
|
1015
|
+
"description": None,
|
|
1016
|
+
"parameterGroup": "DefaultGroup",
|
|
1017
|
+
"parameterValue": None,
|
|
1018
|
+
"sequenceNumber": None,
|
|
1019
|
+
},
|
|
1020
|
+
{
|
|
1021
|
+
"parameterType": "AuthParameter",
|
|
1022
|
+
"parameterName": "Scope",
|
|
1023
|
+
"parameterValue": "scope",
|
|
1024
|
+
"authProvider": None,
|
|
1025
|
+
"certificate": None,
|
|
1026
|
+
"description": None,
|
|
1027
|
+
"externalAuthIdentityProvider": None,
|
|
1028
|
+
"parameterGroup": "DefaultGroup",
|
|
1029
|
+
"sequenceNumber": None,
|
|
1030
|
+
},
|
|
1031
|
+
],
|
|
1032
|
+
}
|
|
1033
|
+
},
|
|
1034
|
+
status=200,
|
|
1035
|
+
)
|
|
1036
|
+
|
|
1037
|
+
# Mock update external credential
|
|
1038
|
+
responses.add(
|
|
1039
|
+
method="PATCH",
|
|
1040
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1041
|
+
json={},
|
|
1042
|
+
status=200,
|
|
1043
|
+
)
|
|
1044
|
+
|
|
1045
|
+
task()
|
|
1046
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
1047
|
+
|
|
1048
|
+
# Verify the PATCH request removed ExternalAuthIdentityProvider
|
|
1049
|
+
patch_call = responses.calls[4] # Last call is the PATCH
|
|
1050
|
+
updated_params = patch_call.request.body
|
|
1051
|
+
import json
|
|
1052
|
+
|
|
1053
|
+
body = json.loads(updated_params)
|
|
1054
|
+
params = body["Metadata"]["externalCredentialParameters"]
|
|
1055
|
+
|
|
1056
|
+
# Should not contain ExternalAuthIdentityProvider
|
|
1057
|
+
assert not any(
|
|
1058
|
+
p.get("parameterType") == "ExternalAuthIdentityProvider" for p in params
|
|
1059
|
+
)
|
|
1060
|
+
# Should contain AuthProvider
|
|
1061
|
+
assert any(p.get("parameterType") == "AuthProvider" for p in params)
|
|
1062
|
+
# Should still contain AuthParameter
|
|
1063
|
+
assert any(p.get("parameterType") == "AuthParameter" for p in params)
|
|
1064
|
+
|
|
1065
|
+
@responses.activate
|
|
1066
|
+
def test_external_auth_identity_provider_removes_auth_provider(self):
|
|
1067
|
+
"""Test that adding ExternalAuthIdentityProvider removes AuthProvider"""
|
|
1068
|
+
# Mock SF API version discovery
|
|
1069
|
+
responses.add(
|
|
1070
|
+
method="GET",
|
|
1071
|
+
url="https://test.salesforce.com/services/data",
|
|
1072
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
1073
|
+
status=200,
|
|
1074
|
+
)
|
|
1075
|
+
|
|
1076
|
+
# Mock installed packages query
|
|
1077
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
1078
|
+
responses.add(
|
|
1079
|
+
method="GET",
|
|
1080
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
1081
|
+
json={"size": 0, "records": []},
|
|
1082
|
+
status=200,
|
|
1083
|
+
)
|
|
1084
|
+
|
|
1085
|
+
task = create_task(
|
|
1086
|
+
UpdateExternalCredential,
|
|
1087
|
+
{
|
|
1088
|
+
"name": "testExtCred",
|
|
1089
|
+
"parameters": [
|
|
1090
|
+
{"external_auth_identity_provider": "MyExternalAuthProvider"}
|
|
1091
|
+
],
|
|
1092
|
+
},
|
|
1093
|
+
)
|
|
1094
|
+
|
|
1095
|
+
ext_cred_id = "0XE1234567890ABC"
|
|
1096
|
+
|
|
1097
|
+
# Mock query for external credential ID
|
|
1098
|
+
responses.add(
|
|
1099
|
+
method="GET",
|
|
1100
|
+
url=f"{tooling_url}/query/?q=SELECT+Id+FROM+ExternalCredential+WHERE+DeveloperName%3D%27testExtCred%27+LIMIT+1",
|
|
1101
|
+
json={"size": 1, "records": [{"Id": ext_cred_id}]},
|
|
1102
|
+
status=200,
|
|
1103
|
+
)
|
|
1104
|
+
|
|
1105
|
+
# Mock get external credential object with AuthProvider
|
|
1106
|
+
responses.add(
|
|
1107
|
+
method="GET",
|
|
1108
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1109
|
+
json={
|
|
1110
|
+
"Metadata": {
|
|
1111
|
+
"externalCredentialParameters": [
|
|
1112
|
+
{
|
|
1113
|
+
"parameterType": "AuthProvider",
|
|
1114
|
+
"parameterName": "AuthProvider",
|
|
1115
|
+
"authProvider": "OldAuthProvider",
|
|
1116
|
+
"certificate": None,
|
|
1117
|
+
"description": None,
|
|
1118
|
+
"externalAuthIdentityProvider": None,
|
|
1119
|
+
"parameterGroup": "DefaultGroup",
|
|
1120
|
+
"parameterValue": "OldAuthProvider",
|
|
1121
|
+
"sequenceNumber": None,
|
|
1122
|
+
},
|
|
1123
|
+
{
|
|
1124
|
+
"parameterType": "AuthParameter",
|
|
1125
|
+
"parameterName": "Scope",
|
|
1126
|
+
"parameterValue": "scope",
|
|
1127
|
+
"authProvider": None,
|
|
1128
|
+
"certificate": None,
|
|
1129
|
+
"description": None,
|
|
1130
|
+
"externalAuthIdentityProvider": None,
|
|
1131
|
+
"parameterGroup": "DefaultGroup",
|
|
1132
|
+
"sequenceNumber": None,
|
|
1133
|
+
},
|
|
1134
|
+
],
|
|
1135
|
+
}
|
|
1136
|
+
},
|
|
1137
|
+
status=200,
|
|
1138
|
+
)
|
|
1139
|
+
|
|
1140
|
+
# Mock update external credential
|
|
1141
|
+
responses.add(
|
|
1142
|
+
method="PATCH",
|
|
1143
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1144
|
+
json={},
|
|
1145
|
+
status=200,
|
|
1146
|
+
)
|
|
1147
|
+
|
|
1148
|
+
task()
|
|
1149
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
1150
|
+
|
|
1151
|
+
# Verify the PATCH request removed AuthProvider
|
|
1152
|
+
patch_call = responses.calls[4] # Last call is the PATCH
|
|
1153
|
+
updated_params = patch_call.request.body
|
|
1154
|
+
import json
|
|
1155
|
+
|
|
1156
|
+
body = json.loads(updated_params)
|
|
1157
|
+
params = body["Metadata"]["externalCredentialParameters"]
|
|
1158
|
+
|
|
1159
|
+
# Should not contain AuthProvider
|
|
1160
|
+
assert not any(p.get("parameterType") == "AuthProvider" for p in params)
|
|
1161
|
+
# Should contain ExternalAuthIdentityProvider
|
|
1162
|
+
assert any(
|
|
1163
|
+
p.get("parameterType") == "ExternalAuthIdentityProvider" for p in params
|
|
1164
|
+
)
|
|
1165
|
+
# Should still contain AuthParameter
|
|
1166
|
+
assert any(p.get("parameterType") == "AuthParameter" for p in params)
|
|
1167
|
+
|
|
1168
|
+
@responses.activate
|
|
1169
|
+
def test_multiple_auth_providers_removed(self):
|
|
1170
|
+
"""Test that multiple conflicting parameters are removed"""
|
|
1171
|
+
# Mock SF API version discovery
|
|
1172
|
+
responses.add(
|
|
1173
|
+
method="GET",
|
|
1174
|
+
url="https://test.salesforce.com/services/data",
|
|
1175
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
1176
|
+
status=200,
|
|
1177
|
+
)
|
|
1178
|
+
|
|
1179
|
+
# Mock installed packages query
|
|
1180
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
1181
|
+
responses.add(
|
|
1182
|
+
method="GET",
|
|
1183
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
1184
|
+
json={"size": 0, "records": []},
|
|
1185
|
+
status=200,
|
|
1186
|
+
)
|
|
1187
|
+
|
|
1188
|
+
task = create_task(
|
|
1189
|
+
UpdateExternalCredential,
|
|
1190
|
+
{
|
|
1191
|
+
"name": "testExtCred",
|
|
1192
|
+
"parameters": [
|
|
1193
|
+
{"external_auth_identity_provider": "MyExternalAuthProvider"}
|
|
1194
|
+
],
|
|
1195
|
+
},
|
|
1196
|
+
)
|
|
1197
|
+
|
|
1198
|
+
ext_cred_id = "0XE1234567890ABC"
|
|
1199
|
+
|
|
1200
|
+
# Mock query for external credential ID
|
|
1201
|
+
responses.add(
|
|
1202
|
+
method="GET",
|
|
1203
|
+
url=f"{tooling_url}/query/?q=SELECT+Id+FROM+ExternalCredential+WHERE+DeveloperName%3D%27testExtCred%27+LIMIT+1",
|
|
1204
|
+
json={"size": 1, "records": [{"Id": ext_cred_id}]},
|
|
1205
|
+
status=200,
|
|
1206
|
+
)
|
|
1207
|
+
|
|
1208
|
+
# Mock get external credential object with multiple AuthProvider parameters
|
|
1209
|
+
responses.add(
|
|
1210
|
+
method="GET",
|
|
1211
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1212
|
+
json={
|
|
1213
|
+
"Metadata": {
|
|
1214
|
+
"externalCredentialParameters": [
|
|
1215
|
+
{
|
|
1216
|
+
"parameterType": "AuthProvider",
|
|
1217
|
+
"parameterName": "AuthProvider",
|
|
1218
|
+
"authProvider": "Provider1",
|
|
1219
|
+
"certificate": None,
|
|
1220
|
+
"description": None,
|
|
1221
|
+
"externalAuthIdentityProvider": None,
|
|
1222
|
+
"parameterGroup": "Group1",
|
|
1223
|
+
"parameterValue": "Provider1",
|
|
1224
|
+
"sequenceNumber": None,
|
|
1225
|
+
},
|
|
1226
|
+
{
|
|
1227
|
+
"parameterType": "AuthProvider",
|
|
1228
|
+
"parameterName": "AuthProvider",
|
|
1229
|
+
"authProvider": "Provider2",
|
|
1230
|
+
"certificate": None,
|
|
1231
|
+
"description": None,
|
|
1232
|
+
"externalAuthIdentityProvider": None,
|
|
1233
|
+
"parameterGroup": "Group2",
|
|
1234
|
+
"parameterValue": "Provider2",
|
|
1235
|
+
"sequenceNumber": None,
|
|
1236
|
+
},
|
|
1237
|
+
],
|
|
1238
|
+
}
|
|
1239
|
+
},
|
|
1240
|
+
status=200,
|
|
1241
|
+
)
|
|
1242
|
+
|
|
1243
|
+
# Mock update external credential
|
|
1244
|
+
responses.add(
|
|
1245
|
+
method="PATCH",
|
|
1246
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1247
|
+
json={},
|
|
1248
|
+
status=200,
|
|
1249
|
+
)
|
|
1250
|
+
|
|
1251
|
+
task()
|
|
1252
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
1253
|
+
|
|
1254
|
+
# Verify all AuthProvider parameters were removed
|
|
1255
|
+
patch_call = responses.calls[4] # Last call is the PATCH
|
|
1256
|
+
updated_params = patch_call.request.body
|
|
1257
|
+
import json
|
|
1258
|
+
|
|
1259
|
+
body = json.loads(updated_params)
|
|
1260
|
+
params = body["Metadata"]["externalCredentialParameters"]
|
|
1261
|
+
|
|
1262
|
+
# Should not contain any AuthProvider
|
|
1263
|
+
auth_providers = [p for p in params if p.get("parameterType") == "AuthProvider"]
|
|
1264
|
+
assert len(auth_providers) == 0
|
|
1265
|
+
|
|
1266
|
+
@responses.activate
|
|
1267
|
+
def test_no_conflict_when_no_existing_parameters(self):
|
|
1268
|
+
"""Test that no error occurs when there are no existing conflicting parameters"""
|
|
1269
|
+
# Mock SF API version discovery
|
|
1270
|
+
responses.add(
|
|
1271
|
+
method="GET",
|
|
1272
|
+
url="https://test.salesforce.com/services/data",
|
|
1273
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
1274
|
+
status=200,
|
|
1275
|
+
)
|
|
1276
|
+
|
|
1277
|
+
# Mock installed packages query
|
|
1278
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
1279
|
+
responses.add(
|
|
1280
|
+
method="GET",
|
|
1281
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
1282
|
+
json={"size": 0, "records": []},
|
|
1283
|
+
status=200,
|
|
1284
|
+
)
|
|
1285
|
+
|
|
1286
|
+
task = create_task(
|
|
1287
|
+
UpdateExternalCredential,
|
|
1288
|
+
{
|
|
1289
|
+
"name": "testExtCred",
|
|
1290
|
+
"parameters": [{"auth_provider": "MyAuthProvider"}],
|
|
1291
|
+
},
|
|
1292
|
+
)
|
|
1293
|
+
|
|
1294
|
+
ext_cred_id = "0XE1234567890ABC"
|
|
1295
|
+
|
|
1296
|
+
# Mock query for external credential ID
|
|
1297
|
+
responses.add(
|
|
1298
|
+
method="GET",
|
|
1299
|
+
url=f"{tooling_url}/query/?q=SELECT+Id+FROM+ExternalCredential+WHERE+DeveloperName%3D%27testExtCred%27+LIMIT+1",
|
|
1300
|
+
json={"size": 1, "records": [{"Id": ext_cred_id}]},
|
|
1301
|
+
status=200,
|
|
1302
|
+
)
|
|
1303
|
+
|
|
1304
|
+
# Mock get external credential object with no parameters
|
|
1305
|
+
responses.add(
|
|
1306
|
+
method="GET",
|
|
1307
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1308
|
+
json={
|
|
1309
|
+
"Metadata": {
|
|
1310
|
+
"externalCredentialParameters": [],
|
|
1311
|
+
}
|
|
1312
|
+
},
|
|
1313
|
+
status=200,
|
|
1314
|
+
)
|
|
1315
|
+
|
|
1316
|
+
# Mock update external credential
|
|
1317
|
+
responses.add(
|
|
1318
|
+
method="PATCH",
|
|
1319
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1320
|
+
json={},
|
|
1321
|
+
status=200,
|
|
1322
|
+
)
|
|
1323
|
+
|
|
1324
|
+
task()
|
|
1325
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
1326
|
+
|
|
1327
|
+
@responses.activate
|
|
1328
|
+
def test_update_existing_auth_provider_removes_external_auth(self):
|
|
1329
|
+
"""Test updating existing AuthProvider also removes ExternalAuthIdentityProvider"""
|
|
1330
|
+
# Mock SF API version discovery
|
|
1331
|
+
responses.add(
|
|
1332
|
+
method="GET",
|
|
1333
|
+
url="https://test.salesforce.com/services/data",
|
|
1334
|
+
json=[{"version": CURRENT_SF_API_VERSION}],
|
|
1335
|
+
status=200,
|
|
1336
|
+
)
|
|
1337
|
+
|
|
1338
|
+
# Mock installed packages query
|
|
1339
|
+
tooling_url = f"https://test.salesforce.com/services/data/v{CURRENT_SF_API_VERSION}/tooling"
|
|
1340
|
+
responses.add(
|
|
1341
|
+
method="GET",
|
|
1342
|
+
url=f"{tooling_url}/query/?q=SELECT+SubscriberPackage.Id%2C+SubscriberPackage.Name%2C+SubscriberPackage.NamespacePrefix%2C+SubscriberPackageVersionId+FROM+InstalledSubscriberPackage",
|
|
1343
|
+
json={"size": 0, "records": []},
|
|
1344
|
+
status=200,
|
|
1345
|
+
)
|
|
1346
|
+
|
|
1347
|
+
task = create_task(
|
|
1348
|
+
UpdateExternalCredential,
|
|
1349
|
+
{
|
|
1350
|
+
"name": "testExtCred",
|
|
1351
|
+
"parameters": [{"auth_provider": "UpdatedAuthProvider"}],
|
|
1352
|
+
},
|
|
1353
|
+
)
|
|
1354
|
+
|
|
1355
|
+
ext_cred_id = "0XE1234567890ABC"
|
|
1356
|
+
|
|
1357
|
+
# Mock query for external credential ID
|
|
1358
|
+
responses.add(
|
|
1359
|
+
method="GET",
|
|
1360
|
+
url=f"{tooling_url}/query/?q=SELECT+Id+FROM+ExternalCredential+WHERE+DeveloperName%3D%27testExtCred%27+LIMIT+1",
|
|
1361
|
+
json={"size": 1, "records": [{"Id": ext_cred_id}]},
|
|
1362
|
+
status=200,
|
|
1363
|
+
)
|
|
1364
|
+
|
|
1365
|
+
# Mock get external credential object with both AuthProvider and ExternalAuthIdentityProvider
|
|
1366
|
+
responses.add(
|
|
1367
|
+
method="GET",
|
|
1368
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1369
|
+
json={
|
|
1370
|
+
"Metadata": {
|
|
1371
|
+
"externalCredentialParameters": [
|
|
1372
|
+
{
|
|
1373
|
+
"parameterType": "AuthProvider",
|
|
1374
|
+
"parameterName": "AuthProvider",
|
|
1375
|
+
"authProvider": "OldAuthProvider",
|
|
1376
|
+
"certificate": None,
|
|
1377
|
+
"description": None,
|
|
1378
|
+
"externalAuthIdentityProvider": None,
|
|
1379
|
+
"parameterGroup": "DefaultGroup",
|
|
1380
|
+
"parameterValue": "OldAuthProvider",
|
|
1381
|
+
"sequenceNumber": None,
|
|
1382
|
+
},
|
|
1383
|
+
{
|
|
1384
|
+
"parameterType": "ExternalAuthIdentityProvider",
|
|
1385
|
+
"parameterName": "ExternalAuthIdentityProvider",
|
|
1386
|
+
"externalAuthIdentityProvider": "SomeProvider",
|
|
1387
|
+
"authProvider": None,
|
|
1388
|
+
"certificate": None,
|
|
1389
|
+
"description": None,
|
|
1390
|
+
"parameterGroup": "DefaultGroup",
|
|
1391
|
+
"parameterValue": None,
|
|
1392
|
+
"sequenceNumber": None,
|
|
1393
|
+
},
|
|
1394
|
+
],
|
|
1395
|
+
}
|
|
1396
|
+
},
|
|
1397
|
+
status=200,
|
|
1398
|
+
)
|
|
1399
|
+
|
|
1400
|
+
# Mock update external credential
|
|
1401
|
+
responses.add(
|
|
1402
|
+
method="PATCH",
|
|
1403
|
+
url=f"{tooling_url}/sobjects/ExternalCredential/{ext_cred_id}",
|
|
1404
|
+
json={},
|
|
1405
|
+
status=200,
|
|
1406
|
+
)
|
|
1407
|
+
|
|
1408
|
+
task()
|
|
1409
|
+
assert len(responses.calls) == 5 # 2 setup + 3 task calls
|
|
1410
|
+
|
|
1411
|
+
# Verify ExternalAuthIdentityProvider was removed
|
|
1412
|
+
patch_call = responses.calls[4] # Last call is the PATCH
|
|
1413
|
+
updated_params = patch_call.request.body
|
|
1414
|
+
import json
|
|
1415
|
+
|
|
1416
|
+
body = json.loads(updated_params)
|
|
1417
|
+
params = body["Metadata"]["externalCredentialParameters"]
|
|
1418
|
+
|
|
1419
|
+
# Should have 2 AuthProviders (old one updated + new one added) and no ExternalAuthIdentityProvider
|
|
1420
|
+
# Actually, since authProvider value is different, it adds a new AuthProvider
|
|
1421
|
+
# So we have old AuthProvider updated to new value, no new one is added
|
|
1422
|
+
auth_providers = [p for p in params if p.get("parameterType") == "AuthProvider"]
|
|
1423
|
+
assert len(auth_providers) >= 1
|
|
1424
|
+
# Should not contain ExternalAuthIdentityProvider
|
|
1425
|
+
assert not any(
|
|
1426
|
+
p.get("parameterType") == "ExternalAuthIdentityProvider" for p in params
|
|
1427
|
+
)
|