From 9a5651a90011d98c3d9541010af9389f2fb7a017 Mon Sep 17 00:00:00 2001
From: Brian Williams <bwilliams@gitlab.com>
Date: Thu, 22 Feb 2024 11:48:34 -0600
Subject: [PATCH] Ensure Event#data has indifferent access

Currently, events have indifferent access when being consumed but not
when being published. This caused a bug when trying to access event data
in a `store.subscribe if:` lambda.
---
 .../process_archived_events_worker_spec.rb               | 4 ++++
 .../process_transfer_events_worker_spec.rb               | 5 +++++
 lib/gitlab/event_store/event.rb                          | 2 +-
 lib/gitlab/event_store/subscriber.rb                     | 2 +-
 spec/lib/gitlab/event_store/event_spec.rb                | 9 +++++++--
 spec/support/matchers/event_store.rb                     | 2 +-
 6 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/ee/spec/workers/vulnerabilities/process_archived_events_worker_spec.rb b/ee/spec/workers/vulnerabilities/process_archived_events_worker_spec.rb
index 61c53db9730f5..6d8a328ca4d27 100644
--- a/ee/spec/workers/vulnerabilities/process_archived_events_worker_spec.rb
+++ b/ee/spec/workers/vulnerabilities/process_archived_events_worker_spec.rb
@@ -17,6 +17,10 @@
     })
   end
 
+  before do
+    stub_feature_flags(update_vuln_reads_archived_via_event: [project, other_project, project_without_vulnerabilities])
+  end
+
   it_behaves_like 'worker with data consistency', described_class, data_consistency: :sticky
 
   subject(:use_event) { consume_event(subscriber: described_class, event: event) }
diff --git a/ee/spec/workers/vulnerabilities/process_transfer_events_worker_spec.rb b/ee/spec/workers/vulnerabilities/process_transfer_events_worker_spec.rb
index ac73f05735490..c11b606613dfc 100644
--- a/ee/spec/workers/vulnerabilities/process_transfer_events_worker_spec.rb
+++ b/ee/spec/workers/vulnerabilities/process_transfer_events_worker_spec.rb
@@ -27,6 +27,11 @@
     })
   end
 
+  before do
+    stub_feature_flags(update_vuln_reads_traversal_ids_via_event: [project, other_project,
+      project_without_vulnerabilities, group])
+  end
+
   it_behaves_like 'worker with data consistency', described_class, data_consistency: :always
 
   subject(:use_event) { consume_event(subscriber: described_class, event: event) }
diff --git a/lib/gitlab/event_store/event.rb b/lib/gitlab/event_store/event.rb
index aecb4fd17c376..8458f6354721e 100644
--- a/lib/gitlab/event_store/event.rb
+++ b/lib/gitlab/event_store/event.rb
@@ -36,7 +36,7 @@ class << self
       def initialize(data:)
         validate_schema!
         validate_data!(data)
-        @data = data
+        @data = data.with_indifferent_access
       end
 
       def schema
diff --git a/lib/gitlab/event_store/subscriber.rb b/lib/gitlab/event_store/subscriber.rb
index 81770624cd9ca..9445d37d25af3 100644
--- a/lib/gitlab/event_store/subscriber.rb
+++ b/lib/gitlab/event_store/subscriber.rb
@@ -43,7 +43,7 @@ def handle_event(event)
       private
 
       def construct_event(event_type, event_data)
-        event_type.new(data: event_data.with_indifferent_access)
+        event_type.new(data: event_data)
       end
     end
   end
diff --git a/spec/lib/gitlab/event_store/event_spec.rb b/spec/lib/gitlab/event_store/event_spec.rb
index 367b333402037..a4a4e3de9925f 100644
--- a/spec/lib/gitlab/event_store/event_spec.rb
+++ b/spec/lib/gitlab/event_store/event_spec.rb
@@ -7,7 +7,7 @@
 RSpec.describe Gitlab::EventStore::Event, feature_category: :shared do
   let(:event_class) { stub_const('TestEvent', Class.new(described_class)) }
   let(:event) { event_class.new(data: data) }
-  let(:data) { { project_id: 123, project_path: 'org/the-project' } }
+  let(:data) { { 'project_id' => 123, 'project_path' => 'org/the-project' } }
 
   context 'when schema is not defined' do
     it 'raises an error on initialization' do
@@ -31,6 +31,11 @@ def schema
       end
     end
 
+    it 'returns data with indifferent access' do
+      expect(event.data[:project_id]).to eq(123)
+      expect(event.data['project_id']).to eq(123)
+    end
+
     describe 'schema validation' do
       context 'when data matches the schema' do
         it 'initializes the event correctly' do
@@ -39,7 +44,7 @@ def schema
       end
 
       context 'when required properties are present as well as unknown properties' do
-        let(:data) { { project_id: 123, unknown_key: 'unknown_value' } }
+        let(:data) { { 'project_id' => 123, 'unknown_key' => 'unknown_value' } }
 
         it 'initializes the event correctly' do
           expect(event.data).to eq(data)
diff --git a/spec/support/matchers/event_store.rb b/spec/support/matchers/event_store.rb
index 582ea20218712..a074e96ed0e74 100644
--- a/spec/support/matchers/event_store.rb
+++ b/spec/support/matchers/event_store.rb
@@ -31,7 +31,7 @@ def match_data?(actual, expected)
   end
 
   chain :with do |expected_data|
-    @expected_data = expected_data
+    @expected_data = expected_data.with_indifferent_access
   end
 
   failure_message do
-- 
GitLab