Skip to content

Commit

Permalink
Merge pull request SFDO-Tooling#3669 from SFDO-Tooling/feature/listme…
Browse files Browse the repository at this point in the history
…tadatatypes

Feature/listmetadatatypes
  • Loading branch information
jkasturi-sf authored Oct 9, 2023
2 parents 3e57b38 + 9f2f5e1 commit 93dc402
Show file tree
Hide file tree
Showing 8 changed files with 146 additions and 0 deletions.
4 changes: 4 additions & 0 deletions cumulusci/cumulusci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,10 @@ tasks:
options:
path: packaged
group: Salesforce Metadata
describe_metadatatypes:
class_path: cumulusci.tasks.salesforce.DescribeMetadataTypes
description: Retrieves the metadata types supported by the org based on the api version
group: Salesforce Metadata
retrieve_src:
description: Retrieves the packaged metadata into the src directory
class_path: cumulusci.tasks.salesforce.RetrievePackaged
Expand Down
41 changes: 41 additions & 0 deletions cumulusci/salesforce_api/metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -678,3 +678,44 @@ def _process_response(self, response):
)
# Unknown response
raise MetadataApiError(f"Unexpected response: {response.text}", response)


class ApiListMetadataTypes(BaseMetadataApiCall):
check_interval = 1
soap_envelope_start = soap_envelopes.DESCRIBE_METADATA
soap_action_start = "describemetadatatypes"

def __init__(self, task, api_version=None):
super(ApiListMetadataTypes, self).__init__(task)
self.metadata_types = []
self.api_version = (
api_version
if api_version
else task.project_config.project__package__api_version
)

def _build_envelope_start(self):

return self.soap_envelope_start.format(
api_version=self.api_version,
)

def _process_response(self, response):
self.metadata_types = []
metaobjects = parseString(response.content).getElementsByTagName(
"metadataObjects"
)

