19.0 vanilla

This commit is contained in:
Ernad Husremovic 2026-03-09 09:31:00 +01:00
parent a1137a1456
commit e1d89e11e3
2789 changed files with 1093187 additions and 605897 deletions

View file

@ -2,6 +2,8 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from . import test_recruitment_process
from . import test_recruitment_talent_pools
from . import test_recruitment
from . import test_utm
from . import test_recruitment_interviewer
from . import test_recruitment_allowed_user_ids

View file

@ -1,71 +1,494 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import tagged, TransactionCase
import base64
from odoo import Command
from odoo.fields import Domain
from odoo.tests import tagged, TransactionCase, Form
@tagged('recruitment')
class TestRecruitment(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.company = cls.env['res.company'].create({
'name': 'Company Test',
'country_id': cls.env.ref('base.us').id,
})
cls.env.user.company_id = cls.company
cls.env.user.company_ids = [Command.set(cls.company.ids)]
cls.TEXT = base64.b64encode(bytes("hr_recruitment", 'utf-8'))
cls.Attachment = cls.env['ir.attachment']
def test_infer_applicant_lang_from_context(self):
# Prerequisites
self.env['res.lang']._activate_lang('pl_PL')
self.env['res.lang']._activate_lang('en_US')
self.env['ir.default'].set('res.partner', 'lang', 'en_US')
# Creating an applicant will create a partner (email_from inverse)
applicant = self.env['hr.applicant'].sudo().with_context(lang='pl_PL').create({
'partner_name': 'Test Applicant',
'email_from': "test_aplicant@example.com"
})
self.assertEqual(applicant.partner_id.lang, 'pl_PL', 'Context langague not used for partner creation')
def test_duplicate_email(self):
# Tests that duplicate email match ignores case
# And that no match is found when there is none
# Tests that duplicate email matching is case insesitive
dup1, dup2, no_dup = self.env['hr.applicant'].create([
{
'name': 'Application 1',
'partner_name': 'Application 1',
'email_from': 'laurie.poiret@aol.ru',
},
{
'name': 'Application 2',
'partner_name': 'Application 2',
'email_from': 'laurie.POIRET@aol.ru',
},
{
'name': 'Application 3',
'partner_name': 'Application 3',
'email_from': 'laure.poiret@aol.ru',
},
])
self.assertEqual(dup1.application_count, 1)
self.assertEqual(dup2.application_count, 1)
self.assertEqual(no_dup.application_count, 0)
self.assertEqual(dup1.application_count, 2)
self.assertEqual(dup2.application_count, 2)
self.assertEqual(no_dup.application_count, 1)
def test_application_count(self):
""" Test that we find same applicants based on simmilar mail,
phone or mobile phone.
"""
A, B, C, D, E, F = self.env['hr.applicant'].create([
def test_similar_applicants_count(self):
"""Test that we find same applicant based on simmilar mail or phone."""
A, B, C, D, E, F, _ = self.env['hr.applicant'].create([
{
'name': 'Application A',
'active': False, # Refused/archived application should still count
'partner_name': 'Application A',
'email_from': 'abc@odoo.com',
'partner_phone': '123',
'partner_mobile': '14-15-16',
},
{
'name': 'Application B',
'partner_name': 'Application B',
'partner_phone': '456',
'partner_mobile': '11-12-13',
},
{
'name': 'Application C',
'partner_name': 'Application C',
'email_from': 'def@odoo.com',
'partner_phone': '123',
'partner_mobile': '14-15-16',
},
{
'name': 'Application D',
'email_from': 'def@odoo.com',
'partner_name': 'Application D',
'email_from': 'abc@odoo.com',
'partner_phone': '456',
'partner_mobile': '14-15-16',
},
{
'name': 'Application E',
'partner_name': 'Application E',
'partner_phone': '',
},
{
'name': 'Application F',
'partner_phone': '11-12-13', # In case phone is configured in a wrong field
}
'partner_name': 'Application F',
'email_from': 'ghi@odoo.com',
'partner_phone': '789',
},
{
'partner_name': 'Application G',
},
])
self.assertEqual(A.application_count, 2) # C, D
self.assertEqual(B.application_count, 2) # D, F
self.assertEqual(C.application_count, 2) # A, D
self.assertEqual(D.application_count, 3) # A, B, C
self.assertEqual(E.application_count, 0)
self.assertEqual(F.application_count, 1) # B
self.assertEqual(A.application_count, 3) # A, C, D
self.assertEqual(B.application_count, 2) # B, D
self.assertEqual(C.application_count, 2) # C, A
self.assertEqual(D.application_count, 3) # D, A, B
self.assertEqual(E.application_count, 0) # Should not match with E and G as there is no data to use for matching.
self.assertEqual(F.application_count, 1) # F
def test_talent_pool_count(self):
tp_A, tp_B = self.env["hr.talent.pool"].create([{"name": "Cool Pool"}, {"name": "Other Pool"}])
t_A, t_B = self.env["hr.applicant"].create(
[
{
"partner_name": "Talent A",
"email_from": "abc@example.com",
"partner_phone": "1234",
"linkedin_profile": "linkedin/talent",
"talent_pool_ids": [tp_A.id, tp_B.id],
},
{
"partner_name": "Talent B",
"email_from": "talent_b@example.com",
"partner_phone": "9999",
"talent_pool_ids": [tp_B.id],
},
]
)
# The only way to create a talent is through the wizards. Talents that are
# created through the wizard also assign their own ID as pool_applicant_id
t_A.pool_applicant_id = t_A.id
t_B.pool_applicant_id = t_B.id
A, B, C, D, E, F, G = self.env["hr.applicant"].create(
[
{"partner_name": "A", "pool_applicant_id": t_A.id},
{
"partner_name": "B",
"email_from": "def@example.com",
"partner_phone": "6789",
"linkedin_profile": "linkedin/b",
"pool_applicant_id": t_A.id,
},
{
"partner_name": "C",
"email_from": "def@example.com",
},
{
"partner_name": "D",
"partner_phone": "6789",
},
{
"partner_name": "E",
"linkedin_profile": "linkedin/b",
},
{
"partner_name": "F",
"email_from": "not_linked@example.com",
"partner_phone": "00000",
"linkedin_profile": "linkedin/not_linked",
},
{"partner_name": "G", "pool_applicant_id": t_B.id},
]
)
self.assertEqual(t_A.talent_pool_count, 2)
self.assertEqual(t_B.talent_pool_count, 1)
self.assertEqual(A.talent_pool_count, 2)
self.assertEqual(B.talent_pool_count, 2)
self.assertEqual(C.talent_pool_count, 2)
self.assertEqual(D.talent_pool_count, 2)
self.assertEqual(E.talent_pool_count, 2)
self.assertEqual(F.talent_pool_count, 0)
self.assertEqual(G.talent_pool_count, 1)
def test_compute_and_search_is_applicant_in_pool(self):
"""
Test that the _compute_is_applicant_in_pool and _search_is_applicant_in_pool
methods return correct information.
An application is considered to be in a pool if it is either directly linked
to a pool (through pool_applicant_id or talents_pool_ids) or shares a phone number,
email or linkedin with another directly linked application.
"""
talent_pool = self.env["hr.talent.pool"].create({"name": "Cool Pool"})
job = self.env["hr.job"].create(
{
"name": "Cool Job",
}
)
A, B, C, D, E, F, G, H = self.env["hr.applicant"].create(
[
{
"partner_name": "Talent A",
"email_from": "mainTalentEmail@example.com",
"talent_pool_ids": talent_pool.ids,
},
{
"partner_name": "Applicant 1 B",
"email_from": "otherTalentEmail@example.com",
"partner_phone": "1234",
"linkedin_profile": "linkedin.com/in/applicant",
"job_id": job.id,
},
{
"partner_name": "Applicant 1 C",
"email_from": "otherTalentEmail@example.com",
"job_id": job.id,
},
{
"partner_name": "Applicant 1 D",
"partner_phone": "1234",
"job_id": job.id,
},
{
"partner_name": "Applicant 1 E",
"linkedin_profile": "linkedin.com/in/applicant",
"job_id": job.id,
},
{
"partner_name": "A different applicant F",
"email_from": "differentEmail@example.com",
"partner_phone": "9876",
"linkedin_profile": "linkedin.com/in/NotAnApplicant",
"job_id": job.id,
},
{
"partner_name": "Talent With No information G",
"talent_pool_ids": talent_pool.ids,
},
{
"partner_name": "Applicant With No information H",
},
]
)
B.pool_applicant_id = A.id
H.pool_applicant_id = G.id
# Testing the compute
# A is directly linked to Cool Pool through talent_pool_ids
self.assertTrue(A.is_applicant_in_pool)
# B is directly linked to Cool Pool through pool_applicant_id
self.assertTrue(B.is_applicant_in_pool)
# C is indirectly linked through email to B who is directly linked
self.assertTrue(C.is_applicant_in_pool)
# D is indirectly linked through phone to B who is directly linked
self.assertTrue(D.is_applicant_in_pool)
# E is indirectly linked through linkedin to B who is directly linked
self.assertTrue(E.is_applicant_in_pool)
# F is not linked to a Pool
self.assertFalse(F.is_applicant_in_pool)
# G is directly linked to Cool Pool through talent_pool_ids
self.assertTrue(G.is_applicant_in_pool)
# H is directly linked to Cool Pool through pool_applicant_id
self.assertTrue(H.is_applicant_in_pool)
# Testing the search
# Note: For some reason testing the search does not work if the compute
# is not tested first which is why these two tests are in one test.
applicant = self.env["hr.applicant"]
in_pool_domain = applicant._search_is_applicant_in_pool("in", [True])
in_pool_applicants = applicant.search(Domain.AND([in_pool_domain, [("company_id", "=", self.env.company.id)]]))
out_of_pool_applicants = applicant.search(Domain.AND([~Domain(in_pool_domain), [("company_id", "=", self.env.company.id)]]))
self.assertCountEqual(in_pool_applicants, A | B | C | D | E | G | H)
self.assertCountEqual(out_of_pool_applicants, F)
def test_application_no_partner_duplicate(self):
""" Test that when applying, the existing partner
doesn't get duplicated.
"""
applicant_data = {
'partner_name': 'Test',
'email_from': 'test@thisisatest.com',
}
# First application, a partner should be created
self.env['hr.applicant'].create(applicant_data)
partner_count = self.env['res.partner'].search_count([('email', '=', 'test@thisisatest.com')])
self.assertEqual(partner_count, 1)
# Second application, no partner should be created
self.env['hr.applicant'].create(applicant_data)
partner_count = self.env['res.partner'].search_count([('email', '=', 'test@thisisatest.com')])
self.assertEqual(partner_count, 1)
def test_target_on_application_hiring(self):
"""
Test that the target is updated when hiring an applicant
"""
job = self.env['hr.job'].create({
'name': 'Test Job',
'no_of_recruitment': 1,
})
applicant = self.env['hr.applicant'].create({
'partner_name': 'Test Applicant',
'job_id': job.id,
})
stage_new = self.env['hr.recruitment.stage'].create({
'name': 'New',
'sequence': 0,
'hired_stage': False,
})
stage_hired = self.env['hr.recruitment.stage'].create({
'name': 'Hired',
'sequence': 1,
'hired_stage': True,
})
self.assertEqual(job.no_of_recruitment, 1)
applicant.stage_id = stage_hired
self.assertEqual(job.no_of_recruitment, 0)
applicant.stage_id = stage_new
self.assertEqual(job.no_of_recruitment, 1)
def test_open_refuse_applicant_wizard_without_partner_name(self):
"""Test opening the refuse wizard when the applicant has no partner_name."""
applicant = self.env['hr.applicant'].create({
'partner_phone': '123',
})
wizard = Form(self.env['applicant.get.refuse.reason'].with_context(
default_applicant_ids=[applicant.id], active_test=False))
wizard_applicant = wizard.applicant_ids[0]
self.assertFalse(wizard_applicant.partner_name)
def test_applicant_refuse_reason(self):
refuse_reason = self.env['hr.applicant.refuse.reason'].create([{'name': 'Fired'}])
app_1, app_2 = self.env['hr.applicant'].create([
{
'partner_name': 'Laurie Poiret',
'email_from': 'laurie.poiret@aol.ru',
},
{
'partner_name': 'Mitchell Admin',
'email_from': 'mitchell_admin@example.com',
},
])
applicant_get_refuse_reason = self.env['applicant.get.refuse.reason'].create([{
'refuse_reason_id': refuse_reason.id,
'applicant_ids': [app_1.id],
'duplicates': True
}])
applicant_get_refuse_reason.action_refuse_reason_apply()
self.assertFalse(self.env['hr.applicant'].search([('email_from', 'ilike', 'laurie.poiret@aol.ru')]))
self.assertEqual(
self.env['hr.applicant'].search([('email_from', 'ilike', 'mitchell_admin@example.com')]),
app_2
)
def test_applicant_refuse_mail_from_template(self):
mail_template = self.env['mail.template'].create({
'name': 'Test template',
'model_id': self.env['ir.model']._get('hr.applicant').id,
'email_from': 'test@test.test',
})
refuse_reason = self.env['hr.applicant.refuse.reason'].create({
'name': 'Not good',
})
applicant = self.env['hr.applicant'].create({
'partner_name': 'Laurie Poiret',
'email_from': 'laurie.poiret@aol.ru',
})
applicant_get_refuse_reason = self.env['applicant.get.refuse.reason'].create([{
'refuse_reason_id': refuse_reason.id,
'applicant_ids': applicant.ids,
'duplicates': True,
}])
mail_values = applicant_get_refuse_reason._prepare_mail_values(applicant)
self.assertEqual(mail_values['email_from'], self.env.user.email_formatted)
refuse_reason_template = self.env['hr.applicant.refuse.reason'].create({
'name': 'Fired',
'template_id': mail_template.id,
})
applicant_get_refuse_reason.refuse_reason_id = refuse_reason_template
mail_values = applicant_get_refuse_reason._prepare_mail_values(applicant)
self.assertEqual(mail_values['email_from'], 'test@test.test')
def test_copy_attachments_while_creating_employee(self):
"""
Test that attachments are copied when creating an employee from an applicant
"""
applicant_1 = self.env['hr.applicant'].create({
'partner_name': 'Applicant 1',
'email_from': 'test_applicant@example.com'
})
applicant_attachment = self.Attachment.create({
'datas': self.TEXT,
'name': 'textFile.txt',
'mimetype': 'text/plain',
'res_model': applicant_1._name,
'res_id': applicant_1.id
})
employee_applicant = applicant_1.create_employee_from_applicant()
self.assertTrue(employee_applicant['res_id'])
attachment_employee_applicant = self.Attachment.search([
('res_model', '=', employee_applicant['res_model']),
('res_id', '=', employee_applicant['res_id']),
])
self.assertEqual(applicant_attachment['datas'], attachment_employee_applicant['datas'])
def test_other_applications_count(self):
"""
Test that the application_count field does not change
when archiving or refusing a linked application.
"""
A1, A2, A3 = self.env["hr.applicant"].create(
[
{"partner_name": "test", "email_from": "test@example.com"},
{"partner_name": "test", "email_from": "test@example.com"},
{"partner_name": "test", "email_from": "test@example.com"},
]
)
self.assertEqual(A1.application_count, 3)
# Archive A2
A2.action_archive()
self.assertEqual(
A1.application_count,
3,
"Application_count should not change when archiving a linked application",
)
# Refuse A3
refuse_reason = self.env["hr.applicant.refuse.reason"].create([{"name": "Fired"}])
applicant_get_refuse_reason = self.env["applicant.get.refuse.reason"].create(
[
{
"refuse_reason_id": refuse_reason.id,
"applicant_ids": [A3.id],
}
]
)
applicant_get_refuse_reason.action_refuse_reason_apply()
self.assertEqual(
A1.application_count,
3,
"The other_applications_count should not change when refusing an application",
)
def test_open_other_applications_count(self):
"""
The smart button labeled 'Other Applications N' (where N represents the number of
other job applications linked to the same applicant) should, when clicked, open a list view
displaying all related applications.
This list should include both the N other applications and the current one,
resulting in a total of N + 1 records.
"""
A1, _, _ = self.env["hr.applicant"].create(
[
{"partner_name": "test", "email_from": "test@example.com"},
{"partner_name": "test", "email_from": "test@example.com"},
{"partner_name": "test", "email_from": "test@example.com"},
]
)
res = A1.action_open_applications()
self.assertEqual(len(res['domain'][0][2]), 3, "The list view should display 3 applications")
def test_applicant_modify_email_number(self):
applicant = self.env['hr.applicant'].create({
'partner_name': 'Mary Applicant',
'email_from': 'applicant@example.com',
'partner_phone': '123456789',
})
self.assertEqual(applicant.partner_id.email, 'applicant@example.com', "Email should have been set on the partner.")
self.assertEqual(applicant.partner_id.phone, '123456789', "Phone should have been set on the partner.")
applicant.email_from = 'applicant_diff@example.com'
self.assertEqual(applicant.partner_id.email, 'applicant_diff@example.com', "Email should have been updated on the partner.")
applicant.partner_phone = '987654321'
self.assertEqual(applicant.partner_id.phone, '987654321', "Phone should have been updated on the partner.")
def test_send_mail_when_refuse_applicant(self):
mail_template = self.env['mail.template'].create({
'name': 'Test template',
'model_id': self.env['ir.model']._get('hr.applicant').id,
'subject': 'Application refused: {{ object.partner_name }}',
})
refuse_reason = self.env['hr.applicant.refuse.reason'].create([{
'name': 'Not good',
'template_id': mail_template.id,
}])
app_1 = self.env['hr.applicant'].create({
'partner_name': 'Mario',
'email_from': 'super@mario.bros',
})
applicant_get_refuse_reason = self.env['applicant.get.refuse.reason'].create({
'refuse_reason_id': refuse_reason.id,
'send_mail': True,
'applicant_ids': [(6, 0, [app_1.id])],
})
applicant_get_refuse_reason._prepare_send_refusal_mails()
mail = self.env['mail.mail'].search([('subject', '=', 'Application refused: Mario')], limit=1)
self.assertEqual(mail.partner_ids, app_1.partner_id)

View file

@ -0,0 +1,70 @@
from odoo.tests import tagged, TransactionCase
@tagged('recruitment_allowed_user_ids')
class TestRecruitmentAllowedUserIds(TransactionCase):
def setUp(self):
super().setUp()
self.env = self.env(context=dict(self.env.context, tracking_disable=True))
self.company_a = self.env['res.company'].create({'name': 'Company A'})
self.company_b = self.env['res.company'].create({'name': 'Company BBS'})
# Internal user in company A
self.user_a = self.env['res.users'].create({
'name': 'User A',
'login': 'usera@test.com',
'email': 'usera@test.com',
'share': False,
'company_ids': [self.company_a.id],
'company_id': self.company_a.id,
})
# Internal user in company B
self.user_b = self.env['res.users'].create({
'name': 'User B',
'login': 'userb@test.com',
'email': 'userb@test.com',
'share': False,
'company_ids': [self.company_b.id],
'company_id': self.company_b.id,
})
def test_recruiter_user_id_with_company(self):
# Test job with company A - should allow user_a but not user_b
job_a = self.env['hr.job'].create({
'name': 'Job Position Company A',
'company_id': self.company_a.id,
})
# user_a can be set as a recruiter
job_a.user_id = self.user_a
self.assertEqual(job_a.user_id, self.user_a)
# Validate that the domain defined on hr.job.user_id contains user_a, but excludes user_b
domain = [('share', '=', False), ('company_ids', '=?', self.company_a.id)]
allowed_users = self.env['res.users'].search(domain)
self.assertIn(self.user_a, allowed_users)
self.assertNotIn(self.user_b, allowed_users)
def test_recruiter_user_id_without_company(self):
# Test job without company - should allow both users
job = self.env['hr.job'].create({
'name': 'Job Position',
'company_id': False,
})
# When company_id is False, users from *any* company are ok
domain = [('share', '=', False), ('company_ids', '=?', False)]
allowed_users = self.env['res.users'].search(domain)
self.assertIn(self.user_a, allowed_users)
self.assertIn(self.user_b, allowed_users)
# Both users should be settable as recruiter
job.user_id = self.user_a
self.assertEqual(job.user_id, self.user_a)
job.user_id = self.user_b
self.assertEqual(job.user_id, self.user_b)

View file

@ -1,12 +1,16 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.exceptions import AccessError
from odoo import fields
from odoo.exceptions import AccessError, UserError
from odoo.tests.common import new_test_user
from odoo.addons.mail.tests.common import MailCommon
from odoo.addons.mail.tests.common import MailCase
from odoo.tests import tagged
class TestRecruitmentInterviewer(MailCommon):
@tagged('recruitment_interviewer')
class TestRecruitmentInterviewer(MailCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
@ -34,55 +38,48 @@ class TestRecruitmentInterviewer(MailCommon):
"""
interviewer_group = self.env.ref('hr_recruitment.group_hr_recruitment_interviewer')
self.assertFalse(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should not be interviewer")
self.assertFalse(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should not be interviewer")
self.job.interviewer_ids = self.simple_user.ids
self.assertTrue(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should be added as interviewer")
self.assertTrue(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should be added as interviewer")
self.job.write({'interviewer_ids': [(5, 0, 0)]})
self.assertFalse(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should be removed from interviewer")
self.assertFalse(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should be removed from interviewer")
applicant = self.env['hr.applicant'].create({
'name': 'toto',
'partner_name': 'toto',
'job_id': self.job.id,
'interviewer_ids': self.simple_user.ids,
})
self.assertTrue(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should be added as interviewer")
self.assertTrue(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should be added as interviewer")
applicant.interviewer_ids = False
self.assertFalse(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should be removed from interviewer")
self.assertFalse(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should be removed from interviewer")
self.job.interviewer_ids = self.simple_user.ids
applicant.interviewer_ids = self.simple_user.ids
self.assertTrue(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should be added as interviewer")
self.assertTrue(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should be added as interviewer")
applicant.interviewer_ids = False
self.assertTrue(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should stay interviewer")
self.assertTrue(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should stay interviewer")
self.job.write({'interviewer_ids': [(5, 0, 0)]})
applicant.interviewer_ids = self.simple_user.ids
self.assertTrue(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should stay interviewer")
self.assertTrue(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should stay interviewer")
applicant.interviewer_ids = False
self.assertFalse(interviewer_group.id in self.simple_user.groups_id.ids, "Simple User should be removed from interviewer")
# A Manager should not be added to the Interviewer group
self.assertFalse(interviewer_group.id in self.manager_user.groups_id.ids, "Manager User should not be interviewer")
applicant.interviewer_ids = self.manager_user.ids
self.assertFalse(interviewer_group.id in self.manager_user.groups_id.ids, "Manager User should not be added in Interviewer group")
self.assertFalse(interviewer_group.id in self.simple_user.all_group_ids.ids, "Simple User should be removed from interviewer")
def test_interviewer_access_rights(self):
applicant = self.env['hr.applicant'].create({
'name': 'toto',
'partner_name': 'toto',
'job_id': self.job.id,
})
with self.assertRaises(AccessError):
applicant.with_user(self.interviewer_user).read()
applicant = self.env['hr.applicant'].create({
'name': 'toto',
'partner_name': 'toto',
'job_id': self.job.id,
'interviewer_ids': self.interviewer_user.ids,
@ -91,7 +88,6 @@ class TestRecruitmentInterviewer(MailCommon):
self.job.interviewer_ids = self.interviewer_user.ids
applicant = self.env['hr.applicant'].create({
'name': 'toto',
'partner_name': 'toto',
'job_id': self.job.id,
})
@ -101,32 +97,60 @@ class TestRecruitmentInterviewer(MailCommon):
applicant.with_user(self.interviewer_user).interviewer_ids = self.simple_user.ids
self.assertEqual(self.simple_user, applicant.interviewer_ids)
with self.assertRaises(AccessError):
with self.assertRaises(UserError):
applicant.with_user(self.interviewer_user).create_employee_from_applicant()
def test_interviewer_chatter(self):
self.manager_user.notification_type = 'email'
self.interviewer_user.notification_type = 'email'
def test_update_interviewer_for_multiple_applicants(self):
"""
Test that assigning interviewer to multiple applicants.
"""
interviewer_user_1 = new_test_user(self.env, 'sma',
groups='base.group_user,hr_recruitment.group_hr_recruitment_interviewer',
name='Recruitment Interviewer1', email='sma@example.com')
interviewer_user_2 = new_test_user(self.env, 'jab',
groups='base.group_user,hr_recruitment.group_hr_recruitment_interviewer',
name='Recruitment Interviewer2', email='jab@example.com')
interviewer_user_3 = new_test_user(self.env, 'aad',
groups='base.group_user,hr_recruitment.group_hr_recruitment_interviewer',
name='Recruitment Interviewer3', email='aad@example.com')
applicant = self.env['hr.applicant'].create({
'name': 'toto',
'partner_name': 'toto',
'partner_name': 'Applicant',
'job_id': self.job.id,
'interviewer_ids': self.interviewer_user.ids,
'interviewer_ids': [(6, 0, [interviewer_user_1.id])]
})
applicants = applicant + applicant.copy({'interviewer_ids': [(6, 0, [interviewer_user_2.id])]})
applicant.message_subscribe(partner_ids=[self.interviewer_user.partner_id.id])
# update interviewer to multiple applicants.
applicants.write({'interviewer_ids': [(4, interviewer_user_3.id)]})
with self.mock_mail_gateway():
message = applicant.message_post(body='A super secret message', message_type='comment', subtype_xmlid='mail.mt_comment')
# Ensure all interviewers are assigned
self.assertCountEqual(
applicants.interviewer_ids.ids, [interviewer_user_1.id, interviewer_user_2.id, interviewer_user_3.id]
)
with self.assertRaises(AccessError):
message.with_user(self.interviewer_user).read()
# Checked that notification message is created
message = self.env['mail.message'].search([('res_id', '=', applicant.id)], limit=1)
self.assertEqual(message.subject, f"You have been assigned as an interviewer for {applicant.display_name}")
try:
self._find_mail_mail_wpartners(self.interviewer_user.partner_id, None)
except AssertionError:
pass
else:
raise AssertionError('No mail.mail should be sent to members of Interviewer group')
self.assertSentEmail(self.env.user.partner_id, [self.manager_user.partner_id])
def test_update_recruiter_for_ongoing_application(self):
Application = self.env['hr.applicant']
new_manager_user = new_test_user(self.env, 'thala',
groups='base.group_user,hr_recruitment.group_hr_recruitment_manager',
name='New Recruitment Manager', email='thala@example.com')
ongoing_application = Application.create({
'job_id': self.job.id,
'user_id': self.manager_user.id,
'application_status': 'ongoing',
})
hired_application = Application.create({
'job_id': self.job.id,
'user_id': self.manager_user.id,
'date_closed': fields.Datetime.now(),
'application_status': 'hired',
})
self.job.write({'user_id': new_manager_user.id})
self.assertEqual(ongoing_application.user_id, new_manager_user)
self.assertEqual(hired_application.user_id, self.manager_user)

View file

@ -1,9 +1,8 @@
# -*- coding: utf-8 -*-
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.tests import common
from odoo.addons.hr.tests.common import TestHrCommon
from odoo.modules.module import get_module_resource
from odoo.tools.misc import file_open
class TestRecruitmentProcess(TestHrCommon):
@ -11,35 +10,35 @@ class TestRecruitmentProcess(TestHrCommon):
def test_00_recruitment_process(self):
""" Test recruitment process """
self.dep_rd = self.env['hr.department'].create({
dep_rd = self.env['hr.department'].create({
'name': 'Research & Development',
})
self.job_developer = self.env['hr.job'].create({
job_developer = self.env['hr.job'].create({
'name': 'Experienced Developer',
'department_id': self.dep_rd.id,
'department_id': dep_rd.id,
'no_of_recruitment': 5,
})
self.employee_niv = self.env['hr.employee'].create({
employee_niv = self.env['hr.employee'].create({
'name': 'Sharlene Rhodes',
})
self.job_developer = self.job_developer.with_user(self.res_users_hr_officer.id)
self.employee_niv = self.employee_niv.with_user(self.res_users_hr_officer.id)
job_developer = job_developer.with_user(self.res_users_hr_officer.id)
employee_niv = employee_niv.with_user(self.res_users_hr_officer.id)
# Create a new HR Recruitment Officer
self.res_users_hr_recruitment_officer = self.env['res.users'].create({
res_users_hr_recruitment_officer = self.env['res.users'].create({
'company_id': self.env.ref('base.main_company').id,
'name': 'HR Recruitment Officer',
'login': "hrro",
'email': "hrofcr@yourcompany.com",
'groups_id': [(6, 0, [self.env.ref('hr_recruitment.group_hr_recruitment_user').id])]
'group_ids': [(6, 0, [self.env.ref('hr_recruitment.group_hr_recruitment_user').id])]
})
# An applicant is interested in the job position. So he sends a resume by email.
# In Order to test process of Recruitment so giving HR officer's rights
with open(get_module_resource('hr_recruitment', 'tests', 'resume.eml'), 'rb') as request_file:
with file_open('hr_recruitment/tests/resume.eml', 'rb') as request_file:
request_message = request_file.read()
self.env['mail.thread'].with_user(self.res_users_hr_recruitment_officer).message_process(
'hr.applicant', request_message, custom_values={"job_id": self.job_developer.id})
self.env['mail.thread'].with_user(res_users_hr_recruitment_officer).message_process(
'hr.applicant', request_message, custom_values={"job_id": job_developer.id})
# After getting the mail, I check the details of the new applicant.
applicant = self.env['hr.applicant'].search([('email_from', 'ilike', 'Richard_Anderson@yahoo.com')], limit=1)
@ -48,15 +47,15 @@ class TestRecruitmentProcess(TestHrCommon):
('name', '=', 'resume.pdf'),
('res_model', '=', self.env['hr.applicant']._name),
('res_id', '=', applicant.id)])
self.assertEqual(applicant.name, 'Application for the post of Jr.application Programmer.', 'Applicant name does not match.')
self.assertEqual(applicant.stage_id, self.env.ref('hr_recruitment.stage_job1'),
"Stage should be 'Initial qualification' and is '%s'." % (applicant.stage_id.name))
self.assertEqual(applicant.partner_name, 'Mr. Richard Anderson', 'Applicant name does not match.')
self.assertEqual(applicant.stage_id, self.env.ref('hr_recruitment.stage_job0'),
"Stage should be 'New' and is '%s'." % (applicant.stage_id.name))
self.assertTrue(resume_ids, 'Resume is not attached.')
# I assign the Job position to the applicant
applicant.write({'job_id': self.job_developer.id})
applicant.write({'job_id': job_developer.id})
# I schedule meeting with applicant for interview.
applicant_meeting = applicant.action_makeMeeting()
self.assertEqual(applicant_meeting['context']['default_name'], 'Application for the post of Jr.application Programmer.',
applicant_meeting = applicant.action_create_meeting()
self.assertEqual(applicant_meeting['context']['default_name'], 'Mr. Richard Anderson',
'Applicant name does not match.')
def test_01_hr_application_notification(self):
@ -71,7 +70,7 @@ class TestRecruitmentProcess(TestHrCommon):
"name": "user_1",
"login": "user_1",
"email": "user_1@example.com",
"groups_id": [
"group_ids": [
(4, self.env.ref("hr.group_hr_manager").id),
(4, self.env.ref("hr_recruitment.group_hr_recruitment_manager").id),
],
@ -88,7 +87,7 @@ class TestRecruitmentProcess(TestHrCommon):
}
)
application = self.env["hr.applicant"].create(
{"name": "Test Job Application for Notification", "job_id": job.id}
{"partner_name": "Test Job Application for Notification", "job_id": job.id}
)
new_application_message = application.message_ids.filtered(
lambda m: m.subtype_id == new_application_mt
@ -96,3 +95,95 @@ class TestRecruitmentProcess(TestHrCommon):
self.assertTrue(
user.partner_id in new_application_message.notified_partner_ids
)
def test_job_platforms(self):
self.env['hr.job.platform'].create({
'name': 'YourJobPlatform',
'email': 'yourjobplatform@platform.com',
'regex': '^New application:.*from (.*)'
})
# Regex applied on Subject
applicant = self.env['hr.applicant'].message_new({
'message_id': 'message_id_for_rec',
'email_from': '"Job Platform Application" <yourjobplatform@platform.com>',
'from': '"Job Platform Application" <yourjobplatform@platform.com>',
'subject': 'New application: ERP Implementation Consultant from John Doe',
'body': 'I want to apply to your company',
})
# Regex applied on Body
applicant2 = self.env['hr.applicant'].message_new({
'message_id': 'message_id_for_rec',
'email_from': '"Job Platform Application" <yourjobplatform@platform.com>',
'from': '"Job Platform Application" <yourjobplatform@platform.com>',
'subject': 'Very badly formatted subject :D',
'body': 'New application: ERP Implementation Consultant from John Doe',
})
self.assertEqual(applicant.partner_name, 'John Doe')
self.assertFalse(applicant.email_from)
self.assertEqual(applicant2.partner_name, 'John Doe')
self.assertFalse(applicant2.email_from)
def test_email_application_multi_company(self):
""" Make sure that receiving emails for jobs in companies different from self.env.company work. """
other_company = self.env['res.company'].create({'name': 'Other Company'})
job_developer = self.env['hr.job'].create({
'name': 'Experienced Developer (Other Company)',
'company_id': other_company.id,
})
with file_open('hr_recruitment/tests/resume.eml', 'rb') as request_file:
request_message = request_file.read()
self.env['mail.thread'].message_process('hr.applicant', request_message, custom_values={"job_id": job_developer.id})
# Make sure the applicant are created in the right company
applicant = self.env['hr.applicant'].search([('email_from', 'ilike', 'Richard_Anderson@yahoo.com')], limit=1)
self.assertEqual(applicant.company_id, other_company, 'Applicant should be created in the right company')
def test_email_application_department_with_no_company(self):
"""
Test that applicants created from incoming emails are assigned the job's company when the job's department
has no company set.
"""
mystery_company = self.env["res.company"].create({"name": "Mystery Company"})
_mail_alias_domain = self.env["mail.alias.domain"].create(
{
"company_ids": [(4, mystery_company.id)],
"name": "test.example.com",
}
)
alias = self.env["mail.alias"].create(
{
"alias_domain_id": mystery_company.alias_domain_id.id,
"alias_name": "mystery_job",
"alias_model_id": self.env["ir.model"]._get_id("hr.job"),
}
)
mystery_department = self.env["hr.department"].create({"name": "Mystery Department", "company_id": False})
mystery_job = self.env["hr.job"].create(
{
"name": "Mystery Job",
"company_id": mystery_company.id,
"department_id": mystery_department.id,
"alias_id": alias.id,
}
)
email = f"""MIME-Version: 1.0
Message-ID: <verymysteriousapplication>
From: Applicant <test@example.com>
To: {mystery_job.alias_id.display_name}
Subject: Job Application
Content-Type: text/plain; charset="UTF-8"
I want to work for you!"""
applicant_from_email = self.env["mail.thread"].message_process("hr.applicant", email)
applicant = self.env["hr.applicant"].browse(applicant_from_email)
self.assertEqual(
applicant.department_id, mystery_department, "Applicant should be assigned to the right department"
)
self.assertEqual(applicant.company_id, mystery_company, "Applicant should be created in the right company")

View file

@ -0,0 +1,339 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.fields import Domain
from odoo.tests import Form, tagged, TransactionCase
from odoo.exceptions import ValidationError
@tagged("recruitment")
class TestRecruitmentTalentPool(TransactionCase):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.t_talent_pool_1, cls.t_talent_pool_2 = cls.env["hr.talent.pool"].create(
[{"name": "Test Talent Pool 1"}, {"name": "Test Talent Pool 2"}]
)
cls.t_applicant_1, cls.t_applicant_2 = cls.env["hr.applicant"].create(
[{"partner_name": "Test Applicant 1"}, {"partner_name": "Test Applicant 2"}]
)
cls.t_job_1, cls.t_job_2, cls.t_job_3 = cls.env["hr.job"].create(
[
{"name": "Job 1"},
{"name": "Job 2"},
{"name": "Job 3"},
]
)
cls.mail_template = cls.env['mail.template'].create({
'name': 'Test stage template',
'model_id': cls.env['ir.model']._get_id('hr.applicant'),
'subject': 'Job application test',
})
def test_add_applicant_to_one_talent_pool(self):
"""
Test that a applicant is duplicated and linked to a pool when creating a talent.
"""
talent_pool_applicant = self.t_talent_pool_1.talent_ids
self.assertFalse(talent_pool_applicant, "There should not be any applicants in the talent pool")
wizard = Form(self.env["talent.pool.add.applicants"])
wizard.talent_pool_ids = self.t_talent_pool_1
wizard.applicant_ids = self.t_applicant_1
talent_pool_applicant = wizard.save()._add_applicants_to_pool()
self.assertTrue(
talent_pool_applicant, "An applicant('talent') should be created when adding an applicant to a pool"
)
self.assertNotEqual(
self.t_applicant_1, talent_pool_applicant, "The 'talent' and the applicant should be two different records"
)
self.assertEqual(
talent_pool_applicant.talent_pool_ids,
self.t_talent_pool_1,
"The talent should be linked to the talent pool",
)
def test_create_talent_in_pool(self):
talent = self.env["hr.applicant"].with_context(default_talent_pool_ids=self.t_talent_pool_1.ids).create({
'partner_name': 'Talent in a pool',
})
self.assertEqual(talent.talent_pool_ids, self.t_talent_pool_1)
self.assertEqual(talent.pool_applicant_id, talent)
job_wizard = Form(self.env["job.add.applicants"].with_context({"default_applicant_ids": talent.ids}))
job_wizard.job_ids = self.t_job_1
job_1_applicant = job_wizard.save()._add_applicants_to_job()
self.assertEqual(job_1_applicant.pool_applicant_id, talent)
def test_add_applicant_to_multiple_talent_pools(self):
"""
Test that a applicant is only duplicated once and linked to multiple pools when creating a talent.
"""
wizard = Form(self.env["talent.pool.add.applicants"])
wizard.talent_pool_ids.add(self.t_talent_pool_1)
wizard.talent_pool_ids.add(self.t_talent_pool_2)
wizard.applicant_ids = self.t_applicant_1
talent_pool_applicant = wizard.save()._add_applicants_to_pool()
self.assertTrue(
talent_pool_applicant, "An applicant('talent') should be created when adding an applicant to a pool"
)
self.assertEqual(
len(talent_pool_applicant), 1, "Exactly one 'talent' should be created when adding an applicant to a pool"
)
self.assertEqual(
talent_pool_applicant.talent_pool_ids,
self.t_talent_pool_1 | self.t_talent_pool_2,
"The 'talent' should belong to both talent pools",
)
def test_add_multiple_applicants_to_multiple_talent_pools(self):
"""
Test that multiple applicants are only duplicated once and linked to multiple pools when creating talents.
"""
talent_pool_applicants = self.t_talent_pool_1.talent_ids | self.t_talent_pool_2.talent_ids
self.assertFalse(talent_pool_applicants, "There should not be any applicants in the talent pools")
with Form(self.env["talent.pool.add.applicants"]) as wizard:
wizard.talent_pool_ids.add(self.t_talent_pool_1)
wizard.talent_pool_ids.add(self.t_talent_pool_2)
wizard.applicant_ids.add(self.t_applicant_1)
wizard.applicant_ids.add(self.t_applicant_2)
talent_pool_applicants = wizard.record._add_applicants_to_pool()
self.assertTrue(
talent_pool_applicants, "An applicant('talent') should be created when adding an applicant to a pool"
)
self.assertEqual(
len(talent_pool_applicants),
2,
"Exactly two 'talents' should be created when adding two applicants to pools",
)
for applicant in talent_pool_applicants:
self.assertEqual(
applicant.talent_pool_ids,
self.t_talent_pool_1 | self.t_talent_pool_2,
f"Talent {applicant.partner_name} should belong to two talent pools",
)
def test_add_applicant_is_only_duplicated_once(self):
"""
Test that a talent is not duplicated when added to two different pools in two different steps.
"""
with Form(self.env["talent.pool.add.applicants"]) as wizard:
wizard.talent_pool_ids = self.t_talent_pool_1
wizard.applicant_ids = self.t_applicant_1
tp_applicant_1 = wizard.record._add_applicants_to_pool()
self.assertTrue(tp_applicant_1, "An applicant('talent') should be created when adding an applicant to a pool")
self.assertEqual(
len(tp_applicant_1), 1, "Exactly one 'talent' should be created when adding an applicant to a pool"
)
# Try adding the same applicant to a different pool
# This is impossible through the UI as there is a domain on the
# `applicant_ids` field.
wizard = Form(self.env["talent.pool.add.applicants"])
wizard.talent_pool_ids = self.t_talent_pool_2
wizard.applicant_ids = self.t_applicant_1
tp_applicant_2 = wizard.save()._add_applicants_to_pool()
self.assertFalse(tp_applicant_2, "A second talent for the same applicant should not have been created")
wizard = Form(self.env["talent.pool.add.applicants"])
wizard.talent_pool_ids = self.t_talent_pool_2
wizard.applicant_ids = tp_applicant_1
tp_applicant_2 = wizard.save()._add_applicants_to_pool()
self.assertEqual(tp_applicant_1, tp_applicant_2, "tp_applicant_1 and tp_applicant_2 should be the same record")
self.assertEqual(
tp_applicant_1.talent_pool_ids,
self.t_talent_pool_1 | self.t_talent_pool_2,
f"tp_applicant_1 should be linked to {self.t_talent_pool_1.name} and {self.t_talent_pool_2.name}",
)
def test_tags_are_added_to_talent(self):
"""
Test that a tag is added to the talent but not the applicant when creating talents.
"""
tag = self.env["hr.applicant.category"].create({"name": "Test Tag"})
talent_pool_applicant = (
self.env["talent.pool.add.applicants"]
.create(
{
"applicant_ids": self.t_applicant_1,
"talent_pool_ids": self.t_talent_pool_1,
"categ_ids": tag,
}
)
._add_applicants_to_pool()
)
self.assertTrue(talent_pool_applicant, "A 'talent' should have been created")
self.assertFalse(self.t_applicant_1.categ_ids, "The original applicant should not have any linked tags")
self.assertEqual(
talent_pool_applicant.categ_ids, tag, "The 'talent' should have the tag 'Test Tag' linked to it"
)
def test_add_talent_to_one_job(self):
"""
Test that a talent is duplicated when added to a job
"""
pool_wizard = Form(self.env["talent.pool.add.applicants"])
pool_wizard.talent_pool_ids = self.t_talent_pool_1
pool_wizard.applicant_ids = self.t_applicant_1
talent_pool_applicant = pool_wizard.save()._add_applicants_to_pool()
recuritment_stage = self.env["hr.recruitment.stage"].create({
"name": "Recruitment Stage",
"job_ids": self.t_job_2.ids,
"template_id": self.mail_template.id,
"sequence": 0,
})
self.assertEqual(
len(talent_pool_applicant), 1, "Exactly one 'talent' should be created when adding an applicant to a pool"
)
job_wizard = Form(
self.env["job.add.applicants"].with_context({"default_applicant_ids": talent_pool_applicant.ids})
)
job_wizard.job_ids = self.t_job_2
job_2_applicant = job_wizard.save()._add_applicants_to_job()
self.flush_tracking()
all_applications = self.env["hr.applicant"].search(Domain("partner_name", "=", "Test Applicant 1"))
self.assertEqual(
len(all_applications),
3,
"""There should be three applications with the name 'Test Applicant 1' - The original, the talent and the one created through the job.add.applicants wizard""",
)
self.assertEqual(
job_2_applicant,
self.t_job_2.application_ids,
"Job_2_applicant, created through the wizard, should be linked to Job 2",
)
self.assertNotEqual(
job_2_applicant, talent_pool_applicant, "Job_2_applicant and the talent should not be the same record"
)
# Make sure that the stage was populated correctly during creation not in compute,
# If it was passed in creation the record will have the mail linked to the stage
self.assertEqual(job_2_applicant.stage_id, recuritment_stage)
self.assertEqual(job_2_applicant.message_ids[0].subject, self.mail_template.subject)
def test_add_talent_to_multiple_jobs(self):
"""
Test that a talent is duplicated multiple times when added to multiple jobs.
"""
pool_wizard = Form(self.env["talent.pool.add.applicants"])
pool_wizard.talent_pool_ids = self.t_talent_pool_1
pool_wizard.applicant_ids = self.t_applicant_1
pool_wizard.save().action_add_applicants_to_pool()
talent_pool_applicant = self.t_talent_pool_1.talent_ids
self.assertEqual(
len(talent_pool_applicant), 1, "Exactly one 'talent' should be created when adding an applicant to a pool"
)
job_wizard = Form(
self.env["job.add.applicants"].with_context({"default_applicant_ids": talent_pool_applicant.ids})
)
job_wizard.job_ids.add(self.t_job_2)
job_wizard.job_ids.add(self.t_job_3)
new_job_applicants = job_wizard.save()._add_applicants_to_job()
all_applications = self.env["hr.applicant"].search(Domain("partner_name", "=", "Test Applicant 1"))
self.assertEqual(
len(all_applications),
4,
"""There should be four applications with the name 'Test Applicant' - The original, the talent and one each for job_2 and job_3, created through the wizard""",
)
self.assertEqual(
new_job_applicants.job_id,
self.t_job_2 | self.t_job_3,
"new_job_applicants, created through the wizard, should be linked to Job 2 and Job 3",
)
def test_add_multiple_talents_to_multiple_jobs(self):
"""
Test that multiple talents are duplicated multiple times when added to multiple jobs.
"""
pool_wizard = Form(self.env["talent.pool.add.applicants"])
pool_wizard.talent_pool_ids = self.t_talent_pool_1
pool_wizard.applicant_ids.add(self.t_applicant_1)
pool_wizard.applicant_ids.add(self.t_applicant_2)
talent_pool_applicants = pool_wizard.save()._add_applicants_to_pool()
self.assertEqual(
len(talent_pool_applicants), 2, "Exactly two 'talents' should be created when adding an applicant to a pool"
)
job_wizard = Form(
self.env["job.add.applicants"].with_context({"default_applicant_ids": talent_pool_applicants.ids})
)
job_wizard.job_ids.add(self.t_job_2)
job_wizard.job_ids.add(self.t_job_3)
new_job_applicants = job_wizard.save()._add_applicants_to_job()
all_a_1_applications = self.env["hr.applicant"].search(Domain("partner_name", "=", "Test Applicant 1"))
all_a_2_applications = self.env["hr.applicant"].search(Domain("partner_name", "=", "Test Applicant 2"))
self.assertEqual(
len(all_a_1_applications),
4,
"""There should be four applications with the name 'Test Applicant 1' - The original, the talent and one each for job_2 and job_3, created through the wizard""",
)
self.assertEqual(
len(all_a_2_applications),
4,
"""There should be four applications with the name 'Test Applicant 2' - The original, the talent and one each for job_2 and job_3, created through the wizard""",
)
new_job_applicants = new_job_applicants.mapped(lambda a: {"name": a.partner_name, "job": a.job_id})
expected = [
{"name": "Test Applicant 1", "job": self.t_job_2},
{"name": "Test Applicant 1", "job": self.t_job_3},
{"name": "Test Applicant 2", "job": self.t_job_2},
{"name": "Test Applicant 2", "job": self.t_job_3},
]
self.assertEqual(
new_job_applicants,
expected,
"new_job_applicants, created through the wizard, should be linked to Job 2 and Job 3",
)
def test_update_applicant_after_adding_to_pool(self):
"""
Test that an applicant's fields (e.g., email) can still be updated after adding them to a talent pool.
"""
self.env["talent.pool.add.applicants"].create({
"applicant_ids": self.t_applicant_1.ids,
"talent_pool_ids": self.t_talent_pool_1,
}).action_add_applicants_to_pool()
new_email = "updated@gmail.com"
self.t_applicant_1.write({"email_from": new_email})
self.assertEqual(
self.t_applicant_1.email_from,
new_email,
"The email_from field should be updated successfully",
)
def test_talent_must_have_at_least_one_pool(self):
"""
Ensure that removing all the talent pool from a talent created raises a ValidationError.
"""
wizard = Form(self.env["talent.pool.add.applicants"])
wizard.talent_pool_ids.add(self.t_talent_pool_1)
wizard.applicant_ids.add(self.t_applicant_1)
talent = wizard.save()._add_applicants_to_pool()
with self.assertRaises(ValidationError):
talent.write({"talent_pool_ids": [(5, 0, 0)]})
def flush_tracking(self):
""" Force the creation of tracking values. """
self.env.flush_all()
self.cr.flush()

View file

@ -2,24 +2,20 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.
from odoo.addons.utm.tests.common import TestUTMCommon
from odoo.exceptions import AccessError, UserError
from odoo.tests.common import new_test_user, tagged, users
from odoo.exceptions import UserError
from odoo.tests.common import tagged, users
@tagged('post_install', '-at_install', 'utm_consistency')
class TestUTMConsistencyHrRecruitment(TestUTMCommon):
@classmethod
def setUpClass(cls):
super().setUpClass()
cls.hr_recruitment_source = cls.env['hr.recruitment.source'].create({
'name': 'Recruitment Source'
})
@users('__system__')
def test_utm_consistency(self):
hr_recruitment_source = self.env['hr.recruitment.source'].create({
'name': 'Recruitment Source'
})
# the source is automatically created when creating a recruitment source
utm_source = self.hr_recruitment_source.source_id
utm_source = hr_recruitment_source.source_id
with self.assertRaises(UserError):
# can't unlink the source as it's used by a mailing.mailing as its source
@ -30,24 +26,3 @@ class TestUTMConsistencyHrRecruitment(TestUTMCommon):
# the creation of the alias of the recruitment source
with self.assertRaises(UserError):
self.env.ref('hr_recruitment.utm_campaign_job').unlink()
def test_create_alias(self):
"""This ensures that users who are not recruitment officers are not allowed to
create a mail alias for the recruiting source while who are recruitment officers are
"""
simple_user = new_test_user(self.env, 'smp',
groups='base.group_user', name='Simple User', email='smp@example.com')
interviewer_user = new_test_user(self.env, 'itw',
groups='base.group_user,hr_recruitment.group_hr_recruitment_interviewer',
name='Recruitment Interviewer', email='itw@example.com')
recruitment_officer_user = new_test_user(self.env, 'rec_off',
groups='base.group_user,hr_recruitment.group_hr_recruitment_user',
name='Recruitment Officer', email='rec_off@example.com')
with self.assertRaises(AccessError):
self.hr_recruitment_source.with_user(simple_user).create_alias()
with self.assertRaises(AccessError):
self.hr_recruitment_source.with_user(interviewer_user).create_alias()
try:
self.hr_recruitment_source.with_user(recruitment_officer_user).create_alias()
except AccessError:
self.fail("Recruitment Officer should be able to create mail alias for hr.recruitment.source.")