Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 0 additions & 17 deletions .github/workflows/rn-build-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -49,23 +49,6 @@ jobs:
bundler-cache: true
working-directory: platforms/react-native/sample

- name: Verify iOS lockfile uses published native SDK
run: scripts/check_published_podfile_lock sample/ios/Podfile.lock

- name: Cache cocoapods
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: platforms/react-native/sample/ios/Pods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('platforms/react-native/sample/ios/Podfile.lock', 'platforms/react-native/sample/Gemfile.lock', 'platforms/react-native/sample/Gemfile', 'platforms/react-native/package.json', 'platforms/react-native/sample/package.json', 'platforms/react-native/modules/@shopify/checkout-kit-react-native/package.json', 'platforms/react-native/pnpm-lock.yaml') }}

- name: Install cocoapods
working-directory: platforms/react-native/sample
run: |
set -euo pipefail
bundle install
cd ios
bundle exec pod install --deployment --repo-update

- name: Build module
run: pnpm module build

Expand Down
32 changes: 0 additions & 32 deletions .github/workflows/rn-test-ios.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,6 @@ jobs:
echo "Xcode Path: $(xcode-select -p)"
echo "Xcode Version: $(xcrun xcodebuild -version)"

- name: Setup iOS Simulator
run: |
xcrun simctl list runtimes
xcrun simctl list devicetypes | grep iPhone
xcrun simctl delete all
CURRENT_SIMULATOR_UUID=$(xcrun simctl create TestDevice "iPhone 16 Pro")
echo "CURRENT_SIMULATOR_UUID=$CURRENT_SIMULATOR_UUID" >> "$GITHUB_ENV"

- name: Setup Node.js, pnpm, and install dependencies
uses: ./.github/actions/setup
with:
Expand All @@ -42,30 +34,6 @@ jobs:
package-json-file: platforms/react-native/package.json
working-directory: platforms/react-native

- name: Setup Ruby
uses: ruby/setup-ruby@afeafc3d1ab54a631816aba4c914a0081c12ff2f # v1.310.0
with:
ruby-version: 3.3.6
bundler-cache: true
working-directory: platforms/react-native/sample

- name: Verify iOS lockfile uses published native SDK
run: scripts/check_published_podfile_lock sample/ios/Podfile.lock

- name: Cache cocoapods
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: platforms/react-native/sample/ios/Pods
key: ${{ runner.os }}-cocoapods-${{ hashFiles('platforms/react-native/sample/ios/Podfile.lock', 'platforms/react-native/sample/Gemfile.lock', 'platforms/react-native/sample/Gemfile', 'platforms/react-native/package.json', 'platforms/react-native/sample/package.json', 'platforms/react-native/modules/@shopify/checkout-kit-react-native/package.json', 'platforms/react-native/pnpm-lock.yaml') }}

- name: Install cocoapods
working-directory: platforms/react-native/sample
run: |
set -euo pipefail
bundle install
cd ios
bundle exec pod install --deployment --repo-update

- name: Build module
run: pnpm module build

Expand Down
45 changes: 27 additions & 18 deletions dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ up:
name: Run Checkout Kit workspace setup
met?: ./scripts/setup_dev_workspace --check --skip-optional-prompts
meet: ./scripts/setup_dev_workspace --skip-optional-prompts
- custom:
name: Prebuild React Native sample native projects
met?: "false"
meet: cd platforms/react-native && pnpm run prebuild -- all -- --clean

open:
"GitHub": "https://github.com/Shopify/checkout-kit"
Expand Down Expand Up @@ -350,29 +354,26 @@ commands:
Runs unit tests across all three React Native targets:
- JS: Jest tests in `platforms/react-native/modules/@shopify/checkout-kit-react-native/tests/`
- iOS: Swift Package tests at `platforms/react-native/modules/@shopify/checkout-kit-react-native/ios/`
- Android: Gradle JVM tests for `:shopify_checkout-kit-react-native` (requires a local Maven publish of `:lib`)
- Android: Gradle JVM tests for `:shopify_checkout-kit-react-native`
run: |
set -e
cd platforms/react-native && pnpm test
cd modules/@shopify/checkout-kit-react-native/ios && swift test
cd ../../../../
USE_LOCAL_SDK=1 ./scripts/publish_android_snapshot
cd sample/android && USE_LOCAL_SDK=1 ./gradlew :shopify_checkout-kit-react-native:test --refresh-dependencies
cd ../../../..
pnpm sample test:android -- --refresh-dependencies
subcommands:
js:
desc: Run JS unit tests via jest
run: cd platforms/react-native && pnpm test
ios:
desc: Run native iOS unit tests (Swift Package at modules/.../ios)
desc: Run native iOS unit tests via Swift Package
run: cd platforms/react-native/modules/@shopify/checkout-kit-react-native/ios && swift test
android:
desc: Run native Android unit tests for the RN module (publishes/uses local platforms/android SDK)
desc: Run native Android unit tests for the RN module
run: |
set -e
cd platforms/react-native
USE_LOCAL_SDK=1 ./scripts/publish_android_snapshot
cd sample/android
USE_LOCAL_SDK=1 ./gradlew :shopify_checkout-kit-react-native:test --refresh-dependencies
pnpm sample test:android -- --refresh-dependencies
lint:
desc: Run all React Native lint checks (Swift, module, sample)
aliases: [style]
Expand Down Expand Up @@ -434,10 +435,10 @@ commands:
fi
echo "Cleaned root, module and sample workspaces"

server:
start:
desc: Start Metro development server
aliases: [s]
run: cd platforms/react-native && pnpm sample start --reset-cache
aliases: [s, server]
run: cd platforms/react-native && pnpm sample start "$@"

ios:
desc: Run the iOS sample app in the simulator.
Expand All @@ -461,16 +462,24 @@ commands:
optional: --local
run: cd platforms/react-native && pnpm sample android "$@"

pod-install:
desc: Install CocoaPods for the iOS sample.
prebuild:
desc: Prebuild generated native sample projects.
long_desc: |
Runs pod install for the iOS sample app.
Runs Expo prebuild for the React Native sample and prepares platform-specific native dependencies.
Existing native folders are preserved unless Expo's --clean arg is passed through.

dev rn prebuild Prebuild iOS and Android
dev rn prebuild ios Prebuild iOS and install CocoaPods
dev rn prebuild android Prebuild Android
dev rn prebuild all -- --clean Regenerate iOS and Android native projects
dev rn prebuild ios --local Prebuild iOS against in-repo Swift SDK sources
dev rn prebuild android --local Prebuild Android against in-repo Android SDK artifacts

--local
Wire the Podfile against in-repo Swift SDK sources.
Use in-repo native SDKs where supported.
syntax:
optional: --local
run: cd platforms/react-native && pnpm run pod-install -- "$@"
optional: "[ios|android|all] [--local] [-- <expo prebuild args>]"
run: cd platforms/react-native && pnpm run prebuild -- "$@"

open:
desc: Open the React Native workspace root or native sample projects
Expand Down
6 changes: 4 additions & 2 deletions platforms/react-native/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -97,8 +97,10 @@ modules/@shopify/checkout-kit-react-native/android/gradlew.bat
# Local gems
sample/vendor

# Sample app
sample/**/AndroidManifest.xml
# Generated sample app native projects
sample/.expo/
sample/ios/
sample/android/

.claude/
CLAUDE.md
5 changes: 4 additions & 1 deletion platforms/react-native/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,7 +223,10 @@ Here's an example of how to get started with Apollo:

```tsx
import {ApolloClient, gql, ApolloProvider} from '@apollo/client';
import {API_VERSION, STOREFRONT_DOMAIN, STOREFRONT_ACCESS_TOKEN} from '@env';

const API_VERSION = '2026-04';
const STOREFRONT_DOMAIN = 'your-store.myshopify.com';
const STOREFRONT_ACCESS_TOKEN = 'your-public-storefront-access-token';

// Create a new instance of the ApolloClient
const client = new ApolloClient({
Expand Down
18 changes: 18 additions & 0 deletions platforms/react-native/__mocks__/expo-constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
const Constants = {
expoConfig: {
extra: {
API_VERSION: '2026-04',
CUSTOMER_ACCOUNT_API_SHOP_ID: 'test-shop-123',
CUSTOMER_ACCOUNT_API_CLIENT_ID: 'test-client-456',
STOREFRONT_DOMAIN: 'test-shop.myshopify.com',
STOREFRONT_ACCESS_TOKEN: 'test-storefront-token',
},
},
};

module.exports = {
__esModule: true,
default: Constants,
};

export {};
12 changes: 12 additions & 0 deletions platforms/react-native/__mocks__/expo-crypto.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const getRandomBytes = jest.fn((size: number) => new Uint8Array(size).fill(1));
const digestStringAsync = jest.fn(async () => btoa(String.fromCharCode(...new Uint8Array(32).fill(1))));

module.exports = {
__esModule: true,
CryptoDigestAlgorithm: {SHA256: 'SHA-256'},
CryptoEncoding: {BASE64: 'base64'},
getRandomBytes,
digestStringAsync,
};

export {};
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
const store: Record<string, string> = {};

const EncryptedStorage = {
setItem: jest.fn(async (key: string, value: string) => {
const SecureStore = {
setItemAsync: jest.fn(async (key: string, value: string) => {
store[key] = value;
}),
getItem: jest.fn(async (key: string) => {
getItemAsync: jest.fn(async (key: string) => {
return store[key] ?? null;
}),
removeItem: jest.fn(async (key: string) => {
deleteItemAsync: jest.fn(async (key: string) => {
delete store[key];
}),
clear: jest.fn(async () => {
Expand All @@ -17,5 +17,8 @@ const EncryptedStorage = {

module.exports = {
__esModule: true,
default: EncryptedStorage,
...SecureStore,
default: SecureStore,
};

export {};
8 changes: 0 additions & 8 deletions platforms/react-native/__mocks__/react-native-config.ts

This file was deleted.

40 changes: 0 additions & 40 deletions platforms/react-native/__mocks__/react-native-quick-crypto.ts

This file was deleted.

14 changes: 10 additions & 4 deletions platforms/react-native/__mocks__/react-native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ const ShopifyCheckoutKit = {
isApplePayAvailable: jest.fn(() => true),
addListener: jest.fn(),
removeListeners: jest.fn(),
eventEmitter: shopifyCheckoutKitEventEmitter,
};

// CommonJS export for Jest manual mock resolution
Expand All @@ -105,6 +106,12 @@ module.exports = {
requireNativeComponent,
codegenNativeComponent,
TurboModuleRegistry: {
get: jest.fn((name: string) => {
if (name === 'ShopifyCheckoutKit') {
return ShopifyCheckoutKit;
}
return null;
}),
getEnforcing: jest.fn((name: string) => {
if (name === 'ShopifyCheckoutKit') {
return ShopifyCheckoutKit;
Expand All @@ -113,10 +120,9 @@ module.exports = {
}),
},
NativeModules: {
ShopifyCheckoutKit: {
...ShopifyCheckoutKit,
eventEmitter: shopifyCheckoutKitEventEmitter,
},
ShopifyCheckoutKit,
},
StyleSheet,
};

export {};
2 changes: 1 addition & 1 deletion platforms/react-native/babel.config.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module.exports = {
presets: ['module:@react-native/babel-preset'],
presets: ['babel-preset-expo'],
};
13 changes: 5 additions & 8 deletions platforms/react-native/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
module.exports = {
preset: 'react-native',
preset: 'jest-expo',
modulePathIgnorePatterns: ['modules/@shopify/checkout-kit-react-native/lib'],
modulePaths: ['<rootDir>/node_modules', '<rootDir>/sample/node_modules'],
moduleNameMapper: {
'^react$': '<rootDir>/node_modules/react',
'^react-native$': '<rootDir>/__mocks__/react-native.ts',
},
setupFiles: ['<rootDir>/jest.setup.ts'],
transform: {
'\\.[jt]sx?$': 'babel-jest',
},
globals: {
'ts-jest': {
tsConfig: {
importHelpers: true,
},
},
},
};
Loading
Loading