Skip to content

Commit d5d5af8

Browse files
committed
test: ✅ add integration tests for meal planner functionality in recipe search
1 parent b5ebb78 commit d5d5af8

File tree

26 files changed

+650
-104
lines changed

26 files changed

+650
-104
lines changed

apps/403-recipe-search-add-button-solution/src/app/recipe/recipe-search.integration.spec.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { TestBed } from '@angular/core/testing';
12
import { render, screen } from '@testing-library/angular';
23
import userEvent from '@testing-library/user-event';
4+
import { firstValueFrom } from 'rxjs';
5+
import { MealPlanner } from '../meal-planner/meal-planner';
6+
import { provideMealRepositoryFake } from '../meal-planner/meal-repository.fake';
37
import { recipeMother } from '../testing/recipe.mother';
48
import {
59
provideRecipeRepositoryFake,
@@ -24,9 +28,36 @@ describe(RecipeSearch.name, () => {
2428
expect(getRecipeNames()).toEqual(['Burger']);
2529
});
2630

31+
it('should add recipe to meal planner', async () => {
32+
const { getFirstAddButton, getMealPlannerRecipeNames } =
33+
await renderComponent();
34+
35+
await userEvent.click(getFirstAddButton());
36+
37+
expect(await getMealPlannerRecipeNames()).toEqual(['Burger']);
38+
});
39+
40+
it("should disable add button if can't add", async () => {
41+
const { getFirstAddButton } =
42+
await renderComponentWithBurgerInMealPlanner();
43+
44+
/* Can't add burger because there is already a burger with the same id. */
45+
expect(getFirstAddButton()).toBeDisabled();
46+
});
47+
48+
async function renderComponentWithBurgerInMealPlanner() {
49+
const { mealPlanner, whenStable, ...utils } = await renderComponent();
50+
51+
mealPlanner.addRecipe(recipeMother.withBasicInfo('Burger').build());
52+
53+
await whenStable();
54+
55+
return utils;
56+
}
57+
2758
async function renderComponent() {
2859
const { fixture } = await render(RecipeSearch, {
29-
providers: [provideRecipeRepositoryFake()],
60+
providers: [provideMealRepositoryFake(), provideRecipeRepositoryFake()],
3061
configureTestBed(testBed) {
3162
testBed
3263
.inject(RecipeRepositoryFake)
@@ -37,16 +68,31 @@ describe(RecipeSearch.name, () => {
3768
},
3869
});
3970

71+
const mealPlanner = TestBed.inject(MealPlanner);
72+
4073
await fixture.whenStable();
4174

4275
return {
76+
mealPlanner,
77+
async getMealPlannerRecipeNames() {
78+
const recipes = await firstValueFrom(mealPlanner.recipes$);
79+
return recipes.map((recipe) => recipe.name);
80+
},
81+
getFirstAddButton() {
82+
return screen.getAllByRole<HTMLButtonElement>('button', {
83+
name: 'ADD',
84+
})[0];
85+
},
4386
getRecipeNames() {
4487
return screen.queryAllByRole('heading').map((el) => el.textContent);
4588
},
4689
async updateFilter({ keywords }: { keywords: string }) {
4790
await userEvent.type(screen.getByLabelText('Keywords'), keywords);
4891
await fixture.whenStable();
4992
},
93+
async whenStable() {
94+
return fixture.whenStable();
95+
},
5096
};
5197
}
5298
});

apps/403-recipe-search-add-button-solution/src/app/recipe/recipe-search.shallow.spec.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe(RecipeSearch.name, () => {
3838
const { getFirstAddButton, getMealPlannerRecipeNames } =
3939
await renderComponent();
4040

41-
await getFirstAddButton().click();
41+
await userEvent.click(getFirstAddButton());
4242

4343
expect(await getMealPlannerRecipeNames()).toEqual(['Burger']);
4444
});
@@ -48,7 +48,7 @@ describe(RecipeSearch.name, () => {
4848
await renderComponentWithBurgerInMealPlanner();
4949

5050
/* Can't add burger because there is already a burger with the same id. */
51-
expect(getFirstAddButton().isDisabled()).toBe(true);
51+
expect(getFirstAddButton()).toBeDisabled();
5252
});
5353

5454
async function renderComponentWithBurgerInMealPlanner() {
@@ -88,13 +88,9 @@ describe(RecipeSearch.name, () => {
8888
return {
8989
mealPlanner,
9090
getFirstAddButton() {
91-
const addButtonEl = screen.getAllByRole<HTMLButtonElement>('button', {
91+
return screen.getAllByRole<HTMLButtonElement>('button', {
9292
name: 'ADD',
9393
})[0];
94-
return {
95-
click: () => userEvent.click(addButtonEl),
96-
isDisabled: () => addButtonEl.disabled,
97-
};
9894
},
9995
async getMealPlannerRecipeNames() {
10096
const recipes = await firstValueFrom(mealPlanner.recipes$);

apps/404-recipe-filter-material-solution/src/app/recipe/recipe-search.integration.spec.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { TestBed } from '@angular/core/testing';
12
import { render, screen } from '@testing-library/angular';
23
import userEvent from '@testing-library/user-event';
4+
import { firstValueFrom } from 'rxjs';
5+
import { MealPlanner } from '../meal-planner/meal-planner';
6+
import { provideMealRepositoryFake } from '../meal-planner/meal-repository.fake';
37
import { recipeMother } from '../testing/recipe.mother';
48
import {
59
provideRecipeRepositoryFake,
@@ -24,9 +28,36 @@ describe(RecipeSearch.name, () => {
2428
expect(getRecipeNames()).toEqual(['Burger']);
2529
});
2630

31+
it('should add recipe to meal planner', async () => {
32+
const { getFirstAddButton, getMealPlannerRecipeNames } =
33+
await renderComponent();
34+
35+
await userEvent.click(getFirstAddButton());
36+
37+
expect(await getMealPlannerRecipeNames()).toEqual(['Burger']);
38+
});
39+
40+
it("should disable add button if can't add", async () => {
41+
const { getFirstAddButton } =
42+
await renderComponentWithBurgerInMealPlanner();
43+
44+
/* Can't add burger because there is already a burger with the same id. */
45+
expect(getFirstAddButton()).toBeDisabled();
46+
});
47+
48+
async function renderComponentWithBurgerInMealPlanner() {
49+
const { mealPlanner, whenStable, ...utils } = await renderComponent();
50+
51+
mealPlanner.addRecipe(recipeMother.withBasicInfo('Burger').build());
52+
53+
await whenStable();
54+
55+
return utils;
56+
}
57+
2758
async function renderComponent() {
2859
const { fixture } = await render(RecipeSearch, {
29-
providers: [provideRecipeRepositoryFake()],
60+
providers: [provideMealRepositoryFake(), provideRecipeRepositoryFake()],
3061
configureTestBed(testBed) {
3162
testBed
3263
.inject(RecipeRepositoryFake)
@@ -37,16 +68,31 @@ describe(RecipeSearch.name, () => {
3768
},
3869
});
3970

71+
const mealPlanner = TestBed.inject(MealPlanner);
72+
4073
await fixture.whenStable();
4174

4275
return {
76+
mealPlanner,
77+
async getMealPlannerRecipeNames() {
78+
const recipes = await firstValueFrom(mealPlanner.recipes$);
79+
return recipes.map((recipe) => recipe.name);
80+
},
81+
getFirstAddButton() {
82+
return screen.getAllByRole<HTMLButtonElement>('button', {
83+
name: 'ADD',
84+
})[0];
85+
},
4386
getRecipeNames() {
4487
return screen.queryAllByRole('heading').map((el) => el.textContent);
4588
},
4689
async updateFilter({ keywords }: { keywords: string }) {
4790
await userEvent.type(screen.getByLabelText('Keywords'), keywords);
4891
await fixture.whenStable();
4992
},
93+
async whenStable() {
94+
return fixture.whenStable();
95+
},
5096
};
5197
}
5298
});

apps/404-recipe-filter-material-solution/src/app/recipe/recipe-search.shallow.spec.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe(RecipeSearch.name, () => {
3838
const { getFirstAddButton, getMealPlannerRecipeNames } =
3939
await renderComponent();
4040

41-
await getFirstAddButton().click();
41+
await userEvent.click(getFirstAddButton());
4242

4343
expect(await getMealPlannerRecipeNames()).toEqual(['Burger']);
4444
});
@@ -48,7 +48,7 @@ describe(RecipeSearch.name, () => {
4848
await renderComponentWithBurgerInMealPlanner();
4949

5050
/* Can't add burger because there is already a burger with the same id. */
51-
expect(getFirstAddButton().isDisabled()).toBe(true);
51+
expect(getFirstAddButton()).toBeDisabled();
5252
});
5353

5454
async function renderComponentWithBurgerInMealPlanner() {
@@ -88,13 +88,9 @@ describe(RecipeSearch.name, () => {
8888
return {
8989
mealPlanner,
9090
getFirstAddButton() {
91-
const addButtonEl = screen.getAllByRole<HTMLButtonElement>('button', {
91+
return screen.getAllByRole<HTMLButtonElement>('button', {
9292
name: 'ADD',
9393
})[0];
94-
return {
95-
click: () => userEvent.click(addButtonEl),
96-
isDisabled: () => addButtonEl.disabled,
97-
};
9894
},
9995
async getMealPlannerRecipeNames() {
10096
const recipes = await firstValueFrom(mealPlanner.recipes$);

apps/404-recipe-filter-material-starter/src/app/recipe/recipe-search.integration.spec.ts

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
import { TestBed } from '@angular/core/testing';
12
import { render, screen } from '@testing-library/angular';
23
import userEvent from '@testing-library/user-event';
4+
import { firstValueFrom } from 'rxjs';
5+
import { MealPlanner } from '../meal-planner/meal-planner';
6+
import { provideMealRepositoryFake } from '../meal-planner/meal-repository.fake';
37
import { recipeMother } from '../testing/recipe.mother';
48
import {
59
provideRecipeRepositoryFake,
@@ -24,9 +28,36 @@ describe(RecipeSearch.name, () => {
2428
expect(getRecipeNames()).toEqual(['Burger']);
2529
});
2630

31+
it('should add recipe to meal planner', async () => {
32+
const { getFirstAddButton, getMealPlannerRecipeNames } =
33+
await renderComponent();
34+
35+
await userEvent.click(getFirstAddButton());
36+
37+
expect(await getMealPlannerRecipeNames()).toEqual(['Burger']);
38+
});
39+
40+
it("should disable add button if can't add", async () => {
41+
const { getFirstAddButton } =
42+
await renderComponentWithBurgerInMealPlanner();
43+
44+
/* Can't add burger because there is already a burger with the same id. */
45+
expect(getFirstAddButton()).toBeDisabled();
46+
});
47+
48+
async function renderComponentWithBurgerInMealPlanner() {
49+
const { mealPlanner, whenStable, ...utils } = await renderComponent();
50+
51+
mealPlanner.addRecipe(recipeMother.withBasicInfo('Burger').build());
52+
53+
await whenStable();
54+
55+
return utils;
56+
}
57+
2758
async function renderComponent() {
2859
const { fixture } = await render(RecipeSearch, {
29-
providers: [provideRecipeRepositoryFake()],
60+
providers: [provideMealRepositoryFake(), provideRecipeRepositoryFake()],
3061
configureTestBed(testBed) {
3162
testBed
3263
.inject(RecipeRepositoryFake)
@@ -37,16 +68,31 @@ describe(RecipeSearch.name, () => {
3768
},
3869
});
3970

71+
const mealPlanner = TestBed.inject(MealPlanner);
72+
4073
await fixture.whenStable();
4174

4275
return {
76+
mealPlanner,
77+
async getMealPlannerRecipeNames() {
78+
const recipes = await firstValueFrom(mealPlanner.recipes$);
79+
return recipes.map((recipe) => recipe.name);
80+
},
81+
getFirstAddButton() {
82+
return screen.getAllByRole<HTMLButtonElement>('button', {
83+
name: 'ADD',
84+
})[0];
85+
},
4386
getRecipeNames() {
4487
return screen.queryAllByRole('heading').map((el) => el.textContent);
4588
},
4689
async updateFilter({ keywords }: { keywords: string }) {
4790
await userEvent.type(screen.getByLabelText('Keywords'), keywords);
4891
await fixture.whenStable();
4992
},
93+
async whenStable() {
94+
return fixture.whenStable();
95+
},
5096
};
5197
}
5298
});

apps/404-recipe-filter-material-starter/src/app/recipe/recipe-search.shallow.spec.ts

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ describe(RecipeSearch.name, () => {
3838
const { getFirstAddButton, getMealPlannerRecipeNames } =
3939
await renderComponent();
4040

41-
await getFirstAddButton().click();
41+
await userEvent.click(getFirstAddButton());
4242

4343
expect(await getMealPlannerRecipeNames()).toEqual(['Burger']);
4444
});
@@ -48,7 +48,7 @@ describe(RecipeSearch.name, () => {
4848
await renderComponentWithBurgerInMealPlanner();
4949

5050
/* Can't add burger because there is already a burger with the same id. */
51-
expect(getFirstAddButton().isDisabled()).toBe(true);
51+
expect(getFirstAddButton()).toBeDisabled();
5252
});
5353

5454
async function renderComponentWithBurgerInMealPlanner() {
@@ -88,13 +88,9 @@ describe(RecipeSearch.name, () => {
8888
return {
8989
mealPlanner,
9090
getFirstAddButton() {
91-
const addButtonEl = screen.getAllByRole<HTMLButtonElement>('button', {
91+
return screen.getAllByRole<HTMLButtonElement>('button', {
9292
name: 'ADD',
9393
})[0];
94-
return {
95-
click: () => userEvent.click(addButtonEl),
96-
isDisabled: () => addButtonEl.disabled,
97-
};
9894
},
9995
async getMealPlannerRecipeNames() {
10096
const recipes = await firstValueFrom(mealPlanner.recipes$);

0 commit comments

Comments
 (0)