Merge pull request #20 from frankrousseau/api-paging-updates

API Paging Updates
This commit is contained in:
Frank Rousseau 2018-12-18 13:44:18 +01:00 committed by GitHub
commit 6ba26496ec
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 709 additions and 108 deletions

View file

@ -12,8 +12,10 @@ module Api
end end
def index def index
aspects = current_user.aspects.map {|a| AspectPresenter.new(a).as_api_json(false) } aspects_query = current_user.aspects
render json: aspects aspects_page = index_pager(aspects_query).response
aspects_page[:data] = aspects_page[:data].map {|a| AspectPresenter.new(a).as_api_json(false) }
render json: aspects_page
end end
def show def show

View file

@ -44,6 +44,14 @@ module Api
def current_user def current_user
current_token ? current_token.authorization.user : nil current_token ? current_token.authorization.user : nil
end end
def index_pager(query)
Api::Paging::RestPaginatorBuilder.new(query, request).index_pager(params)
end
def time_pager(query)
Api::Paging::RestPaginatorBuilder.new(query, request).time_pager(params)
end
end end
end end
end end

View file

@ -29,8 +29,11 @@ module Api
end end
def index def index
comments = comment_service.find_for_post(params[:post_id]) comments_query = comment_service.find_for_post(params[:post_id])
render json: comments.map {|x| comment_as_json(x) } params[:after] = Time.utc(1900).iso8601 if params.permit(:before, :after).empty?
comments_page = time_pager(comments_query).response
comments_page[:data] = comments_page[:data].map {|x| comment_as_json(x) }
render json: comments_page
end end
def destroy def destroy

View file

@ -1,5 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
require "api/paging/index_paginator"
module Api module Api
module V1 module V1
class ContactsController < Api::V1::BaseController class ContactsController < Api::V1::BaseController
@ -16,8 +18,12 @@ module Api
end end
def index def index
contacts = aspects_membership_service.contacts_in_aspect(params[:aspect_id]) contacts_query = aspects_membership_service.contacts_in_aspect(params[:aspect_id])
render json: contacts.map {|c| ContactPresenter.new(c, current_user).as_api_json_without_contact } contacts_page = index_pager(contacts_query).response
contacts_page[:data] = contacts_page[:data].map do |c|
ContactPresenter.new(c, current_user).as_api_json_without_contact
end
render json: contacts_page
end end
def create def create

View file

@ -21,10 +21,11 @@ module Api
params.permit(:only_after, :only_unread) params.permit(:only_after, :only_unread)
mapped_params = {} mapped_params = {}
mapped_params[:only_after] = params[:only_after] if params.has_key?(:only_after) mapped_params[:only_after] = params[:only_after] if params.has_key?(:only_after)
mapped_params[:unread] = params[:only_unread] if params.has_key?(:only_unread) mapped_params[:unread] = params[:only_unread] if params.has_key?(:only_unread)
conversations = conversation_service.all_for_user(mapped_params) conversations_query = conversation_service.all_for_user(mapped_params)
render json: conversations.map {|x| conversation_as_json(x) } conversations_page = pager(conversations_query, "conversations.created_at").response
conversations_page[:data] = conversations_page[:data].map {|x| conversation_as_json(x) }
render json: conversations_page
end end
def show def show
@ -34,7 +35,7 @@ module Api
def create def create
params.require(%i[subject body recipients]) params.require(%i[subject body recipients])
recipient_ids = JSON.parse(params[:recipients]).map {|p| Person.find_from_guid_or_username(id: p).id } recipient_ids = params[:recipients].map {|p| Person.find_from_guid_or_username(id: p).id }
conversation = conversation_service.build( conversation = conversation_service.build(
params[:subject], params[:subject],
params[:body], params[:body],
@ -58,12 +59,18 @@ module Api
head :no_content head :no_content
end end
private
def conversation_service def conversation_service
ConversationService.new(current_user) ConversationService.new(current_user)
end end
def conversation_as_json(conversation) def conversation_as_json(conversation)
ConversationPresenter.new(conversation).as_api_json ConversationPresenter.new(conversation, current_user).as_api_json
end
def pager(query, sort_field)
Api::Paging::RestPaginatorBuilder.new(query, request).time_pager(params, sort_field)
end end
end end
end end

View file

@ -20,8 +20,10 @@ module Api
end end
def show def show
likes = like_service.find_for_post(params[:post_id]) likes_query = like_service.find_for_post(params[:post_id])
render json: likes.map {|x| like_json(x) } likes_page = index_pager(likes_query).response
likes_page[:data] = likes_page[:data].map {|x| like_json(x) }
render json: likes_page
end end
def create def create

View file

@ -29,12 +29,13 @@ module Api
def index def index
conversation = conversation_service.find!(params[:conversation_id]) conversation = conversation_service.find!(params[:conversation_id])
conversation.set_read(current_user) conversation.set_read(current_user)
render( messages_page = index_pager(conversation.messages).response
json: conversation.messages.map {|x| message_json(x) }, messages_page[:data] = messages_page[:data].map {|x| message_json(x) }
status: :created render json: messages_page
)
end end
private
def conversation_service def conversation_service
ConversationService.new(current_user) ConversationService.new(current_user)
end end

View file

@ -27,8 +27,12 @@ module Api
def index def index
after_date = Date.iso8601(params[:only_after]) if params.has_key?(:only_after) after_date = Date.iso8601(params[:only_after]) if params.has_key?(:only_after)
notifications = service.index(params[:only_unread], after_date) notifications_query = service.index(params[:only_unread], after_date)
render json: notifications.map {|note| NotificationPresenter.new(note, default_serializer_options).as_api_json } notifications_page = time_pager(notifications_query).response
notifications_page[:data] = notifications_page[:data].map do |note|
NotificationPresenter.new(note, default_serializer_options).as_api_json
end
render json: notifications_page
rescue ArgumentError rescue ArgumentError
render json: I18n.t("api.endpoint_errors.notifications.cant_process"), status: :unprocessable_entity render json: I18n.t("api.endpoint_errors.notifications.cant_process"), status: :unprocessable_entity
end end

View file

@ -16,8 +16,9 @@ module Api
end end
def index def index
photos = current_user.photos photos_page = time_pager(current_user.photos).response
render json: photos.map {|p| PhotoPresenter.new(p).as_api_json(true) } photos_page[:data] = photos_page[:data].map {|photo| PhotoPresenter.new(photo).as_api_json(true) }
render json: photos_page
end end
def show def show

View file

@ -20,10 +20,15 @@ module Api
end end
def show def show
reshares = reshare_service.find_for_post(params[:post_id]).map do |r| reshares_query = reshare_service.find_for_post(params[:post_id])
{guid: r.guid, author: PersonPresenter.new(r.author).as_api_json} reshares_page = index_pager(reshares_query).response
reshares_page[:data] = reshares_page[:data].map do |r|
{
guid: r.guid,
author: PersonPresenter.new(r.author).as_api_json
}
end end
render json: reshares render json: reshares_page
end end
def create def create
@ -34,6 +39,8 @@ module Api
render json: PostPresenter.new(reshare, current_user).as_api_response render json: PostPresenter.new(reshare, current_user).as_api_response
end end
private
def reshare_service def reshare_service
@reshare_service ||= ReshareService.new(current_user) @reshare_service ||= ReshareService.new(current_user)
end end

View file

@ -14,17 +14,27 @@ module Api
def user_index def user_index
parameters = params.permit(:tag, :name_or_handle) parameters = params.permit(:tag, :name_or_handle)
raise RuntimeError if parameters.keys.length != 1 raise RuntimeError if parameters.keys.length != 1
people = if params.has_key?(:tag) people_query = if params.has_key?(:tag)
Person.profile_tagged_with(params[:tag]) Person.profile_tagged_with(params[:tag])
else else
Person.search(params[:name_or_handle], current_user) Person.search(params[:name_or_handle], current_user)
end end
render json: people.map {|p| PersonPresenter.new(p).as_api_json } user_page = index_pager(people_query).response
user_page[:data] = user_page[:data].map {|p| PersonPresenter.new(p).as_api_json }
render json: user_page
end end
def post_index def post_index
posts = Stream::Tag.new(current_user, params.require(:tag)).posts posts_query = Stream::Tag.new(current_user, params.require(:tag)).posts
render json: posts.map {|p| PostPresenter.new(p).as_api_response } posts_page = time_pager(posts_query, "posts.created_at", "created_at").response
posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post).as_api_response }
render json: posts_page
end
private
def time_pager(query, query_time_field, data_time_field)
Api::Paging::RestPaginatorBuilder.new(query, request).time_pager(params, query_time_field, data_time_field)
end end
end end
end end

