The smoke test can be somebody
Without a token the signed-in half of a gated catalog is untestable here: the real credential store is the OS keychain reached through Electron, and there is no Electron in this process, so every title comes back `signInRequired` and "owned" and "not owned" never happen. SMOKE_TOKEN supplies one. Against a live Orbit it now reports `open:1, purchasable:1, entitled:1` — the free title, the one this account has not bought, and the one it has — which is the first end-to-end proof that the access block survives the whole path from the engine's policy to a card. It only ever reads. A smoke run must not leave a credential on the machine that ran it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -219,6 +219,7 @@ names. `make` on its own lists everything.
|
||||
| `make check` | **typecheck, lint and both test suites** — the gate |
|
||||
| `make start` | run the app against whatever store is installed |
|
||||
| `make smoke` | drive the store with no window and no Electron at all |
|
||||
| `SMOKE_HOME=<dir> SMOKE_TOKEN=<bearer> npm run smoke` | the same, against a sandbox store and as a signed-in person |
|
||||
| `make uitest` | load the window once and report what rendered |
|
||||
| `SELFTEST_SHOT=shot.png npm run uitest` | the same, and the window photographs itself into that file |
|
||||
| `make test` | both test suites |
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { CatalogListing } from '../domain/models/CatalogListing'
|
||||
import type { InstalledStore } from '../domain/models/InstalledStore'
|
||||
import { DESKTOP_STORE_ENGINE } from '../domain/models/StoreEngine'
|
||||
import { deriveStoreId } from '../domain/models/StoreIdentity'
|
||||
import type { CredentialRepository } from '../domain/ports/CredentialRepository'
|
||||
import { NativeStoreCatalogGateway } from '../infrastructure/engine/NativeStoreCatalogGateway'
|
||||
import { HttpTextClient } from '../infrastructure/http/HttpTextClient'
|
||||
import { FileSystemInstalledStoreRepository } from '../infrastructure/repositories/FileSystemInstalledStoreRepository'
|
||||
@@ -26,12 +27,18 @@ import { LOCALES } from '../shared/i18n/MessageBundle'
|
||||
*
|
||||
* npm run smoke the store on this machine
|
||||
* SMOKE_HOME=/path/to/store-home npm run smoke a sandbox store
|
||||
* SMOKE_TOKEN=<bearer> npm run smoke as a signed-in person
|
||||
*
|
||||
* `SMOKE_TOKEN` exists because the signed-in path is otherwise untestable here: the
|
||||
* real credential store is the OS keychain, reached through Electron, and there is no
|
||||
* Electron in this process. Without it a gated catalog can only ever be read as an
|
||||
* anonymous caller, and "owned" and "not owned" never happen.
|
||||
*/
|
||||
class SmokeTest {
|
||||
private failed = false
|
||||
|
||||
private readonly stores = new FileSystemInstalledStoreRepository()
|
||||
private readonly catalogGateway = new NativeStoreCatalogGateway()
|
||||
private readonly catalogGateway = new NativeStoreCatalogGateway(envCredentials())
|
||||
private readonly httpClient = new HttpTextClient()
|
||||
private readonly registry = new HttpStoreRegistryRepository(this.httpClient)
|
||||
private readonly gameMapper = new GameDtoMapper()
|
||||
@@ -219,3 +226,19 @@ void new SmokeTest().run().then(
|
||||
process.exitCode = 1
|
||||
}
|
||||
)
|
||||
|
||||
/**
|
||||
* The token from the environment, for every store.
|
||||
*
|
||||
* Deliberately not per store: this is a test harness pointed at one catalog at a time,
|
||||
* and a keyed map here would be ceremony around a single value. Nothing writes — a
|
||||
* smoke run must not leave a credential behind on the machine that ran it.
|
||||
*/
|
||||
function envCredentials (): CredentialRepository {
|
||||
const token = process.env['SMOKE_TOKEN'] ?? ''
|
||||
return {
|
||||
readToken: (): string | null => (token.length > 0 ? token : null),
|
||||
writeToken: (storeId: string, value: string): void => { void storeId; void value },
|
||||
clearToken: (storeId: string): void => { void storeId }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user