-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2 from composable-com/dev
Additional Unit Tests
- Loading branch information
Showing
14 changed files
with
613 additions
and
68 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2023 Orium | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,22 +1,84 @@ | ||
<p align="center"> | ||
<a href="https://commercetools.com/"> | ||
<img alt="commercetools logo" src="https://unpkg.com/@commercetools-frontend/assets/logos/commercetools_primary-logo_horizontal_RGB.png"> | ||
</a></br> | ||
<b>Connect Application Starter in TypeScript</b> | ||
</p> | ||
# commercetools Fluent Commerce Connector | ||
|
||
This is the `starter-typescript` template to develop [connect applications](https://marketplace.commercetools.com/) in TypeScript. | ||
The Fluent Commerce commercetools connector was created by [Orium](https://orium.com/), and provides the following features: | ||
- Ability to capture customer order events from commercetools to Fluent, including payment transaction details | ||
- Ability to initially load all products from commercetools to Fluent Commerce when the connector is installed | ||
- Ability to continuously synchronize products from commercetools to Fluent Commerce in near real-time | ||
|
||
## Instructions | ||
## Overview | ||
|
||
Use `create-connect-app` cli with `starter-typescript` as `template` value to download this template repository to build the integration application , folder structure needs to be followed to ensure certification & deployment from commercetools connect team as stated [here](https://github.com/commercetools/connect-application-kit#readme) | ||
The application receives events (like product publication or order creation) from commercetools, processes them, and then creates corresponding entities in FluentCommerce. | ||
|
||
## Architecture principles for building an connect application | ||
This is achieved through a POST endpoint which receives the event, processes it, and depending on the event type, either creates a product or an order in FluentCommerce. | ||
|
||
* Connector solution should be lightweight in nature | ||
* Connector solutions should follow test driven development. Unit , Integration (& E2E) tests should be included and successfully passed to be used | ||
* No hardcoding of customer related config. If needed, values in an environment file which should not be maintained in repository | ||
* Connector solution should be supported with detailed documentation | ||
* Connectors should be point to point in nature, currently doesnt support any persistence capabilities apart from in memory persistence | ||
* Connector solution should use open source technologies, although connector itself can be private for specific customer(s) | ||
* Code should not contain console.log statements, use [the included logger](https://github.com/commercetools/merchant-center-application-kit/tree/main/packages-backend/loggers#readme) instead. | ||
## Pre-requisites | ||
- FluentCommerce retail account | ||
- FluentCommerce Lingo account | ||
- commercetools account | ||
- [commercetools API keys](https://docs.commercetools.com/getting-started/create-api-client) (“Admin client”) | ||
|
||
## Installing the connector | ||
In order to install the connector in your commercetools project, you'll need to deploy it. Refer to the [commercetools connect deployment documentation](https://docs.commercetools.com/connect/concepts#deployments). | ||
|
||
Setup the required environment variables when you [create the deployment](https://docs.commercetools.com/connect/getting-started#create-a-deployment): | ||
|
||
- `CTP_CLIENT_ID` | ||
- `CTP_CLIENT_SECRET` | ||
- `CTP_PROJECT_KEY` | ||
- `CTP_SCOPE` | ||
- `CTP_REGION` | ||
- `FLUENT_CLIENT_SECRET` | ||
- `FLUENT_CLIENT_ID` | ||
- `FLUENT_USERNAME` | ||
- `FLUENT_PASSWORD` | ||
- `FLUENT_HOST` | ||
- `FLUENT_CATALOGUE_REF` | ||
- `FLUENT_RETAILER_ID` | ||
- `FLUENT_CATALOG_LOCALE` | ||
|
||
Once the connector is deployed, it should trigger the [`postDeploy` script](https://docs.commercetools.com/connect/convert-existing-integration#postdeploy). | ||
|
||
The post-deploy script will create a commercetools API subscription to listen to “[Order Created](https://docs.commercetools.com/api/projects/messages#order-created)” and “[Product Published](https://docs.commercetools.com/api/projects/messages#product-published)” [messages](https://docs.commercetools.com/api/projects/messages) . Each time an order is created or a product is published, the commercetools API will send a message to the connector. | ||
|
||
## Uninstalling the connector | ||
|
||
In order to uninstall the connector, you’ll need to [send the appropriate HTTP request and delete it](https://docs.commercetools.com/connect/deployments#delete-deployment). | ||
|
||
This will trigger the [`preUndeploy` script](https://docs.commercetools.com/connect/convert-existing-integration#preundeploy) which will delete the messages subscriptions described on the “Installing the connector” section. | ||
|
||
## How it works | ||
|
||
|
||
### Processing Product Changes and first sync | ||
|
||
When the connector is getting deployed, it will get all your commercetools products and create them in FluentCommerce. This connector does not sync product category data. | ||
|
||
When a product is published on commercetools, an event of type 'ProductPublished' is received. The application checks if this product has a key. If there isn't one, the product is not processed. | ||
|
||
If a product key exists, the application proceeds to create or update a 'standard product' and its 'variants' in FluentCommerce. | ||
|
||
If a product key exists, but the variant has an SKU equals to that key, the connector will not process the product. This is because standard products should have a unique Ref in FluentCommerce, and SKU will be used for Ref in variants. | ||
|
||
The standard product, which represents the main product, includes details like the product name, description. The variants represent different forms of the product, like different sizes or colors and include similar information as the standard product, along with their SKU (Stock Keeping Unit). | ||
|
||
### Processing Order Creation | ||
|
||
When an order is created on commercetools, an event of type 'OrderCreated' is received. The application checks if this order has a customer email and customer ID. If these fields don't exist, the order is not processed. | ||
|
||
If they do, the application proceeds to create an order in FluentCommerce. If the customer associated with the order doesn't exist in FluentCommerce, a new customer is created along with the order. | ||
|
||
If there are payments associated with the order, a financial transaction is created in FluentCommerce. | ||
|
||
## FAQ | ||
|
||
### Why do we need the `FLUENT_CATALOG_LOCALE` env variable? | ||
|
||
- By default, commercetools has built-in i18n support. In order to consume the catalog data, we must specify the desired [`LocalizedString`](https://docs.commercetools.com/api/types#localizedstring). | ||
|
||
|
||
|
||
## Useful links | ||
- https://lingo.fluentcommerce.com/asset-library/reference-modules/order/ | ||
- https://lingo.fluentcommerce.com/overview/getting-started/glossary/ | ||
- https://lingo.fluentcommerce.com/apis/graphql/ | ||
- https://lingo.fluentcommerce.com/apis/rest/v4.1/event-api/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,17 +5,17 @@ The Fluent Connector, developed by [Orium](https://www.orium.com), is designed t | |
|
||
|
||
## Security | ||
In accordance with posted requirements, the Fluent connector has undergone the [commercetools certification process](https://docs.commercetools.com/connect/certification) and has been approved prior to public lease. Specific security requirements are part of this process, including a defined timeline for resolution of reported critical and high vulnerabilities. | ||
In accordance with posted requirements, the Fluent connector has undergone the [commercetools certification process](https://docs.commercetools.com/connect/certification) and has been approved prior to public lease. Specific security requirements are part of this process, including a defined timeline for resolution of reported critical and high vulnerabilities. | ||
|
||
While the process certifies the connector, it does not substitute the need to conduct further, ongoing and personalized testing of your holistic product where you utilize this connector. The nature of vulnerabilities in software is that the security landscape changes all the time and continuous scanning is necessary. | ||
While the process certifies the connector, it does not substitute the need to conduct further, ongoing and personalized testing of your holistic product where you utilize this connector. The nature of vulnerabilities in software is that the security landscape changes all the time and continuous scanning is necessary. | ||
|
||
## No Liability and Indemnification | ||
The use of the Fluent connector comes with no warranty. It is completely the responsibility of those who download and use the code to take the necessary precautions to utilize the connector in a way that is safe and secure. The code is provided "as is”, without any representations or warranties of any kind, either expressed or implied. | ||
|
||
You agree to release, indemnify, and hold Orium and its affiliates and subsidiaries, and their officers, directors, employees and agents, harmless from and against any third party claims, liabilities, damages, losses, and expenses, Your continued use of the product constitutes your acceptance of these terms. | ||
You agree to release, indemnify, and hold Orium and its affiliates and subsidiaries, and their officers, directors, employees and agents, harmless from and against any third party claims, liabilities, damages, losses, and expenses, your continued use of the product constitutes your acceptance of these terms. | ||
|
||
## Responsible Disclosure | ||
Researchers and users of any type are welcome to identify potential security issues and submit them as pull requests against the Github repository for consideration. Depending on the veracity of the finding, Orium, in their sole discretion, may choose to compensate the reporter with a reward commensurate to the severity of the finding. Submission of a finding does not guarantee a reward. You may also email us at [email protected]. | ||
Researchers and users of any type are welcome to identify potential security issues and submit them as pull requests against the Github repository for consideration. Depending on the veracity of the finding, Orium, in their sole discretion, may choose to compensate the reporter with a reward commensurate to the severity of the finding. Submission of a finding does not guarantee a reward. You may also email us at [email protected]. | ||
|
||
## Subject to Change | ||
This security policy is subject to change at any time. Notification of an update to this security policy will be communicated via a commit to the Fluent connector repository. Your continued use of the product constitutes acceptance of any changes. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
// ./__mocks__/axios.js | ||
import mockAxios from 'jest-mock-axios'; | ||
export default mockAxios; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
import { ByProjectKeyRequestBuilder } from '@commercetools/platform-sdk/dist/declarations/src/generated/client/by-project-key-request-builder' | ||
import { | ||
MY_SUBSCRIPTION_KEY, | ||
createMySubscription, | ||
deleteMySubscription, | ||
} from './actions' | ||
|
||
describe('createMySubscription', () => { | ||
let mockDeletefn: typeof jest.fn | ||
let mockPostfn: typeof jest.fn | ||
let mockApiRoot: ByProjectKeyRequestBuilder | ||
|
||
const mockGetResponse = { | ||
body: { | ||
results: [{ version: 1 }], | ||
}, | ||
} | ||
|
||
beforeEach(() => { | ||
mockDeletefn = jest.fn().mockReturnThis() | ||
mockPostfn = jest.fn().mockReturnThis() | ||
mockApiRoot = { | ||
subscriptions: jest.fn().mockReturnThis(), | ||
get: jest.fn().mockReturnThis(), | ||
withKey: jest.fn().mockReturnThis(), | ||
execute: jest.fn().mockResolvedValue(mockGetResponse), | ||
delete: mockDeletefn, | ||
post: mockPostfn, | ||
} as unknown as ByProjectKeyRequestBuilder | ||
}) | ||
|
||
it('should delete an existing subscription if one exists', async () => { | ||
await createMySubscription(mockApiRoot, 'topicName', 'projectId') | ||
|
||
expect(mockDeletefn).toHaveBeenCalledWith({ | ||
queryArgs: { version: 1 }, | ||
}) | ||
expect(mockPostfn).toHaveBeenCalledWith({ | ||
body: { | ||
key: MY_SUBSCRIPTION_KEY, | ||
destination: { | ||
projectId: 'projectId', | ||
topic: 'topicName', | ||
type: 'GoogleCloudPubSub', | ||
}, | ||
format: { | ||
type: 'CloudEvents', | ||
cloudEventsVersion: '1.0', | ||
}, | ||
messages: [ | ||
{ | ||
resourceTypeId: 'product', | ||
types: ['ProductPublished'], | ||
}, | ||
{ | ||
resourceTypeId: 'order', | ||
types: ['OrderCreated'], | ||
}, | ||
], | ||
}, | ||
}) | ||
}) | ||
it('should POST with expected body', async () => { | ||
await createMySubscription(mockApiRoot, 'topicName', 'projectId') | ||
|
||
expect(mockPostfn).toHaveBeenCalledWith({ | ||
body: { | ||
key: MY_SUBSCRIPTION_KEY, | ||
destination: { | ||
projectId: 'projectId', | ||
topic: 'topicName', | ||
type: 'GoogleCloudPubSub', | ||
}, | ||
format: { | ||
type: 'CloudEvents', | ||
cloudEventsVersion: '1.0', | ||
}, | ||
messages: [ | ||
{ | ||
resourceTypeId: 'product', | ||
types: ['ProductPublished'], | ||
}, | ||
{ | ||
resourceTypeId: 'order', | ||
types: ['OrderCreated'], | ||
}, | ||
], | ||
}, | ||
}) | ||
}) | ||
}) | ||
|
||
describe('deleteMySubscription', () => { | ||
let mockDeletefn: typeof jest.fn | ||
let mockApiRoot: ByProjectKeyRequestBuilder | ||
|
||
const mockGetResponse = { | ||
body: { | ||
results: [{ version: 1 }], | ||
}, | ||
} | ||
|
||
beforeEach(() => { | ||
mockDeletefn = jest.fn().mockReturnThis() | ||
mockApiRoot = { | ||
subscriptions: jest.fn().mockReturnThis(), | ||
get: jest.fn().mockReturnThis(), | ||
withKey: jest.fn().mockReturnThis(), | ||
execute: jest.fn().mockResolvedValue(mockGetResponse), | ||
delete: mockDeletefn, | ||
} as unknown as ByProjectKeyRequestBuilder | ||
}) | ||
|
||
it('should delete a subscription', async () => { | ||
await deleteMySubscription(mockApiRoot) | ||
|
||
expect(mockDeletefn).toHaveBeenCalledWith({ | ||
queryArgs: { version: 1 }, | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.