mirror of
https://github.com/bringout/oca-ocb-test.git
synced 2026-04-23 18:22:01 +02:00
19.0 vanilla
This commit is contained in:
parent
38c6088dcc
commit
d9452d2060
243 changed files with 30797 additions and 10815 deletions
|
|
@ -14,7 +14,6 @@ pip install odoo-bringout-oca-ocb-test_event_full
|
|||
|
||||
## Dependencies
|
||||
|
||||
This addon depends on:
|
||||
- event
|
||||
- event_booth
|
||||
- event_crm
|
||||
|
|
@ -23,43 +22,18 @@ This addon depends on:
|
|||
- event_sms
|
||||
- payment_demo
|
||||
- website_event_booth_sale_exhibitor
|
||||
- website_event_crm_questions
|
||||
- website_event_exhibitor
|
||||
- website_event_questions
|
||||
- website_event_meet
|
||||
- website_event_sale
|
||||
- website_event_track
|
||||
- website_event_track_live
|
||||
- website_event_track_quiz
|
||||
|
||||
## Manifest Information
|
||||
|
||||
- **Name**: Test Full Event Flow
|
||||
- **Version**: 1.0
|
||||
- **Category**: Hidden/Tests
|
||||
- **License**: LGPL-3
|
||||
- **Installable**: False
|
||||
|
||||
## Source
|
||||
|
||||
Based on [OCA/OCB](https://github.com/OCA/OCB) branch 16.0, addon `test_event_full`.
|
||||
- Repository: https://github.com/OCA/OCB
|
||||
- Branch: 19.0
|
||||
- Path: addons/test_event_full
|
||||
|
||||
## License
|
||||
|
||||
This package maintains the original LGPL-3 license from the upstream Odoo project.
|
||||
|
||||
## Documentation
|
||||
|
||||
- Overview: doc/OVERVIEW.md
|
||||
- Architecture: doc/ARCHITECTURE.md
|
||||
- Models: doc/MODELS.md
|
||||
- Controllers: doc/CONTROLLERS.md
|
||||
- Wizards: doc/WIZARDS.md
|
||||
- Reports: doc/REPORTS.md
|
||||
- Security: doc/SECURITY.md
|
||||
- Install: doc/INSTALL.md
|
||||
- Usage: doc/USAGE.md
|
||||
- Configuration: doc/CONFIGURATION.md
|
||||
- Dependencies: doc/DEPENDENCIES.md
|
||||
- Troubleshooting: doc/TROUBLESHOOTING.md
|
||||
- FAQ: doc/FAQ.md
|
||||
This package preserves the original LGPL-3 license.
|
||||
|
|
|
|||
|
|
@ -1,27 +1,26 @@
|
|||
[project]
|
||||
name = "odoo-bringout-oca-ocb-test_event_full"
|
||||
version = "16.0.0"
|
||||
description = "Test Full Event Flow - Odoo addon"
|
||||
description = "Test Full Event Flow -
|
||||
Odoo addon
|
||||
"
|
||||
authors = [
|
||||
{ name = "Ernad Husremovic", email = "hernad@bring.out.ba" }
|
||||
]
|
||||
dependencies = [
|
||||
"odoo-bringout-oca-ocb-event>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-event_booth>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-event_crm>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-event_crm_sale>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-event_sale>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-event_sms>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-payment_demo>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_booth_sale_exhibitor>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_crm_questions>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_exhibitor>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_questions>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_meet>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_sale>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_track>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_track_live>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_track_quiz>=16.0.0",
|
||||
"odoo-bringout-oca-ocb-event>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-event_booth>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-event_crm>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-event_crm_sale>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-event_sale>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-event_sms>=19.0.0",
|
||||
"TODO_MAP-payment_demo>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_booth_sale_exhibitor>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_exhibitor>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_sale>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_track>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_track_live>=19.0.0",
|
||||
"odoo-bringout-oca-ocb-website_event_track_quiz>=19.0.0",
|
||||
"requests>=2.25.1"
|
||||
]
|
||||
readme = "README.md"
|
||||
|
|
@ -31,7 +30,7 @@ classifiers = [
|
|||
"Intended Audience :: Developers",
|
||||
"License :: OSI Approved :: GNU Lesser General Public License v3 (LGPLv3)",
|
||||
"Programming Language :: Python :: 3",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.11",
|
||||
"Programming Language :: Python :: 3.12",
|
||||
"Topic :: Office/Business",
|
||||
]
|
||||
|
|
|
|||
|
|
@ -19,10 +19,7 @@ automatic lead generation, full Online support, ...
|
|||
'event_sms',
|
||||
'payment_demo',
|
||||
'website_event_booth_sale_exhibitor',
|
||||
'website_event_crm_questions',
|
||||
'website_event_exhibitor',
|
||||
'website_event_questions',
|
||||
'website_event_meet',
|
||||
'website_event_sale',
|
||||
'website_event_track',
|
||||
'website_event_track_live',
|
||||
|
|
@ -35,8 +32,12 @@ automatic lead generation, full Online support, ...
|
|||
],
|
||||
'assets': {
|
||||
'web.assets_tests': [
|
||||
'test_event_full/static/**/*',
|
||||
'test_event_full/static/src/js/tours/*',
|
||||
],
|
||||
'web.assets_unit_tests': [
|
||||
'test_event_full/static/src/js/tests/*',
|
||||
],
|
||||
},
|
||||
'author': 'Odoo S.A.',
|
||||
'license': 'LGPL-3',
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,122 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<odoo><data noupdate="0">
|
||||
|
||||
<record id="event_booth_category_data_1" model="event.booth.category">
|
||||
<field name="description" type="html"><p>Standard</p></field>
|
||||
<field name="name">Standard</field>
|
||||
<field name="product_id" ref="event_booth_sale.product_product_event_booth"/>
|
||||
</record>
|
||||
<record id="event_booth_category_data_2" model="event.booth.category">
|
||||
<field name="description" type="html"><p>Premium</p></field>
|
||||
<field name="name">Premium</field>
|
||||
<field name="product_id" ref="event_booth_sale.product_product_event_booth"/>
|
||||
<field name="price">90</field>
|
||||
</record>
|
||||
|
||||
<record id="event_type_data_full" model="event.type">
|
||||
<field name="auto_confirm" eval="True"/>
|
||||
<field name="default_timezone">Europe/Paris</field>
|
||||
<field name="event_type_booth_ids" eval="[
|
||||
(5, 0),
|
||||
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_1'),
|
||||
'name': 'Standard Booth',
|
||||
}
|
||||
),
|
||||
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_1'),
|
||||
'name': 'Standard Booth 2',
|
||||
}
|
||||
),
|
||||
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_2'),
|
||||
'name': 'Premium Booth',
|
||||
}
|
||||
),
|
||||
(0, 0, {'booth_category_id': ref('test_event_full.event_booth_category_data_2'),
|
||||
'name': 'Premium Booth 2',
|
||||
}
|
||||
)]"/>
|
||||
<field name="event_type_mail_ids" eval="[
|
||||
(5, 0),
|
||||
(0, 0, {'interval_unit': 'now',
|
||||
'interval_type': 'after_sub',
|
||||
'notification_type': 'mail',
|
||||
'template_ref': 'mail.template,%i' % ref('event.event_subscription'),
|
||||
}
|
||||
),
|
||||
(0, 0, {'interval_nbr': 1,
|
||||
'interval_unit': 'days',
|
||||
'interval_type': 'before_event',
|
||||
'notification_type': 'mail',
|
||||
'template_ref': 'mail.template,%i' % ref('event.event_reminder'),
|
||||
}
|
||||
),
|
||||
(0, 0, {'interval_nbr': 1,
|
||||
'interval_unit': 'days',
|
||||
'interval_type': 'after_event',
|
||||
'notification_type': 'sms',
|
||||
'template_ref': 'sms.template,%i' % ref('event_sms.sms_template_data_event_reminder'),
|
||||
}
|
||||
)]"/>
|
||||
<field name="event_type_ticket_ids" eval="[
|
||||
(5, 0),
|
||||
(0, 0, {'description': 'Ticket1 Description',
|
||||
'name': 'Ticket1',
|
||||
'product_id': ref('event_sale.product_product_event'),
|
||||
'seats_max': 10,
|
||||
}
|
||||
),
|
||||
(0, 0, {'description': 'Ticket2 Description',
|
||||
'name': 'Ticket2',
|
||||
'product_id': ref('event_sale.product_product_event'),
|
||||
'price': 45,
|
||||
}
|
||||
)]"/>
|
||||
<field name="has_seats_limitation" eval="True"/>
|
||||
<field name="name">Test Type</field>
|
||||
<field name="note" type="html"><p>Template note</p></field>
|
||||
<field name="question_ids" eval="[(5, 0)]"/>
|
||||
<field name="seats_max">30</field>
|
||||
<field name="tag_ids" eval="[(5, 0)]"/>
|
||||
<field name="ticket_instructions" type="html"><p>Ticket Instructions</p></field>
|
||||
<field name="website_menu" eval="True"/>
|
||||
</record>
|
||||
|
||||
<record id="event_question_type_full_1" model="event.question">
|
||||
<field name="question_type">simple_choice</field>
|
||||
<field name="once_per_order" eval="False"/>
|
||||
<field name="event_type_id" ref="test_event_full.event_type_data_full"/>
|
||||
<field name="title">Question1</field>
|
||||
</record>
|
||||
<record id="event_question_type_full_1_answer_1" model="event.question.answer">
|
||||
<field name="name">Q1-Answer1</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="question_id" ref="test_event_full.event_question_type_full_1"/>
|
||||
</record>
|
||||
<record id="event_question_type_full_1_answer_2" model="event.question.answer">
|
||||
<field name="name">Q1-Answer2</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="question_id" ref="test_event_full.event_question_type_full_1"/>
|
||||
</record>
|
||||
<record id="event_question_type_full_2" model="event.question">
|
||||
<field name="question_type">simple_choice</field>
|
||||
<field name="once_per_order" eval="False"/>
|
||||
<field name="event_type_id" ref="test_event_full.event_type_data_full"/>
|
||||
<field name="title">Question2</field>
|
||||
</record>
|
||||
<record id="event_question_type_full_2_answer_1" model="event.question.answer">
|
||||
<field name="name">Q2-Answer1</field>
|
||||
<field name="sequence">1</field>
|
||||
<field name="question_id" ref="test_event_full.event_question_type_full_2"/>
|
||||
</record>
|
||||
<record id="event_question_type_full_2_answer_2" model="event.question.answer">
|
||||
<field name="name">Q2-Answer2</field>
|
||||
<field name="sequence">2</field>
|
||||
<field name="question_id" ref="test_event_full.event_question_type_full_2"/>
|
||||
</record>
|
||||
<record id="event_question_type_full_3" model="event.question">
|
||||
<field name="question_type">text_box</field>
|
||||
<field name="once_per_order" eval="True"/>
|
||||
<field name="event_type_id" ref="test_event_full.event_type_data_full"/>
|
||||
<field name="title">Question3</field>
|
||||
</record>
|
||||
|
||||
</data></odoo>
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
import { defineMailModels } from "@mail/../tests/mail_test_helpers";
|
||||
import { describe, expect, test } from "@odoo/hoot";
|
||||
import { click, select } from "@odoo/hoot-dom";
|
||||
import { animationFrame } from "@odoo/hoot-mock";
|
||||
import { defineModels, fields, models, mountView, onRpc } from "@web/../tests/web_test_helpers";
|
||||
|
||||
class EventMail extends models.Model {
|
||||
_name = "event.mail";
|
||||
|
||||
template_ref = fields.Reference({
|
||||
selection: [
|
||||
["mail.template", "Mail Template"],
|
||||
["sms.template", "SMS Template"],
|
||||
["some.template", "Some Template"],
|
||||
],
|
||||
});
|
||||
|
||||
_records = [
|
||||
{
|
||||
id: 1,
|
||||
template_ref: "mail.template,1",
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
template_ref: "sms.template,1",
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
template_ref: "some.template,1",
|
||||
},
|
||||
];
|
||||
}
|
||||
class MailTemplate extends models.Model {
|
||||
_name = "mail.template";
|
||||
|
||||
name = fields.Char();
|
||||
|
||||
_records = [{ id: 1, name: "Mail Template 1" }];
|
||||
}
|
||||
class SmsTemplate extends models.Model {
|
||||
_name = "sms.template";
|
||||
|
||||
name = fields.Char();
|
||||
|
||||
_records = [{ id: 1, name: "SMS template 1" }];
|
||||
}
|
||||
class SomeTemplate extends models.Model {
|
||||
_name = "some.template";
|
||||
|
||||
name = fields.Char();
|
||||
|
||||
_records = [{ id: 1, name: "Some Template 1" }];
|
||||
}
|
||||
defineMailModels();
|
||||
defineModels([EventMail, MailTemplate, SmsTemplate, SomeTemplate]);
|
||||
|
||||
describe.current.tags("desktop");
|
||||
|
||||
test("Reference field displays right icons", async () => {
|
||||
// bypass list controller check
|
||||
onRpc("has_group", () => true);
|
||||
|
||||
await mountView({
|
||||
type: "list",
|
||||
resModel: "event.mail",
|
||||
arch: `
|
||||
<list editable="top">
|
||||
<field name="template_ref" widget="EventMailTemplateReferenceField"/>
|
||||
</list>`,
|
||||
});
|
||||
|
||||
// each field cell will be the field of a different record (1 field/line)
|
||||
expect(".o_field_cell").toHaveCount(3);
|
||||
expect(".o_field_cell.o_EventMailTemplateReferenceField_cell").toHaveCount(3);
|
||||
expect(".o_field_cell:eq(0) .fa-envelope").toHaveCount(1);
|
||||
expect(".o_field_cell:eq(1) .fa-mobile").toHaveCount(1);
|
||||
expect(".o_field_cell:eq(2) .fa-envelope").toHaveCount(0);
|
||||
expect(".o_field_cell:eq(2) .fa-mobile").toHaveCount(0);
|
||||
|
||||
// select a sms.template instead of mail.template
|
||||
|
||||
await click(".o_field_cell:eq(0)");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(0) select.o_input");
|
||||
await select("sms.template");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(0) .o_field_many2one_selection input");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(0) .o-autocomplete--dropdown-item");
|
||||
// click out
|
||||
await click(".o_list_renderer");
|
||||
await animationFrame();
|
||||
|
||||
expect(".o_field_cell:eq(0) .fa-mobile").toHaveCount(1);
|
||||
expect(".o_field_cell:eq(0) .fa-envelope").toHaveCount(0);
|
||||
|
||||
// select a some other model to check it has no icon
|
||||
|
||||
await click(".o_field_cell:eq(0)");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(0) select.o_input");
|
||||
await select("some.template");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(0) .o_field_many2one_selection input");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(0) .o-autocomplete--dropdown-item");
|
||||
await click(".o_list_renderer");
|
||||
await animationFrame();
|
||||
|
||||
expect(".o_field_cell:eq(0) .fa-mobile").toHaveCount(0);
|
||||
expect(".o_field_cell:eq(0) .fa-envelope").toHaveCount(0);
|
||||
|
||||
// select no record for the model
|
||||
|
||||
await click(".o_field_cell:eq(1)");
|
||||
await animationFrame();
|
||||
await click(".o_field_cell:eq(1) select.o_input");
|
||||
await select("mail.template");
|
||||
await click(".o_list_renderer");
|
||||
await animationFrame();
|
||||
|
||||
expect(".o_field_cell:eq(1) .fa-mobile").toHaveCount(0);
|
||||
expect(".o_field_cell:eq(1) .fa-envelope").toHaveCount(0);
|
||||
});
|
||||
|
|
@ -1,85 +1,76 @@
|
|||
odoo.define('test_event_full.tour.performance', function (require) {
|
||||
"use strict";
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
import { registry } from "@web/core/registry";
|
||||
import * as wsTourUtils from '@website_sale/js/tours/tour_utils';
|
||||
|
||||
var registerSteps = [{
|
||||
content: "Select 2 units of 'Ticket1' ticket type",
|
||||
trigger: '#o_wevent_tickets_collapse .row.o_wevent_ticket_selector[name="Ticket1"] select',
|
||||
run: 'text 2',
|
||||
content: "Open ticket modal",
|
||||
trigger: 'button.btn-primary:contains("Register")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: "Select 1 unit of 'Ticket2' ticket type",
|
||||
trigger: '#o_wevent_tickets_collapse .row.o_wevent_ticket_selector[name="Ticket2"] select',
|
||||
run: 'text 1',
|
||||
content: "Add 2 units of 'Ticket1' ticket type by clicking the '+' button",
|
||||
trigger: 'button[data-increment-type*="plus"]',
|
||||
run: "dblclick",
|
||||
}, {
|
||||
content: "Edit 1 unit of 'Ticket2' ticket type",
|
||||
trigger: '.modal input:eq(2)',
|
||||
run: "edit 1",
|
||||
}, {
|
||||
content: "Click on 'Register' button",
|
||||
trigger: '#o_wevent_tickets .btn-primary:contains("Register"):not(:disabled)',
|
||||
run: 'click',
|
||||
}, {
|
||||
content: "Fill attendees details",
|
||||
trigger: 'form[id="attendee_registration"] .btn:contains("Continue")',
|
||||
run: function () {
|
||||
$("input[name='1-name']").val("Raoulette Poiluchette");
|
||||
$("input[name='1-phone']").val("0456112233");
|
||||
$("input[name='1-email']").val("raoulette@example.com");
|
||||
$("div[name*='Question1'] select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Q1-Answer2')").val());
|
||||
$("div[name*='Question2'] select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Q2-Answer1')").val());
|
||||
$("input[name='2-name']").val("Michel Tractopelle");
|
||||
$("input[name='2-phone']").val("0456332211");
|
||||
$("input[name='2-email']").val("michel@example.com");
|
||||
$("div[name*='Question1'] select[name*='question_answer-2']").val($("select[name*='question_answer-2'] option:contains('Q1-Answer1')").val());
|
||||
$("div[name*='Question2'] select[name*='question_answer-2']").val($("select[name*='question_answer-2'] option:contains('Q2-Answer2')").val());
|
||||
$("input[name='3-name']").val("Hubert Boitaclous");
|
||||
$("input[name='3-phone']").val("0456995511");
|
||||
$("input[name='3-email']").val("hubert@example.com");
|
||||
$("div[name*='Question1'] select[name*='question_answer-3']").val($("select[name*='question_answer-3'] option:contains('Q1-Answer2')").val());
|
||||
$("div[name*='Question2'] select[name*='question_answer-3']").val($("select[name*='question_answer-3'] option:contains('Q2-Answer2')").val());
|
||||
$("textarea[name*='question_answer']").text("Random answer from random guy");
|
||||
},
|
||||
content: "Choose the 'Q1-Answer2' answer of the 'Question1' for the first ticket",
|
||||
trigger: 'select[name*="1-simple_choice"]',
|
||||
run: "selectByIndex 2",
|
||||
}, {
|
||||
content: "Choose the 'Q2-Answer1' answer of the 'Question2' for the first ticket",
|
||||
trigger: 'select[name*="1-simple_choice"]:last',
|
||||
run: "selectByIndex 1",
|
||||
}, {
|
||||
content: "Choose the 'Q1-Answer1' answer of the 'Question1' for the second ticket",
|
||||
trigger: 'select[name*="2-simple_choice"]',
|
||||
run: "selectByIndex 1",
|
||||
}, {
|
||||
content: "Choose the 'Q2-Answer2' answer of the 'Question2' for the second ticket",
|
||||
trigger: 'select[name*="2-simple_choice"]:last',
|
||||
run: "selectByIndex 2",
|
||||
}, {
|
||||
content: "Choose the 'Q1-Answer2' answer of the 'Question1' for the third ticket",
|
||||
trigger: 'select[name*="3-simple_choice"]',
|
||||
run: "selectByIndex 2",
|
||||
}, {
|
||||
content: "Choose the 'Q2-Answer2' answer of the 'Question2' for the third ticket",
|
||||
trigger: 'select[name*="3-simple_choice"]:last',
|
||||
run: "selectByIndex 2",
|
||||
}, {
|
||||
content: "Fill the text content of the 'Question3' for the third ticket",
|
||||
trigger: 'textarea[name*="text_box"]',
|
||||
run: "edit Random answer from random guy",
|
||||
}, {
|
||||
content: "Validate attendees details",
|
||||
extra_trigger: "input[name='1-name'], input[name='2-name'], input[name='3-name']",
|
||||
trigger: 'button:contains("Continue")',
|
||||
trigger: 'button[type=submit]:last',
|
||||
run: 'click',
|
||||
}, {
|
||||
content: "Address filling",
|
||||
trigger: 'select[name="country_id"]',
|
||||
run: function () {
|
||||
$('input[name="name"]').val('Raoulette Poiluchette');
|
||||
$('input[name="phone"]').val('0456112233');
|
||||
$('input[name="email"]').val('raoulette@example.com');
|
||||
$('input[name="street"]').val('Cheesy Crust Street, 42');
|
||||
$('input[name="city"]').val('CheeseCity');
|
||||
$('input[name="zip"]').val('8888');
|
||||
$('#country_id option:eq(1)').attr('selected', true);
|
||||
},
|
||||
}, {
|
||||
content: "Next",
|
||||
trigger: '.oe_cart .btn:contains("Next")',
|
||||
}, {
|
||||
content: 'Select Test payment provider',
|
||||
trigger: '.o_payment_option_card:contains("Demo")'
|
||||
}, {
|
||||
content: 'Add card number',
|
||||
trigger: 'input[name="customer_input"]',
|
||||
run: 'text 4242424242424242'
|
||||
}, {
|
||||
content: "Pay now",
|
||||
extra_trigger: "#cart_products:contains(Ticket1):contains(Ticket2)",
|
||||
trigger: 'button:contains(Pay Now)',
|
||||
run: 'click',
|
||||
}, {
|
||||
content: 'Payment is successful',
|
||||
trigger: '.oe_website_sale_tx_status:contains("Your payment has been successfully processed.")',
|
||||
run: function () {}
|
||||
}];
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
...wsTourUtils.fillAdressForm({
|
||||
name: "Raoulette Poiluchette",
|
||||
phone: "0456112233",
|
||||
email: "raoulette@example.com",
|
||||
street: "Cheesy Crust Street, 42",
|
||||
city: "CheeseCity",
|
||||
zip: "8888",
|
||||
}),
|
||||
{
|
||||
content: "Confirm address",
|
||||
trigger: 'a[name="website_sale_main_button"]',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
...wsTourUtils.payWithDemo(),
|
||||
];
|
||||
|
||||
|
||||
tour.register('wevent_performance_register', {
|
||||
test: true
|
||||
}, [].concat(
|
||||
registry.category("web_tour.tours").add('wevent_performance_register', {
|
||||
steps: () => [].concat(
|
||||
registerSteps,
|
||||
)
|
||||
);
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1,18 +1,57 @@
|
|||
odoo.define('test_event_full.tour.register', function (require) {
|
||||
"use strict";
|
||||
|
||||
var tour = require('web_tour.tour');
|
||||
import { registry } from "@web/core/registry";
|
||||
import { session } from "@web/session";
|
||||
|
||||
/**
|
||||
* TALKS STEPS
|
||||
*/
|
||||
const reminderToggleSteps = function (talkName, reminderOn, toggleReminder) {
|
||||
let steps = [];
|
||||
if (reminderOn) {
|
||||
steps = steps.concat([{
|
||||
content: `Check Favorite for ${talkName} was already on`,
|
||||
trigger: "div.o_wetrack_js_reminder i.fa-bell",
|
||||
}]);
|
||||
}
|
||||
else {
|
||||
steps = steps.concat([{
|
||||
content: `Check Favorite for ${talkName} was off`,
|
||||
trigger: "div.o_wetrack_js_reminder i.fa-bell-o",
|
||||
}]);
|
||||
if (toggleReminder) {
|
||||
steps = steps.concat([{
|
||||
content: "Set Favorite",
|
||||
trigger: "i[title='Set Favorite']",
|
||||
run: "click",
|
||||
}]);
|
||||
if (session.is_public){
|
||||
steps = steps.concat([{
|
||||
content: "The form of the email reminder modal is filled",
|
||||
trigger: "#o_wetrack_email_reminder_form input[name='email']",
|
||||
run: "fill visitor@odoo.com",
|
||||
},
|
||||
{
|
||||
content: "The form is submit",
|
||||
trigger: "#o_wetrack_email_reminder_form button[type='submit']",
|
||||
run: "click",
|
||||
}]);
|
||||
}
|
||||
steps = steps.concat([{
|
||||
content: `Check Favorite for ${talkName} is now on`,
|
||||
trigger: "div.o_wetrack_js_reminder i.fa-bell",
|
||||
}]);
|
||||
}
|
||||
}
|
||||
return steps;
|
||||
};
|
||||
|
||||
var discoverTalkSteps = function (talkName, fromList, reminderOn, toggleReminder) {
|
||||
const discoverTalkSteps = function (talkName, fromList, checkToggleReminder, reminderOn, toggleReminder) {
|
||||
var steps;
|
||||
if (fromList) {
|
||||
steps = [{
|
||||
content: 'Go on "' + talkName + '" talk in List',
|
||||
trigger: 'a:contains("' + talkName + '")',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
}];
|
||||
}
|
||||
else {
|
||||
|
|
@ -20,109 +59,98 @@ var discoverTalkSteps = function (talkName, fromList, reminderOn, toggleReminder
|
|||
content: 'Click on Live Track',
|
||||
trigger: 'article span:contains("' + talkName + '")',
|
||||
run: 'click',
|
||||
expectUnloadPage: true,
|
||||
}];
|
||||
}
|
||||
steps = steps.concat([{
|
||||
content: `Check we are on the "${talkName}" talk page`,
|
||||
trigger: 'div.o_wesession_track_main',
|
||||
run: function () {}, // it's a check
|
||||
}]);
|
||||
|
||||
if (reminderOn) {
|
||||
steps = steps.concat([{
|
||||
content: `Check Favorite for ${talkName} was already on`,
|
||||
trigger: 'div.o_wetrack_js_reminder i.fa-bell',
|
||||
extra_trigger: 'span.o_wetrack_js_reminder_text:contains("Favorite On")',
|
||||
run: function () {}, // it's a check
|
||||
}]);
|
||||
}
|
||||
else {
|
||||
steps = steps.concat([{
|
||||
content: `Check Favorite for ${talkName} was off`,
|
||||
trigger: 'span.o_wetrack_js_reminder_text:contains("Set Favorite")',
|
||||
run: function () {}, // it's a check
|
||||
}]);
|
||||
if (toggleReminder) {
|
||||
steps = steps.concat([{
|
||||
content: "Set Favorite",
|
||||
trigger: 'span.o_wetrack_js_reminder_text',
|
||||
run: 'click',
|
||||
}, {
|
||||
content: `Check Favorite for ${talkName} is now on`,
|
||||
trigger: 'div.o_wetrack_js_reminder i.fa-bell',
|
||||
extra_trigger: 'span.o_wetrack_js_reminder_text:contains("Favorite On")',
|
||||
run: function () {}, // it's a check
|
||||
}]);
|
||||
}
|
||||
if (checkToggleReminder){
|
||||
steps = steps.concat(reminderToggleSteps(talkName, reminderOn, toggleReminder));
|
||||
}
|
||||
return steps;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* ROOMS STEPS
|
||||
*/
|
||||
|
||||
var discoverRoomSteps = function (roomName) {
|
||||
var steps = [{
|
||||
content: 'Go on "' + roomName + '" room in List',
|
||||
trigger: 'a.o_wevent_meeting_room_card h4:contains("' + roomName + '")',
|
||||
run: function() {
|
||||
// can't click on it, it will try to launch Jitsi and fail on chrome headless
|
||||
},
|
||||
}];
|
||||
return steps;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* REGISTER STEPS
|
||||
*/
|
||||
|
||||
var registerSteps = [{
|
||||
content: 'Go on Register',
|
||||
trigger: 'a.btn-primary:contains("Register")',
|
||||
}, {
|
||||
content: "Select 2 units of 'Standard' ticket type",
|
||||
trigger: '#o_wevent_tickets_collapse .row:has(.o_wevent_registration_multi_select:contains("Free")) select',
|
||||
run: 'text 2',
|
||||
}, {
|
||||
content: "Click on 'Register' button",
|
||||
trigger: '#o_wevent_tickets .btn-primary:contains("Register"):not(:disabled)',
|
||||
run: 'click',
|
||||
}, {
|
||||
content: "Fill attendees details",
|
||||
trigger: 'form[id="attendee_registration"] .btn:contains("Continue")',
|
||||
run: function () {
|
||||
$("input[name='1-name']").val("Raoulette Poiluchette");
|
||||
$("input[name='1-phone']").val("0456112233");
|
||||
$("input[name='1-email']").val("raoulette@example.com");
|
||||
$("select[name*='question_answer-1']").val($("select[name*='question_answer-1'] option:contains('Consumers')").val());
|
||||
$("input[name='2-name']").val("Michel Tractopelle");
|
||||
$("input[name='2-phone']").val("0456332211");
|
||||
$("input[name='2-email']").val("michel@example.com");
|
||||
$("select[name*='question_answer-2']").val($("select[name*='question_answer-1'] option:contains('Research')").val());
|
||||
$("textarea[name*='question_answer']").text("An unicorn told me about you. I ate it afterwards.");
|
||||
const registerSteps = [
|
||||
{
|
||||
content: "Open ticket modal",
|
||||
trigger: "button.btn-primary:contains(Register):enabled",
|
||||
run: "click",
|
||||
},
|
||||
}, {
|
||||
content: "Validate attendees details",
|
||||
extra_trigger: "input[name='1-name'], input[name='2-name'], input[name='3-name']",
|
||||
trigger: 'button:contains("Continue")',
|
||||
run: 'click',
|
||||
}, {
|
||||
trigger: 'div.o_wereg_confirmed_attendees span:contains("Raoulette Poiluchette")',
|
||||
run: function () {} // check
|
||||
}, {
|
||||
trigger: 'div.o_wereg_confirmed_attendees span:contains("Michel Tractopelle")',
|
||||
run: function () {} // check
|
||||
}, {
|
||||
content: "Click on 'register favorites talks' button",
|
||||
trigger: 'a:contains("register to your favorites talks now")',
|
||||
run: 'click',
|
||||
}, {
|
||||
trigger: 'h1:contains("Book your talks")',
|
||||
run: function() {},
|
||||
}];
|
||||
{
|
||||
content: "Edit 2 units of 'Standard' ticket type",
|
||||
trigger: ".modal .o_wevent_ticket_selector input",
|
||||
run: "edit 2",
|
||||
},
|
||||
{
|
||||
content: "Click on 'Register' button",
|
||||
trigger: ".modal #o_wevent_tickets .btn-primary:contains(Register):enabled",
|
||||
run: "click",
|
||||
},
|
||||
{
|
||||
content: "Wait the modal is shown before continue",
|
||||
trigger: ".modal.modal_shown.show form[id=attendee_registration]",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='1-name']",
|
||||
run: "edit Raoulette Poiluchette",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='1-phone']",
|
||||
run: "edit 0456112233",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='1-email']",
|
||||
run: "edit raoulette@example.com",
|
||||
},
|
||||
{
|
||||
trigger: ".modal select[name*='1-simple_choice']",
|
||||
run: "selectByLabel Consumers",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='2-name']",
|
||||
run: "edit Michel Tractopelle",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='2-phone']",
|
||||
run: "edit 0456332211",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='2-email']",
|
||||
run: "edit michel@example.com",
|
||||
},
|
||||
{
|
||||
trigger: ".modal select[name*='2-simple_choice']",
|
||||
run: "selectByLabel Research",
|
||||
},
|
||||
{
|
||||
trigger: ".modal textarea[name*='text_box']",
|
||||
run: "edit An unicorn told me about you. I ate it afterwards.",
|
||||
},
|
||||
{
|
||||
trigger: ".modal input[name*='1-name'], input[name*='2-name'], input[name*='3-name']",
|
||||
},
|
||||
{
|
||||
content: "Validate attendees details",
|
||||
trigger: ".modal button[type=submit]:enabled",
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
content: "Click on 'register favorites talks' button",
|
||||
trigger: "a:contains(register to your favorites talks now)",
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
},
|
||||
{
|
||||
trigger: "h5:contains(Book your talks)",
|
||||
},
|
||||
];
|
||||
|
||||
/**
|
||||
* MAIN STEPS
|
||||
|
|
@ -132,43 +160,46 @@ var initTourSteps = function (eventName) {
|
|||
return [{
|
||||
content: 'Go on "' + eventName + '" page',
|
||||
trigger: 'a[href*="/event"]:contains("' + eventName + '"):first',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
}];
|
||||
};
|
||||
|
||||
var browseTalksSteps = [{
|
||||
content: 'Browse Talks',
|
||||
trigger: 'a:contains("Talks")',
|
||||
content: 'Browse Talks Menu',
|
||||
trigger: 'a[href*="#"]:contains("Talks")',
|
||||
run: "click",
|
||||
}, {
|
||||
content: 'Browse Talks Submenu',
|
||||
trigger: 'a.dropdown-item span:contains("Talks")',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
}, {
|
||||
content: 'Check we are on the talk list page',
|
||||
trigger: 'h1:contains("Book your talks")',
|
||||
run: function () {} // check
|
||||
trigger: 'h5:contains("Book your talks")',
|
||||
}];
|
||||
|
||||
var browseMeetSteps = [{
|
||||
content: 'Browse Meet',
|
||||
trigger: 'a:contains("Community")',
|
||||
var browseBackSteps = [{
|
||||
content: 'Browse Back',
|
||||
trigger: 'a:contains("All Talks")',
|
||||
run: "click",
|
||||
expectUnloadPage: true,
|
||||
}, {
|
||||
content: 'Check we are on the community page',
|
||||
trigger: 'span:contains("Join a room")',
|
||||
run: function () {} // check
|
||||
content: 'Check we are back on the talk list page',
|
||||
trigger: 'h5:contains("Book your talks")',
|
||||
}];
|
||||
|
||||
|
||||
tour.register('wevent_register', {
|
||||
registry.category("web_tour.tours").add('wevent_register', {
|
||||
url: '/event',
|
||||
test: true
|
||||
}, [].concat(
|
||||
steps: () => [].concat(
|
||||
initTourSteps('Online Reveal'),
|
||||
browseTalksSteps,
|
||||
discoverTalkSteps('What This Event Is All About', true, true),
|
||||
browseTalksSteps,
|
||||
discoverTalkSteps('Live Testimonial', false, false, false),
|
||||
browseTalksSteps,
|
||||
discoverTalkSteps('Our Last Day Together !', true, false, true),
|
||||
browseMeetSteps,
|
||||
discoverRoomSteps('Best wood for furniture'),
|
||||
discoverTalkSteps('What This Event Is All About', true, true, true),
|
||||
browseBackSteps,
|
||||
discoverTalkSteps('Live Testimonial', false, false, false, false),
|
||||
browseBackSteps,
|
||||
discoverTalkSteps('Our Last Day Together!', true, true, false, true),
|
||||
browseBackSteps,
|
||||
registerSteps,
|
||||
)
|
||||
);
|
||||
|
||||
});
|
||||
|
|
|
|||
|
|
@ -7,5 +7,5 @@ from . import test_event_event
|
|||
from . import test_event_mail
|
||||
from . import test_event_security
|
||||
from . import test_performance
|
||||
from . import test_wevent_menu
|
||||
from . import test_wevent_register
|
||||
from . import test_event_discount
|
||||
|
|
|
|||
|
|
@ -3,10 +3,14 @@
|
|||
|
||||
from datetime import datetime, timedelta, time
|
||||
|
||||
from odoo import Command
|
||||
from odoo.addons.base.tests.common import HttpCaseWithUserDemo, HttpCaseWithUserPortal
|
||||
from odoo.addons.base.tests.test_ir_cron import CronMixinCase
|
||||
from odoo.addons.event.tests.common import EventCase
|
||||
from odoo.addons.event_crm.tests.common import EventCrmCase
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user, MailCase
|
||||
from odoo.addons.sales_team.tests.common import TestSalesCommon
|
||||
from odoo.addons.sms.tests.common import SMSCase
|
||||
from odoo.addons.website.tests.test_website_visitor import MockVisitor
|
||||
|
||||
|
||||
|
|
@ -15,7 +19,6 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestEventFullCommon, cls).setUpClass()
|
||||
cls._init_mail_gateway()
|
||||
|
||||
# Context data: dates
|
||||
# ------------------------------------------------------------
|
||||
|
|
@ -37,6 +40,7 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
# set country in order to format Belgian numbers
|
||||
cls.company_admin.write({
|
||||
'country_id': cls.env.ref('base.be').id,
|
||||
'email': 'info@yourcompany.com',
|
||||
})
|
||||
cls.event_user = mail_new_test_user(
|
||||
cls.env,
|
||||
|
|
@ -55,7 +59,6 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
'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
|
||||
|
|
@ -68,14 +71,16 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
|
||||
cls.ticket_product = cls.env['product.product'].create({
|
||||
'description_sale': 'Ticket Product Description',
|
||||
'detailed_type': 'event',
|
||||
'type': 'service',
|
||||
'service_tracking': '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',
|
||||
'type': 'service',
|
||||
'service_tracking': 'event_booth',
|
||||
'list_price': 20,
|
||||
'name': 'Test Booth Product',
|
||||
'standard_price': 60.0,
|
||||
|
|
@ -120,9 +125,8 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
# ------------------------------------------------------------
|
||||
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})
|
||||
subscription_template.write({'report_template_ids': [(6, 0, test_registration_report.ids)]})
|
||||
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,
|
||||
|
|
@ -145,21 +149,18 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
'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'),
|
||||
}
|
||||
),
|
||||
|
|
@ -228,15 +229,15 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
'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,
|
||||
})
|
||||
with cls.mock_datetime_and_now(cls, cls.reference_now):
|
||||
cls.test_event = cls.env['event.event'].create({
|
||||
'name': 'Test Event',
|
||||
'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')
|
||||
|
|
@ -251,39 +252,36 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
], limit=1)
|
||||
|
||||
cls.customer_data = [
|
||||
{'email': 'customer.email.%02d@test.example.com' % x,
|
||||
'name': 'My Customer %02d' % x,
|
||||
'mobile': '04569999%02d' % x,
|
||||
{'email': f'customer.email.{idx:02d}@test.example.com',
|
||||
'name': f'My Customer {idx:02d}',
|
||||
'partner_id': False,
|
||||
'phone': '04560000%02d' % x,
|
||||
} for x in range(0, 10)
|
||||
'phone': f'04560000{idx:02d}',
|
||||
} for idx 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,
|
||||
{'email': f'website.email.{idx:02d}@test.example.com',
|
||||
'name': f'My Customer {idx:02d}',
|
||||
'partner_id': cls.env.ref('base.public_partner').id,
|
||||
'phone': '04560000%02d' % x,
|
||||
'phone': f'04560000{idx:02d}',
|
||||
'registration_answer_ids': [
|
||||
(0, 0, {
|
||||
'question_id': cls.test_event.question_ids[0].id,
|
||||
'value_answer_id': cls.test_event.question_ids[0].answer_ids[(x % 2)].id,
|
||||
'value_answer_id': cls.test_event.question_ids[0].answer_ids[(idx % 2)].id,
|
||||
}), (0, 0, {
|
||||
'question_id': cls.test_event.question_ids[1].id,
|
||||
'value_answer_id': cls.test_event.question_ids[1].answer_ids[(x % 2)].id,
|
||||
'value_answer_id': cls.test_event.question_ids[1].answer_ids[(idx % 2)].id,
|
||||
}), (0, 0, {
|
||||
'question_id': cls.test_event.question_ids[2].id,
|
||||
'value_text_box': 'CustomerAnswer%s' % x,
|
||||
'value_text_box': f'CustomerAnswer{idx}',
|
||||
})
|
||||
],
|
||||
} for x in range(0, 10)
|
||||
} for idx 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)
|
||||
{'email': f'partner.email.{idx:02d}@test.example.com',
|
||||
'name': f'PartnerCustomer {idx:02d}',
|
||||
'phone': f'04560000{idx:02d}',
|
||||
} for idx in range(0, 10)
|
||||
])
|
||||
|
||||
def assertLeadConvertion(self, rule, registrations, partner=None, **expected):
|
||||
|
|
@ -304,6 +302,98 @@ class TestEventFullCommon(EventCrmCase, TestSalesCommon, MockVisitor):
|
|||
self.assertIn(answer.value_text_box, lead.description) # better: check multi line
|
||||
|
||||
|
||||
class TestEventMailCommon(EventCase, SMSCase, MailCase, CronMixinCase):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.event_cron_id = cls.env.ref('event.event_mail_scheduler')
|
||||
# deactivate other schedulers to avoid messing with crons
|
||||
cls.env['event.mail'].search([]).unlink()
|
||||
# consider asynchronous sending as default sending
|
||||
cls.env["ir.config_parameter"].set_param("event.event_mail_async", False)
|
||||
|
||||
cls.env.company.write({
|
||||
'email': 'info@yourcompany.example.com',
|
||||
'name': 'YourCompany',
|
||||
})
|
||||
|
||||
# prepare SMS templates
|
||||
cls.sms_template_sub = cls.env['sms.template'].create({
|
||||
'name': 'Test SMS Subscription',
|
||||
'model_id': cls.env.ref('event.model_event_registration').id,
|
||||
'body': '{{ object.event_id.organizer_id.name }} registration confirmation.',
|
||||
'lang': '{{ object.partner_id.lang }}'
|
||||
})
|
||||
cls.sms_template_rem = cls.env['sms.template'].create({
|
||||
'name': 'Test SMS Reminder',
|
||||
'model_id': cls.env.ref('event.model_event_registration').id,
|
||||
'body': '{{ object.event_id.organizer_id.name }} reminder',
|
||||
'lang': '{{ object.partner_id.lang }}'
|
||||
})
|
||||
|
||||
# freeze some datetimes, and ensure more than 1D+1H before event starts
|
||||
# to ease time-based scheduler check
|
||||
# Since `now` is used to set the `create_date` of an event and create_date
|
||||
# has often microseconds, we set it to ensure that the scheduler we still be
|
||||
# launched if scheduled_date == create_date - microseconds
|
||||
cls.reference_now = datetime(2021, 3, 20, 14, 30, 15, 123456)
|
||||
cls.event_date_begin = datetime(2021, 3, 25, 8, 0, 0)
|
||||
cls.event_date_end = datetime(2021, 3, 28, 18, 0, 0)
|
||||
|
||||
cls._setup_test_reports()
|
||||
with cls.mock_datetime_and_now(cls, cls.reference_now):
|
||||
cls.test_event = cls.env['event.event'].create({
|
||||
'name': 'TestEventMail',
|
||||
'user_id': cls.user_eventmanager.id,
|
||||
'date_begin': cls.event_date_begin,
|
||||
'date_end': cls.event_date_end,
|
||||
'event_mail_ids': [
|
||||
(0, 0, { # right at subscription: mail
|
||||
'interval_unit': 'now',
|
||||
'interval_type': 'after_sub',
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_subscription.id}',
|
||||
}),
|
||||
(0, 0, { # right at subscription: sms
|
||||
'interval_unit': 'now',
|
||||
'interval_type': 'after_sub',
|
||||
'notification_type': 'sms',
|
||||
'template_ref': f'sms.template,{cls.sms_template_sub.id}',
|
||||
}),
|
||||
(0, 0, { # 3 days before event: mail
|
||||
'interval_nbr': 3,
|
||||
'interval_unit': 'days',
|
||||
'interval_type': 'before_event',
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_reminder.id}',
|
||||
}),
|
||||
(0, 0, { # 3 days before event: SMS
|
||||
'interval_nbr': 3,
|
||||
'interval_unit': 'days',
|
||||
'interval_type': 'before_event',
|
||||
'notification_type': 'sms',
|
||||
'template_ref': f'sms.template,{cls.sms_template_rem.id}',
|
||||
}),
|
||||
(0, 0, { # 1h after event: mail
|
||||
'interval_nbr': 1,
|
||||
'interval_unit': 'hours',
|
||||
'interval_type': 'after_event',
|
||||
'notification_type': 'mail',
|
||||
'template_ref': f'mail.template,{cls.template_reminder.id}',
|
||||
}),
|
||||
(0, 0, { # 1h after event: SMS
|
||||
'interval_nbr': 1,
|
||||
'interval_unit': 'hours',
|
||||
'interval_type': 'after_event',
|
||||
'notification_type': 'sms',
|
||||
'template_ref': f'sms.template,{cls.sms_template_rem.id}',
|
||||
}),
|
||||
],
|
||||
})
|
||||
|
||||
|
||||
class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor):
|
||||
|
||||
def setUp(self):
|
||||
|
|
@ -322,7 +412,8 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
'description_sale': 'Mighty Description',
|
||||
'list_price': 10,
|
||||
'standard_price': 30.0,
|
||||
'detailed_type': 'event',
|
||||
'type': 'service',
|
||||
'service_tracking': 'event',
|
||||
})
|
||||
|
||||
self.event_tag_category_1 = self.env['event.tag.category'].create({
|
||||
|
|
@ -336,13 +427,12 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
'color': 8,
|
||||
})
|
||||
self.env['event.event'].search(
|
||||
[('name', 'like', '%Online Reveal%')]
|
||||
[('name', 'like', 'Online Reveal')]
|
||||
).write(
|
||||
{'name': 'Do not click on me'}
|
||||
)
|
||||
self.event = self.env['event.event'].create({
|
||||
'name': 'Online Reveal TestEvent',
|
||||
'auto_confirm': True,
|
||||
'stage_id': self.env.ref('event.event_stage_booked').id,
|
||||
'address_id': False,
|
||||
'user_id': self.user_demo.id,
|
||||
|
|
@ -377,7 +467,6 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
'email': 'constantin@test.example.com',
|
||||
'country_id': self.env.ref('base.be').id,
|
||||
'phone': '0485112233',
|
||||
'mobile': False,
|
||||
})
|
||||
self.event_speaker = self.env['res.partner'].create({
|
||||
'name': 'Brandon Freeman',
|
||||
|
|
@ -392,7 +481,7 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
self.event_question_1 = self.env['event.question'].create({
|
||||
'title': 'Which field are you working in',
|
||||
'question_type': 'simple_choice',
|
||||
'event_id': self.event.id,
|
||||
'event_ids': [Command.set(self.event.ids)],
|
||||
'once_per_order': False,
|
||||
'answer_ids': [
|
||||
(0, 0, {'name': 'Consumers'}),
|
||||
|
|
@ -403,7 +492,7 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
self.event_question_2 = self.env['event.question'].create({
|
||||
'title': 'How did you hear about us ?',
|
||||
'question_type': 'text_box',
|
||||
'event_id': self.event.id,
|
||||
'event_ids': [Command.set(self.event.ids)],
|
||||
'once_per_order': True,
|
||||
})
|
||||
|
||||
|
|
@ -421,6 +510,7 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
'wishlisted_by_default': True,
|
||||
'user_id': self.user_admin.id,
|
||||
'partner_id': self.event_speaker.id,
|
||||
'description': 'Performance of Raoul Grosbedon.'
|
||||
})
|
||||
self.track_1 = self.env['event.track'].create({
|
||||
'name': 'Live Testimonial',
|
||||
|
|
@ -431,9 +521,10 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
'is_published': True,
|
||||
'user_id': self.user_admin.id,
|
||||
'partner_id': self.event_speaker.id,
|
||||
'description': 'Description of the live.'
|
||||
})
|
||||
self.track_2 = self.env['event.track'].create({
|
||||
'name': 'Our Last Day Together !',
|
||||
'name': 'Our Last Day Together!',
|
||||
'event_id': self.event.id,
|
||||
'stage_id': self.env.ref('website_event_track.event_track_stage3').id,
|
||||
'date': self.reference_now + timedelta(days=1),
|
||||
|
|
@ -441,22 +532,7 @@ class TestWEventCommon(HttpCaseWithUserDemo, HttpCaseWithUserPortal, MockVisitor
|
|||
'is_published': True,
|
||||
'user_id': self.user_admin.id,
|
||||
'partner_id': self.event_speaker.id,
|
||||
})
|
||||
|
||||
# ------------------------------------------------------------
|
||||
# MEETING ROOMS
|
||||
# ----------------------------------------------------------
|
||||
|
||||
self.env['event.meeting.room'].create({
|
||||
'name': 'Best wood for furniture',
|
||||
'summary': 'Let\'s talk about wood types for furniture',
|
||||
'target_audience': 'wood expert(s)',
|
||||
'is_pinned': True,
|
||||
'website_published': True,
|
||||
'event_id': self.event.id,
|
||||
'room_lang_id': self.env.ref('base.lang_en').id,
|
||||
'room_max_capacity': '12',
|
||||
'room_participant_count': 9,
|
||||
'description': 'Description of our last day together.'
|
||||
})
|
||||
|
||||
self.env.flush_all()
|
||||
|
|
|
|||
|
|
@ -2,9 +2,10 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from odoo.addons.test_event_full.tests.common import TestEventFullCommon
|
||||
from odoo.tests import users
|
||||
from odoo.tests import tagged, users
|
||||
|
||||
|
||||
@tagged("event_crm")
|
||||
class TestEventCrm(TestEventFullCommon):
|
||||
|
||||
@classmethod
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
import time
|
||||
|
||||
from odoo.tests import tagged
|
||||
from odoo.fields import Command
|
||||
|
||||
from odoo.addons.test_event_full.tests.common import TestEventFullCommon
|
||||
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestEventTicketPriceRounding(TestEventFullCommon):
|
||||
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super().setUpClass()
|
||||
|
||||
cls.ticket_product.write({
|
||||
'lst_price': 1.0
|
||||
})
|
||||
|
||||
cls.currency_jpy = cls.env['res.currency'].create({
|
||||
'name': 'JPX',
|
||||
'symbol': '¥',
|
||||
'rounding': 1.0,
|
||||
'rate_ids': [Command.create({'rate': 133.6200, 'name': time.strftime('%Y-%m-%d')})],
|
||||
})
|
||||
|
||||
cls.currency_cad = cls.env['res.currency'].create({
|
||||
'name': 'CXD',
|
||||
'symbol': '$',
|
||||
'rounding': 0.01,
|
||||
'rate_ids': [Command.create({'rate': 1.338800, 'name': time.strftime('%Y-%m-%d')})],
|
||||
})
|
||||
|
||||
cls.pricelist_usd = cls.env['product.pricelist'].create({
|
||||
'name': 'Pricelist USD',
|
||||
'currency_id': cls.env.ref('base.USD').id,
|
||||
})
|
||||
|
||||
cls.pricelist_jpy = cls.env['product.pricelist'].create({
|
||||
'name': 'Pricelist JPY',
|
||||
'currency_id': cls.currency_jpy.id,
|
||||
})
|
||||
|
||||
cls.pricelist_cad = cls.env['product.pricelist'].create({
|
||||
'name': 'Pricelist CAD',
|
||||
'currency_id': cls.currency_cad.id,
|
||||
})
|
||||
|
||||
cls.event_type = cls.env['event.type'].create({
|
||||
'name': 'Test Event Type',
|
||||
'auto_confirm': True,
|
||||
'event_type_ticket_ids': [
|
||||
(0, 0, {
|
||||
'name': 'Test Event Ticket',
|
||||
'product_id': cls.ticket_product.id,
|
||||
'price': 30.0,
|
||||
})
|
||||
],
|
||||
})
|
||||
|
||||
cls.event_ticket = cls.event_type.event_type_ticket_ids[0]
|
||||
|
||||
def test_no_discount_usd(self):
|
||||
ticket = self.event_ticket.with_context(pricelist=self.pricelist_usd.id)
|
||||
ticket._compute_price_reduce()
|
||||
self.assertAlmostEqual(ticket.price_reduce, 30.0, places=6, msg="No discount should be applied for the USD pricelist.")
|
||||
|
||||
def test_no_discount_jpy(self):
|
||||
ticket = self.event_ticket.with_context(pricelist=self.pricelist_jpy.id)
|
||||
ticket._compute_price_reduce()
|
||||
self.assertAlmostEqual(ticket.price_reduce, 30.0, places=6, msg="No discount should be applied for the JPY pricelist.")
|
||||
|
||||
def test_no_discount_cad(self):
|
||||
ticket = self.event_ticket.with_context(pricelist=self.pricelist_cad.id)
|
||||
ticket._compute_price_reduce()
|
||||
self.assertAlmostEqual(ticket.price_reduce, 30.0, places=6, msg="No discount should be applied for the CAD pricelist.")
|
||||
|
|
@ -36,16 +36,13 @@ class TestEventEvent(TestEventFullCommon):
|
|||
|
||||
# check result
|
||||
self.assertEqual(event.address_id, self.env.user.company_id.partner_id)
|
||||
self.assertTrue(event.auto_confirm)
|
||||
self.assertEqual(event.country_id, self.env.user.company_id.country_id)
|
||||
self.assertEqual(event.date_tz, 'Europe/Paris')
|
||||
self.assertEqual(event.event_booth_count, 4)
|
||||
self.assertEqual(len(event.event_mail_ids), 3)
|
||||
self.assertEqual(len(event.event_ticket_ids), 2)
|
||||
self.assertTrue(event.introduction_menu)
|
||||
self.assertTrue(event.location_menu)
|
||||
self.assertTrue(event.menu_register_cta)
|
||||
self.assertEqual(event.message_partner_ids, self.env.user.partner_id + self.env.user.company_id.partner_id)
|
||||
self.assertEqual(event.message_partner_ids, self.env.user.partner_id)
|
||||
self.assertEqual(event.note, '<p>Template note</p>')
|
||||
self.assertTrue(event.register_menu)
|
||||
self.assertEqual(len(event.question_ids), 3)
|
||||
|
|
@ -75,12 +72,23 @@ class TestEventEvent(TestEventFullCommon):
|
|||
self.assertTrue(event.is_ongoing)
|
||||
self.assertTrue(event.event_registrations_started)
|
||||
|
||||
def test_event_kanban_state_on_stage_change(self):
|
||||
"""Test that kanban_state updates correctly when stage is changed."""
|
||||
test_event_1 = self.env['event.event'].browse(self.test_event.ids)
|
||||
test_event_2 = test_event_1.copy()
|
||||
|
||||
test_event_1.kanban_state = 'done'
|
||||
test_event_2.kanban_state = 'cancel' # Event Cancelled
|
||||
|
||||
new_stage = self.env['event.stage'].create({'name': 'New Stage', 'sequence': 1})
|
||||
(test_event_1 | test_event_2).stage_id = new_stage.id # Change event stage
|
||||
|
||||
self.assertEqual(test_event_1.kanban_state, 'normal', 'kanban state should reset to "normal" on stage change')
|
||||
self.assertEqual(test_event_2.kanban_state, 'cancel', 'kanban state should not reset on stage change')
|
||||
|
||||
@freeze_time('2021-12-01 11:00:00')
|
||||
@users('event_user')
|
||||
def test_event_seats_and_schedulers(self):
|
||||
now = datetime.now() # used to force create_date, as sql is not wrapped by freeze gun
|
||||
self.env.cr._now = now
|
||||
|
||||
test_event = self.env['event.event'].browse(self.test_event.ids)
|
||||
ticket_1 = test_event.event_ticket_ids.filtered(lambda ticket: ticket.name == 'Ticket1')
|
||||
ticket_2 = test_event.event_ticket_ids.filtered(lambda ticket: ticket.name == 'Ticket2')
|
||||
|
|
@ -94,14 +102,15 @@ class TestEventEvent(TestEventFullCommon):
|
|||
self.assertFalse(ticket_2.sale_available)
|
||||
|
||||
# make 9 registrations (let 1 on ticket)
|
||||
with self.mock_mail_gateway():
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
self.mock_mail_gateway():
|
||||
self.env['event.registration'].create([
|
||||
{'create_date': now,
|
||||
'email': 'test.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_1.id,
|
||||
'name': 'Customer %d' % x,
|
||||
{
|
||||
'email': 'test.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_1.id,
|
||||
'name': 'Customer %d' % x,
|
||||
}
|
||||
for x in range(0, 9)
|
||||
])
|
||||
|
|
@ -114,27 +123,29 @@ class TestEventEvent(TestEventFullCommon):
|
|||
self.assertEqual(ticket_2.seats_available, 0)
|
||||
|
||||
# prevent registration due to ticket limit
|
||||
with self.assertRaises(exceptions.ValidationError):
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
self.assertRaises(exceptions.ValidationError):
|
||||
self.env['event.registration'].create([
|
||||
{'create_date': now,
|
||||
'email': 'additional.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_1.id,
|
||||
'name': 'Additional Customer %d' % x,
|
||||
{
|
||||
'email': 'additional.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_1.id,
|
||||
'name': 'Additional Customer %d' % x,
|
||||
}
|
||||
for x in range(0, 2)
|
||||
])
|
||||
|
||||
# make 20 registrations (on free ticket)
|
||||
with self.mock_mail_gateway():
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
self.mock_mail_gateway():
|
||||
self.env['event.registration'].create([
|
||||
{'create_date': now,
|
||||
'email': 'other.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_2.id,
|
||||
'name': 'Other Customer %d' % x,
|
||||
{
|
||||
'email': 'other.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_2.id,
|
||||
'name': 'Other Customer %d' % x,
|
||||
}
|
||||
for x in range(0, 20)
|
||||
])
|
||||
|
|
@ -145,14 +156,15 @@ class TestEventEvent(TestEventFullCommon):
|
|||
self.assertEqual(ticket_2.seats_available, 0)
|
||||
|
||||
# prevent registration due to event limit
|
||||
with self.assertRaises(exceptions.ValidationError):
|
||||
with self.mock_datetime_and_now(self.reference_now), \
|
||||
self.assertRaises(exceptions.ValidationError):
|
||||
self.env['event.registration'].create([
|
||||
{'create_date': now,
|
||||
'email': 'additional.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_2.id,
|
||||
'name': 'Additional Customer %d' % x,
|
||||
{
|
||||
'email': 'additional.customer.%02d@test.example.com' % x,
|
||||
'phone': '04560011%02d' % x,
|
||||
'event_id': test_event.id,
|
||||
'event_ticket_id': ticket_2.id,
|
||||
'name': 'Additional Customer %d' % x,
|
||||
}
|
||||
for x in range(0, 2)
|
||||
])
|
||||
|
|
|
|||
|
|
@ -2,15 +2,15 @@
|
|||
# Part of Odoo. See LICENSE file for full copyright and licensing details.
|
||||
|
||||
from datetime import datetime, timedelta
|
||||
from freezegun import freeze_time
|
||||
from unittest.mock import patch
|
||||
|
||||
from odoo.addons.mail.tests.common import MockEmail
|
||||
from odoo.addons.sms.tests.common import MockSMS
|
||||
from odoo.addons.test_event_full.tests.common import TestWEventCommon
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.tools import mute_logger
|
||||
from odoo.addons.test_event_full.tests.common import TestEventFullCommon, TestEventMailCommon
|
||||
from odoo.tests import tagged, users
|
||||
from odoo.tools import formataddr
|
||||
|
||||
class TestTemplateRefModel(TestWEventCommon):
|
||||
|
||||
@tagged('event_mail', 'post_install', '-at_install')
|
||||
class TestEventMailInternals(TestEventMailCommon):
|
||||
|
||||
def test_template_ref_delete_lines(self):
|
||||
""" When deleting a template, related lines should be deleted too """
|
||||
|
|
@ -51,117 +51,303 @@ class TestTemplateRefModel(TestWEventCommon):
|
|||
self.assertEqual(len(event_type.event_type_mail_ids.exists()), 0)
|
||||
self.assertEqual(len(event.event_mail_ids.exists()), 0)
|
||||
|
||||
def test_template_ref_model_constraint(self):
|
||||
|
||||
test_cases = [
|
||||
('mail', 'mail.template', True),
|
||||
('mail', 'sms.template', False),
|
||||
('sms', 'sms.template', True),
|
||||
('sms', 'mail.template', False),
|
||||
]
|
||||
@tagged('event_mail', 'post_install', '-at_install')
|
||||
class TestEventMailSchedule(TestEventMailCommon):
|
||||
|
||||
for notification_type, template_type, valid in test_cases:
|
||||
with self.subTest(notification_type=notification_type, template_type=template_type):
|
||||
if template_type == 'mail.template':
|
||||
template = self.env[template_type].create({
|
||||
'name': 'test template',
|
||||
'model_id': self.env['ir.model']._get_id('event.registration'),
|
||||
})
|
||||
else:
|
||||
template = self.env[template_type].create({
|
||||
'name': 'test template',
|
||||
'body': 'Body Test',
|
||||
'model_id': self.env['ir.model']._get_id('event.registration'),
|
||||
})
|
||||
if not valid:
|
||||
with self.assertRaises(ValidationError) as cm:
|
||||
self.env['event.mail'].create({
|
||||
'event_id': self.event.id,
|
||||
'notification_type': notification_type,
|
||||
'interval_unit': 'now',
|
||||
'interval_type': 'before_event',
|
||||
'template_ref': template,
|
||||
})
|
||||
if notification_type == 'mail':
|
||||
self.assertEqual(str(cm.exception), 'The template which is referenced should be coming from mail.template model.')
|
||||
else:
|
||||
self.assertEqual(str(cm.exception), 'The template which is referenced should be coming from sms.template model.')
|
||||
|
||||
class TestEventSmsMailSchedule(TestWEventCommon, MockEmail, MockSMS):
|
||||
|
||||
@freeze_time('2020-07-06 12:00:00')
|
||||
@mute_logger('odoo.addons.base.models.ir_model', 'odoo.models')
|
||||
def test_event_mail_before_trigger_sent_count(self):
|
||||
""" Emails are sent to both confirmed and unconfirmed attendees.
|
||||
This test checks that the count of sent emails includes the emails sent to unconfirmed ones
|
||||
|
||||
Time in the test is frozen to simulate the following state:
|
||||
|
||||
NOW Event Start Event End
|
||||
12:00 13:00 14:00
|
||||
| | |
|
||||
──────────────────────────────────────►
|
||||
| | time
|
||||
◄─────────────────►
|
||||
3 hours
|
||||
Trigger before event
|
||||
"""
|
||||
self.sms_template_rem = self.env['sms.template'].create({
|
||||
'name': 'Test reminder',
|
||||
'model_id': self.env.ref('event.model_event_registration').id,
|
||||
'body': '{{ object.event_id.organizer_id.name }} reminder',
|
||||
'lang': '{{ object.partner_id.lang }}'
|
||||
})
|
||||
test_event = self.env['event.event'].create({
|
||||
'name': 'TestEventMail',
|
||||
# 'user_id': self.env.ref('base.user_admin').id,
|
||||
'auto_confirm': False,
|
||||
'date_begin': datetime.now() + timedelta(hours=1),
|
||||
'date_end': datetime.now() + timedelta(hours=2),
|
||||
'event_mail_ids': [
|
||||
(0, 0, { # email 3 hours before event
|
||||
'interval_nbr': 3,
|
||||
'interval_unit': 'hours',
|
||||
'interval_type': 'before_event',
|
||||
'template_ref': 'mail.template,%i' % self.env['ir.model.data']._xmlid_to_res_id('event.event_reminder')}),
|
||||
(0, 0, { # sms 3 hours before event
|
||||
'interval_nbr': 3,
|
||||
'interval_unit': 'hours',
|
||||
'interval_type': 'before_event',
|
||||
'notification_type': 'sms',
|
||||
'template_ref': 'sms.template,%i' % self.sms_template_rem.id}),
|
||||
]
|
||||
})
|
||||
mail_scheduler = test_event.event_mail_ids
|
||||
self.assertEqual(len(mail_scheduler), 2, 'There should be two mail schedulers. One for mail one for sms. Cannot perform test')
|
||||
""" Emails are only sent to confirmed attendees. """
|
||||
test_event = self.test_event
|
||||
mail_schedulers = test_event.event_mail_ids
|
||||
self.assertEqual(len(mail_schedulers), 6)
|
||||
before = mail_schedulers.filtered(lambda m: m.interval_type == "before_event" and m.interval_unit == "days")
|
||||
self.assertEqual(len(before), 2)
|
||||
|
||||
# Add registrations
|
||||
self.env['event.registration'].create([{
|
||||
_dummy, _dummy, open_reg, done_reg = self.env['event.registration'].create([{
|
||||
'event_id': test_event.id,
|
||||
'name': 'RegistrationUnconfirmed',
|
||||
'email': 'Registration@Unconfirmed.com',
|
||||
'phone': '1',
|
||||
'state': 'draft',
|
||||
}, {
|
||||
'event_id': test_event.id,
|
||||
'name': 'RegistrationCanceled',
|
||||
'email': 'Registration@Canceled.com',
|
||||
'phone': '2',
|
||||
'state': 'cancel',
|
||||
}, {
|
||||
'event_id': test_event.id,
|
||||
'name': 'RegistrationConfirmed',
|
||||
'email': 'Registration@Confirmed.com',
|
||||
'phone': '3',
|
||||
'state': 'open',
|
||||
}, {
|
||||
'event_id': test_event.id,
|
||||
'name': 'RegistrationDone',
|
||||
'email': 'Registration@Done.com',
|
||||
'phone': '4',
|
||||
'state': 'done',
|
||||
}])
|
||||
|
||||
with self.mock_mail_gateway(), self.mockSMSGateway():
|
||||
mail_scheduler.execute()
|
||||
with self.mock_datetime_and_now(self.event_date_begin - timedelta(days=2)), \
|
||||
self.mock_mail_gateway(), \
|
||||
self.mockSMSGateway():
|
||||
before.execute()
|
||||
|
||||
self.assertEqual(len(self._new_mails), 2, 'Mails were not created')
|
||||
self.assertEqual(len(self._new_sms), 2, 'SMS were not created')
|
||||
for registration in open_reg, done_reg:
|
||||
with self.subTest(registration_state=registration.state, medium='mail'):
|
||||
self.assertMailMailWEmails(
|
||||
[formataddr((registration.name, registration.email.lower()))],
|
||||
'outgoing',
|
||||
)
|
||||
with self.subTest(registration_state=registration.state, medium='sms'):
|
||||
self.assertSMS(
|
||||
self.env['res.partner'],
|
||||
registration.phone,
|
||||
None,
|
||||
)
|
||||
self.assertEqual(len(self._new_mails), 2, 'Mails should not be sent to draft or cancel registrations')
|
||||
self.assertEqual(len(self._new_sms), 2, 'SMS should not be sent to draft or cancel registrations')
|
||||
|
||||
self.assertEqual(test_event.seats_expected, 2, 'Wrong number of expected seats (attendees)')
|
||||
self.assertEqual(test_event.seats_taken, 2, 'Wrong number of seats_taken')
|
||||
|
||||
self.assertEqual(mail_scheduler.filtered(lambda r: r.notification_type == 'mail').mail_count_done, 2,
|
||||
'Wrong Emails Sent Count! Probably emails sent to unconfirmed attendees were not included into the Sent Count')
|
||||
self.assertEqual(mail_scheduler.filtered(lambda r: r.notification_type == 'sms').mail_count_done, 2,
|
||||
'Wrong SMS Sent Count! Probably SMS sent to unconfirmed attendees were not included into the Sent Count')
|
||||
for scheduler in before:
|
||||
self.assertEqual(
|
||||
scheduler.mail_count_done, 2,
|
||||
'Wrong Emails Sent Count! Probably emails sent to unconfirmed attendees were not included into the Sent Count'
|
||||
)
|
||||
|
||||
@users('user_eventmanager')
|
||||
def test_schedule_event_scalability(self):
|
||||
""" Test scalability / iterative work on event-based schedulers """
|
||||
test_event = self.env['event.event'].browse(self.test_event.ids)
|
||||
registrations = self._create_registrations(test_event, 30)
|
||||
registrations = registrations.sorted("id")
|
||||
|
||||
# check event-based schedulers
|
||||
after_mail = test_event.event_mail_ids.filtered(lambda s: s.interval_type == "after_event" and s.notification_type == "mail")
|
||||
self.assertEqual(len(after_mail), 1)
|
||||
self.assertEqual(after_mail.mail_count_done, 0)
|
||||
self.assertFalse(after_mail.mail_done)
|
||||
after_sms = test_event.event_mail_ids.filtered(lambda s: s.interval_type == "after_event" and s.notification_type == "sms")
|
||||
self.assertEqual(len(after_sms), 1)
|
||||
self.assertEqual(after_sms.mail_count_done, 0)
|
||||
self.assertFalse(after_sms.mail_done)
|
||||
before_mail = test_event.event_mail_ids.filtered(lambda s: s.interval_type == "before_event" and s.notification_type == "mail")
|
||||
self.assertEqual(len(before_mail), 1)
|
||||
self.assertEqual(before_mail.mail_count_done, 0)
|
||||
self.assertFalse(before_mail.mail_done)
|
||||
before_sms = test_event.event_mail_ids.filtered(lambda s: s.interval_type == "before_event" and s.notification_type == "sms")
|
||||
self.assertEqual(len(before_sms), 1)
|
||||
self.assertEqual(before_sms.mail_count_done, 0)
|
||||
self.assertFalse(before_sms.mail_done)
|
||||
|
||||
# setup batch and cron limit sizes to check iterative behavior
|
||||
batch_size, cron_limit = 5, 20
|
||||
self.env["ir.config_parameter"].sudo().set_param("mail.batch_size", batch_size)
|
||||
self.env["ir.config_parameter"].sudo().set_param("mail.render.cron.limit", cron_limit)
|
||||
|
||||
# launch before event schedulers -> all communications are sent
|
||||
current_now = self.event_date_begin - timedelta(days=1)
|
||||
EventMail = type(self.env['event.mail'])
|
||||
exec_origin = EventMail._execute_event_based_for_registrations
|
||||
with (
|
||||
patch.object(
|
||||
EventMail, '_execute_event_based_for_registrations', autospec=True, wraps=EventMail, side_effect=exec_origin,
|
||||
) as mock_exec,
|
||||
self.mock_datetime_and_now(current_now),
|
||||
self.mockSMSGateway(),
|
||||
self.mock_mail_gateway(),
|
||||
self.capture_triggers('event.event_mail_scheduler') as capture,
|
||||
):
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
|
||||
self.assertFalse(after_mail.last_registration_id)
|
||||
self.assertEqual(after_mail.mail_count_done, 0)
|
||||
self.assertFalse(after_mail.mail_done)
|
||||
self.assertFalse(after_sms.last_registration_id)
|
||||
self.assertEqual(after_sms.mail_count_done, 0)
|
||||
self.assertFalse(after_sms.mail_done)
|
||||
# iterative work on registrations: only 20 (cron limit) are taken into account
|
||||
self.assertEqual(before_mail.last_registration_id, registrations[19])
|
||||
self.assertEqual(before_mail.mail_count_done, 20)
|
||||
self.assertFalse(before_mail.mail_done)
|
||||
self.assertEqual(before_sms.last_registration_id, registrations[19])
|
||||
self.assertEqual(before_sms.mail_count_done, 20)
|
||||
self.assertFalse(before_sms.mail_done)
|
||||
self.assertEqual(mock_exec.call_count, 8, "Batch of 5 to make 20 registrations: 4 calls / scheduler")
|
||||
# cron should have been triggered for the remaining registrations
|
||||
self.assertSchedulerCronTriggers(capture, [current_now] * 2)
|
||||
|
||||
# relaunch to close scheduler
|
||||
with (
|
||||
self.mock_datetime_and_now(current_now),
|
||||
self.mockSMSGateway(),
|
||||
self.mock_mail_gateway(),
|
||||
self.capture_triggers('event.event_mail_scheduler') as capture,
|
||||
):
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
self.assertEqual(before_mail.last_registration_id, registrations[-1])
|
||||
self.assertEqual(before_mail.mail_count_done, 30)
|
||||
self.assertTrue(before_mail.mail_done)
|
||||
self.assertEqual(before_sms.last_registration_id, registrations[-1])
|
||||
self.assertEqual(before_sms.mail_count_done, 30)
|
||||
self.assertTrue(before_sms.mail_done)
|
||||
self.assertFalse(capture.records)
|
||||
|
||||
# launch after event schedulers -> all communications are sent
|
||||
current_now = self.event_date_end + timedelta(hours=1)
|
||||
with (
|
||||
self.mock_datetime_and_now(current_now),
|
||||
self.mockSMSGateway(),
|
||||
self.mock_mail_gateway(),
|
||||
self.capture_triggers('event.event_mail_scheduler') as capture,
|
||||
):
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
|
||||
# iterative work on registrations: only 20 (cron limit) are taken into account
|
||||
self.assertEqual(after_mail.last_registration_id, registrations[19])
|
||||
self.assertEqual(after_mail.mail_count_done, 20)
|
||||
self.assertFalse(after_mail.mail_done)
|
||||
self.assertEqual(after_sms.last_registration_id, registrations[19])
|
||||
self.assertEqual(after_sms.mail_count_done, 20)
|
||||
self.assertFalse(after_sms.mail_done)
|
||||
self.assertEqual(mock_exec.call_count, 8, "Batch of 5 to make 20 registrations: 4 calls / scheduler")
|
||||
# cron should have been triggered for the remaining registrations
|
||||
self.assertSchedulerCronTriggers(capture, [current_now] * 2)
|
||||
|
||||
# relaunch to close scheduler
|
||||
with (
|
||||
self.mock_datetime_and_now(current_now),
|
||||
self.mockSMSGateway(),
|
||||
self.mock_mail_gateway(),
|
||||
self.capture_triggers('event.event_mail_scheduler') as capture,
|
||||
):
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
self.assertEqual(after_mail.last_registration_id, registrations[-1])
|
||||
self.assertEqual(after_mail.mail_count_done, 30)
|
||||
self.assertTrue(after_mail.mail_done)
|
||||
self.assertEqual(after_sms.last_registration_id, registrations[-1])
|
||||
self.assertEqual(after_sms.mail_count_done, 30)
|
||||
self.assertTrue(after_sms.mail_done)
|
||||
self.assertFalse(capture.records)
|
||||
|
||||
@users('user_eventmanager')
|
||||
def test_schedule_subscription_scalability(self):
|
||||
""" Test scalability / iterative work on subscription-based schedulers """
|
||||
test_event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
sub_mail = test_event.event_mail_ids.filtered(lambda s: s.interval_type == "after_sub" and s.interval_unit == "now" and s.notification_type == "mail")
|
||||
self.assertEqual(len(sub_mail), 1)
|
||||
self.assertEqual(sub_mail.mail_count_done, 0)
|
||||
sub_sms = test_event.event_mail_ids.filtered(lambda s: s.interval_type == "after_sub" and s.interval_unit == "now" and s.notification_type == "sms")
|
||||
self.assertEqual(len(sub_sms), 1)
|
||||
self.assertEqual(sub_sms.mail_count_done, 0)
|
||||
|
||||
# setup batch and cron limit sizes to check iterative behavior
|
||||
batch_size, cron_limit = 5, 20
|
||||
self.env["ir.config_parameter"].sudo().set_param("mail.batch_size", batch_size)
|
||||
self.env["ir.config_parameter"].sudo().set_param("mail.render.cron.limit", cron_limit)
|
||||
|
||||
# create registrations -> each one receives its on subscribe communication
|
||||
EventMailRegistration = type(self.env['event.mail.registration'])
|
||||
exec_origin = EventMailRegistration._execute_on_registrations
|
||||
with patch.object(
|
||||
EventMailRegistration, '_execute_on_registrations', autospec=True, wraps=EventMailRegistration, side_effect=exec_origin,
|
||||
) as mock_exec, \
|
||||
self.mock_datetime_and_now(self.reference_now + timedelta(hours=1)), \
|
||||
self.mockSMSGateway(), \
|
||||
self.mock_mail_gateway(), \
|
||||
self.capture_triggers('event.event_mail_scheduler') as capture:
|
||||
self._create_registrations(test_event, 30)
|
||||
|
||||
# iterative work on registrations: only 20 (cron limit) are taken into account
|
||||
self.assertEqual(sub_mail.mail_count_done, 20)
|
||||
self.assertEqual(sub_sms.mail_count_done, 20)
|
||||
self.assertEqual(mock_exec.call_count, 8, "Batch of 5 to make 20 registrations: 4 calls / scheduler")
|
||||
# cron should have been triggered for the remaining registrations
|
||||
self.assertSchedulerCronTriggers(capture, [self.reference_now + timedelta(hours=1)] * 2)
|
||||
|
||||
# iterative work on registrations, force cron to close those
|
||||
with (
|
||||
patch.object(
|
||||
EventMailRegistration, '_execute_on_registrations', autospec=True, wraps=EventMailRegistration, side_effect=exec_origin,
|
||||
) as mock_exec,
|
||||
self.mock_datetime_and_now(self.reference_now + timedelta(hours=1)),
|
||||
self.mockSMSGateway(),
|
||||
self.mock_mail_gateway(),
|
||||
self.capture_triggers('event.event_mail_scheduler') as capture,
|
||||
):
|
||||
self.event_cron_id.method_direct_trigger()
|
||||
|
||||
# finished sending communications
|
||||
self.assertEqual(sub_mail.mail_count_done, 30)
|
||||
self.assertEqual(sub_sms.mail_count_done, 30)
|
||||
self.assertFalse(capture.records)
|
||||
self.assertEqual(mock_exec.call_count, 4, "Batch of 5 to make 10 remaining registrations: 2 calls / scheduler")
|
||||
|
||||
|
||||
@tagged('event_mail', 'post_install', '-at_install')
|
||||
class TestEventSaleMail(TestEventFullCommon):
|
||||
|
||||
def test_event_mail_on_sale_confirmation(self):
|
||||
"""Test that a mail is sent to the customer when a sale order is confirmed."""
|
||||
ticket = self.test_event.event_ticket_ids[0]
|
||||
self.test_event.env.company.partner_id.email = 'test.email@test.example.com'
|
||||
order_line_vals = {
|
||||
"event_id": self.test_event.id,
|
||||
"event_ticket_id": ticket.id,
|
||||
"product_id": ticket.product_id.id,
|
||||
"product_uom_qty": 1,
|
||||
}
|
||||
self.customer_so.write({"order_line": [(0, 0, order_line_vals)]})
|
||||
|
||||
# check sale mail configuration
|
||||
aftersub = self.test_event.event_mail_ids.filtered(
|
||||
lambda m: m.interval_type == "after_sub"
|
||||
)
|
||||
self.assertTrue(aftersub)
|
||||
aftersub.template_ref.email_from = "{{ (object.event_id.organizer_id.email_formatted or object.event_id.user_id.email_formatted or '') }}"
|
||||
self.assertEqual(self.test_event.organizer_id, self.test_event.env.company.partner_id)
|
||||
|
||||
registration = self.env["event.registration"].create(
|
||||
{
|
||||
**self.website_customer_data[0],
|
||||
"partner_id": self.event_customer.id,
|
||||
"sale_order_line_id": self.customer_so.order_line[0].id,
|
||||
}
|
||||
)
|
||||
self.assertEqual(self.test_event.registration_ids, registration)
|
||||
self.assertEqual(self.customer_so.state, "draft")
|
||||
self.assertEqual(registration.state, "draft")
|
||||
|
||||
with self.mock_mail_gateway():
|
||||
self.customer_so.action_confirm()
|
||||
# mail send is done when writing state value, hence flushing for the test
|
||||
registration.flush_recordset()
|
||||
self.assertEqual(self.customer_so.state, "sale")
|
||||
self.assertEqual(registration.state, "open")
|
||||
|
||||
# Ensure mails are sent to customers right after subscription
|
||||
self.assertMailMailWRecord(
|
||||
registration,
|
||||
[self.event_customer.id],
|
||||
"outgoing",
|
||||
author=self.test_event.organizer_id,
|
||||
fields_values={
|
||||
"email_from": self.test_event.organizer_id.email_formatted,
|
||||
},
|
||||
)
|
||||
|
||||
def test_registration_template_body_translation(self):
|
||||
self.env['res.lang']._activate_lang('fr_BE')
|
||||
test_event = self.test_event
|
||||
self.partners[0].lang = 'fr_BE'
|
||||
self.env.ref('event.event_subscription').with_context(lang='fr_BE').body_html = 'Bonjour'
|
||||
with self.mock_mail_gateway(mail_unlink_sent=False):
|
||||
self.env['event.registration'].create({
|
||||
'event_id': test_event.id,
|
||||
'partner_id': self.partners[0].id
|
||||
})
|
||||
self.assertEqual(self._new_mails[0].body_html, "<p>Bonjour</p>")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from datetime import datetime, timedelta
|
|||
|
||||
from odoo.addons.test_event_full.tests.common import TestEventFullCommon
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.fields import Command
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import users
|
||||
from odoo.tools import mute_logger
|
||||
|
|
@ -55,7 +56,7 @@ class TestEventSecurity(TestEventFullCommon):
|
|||
def test_event_access_event_registration(self):
|
||||
# Event: read ok
|
||||
event = self.test_event.with_user(self.env.user)
|
||||
event.read(['name', 'user_id', 'kanban_state_label'])
|
||||
event.read(['name', 'user_id', 'kanban_state'])
|
||||
|
||||
# Event: read only
|
||||
with self.assertRaises(AccessError):
|
||||
|
|
@ -77,7 +78,7 @@ class TestEventSecurity(TestEventFullCommon):
|
|||
def test_event_access_event_user(self):
|
||||
# Event
|
||||
event = self.test_event.with_user(self.env.user)
|
||||
event.read(['name', 'user_id', 'kanban_state_label'])
|
||||
event.read(['name', 'user_id', 'kanban_state'])
|
||||
event.write({'name': 'New name'})
|
||||
self.env['event.event'].create({
|
||||
'name': 'Event',
|
||||
|
|
@ -133,7 +134,7 @@ class TestEventSecurity(TestEventFullCommon):
|
|||
event_type.unlink()
|
||||
|
||||
# Settings access rights required to enable some features
|
||||
self.user_eventmanager.write({'groups_id': [
|
||||
self.user_eventmanager.write({'group_ids': [
|
||||
(3, self.env.ref('base.group_system').id),
|
||||
(4, self.env.ref('base.group_erp_manager').id)
|
||||
]})
|
||||
|
|
@ -142,6 +143,45 @@ class TestEventSecurity(TestEventFullCommon):
|
|||
})
|
||||
event_config.execute()
|
||||
|
||||
def test_event_question_access(self):
|
||||
""" Check that some user groups have access to questions and answers only if they are linked to at
|
||||
least one published event. """
|
||||
question = self.env['event.question'].create({
|
||||
"title": "Question",
|
||||
"event_ids": [Command.create({
|
||||
'name': 'Unpublished Event',
|
||||
'is_published': False,
|
||||
})]
|
||||
})
|
||||
answer = self.env['event.question.answer'].create({
|
||||
"name": "Answer",
|
||||
"question_id": question.id,
|
||||
})
|
||||
restricted_users = [self.user_employee, self.user_portal, self.user_public]
|
||||
unrestricted_users = [self.user_eventmanager, self.user_eventuser]
|
||||
|
||||
for user in restricted_users:
|
||||
with self.assertRaises(AccessError, msg=f'{user.name} should not have access to questions of unpublished events'):
|
||||
question.with_user(user).read(['title'])
|
||||
with self.assertRaises(AccessError, msg=f'{user.name} should not have access to answers of unpublished events'):
|
||||
answer.with_user(user).read(['name'])
|
||||
|
||||
for user in unrestricted_users:
|
||||
question.with_user(user).read(['title'])
|
||||
answer.with_user(user).read(['name'])
|
||||
|
||||
# To check the access of user groups to questions and answers linked to at least one published event.
|
||||
self.env['event.event'].create({
|
||||
'name': 'Published Event',
|
||||
'is_published': True,
|
||||
'question_ids': [Command.set(question.ids)],
|
||||
})
|
||||
|
||||
# Check that all user groups have access to questions and answers linked to at least one published event.
|
||||
for user in restricted_users + unrestricted_users:
|
||||
question.with_user(user).read(['title'])
|
||||
answer.with_user(user).read(['name'])
|
||||
|
||||
def test_implied_groups(self):
|
||||
"""Test that the implied groups are correctly set.
|
||||
|
||||
|
|
|
|||
|
|
@ -6,8 +6,7 @@ from freezegun import freeze_time
|
|||
|
||||
from odoo.addons.test_event_full.tests.common import TestEventFullCommon
|
||||
from odoo.addons.website.tests.test_performance import UtilPerf
|
||||
from odoo.tests.common import users, warmup, Form
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests import Form, users, warmup, tagged
|
||||
|
||||
|
||||
@tagged('event_performance', 'post_install', '-at_install', '-standard')
|
||||
|
|
@ -17,6 +16,9 @@ class EventPerformanceCase(TestEventFullCommon):
|
|||
super(EventPerformanceCase, self).setUp()
|
||||
# patch registry to simulate a ready environment
|
||||
self.patch(self.env.registry, 'ready', True)
|
||||
# we don't use mock_mail_gateway thus want to mock smtp to test the stack
|
||||
self._mock_smtplib_connection()
|
||||
|
||||
self._flush_tracking()
|
||||
|
||||
def _flush_tracking(self):
|
||||
|
|
@ -52,7 +54,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
batch_size = 20
|
||||
|
||||
# simple without type involved + website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=5368): # tef 4944 / com 4943
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=3418): # tef 3316 / com 3315
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = [
|
||||
dict(self.event_base_vals,
|
||||
|
|
@ -60,7 +62,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
)
|
||||
for x in range(batch_size)
|
||||
]
|
||||
self.env['event.event'].create(event_values)
|
||||
self.env['event.event'].with_context(lang='en_US').create(event_values)
|
||||
|
||||
@users('event_user')
|
||||
@warmup
|
||||
|
|
@ -70,7 +72,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
event_type = self.env['event.type'].browse(self.test_event_type.ids)
|
||||
|
||||
# complex with type
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=439): # 439
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=432): # tef 432
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = [
|
||||
dict(self.event_base_vals,
|
||||
|
|
@ -89,7 +91,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
event_type = self.env['event.type'].browse(self.test_event_type.ids)
|
||||
|
||||
# complex with type + website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=5480): # tef 5056 / com 5055
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=3522): # tef 3420 / com 3419
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = [
|
||||
dict(self.event_base_vals,
|
||||
|
|
@ -97,7 +99,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
)
|
||||
for x in range(batch_size)
|
||||
]
|
||||
self.env['event.event'].create(event_values)
|
||||
self.env['event.event'].with_context(lang='en_US').create(event_values)
|
||||
|
||||
|
||||
@users('event_user')
|
||||
|
|
@ -107,7 +109,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise
|
||||
|
||||
# no type, no website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=206): # tef 160 / com 160
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=108): # tef 103 / com 103
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
# Require for `website_menu` to be visible
|
||||
# <div name="event_menu_configuration" groups="base.group_no_one">
|
||||
|
|
@ -128,7 +130,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise
|
||||
|
||||
# no type, website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=666): # tef 565 / com 566
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=429): # tef 379 / com 380
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
# Require for `website_menu` to be visible
|
||||
# <div name="event_menu_configuration" groups="base.group_no_one">
|
||||
|
|
@ -150,7 +152,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
has_social = 'social_menu' in self.env['event.event'] # otherwise view may crash in enterprise
|
||||
|
||||
# type and website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=692): # tef 593 / com 596
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=472): # tef 426 / com 428
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
# Require for `website_menu` to be visible
|
||||
# <div name="event_menu_configuration" groups="base.group_no_one">
|
||||
|
|
@ -168,7 +170,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
def test_event_create_single_notype(self):
|
||||
""" Test a single event creation """
|
||||
# simple without type involved
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=31): # 31
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=31): # tef 31
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = dict(
|
||||
self.event_base_vals,
|
||||
|
|
@ -181,13 +183,13 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
def test_event_create_single_notype_website(self):
|
||||
""" Test a single event creation """
|
||||
# simple without type involved + website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=352): # tef 327 / com 326
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=242): # tef 228 / com 234
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = dict(
|
||||
self.event_base_vals,
|
||||
website_menu=True
|
||||
)
|
||||
self.env['event.event'].create([event_values])
|
||||
self.env['event.event'].with_context(lang='en_US').create([event_values])
|
||||
|
||||
@users('event_user')
|
||||
@warmup
|
||||
|
|
@ -196,7 +198,7 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
event_type = self.env['event.type'].browse(self.test_event_type.ids)
|
||||
|
||||
# complex with type
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=58): # 58
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=52): # tef 52
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = dict(
|
||||
self.event_base_vals,
|
||||
|
|
@ -212,13 +214,13 @@ class TestEventPerformance(EventPerformanceCase):
|
|||
event_type = self.env['event.type'].browse(self.test_event_type.ids)
|
||||
|
||||
# complex with type + website
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=387): # tef 362 / com 361
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=274): # tef 266 / com 265
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
event_values = dict(
|
||||
self.event_base_vals,
|
||||
event_type_id=event_type.id,
|
||||
)
|
||||
self.env['event.event'].create([event_values])
|
||||
self.env['event.event'].with_context(lang='en_US').create([event_values])
|
||||
|
||||
|
||||
@tagged('event_performance', 'registration_performance', 'post_install', '-at_install', '-standard')
|
||||
|
|
@ -234,7 +236,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
"""
|
||||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=720): # tef only: 674? - com runbot 716 - ent runbot 719
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=638): # tef 633 / com 636
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = [
|
||||
dict(reg_data,
|
||||
|
|
@ -258,7 +260,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
"""
|
||||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=210): # tef 167 / com runbot 206
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=165): # tef 164 / com runbot 163
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = [
|
||||
dict(reg_data,
|
||||
|
|
@ -280,7 +282,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
form like) """
|
||||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=731): # tef only: 685? - com runbot 727
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=651): # tef 647 - com 649
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = [
|
||||
dict(reg_data,
|
||||
|
|
@ -301,12 +303,11 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
""" Test a single registration creation using Form """
|
||||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=231): # tef only: 210? - com runbot 216
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=145): # tef 140 / com 143
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
with Form(self.env['event.registration']) as reg_form:
|
||||
reg_form.event_id = event
|
||||
reg_form.email = 'email.00@test.example.com'
|
||||
reg_form.mobile = '0456999999'
|
||||
reg_form.name = 'My Customer'
|
||||
reg_form.phone = '0456000000'
|
||||
_registration = reg_form.save()
|
||||
|
|
@ -317,7 +318,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
""" Test a single registration creation using Form """
|
||||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=233): # tef only: 213? - com runbot 217
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=146): # tef 141 / com 144
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
with Form(self.env['event.registration']) as reg_form:
|
||||
reg_form.event_id = event
|
||||
|
|
@ -330,7 +331,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
""" Test a single registration creation using Form """
|
||||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=124): # tef 107 / com 109
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=63): # tef 61 / com 61
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
with Form(self.env['event.registration'].with_context(event_lead_rule_skip=True)) as reg_form:
|
||||
reg_form.event_id = event
|
||||
|
|
@ -344,7 +345,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
# simple customer data
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=143): # tef only: 135? - com runbot 140
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=122): # tef 118 / com 120
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = dict(
|
||||
self.customer_data[0],
|
||||
|
|
@ -358,7 +359,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
# partner-based customer
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=149): # tef only: 142? - com runbot 146
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=121): # tef 117 / com 120
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = {
|
||||
'event_id': event.id,
|
||||
|
|
@ -373,7 +374,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
# partner-based customer
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=46): # tef 41 / com 43
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=39): # tef 38 / com 38
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = {
|
||||
'event_id': event.id,
|
||||
|
|
@ -388,7 +389,7 @@ class TestRegistrationPerformance(EventPerformanceCase):
|
|||
event = self.env['event.event'].browse(self.test_event.ids)
|
||||
|
||||
# website customer data
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=151): # tef only: 142? - com runbot 146
|
||||
with freeze_time(self.reference_now), self.assertQueryCount(event_user=126): # tef 122 / com 124
|
||||
self.env.cr._now = self.reference_now # force create_date to check schedulers
|
||||
registration_values = dict(
|
||||
self.website_customer_data[0],
|
||||
|
|
@ -429,7 +430,6 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
|
|||
])
|
||||
|
||||
def _test_url_open(self, url):
|
||||
url += ('?' not in url and '?' or '') + '&debug=disable-t-cache'
|
||||
return self.url_open(url)
|
||||
|
||||
@warmup
|
||||
|
|
@ -437,7 +437,7 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
|
|||
# website customer data
|
||||
with freeze_time(self.reference_now):
|
||||
self.authenticate('user_eventmanager', 'user_eventmanager')
|
||||
with self.assertQueryCount(default=36): # tef 35
|
||||
with self.assertQueryCount(default=35): # tef 34
|
||||
self._test_url_open('/event/%i' % self.test_event.id)
|
||||
|
||||
@warmup
|
||||
|
|
@ -445,7 +445,7 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
|
|||
# website customer data
|
||||
with freeze_time(self.reference_now):
|
||||
self.authenticate(None, None)
|
||||
with self.assertQueryCount(default=27):
|
||||
with self.assertQueryCount(default=25):
|
||||
self._test_url_open('/event/%i' % self.test_event.id)
|
||||
|
||||
@warmup
|
||||
|
|
@ -453,7 +453,7 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
|
|||
# website customer data
|
||||
with freeze_time(self.reference_now):
|
||||
self.authenticate('user_eventmanager', 'user_eventmanager')
|
||||
with self.assertQueryCount(default=39): # tef 38
|
||||
with self.assertQueryCount(default=43): # tef 42
|
||||
self._test_url_open('/event')
|
||||
|
||||
@warmup
|
||||
|
|
@ -461,23 +461,22 @@ class TestOnlineEventPerformance(EventPerformanceCase, UtilPerf):
|
|||
# website customer data
|
||||
with freeze_time(self.reference_now):
|
||||
self.authenticate(None, None)
|
||||
with self.assertQueryCount(default=28):
|
||||
with self.assertQueryCount(default=39):
|
||||
self._test_url_open('/event')
|
||||
|
||||
# @warmup
|
||||
# def test_register_public(self):
|
||||
# with freeze_time(self.reference_now + timedelta(hours=3)): # be sure sales has started
|
||||
# self.assertTrue(self.test_event.event_registrations_started)
|
||||
# self.authenticate(None, None)
|
||||
# with self.assertQueryCount(default=99999): # tef only: 1110
|
||||
# self.browser_js(
|
||||
# '/event/%i/register' % self.test_event.id,
|
||||
# 'odoo.__DEBUG__.services["web_tour.tour"].run("wevent_performance_register")',
|
||||
# 'odoo.__DEBUG__.services["web_tour.tour"].tours.wevent_performance_register.ready',
|
||||
# login=None,
|
||||
# timeout=200,
|
||||
# )
|
||||
@warmup
|
||||
def test_register_public(self):
|
||||
with freeze_time(self.reference_now + timedelta(hours=3)): # be sure sales has started
|
||||
self.assertTrue(self.test_event.event_registrations_started)
|
||||
self.authenticate(None, None)
|
||||
with self.assertQueryCount(default=1197): # tef: 1197
|
||||
self.start_tour(
|
||||
'/event/%i/register' % self.test_event.id,
|
||||
'wevent_performance_register',
|
||||
login=None,
|
||||
timeout=200,
|
||||
)
|
||||
|
||||
# # minimal checkup, to be improved in future tests independently from performance
|
||||
# self.assertEqual(len(self.test_event.registration_ids), 3)
|
||||
# self.assertEqual(len(self.test_event.registration_ids.visitor_id), 1)
|
||||
# minimal checkup, to be improved in future tests independently from performance
|
||||
self.assertEqual(len(self.test_event.registration_ids), 3)
|
||||
self.assertEqual(len(self.test_event.registration_ids.visitor_id), 1)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,41 @@
|
|||
from odoo.addons.test_event_full.tests.common import TestWEventCommon
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import users
|
||||
|
||||
|
||||
@tagged('event_online', 'post_install', '-at_install')
|
||||
class TestWEventMenu(TestWEventCommon):
|
||||
|
||||
@users('admin')
|
||||
def test_seo_data(self):
|
||||
"""Test SEO data for submenus on event website page"""
|
||||
|
||||
self.assertFalse(self.event.website_meta_title, 'Event should initially have no meta title')
|
||||
self.event.write({
|
||||
'website_meta_title': 'info',
|
||||
})
|
||||
self.assertTrue(self.event.website_meta_title, 'Event should have a meta title after writing')
|
||||
|
||||
menus = [
|
||||
('booth_menu_ids', 'Get a Booth'),
|
||||
('exhibitor_menu_ids', 'Exhibitor'),
|
||||
('community_menu_ids', 'Leaderboard'),
|
||||
('track_menu_ids', 'Talks'),
|
||||
('track_menu_ids', 'Agenda'),
|
||||
('track_proposal_menu_ids', 'Talk Proposal'),
|
||||
]
|
||||
|
||||
for menu_field, menu_name in menus:
|
||||
menu = self.event[menu_field]
|
||||
|
||||
if menu_field == 'track_menu_ids':
|
||||
menu_url = '/track' if menu_name == 'Talks' else '/agenda'
|
||||
menu = self.event[menu_field].filtered(lambda menu: menu.menu_id.url.endswith(menu_url))
|
||||
|
||||
self.assertFalse(menu.website_meta_title, f"{menu_name} page should initially have no meta title")
|
||||
menu.write({'website_meta_title': menu_name})
|
||||
|
||||
web_page = self.url_open(menu.menu_id.url)
|
||||
|
||||
self.assertTrue(menu.website_meta_title, f"{menu_name} page should have a meta title after writing")
|
||||
self.assertIn(f"<title>{menu.website_meta_title}</title>", web_page.text)
|
||||
|
|
@ -4,6 +4,7 @@
|
|||
from freezegun import freeze_time
|
||||
|
||||
from odoo import tests
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.addons.test_event_full.tests.common import TestWEventCommon
|
||||
|
||||
|
||||
|
|
@ -11,13 +12,9 @@ from odoo.addons.test_event_full.tests.common import TestWEventCommon
|
|||
class TestWEventRegister(TestWEventCommon):
|
||||
|
||||
def test_register(self):
|
||||
self.env.company.country_id = self.env.ref('base.us')
|
||||
with freeze_time(self.reference_now, tick=True):
|
||||
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
|
||||
)
|
||||
self.start_tour('/event', 'wevent_register', login=None)
|
||||
new_registrations = self.event.registration_ids
|
||||
visitor = new_registrations.visitor_id
|
||||
|
||||
|
|
@ -40,5 +37,15 @@ class TestWEventRegister(TestWEventCommon):
|
|||
self.assertEqual(visitor.display_name, "Raoulette Poiluchette")
|
||||
self.assertEqual(visitor.event_registration_ids, new_registrations)
|
||||
self.assertEqual(visitor.partner_id, self.env['res.partner'])
|
||||
self.assertEqual(visitor.mobile, "0456112233")
|
||||
self.assertEqual(visitor.email, "raoulette@example.com")
|
||||
|
||||
def test_internal_user_register(self):
|
||||
mail_new_test_user(
|
||||
self.env,
|
||||
name='User Internal',
|
||||
login='user_internal',
|
||||
email='user_internal@example.com',
|
||||
groups='base.group_user',
|
||||
)
|
||||
with freeze_time(self.reference_now, tick=True):
|
||||
self.start_tour('/event', 'wevent_register', login='user_internal')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue