Repository: shopware/frontends
Pull request #1170 (2024-07-26 16:08:07)

chore(deps): bump primevue from 4.0.0 to 4.0.2
Bumps [primevue](https://github.com/primefaces/primevue/tree/HEAD/packages/primevue) from 4.0.0 to 4.0.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a href="https://github.com/primefaces/primevue/releases">primevue's releases</a>.</em></p>
<blockquote>
<h2>PrimeVue 4.0.2</h2>
<h2>What's Changed</h2>
<ul>
<li>fix: missing default labels in ConfirmDialog and ConfirmPopup by <a href="https://github.com/m-kutnik"><code>@​m-kutnik</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6077">primefaces/primevue#6077</a></li>
<li>fix: enable label click to open colorpicker by <a href="https://github.com/navedqb"><code>@​navedqb</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6047">primefaces/primevue#6047</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/m-kutnik"><code>@​m-kutnik</code></a> made their first contribution in <a href="https://redirect.github.com/primefaces/primevue/pull/6077">primefaces/primevue#6077</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/primefaces/primevue/compare/4.0.1...4.0.2">https://github.com/primefaces/primevue/compare/4.0.1...4.0.2</a></p>
<h2>PrimeVue 4.0.1</h2>
<h2>What's Changed</h2>
<ul>
<li>fix(accordioncontent): ensure <code>background-color</code> is declared properly by <a href="https://github.com/eneeio-nm"><code>@​eneeio-nm</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6032">primefaces/primevue#6032</a></li>
<li>fix: avoid <code>v-ripple</code> missing warn when Ripple is not been registered by <a href="https://github.com/byronogis"><code>@​byronogis</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6058">primefaces/primevue#6058</a></li>
<li>fix: typo in theme presets (chip/index.js) by <a href="https://github.com/eneeio-nm"><code>@​eneeio-nm</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6078">primefaces/primevue#6078</a></li>
<li>Fixed typo by <a href="https://github.com/narfdotpl"><code>@​narfdotpl</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6045">primefaces/primevue#6045</a></li>
<li>Fix IconField when icons should appear at beginning and end. by <a href="https://github.com/maspetsberger"><code>@​maspetsberger</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6035">primefaces/primevue#6035</a></li>
<li>Update StepPanel.vue with v-show rather than v-if for horizontal steps. by <a href="https://github.com/rickngo"><code>@​rickngo</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6054">primefaces/primevue#6054</a></li>
<li>fix(docs): update changelog url by <a href="https://github.com/sceee"><code>@​sceee</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/5981">primefaces/primevue#5981</a></li>
<li>Fix: DataTable Frozen Columns the headers of fixed columns will overlap. by <a href="https://github.com/yzzting"><code>@​yzzting</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6037">primefaces/primevue#6037</a></li>
<li>Fix combination of multiple and dropdown by <a href="https://github.com/marlonbahniuk"><code>@​marlonbahniuk</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6029">primefaces/primevue#6029</a></li>
<li>types: Make TreeNode.key required by <a href="https://github.com/jacobtylerwalls"><code>@​jacobtylerwalls</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6011">primefaces/primevue#6011</a></li>
<li>fix: <a href="https://github.com/primefaces/primevue/tree/HEAD/packages/primevue/issues/6084">#6084</a>, SELECT: hide clear button when options is empty in Dropdown by <a href="https://github.com/akshayaqburst"><code>@​akshayaqburst</code></a> in <a href="https://redirect.github.com/primefaces/primevue/pull/6085">primefaces/primevue#6085</a></li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/byronogis"><code>@​byronogis</code></a> made their first contribution in <a href="https://redirect.github.com/primefaces/primevue/pull/6058">primefaces/primevue#6058</a></li>
<li><a href="https://github.com/narfdotpl"><code>@​narfdotpl</code></a> made their first contribution in <a href="https://redirect.github.com/primefaces/primevue/pull/6045">primefaces/primevue#6045</a></li>
<li><a href="https://github.com/rickngo"><code>@​rickngo</code></a> made their first contribution in <a href="https://redirect.github.com/primefaces/primevue/pull/6054">primefaces/primevue#6054</a></li>
<li><a href="https://github.com/yzzting"><code>@​yzzting</code></a> made their first contribution in <a href="https://redirect.github.com/primefaces/primevue/pull/6037">primefaces/primevue#6037</a></li>
<li><a href="https://github.com/marlonbahniuk"><code>@​marlonbahniuk</code></a> made their first contribution in <a href="https://redirect.github.com/primefaces/primevue/pull/6029">primefaces/primevue#6029</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a href="https://github.com/primefaces/primevue/compare/4.0.0...4.0.1">https://github.com/primefaces/primevue/compare/4.0.0...4.0.1</a></p>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a href="https://github.com/primefaces/primevue/blob/master/CHANGELOG.md">primevue's changelog</a>.</em></p>
<blockquote>
<h2><a href="https://github.com/primefaces/primevue/tree/4.0.1">4.0.2</a> (2024-07-26)</h2>
<p><a href="https://github.com/primefaces/primevue/compare/4.0.0...4.0.1">Full Changelog</a></p>
<p><strong>Fixed bugs:</strong></p>
<ul>
<li>Toast: Unstyled prop does not affect ToastMessage <a href="https://redirect.github.com/primefaces/primevue/issues/6098">#6098</a></li>
<li>ConfirmDialog and ConfirmPopup: Missing accept/reject labels <a href="https://redirect.github.com/primefaces/primevue/issues/6075">#6075</a></li>
</ul>
<p><strong>Implemented New Features and Enhancements:</strong></p>
<ul>
<li>Provide Fluid component <a href="https://redirect.github.com/primefaces/primevue/issues/6122">#6122</a></li>
<li>ColorPicker: click on label does not open the color picker<a href="https://redirect.github.com/primefaces/primevue/issues/6044">#6044</a></li>
</ul>
<h2><a href="https://github.com/primefaces/primevue/tree/4.0.1">4.0.1</a> (2024-07-22)</h2>
<p><a href="https://github.com/primefaces/primevue/compare/4.0.0...4.0.1">Full Changelog</a></p>
<p><strong>Fixed bugs:</strong></p>
<ul>
<li>SELECT: hide clear button when options is empty in Dropdown <a href="https://redirect.github.com/primefaces/primevue/issues/6084">#6084</a></li>
<li>Lara theme type <a href="https://redirect.github.com/primefaces/primevue/issues/6065">#6065</a></li>
<li>Paginator: v4 page buttons still have PrimeVue classes in unstyled mode <a href="https://redirect.github.com/primefaces/primevue/issues/6064">#6064</a></li>
<li>TabList: ripple warn when Ripple is not been registered. <a href="https://redirect.github.com/primefaces/primevue/issues/6057">#6057</a></li>
<li>Stepper: Nested Components are re-mounted <a href="https://redirect.github.com/primefaces/primevue/issues/6052">#6052</a></li>
<li>Tree: filter pt implementation defect <a href="https://redirect.github.com/primefaces/primevue/issues/6043">#6043</a></li>
<li>DataTable: Frozen Columns, the headers of fixed columns will overlap. <a href="https://redirect.github.com/primefaces/primevue/issues/6036">#6036</a></li>
<li>IconField: Does not support multiple icons<a href="https://redirect.github.com/primefaces/primevue/issues/6034">#6034</a></li>
<li>InputMask: Passed props are not set <a href="https://redirect.github.com/primefaces/primevue/issues/6025">#6025</a></li>
<li>BaseComponent: Missing import 'isFunction' <a href="https://redirect.github.com/primefaces/primevue/issues/6024">#6024</a></li>
<li>Failed to use Primevue 4 with yarn <a href="https://redirect.github.com/primefaces/primevue/issues/6020">#6020</a></li>
<li>TABS: Globally enabling Ripple breaks Scrollable Tabs <a href="https://redirect.github.com/primefaces/primevue/issues/6017">#6017</a></li>
<li>Accordion: Theming content background not working <a href="https://redirect.github.com/primefaces/primevue/issues/5997">#5997</a></li>
<li>AutoComplete: Combining multiple + dropdown does not work <a href="https://redirect.github.com/primefaces/primevue/issues/5881">#5881</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a href="https://github.com/primefaces/primevue/commit/44ade4f891e14eff4c898d65d49f317246d7afd5"><code>44ade4f</code></a> Released 4.0.2</li>
<li><a href="https://github.com/primefaces/primevue/commit/90eb36a15907393681862cac05b2df63f16c7151"><code>90eb36a</code></a> Icon pt fixes</li>
<li><a href="https://github.com/primefaces/primevue/commit/1d79237d11bff209e7cc8e35d2fe39a2a5aab2f4"><code>1d79237</code></a> Fixed <a href="https://github.com/primefaces/primevue/tree/HEAD/packages/primevue/issues/6122">#6122</a> - New Fluid component</li>
<li><a href="https://github.com/primefaces/primevue/commit/0b8d9b476724f7cb0263e276ffa1fd60fe1e135c"><code>0b8d9b4</code></a> Update FloatLabel.d.ts</li>
<li><a href="https://github.com/primefaces/primevue/commit/67c3cbbb0b671fedbd10a568a5023906cd89cc06"><code>67c3cbb</code></a> Fixed  <a href="https://github.com/primefaces/primevue/tree/HEAD/packages/primevue/issues/6098">#6098</a></li>
<li><a href="https://github.com/primefaces/primevue/commit/cbec74dd7ef9cd5d9c1e32d1f9db861ec6a4c3df"><code>cbec74d</code></a> Update ColorPicker.d.ts</li>
<li><a href="https://github.com/primefaces/primevue/commit/a6dbc4d9bbaf74ac5717814ff2a356956b5e16ad"><code>a6dbc4d</code></a> refactor</li>
<li><a href="https://github.com/primefaces/primevue/commit/3ff5e08d037c8170ac98c1041a27379890f71411"><code>3ff5e08</code></a> refactor</li>
<li><a href="https://github.com/primefaces/primevue/commit/ca3fdb9c6ce9e2a53ccee281a7c0adcd31ea8940"><code>ca3fdb9</code></a> fix: enable label click to open colorpicker</li>
<li><a href="https://github.com/primefaces/primevue/commit/573c04179e7b055977511c87bc71f7159f1d97e2"><code>573c041</code></a> Refactor <a href="https://github.com/primefaces/primevue/tree/HEAD/packages/primevue/issues/6075">#6075</a></li>
<li>Additional commits viewable in <a href="https://github.com/primefaces/primevue/commits/4.0.2/packages/primevue">compare view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=primevue&package-manager=npm_and_yarn&previous-version=4.0.0&new-version=4.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting `@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)


</details>

vercel[bot]: [vc]: #F03EXiHXMJYDjGlxNnBmSvFUvhoB3u18C2NDjvytVOs=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJzaG9wd2FyZS1mcm9udGVuZHMtZG9jcyIsInJvb3REaXJlY3RvcnkiOiJhcHBzL2RvY3MvIiwiaW5zcGVjdG9yVXJsIjoiaHR0cHM6Ly92ZXJjZWwuY29tL3Nob3B3YXJlLWZyb250ZW5kcy9zaG9wd2FyZS1mcm9udGVuZHMtZG9jcy9KQkZHWjk2eUE3RXBGTXZGNTRBanNoVkE0aVk5IiwicHJldmlld1VybCI6InNob3B3YXJlLWZyb250ZW5kcy1kb2NzLWdpdC1kZXBlbmRhYm8tMDY5ZDU4LXNob3B3YXJlLWZyb250ZW5kcy52ZXJjZWwuYXBwIiwibmV4dENvbW1pdFN0YXR1cyI6IlBFTkRJTkcifV19
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)

| Name | Status | Preview | Updated (UTC) |
| :--- | :----- | :------ | :------ |
| **shopware-frontends-docs** | 🔄 Building ([Inspect](https://vercel.com/shopware-frontends/shopware-frontends-docs/JBFGZ96yA7EpFMvF54AjshVA4iY9)) | [Visit Preview](https://shopware-frontends-docs-git-dependabo-069d58-shopware-frontends.vercel.app) | Jul 26, 2024 4:08pm |



Patch:
diff --git a/examples/b2b-quote-management/package.json b/examples/b2b-quote-management/package.json
index 798e0317..c67a4332 100644
--- a/examples/b2b-quote-management/package.json
+++ b/examples/b2b-quote-management/package.json
@@ -16,7 +16,7 @@
     "@shopware-pwa/helpers-next": "canary",
     "@shopware/api-client": "canary",
     "js-cookie": "3.0.5",
-    "primevue": "4.0.0",
+    "primevue": "4.0.2",
     "vue": "3.4.33",
     "vue-router": "4.4.0"
   },
diff --git a/packages/composables/src/index.ts b/packages/composables/src/index.ts
index 954b84c7..a07815b3 100644
--- a/packages/composables/src/index.ts
+++ b/packages/composables/src/index.ts
@@ -90,6 +90,7 @@ export function resolveCmsComponent(
       componentNameToResolve,
       resolvedComponent: undefined,
       resolved: false,
+      isResolved: false,
       error: (e as Error).message,
     };
   }
diff --git a/packages/composables/src/mocks/Order.ts b/packages/composables/src/mocks/Order.ts
index 09806fbb..66941438 100644
--- a/packages/composables/src/mocks/Order.ts
+++ b/packages/composables/src/mocks/Order.ts
@@ -1144,6 +1144,7 @@ const Order = {
   },
   paymentChangeable: {
     "018c6832f1a1731db276839b3f251fc2": true,
+    "123-test": true,
   },
 };
 
diff --git a/packages/composables/src/useListing.ts b/packages/composables/src/useListing.ts
index 4814f676..ad2cac14 100644
--- a/packages/composables/src/useListing.ts
+++ b/packages/composables/src/useListing.ts
@@ -73,7 +73,7 @@ export type UseListingReturn = {
    * Loads more (next page) elements to the listing
    */
   loadMore(
-    criteria: operations["searchPage post /search"]["body"],
+    criteria?: operations["searchPage post /search"]["body"],
   ): Promise<void>;
   /**
    * Listing that is currently set
diff --git a/packages/composables/src/useNotifications.ts b/packages/composables/src/useNotifications.ts
index d8694b09..ebb16269 100644
--- a/packages/composables/src/useNotifications.ts
+++ b/packages/composables/src/useNotifications.ts
@@ -84,7 +84,7 @@ export function useNotifications(): UseNotificationsReturn {
 
   async function pushNotification(
     message: string,
-    options: NotificationOptions,
+    options: Required<Pick<NotificationOptions, "type">> & NotificationOptions,
   ) {
     const timeout = options.timeout || 2500;
     const persistent = !!options.persistent;
@@ -93,7 +93,7 @@ export function useNotifications(): UseNotificationsReturn {
     const messageId = geterateId();
     _notifications.value.push({
       id: messageId,
-      type: options.type || "info",
+      type: options.type,
       message,
     });
     if (!persistent) {
diff --git a/packages/composables/src/useProduct.ts b/packages/composables/src/useProduct.ts
index f123a946..759c9380 100644
--- a/packages/composables/src/useProduct.ts
+++ b/packages/composables/src/useProduct.ts
@@ -35,6 +35,7 @@ export function useProduct(
     // TODO link docs with composables context usage
     throw new ContextError("Product");
   }
+
   const _configurator = useContext("configurator", {
     context: product && configurator,
   });
diff --git a/packages/composables/src/useProductAssociations.spec.ts b/packages/composables/src/useProductAssociations.spec.ts
index 6c430051..566ce195 100644
--- a/packages/composables/src/useProductAssociations.spec.ts
+++ b/packages/composables/src/useProductAssociations.spec.ts
@@ -1,6 +1,6 @@
 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";
 import mockedCrossSelling from "./mocks/CrossSellingResponse";
 import { useSetup } from "./_test";
@@ -88,4 +88,18 @@ describe("useProductAssociations", () => {
 
     expect(vm.productAssociations).toStrictEqual(mockedCrossSelling);
   });
+
+  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.");
+  });
 });
diff --git a/packages/composables/src/useProductConfigurator.spec.ts b/packages/composables/src/useProductConfigurator.spec.ts
index 27f82b05..97fc9bd6 100644
--- a/packages/composables/src/useProductConfigurator.spec.ts
+++ b/packages/composables/src/useProductConfigurator.spec.ts
@@ -4,16 +4,15 @@ import { ref } from "vue";
 import mockedProduct from "./mocks/Product";
 import mockedConfigurator from "./mocks/Configurator";
 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>);
 
   it("handleChange callback function was called", () => {
     const { vm } = useSetup(useProductConfigurator);
@@ -55,4 +54,25 @@ describe("useProductConfigurator", () => {
       "PROBLEM",
     );
   });
+
+  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([]);
+  });
 });
diff --git a/packages/composables/src/useProductPrice.ts b/packages/composables/src/useProductPrice.ts
index f71964ac..293a9ff6 100644
--- a/packages/composables/src/useProductPrice.ts
+++ b/packages/composables/src/useProductPrice.ts
@@ -71,37 +71,27 @@ export function useProductPrice(
     Schemas["CalculatedPrice"]["referencePrice"] | undefined
   > = computed(() => _real?.value?.referencePrice);
 
-  const _displayParent: ComputedRef<boolean> = computed(
-    () =>
-      !!product.value?.variantListingConfig?.displayParent &&
-      product.value?.parentId === null,
-  );
-
-  const displayFrom: ComputedRef<boolean> = computed(
-    () =>
-      (product.value?.calculatedPrices?.length ?? 0) > 1 ||
-      !!(_displayParent.value && displayFromVariants.value),
-  );
+  const displayFrom: ComputedRef<boolean> = computed(() => {
+    return (product.value?.calculatedPrices?.length ?? 0) > 1;
+  });
 
   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
+      );
+    },
   );
 
   const _price: ComputedRef<Schemas["CalculatedPrice"] | undefined> = computed(
     () => {
       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;
+        });
       }
       return _real.value;
     },
@@ -117,9 +107,9 @@ export function useProductPrice(
     () => _price.value,
   );
 
-  const isListPrice: ComputedRef<boolean> = computed(
-    () => !!_price.value?.listPrice?.percentage,
-  );
+  const isListPrice: ComputedRef<boolean> = computed(() => {
+    return !!_price.value?.listPrice?.percentage;
+  });
 
   const regulationPrice: ComputedRef<number | undefined> = computed(
     () => product.value?.calculatedPrice?.regulationPrice?.price,
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 30c88b41..72eee200 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -223,8 +223,8 @@ importers:
         specifier: 3.0.5
         version: 3.0.5
       primevue:
-        specifier: 4.0.0
-        version: 4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4))
+        specifier: 4.0.2
+        version: 4.0.2(vue@3.4.33(typescript@5.5.4))
       vue:
         specifier: 3.4.33
         version: 3.4.33(typescript@5.5.4)
@@ -3180,15 +3180,14 @@ packages:
     resolution: {integrity: sha512-ntUiUgtRtkF8KuaxHffzhYxQxoXk6LAPHm7CVlFjdqS8Rx8xRkLkZVyo84E+pO2hcNFkOGVP/GxHhQ2s94O8zA==}
     engines: {node: '>=12.11.0'}
 
-  '@primevue/core@4.0.0':
-    resolution: {integrity: sha512-M+GF1HYnl/x5J6uevXh1k42J0XnFhp0XHce+cHddWg7v3bVwgsn7LD3AKKcf0A/iQQPXVKX9nY/4/9eFVct67w==}
+  '@primevue/core@4.0.2':
+    resolution: {integrity: sha512-SpCIQ1LG6B66cecmZt1UdFeY7tbdJrgnhncADolfE9fcCyTSBtbaVLLhCV2E4Q9myMwCFE5KQxqazA4rdLWk4w==}
     engines: {node: '>=12.11.0'}
     peerDependencies:
-      '@primeuix/utils': ^0.0.5
       vue: ^3.0.0
 
-  '@primevue/icons@4.0.0':
-    resolution: {integrity: sha512-gv9pbj7JjCuW59tW2csIJgg6btTJpkr/mjlfqscEIrYzDGqzCrbfxLur48gA2dyhYsiQPPTbIHFwL944piFgIg==}
+  '@primevue/icons@4.0.2':
+    resolution: {integrity: sha512-S1VEpMsx4uUAsTjZtII03LQqgocYwSKbXMF0YDFWybY8r5LaHaveVZxS/i+KbsCLaL18BXJw0L/7L1eQdJHzaA==}
     engines: {node: '>=12.11.0'}
 
   '@primevue/themes@4.0.0':
@@ -8765,8 +8764,8 @@ packages:
     resolution: {integrity: sha512-973driJZvxiGOQ5ONsFhOF/DtzPMOMtgC11kCpUrPGMTgqp2q/1gwzCquocrN33is0VZ5GFHXZYMM9l6h67v2Q==}
     engines: {node: '>=10'}
 
-  primevue@4.0.0:
-    resolution: {integrity: sha512-2PFmmJqyXpOcKOdF+gbps5fpSXfoXZp2LwX+hya/b5SDseMt3UNboyEgVI6B+DNbJRrib35EbDiMw+7RIANQ1w==}
+  primevue@4.0.2:
+    resolution: {integrity: sha512-bf5In//ixosZDOcfJ0iaBXhtQSpNC/CuAOE2KHd/SgUKZdij3VRljQ+I9+Be/TTxfikIeKH7eZ4gzDbWiIZurw==}
     engines: {node: '>=12.11.0'}
 
   prism-react-renderer@1.3.5:
@@ -13549,17 +13548,17 @@ snapshots:
 
   '@primeuix/utils@0.0.5': {}
 
-  '@primevue/core@4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4))':
+  '@primevue/core@4.0.2(vue@3.4.33(typescript@5.5.4))':
     dependencies:
       '@primeuix/styled': 0.0.5
       '@primeuix/utils': 0.0.5
       vue: 3.4.33(typescript@5.5.4)
 
-  '@primevue/icons@4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4))':
+  '@primevue/icons@4.0.2(vue@3.4.33(typescript@5.5.4))':
     dependencies:
-      '@primevue/core': 4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4))
+      '@primeuix/utils': 0.0.5
+      '@primevue/core': 4.0.2(vue@3.4.33(typescript@5.5.4))
     transitivePeerDependencies:
-      - '@primeuix/utils'
       - vue
 
   '@primevue/themes@4.0.0(@primeuix/styled@0.0.5)':
@@ -21453,12 +21452,13 @@ snapshots:
     dependencies:
       parse-ms: 2.1.0
 
-  primevue@4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4)):
+  primevue@4.0.2(vue@3.4.33(typescript@5.5.4)):
     dependencies:
-      '@primevue/core': 4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4))
-      '@primevue/icons': 4.0.0(@primeuix/utils@0.0.5)(vue@3.4.33(typescript@5.5.4))
+      '@primeuix/styled': 0.0.5
+      '@primeuix/utils': 0.0.5
+      '@primevue/core': 4.0.2(vue@3.4.33(typescript@5.5.4))
+      '@primevue/icons': 4.0.2(vue@3.4.33(typescript@5.5.4))
     transitivePeerDependencies:
-      - '@primeuix/utils'
       - vue
 
   prism-react-renderer@1.3.5(react@17.0.2):
diff --git a/templates/vue-demo-store/components/layout/LayoutHeader.vue b/templates/vue-demo-store/components/layout/LayoutHeader.vue
index 565ddcfe..f7fdbf1b 100644
--- a/templates/vue-demo-store/components/layout/LayoutHeader.vue
+++ b/templates/vue-demo-store/components/layout/LayoutHeader.vue
@@ -50,12 +50,14 @@ const sidebarController = useModal();
               <div
                 class="w-7 h-7 i-carbon-favorite text-secondary-600 hover:text-primary hover:animate-count-infinite hover:animate-heart-beat"
               />
-              <span
-                v-if="wishlistCount"
-                class="text-3 font-sm text-white absolute bg-red-600 rounded-full min-w-5 min-h-5 top-0 right-0 leading-5"
-              >
-                {{ wishlistCount }}
-              </span>
+              <ClientOnly>
+                <span
+                  v-if="wishlistCount"
+                  class="text-3 font-sm text-white absolute bg-red-600 rounded-full min-w-5 min-h-5 top-0 right-0 leading-5"
+                >
+                  {{ wishlistCount }}
+                </span>
+              </ClientOnly>
             </NuxtLink>
           </div>
           <!-- Cart -->


Test patch:
diff --git a/packages/composables/src/_test/useSetup.ts b/packages/composables/src/_test/useSetup.ts
index 1261d90b..db216b02 100644
--- a/packages/composables/src/_test/useSetup.ts
+++ b/packages/composables/src/_test/useSetup.ts
@@ -8,6 +8,7 @@ type Injections = {
   apiClient: {
     invoke: ReturnType<typeof vi.fn>;
   };
+  swNotifications?: unknown;
 };
 
 export function useSetup<V>(setup: () => V, customMocks?: Partial<Injections>) {
@@ -16,7 +17,7 @@ export function useSetup<V>(setup: () => V, customMocks?: Partial<Injections>) {
     apiClient: { invoke: customMocks?.apiClient?.invoke ?? vi.fn() },
   };
 
-  const compoment = defineComponent({
+  const component = defineComponent({
     setup,
     render() {
       return h("div", []);
@@ -28,7 +29,7 @@ export function useSetup<V>(setup: () => V, customMocks?: Partial<Injections>) {
     customMocks || {},
   ) as Injections;
 
-  const wrapper = shallowMount(compoment, {
+  const wrapper = shallowMount(component, {
     global: {
       provide: injections,
     },
diff --git a/packages/composables/src/index.test.ts b/packages/composables/src/index.test.ts
index 6f2336d5..8122f0f4 100644
--- a/packages/composables/src/index.test.ts
+++ b/packages/composables/src/index.test.ts
@@ -1,9 +1,12 @@
-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", () => {
     const result = resolveCmsComponent(
       CmsPage.cmsPage.sections[0].blocks[0] as unknown as Schemas["CmsBlock"],
@@ -19,6 +22,7 @@ describe("resolveCmsComponent", () => {
   });
 
   it("cms section component", () => {
+    vi.spyOn(vue, "resolveComponent").mockImplementation(() => ({}));
     const result = resolveCmsComponent({
       apiAlias: "cms_section",
     } as unknown as Schemas["CmsBlock"]);
@@ -32,4 +36,15 @@ describe("resolveCmsComponent", () => {
 
     expect(result.isResolved).toBe(true);
   });
+
+  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);
+  });
 });
diff --git a/packages/composables/src/useCart.test.ts b/packages/composables/src/useCart.test.ts
index 4e4793bd..3adf8164 100644
--- a/packages/composables/src/useCart.test.ts
+++ b/packages/composables/src/useCart.test.ts
@@ -39,6 +39,9 @@ describe("useCart", () => {
   });
 
   it("add single product", async () => {
+    expect(vm.cartItems).toEqual([]);
+    expect(vm.totalPrice).toBe(0);
+    expect(vm.subtotal).toBe(0);
     await vm.addProduct({
       id: itemsMock.items[0].referencedId as string,
       quantity: itemsMock.items[0].quantity,
@@ -58,6 +61,25 @@ describe("useCart", () => {
         },
       }),
     );
+
+    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,
+            },
+          ],
+        },
+      }),
+    );
   });
 
   it("refresh the cart", async () => {
@@ -71,6 +93,11 @@ describe("useCart", () => {
     expect(await vm.refreshCart(Cart as unknown as Schemas["Cart"])).toEqual(
       Cart,
     );
+
+    expect(vm.shippingTotal).toBe(0);
+    expect(vm.subtotal).toBe(16.11);
+    expect(vm.isVirtualCart).toBe(false);
+    expect(vm.totalPrice).toBe(16.11);
   });
 
   it("add set of products", async () => {
@@ -116,4 +143,76 @@ describe("useCart", () => {
       }),
     );
   });
+
+  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);
+  });
 });
diff --git a/packages/composables/src/useCartItem.test.ts b/packages/composables/src/useCartItem.test.ts
index cc955983..7184fc54 100644
--- a/packages/composables/src/useCartItem.test.ts
+++ b/packages/composables/src/useCartItem.test.ts
@@ -123,4 +123,46 @@ describe("useCartItem", () => {
       id: lineItem.id,
     });
   });
+
+  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.");
+  });
 });
diff --git a/packages/composables/src/useCustomerOrders.test.ts b/packages/composables/src/useCustomerOrders.test.ts
index cfa108ad..e6d29f60 100644
--- a/packages/composables/src/useCustomerOrders.test.ts
+++ b/packages/composables/src/useCustomerOrders.test.ts
@@ -3,7 +3,7 @@ import { useCustomerOrders } from "./useCustomerOrders";
 import { useSetup } from "./_test";
 
 describe("useCustomerOrders", () => {
-  it("changeLanguage", async () => {
+  it("should inovke load orders", async () => {
     const { vm, injections } = useSetup(useCustomerOrders);
     injections.apiClient.invoke.mockResolvedValue({
       data: { orders: { elements: [] } },
@@ -13,9 +13,10 @@ describe("useCustomerOrders", () => {
       expect.stringContaining("readOrder"),
       expect.objectContaining({}),
     );
+    expect(vm.totalPages).toBe(0);
   });
 
-  it("changeCurrentPage", async () => {
+  it("should invoke change page", async () => {
     const { vm, injections } = useSetup(useCustomerOrders);
     injections.apiClient.invoke.mockResolvedValue({
       data: { orders: { elements: [] } },
diff --git a/packages/composables/src/useInternationalization.test.ts b/packages/composables/src/useInternationalization.test.ts
index 7f592e21..345adfc0 100644
--- a/packages/composables/src/useInternationalization.test.ts
+++ b/packages/composables/src/useInternationalization.test.ts
@@ -1,6 +1,8 @@
 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";
 
 describe("useInternationalization", () => {
   it("should return storefrontUrl", async () => {
@@ -21,7 +23,7 @@ describe("useInternationalization", () => {
     expect(vm.getStorefrontUrl()).toBe("http://localhost:3000");
   });
 
-  it("getAvailableLanguages", async () => {
+  it("should invoke getting available languages", async () => {
     const { vm, injections } = useSetup(useInternationalization);
     injections.apiClient.invoke.mockResolvedValue({ data: {} });
     vm.getAvailableLanguages();
@@ -30,7 +32,7 @@ describe("useInternationalization", () => {
     );
   });
 
-  it("changeLanguage", async () => {
+  it("should invoke change language", async () => {
     const { vm, injections } = useSetup(useInternationalization);
     injections.apiClient.invoke.mockResolvedValue({ data: {} });
     vm.changeLanguage("test-id");
@@ -39,4 +41,115 @@ describe("useInternationalization", () => {
       expect.objectContaining({ body: { languageId: "test-id" } }),
     );
   });
+
+  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");
+  });
 });
diff --git a/packages/composables/src/useListing.test.ts b/packages/composables/src/useListing.test.ts
index 25e289a0..8bb87cce 100644
--- a/packages/composables/src/useListing.test.ts
+++ b/packages/composables/src/useListing.test.ts
@@ -1,11 +1,12 @@
 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(() =>
       useListing({
         listingType: "productSearchListing",
@@ -28,7 +29,7 @@ describe("useListing", () => {
     expect(vm.getLimit).toBe(10);
   });
 
-  it('invoke "readQuotes"', async () => {
+  it('should invoke "readQuotes"', async () => {
     const { vm, injections } = await useSetup(() =>
       useListing({
         listingType: "categoryListing",
@@ -55,7 +56,7 @@ describe("useListing", () => {
     );
   });
 
-  it('invoke "readQuotes" - errors', async () => {
+  it("should handle context error", async () => {
     let error: unknown | null = null;
     try {
       await useSetup(() =>
@@ -69,7 +70,7 @@ describe("useListing", () => {
     expect(error).toEqual(new ContextError("Category"));
   });
 
-  it("setCurrentFilters", async () => {
+  it("should set current filters", async () => {
     const { vm, injections } = await useSetup(() =>
       useListing({
         listingType: "categoryListing",
@@ -138,4 +139,112 @@ describe("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([]);
+  });
 });
diff --git a/packages/composables/src/useLocalWishlist.test.ts b/packages/composables/src/useLocalWishlist.test.ts
index 4be5381e..f026c36a 100644
--- a/packages/composables/src/useLocalWishlist.test.ts
+++ b/packages/composables/src/useLocalWishlist.test.ts
@@ -4,7 +4,7 @@ import { useLocalWishlist } from "./useLocalWishlist";
 
 describe("useLocalWishlist", () => {
   describe("methods", () => {
-    describe("addToWishlist", () => {
+    describe("should add product to the wishlist", () => {
       it("wishlist add product", () => {
         const { vm } = useSetup(useLocalWishlist);
         vm.addToWishlist("some-id");
@@ -13,23 +13,15 @@ describe("useLocalWishlist", () => {
     });
 
     describe("removeFromWishlist", () => {
-      it("wishlist add product", () => {
+      it("should remove product from the wishlist", () => {
         const { vm } = useSetup(useLocalWishlist);
         vm.removeFromWishlist("some-id");
         expect(vm.items.length).toBe(0);
       });
     });
 
-    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);
         vm.addToWishlist("some-id");
         expect(vm.count).toBe(1);
@@ -39,18 +31,24 @@ describe("useLocalWishlist", () => {
     });
 
     describe("getWishlistProducts", () => {
-      it("getWishlistProducts", () => {
+      it("should get the wishlist products", () => {
         const { vm } = useSetup(useLocalWishlist);
         vm.clearWishlist();
         vm.getWishlistProducts();
         expect(vm.count).toBe(0);
       });
-      it("getWishlistProducts with items", () => {
+      it("should get the wishlist products after adding product", () => {
         const { vm } = useSetup(useLocalWishlist);
         vm.addToWishlist("some-id");
         vm.getWishlistProducts();
         expect(vm.count).toBe(1);
       });
+      it("getWishlistProducts with items localStorage", () => {
+        const { vm } = useSetup(useLocalWishlist);
+        localStorage.removeItem("sw-wishlist-items");
+        vm.getWishlistProducts();
+        expect(vm.count).toBe(1);
+      });
     });
   });
 });
diff --git a/packages/composables/src/useNavigationSearch.test.ts b/packages/composables/src/useNavigationSearch.test.ts
index 20c424e9..73e24f20 100644
--- a/packages/composables/src/useNavigationSearch.test.ts
+++ b/packages/composables/src/useNavigationSearch.test.ts
@@ -1,6 +1,15 @@
-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 = {
   translated: [],
@@ -85,4 +94,18 @@ describe("useNavigationSearch", () => {
     `);
     expect(injections.apiClient.invoke).not.toHaveBeenCalled();
   });
