From 5145b2360486d6046d4321842e542512037428ba Mon Sep 17 00:00:00 2001 From: Romain Courteaud <romain@nexedi.com> Date: Tue, 12 Mar 2013 17:55:29 +0100 Subject: [PATCH] Test default crm escalation scenario. --- .../testSlapOSERP5DefaultScenario.py | 450 ++++++++++++++++++ master/bt5/slapos_erp5/bt/revision | 2 +- 2 files changed, 451 insertions(+), 1 deletion(-) diff --git a/master/bt5/slapos_erp5/TestTemplateItem/testSlapOSERP5DefaultScenario.py b/master/bt5/slapos_erp5/TestTemplateItem/testSlapOSERP5DefaultScenario.py index 3efbd5b86..adb3d4976 100644 --- a/master/bt5/slapos_erp5/TestTemplateItem/testSlapOSERP5DefaultScenario.py +++ b/master/bt5/slapos_erp5/TestTemplateItem/testSlapOSERP5DefaultScenario.py @@ -12,6 +12,7 @@ from AccessControl.SecurityManagement import getSecurityManager, \ setSecurityManager from DateTime import DateTime import json +import re def changeSkin(skin_name): def decorator(func): @@ -759,3 +760,452 @@ class TestSlapOSDefaultScenario(TestSlapOSSecurityMixin): self.login(friend_reference) self.usePayzenManually(self.web_site, friend_reference) + +class TestSlapOSDefaultCRMEscalation(TestSlapOSSecurityMixin): + def joinSlapOS(self, web_site, reference): + def findMessage(email, body): + for candidate in reversed(self.portal.MailHost.getMessageList()): + if [q for q in candidate[1] if email in q] and body in candidate[2]: + return candidate[2] + + credential_request_form = self.web_site.ERP5Site_viewCredentialRequestForm() + + self.assertTrue('Vifib Cloud is a distributed cloud around the' + in credential_request_form) + + email = '%s@example.com' % reference + + request = web_site.ERP5Site_newCredentialRequest( + reference=reference, + first_name='Joe', + last_name=reference, + default_email_text=email + ) + + self.assertTrue('Thanks%20for%20your%20registration.%20You%20will%20be%2' + '0receive%20an%20email%20to%20activate%20your%20account.' in request) + + self.tic() + + to_click_message = findMessage(email, 'You have requested one user') + + self.assertNotEqual(None, to_click_message) + + to_click_url = re.search('href="(.+?)"', to_click_message).group(1) + + self.assertTrue('ERP5Site_activeLogin' in to_click_url) + + join_key = to_click_url.split('=')[-1] + + web_site.ERP5Site_activeLogin(key=join_key) + + self.tic() + + welcome_message = findMessage(email, "the creation of you new ERP5 account") + self.assertNotEqual(None, welcome_message) + + @changeSkin('Hosting') + def WebSection_getCurrentHostingSubscriptionList(self): + return self.web_site.hosting.myspace.my_services\ + .WebSection_getCurrentHostingSubscriptionList() + + def personRequestInstanceNotReady(self, **kw): + response = self.portal.portal_slap.requestComputerPartition(**kw) + status = getattr(response, 'status', None) + self.assertEqual(408, status) + self.tic() + + def personRequestInstance(self, **kw): + response = self.portal.portal_slap.requestComputerPartition(**kw) + self.assertTrue(isinstance(response, str)) + software_instance = xml_marshaller.xml_marshaller.loads(response) + self.assertEqual('SoftwareInstance', software_instance.__class__.__name__) + self.tic() + return software_instance + + def assertHostingSubscriptionSimulationCoverage(self, subscription): + self.login() + # this is document level assertion, as simulation and its specific delivery + # is covered by unit tests + packing_list_line_list = subscription.getAggregateRelatedValueList( + portal_type='Sale Packing List Line') + self.assertTrue(len(packing_list_line_list) >= 2) + for packing_list_line in packing_list_line_list: + packing_list = packing_list_line.getParentValue() + self.assertEqual('Sale Packing List', + packing_list.getPortalType()) + self.assertEqual('delivered', + packing_list.getSimulationState()) + causality_state = packing_list.getCausalityState() + self.assertEqual('solved', causality_state) + + def assertAggregatedSalePackingList(self, delivery): + self.assertEqual('delivered', delivery.getSimulationState()) + self.assertEqual('solved', delivery.getCausalityState()) + + invoice_list= delivery.getCausalityRelatedValueList( + portal_type='Sale Invoice Transaction') + self.assertEqual(1, len(invoice_list)) + invoice = invoice_list[0].getObject() + + causality_list = invoice.getCausalityValueList() + + self.assertSameSet([delivery], causality_list) + + self.assertEqual('stopped', invoice.getSimulationState()) + self.assertEqual('solved', invoice.getCausalityState()) + + payment_list = invoice.getCausalityRelatedValueList( + portal_type='Payment Transaction') + self.assertEqual(1, len(payment_list)) + + payment = payment_list[0].getObject() + + causality_list = payment.getCausalityValueList() + self.assertSameSet([invoice], causality_list) + + self.assertEqual('cancelled', payment.getSimulationState()) + self.assertEqual('draft', payment.getCausalityState()) + + self.assertEqual(-1 * payment.PaymentTransaction_getTotalPayablePrice(), + invoice.getTotalPrice()) + + # Check reverse invoice + reverse_invoice_list = invoice.getCausalityRelatedValueList( + portal_type='Sale Invoice Transaction') + self.assertEqual(1, len(reverse_invoice_list)) + + reverse_invoice = reverse_invoice_list[0].getObject() + + causality_list = reverse_invoice.getCausalityValueList() + self.assertSameSet([invoice], causality_list) + + self.assertEqual('stopped', reverse_invoice.getSimulationState()) + self.assertEqual('draft', reverse_invoice.getCausalityState()) + + payment_list = reverse_invoice.getCausalityRelatedValueList( + portal_type='Payment Transaction') + self.assertEqual(0, len(payment_list)) + + def assertPersonDocumentCoverage(self, person): + self.login() + subscription_list = self.portal.portal_catalog( + portal_type='Hosting Subscription', + default_destination_section_uid=person.getUid()) + for subscription in subscription_list: + self.assertHostingSubscriptionSimulationCoverage( + subscription.getObject()) + + aggregated_delivery_list = self.portal.portal_catalog( + portal_type='Sale Packing List', + default_destination_section_uid=person.getUid(), + specialise_uid=self.portal.restrictedTraverse(self.portal\ + .portal_preferences.getPreferredAggregatedSaleTradeCondition()\ + ).getUid() + ) + + if len(subscription_list) == 0: + self.assertEqual(0, len(aggregated_delivery_list)) + return + + self.assertNotEqual(0, len(aggregated_delivery_list)) + for aggregated_delivery in aggregated_delivery_list: + self.assertAggregatedSalePackingList(aggregated_delivery.getObject()) + + self.assertEqual(0, person.Entity_statBalance()) + + def assertOpenSaleOrderCoverage(self, person_reference): + self.login() + person = self.portal.portal_catalog.getResultValue(portal_type='Person', + reference=person_reference) + hosting_subscription_list = self.portal.portal_catalog( + portal_type='Hosting Subscription', + default_destination_section_uid=person.getUid() + ) + + open_sale_order_list = self.portal.portal_catalog( + portal_type='Open Sale Order', + default_destination_uid=person.getUid(), + ) + + if len(hosting_subscription_list) == 0: + self.assertEqual(0, len(open_sale_order_list)) + return + + self.assertEqual(1, len(open_sale_order_list)) + + open_sale_order = open_sale_order_list[0] + line_list = open_sale_order.contentValues( + portal_type='Open Sale Order Line') + self.assertEqual(len(hosting_subscription_list), len(line_list)) + self.assertSameSet( + [q.getRelativeUrl() for q in hosting_subscription_list], + [q.getAggregate() for q in line_list] + ) + + def assertSubscriptionStopped(self, person): + self.login() + subscription_list = self.portal.portal_catalog( + portal_type='Hosting Subscription', + default_destination_section_uid=person.getUid()) + self.assertEqual(len(subscription_list), 1) + for subscription in subscription_list: + self.assertEqual(subscription.getSlapState(), "stop_requested") + + def assertSubscriptionDestroyed(self, person): + self.login() + subscription_list = self.portal.portal_catalog( + portal_type='Hosting Subscription', + default_destination_section_uid=person.getUid()) + self.assertEqual(len(subscription_list), 1) + for subscription in subscription_list: + self.assertEqual(subscription.getSlapState(), "destroy_requested") + + def trickCrmEvent(self, service_id, day, person_reference): + self.login() + person = self.portal.portal_catalog.getResultValue(portal_type='Person', + reference=person_reference) + ticket = self.portal.portal_catalog.getResultValue( + portal_type='Regularisation Request', + simulation_state='suspended', + default_source_project_uid=person.getUid() + ) + + event = self.portal.portal_catalog.getResultValue( + portal_type='Mail Message', + default_resource_uid=self.portal.service_module[service_id].getUid(), + default_follow_up_uid=ticket.getUid(), + ) + event.edit(start_date=event.getStartDate()-day) + data = event.getData() + data = re.sub( + "\nDate: .*\n", + "\nDate: %s\n" % (event.getStartDate()-day).rfc822(), + data) + event.edit(data=data) + + def requestInstance(self, person_reference, instance_title, + software_release, software_type): + + self.login(person_reference) + self.personRequestInstanceNotReady( + software_release=software_release, + software_type=software_type, + partition_reference=instance_title, + ) + + def test_crm_escalation(self): + # some preparation + self.logout() + self.web_site = self.portal.web_site_module.hosting + + # join as the another visitor and request software instance on public + # computer + self.logout() + public_reference = 'public-%s' % self.generateNewId() + self.joinSlapOS(self.web_site, public_reference) + + public_instance_title = 'Public title %s' % self.generateNewId() + public_instance_type = 'public type' + public_server_software = self.generateNewSoftwareReleaseUrl() + self.requestInstance(public_reference, public_instance_title, + public_server_software, public_instance_type) + + # check the Open Sale Order coverage + self.stepCallSlaposRequestUpdateHostingSubscriptionOpenSaleOrderAlarm() + self.tic() + + self.login() + + self.assertOpenSaleOrderCoverage(public_reference) + + # generate simulation for open order + + self.stepCallUpdateOpenOrderSimulationAlarm() + self.tic() + + # build subscription packing list + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + + # build other deliveries + self.stepCallSlaposInstanceInvoicingAlarm() + self.tic() + + # stabilise build deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # build aggregated packing list + self.stepCallSlaposTriggerAggregatedDeliveryOrderBuilderAlarm() + self.tic() + + # stabilise aggregated deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # deliver aggregated deliveries + self.stepCallSlaposDeliverConfirmedAggregatedSalePackingListAlarm( + accounting_date=DateTime('2222/01/01')) + self.tic() + + # stabilise aggregated deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # build aggregated invoices + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + + # stabilise aggregated invoices and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # update invoices with their tax & discount + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # update invoices with their tax & discount transaction lines + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # stop the invoices and solve them again + self.stepCallSlaposStopConfirmedAggregatedSaleInvoiceTransactionAlarm() + self.tic() + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # build the aggregated payment + self.stepCallSlaposTriggerPaymentTransactionOrderBuilderAlarm() + self.tic() + + # start the payzen payment + self.stepCallSlaposPayzenUpdateConfirmedPaymentAlarm() + self.tic() + + # stabilise the payment deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # create the regularisation request + self.stepCallSlaposCrmCreateRegularisationRequestAlarm() + self.tic() + + person = self.portal.portal_catalog.getResultValue(portal_type='Person', + reference=public_reference) + + # escalate 1 + self.trickCrmEvent('slapos_crm_acknowledgement', 38, public_reference) + self.stepCallSlaposCrmTriggerAcknowledgmentEscalationAlarm() + self.tic() + + # escalate 2 + self.trickCrmEvent('slapos_crm_stop_reminder', 7, public_reference) + self.stepCallSlaposCrmTriggerStopReminderEscalationAlarm() + self.tic() + + # stop the subscription + self.stepCallSlaposCrmStopHostingSubscriptionAlarm() + self.tic() + self.assertSubscriptionStopped(person) + + # escalate 3 + self.trickCrmEvent('slapos_crm_stop_acknowledgement', 13, public_reference) + self.stepCallSlaposCrmTriggerStopAcknowledgmentEscalationAlarm() + self.tic() + + # escalate 4 + self.trickCrmEvent('slapos_crm_delete_reminder', 2, public_reference) + self.stepCallSlaposCrmTriggerDeleteReminderEscalationAlarm() + self.tic() + + # delete the subscription + self.stepCallSlaposCrmDeleteHostingSubscriptionAlarm() + self.tic() + self.assertSubscriptionDestroyed(person) + + # check the Open Sale Order coverage + self.stepCallSlaposRequestUpdateHostingSubscriptionOpenSaleOrderAlarm() + self.tic() + + # cancel the invoice + self.stepCallSlaposCrmCancelInvoiceAlarm() + self.tic() + + # close the ticket + self.stepCallSlaposCrmInvalidateSuspendedRegularisationRequestAlarm() + self.tic() + + # update open order simulation + self.stepCallUpdateOpenOrderSimulationAlarm() + self.tic() + + # build subscription packing list + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + + # stabilise build deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # build aggregated packing list + self.stepCallSlaposTriggerAggregatedDeliveryOrderBuilderAlarm() + self.tic() + + # stabilise aggregated deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # deliver aggregated deliveries + self.stepCallSlaposDeliverConfirmedAggregatedSalePackingListAlarm( + accounting_date=DateTime('2222/01/01')) + self.tic() + + # stabilise aggregated deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # build aggregated invoices + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + + # stabilise aggregated invoices and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # update invoices with their tax & discount + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # update invoices with their tax & discount transaction lines + self.stepCallSlaposTriggerBuildAlarm() + self.tic() + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # stop the invoices and solve them again + self.stepCallSlaposStopConfirmedAggregatedSaleInvoiceTransactionAlarm() + self.tic() + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # build the aggregated payment + self.stepCallSlaposTriggerPaymentTransactionOrderBuilderAlarm() + self.tic() + + # start the payzen payment + self.stepCallSlaposPayzenUpdateConfirmedPaymentAlarm() + self.tic() + + # stabilise the payment deliveries and expand them + self.stepCallSlaposManageBuildingCalculatingDeliveryAlarm() + self.tic() + + # check final document state + self.assertPersonDocumentCoverage(person) diff --git a/master/bt5/slapos_erp5/bt/revision b/master/bt5/slapos_erp5/bt/revision index 59f313503..09df92759 100644 --- a/master/bt5/slapos_erp5/bt/revision +++ b/master/bt5/slapos_erp5/bt/revision @@ -1 +1 @@ -165 \ No newline at end of file +166 \ No newline at end of file -- 2.30.9