diff --git a/.gitignore b/.gitignore index ad06c5c..2ec588f 100644 --- a/.gitignore +++ b/.gitignore @@ -10,5 +10,6 @@ spec/dummy/db/development.sqlite3 spec/dummy/db/schema.rb spec/dummy/db/migrate spec/dummy/db/*.sqlite3 +spec/dummy/public Gemfile.lock .ruby-version diff --git a/app/controllers/alchemy/json_api/base_controller.rb b/app/controllers/alchemy/json_api/base_controller.rb index e4955b3..c89399a 100644 --- a/app/controllers/alchemy/json_api/base_controller.rb +++ b/app/controllers/alchemy/json_api/base_controller.rb @@ -6,6 +6,7 @@ class BaseController < ::ApplicationController include JSONAPI::Fetching include JSONAPI::Errors include JSONAPI::Filtering + include JSONAPI::Pagination end end end diff --git a/app/controllers/alchemy/json_api/pages_controller.rb b/app/controllers/alchemy/json_api/pages_controller.rb index 1a0a7c5..ffbda0f 100644 --- a/app/controllers/alchemy/json_api/pages_controller.rb +++ b/app/controllers/alchemy/json_api/pages_controller.rb @@ -8,7 +8,9 @@ def index allowed = [:page_layout] jsonapi_filter(page_scope, allowed) do |filtered| - render jsonapi: filtered.result + jsonapi_paginate(filtered.result) do |paginated| + render jsonapi: paginated + end end end @@ -18,6 +20,15 @@ def show private + def jsonapi_meta(pages) + pagination = jsonapi_pagination_meta(pages) + + { + pagination: pagination.presence, + total: page_scope.count + }.compact + end + def load_page @page = load_page_by_id || load_page_by_urlname || raise(ActiveRecord::RecordNotFound) end diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 0000000..a6c7852 --- /dev/null +++ b/bin/rspec @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +# frozen_string_literal: true + +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require "pathname" +ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +bundle_binstub = File.expand_path("../bundle", __FILE__) + +if File.file?(bundle_binstub) + if File.read(bundle_binstub, 300) =~ /This file was generated by Bundler/ + load(bundle_binstub) + else + abort("Your `bin/bundle` was not generated by Bundler, so this binstub cannot run. +Replace `bin/bundle` by running `bundle binstubs bundler --force`, then run this command again.") + end +end + +require "rubygems" +require "bundler/setup" + +load Gem.bin_path("rspec-core", "rspec") diff --git a/spec/requests/alchemy/json_api/layout_pages_spec.rb b/spec/requests/alchemy/json_api/layout_pages_spec.rb index f43d7cf..c48b0fc 100644 --- a/spec/requests/alchemy/json_api/layout_pages_spec.rb +++ b/spec/requests/alchemy/json_api/layout_pages_spec.rb @@ -56,16 +56,40 @@ 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) } + context "with contentpages and unpublished layout 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)) + it "returns only public layout pages" 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 + + context "with pagination params" do + before do + FactoryBot.create_list(:alchemy_page, 3, :layoutpage, :public) + end + + it "returns paginated result" do + get alchemy_json_api.layout_pages_path(page: { number: 2, size: 1 }) + document = JSON.parse(response.body) + expect(document["data"].length).to eq(1) + expect(document["meta"]).to eq({ + "pagination" => { + "current" => 2, + "first" => 1, + "last" => 3, + "next" => 3, + "prev" => 1, + }, + "total" => 3, + }) + end end end end diff --git a/spec/requests/alchemy/json_api/pages_spec.rb b/spec/requests/alchemy/json_api/pages_spec.rb index dc79de1..b2856e9 100644 --- a/spec/requests/alchemy/json_api/pages_spec.rb +++ b/spec/requests/alchemy/json_api/pages_spec.rb @@ -59,16 +59,40 @@ end describe "GET /alchemy/json_api/pages" do - let!(:layoutpage) { FactoryBot.create(:alchemy_page, :layoutpage, :public) } - let!(:non_public_page) { FactoryBot.create(:alchemy_page) } - let!(:public_page) { FactoryBot.create(:alchemy_page, :public) } + context "with layoutpages and unpublished pages" do + let!(:layoutpage) { FactoryBot.create(:alchemy_page, :layoutpage, :public) } + let!(:non_public_page) { FactoryBot.create(:alchemy_page) } + let!(:public_page) { FactoryBot.create(:alchemy_page, :public) } - it "displays the layoutpage and the public page" do - get alchemy_json_api.pages_path - document = JSON.parse(response.body) - 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)) + it "returns public content pages only" do + get alchemy_json_api.pages_path + document = JSON.parse(response.body) + 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 + end + + context "with pagination params" do + before do + FactoryBot.create_list(:alchemy_page, 3, :public) + end + + it "returns paginated result" do + get alchemy_json_api.pages_path(page: { number: 2, size: 1 }) + document = JSON.parse(response.body) + expect(document["data"].length).to eq(1) + expect(document["meta"]).to eq({ + "pagination" => { + "current" => 2, + "first" => 1, + "last" => 4, + "next" => 3, + "prev" => 1, + }, + "total" => 4, + }) + end end end end