From 11bb885c5e47094c405a9ee87b88bfcfa3877880 Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 09:28:09 +0100 Subject: [PATCH 01/10] add link seralizer/deserializer --- .../data_package/link_deserializer.rb | 10 ++++++++++ .../data_package/link_serializer.rb | 9 +++++++++ .../data_package/link_deserializer_spec.rb | 18 ++++++++++++++++++ .../data_package/link_serializer_spec.rb | 14 ++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 app/deserializers/data_package/link_deserializer.rb create mode 100644 app/serializers/data_package/link_serializer.rb create mode 100644 spec/deserializers/data_package/link_deserializer_spec.rb create mode 100644 spec/serializers/data_package/link_serializer_spec.rb diff --git a/app/deserializers/data_package/link_deserializer.rb b/app/deserializers/data_package/link_deserializer.rb new file mode 100644 index 000000000..18c21d352 --- /dev/null +++ b/app/deserializers/data_package/link_deserializer.rb @@ -0,0 +1,10 @@ +module DataPackage + class LinkDeserializer < BaseDeserializer + def deserialize + return unless @object + { + url: @object["path"] + }.compact + end + end +end diff --git a/app/serializers/data_package/link_serializer.rb b/app/serializers/data_package/link_serializer.rb new file mode 100644 index 000000000..309437c56 --- /dev/null +++ b/app/serializers/data_package/link_serializer.rb @@ -0,0 +1,9 @@ +module DataPackage + class LinkSerializer < BaseSerializer + def serialize + { + path: @object.url + }.compact + end + end +end diff --git a/spec/deserializers/data_package/link_deserializer_spec.rb b/spec/deserializers/data_package/link_deserializer_spec.rb new file mode 100644 index 000000000..28fd608f7 --- /dev/null +++ b/spec/deserializers/data_package/link_deserializer_spec.rb @@ -0,0 +1,18 @@ +require "rails_helper" + +RSpec.describe DataPackage::LinkDeserializer do + context "when parsing a Data Package" do + subject(:deserializer) { described_class.new(object) } + + let(:output) { deserializer.deserialize } + let(:object) do + { + "path" => "http://example.com" + } + end + + it "parses url" do + expect(output[:url]).to eq "http://example.com" + end + end +end diff --git a/spec/serializers/data_package/link_serializer_spec.rb b/spec/serializers/data_package/link_serializer_spec.rb new file mode 100644 index 000000000..8d6e78eaf --- /dev/null +++ b/spec/serializers/data_package/link_serializer_spec.rb @@ -0,0 +1,14 @@ +require "rails_helper" + +RSpec.describe DataPackage::LinkSerializer do + context "when generating an Data Package representation" do + subject(:serializer) { described_class.new(object) } + + let(:output) { serializer.serialize } + let(:object) { create(:link, linkable: create(:model)) } + + it "includes path" do + expect(output[:path]).to eq object.url + end + end +end From a25080f040299c13466941909bdcb50845d6c0bd Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 09:32:45 +0100 Subject: [PATCH 02/10] add custom schema link --- app/serializers/data_package/model_serializer.rb | 1 + spec/serializers/data_package/model_serializer_spec.rb | 8 +++++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/app/serializers/data_package/model_serializer.rb b/app/serializers/data_package/model_serializer.rb index 80e4bd398..77cfef31b 100644 --- a/app/serializers/data_package/model_serializer.rb +++ b/app/serializers/data_package/model_serializer.rb @@ -2,6 +2,7 @@ module DataPackage class ModelSerializer < BaseSerializer def serialize { + "$schema": "https://manyfold.app/profiles/0.0/datapackage.json", name: @object.name.parameterize, title: @object.name, description: [@object.caption, @object.notes].compact.join("\n\n"), diff --git a/spec/serializers/data_package/model_serializer_spec.rb b/spec/serializers/data_package/model_serializer_spec.rb index 5dfcc85f0..4f7d0afb4 100644 --- a/spec/serializers/data_package/model_serializer_spec.rb +++ b/spec/serializers/data_package/model_serializer_spec.rb @@ -98,8 +98,10 @@ expect(output[:contributors]).to be_nil end - it "includes links" - - it "includes collection" + context "with extension fields" do + it "includes link to extension schema" do + expect(output[:"$schema"]).to eq "https://manyfold.app/profiles/0.0/datapackage.json" + end + end end end From 488a0b5ae8b6d2f96b6c20926b82055b4a13e708 Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 09:39:52 +0100 Subject: [PATCH 03/10] Add resource extension fields to datapackages --- .../data_package/model_file_serializer.rb | 8 ++++-- .../model_file_serializer_spec.rb | 27 +++++++++++++++---- 2 files changed, 28 insertions(+), 7 deletions(-) diff --git a/app/serializers/data_package/model_file_serializer.rb b/app/serializers/data_package/model_file_serializer.rb index f5a8483ac..1e5ae5065 100644 --- a/app/serializers/data_package/model_file_serializer.rb +++ b/app/serializers/data_package/model_file_serializer.rb @@ -5,8 +5,12 @@ def serialize { name: @object.basename.parameterize, path: @object.filename, - mediatype: @object.mime_type - } + mediatype: @object.mime_type, + caption: @object.caption, + description: @object.notes, + up: @object.y_up ? "+y" : "+z", + presupported: @object.presupported + }.compact end end end diff --git a/spec/serializers/data_package/model_file_serializer_spec.rb b/spec/serializers/data_package/model_file_serializer_spec.rb index 9d98896ad..5f7bf4825 100644 --- a/spec/serializers/data_package/model_file_serializer_spec.rb +++ b/spec/serializers/data_package/model_file_serializer_spec.rb @@ -5,7 +5,14 @@ subject(:serializer) { described_class.new(object) } let(:output) { serializer.serialize } - let(:object) { create(:model_file, filename: "files/test model.stl") } + let(:object) { + create(:model_file, + filename: "files/test model.stl", + presupported: true, + y_up: true, + caption: "caption goes here", + notes: "description goes here") + } it "includes name" do expect(output[:name]).to eq "test-model" @@ -19,12 +26,22 @@ expect(output[:mediatype]).to eq "model/stl" end - it "includes notes" + context "with extension fields" do + it "includes notes" do + expect(output[:description]).to eq "description goes here" + end - it "includes caption" + it "includes caption" do + expect(output[:caption]).to eq "caption goes here" + end - it "includes presupported flag" + it "includes presupported flag" do + expect(output[:presupported]).to be true + end - it "includes orientation" + it "includes orientation" do + expect(output[:up]).to eq "+y" + end + end end end From 4bc9fab621b7171f644be60dd1f87c8f131c59da Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 09:50:41 +0100 Subject: [PATCH 04/10] separate out description and caption in model serializer --- .../data_package/model_deserializer.rb | 4 ++-- .../data_package/model_serializer.rb | 3 ++- .../data_package/model_deserializer_spec.rb | 5 +++-- .../data_package/model_serializer_spec.rb | 20 ++++++------------- 4 files changed, 13 insertions(+), 19 deletions(-) diff --git a/app/deserializers/data_package/model_deserializer.rb b/app/deserializers/data_package/model_deserializer.rb index f75a46558..81a1a7b60 100644 --- a/app/deserializers/data_package/model_deserializer.rb +++ b/app/deserializers/data_package/model_deserializer.rb @@ -3,8 +3,8 @@ class ModelDeserializer < BaseDeserializer def deserialize { name: @object["title"], - caption: @object["description"].split("\n\n", 2).first, - notes: @object["description"].split("\n\n", 2).last, + caption: @object["caption"], + notes: @object["description"], links_attributes: [{url: @object["homepage"]}], preview_file: @object["image"], tag_list: @object["keywords"], diff --git a/app/serializers/data_package/model_serializer.rb b/app/serializers/data_package/model_serializer.rb index 77cfef31b..575e1602c 100644 --- a/app/serializers/data_package/model_serializer.rb +++ b/app/serializers/data_package/model_serializer.rb @@ -5,7 +5,8 @@ def serialize "$schema": "https://manyfold.app/profiles/0.0/datapackage.json", name: @object.name.parameterize, title: @object.name, - description: [@object.caption, @object.notes].compact.join("\n\n"), + caption: @object.caption, + description: @object.notes, homepage: Rails.application.routes.url_helpers.url_for(@object), image: @object.preview_file&.is_image? ? @object.preview_file.filename : nil, keywords: @object.tag_list, diff --git a/spec/deserializers/data_package/model_deserializer_spec.rb b/spec/deserializers/data_package/model_deserializer_spec.rb index a1364162a..36b409450 100644 --- a/spec/deserializers/data_package/model_deserializer_spec.rb +++ b/spec/deserializers/data_package/model_deserializer_spec.rb @@ -12,7 +12,8 @@ "homepage" => "https://example.com", "image" => "images/pic.png", "keywords" => ["fantasy", "wizard"], - "description" => "caption\n\nand multiline\nnote", + "caption" => "caption", + "description" => "multiline\nnote", "licenses" => [ { "name" => "MIT", @@ -44,7 +45,7 @@ end it "parses notes" do - expect(output[:notes]).to eq "and multiline\nnote" + expect(output[:notes]).to eq "multiline\nnote" end it "parses homepage link" do diff --git a/spec/serializers/data_package/model_serializer_spec.rb b/spec/serializers/data_package/model_serializer_spec.rb index 4f7d0afb4..c0c632bf4 100644 --- a/spec/serializers/data_package/model_serializer_spec.rb +++ b/spec/serializers/data_package/model_serializer_spec.rb @@ -21,19 +21,7 @@ expect(output[:title]).to eq "Test Model" end - it "includes caption and notes in description" do - expect(output[:description]).to eq "#{object.caption} - -#{object.notes}" - end - - it "includes just caption if there's no notes" do - object.notes = nil - expect(output[:description]).to eq object.caption - end - - it "includes just notes if there's no caption" do - object.caption = nil + it "includes notes in description field" do expect(output[:description]).to eq object.notes end @@ -100,7 +88,11 @@ context "with extension fields" do it "includes link to extension schema" do - expect(output[:"$schema"]).to eq "https://manyfold.app/profiles/0.0/datapackage.json" + expect(output[:$schema]).to eq "https://manyfold.app/profiles/0.0/datapackage.json" + end + + it "includes caption" do + expect(output[:caption]).to eq object.caption end end end From b50d890271dc593a9a878726871b9716c20f7292 Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 09:58:02 +0100 Subject: [PATCH 05/10] don't include self link for found creators --- app/deserializers/data_package/creator_deserializer.rb | 5 +++-- .../deserializers/data_package/creator_deserializer_spec.rb | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/deserializers/data_package/creator_deserializer.rb b/app/deserializers/data_package/creator_deserializer.rb index 46d97d405..42be5309b 100644 --- a/app/deserializers/data_package/creator_deserializer.rb +++ b/app/deserializers/data_package/creator_deserializer.rb @@ -10,8 +10,9 @@ def deserialize end rescue ActionController::RoutingError, ActiveRecord::RecordNotFound end - attributes[:links_attributes] = [{url: @object["path"]}] unless attributes.has_key?(:creator_id) - attributes + attributes[:links_attributes] = [] + attributes[:links_attributes] << {url: @object["path"]} unless attributes.has_key?(:id) + attributes.compact end end end diff --git a/spec/deserializers/data_package/creator_deserializer_spec.rb b/spec/deserializers/data_package/creator_deserializer_spec.rb index e686843cf..cba607543 100644 --- a/spec/deserializers/data_package/creator_deserializer_spec.rb +++ b/spec/deserializers/data_package/creator_deserializer_spec.rb @@ -24,6 +24,10 @@ expect(output[:id]).to eq creator.id end + it "does not add main detected path as link" do + expect(output[:links_attributes]).not_to include({url: "http://localhost:3214/creators/#{creator.to_param}"}) + end + it "parses links" it "parses notes" @@ -44,7 +48,7 @@ expect(output[:name]).to eq "Bruce Wayne" end - it "extracts links" do + it "includes main path as link" do expect(output[:links_attributes]).to include({ url: "http://example.com/bruce-wayne" }) From a49c6b55602d1397ab78a0ecdfd7c551ee4bb22b Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 10:18:50 +0100 Subject: [PATCH 06/10] add extensions data for creator records --- .../data_package/creator_deserializer.rb | 8 +++++-- .../data_package/creator_serializer.rb | 7 +++++-- .../data_package/creator_deserializer_spec.rb | 21 +++++++++++++++---- .../data_package/creator_serializer_spec.rb | 21 +++++++++++++++---- 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/app/deserializers/data_package/creator_deserializer.rb b/app/deserializers/data_package/creator_deserializer.rb index 42be5309b..11c3659d8 100644 --- a/app/deserializers/data_package/creator_deserializer.rb +++ b/app/deserializers/data_package/creator_deserializer.rb @@ -2,7 +2,11 @@ module DataPackage class CreatorDeserializer < BaseDeserializer def deserialize return unless @object && @object["roles"]&.include?("creator") - attributes = {name: @object["title"]} + attributes = { + name: @object["title"], + caption: @object["caption"], + notes: @object["description"] + } begin route_options = Rails.application.routes.recognize_path(@object["path"]) if route_options[:controller] == "creators" @@ -10,7 +14,7 @@ def deserialize end rescue ActionController::RoutingError, ActiveRecord::RecordNotFound end - attributes[:links_attributes] = [] + attributes[:links_attributes] = @object["links"]&.map { |it| LinkDeserializer.new(it).deserialize } || [] attributes[:links_attributes] << {url: @object["path"]} unless attributes.has_key?(:id) attributes.compact end diff --git a/app/serializers/data_package/creator_serializer.rb b/app/serializers/data_package/creator_serializer.rb index 78c32dbf4..a8b254408 100644 --- a/app/serializers/data_package/creator_serializer.rb +++ b/app/serializers/data_package/creator_serializer.rb @@ -4,8 +4,11 @@ def serialize { title: @object.name, path: Rails.application.routes.url_helpers.url_for(@object), - roles: ["creator"] - } + roles: ["creator"], + caption: @object.caption, + description: @object.notes, + links: @object.links.map { |it| LinkSerializer.new(it).serialize } + }.compact end end end diff --git a/spec/deserializers/data_package/creator_deserializer_spec.rb b/spec/deserializers/data_package/creator_deserializer_spec.rb index cba607543..60e74179a 100644 --- a/spec/deserializers/data_package/creator_deserializer_spec.rb +++ b/spec/deserializers/data_package/creator_deserializer_spec.rb @@ -12,7 +12,14 @@ { "title" => creator.name, "path" => "http://localhost:3214/creators/#{creator.to_param}", - "roles" => ["creator"] + "roles" => ["creator"], + "caption" => "caption goes here", + "description" => "description goes here", + "links" => [ + { + "path" => "http://example.com" + } + ] } end @@ -28,11 +35,17 @@ expect(output[:links_attributes]).not_to include({url: "http://localhost:3214/creators/#{creator.to_param}"}) end - it "parses links" + it "parses links" do + expect(output[:links_attributes]).to include({url: "http://example.com"}) + end - it "parses notes" + it "parses notes" do + expect(output[:notes]).to eq "description goes here" + end - it "parses caption" + it "parses caption" do + expect(output[:caption]).to eq "caption goes here" + end end context "with a valid creator hosted elsewhere" do diff --git a/spec/serializers/data_package/creator_serializer_spec.rb b/spec/serializers/data_package/creator_serializer_spec.rb index bf29e23f0..b06a77ab2 100644 --- a/spec/serializers/data_package/creator_serializer_spec.rb +++ b/spec/serializers/data_package/creator_serializer_spec.rb @@ -5,7 +5,12 @@ subject(:serializer) { described_class.new(object) } let(:output) { serializer.serialize } - let(:object) { create(:creator) } + let(:object) { + create(:creator, + links_attributes: [{url: "https://example.com"}], + caption: "caption goes here", + notes: "notes go here") + } it "includes name" do expect(output[:title]).to eq object.name @@ -19,10 +24,18 @@ expect(output[:path]).to eq "http://localhost:3214/creators/#{object.to_param}" end - it "includes links" + context "with extension fields" do + it "includes links" do + expect(output.dig(:links, 0, :path)).to be_present + end - it "includes notes" + it "includes caption" do + expect(output[:caption]).to eq object.caption + end - it "includes caption" + it "includes notes" do + expect(output[:description]).to eq object.notes + end + end end end From b45b6004b824d7d22f829c352eedd6065e35e427 Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 10:23:07 +0100 Subject: [PATCH 07/10] add serializer/deserializer for collection data --- .../data_package/collection_deserializer.rb | 22 ++++++ .../data_package/collection_serializer.rb | 13 ++++ .../collection_deserializer_spec.rb | 70 +++++++++++++++++++ .../collection_serializer_spec.rb | 37 ++++++++++ 4 files changed, 142 insertions(+) create mode 100644 app/deserializers/data_package/collection_deserializer.rb create mode 100644 app/serializers/data_package/collection_serializer.rb create mode 100644 spec/deserializers/data_package/collection_deserializer_spec.rb create mode 100644 spec/serializers/data_package/collection_serializer_spec.rb diff --git a/app/deserializers/data_package/collection_deserializer.rb b/app/deserializers/data_package/collection_deserializer.rb new file mode 100644 index 000000000..8484852ba --- /dev/null +++ b/app/deserializers/data_package/collection_deserializer.rb @@ -0,0 +1,22 @@ +module DataPackage + class CollectionDeserializer < BaseDeserializer + def deserialize + return unless @object + attributes = { + name: @object["title"], + caption: @object["caption"], + notes: @object["description"] + } + begin + route_options = Rails.application.routes.recognize_path(@object["path"]) + if route_options[:controller] == "collections" + attributes[:id] = Collection.find_param(route_options[:id]).id + end + rescue ActionController::RoutingError, ActiveRecord::RecordNotFound + end + attributes[:links_attributes] = @object["links"]&.map { |it| LinkDeserializer.new(it).deserialize } || [] + attributes[:links_attributes] << {url: @object["path"]} unless attributes.has_key?(:id) + attributes.compact + end + end +end diff --git a/app/serializers/data_package/collection_serializer.rb b/app/serializers/data_package/collection_serializer.rb new file mode 100644 index 000000000..8f0c6012a --- /dev/null +++ b/app/serializers/data_package/collection_serializer.rb @@ -0,0 +1,13 @@ +module DataPackage + class CollectionSerializer < BaseSerializer + def serialize + { + title: @object.name, + path: Rails.application.routes.url_helpers.url_for(@object), + caption: @object.caption, + description: @object.notes, + links: @object.links.map { |it| LinkSerializer.new(it).serialize } + }.compact + end + end +end diff --git a/spec/deserializers/data_package/collection_deserializer_spec.rb b/spec/deserializers/data_package/collection_deserializer_spec.rb new file mode 100644 index 000000000..778b42055 --- /dev/null +++ b/spec/deserializers/data_package/collection_deserializer_spec.rb @@ -0,0 +1,70 @@ +require "rails_helper" + +RSpec.describe DataPackage::CollectionDeserializer do + context "when parsing a Data Package" do + subject(:deserializer) { described_class.new(object) } + + let(:output) { deserializer.deserialize } + + context "with a valid collection linked to this server" do + let(:collection) { create(:collection) } + let(:object) do + { + "title" => collection.name, + "path" => "http://localhost:3214/collections/#{collection.to_param}", + "caption" => "caption goes here", + "description" => "description goes here", + "links" => [ + { + "path" => "http://example.com" + } + ] + } + end + + it "parses name" do + expect(output[:name]).to eq collection.name + end + + it "matches collection ID" do + expect(output[:id]).to eq collection.id + end + + it "does not add main detected path as link" do + expect(output[:links_attributes]).not_to include({url: "http://localhost:3214/collections/#{collection.to_param}"}) + end + + it "parses links" do + expect(output[:links_attributes]).to include({url: "http://example.com"}) + end + + it "parses notes" do + expect(output[:notes]).to eq "description goes here" + end + + it "parses caption" do + expect(output[:caption]).to eq "caption goes here" + end + end + + context "with a valid collection hosted elsewhere" do + let(:object) do + { + "title" => "Bruce Wayne", + "path" => "http://example.com/bruce-wayne", + "roles" => ["collection"] + } + end + + it "parses name" do + expect(output[:name]).to eq "Bruce Wayne" + end + + it "includes main path as link" do + expect(output[:links_attributes]).to include({ + url: "http://example.com/bruce-wayne" + }) + end + end + end +end diff --git a/spec/serializers/data_package/collection_serializer_spec.rb b/spec/serializers/data_package/collection_serializer_spec.rb new file mode 100644 index 000000000..8e56bd609 --- /dev/null +++ b/spec/serializers/data_package/collection_serializer_spec.rb @@ -0,0 +1,37 @@ +require "rails_helper" + +RSpec.describe DataPackage::CollectionSerializer do + context "when generating an Data Package representation" do + subject(:serializer) { described_class.new(object) } + + let(:output) { serializer.serialize } + let(:object) { + create(:collection, + links_attributes: [{url: "https://example.com"}], + caption: "caption goes here", + notes: "notes go here") + } + + it "includes name" do + expect(output[:title]).to eq object.name + end + + it "includes path" do + expect(output[:path]).to eq "http://localhost:3214/collections/#{object.to_param}" + end + + context "with extension fields" do + it "includes links" do + expect(output.dig(:links, 0, :path)).to be_present + end + + it "includes caption" do + expect(output[:caption]).to eq object.caption + end + + it "includes notes" do + expect(output[:description]).to eq object.notes + end + end + end +end From 12b75e6dc7859b1b4d6355423d714e3a39bc42da Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 10:49:19 +0100 Subject: [PATCH 08/10] add deserialization of modelfile extensions --- .../data_package/model_file_deserializer.rb | 8 +++++-- .../model_file_deserializer_spec.rb | 22 ++++++++++++++----- 2 files changed, 23 insertions(+), 7 deletions(-) diff --git a/app/deserializers/data_package/model_file_deserializer.rb b/app/deserializers/data_package/model_file_deserializer.rb index 19ae55608..aa2efa104 100644 --- a/app/deserializers/data_package/model_file_deserializer.rb +++ b/app/deserializers/data_package/model_file_deserializer.rb @@ -3,8 +3,12 @@ class ModelFileDeserializer < BaseDeserializer def deserialize { filename: @object["path"], - mime_type: @object["mediatype"] - } + mime_type: @object["mediatype"], + caption: @object["caption"], + notes: @object["description"], + presupported: @object["presupported"], + y_up: (@object["up"] == "+y") + }.compact end end end diff --git a/spec/deserializers/data_package/model_file_deserializer_spec.rb b/spec/deserializers/data_package/model_file_deserializer_spec.rb index 154762e59..afecdf03e 100644 --- a/spec/deserializers/data_package/model_file_deserializer_spec.rb +++ b/spec/deserializers/data_package/model_file_deserializer_spec.rb @@ -8,7 +8,11 @@ let(:object) { { "path" => "files/test.stl", - "mediatype" => "model/stl" + "mediatype" => "model/stl", + "caption" => "caption goes here", + "description" => "description goes here", + "up" => "+y", + "presupported" => true } } @@ -20,12 +24,20 @@ expect(output[:mime_type]).to eq "model/stl" end - it "parses notes" + it "parses notes" do + expect(output[:notes]).to eq "description goes here" + end - it "parses caption" + it "parses caption" do + expect(output[:caption]).to eq "caption goes here" + end - it "parses presupported flag" + it "parses presupported flag" do + expect(output[:presupported]).to be true + end - it "parses orientation" + it "parses orientation" do + expect(output[:y_up]).to be true + end end end From d7fddd8e70aebc1220dc06e0f5cba6b221cf71a8 Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 10:53:46 +0100 Subject: [PATCH 09/10] add model extensions to serializer/deserializer --- .../data_package/model_deserializer.rb | 13 ++++++++-- .../data_package/model_serializer.rb | 4 +++- .../data_package/model_deserializer_spec.rb | 24 +++++++++++++++++-- .../data_package/model_serializer_spec.rb | 16 ++++++++++++- 4 files changed, 51 insertions(+), 6 deletions(-) diff --git a/app/deserializers/data_package/model_deserializer.rb b/app/deserializers/data_package/model_deserializer.rb index 81a1a7b60..1da0ca0e6 100644 --- a/app/deserializers/data_package/model_deserializer.rb +++ b/app/deserializers/data_package/model_deserializer.rb @@ -5,13 +5,22 @@ def deserialize name: @object["title"], caption: @object["caption"], notes: @object["description"], - links_attributes: [{url: @object["homepage"]}], + links_attributes: parse_links, preview_file: @object["image"], tag_list: @object["keywords"], license: @object.dig("licenses", 0, "name"), model_files: @object["resources"]&.map { |it| ModelFileDeserializer.new(it).deserialize }, - creator: CreatorDeserializer.new(@object["contributors"]&.find { |it| it["roles"].include?("creator") }).deserialize + creator: CreatorDeserializer.new(@object["contributors"]&.find { |it| it["roles"].include?("creator") }).deserialize, + collection: CollectionDeserializer.new(@object.dig("collections", 0)).deserialize }.compact end + + private + + def parse_links + links = (@object["links"] || []).map { |it| LinkDeserializer.new(it).deserialize } + links << {url: @object["homepage"]} if @object["homepage"] + links + end end end diff --git a/app/serializers/data_package/model_serializer.rb b/app/serializers/data_package/model_serializer.rb index 575e1602c..27ceb35ea 100644 --- a/app/serializers/data_package/model_serializer.rb +++ b/app/serializers/data_package/model_serializer.rb @@ -17,7 +17,9 @@ def serialize }.compact ] : nil), resources: @object.model_files.filter_map { |it| ModelFileSerializer.new(it).serialize }, - contributors: @object.creator ? [CreatorSerializer.new(@object.creator).serialize] : nil + contributors: @object.creator ? [CreatorSerializer.new(@object.creator).serialize] : nil, + collections: @object.collection ? [CollectionSerializer.new(@object.collection).serialize] : nil, + links: @object.links.map { |it| LinkSerializer.new(it).serialize } }.compact end end diff --git a/spec/deserializers/data_package/model_deserializer_spec.rb b/spec/deserializers/data_package/model_deserializer_spec.rb index 36b409450..fc34f6863 100644 --- a/spec/deserializers/data_package/model_deserializer_spec.rb +++ b/spec/deserializers/data_package/model_deserializer_spec.rb @@ -32,6 +32,17 @@ "path" => "http://localhost:3214/creators/bruce-wayne", "roles" => ["creator"] } + ], + "collections" => [ + { + "title" => "Wonderful Toys", + "path" => "http://localhost:3214/collections/abc123" + } + ], + "links" => [ + { + "path" => "https://example.com/other-link" + } ] } end @@ -52,7 +63,9 @@ expect(output[:links_attributes]).to include({url: "https://example.com"}) end - it "parses other links" + it "parses other links" do + expect(output[:links_attributes]).to include({url: "https://example.com/other-link"}) + end it "parses preview image" do expect(output[:preview_file]).to eq "images/pic.png" @@ -79,6 +92,13 @@ expect(output.dig(:creator, :links_attributes, 0, :url)).to eq "http://localhost:3214/creators/bruce-wayne" end - it "parses collection" + it "parses collection ID if collection exists" do + collection = create(:collection, name: "Wonderful Toys", public_id: "abc123") + expect(output.dig(:collection, :id)).to eq collection.id + end + + it "parses collection link if collection doesn't exist" do + expect(output.dig(:collection, :links_attributes, 0, :url)).to eq "http://localhost:3214/collections/abc123" + end end end diff --git a/spec/serializers/data_package/model_serializer_spec.rb b/spec/serializers/data_package/model_serializer_spec.rb index c0c632bf4..d01850afd 100644 --- a/spec/serializers/data_package/model_serializer_spec.rb +++ b/spec/serializers/data_package/model_serializer_spec.rb @@ -6,7 +6,13 @@ let(:output) { serializer.serialize } let(:object) { - m = create(:model, :with_tags, name: "Test Model", creator: create(:creator)) + m = create(:model, :with_tags, + name: "Test Model", + creator: create(:creator), + collection: create(:collection), + links_attributes: [ + {url: "https://example.com"} + ]) image = create(:model_file, filename: "image.png", model: m) m.preview_file = image create(:model_file, filename: "model.stl", model: m) @@ -91,6 +97,14 @@ expect(output[:$schema]).to eq "https://manyfold.app/profiles/0.0/datapackage.json" end + it "includes links" do + expect(output.dig(:links, 0, :path)).to be_present + end + + it "includes collection data" do + expect(output.dig(:collections, 0, :title)).to be_present + end + it "includes caption" do expect(output[:caption]).to eq object.caption end From 7ce3d6bb5ba068bf35db235f43139736cc801a05 Mon Sep 17 00:00:00 2001 From: James Smith Date: Fri, 4 Apr 2025 11:22:30 +0100 Subject: [PATCH 10/10] add sensitive flag to serializers --- app/deserializers/data_package/model_deserializer.rb | 1 + app/serializers/data_package/model_serializer.rb | 1 + spec/deserializers/data_package/model_deserializer_spec.rb | 7 ++++++- spec/serializers/data_package/model_serializer_spec.rb | 5 +++++ 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/app/deserializers/data_package/model_deserializer.rb b/app/deserializers/data_package/model_deserializer.rb index 1da0ca0e6..34e8b7db0 100644 --- a/app/deserializers/data_package/model_deserializer.rb +++ b/app/deserializers/data_package/model_deserializer.rb @@ -8,6 +8,7 @@ def deserialize links_attributes: parse_links, preview_file: @object["image"], tag_list: @object["keywords"], + sensitive: @object["sensitive"], license: @object.dig("licenses", 0, "name"), model_files: @object["resources"]&.map { |it| ModelFileDeserializer.new(it).deserialize }, creator: CreatorDeserializer.new(@object["contributors"]&.find { |it| it["roles"].include?("creator") }).deserialize, diff --git a/app/serializers/data_package/model_serializer.rb b/app/serializers/data_package/model_serializer.rb index 27ceb35ea..4bbff1a29 100644 --- a/app/serializers/data_package/model_serializer.rb +++ b/app/serializers/data_package/model_serializer.rb @@ -17,6 +17,7 @@ def serialize }.compact ] : nil), resources: @object.model_files.filter_map { |it| ModelFileSerializer.new(it).serialize }, + sensitive: @object.sensitive, contributors: @object.creator ? [CreatorSerializer.new(@object.creator).serialize] : nil, collections: @object.collection ? [CollectionSerializer.new(@object.collection).serialize] : nil, links: @object.links.map { |it| LinkSerializer.new(it).serialize } diff --git a/spec/deserializers/data_package/model_deserializer_spec.rb b/spec/deserializers/data_package/model_deserializer_spec.rb index fc34f6863..f399dcd26 100644 --- a/spec/deserializers/data_package/model_deserializer_spec.rb +++ b/spec/deserializers/data_package/model_deserializer_spec.rb @@ -43,7 +43,8 @@ { "path" => "https://example.com/other-link" } - ] + ], + "sensitive" => true } end @@ -100,5 +101,9 @@ it "parses collection link if collection doesn't exist" do expect(output.dig(:collection, :links_attributes, 0, :url)).to eq "http://localhost:3214/collections/abc123" end + + it "parses sensitive flag" do + expect(output[:sensitive]).to be true + end end end diff --git a/spec/serializers/data_package/model_serializer_spec.rb b/spec/serializers/data_package/model_serializer_spec.rb index d01850afd..2f9b23a15 100644 --- a/spec/serializers/data_package/model_serializer_spec.rb +++ b/spec/serializers/data_package/model_serializer_spec.rb @@ -10,6 +10,7 @@ name: "Test Model", creator: create(:creator), collection: create(:collection), + sensitive: true, links_attributes: [ {url: "https://example.com"} ]) @@ -108,6 +109,10 @@ it "includes caption" do expect(output[:caption]).to eq object.caption end + + it "includes sensitive flag" do + expect(output[:sensitive]).to eq object.sensitive + end end end end