Optimize factory usage for build action entity

What does this MR do and why?

This MR replaces create with build_stubbed in spec/serializers/build_action_entity_spec.rb to optimize the factory usage as recommended in our handbook. This spec is part of the list .rubocop_todo/rspec/factory_bot/avoid_create.yml. It was verified that database persistence is not needed using the factory doctor command FDOC=1 bin/rspec spec/serializers/build_action_entity_spec.rb.

Factory Usage Optimization Results

Before optimization:

  • Factory time: 3.492s (16.32% of total time)

After optimization:

  • Factory time: 0.081s (0.43% of total time)

🚀 Improvement:

  • Factory time reduced by: 3.411s
  • Factory time percentage reduced by: 15.89%
  • Overall factory usage improvement: 97.7%

Factory Doctor Output

[TEST PROF INFO] FactoryDoctor enabled (event: "sql.active_record", threshold: 0.01)
Run options: include {:focus=>true}

All examples were filtered out; ignoring {:focus=>true}
==> Using precompiled Gitaly binaries from cache

Test environment set up in 1.3719100000162143 seconds
......[TEST PROF INFO] FactoryDoctor report

Total (potentially) bad examples: 3
Total wasted time: 00:02.523

BuildActionEntity (./spec/serializers/build_action_entity_spec.rb:5) (21 records created, 00:02.523)
  contains original job name (./spec/serializers/build_action_entity_spec.rb:21)  7 records created, 00:01.812
  contains path to the action play (./spec/serializers/build_action_entity_spec.rb:25)  7 records created, 00:00.356
  contains whether it is playable (./spec/serializers/build_action_entity_spec.rb:29)  7 records created, 00:00.354




Finished in 17.42 seconds (files took 15.21 seconds to load)
6 examples, 0 failures

[TEST PROF INFO] Time spent in factories: 00:03.638 (16.55% of total time)

Factory time before the update

[TEST PROF INFO] Time spent in factories: 00:03.492 (16.32% of total time)

Factory time after update

[TEST PROF INFO] Time spent in factories: 00:00.081 (0.43% of total time)

AI Agent Output

**Changes made:**

- **Line 6:** `create(:ci_build, ...)` → `build_stubbed(:ci_build, ...)` — eliminates ~6 associated DB records (pipeline, project, namespace, author, etc.) that `ci_build` factory creates transitively.
- **Line 8:** `create(:user)` → `build_stubbed(:user)` — eliminates the user record. The user is only accessed via `request.current_user`, which is already a stubbed double.

**Why this works:**
- `build_stubbed` provides a fake integer ID, so `jobs/#{job.id}/play` path assertions in line 25 still work.
- `job.playable?` (line 29) is computed from in-memory attributes (status, when, etc.) — no DB query needed.
- `name` attribute (line 21) is purely in-memory.
- The `when job is scheduled` context overrides `let(:job)` with its own `create(:ci_build, :scheduled)`, so those tests are unaffected.

**Performance improvement:** ~7 DB records eliminated per example × 3 examples = ~21 fewer DB insertions, saving roughly 2.5s based on the FactoryDoctor report.

This MR also adds the missing feature category in this spec.

References

Relates to: #378910.

MR acceptance checklist

Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.

Merge request reports

Loading