Repository navigation
feat: shared testing package, transaction toasts, and wallet re-authorization - #263
Open
Dawnaurora25 wants to merge 2 commits into
Open
Dawnaurora25 wants to merge 2 commits into
Dawnaurora25 wants to merge 2 commits into
Conversation
Gives the workspace one place for test doubles instead of hand-rolled stubs: `packages/testing` becomes a real, private workspace package exporting a FakeTransport (in-memory Soroban RPC), Stream/Escrow/Split fixtures, and a createTestClient harness, with the SDK suite as its first consumer (Closes SorobanForge#150). Replaces the per-page inline success/error banners with a shared ToastProvider + useToast in packages/ui — success/error/info, configurable auto-dismiss that pauses on hover or focus, and a portal container announced through a polite live region — and reports stream create/withdraw/cancel through it (Closes SorobanForge#129). Stops trusting localStorage for auto-reconnect: the stored session is only shown as connected once the wallet actually grants access, a denied or unavailable wallet returns to disconnected without an error banner, and a new isCheckingWallet state keeps connect buttons from flashing while that happens (Closes SorobanForge#123). Documents only the packages that exist (README layout, ARCHITECTURE table), drops the stale `@stellar-starter-kit/core` path mapping, and keeps the lockfile in sync with the new package (Closes SorobanForge#155).
|
@Dawnaurora25 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
|
@Dawnaurora25 is attempting to deploy a commit to the techalhaji's projects Team on Vercel. A member of the Team first needs to authorize it. |
Collaborator
|
resolve conflicts please |
The Lint Codebase job runs `prettier --check .`, and six files introduced by the test-doubles migration did not match the repo's formatter output: the five SDK suites had the `makeClient` arrow split although it fits on one line, and `createFakeTransport` wrapped spy chains that fit. Formatting them is required before the typecheck and test jobs can even be reached. 🤖 Generated with Codebuff Co-Authored-By: Codebuff <noreply@codebuff.com>
This branch has not been deployed
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Closes #150, Closes #155, Closes #129, Closes #123.
Four issues, one coherent change: the workspace gains a real, private test-doubles package, the dashboard gains a shared notification surface, and the wallet layer stops trusting
localStoragefor auto-reconnect. They are shipped together because they interlock — #155's cleanup is what turns thepackages/testingplaceholder into the package #150 asks for, and both the SDK suite and the wallet tests consume the new package's conventions.packages/testingis a real workspace package:FakeTransport,Stream/Escrow/Splitfixtures,createTestClient, README with a worked example, and the SDK suite as its first consumer.@stellar-starter-kit/corepath mapping is gone; the lockfile accounts for the workspace graph.ToastProvider+useToastinpackages/ui, used by the streams page to report create/withdraw/cancel and their transaction hashes.isCheckingWalletstate that stops the connect button from flashing.1.
@stellar-starter-kit/testing— a real testing package (Closes #150)Before: every package hand-rolled its own stubs. The SDK, for example, carried a 190-line
packages/sdk/src/test-helpers.tsthat patchedSorobanRpc.Server.prototypead hoc.packages/testingexisted only as an empty, untracked directory.After:
packages/testingis a proper workspace package (added topnpm-workspace.yaml'spackages/*glob, declared inpnpm-lock.yaml, built and linted by Turborepo like every sibling).What it exports
createFakeTransport(options?)— the in-memory RPC transport. Constructing one swaps the five RPC methods the SDK and the dashboard call (getAccount,simulateTransaction,prepareTransaction,sendTransaction,getTransaction) for canned, in-memory answers: sequence100, a successful simulation,prepareTransactionpassthrough,PENDING/SUCCESSsubmissions with hashabc123. Every method stays avi.fn, so a test can still domockResolvedValueOnce/mockRejectedValueOnceand assert onmock.calls. Helpers:calls()(round trips),reset(),restore(), andrespondWith({ get_stream: streamScVal() })for per-method simulations.streamFixture(),escrowFixture(),splitFixture()return fully-populated domain values withPartialoverrides (decimal strings foru64/i128, per thepackages/typesconvention), plusstreamScVal()which encodes aStreamexactly as the contract'sget_streamreturns it, and stableCONTRACT_ID/TOKEN_ID/PUBLIC_KEY/RECIPIENT/ARBITER.createTestClient(factory, options?)— the harness. Installs a transport and builds a client with test-safe defaults (https://rpc.invalid, 1 ms poll interval, identity signer), returning{ client, transport, withClient, restore }.withClient(overrides)builds additional clients against the same transport, which is what the existing poll/timeout tests need.simulationSuccess,simulationError,sendResponse,txResponse,trappedResult,badSequenceResult,contractErrorEvent,invokedCall,simulateByMethod.@stellar-starter-kit/sdk(the SDK's tests depend on it, which would make the workspace graph circular and break Turborepo's^build/^testtask graph).createTestClienttherefore takes the client factory —createTestClient((config) => new StreamsClient(config))— andTestClientConfigmirrorsStreamsClientOptionsfield for field so it type-checks without a cast. This is documented in both the README and the source.The SDK is the first consumer
packages/sdk/src/test-helpers.tsis deleted. All five SDK test files now import from@stellar-starter-kit/testing, declaring it as a workspacedevDependency:packages/sdk/vitest.config.tsresolves the package from source (../testing/src/index.ts), sopnpm testworks without buildingdistfirst — the test job in CI installs and runs, it does not build.packages/sdk/tsconfig.jsondrops its stale@stellar-starter-kit/corepath mapping (a reference to a package that does not exist — part of #155).Private and never bundled
"private": true, noapps/webdependency, no import from shipped runtime code. The README states this explicitly and explains the intended usage with one complete example test.2.
ToastProvider+useToast(Closes #129)packages/ui/src/toast.tsx(exported from the package index, alongside its types):success,error,infoviatoast.success(...),toast.error(...),toast.info(...), or the generictoast.show(variant, title, options).durationoverrides the provider'sdefaultDuration(5 s);0keeps a toast until it is dismissed. The timer pauses on hover, focus, and resumes with the remaining time — it is not restarted.createPortal(..., document.body)after hydration, on arole="status"+aria-live="polite"+aria-atomic="false"region, so every toast is announced without stealing focus. Each toast has a labelled dismiss button (aria-label="Dismiss notification") and decorative icons arearia-hidden.options.hash+options.explorerUrlrender a "View transaction" link instead of the ad-hoc HTML string the pages were interpolating into banner text.maxToasts(default 4) drops the oldest toast.framer-motion, already a dependency ofpackages/ui— no new dependencies anywhere in this PR.Wired into the app
apps/web/src/app/layout.tsxwraps the app in<ToastProvider>(insideWalletProvider), so the container exists for every route.apps/web/src/app/streams/page.tsxremoves its localerror/successstate and theAnimatePresencebanner, and reports every outcome through toasts: create, withdraw, and cancel all go throughrunAction/handleCreate→notify(...), and successes go through a singlenotifyTx(title, hash)helper that formats the tx link once. A stream lookup failure, a rejected signature, a missing contract id, and a failed connect are error toasts.3. Re-authorize the wallet session on load (Closes #123)
packages/wallets/src/WalletProvider.tsx:requestAddress(provider)helper is the only place an address is read from a wallet — it is now shared byconnectand by the restore effect, so both paths ask for access the same way (FreighterisConnected+requestAccess, with thegetAddressfallback for older builds; AlbedopublicKey; Rabetconnect; HanagetPublicKey).localStorageand never setserror, because the user never asked to connect.isCheckingWallet. A new context field alongsideisConnecting, true while the restore request is in flight; the streams page disables the connect button and shows "Checking wallet…" instead of "Wallet not connected", so returning users no longer see the button flash.Tests (granted, denied, unavailable)
packages/wallets/src/WalletProvider.test.tsxgains five cases, rendering insideactso the async restore is fully flushed before asserting:localStorage, andlocalStorageis re-persisted;isCheckingWalletistrueandisConnectedisfalse, then flips when access arrives (this is the anti-flash guarantee, asserted directly with a deferred promise);error === null,localStoragecleared, norequestAccesscall leaked;isConnected: false) → disconnected,error === null,requestAccessnever called;error === null.The pre-existing "auto-reconnect" and "disconnect" tests were updated to grant access first, since the old behaviour they asserted (showing a stored address before it was granted) is exactly the bug.
4. Workspace + documentation hygiene (Closes #155)
packages/cli,packages/core,packages/confighave no scaffolded content and no owner: they are not re-created.packages/testingis the one placeholder that earned a real package (see above), so nothing is left dangling.@stellar-starter-kit/corepath mapping inpackages/sdk/tsconfig.json(a mapping to apackages/core/distthat never existed).ARCHITECTURE.mdand the README layout tree list only packages that exist, now includingtestingwith a one-line responsibility; the README also documents the testing package and links its README.pnpm-lock.yamlmatchespackage.jsonfiles exactly (newpackages/testingimporter,packages/sdk→link:../testing), sopnpm install --frozen-lockfilein CI stays green..gitignorealready covers every artifact these directories can produce (node_modules,.turbo,dist,*.tsbuildinfo), so nothing regenerates as a spurious change — verified rather than changed.Files changed
packages/testing/{package.json,tsconfig.json,vitest.config.ts,README.md},packages/testing/src/{index,transport,fixtures,client,index.test}.tspackages/sdk/package.json,tsconfig.json,vitest.config.ts,src/*.test.ts(5 files), deletedsrc/test-helpers.tspackages/ui/src/toast.tsx(new),packages/ui/src/index.tspackages/wallets/src/WalletProvider.tsx,WalletProvider.test.tsxapps/web/src/app/layout.tsx,apps/web/src/app/streams/page.tsxpnpm-lock.yaml,ARCHITECTURE.md,README.mdVerification
packages/testingships its own tests (src/index.test.ts): the transport answersgetAccount/simulate/submit/confirm in memory,respondWithroutes by contract method, an unregistered method fails loudly,restore()puts the realSorobanRpc.Servermethods back,createTestClientapplies and overrides defaults on one shared transport, and the fixtures/streamScValround-trip throughscValToNative.packages/testinghas atestscript precisely soturbo run testexercises it instead of failing on an empty suite.packages/testingdepends only on@stellar/stellar-sdk,@stellar-starter-kit/types, andvitest; the toast usesframer-motion+lucide-react, whichpackages/uialready depended on; the app already depended on@stellar-starter-kit/ui.packages/testingdepends on nothing that depends on it, so^build/^teststay acyclic forturbo run build|typecheck|test..ts/.tsxparses with zero syntax diagnostics (TypeScript compiler API), every JSON file parses,pnpm-lock.yamlloads as valid YAML with the new importer present, and every named import the SDK tests take from@stellar-starter-kit/testingand./indexresolves to a real export. The full gate —pnpm lint+format:check,typecheck,test,build, and the Rust contract job — runs on CI.