Skip to content
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.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 29 additions & 5 deletions app/api/v1/resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,39 @@ class Resources < MountableAPI
desc 'Returns CTIDs of existing resources'
params do
requires :ctids, type: [String], desc: 'CTIDs'
optional :@type, type: String, desc: 'Resource type'
end
post 'check_existence' do
status(:ok)

@envelope_community
.envelope_resources
.not_deleted
.where('resource_id IN (?)', params[:ctids])
.pluck(:resource_id)
resource_types =
if (type = params[:@type]).present?
resolver = CtdlSubclassesResolver.new(envelope_community: @envelope_community)

unless resolver.all_classes.include?(type)
error!(
{ errors: ['@type does not have a valid value'] },
:unprocessable_entity
)
end

resolver.root_class = type

resolver.subclasses.filter_map do |subclass|
@envelope_community
.config
.dig('resource_type', 'values_map', subclass)
end
end

envelope_resources = @envelope_community
.envelope_resources
.not_deleted
.where('resource_id IN (?)', params[:ctids])

envelope_resources.where!(resource_type: resource_types.uniq) unless resource_types.nil?

envelope_resources.pluck(:resource_id)
end

desc 'Returns resources with the given CTIDs or bnodes IDs'
Expand Down
13 changes: 10 additions & 3 deletions app/services/ctdl_subclasses_resolver.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
class CtdlSubclassesResolver # rubocop:todo Style/Documentation
SUBCLASSES_MAP_FILE = MR.root_path.join('fixtures', 'subclasses_map.json')

attr_reader :envelope_community_config, :include_root, :root_class
attr_accessor :root_class
attr_reader :envelope_community_config, :include_root

def initialize(envelope_community:, root_class:, include_root: true)
def initialize(envelope_community:, root_class: nil, include_root: true)
@envelope_community_config = envelope_community.config
@include_root = include_root
@root_class = root_class
end

def all_classes(map = ctdl_subclasses_map)
map.flat_map do |type, submap|
[type, *all_classes(submap)]
end.uniq
end

def subclasses
@subclasses ||= collect_subclasses(initial_map_item) +
(include_root ? [root_class] : [])
(include_root && root_class ? [root_class] : [])
end

def initial_map_item
Expand Down
5 changes: 5 additions & 0 deletions lib/swagger_docs/sections/resources.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ module Resources # rubocop:todo Metrics/ModuleLength, Style/Documentation
key :type, :string
end
end

property :@type do
key :type, :string
key :description, 'CTDL type'
end
end
end

Expand Down
38 changes: 36 additions & 2 deletions spec/api/v1/resources_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@
let(:ctid1) { Faker::Lorem.characters(number: 32) } # rubocop:todo RSpec/IndexedLet
let(:ctid2) { Faker::Lorem.characters(number: 32) } # rubocop:todo RSpec/IndexedLet
let(:ctid3) { Faker::Lorem.characters(number: 32) } # rubocop:todo RSpec/IndexedLet
let(:ctid4) { Faker::Lorem.characters(number: 32) } # rubocop:todo RSpec/IndexedLet

before do
resource1 = attributes_for(:cer_competency_framework, ctid: ctid1)
Expand All @@ -382,6 +383,10 @@
.except(:id)
.stringify_keys

resource4 = attributes_for(:cer_org, ctid: ctid4)
.except(:id)
.stringify_keys

create(
:envelope,
:from_cer,
Expand All @@ -402,12 +407,41 @@
processed_resource: attributes_for(:cer_graph_competency_framework)
.merge(:@graph => [resource3])
)

create(
:envelope,
:from_cer,
processed_resource: attributes_for(:cer_org)
.merge(:@graph => [resource4])
)
end

it 'returns existing CTIDs' do
post '/resources/check_existence', { ctids: [ctid1, ctid2, ctid3] }
# rubocop:todo RSpec/MultipleExpectations
it 'returns existing CTIDs' do # rubocop:todo RSpec/ExampleLength
# rubocop:enable RSpec/MultipleExpectations
post '/resources/check_existence', { ctids: [ctid1, ctid2, ctid3, ctid4] }
expect_status(:ok)
expect(JSON(response.body)).to contain_exactly(ctid1, ctid4)

post '/resources/check_existence',
{ ctids: [ctid1, ctid2, ctid3, ctid4], '@type': 'foobar' }
expect_status(:unprocessable_entity)
expect_json(errors: ['@type does not have a valid value'])

post '/resources/check_existence',
{ ctids: [ctid1, ctid2, ctid3, ctid4], '@type': 'ceasn:CompetencyFramework' }
expect_status(:ok)
expect(JSON(response.body)).to contain_exactly(ctid1)

post '/resources/check_existence',
{ ctids: [ctid1, ctid2, ctid3, ctid4], '@type': 'ceterms:CredentialOrganization' }
expect_status(:ok)
expect(JSON(response.body)).to contain_exactly(ctid4)

post '/resources/check_existence',
{ ctids: [ctid1, ctid2, ctid3, ctid4], '@type': 'ceterms:Organization' }
expect_status(:ok)
expect(JSON(response.body)).to contain_exactly(ctid4)
end
end
# rubocop:enable RSpec/MultipleMemoizedHelpers
Expand Down