From bab9d663d29c0503ced4feb6809e00946a853f74 Mon Sep 17 00:00:00 2001 From: Sojan Jose Date: Sun, 29 Mar 2020 12:16:31 +0530 Subject: [PATCH] Feature: API for updating account settings (#645) * Feature: API for updating account settings - API to update account locale - API to update account name - API to show account info --- .nvmrc | 1 + .../api/v1/accounts/accounts_controller.rb | 22 +++++- app/models/account.rb | 3 + app/policies/account_policy.rb | 13 ++++ app/views/api/v1/accounts/show.json.jbuilder | 3 + .../api/v1/accounts/update.json.jbuilder | 3 + config/initializers/languages.rb | 18 +++++ config/routes.rb | 2 +- .../20200325210612_add_locale_to_account.rb | 5 ++ db/schema.rb | 3 +- .../v1/accounts/accounts_controller_spec.rb | 71 +++++++++++++++++++ 11 files changed, 140 insertions(+), 4 deletions(-) create mode 100644 .nvmrc create mode 100644 app/policies/account_policy.rb create mode 100644 app/views/api/v1/accounts/show.json.jbuilder create mode 100644 app/views/api/v1/accounts/update.json.jbuilder create mode 100644 config/initializers/languages.rb create mode 100644 db/migrate/20200325210612_add_locale_to_account.rb diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000..66df3b7ab --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +12.16.1 diff --git a/app/controllers/api/v1/accounts/accounts_controller.rb b/app/controllers/api/v1/accounts/accounts_controller.rb index da5c0e77b..b8ad4fa46 100644 --- a/app/controllers/api/v1/accounts/accounts_controller.rb +++ b/app/controllers/api/v1/accounts/accounts_controller.rb @@ -4,7 +4,9 @@ class Api::V1::Accounts::AccountsController < Api::BaseController skip_before_action :verify_authenticity_token, only: [:create] skip_before_action :authenticate_user!, :set_current_user, :check_subscription, :handle_with_exception, only: [:create], raise: false - before_action :check_signup_enabled + before_action :check_signup_enabled, only: [:create] + before_action :check_authorization, except: [:create] + before_action :fetch_account, except: [:create] rescue_from CustomExceptions::Account::InvalidEmail, CustomExceptions::Account::UserExists, @@ -24,10 +26,26 @@ class Api::V1::Accounts::AccountsController < Api::BaseController end end + def show + render 'api/v1/accounts/show.json' + end + + def update + @account.update!(account_params.slice(:name, :locale)) + end + private + def check_authorization + authorize(Account) + end + + def fetch_account + @account = current_user.accounts.find(params[:id]) + end + def account_params - params.permit(:account_name, :email) + params.permit(:account_name, :email, :name, :locale) end def check_signup_enabled diff --git a/app/models/account.rb b/app/models/account.rb index b4450b88d..ca81bea2e 100644 --- a/app/models/account.rb +++ b/app/models/account.rb @@ -3,6 +3,7 @@ # Table name: accounts # # id :integer not null, primary key +# locale :integer default("English") # name :string not null # created_at :datetime not null # updated_at :datetime not null @@ -30,6 +31,8 @@ class Account < ApplicationRecord has_one :subscription, dependent: :destroy has_many :notification_settings, dependent: :destroy + enum locale: LANGUAGES_CONFIG.map { |key, val| [val[:iso_639_3_code], key] }.to_h + after_create :create_subscription after_create :notify_creation after_destroy :notify_deletion diff --git a/app/policies/account_policy.rb b/app/policies/account_policy.rb new file mode 100644 index 000000000..9577a3247 --- /dev/null +++ b/app/policies/account_policy.rb @@ -0,0 +1,13 @@ +class AccountPolicy < ApplicationPolicy + def show? + # FIXME : temporary hack to transition over to multiple accounts per user + # We should be fetching the current account user relationship here. + @user.administrator? + end + + def update? + # FIXME : temporary hack to transition over to multiple accounts per user + # We should be fetching the current account user relationship here. + @user.administrator? + end +end diff --git a/app/views/api/v1/accounts/show.json.jbuilder b/app/views/api/v1/accounts/show.json.jbuilder new file mode 100644 index 000000000..9c063f912 --- /dev/null +++ b/app/views/api/v1/accounts/show.json.jbuilder @@ -0,0 +1,3 @@ +json.id @account.id +json.name @account.name +json.locale @account.locale diff --git a/app/views/api/v1/accounts/update.json.jbuilder b/app/views/api/v1/accounts/update.json.jbuilder new file mode 100644 index 000000000..9c063f912 --- /dev/null +++ b/app/views/api/v1/accounts/update.json.jbuilder @@ -0,0 +1,3 @@ +json.id @account.id +json.name @account.name +json.locale @account.locale diff --git a/config/initializers/languages.rb b/config/initializers/languages.rb new file mode 100644 index 000000000..5c3914069 --- /dev/null +++ b/config/initializers/languages.rb @@ -0,0 +1,18 @@ +# Based on ISO_639-3 Codes. ref: https://en.wikipedia.org/wiki/List_of_ISO_639-2_codes +# This Hash is used in account model, so do not change the index for existing languages + +LANGUAGES_CONFIG = { + 0 => { name: 'English', iso_639_3_code: 'eng' }, + 1 => { name: 'Arabic', iso_639_3_code: 'ara' }, + 2 => { name: 'Dutch', iso_639_3_code: 'nld' }, + 3 => { name: 'French', iso_639_3_code: 'fra' }, + 4 => { name: 'German', iso_639_3_code: 'deu' }, + 5 => { name: 'Hindi', iso_639_3_code: 'hin' }, + 6 => { name: 'Italian', iso_639_3_code: 'ita' }, + 7 => { name: 'Japanese', iso_639_3_code: 'jpn' }, + 8 => { name: 'Korean', iso_639_3_code: 'kor' }, + 9 => { name: 'Portugues', iso_639_3_code: 'por' }, + 10 => { name: 'Russian', iso_639_3_code: 'rus' }, + 11 => { name: 'Chinese', iso_639_3_code: 'zho' }, + 12 => { name: 'Spanish', iso_639_3_code: 'spa' } +}.freeze diff --git a/config/routes.rb b/config/routes.rb index 978d394f4..32ae38733 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -21,7 +21,7 @@ Rails.application.routes.draw do namespace :v1 do # ---------------------------------- # start of account scoped api routes - resources :accounts, only: [:create], module: :accounts do + resources :accounts, only: [:create, :show, :update], module: :accounts do namespace :actions do resource :contact_merge, only: [:create] end diff --git a/db/migrate/20200325210612_add_locale_to_account.rb b/db/migrate/20200325210612_add_locale_to_account.rb new file mode 100644 index 000000000..08ecff067 --- /dev/null +++ b/db/migrate/20200325210612_add_locale_to_account.rb @@ -0,0 +1,5 @@ +class AddLocaleToAccount < ActiveRecord::Migration[6.0] + def change + add_column :accounts, :locale, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index 6546b9705..c94788d03 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_03_11_083854) do +ActiveRecord::Schema.define(version: 2020_03_25_210612) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -41,6 +41,7 @@ ActiveRecord::Schema.define(version: 2020_03_11_083854) do t.string "name", null: false t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "locale", default: 0 end create_table "active_storage_attachments", force: :cascade do |t| diff --git a/spec/controllers/api/v1/accounts/accounts_controller_spec.rb b/spec/controllers/api/v1/accounts/accounts_controller_spec.rb index c5426788b..eb5c15a92 100644 --- a/spec/controllers/api/v1/accounts/accounts_controller_spec.rb +++ b/spec/controllers/api/v1/accounts/accounts_controller_spec.rb @@ -75,4 +75,75 @@ RSpec.describe 'Accounts API', type: :request do end end end + + describe 'GET /api/v1/accounts/{account.id}' do + let(:account) { create(:account) } + let(:agent) { create(:user, account: account, role: :agent) } + let(:admin) { create(:user, account: account, role: :administrator) } + + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + get "/api/v1/accounts/#{account.id}" + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an unauthorized user' do + it 'returns unauthorized' do + get "/api/v1/accounts/#{account.id}", + headers: agent.create_new_auth_token + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + it 'shows an account' do + get "/api/v1/accounts/#{account.id}", + headers: admin.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:success) + expect(response.body).to include(account.name) + expect(response.body).to include(account.locale) + end + end + end + + describe 'PUT /api/v1/accounts/{account.id}' do + let(:account) { create(:account) } + let(:agent) { create(:user, account: account, role: :agent) } + let(:admin) { create(:user, account: account, role: :administrator) } + + context 'when it is an unauthenticated user' do + it 'returns unauthorized' do + put "/api/v1/accounts/#{account.id}" + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an unauthorized user' do + it 'returns unauthorized' do + put "/api/v1/accounts/#{account.id}", + headers: agent.create_new_auth_token + + expect(response).to have_http_status(:unauthorized) + end + end + + context 'when it is an authenticated user' do + params = { name: 'New Name', locale: 'ara' } + + it 'modifies an account' do + put "/api/v1/accounts/#{account.id}", + params: params, + headers: admin.create_new_auth_token, + as: :json + + expect(response).to have_http_status(:success) + expect(account.reload.name).to eq(params[:name]) + expect(account.reload.locale).to eq(params[:locale]) + end + end + end end