Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FI-1819: Make headers unique #298

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
40 changes: 40 additions & 0 deletions lib/inferno/db/migrations/009_make_headers_unique.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
Sequel.migration do
change do
create_table :unique_headers do
column :id, String, primary_key: true, null: false, size: 36
column :type, String, size: 10 # request / response
column :name, String, size: 255
column :value, String, text: true

index [:type, :name, :value], unique: true
end

create_table :requests_unique_headers do
foreign_key :unique_headers_id, :unique_headers, index: true, type: String, null: false, size: 36, key: [:id]
foreign_key :requests_id, :requests, index: true, type: Integer, null: false, size: 36, key: [:index]
index [:requests_id, :unique_headers_id], unique: true
end

headers_table = self[:headers]
unique_headers_table = self[:unique_headers]
join_table = self[:requests_unique_headers]

headers_table.order(:id).paged_each do |header|
type = header[:type]
name = header[:name]
value = header[:value]
request_id = header[:request_id]

unique_header_id = unique_headers_table.where(type:, name:, value:).get(:id)

if unique_header_id.blank?
unique_header_id = SecureRandom.uuid
unique_headers_table.insert(id: unique_header_id, type:, name:, value:)
end

join_table.insert(requests_id: request_id, unique_headers_id: unique_header_id)
end

drop_table :headers
end
end
31 changes: 20 additions & 11 deletions lib/inferno/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,17 @@
primary_key [:id]
end

create_table(:unique_headers, :ignore_index_errors=>true) do
String :id, :size=>36, :null=>false
String :type, :size=>10
String :name, :size=>255
String :value, :text=>true

primary_key [:id]

index [:type, :name, :value], :unique=>true
end

create_table(:session_data, :ignore_index_errors=>true) do
String :id, :size=>255, :null=>false
foreign_key :test_session_id, :test_sessions, :type=>String, :size=>36, :null=>false, :key=>[:id]
Expand Down Expand Up @@ -103,23 +114,21 @@
index [:test_session_id, :name]
end

create_table(:headers, :ignore_index_errors=>true) do
String :id, :size=>36, :null=>false
foreign_key :request_id, :requests, :null=>false, :key=>[:index]
String :type, :size=>255, :null=>false
String :name, :size=>255, :null=>false
String :value, :text=>true

index [:id]
index [:request_id]
end

create_table(:requests_results, :ignore_index_errors=>true) do
foreign_key :results_id, :results, :type=>String, :size=>36, :null=>false, :key=>[:id]
foreign_key :requests_id, :requests, :null=>false, :key=>[:index]

index [:requests_id]
index [:results_id]
end

create_table(:requests_unique_headers, :ignore_index_errors=>true) do
foreign_key :unique_headers_id, :unique_headers, :type=>String, :size=>36, :null=>false, :key=>[:id]
foreign_key :requests_id, :requests, :null=>false, :key=>[:index]

index [:requests_id]
index [:requests_id, :unique_headers_id], :unique=>true
index [:unique_headers_id]
end
end
end
15 changes: 9 additions & 6 deletions lib/inferno/repositories/headers.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,21 @@
module Inferno
module Repositories
class Headers < Repository
def self.table_name
:unique_headers
end

class Model < Sequel::Model(db)
many_to_one :request, class: 'Inferno::Repositories::Requests::Model', key: :request_id
many_to_many :request,
class: 'Inferno::Repositories::Requests::Model',
join_table: :requests_unique_headers,
left_key: :unique_headers_id,
right_key: :requests_id

def before_create
self.id = SecureRandom.uuid
super
end

def validate
super
errors.add(:request_id, 'must be present') if request_id.blank?
end
end
end
end
Expand Down
35 changes: 28 additions & 7 deletions lib/inferno/repositories/requests.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ class Requests < Repository
def create(params)
request = self.class::Model.create(db_params(params))

request_headers = (params[:request_headers] || []).map do |header|
request.add_header(header.merge(request_id: request.index, type: 'request'))
request_headers = (params[:request_headers] || []).map do |header_hash|
request.add_header(header_hash.merge(type: 'request'))
end
response_headers = (params[:response_headers] || []).map do |header|
request.add_header(header.merge(request_id: request.index, type: 'response'))
response_headers = (params[:response_headers] || []).map do |header_hash|
request.add_header(header_hash.merge(type: 'response'))
end

headers = (request_headers + response_headers).map { |header| headers_repo.build_entity(header.to_hash) }
Expand Down Expand Up @@ -73,9 +73,17 @@ def json_serializer_options
end

class Model < Sequel::Model(db)
many_to_many :result, class: 'Inferno::Repositories::Results::Model', join_table: :requests_results,
left_key: :request_id, right_key: :result_id
one_to_many :headers, class: 'Inferno::Repositories::Headers::Model', key: :request_id
many_to_many :result,
class: 'Inferno::Repositories::Results::Model',
join_table: :requests_results,
left_key: :requests_id,
right_key: :results_id
many_to_many :headers,
class: 'Inferno::Repositories::Headers::Model',
join_table: :requests_unique_headers,
left_key: :requests_id,
right_key: :unique_headers_id,
adder: :add_header

def before_create
self.id = SecureRandom.uuid
Expand All @@ -84,6 +92,19 @@ def before_create
self.updated_at ||= time
super
end

def add_header(header_hash)
Headers::Model.find_or_create(
type: header_hash[:type],
name: header_hash[:name],
value: header_hash[:value]
).tap do |header|
Inferno::Application['db.connection'][:requests_unique_headers].insert(
unique_headers_id: header.id,
requests_id: index
)
end
end
end
end
end
Expand Down
14 changes: 14 additions & 0 deletions spec/inferno/repositories/requests_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,20 @@
expect(response_header.name).to eq('RESPONSE_HEADER_NAME')
expect(response_header.value).to eq('RESPONSE_HEADER_VALUE')
end

it 'does not create duplicate headers' do
repo.create(request_params)
repo.create(request_params)

expect(described_class.new.db.count).to eq(2)
expect(Inferno::Repositories::Headers.new.db.count).to eq(2)

persisted_header_values = Inferno::Repositories::Headers.new.db.all.map do |hash|
hash[:value]
end

expect(persisted_header_values).to match_array(['REQUEST_HEADER_VALUE', 'RESPONSE_HEADER_VALUE'])
end
end

describe '#find' do
Expand Down