Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PART 1] Add task pagination endpoint for user tasks #14252

Merged
merged 10 commits into from
May 15, 2020
41 changes: 41 additions & 0 deletions app/controllers/concerns/task_pagination_concern.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# frozen_string_literal: true

# shared code for controllers that paginate tasks.
# requires methods:
# * total_items
# * allowed_params
#
module TaskPaginationConcern
extend ActiveSupport::Concern

def pagination_json
{
tasks: json_tasks(task_pager.paged_tasks),
task_page_count: task_pager.task_page_count,
total_task_count: task_pager.total_task_count,
tasks_per_page: TaskPager::TASKS_PER_PAGE
}
end

private

def task_pager
@task_pager ||= TaskPager.new(
assignee: assignee,
tab_name: params[Constants.QUEUE_CONFIG.TAB_NAME_REQUEST_PARAM.to_sym],
page: params[Constants.QUEUE_CONFIG.PAGE_NUMBER_REQUEST_PARAM.to_sym],
sort_order: params[Constants.QUEUE_CONFIG.SORT_DIRECTION_REQUEST_PARAM.to_sym],
sort_by: params[Constants.QUEUE_CONFIG.SORT_COLUMN_REQUEST_PARAM.to_sym],
filters: params[Constants.QUEUE_CONFIG.FILTER_COLUMN_REQUEST_PARAM.to_sym]
)
end

def json_tasks(tasks)
tasks = AppealRepository.eager_load_legacy_appeals_for_tasks(tasks)
params = { user: current_user }

AmaAndLegacyTaskSerializer.new(
tasks: tasks, params: params, ama_serializer: WorkQueue::TaskSerializer
).call
end
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled out of app/controllers/organizations/task_pages_controller.rb to be reused in app/controllers/users/task_pages_controller.rb

29 changes: 5 additions & 24 deletions app/controllers/organizations/task_pages_controller.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# frozen_string_literal: true

class Organizations::TaskPagesController < OrganizationsController
include TaskPaginationConcern

before_action :verify_organization_access, only: [:index]
before_action :verify_role_access, only: [:index]

Expand All @@ -24,12 +26,7 @@ class Organizations::TaskPagesController < OrganizationsController
# }>

def index
render json: {
tasks: json_tasks(task_pager.paged_tasks),
task_page_count: task_pager.task_page_count,
total_task_count: task_pager.total_task_count,
tasks_per_page: TaskPager::TASKS_PER_PAGE
}
render json: pagination_json
end

private
Expand All @@ -38,23 +35,7 @@ def organization_url
params[:organization_url]
end

def task_pager
@task_pager ||= TaskPager.new(
assignee: organization,
tab_name: params[Constants.QUEUE_CONFIG.TAB_NAME_REQUEST_PARAM.to_sym],
page: params[Constants.QUEUE_CONFIG.PAGE_NUMBER_REQUEST_PARAM.to_sym],
sort_order: params[Constants.QUEUE_CONFIG.SORT_DIRECTION_REQUEST_PARAM.to_sym],
sort_by: params[Constants.QUEUE_CONFIG.SORT_COLUMN_REQUEST_PARAM.to_sym],
filters: params[Constants.QUEUE_CONFIG.FILTER_COLUMN_REQUEST_PARAM.to_sym]
)
end

def json_tasks(tasks)
tasks = AppealRepository.eager_load_legacy_appeals_for_tasks(tasks)
params = { user: current_user }

AmaAndLegacyTaskSerializer.new(
tasks: tasks, params: params, ama_serializer: organization.ama_task_serializer
).call
def assignee
organization
end
end
34 changes: 34 additions & 0 deletions app/controllers/users/task_pages_controller.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

class Users::TaskPagesController < UsersController
include TaskPaginationConcern

hschallhorn marked this conversation as resolved.
Show resolved Hide resolved
# /users/{user.id}/task_pages?
# tab=on_hold&
# sort_by=case_details_link&
# order=desc&
# filter[]=col%3Ddocket_type%26val%3Dlegacy&
# filter[]=col%3Dtask_action%26val%3Dtranslation&
# page=3
#
hschallhorn marked this conversation as resolved.
Show resolved Hide resolved
# params = <ActionController::Parameters {
# "tab"=>"on_hold",
# "sort_by"=>"case_details_link",
# "order"=>"desc",
# "filter"=>[
# "col=docketNumberColumn&val=legacy,evidence_submission",
# "col=taskColumn&val=Unaccredited rep,Extension"
# ],
# "page"=>"3"
# }>

def index
render json: pagination_json
end

private

def assignee
user
end
end
10 changes: 7 additions & 3 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ def update
end

def represented_organizations
render json: { represented_organizations: User.find(params[:id]).vsos_user_represents }
render json: { represented_organizations: User.find(id).vsos_user_represents }
end

def judge
Expand Down Expand Up @@ -77,16 +77,20 @@ def filter_by_css_id_or_name
render json: { users: json_users(users) }
end

def id
@id ||= params[:id] || params[:user_id]
hschallhorn marked this conversation as resolved.
Show resolved Hide resolved
end

def user
unless css_id || params[:id]
unless css_id || id
fail(
Caseflow::Error::InvalidParameter,
parameter: "css_id or id",
message: "Must provide a css id or user id"
)
end

@user ||= params[:id] ? User.find(params[:id]) : User.find_by_css_id(css_id)
@user ||= id ? User.find(id) : User.find_by_css_id(css_id)
end

def user_to_modify
Expand Down
4 changes: 0 additions & 4 deletions app/models/organization.rb
Original file line number Diff line number Diff line change
Expand Up @@ -141,10 +141,6 @@ def completed_tasks_tab
::OrganizationCompletedTasksTab.new(assignee: self, show_regional_office_column: show_regional_office_in_queue?)
end