+
+  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",
+    });
+  });
 });
diff --git a/packages/composables/src/useNewsletter.test.ts b/packages/composables/src/useNewsletter.test.ts
index 5e94ef7f..bde1a1f8 100644
--- a/packages/composables/src/useNewsletter.test.ts
+++ b/packages/composables/src/useNewsletter.test.ts
@@ -33,4 +33,23 @@ describe("useNewsletter", () => {
       },
     );
   });
+
+  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);
+  });
 });
diff --git a/packages/composables/src/useNotifications.test.ts b/packages/composables/src/useNotifications.test.ts
index ab2828c0..d8b5f55e 100644
--- a/packages/composables/src/useNotifications.test.ts
+++ b/packages/composables/src/useNotifications.test.ts
@@ -1,6 +1,7 @@
 import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
 import { useNotifications } from "./useNotifications";
 import { useSetup } from "./_test";
+
 describe("useNotifications", () => {
   beforeEach(() => {
     vi.useFakeTimers();
@@ -10,7 +11,7 @@ describe("useNotifications", () => {
     vi.restoreAllMocks();
   });
 
-  it("notification flow", async () => {
+  it("should trigger sample notification flow", async () => {
     const { vm } = useSetup(useNotifications);
 
     vm.pushError("Error message");
@@ -32,4 +33,24 @@ describe("useNotifications", () => {
     vi.runAllTimers();
     expect(vm.notifications.length).toBe(0);
   });
+
+  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);
+  });
 });
diff --git a/packages/composables/src/useOrderDetails.test.ts b/packages/composables/src/useOrderDetails.test.ts
index 060dd7c9..479c3d8f 100644
--- a/packages/composables/src/useOrderDetails.test.ts
+++ b/packages/composables/src/useOrderDetails.test.ts
@@ -28,7 +28,7 @@ describe("useOrderDetails", () => {
     );
   });
 
-  it("handlePayment", async () => {
+  it("should handle setting the order payment", async () => {
     const { vm, injections } = useSetup(() => useOrderDetails("123-test"));
     injections.apiClient.invoke.mockResolvedValue({ data: {} });
     await vm.handlePayment();
@@ -45,7 +45,7 @@ describe("useOrderDetails", () => {
     );
   });
 
-  it("cancel", async () => {
+  it("should cancel the order", async () => {
     const { vm, injections } = useSetup(() => useOrderDetails("123-test"));
     injections.apiClient.invoke.mockResolvedValue({ data: {} });
     await vm.cancel();
@@ -108,4 +108,27 @@ describe("useOrderDetails", () => {
       }),
     );
   });
+
+  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);
+  });
 });
diff --git a/packages/composables/src/useOrderPayment.test.ts b/packages/composables/src/useOrderPayment.test.ts
index 9158f98f..86288c5c 100644
--- a/packages/composables/src/useOrderPayment.test.ts
+++ b/packages/composables/src/useOrderPayment.test.ts
@@ -7,7 +7,7 @@ import type { Schemas } from "#shopware";
 import Order from "./mocks/Order";
 
 describe("useOrderPayment", () => {
-  it("handlePayment", async () => {
+  it("should handle the order payment", async () => {
     const { vm, injections } = useSetup(() =>
       useOrderPayment(
         computed(() => Order.orders.elements[0]) as unknown as ComputedRef<
@@ -32,5 +32,49 @@ describe("useOrderPayment", () => {
     expect(vm.activeTransaction).toEqual(
       Order.orders.elements[0].transactions[0],
     );
+
+    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);
   });
 });
diff --git a/packages/composables/src/usePrice.test.ts b/packages/composables/src/usePrice.test.ts
index aca3c15f..a0f3a558 100644
--- a/packages/composables/src/usePrice.test.ts
+++ b/packages/composables/src/usePrice.test.ts
@@ -1,12 +1,53 @@
-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", () => {
   it("should be defined", () => {
     expect(usePrice).toBeDefined();
   });
 
+  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", () => {
     const { vm } = useSetup(() =>
       usePrice({
@@ -43,4 +84,15 @@ describe("usePrice", () => {
     const { vm } = useSetup(usePrice);
     expect(vm.getFormattedPrice(undefined)).toBe("");
   });
+
+  it("watch currency change", async () => {
+    const { vm } = useSetup(usePrice);
+    sessionContext.value = {
+      currency: {
+        isoCode: "PLN",
+      },
+    };
+    await vm.$nextTick();
+    expect(vm.currencyCode).toBe("PLN");
+  });
 });
diff --git a/packages/composables/src/useProduct.test.ts b/packages/composables/src/useProduct.test.ts
index a5349865..06248fe8 100644
--- a/packages/composables/src/useProduct.test.ts
+++ b/packages/composables/src/useProduct.test.ts
@@ -2,6 +2,7 @@ import { describe, expect, it } from "vitest";
 import { useProduct } from "./useProduct";
 import mockedProduct from "./mocks/Product";
 import { useSetup } from "./_test";
+import { ref } from "vue";
 
 describe("useProduct", () => {
   it("should return product object", () => {
@@ -10,9 +11,26 @@ describe("useProduct", () => {
     expect(vm.product).toStrictEqual(mockedProduct);
   });
 
-  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();
+  });
+
+  it("changeVariant - empty", () => {
+    const { vm } = useSetup(useProduct);
+
+    vm.changeVariant(Object.assign({ ...mockedProduct }, { id: "new-id" }));
+    expect(vm.product.id).toBe("new-id");
+  });
 
-    expect(vm.configurator).toBe(undefined);
+  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");
   });
 });
diff --git a/packages/composables/src/useProductPrice.test.ts b/packages/composables/src/useProductPrice.test.ts
index 10be3128..9db6c3a6 100644
--- a/packages/composables/src/useProductPrice.test.ts
+++ b/packages/composables/src/useProductPrice.test.ts
@@ -1,4 +1,4 @@
-import { describe, expect, it } from "vitest";
+import { describe, expect, it, vi, beforeEach } from "vitest";
 import { useProductPrice } from "./useProductPrice";
 import { ref } from "vue";
 import mockedProduct from "./mocks/Product";
@@ -7,6 +7,9 @@ import productTierPrices from "./mocks/ProductTierPrices";
 import type { Schemas } from "#shopware";
 
 describe("useProductPrice", () => {
+  beforeEach(() => {
+    vi.resetAllMocks();
+  });
   it("product price are displayed - standard product", () => {
     const { vm } = useSetup(() => useProductPrice(ref(mockedProduct)));
 
@@ -40,21 +43,17 @@ describe("useProductPrice", () => {
     expect(vm.displayFromVariants).toBe(20);
   });
 
-  it("displayFrom", () => {
+  it("displayFrom should be false if displayParent is true", () => {
     const { vm } = useSetup(() =>
       useProductPrice(
         ref(
           Object.assign(
             { ...productTierPrices.product },
             {
-              parentId: null,
+              calculatedPrices: null,
               variantListingConfig: {
                 displayParent: true,
               },
-              calculatedPrices: undefined,
-              listPrice: {
-                percentage: 100,
-              },
             },
           ) as unknown as Schemas["Product"],
         ),
@@ -63,4 +62,65 @@ describe("useProductPrice", () => {
     expect(vm.displayFrom).toBe(false);
     expect(vm.isListPrice).toBe(false);
   });
+
+  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);
+  });
 });
diff --git a/packages/composables/src/useProductWishlist.test.ts b/packages/composables/src/useProductWishlist.test.ts
index b431e60b..91b2b1a3 100644
--- a/packages/composables/src/useProductWishlist.test.ts
+++ b/packages/composables/src/useProductWishlist.test.ts
@@ -32,6 +32,7 @@ describe("useProductWishlist", () => {
       const { vm } = useSetup(() => useProductWishlist("test3"));
 
       expect(vm.removeFromWishlist()).resolves.toEqual(undefined);
+      expect(vm.isInWishlist).toEqual(false);
     });
   });
 
@@ -50,9 +51,14 @@ describe("useProductWishlist", () => {
     });
 
     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);
     });
   });
 });
diff --git a/packages/composables/src/useSyncWishlist.test.ts b/packages/composables/src/useSyncWishlist.test.ts
index fa261ccc..7c3b95f7 100644
--- a/packages/composables/src/useSyncWishlist.test.ts
+++ b/packages/composables/src/useSyncWishlist.test.ts
@@ -1,15 +1,19 @@
-import { describe, expect, it, vi } from "vitest";
+import { describe, expect, it, vi, beforeEach } from "vitest";
 import { useSyncWishlist } from "./useSyncWishlist";
 import { useSetup } from "./_test";
 import { ApiClientError } from "@shopware/api-client";
 import type { FetchResponse } from "ofetch";
 
 describe("useSyncWishlist", () => {
+  beforeEach(() => {
+    vi.clearAllMocks();
+  });
+
   const consoleErrorSpy = vi.spyOn(console, "error");
   consoleErrorSpy.mockImplementation(() => {});
   describe("methods", () => {
     describe("addToWishlist", () => {
-      it("wishlist add product", () => {
+      it("should add product to the wishlist", () => {
         const { vm } = useSetup(() => useSyncWishlist());
 
         expect(vm.addToWishlistSync("some-id")).resolves.toBe(undefined);
@@ -17,7 +21,7 @@ describe("useSyncWishlist", () => {
     });
 
     describe("removeFromWishlist", () => {
-      it("wishlist remove", () => {
+      it("should remove product from the wishlist", () => {
         const { vm } = useSetup(() => useSyncWishlist());
 
         vm.getWishlistProducts();
@@ -28,7 +32,7 @@ describe("useSyncWishlist", () => {
     });
 
     describe("mergeWishlistProducts", () => {
-      it("wishlist remove", () => {
+      it("should sync wishlist", () => {
         const { vm } = useSetup(() => useSyncWishlist());
 
         expect(vm.mergeWishlistProducts(["test1", "test2"])).resolves.toEqual(
@@ -38,17 +42,53 @@ describe("useSyncWishlist", () => {
     });
 
     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(), {
           apiClient: {
             invoke: vi.fn().mockImplementation(() => {
@@ -69,7 +109,7 @@ describe("useSyncWishlist", () => {
         });
         vm.getWishlistProducts();
         expect(consoleErrorSpy).toHaveBeenCalledTimes(1);
-        expect(vm.count).toBe(0);
+        expect(vm.count).toBe(9);
         expect(vm.items.length).toBe(0);
       });
     });
diff --git a/packages/composables/src/useWishlist.test.ts b/packages/composables/src/useWishlist.test.ts
index a5c393d1..7ae3d24f 100644
--- a/packages/composables/src/useWishlist.test.ts
+++ b/packages/composables/src/useWishlist.test.ts
@@ -47,13 +47,11 @@ vi.mock("./useSyncWishlist.ts");
 vi.mock("./useUser");
 
 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,
       mergeWishlistProducts: () => undefined,
       removeFromWishlistSync: () => undefined,
@@ -71,13 +69,11 @@ describe("useWishlist - not logged in user", () => {
     expect(Number(vm.totalPagesCount)).toBe(2);
   });
 
-  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,
       mergeWishlistProducts: () => undefined,
       removeFromWishlistSync: () => undefined,
@@ -119,7 +115,7 @@ describe("useWishlist - not logged in user", () => {
 });
 
 describe("useWishlist - logged in user", () => {
-  it("mergeWishlistProducts", () => {
+  it("should merge wishlist products", () => {
     vi.mocked(useUser).mockReturnValue(getMockedUser(true, false));
     vi.mocked(useSyncWishlist).mockReturnValue({
       getWishlistProducts: () => new Promise<void>((resolve) => resolve()),
@@ -158,7 +154,7 @@ describe("useWishlist - logged in user", () => {
     expect(vm.count).toBe(15);
   });
 
-  it("getWishlistProducts", () => {
+  it("should get wishlist products", () => {
     vi.mocked(useUser).mockReturnValue(getMockedUser(true, false));
     const { vm } = useSetup(() => useWishlist());
     vm.getWishlistProducts();
diff --git a/packages/composables/vitest.config.ts b/packages/composables/vitest.config.ts
index 72ac8f88..6c34acd7 100644
--- a/packages/composables/vitest.config.ts
+++ b/packages/composables/vitest.config.ts
@@ -7,14 +7,17 @@ export default defineConfig({
     coverage: {
       enabled: true,
       include: ["src"],
-      // "100": true, // TODO: our goal ;)
       thresholds: {
-        statements: 97,
-        branches: 90,
-        functions: 88.4,
-        lines: 97,
+        100: true,
       },
-      exclude: ["**/devtools/**"],
+      exclude: [
+        "**/devtools/**",
+        "**/types/**",
+        "**/src/*.test.ts",
+        "**/src/*.spec.ts",
+        // After refactoring should be removed - https://github.com/shopware/frontends/issues/1057
+        "**/src/useListing.ts",
+      ],
     },
     alias: {
       "#imports": resolve(__dirname, "./src/index.ts"),