for metadataobject in metaobjects:
self.metadata_types.append(
self._get_element_value(metadataobject, "xmlName")
)
child_elements = metadataobject.getElementsByTagName("childXmlNames")
child_xml_names = [
element.firstChild.nodeValue for element in child_elements
]
self.metadata_types += child_xml_names
self.metadata_types.sort()
self.status = "Done"
self.task.logger.info(self.status)
return self.metadata_types
14 changes: 14 additions & 0 deletions cumulusci/salesforce_api/soap_envelopes.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,17 @@
</urn:create>
</soapenv:Body>
</soapenv:Envelope>"""

DESCRIBE_METADATA = """<?xml version="1.0" encoding="utf-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://soap.sforce.com/2006/04/metadata">
<soapenv:Header>
<tns:SessionHeader>
<tns:sessionId>###SESSION_ID###</tns:sessionId>
</tns:SessionHeader>
</soapenv:Header>
<soapenv:Body>
<tns:describeMetadata>
<asOfVersion>{api_version}</asOfVersion>
</tns:describeMetadata>
</soapenv:Body>
</soapenv:Envelope>"""
3 changes: 3 additions & 0 deletions cumulusci/salesforce_api/tests/metadata_test_strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,6 @@
status_envelope = '<?xml version="1.0" encoding="utf-8"?>\n<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">\n <soap:Header>\n <SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata">\n <sessionId>###SESSION_ID###</sessionId>\n </SessionHeader>\n </soap:Header>\n <soap:Body>\n <checkStatus xmlns="http://soap.sforce.com/2006/04/metadata">\n <asyncProcessId>{process_id}</asyncProcessId>\n </checkStatus>\n </soap:Body>\n</soap:Envelope>'

deploy_status_envelope = '<?xml version="1.0" encoding="utf-8"?>\n<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">\n <soap:Header>\n <SessionHeader xmlns="http://soap.sforce.com/2006/04/metadata">\n <sessionId>###SESSION_ID###</sessionId>\n </SessionHeader>\n </soap:Header>\n <soap:Body>\n <checkDeployStatus xmlns="http://soap.sforce.com/2006/04/metadata">\n <asyncProcessId>{process_id}</asyncProcessId>\n <includeDetails>true</includeDetails>\n </checkDeployStatus>\n </soap:Body>\n</soap:Envelope>'

list_metadata_types_envelope = '<?xml version="1.0" encoding="utf-8"?>\n<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tns="http://soap.sforce.com/2006/04/metadata">\n <soapenv:Header>\n <tns:SessionHeader>\n <tns:sessionId>###SESSION_ID###</tns:sessionId>\n </tns:SessionHeader>\n </soapenv:Header>\n <soapenv:Body>\n <tns:describeMetadata>\n <asOfVersion>{api_version}</asOfVersion>\n </tns:describeMetadata>\n </soapenv:Body>\n</soapenv:Envelope>'
list_metadata_types_result = '<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns="http://soap.sforce.com/2006/04/metadata"><soapenv:Body><describeMetadataResponse><result><metadataObjects><childXmlNames>WorkflowFieldUpdate</childXmlNames><directoryName>workflows</directoryName><inFolder>false</inFolder><metaFile>false</metaFile><suffix>workflow</suffix><xmlName>Workflow</xmlName></metadataObjects><organizationNamespace></organizationNamespace><partialSaveAllowed>true</partialSaveAllowed><testRequired>false</testRequired></result></describeMetadataResponse></soapenv:Body></soapenv:Envelope>'
39 changes: 39 additions & 0 deletions cumulusci/salesforce_api/tests/test_metadata.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from cumulusci.salesforce_api.metadata import (
ApiDeploy,
ApiListMetadata,
ApiListMetadataTypes,
ApiRetrieveInstalledPackages,
ApiRetrievePackaged,
ApiRetrieveUnpackaged,
Expand All @@ -36,6 +37,8 @@
list_metadata_result,
list_metadata_result_bad_val,
list_metadata_start_envelope,
list_metadata_types_envelope,
list_metadata_types_result,
result_envelope,
retrieve_packaged_start_envelope,
retrieve_result,
Expand Down Expand Up @@ -843,6 +846,42 @@ def test_bad_date_somehow(self):
api()


class TestApiListMetadataTypes(TestBaseTestMetadataApi):
api_class = ApiListMetadataTypes
envelope_start = list_metadata_types_envelope

def setup_method(self):
super().setup_method()
self.metadata_types = None
self.api_version = self.project_config.project__package__api_version

def _response_call_success_result(self, response_result):
return list_metadata_types_result

def _expected_call_success_result(self, response_result=None):
metadata_types = ["Workflow", "WorkflowFieldUpdate"]
return metadata_types

def _create_instance(self, task, api_version=None):
return super()._create_instance(task, api_version)

@responses.activate
def test_call_success(self):
org_config = {
"instance_url": "https://na12.salesforce.com",
"id": "https://login.salesforce.com/id/00D000000000000ABC/005000000000000ABC",
"access_token": "0123456789",
}
task = self._create_task(org_config=org_config)
api = self._create_instance(task)
if not self.api_class.soap_envelope_start:
api.soap_envelope_start = "{api_version}"
self._mock_call_mdapi(api, list_metadata_types_result)

metadata_types = api()
assert metadata_types == self._expected_call_success_result()


class TestApiRetrieveUnpackaged(TestBaseTestMetadataApi):
maxDiff = None
api_class = ApiRetrieveUnpackaged
Expand Down
26 changes: 26 additions & 0 deletions cumulusci/tasks/salesforce/DescribeMetadataTypes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
from cumulusci.salesforce_api.metadata import ApiListMetadataTypes
from cumulusci.tasks.salesforce import BaseRetrieveMetadata


class DescribeMetadataTypes(BaseRetrieveMetadata):
api_class = ApiListMetadataTypes
task_options = {
"api_version": {
"description": "Override the API version used to list metadatatypes"
},
}

def _init_options(self, kwargs):
super(DescribeMetadataTypes, self)._init_options(kwargs)
if "api_version" not in self.options:
self.options[
"api_version"
] = self.project_config.project__package__api_version

def _get_api(self):
return self.api_class(self, self.options.get("api_version"))

def _run_task(self):
api_object = self._get_api()
metadata_list = api_object()
self.logger.info("Metadata Types supported by org:\n" + str(metadata_list))
1 change: 1 addition & 0 deletions cumulusci/tasks/salesforce/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
"PublishCommunity": "cumulusci.tasks.salesforce.PublishCommunity",
"RetrievePackaged": "cumulusci.tasks.salesforce.RetrievePackaged",
"RetrieveReportsAndDashboards": "cumulusci.tasks.salesforce.RetrieveReportsAndDashboards",
"DescribeMetadataTypes": "cumulusci.tasks.salesforce.DescribeMetadataTypes",
"RetrieveUnpackaged": "cumulusci.tasks.salesforce.RetrieveUnpackaged",
"SOQLQuery": "cumulusci.tasks.salesforce.SOQLQuery",
"SetTDTMHandlerStatus": "cumulusci.tasks.salesforce.trigger_handlers",
Expand Down
18 changes: 18 additions & 0 deletions cumulusci/tasks/salesforce/tests/test_describemetadatatypes.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from unittest import mock

from cumulusci.tasks.salesforce import DescribeMetadataTypes

from .util import create_task


class TestRetrieveMetadataTypes:
def test_run_task(self):
task = create_task(DescribeMetadataTypes)
task._get_api = mock.Mock()
task()
task._get_api.assert_called_once()

def test_run_task_with_apiversion(self):
task = create_task(DescribeMetadataTypes, {"api_version": 8.0})
assert task.options.get("api_version") == 8.0
task._get_api()

0 comments on commit 93dc402

Please sign in to comment.