Skip to content

Commit

Permalink
blacken, get SF domain from SALESFORCE_SANDBOX
Browse files Browse the repository at this point in the history
  • Loading branch information
davisagli committed Oct 19, 2023
1 parent e48d2cd commit 555c995
Show file tree
Hide file tree
Showing 8 changed files with 131 additions and 78 deletions.
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
version="1.0a1",
description="Adds a behavior to collective.easyform to sync data to Salesforce",
long_description=long_description,
long_description_content_type='text/markdown',
long_description_content_type="text/markdown",
# Get more from https://pypi.org/classifiers/
classifiers=[
"Environment :: Web Environment",
Expand Down
36 changes: 28 additions & 8 deletions src/jazkarta/easyformplugin/salesforce/action.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,16 @@
"username": os.environ.get("SALESFORCE_USERNAME"),
"password": os.environ.get("SALESFORCE_PASSWORD"),
"security_token": os.environ.get("SALESFORCE_TOKEN"),
"domain": os.environ.get("SALESFORCE_DOMAIN"),
"domain": os.environ.get("SALESFORCE_DOMAIN")
or (
"test"
if os.environ.get("SALESFORCE_SANDBOX", "true").lower() in ("true", "1")
else "login"
),
"version": "55.0",
}


@implementer(ISaveToSalesforce)
class SendToSalesforce(Action):
"""easyform action which creates or updates a record in Salesforce
Expand Down Expand Up @@ -67,9 +73,15 @@ def onSuccess(self, fields, request):
result = sobject.create(data)
if result["success"]:
sf_id = result["id"]
logger.info(u"Created {} {} in Salesforce".format(sobject_name, sf_id))
logger.info(
"Created {} {} in Salesforce".format(sobject_name, sf_id)
)
else:
raise Exception(u"Failed to create {} in Salesforce: {}".format(sobject_name, result["errors"]))
raise Exception(
"Failed to create {} in Salesforce: {}".format(
sobject_name, result["errors"]
)
)
elif op_name == "update":
sf_id = request.cookies.get("sf_id")
if sf_id:
Expand All @@ -79,12 +91,20 @@ def onSuccess(self, fields, request):
result = sobject.create(data)
sf_id = result["Id"]
else:
raise Exception(u"No Salesforce object matched for update")
raise Exception("No Salesforce object matched for update")
if result == 204:
request.response.expireCookie("sf_id", path=form.absolute_url_path())
logger.info(u"Updated {} {} in Salesforce".format(sobject_name, sf_id))
request.response.expireCookie(
"sf_id", path=form.absolute_url_path()
)
logger.info(
"Updated {} {} in Salesforce".format(sobject_name, sf_id)
)
else:
raise Exception(u"Failed to update {} {} in Salesforce: {}".format(sobject_name, sf_id, result))
raise Exception(
"Failed to update {} {} in Salesforce: {}".format(
sobject_name, sf_id, result
)
)
else:
raise ValueError("Unsupported operation: {}".format(operation))

Expand Down Expand Up @@ -126,7 +146,7 @@ def prepare_salesforce_data(self, fields, form_input, expr_context):
# Action factory used by the UI for adding a new easyform action
SendToSalesforceAction = ActionFactory(
SendToSalesforce,
_(u"label_salesforce_action", default=u"Send to Salesforce"),
_("label_salesforce_action", default="Send to Salesforce"),
"jazkarta.easyformplugin.salesforce.AddSalesforceActions",
)

Expand Down
58 changes: 32 additions & 26 deletions src/jazkarta/easyformplugin/salesforce/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@ class ISaveToSalesforce(IAction):

directives.read_permission(operations=MODIFY_PORTAL_CONTENT)
operations = JSONField(
title=_(u"label_salesforce_operations", default=u"Salesforce Operations"),
description=_(u"help_salesforce_operations", default=u"""<p>A JSON list of operations to perform.</p>
title=_("label_salesforce_operations", default="Salesforce Operations"),
description=_(
"help_salesforce_operations",
default="""<p>A JSON list of operations to perform.</p>
<p>Each operation must specify:</p>
<ul>
Expand Down Expand Up @@ -47,30 +49,34 @@ class ISaveToSalesforce(IAction):
}
]
</pre>
"""),
""",
),
defaultFactory=list,
schema=json.dumps({
"type": "array",
"items": {
"type": "object",
"required": [
"sobject",
"operation",
"fields",
],
"properties": {
"sobject": {"type": "string"},
"operation": {"type": "string", "enum": ["create", "update"]},
"match_expression": {"type": "string"},
"action_if_no_existing_object": {"type": "string", "enum": ["abort", "create"]},
"fields": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
schema=json.dumps(
{
"type": "array",
"items": {
"type": "object",
"required": [
"sobject",
"operation",
"fields",
],
"properties": {
"sobject": {"type": "string"},
"operation": {"type": "string", "enum": ["create", "update"]},
"match_expression": {"type": "string"},
"action_if_no_existing_object": {
"type": "string",
"enum": ["abort", "create"],
},
"fields": {
"type": "object",
"additionalProperties": {"type": "string"},
},
},
"additionalProperties": False,
},
"additionalProperties": False,
},
})
}
),
)
12 changes: 9 additions & 3 deletions src/jazkarta/easyformplugin/salesforce/migration.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,9 @@
from collective.easyform.migration.actions import TYPES_MAPPING, Type, append_field, append_node
from collective.easyform.migration.actions import (
TYPES_MAPPING,
Type,
append_field,
append_node,
)
import json


Expand All @@ -13,7 +18,7 @@ def append_sf_action(schema, type_, name, properties):
for item in properties["fieldMap"]:
if "/" in item["field_path"]:
raise NotImplementedError("Fields in fieldset folders not supported yet.")
fields[item["sf_field"]] = "form:" + item['field_path']
fields[item["sf_field"]] = "form:" + item["field_path"]
for item in properties["presetValueMap"]:
fields[item["sf_field"]] = item["value"]
op = {
Expand All @@ -26,7 +31,8 @@ def append_sf_action(schema, type_, name, properties):
if properties["actionIfNoExistingObject"] not in ("abort", "create"):
raise NotImplementedError(
"Unsupported actionIfNoExistingObject: {}".format(
properties['actionIfNoExistingObject'])
properties["actionIfNoExistingObject"]
)
)
op["action_if_no_existing_object"] = properties["actionIfNoExistingObject"]
if properties["dependencyMap"]:
Expand Down
13 changes: 8 additions & 5 deletions src/jazkarta/easyformplugin/salesforce/prefill.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
from .interfaces import ISaveToSalesforce


@adapter(IEasyForm, IJazkartaEasyformpluginSalesforceLayer, IEasyFormForm, IField, Interface)
@adapter(
IEasyForm, IJazkartaEasyformpluginSalesforceLayer, IEasyFormForm, IField, Interface
)
def prefill_value_factory(context, request, view, field, widget):
"""Return a SalesforcePrefillValue if and only if there is a
Salesforce action mapping the field
Expand All @@ -42,15 +44,14 @@ def prefill_value_factory(context, request, view, field, widget):

