Full test infrastructure, code audit fixes, and real E2E integration tests

Test infrastructure:
- Django standalone test runner (pytest-django, test settings, EmailUser model)
- React unit tests via Vitest with jsdom, jest compat layer, path aliases
- Playwright E2E tests using generated hooks in a real Chromium browser
- Docker Compose test backend (Django + Redis) for integration testing
- Desktop integration test app (PyWebView + Django + uvicorn)
- Makefile with test/test-django/test-react/test-integration targets

Library bugs found and fixed:
- hasJWT truthiness: undefined !== null was true, skipping session init
- process.env crash: CSR client referenced process.env in non-Node browsers
- baseUrl not forwarded: DjareaProvider didn't pass baseUrl to CSR client
- Relative URL handling: new URL() failed with relative base paths
- call() race condition: HTTP requests fired before CSRF cookie was set
- Session init await: added sessionRef promise so call() waits for session
- path_prefix on schema export: both export commands failed with URL reverse
- NullBooleanField removed: referenced field doesn't exist in Django 5.0+
- lru_cache on JWT settings: get_settings() now cached as intended
- Channel message routing: broadcasts now include channel name and params
- httpFunctionCall: fixed URL and request body format

Generator fixes:
- Removed 1,100 lines of REST/OpenAPI client generation (not part of Djarea)
- Generator now works for djarea-only projects without django-ninja REST APIs
- Generated DjangoContext now includes ChannelProvider when channels exist
- Fixed env var passthrough for schema export commands
- Deduplicated fetch logic into single runDjangoCommand helper

Test quality:
- Fixed 33 tautological Django tests with real assertions
- Found hidden bug: benchmark functions were never registered
- Found hidden bug: unicode lookalike test used plain ASCII
- Deleted worthless React unit tests (duplicates, shape checks, Zod-tests-Zod)
- Replaced jsdom integration tests with Playwright browser tests

Example apps:
- example/: Integration test backend with 33 server functions, 5 forms,
  4 channels covering auth variations, contexts, class-based ServerFunction,
  error codes, DjareaFormMixin, formsets, and JWT
- desktop/: PyWebView desktop app with file system access, SQLite CRUD,
  system introspection, and 39 real HTTP integration tests

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-31 01:17:48 -04:00
commit 4451ec24a1
179 changed files with 27699 additions and 0 deletions

View File

@@ -0,0 +1,76 @@
/**
* djarea/channels
*
* Real-time WebSocket communication with Django Channels.
* Type-safe bidirectional messaging.
*
* ## Setup
*
* ```tsx
* // layout.tsx
* import { ChannelProvider } from 'djarea/channels'
*
* export default function Layout({ children }) {
* return (
* <ChannelProvider>
* {children}
* </ChannelProvider>
* )
* }
* ```
*
* ## Usage
*
* ```tsx
* // Using generated hooks (recommended)
* import { useChatChannel } from '@/api/generated.channels'
*
* function Chat({ room }) {
* const chat = useChatChannel({ room })
*
* chat.status // 'connecting' | 'connected' | 'disconnected'
* chat.messages // DjangoMessage[]
* chat.send({ text: 'Hello' }) // Send ReactMessage
* }
* ```
*
* ```tsx
* // Using raw hook (for custom channels)
* import { useChannel } from 'djarea/channels'
*
* function CustomChannel() {
* const channel = useChannel<
* { room: string }, // Params
* { user: string; text: string }, // DjangoMessage
* { text: string } // ReactMessage
* >('chat', { room: 'general' })
*
* // ...
* }
* ```
*/
// Context
export { ChannelProvider, useChannelContext, useChannelStatus } from './context'
export type { ChannelProviderProps } from './context'
// Hooks
export { useChannel, useChannelLatest, useRPC, RPCError } from './hooks'
export type { UseChannelOptions, RPCClient } from './hooks'
// Connection (for advanced use)
export { ChannelConnection, getDefaultConnection } from './connection'
export type {
ChannelConnectionOptions,
RPCRequest,
RPCResponse,
RPCSuccessResponse,
RPCErrorResponse,
} from './connection'
// Types
export type {
ConnectionStatus,
ChannelSubscription,
SubscribeOptions,
} from './types'