Skip to content
Open
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
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
1 change: 0 additions & 1 deletion .bun-version

This file was deleted.

120 changes: 120 additions & 0 deletions .cursor/rules/writing-tests.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
---
description:
globs:
alwaysApply: true
---
# Frontend Testing Strategy

When writing tests for our frontend monorepo, follow these principles:

## Core Philosophy
- Test behaviors, not implementations
- Optimize for confidence, readability, and maintainability
- Follow the testing pyramid: unit tests > integration tests > E2E tests
- Reference existing tests for examples of our team's best practices. For example: [useBooleanState.test.ts](mdc:packages/utilities/src/react/useBooleanState.test.ts) [useSwapNetworkNotification.test.ts](mdc:packages/uniswap/src/features/transactions/swap/form/hooks/useSwapNetworkNotification.test.ts)

## Test Structure & Patterns

### Unit Tests
- Test individual functions, hooks, and components in isolation
- Use Jest and React Testing Library/React Native Testing Library
- Follow Arrange-Act-Assert pattern
- Mock dependencies appropriately
- Name tests descriptively: `it('should [behavior] when [condition]')`

```typescript
// Component test example
test('should display error when form submission fails', async () => {
// Arrange
const errorMessage = 'Invalid credentials';
const mockSubmit = jest.fn().mockRejectedValue(new Error(errorMessage));
render(<LoginForm onSubmit={mockSubmit} />);

// Act
await userEvent.type(screen.getByLabelText(/email/i), 'user@example.com');
await userEvent.type(screen.getByLabelText(/password/i), 'password123');
await userEvent.click(screen.getByRole('button', { name: /login/i }));

// Assert
expect(await screen.findByText(errorMessage)).toBeInTheDocument();
expect(mockSubmit).toHaveBeenCalledWith({
email: 'user@example.com',
password: 'password123'
});
});

// Hook test example
test('should increment counter when increment function is called', () => {
// Arrange
const { result } = renderHook(() => useCounter(0));

// Act
act(() => {
result.current.increment();
});

// Assert
expect(result.current.count).toBe(1);
});
```

### Integration Tests
- Test interactions between multiple components
- Focus on user workflows and component communication
- Use React Testing Library's user-event
- Minimize mocking to test actual integrations

## Best Practices

### Test Data Management
- Create factory functions for generating test data
- Use TypeScript to ensure test data matches expected interfaces

```typescript
const createUser = (overrides = {}): User => ({
id: uuid(),
name: 'Test User',
email: 'test@example.com',
role: 'user',
...overrides
});
```

### Mocking Strategy
- Prefer manual mocks over automatic mocks
- Mock at the boundary of your system (API calls, third-party services)
- For React Native, mock native modules using Jest's mock functions

```typescript
jest.mock('packages/uniswap/...', () => ({
fetchUserData: jest.fn().mockResolvedValue({
id: '123',
name: 'Test User',
email: 'test@example.com'
})
}));
```

### Coverage Guidelines
- Aim for 80% coverage overall, 90%+ for critical business logic
- When requested to write UI tests, cover all user-facing components with at least basic rendering tests
- Test error states and edge cases; when unceratin about these states and cases, stop and ask for clarification before continuing
- Focus on quality over quantity - 5 well-written tests > 20 poor tests

## Monorepo Considerations
- Use the same path import strategy found in other files; everything should pass linting
- Respect the testing configuration of each package
- For shared components, test in their own package, not in consuming packages

## Implementation Checklist

When implementing tests, verify:

1. ✅ Tests focus on component/function behavior
2. ✅ Tests are isolated and don't depend on each other
3. ✅ Mocks are used appropriately and documented
4. ✅ Error states and edge cases are covered
5. ✅ Tests are readable and maintainable
6. ✅ Tests fail when they should (verify with temporary bug)
7. ✅ Test file structure matches source code structure
8. ✅ Import paths follow monorepo conventions
7 changes: 0 additions & 7 deletions .cursorignore

This file was deleted.