View file

@ -9,12 +9,12 @@ module Api
def aspects def aspects
aspect_ids = params.has_key?(:aspect_ids) ? JSON.parse(params[:aspect_ids]) : [] aspect_ids = params.has_key?(:aspect_ids) ? JSON.parse(params[:aspect_ids]) : []
@stream = Stream::Aspect.new(current_user, aspect_ids, max_time: max_time) @stream = Stream::Aspect.new(current_user, aspect_ids, max_time: stream_max_time)
stream_responder stream_responder
end end
def activity def activity
stream_responder(Stream::Activity) stream_responder(Stream::Activity, "posts.interacted_at", "interacted_at")
end end
def multi def multi
@ -39,10 +39,25 @@ module Api
private private
def stream_responder(stream_klass=nil) def stream_responder(stream_klass=nil, query_time_field="posts.created_at", data_time_field="created_at")
@stream = stream_klass.present? ? stream_klass.new(current_user, max_time: max_time) : @stream @stream = stream_klass.present? ? stream_klass.new(current_user, max_time: stream_max_time) : @stream
posts_page = pager(@stream.stream_posts, query_time_field, data_time_field).response
posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post, current_user).as_api_response }
posts_page[:links].delete(:previous)
render json: posts_page
end
render json: @stream.stream_posts.map {|p| PostPresenter.new(p, current_user).as_api_response } def stream_max_time
if params.has_key?("before")
Time.iso8601(params["before"])
else
max_time
end
end
def pager(query, query_time_field, data_time_field)
Api::Paging::RestPaginatorBuilder.new(query, request, true, 15)
.time_pager(params, query_time_field, data_time_field)
end end
end end
end end

View file

@ -44,20 +44,26 @@ module Api
return return
end end
contacts_with_profile = AspectsMembershipService.new(current_user).all_contacts contacts_query = AspectsMembershipService.new(current_user).all_contacts
render json: contacts_with_profile.map {|c| PersonPresenter.new(c.person).as_api_json } contacts_page = index_pager(contacts_query).response
contacts_page[:data] = contacts_page[:data].map {|c| PersonPresenter.new(c.person).as_api_json }
render json: contacts_page
end end
def photos def photos
person = Person.find_by!(guid: params[:user_id]) person = Person.find_by!(guid: params[:user_id])
photos = Photo.visible(current_user, person, :all, Time.current) photos_query = Photo.visible(current_user, person, :all, Time.current)
render json: photos.map {|photo| PhotoPresenter.new(photo).as_api_json(true) } photos_page = time_pager(photos_query).response
photos_page[:data] = photos_page[:data].map {|photo| PhotoPresenter.new(photo).as_api_json(true) }
render json: photos_page
end end
def posts def posts
person = Person.find_by!(guid: params[:user_id]) person = Person.find_by!(guid: params[:user_id])
posts = current_user.posts_from(person) posts_query = current_user.posts_from(person, false)
render json: posts.map {|post| PostPresenter.new(post, current_user).as_api_response } posts_page = time_pager(posts_query).response
posts_page[:data] = posts_page[:data].map {|post| PostPresenter.new(post, current_user).as_api_response }
render json: posts_page
end end
private private

