[REF] test_event_full: cleanup tests

Purpose of this commit is to make test_event_full globally independent from
other event sub modules testing data. We now define a complete event type
with all sub options clearly activated in a single setup. That way tests
in test_event_full are easier to read, understand and modify.

A custom report replacing badge report is added as the base one is quite
complex. It is easier to test the result with simpler templates.

Task-2703285 (Event performance improvements)
Task-2703289 (Event testing and coverage)

Part-of: odoo/odoo#81068
This commit is contained in:
Thibault Delavallée
2021-12-16 17:33:48 +00:00
parent 237911775c
commit ad5c08ca09
7 changed files with 323 additions and 117 deletions
+4 -1
View File
@@ -25,7 +25,10 @@ automatic lead generation, full Online support, ...
'website_event_track_live',
'website_event_track_quiz',
],
'installable': True,
'data': [
'data/ir_actions_report_data.xml',
'views/event_registration_templates_reports.xml',
],
'assets': {
'web.assets_tests': [
'test_event_full/static/**/*',
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<record id="event_registration_report_test" model="ir.actions.report">
<field name="name">Test Report</field>
<field name="model">event.registration</field>
<field name="report_type">qweb-pdf</field>
<field name="report_name">test_event_full.event_registration_template_report</field>
<field name="report_file">test_event_full.event_registration_template_report</field>
<field name="print_report_name">'Badge - %s - %s' % ((object.event_id.name or 'Event').replace('/',''), object.name.replace('/',''))</field>
<field name="binding_model_id" ref="event.model_event_registration"/>
<field name="binding_type">report</field>
</record>
</odoo>
+256 -71
View File
@@ -4,109 +4,287 @@
from datetime import datetime, timedelta, time
from odoo.addons.base.tests.common import HttpCaseWithUserDemo, HttpCaseWithUserPortal
from odoo.addons.event_crm.tests.common import TestEventCrmCommon
from odoo.addons.event_crm.tests.common import EventCrmCase
from odoo.addons.mail.tests.common import mail_new_test_user
from odoo.addons.sales_team.tests.common import TestSalesCommon
from odoo.addons.website.tests.test_website_visitor import MockVisitor
class TestEventFullCommon(TestEventCrmCommon, TestSalesCommon, MockVisitor):
class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
@classmethod
def setUpClass(cls):
super(TestEventFullCommon, cls).setUpClass()
cls._init_mail_gateway()
# ------------------------------------------------------------
# TICKET INFORMATIONS
# Context data: dates
# ------------------------------------------------------------
cls.event_product = cls.env['product.product'].create({
'name': 'Test Registration Product',
'description_sale': 'Mighty Description',
'list_price': 10,
'standard_price': 30.0,
'detailed_type': 'event',
# Mock dates to have reproducible computed fields based on time
cls.reference_now = datetime(2021, 12, 1, 10, 0, 0)
cls.reference_today = datetime(2021, 12, 1)
# Users and contacts
# ------------------------------------------------------------
cls.admin_user = cls.env.ref('base.user_admin')
cls.admin_user.write({
'country_id': cls.env.ref('base.be').id,
'login': 'admin',
'notification_type': 'inbox',
})
cls.website = cls.env['website'].search([
('company_id', '=', cls.env.user.company_id.id)
], limit=1)
cls.event_0.write({
# event if 8-18 in Europe/Brussels (DST) (first day: begins at 9, last day: ends at 15)
'date_begin': datetime.combine(cls.reference_now, time(7, 0)) - timedelta(days=1),
'date_end': datetime.combine(cls.reference_now, time(13, 0)) + timedelta(days=1),
# ticket informations
'event_ticket_ids': [
(5, 0),
(0, 0, {
'name': 'First Ticket',
'product_id': cls.event_product.id,
'seats_max': 30,
}), (0, 0, {
'name': 'Second Ticket',
'product_id': cls.event_product.id,
})
],
cls.company_admin = cls.admin_user.company_id
# set country in order to format Belgian numbers
cls.company_admin.write({
'country_id': cls.env.ref('base.be').id,
})
cls.event_user = mail_new_test_user(
cls.env,
company_id=cls.company_admin.id,
company_ids=[(4, cls.company_admin.id)],
country_id=cls.env.ref('base.be').id,
groups='base.group_user,base.group_partner_manager,event.group_event_user',
email='e.e@example.com',
login='event_user',
name='Ernest Employee',
notification_type='inbox',
signature='--\nErnest',
)
cls.customer = cls.env['res.partner'].create({
'country_id': cls.env.ref('base.be').id,
'email': 'customer.test@example.com',
'name': 'Test Customer',
'mobile': '0456123456',
'phone': '0456123456',
})
# make a SO for a customer, selling some tickets
cls.customer_so = cls.env['sale.order'].with_user(cls.user_sales_salesman).create({
'partner_id': cls.event_customer.id,
})
# ------------------------------------------------------------
# QUESTIONS
# Side records for event main records
# ------------------------------------------------------------
cls.event_question_1 = cls.env['event.question'].create({
'title': 'Question1',
'question_type': 'simple_choice',
'event_id': cls.event_0.id,
'once_per_order': False,
'answer_ids': [
(0, 0, {'name': 'Q1-Answer1'}),
(0, 0, {'name': 'Q1-Answer2'})
cls.ticket_product = cls.env['product.product'].create({
'description_sale': 'Ticket Product Description',
'detailed_type': 'event',
'list_price': 10,
'name': 'Test Registration Product',
'standard_price': 30.0,
})
cls.booth_product = cls.env['product.product'].create({
'description_sale': 'Booth Product Description',
'detailed_type': 'event_booth',
'list_price': 20,
'name': 'Test Booth Product',
'standard_price': 60.0,
})
cls.tag_categories = cls.env['event.tag.category'].create([
{'is_published': True, 'name': 'Published Category'},
{'is_published': False, 'name': 'Unpublished Category'},
])
cls.tags = cls.env['event.tag'].create([
{'category_id': cls.tag_categories[0].id, 'name': 'PubTag1'},
{'category_id': cls.tag_categories[0].id, 'color': 0, 'name': 'PubTag2'},
{'category_id': cls.tag_categories[1].id, 'name': 'UnpubTag1'},
])
cls.event_booth_categories = cls.env['event.booth.category'].create([
{'description': '<p>Standard</p>',
'name': 'Standard',
'product_id': cls.booth_product.id,
},
{'description': '<p>Premium</p>',
'name': 'Premium',
'product_id': cls.booth_product.id,
'price': 90,
}
])
cls.sponsor_types = cls.env['event.sponsor.type'].create([
{'name': 'GigaTop',
'sequence': 1,
}
])
cls.sponsor_partners = cls.env['res.partner'].create([
{'country_id': cls.env.ref('base.be').id,
'email': 'event.sponsor@example.com',
'name': 'EventSponsor',
'phone': '04856112233',
}
])
# Event type
# ------------------------------------------------------------
test_registration_report = cls.env.ref('test_event_full.event_registration_report_test')
subscription_template = cls.env.ref('event.event_subscription')
subscription_template.write({'report_template': test_registration_report.id})
cls.test_event_type = cls.env['event.type'].create({
'auto_confirm': True,
'default_timezone': 'Europe/Paris',
'event_type_booth_ids': [
(0, 0, {'booth_category_id': cls.event_booth_categories[0].id,
'name': 'Standard Booth',
}
),
(0, 0, {'booth_category_id': cls.event_booth_categories[0].id,
'name': 'Standard Booth 2',
}
),
(0, 0, {'booth_category_id': cls.event_booth_categories[1].id,
'name': 'Premium Booth',
}
),
(0, 0, {'booth_category_id': cls.event_booth_categories[1].id,
'name': 'Premium Booth 2',
}
),
],
})
cls.event_question_2 = cls.env['event.question'].create({
'title': 'Question2',
'question_type': 'simple_choice',
'event_id': cls.event_0.id,
'once_per_order': True,
'answer_ids': [
(0, 0, {'name': 'Q2-Answer1'}),
(0, 0, {'name': 'Q2-Answer2'})
'event_type_mail_ids': [
(0, 0, {'interval_unit': 'now', # right at subscription
'interval_type': 'after_sub',
'notification_type': 'mail',
'template_ref': 'mail.template,%i' % subscription_template.id,
}
),
(0, 0, {'interval_nbr': 1, # 1 days before event
'interval_unit': 'days',
'interval_type': 'before_event',
'notification_type': 'mail',
'template_ref': 'mail.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event.event_reminder'),
}
),
(0, 0, {'interval_nbr': 1, # 1 days after event
'interval_unit': 'days',
'interval_type': 'after_event',
'notification_type': 'sms',
'template_ref': 'sms.template,%i' % cls.env['ir.model.data']._xmlid_to_res_id('event_sms.sms_template_data_event_reminder'),
}
),
],
})
cls.event_question_3 = cls.env['event.question'].create({
'title': 'Question3',
'question_type': 'text_box',
'event_id': cls.event_0.id,
'once_per_order': True,
'event_type_ticket_ids': [
(0, 0, {'description': 'Ticket1 Description',
'name': 'Ticket1',
'product_id': cls.ticket_product.id,
'seats_max': 10,
}
),
(0, 0, {'description': 'Ticket2 Description',
'name': 'Ticket2',
'product_id': cls.ticket_product.id,
'price': 45,
}
)
],
'has_seats_limitation': True,
'name': 'Test Type',
'note': '<p>Template note</p>',
'question_ids': [
(0, 0, {'answer_ids':
[(0, 0, {'name': 'Q1-Answer1'}),
(0, 0, {'name': 'Q1-Answer2'}),
],
'question_type': 'simple_choice',
'once_per_order': False,
'title': 'Question1',
}
),
(0, 0, {'answer_ids':
[(0, 0, {'name': 'Q2-Answer1'}),
(0, 0, {'name': 'Q2-Answer2'}),
],
'question_type': 'simple_choice',
'once_per_order': False,
'title': 'Question2',
}
),
(0, 0, {'question_type': 'text_box',
'once_per_order': True,
'title': 'Question3',
}
),
],
'seats_max': 30,
'tag_ids': [(4, tag.id) for tag in cls.tags],
'ticket_instructions': '<p>Ticket Instructions</p>',
'website_menu': True,
})
# ------------------------------------------------------------
# DATA MARSHMALLING
# Stages
cls.stage_def = cls.env['event.stage'].create({
'name': 'First Stage',
'sequence': 0,
})
# Event data
# ------------------------------------------------------------
cls.website_customer_data = [{
'name': 'My Customer %02d' % x,
'partner_id': cls.env.ref('base.public_partner').id,
'email': 'email.%02d@test.example.com' % x,
'phone': '04560000%02d' % x,
'registration_answer_ids': [
cls.event_base_vals = {
'name': 'Test Event',
'date_begin': cls.reference_now + timedelta(days=1),
'date_end': cls.reference_now + timedelta(days=5),
'is_published': True,
}
cls.test_event = cls.env['event.event'].create({
'name': 'Test Event',
'auto_confirm': True,
'date_begin': datetime.now() + timedelta(days=1),
'date_end': datetime.now() + timedelta(days=5),
'date_tz': 'Europe/Brussels',
'event_type_id': cls.test_event_type.id,
'is_published': True,
})
# update post-synchronize data
ticket_1 = cls.test_event.event_ticket_ids.filtered(lambda t: t.name == 'Ticket1')
ticket_2 = cls.test_event.event_ticket_ids.filtered(lambda t: t.name == 'Ticket2')
ticket_1.start_sale_datetime = cls.reference_now + timedelta(hours=1)
ticket_2.start_sale_datetime = cls.reference_now + timedelta(hours=2)
# Website data
# ------------------------------------------------------------
cls.website = cls.env['website'].search([
('company_id', '=', cls.company_admin.id)
], limit=1)
cls.customer_data = [
{'email': 'customer.email.%02d@test.example.com' % x,
'name': 'My Customer %02d' % x,
'mobile': '04569999%02d' % x,
'partner_id': False,
'phone': '04560000%02d' % x,
} for x in range(0, 10)
]
cls.website_customer_data = [
{'email': 'website.email.%02d@test.example.com' % x,
'name': 'My Customer %02d' % x,
'mobile': '04569999%02d' % x,
'partner_id': cls.env.ref('base.public_partner').id,
'phone': '04560000%02d' % x,
'registration_answer_ids': [
(0, 0, {
'question_id': cls.event_question_1.id,
'value_answer_id': cls.event_question_1.answer_ids[(x % 2)].id,
'question_id': cls.test_event.question_ids[0].id,
'value_answer_id': cls.test_event.question_ids[0].answer_ids[(x % 2)].id,
}), (0, 0, {
'question_id': cls.event_question_2.id,
'value_answer_id': cls.event_question_2.answer_ids[(x % 2)].id,
'question_id': cls.test_event.question_ids[1].id,
'value_answer_id': cls.test_event.question_ids[1].answer_ids[(x % 2)].id,
}), (0, 0, {
'question_id': cls.event_question_3.id,
'question_id': cls.test_event.question_ids[2].id,
'value_text_box': 'CustomerAnswer%s' % x,
})
],
} for x in range(0, 4)]
],
} for x in range(0, 10)
]
cls.partners = cls.env['res.partner'].create([
{'email': 'partner.email.%02d@test.example.com' % x,
'name': 'PartnerCustomer',
'mobile': '04569999%02d' % x,
'phone': '04560000%02d' % x,
} for x in range(0, 10)
])
def assertLeadConvertion(self, rule, registrations, partner=None, **expected):
super(TestEventFullCommon, self).assertLeadConvertion(rule, registrations, partner=partner, **expected)
@@ -131,6 +309,13 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
def setUp(self):
super(TestWEventCommon, self).setUp()
# Context data: dates
# ------------------------------------------------------------
# Mock dates to have reproducible computed fields based on time
self.reference_now = datetime(2021, 12, 1, 10, 0, 0)
self.reference_today = datetime(2021, 12, 1)
self.event_product = self.env['product.product'].create({
'name': 'Test Event Registration',
'default_code': 'EVENT_REG',
+21 -17
View File
@@ -12,8 +12,10 @@ class TestEventCrm(TestEventFullCommon):
super(TestEventCrm, cls).setUpClass()
cls.TICKET1_COUNT, cls.TICKET2_COUNT = 3, 1
ticket1 = cls.event_0.event_ticket_ids[0]
ticket2 = cls.event_0.event_ticket_ids[1]
ticket1 = cls.test_event.event_ticket_ids[0]
ticket2 = cls.test_event.event_ticket_ids[1]
(cls.test_rule_attendee + cls.test_rule_order).write({'event_id': cls.test_event.id})
# PREPARE SO DATA
# ------------------------------------------------------------
@@ -22,12 +24,12 @@ class TestEventCrm(TestEventFullCommon):
cls.customer_so.write({
'order_line': [
(0, 0, {
'event_id': cls.event_0.id,
'event_id': cls.test_event.id,
'event_ticket_id': ticket1.id,
'product_id': ticket1.product_id.id,
'product_uom_qty': cls.TICKET1_COUNT,
}), (0, 0, {
'event_id': cls.event_0.id,
'event_id': cls.test_event.id,
'event_ticket_id': ticket2.id,
'product_id': ticket2.product_id.id,
'product_uom_qty': cls.TICKET2_COUNT,
@@ -52,7 +54,7 @@ class TestEventCrm(TestEventFullCommon):
t1_registrations = self.env['event.registration'].create(t1_reg_vals)
# check effect: registrations, leads
self.assertEqual(self.event_0.registration_ids, t1_registrations)
self.assertEqual(self.test_event.registration_ids, t1_registrations)
self.assertEqual(len(self.test_rule_order.lead_ids), 1)
self.assertEqual(self.test_rule_order_done.lead_ids, self.env['crm.lead'])
# check lead converted based on registrations
@@ -62,17 +64,17 @@ class TestEventCrm(TestEventFullCommon):
# and added to the lead as part of the same group
customer_so.action_confirm()
self.assertEqual(customer_so.state, 'sale')
self.assertEqual(len(self.event_0.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT)
self.assertEqual(len(self.test_event.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT)
self.assertEqual(len(self.test_rule_order.lead_ids), 1) # no new lead created
self.assertEqual(self.test_rule_order_done.lead_ids, self.env['crm.lead']) # this one still not triggered
# check existing lead has been updated with new registrations
self.assertLeadConvertion(self.test_rule_order, self.event_0.registration_ids, partner=customer_so.partner_id)
self.assertLeadConvertion(self.test_rule_order, self.test_event.registration_ids, partner=customer_so.partner_id)
# Confirm registrations -> trigger the "DONE" rule, one new lead linked to all
# event registrations created in this test as all belong to the same SO
self.event_0.registration_ids.write({'state': 'done'})
self.assertLeadConvertion(self.test_rule_order_done, self.event_0.registration_ids, partner=customer_so.partner_id)
self.test_event.registration_ids.write({'state': 'done'})
self.assertLeadConvertion(self.test_rule_order_done, self.test_event.registration_ids, partner=customer_so.partner_id)
@users('user_sales_salesman')
def test_event_crm_sale_mixed_group(self):
@@ -83,9 +85,9 @@ class TestEventCrm(TestEventFullCommon):
'partner_id': public_partner.id,
'order_line': [
(0, 0, {
'event_id': self.event_0.id,
'event_ticket_id': self.event_0.event_ticket_ids[0].id,
'product_id': self.event_0.event_ticket_ids[0].product_id.id,
'event_id': self.test_event.id,
'event_ticket_id': self.test_event.event_ticket_ids[0].id,
'product_id': self.test_event.event_ticket_ids[0].product_id.id,
'product_uom_qty': 2,
})
]
@@ -109,9 +111,9 @@ class TestEventCrm(TestEventFullCommon):
]
self.env['event.registration'].create(mixed_reg_vals)
public_regs = self.event_0.registration_ids.filtered(lambda reg: reg.sale_order_id == public_so)
public_regs = self.test_event.registration_ids.filtered(lambda reg: reg.sale_order_id == public_so)
self.assertEqual(len(public_regs), 2)
customer_regs = self.event_0.registration_ids.filtered(lambda reg: reg.sale_order_id == customer_so)
customer_regs = self.test_event.registration_ids.filtered(lambda reg: reg.sale_order_id == customer_so)
self.assertEqual(len(customer_regs), 2)
self.assertLeadConvertion(self.test_rule_order, public_regs, partner=None)
self.assertLeadConvertion(self.test_rule_order, customer_regs, partner=customer_so.partner_id)
@@ -122,7 +124,9 @@ class TestEventCrm(TestEventFullCommon):
This somehow simulates a simplified website_event_sale flow. """
public_partner = self.env.ref('base.public_partner')
customer_so = self.env['sale.order'].browse(self.customer_so.id)
customer_so.write({'partner_id': public_partner.id})
customer_so.write({
'partner_id': public_partner.id,
})
# adding some tickets to SO
t1_reg_vals = [
@@ -132,7 +136,7 @@ class TestEventCrm(TestEventFullCommon):
for customer_data in self.website_customer_data[:self.TICKET1_COUNT]
]
t1_registrations = self.env['event.registration'].create(t1_reg_vals)
self.assertEqual(self.event_0.registration_ids, t1_registrations)
self.assertEqual(self.test_event.registration_ids, t1_registrations)
# check lead converted based on registrations
self.assertLeadConvertion(self.test_rule_order, t1_registrations, partner=None)
@@ -141,7 +145,7 @@ class TestEventCrm(TestEventFullCommon):
# BUT as public user -> no email -> not taken into account by rule
customer_so.action_confirm()
self.assertEqual(customer_so.state, 'sale')
self.assertEqual(len(self.event_0.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT)
self.assertEqual(len(self.test_event.registration_ids), self.TICKET1_COUNT + self.TICKET2_COUNT)
self.assertLeadConvertion(self.test_rule_order, t1_registrations, partner=None)
# SO has a customer set -> main contact of lead is updated accordingly
@@ -3,30 +3,15 @@
from datetime import datetime, timedelta
from odoo import fields
from odoo.addons.event.tests.common import EventCase
from odoo.addons.test_event_full.tests.common import TestEventFullCommon
from odoo.exceptions import AccessError
from odoo.tests import tagged
from odoo.tests.common import users
from odoo.tools import mute_logger
class TestEventSecurity(EventCase):
@classmethod
def setUpClass(cls):
super(TestEventSecurity, cls).setUpClass()
cls.test_event = cls.env['event.event'].create({
'auto_confirm': True,
'date_begin': fields.Datetime.to_string(datetime.today() + timedelta(days=1)),
'date_end': fields.Datetime.to_string(datetime.today() + timedelta(days=15)),
'date_tz': 'Europe/Brussels',
'name': 'TestEvent',
})
cls.test_event_type = cls.env['event.type'].create({
'auto_confirm': True,
'name': 'Update Type',
})
@tagged('security')
class TestEventSecurity(TestEventFullCommon):
@users('user_employee')
@mute_logger('odoo.models.unlink', 'odoo.addons.base.models.ir_model')
@@ -80,9 +65,9 @@ class TestEventSecurity(EventCase):
# Event Registration
registration = self.env['event.registration'].create({
'event_id': self.test_event.id,
'event_id': event.id,
})
self.assertEqual(registration.event_id.name, self.test_event.name, 'Registration users should be able to read')
self.assertEqual(registration.event_id.name, event.name, 'Registration users should be able to read')
registration.name = 'Test write'
with self.assertRaises(AccessError):
registration.unlink()
@@ -1,21 +1,23 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from freezegun import freeze_time
from odoo import tests
from odoo.addons.test_event_full.tests.common import TestWEventCommon
from odoo.tests.common import HOST
@tests.common.tagged('post_install', '-at_install')
class TestWEventRegister(TestWEventCommon):
def test_register(self):
self.browser_js(
'/event',
'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_register")',
'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_register.ready',
login=None
)
with freeze_time(self.reference_now):
self.browser_js(
'/event',
'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_register")',
'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_register.ready',
login=None
)
new_registrations = self.event.registration_ids
visitor = new_registrations.visitor_id
@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<odoo>
<template id="event_registration_template_report">
<t t-call="web.html_container">
<t t-foreach="docs" t-as="registration">
<t t-call="web.external_layout">
<div class="page">
<p>This is a sample of an external report.</p>
</div>
</t>
</t>
</t>
</template>
</odoo>