Skip to content

Commit

Permalink
test: assert that the extension displays some text
Browse files Browse the repository at this point in the history
  • Loading branch information
suryarajendhran committed Jul 25, 2024
1 parent f4fa8e5 commit 247accb
Show file tree
Hide file tree
Showing 13 changed files with 242 additions and 13 deletions.
39 changes: 39 additions & 0 deletions extensions/checkout-ui-2/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# Checkout UI Extension

Checkout UI extensions let app developers build custom functionality that merchants can install at defined targets in the checkout flow. You can learn more about checkout UI extensions in Shopify’s [developer documentation](https://shopify.dev/api/checkout-extensions/checkout).

## Prerequisites

Before you start building your extension, make sure that you’ve created a [development store](https://shopify.dev/docs/apps/tools/development-stores) with the [checkout extensibility developer preview](https://shopify.dev/docs/api/release-notes/developer-previews#previewing-new-features).

## Your new Extension

Your new extension contains the following files:

- `README.md`, the file you are reading right now.
- `shopify.extension.toml`, the configuration file for your extension. This file defines your extension’s name, where it will appear in the checkout, and other metadata.
- `src/Checkout.tsx`, the source code for your extension.
- `locales/en.default.json` and `locales/fr.json`, which contain translations used to [localized your extension](https://shopify.dev/docs/apps/checkout/best-practices/localizing-ui-extensions).

By default, your extension is configured to target the `purchase.checkout.block.render` [extension target](https://shopify.dev/docs/api/checkout-ui-extensions/extension-targets-overview). You will find the target both in your `shopify.extension.toml`, and in the source code of your extension. The default target allows the merchant to configure where in the checkout *they* want your extension to appear. If you are building an extension that is tied to existing UI element in the checkout, such as the cart lines or shipping options, you can change the extension target so that your UI extension will render in the correct location. Check out the list of [all available extension targets](https://shopify.dev/docs/api/checkout-ui-extensions/extension-targets-overview) to get some inspiration for the kinds of content you can provide with checkout UI extensions.

To build your extension, you will need to use APIs provided by Shopify that let you render content, and to read and write data in the checkout. The following resources will help you get started with checkout extensions:

- [APIs by extension target](https://shopify.dev/docs/api/checkout-ui-extensions/targets)
- [All APIs for reading and writing checkout data](https://shopify.dev/docs/api/checkout-ui-extensions/apis)
- [Available components and their properties](https://shopify.dev/docs/api/checkout-ui-extensions/components)

## Useful Links

- [Checkout app documentation](https://shopify.dev/apps/checkout)
- [Checkout UI extension documentation](https://shopify.dev/api/checkout-extensions)
- [Configuration](https://shopify.dev/docs/api/checkout-ui-extensions/configuration)
- [Extension Targets](https://shopify.dev/docs/api/checkout-ui-extensions/targets)
- [API Reference](https://shopify.dev/docs/api/checkout-ui-extensions/apis)
- [UI Components](https://shopify.dev/docs/api/checkout-ui-extensions/components)
- [Checkout UI extension tutorials](https://shopify.dev/docs/apps/checkout)
- [Enable extended delivery instructions](https://shopify.dev/apps/checkout/delivery-instructions)
- [Creating a custom banner](https://shopify.dev/apps/checkout/custom-banners)
- [Thank you and order status pages](https://shopify.dev/docs/apps/checkout/thank-you-order-status)
- [Adding field validation](https://shopify.dev/apps/checkout/validation)
- [Localizing an extension](https://shopify.dev/apps/checkout/localize-ui-extensions)
7 changes: 7 additions & 0 deletions extensions/checkout-ui-2/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
presets: [
['@babel/preset-env', { targets: { node: 'current' } }],
['@babel/preset-react', { runtime: 'automatic' }],
'@babel/preset-typescript',
],
};
5 changes: 5 additions & 0 deletions extensions/checkout-ui-2/locales/en.default.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"welcome": "Welcome to the {{target}} extension!",
"iWouldLikeAFreeGiftWithMyOrder": "I would like to receive a free gift with my order",
"attributeChangesAreNotSupported": "Attribute changes are not supported in this checkout"
}
5 changes: 5 additions & 0 deletions extensions/checkout-ui-2/locales/fr.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"welcome": "Bienvenue dans l'extension {{target}}!",
"iWouldLikeAFreeGiftWithMyOrder": "Je souhaite recevoir un cadeau gratuit avec ma commande",
"attributeChangesAreNotSupported": "Les modifications d'attribut ne sont pas prises en charge dans cette commande"
}
21 changes: 21 additions & 0 deletions extensions/checkout-ui-2/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
{
"name": "checkout-ui-2",
"private": true,
"version": "1.0.0",
"license": "UNLICENSED",
"scripts": {
"test": "jest"
},
"dependencies": {
"@shopify/ui-extensions": "2024.7.x",
"@shopify/ui-extensions-react": "2024.7.x",
"react": "^18.0.0"
},
"devDependencies": {
"@babel/preset-typescript": "^7.24.7",
"@types/jest": "^29.5.12",
"@types/react": "^18.0.0",
"jest": "^29.7.0",
"react-reconciler": "0.29.0"
}
}
52 changes: 52 additions & 0 deletions extensions/checkout-ui-2/shopify.extension.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Learn more about configuring your checkout UI extension:
# https://shopify.dev/api/checkout-extensions/checkout/configuration

# The version of APIs your extension will receive. Learn more:
# https://shopify.dev/docs/api/usage/versioning
api_version = "2024-07"

[[extensions]]
name = "checkout-ui-2"
handle = "checkout-ui-2"
type = "ui_extension"


# Controls where in Shopify your extension will be injected,
# and the file that contains your extension’s source code. Learn more:
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/extension-targets-overview

[[extensions.targeting]]
module = "./src/Checkout.tsx"
target = "purchase.checkout.block.render"

[extensions.capabilities]
# Gives your extension access to directly query Shopify’s storefront API.
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/configuration#api-access
api_access = true

# Gives your extension access to make external network calls, using the
# JavaScript `fetch()` API. Learn more:
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/configuration#network-access
# network_access = true

# Loads metafields on checkout resources, including the cart,
# products, customers, and more. Learn more:
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/configuration#metafields

# [[extensions.metafields]]
# namespace = "my_namespace"
# key = "my_key"
# [[extensions.metafields]]
# namespace = "my_namespace"
# key = "my_other_key"

# Defines settings that will be collected from merchants installing
# your extension. Learn more:
# https://shopify.dev/docs/api/checkout-ui-extensions/unstable/configuration#settings-definition

# [extensions.settings]
# [[extensions.settings.fields]]
# key = "banner_title"
# type = "single_line_text_field"
# name = "Banner title"
# description = "Enter a title for the banner"
28 changes: 28 additions & 0 deletions extensions/checkout-ui-2/src/Checkout.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { mount } from '@remote-ui/testing'
import { createRoot } from '@remote-ui/react'
import { Extension } from './Checkout'
import * as Shopify from '@shopify/ui-extensions-react/checkout';
import '@remote-ui/testing/matchers';

jest.mock('@shopify/ui-extensions-react/checkout', () => {
return {
__esModule: true,
...jest.requireActual('@shopify/ui-extensions-react/checkout'),
};
});

jest
.spyOn(Shopify, 'useTranslate')
.mockImplementation(() => (translationKey: string) => translationKey as any);

jest.spyOn(Shopify, 'useApi').mockImplementation(() => ({ extension: { target: 'purchase.checkout.block.render' } }));

describe('Header', () => {
it('renders the header', () => {
const app = mount((root) => {
createRoot(root).render(<Extension />)
})

expect(app).toContainRemoteText('welcome');
})
})
27 changes: 27 additions & 0 deletions extensions/checkout-ui-2/src/Checkout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import {
reactExtension,
Banner,
BlockStack,
Text,
useApi,
useTranslate,
} from "@shopify/ui-extensions-react/checkout";

export default reactExtension("purchase.checkout.block.render", () => (
<Extension />
));

export function Extension() {
const translate = useTranslate();
const { extension } = useApi();

return (
<BlockStack border={"dotted"} padding={"tight"}>
<Banner title="checkout-ui">
{translate("welcome", {
target: <Text emphasis="italic">{extension.target}</Text>,
})}
</Banner>
</BlockStack>
);
}
9 changes: 9 additions & 0 deletions extensions/checkout-ui-2/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
// This tsconfig.json file is only needed to inform the IDE
// About the `react-jsx` tsconfig option, so IDE don't complain about missing react import
// Changing options here won't affect the build of your extension
"compilerOptions": {
"jsx": "react-jsx"
},
"include": ["./src"]
}
11 changes: 0 additions & 11 deletions extensions/checkout-ui/__tests__/Checkout.test.jsx

This file was deleted.

3 changes: 1 addition & 2 deletions extensions/checkout-ui/src/Checkout.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,11 @@ import {
useTranslate,
} from "@shopify/ui-extensions-react/checkout";

// 1. Choose an extension target
export default reactExtension("purchase.checkout.block.render", () => (
<Extension />
));

function Extension() {
export function Extension() {
const translate = useTranslate();
const { extension } = useApi();

Expand Down
28 changes: 28 additions & 0 deletions extensions/checkout-ui/src/Checkout.test.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { mount } from '@remote-ui/testing'
import { createRoot } from '@remote-ui/react'
import { Extension } from './Checkout'
import * as Shopify from '@shopify/ui-extensions-react/checkout';
import '@remote-ui/testing/matchers';

jest.mock('@shopify/ui-extensions-react/checkout', () => {
return {
__esModule: true,
...jest.requireActual('@shopify/ui-extensions-react/checkout'),
};
});

jest
.spyOn(Shopify, 'useTranslate')
.mockImplementation(() => (translationKey) => translationKey);

jest.spyOn(Shopify, 'useApi').mockImplementation(() => ({ extension: { target: 'purchase.checkout.block.render' } }));

describe('Header', () => {
it('renders the header', () => {
const app = mount((root) => {
createRoot(root).render(<Extension />)
})

expect(app).toContainRemoteText('welcome');
})
})
20 changes: 20 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 247accb

Please sign in to comment.