Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/pull/4171'
Browse files Browse the repository at this point in the history
  • Loading branch information
tomhughes committed Aug 17, 2023
2 parents 6b8c8e8 + 5016def commit 54164f6
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 15 deletions.
36 changes: 33 additions & 3 deletions app/controllers/api/changesets_controller.rb
Expand Up @@ -157,6 +157,8 @@ def download
##
# query changesets by bounding box, time, user or open/closed status.
def query
raise OSM::APIBadUserInput, "cannot use order=oldest with time" if params[:time] && params[:order] == "oldest"

# find any bounding box
bbox = BoundingBox.from_bbox_params(params) if params["bbox"]

Expand All @@ -166,15 +168,16 @@ def query
changesets = conditions_bbox(changesets, bbox)
changesets = conditions_user(changesets, params["user"], params["display_name"])
changesets = conditions_time(changesets, params["time"])
changesets = conditions_from_to(changesets, params["from"], params["to"])
changesets = conditions_open(changesets, params["open"])
changesets = conditions_closed(changesets, params["closed"])
changesets = conditions_ids(changesets, params["changesets"])

# sort the changesets
changesets = if params[:order] == "oldest"
changesets.order(:closed_at => :asc)
changesets.order(:created_at => :asc)
else
changesets.order(:closed_at => :desc)
changesets.order(:created_at => :desc)
end

# limit the result
Expand Down Expand Up @@ -327,7 +330,7 @@ def conditions_user(changesets, user, name)
end

##
# restrict changes to those closed during a particular time period
# restrict changesets to those during a particular time period
def conditions_time(changesets, time)
if time.nil?
changesets
Expand All @@ -351,6 +354,33 @@ def conditions_time(changesets, time)
raise OSM::APIBadUserInput, e.message.to_s
end

##
# restrict changesets to those opened during a particular time period
# works similar to from..to of notes controller, including the requirement of 'from' when specifying 'to'
def conditions_from_to(changesets, from, to)
if from
begin
from = Time.parse(from).utc
rescue ArgumentError
raise OSM::APIBadUserInput, "Date #{from} is in a wrong format"
end

begin
to = if to
Time.parse(to).utc
else
Time.now.utc
end
rescue ArgumentError
raise OSM::APIBadUserInput, "Date #{to} is in a wrong format"
end

changesets.where(:created_at => from..to)
else
changesets
end
end

##
# return changesets which are open (haven't been closed yet)
# we do this by seeing if the 'closed at' time is in the future. Also if we've
Expand Down
74 changes: 62 additions & 12 deletions test/controllers/api/changesets_controller_test.rb
Expand Up @@ -1968,38 +1968,85 @@ def test_query_limit
end

##
# test the query functionality of changesets with the order parameter
# test the query functionality of sequential changesets with order and time parameters
def test_query_order
user = create(:user)
changeset1 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 1, 1, 0, 0, 0), :closed_at => Time.utc(2008, 1, 2, 0, 0, 0))
changeset2 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 2, 1, 0, 0, 0), :closed_at => Time.utc(2008, 2, 2, 0, 0, 0))
changeset3 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 3, 1, 0, 0, 0), :closed_at => Time.utc(2008, 3, 2, 0, 0, 0))
changeset4 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 4, 1, 0, 0, 0), :closed_at => Time.utc(2008, 4, 2, 0, 0, 0))
changeset5 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 5, 1, 0, 0, 0), :closed_at => Time.utc(2008, 5, 2, 0, 0, 0))
changeset6 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2008, 6, 1, 0, 0, 0), :closed_at => Time.utc(2008, 6, 2, 0, 0, 0))

get changesets_path
assert_response :success
assert_changesets_in_order [changeset6, changeset5, changeset4, changeset3, changeset2, changeset1]

get changesets_path(:order => "oldest")
assert_response :success
assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4, changeset5]
assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4, changeset5, changeset6]

[
# lower time bound at the opening time of a changeset
["2008-02-01T00:00:00Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3, changeset2], [changeset5, changeset4, changeset3, changeset2]],
# lower time bound in the middle of a changeset
["2008-02-01T12:00:00Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3, changeset2], [changeset5, changeset4, changeset3]],
# lower time bound at the closing time of a changeset
["2008-02-02T00:00:00Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3, changeset2], [changeset5, changeset4, changeset3]],
# lower time bound after the closing time of a changeset
["2008-02-02T00:00:01Z", "2008-05-15T00:00:00Z", [changeset5, changeset4, changeset3], [changeset5, changeset4, changeset3]],
# upper time bound in the middle of a changeset
["2007-09-09T12:00:00Z", "2008-04-01T12:00:00Z", [changeset4, changeset3, changeset2, changeset1], [changeset4, changeset3, changeset2, changeset1]],
# empty range
["2009-02-02T00:00:01Z", "2018-05-15T00:00:00Z", [], []]
].each do |from, to, interval_changesets, point_changesets|
get changesets_path(:time => "#{from},#{to}")
assert_response :success
assert_changesets_in_order interval_changesets

get changesets_path(:order => "oldest", :time => "2008-01-01T00:00Z,2018-01-01T00:00Z")
get changesets_path(:from => from, :to => to)
assert_response :success
assert_changesets_in_order point_changesets

get changesets_path(:from => from, :to => to, :order => "oldest")
assert_response :success
assert_changesets_in_order point_changesets.reverse
end
end

##
# test the query functionality of overlapping changesets with order and time parameters
def test_query_order_overlapping
user = create(:user)
changeset1 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 4, 17, 0, 0), :closed_at => Time.utc(2015, 6, 4, 17, 0, 0))
changeset2 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 4, 16, 0, 0), :closed_at => Time.utc(2015, 6, 4, 18, 0, 0))
changeset3 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 4, 14, 0, 0), :closed_at => Time.utc(2015, 6, 4, 20, 0, 0))
changeset4 = create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 3, 23, 0, 0), :closed_at => Time.utc(2015, 6, 4, 23, 0, 0))
create(:changeset, :closed, :user => user, :created_at => Time.utc(2015, 6, 2, 23, 0, 0), :closed_at => Time.utc(2015, 6, 3, 23, 0, 0))

get changesets_path(:time => "2015-06-04T00:00:00Z")
assert_response :success
assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4, changeset5]
assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4]

get changesets_path(:order => "oldest", :time => "2008-01-02T00:00Z,2018-01-01T00:00Z")
get changesets_path(:from => "2015-06-04T00:00:00Z")
assert_response :success
assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4, changeset5]
assert_changesets_in_order [changeset1, changeset2, changeset3]

get changesets_path(:order => "oldest", :time => "2008-01-02T00:01Z,2018-01-01T00:00Z")
get changesets_path(:from => "2015-06-04T00:00:00Z", :order => "oldest")
assert_response :success
assert_changesets_in_order [changeset2, changeset3, changeset4, changeset5]
assert_changesets_in_order [changeset3, changeset2, changeset1]

get changesets_path(:order => "oldest", :time => "2008-04-01T00:00Z,2018-01-01T00:00Z")
get changesets_path(:time => "2015-06-04T16:00:00Z,2015-06-04T17:30:00Z")
assert_response :success
assert_changesets_in_order [changeset4, changeset5]
assert_changesets_in_order [changeset1, changeset2, changeset3, changeset4]

get changesets_path(:order => "oldest", :time => "2008-06-01T00:00Z,2018-01-01T00:00Z")
get changesets_path(:from => "2015-06-04T16:00:00Z", :to => "2015-06-04T17:30:00Z")
assert_response :success
assert_changesets_in_order []
assert_changesets_in_order [changeset1, changeset2]

get changesets_path(:from => "2015-06-04T16:00:00Z", :to => "2015-06-04T17:30:00Z", :order => "oldest")
assert_response :success
assert_changesets_in_order [changeset2, changeset1]
end

##
Expand Down Expand Up @@ -2029,6 +2076,9 @@ def test_query_invalid
get changesets_path(:user => uid)
assert_response :bad_request, "'#{uid}' isn't a valid user ID"
end

get changesets_path(:order => "oldest", :time => "2008-01-01T00:00Z,2018-01-01T00:00Z")
assert_response :bad_request, "cannot use order=oldest with time"
end

##
Expand Down

0 comments on commit 54164f6

Please sign in to comment.