[EE] Spec: opt out of let_it_be freeze in ee/spec/requests/part-1 (103 files) (#600267)

Description

Part of #600267.

Adds freeze: false to 298 let_it_be declaration(s) across 103 spec file(s) under ee/spec/requests/part-1/ that mutate their subjects in examples or hooks.

This is a no-op against current masterlet_it_be does not freeze by default today. The change is preparation for an eventual flip of the default (see !71373 and !234596). With this patch in place, every file in this MR will continue to pass once the default is flipped.

Why per-call freeze: false and not the global config inverse?

You may wonder why this MR adds freeze: false to specific declarations rather than setting the inverse globally:

TestProf::LetItBe.configure do |config|
  config.default_modifiers[:freeze] = false
end

The end-state goal is 100 % frozen let_it_be subjects, not perpetual freeze: false. Inverting the global default would let new specs land without freeze: false and silently mutate shared state, undoing the progress made here. Patching per call:

  • Identifies the exact set of subjects that need to remain mutable today (out of ~32 000 declarations in CE; only ~10 % need it).
  • Lets us flip the global default to freeze: true once every shared subject that requires mutation is explicitly opted out.
  • Surfaces every new mutation as a FrozenError at PR-time rather than as silent cross-test pollution.

See #600267 for the rollout plan and per-pass statistics.

Changes

  • ee/spec/requests/api/ai/duo_workflows/cascading_settings_spec.rb — :root_group, :other_subgroup
  • ee/spec/requests/api/ai/duo_workflows/workflows_internal_spec.rb — :ai_settings, :group
  • ee/spec/requests/api/ai/third_party_agents_spec.rb — :unauthorized_user, :unauthorized_token
  • ee/spec/requests/api/award_emoji_spec.rb — :epic, :note, :award_emoji
  • ee/spec/requests/api/branches_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/clusters/agent_url_configurations_spec.rb — :agent, :url_configuration (×3), :receptive_agent
  • ee/spec/requests/api/code_suggestions_spec.rb — :authorized_user, :unauthorized_user, :tokens
  • ee/spec/requests/api/epic_issues_spec.rb — :issue, :epic_issue
  • ee/spec/requests/api/graphql/ai/catalog/agent_flow_config_resolver_spec.rb — :agent, :agent_version, :different_agent, :different_agent_version
  • ee/spec/requests/api/graphql/ai/catalog/agent_versions_mcp_servers_spec.rb — :linear_mcp_server, :catalog_item, :first_agent_version
  • ee/spec/requests/api/graphql/ai/catalog/item_versions_spec.rb — :public_items
  • ee/spec/requests/api/graphql/ai/duo_workflows_events_spec.rb — :project, :user, :checkpoints, :ide_workflow
  • ee/spec/requests/api/graphql/ai/model_selection/namespaces/features_settings_spec.rb — :group
  • ee/spec/requests/api/graphql/ai/model_selection/namespaces/update_spec.rb — :group
  • ee/spec/requests/api/graphql/analytics/dora/dora_scores_spec.rb — :group, :ruby_topic, :project_1
  • ee/spec/requests/api/graphql/audit_events/group/namespace_filters/create_spec.rb — :legacy_destination
  • ee/spec/requests/api/graphql/boards/board_list_query_spec.rb — :project, :label, :current_iteration1, :issue1
  • ee/spec/requests/api/graphql/boards/boards_query_spec.rb — :label
  • ee/spec/requests/api/graphql/gitlab_subscriptions/user_add_on_assignments/bulk_create_spec.rb — :add_on_purchase
  • ee/spec/requests/api/graphql/gitlab_subscriptions/user_add_on_assignments/bulk_remove_spec.rb — :add_on_purchase
  • ee/spec/requests/api/graphql/group/ci_cd_settings_spec.rb — :group
  • ee/spec/requests/api/graphql/group/epics_spec.rb — :project, :label, :epic_a (×3), :issue, :group, :epic_b (×2)
  • ee/spec/requests/api/graphql/instance_security_dashboard_spec.rb — :user
  • ee/spec/requests/api/graphql/issue/issue_spec.rb — :issue (×3), :blocking_work_item, :blocking_link
  • ee/spec/requests/api/graphql/members/group_standard_roles_spec.rb — :user, :group_1, :member_1
  • ee/spec/requests/api/graphql/members/instance_standard_roles_spec.rb — :user, :member_1
  • ee/spec/requests/api/graphql/merge_trains/trains_spec.rb — :private_project, :public_project
  • ee/spec/requests/api/graphql/mutations/ai/catalog/item_consumer/create_spec.rb — :item (×3), :item_old_released_version, :foundational_flow, :foundational_flow_latest_released_version
  • ee/spec/requests/api/graphql/mutations/ai/duo_workflows/create_spec.rb — :agent, :agent_version
  • ee/spec/requests/api/graphql/mutations/analytics/custom_dashboards/create_spec.rb — :user
  • ee/spec/requests/api/graphql/mutations/approval_project_rules/update_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/graphql/mutations/audit_events/external_audit_event_destinations/destroy_spec.rb — :destination
  • ee/spec/requests/api/graphql/mutations/audit_events/external_audit_event_destinations/update_spec.rb — :destination
  • ee/spec/requests/api/graphql/mutations/branch_rules/approval_project_rules/create_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/graphql/mutations/branch_rules/external_status_checks/create_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/graphql/mutations/branch_rules/external_status_checks/destroy_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/graphql/mutations/branch_rules/external_status_checks/update_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/graphql/mutations/branch_rules/update_spec.rb — :project
  • ee/spec/requests/api/graphql/mutations/ci/namespace_ci_cd_settings_update_spec.rb — :namespace
  • ee/spec/requests/api/graphql/mutations/dependency_proxy/packages/settings/update_spec.rb — :project
  • ee/spec/requests/api/graphql/mutations/gitlab_subscriptions/member_management/process_user_billable_promotion_request_spec.rb — :user
  • ee/spec/requests/api/graphql/mutations/issues/promote_to_epic_spec.rb — :issue
  • ee/spec/requests/api/graphql/mutations/issues/set_epic_spec.rb — :issue, :input
  • ee/spec/requests/api/graphql/mutations/members/groups/ee/bulk_update_spec.rb — :user, :group, :group_member
  • ee/spec/requests/api/graphql/mutations/merge_requests/set_assignees_spec.rb — :merge_request
  • ee/spec/requests/api/graphql/mutations/merge_trains/cars/delete_spec.rb — :target_project
  • ee/spec/requests/api/graphql/mutations/notes/create/note_spec.rb — :noteable (×4)
  • ee/spec/requests/api/graphql/mutations/projects/generate_commit_message_spec.rb — :group
  • ee/spec/requests/api/graphql/mutations/projects/summarize_new_merge_request_spec.rb — :group
  • ee/spec/requests/api/graphql/mutations/releases/update_spec.rb — :project, :tag_name, :release
  • ee/spec/requests/api/graphql/mutations/security/configuration/set_group_secret_push_protection_spec.rb — :namespace (×2), :current_user (×4)
  • ee/spec/requests/api/graphql/mutations/security/configuration/set_group_validity_checks_spec.rb — :namespace (×2), :current_user (×4)
  • ee/spec/requests/api/graphql/mutations/security/finding/refresh_finding_token_status_spec.rb — :project
  • ee/spec/requests/api/graphql/mutations/security/finding/refresh_security_finding_token_status_spec.rb — :project, :pat_token, :shared_pat_token
  • ee/spec/requests/api/graphql/mutations/security/finding/revert_to_detected_spec.rb — :vulnerability (×2)
  • ee/spec/requests/api/graphql/mutations/virtual_registries/container/cache/entry/destroy_spec.rb — :upstream, :cache_entry
  • ee/spec/requests/api/graphql/mutations/virtual_registries/container/registry/cache/destroy_spec.rb — :upstream, :cache
  • ee/spec/requests/api/graphql/mutations/virtual_registries/container/upstream/cache/destroy_spec.rb — :upstream, :cache
  • ee/spec/requests/api/graphql/mutations/virtual_registries/packages/maven/cache/entry/destroy_spec.rb — :group, :upstream, :cache_entry
  • ee/spec/requests/api/graphql/mutations/virtual_registries/packages/maven/registry/cache/destroy_spec.rb — :upstream, :cache
  • ee/spec/requests/api/graphql/mutations/virtual_registries/packages/maven/upstream/cache/destroy_spec.rb — :upstream, :cache
  • ee/spec/requests/api/graphql/mutations/vulnerabilities/create_external_issue_link_spec.rb — :project, :finding, :vulnerability
  • ee/spec/requests/api/graphql/mutations/vulnerabilities/refresh_vulnerability_finding_token_status_spec.rb — :project
  • ee/spec/requests/api/graphql/mutations/work_items/update_spec.rb — :work_item (×15), :child_in_new_parent
  • ee/spec/requests/api/graphql/project/ai_catalog_item_spec.rb — :item (×2)
  • ee/spec/requests/api/graphql/project/autocomplete_users_spec.rb — :project, :merge_request, :protected_branch
  • ee/spec/requests/api/graphql/project/branch_rules/approval_project_rules_spec.rb — :current_user, :branch_rule, :project, :approval_project_rule
  • ee/spec/requests/api/graphql/project/branch_rules/squash_options_spec.rb — :project, :protected_branch
  • ee/spec/requests/api/graphql/project/branch_rules_spec.rb — :project, :branch_name_a, :protected_branch_a, :group_protected_branch
  • ee/spec/requests/api/graphql/project/product_analytics/product_analytics_spec.rb — :purchase
  • ee/spec/requests/api/graphql/secrets_management/openbao_health_query_spec.rb — :current_user
  • ee/spec/requests/api/graphql/security/tracked_refs_resolver_spec.rb — :project
  • ee/spec/requests/api/graphql/virtual_registries/container/upstream_query_spec.rb — :upstream, :cache_entries
  • ee/spec/requests/api/graphql/virtual_registries/packages/maven/upstream_query_spec.rb — :upstream, :cache_entries
  • ee/spec/requests/api/graphql/wikis/wiki_page_spec.rb — :user, :group (×2), :wiki_page_meta (×2), :note (×2), :discussion
  • ee/spec/requests/api/graphql/work_items/custom_field_filters_spec.rb — :group_label, :work_item_a (×2)
  • ee/spec/requests/api/group_boards_spec.rb — :user, :board_parent, :dev_list, :test_list, :milestone, :board_label, :board
  • ee/spec/requests/api/group_hooks_spec.rb — :group, :user (×2), :project (×2), :role, :membership
  • ee/spec/requests/api/group_push_rule_spec.rb — :group
  • ee/spec/requests/api/group_service_accounts_spec.rb — :service_account_user (×2)
  • ee/spec/requests/api/integrations_spec.rb — :project_integrations_map
  • ee/spec/requests/api/managed_licenses_spec.rb — :project
  • ee/spec/requests/api/merge_request_approvals_spec.rb — :user
  • ee/spec/requests/api/merge_trains_spec.rb — :project
  • ee/spec/requests/api/project_approval_rules_spec.rb — :project, :approver
  • ee/spec/requests/api/project_approval_settings_spec.rb — :project, :approver
  • ee/spec/requests/api/projects_spec.rb — :group (×2)
  • ee/spec/requests/api/protected_branches_spec.rb — :project
  • ee/spec/requests/api/protected_tags_spec.rb — :project
  • ee/spec/requests/api/related_epic_links_spec.rb — :group (×4)
  • ee/spec/requests/api/status_checks_spec.rb — :project, :protected_branch (×3), :protected_branches
  • ee/spec/requests/api/vulnerability_archive_exports_spec.rb — :archive_export
  • ee/spec/requests/custom_roles/admin_security_attributes/request_spec.rb — :user, :group, :role, :membership
  • ee/spec/requests/custom_roles/read_virtual_registry/request_spec.rb — :group, :user, :role, :membership, :user_without_role, :membership_without_role
  • ee/spec/requests/custom_roles/regular/admin_cicd_variables/groups_request_spec.rb — :user, :group, :role, :member
  • ee/spec/requests/custom_roles/regular/admin_cicd_variables/projects_request_spec.rb — :user, :project, :role (×2), :member (×2)
  • ee/spec/requests/custom_roles/regular/admin_group_member/request_spec.rb — :current_user, :group, :role, :membership
  • ee/spec/requests/custom_roles/regular/admin_protected_environments/groups_request_spec.rb — :user, :group (×2), :role, :group_member
  • ee/spec/requests/custom_roles/regular/admin_push_rules/groups_request_spec.rb — :user, :group, :role, :member
  • ee/spec/requests/custom_roles/regular/admin_runners/request_spec.rb — :user, :project, :role (×2), :membership (×17)
  • ee/spec/requests/custom_roles/regular/admin_terraform_state/request_spec.rb — :user, :project
  • ee/spec/requests/custom_roles/regular/admin_web_hook/request_spec.rb — :user
  • ee/spec/requests/custom_roles/regular/manage_deploy_tokens/request_spec.rb — :user, :project, :membership (×3), :url (×2)

Verification

Each file was processed by the let-it-be-frozen-cleanup-harness (see #600267 for the methodology):

  1. Append a working-tree-only patch to spec/support/let_it_be.rb that sets default_modifiers[:freeze] = true for let_it_be (and keeps freeze: false for let_it_be_with_reload / _with_refind).
  2. Run bundle exec rspec <file> --format json. Collect every FrozenError failure.
  3. Map each FrozenError backtrace frame back to the let_it_be(:NAME) declaration whose subject was mutated. Detect dependency chains: e.g. let_it_be(:award_emoji) { create(:award_emoji, awardable: note) } resolves to both :award_emoji and :note.
  4. Rewrite each offending declaration with freeze: false via a Prism AST patcher (idempotent; preserves existing positional + keyword args).
  5. Re-run the previously-failing examples; iterate up to 3 times if new FrozenErrors surface.
  6. Discard the freeze fixture; keep only the spec edits in the commit.

In total this MR resolves 1343 FrozenError(s) that would surface today if let_it_be defaulted to freeze: true.

Sample FrozenError traces from this rollup

ee/spec/requests/api/ai/duo_workflows/cascading_settings_spec.rb (sample of 10 failure(s)):

Duo Workflows endpoints with cascading settings POST /api/v4/ai/duo_workflows/direct_access when subgroup overrides tool_approval_for_session_enabled to false filters tool_call_approval out of server_capabilities using the subgroup setting
./ee/spec/requests/api/ai/duo_workflows/cascading_settings_spec.rb:273:in `block (4 levels) in <top (required)>'

Duo Workflows endpoints with cascading settings POST /api/v4/ai/duo_workflows/direct_access when subgroup overrides tool_approval_for_session_enabled to true while root is false keeps tool_call_approval because the subgroup override is honored
./ee/spec/requests/api/ai/duo_workflows/cascading_settings_spec.rb:291:in `block (4 levels) in <top (required)>'

ee/spec/requests/api/ai/duo_workflows/workflows_internal_spec.rb (sample of 58 failure(s)):

API::Ai::DuoWorkflows::WorkflowsInternal POST /ai/duo_workflows/workflows/:id/checkpoints allows creating multiple checkpoints for a workflow
./ee/spec/requests/api/ai/duo_workflows/workflows_internal_spec.rb:10:in `block (2 levels) in <top (required)>'

API::Ai::DuoWorkflows::WorkflowsInternal POST /ai/duo_workflows/workflows/:id/checkpoints fails if the thread_ts is an empty string
./ee/spec/requests/api/ai/duo_workflows/workflows_internal_spec.rb:10:in `block (2 levels) in <top (required)>'

ee/spec/requests/api/ai/third_party_agents_spec.rb (sample of 10 failure(s)):

API::Ai::ThirdPartyAgents POST /ai/third_party_agents/direct_access when feature flag is disabled returns 404
./ee/spec/requests/api/ai/third_party_agents_spec.rb:12:in `block (2 levels) in <top (required)>'

API::Ai::ThirdPartyAgents POST /ai/third_party_agents/direct_access when user is not logged in returns 401 unauthorized
./ee/spec/requests/api/ai/third_party_agents_spec.rb:12:in `block (2 levels) in <top (required)>'

(+ 100 more file(s) with FrozenError traces; full set captured in the harness logs.)

How a reviewer can spot-check

Every change in this MR is one of:

-    let_it_be(:foo) { ... }
+    let_it_be(:foo, freeze: false) { ... }

or

-    let_it_be(:foo, trait, attr: val) { ... }
+    let_it_be(:foo, trait, attr: val, freeze: false) { ... }

A git diff master..HEAD should show only freeze: false keyword arg insertions in let_it_be(...) calls.

References

  • #600267 (tracking issue)
  • !71373 (original freeze-default attempt)
  • !234596 (RSpec/LetItBeImmutable cop, parent rollout)

Merge request reports

Loading