19 changes: 8 additions & 11 deletions .depcheckrc
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,20 @@ ignores: [
'@graphql-codegen/*',
'@commitlint/*',
'@uniswap/eslint-config',
'@uniswap/biome-config',
'i18next',
'moti',
'wrangler',
'react-router',
# Dependencies that depcheck thinks are missing but are actually present or never used
'@yarnpkg/core',
'@yarnpkg/cli',
'clipanion',
'@yarnpkg/fslib',
'bufferutil',
'utf-8-validate',
'@yarnpkg/parsers',
'@yarnpkg/plugin-git',
'semver',
'typanion',
'@biomejs/biome',
"@nx/js",
"@nx/workspace",
"@swc/helpers",
# needed for ci
'dd-trace',
# depcheck flags itself as unused
'depcheck',
'turbo-ignore',
'prettier',
'prettier-plugin-organize-imports',
]
53 changes: 0 additions & 53 deletions .dockerignore

This file was deleted.

97 changes: 51 additions & 46 deletions .env.defaults
Original file line number Diff line number Diff line change
@@ -1,46 +1,51 @@
# Use this file for default/shared values
# These will be overriden in web by .env and overriden in mobile by .env.defaults.local
# And keep env vars in sync with env.d.ts
# In order to run the app locally you need to run `bun mobile env:local:download` or `bun extension env:local:download`
ALCHEMY_API_KEY=stored-in-.env.local
APPSFLYER_API_KEY=stored-in-.env.local
APPSFLYER_APP_ID=stored-in-.env.local
CROWDIN_ENTERPRISE_ACCESS_TOKEN=stored-in-.env.local
DATADOG_CLIENT_TOKEN=stored-in-.env.local
DATADOG_PROJECT_ID=stored-in-.env.local
INFURA_KEY=stored-in-.env.local
ONESIGNAL_APP_ID=stored-in-.env.local
QUICKNODE_ENDPOINT_NAME=stored-in-.env.local
QUICKNODE_ENDPOINT_TOKEN=stored-in-.env.local
SIMPLEHASH_API_KEY=stored-in-.env.local
SIMPLEHASH_API_URL=stored-in-.env.local
STATSIG_API_KEY=stored-in-.env.local
STATSIG_PROXY_URL=stored-in-.env
UNISWAP_API_KEY=stored-in-.env.local
WALLETCONNECT_PROJECT_ID=stored-in-.env.local
WALLETCONNECT_PROJECT_ID_BETA=stored-in-.env.local
WALLETCONNECT_PROJECT_ID_DEV=stored-in-.env.local
TRADING_API_KEY=stored-in-.env.local
FIREBASE_APP_CHECK_DEBUG_TOKEN=stored-in-.env.local
INCLUDE_PROTOTYPE_FEATURES=stored-in-.env.local
GH_TOKEN_RN_CLI=
NPM_READ_ONLY_TOKEN=stored-in-.env.local
IS_E2E_TEST=false
ENABLE_SESSION_SERVICE=false
ENABLE_SESSION_UPGRADE_AUTO=false
ENABLE_ENTRY_GATEWAY_PROXY=false
# URL overrides (keep empty in this file)
AMPLITUDE_PROXY_URL_OVERRIDE=
API_BASE_URL_OVERRIDE=
API_BASE_URL_V2_OVERRIDE=
FOR_API_URL_OVERRIDE=
GRAPHQL_URL_OVERRIDE=
SCANTASTIC_API_URL_OVERRIDE=
STATSIG_PROXY_URL_OVERRIDE=
TRADING_API_URL_OVERRIDE=
UNITAGS_API_URL_OVERRIDE=
UNISWAP_NOTIF_API_BASE_URL_OVERRIDE=
ENTRY_GATEWAY_API_URL_OVERRIDE=
LIQUIDITY_SERVICE_URL_OVERRIDE=
JUPITER_PROXY_URL=
BLOCKAID_PROXY_URL=
ALCHEMY_API_KEY='key'
AMPLITUDE_EXPERIMENTS_DEPLOYMENT_KEY='key'
APPSFLYER_API_KEY='key'
APPSFLYER_APP_ID="123"
FIAT_ON_RAMP_API_URL='https://api.uniswap.org'
MOONPAY_API_KEY='key'
MOONPAY_API_URL='https://api.moonpay.com'
MOONPAY_WIDGET_API_URL='https://api.moonpay.com'
INFURA_PROJECT_ID="123"
ONESIGNAL_APP_ID="123"
QUICKNODE_BNB_RPC_URL='https://api.uniswap.org'
SENTRY_DSN='http://sentry.com'
SHAKE_CLIENT_ID="123"
SHAKE_CLIENT_SECRET="123"
SIMPLEHASH_API_KEY='key'
SIMPLEHASH_API_URL='https://api.simplehash.com'
STATSIG_PROXY_URL='https://api.statsig.com'
TEMP_SCANTASTIC_URL='https://api.uniswap.org'
TRADING_API_KEY='key'
TRADING_API_URL='https://api.uniswap.org'
UNISWAP_API_KEY='key'
UNISWAP_API_BASE_URL='https://api.uniswap.org'
UNISWAP_APP_URL='https://app.uniswap.org'
WALLETCONNECT_PROJECT_ID='c13d3da1bc06016a912d14d526d0b50c'
UNITAGS_API_URL='https://api.uniswap.org/unitags'
FIREBASE_APP_CHECK_DEBUG_TOKEN='token'
INFURA_KEY='099fc58e0de9451d80b18d7c74caa7c1'
QUICKNODE_ARBITRUM_RPC_URL=''
QUICKNODE_MAINNET_RPC_URL=''
QUICKNODE_ZKSYNC_RPC_URL=''
QUICKNODE_ZORA_RPC_URL=''
AMPLITUDE_PROXY_URL_OVERRIDE=''
API_BASE_URL_OVERRIDE=''
API_BASE_URL_V2_OVERRIDE=''
DATADOG_CLIENT_TOKEN=''
DATADOG_PROJECT_ID=''
FOR_API_URL_OVERRIDE=''
GRAPHQL_URL_OVERRIDE=''
OPENAI_API_KEY=''
QUICKNODE_ENDPOINT_NAME='ancient-weathered-meadow'
QUICKNODE_ENDPOINT_TOKEN='b70553231e05cc311dc2cf44e46843e4ef366da3'
QUICKNODE_MONAD_TESTNET_RPC_URL=''
SCANTASTIC_API_URL_OVERRIDE=''
STATSIG_PROXY_URL_OVERRIDE=''
TRADING_API_URL_OVERRIDE=''
UNITAGS_API_URL_OVERRIDE=''
INCLUDE_PROTOTYPE_FEATURES=''
STATSIG_API_KEY=''
WALLETCONNECT_PROJECT_ID_BETA='c13d3da1bc06016a912d14d526d0b50c'
WALLETCONNECT_PROJECT_ID_DEV='c13d3da1bc06016a912d14d526d0b50c'
IS_E2E_TEST='false'
18 changes: 2 additions & 16 deletions .github/workflows/tag_and_release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,21 +8,7 @@ jobs:
deploy-to-prod:
runs-on: ubuntu-latest
steps:
- uses: bullfrogsec/bullfrog@dcde5841b19b7ef693224207a7fdec67fce604db # v0.8.3
with:
# List of IPs to allow outbound connections to.
# By default, only localhost and IPs required for the essential operations of Github Actions are allowed.
# allowed-ips:|

# List of domains to allow outbound connections to.
# Wildcards are accepted. For example, if allowing `*.google.com`, this will allow `www.google.com`, `console.cloud.google.com` but not `google.com`.
# By default, only domains required for essential operations of Github Actions and uploading job summaries are allowed.
# Refer to https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners/about-github-hosted-runners#communication-requirements-for-github-hosted-runners-and-github for additional domains that should be allowed for additional Github Actions features.
#allowed-domains: |
# The egress policy to enforce. Valid values are `audit` and `block`.
# Default: audit
egress-policy: audit
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683
- uses: actions/checkout@v3

- name: 🧷️ Get version
uses: juliangruber/read-file-action@02bbba9876a8f870efd4ad64e3b9088d3fb94d4b
Expand All @@ -45,7 +31,7 @@ jobs:
tag_prefix: ""

- name: 🪽 Release
uses: actions/create-release@c9ba6969f07ed90fae07e2e66100dd03f9b1a50e
uses: actions/create-release@v1.1.0
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
with:
Expand Down
Loading