Socket
Socket
Sign inDemoInstall

@shopware-pwa/composables-next

Package Overview
Dependencies
Maintainers
0
Versions
685
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@shopware-pwa/composables-next - npm Package Compare versions

Comparing version 1.1.0 to 1.1.1

18

package.json
{
"name": "@shopware-pwa/composables-next",
"version": "1.1.0",
"version": "1.1.1",
"description": "Shopware Frontends composables for Vue",

@@ -57,15 +57,15 @@ "author": "Shopware",

"scule": "1.3.0",
"@shopware-pwa/helpers-next": "1.0.0",
"@shopware/api-client": "1.0.1"
"@shopware-pwa/helpers-next": "1.0.1",
"@shopware/api-client": "1.0.2"
},
"devDependencies": {
"@nuxt/kit": "3.12.2",
"@vitest/coverage-v8": "1.6.0",
"@nuxt/kit": "3.12.4",
"@vitest/coverage-v8": "2.0.4",
"@vue/test-utils": "2.4.6",
"happy-dom": "14.12.3",
"typescript": "5.5.3",
"typescript": "5.5.4",
"unbuild": "2.0.0",
"vitest": "1.6.0",
"vue": "3.4.31",
"eslint-config-shopware": "0.0.9",
"vitest": "2.0.4",
"vue": "3.4.35",
"eslint-config-shopware": "1.0.0",
"tsconfig": "0.0.0"

@@ -72,0 +72,0 @@ },

@@ -154,12 +154,14 @@ # shopware/frontends - composables-next