@implementer(IValue)
class SalesforcePrefillValue(object):

def __init__(self, form, field, operation, sf_field):
self.form = form
self.field = field
self.operation = operation
self.sf_field = sf_field

self.request = getRequest()
if not hasattr(self.request, '_jazkarta_easyform_sf_queries'):
if not hasattr(self.request, "_jazkarta_easyform_sf_queries"):
self.request._jazkarta_easyform_sf_queries = {}
self.query_cache = self.request._jazkarta_easyform_sf_queries

Expand All @@ -64,11 +65,13 @@ def query(self):
if soql not in self.query_cache:
sf = Salesforce(**SF_CREDENTIALS)
result = sf.query(soql)
if result['totalSize'] != 1:
if result["totalSize"] != 1:
raise Exception("Didn't find match")
self.query_cache[soql] = result["records"][0]
item = self.query_cache[soql]
self.request.response.setCookie('sf_id', item['Id'], path=self.form.absolute_url_path())
self.request.response.setCookie(
"sf_id", item["Id"], path=self.form.absolute_url_path()
)
return item

def get(self):
Expand Down
5 changes: 2 additions & 3 deletions src/jazkarta/easyformplugin/salesforce/testing.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@


class JazkartaEasyformpluginSalesforceLayer(PloneSandboxLayer):

defaultBases = (PLONE_APP_CONTENTTYPES_FIXTURE,)

def setUpZope(self, app, configurationContext):
Expand Down Expand Up @@ -58,7 +57,7 @@ def setUpPloneSite(self, portal):
def scrub_login_request(request):
if request.body is not None:
request.body = re.sub(
br"<n1:(username|password)>.*?</n1:\1>",
rb"<n1:(username|password)>.*?</n1:\1>",
lambda m: b"<n1:" + m.group(1) + b">REDACTED</n1:" + m.group(1) + b">",
request.body,
)
Expand All @@ -67,7 +66,7 @@ def scrub_login_request(request):

def scrub_login_response(response):
response["body"]["string"] = re.sub(
br"<sessionId>.*?</sessionId>",
rb"<sessionId>.*?</sessionId>",
b"<sessionId>FAKE_SESSION</sessionId>",
response["body"]["string"],
)
Expand Down
82 changes: 51 additions & 31 deletions src/jazkarta/easyformplugin/salesforce/tests/test_integration.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,9 @@ def setUp(self):
def test_01_submit_form_with_salesforce_adapter(self):
# Open browser
browser = Browser(self.layer["app"])
browser.addHeader("Authorization", "Basic {}:{}".format(TEST_USER_NAME, TEST_USER_PASSWORD))
browser.addHeader(
"Authorization", "Basic {}:{}".format(TEST_USER_NAME, TEST_USER_PASSWORD)
)
browser.handleErrors = False
form_url = self.form.absolute_url()