View file

@ -67,8 +67,10 @@ module User::Querying
contact_for(person).aspects contact_for(person).aspects
end end
def posts_from(person) def posts_from(person, with_order=true)
Post.from_person_visible_by_user(self, person).order("posts.created_at desc") base_query = Post.from_person_visible_by_user(self, person)
return base_query.order("posts.created_at desc") if with_order
base_query
end end
def photos_from(person, opts={}) def photos_from(person, opts={})

View file

@ -2,8 +2,7 @@
class ConversationPresenter < BasePresenter class ConversationPresenter < BasePresenter
def as_api_json def as_api_json
read = !@presentable.conversation_visibilities.empty? && read = @presentable.conversation_visibilities.find_by(person_id: current_user.person_id)&.unread == 0
@presentable.conversation_visibilities[0].unread == 0
{ {
guid: @presentable.guid, guid: @presentable.guid,
subject: @presentable.subject, subject: @presentable.subject,

View file

@ -3,7 +3,7 @@
class NotificationPresenter < BasePresenter class NotificationPresenter < BasePresenter
def as_api_json(include_target=true) def as_api_json(include_target=true)
data = base_hash data = base_hash
data = data.merge(target: target_json) if include_target data = data.merge(target: target_json) if include_target && target
data data
end end

View file

@ -0,0 +1,38 @@
# frozen_string_literal: true
module Api
module Paging
class IndexPaginator
def initialize(query_base, current_page, limit)
@query_base = query_base
@current_page = current_page.to_i
@limit = limit.to_i
end
def page_data
@page_data ||= @query_base.paginate(page: @current_page, per_page: @limit)
@max_page = (@query_base.count * 1.0 / @limit * 1.0).ceil
@max_page = 1 if @max_page < 1
@page_data
end
def next_page(for_url=true)
page_data
return nil if for_url && @current_page == @max_page
return "page=#{@current_page + 1}" if for_url
IndexPaginator.new(@query_base, @current_page + 1, @limit)
end
def previous_page(for_url=true)
page_data
return nil if for_url && @current_page == 1
return "page=#{@current_page - 1}" if for_url
IndexPaginator.new(@query_base, @current_page - 1, @limit)
end
def filter_parameters(parameters)
parameters.delete(:page)
end
end
end
end

View file

@ -0,0 +1,47 @@
# frozen_string_literal: true
module Api
module Paging
class RestPagedResponseBuilder
def initialize(pager, request, allowed_params=nil)
@pager = pager
@base_url = request.original_url.split("?").first if request
@query_parameters = if allowed_params
allowed_params
elsif request&.query_parameters
request&.query_parameters
else
{}
end
end
def response
{
links: navigation_builder,
data: @pager.page_data
}
end
private
def navigation_builder
previous_page = @pager.previous_page
links = {}
links[:previous] = link_builder(previous_page) if previous_page
next_page = @pager.next_page
links[:next] = link_builder(next_page) if next_page
links
end
def link_builder(page_parameter)
"#{@base_url}?#{filtered_original_parameters}#{page_parameter}"
end
def filtered_original_parameters
@pager.filter_parameters(@query_parameters)
return "" if @query_parameters.empty?
@query_parameters.map {|k, v| "#{k}=#{v}" }.join("&") + "&"
end
end
end
end

View file

@ -0,0 +1,79 @@
# frozen_string_literal: true
module Api
module Paging
class RestPaginatorBuilder
MAX_LIMIT = 100
DEFAULT_LIMIT = 15
def initialize(base_query, request, allow_default_page=true, default_limit=DEFAULT_LIMIT)
@base_query = base_query
@request = request
@allow_default_page = allow_default_page
@default_limit = if default_limit < MAX_LIMIT && default_limit > 0
default_limit
else
DEFAULT_LIMIT
end
end
def index_pager(params)
current_page = current_page_settings(params)
paged_response_builder(IndexPaginator.new(@base_query, current_page, limit_settings(params)))
end
def time_pager(params, query_time_field="created_at", data_time_field=query_time_field)
is_descending, current_time = time_settings(params)
paged_response_builder(
TimePaginator.new(
query_base: @base_query,
query_time_field: query_time_field,
data_time_field: data_time_field,
current_time: current_time,
is_descending: is_descending,
limit: limit_settings(params)
)
)
end
private
def current_page_settings(params)
if params["page"]
requested_page = params["page"]
requested_page = 1 if requested_page < 1
requested_page
elsif @allow_default_page
1
else
raise ActionController::ParameterMissing
end
end
def paged_response_builder(paginator)
Api::Paging::RestPagedResponseBuilder.new(paginator, @request)
end
def time_settings(params)
time_params = params.permit("before", "after")
time_params["before"] = (Time.current + 1.year).iso8601 if time_params.empty? && @allow_default_page
raise "Missing time parameters for query building" if time_params.empty?
if time_params["before"]
is_descending = true
current_time = Time.iso8601(time_params["before"])
else
is_descending = false
current_time = Time.iso8601(time_params["after"])
end
[is_descending, current_time]
end
def limit_settings(params)
requested_limit = params["per_page"]
return @default_limit unless requested_limit
requested_limit = [1, requested_limit].max
[requested_limit, MAX_LIMIT].min
end
end
end
end

View file

@ -0,0 +1,103 @@
# frozen_string_literal: true
module Api
module Paging
class TimePaginator
def initialize(opts={})
@query_base = opts[:query_base]
@query_time_field = opts[:query_time_field]
@data_time_field = opts[:data_time_field]
@current_time = opts[:current_time]
@limit = opts[:limit]
@is_descending = opts[:is_descending]
direction = if @is_descending
"<"
else
">"
end
@time_query_string = "#{@query_time_field} #{direction} ?"
@sort_string = if @is_descending
"#{@query_time_field} DESC"
else
"#{@query_time_field} ASC"
end
end
def page_data
return @data if @data
@data = @query_base.where([@time_query_string, @current_time.iso8601(3)]).limit(@limit).order(@sort_string)
time_data = @data.map {|d| d[@data_time_field] }.sort
@min_time = time_data.first
@max_time = time_data.last + 0.001.seconds if time_data.last
@data
end
def next_page(for_url=true)
page_data
return nil unless next_time
return next_page_as_query_parameter if for_url
TimePaginator.new(
query_base: @query_base,
query_time_field: @query_time_field,
query_data_field: @data_time_field,
current_time: next_time,
is_descending: @is_descending,
limit: @limit
)
end
def previous_page(for_url=true)
page_data
return nil unless previous_time
return previous_page_as_query_parameter if for_url
TimePaginator.new(
query_base: @query_base,
query_time_field: @query_time_field,
query_data_field: @data_time_field,
current_time: previous_time,
is_descending: !@is_descending,
limit: @limit
)
end
def filter_parameters(parameters)
parameters.delete(:before)
parameters.delete(:after)
end
private
def next_time
if @is_descending
@min_time
else
@max_time
end
end
def previous_time
if @is_descending
@max_time
else
@min_time
end
end
def next_page_as_query_parameter
if @is_descending
"before=#{next_time.iso8601(3)}"
else
"after=#{next_time.iso8601(3)}"
end
end
def previous_page_as_query_parameter
if @is_descending
"after=#{previous_time.iso8601(3)}"
else
"before=#{previous_time.iso8601(3)}"
end
end
end
end
end

View file

@ -20,7 +20,7 @@ describe Api::V1::AspectsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
aspects = JSON.parse(response.body) aspects = response_body_data(response)
expect(aspects.length).to eq(auth.user.aspects.length) expect(aspects.length).to eq(auth.user.aspects.length)
aspects.each do |aspect| aspects.each do |aspect|
found_aspect = auth.user.aspects.find_by(id: aspect["id"]) found_aspect = auth.user.aspects.find_by(id: aspect["id"])
@ -299,4 +299,8 @@ describe Api::V1::AspectsController do
end end
end end
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
end end

View file

@ -70,8 +70,8 @@ describe Api::V1::CommentsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
expect(response_body(response).length).to eq(2) comments = response_body_data(response)
comments = response_body(response) expect(comments.length).to eq(2)
confirm_comment_format(comments[0], auth.user, @comment_text1) confirm_comment_format(comments[0], auth.user, @comment_text1)
confirm_comment_format(comments[1], auth.user, @comment_text2) confirm_comment_format(comments[1], auth.user, @comment_text2)
end end
@ -289,6 +289,10 @@ describe Api::V1::CommentsController do
JSON.parse(response.body) JSON.parse(response.body)
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
private private
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize

View file

@ -26,7 +26,7 @@ describe Api::V1::ContactsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
contacts = JSON.parse(response.body) contacts = response_body_data(response)
expect(contacts.length).to eq(1) expect(contacts.length).to eq(1)
confirm_person_format(contacts[0], alice) confirm_person_format(contacts[0], alice)
@ -35,7 +35,7 @@ describe Api::V1::ContactsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
contacts = JSON.parse(response.body) contacts = response_body_data(response)
expect(contacts.length).to eq(@aspect1.contacts.length) expect(contacts.length).to eq(@aspect1.contacts.length)
end end
end end
@ -218,6 +218,10 @@ describe Api::V1::ContactsController do
end end
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
def aspects_membership_service(user=auth.user) def aspects_membership_service(user=auth.user)
AspectsMembershipService.new(user) AspectsMembershipService.new(user)
end end

View file

@ -13,10 +13,10 @@ describe Api::V1::ConversationsController do
alice.share_with auth.user.person, alice.aspects[0] alice.share_with auth.user.person, alice.aspects[0]
auth.user.disconnected_by(eve) auth.user.disconnected_by(eve)
@conversation = { @conversation_request = {
subject: "new conversation", subject: "new conversation",
body: "first message", body: "first message",
recipients: JSON.generate([alice.guid]), recipients: [alice.guid],
access_token: access_token access_token: access_token
} }
end end
@ -24,10 +24,10 @@ describe Api::V1::ConversationsController do
describe "#create" do describe "#create" do
context "with valid data" do context "with valid data" do
it "creates the conversation" do it "creates the conversation" do
post api_v1_conversations_path, params: @conversation post api_v1_conversations_path, params: @conversation_request
expect(response.status).to eq 201 expect(response.status).to eq 201
conversation = JSON.parse(response.body) conversation = JSON.parse(response.body)
confirm_conversation_format(conversation, @conversation, [auth.user, alice]) confirm_conversation_format(conversation, @conversation_request, [auth.user, alice])
end end
end end
@ -75,7 +75,7 @@ describe Api::V1::ConversationsController do
incomplete_conversation = { incomplete_conversation = {
subject: "new conversation", subject: "new conversation",
body: "first message", body: "first message",
recipients: JSON.generate(["999_999_999"]), recipients: ["999_999_999"],
access_token: access_token access_token: access_token
} }
post api_v1_conversations_path, params: incomplete_conversation post api_v1_conversations_path, params: incomplete_conversation
@ -87,7 +87,7 @@ describe Api::V1::ConversationsController do
incomplete_conversation = { incomplete_conversation = {
subject: "new conversation", subject: "new conversation",
body: "first message", body: "first message",
recipients: JSON.generate([eve.guid]), recipients: [eve.guid],
access_token: access_token access_token: access_token
} }
post api_v1_conversations_path, params: incomplete_conversation post api_v1_conversations_path, params: incomplete_conversation
@ -99,25 +99,28 @@ describe Api::V1::ConversationsController do
describe "#index" do describe "#index" do
before do before do
post api_v1_conversations_path, params: @conversation post api_v1_conversations_path, params: @conversation_request
post api_v1_conversations_path, params: @conversation @read_conversation_guid = JSON.parse(response.body)["guid"]
@read_conversation = conversation_service.find!(@read_conversation_guid)
post api_v1_conversations_path, params: @conversation_request
sleep(1) sleep(1)
post api_v1_conversations_path, params: @conversation post api_v1_conversations_path, params: @conversation_request
conversation_guid = JSON.parse(response.body)["guid"] @conversation_guid = JSON.parse(response.body)["guid"]
conversation = conversation_service.find!(conversation_guid) @conversation = conversation_service.find!(@conversation_guid)
conversation.conversation_visibilities[0].unread = 1 @conversation.conversation_visibilities[0].unread = 1
conversation.conversation_visibilities[0].save! @conversation.conversation_visibilities[0].save!
conversation.conversation_visibilities[1].unread = 1 @conversation.conversation_visibilities[1].unread = 1
conversation.conversation_visibilities[1].save! @conversation.conversation_visibilities[1].save!
@date = conversation.created_at @date = @conversation.created_at
end end
it "returns all the user conversations" do it "returns all the user conversations" do
get api_v1_conversations_path, params: {access_token: access_token} get api_v1_conversations_path, params: {access_token: access_token}
expect(response.status).to eq 200 expect(response.status).to eq 200
returned_conversations = JSON.parse(response.body) returned_conversations = response_body_data(response)
expect(returned_conversations.length).to eq 3 expect(returned_conversations.length).to eq 3
confirm_conversation_format(returned_conversations[0], @conversation, [auth.user, alice]) actual_conversation = returned_conversations.select {|c| c["guid"] == @read_conversation_guid }[0]
confirm_conversation_format(actual_conversation, @read_conversation, [auth.user, alice])
end end
it "returns all the user unread conversations" do it "returns all the user unread conversations" do
@ -126,7 +129,7 @@ describe Api::V1::ConversationsController do
params: {only_unread: true, access_token: access_token} params: {only_unread: true, access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
expect(JSON.parse(response.body).length).to eq 2 expect(response_body_data(response).length).to eq 2
end end
it "returns all the user conversations after a given date" do it "returns all the user conversations after a given date" do
@ -135,14 +138,16 @@ describe Api::V1::ConversationsController do
params: {only_after: @date, access_token: access_token} params: {only_after: @date, access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
expect(JSON.parse(response.body).length).to eq 1 expect(response_body_data(response).length).to eq 1
end end
end end
describe "#show" do describe "#show" do
context "valid conversation ID" do context "valid conversation ID" do
before do before do
post api_v1_conversations_path, params: @conversation post api_v1_conversations_path, params: @conversation_request
@conversation_guid = JSON.parse(response.body)["guid"]
@conversation = conversation_service.find!(@conversation_guid)
end end
it "returns the corresponding conversation" do it "returns the corresponding conversation" do
@ -177,13 +182,13 @@ describe Api::V1::ConversationsController do
auth.user.person, auth_participant.user.aspects[0] auth.user.person, auth_participant.user.aspects[0]
) )
@conversation = { @conversation_request = {
subject: "new conversation", subject: "new conversation",
body: "first message", body: "first message",
recipients: JSON.generate([auth_participant.user.guid]), recipients: [auth_participant.user.guid],
access_token: access_token access_token: access_token
} }
post api_v1_conversations_path, params: @conversation post api_v1_conversations_path, params: @conversation_request
@conversation_guid = JSON.parse(response.body)["guid"] @conversation_guid = JSON.parse(response.body)["guid"]
end end
@ -251,6 +256,10 @@ describe Api::V1::ConversationsController do
private private
def response_body_data(response)
JSON.parse(response.body)["data"]
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
def confirm_conversation_format(conversation, ref_conversation, ref_participants) def confirm_conversation_format(conversation, ref_conversation, ref_participants)
expect(conversation["guid"]).to_not be_nil expect(conversation["guid"]).to_not be_nil

View file

@ -23,7 +23,7 @@ describe Api::V1::LikesController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
likes = response_body(response) likes = response_body_data(response)
expect(likes.length).to eq(0) expect(likes.length).to eq(0)
end end
@ -36,7 +36,7 @@ describe Api::V1::LikesController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
likes = response_body(response) likes = response_body_data(response)
expect(likes.length).to eq(3) expect(likes.length).to eq(3)
confirm_like_format(likes, alice) confirm_like_format(likes, alice)
confirm_like_format(likes, bob) confirm_like_format(likes, bob)
@ -170,4 +170,8 @@ describe Api::V1::LikesController do
def response_body(response) def response_body(response)
JSON.parse(response.body) JSON.parse(response.body)
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
end end

View file

@ -15,7 +15,7 @@ describe Api::V1::MessagesController do
@conversation = { @conversation = {
subject: "new conversation", subject: "new conversation",
body: "first message", body: "first message",
recipients: JSON.generate([alice.guid]), recipients: [alice.guid],
access_token: access_token access_token: access_token
} }
@ -43,7 +43,7 @@ describe Api::V1::MessagesController do
api_v1_conversation_messages_path(@conversation_guid), api_v1_conversation_messages_path(@conversation_guid),
params: {access_token: access_token} params: {access_token: access_token}
) )
messages = JSON.parse(response.body) messages = response_body_data(response)
expect(messages.length).to eq 2 expect(messages.length).to eq 2
confirm_message_format(messages[1], @message_text, auth.user) confirm_message_format(messages[1], @message_text, auth.user)
end end
@ -93,7 +93,8 @@ describe Api::V1::MessagesController do
api_v1_conversation_messages_path(@conversation_guid), api_v1_conversation_messages_path(@conversation_guid),
params: {access_token: access_token} params: {access_token: access_token}
) )
messages = JSON.parse(response.body) expect(response.status).to eq 200
messages = response_body_data(response)
expect(messages.length).to eq 1 expect(messages.length).to eq 1
confirm_message_format(messages[0], "first message", auth.user) confirm_message_format(messages[0], "first message", auth.user)
@ -105,10 +106,14 @@ describe Api::V1::MessagesController do
private private
def response_body_data(response)
JSON.parse(response.body)["data"]
end
def get_conversation(conversation_id) def get_conversation(conversation_id)
conversation_service = ConversationService.new(auth.user) conversation_service = ConversationService.new(auth.user)
raw_conversation = conversation_service.find!(conversation_id) raw_conversation = conversation_service.find!(conversation_id)
ConversationPresenter.new(raw_conversation).as_api_json ConversationPresenter.new(raw_conversation, auth.user).as_api_json
end end
def confirm_message_format(message, ref_message, author) def confirm_message_format(message, ref_message, author)

