Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Debt] Improve seeding for RoD #10290

Merged
merged 49 commits into from
May 22, 2024
Merged
Show file tree
Hide file tree
Changes from 45 commits
Commits
Show all changes
49 commits
Select commit Hold shift + click to select a range
6cbfd3f
Add pools for RoD testing
brindasasi May 7, 2024
b3a2955
add EX-03
brindasasi May 8, 2024
931aadc
add EX classification
brindasasi May 8, 2024
d8f04dd
add EX03
brindasasi May 9, 2024
ce6cbbc
Merge branch 'main' into 10110-improve-ROD-seeding
brindasasi May 9, 2024
3588404
extract out skill,questions creation
brindasasi May 10, 2024
846834e
fix poolskill
brindasasi May 10, 2024
11aee99
add more pool data
brindasasi May 13, 2024
c53fbd4
add personas
brindasasi May 13, 2024
5be18a8
Merge branch 'main' into 10110-improve-ROD-seeding
brindasasi May 13, 2024
b33243a
fix linting
brindasasi May 13, 2024
d54122c
Revert "fix linting"
brindasasi May 13, 2024
93b58f4
fix linting
brindasasi May 13, 2024
f921bcd
fix linting
brindasasi May 13, 2024
0c2e15c
add missing assessment results nuances
brindasasi May 13, 2024
6e23470
Merge branch 'main' into 10110-improve-ROD-seeding
brindasasi May 13, 2024
583b0fc
fix pool tests
brindasasi May 13, 2024
53b92ff
Fix ScreeningQuestionsTest
brindasasi May 14, 2024
a36ece9
fix tests
brindasasi May 14, 2024
c819cbc
Merge branch 'main' into 10110-improve-ROD-seeding
brindasasi May 14, 2024
9790600
fix linting
brindasasi May 14, 2024
7a4c8a1
remove duplicate code
brindasasi May 14, 2024
add3038
fix the citizenship status for the personas
brindasasi May 14, 2024
5788334
fix pools & spacing between them
brindasasi May 14, 2024
8f825e6
fix test
vd1992 May 14, 2024
23ba5e3
fix linting
brindasasi May 14, 2024
22322fb
clean up PoolTestSeeder
brindasasi May 15, 2024
23122e2
code clean up
brindasasi May 15, 2024
590e70e
fix line formatting
brindasasi May 15, 2024
13356bf
fix duplicate code
brindasasi May 21, 2024
e5d14d7
fix pool naming
brindasasi May 21, 2024
0cd7f01
fix pool naming
brindasasi May 21, 2024
d97a986
improve pool seeder performance
brindasasi May 22, 2024
ea11119
add priority no
brindasasi May 22, 2024
e899cbf
fix linting
brindasasi May 22, 2024
5fd24d8
add stream
brindasasi May 22, 2024
927ad79
Revert "improve pool seeder performance"
brindasasi May 22, 2024
77f1328
restore the lost changes
brindasasi May 22, 2024
641bbe4
remove unnecessary code
brindasasi May 22, 2024
326ee85
fix linting
brindasasi May 22, 2024
a674653
Merge branch 'main' into 10110-improve-ROD-seeding
brindasasi May 22, 2024
cce5ff8
restore the last changes
brindasasi May 22, 2024
c178ca0
fix linting
brindasasi May 22, 2024
e036c05
fix after latest main merge in
brindasasi May 22, 2024
1e5d6ec
applyToAllPools should be private
brindasasi May 22, 2024
8b25203
try the flaky test with sep user instance
brindasasi May 22, 2024
9594209
fix the test
brindasasi May 22, 2024
5059c9f
try split the tests into 2
brindasasi May 22, 2024
5bddd16
lint fix
brindasasi May 22, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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()
Comment on lines 73 to -75
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The removal of the configure() function seemed to trip some stuff up as I believe it runs automatically.
Resolved test failure by calling the needed function in 8f825e6

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) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've removed this hard coded skills during pool creation as we need diff no. of skills for the tests.

$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()
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this also has been taken out so we can customize the no. of questions per pool

->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
Loading