Skip to content

fix(datasource): don't load test files as entities - #3375

Open
fallenbagel wants to merge 4 commits into
developfrom
fix/test-file-entity-loading
Open

fix(datasource): don't load test files as entities#3375
fallenbagel wants to merge 4 commits into
developfrom
fix/test-file-entity-loading

Conversation

@fallenbagel

@fallenbagel fallenbagel commented Aug 12, 2026

Copy link
Copy Markdown
Member

Description

TypeORM entities and subscribers load from directory globs over every .ts file under server/entity and server/subscriber. While it is harmless today since neither folder has a test file, but drop one in and requiring it runs the module body, which calls setupTestDb() again. That registers a second root before and beforeEach after the runner already built its tree, so two schema rebuilds collide on the single in-memory sqlite connection: "cannot start a transaction within a transaction," every test cancelled, nothing in the failure pointing at the actual file or the actual error.

Production is worse. build:server compiles every .ts under server, test files included, and production loads dist/entity/**/*.js, so a compiled test file there runs its module body at boot. seedTestDb calls dropDatabase() on the shared dataSource with no check on which database it's pointing at, then rebuilds the schema and seeds admin@seerr.dev with Permission.ADMIN and a hardcoded bcrypt hash. I confirmed this against a throwaway sqlite file under NODE_ENV=production and it dropped a table I'd put there first, rebuilt 15 tables, and left those two accounts behind.

Important

No released version is affected. No tag ships a test file under dist/entity or dist/subscriber, so there's nothing to fix or disclose.

Now, seedTestDb and resetTestDb refuse to run unless NODE_ENV is test. cypress:prepare, now opts in via seedTestDb({ allowOutsideTest: true }). This deny-unless-permitted was added because a plain node process with no NODE_ENV set resolves to devConfig against config/db/db.sqlite3, someone's real database if they're running from source.

In addition, build:server points at a new server/tsconfig.build.json that excludes *.test.ts, so dist stops shipping the compiled test files it currently produces. Config was separated because because typecheck:server is the only thing type checking those files, and the root tsconfig covers src only and excluding at the base would've silently dropped the files from CI.

Lastly, typeORM gets the entity and subscriber classes directly instead of globs, which also drops the duplicated ts/js patterns across the five config variants. Narrowing the globs to skip *.test.ts would achieve the same thing provided the files named are named that way in directories and a differently named test file, a helper, or a newly globbed directory brings the whole thing back. Classes mean nothing is matched by pattern, at the cost of a list to keep current, forget to add an entity and it throws EntityMetadataNotFoundError the first time its repository is used anyways. Much more safer this way. Migrations stay globbed.

How Has This Been Tested?

  • Checked the dist if the test files were carried after build
  • Checked if the tests still run
  • Checked if entities and subscribers were properly loaded.

Screenshots / Logs (if applicable)

Checklist:

  • I have read and followed the contribution guidelines.
  • Disclosed any use of AI (see our policy)
  • I have updated the documentation accordingly.
  • All new and existing tests passed.
  • Successful build pnpm build
  • Translation keys pnpm i18n:extract
  • Database migration (if required)

Summary by CodeRabbit

  • Bug Fixes

    • Network settings updates now refresh status information without triggering unnecessary update-availability checks.
    • Database seeding and reset operations are protected from accidental use outside test environments.
  • Build Improvements

    • Production builds now use dedicated build settings and exclude test files, improving build reliability.
  • Tests

    • Added coverage confirming database safety protections in non-test environments.

Copilot AI lite review requested due to automatic review settings August 12, 2026 05:25
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: a98f6b91-65a9-400a-9599-98529db8824e

📥 Commits

Reviewing files that changed from the base of the PR and between 39ff48c and 8dbc244.

📒 Files selected for processing (7)
  • package.json
  • server/datasource.ts
  • server/scripts/prepareTestDb.ts
  • server/tsconfig.build.json
  • server/utils/seedTestDb.test.ts
  • server/utils/seedTestDb.ts
  • src/components/Settings/SettingsNetwork/index.tsx

📝 Walkthrough

Walkthrough

The server build now uses a dedicated configuration and explicit database registrations. Test database mutations require test mode unless seeding explicitly opts out. Network settings refresh status without checking update availability.

Changes

Database build and test safety

Layer / File(s) Summary
Explicit database build and registration
server/tsconfig.build.json, package.json, server/datasource.ts
The server build excludes test files. Data sources use directly imported entities and subscribers instead of filesystem globs.
Test database environment guard
server/utils/seedTestDb.ts, server/scripts/prepareTestDb.ts, server/utils/seedTestDb.test.ts
Seeding and resetting reject execution outside test mode unless seeding receives allowOutsideTest. Tests verify the guard and restore NODE_ENV.

Network settings status refresh

Layer / File(s) Summary
Status refresh endpoint
src/components/Settings/SettingsNetwork/index.tsx
The post-save status refresh uses /api/v1/status?checkUpdateAvailable=false.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Possibly related PRs

Suggested reviewers: 0xsysr3ll, gauthier-th

Poem

A rabbit checks the database gate,
And keeps unsafe seeds from fate.
Build paths bloom with names in line,
While status skips the update sign.
Hop, hop—tests restore the state!

