Skip to content

Commit ee11419

Browse files
committed
Add stock level message to product page based on inventory settings - add tests
1 parent 0311fea commit ee11419

File tree

6 files changed

+112
-0
lines changed

6 files changed

+112
-0
lines changed

core/tests/fixtures/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import { CustomerFixture } from './customer';
1414
import { OrderFixture } from './order';
1515
import { extendedPage, toHaveURL } from './page';
1616
import { PromotionFixture } from './promotion';
17+
import { SettingsFixture } from './settings';
1718
import { WebPageFixture } from './webpage';
1819

1920
interface Fixtures {
@@ -23,6 +24,7 @@ interface Fixtures {
2324
customer: CustomerFixture;
2425
currency: CurrencyFixture;
2526
promotion: PromotionFixture;
27+
settings: SettingsFixture;
2628
webPage: WebPageFixture;
2729
/**
2830
* 'reuseCustomerSession' sets the the configuration for the customer fixture and determines whether to reuse the customer session.
@@ -107,6 +109,16 @@ export const test = baseTest.extend<Fixtures>({
107109
},
108110
{ scope: 'test' },
109111
],
112+
settings: [
113+
async ({ page }, use, currentTest) => {
114+
const settingsFixture = new SettingsFixture(page, currentTest);
115+
116+
await use(settingsFixture);
117+
118+
await settingsFixture.cleanup();
119+
},
120+
{ scope: 'test' },
121+
],
110122
webPage: [
111123
async ({ page }, use, currentTest) => {
112124
const webPageFixture = new WebPageFixture(page, currentTest);
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { Fixture } from '~/tests/fixtures/fixture';
2+
import { InventorySettings } from '~/tests/fixtures/utils/api/settings';
3+
4+
export class SettingsFixture extends Fixture {
5+
private initialInventorySettings: InventorySettings | null = null;
6+
7+
async getInventorySettings(): Promise<InventorySettings> {
8+
const settings = await this.api.settings.getInventorySettings();
9+
10+
return settings;
11+
}
12+
13+
async setInventorySettings(settings: InventorySettings): Promise<void> {
14+
if (!this.initialInventorySettings) {
15+
this.initialInventorySettings = await this.getInventorySettings();
16+
}
17+
18+
await this.api.settings.setInventorySettings(settings);
19+
}
20+
21+
async cleanup() {
22+
if (this.initialInventorySettings) {
23+
await this.api.settings.setInventorySettings(this.initialInventorySettings);
24+
}
25+
}
26+
}

core/tests/fixtures/utils/api/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { CurrenciesApi, currenciesHttpClient } from '~/tests/fixtures/utils/api/
44
import { CustomersApi, customersHttpClient } from '~/tests/fixtures/utils/api/customers';
55
import { OrdersApi, ordersHttpClient } from '~/tests/fixtures/utils/api/orders';
66
import { PromotionsApi, promotionsHttpClient } from '~/tests/fixtures/utils/api/promotions';
7+
import { SettingsApi, settingsHttpClient } from '~/tests/fixtures/utils/api/settings';
78
import { WebPagesApi, webPagesHttpClient } from '~/tests/fixtures/utils/api/webpages';
89

910
export interface ApiClient {
@@ -13,6 +14,7 @@ export interface ApiClient {
1314
currencies: CurrenciesApi;
1415
orders: OrdersApi;
1516
promotions: PromotionsApi;
17+
settings: SettingsApi;
1618
webPages: WebPagesApi;
1719
}
1820

@@ -23,5 +25,6 @@ export const httpApiClient: ApiClient = {
2325
currencies: currenciesHttpClient,
2426
orders: ordersHttpClient,
2527
promotions: promotionsHttpClient,
28+
settings: settingsHttpClient,
2629
webPages: webPagesHttpClient,
2730
};
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import { z } from 'zod';
2+
3+
import { httpClient } from '../client';
4+
import { apiResponseSchema } from '../schema';
5+
6+
import { InventorySettings, SettingsApi } from '.';
7+
8+
const InventorySettingsSchema = z
9+
.object({
10+
default_out_of_stock_message: z.string(),
11+
show_out_of_stock_message: z.boolean(),
12+
stock_level_display: z.enum(['DONT_SHOW', 'SHOW', 'SHOW_WHEN_LOW']).nullable(),
13+
})
14+
.transform(
15+
(data): InventorySettings => ({
16+
defaultOutOfStockMessage: data.default_out_of_stock_message,
17+
showOutOfStockMessage: data.show_out_of_stock_message,
18+
stockLevelDisplay: data.stock_level_display,
19+
}),
20+
);
21+
22+
export const settingsHttpClient: SettingsApi = {
23+
getInventorySettings: async (): Promise<InventorySettings> => {
24+
const resp = await httpClient
25+
.get(`/v3/settings/inventory`)
26+
.parse(apiResponseSchema(InventorySettingsSchema));
27+
28+
return resp.data;
29+
},
30+
setInventorySettings: async (settings: InventorySettings): Promise<void> => {
31+
await httpClient.put(`/v3/settings/inventory`, settings);
32+
},
33+
};
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export interface InventorySettings {
2+
readonly defaultOutOfStockMessage?: string;
3+
readonly showOutOfStockMessage?: boolean;
4+
readonly stockLevelDisplay?: 'DONT_SHOW' | 'SHOW' | 'SHOW_WHEN_LOW' | null;
5+
}
6+
7+
export interface SettingsApi {
8+
getInventorySettings: () => Promise<InventorySettings>;
9+
setInventorySettings: (settings: InventorySettings) => Promise<void>;
10+
}
11+
12+
export { settingsHttpClient } from './http';

core/tests/ui/e2e/product.spec.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,31 @@ test('Displays a simple product and can add it to the cart', async ({
3434

3535
test('Displays out of stock product correctly', async ({ page, catalog }) => {
3636
const t = await getTranslations('Product.ProductDetails');
37+
38+
const product = await catalog.createSimpleProduct({
39+
inventoryTracking: 'product',
40+
inventoryLevel: 0,
41+
});
42+
43+
await page.goto(product.path);
44+
await page.waitForLoadState('networkidle');
45+
46+
await expect(page.getByRole('heading', { name: product.name })).toBeVisible();
47+
await expect(page.getByRole('button', { name: t('Submit.outOfStock') })).toBeVisible();
48+
});
49+
50+
test('Displays out of stock product correctly when out of stock message is enabled', async ({
51+
page,
52+
catalog,
53+
settings,
54+
}) => {
55+
const t = await getTranslations('Product.ProductDetails');
56+
57+
await settings.setInventorySettings({
58+
showOutOfStockMessage: true,
59+
defaultOutOfStockMessage: 'Currently out of stock',
60+
});
61+
3762
const product = await catalog.createSimpleProduct({
3863
inventoryTracking: 'product',
3964
inventoryLevel: 0,
@@ -44,6 +69,7 @@ test('Displays out of stock product correctly', async ({ page, catalog }) => {
4469

4570
await expect(page.getByRole('heading', { name: product.name })).toBeVisible();
4671
await expect(page.getByRole('button', { name: t('Submit.outOfStock') })).toBeVisible();
72+
await expect(page.getByText('Currently out of stock')).toBeVisible();
4773
});
4874

4975
test('Displays product price correctly for an alternate currency', async ({

0 commit comments

Comments
 (0)