diff --git a/app/controllers/api/transformation_mappings_controller.rb b/app/controllers/api/transformation_mappings_controller.rb new file mode 100644 index 0000000000..7dae753e74 --- /dev/null +++ b/app/controllers/api/transformation_mappings_controller.rb @@ -0,0 +1,28 @@ +module Api + class TransformationMappingsController < BaseController + def create_resource(_type, _id, data = {}) + raise "Must specify transformation_mapping_items" unless data["transformation_mapping_items"] + TransformationMapping.new(data.except("transformation_mapping_items")).tap do |mapping| + mapping.transformation_mapping_items = create_mapping_items(data["transformation_mapping_items"]) + mapping.save! + end + rescue StandardError => err + raise BadRequestError, "Could not create Transformation Mapping - #{err}" + end + + private + + def create_mapping_items(items) + items.collect do |item| + raise "Must specify source and destination hrefs" unless item["source"] && item["destination"] + TransformationMappingItem.new(:source => fetch_mapping_resource(item["source"]), :destination => fetch_mapping_resource(item["destination"])) + end + end + + def fetch_mapping_resource(href) + resource_href = Api::Href.new(href) + raise "Invalid source or destination type #{resource_href.subject}" unless collection_config.collection?(resource_href.subject) + resource_search(resource_href.subject_id, resource_href.subject, collection_class(resource_href.subject.to_sym)) + end + end +end diff --git a/config/api.yml b/config/api.yml index 6a8f4ee7b3..37bd08fcb2 100644 --- a/config/api.yml +++ b/config/api.yml @@ -2903,6 +2903,24 @@ :delete: - :name: delete :identifier: rbac_tenant_manage_quotas + :transformation_mappings: + :description: Transformation Mappings + :identifier: transformation_mapping + :verbs: *gp + :klass: TransformationMapping + :options: + - :collection + :collection_actions: + :get: + - :name: read + :identifier: transformation_mapping_show_list + :post: + - :name: create + :identifier: transformation_mapping_new + :resource_actions: + :get: + - :name: read + :identifier: transformation_mapping_show :users: :description: Users :identifier: rbac_user diff --git a/spec/requests/transformation_mappings_spec.rb b/spec/requests/transformation_mappings_spec.rb new file mode 100644 index 0000000000..dc1791ba36 --- /dev/null +++ b/spec/requests/transformation_mappings_spec.rb @@ -0,0 +1,146 @@ +describe "Transformation Mappings" do + let(:transformation_mapping) { FactoryGirl.create(:transformation_mapping) } + + describe "GET /api/transformation_mappings" do + context "with an appropriate role" do + it "retrieves transformation mappings with an appropriate role" do + api_basic_authorize(collection_action_identifier(:transformation_mappings, :read, :get)) + + get(api_transformation_mappings_url) + + expect(response).to have_http_status(:ok) + end + end + + context "without an appropriate role" do + it "is forbidden" do + api_basic_authorize + + get(api_transformation_mappings_url) + + expect(response).to have_http_status(:forbidden) + end + end + end + + describe "GET /api/transformation_mappings/:id" do + context "with an appropriate role" do + it "returns the transformation mapping" do + api_basic_authorize(action_identifier(:transformation_mappings, :read, :resource_actions, :get)) + + get(api_transformation_mapping_url(nil, transformation_mapping)) + + expect(response.parsed_body).to include('id' => transformation_mapping.id.to_s) + expect(response).to have_http_status(:ok) + end + end + + context "without an appropriate role" do + it "is forbidden" do + api_basic_authorize + + get(api_transformation_mapping_url(nil, transformation_mapping)) + + expect(response).to have_http_status(:forbidden) + end + end + end + + describe "POST /api/transformation_mappings" do + let(:cluster) { FactoryGirl.create(:ems_cluster) } + let(:cluster2) { FactoryGirl.create(:ems_cluster) } + + context "with an appropriate role" do + it "can create a new transformation mapping" do + api_basic_authorize(collection_action_identifier(:transformation_mappings, :create)) + + new_mapping = {"name" => "new transformation mapping", + "transformation_mapping_items" => [ + { "source" => api_cluster_url(nil, cluster), "destination" => api_cluster_url(nil, cluster2) } + ]} + post(api_transformation_mappings_url, :params => new_mapping) + + expected = { + "results" => [a_hash_including("href" => a_string_including(api_transformation_mappings_url), + "name" => "new transformation mapping")] + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:ok) + end + + it "will raise a bad request if mappings are not specified" do + api_basic_authorize(collection_action_identifier(:transformation_mappings, :create)) + + new_mapping = {"name" => "new transformation mapping"} + post(api_transformation_mappings_url, :params => new_mapping) + + expected = { + "error" => a_hash_including( + "kind" => "bad_request", + "message" => /Must specify transformation_mapping_items/ + ) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:bad_request) + end + + it "will raise a bad request if source and destination are not specified for mappings" do + api_basic_authorize(collection_action_identifier(:transformation_mappings, :create)) + + new_mapping = {"name" => "new transformation mapping", "transformation_mapping_items" => [{}]} + post(api_transformation_mappings_url, :params => new_mapping) + + expected = { + "error" => a_hash_including( + "kind" => "bad_request", + "message" => /Must specify source and destination hrefs/ + ) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:bad_request) + end + + it "will raise a bad request for a bad source or destination" do + api_basic_authorize(collection_action_identifier(:transformation_mappings, :create)) + + new_mapping = {"name" => "new transformation mapping", "transformation_mapping_items" => [{ "source" => "/api/bogus/:id", "destination" => api_cluster_url(nil, cluster2) }]} + post(api_transformation_mappings_url, :params => new_mapping) + + expected = { + "error" => a_hash_including( + "kind" => "bad_request", + "message" => /Invalid source or destination type bogus/ + ) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:bad_request) + end + + it "will raise a bad request for a nonexistent source or destination" do + api_basic_authorize(collection_action_identifier(:transformation_mappings, :create)) + + new_mapping = {"name" => "new transformation mapping", "transformation_mapping_items" => [{ "source" => api_cluster_url(nil, cluster2), "destination" => api_cluster_url(nil, 999_999) }]} + post(api_transformation_mappings_url, :params => new_mapping) + + expected = { + "error" => a_hash_including( + "kind" => "bad_request", + "message" => /Couldn't find EmsCluster with 'id'=999999/ + ) + } + expect(response.parsed_body).to include(expected) + expect(response).to have_http_status(:bad_request) + end + end + + context "without an appropriate role" do + it "is forbidden" do + api_basic_authorize + + get(api_transformation_mapping_url(nil, transformation_mapping)) + + expect(response).to have_http_status(:forbidden) + end + end + end +end