🚥 Pre-merge checks | ✅ 4
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly and concisely describes the primary change: preventing test files from loading as TypeORM entities.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@fallenbagel fallenbagel changed the title fix/test file entity loading fix(requests): stop editing a request from stealing another's season Aug 12, 2026
@fallenbagel fallenbagel changed the title fix(requests): stop editing a request from stealing another's season fix(datasource): don't load test files as entities Aug 12, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR hardens and stabilizes the server’s test database setup and TypeORM entity/subscriber loading, while keeping server builds free of test-only files.

Changes:

  • Added an explicit NODE_ENV === 'test' guard to prevent accidental destructive seeding/resets, with an opt-in escape hatch for tooling.
  • Replaced TypeORM glob-based entity/subscriber discovery with explicit imports to ensure consistent entity loading.
  • Updated the server build config to exclude *.test.ts and adjusted build:server to use the new build tsconfig.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
server/utils/seedTestDb.ts Adds a safety guard for destructive test DB operations and an opt-in override.
server/utils/seedTestDb.test.ts Adds unit tests for the test DB guard behavior.
server/tsconfig.build.json New build tsconfig excluding *.test.ts from server compilation output.
server/scripts/prepareTestDb.ts Opts into seeding outside NODE_ENV=test for Cypress preparation.
server/datasource.ts Switches entity/subscriber loading from glob strings to explicit imports/arrays.
package.json Updates build:server to use server/tsconfig.build.json (and matching tsc-alias).

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread server/utils/seedTestDb.test.ts Outdated
@cypress

cypress Bot commented Aug 12, 2026

Copy link
Copy Markdown

seerr    Run #3636

Run Properties:  status check passed Passed #3636  •  git commit 8dbc244404: fix(datasource): don't load test files as entities
Project seerr
Branch Review fix/test-file-entity-loading
Run status status check passed Passed #3636
Run duration 01m 58s
Commit git commit 8dbc244404: fix(datasource): don't load test files as entities
Committer fallenbagel
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 0
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 33
View all changes introduced in this branch ↗︎

seedTestDb and resetTestDb operate on the shared dataSource, which points
at whatever NODE_ENV selects, and neither checked where it was pointing
before dropping every table and seeding an admin account with a hardcoded
password hash. Both now refuse unless NODE_ENV is test or ALLOW_DB_RESET
is set, which cypress:prepare passes because it seeds the on-disk dev
database on purpose.
The build compiled every .ts under server, so twelve test files shipped in
dist. Anything under dist/entity or dist/subscriber gets loaded by the
production entity and subscriber globs, which means a test file in one of
those directories would run at boot. The build now uses its own tsconfig
that excludes *.test.ts, while typecheck:server keeps using the base
config so the test files are still type checked.
The entity and subscriber options were globs over a whole directory, so
every file in server/entity and server/subscriber was required at
initialize, test files included. A test file there would run its module
body inside any process that opens the datasource, including a production
boot. Both options now take the classes directly, which also removes the
duplicate ts and js patterns across the five config variants. Migrations
stay globbed since they are ordered by filename and there are hundreds of
them.
StatusChecker polls /api/v1/status?checkUpdateAvailable=false, but saving
network settings revalidated /api/v1/status, which is a different SWR key
and nothing subscribes to it. The keys stopped matching in #3137 when the
version check toggle was added, so since then the restart modal has only
appeared on the next sixty second poll or on a fresh page load.

The general settings cypress spec covered this and kept passing because
earlier specs left the restart flag dirty, so the modal was already up when
the spec loaded the page. Cleaning that up in #3368 removed the stale flag
the spec was leaning on and the real gap surfaced.
@fallenbagel
fallenbagel force-pushed the fix/test-file-entity-loading branch from a34e853 to 8dbc244 Compare August 12, 2026 05:54
Copilot AI review requested due to automatic review settings August 12, 2026 05:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 7 out of 7 changed files in this pull request and generated no new comments.

Suppressed comments (2)

src/components/Settings/SettingsNetwork/index.tsx:179

  • checkUpdateAvailable=false may not actually disable update checks because Express query values are strings; on the server, /status treats any defined value as checkUpdate and then uses if (checkUpdate), so the string 'false' is truthy. This means the request keyed by this URL can still trigger GitHub update checking (and related rate limiting). Consider parsing req.query.checkUpdateAvailable as a real boolean server-side (e.g., === 'true'), or change the client/server contract to use a falsy value.
              // the key StatusChecker polls on, so the restart modal shows at once
              mutate('/api/v1/status?checkUpdateAvailable=false');

server/utils/seedTestDb.ts:27

  • The new guard error message says it "drops every table", but seedTestDb can be called with preserveDb: true and then it won’t drop the DB. Also, including the current NODE_ENV value would make the failure easier to diagnose in CI/automation.
  throw new Error(
    `Refusing to ${operation} while NODE_ENV is not test: this drops every table and seeds accounts with a known password.`
  );

@fallenbagel
fallenbagel marked this pull request as ready for review August 12, 2026 06:12
@fallenbagel
fallenbagel requested a review from a team as a code owner August 12, 2026 06:12
@fallenbagel fallenbagel added this to the v3.5.0 milestone Aug 12, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants