feat(web): worker route integration-test lane for #94 - #177
LyuboslavLyubenov wants to merge 33 commits into
Conversation
nedda76
left a comment
There was a problem hiding this comment.
Прегледах интеграционния тестов стек (с няколко агента, всеки стъпил на реалния код). Посоката е добра — реален SSR Worker през Miniflare, покрити са правилните маршрути от #94. Но има няколко неща за оправяне преди merge, едно от които блокира CI.
🔴 Блокер — hardcode-нати абсолютни пътища към машината на автора (/Users/lyuboslavlyubenov/Desktop/...) в vitest.integration.config.ts (редове 16 и 32), test/integration/setup.ts:44 и test/integration/global-setup.ts:6. Интеграционната lane не тръгва на никоя друга машина или в CI — вероятно затова няма докладвани checks по PR-а.
🔴 Scope — pnpm-lock.yaml въвежда чужд ralph: workspace с @opencode-ai/sdk и wrangler, несвързан с този PR.
🟠 Dead code — 666 реда архивирани R2 spike тестове, изключени от самата конфигурация.
🟠 Тестово качество — няколко asserts дават фалшива увереност (детайли по редовете).
🟡 Документация — test/README.md твърди „46 теста / 9 файла“, а реалната lane пуска 34 теста / 7 файла (броят включва изключения архив).
Подробностите са в коментарите по редовете.
lyubomir-bozhinov
left a comment
There was a problem hiding this comment.
Проверих срещу head 5f6c40225 (не срещу по-ранния коммит) — двата 🔴 блокера на Неда са затворени:
- Hardcode-натите пътища ги няма:
repoRootсега се извежда отpath.resolve(path.dirname(fileURLToPath(import.meta.url)), '../..')— портативно, lane-ът тръгва извън машината на автора. pnpm-lock.yamlизобщо не е пипнат на head — чуждиятralph:workspace /@opencode-ai/sdkго няма.
Посоката е добра: реален SSR Worker през Miniflare (getPlatformProxy, in-memory D1 + binding-и), покрити маршрути от #94, плюс реални регресии за CSV rate-limit (429 + Retry-After) и keyset пейджинг (#87). Security scan на харнеса е чист.
Една residual бележка (не блокер): ralph/ директорията не съществува в репото, но добавените docs (test/README.md, docs/spec/integration-testing.md) и няколко съобщения за провал на тестове още сочат към ralph/criteria-revisions.md, ralph/assumptions.md, ralph/evidence.md. Тоест човек, който дебъгва паднал тест, ще подгони файл, който го няма. Махнатият ralph workspace е оставил dangling препратки — изчистете ги (или върнете файловете под docs/). Плюс 4 inline .skip блока, които може да отпаднат.
След почистване на висящите препратки — от моя страна готово.
done |
lyubomir-bozhinov
left a comment
There was a problem hiding this comment.
Благодаря — проверих срещу head 9d3e8c35a: висящите ralph/*.md препратки ги няма (чист scan по docs + тестовете), а двата 🔴 блокера на Неда (hardcode-нати пътища, чужд ralph: workspace в lockfile) бяха затворени още по-рано. От моя страна по кода е чисто.
Lane-ът е стойностен: реален SSR Worker през Miniflare, покрити маршрути от #94, регресии за CSV rate-limit (429 + Retry-After) и keyset пейджинг (#87). Одобрявам — при условие че CI мине зелено (advisory; финалният merge е на maintainer).
Бележка: в момента няма пуснат CI на този PR — workflow-ите на fork PR изчакват maintainer с write достъп да цъкне „Approve and run workflows". Щом се пусне и е зелено, одобрението важи.
Бележките на Неда за полиране (архивните R2 тестове / броя в README) остават на твоя преценка — не са блокер от моя страна.
|
Благодаря — наистина качествен принос. Прегледах целия diff на HEAD Сигурност и цялост на данните: чисто. Промяната е само тестове + документация, без да се пипа продукционен runtime, query или миграционен код. Fixture SQL-ът е изцяло статичен — Предишните блокери: всички затворени на HEAD — портативна резолюция на пътищата през Acceptance критерии (#94): покрити — всеки динамичен route има поне един интеграционен тест срещу miniflare D1, а security/cache заглавките са под регресионен тест. Няколко не-блокиращи бележки за полиране, на твоя преценка:
Една оперативна бележка: CI още не е пускан (fork PR-ите изискват maintainer да одобри workflow-ите), така че одобрението ми важи при зелен пробег. Вердикт: Одобрявам — при условие че CI мине зелено. Няма съображения за сигурност, SQL injection, верига на доставки или цялост на данните; остатъчните бележки са само полиране. |
PR midt-bg#177 (ralph/web-route-integration, for midt-bg#94) already owns the worker-route integration-test lane and is further along; shipping a second integration architecture here would collide on apps/web/package.json (both rewrite the `test` script) and leave the repo with two conventions and two runtimes. Remove the pool-workers dependency, vitest.workers.config.ts, wrangler.test.jsonc, and rate-limit.workerd.test.ts; restore package.json / vitest.config.ts / tsconfig.cloudflare.json / pnpm-lock.yaml to their prior state. The fix plus the unit + classifier + node integration tests already prove the .data bypass is closed. The .data rate-limit regression will land in midt-bg#177's lane instead. Backs midt-bg#184.
|
нещо чакаме ли за да се мърджне пр-а? |
nedda76
left a comment
There was a problem hiding this comment.
Прегледах последните промени — трите блокера (hardcode-нати пътища, ralph/@opencode-ai/sdk, архивните R2 spike тестове) и всички по-дребни бележки са адресирани чисто, а rate-limit helper-ът е дори по-строг, отколкото предложих. От моя страна е готово за merge (CI-то настрана — червеното е заварен prettier дълг на main, оправя се в #174). Оставям само една дребна, неблокираща бележка по-долу.
|
Всё проверено. Writing the final review. Прегледах PR #177 изцяло срещу HEAD Обхват и естество на промяната Сигурност и цялост на данните — чисто
Предходни блокери — всички затворени на HEAD (проверено локално)
Спрямо issue #94: покрито — всеки динамичен маршрут има поне един интеграционен тест срещу miniflare D1, плюс реални регресии за CSV rate-limit и keyset пейджинг (#87). Отклоненията от буквалния текст на тикета ( Остатъчни, неблокиращи бележки (на преценка на автора):
Вердикт: Одобрявам — при условие че CI мине зелено. Няма съображения за сигурност, SQL injection, верига на доставки или цялост на данните; остатъчните бележки са само полиране. |
|
Прегледах PR #177 изцяло срещу текущия HEAD Обхват и естество на промяната Сигурност и цялост на данните — чисто
Предходни блокери — всички затворени на HEAD (проверено локално)
Спрямо issue #94: покрито — всеки динамичен маршрут има поне един интеграционен тест срещу miniflare D1, плюс реални регресии за CSV rate-limit и keyset пейджинг (#87). Отклоненията от буквалния текст на тикета ( Остатъчни, неблокиращи бележки (на преценка на автора):
Вердикт: Одобрявам — при условие че CI мине зелено. Няма съображения за сигурност, SQL injection, верига на доставки или цялост на данните; остатъчните бележки са само полиране. |
setup.ts and global-setup.ts each inlined ~60 lines of identical SQL helpers and fixture constants. The duplication was a drift hazard — any change to the fixture seed had to be made in lockstep in both files. Move stripSqlCommentsAndCollapse, buildContractsInsert, and the seven FIXTURE_* constants (plus a canonical FIXTURE_STATEMENTS array) into a new helpers/fixtures.ts module that both files now import. Behaviour is unchanged: same SQL emitted, same apply order, same INSERT OR IGNORE semantics. Test count and outputs unchanged: pnpm --filter @sigma/web test still runs 335 unit + 34 integration = 369 tests, all green. Reviewer note: addresses the duplication comment from midt-bg#177 (ydimitrof on c733245).
The merge of main into ralph/web-route-integration brought in new unit tests, shifting the totals: 31 unit files / 335 unit tests, 7 integration files / 34 integration tests, 38 files / 369 tests total. The previous counts in apps/web/test/README.md (30 / 284, 37 / 318) were stale. Also drop a note that fixture declarations and SQL helpers now live in helpers/fixtures.ts (shared between setup.ts and global-setup.ts), so future maintainers editing the seed know where the source of truth is. Reviewer note: addresses the README/PR-description drift comment from midt-bg#177 (ydimitrof on e5e7cf7, repeated on c733245 after the main merge).
|
Адресирах трите неблокиращи полиращи бележки от ydimitrof (на
Промените:
(„does notime out" в Проверки локално:
Моля за свежа ревю pass, когато ви е удобно — diff е малък, нетно 3 файла премахнати от 4 в полза на 1 нов. |
|
Прегледах трите комита над |
ydimitrof
left a comment
There was a problem hiding this comment.
Преглед на PR — интеграционна тест-лента за Worker route (#94)
Какво прави PR-ът
PR-ът добавя нова integration-test лента за apps/web, която упражнява реалния SSR Worker pipeline (wrangler.getPlatformProxy + in-memory D1 + caches polyfill). Включени са нови тестове (contracts-csv, contracts-detail-json, contracts-pagination, edge-cache, routes, sitemaps, rate-limit.csv), споделени fixtures/helpers, фикстурата setup.ts, vitest workspace/integration конфигурациите, wrangler.jsonc, както и подробен ADR-0002. Промените са изцяло в тестове, конфигурация и документация — нулев production код.
Като цяло работата е с високо качество: тестовете са добре именувани и асъртват смислени контракти, коментарите обясняват намеренията, fixtures/helpers са споделени без дублиране, изолацията на miniflare state и идемпотентната фикстура (INSERT OR IGNORE) са добре обмислени, а per-IP изолационният тест умишлено проверява за изтичане на глобален rate-limit брояч.
Сигурност (Фаза 0) — CLEAN
- Няма hardcoded секрети. Всички IP адреси са от документационните RFC 5737 диапазони (
203.0.113.0/24,198.51.100.0/24) — не са реални. - Няма нови зависимости, няма промени в URL whitelist, няма подозрителни/обфускирани патърни.
Най-важни забележки
-
contracts-csv.test.ts— тривиално минаващ тест (нарушава „NO CHEATER TESTS“). Тестът приема едновременно200И500като успех, което означава, че CSV export-ът може да е напълно счупен (винаги 500) и тестът пак ще е зелен — той не доказва, че маршрутът реално сервира CSV. Разбираемо е, че ADR-0002 маркира 200-пътя като отложен scope cut, но в текущия си вид тестът гарантира почти нищо за самата функционалност. Това е основната забележка за адресиране преди merge. -
global-setup.ts— риск от изолиранglobalThis.__SIGMA_PROXY__stash. VitestglobalSetupсе изпълнява в главния процес, а тестовите файлове — в pool worker-и, които не споделятglobalThis. Междувременно повечето тестове твърдят, че proxy-то се bootstrap-ва лениво отsetup.ts(per-file). Има рискglobal-setupда засява отделен in-memory D1 (persist: false), който тестовете никога не използват. (setup.tsе в другата партида — това е забележка за проверка, не потвърден дефект.)
Дребни забележки
stripSqlCommentsAndCollapseмаха--и колабсира whitespace преди string-aware парсването (виж inline).contracts-pagination.test.tsиhelpers/headers.tsзавършват без newline в края на файла.- Консистентност на коментарите:
contracts-detail-json.test.tsтвърди „proxy is bootstrapped by ./global-setup.ts“, докато други тестове твърдят „by ./setup.ts (lazy per-file)“. Едно от двете е неточно — архитектурата трябва да е описана еднакво навсякъде. - Няколко дребни бележки около конфигурацията и стила (инлайн) — нищо блокиращо.
Вердикт: COMMENT
Солидна, добре документирана работа без блокиращи проблеми. Преди merge препоръчвам да се адресира т.1 (cheater-тестът за CSV) и да се потвърди т.2 (реалният път на bootstrap-ване на proxy-то), за да минат quality gate-овете за тестове. Останалите забележки са незадължителни подобрения.
…omes, drop redundant globalSetup Nine review threads on the integration-test lane (PR midt-bg#177): T-002 — contracts-csv "cheater" 200||500 assertion. The disjunction passed even if /contracts.csv always 500'd in production. Gate the expected outcome on the build mode (import.meta.env.DEV): DEV asserts the documented devalue 500; a prod/pre-built lane asserts the 200 contract. A status outside the mode's expectation now fails loudly instead of being tolerated. T-003 — redundant vitest globalSetup. global-setup.ts booted a proxy, ran migrations, seeded fixtures, then disposed — but vitest runs each test file in its own worker, so globalThis.__SIGMA_PROXY__ was not visible to tests (setup.ts already bootstraps per-worker). Removed global-setup.ts, unwired it from the config, and updated setup.ts / fixtures.ts / README / sibling test comments to reflect per-worker lazy bootstrap as the only path. T-004 — stripSqlCommentsAndCollapse corrupted string literals. The per-line `--` strip ran before the string-aware split, so `'a--b'` became `'a`; and collapse-whitespace mangled `'a b'` → `'a b'`. Rewrote as a single string- aware char scanner (comment strip + statement split + whitespace collapse all honour in-string state). Added helpers/fixtures.test.ts (7 tests) covering good/bad paths including the two regression cases. TDD: failing tests first. T-005 — duplicated server.deps.inline. Defined identically at top-level `server` (Vite dev-server, unused by `vitest run`) and `test.server`. Removed the top-level copy with an explanatory comment. T-006 — dead exclude config. The exclude list targets paths the include glob never matches. Kept it as a defensive safety net with a comment explaining why (it blocks accidental double-runs if `include` is ever widened). T-007 — comment/regex mismatch in compareSemverDesc. The comment described a `(peer-deps-hash)` parens flavour that does not occur in pnpm store dir names (only in resolved package.json deps); the actual store dirs use plain semver or `_`-delimited peer-dep suffixes. Rewrote the comment to describe the real formats. T-008 / T-009 — missing trailing newline in routes.test.ts and sitemaps.test.ts. Added. T-010 — rate-limit 500 masking. assertCsvNonRateLimitedResponse accepted any 500 whose body matched the devalue text, which could mask a real regression with the same shape. Added a hard `not.toBe(429)` floor (rate-limit leak fails loudly regardless of body), gated the 500 acceptance on import.meta.env.DEV, and linked the tolerance to the ADR-0002 deferred item. Validation: integration lane 8 files / 41 tests pass (was 7 / 34, +7 new fixtures tests); unit lane 31 files / 335 tests pass; `pnpm typecheck` exit 0.
…p version (T-001) PR midt-bg#177 review T-001 (non-blocking): the `.find()` fallback picked the first @opentelemetry/api store entry after a descending semver sort. If pnpm ever hoists two versions, that can differ from the version the app actually imports, silently aliasing the wrong build/esm. Extract the store-walking logic into a pure, unit-tested helper `pickOtelStoreEntry` that prefers an EXACT match on the version the app declares in package.json (stripping semver range operators and ignoring the `_…` peer-dep hash), falling back to the highest semver when the app version is absent. Both branches are deterministic. TDD: 7 tests covering empty store, exact match (incl. peer-dep hash suffix), fallback to highest semver, determinism under input reordering, and ignoring unrelated @opentelemetry/* packages. Integration lane 9 files / 48 tests pass; typecheck exit 0.
|
Прегледах #177 на дълбочина срещу head Истински, не мокнат: Дискриминиращо там, където има значение:
Честно скоупнато (плюс, не минус): Две неща за яснота (не блокират):
Солидна работа — реален път, честни граници, дискриминиращи тестове. |
|
@lyubomir-bozhinov Благодаря за задълбочения преглед и одобрението. По двете бележки: 1. Координация с #183 — съгласен, това е точното място. Ще разширя 2. Обхват — потвърдено разбиране. Lane-ът валидира worker/header контракта (статус, security headers, rate-limit, content-type, Нищо блокиращо за action този пас — приемам одобрението. PR-ът е |
setup.ts and global-setup.ts each inlined ~60 lines of identical SQL helpers and fixture constants. The duplication was a drift hazard — any change to the fixture seed had to be made in lockstep in both files. Move stripSqlCommentsAndCollapse, buildContractsInsert, and the seven FIXTURE_* constants (plus a canonical FIXTURE_STATEMENTS array) into a new helpers/fixtures.ts module that both files now import. Behaviour is unchanged: same SQL emitted, same apply order, same INSERT OR IGNORE semantics. Test count and outputs unchanged: pnpm --filter @sigma/web test still runs 335 unit + 34 integration = 369 tests, all green. Reviewer note: addresses the duplication comment from midt-bg#177 (ydimitrof on c733245).
…omes, drop redundant globalSetup Nine review threads on the integration-test lane (PR midt-bg#177): T-002 — contracts-csv "cheater" 200||500 assertion. The disjunction passed even if /contracts.csv always 500'd in production. Gate the expected outcome on the build mode (import.meta.env.DEV): DEV asserts the documented devalue 500; a prod/pre-built lane asserts the 200 contract. A status outside the mode's expectation now fails loudly instead of being tolerated. T-003 — redundant vitest globalSetup. global-setup.ts booted a proxy, ran migrations, seeded fixtures, then disposed — but vitest runs each test file in its own worker, so globalThis.__SIGMA_PROXY__ was not visible to tests (setup.ts already bootstraps per-worker). Removed global-setup.ts, unwired it from the config, and updated setup.ts / fixtures.ts / README / sibling test comments to reflect per-worker lazy bootstrap as the only path. T-004 — stripSqlCommentsAndCollapse corrupted string literals. The per-line `--` strip ran before the string-aware split, so `'a--b'` became `'a`; and collapse-whitespace mangled `'a b'` → `'a b'`. Rewrote as a single string- aware char scanner (comment strip + statement split + whitespace collapse all honour in-string state). Added helpers/fixtures.test.ts (7 tests) covering good/bad paths including the two regression cases. TDD: failing tests first. T-005 — duplicated server.deps.inline. Defined identically at top-level `server` (Vite dev-server, unused by `vitest run`) and `test.server`. Removed the top-level copy with an explanatory comment. T-006 — dead exclude config. The exclude list targets paths the include glob never matches. Kept it as a defensive safety net with a comment explaining why (it blocks accidental double-runs if `include` is ever widened). T-007 — comment/regex mismatch in compareSemverDesc. The comment described a `(peer-deps-hash)` parens flavour that does not occur in pnpm store dir names (only in resolved package.json deps); the actual store dirs use plain semver or `_`-delimited peer-dep suffixes. Rewrote the comment to describe the real formats. T-008 / T-009 — missing trailing newline in routes.test.ts and sitemaps.test.ts. Added. T-010 — rate-limit 500 masking. assertCsvNonRateLimitedResponse accepted any 500 whose body matched the devalue text, which could mask a real regression with the same shape. Added a hard `not.toBe(429)` floor (rate-limit leak fails loudly regardless of body), gated the 500 acceptance on import.meta.env.DEV, and linked the tolerance to the ADR-0002 deferred item. Validation: integration lane 8 files / 41 tests pass (was 7 / 34, +7 new fixtures tests); unit lane 31 files / 335 tests pass; `pnpm typecheck` exit 0.
…p version (T-001) PR midt-bg#177 review T-001 (non-blocking): the `.find()` fallback picked the first @opentelemetry/api store entry after a descending semver sort. If pnpm ever hoists two versions, that can differ from the version the app actually imports, silently aliasing the wrong build/esm. Extract the store-walking logic into a pure, unit-tested helper `pickOtelStoreEntry` that prefers an EXACT match on the version the app declares in package.json (stripping semver range operators and ignoring the `_…` peer-dep hash), falling back to the highest semver when the app version is absent. Both branches are deterministic. TDD: 7 tests covering empty store, exact match (incl. peer-dep hash suffix), fallback to highest semver, determinism under input reordering, and ignoring unrelated @opentelemetry/* packages. Integration lane 9 files / 48 tests pass; typecheck exit 0.
…tstrap from env.DB scan After upstream's migration 0002 added contracts.current_value_currency (read by getContract → packages/db/src/queries/details.ts), the integration test proxy only loaded migrations 0000 and 0001. The local D1 therefore lacked the column every contract-route loader reads, and tests hitting /contracts/:id or /contracts/:id.json returned 500 instead of 200/404. Apply 0002 in setup.ts. The read-only D1 chokepoint guard (apps/web/app/lib/readonly-db-chokepoint.test.ts midt-bg#199/midt-bg#225) forbids env.DB in any web source. test/integration/setup.ts must use proxy.env.DB.exec() to apply migrations — schema admin, not application data access, and only runs inside the vitest integration config (not the deployed Worker). Exempt that single file from the scan with a rationale comment so the chokepoint stays hermetic for everything else.
…lint Eleven files in the PR's test/config surface had pre-existing prettier debt that the upstream prettier version (3.8.3) flags: the integration test files, the vitest integration config + workspace, and the root README. Same content, whitespace only. The lint gate is blocking on these (AGENTS.md / repo CI), so this is non-optional for merge. Verified: pnpm typecheck, pnpm --filter @sigma/web test → 530 passing (52 files, 8 integration files, 41 integration tests), pnpm lint clean.
…NTS_SQL resolves value_restated/value_suspect after rebase
PR midt-bg#177 review (ydimitrof, 2026-08-18): `readOtelAppVersion` в `vitest.integration.config.ts` извличаше версията на `@opentelemetry/api` с `replace(/^[~^>=<\s]+/, '').split(' ').pop()`. За съставен range като ">=1.9.1 <2.0.0" `.pop()` връщаше горната граница (`<2.0.0`), `compareSemverDesc` я парсваше като `NaN → 0` и лентата алиасваше грешен store entry. Това е само fallback път (след `require.resolve`), така че рискът беше нисък, но фиксът е едноредов. Извлечен е чист helper `extractSemverCore(spec): string | null`, който хваща първото semver ядро в spec-а. Експортиран е за тестване. Добавени са четири unit теста в `otel-store-entry.test.ts` (caret/tilde/exact, съставен range, липсващо ядро, празен вход).
PR midt-bg#177 review (ydimitrof, 2026-08-18): два header-assertion хелпера от `apps/web/test/integration/helpers/headers.ts` бяха експортирани и документирани в `apps/web/test/README.md`, но НЕ се извикваха никъде в integration лентата (dead code, нарушение на правилото „NO DEAD CODE"): - `assertCsvContentType` — заменен inline `expect(res.headers.get('Content-Type')...)` в `contracts-csv.test.ts` с директно извикване на хелпера. - `assertCacheable` — извикан в `edge-cache.test.ts` за `GET /` (който е в `publicCache()` opt-in set с `s-maxage + stale-while-revalidate`). За `GET /sitemap.xml` НЕ е приложим (sitemap-ът използва browser cache `public, max-age=86400`, не edge cache) — оставен е коментар, който фиксира разликата в семантиката.
PR midt-bg#177 review (ydimitrof, 2026-08-18), два свързани проблема: **(T-009) Крехък lockstep с миграциите.** `setup.ts` прилагаше ръчно подбрано подмножество `[0000, 0001, 0002, 0006, 0007]` и прескачаше 0003-0005. Работеше само докато никоя прескочена миграция не създаваше обект, който 0006/0007 ALTER-ват (тригер върху `interest_links` от 0010, който зависи от 0003). Бъдещо пренареждане щеше да счупи лентата тихо. Заменено е с auto-discovery: `paths.ts` чете `packages/db/migrations/`, филтрира по `^\d{4}_.*\.sql$, сортира по водещите 4 цифри и експортира `LISTED_MIGRATIONS`. `setup.ts` ги прилага в ред. Тестовете в `fixtures.test.ts` пинват contiguity, наличието на 0006/0007 и минимален брой 11. **(T-010) Тригер телата се чупят на наивния split-on-`;`.** Когато лентата започна да прилага 0010, `stripSqlCommentsAndCollapse` раздели `CREATE TRIGGER … BEGIN SELECT RAISE(ABORT, '…'); END;` на половин `CREATE TRIGGER … BEGIN SELECT RAISE(…)` (без `END;`), D1 върна `incomplete input: SQLITE_ERROR`. Scanner-ът вече следи BEGIN/END depth и третира `;` при depth > 0 като вътрешен separator, който НЕ флашва statement — целият `BEGIN … END` блок (включително вътрешните `;`) се доставя на `DB.exec()` като един statement. BEGIN/END се разпознават само на keyword boundary (предходен whitespace + следващ не-word char), за да не реагират на колони `begin_at`/`end_at`. Добавени са три регресионни теста: trigger с вътрешен RAISE, trigger без WHEN и INSERT с колони `begin_at`/`end_at` (negative test).
…the stale static default
…o its types are checked
…e (decreasing amount_eur)
…QL scanner (PR midt-bg#177 review)
…tion with it.todo (PR midt-bg#177 review)
…gn example (PR midt-bg#177 review)
… pays the FS read
…m/main After rebase onto upstream/main (a191ece), the upstream robots.tsx no longer emits Disallow: /search or Disallow: /*.csv. The integration test locked in the old literal form. Adjusting the test to assert the current (upstream) shape keeps the integration lane green without changing the route under test.
b0abb49 to
4ff6bb8
Compare
Daily autonomous review (2026-09-18) — rebase onto current upstream/mainState of action items from prior review. All 37 review threads remain What I did this pass (rebase):
Verification (local, on the post-rebase tip
State:
Coordination note with PR #183 remains a tracked post-merge follow-up: extend |
Daily autonomous review (2026-09-19) — rebase onto current upstream/mainState of action items from prior review. All 37 review threads remain What I did this pass (rebase):
Verification (local, on the post-rebase tip
State:
|
The post-rebase lint gate flagged fixtures.test.ts: comments and a nested describe exceeded printWidth and the nesting drifted by one level (the 8a96484 commit landed after the prior prettier-format pass). Reformat only; tests still pass (18/18).
Daily autonomous review (2026-09-21) — rebase onto current upstream/mainState of action items from prior review. All 37 review threads remain What I did this pass (rebase):
Verification (local, on the post-rebase tip
State:
Coordination note with PR #183 remains a tracked post-merge follow-up: extend |
Какво и защо
Този pull request добавя интеграционен тестов стек за
apps/web, който валидира реалния SSR Cloudflare Worker (workers/app.ts) чрез Wrangler/Miniflare, а не само изолирани unit тестове с мокове. Целта е критичните публични маршрути, логиката за кеширане и сигурност, ограничаването на честотата на заявките и поведението на пейджинг с ключови множества да бъдат проверявани по реалния път на заявките преди сливане на промените.Потребителска история
Като поддържащ СИГМА, искам CI да улавя регресии в реалните уеб маршрути — например неправилни хедъри за сигурност/кеширане, счупено ограничение на честотата на заявките за CSV, отклонения в пейджинга на
/contracts(#87) или проблеми с отговорите на sitemap/robots — без да се налага ръчна проверка или имитация на продукционна среда.Детайли по имплементацията
apps/web/vitest.integration.config.ts) и конфигурация за работната среда (apps/web/vitest.workspace.ts), така чеpnpm --filter @sigma/web testда изпълнява едновременно unit и интеграционни тестове.apps/web/test/integration/с помощна функцияappFetch(request), лениво зареждане на реалния Worker и настройка наwrangler.getPlatformProxy()за предварително заредени D1, Cache и RateLimit биндинги.Content-Type,Cache-Control,X-Edge-Cache,Retry-Afterпри статус 429 иContent-Dispositionза CSV файлове./search,/companies,/authorities,/contracts,/contracts/:slug,/contracts/:slug.json,/contracts.csv,/sitemap.xml,/sitemap-pages.xml,/sitemap-contracts.xml,/sitemap-companies.xml,/sitemap-authorities.xmlи/robots.txt.CF-Connecting-IPвръща коректен429съсRetry-After./contracts?cursor=…, който проверява стабилността на втория резултатен сет през публичния маршрут.docs/spec/integration-testing.md, инструкции за изпълнение вapps/web/test/README.md, както и препратки вREADME.mdиdocs/README.md.Свързан issue
Затваря #94. Покрива и проверка за регресия, свързана с #87.
Вид промяна
Как е тествано
pnpm --filter @sigma/web test— 318 успешни теста (284 unit + 34 integration), 0 неуспешни. Потвърдено стабилно при три последователни изпълнения.pnpm --filter @sigma/web test:unit— 284 успешни теста, 0 неуспешни.pnpm --filter @sigma/web test:integration— 34 успешни теста, 0 неуспешни.pnpm --filter @sigma/web typecheck— изходен код 0 (wrangler types && react-router typegen && tsc -b).Чеклист
Co-Authored-By:трейлърmidt-bg/sigma:mainpnpm --filter @sigma/web typecheckминава успешноpnpm --filter @sigma/web testминава успешноpnpm lintе чист (не е изпълняван отделно в този цикъл).env*или.dev.varsфайловеdocs/е актуализиранаdiscord: lubakmanqk