From f89a7d75ccca44d3f6072d67f02af5374cce6561 Mon Sep 17 00:00:00 2001
From: Rafael Monnerat <rafael@nexedi.com>
Date: Fri, 3 Jan 2020 02:26:15 +0000
Subject: [PATCH] slapos_subscription_request: Implement notification when
 Instance is ready script

---
 ...bscriptionRequest_notifyInstanceIsReady.py | 52 ++++++++++++++-
 ...est.erp5.testSlapOSSubscriptionScenario.py |  1 +
 .../test.erp5.testSlapOSSubscriptionSkins.py  | 64 +++++++++++++++++++
 3 files changed, 116 insertions(+), 1 deletion(-)

diff --git a/master/bt5/slapos_subscription_request/SkinTemplateItem/portal_skins/slapos_subscription_request/SubscriptionRequest_notifyInstanceIsReady.py b/master/bt5/slapos_subscription_request/SkinTemplateItem/portal_skins/slapos_subscription_request/SubscriptionRequest_notifyInstanceIsReady.py
index 62b15d78a..e34f090b5 100644
--- a/master/bt5/slapos_subscription_request/SkinTemplateItem/portal_skins/slapos_subscription_request/SubscriptionRequest_notifyInstanceIsReady.py
+++ b/master/bt5/slapos_subscription_request/SkinTemplateItem/portal_skins/slapos_subscription_request/SubscriptionRequest_notifyInstanceIsReady.py
@@ -1 +1,51 @@
-# Do nothing for now
+portal = context.getPortalObject()
+
+if context.getSimulationState() != "confirmed":
+  return
+
+hosting_subscription = context.getAggregateValue()
+
+for instance in hosting_subscription.getSpecialiseRelatedValueList(portal_type="Software Instance"):
+  if (not instance.getAggregate()) or instance.SoftwareInstance_hasReportedError():
+    # Some instance still failing, so instance seems not ready yet.
+    return
+
+# Instance is ok, we should move foward
+portal = context.getPortalObject()
+sender = context.getSourceSectionValue(portal_type="Person")
+recipient = context.getDestinationSectionValue(portal_type="Person")
+
+# Get message from catalog
+notification_reference = 'subscription_request-instance-is-ready'
+notification_message = portal.portal_notifications.getDocumentValue(
+    reference=notification_reference, language=recipient.getLanguage())
+
+if notification_message is None:
+  raise ValueError, 'Unable to found Notification Message with reference "%s".' % notification_reference
+
+# Set notification mapping
+notification_mapping_dict = {
+  'name': recipient.getTitle(),
+  'subscription_title': context.getTitle(),
+  'hosting_subscription_relative_url': hosting_subscription.getRelativeUrl()}
+
+# Preserve HTML else convert to text
+if notification_message.getContentType() == "text/html":
+  mail_text = notification_message.asEntireHTML(
+    substitution_method_parameter_dict={'mapping_dict':notification_mapping_dict})
+else:
+  mail_text = notification_message.asText(
+    substitution_method_parameter_dict={'mapping_dict':notification_mapping_dict})
+
+portal.portal_notifications.sendMessage(
+  sender=sender,
+  recipient=recipient,
+  subject=notification_message.getTitle(),
+  message=mail_text,
+  message_text_format=notification_message.getContentType(),
+  notifier_list=(portal.portal_preferences.getPreferredLoginAndPasswordNotifier(),),
+  store_as_event= portal.portal_preferences.isPreferredStoreEvents(),
+  event_keyword_argument_dict={'follow_up':context.getRelativeUrl()},
+  )
+
+context.start()
diff --git a/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionScenario.py b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionScenario.py
index 70efd2217..7f51051ed 100644
--- a/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionScenario.py
+++ b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionScenario.py
@@ -33,6 +33,7 @@ class TestSlapOSSubscriptionScenarioMixin(DefaultScenarioMixin):
     self.portal.portal_alarms.slapos_subscription_request_process_draft.setEnabled(True)
     self.portal.portal_alarms.slapos_subscription_request_process_ordered.setEnabled(True)
     self.portal.portal_alarms.slapos_subscription_request_process_planned.setEnabled(True)
+    self.portal.portal_alarms.slapos_subscription_request_process_confirmed.setEnabled(True)
 
     DefaultScenarioMixin.afterSetUp(self)
 
diff --git a/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionSkins.py b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionSkins.py
index e47cd2252..1730451d6 100644
--- a/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionSkins.py
+++ b/master/bt5/slapos_subscription_request/TestTemplateItem/portal_components/test.erp5.testSlapOSSubscriptionSkins.py
@@ -838,6 +838,70 @@ class TestSubscriptionRequest_sendAcceptedNotification(TestSubscriptionSkinsMixi
       event.getTextContent(),'%s %s password' % (person.getTitle(), person.getUserId()))
 
 
+class TestSubscriptionRequest_notifyInstanceIsReady(TestSubscriptionSkinsMixin):
+
+  def _makeNotificationMessage(self, reference,
+      content_type='text/html', text_content="${name} ${subscription_title} ${hosting_subscription_relative_url}"):
+
+    notification_message = self.portal.notification_message_module.newContent(
+      portal_type="Notification Message",
+      text_content_substitution_mapping_method_id='NotificationMessage_getSubstitutionMappingDictFromArgument',
+      title='TestSubscriptionSkins Notification Message %s' % reference,
+      text_content=text_content,
+      content_type=content_type,
+      reference=reference,
+      version=999,
+      language="en"
+      )
+    notification_message.validate()
+    return notification_message
+
+  @simulate('SoftwareInstance_hasReportedError', '*args, **kwargs','return')
+  def test_send_notification_instance_is_ready(self):
+    email = "abc%s@nexedi.com" % self.new_id
+    name = "Cous Cous %s" % self.new_id
+
+    self._makeNotificationMessage(reference='subscription_request-instance-is-ready',
+                                  text_content="${name} ${subscription_title} ${hosting_subscription_relative_url}")
+    person, _ = self.portal.SubscriptionRequest_createUser(name=name, email=email)
+    person.setDefaultEmailText(email)
+
+    subscription_request = self.newSubscriptionRequest(
+      quantity=1, destination_section_value=person,
+    price=195.5,
+    price_currency="currency_module/EUR",
+    default_email_text="abc%s@nexedi.com" % self.new_id)
+    self._makeTree()
+    _, p1 = self._makeComputer()
+    _, p2 = self._makeComputer()
+
+    self.person_user = person
+    self.hosting_subscription.setDestinationSection(self.person_user.getRelativeUrl())
+    subscription_request.setAggregateValue(self.hosting_subscription)
+    self.software_instance.setAggregateValue(p1)
+    self.requested_software_instance.setAggregateValue(p2)
+    
+    self.tic()
+    subscription_request.plan()
+    subscription_request.order()
+    subscription_request.confirm()
+
+    self.tic()
+    subscription_request.SubscriptionRequest_notifyInstanceIsReady()
+
+    self.tic()
+    event = subscription_request.getFollowUpRelatedValue(portal_type="Mail Message")
+
+    self.assertEqual(event.getTitle(),
+      'TestSubscriptionSkins Notification Message subscription_request-instance-is-ready')
+    self.assertEqual(event.getContentType(),'text/html')
+
+    self.assertEqual(
+      event.getTextContent(),'%s %s %s' % (person.getTitle(), subscription_request.getTitle(),
+        self.hosting_subscription.getRelativeUrl()))
+
+
+
 #class SubscriptionRequest_checkPaymentBalance(TestSubscriptionSkinsMixin):
 #  def test(self):
 #    raise
-- 
2.30.9