58263f6ea8a72cbb1da78a7408270cf241c11866
[odoo/odoo.git] / addons / project / tests / test_project_flow.py
1 # -*- coding: utf-8 -*-
2 ##############################################################################
3 #
4 #    OpenERP, Open Source Business Applications
5 #    Copyright (c) 2013-TODAY OpenERP S.A. <http://www.openerp.com>
6 #
7 #    This program is free software: you can redistribute it and/or modify
8 #    it under the terms of the GNU Affero General Public License as
9 #    published by the Free Software Foundation, either version 3 of the
10 #    License, or (at your option) any later version.
11 #
12 #    This program is distributed in the hope that it will be useful,
13 #    but WITHOUT ANY WARRANTY; without even the implied warranty of
14 #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 #    GNU Affero General Public License for more details.
16 #
17 #    You should have received a copy of the GNU Affero General Public License
18 #    along with this program.  If not, see <http://www.gnu.org/licenses/>.
19 #
20 ##############################################################################
21
22 from openerp.addons.project.tests.test_project_base import TestProjectBase
23 from openerp.exceptions import AccessError
24 from openerp.tools import mute_logger
25
26
27 EMAIL_TPL = """Return-Path: <whatever-2a840@postmaster.twitter.com>
28 X-Original-To: {email_to}
29 Delivered-To: {email_to}
30 To: {email_to}
31 Received: by mail1.openerp.com (Postfix, from userid 10002)
32     id 5DF9ABFB2A; Fri, 10 Aug 2012 16:16:39 +0200 (CEST)
33 Message-ID: {msg_id}
34 Date: Tue, 29 Nov 2011 12:43:21 +0530
35 From: {email_from}
36 MIME-Version: 1.0
37 Subject: {subject}
38 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
39
40 Hello,
41
42 This email should create a new entry in your module. Please check that it
43 effectively works.
44
45 Thanks,
46
47 --
48 Raoul Boitempoils
49 Integrator at Agrolait"""
50
51
52 class TestProjectFlow(TestProjectBase):
53
54     @mute_logger('openerp.addons.base.ir.ir_model', 'openerp.models')
55     def test_00_project_process(self):
56         """ Testing project management """
57         cr, uid, user_projectuser_id, user_projectmanager_id, project_pigs_id = self.cr, self.uid, self.user_projectuser_id, self.user_projectmanager_id, self.project_pigs_id
58
59         # ProjectUser: set project as template -> raise
60         self.assertRaises(AccessError, self.project_project.set_template, cr, user_projectuser_id, [project_pigs_id])
61
62         # Other tests are done using a ProjectManager
63         project = self.project_project.browse(cr, user_projectmanager_id, project_pigs_id)
64         self.assertNotEqual(project.state, 'template', 'project: incorrect state, should not be a template')
65
66         # Set test project as template
67         self.project_project.set_template(cr, user_projectmanager_id, [project_pigs_id])
68         project.refresh()
69         self.assertEqual(project.state, 'template', 'project: set_template: project state should be template')
70         self.assertEqual(len(project.tasks), 0, 'project: set_template: project tasks should have been set inactive')
71
72         # Duplicate template
73         new_template_act = self.project_project.duplicate_template(cr, user_projectmanager_id, [project_pigs_id])
74         new_project = self.project_project.browse(cr, user_projectmanager_id, new_template_act['res_id'])
75         self.assertEqual(new_project.state, 'open', 'project: incorrect duplicate_template')
76         self.assertEqual(len(new_project.tasks), 2, 'project: duplicating a project template should duplicate its tasks')
77
78         # Convert into real project
79         self.project_project.reset_project(cr, user_projectmanager_id, [project_pigs_id])
80         project.refresh()
81         self.assertEqual(project.state, 'open', 'project: resetted project should be in open state')
82         self.assertEqual(len(project.tasks), 2, 'project: reset_project: project tasks should have been set active')
83
84         # Put as pending
85         self.project_project.set_pending(cr, user_projectmanager_id, [project_pigs_id])
86         project.refresh()
87         self.assertEqual(project.state, 'pending', 'project: should be in pending state')
88
89         # Re-open
90         self.project_project.set_open(cr, user_projectmanager_id, [project_pigs_id])
91         project.refresh()
92         self.assertEqual(project.state, 'open', 'project: reopened project should be in open state')
93
94         # Close project
95         self.project_project.set_done(cr, user_projectmanager_id, [project_pigs_id])
96         project.refresh()
97         self.assertEqual(project.state, 'close', 'project: closed project should be in close state')
98
99         # Re-open
100         self.project_project.set_open(cr, user_projectmanager_id, [project_pigs_id])
101         project.refresh()
102
103         # Re-convert into a template and schedule tasks
104         self.project_project.set_template(cr, user_projectmanager_id, [project_pigs_id])
105         self.project_project.schedule_tasks(cr, user_projectmanager_id, [project_pigs_id])
106
107         # Copy the project
108         new_project_id = self.project_project.copy(cr, user_projectmanager_id, project_pigs_id)
109         new_project = self.project_project.browse(cr, user_projectmanager_id, new_project_id)
110         self.assertEqual(len(new_project.tasks), 2, 'project: copied project should have copied task')
111
112         # Cancel the project
113         self.project_project.set_cancel(cr, user_projectmanager_id, [project_pigs_id])
114         self.assertEqual(project.state, 'cancelled', 'project: cancelled project should be in cancel state')
115
116     def test_10_task_process(self):
117         """ Testing task creation and management """
118         cr, uid, user_projectuser_id, user_projectmanager_id, project_pigs_id = self.cr, self.uid, self.user_projectuser_id, self.user_projectmanager_id, self.project_pigs_id
119
120         def format_and_process(template, email_to='project+pigs@mydomain.com, other@gmail.com', subject='Frogs',
121                                email_from='Patrick Ratatouille <patrick.ratatouille@agrolait.com>',
122                                msg_id='<1198923581.41972151344608186760.JavaMail@agrolait.com>'):
123             self.assertEqual(self.project_task.search(cr, uid, [('name', '=', subject)]), [])
124             mail = template.format(email_to=email_to, subject=subject, email_from=email_from, msg_id=msg_id)
125             self.mail_thread.message_process(cr, uid, None, mail)
126             return self.project_task.search(cr, uid, [('name', '=', subject)])
127
128         # Do: incoming mail from an unknown partner on an alias creates a new task 'Frogs'
129         frogs = format_and_process(EMAIL_TPL)
130
131         # Test: one task created by mailgateway administrator
132         self.assertEqual(len(frogs), 1, 'project: message_process: a new project.task should have been created')
133         task = self.project_task.browse(cr, user_projectuser_id, frogs[0])
134         res = self.project_task.get_metadata(cr, uid, [task.id])[0].get('create_uid') or [None]
135         self.assertEqual(res[0], uid,
136                          'project: message_process: task should have been created by uid as alias_user_id is False on the alias')
137         # Test: messages
138         self.assertEqual(len(task.message_ids), 3,
139                          'project: message_process: newly created task should have 2 messages: creation and email')
140         self.assertEqual(task.message_ids[2].subtype_id.name, 'Task Created',
141                          'project: message_process: first message of new task should have Task Created subtype')
142         self.assertEqual(task.message_ids[1].subtype_id.name, 'Task Assigned',
143                          'project: message_process: first message of new task should have Task Created subtype')
144         self.assertEqual(task.message_ids[0].author_id.id, self.email_partner_id,
145                          'project: message_process: second message should be the one from Agrolait (partner failed)')
146         self.assertEqual(task.message_ids[0].subject, 'Frogs',
147                          'project: message_process: second message should be the one from Agrolait (subject failed)')
148         # Test: task content
149         self.assertEqual(task.name, 'Frogs', 'project_task: name should be the email subject')
150         self.assertEqual(task.project_id.id, self.project_pigs_id, 'project_task: incorrect project')
151         self.assertEqual(task.stage_id.sequence, 1, 'project_task: should have a stage with sequence=1')
152
153         # Open the delegation wizard
154         delegate_id = self.project_task_delegate.create(cr, user_projectuser_id, {
155             'user_id': user_projectuser_id,
156             'planned_hours': 12.0,
157             'planned_hours_me': 2.0,
158         }, {'active_id': task.id})
159         self.project_task_delegate.delegate(cr, user_projectuser_id, [delegate_id], {'active_id': task.id})
160
161         # Check delegation details
162         task.refresh()
163         self.assertEqual(task.planned_hours, 2, 'project_task_delegate: planned hours is not correct after delegation')