summaryrefslogtreecommitdiff
path: root/addons
diff options
context:
space:
mode:
Diffstat (limited to 'addons')
-rw-r--r--addons/survey/static/src/js/survey_session_manage.js6
-rw-r--r--addons/survey/static/tests/tours/survey_session_manage_test.js19
-rw-r--r--addons/survey/static/tests/tours/survey_tour_session_create.js20
-rw-r--r--addons/survey/static/tests/tours/survey_tour_session_manage.js440
-rw-r--r--addons/survey/static/tests/tours/survey_tour_session_start.js32
-rw-r--r--addons/survey/static/tests/tours/survey_tour_session_tools.js21
-rw-r--r--addons/survey/tests/__init__.py1
-rw-r--r--addons/survey/tests/test_survey_ui_session.py210
-rw-r--r--addons/survey/views/assets.xml5
9 files changed, 752 insertions, 2 deletions
diff --git a/addons/survey/static/src/js/survey_session_manage.js b/addons/survey/static/src/js/survey_session_manage.js
index 1a83175e79e..897aab6d7b3 100644
--- a/addons/survey/static/src/js/survey_session_manage.js
+++ b/addons/survey/static/src/js/survey_session_manage.js
@@ -376,7 +376,7 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend({
_refreshResults: function () {
var self = this;
- this._rpc({
+ return this._rpc({
route: _.str.sprintf('/survey/session/results/%s', self.surveyAccessToken)
}).then(function (questionResults) {
if (questionResults) {
@@ -398,6 +398,8 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend({
);
}
}
+
+ return Promise.resolve();
}, function () {
// on failure, stop refreshing
clearInterval(self.resultsRefreshInterval);
@@ -412,7 +414,7 @@ publicWidget.registry.SurveySessionManage = publicWidget.Widget.extend({
_refreshAttendeesCount: function () {
var self = this;
- self._rpc({
+ return self._rpc({
model: 'survey.survey',
method: 'read',
args: [[self.surveyId], ['session_answer_count']],
diff --git a/addons/survey/static/tests/tours/survey_session_manage_test.js b/addons/survey/static/tests/tours/survey_session_manage_test.js
new file mode 100644
index 00000000000..acf3d99c945
--- /dev/null
+++ b/addons/survey/static/tests/tours/survey_session_manage_test.js
@@ -0,0 +1,19 @@
+odoo.define('survey.session_manage_test', function (require) {
+"use strict";
+
+var SessionManager = require('survey.session_manage');
+/**
+ * Small override for test/tour purposes.
+ * We trigger the fetch of answer results immediately at the start.
+ * (Instead of wasting 2 seconds waiting after the start).
+ */
+SessionManager.include({
+ start: function () {
+ return this._super.apply(this, arguments)
+ .then(this._refreshResults.bind(this));
+ }
+});
+
+return SessionManager;
+
+});
diff --git a/addons/survey/static/tests/tours/survey_tour_session_create.js b/addons/survey/static/tests/tours/survey_tour_session_create.js
new file mode 100644
index 00000000000..ac0c2f275d9
--- /dev/null
+++ b/addons/survey/static/tests/tours/survey_tour_session_create.js
@@ -0,0 +1,20 @@
+odoo.define('survey.test_survey_session_create_tour', function (require) {
+"use strict";
+
+var tour = require('web_tour.tour');
+var surveySessionTools = require('survey.session_tour_tools');
+
+/**
+ * Small tour that will simply start the session and wait for attendees.
+ */
+tour.register('test_survey_session_create_tour', {
+ url: "/web",
+ test: true,
+}, [].concat(surveySessionTools.accessSurveySteps, [{
+ trigger: 'button[name="action_start_session"]',
+}, {
+ trigger: '.o_survey_session_attendees_count:contains("0")',
+ run: function () {} // check session is correctly started
+}]));
+
+});
diff --git a/addons/survey/static/tests/tours/survey_tour_session_manage.js b/addons/survey/static/tests/tours/survey_tour_session_manage.js
new file mode 100644
index 00000000000..36b5d8dfeca
--- /dev/null
+++ b/addons/survey/static/tests/tours/survey_tour_session_manage.js
@@ -0,0 +1,440 @@
+odoo.define('survey.test_survey_session_manage_tour', function (require) {
+"use strict";
+
+var tour = require('web_tour.tour');
+var surveySessionTools = require('survey.session_tour_tools');
+
+/**
+ * Since the chart is rendered using SVG, we can't use jQuery triggers to check if everything
+ * is correctly rendered.
+ * This helper method returns the chart data (Chartjs framework specific) in the following structure:
+ * [{ value, backgroundColor, labelColor }]
+ */
+var getChartData = function () {
+ var chartData = [];
+ var rootWidget = odoo.__DEBUG__.services['root.widget'];
+ var surveyManagePublicWidget = rootWidget.publicWidgets.find(function (widget) {
+ return widget.$el.hasClass('o_survey_session_manage');
+ });
+
+ if (!surveyManagePublicWidget) {
+ return chartData;
+ }
+
+ surveyManagePublicWidget.resultsChart.chart.data.datasets[0].data.forEach(function (value, index) {
+ chartData.push({
+ value: value,
+ backgroundColor: surveyManagePublicWidget.resultsChart._getBackgroundColor({dataIndex: index}),
+ labelColor: surveyManagePublicWidget.resultsChart._getLabelColor({dataIndex: index}),
+ });
+ });
+
+ return chartData;
+};
+
+var nextScreen = function () {
+ var e = $.Event('keydown');
+ e.keyCode = 39; // arrow-right
+ $(document).trigger(e);
+};
+
+var previousScreen = function () {
+ var e = $.Event('keydown');
+ e.keyCode = 37; // arrow-left
+ $(document).trigger(e);
+};
+
+var REGULAR_ANSWER_COLOR = '#212529';
+var CORRECT_ANSWER_COLOR = '#2CBB70';
+var WRONG_ANSWER_COLOR = '#D9534F';
+
+/**
+ * A 'regular' answer is an answer that is nor correct, nor incorrect.
+ * The check is based on the specific opacity (0.8) and color of those answers.
+ */
+var isRegularAnswer = function (answer) {
+ return answer.backgroundColor.includes('0.8') &&
+ answer.labelColor === REGULAR_ANSWER_COLOR;
+};
+
+/**
+ * The check is based on the specific opacity (0.8) and color of correct answers.
+ */
+var isCorrectAnswer = function (answer) {
+ return answer.backgroundColor.includes('0.8') &&
+ answer.labelColor === CORRECT_ANSWER_COLOR;
+};
+
+/**
+ * The check is based on the specific opacity (0.3) and color of incorrect answers.
+ */
+var isIncorrectAnswer = function (answer) {
+ return answer.backgroundColor.includes('0.3') &&
+ answer.labelColor === WRONG_ANSWER_COLOR;
+};
+
+/**
+ * Tour that will test the whole survey session from the host point of view.
+ *
+ * Break down of the main points:
+ * - Open the 'session manager' (the session was already created by a previous tour)
+ * - Display the nickname question, and move to the next one (as answers are not displayed)
+ * - Check answers are correctly displayed for the 3 'simple' question types (text, date, datetime)
+ * - Move to the choice question and check that answers are displayed
+ * (The check is rather complex, see 'getChartData' for details)
+ * - If everything is correctly displayed, move to the next question
+ * - On the scored choice question, check that the screens are correctly chained:
+ * no results displayed -> results displayed -> correct/incorrect answers -> leaderboard
+ * - On the scored + timed multiple choice question, check the same than previous question,
+ * except that the results are supposed to be displayed automatically when the question timer runs out
+ * - Test the 'back' behavior and check that screens are reversed correctly
+ * - Check that our final leaderboard is correct based on attendees answers
+ * - Close the survey session
+ */
+tour.register('test_survey_session_manage_tour', {
+ url: "/web",
+ test: true,
+}, [].concat(surveySessionTools.accessSurveySteps, [{
+ trigger: 'button[name="action_open_session_manager"]',
+}, {
+ trigger: 'h1:contains("Nickname")',
+ run: function () {} // check nickname question is displayed
+}, {
+ trigger: 'h1',
+ run: nextScreen
+}, {
+ trigger: 'h1:contains("Text Question")',
+ run: function () {} // check text question is displayed
+}, {
+ trigger: '.o_survey_session_progress_small:contains("3 / 3")',
+ run: function () {} // check we have 3 answers
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("Attendee 1 is the best")',
+ run: function () {} // check attendee 1 answer is displayed
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("Attendee 2 rulez")',
+ run: function () {} // check attendee 2 answer is displayed
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("Attendee 3 will crush you")',
+ run: function () {} // check attendee 3 answer is displayed
+}, {
+ trigger: 'h1',
+ run: nextScreen
+}, {
+ trigger: '.o_survey_session_progress_small:contains("2 / 3")',
+ run: function () {} // check we have 2 answers
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("10/10/2010")',
+ run: function () {} // check attendee 1 answer is displayed
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("11/11/2011")',
+ run: function () {} // check attendee 2 answer is displayed
+}, {
+ trigger: 'h1',
+ run: nextScreen
+}, {
+ trigger: '.o_survey_session_progress_small:contains("2 / 3")',
+ run: function () {} // check we have 2 answers
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("10/10/2010 10:00:00")',
+ run: function () {} // check attendee 2 answer is displayed
+}, {
+ trigger: '.o_survey_session_text_answer_container:contains("11/11/2011 15:55:55")',
+ run: function () {} // check attendee 3 answer is displayed
+}, {
+ trigger: 'h1',
+ run: nextScreen
+}, {
+ trigger: 'h1:contains("Regular Simple Choice")',
+ run: function () {
+ var chartData = getChartData();
+ if (chartData.length !== 3) {
+ console.error('Chart data should contain 3 records!');
+ return;
+ }
+
+ var firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 2 || !isRegularAnswer(firstAnswerData)) {
+ console.error('First answer should be picked by 2 users!');
+ return;
+ }
+
+ var secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 1 || !isRegularAnswer(secondAnswerData)) {
+ console.error('Second answer should be picked by 1 user!');
+ return;
+ }
+
+ var thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 0 || !isRegularAnswer(thirdAnswerData)) {
+ console.error('Third answer should be picked by no users!');
+ return;
+ }
+
+ nextScreen();
+ }
+}, {
+ trigger: 'h1:contains("Scored Simple Choice")',
+ run: function () {
+ var chartData = getChartData();
+ if (chartData.length !== 4) {
+ console.error('Chart data should contain 4 records!');
+ return;
+ }
+
+ for (var i = 0; i < chartData.length; i++) {
+ if (chartData[i].value !== 0) {
+ console.error(
+ 'Chart data should all be 0 because "next screen" that shows ' +
+ 'answers values is not triggered yet!');
+ return;
+ }
+ }
+
+ nextScreen();
+ chartData = getChartData();
+
+ var firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 1 || !isRegularAnswer(firstAnswerData)) {
+ console.error(
+ 'First answer should be picked by 1 user and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ var secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 1 || !isRegularAnswer(secondAnswerData)) {
+ console.error(
+ 'Second answer should be picked by 1 user and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ var thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 1 || !isRegularAnswer(thirdAnswerData)) {
+ console.error(
+ 'Third answer should be picked by 1 user and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ var fourthAnswerData = chartData[3];
+ if (fourthAnswerData.value !== 0 || !isRegularAnswer(fourthAnswerData)) {
+ console.error(
+ 'Fourth answer should be picked by no users and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ nextScreen();
+ chartData = getChartData();
+
+ firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 1 || !isCorrectAnswer(firstAnswerData)) {
+ console.error(
+ 'First answer should be picked by 1 user and it should be correct!'
+ );
+ return;
+ }
+
+ secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 1 || !isIncorrectAnswer(secondAnswerData)) {
+ console.error(
+ 'Second answer should be picked by 1 user and it should be incorrect!'
+ );
+ return;
+ }
+
+ thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 1 || !isIncorrectAnswer(thirdAnswerData)) {
+ console.error(
+ 'Third answer should be picked by 1 user and it should be incorrect!'
+ );
+ return;
+ }
+
+ fourthAnswerData = chartData[3];
+ if (fourthAnswerData.value !== 0 || !isIncorrectAnswer(fourthAnswerData)) {
+ console.error(
+ 'Fourth answer should be picked by no users and it should be incorrect!'
+ );
+ return;
+ }
+
+ nextScreen();
+ nextScreen();
+ }
+}, {
+ trigger: 'h1:contains("Timed Scored Multiple Choice")',
+ run: function () {
+ var chartData = getChartData();
+ if (chartData.length !== 3) {
+ console.error('Chart data should contain 4 records!');
+ return;
+ }
+
+ for (var i = 0; i < chartData.length; i++) {
+ if (chartData[i].value !== 0) {
+ console.error(
+ 'Chart data should all be 0 because "next screen" that shows ' +
+ 'answers values is not triggered yet!');
+ return;
+ }
+ }
+
+ // after 1 second, results are displayed automatically because question timer
+ // runs out
+ setTimeout(function () {
+ chartData = getChartData();
+ var firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 2 || !isRegularAnswer(firstAnswerData)) {
+ console.error(
+ 'First answer should be picked by 2 users and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ var secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 2 || !isRegularAnswer(secondAnswerData)) {
+ console.error(
+ 'Second answer should be picked by 2 users and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ var thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 1 || !isRegularAnswer(thirdAnswerData)) {
+ console.error(
+ 'Third answer should be picked by 1 user and its correctness should not be shown yet!'
+ );
+ return;
+ }
+
+ nextScreen();
+ chartData = getChartData();
+
+ firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 2 || !isCorrectAnswer(firstAnswerData)) {
+ console.error(
+ 'First answer should be picked by 2 users and it should be correct!'
+ );
+ return;
+ }
+
+ secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 2 || !isCorrectAnswer(secondAnswerData)) {
+ console.error(
+ 'Second answer should be picked by 2 users and it should be correct!'
+ );
+ return;
+ }
+
+ thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 1 || !isIncorrectAnswer(thirdAnswerData)) {
+ console.error(
+ 'Third answer should be picked by 1 user and it should be incorrect!'
+ );
+ return;
+ }
+
+ nextScreen();
+ }, 1500);
+ }
+}, {
+ trigger: 'h1:contains("Final Leaderboard")',
+ run: function () {} // Final Leaderboard is displayed
+}, {
+ trigger: 'h1',
+ run: function () {
+ // previous screen testing
+ previousScreen();
+ var chartData = getChartData();
+
+ var firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 2 || !isCorrectAnswer(firstAnswerData)) {
+ console.error(
+ 'First answer should be picked by 2 users and it should be correct!'
+ );
+ return;
+ }
+
+ var secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 2 || !isCorrectAnswer(secondAnswerData)) {
+ console.error(
+ 'Second answer should be picked by 2 users and it should be correct!'
+ );
+ return;
+ }
+
+ var thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 1 || !isIncorrectAnswer(thirdAnswerData)) {
+ console.error(
+ 'Third answer should be picked by 1 user and it should be incorrect!'
+ );
+ return;
+ }
+
+ previousScreen();
+ chartData = getChartData();
+
+ firstAnswerData = chartData[0];
+ if (firstAnswerData.value !== 2 || !isRegularAnswer(firstAnswerData)) {
+ console.error(
+ 'First answer should be picked by 2 users and its correctness should not be shown!'
+ );
+ return;
+ }
+
+ secondAnswerData = chartData[1];
+ if (secondAnswerData.value !== 2 || !isRegularAnswer(secondAnswerData)) {
+ console.error(
+ 'Second answer should be picked by 2 users and its correctness should not be shown!'
+ );
+ return;
+ }
+
+ thirdAnswerData = chartData[2];
+ if (thirdAnswerData.value !== 1 || !isRegularAnswer(thirdAnswerData)) {
+ console.error(
+ 'Third answer should be picked by 1 user and its correctness should not be shown!'
+ );
+ return;
+ }
+
+ previousScreen();
+ chartData = getChartData();
+
+ for (var i = 0; i < chartData.length; i++) {
+ if (chartData[i].value !== 0) {
+ console.error(
+ 'Chart data should all be 0 because "next screen" that shows ' +
+ 'answers values is not triggered yet!');
+ return;
+ }
+ }
+
+ // Now we go forward to the "Final Leaderboard" again (4 times)
+ for (i = 0; i < 4; i++) {
+ nextScreen();
+ }
+ }
+}, {
+ trigger: 'h1:contains("Final Leaderboard")',
+ run: function () {} // Final Leaderboard is displayed
+}, {
+ trigger: '.o_survey_session_leaderboard_item:contains("azerty"):contains("1."):contains("40")',
+ run: function () {} // 'azerty' is first with 40 points
+}, {
+ trigger: '.o_survey_session_leaderboard_item:contains("xxxTheB"):contains("2."):contains("20")',
+ run: function () {} // 'xxxTheBestxxx' is second with 20 points
+}, {
+ trigger: '.o_survey_session_leaderboard_item:contains("nicktalope"):contains("3."):contains("10")',
+ run: function () {} // 'nicktalope' is third with 10 points
+}, {
+ trigger: '.o_survey_session_close:has("i.fa-close")'
+}, {
+ trigger: 'button[name="action_start_session"]',
+ run: function () {} // check that we can start another session
+}]));
+
+});
diff --git a/addons/survey/static/tests/tours/survey_tour_session_start.js b/addons/survey/static/tests/tours/survey_tour_session_start.js
new file mode 100644
index 00000000000..309ce0afaeb
--- /dev/null
+++ b/addons/survey/static/tests/tours/survey_tour_session_start.js
@@ -0,0 +1,32 @@
+odoo.define('survey.test_survey_session_start_tour', function (require) {
+"use strict";
+
+var tour = require('web_tour.tour');
+var surveySessionTools = require('survey.session_tour_tools');
+
+/**
+ * Small tour that will open the session manager and check
+ * that the attendees are accounted for, then start the session
+ * by going to the first question.
+ */
+tour.register('test_survey_session_start_tour', {
+ url: "/web",
+ test: true,
+}, [].concat(surveySessionTools.accessSurveySteps, [{
+ trigger: 'button[name="action_open_session_manager"]',
+}, {
+ trigger: '.o_survey_session_attendees_count:contains("3")',
+ run: function () {} // check attendees count
+}, {
+ trigger: 'h1',
+ run: function () {
+ var e = $.Event('keydown');
+ e.keyCode = 39; // arrow-right
+ $(document).trigger(e); // start session
+ }
+}, {
+ trigger: 'h1:contains("Nickname")',
+ run: function () {} // check first question is displayed
+}]));
+
+});
diff --git a/addons/survey/static/tests/tours/survey_tour_session_tools.js b/addons/survey/static/tests/tours/survey_tour_session_tools.js
new file mode 100644
index 00000000000..a42d72e26cf
--- /dev/null
+++ b/addons/survey/static/tests/tours/survey_tour_session_tools.js
@@ -0,0 +1,21 @@
+odoo.define('survey.session_tour_tools', function (require) {
+'use strict';
+
+var tour = require('web_tour.tour');
+
+/**
+ * Tool that gathers common steps to every 'survey session' tours.
+ */
+return {
+ accessSurveySteps: [tour.stepUtils.showAppsMenuItem(), {
+ trigger: '.o_app[data-menu-xmlid="survey.menu_surveys"]',
+ edition: 'community'
+ }, {
+ trigger: '.o_app[data-menu-xmlid="survey.menu_surveys"]',
+ edition: 'enterprise'
+ }, {
+ trigger: '.oe_kanban_card:contains("User Session Survey")',
+ }]
+};
+
+});
diff --git a/addons/survey/tests/__init__.py b/addons/survey/tests/__init__.py
index 76df1c8efa8..a7d6dc8d60a 100644
--- a/addons/survey/tests/__init__.py
+++ b/addons/survey/tests/__init__.py
@@ -10,5 +10,6 @@ from . import test_survey_security
from . import test_survey_randomize
from . import test_survey_ui_certification
from . import test_survey_ui_feedback
+from . import test_survey_ui_session
from . import test_survey_compute_pages_questions
from . import test_certification_badge
diff --git a/addons/survey/tests/test_survey_ui_session.py b/addons/survey/tests/test_survey_ui_session.py
new file mode 100644
index 00000000000..53dd81ea62b
--- /dev/null
+++ b/addons/survey/tests/test_survey_ui_session.py
@@ -0,0 +1,210 @@
+# -*- coding: utf-8 -*-
+# Part of Odoo. See LICENSE file for full copyright and licensing details.
+
+from dateutil.relativedelta import relativedelta
+
+from odoo import fields
+from odoo.tests.common import tagged, HttpCase
+
+
+@tagged('post_install', '-at_install')
+class TestUiSession(HttpCase):
+ def test_admin_survey_session(self):
+ """ This method tests a full 'survey session' flow.
+ Break down of different steps:
+ - Create the test data
+ - A scored survey
+ - A nickname question
+ - "Simple" type questions (text, date, datetime)
+ - A regular simple choice
+ - A scored simple choice
+ - A scored AND timed multiple choice
+ - Create a new survey session
+ - Register 3 attendees to it
+ - Open the session manager to check that our attendees are accounted for
+ - Create some answers to our survey questions.
+ - Then run the 'big' manage session tour (see JS doc for details)
+ - And finally check that our session and attendees inputs are correctly closed. """
+
+ # =======================
+ # CREATE SURVEY TEST DATA
+ # =======================
+
+ test_start_time = fields.Datetime.now()
+
+ survey_session = self.env['survey.survey'].create({
+ 'title': 'User Session Survey',
+ 'access_token': 'b137640d-14d4-4748-9ef6-344caaaaafe',
+ 'state': 'open',
+ 'access_mode': 'public',
+ 'users_can_go_back': False,
+ 'questions_layout': 'page_per_question',
+ 'scoring_type': 'scoring_without_answers'
+ })
+
+ nickname_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Nickname',
+ 'save_as_nickname': True,
+ 'sequence': 1,
+ 'question_type': 'char_box',
+ })
+ text_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Text Question',
+ 'sequence': 2,
+ 'question_type': 'char_box',
+ })
+ date_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Date Question',
+ 'sequence': 3,
+ 'question_type': 'date',
+ })
+ datetime_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Datetime Question',
+ 'sequence': 4,
+ 'question_type': 'datetime',
+ })
+ simple_choice_answer_1 = self.env['survey.question.answer'].create({
+ 'value': 'First'
+ })
+ simple_choice_answer_2 = self.env['survey.question.answer'].create({
+ 'value': 'Second'
+ })
+ simple_choice_answer_3 = self.env['survey.question.answer'].create({
+ 'value': 'Third'
+ })
+ simple_choice_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Regular Simple Choice',
+ 'sequence': 5,
+ 'question_type': 'simple_choice',
+ 'suggested_answer_ids': [
+ (4, simple_choice_answer_1.id),
+ (4, simple_choice_answer_2.id),
+ (4, simple_choice_answer_3.id)],
+ })
+ scored_choice_answer_1 = self.env['survey.question.answer'].create({
+ 'value': 'Correct',
+ 'is_correct': True,
+ 'answer_score': 30
+ })
+ scored_choice_answer_2 = self.env['survey.question.answer'].create({
+ 'value': 'Incorrect 1'
+ })
+ scored_choice_answer_3 = self.env['survey.question.answer'].create({
+ 'value': 'Incorrect 2'
+ })
+ scored_choice_answer_4 = self.env['survey.question.answer'].create({
+ 'value': 'Incorrect 3'
+ })
+ scored_choice_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Scored Simple Choice',
+ 'sequence': 6,
+ 'question_type': 'simple_choice',
+ 'suggested_answer_ids': [
+ (4, scored_choice_answer_1.id),
+ (4, scored_choice_answer_2.id),
+ (4, scored_choice_answer_3.id),
+ (4, scored_choice_answer_4.id)],
+ })
+ timed_scored_choice_answer_1 = self.env['survey.question.answer'].create({
+ 'value': 'Correct',
+ 'is_correct': True,
+ 'answer_score': 30
+ })
+ timed_scored_choice_answer_2 = self.env['survey.question.answer'].create({
+ 'value': 'Also correct but less points',
+ 'is_correct': True,
+ 'answer_score': 10
+ })
+ timed_scored_choice_answer_3 = self.env['survey.question.answer'].create({
+ 'value': 'Incorrect',
+ 'answer_score': -40
+ })
+ timed_scored_choice_question = self.env['survey.question'].create({
+ 'survey_id': survey_session.id,
+ 'title': 'Timed Scored Multiple Choice',
+ 'sequence': 6,
+ 'question_type': 'multiple_choice',
+ 'is_time_limited': True,
+ 'time_limit': 1,
+ 'suggested_answer_ids': [
+ (4, timed_scored_choice_answer_1.id),
+ (4, timed_scored_choice_answer_2.id),
+ (4, timed_scored_choice_answer_3.id)],
+ })
+
+ # =======================
+ # PART 1 : CREATE SESSION
+ # =======================
+
+ self.start_tour('/web', 'test_survey_session_create_tour', login='admin')
+
+ # tricky part: we only take into account answers created after the session_start_time
+ # the create_date of the answers we just saved is set to the beginning of the test.
+ # but the session_start_time is set after that.
+ # So we cheat on the session start date to be able to count answers properly.
+ survey_session.write({'session_start_time': test_start_time - relativedelta(minutes=10)})
+
+ attendee_1 = survey_session._create_answer()
+ attendee_2 = survey_session._create_answer()
+ attendee_3 = survey_session._create_answer()
+ all_attendees = [attendee_1, attendee_2, attendee_3]
+
+ self.assertEqual('ready', survey_session.session_state)
+ self.assertTrue(all(attendee.is_session_answer for attendee in all_attendees),
+ "Created answers should be within the session.")
+ self.assertTrue(all(attendee.state == 'new' for attendee in all_attendees),
+ "Created answers should be in the 'new' state.")
+
+ # =========================================
+ # PART 2 : OPEN SESSION AND CHECK ATTENDEES
+ # =========================================
+
+ self.start_tour('/web', 'test_survey_session_start_tour', login='admin')
+
+ self.assertEqual('in_progress', survey_session.session_state)
+ self.assertTrue(bool(survey_session.session_start_time))
+
+ # ========================================
+ # PART 3 : CREATE ANSWERS & MANAGE SESSION
+ # ========================================
+
+ # create a few answers beforehand to avoid having to back and forth too
+ # many times between the tours and the python test
+
+ attendee_1.save_lines(nickname_question, 'xxxTheBestxxx')
+ attendee_2.save_lines(nickname_question, 'azerty')
+ attendee_3.save_lines(nickname_question, 'nicktalope')
+ self.assertEqual('xxxTheBestxxx', attendee_1.nickname)
+ self.assertEqual('azerty', attendee_2.nickname)
+ self.assertEqual('nicktalope', attendee_3.nickname)
+
+ attendee_1.save_lines(text_question, 'Attendee 1 is the best')
+ attendee_2.save_lines(text_question, 'Attendee 2 rulez')
+ attendee_3.save_lines(text_question, 'Attendee 3 will crush you')
+ attendee_1.save_lines(date_question, '2010-10-10')
+ attendee_2.save_lines(date_question, '2011-11-11')
+ attendee_2.save_lines(datetime_question, '2010-10-10 10:00:00')
+ attendee_3.save_lines(datetime_question, '2011-11-11 15:55:55')
+ attendee_1.save_lines(simple_choice_question, simple_choice_answer_1.id)
+ attendee_2.save_lines(simple_choice_question, simple_choice_answer_1.id)
+ attendee_3.save_lines(simple_choice_question, simple_choice_answer_2.id)
+ attendee_1.save_lines(scored_choice_question, scored_choice_answer_1.id)
+ attendee_2.save_lines(scored_choice_question, scored_choice_answer_2.id)
+ attendee_3.save_lines(scored_choice_question, scored_choice_answer_3.id)
+ attendee_1.save_lines(timed_scored_choice_question,
+ [timed_scored_choice_answer_1.id, timed_scored_choice_answer_3.id])
+ attendee_2.save_lines(timed_scored_choice_question,
+ [timed_scored_choice_answer_1.id, timed_scored_choice_answer_2.id])
+ attendee_3.save_lines(timed_scored_choice_question,
+ [timed_scored_choice_answer_2.id])
+
+ self.start_tour('/web', 'test_survey_session_manage_tour', login='admin')
+
+ self.assertFalse(bool(survey_session.session_state))
+ self.assertTrue(all(answer.state == 'done' for answer in all_attendees))
diff --git a/addons/survey/views/assets.xml b/addons/survey/views/assets.xml
index 19aaac1a2a0..a05c8f9340e 100644
--- a/addons/survey/views/assets.xml
+++ b/addons/survey/views/assets.xml
@@ -58,6 +58,11 @@
<script type="text/javascript" src="/survey/static/tests/tours/certification_success.js"></script>
<script type="text/javascript" src="/survey/static/tests/tours/survey.js"></script>
<script type="text/javascript" src="/survey/static/tests/tours/survey_prefill.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_tools.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_create.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_start.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_tour_session_manage.js"></script>
+ <script type="text/javascript" src="/survey/static/tests/tours/survey_session_manage_test.js"></script>
</xpath>
</template>
</data>