From 029209a6349178cdd2c613f5d9fb2985bbfae980 Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Tue, 5 Jul 2022 17:15:38 +0530 Subject: [PATCH] feat: Portal and Category public APIs (#4946) --- .../api/v1/accounts/articles_controller.rb | 3 +- .../api/v1/accounts/portals_controller.rb | 5 +++ .../api/v1/portals/categories_controller.rb | 20 +++++++++++ .../public/api/v1/portals_controller.rb | 11 ++++++ app/models/article.rb | 6 +++- app/models/portal.rb | 2 ++ .../api/v1/kbase/portal/show.json.jbuilder | 1 - .../models/_associated_category.json.jbuilder | 5 +++ .../api/v1/models/_category.json.jbuilder | 22 +++++++++++- .../api/v1/models/_portal.json.jbuilder | 11 ++++-- .../v1/portals/categories/index.json.jbuilder | 3 ++ .../v1/portals/categories/show.json.jbuilder | 1 + .../public/api/v1/portals/index.json.jbuilder | 1 + .../public/api/v1/portals/show.json.jbuilder | 1 + config/routes.rb | 9 ++++- .../v1/accounts/articles_controller_spec.rb | 5 ++- .../v1/portals/categories_controller_spec.rb | 36 +++++++++++++++++++ .../public/api/v1/portals_controller_spec.rb | 21 +++++++++++ 18 files changed, 154 insertions(+), 9 deletions(-) create mode 100644 app/controllers/public/api/v1/portals/categories_controller.rb create mode 100644 app/controllers/public/api/v1/portals_controller.rb delete mode 100644 app/views/public/api/v1/kbase/portal/show.json.jbuilder create mode 100644 app/views/public/api/v1/models/_associated_category.json.jbuilder create mode 100644 app/views/public/api/v1/portals/categories/index.json.jbuilder create mode 100644 app/views/public/api/v1/portals/categories/show.json.jbuilder create mode 100644 app/views/public/api/v1/portals/index.json.jbuilder create mode 100644 app/views/public/api/v1/portals/show.json.jbuilder create mode 100644 spec/controllers/public/api/v1/portals/categories_controller_spec.rb create mode 100644 spec/controllers/public/api/v1/portals_controller_spec.rb diff --git a/app/controllers/api/v1/accounts/articles_controller.rb b/app/controllers/api/v1/accounts/articles_controller.rb index 0037bc405..249352e18 100644 --- a/app/controllers/api/v1/accounts/articles_controller.rb +++ b/app/controllers/api/v1/accounts/articles_controller.rb @@ -11,6 +11,7 @@ class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController def create @article = @portal.articles.create!(article_params) @article.associate_root_article(article_params[:associated_article_id]) + @article.draft! render json: { error: @article.errors.messages }, status: :unprocessable_entity and return unless @article.valid? end @@ -39,7 +40,7 @@ class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController def article_params params.require(:article).permit( - :title, :content, :description, :position, :category_id, :author_id, :associated_article_id + :title, :content, :description, :position, :category_id, :author_id, :associated_article_id, :status ) end diff --git a/app/controllers/api/v1/accounts/portals_controller.rb b/app/controllers/api/v1/accounts/portals_controller.rb index ab4014123..d5b1281bf 100644 --- a/app/controllers/api/v1/accounts/portals_controller.rb +++ b/app/controllers/api/v1/accounts/portals_controller.rb @@ -26,6 +26,11 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController head :ok end + def archive + @portal.update(archive: true) + head :ok + end + private def fetch_portal diff --git a/app/controllers/public/api/v1/portals/categories_controller.rb b/app/controllers/public/api/v1/portals/categories_controller.rb new file mode 100644 index 000000000..cf57d73ff --- /dev/null +++ b/app/controllers/public/api/v1/portals/categories_controller.rb @@ -0,0 +1,20 @@ +class Public::Api::V1::Portals::CategoriesController < PublicController + before_action :set_portal + before_action :set_category, only: [:show] + + def index + @categories = @portal.categories + end + + def show; end + + private + + def set_category + @category = @portal.categories.find_by!(slug: params[:slug]) + end + + def set_portal + @portal = ::Portal.find_by!(slug: params[:portal_slug], archived: false) + end +end diff --git a/app/controllers/public/api/v1/portals_controller.rb b/app/controllers/public/api/v1/portals_controller.rb new file mode 100644 index 000000000..aedf1a09d --- /dev/null +++ b/app/controllers/public/api/v1/portals_controller.rb @@ -0,0 +1,11 @@ +class Public::Api::V1::PortalsController < PublicController + before_action :set_portal + + def show; end + + private + + def set_portal + @portal = ::Portal.find_by!(slug: params[:slug], archived: false) + end +end diff --git a/app/models/article.rb b/app/models/article.rb index a8d356dd1..65482957e 100644 --- a/app/models/article.rb +++ b/app/models/article.rb @@ -53,7 +53,7 @@ class Article < ApplicationRecord validates :title, presence: true validates :content, presence: true - enum status: { draft: 0, published: 1 } + enum status: { draft: 0, published: 1, archived: 2 } scope :search_by_category_slug, ->(category_slug) { where(categories: { slug: category_slug }) if category_slug.present? } scope :search_by_category_locale, ->(locale) { where(categories: { locale: locale }) if locale.present? } @@ -100,6 +100,10 @@ class Article < ApplicationRecord article.associated_article_id || article.id end + def draft! + update(status: :draft) + end + private def ensure_account_id diff --git a/app/models/portal.rb b/app/models/portal.rb index eb823d211..88fcb957d 100644 --- a/app/models/portal.rb +++ b/app/models/portal.rb @@ -39,4 +39,6 @@ class Portal < ApplicationRecord validates :slug, presence: true, uniqueness: true accepts_nested_attributes_for :members + + scope :active, -> { where(archived: false) } end diff --git a/app/views/public/api/v1/kbase/portal/show.json.jbuilder b/app/views/public/api/v1/kbase/portal/show.json.jbuilder deleted file mode 100644 index f4bc72924..000000000 --- a/app/views/public/api/v1/kbase/portal/show.json.jbuilder +++ /dev/null @@ -1 +0,0 @@ -json.partial! 'portal', portal: @portal diff --git a/app/views/public/api/v1/models/_associated_category.json.jbuilder b/app/views/public/api/v1/models/_associated_category.json.jbuilder new file mode 100644 index 000000000..881ea6a54 --- /dev/null +++ b/app/views/public/api/v1/models/_associated_category.json.jbuilder @@ -0,0 +1,5 @@ +json.name category.name +json.slug category.slug +json.locale category.locale +json.description category.description +json.position category.position diff --git a/app/views/public/api/v1/models/_category.json.jbuilder b/app/views/public/api/v1/models/_category.json.jbuilder index 355a16608..c79febc63 100644 --- a/app/views/public/api/v1/models/_category.json.jbuilder +++ b/app/views/public/api/v1/models/_category.json.jbuilder @@ -1,5 +1,25 @@ -json.id category.id json.name category.name +json.slug category.slug json.locale category.locale json.description category.description json.position category.position + +json.related_categories do + if category.related_categories.any? + json.array! category.related_categories.each do |related_category| + json.partial! partial: 'associated_category', category: related_category + end + end +end + +if category.parent_category.present? + json.parent_category do + json.partial! partial: 'associated_category', category: category.parent_category + end +end + +if category.linked_category.present? + json.linked_category do + json.partial! partial: 'associated_category', category: category.linked_category + end +end diff --git a/app/views/public/api/v1/models/_portal.json.jbuilder b/app/views/public/api/v1/models/_portal.json.jbuilder index d612f5265..405541a5b 100644 --- a/app/views/public/api/v1/models/_portal.json.jbuilder +++ b/app/views/public/api/v1/models/_portal.json.jbuilder @@ -1,9 +1,14 @@ -json.id portal.id -json.color portal.color json.custom_domain portal.custom_domain json.header_text portal.header_text json.homepage_link portal.homepage_link json.name portal.name json.page_title portal.page_title json.slug portal.slug -json.config portal.config + +json.categories do + if portal.categories.any? + json.array! portal.categories.each do |category| + json.partial! 'categories/category.json.jbuilder', category: category + end + end +end diff --git a/app/views/public/api/v1/portals/categories/index.json.jbuilder b/app/views/public/api/v1/portals/categories/index.json.jbuilder new file mode 100644 index 000000000..f28416dd5 --- /dev/null +++ b/app/views/public/api/v1/portals/categories/index.json.jbuilder @@ -0,0 +1,3 @@ +json.payload do + json.array! @categories, partial: 'public/api/v1/models/category.json.jbuilder', as: :category +end diff --git a/app/views/public/api/v1/portals/categories/show.json.jbuilder b/app/views/public/api/v1/portals/categories/show.json.jbuilder new file mode 100644 index 000000000..6584b0a3d --- /dev/null +++ b/app/views/public/api/v1/portals/categories/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'public/api/v1/models/category.json.jbuilder', category: @category diff --git a/app/views/public/api/v1/portals/index.json.jbuilder b/app/views/public/api/v1/portals/index.json.jbuilder new file mode 100644 index 000000000..41f359789 --- /dev/null +++ b/app/views/public/api/v1/portals/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @portals, partial: 'public/api/v1/models/portal.json.jbuilder', as: :portal diff --git a/app/views/public/api/v1/portals/show.json.jbuilder b/app/views/public/api/v1/portals/show.json.jbuilder new file mode 100644 index 000000000..70b9c4f07 --- /dev/null +++ b/app/views/public/api/v1/portals/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'public/api/v1/models/portal.json.jbuilder', portal: @portal diff --git a/config/routes.rb b/config/routes.rb index 8f34700fc..a6a75c8d8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -157,7 +157,7 @@ Rails.application.routes.draw do resources :portals do member do - post :archive + patch :archive put :add_members end resources :categories @@ -258,6 +258,13 @@ Rails.application.routes.draw do end end end + resources :portals, only: [:show], param: :slug do + scope module: :portals do + resources :categories, only: [:index, :show], param: :slug do + resources :articles, only: [:index, :show], param: :slug + end + end + end resources :csat_survey, only: [:show, :update] end end diff --git a/spec/controllers/api/v1/accounts/articles_controller_spec.rb b/spec/controllers/api/v1/accounts/articles_controller_spec.rb index 13abba627..807def183 100644 --- a/spec/controllers/api/v1/accounts/articles_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/articles_controller_spec.rb @@ -35,6 +35,7 @@ RSpec.describe 'Api::V1::Accounts::Articles', type: :request do expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) expect(json_response['payload']['title']).to eql('MyTitle') + expect(json_response['payload']['status']).to eql('draft') end it 'associate to the root article' do @@ -100,10 +101,11 @@ RSpec.describe 'Api::V1::Accounts::Articles', type: :request do end context 'when it is an authenticated user' do - it 'updates category' do + it 'updates article' do article_params = { article: { title: 'MyTitle2', + status: 'published', description: 'test_description' } } @@ -116,6 +118,7 @@ RSpec.describe 'Api::V1::Accounts::Articles', type: :request do expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) expect(json_response['payload']['title']).to eql(article_params[:article][:title]) + expect(json_response['payload']['status']).to eql(article_params[:article][:status]) end end end diff --git a/spec/controllers/public/api/v1/portals/categories_controller_spec.rb b/spec/controllers/public/api/v1/portals/categories_controller_spec.rb new file mode 100644 index 000000000..524871447 --- /dev/null +++ b/spec/controllers/public/api/v1/portals/categories_controller_spec.rb @@ -0,0 +1,36 @@ +require 'rails_helper' + +RSpec.describe 'Public Categories API', type: :request do + let!(:account) { create(:account) } + let!(:portal) { create(:portal, slug: 'test-portal') } + + before do + create(:category, slug: 'test-category-1', portal_id: portal.id, account_id: account.id) + create(:category, slug: 'test-category-2', portal_id: portal.id, account_id: account.id) + create(:category, slug: 'test-category-3', portal_id: portal.id, account_id: account.id) + end + + describe 'GET /public/api/v1/portals/:portal_slug/categories' do + it 'Fetch all categories in the portal' do + get "/public/api/v1/portals/#{portal.slug}/categories" + + expect(response).to have_http_status(:success) + json_response = JSON.parse(response.body) + + expect(json_response['payload'].length).to eql portal.categories.count + end + end + + describe 'GET /public/api/v1/portals/:portal_slug/categories/:slug' do + it 'Fetch category with the slug' do + category_slug = 'test-category-3' + + get "/public/api/v1/portals/#{portal.slug}/categories/#{category_slug}" + + expect(response).to have_http_status(:success) + json_response = JSON.parse(response.body) + + expect(json_response['slug']).to eql category_slug + end + end +end diff --git a/spec/controllers/public/api/v1/portals_controller_spec.rb b/spec/controllers/public/api/v1/portals_controller_spec.rb new file mode 100644 index 000000000..4abf78c70 --- /dev/null +++ b/spec/controllers/public/api/v1/portals_controller_spec.rb @@ -0,0 +1,21 @@ +require 'rails_helper' + +RSpec.describe 'Public Portals API', type: :request do + let!(:account) { create(:account) } + let!(:portal) { create(:portal, slug: 'test-portal', account_id: account.id) } + + before do + create(:portal, slug: 'test-portal-1', account_id: account.id) + create(:portal, slug: 'test-portal-2', account_id: account.id) + end + + describe 'GET /public/api/v1/portals/{portal_slug}' do + it 'Show portal and categories belonging to the portal' do + get "/public/api/v1/portals/#{portal.slug}" + + expect(response).to have_http_status(:success) + json_response = JSON.parse(response.body) + expect(json_response['slug']).to eql 'test-portal' + end + end +end