Skip to content

Commit

Permalink
[Debt] Improve seeding for RoD (#10290)
Browse files Browse the repository at this point in the history
* Add pools for RoD testing

* add EX-03

* add EX classification

* add EX03

* extract out skill,questions creation

* fix poolskill

* add more pool data

* add personas

* fix linting

* Revert "fix linting"

This reverts commit b33243a.

* fix linting

* fix linting

* add missing assessment results nuances

* fix pool tests

* Fix ScreeningQuestionsTest

* fix tests

* fix linting

* remove duplicate code

* fix the citizenship status for the personas

* fix  pools & spacing between them

* fix test

* fix linting

* clean up PoolTestSeeder

* code clean up

* fix line formatting

* fix duplicate code

* fix pool naming

* fix pool naming

* improve pool seeder performance

* add priority no

* fix linting

* add stream

* Revert "improve pool seeder performance"

This reverts commit d97a986.

* restore the lost changes

* remove unnecessary code

* fix linting

* restore the last changes

* fix linting

* fix after latest main merge in

* applyToAllPools should be private

* try the flaky test with sep user instance

* fix the test

* try split the tests into 2

* lint fix

---------

Co-authored-by: vd1992 <[email protected]>
  • Loading branch information
brindasasi and vd1992 authored May 22, 2024
1 parent 184aa34 commit 5f14621
Show file tree
Hide file tree
Showing 20 changed files with 750 additions and 130 deletions.
1 change: 1 addition & 0 deletions api/app/Enums/GenericJobTitleKey.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ enum GenericJobTitleKey
case TECHNICAL_ADVISOR_IT03;
case SENIOR_ADVISOR_IT04;
case MANAGER_IT04;
case EXECUTIVE_EX03;
}
2 changes: 2 additions & 0 deletions api/app/Models/PoolSkill.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@ class PoolSkill extends Model

protected $keyType = 'string';

protected $fillable = ['skill_id', 'type', 'required_skill_level'];

protected static function boot()
{
parent::boot();
Expand Down
193 changes: 137 additions & 56 deletions api/database/factories/PoolFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@
use App\Models\Classification;
use App\Models\GeneralQuestion;
use App\Models\Pool;
use App\Models\PoolSkill;
use App\Models\ScreeningQuestion;
use App\Models\Skill;
use App\Models\Team;
Expand Down Expand Up @@ -72,65 +71,117 @@ public function definition()
];
}

