Merge branch 'master' into develop
This commit is contained in:
29
README.md
29
README.md
@@ -6,6 +6,17 @@
|
||||
<h1 align="center">
|
||||
Medusa
|
||||
</h1>
|
||||
|
||||
<h4 align="center">
|
||||
<a href="https://www.medusa-commerce.com">Website</a> |
|
||||
<a href="https://roadmap.medusa-commerce.com">Roadmap</a> |
|
||||
<a href="https://www.medusa-commerce.com/blog">Blog</a> |
|
||||
<a href="https://www.linkedin.com/company/medusa-commerce">LinkedIn</a> |
|
||||
<a href="https://twitter.com/medusajs">Twitter</a> |
|
||||
<a href="https://docs.medusa-commerce.com">Documentation</a> |
|
||||
<a href="https://medusajs.notion.site/medusajs/Medusa-Home-3485f8605d834a07949b17d1a9f7eafd">Notion</a>
|
||||
</h4>
|
||||
|
||||
<p align="center">
|
||||
Medusa is an open-source headless commerce engine that enables developers to create amazing digital commerce experiences.
|
||||
</p>
|
||||
@@ -105,21 +116,3 @@ The Medusa repository is a mono-repository managed using Lerna. Lerna allows us
|
||||
Licensed under the [MIT License](https://github.com/medusajs/medusa/blob/master/LICENSE)
|
||||
|
||||
## Thank you!
|
||||
|
||||
<p>
|
||||
<a href="https://www.medusa-commerce.com">
|
||||
Website
|
||||
</a>
|
||||
|
|
||||
<a href="https://medusajs.notion.site/medusajs/Medusa-Home-3485f8605d834a07949b17d1a9f7eafd">
|
||||
Notion Home
|
||||
</a>
|
||||
|
|
||||
<a href="https://twitter.com/intent/follow?screen_name=medusajs">
|
||||
Twitter
|
||||
</a>
|
||||
|
|
||||
<a href="https://docs.medusa-commerce.com">
|
||||
Docs
|
||||
</a>
|
||||
</p>
|
||||
|
||||
121
docs/content/how-to/deploying-on-qovery.md
Normal file
121
docs/content/how-to/deploying-on-qovery.md
Normal file
@@ -0,0 +1,121 @@
|
||||
# Deploying on Qovery
|
||||
|
||||
This is a guide for deploying a Medusa project to Qovery. Qovery is a Continuous Deployment Platform, that provides you with the developer experience of Heroku on top of your cloud provider (e.g. AWS, DigitalOcean).
|
||||
|
||||
> We assume, that you are currently running a local instance of Medusa. If not, check out our [Quickstart](https://docs.medusa-commerce.com/quickstart/quick-start) or use `npx create-medusa-app` to set up your application in a matter of minutes. For the latter, see [this guide](https://docs.medusa-commerce.com/how-to/create-medusa-app) for a small walkthrough.
|
||||
|
||||
### 1. Qovery Console
|
||||
|
||||
Create an account on [Qovery](https://www.qovery.com/) on their free community plan and jump into the console.
|
||||
|
||||
### 2. Setup
|
||||
|
||||
Create a project and an environment.
|
||||
|
||||
### 3. Add your Medusa app
|
||||
|
||||
Add a new app to your Qovery environment and connect the Git repository that holds your Medusa project. In your application settings, set the port to 9000 unless something else is specified in your setup.
|
||||
|
||||
> If you used our `npx` starter, your repository will most likely hold all components; storefront, admin and backend. Ensure that **Root application path** in Qovery is pointing to your Medusa project (`/backend`).
|
||||
|
||||
### 4. Add a database
|
||||
|
||||
Navigate to your environment overview and add the databases required by Medusa.
|
||||
|
||||
- Add Postgres database version 10, 11 or 12
|
||||
- Add Redis database version 5 or 6
|
||||
|
||||
### 5. Configure Medusa
|
||||
|
||||
Our Medusa project needs a bit of configuration to fit the needs of Qovery.
|
||||
|
||||
#### Update `medusa-config.js`
|
||||
|
||||
First, add the Postgres and Redis database url to your `medusa-config.js`. In Qovery, click on your Medusa app in the environment overview. Navigate to environment variables in the sidebar on the left. Among the secret variables you should find your database urls. They should look something like this:
|
||||
|
||||
```javascript=
|
||||
QOVERY_REDIS_123456789_DATABASE_URL
|
||||
QOVERY_POSTGRESQL_123456789_DATABASE_URL
|
||||
```
|
||||
|
||||
Add these to your `medusa-config.js`.
|
||||
|
||||
```javascript=
|
||||
const DATABASE_URL = process.env.QOVERY_POSTGRESQL_123456789_DATABASE_URL
|
||||
const REDIS_URL= process.env.QOVERY_REDIS_123456789_DATABASE_URL
|
||||
```
|
||||
|
||||
Furthermore, update `module.exports` to include the following:
|
||||
|
||||
```javascript=
|
||||
module.exports = {
|
||||
projectConfig: {
|
||||
redis_url: REDIS_URL,
|
||||
database_url: DATABASE_URL,
|
||||
database_type: "postgres",
|
||||
store_cors: STORE_CORS,
|
||||
admin_cors: ADMIN_CORS,
|
||||
database_extra: { }
|
||||
},
|
||||
plugins,
|
||||
};
|
||||
```
|
||||
|
||||
> **IMPORTANT**: We are using the Qovery community plan, that does not allow SSL connections for the database, so this is disabled.
|
||||
>
|
||||
> In a production environment, you would need the following in the config:
|
||||
> `database_extra: { ssl: { rejectUnauthorized: false } }`
|
||||
|
||||
#### Add some extra variables
|
||||
|
||||
We need to add a couple of more environment variables in Qovery. Add the following variables in your Console with an application scope:
|
||||
|
||||
```javascript=
|
||||
JTW_SECRET=something_secret_jwt
|
||||
COOKIE_SECRET=something_secret_cookie
|
||||
```
|
||||
|
||||
> Make sure to use actual secrets in a production environment.
|
||||
|
||||
#### Update `package.json`
|
||||
|
||||
Update `scripts` to the following:
|
||||
|
||||
```json=
|
||||
"scripts": {
|
||||
"serve": "medusa start",
|
||||
"start": "medusa migrations run && medusa start",
|
||||
"prepare": "npm run build",
|
||||
"build": "babel src -d dist --extensions \".ts,.js\""
|
||||
},
|
||||
```
|
||||
|
||||
### 6. Deploy Medusa
|
||||
|
||||
Finally, deploy your Redis and Postgres followed by your Medusa application.
|
||||
|
||||
#### Deploy databases
|
||||
In your environment overview in Qovery, deploy your databases one after the other. Only when these are deployed, proceed to next step.
|
||||
|
||||
#### Push changes to your repository
|
||||
|
||||
To initialise your first build Qovery, simply commit and push your changes.
|
||||
|
||||
```shell=
|
||||
git add .
|
||||
git commit -m "chore: Qovery setup"
|
||||
git push origin main
|
||||
```
|
||||
|
||||
### 6. Try it out!
|
||||
|
||||
In Qovery, click on your Medusa app in the environment overview. In the top right you are able to open up your application. Navigate to `/health` to ensure, that the app is running.
|
||||
|
||||
### What's next?
|
||||
|
||||
You now have an application running on Qovery. This can be scaled and configured to fit your business needs. As mentioned, we used the community plan, so this should be upgraded when moving to production.
|
||||
|
||||
Furthermore, you can deploy Medusa Admin for your application, such that you can start managing your store from an interface.
|
||||
|
||||
- [Deploy Admin on Netlify](https://docs.medusa-commerce.com/how-to/deploying-admin-on-netlify)
|
||||
- Deploy Admin on Gatsby Cloud (Coming soon)
|
||||
@@ -0,0 +1,304 @@
|
||||
---
|
||||
title: Making your store more powerful with Contentful
|
||||
---
|
||||
|
||||
# Making your store more powerful with Contentful
|
||||
|
||||
In [part 1](https://docs.medusa-commerce.com/how-to/headless-ecommerce-store-with-gatsby-contentful-medusa/) of this series you have set up [Medusa](https://medusa-commerce.com) with Contentful as your CMS system and added a Gatsby storefront. In this part you will get a further introduction to Contentful and learn how [`medusa-plugin-contentful`](https://github.com/medusajs/medusa/tree/master/packages/medusa-plugin-contentful) can be leveraged to make your store more powerful. Apart from a front page, product pages and a checkout flow, most ecommerce stores also need miscalleneous pages like About and Contact pages. In this guide you will add a Rich Text content module to your Contentful space so that you can make this pages cool. You will also see how the content modules can be used to give your product pages more life.
|
||||
|
||||
|
||||
What you will do in this guide:
|
||||
- Add a rich text content module
|
||||
- Add rich text to your `/about` page
|
||||
- Add a "Related Products" section to your product page
|
||||
|
||||
Topics covered:
|
||||
- Contentful Migrations
|
||||
- Product enrichment
|
||||
|
||||
## Creating a rich text content module
|
||||
In this guide you will make use of [Contentful Migrations](https://github.com/contentful/contentful-migration) to keep a versioned controlled record of how your Content evolves over time. The Contentful app allows you to create content models straight from their dashboard, however, when using the migrations tool you will be able to 1) quickly replicate your Contentful space and 2) incorporate migrations as part of a CI/CD pipeline. [You can read more about how to use CMS as Code here](https://www.contentful.com/help/cms-as-code/).
|
||||
|
||||
To prepare your migration create a new file at `contentful-migrations/rich-text.js` and add the following code:
|
||||
|
||||
```javascript
|
||||
// contentful-migrations/rich-text.js
|
||||
|
||||
module.exports = function (migration, context) {
|
||||
const richText = migration
|
||||
.createContentType("richText")
|
||||
.name("Rich Text")
|
||||
.displayField("title");
|
||||
|
||||
richText.createField("title").name("Title (Internal)").type("Symbol");
|
||||
richText.createField("body").name("Body").type("RichText");
|
||||
};
|
||||
```
|
||||
|
||||
This small snippet will create a content model in your Contentful space with two fields: a title which will be used to name entries in a meaningful manner (i.e. it won't be displayed to customers) and a body which contains the rich text to display. To apply your migration run:
|
||||
|
||||
```shell
|
||||
yarn migrate:contentful --file contentful-migrations/rich-text.js
|
||||
```
|
||||
|
||||
If you go to your Contentful space and click Content Model you will see that the Rich Text model has been added to your space:
|
||||

|
||||
|
||||
The validation rules in the Page model only allow Hero and Tile Sections to be added to the Content Modules fields so you will need another migration to make it possible for pages to make use of the new Rich Text modules. Create a new migration at `contentful-migrations/update-page-module-validation.js` and add the following:
|
||||
|
||||
```javascript
|
||||
// contentful-migrations/update-page-module-validation.js
|
||||
|
||||
module.exports = function (migration, context) {
|
||||
const page = migration.editContentType("page");
|
||||
|
||||
page.editField("contentModules").items({
|
||||
type: "Link",
|
||||
linkType: "Entry",
|
||||
validations: [
|
||||
{
|
||||
linkContentType: ["hero", "tileSection", "richText"],
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
After migrating your space you are ready create your new contact page:
|
||||
|
||||
```shell
|
||||
yarn migrate:contentful --file contentful-migrations/update-page-module-validation.js
|
||||
```
|
||||
|
||||
## Adding Rich Text to About
|
||||
|
||||
To use your new Rich Text module **Content > Page > About**, and click **Add Content > Page**. You will now make use of the new Rich Text module to add some more details about your store. You can write your own text or use the text provided below if you just want to copy/paste.
|
||||
|
||||
> ### About Medusa
|
||||
>
|
||||
> Medusa is an open-source headless commerce engine for fast-growing businesses. Getting started with Medusa is very easy and you will be able to start selling online with a basic setup in no time, however, the real power of Medusa starts showing up when you add custom functionality and extend your core to fit your needs.
|
||||
>
|
||||
> The core Medusa package and all the official Medusa plugins ship as individual NPM packages that you install into a Node project. You store and plugins are configured in your medusa-config.js file making it very easy to manage your store as your business grows. Custom functionality doesn't have to come from plugins, you can also add project-level functionality by simply adding files in your `src/` folder. Medusa will automatically register your custom functionalities in the bootstrap phase.
|
||||
|
||||

|
||||
|
||||
When you have added your text you can click **Publish changes** (make sure the About page is published too).
|
||||
|
||||
## Updating the storefront to support the Rich Text module
|
||||
|
||||
> If you want to jump straight to the final frontend code visit [medusajs/medusa-contentful-storefront@part-2](https://github.com/medusajs/medusa-contentful-storefront/tree/part-2).
|
||||
|
||||
To display your newly created Rich Text module open up the storefront code and create a new file at `src/components/rich-text/rich-text.jsx`.
|
||||
|
||||
```jsx
|
||||
// src/components/rich-text/rich-text.jsx
|
||||
|
||||
import React from "react"
|
||||
import { renderRichText } from "gatsby-source-contentful/rich-text"
|
||||
|
||||
import * as styles from "../../styles/rich-text.module.css"
|
||||
|
||||
const RichText = ({ data }) => {
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<div className={styles.content}>
|
||||
{data.body ? renderRichText(data.body) : ""}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default RichText
|
||||
```
|
||||
|
||||
The `renderRichText` function is imported from the `gatsby-source-contentful` plugin to easily transform the text you entered in the Rich Text module to html. To make the Rich Text component render nicely add a style file as well at `src/styles/rich-text.module.css`.
|
||||
|
||||
```css
|
||||
/* src/styles/rich-text.module.css */
|
||||
|
||||
.container {
|
||||
display: flex;
|
||||
padding-top: 100px;
|
||||
padding-bottom: 100px;
|
||||
}
|
||||
|
||||
.content {
|
||||
margin: auto;
|
||||
max-width: 870px;
|
||||
}
|
||||
```
|
||||
|
||||
If you restart your storefront server now you will not be able to see your new Rich Text module just yet. The last step to making that happen will be to let the Page component know to render the new Rich Text component when it encounters Rich Text in the Page's Content Modules. In your editor open up the file `src/pages/{ContentfulPage.slug}.js` and add the following:
|
||||
|
||||
At the top of the file import your `RichText` component:
|
||||
|
||||
```javascript
|
||||
...
|
||||
import RichText from "../components/rich-text/rich-text"
|
||||
...
|
||||
```
|
||||
|
||||
Now in the `contentModules.map` function return the `RichText` component whenever a `ContentfulRichText` module is encountered. Add a case to the switch statement:
|
||||
|
||||
```javascript
|
||||
case "ContentfulRichText":
|
||||
return <RichText key={cm.id} data={cm} />
|
||||
```
|
||||
|
||||
Finally you will need to fetch the Rich Text data from Gatsby's data layer by modifying the GraphQL code at the bottom of the file after the line with `contentModules {` add:
|
||||
|
||||
```graphql
|
||||
... on ContentfulRichText {
|
||||
id
|
||||
body {
|
||||
raw
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Restart your local Gatsby server and visit `http://localhost:8000/about`, you will now see the your newly added Rich Text module.
|
||||
|
||||

|
||||
|
||||
## Enriching your Product pages
|
||||
You have now seen how the Page model in Contentful can be extended to include a new content module in a reusable and modular manner. The same idea can be extended to your Product pages allowing you to create completely bespoke universes around your products. You will use the same techniques as above to create a Related Products section below the "Medusa Shirt" product.
|
||||
|
||||
### Migrating Products
|
||||
First, add a new field to the Product content model. Using migrations you can create a file `contentful-migrations/product-add-modules.js`:
|
||||
|
||||
```javascript
|
||||
// contentful-migrations/product-add-modules.js
|
||||
|
||||
module.exports = function (migration, context) {
|
||||
const product = migration.editContentType("product");
|
||||
|
||||
product
|
||||
.createField("contentModules")
|
||||
.name("Content Modules")
|
||||
.type("Array")
|
||||
.items({
|
||||
type: "Link",
|
||||
linkType: "Entry",
|
||||
validations: [
|
||||
{
|
||||
linkContentType: ["hero", "tileSection", "richText"],
|
||||
},
|
||||
],
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
Run the migration:
|
||||
```
|
||||
yarn migrate:contentful --file contentful-migrations/product-add-modules.js
|
||||
```
|
||||
|
||||
### Adding "Related Products" Tile Section
|
||||
After the migration you can now add Content Modules to Products, to enrich the Product pages with relevant content. In this guide you will add a Tile Section that holds "Related Products", but the functionality could be further extended to showcase look book images, inspirational content or more detailed product descriptions.
|
||||
|
||||
In Contentful go to **Content > Product > Medusa Shirt** scroll all the way to the bottom, where you should be able to find the new *Content Modules* field:
|
||||
|
||||

|
||||
|
||||
Click **Add content > Tile Section** which will open a new Tile Section. For the Title write "Related Products", and for Tiles click **Add content > Add existing content > Medusa Waterbottle > Insert 1 entry**.
|
||||
|
||||

|
||||
|
||||
|
||||
Click **Publish** and make sure that the Medusa Shirt product is published too.
|
||||
|
||||
Your data is now ready to be used in the storefront, but you still need to make a couple of changes to the storefront code to be able to view the new content.
|
||||
|
||||
## Adding Content Modules to Product pages
|
||||
Just like you did for the Page component, you will have to fetch the Content Modules from Gatsby's GraphQL data layer.
|
||||
|
||||
In the file `src/pages/products/{ContentfulProduct.handle}.js` add the following in the GraphQL query at the bottom of the file (e.g. after the variants query):
|
||||
|
||||
```graphql
|
||||
# src/pages/products/{ContentfulProduct.handle}.js
|
||||
|
||||
contentModules {
|
||||
... on ContentfulTileSection {
|
||||
id
|
||||
title
|
||||
tiles {
|
||||
... on ContentfulProduct {
|
||||
id
|
||||
title
|
||||
handle
|
||||
thumbnail {
|
||||
gatsbyImageData
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
... on ContentfulTile {
|
||||
id
|
||||
title
|
||||
cta
|
||||
image {
|
||||
gatsbyImageData
|
||||
}
|
||||
link {
|
||||
linkTo
|
||||
reference {
|
||||
slug
|
||||
}
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
internal {
|
||||
type
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
This snippet will query the Content Modules defined for the product and will allow you to use the data in your components.
|
||||
|
||||
|
||||
Next open up the `src/views/products.jsx` file and add the following snippets.
|
||||
|
||||
Import the `TileSection` component:
|
||||
```javascript
|
||||
import TileSection from "../components/tile-section/tile-section"
|
||||
```
|
||||
|
||||
|
||||
Add the Content Modules in the JSX just before the final closing `div`:
|
||||
|
||||
```jsx
|
||||
// src/views/products.jsx
|
||||
|
||||
<div className={styles.contentModules}>
|
||||
{product.contentModules?.map((cm) => {
|
||||
switch (cm.internal.type) {
|
||||
case "ContentfulTileSection":
|
||||
return <TileSection key={cm.id} data={cm} />
|
||||
default:
|
||||
return null
|
||||
}
|
||||
})}
|
||||
</div>
|
||||
```
|
||||
|
||||
Restart the Gatsby server and visit http://localhost:8000/product/medusa-shirt you should now see the new "Related Products" Tile Section below the Product page controls.
|
||||
|
||||

|
||||
|
||||
|
||||
## Summary
|
||||
In this guide you created a new content model for Rich Text input in Contentful using [contentful-migration](https://github.com/contentful/contentful-migration). You further extended the storefront to render the new Rich Text plugin. The concepts in this guide are meant to demonstrate how Contentful can be used to make your store more powerful in a modular and scalable way. The content modules covered in this guide could be further extended to add other custom modules, for example, you could add a Newsletter Signup, module that when encountered in the code renders a newsletter form.
|
||||
|
||||
## What's next
|
||||
In the next part of this guide you will learn how to implement further commerce functionalities to your site such as adding support for discount codes, region based shopping and more. (Coming soon)
|
||||
|
||||
- [Deploying Medusa on Heroku](https://docs.medusa-commerce.com/how-to/deploying-on-heroku)
|
||||
- [Deploying Medusa Admin on Netlify](https://docs.medusa-commerce.com/how-to/deploying-admin-on-netlify)
|
||||
@@ -135,6 +135,57 @@ describe("RestockNotificationService", () => {
|
||||
})
|
||||
|
||||
describe("triggerRestock", () => {
|
||||
afterEach(() => {
|
||||
jest.useRealTimers()
|
||||
})
|
||||
|
||||
it("trigger delay default to 0", async () => {
|
||||
const restockNotiService = new RestockNotificationService({
|
||||
manager: MockManager,
|
||||
productVariantService: ProductVariantService,
|
||||
restockNotificationModel: RestockNotificationModel,
|
||||
eventBusService: EventBusService,
|
||||
})
|
||||
|
||||
restockNotiService.restockExecute_ = jest.fn()
|
||||
|
||||
jest.clearAllMocks()
|
||||
jest.useFakeTimers()
|
||||
|
||||
restockNotiService.triggerRestock("variant_test")
|
||||
|
||||
jest.runAllTimers()
|
||||
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1)
|
||||
expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 0)
|
||||
})
|
||||
|
||||
it("trigger delay 10", async () => {
|
||||
const restockNotiService = new RestockNotificationService(
|
||||
{
|
||||
manager: MockManager,
|
||||
productVariantService: ProductVariantService,
|
||||
restockNotificationModel: RestockNotificationModel,
|
||||
eventBusService: EventBusService,
|
||||
},
|
||||
{ trigger_delay: 10 }
|
||||
)
|
||||
|
||||
restockNotiService.restockExecute_ = jest.fn()
|
||||
|
||||
jest.clearAllMocks()
|
||||
jest.useFakeTimers()
|
||||
|
||||
restockNotiService.triggerRestock("variant_test")
|
||||
|
||||
jest.runAllTimers()
|
||||
|
||||
expect(setTimeout).toHaveBeenCalledTimes(1)
|
||||
expect(setTimeout).toHaveBeenCalledWith(expect.any(Function), 10)
|
||||
})
|
||||
})
|
||||
|
||||
describe("restockExecute_", () => {
|
||||
const restockNotiService = new RestockNotificationService({
|
||||
manager: MockManager,
|
||||
productVariantService: ProductVariantService,
|
||||
@@ -145,20 +196,20 @@ describe("RestockNotificationService", () => {
|
||||
it("non-existing noti does nothing", async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
await expect(restockNotiService.triggerRestock("variant_test")).resolves
|
||||
await expect(restockNotiService.restockExecute_("variant_test")).resolves
|
||||
})
|
||||
|
||||
it("existing noti but out of stock does nothing", async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
await expect(restockNotiService.triggerRestock("variant_outofstock"))
|
||||
await expect(restockNotiService.restockExecute_("variant_outofstock"))
|
||||
.resolves
|
||||
})
|
||||
|
||||
it("existing noti emits and deletes", async () => {
|
||||
jest.clearAllMocks()
|
||||
|
||||
await restockNotiService.triggerRestock("variant_1234")
|
||||
await restockNotiService.restockExecute_("variant_1234")
|
||||
|
||||
expect(EventBusService.emit).toHaveBeenCalledTimes(1)
|
||||
expect(EventBusService.emit).toHaveBeenCalledWith(
|
||||
@@ -187,7 +238,7 @@ describe("RestockNotificationService", () => {
|
||||
{ inventory_required: 5 }
|
||||
)
|
||||
|
||||
await service.triggerRestock("variant_1234")
|
||||
await service.restockExecute_("variant_1234")
|
||||
|
||||
expect(EventBusService.emit).toHaveBeenCalledTimes(1)
|
||||
expect(EventBusService.emit).toHaveBeenCalledWith(
|
||||
@@ -214,7 +265,7 @@ describe("RestockNotificationService", () => {
|
||||
{ inventory_required: 5 }
|
||||
)
|
||||
|
||||
await service.triggerRestock("variant_low_inventory")
|
||||
await service.restockExecute_("variant_low_inventory")
|
||||
|
||||
expect(EventBusService.emit).toHaveBeenCalledTimes(0)
|
||||
expect(RestockNotificationModel.delete).toHaveBeenCalledTimes(0)
|
||||
|
||||
@@ -108,10 +108,15 @@ class RestockNotificationService extends BaseService {
|
||||
* and emits a restocked event to the event bus. After successful emission the
|
||||
* restock notification is deleted.
|
||||
* @param {string} variantId - the variant id to trigger restock for
|
||||
* @return {Promise<RestockNotification>} The resulting restock notification
|
||||
* @return The resulting restock notification
|
||||
*/
|
||||
async triggerRestock(variantId) {
|
||||
return this.atomicPhase_(async (manager) => {
|
||||
triggerRestock(variantId) {
|
||||
const delay = this.options_?.trigger_delay ?? 0
|
||||
setTimeout(() => this.restockExecute_(variantId), delay)
|
||||
}
|
||||
|
||||
async restockExecute_(variantId) {
|
||||
return await this.atomicPhase_(async (manager) => {
|
||||
const restockRepo = manager.getRepository(this.restockNotificationModel_)
|
||||
|
||||
const existing = await this.retrieve(variantId)
|
||||
|
||||
@@ -614,7 +614,9 @@ class CartService extends BaseService {
|
||||
})
|
||||
|
||||
if ("region_id" in update) {
|
||||
await this.setRegion_(cart, update.region_id, update.country_code)
|
||||
const countryCode =
|
||||
update.country_code || update.shipping_address?.country_code
|
||||
await this.setRegion_(cart, update.region_id, countryCode)
|
||||
}
|
||||
|
||||
if ("customer_id" in update) {
|
||||
|
||||
@@ -69,6 +69,10 @@ module.exports = {
|
||||
type: "doc",
|
||||
id: "how-to/headless-ecommerce-store-with-gatsby-contentful-medusa",
|
||||
},
|
||||
{
|
||||
type: "doc",
|
||||
id: "how-to/making-your-store-more-powerful-with-contentful",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user