diff --git a/app/controllers/api/v1/accounts/kbase/base_controller.rb b/app/controllers/api/v1/accounts/kbase/base_controller.rb index f50140883..4f62cd858 100644 --- a/app/controllers/api/v1/accounts/kbase/base_controller.rb +++ b/app/controllers/api/v1/accounts/kbase/base_controller.rb @@ -4,6 +4,6 @@ class Api::V1::Accounts::Kbase::BaseController < Api::V1::Accounts::BaseControll private def portal - @portal ||= Current.account.kbase_portals.find_by(id: params[:portal_id]) + @portal ||= Current.account.kbase_portals.find_by(slug: params[:portal_id]) end end diff --git a/app/controllers/api/v1/accounts/kbase/portals_controller.rb b/app/controllers/api/v1/accounts/kbase/portals_controller.rb index 804b2d421..5ec1b4a83 100644 --- a/app/controllers/api/v1/accounts/kbase/portals_controller.rb +++ b/app/controllers/api/v1/accounts/kbase/portals_controller.rb @@ -1,10 +1,12 @@ -class Api::V1::Accounts::Kbase::PortalsController < Api::V1::Accounts::Kbase::BaseController +class Api::V1::Accounts::Kbase::PortalsController < Api::V1::Accounts::BaseController before_action :fetch_portal, except: [:index, :create] def index @portals = Current.account.kbase_portals end + def show; end + def create @portal = Current.account.kbase_portals.create!(portal_params) end @@ -21,7 +23,11 @@ class Api::V1::Accounts::Kbase::PortalsController < Api::V1::Accounts::Kbase::Ba private def fetch_portal - @portal = current_account.kbase_portals.find(params[:id]) + @portal = Current.account.kbase_portals.find_by(slug: permitted_params[:id]) + end + + def permitted_params + params.permit(:id) end def portal_params diff --git a/app/models/kbase/category.rb b/app/models/kbase/category.rb index 024efae8e..d2b270306 100644 --- a/app/models/kbase/category.rb +++ b/app/models/kbase/category.rb @@ -4,6 +4,7 @@ # # id :bigint not null, primary key # description :text +# locale :string default("en") # name :string # position :integer # created_at :datetime not null @@ -11,6 +12,10 @@ # account_id :integer not null # portal_id :integer not null # +# Indexes +# +# index_kbase_categories_on_locale_and_account_id (locale,account_id) +# class Kbase::Category < ApplicationRecord belongs_to :account belongs_to :portal diff --git a/app/models/kbase/portal.rb b/app/models/kbase/portal.rb index 03f8e29bf..c381e5c46 100644 --- a/app/models/kbase/portal.rb +++ b/app/models/kbase/portal.rb @@ -3,8 +3,8 @@ # Table name: kbase_portals # # id :bigint not null, primary key -# account_id :integer not null # color :string +# config :jsonb # custom_domain :string # header_text :text # homepage_link :string @@ -13,6 +13,7 @@ # slug :string not null # created_at :datetime not null # updated_at :datetime not null +# account_id :integer not null # # Indexes # @@ -26,5 +27,5 @@ class Kbase::Portal < ApplicationRecord validates :account_id, presence: true validates :name, presence: true - validates :slug, presence: true + validates :slug, presence: true, uniqueness: true end diff --git a/app/views/api/v1/accounts/kbase/portals/_portal.json.jbuilder b/app/views/api/v1/accounts/kbase/portals/_portal.json.jbuilder index 92ddc41ba..d612f5265 100644 --- a/app/views/api/v1/accounts/kbase/portals/_portal.json.jbuilder +++ b/app/views/api/v1/accounts/kbase/portals/_portal.json.jbuilder @@ -6,3 +6,4 @@ json.homepage_link portal.homepage_link json.name portal.name json.page_title portal.page_title json.slug portal.slug +json.config portal.config diff --git a/app/views/api/v1/accounts/kbase/portals/create.json.jbuilder b/app/views/api/v1/accounts/kbase/portals/create.json.jbuilder index c46e46321..f4bc72924 100644 --- a/app/views/api/v1/accounts/kbase/portals/create.json.jbuilder +++ b/app/views/api/v1/accounts/kbase/portals/create.json.jbuilder @@ -1,3 +1 @@ -json.payload do - json.partial! 'portal', portal: @portal -end +json.partial! 'portal', portal: @portal diff --git a/app/views/api/v1/accounts/kbase/portals/index.json.jbuilder b/app/views/api/v1/accounts/kbase/portals/index.json.jbuilder index 3e4553382..4a7949da1 100644 --- a/app/views/api/v1/accounts/kbase/portals/index.json.jbuilder +++ b/app/views/api/v1/accounts/kbase/portals/index.json.jbuilder @@ -1,3 +1 @@ -json.payload do - json.array! @portals, partial: 'portal', as: :portal -end +json.array! @portals, partial: 'portal', as: :portal diff --git a/app/views/api/v1/accounts/kbase/portals/show.json.jbuilder b/app/views/api/v1/accounts/kbase/portals/show.json.jbuilder new file mode 100644 index 000000000..f4bc72924 --- /dev/null +++ b/app/views/api/v1/accounts/kbase/portals/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'portal', portal: @portal diff --git a/app/views/api/v1/accounts/kbase/portals/update.json.jbuilder b/app/views/api/v1/accounts/kbase/portals/update.json.jbuilder index c46e46321..f4bc72924 100644 --- a/app/views/api/v1/accounts/kbase/portals/update.json.jbuilder +++ b/app/views/api/v1/accounts/kbase/portals/update.json.jbuilder @@ -1,3 +1 @@ -json.payload do - json.partial! 'portal', portal: @portal -end +json.partial! 'portal', portal: @portal diff --git a/app/views/public/api/v1/kbase/portal/show.json.jbuilder b/app/views/public/api/v1/kbase/portal/show.json.jbuilder new file mode 100644 index 000000000..f4bc72924 --- /dev/null +++ b/app/views/public/api/v1/kbase/portal/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! 'portal', portal: @portal diff --git a/app/views/public/api/v1/models/kbase/_category.json.jbuilder b/app/views/public/api/v1/models/kbase/_category.json.jbuilder new file mode 100644 index 000000000..355a16608 --- /dev/null +++ b/app/views/public/api/v1/models/kbase/_category.json.jbuilder @@ -0,0 +1,5 @@ +json.id category.id +json.name category.name +json.locale category.locale +json.description category.description +json.position category.position diff --git a/app/views/public/api/v1/models/kbase/_portal.json.jbuilder b/app/views/public/api/v1/models/kbase/_portal.json.jbuilder new file mode 100644 index 000000000..d612f5265 --- /dev/null +++ b/app/views/public/api/v1/models/kbase/_portal.json.jbuilder @@ -0,0 +1,9 @@ +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 diff --git a/db/migrate/20220416203340_add_config_to_portal.rb b/db/migrate/20220416203340_add_config_to_portal.rb new file mode 100644 index 000000000..27cd53773 --- /dev/null +++ b/db/migrate/20220416203340_add_config_to_portal.rb @@ -0,0 +1,5 @@ +class AddConfigToPortal < ActiveRecord::Migration[6.1] + def change + add_column :kbase_portals, :config, :jsonb, default: { allowed_locales: ['en'] } + end +end diff --git a/db/migrate/20220416205519_add_locale_to_kbase_category.rb b/db/migrate/20220416205519_add_locale_to_kbase_category.rb new file mode 100644 index 000000000..04cdc4bf3 --- /dev/null +++ b/db/migrate/20220416205519_add_locale_to_kbase_category.rb @@ -0,0 +1,7 @@ +class AddLocaleToKbaseCategory < ActiveRecord::Migration[6.1] + def change + add_column :kbase_categories, :locale, :string, default: 'en' + add_index :kbase_categories, :locale + add_index :kbase_categories, [:locale, :account_id] + end +end diff --git a/db/schema.rb b/db/schema.rb index 8373fe31f..2d03ce428 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -507,6 +507,8 @@ ActiveRecord::Schema.define(version: 2022_04_18_094715) do t.integer "position" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.string "locale", default: "en" + t.index ["locale", "account_id"], name: "index_kbase_categories_on_locale_and_account_id" end create_table "kbase_folders", force: :cascade do |t| @@ -528,6 +530,7 @@ ActiveRecord::Schema.define(version: 2022_04_18_094715) do t.text "header_text" t.datetime "created_at", precision: 6, null: false t.datetime "updated_at", precision: 6, null: false + t.jsonb "config", default: {"allowed_locales"=>["en"]} t.index ["slug"], name: "index_kbase_portals_on_slug", unique: true end diff --git a/spec/requests/api/v1/accounts/kbase/categories_request_spec.rb b/spec/controllers/api/v1/accounts/kbase/categories_controller_spec.rb similarity index 90% rename from spec/requests/api/v1/accounts/kbase/categories_request_spec.rb rename to spec/controllers/api/v1/accounts/kbase/categories_controller_spec.rb index 2c8f54241..4d98cd898 100644 --- a/spec/requests/api/v1/accounts/kbase/categories_request_spec.rb +++ b/spec/controllers/api/v1/accounts/kbase/categories_controller_spec.rb @@ -6,10 +6,10 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do let!(:portal) { create(:kbase_portal, name: 'test_portal', account_id: account.id) } let!(:category) { create(:kbase_category, name: 'category', portal: portal, account_id: account.id) } - describe 'POST /api/v1/accounts/{account.id}/kbase/portals/{portal.id}/categories' do + describe 'POST /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}/categories' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - post "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories", params: {} + post "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories", params: {} expect(response).to have_http_status(:unauthorized) end end @@ -23,7 +23,7 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do position: 1 } } - post "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories", + post "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories", params: category_params, headers: agent.create_new_auth_token expect(response).to have_http_status(:success) @@ -33,10 +33,10 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do end end - describe 'PUT /api/v1/accounts/{account.id}/kbase/portals/{portal.id}/categories/{category.id}' do + describe 'PUT /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}/categories/{category.id}' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories/#{category.id}", params: {} + put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories/#{category.id}", params: {} expect(response).to have_http_status(:unauthorized) end end @@ -53,7 +53,7 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do expect(category.name).not_to eql(category_params[:category][:name]) - put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories/#{category.id}", + put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories/#{category.id}", params: category_params, headers: agent.create_new_auth_token expect(response).to have_http_status(:success) @@ -63,17 +63,17 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do end end - describe 'DELETE /api/v1/accounts/{account.id}/kbase/portals/{portal.id}/categories/{category.id}' do + describe 'DELETE /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}/categories/{category.id}' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories/#{category.id}", params: {} + delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories/#{category.id}", params: {} expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do it 'deletes category' do - delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories/#{category.id}", + delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories/#{category.id}", headers: agent.create_new_auth_token expect(response).to have_http_status(:success) deleted_category = Kbase::Category.find_by(id: category.id) @@ -82,10 +82,10 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do end end - describe 'GET /api/v1/accounts/{account.id}/kbase/portals/{portal.id}/categories' do + describe 'GET /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}/categories' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - get "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories" + get "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories" expect(response).to have_http_status(:unauthorized) end end @@ -95,7 +95,7 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Categories', type: :request do category2 = create(:kbase_category, name: 'test_category_2', portal: portal) expect(category2.id).not_to be nil - get "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}/categories", + get "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}/categories", headers: agent.create_new_auth_token expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) diff --git a/spec/requests/api/v1/accounts/kbase/portals_request_spec.rb b/spec/controllers/api/v1/accounts/kbase/portals_controller_spec.rb similarity index 72% rename from spec/requests/api/v1/accounts/kbase/portals_request_spec.rb rename to spec/controllers/api/v1/accounts/kbase/portals_controller_spec.rb index 9adf9cba6..eae356930 100644 --- a/spec/requests/api/v1/accounts/kbase/portals_request_spec.rb +++ b/spec/controllers/api/v1/accounts/kbase/portals_controller_spec.rb @@ -3,7 +3,47 @@ require 'rails_helper' RSpec.describe 'Api::V1::Accounts::Kbase::Portals', type: :request do let(:account) { create(:account) } let(:agent) { create(:user, account: account, role: :agent) } - let!(:portal) { create(:kbase_portal, name: 'test_portal', account_id: account.id) } + let!(:portal) { create(:kbase_portal, slug: 'portal-1', name: 'test_portal', account_id: account.id) } + + describe 'GET /api/v1/accounts/{account.id}/kbase/portals' do + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + get "/api/v1/accounts/#{account.id}/kbase/portals" + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + it 'get all portals' do + portal2 = create(:kbase_portal, name: 'test_portal_2', account_id: account.id, slug: 'portal-2') + expect(portal2.id).not_to be nil + get "/api/v1/accounts/#{account.id}/kbase/portals", + headers: agent.create_new_auth_token + expect(response).to have_http_status(:success) + json_response = JSON.parse(response.body) + expect(json_response.count).to be 2 + end + end + end + + describe 'GET /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}' do + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + get "/api/v1/accounts/#{account.id}/kbase/portals" + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + it 'get one portals' do + get "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}", + headers: agent.create_new_auth_token + expect(response).to have_http_status(:success) + json_response = JSON.parse(response.body) + expect(json_response['name']).to eq portal.name + end + end + end describe 'POST /api/v1/accounts/{account.id}/kbase/portals' do context 'when it is an unauthenticated user' do @@ -26,15 +66,15 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Portals', type: :request do headers: agent.create_new_auth_token expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) - expect(json_response['payload']['name']).to eql('test_portal') + expect(json_response['name']).to eql('test_portal') end end end - describe 'PUT /api/v1/accounts/{account.id}/kbase/portals/{portal.id}' do + describe 'PUT /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}", params: {} + put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}", params: {} expect(response).to have_http_status(:unauthorized) end end @@ -49,53 +89,32 @@ RSpec.describe 'Api::V1::Accounts::Kbase::Portals', type: :request do expect(portal.name).to eql('test_portal') - put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}", + put "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}", params: portal_params, headers: agent.create_new_auth_token expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) - expect(json_response['payload']['name']).to eql(portal_params[:portal][:name]) + expect(json_response['name']).to eql(portal_params[:portal][:name]) end end end - describe 'DELETE /api/v1/accounts/{account.id}/kbase/portals/{portal.id}' do + describe 'DELETE /api/v1/accounts/{account.id}/kbase/portals/{portal.slug}' do context 'when it is an unauthenticated user' do it 'returns unauthorized' do - delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}", params: {} + delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}", params: {} expect(response).to have_http_status(:unauthorized) end end context 'when it is an authenticated user' do it 'deletes portal' do - delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.id}", + delete "/api/v1/accounts/#{account.id}/kbase/portals/#{portal.slug}", headers: agent.create_new_auth_token expect(response).to have_http_status(:success) - deleted_portal = Kbase::Portal.find_by(id: portal.id) + deleted_portal = Kbase::Portal.find_by(id: portal.slug) expect(deleted_portal).to be nil end end end - - describe 'GET /api/v1/accounts/{account.id}/kbase/portals' do - context 'when it is an unauthenticated user' do - it 'returns unauthorized' do - get "/api/v1/accounts/#{account.id}/kbase/portals" - expect(response).to have_http_status(:unauthorized) - end - end - - context 'when it is an authenticated user' do - it 'get all portals' do - portal2 = create(:kbase_portal, name: 'test_portal_2', account_id: account.id) - expect(portal2.id).not_to be nil - get "/api/v1/accounts/#{account.id}/kbase/portals", - headers: agent.create_new_auth_token - expect(response).to have_http_status(:success) - json_response = JSON.parse(response.body) - expect(json_response['payload'].count).to be 2 - end - end - end end