Skip to content
This repository has been archived by the owner on Jan 12, 2021. It is now read-only.

Commit

Permalink
Parse the related link to assign the foreign keys if the data node is…
Browse files Browse the repository at this point in the history
… not returned.
  • Loading branch information
kevintyll committed Dec 9, 2015
1 parent cd9578f commit d29f5a0
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 8 deletions.
25 changes: 22 additions & 3 deletions lib/esp/extensions/active_resource/formats/json_api_format.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ def self.parse_elements(object)

def self.parse_relationships!(object, included)
object.fetch('relationships', {}).each do |assoc, details|
extract_foreign_keys!(object, assoc, details['data'])
extract_foreign_keys!(object, assoc, details)
merge_included_objects!(object, assoc, details['data'], included)
end
end
Expand All @@ -82,15 +82,34 @@ def self.merge_attributes!(object)
object.merge! object.delete('attributes') unless object['attributes'].blank?
end

def self.extract_foreign_keys!(object, assoc, data)
return if data.blank?
def self.extract_foreign_keys!(object, assoc, assoc_details)
data = assoc_details['data']
related_link = assoc_details.fetch('links', {}).fetch('related', {})
if data.present?
parse_data(object, assoc, data)
elsif related_link.present?
parse_related_link(object, assoc, related_link)
end
end

def self.parse_data(object, assoc, data)
if data.is_a? Array
object["#{assoc.singularize}_ids"] = data.map { |d| d['id'] }
else
object["#{assoc}_id"] = data['id']
end
end

def self.parse_related_link(object, assoc, related_link)
# parse the url to get the id if the data node is not returned
related_link.scan(%r{/(\d+)\.json$}) do |id|
object["#{assoc}_id"] = id.first
end
return if object["#{assoc}_id"].present?
uri = URI.parse(related_link)
object["#{assoc.singularize}_ids"] = Rack::Utils.parse_nested_query(CGI.unescape(uri.query)).fetch('filter', {}).fetch('id_in', []) if uri.query.present?
end

def self.merge_included_objects!(object, assoc, data, included)
return if included.blank?
object[assoc] = case data
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class JsonAPIFormatTest < ActiveSupport::TestCase
parsed_json = JSON.parse(json)
stub_request(:get, %r{reports/1/alerts.json*}).to_return(body: json)

alert = ESP::Alert.for_report(1).first
alert = ESP::Alert.for_report(1, include: 'external_accounts,regions,signatures,cloud_trail_events').first

assert_equal parsed_json['included'].detect { |e| e['type'] == 'external_accounts' }['id'], alert.external_account.id
assert_equal parsed_json['included'].detect { |e| e['type'] == 'regions' }['id'], alert.region.id
Expand Down Expand Up @@ -58,6 +58,29 @@ class JsonAPIFormatTest < ActiveSupport::TestCase
teardown do
WebMock.disable_net_connect!
end

should 'merge included objects' do
alert = ESP::Alert.find(1, include: 'external_account,region,signature')

assert_not_nil alert.attributes['external_account']
assert_equal alert.external_account_id, alert.external_account.id
assert_not_nil alert.attributes['region']
assert_equal alert.region_id, alert.region.id
assert_not_nil alert.attributes['signature']
assert_equal alert.signature_id, alert.signature.id
end

should 'assign foreign key for a belongs_to relationship' do
user = ESP::User.last

assert_not_nil user.organization_id
end

should 'assign foreign key for a has_many relationship' do
user = ESP::User.last

assert_not_nil user.sub_organization_ids
end
end
end

Expand Down
8 changes: 4 additions & 4 deletions test/esp/resources/suppression_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -168,31 +168,31 @@ class SuppressionTest < ActiveSupport::TestCase
should 'return regions' do
r = @s.regions

assert_equal @s.relationships.regions.data.map(&:id).sort, r.map(&:id).sort
assert_equal ESP::Region, r.resource_class unless r == []
end
end

context '#external_accounts' do
should 'return external_accounts' do
e = @s.external_accounts

assert_equal @s.relationships.external_accounts.data.map(&:id).sort, e.map(&:id).sort
assert_equal ESP::ExternalAccount, e.resource_class
end
end

context '#signatures' do
should 'return signatures' do
s = @s.signatures

assert_equal @s.relationships.signatures.data.map(&:id).sort, s.map(&:id).sort
assert_equal ESP::Signature, s.resource_class unless s == []
end
end

context '#custom_signatures' do
should 'return custom_signatures' do
cs = @s.custom_signatures

assert_equal @s.relationships.custom_signatures.data.map(&:id).sort, cs.map(&:id).sort
assert_equal ESP::CustomSignature, cs.resource_class unless cs == []
end
end

Expand Down

0 comments on commit d29f5a0

Please sign in to comment.