def ama_task_serializer
WorkQueue::TaskSerializer
end

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

private

def clean_url
Expand Down
2 changes: 1 addition & 1 deletion app/models/queue_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ def attach_tasks_to_tab(tab)
# This allows us to only instantiate TaskPager if we are using the task pages API.
task_page_count: task_pager.task_page_count,
total_task_count: tab.tasks.count,
task_page_endpoint_base_path: "#{assignee_is_org? ? "#{assignee.path}/" : ''}#{endpoint}"
task_page_endpoint_base_path: "#{assignee_is_org? ? "#{assignee.path}/" : "users/#{assignee.id}/"}#{endpoint}"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

URL the front end will use to request paged tasks

)
end

Expand Down
5 changes: 3 additions & 2 deletions config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -218,10 +218,11 @@
patch "/messages/:id", to: "inbox#update"
end

resources :users, only: [:index, :update]
resources :users, only: [:index] do
resources :users, only: [:index, :update] do
resources :task_pages, only: [:index], controller: 'users/task_pages'
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

New route for the pagination of user tasks

get 'represented_organizations', on: :member
end

get 'user', to: 'users#search'
get 'user_info/represented_organizations'

Expand Down
54 changes: 7 additions & 47 deletions spec/controllers/organizations/task_pages_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -1,62 +1,22 @@
# frozen_string_literal: true

describe Organizations::TaskPagesController, :postgres, type: :controller do
let(:organization) { create(:organization) }
let(:url) { organization.url }
require_relative "../paged_tasks_shared_examples"

let(:assignee) { create(:organization) }
let(:url) { assignee.url }
let(:params) { { organization_url: url, tab: tab_name } }

let(:user) { create(:user) }

before do
organization.add_user(user)
assignee.add_user(user)
User.authenticate!(user: user)
end

describe "GET organization/:organization_url/task_pages" do
context "when user is member of the organization and the organization has tasks" do
let(:tab_name) { Constants.QUEUE_CONFIG.UNASSIGNED_TASKS_TAB_NAME }
let(:task_count) { 4 }

before { create_list(:ama_task, task_count, assigned_to: organization) }

subject do
get(:index, params: { organization_url: url, tab: tab_name })
expect(response.status).to eq(200)
JSON.parse(response.body)
end

it "returns correct elements of the response" do
expect(subject.keys).to match_array(%w[tasks task_page_count total_task_count tasks_per_page])
end

it "returns correct number of tasks" do
expect(subject["tasks"]["data"].size).to eq(task_count)
end

it "returns correct task_page_count" do
expect(subject["task_page_count"]).to eq((task_count.to_f / TaskPager::TASKS_PER_PAGE).ceil)
end

it "returns correct total_task_count" do
expect(subject["total_task_count"]).to eq(task_count)
end

it "returns correct tasks_per_page" do
expect(subject["tasks_per_page"]).to eq(TaskPager::TASKS_PER_PAGE)
end

it "only instantiates TaskPager a single time" do
task_pager = instance_double(TaskPager)
expect(TaskPager).to receive(:new).and_return(task_pager).exactly(1).times

expect(task_pager).to receive(:paged_tasks)
expect(task_pager).to receive(:task_page_count)
expect(task_pager).to receive(:total_task_count)

# Prevent this call from actually firing since it will fail due to the instance_double.
allow_any_instance_of(::Organizations::TaskPagesController).to receive(:json_tasks).and_return([])

subject
end
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pulled out into spec/controllers/paged_tasks_shared_examples.rb

it_behaves_like "paged assignee tasks"
end
end
end
50 changes: 50 additions & 0 deletions spec/controllers/paged_tasks_shared_examples.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
# frozen_string_literal: true

# Shared examples for user and organization task pages controllers

shared_examples "paged assignee tasks" do
let(:tab_name) { assignee.class.default_active_tab }
let(:task_count) { 4 }
hschallhorn marked this conversation as resolved.
Show resolved Hide resolved

before { create_list(:ama_task, task_count, assigned_to: assignee) }

subject do
get(:index, params: params)
expect(response.status).to eq(200)
JSON.parse(response.body)
end

it "returns correct elements of the response" do
expect(subject.keys).to match_array(%w[tasks task_page_count total_task_count tasks_per_page])
end

it "returns correct number of tasks" do
expect(subject["tasks"]["data"].size).to eq(task_count)
end

it "returns correct task_page_count" do
expect(subject["task_page_count"]).to eq((task_count.to_f / TaskPager::TASKS_PER_PAGE).ceil)
end

it "returns correct total_task_count" do
expect(subject["total_task_count"]).to eq(task_count)
end

it "returns correct tasks_per_page" do
expect(subject["tasks_per_page"]).to eq(TaskPager::TASKS_PER_PAGE)
end

it "only instantiates TaskPager a single time" do
task_pager = instance_double(TaskPager)
expect(TaskPager).to receive(:new).and_return(task_pager).exactly(1).times

expect(task_pager).to receive(:paged_tasks)
expect(task_pager).to receive(:task_page_count)
expect(task_pager).to receive(:total_task_count)

# Prevent this call from actually firing since it will fail due to the instance_double.
allow_any_instance_of(TaskPaginationConcern).to receive(:json_tasks).and_return([])

subject
end
end
17 changes: 17 additions & 0 deletions spec/controllers/users/task_pages_controller_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

describe Users::TaskPagesController, :postgres, type: :controller do
require_relative "../paged_tasks_shared_examples"

let(:assignee) { create(:user) }
let(:url) { assignee.id }
let(:params) { { user_id: url, tab: tab_name } }

before do
User.authenticate!(user: assignee)
end

describe "GET user/:user_id/task_pages" do
it_behaves_like "paged assignee tasks"
end
end