Expand All @@ -75,20 +77,22 @@ def test_01_submit_form_with_salesforce_adapter(self):
browser.getControl("Send to Salesforce").selected = True
browser.getControl("Add").click()
browser.open(form_url + "/actions/sf_contact")
browser.getControl("Operations").value = json.dumps([
{
"sobject": "Contact",
"operation": "create",
"fields": {
"Description": "Created by jazkarta.easyformplugin.salesforce tests",
"FirstName": "form:first_name",
"LastName": "form:last_name",
"Birthdate": "form:birthdate",
"CreatedDate": "python:now",
"DoNotCall": "form:do_not_call"
browser.getControl("Operations").value = json.dumps(
[
{
"sobject": "Contact",
"operation": "create",
"fields": {
"Description": "Created by jazkarta.easyformplugin.salesforce tests",
"FirstName": "form:first_name",
"LastName": "form:last_name",
"Birthdate": "form:birthdate",
"CreatedDate": "python:now",
"DoNotCall": "form:do_not_call",
},
},
},
])
]
)
browser.getControl("Save").click()

# Fill and submit the form
Expand All @@ -103,15 +107,25 @@ def test_01_submit_form_with_salesforce_adapter(self):

self.assertEqual(len(cassette), 2)
actual_data = json.loads(cassette.requests[-1].body)
assert set(actual_data.keys()) == {"FirstName", "LastName", "Birthdate", "CreatedDate", "DoNotCall", "Description"}
assert set(actual_data.keys()) == {
"FirstName",
"LastName",
"Birthdate",
"CreatedDate",
"DoNotCall",
"Description",
}
assert actual_data["FirstName"] is None
assert actual_data["LastName"] == "McTesterson"
assert actual_data["DoNotCall"] == True
assert actual_data["Birthdate"] == "1985-09-30"
created_date = parse(actual_data["CreatedDate"])
assert isinstance(created_date, datetime)
assert created_date.tzinfo is not None
assert actual_data["Description"] == "Created by jazkarta.easyformplugin.salesforce tests"
assert (
actual_data["Description"]
== "Created by jazkarta.easyformplugin.salesforce tests"
)
assert json.loads(cassette.responses[-1]["body"]["string"])["success"]

def test_02_prefill_form_from_salesforce(self):
Expand All @@ -121,7 +135,9 @@ def test_02_prefill_form_from_salesforce(self):

# Open browser
browser = Browser(self.layer["app"])
browser.addHeader("Authorization", "Basic {}:{}".format(TEST_USER_NAME, TEST_USER_PASSWORD))
browser.addHeader(
"Authorization", "Basic {}:{}".format(TEST_USER_NAME, TEST_USER_PASSWORD)
)
browser.handleErrors = False
form_url = self.form.absolute_url()

Expand All @@ -132,20 +148,22 @@ def test_02_prefill_form_from_salesforce(self):
browser.getControl("Send to Salesforce").selected = True
browser.getControl("Add").click()
browser.open(form_url + "/actions/sf_contact")
browser.getControl("Operations").value = json.dumps([
{
"sobject": "Contact",
"operation": "update",
"match_expression": "LastName = 'McTesterson'",
"fields": {
"Description": "Created by jazkarta.easyformplugin.salesforce tests",
"FirstName": "form:first_name",
"LastName": "form:last_name",
"Birthdate": "form:birthdate",
"DoNotCall": "form:do_not_call"
browser.getControl("Operations").value = json.dumps(
[
{
"sobject": "Contact",
"operation": "update",
"match_expression": "LastName = 'McTesterson'",
"fields": {
"Description": "Created by jazkarta.easyformplugin.salesforce tests",
"FirstName": "form:first_name",
"LastName": "form:last_name",
"Birthdate": "form:birthdate",
"DoNotCall": "form:do_not_call",
},
},
},
])
]
)
browser.getControl("Save").click()

# Fill and submit the form
Expand All @@ -156,7 +174,9 @@ def test_02_prefill_form_from_salesforce(self):
assert browser.getControl("First Name").value == ""
assert browser.getControl("Last Name").value == "McTesterson"
assert browser.getControl("Do Not Call").selected
assert browser.getControl(name="form.widgets.birthdate").value == "1985-09-30"
assert (
browser.getControl(name="form.widgets.birthdate").value == "1985-09-30"
)

# Edit and submit the form
browser.getControl("First Name").value = "Testy"
Expand Down
1 change: 0 additions & 1 deletion src/jazkarta/easyformplugin/salesforce/tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,6 @@ def test_browserlayer(self):


class TestUninstall(unittest.TestCase):

layer = JAZKARTA_EASYFORMPLUGIN_SALESFORCE_INTEGRATION_TESTING

def setUp(self):
Expand Down

0 comments on commit 555c995

Please sign in to comment.