From 37bee805f7846aa166caf518ef7219c6d15daf8f Mon Sep 17 00:00:00 2001 From: Martin Meyerhoff Date: Fri, 8 May 2020 11:23:44 +0200 Subject: [PATCH] Add Layout Pages Controller Sometimes we need content pages, sometimes we need layoutpages. For an API consumer, using the Ransack API for this (`filter: { layoutpage_true: "1" }`) is cumbersome and unintuitive. This adds a new controller instead and limits the pages controller to content pages. --- .../json_api/layout_pages_controller.rb | 11 +++ .../alchemy/json_api/pages_controller.rb | 6 +- config/routes.rb | 1 + .../alchemy/json_api/layout_pages_spec.rb | 70 +++++++++++++++++++ spec/requests/alchemy/json_api/pages_spec.rb | 12 +--- 5 files changed, 88 insertions(+), 12 deletions(-) create mode 100644 app/controllers/alchemy/json_api/layout_pages_controller.rb create mode 100644 spec/requests/alchemy/json_api/layout_pages_spec.rb diff --git a/app/controllers/alchemy/json_api/layout_pages_controller.rb b/app/controllers/alchemy/json_api/layout_pages_controller.rb new file mode 100644 index 0000000..2ecad29 --- /dev/null +++ b/app/controllers/alchemy/json_api/layout_pages_controller.rb @@ -0,0 +1,11 @@ +module Alchemy + module JsonApi + class LayoutPagesController < JsonApi::PagesController + private + + def page_scope + base_page_scope.layoutpages + end + end + end +end diff --git a/app/controllers/alchemy/json_api/pages_controller.rb b/app/controllers/alchemy/json_api/pages_controller.rb index 0958a5c..c36642b 100644 --- a/app/controllers/alchemy/json_api/pages_controller.rb +++ b/app/controllers/alchemy/json_api/pages_controller.rb @@ -4,7 +4,7 @@ class PagesController < JsonApi::BaseController before_action :load_page, only: :show def index - allowed = [:page_layout, :layoutpage] + allowed = [:page_layout] jsonapi_filter(page_scope, allowed) do |filtered| render jsonapi: filtered.result @@ -31,6 +31,10 @@ def load_page_by_urlname end def page_scope + base_page_scope.contentpages + end + + def base_page_scope ::Alchemy::Page. with_language(Language.current). published. diff --git a/config/routes.rb b/config/routes.rb index 21e4543..8d8f88d 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ Alchemy::JsonApi::Engine.routes.draw do resources :pages, only: [:show, :index] + resources :layout_pages, only: [:show, :index] end diff --git a/spec/requests/alchemy/json_api/layout_pages_spec.rb b/spec/requests/alchemy/json_api/layout_pages_spec.rb new file mode 100644 index 0000000..3157182 --- /dev/null +++ b/spec/requests/alchemy/json_api/layout_pages_spec.rb @@ -0,0 +1,70 @@ +require 'rails_helper' +require "alchemy/test_support/factories/page_factory" +require "alchemy/test_support/factories/element_factory" + +RSpec.describe "Alchemy::JsonApi::Pages", type: :request do + let(:page) do + FactoryBot.create( + :alchemy_page, + :public, + urlname: nil, + title: "Footer", + layoutpage: true + ) + end + + describe "GET /alchemy/json_api/pages/:id" do + it "gets a valid JSON:API document" do + get alchemy_json_api.layout_page_path(page) + expect(response).to have_http_status(200) + document = JSON.parse(response.body) + expect(document['data']).to have_id(page.id.to_s) + expect(document['data']).to have_type("page") + end + + context 'when requesting a content page' do + let(:page) { FactoryBot.create(:alchemy_page, :public, elements: [element]) } + let(:element) { FactoryBot.create(:alchemy_element, name: "article", autogenerate_contents: true) } + + it "returns a 404" do + get alchemy_json_api.layout_page_path(page) + expect(response).to have_http_status(404) + end + end + + context "when requesting a URL" do + it "finds the page" do + get alchemy_json_api.layout_page_path(page.urlname) + expect(response).to have_http_status(200) + document = JSON.parse(response.body) + expect(document['data']).to have_id(page.id.to_s) + expect(document['data']).to have_type("page") + end + end + + context 'when the language is incorrect' do + let!(:language) { FactoryBot.create(:alchemy_language) } + let!(:other_language) { FactoryBot.create(:alchemy_language, :english) } + let(:page) { FactoryBot.create(:alchemy_page, :public, layoutpage: true, language: other_language) } + + it 'returns a 404' do + get alchemy_json_api.layout_page_path(page.urlname) + expect(response).to have_http_status(404) + end + end + end + + describe "GET /alchemy/json_api/pages" do + let!(:layoutpage) { FactoryBot.create(:alchemy_page, :layoutpage, :public) } + let!(:non_public_layout_page) { FactoryBot.create(:alchemy_page, :layoutpage) } + let!(:public_page) { FactoryBot.create(:alchemy_page, :public) } + + it "displays the layoutpage and the public page" do + get alchemy_json_api.layout_pages_path + document = JSON.parse(response.body) + expect(document['data']).to include(have_id(layoutpage.id.to_s)) + expect(document['data']).not_to include(have_id(non_public_layout_page.id.to_s)) + expect(document['data']).not_to include(have_id(public_page.id.to_s)) + end + end +end diff --git a/spec/requests/alchemy/json_api/pages_spec.rb b/spec/requests/alchemy/json_api/pages_spec.rb index 7b18b2c..b705544 100644 --- a/spec/requests/alchemy/json_api/pages_spec.rb +++ b/spec/requests/alchemy/json_api/pages_spec.rb @@ -65,19 +65,9 @@ it "displays the layoutpage and the public page" do get alchemy_json_api.pages_path document = JSON.parse(response.body) - expect(document['data']).to include(have_id(layoutpage.id.to_s)) + expect(document['data']).not_to include(have_id(layoutpage.id.to_s)) expect(document['data']).not_to include(have_id(non_public_page.id.to_s)) expect(document['data']).to include(have_id(public_page.id.to_s)) end - - context "with a filter parameter" do - it "displays the layoutpage but not the public page" do - get alchemy_json_api.pages_path(filter: {layoutpage_true: "1"}) - document = JSON.parse(response.body) - expect(document['data']).to include(have_id(layoutpage.id.to_s)) - expect(document['data']).not_to include(have_id(non_public_page.id.to_s)) - expect(document['data']).not_to include(have_id(public_page.id.to_s)) - end - end end end