### Latest changes: 1.1.0
### Latest changes: 1.1.1
### Minor Changes
### Patch Changes
- [#1071](https://github.com/shopware/frontends/pull/1071) [`f9d2735`](https://github.com/shopware/frontends/commit/f9d27353ec6383cb22cdece0469f8fdd13250958) Thanks [@mdanilowicz](https://github.com/mdanilowicz)! - - `useCart` - new `addProducts` function that allows adding a set of products to the cart
- [#1074](https://github.com/shopware/frontends/pull/1074) [`b688163`](https://github.com/shopware/frontends/commit/b68816391ee8ed1ac94a6462a2a016d708f259b4) Thanks [@mkucmus](https://github.com/mkucmus)! - `useOrderDetails` - Load shipping address for the order details. Ivoking a `loadOrderDetails` method now will fetch also a `shippingOrderAddress` association.
- [#893](https://github.com/shopware/frontends/pull/893) [`d95751e`](https://github.com/shopware/frontends/commit/d95751ecde443a033f17def838bcc25aeba6951e) Thanks [@khanSoliheen](https://github.com/khanSoliheen)! - - `useWishList`:
- Added `getCurrentPage` and `getTotalPagesCount` to the returned object
- Changed `getWishlistProducts` to accept `page` and `query` as optional parameters
- `useSyncWishList`:
- Changed `getWishlistProducts`, added Parameter to pass default criterias
- [#1089](https://github.com/shopware/frontends/pull/1089) [`db7c93f`](https://github.com/shopware/frontends/commit/db7c93ff8cbb581221c11a492e77068af8faa8d6) Thanks [@mkucmus](https://github.com/mkucmus)! - Migrate eslint config to flat format
- [#1099](https://github.com/shopware/frontends/pull/1099) [`3bde5fe`](https://github.com/shopware/frontends/commit/3bde5fe6d4a9c31d380defc05a7903cf99cb8136) Thanks [@mdanilowicz](https://github.com/mdanilowicz)! - `useCart` - Fixed adding promotion code
- Updated dependencies [[`b688163`](https://github.com/shopware/frontends/commit/b68816391ee8ed1ac94a6462a2a016d708f259b4), [`db7c93f`](https://github.com/shopware/frontends/commit/db7c93ff8cbb581221c11a492e77068af8faa8d6), [`b688163`](https://github.com/shopware/frontends/commit/b68816391ee8ed1ac94a6462a2a016d708f259b4)]:
- @shopware-pwa/helpers-next@1.0.1
- @shopware/api-client@1.0.2

@@ -11,2 +11,3 @@ import { shallowMount } from "@vue/test-utils";

};
swNotifications?: unknown;
};

@@ -20,3 +21,3 @@

const compoment = defineComponent({
const component = defineComponent({
setup,

@@ -33,3 +34,3 @@ render() {

const wrapper = shallowMount(compoment, {
const wrapper = shallowMount(component, {
global: {

@@ -36,0 +37,0 @@ provide: injections,

@@ -1,7 +0,10 @@

import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import { resolveCmsComponent, getDefaultApiParams } from "./index";
import CmsPage from "./mocks/CmsPage";
import type { Schemas } from "#shopware";
import * as vue from "vue";
vi.mock("vue");
describe("resolveCmsComponent", () => {
vi.spyOn(vue, "resolveComponent").mockImplementation((element) => element);
it("should resolve a cms component", () => {

@@ -22,2 +25,3 @@ const result = resolveCmsComponent(

it("cms section component", () => {
vi.spyOn(vue, "resolveComponent").mockImplementation(() => ({}));
const result = resolveCmsComponent({

@@ -36,2 +40,13 @@ apiAlias: "cms_section",

});
it("component should not be resolved because of the error", () => {
vi.spyOn(vue, "resolveComponent").mockImplementation(() => {
throw new Error("error");
});
const result = resolveCmsComponent({
apiAlias: "cms_custom",
} as unknown as Schemas["CmsBlock"]);
expect(result.isResolved).toBe(false);
});
});

@@ -93,2 +93,3 @@ import type { Schemas } from "#shopware";

resolved: false,
isResolved: false,
error: (e as Error).message,

@@ -95,0 +96,0 @@ };

@@ -1147,2 +1147,3 @@ const Order = {

"018c6832f1a1731db276839b3f251fc2": true,
"123-test": true,
},

@@ -1149,0 +1150,0 @@ };

@@ -59,2 +59,3 @@ import type { Schemas } from "#shopware";

verticalAlign: ElementConfig<VerticalAlign>;
horizontalAlign: ElementConfig<VerticalAlign>;
};

@@ -61,0 +62,0 @@

@@ -42,2 +42,5 @@ import { describe, expect, it, beforeEach, vi } from "vitest";

it("add single product", async () => {
expect(vm.cartItems).toEqual([]);
expect(vm.totalPrice).toBe(0);
expect(vm.subtotal).toBe(0);
await vm.addProduct({

@@ -62,2 +65,21 @@ id: itemsMock.items[0].referencedId as string,

);
await vm.addProduct({
id: itemsMock.items[0].referencedId as string,
});
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("addLineItem"),
expect.objectContaining({
body: {
items: [
{
type: itemsMock.items[0].type,
id: itemsMock.items[0].referencedId,
quantity: 0,
},
],
},
}),
);
});

@@ -76,2 +98,7 @@

);
expect(vm.shippingTotal).toBe(0);
expect(vm.subtotal).toBe(16.11);
expect(vm.isVirtualCart).toBe(false);
expect(vm.totalPrice).toBe(16.11);
});

@@ -122,2 +149,74 @@

});
it("submitPromotionCode", async () => {
injections.apiClient.invoke.mockResolvedValue({
data: {
lineItems: [
{
type: "promotion",
payload: {
code: "3a64e872ca404522a2c5d43ebc751e6b",
},
},
{
type: "product",
good: true,
quantity: 1,
id: "e05e9340aff4484f9009646dfd572df9",
},
],
},
});
await vm.addPromotionCode("PROMO_CODE");
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("addLineItem"),
expect.objectContaining({
body: {
items: [
{
referencedId: "PROMO_CODE",
type: "promotion",
},
],
},
}),
);
expect(vm.appliedPromotionCodes).toEqual([
{
type: "promotion",
payload: {
code: "3a64e872ca404522a2c5d43ebc751e6b",
},
},
]);
expect(vm.count).toBe(1);
expect(vm.totalPrice).toBe(0);
});
it("handle api cart error", async () => {
injections.apiClient.invoke.mockResolvedValue({
data: {
errors: [
{
status: 400,
code: "CHECKOUT__CART_ITEM_NOT_FOUND",
detail: "Line item not found",
},
],
},
});
await vm.refreshCart();
await vm.addProducts(itemsMock.items);
expect(vm.consumeCartErrors()).toEqual({
"0": {
status: 400,
code: "CHECKOUT__CART_ITEM_NOT_FOUND",
detail: "Line item not found",
},
});
expect(vm.consumeCartErrors()).toEqual(null);
});
});

@@ -123,3 +123,3 @@ import { computed } from "vue";

id: params.id,
quantity: params.quantity,
quantity: params.quantity ?? 0,
type: "product",

@@ -194,3 +194,3 @@ },

{
id: promotionCode,
referencedId: promotionCode,
type: "promotion",

@@ -197,0 +197,0 @@ },

@@ -126,2 +126,44 @@ import { useCartItem } from "./useCartItem";

});
it("itemSpecialPrice", () => {
const { vm } = useSetup(() =>
useCartItem(
ref(
Object.assign(
{ ...lineItem },
{
price: {
listPrice: {
price: 10,
},
unitPrice: 5,
},
},
),
) as unknown as Ref<Schemas["LineItem"]>,
),
);
expect(vm.itemSpecialPrice).toBe(5);
});
it("itemRegularPrice from listPrice", () => {
const { vm } = useSetup(() =>
useCartItem(
ref({
price: {
listPrice: {
price: 10,
},
},
}) as unknown as Ref<Schemas["LineItem"]>,
),
);
expect(vm.itemRegularPrice).toBe(10);
});
it("should throw an error if cartItem is not provided", () => {
expect(() =>
// @ts-expect-error we deliberately pass null to invoke error
useCartItem(null),
).toThrow("[useCartItem] mandatory cartItem argument is missing.");
});
});

@@ -6,3 +6,3 @@ import { describe, expect, it } from "vitest";

describe("useCustomerOrders", () => {
it("changeLanguage", async () => {
it("should inovke load orders", async () => {
const { vm, injections } = useSetup(useCustomerOrders);

@@ -17,5 +17,6 @@ injections.apiClient.invoke.mockResolvedValue({

);
expect(vm.totalPages).toBe(0);
});
it("changeCurrentPage", async () => {
it("should invoke change page", async () => {
const { vm, injections } = useSetup(useCustomerOrders);

@@ -22,0 +23,0 @@ injections.apiClient.invoke.mockResolvedValue({

import { describe, expect, it, vi } from "vitest";
import { useInternationalization } from "./useInternationalization";
import type { RouteObject } from "./useInternationalization";
import { useSetup } from "./_test";
import type { Schemas } from "#shopware";

@@ -24,3 +26,3 @@ describe("useInternationalization", () => {

it("getAvailableLanguages", async () => {
it("should invoke getting available languages", async () => {
const { vm, injections } = useSetup(useInternationalization);

@@ -34,3 +36,3 @@ injections.apiClient.invoke.mockResolvedValue({ data: {} });

it("changeLanguage", async () => {
it("should invoke change language", async () => {
const { vm, injections } = useSetup(useInternationalization);

@@ -44,2 +46,113 @@ injections.apiClient.invoke.mockResolvedValue({ data: {} });

});
it("getLanguageCodeFromId", async () => {
const { vm } = useSetup(useInternationalization);
vm.languages = [
{ id: "test-id", translationCode: { code: "test-code" } },
] as Schemas["Language"][];
expect(vm.getLanguageCodeFromId("test-id")).toBe("test-code");
});
it("getLanguageCodeFromId - no translationCode", async () => {
const { vm } = useSetup(useInternationalization);
vm.languages = [{ id: "test-id" }] as Schemas["Language"][];
expect(vm.getLanguageCodeFromId("test-id")).toBe("");
});
it("getLanguageCodeFromId - no languages", async () => {
const { vm } = useSetup(useInternationalization);
expect(() => vm.getLanguageCodeFromId("test-id")).toThrowError();
});
it("getLanguageIdFromCode", async () => {
const { vm } = useSetup(useInternationalization);
vm.languages = [
{ id: "test-id", translationCode: { code: "test-code" } },
] as Schemas["Language"][];
expect(vm.getLanguageIdFromCode("test-code")).toBe("test-id");
});
it("getLanguageIdFromCode - no id", async () => {
const { vm } = useSetup(useInternationalization);
vm.languages = [
{ translationCode: { code: "test-code" } },
] as Schemas["Language"][];
expect(vm.getLanguageIdFromCode("test-code")).toBe("");
});
it("getLanguageIdFromCode - no languages", async () => {
const { vm } = useSetup(useInternationalization);
expect(() => vm.getLanguageIdFromCode("test-code")).toThrowError();
});
it("should return the storefront url with the devStorefrontUrl", async () => {
const url = "http://frontend.test";
const { vm } = useSetup(useInternationalization);
expect(vm.replaceToDevStorefront(url)).toBe(url);
});
it("formatLink", async () => {
const { vm } = useSetup(() =>
useInternationalization((element) => element),
);
expect(vm.formatLink("test")).toBe("test");
});
it("formatLink with path", async () => {
const { vm } = useSetup(() =>
useInternationalization((element) => element),
);
expect(vm.formatLink({ path: "test" })).toStrictEqual({ path: "test" });
});
it("formatLink custom structure", async () => {
const { vm } = useSetup(() =>
useInternationalization((element) => element),
);
expect(
vm.formatLink({ custom: "test" } as unknown as RouteObject),
).toStrictEqual({
custom: "test",
});
});
it("replaceToDevStorefront with devStorefrontUrl", async () => {
const { vm } = useSetup(
() => useInternationalization((element) => element),
{
shopware: { devStorefrontUrl: "http://dev-storefront.test" },
},
);
expect(vm.getStorefrontUrl()).toBe("http://dev-storefront.test");
expect(vm.replaceToDevStorefront("http://localhost:3000/test")).toBe(
"http://dev-storefront.test/test",
);
});
it("getStorefrontUrl without devStorefrontUrl and window", async () => {
vi.spyOn(window, "location", "get").mockImplementation(
() => ({}) as Location,
);
const { vm } = useSetup(
() => useInternationalization((element) => element),
{
shopware: { devStorefrontUrl: null },
},
);
expect(vm.getStorefrontUrl()).toBe("");
});
it("pathResolver absolute path", async () => {
const { vm } = useSetup(() =>
useInternationalization((element) => element),
);
expect(vm.formatLink("http://www.test.test")).toBe("http://www.test.test");
});
it("pathResolver without resolver", async () => {
const { vm } = useSetup(() => useInternationalization());
expect(vm.formatLink("test")).toBe("test");
});
});
import { describe, expect, it } from "vitest";
import { useListing } from "./useListing";
import { useListing, useCategoryListing } from "./useListing";
import { useSetup } from "./_test";
import searchMock from "./mocks/Search";
import ContextError from "./helpers/ContextError";
import type { Schemas } from "#shopware";
describe("useListing", () => {
it("invoke search", async () => {
it("should invoke search", async () => {
const { vm, injections } = await useSetup(() =>

@@ -31,3 +32,3 @@ useListing({

it('invoke "readQuotes"', async () => {
it('should invoke "readQuotes"', async () => {
const { vm, injections } = await useSetup(() =>

@@ -59,3 +60,3 @@ useListing({

it('invoke "readQuotes" - errors', async () => {
it("should handle context error", async () => {
let error: unknown | null = null;

@@ -74,3 +75,3 @@ try {

it("setCurrentFilters", async () => {
it("should set current filters", async () => {
const { vm, injections } = await useSetup(() =>

@@ -144,2 +145,110 @@ useListing({

});
it("useCategoryListing - error is thrown when listingContext was not provided in parent tree", async () => {
expect(() => useSetup(useCategoryListing)).toThrowError();
});
it("setInitialListing", async () => {
const { vm } = await useSetup(() =>
useListing({
listingType: "categoryListing",
categoryId: "1234",
}),
);
vm.setInitialListing({
apiAlias: "product_listing",
} as Schemas["ProductListingResult"]);
expect(vm.getInitialListing).toEqual({ apiAlias: "product_listing" });
});
it("initSearch", () => {
const { vm, injections } = useSetup(() =>
useListing({ listingType: "productSearchListing" }),
);
injections.apiClient.invoke.mockResolvedValue({ data: {} });
vm.initSearch({
search: "test",
});
expect(vm.getCurrentPage).toBe(1);
expect(vm.getTotalPagesCount).toBe(0);
expect(vm.getLimit).toBe(10);
});
it("loadMore", async () => {
const { vm, injections } = await useSetup(() =>
useListing({
listingType: "productSearchListing",
}),
);
injections.apiClient.invoke.mockResolvedValue({ data: { page: 1 } });
await vm.loadMore();
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("search"),
expect.objectContaining({
body: {
p: 2,
},
headers: {
"sw-include-seo-urls": true,
},
}),
);
});
it("changeCurrentSortingOrder", async () => {
const { vm, injections } = await useSetup(() =>
useListing({
listingType: "productSearchListing",
}),
);
injections.apiClient.invoke.mockResolvedValue({ data: { page: 1 } });
vm.changeCurrentSortingOrder("test");
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("search"),
expect.objectContaining({
body: {
order: "test",
},
headers: {
"sw-include-seo-urls": true,
},
}),
);
});
it("changeCurrentPage", async () => {
const { vm, injections } = await useSetup(() =>
useListing({
listingType: "productSearchListing",
}),
);
injections.apiClient.invoke.mockResolvedValue({ data: { page: 1 } });
vm.changeCurrentPage(2);
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("search"),
expect.objectContaining({
body: {
page: 2,
},
headers: {
"sw-include-seo-urls": true,
},
}),
);
});
it("getAvailableFilters", async () => {
const { vm } = await useSetup(() =>
useListing({
listingType: "productSearchListing",
}),
);
expect(vm.getAvailableFilters).toEqual([]);
});
});

@@ -76,3 +76,3 @@ import { inject, computed, ref, provide } from "vue";

loadMore(
criteria: operations["searchPage post /search"]["body"],
criteria?: operations["searchPage post /search"]["body"],
): Promise<void>;

@@ -79,0 +79,0 @@ /**

@@ -7,3 +7,3 @@ import { describe, expect, it } from "vitest";

describe("methods", () => {
describe("addToWishlist", () => {
describe("should add product to the wishlist", () => {
it("wishlist add product", () => {

@@ -17,3 +17,3 @@ const { vm } = useSetup(useLocalWishlist);

describe("removeFromWishlist", () => {
it("wishlist add product", () => {
it("should remove product from the wishlist", () => {
const { vm } = useSetup(useLocalWishlist);

@@ -25,12 +25,4 @@ vm.removeFromWishlist("some-id");

describe("removeFromWishlist", () => {
it("wishlist remove product", () => {
const { vm } = useSetup(useLocalWishlist);
vm.removeFromWishlist("some-id");
expect(vm.count).toBe(0);
});
});
describe("clearWishlist", () => {
it("clearWishlist", () => {
it("should clear the wishlist", () => {
const { vm } = useSetup(useLocalWishlist);

@@ -45,3 +37,3 @@ vm.addToWishlist("some-id");

describe("getWishlistProducts", () => {
it("getWishlistProducts", () => {
it("should get the wishlist products", () => {
const { vm } = useSetup(useLocalWishlist);

@@ -52,3 +44,3 @@ vm.clearWishlist();

});
it("getWishlistProducts with items", () => {
it("should get the wishlist products after adding product", () => {
const { vm } = useSetup(useLocalWishlist);

@@ -59,4 +51,10 @@ vm.addToWishlist("some-id");

});
it("getWishlistProducts with items localStorage", () => {
const { vm } = useSetup(useLocalWishlist);
localStorage.removeItem("sw-wishlist-items");
vm.getWishlistProducts();
expect(vm.count).toBe(1);
});
});
});
});

@@ -1,5 +0,14 @@

import { describe, expect, it } from "vitest";
import { describe, expect, it, vi } from "vitest";
import { useNavigationSearch } from "./useNavigationSearch";
import { useSetup } from "./_test";
import { useSessionContext } from "./useSessionContext";
import { ref } from "vue";
vi.mock("./useSessionContext.ts");
const sessionContext = ref();
vi.mocked(useSessionContext).mockReturnValue({
sessionContext,
} as unknown as ReturnType<typeof useSessionContext>);
const mockedResponse = {

@@ -88,2 +97,16 @@ translated: [],

});
it("resolvePath with categoryId", async () => {
const { vm } = useSetup(useNavigationSearch);
sessionContext.value = {
salesChannel: {
navigationCategoryId: "categoryIdTest",
},
};
expect(await vm.resolvePath("/")).toStrictEqual({
foreignKey: "categoryIdTest",
routeName: "frontend.navigation.page",
});
});
});

@@ -36,2 +36,21 @@ import { describe, expect, it } from "vitest";

});
it("getNewsletterStatus", async () => {
const { vm, injections } = useSetup(useNewsletter);
injections.apiClient.invoke.mockResolvedValue({ data: {} });
await vm.getNewsletterStatus();
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("readNewsletterRecipient"),
);
});
it("isNewsletterSubscriber", async () => {
const { vm } = useSetup(useNewsletter);
expect(vm.isNewsletterSubscriber).toBe(false);
vm.newsletterStatus = "direct";
expect(vm.isNewsletterSubscriber).toBe(true);
});
});
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { useNotifications } from "./useNotifications";
import { useSetup } from "./_test";
describe("useNotifications", () => {

@@ -13,3 +14,3 @@ beforeEach(() => {

it("notification flow", async () => {
it("should trigger sample notification flow", async () => {
const { vm } = useSetup(useNotifications);

@@ -36,2 +37,22 @@

});
it("injected empty swNotifications", () => {
const { vm } = useSetup(useNotifications, {
swNotifications: { value: null },
});
expect(vm.notifications).toEqual([]);
vm.removeOne(2332);
expect(vm.notifications).toEqual([]);
vm.pushSuccess("test");
});
it("injected empty swNotifications and push success", () => {
const { vm } = useSetup(useNotifications, {
swNotifications: { value: null },
});
vm.pushSuccess("test");
expect(vm.notifications.length).toBe(1);
});
});

@@ -87,3 +87,3 @@ import { computed, ref, inject, provide } from "vue";

message: string,
options: NotificationOptions,
options: Required<Pick<NotificationOptions, "type">> & NotificationOptions,
) {

@@ -97,3 +97,3 @@ const timeout = options.timeout || 2500;

id: messageId,
type: options.type || "info",
type: options.type,
message,

@@ -100,0 +100,0 @@ });

@@ -31,3 +31,3 @@ import { describe, expect, it } from "vitest";

it("handlePayment", async () => {
it("should handle setting the order payment", async () => {
const { vm, injections } = useSetup(() => useOrderDetails("123-test"));

@@ -49,3 +49,3 @@ injections.apiClient.invoke.mockResolvedValue({ data: {} });

it("cancel", async () => {
it("should cancel the order", async () => {
const { vm, injections } = useSetup(() => useOrderDetails("123-test"));

@@ -113,2 +113,25 @@ injections.apiClient.invoke.mockResolvedValue({ data: {} });

});
it("getPaymentMethods", async () => {
const { vm, injections } = useSetup(() => useOrderDetails("123-test"));
injections.apiClient.invoke.mockResolvedValue({ data: {} });
await vm.getPaymentMethods();
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("readPaymentMethod"),
expect.objectContaining({
body: {
onlyAvailable: true,
},
}),
);
});
it("paymentChangeable", async () => {
const { vm, injections } = useSetup(() => useOrderDetails("123-test", {}));
injections.apiClient.invoke.mockResolvedValue({ data: Order });
expect(vm.paymentChangeable).toEqual(false);
await vm.loadOrderDetails();
expect(vm.paymentChangeable).toEqual(true);
});
});

@@ -27,2 +27,3 @@ import { computed, ref, inject, provide } from "vue";

shippingMethod: {},
shippingOrderAddress: {},
stateMachineState: {},

@@ -199,3 +200,5 @@ },

const total = computed(() => _sharedOrder.value?.price?.totalPrice);
const status = computed(() => _sharedOrder.value?.stateMachineState?.name);
const status = computed(
() => _sharedOrder.value?.stateMachineState?.translated.name,
);
const statusTechnicalName = computed(

@@ -202,0 +205,0 @@ () => _sharedOrder.value?.stateMachineState?.technicalName,

@@ -10,3 +10,3 @@ import { describe, expect, it } from "vitest";

describe("useOrderPayment", () => {
it("handlePayment", async () => {
it("should handle the order payment", async () => {
const { vm, injections } = useSetup(() =>

@@ -36,3 +36,47 @@ useOrderPayment(

);
vm.changePaymentMethod("test");
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("orderSetPayment"),
expect.objectContaining({
body: {
orderId: "018c6832f1a1731db276839b3f251fc2",
paymentMethodId: "test",
},
}),
);
});
it("should not invoke API calls for empty order", async () => {
const { vm } = useSetup(() =>
useOrderPayment(
computed(() => null) as unknown as ComputedRef<Schemas["Order"]>,
),
);
expect(vm.changePaymentMethod("test")).resolves.toBeUndefined();
expect(vm.handlePayment()).resolves.toBeUndefined();
});
it("should be a asynchronous payment", () => {
const { vm } = useSetup(() =>
useOrderPayment(
computed(() =>
Object.assign(Order.orders.elements[0], {
transactions: [
{
paymentMethod: {
active: true,
asynchronous: true,
afterOrderEnabled: true,
},
},
],
}),
) as unknown as ComputedRef<Schemas["Order"]>,
),
);
expect(vm.isAsynchronous).toBe(true);
});
});

@@ -1,5 +0,18 @@

import { describe, expect, it } from "vitest";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { ref } from "vue";
import { usePrice } from "./usePrice";
import { useSetup } from "./_test";
import { useSessionContext } from "./useSessionContext";
const currentNavigator = global.navigator;
vi.mock("./useSessionContext.ts");
const sessionContext = ref();
beforeEach(() => {
vi.clearAllMocks();
vi.mocked(useSessionContext).mockReturnValue({
sessionContext,
} as unknown as ReturnType<typeof useSessionContext>);
});
describe("usePrice", () => {

@@ -10,2 +23,30 @@ it("should be defined", () => {

it("use default locale if locale is not provided", () => {
vi.spyOn(global, "navigator", "get").mockImplementation(
() => ({}) as Navigator,
);
const { vm } = useSetup(usePrice);
expect(vm.getFormattedPrice(2.55)).toMatchInlineSnapshot('"2.55"');
vm.update({
currencyCode: "USD",
localeCode: undefined,
});
expect(vm.getFormattedPrice(2.55)).toMatchInlineSnapshot('"$2.55"');
});
it("should use navigator language if locale is not provided", () => {
vi.spyOn(global, "navigator", "get").mockImplementation(
() => currentNavigator,
);
vi.spyOn(navigator, "language", "get").mockImplementation(() => "en-FR");
const { vm } = useSetup(usePrice);
vm.update({
currencyCode: "USD",
localeCode: undefined,
});
expect(vm.getFormattedPrice(2.55)).toMatchInlineSnapshot('"$2.55"');
});
it("should init price object", () => {

@@ -47,2 +88,13 @@ const { vm } = useSetup(() =>

});
it("watch currency change", async () => {
const { vm } = useSetup(usePrice);
sessionContext.value = {
currency: {
isoCode: "PLN",
},
};
await vm.$nextTick();
expect(vm.currencyCode).toBe("PLN");
});
});

@@ -5,2 +5,3 @@ import { describe, expect, it } from "vitest";

import { useSetup } from "./_test";
import { ref } from "vue";

@@ -14,7 +15,24 @@ describe("useProduct", () => {

it("should return undefined configurator object", () => {
it("changeVariant - should merge the current product with the new variant data", () => {
const { vm } = useSetup(() => useProduct(mockedProduct));
expect(vm.changeVariant()).toBeUndefined();
});
expect(vm.configurator).toBe(undefined);
it("changeVariant - empty", () => {
const { vm } = useSetup(useProduct);
vm.changeVariant(Object.assign({ ...mockedProduct }, { id: "new-id" }));
expect(vm.product.id).toBe("new-id");
});
it("init without product should throw an error", () => {
expect(() =>
useSetup(() =>
useProduct(
// @ts-expect-error if API returns null we want to be prepared for it
ref(null),
),
),
).toThrowError("Product context is not provided");
});
});

@@ -21,3 +21,3 @@ import { computed } from "vue";

*/
changeVariant(variant: Partial<Schemas["Product"]>): void;
changeVariant(variant?: Partial<Schemas["Product"]>): void;
};

@@ -39,2 +39,3 @@

}
const _configurator = useContext("configurator", {

@@ -44,3 +45,7 @@ context: product && configurator,

function changeVariant(variant: Partial<Schemas["Product"]>) {
function changeVariant(variant?: Partial<Schemas["Product"]>) {
if (!variant) {
console.warn("[useProduct][changeVariant]: Provided variant is empty");
return;
}
_product.value = Object.assign({}, _product.value, variant);

@@ -47,0 +52,0 @@ }

import { describe, expect, it, vi } from "vitest";
import { useProductAssociations } from "./useProductAssociations";
import { computed } from "vue";
import { computed, ref } from "vue";
import mockedProduct from "./mocks/Product";

@@ -91,2 +91,16 @@ import mockedCrossSelling from "./mocks/CrossSellingResponse";

});
it("init without product should throw an error", () => {
expect(() =>
useSetup(() =>
useProductAssociations(
// @ts-expect-error if API returns null we want to be prepared for it
ref(null),
{
associationContext: "cross-selling",
},
),
),
).toThrowError("[useProductAssociations]: Product is not provided.");
});
});

@@ -7,12 +7,11 @@ import { describe, expect, it, vi } from "vitest";

import { useSetup } from "./_test";
import { useProduct } from "./useProduct";
vi.mock("./useProduct.ts");
describe("useProductConfigurator", () => {
vi.mock("./useProduct.ts", () => ({
useProduct() {
return {
configurator: ref(mockedConfigurator),
product: ref(mockedProduct),
};
},
}));
vi.mocked(useProduct).mockReturnValue({
configurator: ref(mockedConfigurator),
product: ref(mockedProduct),
} as unknown as ReturnType<typeof useProduct>);

@@ -59,2 +58,23 @@ it("handleChange callback function was called", () => {

});
it("product - with options", () => {
vi.mocked(useProduct).mockReturnValue({
configurator: ref(null),
product: ref({
options: [
{
id: "cc02c6cf39ad43d5856a25f8928490bf",
},
{
id: "aa02c6cf39ad43d5856a25f8928490bf",
},
],
}),
} as unknown as ReturnType<typeof useProduct>);
const { vm } = useSetup(useProductConfigurator);
expect(vm.isLoadingOptions).toBe(true);
expect(vm.getOptionGroups).toStrictEqual([]);
});
});

@@ -1,2 +0,2 @@

import { describe, expect, it } from "vitest";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { useProductPrice } from "./useProductPrice";

@@ -10,2 +10,5 @@ import { ref } from "vue";

describe("useProductPrice", () => {
beforeEach(() => {
vi.resetAllMocks();
});
it("product price are displayed - standard product", () => {

@@ -44,3 +47,3 @@ const { vm } = useSetup(() => useProductPrice(ref(mockedProduct)));

it("displayFrom", () => {
it("displayFrom should be false if displayParent is true", () => {
const { vm } = useSetup(() =>

@@ -52,10 +55,6 @@ useProductPrice(

{
parentId: null,
calculatedPrices: null,
variantListingConfig: {
displayParent: true,
},
calculatedPrices: undefined,
listPrice: {
percentage: 100,
},
},

@@ -69,2 +68,63 @@ ) as unknown as Schemas["Product"],

});
it("isListPrice should be false with more than one calculatedPrices value", () => {
const { vm } = useSetup(() =>
useProductPrice(
ref(
Object.assign(
{ ...productTierPrices.product },
{
listPrice: 80,
calculatedPrices: [
{
unitPrice: 10,
},
{
unitPrice: 20,
},
],
},
) as unknown as Schemas["Product"],
),
),
);
expect(vm.displayFrom).toBe(true);
expect(vm.isListPrice).toBe(false);
});
it("isListPrice should be true with one calculatedPrices value", () => {
const { vm } = useSetup(() =>
useProductPrice(
ref({
calculatedPrices: [
{
listPrice: {
percentage: 10,
},
},
],
} as unknown as Schemas["Product"]),
),
);
expect(vm.displayFrom).toBe(false);
expect(vm.isListPrice).toBe(true);
});
it("displayFrom - second variant", async () => {
const { vm } = useSetup(() =>
useProductPrice(
ref({
variantListingConfig: {
displayParent: true,
},
parentId: null,
calculatedCheapestPrice: {
hasRange: true,
},
} as unknown as Schemas["Product"]),
),
);
expect(vm.displayFrom).toBe(false);
expect(vm.isListPrice).toBe(false);
});
});

@@ -74,20 +74,15 @@ import type { Schemas } from "#shopware";

const _displayParent: ComputedRef<boolean> = computed(
() =>
!!product.value?.variantListingConfig?.displayParent &&
product.value?.parentId === null,
);
const displayFrom: ComputedRef<boolean> = computed(() => {
return (product.value?.calculatedPrices?.length ?? 0) > 1;
});
const displayFrom: ComputedRef<boolean> = computed(
() =>
(product.value?.calculatedPrices?.length ?? 0) > 1 ||
!!(_displayParent.value && displayFromVariants.value),
);
const displayFromVariants: ComputedRef<number | false | undefined> = computed(
() =>
!!product.value?.parentId &&
product.value?.calculatedCheapestPrice?.hasRange &&
_real?.value?.unitPrice !== _cheapest?.value?.unitPrice &&
_cheapest?.value?.unitPrice,
() => {
return (
!!product.value?.parentId &&
product.value?.calculatedCheapestPrice?.hasRange &&
_real?.value?.unitPrice !== _cheapest?.value?.unitPrice &&
_cheapest?.value?.unitPrice
);
},
);

@@ -98,10 +93,5 @@

if (displayFrom.value && getProductTierPrices(product.value).length > 1) {
const lowest = product.value?.calculatedPrices?.reduce(
(previous, current) => {
return current.unitPrice < previous.unitPrice ? current : previous;
},
);
return (
lowest || (_cheapest.value as unknown as Schemas["CalculatedPrice"])
);
return product.value?.calculatedPrices?.reduce((previous, current) => {
return current.unitPrice < previous.unitPrice ? current : previous;
});
}

@@ -122,5 +112,5 @@ return _real.value;

const isListPrice: ComputedRef<boolean> = computed(
() => !!_price.value?.listPrice?.percentage,
);
const isListPrice: ComputedRef<boolean> = computed(() => {
return !!_price.value?.listPrice?.percentage;
});

@@ -127,0 +117,0 @@ const regulationPrice: ComputedRef<number | undefined> = computed(

@@ -35,2 +35,3 @@ import { describe, expect, it, vi } from "vitest";

expect(vm.removeFromWishlist()).resolves.toEqual(undefined);
expect(vm.isInWishlist).toEqual(false);
});

@@ -54,7 +55,12 @@ });

it("removeFromWishlist", () => {
vi.mocked(useUser).mockReturnValue({
isLoggedIn: ref(true),
isGuestSession: ref(false),
} as ReturnType<typeof useUser>);
const { vm } = useSetup(() => useProductWishlist("test3"));
expect(vm.removeFromWishlist()).resolves.toEqual(undefined);
expect(vm.isInWishlist).toEqual(false);
});
});
});

@@ -1,2 +0,2 @@

import { describe, expect, it, vi } from "vitest";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { useSyncWishlist } from "./useSyncWishlist";

@@ -8,2 +8,6 @@ import { useSetup } from "./_test";

describe("useSyncWishlist", () => {
beforeEach(() => {
vi.clearAllMocks();
});
const consoleErrorSpy = vi.spyOn(console, "error");

@@ -13,3 +17,3 @@ consoleErrorSpy.mockImplementation(() => {});

describe("addToWishlist", () => {
it("wishlist add product", () => {
it("should add product to the wishlist", () => {
const { vm } = useSetup(() => useSyncWishlist());

@@ -22,3 +26,3 @@

describe("removeFromWishlist", () => {
it("wishlist remove", () => {
it("should remove product from the wishlist", () => {
const { vm } = useSetup(() => useSyncWishlist());

@@ -34,3 +38,3 @@

describe("mergeWishlistProducts", () => {
it("wishlist remove", () => {
it("should sync wishlist", () => {
const { vm } = useSetup(() => useSyncWishlist());

@@ -45,13 +49,49 @@

describe("getWishlistProducts", () => {
it("getWishlistProducts", () => {
const { vm } = useSetup(() => useSyncWishlist());
it("should get wishlist products", async () => {
const { vm, injections } = useSetup(() => useSyncWishlist());
injections.apiClient.invoke.mockResolvedValue({
data: {
products: {
elements: [],
},
},
});
await vm.getWishlistProducts();
vm.getWishlistProducts();
expect(vm.count).toBe(0);
expect(vm.items.length).toBe(0);
});
it("getWishlistProducts", async () => {
const { vm, injections } = useSetup(() => useSyncWishlist());
injections.apiClient.invoke.mockResolvedValue({
data: {
products: {
total: 9,
page: 1,
elements: [
{
id: "test-id",
},
],
},
},
});
await vm.getWishlistProducts();
expect(injections.apiClient.invoke).toHaveBeenCalledWith(
expect.stringContaining("readCustomerWishlist"),
expect.objectContaining({
body: {
"total-count-mode": "exact",
},
}),
);
expect(vm.count).toBe(9);
expect(vm.items.length).toBe(1);
});
});
describe("getWishlistProducts - error", () => {
it("getWishlistProducts", async () => {
it("should handle error after fetching product wishlist", async () => {
const { vm } = useSetup(() => useSyncWishlist(), {

@@ -77,3 +117,3 @@ apiClient: {

expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
expect(vm.count).toBe(0);
expect(vm.count).toBe(9);
expect(vm.items.length).toBe(0);

@@ -80,0 +120,0 @@ });

@@ -50,9 +50,7 @@ import { describe, expect, it, vi } from "vitest";

describe("useWishlist - not logged in user", () => {
it("mergeWishlistProducts", () => {
it("should merge wishlist products", () => {
vi.mocked(useUser).mockReturnValue(getMockedUser(false, true));
vi.mocked(useSyncWishlist).mockReturnValue({
getWishlistProducts: () => new Promise<void>((resolve) => resolve()),
items: computed((): string[] => {
return ["test1"];
}),
items: computed((): string[] => []),
addToWishlistSync: () => undefined,

@@ -75,9 +73,7 @@ mergeWishlistProducts: () => undefined,

it("getWishlistProducts", async () => {
it("should get wishlist products", async () => {
vi.mocked(useUser).mockReturnValue(getMockedUser(false, true));
vi.mocked(useSyncWishlist).mockReturnValue({
getWishlistProducts: () => new Promise<void>((resolve) => resolve()),
items: computed((): string[] => {
return ["test1"];
}),
items: computed((): string[] => ["test1"]),
addToWishlistSync: () => undefined,

@@ -124,3 +120,3 @@ mergeWishlistProducts: () => undefined,

describe("useWishlist - logged in user", () => {
it("mergeWishlistProducts", () => {
it("should merge wishlist products", () => {
vi.mocked(useUser).mockReturnValue(getMockedUser(true, false));

@@ -164,3 +160,3 @@ vi.mocked(useSyncWishlist).mockReturnValue({

it("getWishlistProducts", () => {
it("should get wishlist products", () => {
vi.mocked(useUser).mockReturnValue(getMockedUser(true, false));

@@ -167,0 +163,0 @@ const { vm } = useSetup(() => useWishlist());

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc