[IMP] project: add project updates tests
This commit adds project update tests. PR : #68899 task-2393768
This commit is contained in:
@@ -80,6 +80,9 @@
|
||||
],
|
||||
'web.qunit_suite_tests': [
|
||||
'project/static/tests/burndown_chart_tests.js',
|
||||
]
|
||||
],
|
||||
'web.assets_tests': [
|
||||
'project/static/tests/tours/**/*',
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,139 @@
|
||||
/** @odoo-module **/
|
||||
|
||||
import tour from 'web_tour.tour';
|
||||
|
||||
tour.register('project_update_tour', {
|
||||
test: true,
|
||||
url: '/web',
|
||||
},
|
||||
[tour.stepUtils.showAppsMenuItem(), {
|
||||
trigger: '.o_app[data-menu-xmlid="project.menu_main_pm"]',
|
||||
}, {
|
||||
trigger: '.o-kanban-button-new',
|
||||
extra_trigger: '.o_project_kanban',
|
||||
width: 200,
|
||||
}, {
|
||||
trigger: 'input.o_project_name',
|
||||
run: 'text New Project'
|
||||
}, {
|
||||
trigger: '.o_open_tasks',
|
||||
run: function (actions) {
|
||||
actions.auto('.modal:visible .btn.btn-primary');
|
||||
},
|
||||
}, {
|
||||
trigger: ".o_kanban_project_tasks .o_column_quick_create .input-group",
|
||||
run: function (actions) {
|
||||
actions.text("New", this.$anchor.find("input"));
|
||||
},
|
||||
}, {
|
||||
trigger: ".o_kanban_project_tasks .o_column_quick_create .o_kanban_add",
|
||||
auto: true,
|
||||
}, {
|
||||
trigger: ".o_kanban_project_tasks .o_column_quick_create .input-group",
|
||||
extra_trigger: '.o_kanban_group',
|
||||
run: function (actions) {
|
||||
actions.text("Done", this.$anchor.find("input"));
|
||||
},
|
||||
}, {
|
||||
trigger: ".o_kanban_project_tasks .o_column_quick_create .o_kanban_add",
|
||||
auto: true,
|
||||
}, {
|
||||
trigger: '.o-kanban-button-new',
|
||||
extra_trigger: '.o_kanban_group:eq(0)'
|
||||
}, {
|
||||
trigger: '.o_kanban_quick_create input.o_field_char[name=name]',
|
||||
extra_trigger: '.o_kanban_project_tasks',
|
||||
run: 'text New task'
|
||||
}, {
|
||||
trigger: '.o_kanban_quick_create .o_kanban_add',
|
||||
extra_trigger: '.o_kanban_project_tasks'
|
||||
}, {
|
||||
trigger: '.o-kanban-button-new',
|
||||
extra_trigger: '.o_kanban_group:eq(0)'
|
||||
}, {
|
||||
trigger: '.o_kanban_quick_create input.o_field_char[name=name]',
|
||||
extra_trigger: '.o_kanban_project_tasks',
|
||||
run: 'text Second task'
|
||||
}, {
|
||||
trigger: '.o_kanban_quick_create .o_kanban_add',
|
||||
extra_trigger: '.o_kanban_project_tasks'
|
||||
}, {
|
||||
trigger: '.o_kanban_header:eq(1)',
|
||||
run: function () {
|
||||
$('.o_kanban_config.dropdown .dropdown-toggle').eq(1).click();
|
||||
}
|
||||
}, {
|
||||
trigger: ".dropdown-item.o_column_edit",
|
||||
}, {
|
||||
trigger: ".o_field_widget[name=fold] input",
|
||||
}, {
|
||||
trigger: ".modal-footer button",
|
||||
}, {
|
||||
trigger: ".o_kanban_record .oe_kanban_content",
|
||||
extra_trigger: '.o_kanban_project_tasks',
|
||||
run: "drag_and_drop .o_kanban_group:eq(1) ",
|
||||
}, {
|
||||
trigger: ".o_project_updates_breadcrumb",
|
||||
}, {
|
||||
trigger: ".o_add_milestone a",
|
||||
}, {
|
||||
trigger: "input.o_field_widget[name=name]",
|
||||
run: 'text New milestone'
|
||||
}, {
|
||||
trigger: "input.datetimepicker-input[name=deadline]",
|
||||
run: 'text 12/12/2099'
|
||||
}, {
|
||||
trigger: ".modal-footer button"
|
||||
}, {
|
||||
trigger: ".o_add_milestone a",
|
||||
}, {
|
||||
trigger: "input.o_field_widget[name=name]",
|
||||
run: 'text Second milestone'
|
||||
}, {
|
||||
trigger: "input.datetimepicker-input[name=deadline]",
|
||||
run: 'text 12/12/2021'
|
||||
}, {
|
||||
trigger: ".modal-footer button"
|
||||
}, {
|
||||
trigger: ".o_rightpanel_left_button:eq(0)"
|
||||
}, {
|
||||
trigger: ".breadcrumb :contains('Tasks Analysis')",
|
||||
}, {
|
||||
trigger: ".o_back_button"
|
||||
}, {
|
||||
trigger: ".o_rightpanel_left_button:eq(1)"
|
||||
}, {
|
||||
trigger: ".breadcrumb :contains('Burndown Chart')",
|
||||
}, {
|
||||
trigger: ".o_back_button"
|
||||
}, {
|
||||
trigger: ".o_open_milestone:eq(1) .o_milestone_detail span:eq(0)",
|
||||
extra_trigger: ".o_add_milestone a"
|
||||
}, {
|
||||
trigger: "input.datetimepicker-input[name=deadline]",
|
||||
run: 'text 12/12/2100'
|
||||
}, {
|
||||
trigger: ".modal-footer button"
|
||||
}, {
|
||||
trigger: ".o-kanban-button-new"
|
||||
}, {
|
||||
trigger: "input.o_field_widget[name=name]",
|
||||
run: 'text New update'
|
||||
}, {
|
||||
trigger: ".o_form_button_save"
|
||||
}, {
|
||||
trigger: ".o_field_widget[name=description] :contains('1 tasks are open, out of 2.')",
|
||||
run: function () {},
|
||||
}, {
|
||||
trigger: ".o_field_widget[name=description] :contains('2 were created')",
|
||||
run: function () {},
|
||||
}, {
|
||||
trigger: ".o_field_widget[name=description] :contains('1 was closed')",
|
||||
run: function () {},
|
||||
}, {
|
||||
trigger: ".o_field_widget[name=description] :contains('New milestone') :contains('(due on 12/12/2100)')",
|
||||
run: function () {},
|
||||
}, {
|
||||
trigger: ".o_field_widget[name=description] :contains('New milestone') :contains('(12/12/2099 => 12/12/2100)')",
|
||||
run: function () {},
|
||||
}]);
|
||||
@@ -7,6 +7,9 @@ from . import test_project_flow
|
||||
from . import test_project_recurrence
|
||||
from . import test_project_subtasks
|
||||
from . import test_project_ui
|
||||
from . import test_project_update_access_rights
|
||||
from . import test_project_update_flow
|
||||
from . import test_project_update_ui
|
||||
from . import test_portal
|
||||
from . import test_multicompany
|
||||
from . import test_task_dependencies
|
||||
|
||||
@@ -0,0 +1,56 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo.exceptions import AccessError
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import users
|
||||
|
||||
from odoo.addons.mail.tests.common import mail_new_test_user
|
||||
from odoo.addons.project.tests.test_project_base import TestProjectCommon
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestProjectUpdateAccessRights(TestProjectCommon):
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
super(TestProjectUpdateAccessRights, cls).setUpClass()
|
||||
cls.project_update_1 = cls.env['project.update'].create({
|
||||
'name': "Test Project Update",
|
||||
'project_id': cls.project_pigs.id,
|
||||
'status': 'on_track',
|
||||
})
|
||||
cls.base_user = mail_new_test_user(cls.env, 'Base user', groups='base.group_user')
|
||||
cls.project_user = mail_new_test_user(cls.env, 'Project user', groups='project.group_project_user')
|
||||
cls.project_manager = mail_new_test_user(cls.env, 'Project admin', groups='project.group_project_manager')
|
||||
|
||||
@users('Project user', 'Project admin', 'Base user')
|
||||
def test_project_update_user_can_read(self):
|
||||
self.project_update_1.with_user(self.env.user).name
|
||||
|
||||
@users('Project user', 'Base user')
|
||||
def test_project_update_user_no_write(self):
|
||||
with self.assertRaises(AccessError, msg="%s should not be able to write in the project update" % self.env.user.name):
|
||||
self.project_update_1.with_user(self.env.user).name = "Test write"
|
||||
|
||||
@users('Project admin')
|
||||
def test_project_update_admin_can_write(self):
|
||||
self.project_update_1.with_user(self.env.user).name = "Test write"
|
||||
|
||||
@users('Project user')
|
||||
def test_project_update_user_project_owner_cannot_write(self):
|
||||
self.project_pigs.user_id = self.env.user
|
||||
with self.assertRaises(AccessError, msg="%s, who owns the project, should not be able to write in the project update" % self.env.user.name):
|
||||
self.project_update_1.with_user(self.env.user).name = "Test write"
|
||||
|
||||
@users('Project user', 'Base user')
|
||||
def test_project_update_user_no_unlink(self):
|
||||
with self.assertRaises(AccessError, msg="%s should not be able to unlink in the project update" % self.env.user.name):
|
||||
self.project_update_1.with_user(self.env.user).unlink()
|
||||
|
||||
@users('Project admin')
|
||||
def test_project_update_admin_unlink(self):
|
||||
self.project_update_1.with_user(self.env.user).unlink()
|
||||
|
||||
@users('Project user')
|
||||
def test_project_update_user_project_owner_no_unlink(self):
|
||||
self.project_pigs.user_id = self.env.user
|
||||
with self.assertRaises(AccessError, msg="%s should not be able to unlink the project update even if project owner" % self.env.user.name):
|
||||
self.project_update_1.with_user(self.env.user).unlink()
|
||||
@@ -0,0 +1,82 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from dateutil.relativedelta import relativedelta
|
||||
|
||||
from odoo import fields
|
||||
from odoo.tests import tagged
|
||||
from odoo.tests.common import Form
|
||||
|
||||
from odoo.addons.project.tests.test_project_base import TestProjectCommon
|
||||
|
||||
@tagged('-at_install', 'post_install')
|
||||
class TestProjectUpdate(TestProjectCommon):
|
||||
|
||||
def test_project_update_form(self):
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 1"
|
||||
milestone_form.deadline = fields.Date.today()
|
||||
|
||||
try:
|
||||
with Form(self.env['project.update'].with_context({'default_project_id': self.project_pigs.id})) as update_form:
|
||||
update_form.name = "Test"
|
||||
update_form.progress = 65
|
||||
update = update_form.save()
|
||||
except Exception as e:
|
||||
raise AssertionError("Error raised unexpectedly while filling the project update form ! Exception : " + e.args[0])
|
||||
|
||||
self.assertEqual(update.user_id, self.env.user, "The author is the user who created the update.")
|
||||
self.assertNotEqual(len(update.description), 0, "The description should not be empty.")
|
||||
self.assertTrue("Tasks" in update.description, "The description should contain 'Tasks'.")
|
||||
self.assertTrue("Milestone" in update.description, "The description should contain 'Milestone'.")
|
||||
self.assertEqual(update.status, 'on_track', "The status should be the default one.")
|
||||
|
||||
with Form(self.env['project.update'].with_context({'default_project_id': self.project_pigs.id})) as update_form:
|
||||
update_form.name = "Test 2"
|
||||
update = update_form.save()
|
||||
self.assertEqual(update.progress, 65, "The default progress is the one from the previous update by default")
|
||||
|
||||
def test_project_update_description(self):
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 1"
|
||||
milestone_form.deadline = fields.Date.today()
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 2"
|
||||
milestone_form.deadline = fields.Date.today()
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 3"
|
||||
milestone_form.deadline = fields.Date.today() + relativedelta(years=2)
|
||||
|
||||
template_values = self.env['project.update']._get_template_values(self.project_pigs)
|
||||
|
||||
self.assertEqual(template_values['tasks']['open_tasks'], 2, "Open tasks should be equal to 2")
|
||||
self.assertEqual(template_values['tasks']['total_tasks'], 2, "Total tasks should be equal to 2")
|
||||
self.assertEqual(template_values['tasks']['created_tasks'], 2, "Created tasks should be equal to 2")
|
||||
self.assertEqual(template_values['tasks']['closed_tasks'], 0, "Closed tasks should be equal to 0")
|
||||
|
||||
self.assertEqual(len(template_values['milestones']['list']), 2, "Milestone list length should be equal to 2")
|
||||
self.assertEqual(len(template_values['milestones']['created']), 3, "Milestone created length tasks should be equal to 3")
|
||||
|
||||
def test_project_update_panel(self):
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 1"
|
||||
milestone_form.deadline = fields.Date.today() + relativedelta(years=-1)
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 2"
|
||||
milestone_form.deadline = fields.Date.today() + relativedelta(years=-1)
|
||||
milestone_form.is_reached = True
|
||||
with Form(self.env['project.milestone'].with_context({'default_project_id': self.project_pigs.id})) as milestone_form:
|
||||
milestone_form.name = "Test 3"
|
||||
milestone_form.deadline = fields.Date.today() + relativedelta(years=2)
|
||||
|
||||
panel_data = self.project_pigs.get_panel_data()
|
||||
|
||||
self.assertEqual(len(panel_data['tasks_analysis']['data']), 2, "Panel data should contain 'tasks' entry")
|
||||
self.assertEqual(len(panel_data['milestones']['data']), 3, "Panel data should contain 'milestone' entry")
|
||||
self.assertFalse(panel_data['milestones']['data'][0]['is_deadline_exceeded'], "Milestone is achieved")
|
||||
self.assertTrue(panel_data['milestones']['data'][1]['is_deadline_exceeded'], "Milestone is exceeded")
|
||||
self.assertTrue(panel_data['milestones']['data'][0]['is_reached'], "Milestone is done")
|
||||
self.assertFalse(panel_data['milestones']['data'][1]['is_reached'], "Milestone isn't done")
|
||||
# sorting
|
||||
self.assertEqual(panel_data['milestones']['data'][0]['name'], "Test 2", "Sorting isn't correct")
|
||||
self.assertEqual(panel_data['milestones']['data'][1]['name'], "Test 1", "Sorting isn't correct")
|
||||
self.assertEqual(panel_data['milestones']['data'][2]['name'], "Test 3", "Sorting isn't correct")
|
||||
@@ -0,0 +1,9 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from odoo.tests import HttpCase, tagged
|
||||
|
||||
@tagged('post_install', '-at_install')
|
||||
class TestProjectUpdateUi(HttpCase):
|
||||
|
||||
def test_01_project_tour(self):
|
||||
self.start_tour("/web", 'project_update_tour', login="admin")
|
||||
Reference in New Issue
Block a user