From c5b245977a353584ee591e2df51774ebd250f6d8 Mon Sep 17 00:00:00 2001 From: Tejaswini Chile Date: Thu, 9 Feb 2023 14:05:45 +0530 Subject: [PATCH] Added one more endpoint to attach tempfile and get logo (#6407) --- .../api/v1/accounts/articles_controller.rb | 16 +++++++-- .../api/v1/accounts/portals_controller.rb | 16 +++++++-- app/policies/article_policy.rb | 4 +++ app/policies/portal_policy.rb | 4 +++ .../api/v1/models/hc/_portal.json.jbuilder | 2 ++ config/routes.rb | 5 ++- .../v1/accounts/articles_controller_spec.rb | 18 ++++++++++ .../v1/accounts/portals_controller_spec.rb | 35 ++++++++++++++++--- 8 files changed, 90 insertions(+), 10 deletions(-) diff --git a/app/controllers/api/v1/accounts/articles_controller.rb b/app/controllers/api/v1/accounts/articles_controller.rb index 23855267d..847db90d0 100644 --- a/app/controllers/api/v1/accounts/articles_controller.rb +++ b/app/controllers/api/v1/accounts/articles_controller.rb @@ -1,7 +1,7 @@ class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController before_action :portal before_action :check_authorization - before_action :fetch_article, except: [:index, :create] + before_action :fetch_article, except: [:index, :create, :attach_file] before_action :set_current_page, only: [:index] def index @@ -23,7 +23,8 @@ class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController def show; end def update - @article.update!(article_params) + @article.update!(article_params) if params[:article].present? + render json: { error: @article.errors.messages }, status: :unprocessable_entity and return unless @article.valid? end def destroy @@ -31,6 +32,17 @@ class Api::V1::Accounts::ArticlesController < Api::V1::Accounts::BaseController head :ok end + def attach_file + file_blob = ActiveStorage::Blob.create_and_upload!( + key: nil, + io: params[:background_image].tempfile, + filename: params[:background_image].original_filename, + content_type: params[:background_image].content_type + ) + file_blob.save! + render json: { file_url: url_for(file_blob) } + end + private def fetch_article diff --git a/app/controllers/api/v1/accounts/portals_controller.rb b/app/controllers/api/v1/accounts/portals_controller.rb index d28ae54b7..b1837acbd 100644 --- a/app/controllers/api/v1/accounts/portals_controller.rb +++ b/app/controllers/api/v1/accounts/portals_controller.rb @@ -1,7 +1,7 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController include ::FileTypeHelper - before_action :fetch_portal, except: [:index, :create] + before_action :fetch_portal, except: [:index, :create, :attach_file] before_action :check_authorization before_action :set_current_page, only: [:index] @@ -48,7 +48,19 @@ class Api::V1::Accounts::PortalsController < Api::V1::Accounts::BaseController end def process_attached_logo - @portal.logo.attach(params[:logo]) + blob_id = params[:blob_id] + blob = ActiveStorage::Blob.find_by(id: blob_id) + @portal.logo.attach(blob) + end + + def attach_file + file_blob = ActiveStorage::Blob.create_and_upload!( + key: nil, + io: params[:logo].tempfile, + filename: params[:logo].original_filename, + content_type: params[:logo].content_type + ) + render json: { blob_key: file_blob.key, blob_id: file_blob.id } end private diff --git a/app/policies/article_policy.rb b/app/policies/article_policy.rb index 1fb6c54da..db3443112 100644 --- a/app/policies/article_policy.rb +++ b/app/policies/article_policy.rb @@ -23,6 +23,10 @@ class ArticlePolicy < ApplicationPolicy @account_user.administrator? || portal_member? end + def attach_file? + @account_user.administrator? || portal_member? + end + private def portal_member? diff --git a/app/policies/portal_policy.rb b/app/policies/portal_policy.rb index a27f0f92f..b924c42a3 100644 --- a/app/policies/portal_policy.rb +++ b/app/policies/portal_policy.rb @@ -27,6 +27,10 @@ class PortalPolicy < ApplicationPolicy @account_user.administrator? end + def attach_file? + @account_user.administrator? + end + private def portal_member? diff --git a/app/views/public/api/v1/models/hc/_portal.json.jbuilder b/app/views/public/api/v1/models/hc/_portal.json.jbuilder index a6bff31fd..2e7b99901 100644 --- a/app/views/public/api/v1/models/hc/_portal.json.jbuilder +++ b/app/views/public/api/v1/models/hc/_portal.json.jbuilder @@ -13,6 +13,8 @@ json.categories do end end +json.logo portal.file_base_data if portal.logo.present? + json.meta do json.articles_count portal.articles.published.size json.categories_count portal.categories.size diff --git a/config/routes.rb b/config/routes.rb index bb7bc8c35..141e9a0dd 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -177,8 +177,11 @@ Rails.application.routes.draw do patch :archive put :add_members end + post :attach_file, on: :collection resources :categories - resources :articles + resources :articles do + post :attach_file, on: :collection + end end 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 1de808a20..747a0c88d 100644 --- a/spec/controllers/api/v1/accounts/articles_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/articles_controller_spec.rb @@ -232,5 +232,23 @@ RSpec.describe 'Api::V1::Accounts::Articles', type: :request do expect(json_response['payload']['id']).to eq(root_article.id) end end + + describe 'Upload an image' do + let(:article) { create(:article, account_id: account.id, category_id: category.id, portal_id: portal.id, author_id: agent.id) } + + it 'update the article with an image' do + file = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') + + post "/api/v1/accounts/#{account.id}/portals/#{article.portal.slug}/articles/attach_file", + headers: agent.create_new_auth_token, + params: { background_image: file } + + expect(response).to have_http_status(:success) + + blob = JSON.parse(response.body) + + expect(blob['file_url']).to be_present + end + end end end diff --git a/spec/controllers/api/v1/accounts/portals_controller_spec.rb b/spec/controllers/api/v1/accounts/portals_controller_spec.rb index 8f10b6b60..2875f1a29 100644 --- a/spec/controllers/api/v1/accounts/portals_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/portals_controller_spec.rb @@ -86,15 +86,12 @@ RSpec.describe 'Api::V1::Accounts::Portals', type: :request do context 'when it is an authenticated user' do it 'creates portal' do - file = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') - portal_params = { portal: { name: 'test_portal', slug: 'test_kbase', custom_domain: 'https://support.chatwoot.dev' - }, - logo: file + } } post "/api/v1/accounts/#{account.id}/portals", params: portal_params, @@ -103,7 +100,6 @@ RSpec.describe 'Api::V1::Accounts::Portals', type: :request do expect(response).to have_http_status(:success) json_response = JSON.parse(response.body) expect(json_response['name']).to eql('test_portal') - expect(json_response['logo']['filename']).to eql('avatar.png') expect(json_response['custom_domain']).to eql('support.chatwoot.dev') end end @@ -214,4 +210,33 @@ RSpec.describe 'Api::V1::Accounts::Portals', type: :request do end end end + + describe 'POST /api/v1/accounts/{account.id}/portals/attach_file' do + it 'update the portal with a logo' do + file = fixture_file_upload(Rails.root.join('spec/assets/avatar.png'), 'image/png') + + post "/api/v1/accounts/#{account.id}/portals/attach_file", + headers: admin.create_new_auth_token, + params: { logo: file } + + expect(response).to have_http_status(:success) + + blob = JSON.parse(response.body) + + expect(blob['blob_key']).to be_present + expect(blob['blob_id']).to be_present + + params = { blob_id: blob['blob_id'] } + + expect(portal.logo.attachment).not_to be_present + + patch "/api/v1/accounts/#{account.id}/portals/#{portal.slug}", + headers: admin.create_new_auth_token, + params: params + portal.reload + + expect(portal.logo.presence).to be_truthy + expect(portal.logo.attachment).to be_present + end + end end