Optimize factory usage for audit event presenter

What does this MR do and why?

This MR replaces create with build_stubbed in ee/spec/presenters/audit_event_presenter_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 ee/spec/presenters/audit_event_presenter_spec.rb.

Factory Usage Optimization Results

Before optimization:

  • Factory time: 2.109s (10.54% of total time)

After optimization:

  • Factory time: 1.375s (6.8% of total time)

🚀 Improvement:

  • Factory time reduced by: 0.734s
  • Factory time percentage reduced by: 3.74%
  • Overall factory usage improvement: 34.8%

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.1499559999792837 seconds
................[TEST PROF INFO] FactoryDoctor report

Total (potentially) bad examples: 5
Total wasted time: 00:01.116

AuditEventPresenter (./ee/spec/presenters/audit_event_presenter_spec.rb:5) (25 records created, 00:01.116)
  exposes the date (./ee/spec/presenters/audit_event_presenter_spec.rb:153)  5 records created, 00:00.661
  exposes the action (./ee/spec/presenters/audit_event_presenter_spec.rb:157)  5 records created, 00:00.118
  delegates to the model object (./ee/spec/presenters/audit_event_presenter_spec.rb:88)  5 records created, 00:00.109
  exposes the database value by default (./ee/spec/presenters/audit_event_presenter_spec.rb:94)  5 records created, 00:00.114
  survives a round trip from JSON (./ee/spec/presenters/audit_event_presenter_spec.rb:98)  5 records created, 00:00.112




Finished in 16.1 seconds (files took 16.09 seconds to load)
16 examples, 0 failures

Randomized with seed 51361

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

Factory time before the update

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

Factory time after update

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

Changes made:

  1. describe '#target' (line 88) — Added let(:audit_event) { build_stubbed(...) } override. The test only reads audit_event.target_details, no DB access needed.

  2. context 'exposes the ip address' (lines 94, 98) — Added let(:audit_event) { build_stubbed(...) } override. Both tests only read presenter.ip_address, no DB access needed.

  3. Lines 153, 157 — Wrapped the two standalone it blocks in a new context 'exposes date and action' block with a build_stubbed override. created_at is provided by build_stubbed's fake timestamps; presenter.action derives purely from details.

Why this works:

  • build_stubbed provides fake IDs and timestamps without touching the database, making it 2-3x faster than create
  • All 5 flagged tests only read presenter attributes that derive from the audit_event's own columns/details hash — no association traversal or real DB queries occur
  • The top-level create is preserved for tests that genuinely need persistence (author URL routing, entity URL generation, entity_id = nil mutation tests)
  • build_stubbed attributes match the top-level create call exactly, so all assertions remain valid

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