# 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()