From 28e17d0d7178b26a926085d74ea9b3ae62d88a3d Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Fri, 8 May 2020 11:07:07 +0200 Subject: [PATCH] Add Language Serializer This allows us to side-load the menu items belonging to a page by doing: GET /jsonapi/pages?include=language.menu_items --- .../alchemy/json_api/language_serializer.rb | 28 ++++++++++ .../alchemy/json_api/page_serializer.rb | 2 + .../json_api/language_serializer_spec.rb | 55 +++++++++++++++++++ .../alchemy/json_api/page_serializer_spec.rb | 1 + 4 files changed, 86 insertions(+) create mode 100644 app/serializers/alchemy/json_api/language_serializer.rb create mode 100644 spec/serializers/alchemy/json_api/language_serializer_spec.rb diff --git a/app/serializers/alchemy/json_api/language_serializer.rb b/app/serializers/alchemy/json_api/language_serializer.rb new file mode 100644 index 0000000..db78981 --- /dev/null +++ b/app/serializers/alchemy/json_api/language_serializer.rb @@ -0,0 +1,28 @@ +module Alchemy + module JsonApi + class LanguageSerializer + include FastJsonapi::ObjectSerializer + attributes( + :name, + :language_code, + :country_code, + :locale + ) + + has_many :menu_items, record_type: :node, serializer: NodeSerializer, id_method_name: :node_ids + has_many :menus, record_type: :node, serializer: NodeSerializer do |language| + language.nodes.select { |n| n.parent.nil? } + end + has_many :pages + has_one :root_page, record_type: :page, serializer: PageSerializer do |language| + language.root_page + end + + with_options if: -> (_, params) { params[:admin] == true } do + attribute :created_at + attribute :updated_at + attribute :public + end + end + end +end diff --git a/app/serializers/alchemy/json_api/page_serializer.rb b/app/serializers/alchemy/json_api/page_serializer.rb index d884b7e..faa82f0 100644 --- a/app/serializers/alchemy/json_api/page_serializer.rb +++ b/app/serializers/alchemy/json_api/page_serializer.rb @@ -14,6 +14,8 @@ class PageSerializer :updated_at, ) + belongs_to :language + has_many :elements has_many :all_elements, record_type: :element, serializer: ElementSerializer diff --git a/spec/serializers/alchemy/json_api/language_serializer_spec.rb b/spec/serializers/alchemy/json_api/language_serializer_spec.rb new file mode 100644 index 0000000..763f06d --- /dev/null +++ b/spec/serializers/alchemy/json_api/language_serializer_spec.rb @@ -0,0 +1,55 @@ +require "rails_helper" +require "alchemy/test_support/factories/language_factory" +require "alchemy/test_support/factories/page_factory" +require "alchemy/test_support/factories/node_factory" + +RSpec.describe Alchemy::JsonApi::LanguageSerializer do + let(:language) do + FactoryBot.create( + :alchemy_language, + country_code: "DE", + language_code: "de" + ) + end + let(:options) { {} } + + subject(:serializer) { described_class.new(language, options) } + + describe "#to_serializable_hash" do + subject { serializer.serializable_hash } + + it "has the right keys and values" do + attributes = subject[:data][:attributes] + expect(attributes[:name]).to eq("Deutsch") + expect(attributes[:language_code]).to eq("de") + expect(attributes[:country_code]).to eq("DE") + expect(attributes[:locale]).to eq("de") + end + + context "with admin set to true" do + let(:options) { {params: {admin: true}} } + + it "includes admin-only attributes" do + attributes = subject[:data][:attributes] + expect(attributes[:created_at]).to be_present + expect(attributes[:updated_at]).to be_present + expect(attributes[:public]).to be true + end + end + end + + describe "relationships" do + let!(:root_page) { FactoryBot.create(:alchemy_page, :language_root, language: language) } + let!(:menu) { FactoryBot.create(:alchemy_node, language: language) } + let!(:menu_node) { FactoryBot.create(:alchemy_node, language: language, parent: menu) } + + subject { serializer.serializable_hash[:data][:relationships] } + + it "has the right keys and values" do + expect(subject[:root_page]).to eq(data: { id: root_page.id.to_s, type: :page }) + expect(subject[:pages]).to eq(data: [{ id: root_page.id.to_s, type: :page }]) + expect(subject[:menus]).to eq(data: [{ id: menu.id.to_s, type: :node }]) + expect(subject[:menu_items]).to eq(data: [{ id: menu.id.to_s, type: :node }, { id: menu_node.id.to_s, type: :node}]) + end + end +end diff --git a/spec/serializers/alchemy/json_api/page_serializer_spec.rb b/spec/serializers/alchemy/json_api/page_serializer_spec.rb index bf24413..c9af953 100644 --- a/spec/serializers/alchemy/json_api/page_serializer_spec.rb +++ b/spec/serializers/alchemy/json_api/page_serializer_spec.rb @@ -62,6 +62,7 @@ it "has the right keys and values" do expect(subject[:elements]).to eq(data: [{ id: element.id.to_s, type: :element }]) expect(subject[:all_elements]).to eq(data: [{ id: element.id.to_s, type: :element }]) + expect(subject[:language]).to eq(data: { id: page.language_id.to_s, type: :language }) end end end