public function configure()
public function withPoolSkills($essentialCount, $nonEssentialCount)
{
return $this->afterCreating(function (Pool $pool) {
return $this->afterCreating(function (Pool $pool) use ($essentialCount, $nonEssentialCount) {
$skills = Skill::inRandomOrder()->limit(10)->get();
//slice first set of skills as essential skills
$essentialSkills = $skills->slice(0, $essentialCount);
//slice next set of skills as non essential skills
$nonEssentialSkills = $skills->slice($essentialCount, $nonEssentialCount);
$this->createPoolSkills($pool, $essentialSkills, PoolSkillType::ESSENTIAL->name);
$this->createPoolSkills($pool, $nonEssentialSkills, PoolSkillType::NONESSENTIAL->name);
});
}

foreach ($skills->slice(0, 5) as $skill) {
$poolSkill = new PoolSkill();
$poolSkill->skill_id = $skill->id;
$poolSkill->type = PoolSkillType::ESSENTIAL->name;
$poolSkill->required_skill_level = $this->faker->randomElement(array_column(SkillLevel::cases(), 'name'));
$pool->poolSkills()->save($poolSkill);
}
foreach ($skills->slice(5, 5) as $skill) {
$poolSkill = new PoolSkill();
$poolSkill->skill_id = $skill->id;
$poolSkill->type = PoolSkillType::NONESSENTIAL->name;
$poolSkill->required_skill_level = $this->faker->randomElement(array_column(SkillLevel::cases(), 'name'));
$pool->poolSkills()->save($poolSkill);
}
private function createPoolSkills($pool, $skills, $type)
{
// for each skills create it as pool skill
foreach ($skills as $skill) {
$pool->poolSkills()->create([
'skill_id' => $skill->id,
'type' => $type,
'required_skill_level' => $this->faker->randomElement(array_column(SkillLevel::cases(), 'name')),
]);
}
}

GeneralQuestion::factory()
->count(3)
->sequence(
['sort_order' => 1],
['sort_order' => 2],
['sort_order' => 3],
)
->create(['pool_id' => $pool->id]);

$screeningAssessmentStep = AssessmentStep::factory()->create(
[
'pool_id' => $pool->id,
'type' => AssessmentStepType::SCREENING_QUESTIONS_AT_APPLICATION->name,
]
);
ScreeningQuestion::factory()
->count(3)
->sequence(
['sort_order' => 1],
['sort_order' => 2],
['sort_order' => 3],
)
->create(
[
'pool_id' => $pool->id,
'assessment_step_id' => $screeningAssessmentStep->id,
]
);
public function withQuestions($generalQuestionsCount, $screeningQuestionsCount)
{
return $this->afterCreating(function (Pool $pool) use ($generalQuestionsCount, $screeningQuestionsCount) {
$this->createQuestions(GeneralQuestion::class, $generalQuestionsCount, $pool->id);
$this->createQuestions(ScreeningQuestion::class, $screeningQuestionsCount, $pool->id, $this->createAssessmentStepWithPoolSkills($pool, AssessmentStepType::SCREENING_QUESTIONS_AT_APPLICATION->name)->id);
});
}

private function createAssessmentStep($pool, $type)
{
return AssessmentStep::factory()
->create([
'pool_id' => $pool->id,
'type' => $type,
]);
}

private function createAssessmentStepWithPoolSkills($pool, $type)
{
$step = $this->createAssessmentStep($pool, $type);
$poolSkillArray = $pool->poolSkills->pluck('id')->toArray();
$step->poolSkills()->sync($poolSkillArray);

return $step;
}

public function withAssessmentStepAndWithoutPoolSkills()
{
return $this->afterCreating(function (Pool $pool) {
$step = $this->createAssessmentStep($pool, AssessmentStepType::SCREENING_QUESTIONS_AT_APPLICATION->name);

return $step;
});
}

private function createQuestions($factory, $count, $poolId, $assessmentStepId = null)
{
$sequence = [];
for ($i = 1; $i <= $count; $i++) {
$sequence[] = ['sort_order' => $i];
}
if ($assessmentStepId !== null) {
$factory::factory()
->count($count)
->sequence(...$sequence)
->create([
'pool_id' => $poolId,
'assessment_step_id' => $assessmentStepId,
]);
} else {
$factory::factory()
->count($count)
->sequence(...$sequence)
->create([
'pool_id' => $poolId,
]);
}
}

/**
* Indicate that the pool is draft.
*/
public function draft(): Factory
{
return $this->state(function (array $attributes) {
// the base state is draft already
return [];
$hasSpecialNote = $this->faker->boolean();
$isRemote = $this->faker->boolean();

return [
'operational_requirements' => $this->faker->randomElements(array_column(OperationalRequirement::cases(), 'name'), 2),
'key_tasks' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
'your_impact' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
'what_to_expect' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
'what_to_expect_admission' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
'about_us' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
'security_clearance' => $this->faker->randomElement(array_column(SecurityStatus::cases(), 'name')),
'advertisement_language' => $this->faker->randomElement(array_column(PoolLanguage::cases(), 'name')),
'advertisement_location' => ! $isRemote ? ['en' => $this->faker->country(), 'fr' => $this->faker->country()] : null,
'special_note' => ! $hasSpecialNote ? ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'] : null,
'is_remote' => $this->faker->boolean,
'stream' => $this->faker->randomElement(PoolStream::cases())->name,
'process_number' => $this->faker->word(),
'publishing_group' => $this->faker->randomElement(array_column(PublishingGroup::cases(), 'name')),
'opportunity_length' => $this->faker->randomElement(array_column(PoolOpportunityLength::cases(), 'name')),
];
});
}

Expand All @@ -146,7 +197,6 @@ public function published(): Factory
return [
// published in the past, closes in the future
'published_at' => $this->faker->dateTimeBetween('-30 days', '-1 days'),

'operational_requirements' => $this->faker->randomElements(array_column(OperationalRequirement::cases(), 'name'), 2),
'key_tasks' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
'your_impact' => ['en' => $this->faker->paragraph().' EN', 'fr' => $this->faker->paragraph().' FR'],
Expand Down Expand Up @@ -217,16 +267,47 @@ public function candidatesAvailableInSearch()
*
* @return \Illuminate\Database\Eloquent\Factories\Factory
*/
public function withAssessments()
public function withAssessments($noOfAssessmentSteps = 2)
{
return $this->afterCreating(function (Pool $pool) {
$step1 = AssessmentStep::factory()
->create(['pool_id' => $pool->id]);
$step2 = AssessmentStep::factory()
->create(['pool_id' => $pool->id]);
$poolSkillArray = $pool->poolSkills->pluck('id')->toArray();
$step1->poolSkills()->sync(array_slice($poolSkillArray, 0, 5, true));
$step2->poolSkills()->sync(array_slice($poolSkillArray, 5, 5, true));
return $this->afterCreating(function (Pool $pool, $noOfAssessmentSteps) {
$steps = [];
$this->createAssessmentStepWithPoolSkills($pool, AssessmentStepType::SCREENING_QUESTIONS_AT_APPLICATION->name);

for ($i = 0; $i < $noOfAssessmentSteps - 1; $i++) {
$steps[$i] = $this->createAssessmentStepWithPoolSkills($pool, $this->faker->randomElement(array_column(AssessmentStepType::cases(), 'name'))->name);
}
});
}

// Add a single assessment step to the pool for the given assessment step type
public function WithAssessmentStep(AssessmentStepType $type)
{
return $this->afterCreating(function (Pool $pool) use ($type) {

$step = $this->createAssessmentStep($pool, $type->name);
$poolSkillArray = $pool->poolSkills()->pluck('id')->toArray();
$step->poolSkills()->sync($poolSkillArray);

return $step;
});
}

/**
* Create a new pool or get an existing pool based on the given attributes.
*
* @param array $attributes The attributes of the pool.
* @return Pool The created or existing pool.
*/
public function createOrGetExisting($attributes = [])
{
$pool = Pool::where('name->en', $attributes['name']['en'])
->where('name->fr', $attributes['name']['fr'])
->first();

if ($pool) {
return $pool;
}

return $this->create($attributes);
}
}
49 changes: 26 additions & 23 deletions api/database/factories/UserFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -129,40 +129,43 @@ public function definition()
];
}

public function withSkillsAndExperiences($count = 10)
private function createExperienceAndSyncSkills($user, $skills)
{
$experienceFactories = [
AwardExperience::factory(['user_id' => $user->id]),
CommunityExperience::factory(['user_id' => $user->id]),
EducationExperience::factory(['user_id' => $user->id]),
PersonalExperience::factory(['user_id' => $user->id]),
WorkExperience::factory(['user_id' => $user->id]),
];

$experience = $this->faker->randomElement($experienceFactories)->create();
$skillsForExperience = $this->faker->randomElements($skills, $this->faker->numberBetween(1, $skills->count()));
$syncDataExperience = array_map(function ($skill) {
return ['id' => $skill->id, 'details' => $this->faker->text()];
}, $skillsForExperience);

$experience->syncSkills($syncDataExperience);
}

public function withSkillsAndExperiences($count = 10, $skills = [])
{
if (empty($skills)) {
$allSkills = Skill::select('id')->inRandomOrder()->take($count)->get();
} else {
$allSkills = $skills;
}
$allSkills = Skill::select('id')->inRandomOrder()->take($count)->get();

return $this->afterCreating(function (User $user) use ($count, $allSkills) {
$experienceFactories = [
AwardExperience::factory(['user_id' => $user->id]),
CommunityExperience::factory(['user_id' => $user->id]),
EducationExperience::factory(['user_id' => $user->id]),
PersonalExperience::factory(['user_id' => $user->id]),
WorkExperience::factory(['user_id' => $user->id]),
];

$skillSequence = $allSkills->shuffle()->map(fn ($skill) => ['skill_id' => $skill['id']])->toArray();

$userSkills = UserSkill::factory($count)->for($user)
->sequence(...$skillSequence)
->create();
$skills = $userSkills->map(fn ($us) => $us->skill);

// create two experiences and attach a random number of skills to each through experience_skill pivot
$experienceOne = $this->faker->randomElement($experienceFactories)->create();
$skillsForExperienceOne = $this->faker->randomElements($skills, $this->faker->numberBetween(1, $skills->count()));
$syncDataExperienceOne = array_map(function ($skill) {
return ['id' => $skill->id, 'details' => $this->faker->text()];
}, $skillsForExperienceOne);
$experienceOne->syncSkills($syncDataExperienceOne);

$experienceTwo = $this->faker->randomElement($experienceFactories)->create();
$skillsForExperienceTwo = $this->faker->randomElements($skills, $this->faker->numberBetween(1, $skills->count()));
$syncDataExperienceTwo = array_map(function ($skill) {
return ['id' => $skill->id, 'details' => $this->faker->text()];
}, $skillsForExperienceTwo);
$experienceTwo->syncSkills($syncDataExperienceTwo);
$this->createExperienceAndSyncSkills($user, $skills);
});
}

Expand Down
Loading

0 comments on commit 5f14621

Please sign in to comment.