[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/messages/da.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/buybox-context.title": "Buybox-kontekst",
  "store/buybox-context.sortStrategy-title": "Sorteringsstrategi",
  "store/buybox-context.sortStrategy-description": "Konfigurer strategien til at rangordne sælgere i Buybox",
  "store/buybox-context.triggerCepChangeEvent-title": "Udløser postnummerændringshændelse",
  "store/buybox-context.triggerCepChangeEvent-description": "Konfigurer, hvilken begivenhed der skal bruges til at rangordne sælgere i Buybox",
  "store/buybox-context.price.label": "Pris",
  "store/buybox-context.price-and-shipping.label": "Pris og forsendelse",
  "store/buybox-context.custom-expression": "Brugerdefineret udtryk",
  "store/buybox-context.protocol": "Protokol",
  "store/buybox-context.order-form.label": "Ordreformular",
  "store/buybox-context.seller-selector.label": "Sælgervælger",
  "store/buybox-context.expression-title": "Udtryk",
  "store/buybox-context.expression-description": "Konfigurer udtryk til at rangordne sælgere: productPrice, productSpotPrice, productAvailableQuantity, minShippingPrice, maxShippingPrice, minShippingEstimate, maxShippingEstimate",
  "store/buybox-context.protocol-error": "Der opstod en fejl under udførelsen af sorteringsprotokollen, og sorteringsstrategien blev ændret til pris."
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/messages/th.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/buybox-context.title": "บริบทของ Buybox",
  "store/buybox-context.sortStrategy-title": "กลยุทธ์การคัดแยก",
  "store/buybox-context.sortStrategy-description": "กำหนดค่ากลยุทธ์เพื่อคัดแยกผู้ขายใน Buybox",
  "store/buybox-context.triggerCepChangeEvent-title": "กระตุ้นเหตุการณ์การเปลี่ยนแปลงใน CEP",
  "store/buybox-context.triggerCepChangeEvent-description": "กำหนดค่าว่าจะใช้เหตุการณ์ใดเป็นตัวคัดแยกผู้ขายใน Buybox",
  "store/buybox-context.price.label": "ราคา",
  "store/buybox-context.price-and-shipping.label": "ราคาและการขนส่ง",
  "store/buybox-context.custom-expression": "Expression ที่กำหนดเอง",
  "store/buybox-context.protocol": "โปรโตคอล",
  "store/buybox-context.order-form.label": "แบบฟอร์มคำสั่ง",
  "store/buybox-context.seller-selector.label": "ผู้ขายที่มีให้เลือก",
  "store/buybox-context.expression-title": "Expression",
  "store/buybox-context.expression-description": "กำหนดค่า Expression ที่จะคัดแยกผู้ขาย: productPrice, productSpotPrice, productAvailableQuantity, minShippingPrice, maxShippingPrice, minShippingEstimate, maxShippingEstimate",
  "store/buybox-context.protocol-error": "เกิดข้อผิดพลาดเมื่อทำรายการโปรโตคอลการคัดแยก และมีการเปลี่ยนกลยุทธ์การคัดแยกไปที่ราคา"
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/messages/sv.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/buybox-context.title": "Buybox Kontext",
  "store/buybox-context.sortStrategy-title": "Sorteringsstrategi",
  "store/buybox-context.sortStrategy-description": "Konfigurera strategin för att rangordna säljare i Buyboxen",
  "store/buybox-context.triggerCepChangeEvent-title": "Trigga händelsen för postnummerändring",
  "store/buybox-context.triggerCepChangeEvent-description": "Konfigurera vilken händelse som ska användas för att rangordna säljare i Buyboxen",
  "store/buybox-context.price.label": "Pris",
  "store/buybox-context.price-and-shipping.label": "Pris och frakt",
  "store/buybox-context.custom-expression": "Anpassat uttryck",
  "store/buybox-context.protocol": "Protokoll",
  "store/buybox-context.order-form.label": "Orderformulär",
  "store/buybox-context.seller-selector.label": "Säljareväljare",
  "store/buybox-context.expression-title": "Uttryck",
  "store/buybox-context.expression-description": "Konfigurera uttryck för att rangordna säljare: productPrice, productSpotPrice, productAvailableQuantity, minShippingPrice, maxShippingPrice, minShippingEstimate, maxShippingEstimate",
  "store/buybox-context.protocol-error": "Ett fel inträffade vid utförandet av sorteringsprotokollet och sorteringsstrategin ändrades till pris."
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/messages/es.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/buybox-context.title": "Buybox Context",
  "store/buybox-context.sortStrategy-title": "Estrategia de ordenación",
  "store/buybox-context.sortStrategy-description": "Configura la estrategia para clasificar los sellers en el Buybox",
  "store/buybox-context.triggerCepChangeEvent-title": "Activar evento de cambio de código postal",
  "store/buybox-context.triggerCepChangeEvent-description": "Configura qué evento se utilizará para clasificar los sellers en el Buybox",
  "store/buybox-context.price.label": "Precio",
  "store/buybox-context.price-and-shipping.label": "Precio y envío",
  "store/buybox-context.custom-expression": "Expresión personalizada",
  "store/buybox-context.protocol": "Protocolo",
  "store/buybox-context.order-form.label": "Formulario de pedido",
  "store/buybox-context.seller-selector.label": "Selector de sellers",
  "store/buybox-context.expression-title": "Expresión",
  "store/buybox-context.expression-description": "Configura expresiones para clasificar los sellers: productPrice, productSpotPrice, productAvailableQuantity, minShippingPrice, maxShippingPrice, minShippingEstimate, maxShippingEstimate",
  "store/buybox-context.protocol-error": "Se produjo un error al ejecutar el protocolo de ordenación y se cambió la estrategia de ordenación a precio."
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/messages/ar.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/buybox-context.title": "سياق علبة الشراء",
  "store/buybox-context.sortStrategy-title": "استراتيجية الفرز",
  "store/buybox-context.sortStrategy-description": "قم بإعداد إستراتيجية لترتيب البائعين في علبة الشراء",
  "store/buybox-context.triggerCepChangeEvent-title": "تشغيل حدث تغيير الرمز البريدي",
  "store/buybox-context.triggerCepChangeEvent-description": "قم بإعداد الحدث الذي سيتم استخدامه لترتيب البائعين في علبة الشراء",
  "store/buybox-context.price.label": "السعر",
  "store/buybox-context.price-and-shipping.label": "السعر والشحن",
  "store/buybox-context.custom-expression": "تعبير مخصص",
  "store/buybox-context.protocol": "البروتوكول",
  "store/buybox-context.order-form.label": "استمارة الطلب",
  "store/buybox-context.seller-selector.label": "محدد البائع",
  "store/buybox-context.expression-title": "التعبير",
  "store/buybox-context.expression-description": "قم بإعداد التعابير لترتيب البائعين: productPrice, productSpotPrice, productAvailableQuantity, minShippingPrice, maxShippingPrice, minShippingEstimate, maxShippingEstimate",
  "store/buybox-context.protocol-error": "تم تغيير الخطأ أثناء تنفيذ بروتوكول الفرز واستراتيجية الفرز إلى السعر."
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/messages/es-MX.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "store/buybox-context.title": "Buybox Context",
  "store/buybox-context.sortStrategy-title": "Estrategia de ordenación",
  "store/buybox-context.sortStrategy-description": "Configura la estrategia para clasificar los sellers en el Buybox",
  "store/buybox-context.triggerCepChangeEvent-title": "Activar evento de cambio de código postal",
  "store/buybox-context.triggerCepChangeEvent-description": "Configura qué evento se utilizará para clasificar los sellers en el Buybox",
  "store/buybox-context.price.label": "Precio",
  "store/buybox-context.price-and-shipping.label": "Precio y envío",
  "store/buybox-context.custom-expression": "Expresión personalizada",
  "store/buybox-context.protocol": "Protocolo",
  "store/buybox-context.order-form.label": "Formulario de pedido",
  "store/buybox-context.seller-selector.label": "Selector de sellers",
  "store/buybox-context.expression-title": "Expresión",
  "store/buybox-context.expression-description": "Configura expresiones para clasificar los sellers: productPrice, productSpotPrice, productAvailableQuantity, minShippingPrice, maxShippingPrice, minShippingEstimate, maxShippingEstimate",
  "store/buybox-context.protocol-error": "Se produjo un error al ejecutar el protocolo de ordenación y se cambió la estrategia de ordenación a precio."
}
```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/docs/README.md from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```markdown
📢 Use this project, [contribute](https://github.com/vtex-apps/buybox-context) to it or open issues to help evolve it using [Store Discussion](https://github.com/vtex-apps/store-discussion).

# Buybox Context

##  ⚠ Maintenance ⚠
*Starting June 1st 2023, this application will no longer be maintained by VTEX.*

---

<!-- DOCS-IGNORE:start -->
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->

[![All Contributors](https://img.shields.io/badge/all_contributors-0-orange.svg?style=flat-square)](#contributors-)

<!-- ALL-CONTRIBUTORS-BADGE:END -->
<!-- DOCS-IGNORE:end -->

Buybox context is a component to add the possibility to sort the sellers of a product that is sold by multiple sellers.
When Buybox context wrap a Product context, it change the ordenation of sellers and set the new `sellerDefault` on seller list of current product.

## Configuration

In this section, you first must **add the primary instructions** that will allow users to use the app's blocks in their store, such as:

1. Adding the app as a theme dependency in the `manifest.json` file;

```json
  "dependencies": {
    "vtexbr.buybox-context": "1.x"
  }
```

> 📢 If you want to use the [vtex.seller-selector](https://github.com/vtex-apps/seller-selector) app to boost your development, you can add it as a dependency in the `manifest.json` file
>
> ```json
>    "dependencies": {
>      "vtex.seller-selector": "0.x"
>    }
> ```

2. Wrap a block that uses the [`Product Context`](https://github.com/vtex-apps/product-context) and configure the `sortStrategy` that will be used to sort the sellers.

```json
  "buybox-context": {
    "props": {
      "conditionalStrategy": {
        "sortStrategy": "priceShipping",
      }
      "triggerCepChangeEvent": "sellerSelector"
    },
    "children": [
      ...
    ]
  }
```

Now, you are able to use all the blocks exported by the `buybox-context` app. Check out the full list below:

### `buybox-context` props

| Prop name               | Type     | Description                                                                                | Default value |
| ----------------------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| `conditionalStrategy`   | `object` | Object responsible to provide the sort strategy and custom expresions.                                                                                | `undefined`   |
| `triggerCepChangeEvent` | `enum`   | The Buybox Context depends on CEP event to get Sellers of Product. Depending on context the Buybox Context is used, you can select what this component will be listening to intercept changes and reorder sellers. | `"orderForm"` |
| `children`              | `array`  | Array with `block` components, that use the `Product Context` to sort sellers.                                                                                | `null`        |

- `conditionalStrategy` props

| Prop name      | Type     | Description                                                                                | Default value |
| -------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------- |
| `sortStrategy` | `enum`   | Use to select which sort strategy will be used to sort the sellers. If this prop isn't informed, nothing will be done.                                                                                | `undefined`   |
| `expression`   | `string` | Custom expression based on a math expression, with predefined [`variables`](#custom-expression-variables). The lowest value resultant of this expression, will be positioned at the top of the sellers list. For more details about how to create expressions, click [here](https://github.com/silentmatt/expr-eval#readme). | `undefined`   |

- `sortStrategy` enum:
  | Prop name | Type | Description |
  | --------- | -------- | ----------- |
  | `price` | `string` | Sort sellers **only product price**. The sellers at the top of the list will have the lowest prices. |
  | `priceShipping` | `string` | Sort sellers by **product price + shipping price**. The lowest sum between these two values, will be positioned at the top of the sellers list. |
  | `customExpression` | `string` | Sort sellers by a custom expression based on a math expression, with predefined [`variables`](#custom-expression-variables). The lowest value resultant of this expression, will be positioned at the top of the sellers list. For more details about how to create expressions, click [here](https://github.com/silentmatt/expr-eval#readme) |
  | `protocol` | `string` | Sort sellers using a protocol defined on [buybox-graphql](https://github.com/vtex-apps/buybox-graphql). This protocol defines the contract to receive and respond with the sorted data. For that to work, it's necessary to implement a resolver for this contract. The [buybox-resolver](https://github.com/vtex-apps/buybox-resolver) was created as an example of that implementation. |

- `triggerCepChangeEvent` enum:
  | Prop name | Type | Description |
  | --------- | -------- | ----------- |
  | `orderForm` | `string` | Used for listening [`useOrderForm()`](https://github.com/vtex-apps/order-manager#orderform-orderform) changes, to get sellers and logistics info to sort seller list with new shipping values. |
  | `sellerSelector` | `string` | Used for listening [`useSellerContext()`]() changes, to get sellers and logistics info to sort seller list with new shipping values. |

- `children` array: Array with `block` components

📢 _The `sortStrategy` and `triggerCepChangeEvent` can be changed using Site Editor_

### Custom expression variables

| Variable                   | Entity   | Description                     |
| -------------------------- | -------- | ------------------------------- |
| `productPrice`             | Product  | Product price                   |
| `productSpotPrice`         | Product  | Product spot price              |
| `productAvailableQuantity` | Product  | Product available quantity      |
| `minShippingPrice`         | Shipping | Cheapest shipping price         |
| `maxShippingPrice`         | Shipping | Most expensive shipping price   |
| `minShippingEstimate`      | Shipping | Minimum estimated delivery time |
| `maxShippingEstimate`      | Shipping | Maximum estimated delivery time |

### `seller-body.buybox` props

| Prop name  | Type    | Description                                                                                | Default value |
| ---------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------- |
| `children` | `array` | Array with `block` components. It's very recommended you follow the [seller-sellector](https://github.com/vtex-apps/seller-selector#advanced-configuration) instrucions to use this. | `null`        |

- `children` array: Array with `block` components.

## Dependences

- [vtex.product-context](https://github.com/vtex-apps/product-context)
- [vtex.order-manager](https://github.com/vtex-apps/order-manager)
- [vtex.seller-selector](https://github.com/vtex-apps/seller-selector)
- [expr-eval](https://github.com/silentmatt/expr-eval)

## Modus Operandi

### Product Page

On product page you can add the `buybox-context` where make sense the behavior of select the Buybox winner. In the example bellow `flex-layout.col#right-col` is the block that contains product values and conditions. See below:

```json
{
  ...
  "flex-layout.row#product-main": {
    "children": [
      "flex-layout.col#stack",
      "flex-layout.col#right-col"
    ]
  }
  ...
}
```

After adding the `buybox-context` in this example, the new code will be like bellow:

```diff
{
  ...
  "flex-layout.row#product-main": {
    "children": [
      "flex-layout.col#stack",
-     "flex-layout.col#right-col"
+     "vtex.buybox-context:buybox-context#product-col"
    ]
  },
+ "vtex.buybox-context:buybox-context#product-col": {
+   "props": {
+     "conditionalStrategy": {
+       "sortStrategy": "priceShipping"
+     },
+     "triggerCepChangeEvent": "orderForm"
+   },
+   "children": [
+     "flex-layout.col#right-col"
+   ]
+ },
  ...
}
```

ℹ _By default the prop `triggerCepChangeEvent` value is `orderForm`, which makes this prop optional._

### Sellers

With [seller-selector](https://github.com/vtex-apps/seller-selector) and `buybox-context` installed in your theme, do you can create or edit file in `store/blocks/sellers/sellers.jsonc` and add this code bellow:

```json
{
  "store.sellers": {
    "blocks": ["vtex.seller-selector:seller-table"]
  },
  "vtex.seller-selector:seller-table": {
    "children": [
      "vtex.seller-selector:seller-simulate-shipping",
      "vtex.seller-selector:seller-head",
      "buybox-context"
    ]
  },
  "buybox-context": {
    "props": {
      "conditionalStrategy": {
        "sortStrategy": "priceShipping"
      },
      "triggerCepChangeEvent": "sellerSelector"
    },
    "children": ["seller-body.buybox"]
  },
  "seller-body.buybox": {
    "children": ["vtex.seller-selector:seller-row"]
  }
}
```

That way you will have a page similar to this:
![image](https://user-images.githubusercontent.com/17439470/133501110-e143b472-1b58-4ee8-8759-8096ca32df0c.png)

ℹ _To have the full behaviour using `seller-body.buybox`, it will be necessary to set the `triggerCepChangeEvent` as `sellerSelector` props on `buybox-context`. Because the default value for this parameter is `orderForm`, but on this page we usually use the `seller-simulate-shipping` to calculate shipping_

## Customization

In order to apply CSS customizations in this and other blocks, follow the instructions given in the recipe on [Using CSS Handles for store customization](https://vtex.io/docs/recipes/style/using-css-handles-for-store-customization).

| CSS Handles  |
| ------------ |
| `sellerList` |

<!-- DOCS-IGNORE:start -->

## Contributors ✨

Thanks goes to these wonderful people:

<!-- ALL-CONTRIBUTORS-LIST:START - Do not remove or modify this section -->
<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<!-- markdownlint-enable -->
<!-- prettier-ignore-end -->

<!-- ALL-CONTRIBUTORS-LIST:END -->

This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome!

<!-- DOCS-IGNORE:end -->

**Upcoming documentation:**

- [Feature/brpa 352 sort by expression](https://github.com/vtex-apps/buybox-context/pull/5)
- [add a conditional field expression](https://github.com/vtex-apps/buybox-context/pull/6)
- [add productSpotPrice and productAvailableQuantity variables](https://github.com/vtex-apps/buybox-context/pull/7)
- [add shipping estimate as variable](https://github.com/vtex-apps/buybox-context/pull/8)

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/package.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "scripts": {
    "test": "vtex-test-tools test"
  },
  "dependencies": {
    "apollo-client": "^2.6.8",
    "expr-eval": "^2.0.2",
    "react": "^16.12.0",
    "react-apollo": "^3.1.3",
    "react-dom": "^16.12.0",
    "react-intl": "^3.12.0"
  },
  "devDependencies": {
    "@apollo/react-testing": "^3.1.3",
    "@types/jest": "^25.1.4",
    "@types/node": "^13.9.8",
    "@types/react": "^16.9.31",
    "@vtex/test-tools": "^3.3.2",
    "@vtex/tsconfig": "^0.4.4",
    "apollo-cache-inmemory": "^1.6.5",
    "graphql": "^14.6.0",
    "typescript": "3.9.7",
    "vtex.css-handles": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.css-handles@0.4.4/public/@types/vtex.css-handles",
    "vtex.order-manager": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.order-manager@0.11.1/public/@types/vtex.order-manager",
    "vtex.product-context": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.product-context@0.10.0/public/@types/vtex.product-context",
    "vtex.render-runtime": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.render-runtime@8.132.3/public/@types/vtex.render-runtime",
    "vtex.seller-selector": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.seller-selector@0.3.0/public/@types/vtex.seller-selector",
    "vtex.store": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store@2.120.1/public/@types/vtex.store",
    "vtex.store-graphql": "http://vtex.vtexassets.com/_v/public/typings/v1/vtex.store-graphql@2.147.3/public/@types/vtex.store-graphql"
  },
  "version": "1.1.0"
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/SellerBody.tsx from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { ReactNode } from 'react'
import React, { useCallback } from 'react'
import { useCssHandles } from 'vtex.css-handles'
import { CurrentSellerContext } from 'vtex.seller-selector'

import { useBuyBoxContext } from './context/BuyboxContext'
import type { LogisticsInfo, Seller } from './typings/types'

const SELLERS_CSS_HANDLES = ['sellerList']

interface Props {
  children: ReactNode
}

interface CurrentSellerContextValue {
  currentSeller: Seller | null
  shipping: LogisticsInfo | null
}

const SellerBody: StorefrontFunctionComponent<Props> = ({ children }) => {
  const handles = useCssHandles(SELLERS_CSS_HANDLES)

  const { sortedSellers, sortedLogisticsInfo } = useBuyBoxContext()

  const currentSellerCreate = useCallback(
    (current: Seller, index: number) => {
      const currentContext: CurrentSellerContextValue = {
        currentSeller: current,
        shipping: sortedLogisticsInfo ? sortedLogisticsInfo[index] : null,
      }

      return currentContext
    },
    [sortedLogisticsInfo]
  )

  return (
    <div className={`${handles.sellers} mh7 mb7`}>
      {sortedSellers?.map((current, index: number) => (
        <CurrentSellerContext.CurrentSellerProvider
          value={currentSellerCreate(current, index)}
          key={index}
        >
          {children}
        </CurrentSellerContext.CurrentSellerProvider>
      ))}
    </div>
  )
}

export default SellerBody

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/BuyboxApp.tsx from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'

import { ProductWithSortedSellers } from './components/ProductWithSortedSellers'
import BuyboxProvider from './provider/BuyboxProvider'
import type { Strategies, TriggerCepChangeEventType } from './typings/types'
import { messages } from './utils/messages'

interface Props {
  conditionalStrategy?: {
    sortStrategy?: Strategies
    expression?: string
  }
  triggerCepChangeEvent?: TriggerCepChangeEventType
}

const BuyboxApp: StorefrontFunctionComponent<Props> = ({
  children,
  conditionalStrategy = { sortStrategy: 'price' },
  triggerCepChangeEvent = 'orderForm',
}) => {
  return conditionalStrategy?.sortStrategy ? (
    <BuyboxProvider
      sortStrategy={conditionalStrategy.sortStrategy}
      triggerCepChangeEvent={triggerCepChangeEvent}
      expression={conditionalStrategy.expression}
    >
      <ProductWithSortedSellers>{children}</ProductWithSortedSellers>
    </BuyboxProvider>
  ) : (
    <>{children}</>
  )
}

BuyboxApp.schema = {
  title: messages.title.id,
  type: 'object',
  properties: {
    conditionalStrategy: {
      type: 'object',
      properties: {
        sortStrategy: {
          type: 'string',
          title: messages.sortStrategyTitle.id,
          description: messages.sortStrategyDescription.id,
          enum: ['price', 'priceShipping', 'customExpression', 'protocol'],
          enumNames: [
            'store/buybox-context.price.label',
            'store/buybox-context.price-and-shipping.label',
            'store/buybox-context.custom-expression',
            'store/buybox-context.protocol',
          ],
        },
      },
      dependencies: {
        sortStrategy: {
          oneOf: [
            {
              properties: {
                sortStrategy: {
                  enum: ['customExpression'],
                },
                expression: {
                  type: 'string',
                  title: messages.expressionTitle.id,
                  description: messages.expressionDescription.id,
                },
              },
            },
          ],
        },
      },
    },
    triggerCepChangeEvent: {
      type: 'string',
      title: messages.triggerCepChangeEventTitle.id,
      description: messages.triggerCepChangeEventDescription.id,
      enum: ['orderForm', 'sellerSelector'],
      enumNames: [
        'store/buybox-context.order-form.label',
        'store/buybox-context.seller-selector.label',
      ],
      default: 'orderForm',
    },
  },
}

export default BuyboxApp

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/store/interfaces.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "buybox-context": {
    "component": "BuyboxApp",
    "composition": "children"
  },
  "seller-body.buybox": {
    "component": "SellerBody",
    "composition": "children"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/public/metadata/messages/es-AR.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "Buybox",
  "headline": "Muestra un producto con diferentes sellers destacando la mejor oferta",
  "overview": "Con esta aplicación, puedes configurar reglas de elegibilidad de sellers para el producto y mostrar el producto que tenga la mejor oferta para el cliente.",
  "additionalInformation": "Después de instalar la aplicación, la debes configurar en el tema de la tienda en un contexto de producto.",
  "features": [
    "Clasifica los sellers de un producto de forma personalizada",
    "Crea tu propia ordenación utilizando expresiones con atributos del producto",
    "Flexibilidad para utilizar los órdenes predefinidos o personalizados"
  ],
  "websiteURL": "https://vtex.com/",
  "support": {
    "url": "https://support.vtex.com/hc/requests"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/public/metadata/messages/pt-BR.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "Buybox",
  "headline": "Exiba um produto com diferentes sellers, destacando a melhor oferta",
  "overview": "Com este aplicativo, você poderá configurar as regras de elegibilidade de sellers para um produto e mostrar a melhor oferta para o cliente.",
  "additionalInformation": "Após a instalação, o aplicativo deve ser configurado no tema da loja, em um contexto de produto.",
  "features": [
    "Ordene os sellers de um produto de forma personalizada",
    "Crie sua própria estratégia de ordenação utilizando expressões com atributos do produto",
    "Flexibilidade para utilizar ordenações predefinidas ou customizadas"
  ],
  "websiteURL": "https://vtex.com/br-pt/",
  "support": {
    "url": "https://support.vtex.com/hc/requests"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/public/metadata/messages/en-US.json from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```json
{
  "name": "Buybox",
  "headline": "Display a product with different sellers, featuring the best offer",
  "overview": "With this app, you will be able to define seller eligibility rules for a product and feature the best offer to the customer.",
  "additionalInformation": "After installing this app, you must configure it in the store theme, in a product context.",
  "features": [
    "Rank sellers of a product based on custom criteria",
    "Create your own sorting strategy using expressions with product attributes",
    "Flexibility to use predefined or custom sorting settings"
  ],
  "websiteURL": "https://vtex.com/",
  "support": {
    "url": "https://support.vtex.com/hc/requests"
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/context/BuyboxContext.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { createContext, useContext } from 'react'

import type {
  LogisticsInfo,
  Seller,
  SellerLogisticsInfoResult,
} from '../typings/types'

export interface BuyBoxContextType {
  sortedSellersLogisticInfo: SellerLogisticsInfoResult[]
  sortedSellers: Seller[]
  sortedLogisticsInfo: LogisticsInfo[]
}

export const BuyBoxContext = createContext<BuyBoxContextType>({
  sortedSellersLogisticInfo: [],
  sortedSellers: [],
  sortedLogisticsInfo: [],
})

export function useBuyBoxContext() {
  return useContext(BuyBoxContext)
}

export default BuyBoxContext

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/typings/storefront.d.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { FunctionComponent } from 'react'

declare global {
  interface StorefrontFunctionComponent<P = GenericObject>
    extends FunctionComponent<P> {
    getSchema?(props: P): GenericObject
    schema?: GenericObject
  }

  interface StorefrontComponent<P = GenericObject, S = GenericObject>
    extends Component<P, S> {
    getSchema?(props: P): GenericObject
    schema: GenericObject
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/typings/types.d.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { LogisticsInfo as SellerContextLogisticsInfo } from 'vtex.seller-selector/react/SellerContext'
import type { Seller as SellerContextSeller } from 'vtex.product-context/react/ProductTypes'

export type Strategies =
  | 'price'
  | 'priceShipping'
  | 'customExpression'
  | 'protocol'
export type TriggerCepChangeEventType = 'orderForm' | 'sellerSelector'

export type LogisticsInfo = SellerContextLogisticsInfo
export type Seller = SellerContextSeller

export interface SellerLogisticsInfoResult {
  seller: Seller
  logisticsInfo?: LogisticsInfo
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/typings/gql.d.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.gql' {
  import { DocumentNode } from 'graphql'

  const Schema: DocumentNode

  export default Schema
}

declare module '*.graphql' {
  import { DocumentNode } from 'graphql'

  const schema: DocumentNode

  export default Schema
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/typings/css.d.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
declare module '*.css' {
  type Styles = {
    [selector: string]: string
  }

  const styles: Styles

  export default styles
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/provider/BuyboxProvider.tsx from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { ReactNode } from 'react'
import React from 'react'
import { useIntl } from 'react-intl'

import BuyboxContext from '../context/BuyboxContext'
import { useReduceSellerLogisticsInfo } from '../hooks/useReduceSellerLogisticsInfo'
import { useSellerLoginstcsInfoSellerSelector } from '../hooks/useSellerLoginstcsInfoSellerSelector'
import { useSellerLogisticsInfo } from '../hooks/useSellerLogisticsInfo'
import { useSellersByProtocol } from '../hooks/useSellersByProtocol'
import type {
  SellerLogisticsInfoResult,
  Strategies,
  TriggerCepChangeEventType,
} from '../typings/types'
import { messages } from '../utils/messages'
import {
  sortSellersByCustomExpression,
  sortSellersByPrice,
  sortSellersByPriceShipping,
} from '../utils/sortSellers'

const SortStrategyFunctions: {
  [key in Strategies]: (
    sellersInfo: SellerLogisticsInfoResult[],
    expression?: string
  ) => SellerLogisticsInfoResult[]
} = {
  price: sortSellersByPrice,
  priceShipping: sortSellersByPriceShipping,
  customExpression: sortSellersByCustomExpression,
  protocol: useSellersByProtocol,
}

const SellerLogisticsInfoFunctions: {
  [key in TriggerCepChangeEventType]: () => SellerLogisticsInfoResult[]
} = {
  orderForm: useSellerLogisticsInfo,
  sellerSelector: useSellerLoginstcsInfoSellerSelector,
}

interface Props {
  children: ReactNode
  sortStrategy: Strategies
  expression?: string
  triggerCepChangeEvent: TriggerCepChangeEventType
}

const BuyboxProvider = ({
  children,
  sortStrategy,
  expression,
  triggerCepChangeEvent,
}: Props) => {
  const intl = useIntl()

  const sellersInfoResult =
    SellerLogisticsInfoFunctions[triggerCepChangeEvent]()

  let sortedSellersLogisticInfo: SellerLogisticsInfoResult[] = []

  try {
    sortedSellersLogisticInfo = SortStrategyFunctions[sortStrategy](
      sellersInfoResult,
      expression
    )
  } catch (error) {
    sortedSellersLogisticInfo = SortStrategyFunctions.price(sellersInfoResult)

    console.error(intl.formatMessage(messages.protocolError), '\n', error)
  }

  const { sellers: sortedSellers, logisticsInfo: sortedLogisticsInfo } =
    useReduceSellerLogisticsInfo({
      sellerLogisticsInfo: sortedSellersLogisticInfo,
    })

  return (
    <BuyboxContext.Provider
      value={{
        sortedSellersLogisticInfo,
        sortedSellers,
        sortedLogisticsInfo,
      }}
    >
      {children}
    </BuyboxContext.Provider>
  )
}

export default BuyboxProvider

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/utils/shippingEstimate.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
// eslint-disable-next-line no-restricted-syntax
export enum UnitTime {
  m = 0, // minutes
  h = 1, // hours
  d = 2, // days
  bd = 3, // business days
}

const MINUTES = 1
const HOUR_IN_MINUTES = MINUTES * 60
const DAYS_IN_MINUTES = HOUR_IN_MINUTES * 24
const BUSINESS_DAYS_IN_MINUTES = DAYS_IN_MINUTES * 1.4

export const UnitTimeWeight: { [key in keyof typeof UnitTime]: number } = {
  m: MINUTES,
  h: HOUR_IN_MINUTES,
  d: DAYS_IN_MINUTES,
  bd: BUSINESS_DAYS_IN_MINUTES,
}

export const splitShippingEstimate = (shippingEstimate: string) => {
  const timeAmount = Number(shippingEstimate.split(/\D+/)[0])
  const unitTime = shippingEstimate.split(/[0-9]+/)[1] as keyof typeof UnitTime

  return { timeAmount, unitTime }
}

export const evaluateShippingEstimate = (shippingEstimate: string) => {
  const { timeAmount, unitTime } = splitShippingEstimate(shippingEstimate)

  return timeAmount * UnitTimeWeight[unitTime]
}

export const compare = (
  shippingEstimateA: string,
  shippingEstimateB: string
) => {
  const { timeAmount: timeAmountA, unitTime: unitTimeA } =
    splitShippingEstimate(shippingEstimateA)

  const { timeAmount: timeAmountB, unitTime: unitTimeB } =
    splitShippingEstimate(shippingEstimateB)

  if (unitTimeA !== unitTimeB) {
    return UnitTime[unitTimeA] - UnitTime[unitTimeB]
  }

  if (timeAmountA !== timeAmountB) {
    return timeAmountA - timeAmountB
  }

  return 0
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/utils/sortSellers.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { Parser } from 'expr-eval'

import type {
  LogisticsInfo,
  Seller,
  SellerLogisticsInfoResult,
} from '../typings/types'
import { compare, evaluateShippingEstimate } from './shippingEstimate'

export const sortSellersByPrice = (
  sellersInfo: SellerLogisticsInfoResult[]
) => {
  if (!sellersInfo) return []

  const sortedList = [...sellersInfo]

  sortedList.sort(
    (sellerA, sellerB) =>
      Number(sellerA.seller.commertialOffer.Price) -
      Number(sellerB.seller.commertialOffer.Price)
  )

  return sortedList
}

export const sortSellersByPriceShipping = (
  sellersInfo: SellerLogisticsInfoResult[]
) => {
  if (!sellersInfo) return []

  const sortedList = [...sellersInfo]

  sortedList.sort((sellerA, sellerB) => {
    if (!sellerA.logisticsInfo?.slas?.length) {
      return 1
    }

    if (!sellerB.logisticsInfo?.slas?.length) {
      return -1
    }

    const shippingPriceA = sellerA.logisticsInfo?.slas?.length
      ? sellerA.logisticsInfo.slas[0].price / 100
      : 0

    const shippingPriceB = sellerB.logisticsInfo?.slas?.length
      ? sellerB.logisticsInfo.slas[0].price / 100
      : 0

    return (
      Number(sellerA.seller.commertialOffer.Price + shippingPriceA) -
      Number(sellerB.seller.commertialOffer.Price + shippingPriceB)
    )
  })

  return sortedList
}

type ExpressionVariablesType =
  | 'productPrice'
  | 'productSpotPrice'
  | 'productAvailableQuantity'
  | 'minShippingPrice'
  | 'maxShippingPrice'
  | 'minShippingEstimate'
  | 'maxShippingEstimate'

type ExpressionVariablesDictionaryType = {
  [key in ExpressionVariablesType]?: (
    seller: Seller,
    logisticsInfo?: LogisticsInfo
  ) => number | string | undefined
}

type LogisticsInfoSLA = LogisticsInfo['slas']

// alternative functions to sort SLA's before sort sellers
const sortSLAByField = {
  minPrice: (slas: LogisticsInfoSLA) =>
    slas.sort((slaA, slaB) => Number(slaA.price) - Number(slaB.price)),
  maxPrice: (slas: LogisticsInfoSLA) =>
    slas.sort((slaA, slaB) => Number(slaB.price) - Number(slaA.price)),
  minShippingEstimate: (slas: LogisticsInfoSLA) =>
    slas?.sort((slaA, slaB) =>
      compare(slaA.shippingEstimate, slaB.shippingEstimate)
    ),
  maxShippingEstimate: (slas: LogisticsInfoSLA) =>
    slas?.sort((slaB, slaA) =>
      compare(slaA.shippingEstimate, slaB.shippingEstimate)
    ),
}

// functions used to get expression values based on ExpressionVariablesType inputed by user
const expressionVariables: ExpressionVariablesDictionaryType = {
  productPrice: (seller: Seller, _logisticsInfo?: LogisticsInfo) =>
    seller.commertialOffer.Price,
  productSpotPrice: (seller: Seller, _logisticsInfo?: LogisticsInfo) =>
    seller.commertialOffer.spotPrice,
  productAvailableQuantity: (seller: Seller, _logisticsInfo?: LogisticsInfo) =>
    seller.commertialOffer.AvailableQuantity,
  minShippingPrice: (_seller: Seller, logisticsInfo?: LogisticsInfo) =>
    logisticsInfo?.slas[0]?.price !== undefined
      ? sortSLAByField.minPrice(logisticsInfo?.slas)[0]?.price / 100
      : undefined,
  maxShippingPrice: (_seller: Seller, logisticsInfo?: LogisticsInfo) =>
    logisticsInfo?.slas[0]?.price !== undefined
      ? sortSLAByField.maxPrice(logisticsInfo?.slas)[0]?.price / 100
      : undefined,
  minShippingEstimate: (_seller: Seller, logisticsInfo?: LogisticsInfo) => {
    const shippingEstimate =
      logisticsInfo &&
      sortSLAByField.minShippingEstimate(logisticsInfo.slas)[0]
        ?.shippingEstimate

    if (shippingEstimate) {
      return evaluateShippingEstimate(shippingEstimate)
    }

    return undefined
  },
  maxShippingEstimate: (_seller: Seller, logisticsInfo?: LogisticsInfo) => {
    const shippingEstimate =
      logisticsInfo &&
      sortSLAByField.maxShippingEstimate(logisticsInfo.slas)[0]
        ?.shippingEstimate

    if (shippingEstimate) {
      return evaluateShippingEstimate(shippingEstimate)
    }

    return undefined
  },
}

export const sortSellersByCustomExpression = (
  sellersInfo: SellerLogisticsInfoResult[],
  expression?: string
) => {
  if (!sellersInfo) return []

  if (!expression) return sellersInfo

  const logisticInfoVariables: ExpressionVariablesType[] = [
    'minShippingPrice',
    'maxShippingPrice',
    'minShippingEstimate',
    'maxShippingEstimate',
  ]

  const sortedList = [...sellersInfo]

  const variables = Object.keys(expressionVariables)
    .filter((e) => expression.includes(e))
    .reduce((accumulator: ExpressionVariablesDictionaryType, key) => {
      return {
        ...accumulator,
        [key]: expressionVariables[key as ExpressionVariablesType],
      }
    }, {})

  try {
    sortedList.sort((sellerA, sellerB) => {
      // set the sellers without SLA calculated to end of the array
      if (logisticInfoVariables.some((info) => expression.includes(info))) {
        if (!sellerA.logisticsInfo?.slas?.length) {
          return 1
        }

        if (!sellerB.logisticsInfo?.slas?.length) {
          return -1
        }
      }

      const { valuesSellerA, valuesSellerB } = Object.keys(variables).reduce(
        (
          accumulator: {
            valuesSellerA: {
              [key in ExpressionVariablesType]?: any
            }
            valuesSellerB: {
              [key in ExpressionVariablesType]?: any
            }
          },
          key: string
        ) => {
          const exec = expressionVariables[key as ExpressionVariablesType]

          const valueA = exec?.(sellerA.seller, sellerA.logisticsInfo)
          const valueB = exec?.(sellerB.seller, sellerB.logisticsInfo)

          return {
            valuesSellerA: { ...accumulator.valuesSellerA, [key]: valueA ?? 0 },
            valuesSellerB: { ...accumulator.valuesSellerB, [key]: valueB ?? 0 },
          }
        },
        { valuesSellerA: {}, valuesSellerB: {} }
      )

      const parser = new Parser()
      const expr = parser.parse(expression)

      const resultA = expr.evaluate({
        ...valuesSellerA,
      })

      const resultB = expr.evaluate({
        ...valuesSellerB,
      })

      return resultA - resultB
    })
  } catch (error) {
    console.error('Invalid variable on expression: ', error.message)

    return sellersInfo
  }

  return sortedList
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/utils/messages.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { MessageDescriptor } from 'react-intl'
import { defineMessages } from 'react-intl'

export const messages: {
  [name: string]: MessageDescriptor
} = defineMessages({
  title: {
    id: 'store/buybox-context.title',
  },
  sortStrategyTitle: {
    id: 'store/buybox-context.sortStrategy-title',
  },
  sortStrategyDescription: {
    id: 'store/buybox-context.sortStrategy-description',
  },
  triggerCepChangeEventTitle: {
    id: 'store/buybox-context.triggerCepChangeEvent-title',
  },
  triggerCepChangeEventDescription: {
    id: 'store/buybox-context.triggerCepChangeEvent-description',
  },
  expressionTitle: {
    id: 'store/buybox-context.expression-title',
  },
  expressionDescription: {
    id: 'store/buybox-context.expression-description',
  },
  protocolError: {
    id: 'store/buybox-context.protocol-error',
  },
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/utils/index.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { Seller } from '../typings/types'

export const isAvailableSeller = (seller: Seller) => {
  return seller.commertialOffer.AvailableQuantity > 0
}

export const getAvailableSellers = (sellers: Seller[] | undefined) => {
  if (!sellers) return []

  return sellers.filter(isAvailableSeller)
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/components/ProductWithSortedSellers.tsx from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
import type { FC } from 'react'
import React from 'react'
import { ProductContextProvider, useProduct } from 'vtex.product-context'

import { useNewProductWithSellers } from '../hooks/useNewProductWithSellers'
import { useBuyBoxContext } from '../context/BuyboxContext'

export const ProductWithSortedSellers: FC = ({ children }) => {
  const productContext = useProduct() ?? {}
  const { sortedSellers } = useBuyBoxContext()

  const newProduct = useNewProductWithSellers({
    productContext,
    sellers: sortedSellers,
  })

  return (
    <ProductContextProvider
      query={{ skuId: productContext.selectedItem?.itemId }}
      product={newProduct}
    >
      {children}
    </ProductContextProvider>
  )
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/BuyboxContext.test.tsx from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```tsx
import React from 'react'
import { render } from '@vtex/test-tools/react'

import BuyboxApp from '../BuyboxApp'

test('BuyboxContext rendered', () => {
  const { container } = render(<BuyboxApp />)

  expect(container).toBeTruthy()
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/graphql/SimulateShipping.gql from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```graphql
query SimulateShipping(
  $shippingItems: [ShippingItem]
  $postalCode: String
  $country: String
) {
  shipping(items: $shippingItems, postalCode: $postalCode, country: $country)
    @context(provider: "vtex.store-graphql") {
    logisticsInfo {
      itemIndex
      slas {
        id
        name
        price
      }
    }
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/graphql/SortSellersProtocol.gql from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```graphql
query SortSellersProtocol(
  $skuId: ID!
  $postalCode: String
  $country: String
  $salesChannel: Int
) {
  sortSellers(
    skuId: $skuId
    postalCode: $postalCode
    country: $country
    salesChannel: $salesChannel
  ) @context(provider: "vtex.buybox-graphql") {
    sellers
  }
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/hooks/useSellersByProtocol.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useQuery } from 'react-apollo'
import { useProduct } from 'vtex.product-context'
import { OrderForm } from 'vtex.order-manager'
import { useRuntime } from 'vtex.render-runtime'

import SortSellersProtocol from '../graphql/SortSellersProtocol.gql'
import type { SellerLogisticsInfoResult } from '../typings/types'

interface SortedSellersProtocol {
  sortSellers: {
    sellers: string[]
  }
}

interface SortedSellersProtocolVariables {
  skuId: string
  postalCode?: string
  country?: string
  salesChannel?: number
}

export const useSellersByProtocol = (
  sellersInfo: SellerLogisticsInfoResult[]
) => {
  const { selectedItem } = useProduct() ?? {}
  const orderFormContext = OrderForm?.useOrderForm() ?? {}

  const runtime = useRuntime()
  const {
    culture: { country },
  } = runtime

  const { data, loading, error } = useQuery<
    SortedSellersProtocol,
    SortedSellersProtocolVariables
  >(SortSellersProtocol, {
    variables: {
      skuId: selectedItem?.itemId ?? '',
      country,
      postalCode:
        orderFormContext.orderForm?.shipping?.selectedAddress?.postalCode ?? '',
    },
    ssr: false,
  })

  if (error) throw error

  if (!sellersInfo.length || !data?.sortSellers?.sellers || loading) {
    return []
  }

  const sellersInfoIndex = sellersInfo.reduce(
    (acummulator, currentValue) => {
      acummulator[currentValue.seller.sellerId] = currentValue

      return acummulator
    },
    {} as {
      [key in string]: SellerLogisticsInfoResult
    }
  )

  return data.sortSellers.sellers.reduce((acummulator, sellerId) => {
    if (sellersInfoIndex[sellerId]) {
      acummulator.push(sellersInfoIndex[sellerId])
    }

    return acummulator
  }, [] as SellerLogisticsInfoResult[])
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/hooks/useReduceSellerLogisticsInfo.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type {
  LogisticsInfo,
  Seller,
  SellerLogisticsInfoResult,
} from '../typings/types'

interface ReducerAcumulator {
  sellers: Seller[]
  logisticsInfo: LogisticsInfo[]
}

interface Props {
  sellerLogisticsInfo: SellerLogisticsInfoResult[]
}

export const useReduceSellerLogisticsInfo = ({
  sellerLogisticsInfo,
}: Props): ReducerAcumulator => {
  const initialValue = {
    sellers: [],
    logisticsInfo: [],
  }

  if (!sellerLogisticsInfo) {
    return initialValue
  }

  const reducer = (
    acumulator: ReducerAcumulator,
    currentValue: SellerLogisticsInfoResult,
    index: number
  ) => {
    // set the buybox winner seller as default seller
    currentValue.seller.sellerDefault = index === 0

    acumulator.sellers.push(currentValue.seller)
    currentValue.logisticsInfo &&
      acumulator.logisticsInfo.push(currentValue.logisticsInfo)

    return acumulator
  }

  return sellerLogisticsInfo.reduce(reducer, {
    sellers: [],
    logisticsInfo: [],
  })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/hooks/useSellerLoginstcsInfoSellerSelector.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useMemo } from 'react'
import { useProduct } from 'vtex.product-context'
import { SellerContext } from 'vtex.seller-selector'

import type { LogisticsInfo, SellerLogisticsInfoResult } from '../typings/types'
import { isAvailableSeller } from '../utils'

export const useSellerLoginstcsInfoSellerSelector =
  (): SellerLogisticsInfoResult[] => {
    const { selectedItem } = useProduct() ?? {}

    const { shippingQuotes } = SellerContext.useSellerContext()

    const logisticsInfo = useMemo(
      () =>
        shippingQuotes?.logisticsInfo.reduce((acummulator, currentValue) => {
          acummulator[currentValue.itemIndex] = currentValue

          return acummulator
        }, {} as { [key in string]: LogisticsInfo }),
      [shippingQuotes?.logisticsInfo]
    )

    return selectedItem
      ? selectedItem.sellers.reduce((accumulator, seller, index) => {
          if (isAvailableSeller(seller)) {
            accumulator.push({
              seller,
              logisticsInfo: logisticsInfo ? logisticsInfo[index] : undefined,
            })
          }

          return accumulator
        }, [] as SellerLogisticsInfoResult[])
      : []
  }

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/hooks/useReduceProduct.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useCallback } from 'react'
import type {
  Item,
  ProductContextState,
} from 'vtex.product-context/react/ProductTypes'

interface ReducerInterface {
  productItemsWithoutSelected: Item[]
  productSelectedItem: Item | undefined
}

export const useReduceProduct = (
  productContext: Partial<ProductContextState>
): ReducerInterface => {
  const initialValue: ReducerInterface = {
    productItemsWithoutSelected: [],
    productSelectedItem: undefined,
  }

  const reducer = useCallback(
    (acumulator: ReducerInterface, currentValue: Item) => {
      if (currentValue.itemId === productContext.selectedItem?.itemId) {
        acumulator.productSelectedItem = { ...currentValue }
      } else {
        acumulator.productItemsWithoutSelected?.push({ ...currentValue })
      }

      return acumulator
    },
    [productContext.selectedItem?.itemId]
  )

  if (!productContext.product) {
    return { ...initialValue }
  }

  return productContext.product.items.reduce(reducer, { ...initialValue })
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/hooks/useNewProductWithSellers.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { useMemo } from 'react'
import type {
  MaybeProduct,
  ProductContextState,
} from 'vtex.product-context/react/ProductTypes'

import type { Seller } from '../typings/types'
import { useReduceProduct } from './useReduceProduct'

interface Props {
  productContext: Partial<ProductContextState>
  sellers: Seller[]
}

export const useNewProductWithSellers = ({
  productContext,
  sellers,
}: Props): MaybeProduct => {
  const { productSelectedItem, productItemsWithoutSelected } =
    useReduceProduct(productContext)

  const productWithSortedSellers = useMemo<MaybeProduct>(() => {
    if (
      productContext.product &&
      productSelectedItem &&
      productItemsWithoutSelected
    ) {
      return {
        ...productContext.product,
        items: [
          ...productItemsWithoutSelected,
          { ...productSelectedItem, sellers: [...sellers] },
        ],
      }
    }

    return undefined
  }, [
    productContext.product,
    productSelectedItem,
    productItemsWithoutSelected,
    sellers,
  ])

  const newProduct = useMemo(() => {
    return productWithSortedSellers ?? productContext.product
  }, [productContext.product, productWithSortedSellers])

  return newProduct
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/hooks/useSellerLogisticsInfo.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { ShippingQuote } from 'vtex.seller-selector/react/SellerContext'
import { useLazyQuery } from 'react-apollo'
import { useRuntime } from 'vtex.render-runtime'
import { useEffect, useMemo } from 'react'
import { OrderForm } from 'vtex.order-manager'
import { useProduct } from 'vtex.product-context'

import SimulateShippingQuery from '../graphql/SimulateShipping.gql'
import type { LogisticsInfo, SellerLogisticsInfoResult } from '../typings/types'
import { getAvailableSellers } from '../utils'

export const useSellerLogisticsInfo = (): SellerLogisticsInfoResult[] => {
  const { selectedItem, selectedQuantity } = useProduct() ?? {}
  const orderFormContext = OrderForm?.useOrderForm() ?? {}

  const [updateShippingQuotes, { data: shippingData, error }] = useLazyQuery<{
    shipping: ShippingQuote
  }>(SimulateShippingQuery)

  const availableSellers = useMemo(
    () => getAvailableSellers(selectedItem?.sellers),
    [selectedItem]
  )

  const shippingItems = useMemo(
    () =>
      availableSellers.map((current) => ({
        id: selectedItem?.itemId,
        quantity: selectedQuantity?.toString() ?? '1',
        seller: current.sellerId,
      })),
    [selectedItem?.itemId, availableSellers, selectedQuantity]
  )

  const runtime = useRuntime()
  const {
    culture: { country },
  } = runtime

  const variables = useMemo(() => {
    return {
      shippingItems,
      country,
      postalCode:
        orderFormContext.orderForm?.shipping?.selectedAddress?.postalCode ?? '',
    }
  }, [
    country,
    orderFormContext.orderForm?.shipping?.selectedAddress?.postalCode,
    shippingItems,
  ])

  const logisticsInfo = useMemo(
    () =>
      shippingData?.shipping.logisticsInfo?.reduce(
        (acummulator, currentValue) => {
          acummulator[currentValue.itemIndex] = currentValue

          return acummulator
        },
        {} as { [key in string]: LogisticsInfo }
      ),
    [shippingData?.shipping.logisticsInfo]
  )

  useEffect(() => {
    updateShippingQuotes({ variables: { ...variables } })
  }, [updateShippingQuotes, variables])

  if (availableSellers && logisticsInfo) {
    return availableSellers.map((seller, index) => {
      return {
        seller,
        logisticsInfo: logisticsInfo[index],
      }
    })
  }

  if (availableSellers && error) {
    return availableSellers.map((seller) => {
      return {
        seller,
        logisticsInfo: undefined,
      }
    })
  }

  return []
}

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/utils/index.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { getAvailableSellers } from '../../utils'

describe('getAvailableSellers', () => {
  const sellers = [
    {
      sellerId: '1',
      sellerName: 'SELLER NAME 1',
      sellerDefault: false,
      addToCartLink: '',
      commertialOffer: {
        discountHighlights: [],
        teasers: [],
        Price: 280.5,
        ListPrice: 280.5,
        Tax: 0,
        taxPercentage: 0,
        spotPrice: 280.5,
        PriceWithoutDiscount: 280.5,
        RewardValue: 0,
        PriceValidUntil: '2022-08-25T13:35:42Z',
        AvailableQuantity: 6000,
        CacheVersionUsedToCallCheckout: 'B2D78F230C87C13044F23B4A0F4BA986_',
        Installments: [],
      },
    },
    {
      sellerId: '2',
      sellerName: 'SELLER NAME 2',
      sellerDefault: true,
      addToCartLink: '',
      commertialOffer: {
        discountHighlights: [],
        teasers: [],
        Price: 100,
        ListPrice: 100,
        Tax: 0,
        taxPercentage: 0,
        spotPrice: 100,
        PriceWithoutDiscount: 100,
        RewardValue: 0,
        PriceValidUntil: '2022-08-25T13:35:41Z',
        AvailableQuantity: 0,
        CacheVersionUsedToCallCheckout: 'B2D78F230C87C13044F23B4A0F4BA986_',
        Installments: [],
      },
    },
    {
      sellerId: '3',
      sellerName: 'SELLER NAME 3',
      sellerDefault: false,
      addToCartLink: '',
      commertialOffer: {
        discountHighlights: [],
        teasers: [],
        Price: 1,
        ListPrice: 1,
        Tax: 0,
        taxPercentage: 0,
        spotPrice: 1,
        PriceWithoutDiscount: 1,
        RewardValue: 0,
        PriceValidUntil: '2022-08-25T13:35:42Z',
        AvailableQuantity: 6000,
        CacheVersionUsedToCallCheckout: 'B2D78F230C87C13044F23B4A0F4BA986_',
        Installments: [],
      },
    },
    {
      sellerId: '4',
      sellerName: 'SELLER NAME 4',
      sellerDefault: true,
      addToCartLink: '',
      commertialOffer: {
        discountHighlights: [],
        teasers: [],
        Price: 25,
        ListPrice: 25,
        Tax: 0,
        taxPercentage: 0,
        spotPrice: 25,
        PriceWithoutDiscount: 25,
        RewardValue: 0,
        PriceValidUntil: '2022-08-25T13:35:41Z',
        AvailableQuantity: 992,
        CacheVersionUsedToCallCheckout: 'B2D78F230C87C13044F23B4A0F4BA986_',
        Installments: [],
      },
    },
    {
      sellerId: '5',
      sellerName: 'SELLER NAME 5',
      sellerDefault: false,
      addToCartLink: '',
      commertialOffer: {
        discountHighlights: [],
        teasers: [],
        Price: 15,
        ListPrice: 15,
        Tax: 0,
        taxPercentage: 0,
        spotPrice: 15,
        PriceWithoutDiscount: 15,
        RewardValue: 0,
        PriceValidUntil: '2022-08-25T13:35:42Z',
        AvailableQuantity: 0,
        CacheVersionUsedToCallCheckout: 'B2D78F230C87C13044F23B4A0F4BA986_',
        Installments: [],
      },
    },
    {
      sellerId: '6',
      sellerName: 'SELLER NAME 6',
      sellerDefault: true,
      addToCartLink: '',
      commertialOffer: {
        discountHighlights: [],
        teasers: [],
        Price: 80,
        ListPrice: 80,
        Tax: 0,
        taxPercentage: 0,
        spotPrice: 80,
        PriceWithoutDiscount: 80,
        RewardValue: 0,
        PriceValidUntil: '2022-08-25T13:35:41Z',
        AvailableQuantity: 0,
        CacheVersionUsedToCallCheckout: 'B2D78F230C87C13044F23B4A0F4BA986_',
        Installments: [],
      },
    },
  ]

  it('should return an array with available sellers', () => {
    // act
    const availableSellers = getAvailableSellers(sellers)

    // assert
    expect(
      availableSellers.map((seller) => seller.commertialOffer.AvailableQuantity)
    ).toBeTruthy()
  })

  it('should return an empty array', () => {
    // act
    const availableSellers = getAvailableSellers(undefined)

    // assert
    expect(availableSellers).toStrictEqual([])
  })

  it('should return an empty array when all sellers are unavailable', () => {
    // arrange
    const unavailables = sellers.filter(
      (seller) => seller.commertialOffer.AvailableQuantity === 0
    )

    // act
    const availableSellers = getAvailableSellers(unavailables)

    // assert
    expect(availableSellers).toStrictEqual([])
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/utils/sortSellers.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import type { SellerLogisticsInfoResult } from '../../typings/types'
import {
  sortSellersByCustomExpression,
  sortSellersByPrice,
  sortSellersByPriceShipping,
} from '../../utils/sortSellers'
// eslint-disable-next-line jest/no-mocks-import
import {
  unsortedSellersMock,
  unsortedSellersShippingMock,
  sortedSellerLogisticsInfoMock,
  unsortedSellerLogisticsInfoMock,
} from '../../__mocks__/sellers'

describe('sortSellersByPrice', () => {
  it('should sort sellers correctly', () => {
    // arrange
    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersMock

    const expected: SellerLogisticsInfoResult[] = [
      seller3,
      seller5,
      seller4,
      seller6,
      seller2,
      seller1,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] = unsortedSellersMock

    // act
    const sortedSellers = sortSellersByPrice(unsortedSellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should mantain sellers sort', () => {
    // arrange
    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersMock

    const expected: SellerLogisticsInfoResult[] = [
      seller3,
      seller5,
      seller4,
      seller6,
      seller2,
      seller1,
    ]

    const sellers: SellerLogisticsInfoResult[] = [...expected]

    // act
    const sortedSellers = sortSellersByPrice(sellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should return a array empty', () => {
    // arrange
    const expected: SellerLogisticsInfoResult[] = []
    const unsortedSellers: SellerLogisticsInfoResult[] = []

    // act
    const sortedSellers = sortSellersByPrice(unsortedSellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })
})

describe('sortSellersByPriceShipping', () => {
  it('should sort sellers correctly', () => {
    // arrange
    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByPriceShipping(unsortedSellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should mantain sellers sort', () => {
    // arrange
    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const sellers: SellerLogisticsInfoResult[] = [...expected]

    // act
    const sortedSellers = sortSellersByPriceShipping(sellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should set seller to last position when have not SLA', () => {
    // arrange
    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const hasSLA: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
    ]

    const hasNotSLA: SellerLogisticsInfoResult[] = [seller3, seller4]

    // act
    const sortedSellers = sortSellersByPriceShipping(
      unsortedSellersShippingMock
    )

    // assert
    const SLAs = sortedSellers.filter(
      (seller) => seller.logisticsInfo?.slas.length
    )

    expect(SLAs).toStrictEqual(hasSLA)
    expect(sortedSellers.splice(SLAs.length)).toStrictEqual(hasNotSLA)
  })

  it('should return a array empty', () => {
    // arrange
    const expected: SellerLogisticsInfoResult[] = []
    const unsortedSellers: SellerLogisticsInfoResult[] = []

    // act
    const sortedSellers = sortSellersByPrice(unsortedSellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })
})

describe('sortSellersByCustomExpression', () => {
  it('should sort sellers correctly with expression productPrice + minShippingPrice', () => {
    // arrange
    const expression = 'productPrice + minShippingPrice'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should sort sellers correctly with expression productPrice + maxShippingPrice', () => {
    // arrange
    const expression = 'productPrice + maxShippingPrice'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller6,
      seller5,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should sort sellers correctly with expression productSpotPrice + minShippingPrice', () => {
    // arrange
    const expression = 'productSpotPrice + minShippingPrice'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should sort sellers correctly with expression productAvailableQuantity < 1000', () => {
    // arrange
    const expression = 'productAvailableQuantity < 1000'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller1,
      seller3,
      seller5,
      seller2,
      seller4,
      seller6,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should sort sellers correctly with expression minShippingEstimate', () => {
    // arrange
    const expression = 'minShippingEstimate'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller6,
      seller5,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should sort sellers correctly with expression maxShippingEstimate', () => {
    // arrange
    const expression = 'maxShippingEstimate'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller5,
      seller2,
      seller1,
      seller6,
      seller3,
      seller4,
    ]

    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should mantain sellers sort', () => {
    // arrange
    const expression = 'productPrice + minShippingPrice'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const expected: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
      seller3,
      seller4,
    ]

    const sellers: SellerLogisticsInfoResult[] = [...expected]

    // act
    const sortedSellers = sortSellersByCustomExpression(sellers, expression)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should set seller to last position when have not SLA', () => {
    // arrange
    const expression = 'productPrice + minShippingPrice'

    const [seller1, seller2, seller3, seller4, seller5, seller6] =
      unsortedSellersShippingMock

    const hasSLA: SellerLogisticsInfoResult[] = [
      seller5,
      seller6,
      seller2,
      seller1,
    ]

    const hasNotSLA: SellerLogisticsInfoResult[] = [seller3, seller4]

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellersShippingMock,
      expression
    )

    // assert
    const SLAs = sortedSellers.filter(
      (seller) => seller.logisticsInfo?.slas.length
    )

    expect(SLAs).toStrictEqual(hasSLA)
    expect(sortedSellers.splice(SLAs.length)).toStrictEqual(hasNotSLA)
  })

  it('should return a array empty', () => {
    // arrange
    const expected: SellerLogisticsInfoResult[] = []
    const unsortedSellers: SellerLogisticsInfoResult[] = []

    // act
    const sortedSellers = sortSellersByCustomExpression(unsortedSellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should return a same array unsorted when expression is empty', () => {
    // arrange
    const expected: SellerLogisticsInfoResult[] = unsortedSellersShippingMock
    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(unsortedSellers)

    // assert
    expect(sortedSellers).toStrictEqual(expected)
  })

  it('should return a same array unsorted when expression is wrong', () => {
    // arrange
    const expression = 'wrongWord1 + wrongWord2'

    jest.spyOn(console, 'error').mockImplementation()

    const expected: SellerLogisticsInfoResult[] = unsortedSellersShippingMock
    const unsortedSellers: SellerLogisticsInfoResult[] =
      unsortedSellersShippingMock

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellers,
      expression
    )

    // assert
    expect(sortedSellers).toStrictEqual(expected)
    expect(console.error).toBeCalledTimes(1)
  })

  it('should sort by SLA correctly when the price is of SLA is 0.00 and shipping estimate is bigger', () => {
    // arrange
    const expression = 'minShippingEstimate * 100000 + maxShippingPrice'

    // act
    const sortedSellers = sortSellersByCustomExpression(
      unsortedSellerLogisticsInfoMock,
      expression
    )

    // assert
    const SLAs = sortedSellers
      .filter((seller) => seller.logisticsInfo?.slas.length)
      .map((sla, index) => {
        return {
          ...sla,
          seller: {
            ...sla.seller,
            sellerDefault: index === 0,
          },
        }
      })

    expect(SLAs).toEqual(sortedSellerLogisticsInfoMock)
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/utils/shippingEstimate.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import {
  compare,
  evaluateShippingEstimate,
  splitShippingEstimate,
  UnitTime,
  UnitTimeWeight,
} from '../../utils/shippingEstimate'

describe('evaluateShippingEstimate', () => {
  it('should be return business days weight correctly', () => {
    // arrange
    const shippingEstimate = '8bd'

    // act
    const result = evaluateShippingEstimate(shippingEstimate)

    // assert
    expect(result).toEqual(8 * UnitTimeWeight.bd)
  })
  it('should be return days weight correctly', () => {
    // arrange
    const shippingEstimate = '1d'

    // act
    const result = evaluateShippingEstimate(shippingEstimate)

    // assert
    expect(result).toEqual(1 * UnitTimeWeight.d)
  })
  it('should be return hours weight correctly', () => {
    // arrange
    const shippingEstimate = '2h'

    // act
    const result = evaluateShippingEstimate(shippingEstimate)

    // assert
    expect(result).toEqual(2 * UnitTimeWeight.h)
  })
  it('should be return minutes weight correctly', () => {
    // arrange
    const shippingEstimate = '30m'

    // act
    const result = evaluateShippingEstimate(shippingEstimate)

    // assert
    expect(result).toEqual(30 * UnitTimeWeight.m)
  })
})

describe('splitShippingEstimate', () => {
  it('should be return business days correctly', () => {
    // arrange
    const shippingEstimate = '8bd'

    // act
    const { timeAmount, unitTime } = splitShippingEstimate(shippingEstimate)

    // assert
    expect(timeAmount).toEqual(8)
    expect(UnitTime[unitTime]).toEqual(UnitTime.bd)
  })

  it('should be return days correctly', () => {
    // arrange
    const shippingEstimate = '1d'

    // act
    const { timeAmount, unitTime } = splitShippingEstimate(shippingEstimate)

    // assert
    expect(timeAmount).toEqual(1)
    expect(UnitTime[unitTime]).toEqual(UnitTime.d)
  })

  it('should be return hours correctly', () => {
    // arrange
    const shippingEstimate = '2h'

    // act
    const { timeAmount, unitTime } = splitShippingEstimate(shippingEstimate)

    // assert
    expect(timeAmount).toEqual(2)
    expect(UnitTime[unitTime]).toEqual(UnitTime.h)
  })
  it('should be return minutes correctly', () => {
    // arrange
    const shippingEstimate = '30m'

    // act
    const { timeAmount, unitTime } = splitShippingEstimate(shippingEstimate)

    // assert
    expect(timeAmount).toEqual(30)
    expect(UnitTime[unitTime]).toEqual(UnitTime.m)
  })
})

describe('compare', () => {
  it('should be return 1 when the first value is greater', () => {
    // arrange
    const shippingEstimateA = '8bd'
    const shippingEstimateB = '7bd'

    // act
    const result = compare(shippingEstimateA, shippingEstimateB)

    // assert
    expect(result).toEqual(1)
  })

  it('should be return -1 when the first value is smaller', () => {
    // arrange
    const shippingEstimateA = '7bd'
    const shippingEstimateB = '8bd'

    // act
    const result = compare(shippingEstimateA, shippingEstimateB)

    // assert
    expect(result).toEqual(-1)
  })
  it('should be return 0 when two vales are equal', () => {
    // arrange
    const shippingEstimateA = '8bd'
    const shippingEstimateB = '8bd'

    // act
    const result = compare(shippingEstimateA, shippingEstimateB)

    // assert
    expect(result).toEqual(0)
  })

  it('should be return 1 when the first value is a work day', () => {
    // arrange
    const shippingEstimateA = '1bd'
    const shippingEstimateB = '1d'

    // act
    const result = compare(shippingEstimateA, shippingEstimateB)

    // assert
    expect(result).toEqual(1)
  })
  it('should be return 1 when the first value is a day', () => {
    // arrange
    const shippingEstimateA = '1d'
    const shippingEstimateB = '1h'

    // act
    const result = compare(shippingEstimateA, shippingEstimateB)

    // assert
    expect(result).toEqual(1)
  })
  it('should be return 1 when the first value is a hour', () => {
    // arrange
    const shippingEstimateA = '1h'
    const shippingEstimateB = '1m'

    // act
    const result = compare(shippingEstimateA, shippingEstimateB)

    // assert
    expect(result).toEqual(1)
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/hooks/useReduceSellerLogisticsInfo.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { renderHook } from '@vtex/test-tools/react'

import { useReduceSellerLogisticsInfo } from '../../hooks/useReduceSellerLogisticsInfo'
import type { SellerLogisticsInfoResult } from '../../typings/types'
// eslint-disable-next-line jest/no-mocks-import
import { unsortedSellersMock } from '../../__mocks__/sellers'

describe('useReduceSellerLogisticsInfo', () => {
  it('should return sellers and logistics info correctly', async () => {
    // arrange
    const sellerLogisticsInfo: SellerLogisticsInfoResult[] = unsortedSellersMock

    // act
    const {
      result: {
        current: { sellers, logisticsInfo },
      },
    } = renderHook(() =>
      useReduceSellerLogisticsInfo({
        sellerLogisticsInfo,
      })
    )

    // assert
    expect(sellerLogisticsInfo.map((s) => s.seller)).toStrictEqual(sellers)
    expect(sellerLogisticsInfo.map((s) => s.logisticsInfo)).toStrictEqual(
      logisticsInfo
    )
  })

  it('should return first seller as default', async () => {
    // arrange
    const sellerLogisticsInfo: SellerLogisticsInfoResult[] = unsortedSellersMock

    // act
    const {
      result: {
        current: { sellers },
      },
    } = renderHook(() =>
      useReduceSellerLogisticsInfo({
        sellerLogisticsInfo,
      })
    )

    // assert
    expect(sellers[0].sellerDefault).toBeTruthy()
    expect(
      sellers.slice(1, sellers.length).some((s) => s.sellerDefault)
    ).toBeFalsy()
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/hooks/useSellerLogisticsInfo.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { renderHook } from '@vtex/test-tools/react'
import { OrderForm } from 'vtex.order-manager'
import * as productContext from 'vtex.product-context'
import * as reactapollo from 'react-apollo'

import { useSellerLogisticsInfo } from '../../hooks/useSellerLogisticsInfo'
// eslint-disable-next-line jest/no-mocks-import
import { productContextState } from '../../__mocks__/productContext'

describe('useNewProductWithSellers', () => {
  jest
    .spyOn(productContext, 'useProduct')
    .mockImplementation(() => productContextState)

  jest.spyOn(OrderForm, 'useOrderForm').mockImplementation(() => {
    return {
      orderForm: {
        shipping: {
          selectedAddress: {
            postalCode: '',
          },
        },
      },
    }
  })

  it('should return an empty array when logistics info does not exists', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useLazyQuery')
      .mockImplementation()
      .mockReturnValue([
        jest.fn(),
        {
          data: { shipping: {} },
          refetch: jest.fn(),
        },
      ] as any)

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellerLogisticsInfo())

    // assert
    expect(sellersInfoResult).toStrictEqual([])
  })

  it('should return correctly when logistics info exists', async () => {
    // arrange
    const shippingData = {
      shipping: {
        logisticsInfo: [
          {
            itemIndex: '0',
            slas: [
              {
                id: 'Transportadora1',
                name: 'Transportadora1',
                price: 3520,
              },
              {
                id: 'Transportadora2',
                name: 'Transportadora2',
                price: 3520,
              },
            ],
          },
        ],
      },
    }

    jest
      .spyOn(reactapollo, 'useLazyQuery')
      .mockImplementation()
      .mockReturnValue([
        jest.fn(),
        {
          data: { ...shippingData },
          refetch: jest.fn(),
        },
      ] as any)

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellerLogisticsInfo())

    // assert
    expect(sellersInfoResult[0].seller).toStrictEqual(
      productContextState.selectedItem?.sellers[0]
    )
    expect(sellersInfoResult[0].logisticsInfo).toStrictEqual(
      shippingData.shipping.logisticsInfo[0]
    )
    expect(sellersInfoResult[1].seller).toStrictEqual(
      productContextState.selectedItem?.sellers[1]
    )
    expect(sellersInfoResult[1].logisticsInfo).toStrictEqual(
      shippingData.shipping.logisticsInfo[1]
    )
  })

  it('should return correctly when got error to find logistcInfo', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useLazyQuery')
      .mockImplementation()
      .mockReturnValue([
        jest.fn(),
        {
          error: new Error(),
          refetch: jest.fn(),
        },
      ] as any)

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellerLogisticsInfo())

    // assert
    expect(sellersInfoResult[0].seller).toStrictEqual(
      productContextState.selectedItem?.sellers[0]
    )
    expect(sellersInfoResult[0].logisticsInfo).toBeUndefined()
    expect(sellersInfoResult[1].seller).toStrictEqual(
      productContextState.selectedItem?.sellers[1]
    )
    expect(sellersInfoResult[1].logisticsInfo).toBeUndefined()
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/hooks/useReduceProduct.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { renderHook, waitFor, cleanup } from '@vtex/test-tools/react'

import { useReduceProduct } from '../../hooks/useReduceProduct'
// eslint-disable-next-line jest/no-mocks-import
import { productContextState } from '../../__mocks__/productContext'

describe('sortSellersByPrice', () => {
  beforeEach(() => {
    cleanup()
  })

  it('should return items without selectedItem', async () => {
    // arrange
    const { selectedItem } = { ...productContextState }

    // act
    const {
      result: {
        current: { productItemsWithoutSelected },
      },
    } = renderHook(() => useReduceProduct({ ...productContextState }))

    // assert

    await waitFor(() =>
      expect(
        productItemsWithoutSelected.find(
          (item) => item.itemId === selectedItem?.itemId
        )
      ).toBeFalsy()
    )
  })

  it('should return selectedItem correctly', async () => {
    // arrange
    const { selectedItem } = { ...productContextState }

    // act
    const {
      result: {
        current: { productSelectedItem },
      },
    } = renderHook(() => useReduceProduct({ ...productContextState }))

    // assert

    await waitFor(() =>
      expect(productSelectedItem?.itemId).toBe(selectedItem?.itemId)
    )
  })

  it('should return selectedItem empty', async () => {
    // arrange
    const state = { ...productContextState, selectedItem: undefined }

    // act
    const {
      result: {
        current: { productSelectedItem },
      },
    } = renderHook(() => useReduceProduct(state))

    // assert
    await waitFor(() => expect(productSelectedItem).toBeFalsy())
  })

  it('should return productItemsWithoutSelected with all items', async () => {
    // arrange
    const state = { ...productContextState, selectedItem: undefined }

    // act
    const {
      result: {
        current: { productItemsWithoutSelected },
      },
    } = renderHook(() => useReduceProduct(state))

    // assert
    await waitFor(() =>
      expect(productItemsWithoutSelected).toStrictEqual(
        productContextState.product?.items
      )
    )
  })

  it('should return initial values', async () => {
    // arrange
    const initialValue = {
      productItemsWithoutSelected: [],
      productSelectedItem: undefined,
    }

    // act
    const {
      result: { current },
    } = renderHook(() =>
      useReduceProduct({ ...productContextState, product: undefined })
    )

    // assert
    await waitFor(() => expect(current).toStrictEqual(initialValue))
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/hooks/useSellersByProtocol.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { renderHook } from '@vtex/test-tools/react'
import * as reactapollo from 'react-apollo'

import { useSellersByProtocol } from '../../hooks/useSellersByProtocol'
import type { SellerLogisticsInfoResult } from '../../typings/types'
// eslint-disable-next-line jest/no-mocks-import
import { unsortedSellersMock } from '../../__mocks__/sellers'

describe('useSellersByProtocol', () => {
  it('should return an array with ordered sellers by protocol', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useQuery')
      .mockImplementation()
      .mockReturnValue({
        data: {
          sortSellers: {
            sellers: ['3', '1', '4', '2', '5'],
          },
        },
      } as any)

    const sellerLogisticsInfo: SellerLogisticsInfoResult[] = unsortedSellersMock

    const [seller1, seller2, seller3, seller4, seller5] = unsortedSellersMock

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellersByProtocol(sellerLogisticsInfo))

    // assert
    expect(sellersInfoResult).toStrictEqual([
      seller3,
      seller1,
      seller4,
      seller2,
      seller5,
    ])
  })

  it('should return an empty array when loading is true', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useQuery')
      .mockImplementation()
      .mockReturnValue({
        data: {
          sortSellers: {
            sellers: ['3', '1', '4', '2', '5'],
          },
        },
        loading: true,
      } as any)

    const sellerLogisticsInfo: SellerLogisticsInfoResult[] = unsortedSellersMock

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellersByProtocol(sellerLogisticsInfo))

    // assert
    expect(sellersInfoResult).toStrictEqual([])
  })

  it('should return an empty array when data is empty', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useQuery')
      .mockImplementation()
      .mockReturnValue({
        data: {},
      } as any)

    const sellerLogisticsInfo: SellerLogisticsInfoResult[] = unsortedSellersMock

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellersByProtocol(sellerLogisticsInfo))

    // assert
    expect(sellersInfoResult).toStrictEqual([])
  })

  it('should return an empty array when sellersInfo parameter is empty', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useQuery')
      .mockImplementation()
      .mockReturnValue({
        data: {
          sortSellers: {
            sellers: ['3', '1', '4', '2', '5'],
          },
        },
        loading: true,
      } as any)

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellersByProtocol([]))

    // assert
    expect(sellersInfoResult).toStrictEqual([])
  })

  it('should return an array without sellers that do not exists on sellerLogisticsInfo', async () => {
    // arrange
    jest
      .spyOn(reactapollo, 'useQuery')
      .mockImplementation()
      .mockReturnValue({
        data: {
          sortSellers: {
            sellers: ['10', '20', '3', '1', '4', '2', '5'],
          },
        },
      } as any)

    const sellerLogisticsInfo: SellerLogisticsInfoResult[] = unsortedSellersMock

    const [seller1, seller2, seller3, seller4, seller5] = unsortedSellersMock

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellersByProtocol(sellerLogisticsInfo))

    // assert
    expect(sellersInfoResult).toStrictEqual([
      seller3,
      seller1,
      seller4,
      seller2,
      seller5,
    ])
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/hooks/useNewProductWithSellers.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { renderHook } from '@vtex/test-tools/react'
import type { ProductContextState } from 'vtex.product-context/react/ProductContextProvider'

import { useNewProductWithSellers } from '../../hooks/useNewProductWithSellers'
import type { Seller } from '../../typings/types'
// eslint-disable-next-line jest/no-mocks-import
import { productContextState } from '../../__mocks__/productContext'
// eslint-disable-next-line jest/no-mocks-import
import { unsortedSellersMock } from '../../__mocks__/sellers'

describe('useNewProductWithSellers', () => {
  it('should return new product with sellers ordered', async () => {
    // arrange
    const productContext: Partial<ProductContextState> = productContextState
    const sellers: Seller[] = [unsortedSellersMock[0].seller]

    // act
    const {
      result: { current: newProduct },
    } = renderHook(() =>
      useNewProductWithSellers({
        productContext,
        sellers,
      })
    )

    // assert
    expect(productContext.selectedItem?.sellers).not.toStrictEqual(sellers)
    expect(newProduct?.items[0].sellers).toStrictEqual(sellers)
  })
})

```


[System] You are an expert VTEX IO developer. You specialize in building VTEX Store Framework apps, React components, GraphQL APIs, and Node.js services for e-commerce platforms.

[User] Show me the implementation of buybox-context/react/__tests__/hooks/useSellerLoginstcsInfoSellerSelector.test.ts from the buybox-context VTEX app.

[Assistant]
Here's the implementation:

```typescript
import { renderHook } from '@vtex/test-tools/react'
import * as productContext from 'vtex.product-context'
import { SellerContext } from 'vtex.seller-selector'

import { useSellerLoginstcsInfoSellerSelector } from '../../hooks/useSellerLoginstcsInfoSellerSelector'
import type { LogisticsInfo } from '../../typings/types'
// eslint-disable-next-line jest/no-mocks-import
import { productContextState } from '../../__mocks__/productContext'

describe('useSellerLoginstcsInfoSellerSelector', () => {
  it('should return sellers and logistics info correctly', async () => {
    // arrange
    const shippingQuotes = {
      sellerList: null,
      shippingQuotes: {
        logisticsInfo: [
          { itemIndex: 0, slas: [] },
          {
            itemIndex: 1,
            slas: [
              {
                id: '1',
                name: 'logistic name 1',
                price: 4000,
                shippingEstimate: '3d',
                shippingEstimateDate: '',
              },
              {
                id: '2',
                name: 'logistic name 2',
                price: 9000,
                shippingEstimate: '1h',
                shippingEstimateDate: '',
              },
            ],
          },
        ] as LogisticsInfo[],
      },
      setShippingQuotes: jest.fn(),
      limitShownShippingInformation: 0,
    }

    jest
      .spyOn(productContext, 'useProduct')
      .mockImplementation(() => productContextState)

    jest
      .spyOn(SellerContext, 'useSellerContext')
      .mockImplementation(() => shippingQuotes)

    // act
    const {
      result: { current: sellersInfoResult },
    } = renderHook(() => useSellerLoginstcsInfoSellerSelector())

    // assert
    expect(sellersInfoResult[0].seller).toStrictEqual(
      productContextState.selectedItem?.sellers[0]
    )
    expect(sellersInfoResult[0].logisticsInfo).toStrictEqual(
      shippingQuotes.shippingQuotes.logisticsInfo[0]
    )
    expect(sellersInfoResult[1].seller).toStrictEqual(
      productContextState.selectedItem?.sellers[1]
    )
    expect(sellersInfoResult[1].logisticsInfo).toStrictEqual(
      shippingQuotes.shippingQuotes.logisticsInfo[1]
    )
  })
})

```