View file

@ -26,7 +26,7 @@ describe Api::V1::NotificationsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
notification = JSON.parse(response.body) notification = response_body_data(response)
expect(notification.length).to eq(1) expect(notification.length).to eq(1)
confirm_notification_format(notification[0], @notification, "also_commented", nil) confirm_notification_format(notification[0], @notification, "also_commented", nil)
end end
@ -37,7 +37,7 @@ describe Api::V1::NotificationsController do
params: {only_unread: true, access_token: access_token} params: {only_unread: true, access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
notification = JSON.parse(response.body) notification = response_body_data(response)
expect(notification.length).to eq(1) expect(notification.length).to eq(1)
@notification.set_read_state(true) @notification.set_read_state(true)
get( get(
@ -45,7 +45,7 @@ describe Api::V1::NotificationsController do
params: {only_unread: true, access_token: access_token} params: {only_unread: true, access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
notification = JSON.parse(response.body) notification = response_body_data(response)
expect(notification.length).to eq(0) expect(notification.length).to eq(0)
end end
@ -55,7 +55,7 @@ describe Api::V1::NotificationsController do
params: {only_after: (Date.current - 1.day).iso8601, access_token: access_token} params: {only_after: (Date.current - 1.day).iso8601, access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
notification = JSON.parse(response.body) notification = response_body_data(response)
expect(notification.length).to eq(1) expect(notification.length).to eq(1)
@notification.set_read_state(true) @notification.set_read_state(true)
get( get(
@ -63,7 +63,7 @@ describe Api::V1::NotificationsController do
params: {only_after: (Date.current + 1.day).iso8601, access_token: access_token} params: {only_after: (Date.current + 1.day).iso8601, access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
notification = JSON.parse(response.body) notification = response_body_data(response)
expect(notification.length).to eq(0) expect(notification.length).to eq(0)
end end
end end
@ -195,6 +195,10 @@ describe Api::V1::NotificationsController do
private private
def response_body_data(response)
JSON.parse(response.body)["data"]
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
def confirm_notification_format(notification, ref_notification, expected_type, target) def confirm_notification_format(notification, ref_notification, expected_type, target)
expect(notification["guid"]).to eq(ref_notification.guid) expect(notification["guid"]).to eq(ref_notification.guid)

View file

@ -93,7 +93,7 @@ describe Api::V1::PhotosController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
photos = JSON.parse(response.body) photos = response_body_data(response)
expect(photos.length).to eq(2) expect(photos.length).to eq(2)
end end
end end
@ -267,6 +267,10 @@ describe Api::V1::PhotosController do
end end
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
def confirm_photo_format(photo, ref_photo, ref_user) def confirm_photo_format(photo, ref_photo, ref_user)
expect(photo["guid"]).to eq(ref_photo.guid) expect(photo["guid"]).to eq(ref_photo.guid)

View file

@ -35,7 +35,7 @@ describe Api::V1::ResharesController do
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
reshares = JSON.parse(response.body) reshares = response_body_data(response)
expect(reshares.length).to eq(1) expect(reshares.length).to eq(1)
reshare = reshares[0] reshare = reshares[0]
expect(reshare["guid"]).not_to be_nil expect(reshare["guid"]).not_to be_nil
@ -57,7 +57,7 @@ describe Api::V1::ResharesController do
} }
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
reshares = JSON.parse(response.body) reshares = response_body_data(response)
expect(reshares.length).to eq(0) expect(reshares.length).to eq(0)
end end
end end
@ -169,7 +169,6 @@ describe Api::V1::ResharesController do
access_token: access_token access_token: access_token
} }
) )
puts(response.body)
expect(response.status).to eq(404) expect(response.status).to eq(404)
expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found")) expect(response.body).to eq(I18n.t("api.endpoint_errors.posts.post_not_found"))
end end
@ -204,6 +203,10 @@ describe Api::V1::ResharesController do
@reshare_service ||= ReshareService.new(user) @reshare_service ||= ReshareService.new(user)
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
# rubocop:disable Metrics/AbcSize # rubocop:disable Metrics/AbcSize
def confirm_person_format(post_person, user) def confirm_person_format(post_person, user)
expect(post_person["guid"]).to eq(user.guid) expect(post_person["guid"]).to eq(user.guid)

View file

@ -39,7 +39,7 @@ describe Api::V1::SearchController do
params: {tag: "one", access_token: access_token} params: {tag: "one", access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
users = JSON.parse(response.body) users = response_body_data(response)
expect(users.length).to eq(14) expect(users.length).to eq(14)
end end
@ -49,7 +49,7 @@ describe Api::V1::SearchController do
params: {name_or_handle: "Terry", access_token: access_token} params: {name_or_handle: "Terry", access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
users = JSON.parse(response.body) users = response_body_data(response)
expect(users.length).to eq(1) expect(users.length).to eq(1)
end end
@ -59,7 +59,7 @@ describe Api::V1::SearchController do
params: {name_or_handle: "findable", access_token: access_token} params: {name_or_handle: "findable", access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
users = JSON.parse(response.body) users = response_body_data(response)
expect(users.length).to eq(1) expect(users.length).to eq(1)
end end
@ -69,7 +69,7 @@ describe Api::V1::SearchController do
params: {name_or_handle: "Closed", access_token: access_token} params: {name_or_handle: "Closed", access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
users = JSON.parse(response.body) users = response_body_data(response)
expect(users.length).to eq(0) expect(users.length).to eq(0)
end end
@ -79,7 +79,7 @@ describe Api::V1::SearchController do
params: {name_or_handle: "unsearchable@example.org", access_token: access_token} params: {name_or_handle: "unsearchable@example.org", access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
users = JSON.parse(response.body) users = response_body_data(response)
expect(users.length).to eq(0) expect(users.length).to eq(0)
end end
@ -131,7 +131,7 @@ describe Api::V1::SearchController do
params: {tag: "tag2", access_token: access_token} params: {tag: "tag2", access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
posts = JSON.parse(response.body) posts = response_body_data(response)
expect(posts.length).to eq(2) expect(posts.length).to eq(2)
end end
@ -152,4 +152,8 @@ describe Api::V1::SearchController do
expect(response.status).to eq(401) expect(response.status).to eq(401)
end end
end end
def response_body_data(response)
JSON.parse(response.body)["data"]
end
end end

View file

@ -20,7 +20,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 1 expect(post.length).to eq 1
confirm_post_format(post[0], auth.user, @status) confirm_post_format(post[0], auth.user, @status)
end end
@ -31,7 +31,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 1 expect(post.length).to eq 1
confirm_post_format(post[0], auth.user, @status) confirm_post_format(post[0], auth.user, @status)
end end
@ -52,7 +52,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 0 expect(post.length).to eq 0
end end
end end
@ -64,7 +64,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 1 expect(post.length).to eq 1
confirm_post_format(post[0], auth.user, @status) confirm_post_format(post[0], auth.user, @status)
end end
@ -77,7 +77,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 1 expect(post.length).to eq 1
confirm_post_format(post[0], auth.user, @status) confirm_post_format(post[0], auth.user, @status)
end end
@ -90,7 +90,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 0 expect(post.length).to eq 0
end end
end end
@ -102,7 +102,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 0 expect(post.length).to eq 0
end end
end end
@ -114,7 +114,7 @@ describe Api::V1::StreamsController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq 200 expect(response.status).to eq 200
post = JSON.parse(response.body) post = response_body_data(response)
expect(post.length).to eq 1 expect(post.length).to eq 1
confirm_post_format(post[0], auth.user, @status) confirm_post_format(post[0], auth.user, @status)
end end
@ -205,4 +205,8 @@ describe Api::V1::StreamsController do
confirm_person_format(root["author"], root_poster) confirm_person_format(root["author"], root_poster)
end end
# rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/AbcSize
def response_body_data(response)
JSON.parse(response.body)["data"]
end
end end

View file

@ -237,7 +237,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
contacts = JSON.parse(response.body) contacts = response_body_data(response)
expect(contacts.length).to eq(0) expect(contacts.length).to eq(0)
auth.user.share_with(alice.person, auth.user.aspects.first) auth.user.share_with(alice.person, auth.user.aspects.first)
@ -246,7 +246,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
contacts = JSON.parse(response.body) contacts = response_body_data(response)
expect(contacts.length).to eq(1) expect(contacts.length).to eq(1)
confirm_person_format(contacts[0], alice) confirm_person_format(contacts[0], alice)
end end
@ -301,7 +301,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
photos = JSON.parse(response.body) photos = response_body_data(response)
expect(photos.length).to eq(3) expect(photos.length).to eq(3)
guids = photos.map {|photo| photo["guid"] } guids = photos.map {|photo| photo["guid"] }
expect(guids).to include(@public_photo1.guid, @public_photo2.guid, @shared_photo1.guid) expect(guids).to include(@public_photo1.guid, @public_photo2.guid, @shared_photo1.guid)
@ -361,7 +361,7 @@ describe Api::V1::UsersController do
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
posts = JSON.parse(response.body) posts = response_body_data(response)
expect(posts.length).to eq(3) expect(posts.length).to eq(3)
guids = posts.map {|post| post["guid"] } guids = posts.map {|post| post["guid"] }
expect(guids).to include(@public_post1.guid, @public_post2.guid, @shared_post1.guid) expect(guids).to include(@public_post1.guid, @public_post2.guid, @shared_post1.guid)
@ -370,13 +370,13 @@ describe Api::V1::UsersController do
confirm_post_format(post[0], alice, @public_post1) confirm_post_format(post[0], alice, @public_post1)
end end
it "returns logged in user's photos" do it "returns logged in user's posts" do
get( get(
api_v1_user_posts_path(auth.user.guid), api_v1_user_posts_path(auth.user.guid),
params: {access_token: access_token} params: {access_token: access_token}
) )
expect(response.status).to eq(200) expect(response.status).to eq(200)
posts = JSON.parse(response.body) posts = response_body_data(response)
expect(posts.length).to eq(2) expect(posts.length).to eq(2)
end end
end end
@ -483,4 +483,8 @@ describe Api::V1::UsersController do
end end
end end
# rubocop:enable Metrics/AbcSize # rubocop:enable Metrics/AbcSize
def response_body_data(response)
JSON.parse(response.body)["data"]
end
end end

View file

@ -0,0 +1,61 @@
# frozen_string_literal: true
describe Api::Paging::IndexPaginator do
before do
(1..7).each do |i|
public = !(i == 1 || i == 6)
alice.post(
:status_message,
text: "Post #{i}",
public: public
)
end
@alice_search = alice.posts.where(public: true).order("id ASC")
@limit = 2
end
it "goes through using direct paging" do
pager = Api::Paging::IndexPaginator.new(@alice_search, 1, @limit)
page = pager.page_data
validate_page(page, :created_at, false)
page_count = 0
until page&.empty?
page_count += 1
pager = pager.next_page(false)
page = pager.page_data
validate_page(page, :created_at, false)
end
expect(page_count).to eq(3)
end
it "goes through using Query Parameter data" do
page_num = 1
pager = Api::Paging::IndexPaginator.new(@alice_search, page_num, @limit)
page = pager.page_data
validate_page(page, :created_at, false)
page_count = 0
until page&.empty?
page_count += 1
break unless pager.next_page
np = pager.next_page.split("=").last.to_i
pager = Api::Paging::IndexPaginator.new(@alice_search, np, @limit)
page = pager.page_data
validate_page(page, :created_at, false)
end
expect(page_count).to eq(3)
end
def validate_page(page, field, is_descending)
expect(page.length).to be <= @limit
last_value = nil
page.each do |element|
last_value ||= element[field]
if is_descending
expect(last_value).to be >= element[field]
else
expect(last_value).to be <= element[field]
end
last_value = element[field]
end
end
end

View file

@ -0,0 +1,13 @@
# frozen_string_literal: true
describe Api::Paging::RestPagedResponseBuilder do
before do
@pager = Api::Paging::IndexPaginator.new(alice.posts, 1, 5)
end
it "returns page of data" do
builder = Api::Paging::RestPagedResponseBuilder.new(@pager, nil)
response = builder.response
expect(response[:links]).not_to be_nil
expect(response[:data]).not_to be_nil
end
end

View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
describe Api::Paging::RestPaginatorBuilder do
it "generates page response builder called with index-based pager" do
params = ActionController::Parameters.new(page: 1)
pager = Api::Paging::RestPaginatorBuilder.new(alice.posts, nil).index_pager(params)
expect(pager.is_a?(Api::Paging::RestPagedResponseBuilder)).to be_truthy
end
it "generates page response builder with time-based pager" do
params = ActionController::Parameters.new(before: Time.current.iso8601)
pager = Api::Paging::RestPaginatorBuilder.new(alice.posts, nil).time_pager(params)
expect(pager.is_a?(Api::Paging::RestPagedResponseBuilder)).to be_truthy
end
end

View file

@ -0,0 +1,119 @@
# frozen_string_literal: true
describe Api::Paging::TimePaginator do
before do
(1..7).each do |i|
public = !(i == 1 || i == 6)
alice.post(
:status_message,
text: "Post #{i}",
public: public
)
sleep(0.01.seconds)
end
@alice_search = alice.posts.where(public: true)
@limit = 2
end
it "goes through decending using direct paging" do
pager = Api::Paging::TimePaginator.new(
query_base: @alice_search,
query_time_field: :created_at,
data_time_field: :created_at,
current_time: Time.current,
is_descending: true,
limit: @limit
)
page = pager.page_data
last_time = validate_page(page, :created_at, true, nil)
while page&.empty?
pager = pager.next_page(false)
page = pager.page_data
last_time = validate_page(page, :created_at, true, last_time)
end
end
it "goes through descending using Query Parameter data" do
pager = Api::Paging::TimePaginator.new(
query_base: @alice_search,
query_time_field: :created_at,
data_time_field: :created_at,
current_time: Time.current,
is_descending: true,
limit: @limit
)
page = pager.page_data
last_time = validate_page(page, :created_at, true, nil)
while page&.empty?
next_time = Time.iso8601(pager.next_page.split("=").last)
pager = Api::Paging::TimePaginator.new(
query_base: @alice_search,
query_time_field: :created_at,
data_time_field: :created_at,
current_time: next_time,
is_descending: true,
limit: @limit
)
page = pager.page_data
last_time = validate_page(page, :created_at, true, last_time)
end
end
it "goes through ascending using direct paging" do
pager = Api::Paging::TimePaginator.new(
query_base: @alice_search,
query_time_field: :created_at,
data_time_field: :created_at,
current_time: (Time.current - 1.year),
is_descending: false,
limit: @limit
)
page = pager.page_data
last_time = validate_page(page, :created_at, false, nil)
while page&.empty?
pager = pager.next_page(false)
page = pager.page_data
last_time = validate_page(page, :created_at, false, last_time)
end
end
it "goes through ascending using Query Parameter data" do
pager = Api::Paging::TimePaginator.new(
query_base: @alice_search,
query_time_field: :created_at,
data_time_field: :created_at,
current_time: (Time.current - 1.year),
is_descending: false,
limit: @limit
)
page = pager.page_data
last_time = validate_page(page, :created_at, false, nil)
while page&.empty?
next_time = Time.iso8601(pager.next_page.split("=").last)
pager = Api::Paging::TimePaginator.new(
query_base: @alice_search,
query_time_field: :created_at,
data_time_field: :created_at,
current_time: next_time,
is_descending: false,
limit: @limit
)
page = pager.page_data
last_time = validate_page(page, :created_at, false, last_time)
end
end
def validate_page(page, field, is_descending, last_time)
expect(page.length).to be <= @limit
page.each do |element|
last_time ||= element[field]
if is_descending
expect(last_time).to be >= element[field]
else
expect(last_time).to be <= element[field]
end
last_time = element[field]
end
last_time
end
end