can [:read, :feed, :search], Note
can :create, Note unless user
- can [:read, :download], Changeset
+ can :read, Changeset
can :read, ChangesetComment
can :read, Tracepoint
can :read, User
# Add a comment to a changeset
def create
# Check the arguments are sane
- raise OSM::APIBadUserInput, "No id was given" unless params[:id]
+ raise OSM::APIBadUserInput, "No id was given" unless params[:changeset_id]
raise OSM::APIBadUserInput, "No text was given" if params[:text].blank?
raise OSM::APIRateLimitExceeded if rate_limit_exceeded?
# Extract the arguments
- id = params[:id].to_i
+ changeset_id = params[:changeset_id].to_i
body = params[:text]
# Find the changeset and check it is valid
- changeset = Changeset.find(id)
+ changeset = Changeset.find(changeset_id)
raise OSM::APIChangesetNotYetClosedError, changeset if changeset.open?
# Add a comment to the changeset
--- /dev/null
+module Api
+ module Changesets
+ class DownloadsController < ApiController
+ before_action :setup_user_auth
+
+ authorize_resource :changeset
+
+ before_action :set_request_formats
+
+ ##
+ # download the changeset as an osmChange document.
+ #
+ # to make it easier to revert diffs it would be better if the osmChange
+ # format were reversible, i.e: contained both old and new versions of
+ # modified elements. but it doesn't at the moment...
+ #
+ # this method cannot order the database changes fully (i.e: timestamp and
+ # version number may be too coarse) so the resulting diff may not apply
+ # to a different database. however since changesets are not atomic this
+ # behaviour cannot be guaranteed anyway and is the result of a design
+ # choice.
+ def show
+ changeset = Changeset.find(params[:changeset_id])
+
+ # get all the elements in the changeset which haven't been redacted
+ # and stick them in a big array.
+ elements = if show_redactions?
+ [changeset.old_nodes,
+ changeset.old_ways,
+ changeset.old_relations].flatten
+ else
+ [changeset.old_nodes.unredacted,
+ changeset.old_ways.unredacted,
+ changeset.old_relations.unredacted].flatten
+ end
+
+ # sort the elements by timestamp and version number, as this is the
+ # almost sensible ordering available. this would be much nicer if
+ # global (SVN-style) versioning were used - then that would be
+ # unambiguous.
+ elements.sort_by! { |e| [e.timestamp, e.version] }
+
+ # generate an output element for each operation. note: we avoid looking
+ # at the history because it is simpler - but it would be more correct to
+ # check these assertions.
+ @created = []
+ @modified = []
+ @deleted = []
+
+ elements.each do |elt|
+ if elt.version == 1
+ # first version, so it must be newly-created.
+ @created << elt
+ elsif elt.visible
+ # must be a modify
+ @modified << elt
+ else
+ # if the element isn't visible then it must have been deleted
+ @deleted << elt
+ end
+ end
+
+ respond_to do |format|
+ format.xml
+ end
+ end
+
+ private
+
+ def show_redactions?
+ current_user&.moderator? && params[:show_redactions] == "true"
+ end
+ end
+ end
+end
end
end
- ##
- # download the changeset as an osmChange document.
- #
- # to make it easier to revert diffs it would be better if the osmChange
- # format were reversible, i.e: contained both old and new versions of
- # modified elements. but it doesn't at the moment...
- #
- # this method cannot order the database changes fully (i.e: timestamp and
- # version number may be too coarse) so the resulting diff may not apply
- # to a different database. however since changesets are not atomic this
- # behaviour cannot be guaranteed anyway and is the result of a design
- # choice.
- def download
- changeset = Changeset.find(params[:id])
-
- # get all the elements in the changeset which haven't been redacted
- # and stick them in a big array.
- elements = [changeset.old_nodes.unredacted,
- changeset.old_ways.unredacted,
- changeset.old_relations.unredacted].flatten
-
- # sort the elements by timestamp and version number, as this is the
- # almost sensible ordering available. this would be much nicer if
- # global (SVN-style) versioning were used - then that would be
- # unambiguous.
- elements.sort_by! { |e| [e.timestamp, e.version] }
-
- # generate an output element for each operation. note: we avoid looking
- # at the history because it is simpler - but it would be more correct to
- # check these assertions.
- @created = []
- @modified = []
- @deleted = []
-
- elements.each do |elt|
- if elt.version == 1
- # first version, so it must be newly-created.
- @created << elt
- elsif elt.visible
- # must be a modify
- @modified << elt
- else
- # if the element isn't visible then it must have been deleted
- @deleted << elt
- end
- end
-
- respond_to do |format|
- format.xml
- end
- end
-
##
# updates a changeset's tags. none of the changeset's attributes are
# user-modifiable, so they will be ignored.
##
# display a list of users matching specified criteria
def show
- @params = params.permit(:status, :ip, :before, :after)
+ @params = params.permit(:status, :username, :ip, :before, :after)
users = User.all
users = users.where(:status => @params[:status]) if @params[:status].present?
+ users = users.where("LOWER(email) = LOWER(?) OR LOWER(NORMALIZE(display_name, NFKC)) = LOWER(NORMALIZE(?, NFKC))", @params[:username], @params[:username]) if @params[:username].present?
users = users.where("creation_address <<= ?", @params[:ip]) if @params[:ip].present?
@users_count = users.limit(501).count
xml.osmChange(OSM::API.new.xml_root_attributes) do |osm|
@created.each do |elt|
osm.create do |create|
- create << render(elt)
+ create << render(:partial => "api/#{elt.to_partial_path}", :object => elt)
end
end
@modified.each do |elt|
osm.modify do |modify|
- modify << render(elt)
+ modify << render(:partial => "api/#{elt.to_partial_path}", :object => elt)
end
end
@deleted.each do |elt|
osm.delete do |delete|
- delete << render(elt)
+ delete << render(:partial => "api/#{elt.to_partial_path}", :object => elt)
end
end
end
@changesets.each do |changeset|
feed.entry(changeset, :updated => changeset.closed_at, :id => changeset_url(changeset.id, :only_path => false)) do |entry|
entry.link :rel => "alternate",
- :href => changeset_show_url(changeset, :only_path => false),
+ :href => api_changeset_url(changeset, :only_path => false),
:type => "application/osm+xml"
entry.link :rel => "alternate",
- :href => changeset_download_url(changeset, :only_path => false),
+ :href => api_changeset_download_url(changeset, :only_path => false),
:type => "application/osmChange+xml"
if !changeset.tags.empty? && changeset.tags.key?("comment")
:name => "comment",
:disabled => true,
:data => { :method => "POST",
- :url => changeset_comment_url(@changeset) } %>
+ :url => api_changeset_changeset_comments_path(@changeset) } %>
</div>
</form>
<% else %>
</div>
<div class='secondary-actions'>
- <%= link_to(t(".changesetxml"), :controller => "api/changesets", :action => "show") %>
+ <%= link_to t(".changesetxml"), api_changeset_path(@changeset) %>
·
- <%= link_to(t(".osmchangexml"), :controller => "api/changesets", :action => "download") %>
+ <%= link_to t(".osmchangexml"), api_changeset_download_path(@changeset) %>
</div>
<% if @next_by_user || @prev_by_user %>
:data => { :behavior => "category_dropdown" },
:class => "form-select" %>
</div>
+ <div class="mb-3 col-md">
+ <%= text_field_tag :username,
+ params[:username],
+ :placeholder => t(".name_or_email"),
+ :autocomplete => "on",
+ :class => "form-control" %>
+ </div>
<div class="mb-3 col-md">
<%= text_field_tag :ip,
params[:ip],
resource "/diary/*/rss", :headers => :any, :methods => [:get]
resource "/trace/*/data", :headers => :any, :methods => [:get]
resource "/user/*/diary/rss", :headers => :any, :methods => [:get]
+ resource "/rails/active_storage/*", :headers => :any, :methods => [:get]
end
end
confirmed: Confirmed
suspended: Suspended
deleted: Deleted
+ name_or_email: Name or Email
ip_address: IP Address
search: Search
page:
get "permissions" => "permissions#show"
post "changeset/:id/upload" => "changesets#upload", :as => :changeset_upload, :id => /\d+/
- get "changeset/:id/download" => "changesets#download", :as => :changeset_download, :id => /\d+/
- get "changeset/:id" => "changesets#show", :as => :changeset_show, :id => /\d+/
post "changeset/:id/subscribe" => "changesets#subscribe", :as => :api_changeset_subscribe, :id => /\d+/
post "changeset/:id/unsubscribe" => "changesets#unsubscribe", :as => :api_changeset_unsubscribe, :id => /\d+/
- put "changeset/:id" => "changesets#update", :id => /\d+/
put "changeset/:id/close" => "changesets#close", :as => :changeset_close, :id => /\d+/
- post "changeset/:id/comment" => "changeset_comments#create", :as => :changeset_comment, :id => /\d+/
post "changeset/comment/:id/hide" => "changeset_comments#destroy", :as => :changeset_comment_hide, :id => /\d+/
post "changeset/comment/:id/unhide" => "changeset_comments#restore", :as => :changeset_comment_unhide, :id => /\d+/
end
namespace :api, :path => "api/0.6" do
resources :changesets, :only => [:index, :create]
+ resources :changesets, :path => "changeset", :id => /\d+/, :only => [:show, :update] do
+ resource :download, :module => :changesets, :only => :show
+ resources :changeset_comments, :path => "comment", :only => :create
+ end
put "changeset/create" => "changesets#create", :as => nil
resources :changeset_comments, :only => :index
)
assert_routing(
{ :path => "/api/0.6/changeset/1/comment", :method => :post },
- { :controller => "api/changeset_comments", :action => "create", :id => "1" }
+ { :controller => "api/changeset_comments", :action => "create", :changeset_id => "1" }
)
assert_routing(
{ :path => "/api/0.6/changeset/1/comment.json", :method => :post },
- { :controller => "api/changeset_comments", :action => "create", :id => "1", :format => "json" }
+ { :controller => "api/changeset_comments", :action => "create", :changeset_id => "1", :format => "json" }
)
assert_routing(
{ :path => "/api/0.6/changeset/comment/1/hide", :method => :post },
def test_create_by_unauthorized
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset, :closed), :text => "This is a comment")
+ post api_changeset_changeset_comments_path(create(:changeset, :closed), :text => "This is a comment")
assert_response :unauthorized
end
end
def test_create_on_missing_changeset
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(999111, :text => "This is a comment"), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(999111, :text => "This is a comment"), :headers => bearer_authorization_header
assert_response :not_found
end
end
def test_create_on_open_changeset
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset), :text => "This is a comment"), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(create(:changeset), :text => "This is a comment"), :headers => bearer_authorization_header
assert_response :conflict
end
end
def test_create_without_text
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset, :closed)), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(create(:changeset, :closed)), :headers => bearer_authorization_header
assert_response :bad_request
end
end
def test_create_with_empty_text
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(create(:changeset, :closed), :text => ""), :headers => bearer_authorization_header
+ post api_changeset_changeset_comments_path(create(:changeset, :closed), :text => ""), :headers => bearer_authorization_header
assert_response :bad_request
end
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 0 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :forbidden
end
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 0 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :forbidden
end
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 1 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :success
end
changeset = create(:changeset, :closed)
assert_difference "ChangesetComment.count", 1 do
- post changeset_comment_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset), :params => { :text => "This is a comment" }, :headers => auth_header
assert_response :success
end
assert_difference "ChangesetComment.count", 1 do
assert_no_difference "ActionMailer::Base.deliveries.size" do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_no_difference "ActionMailer::Base.deliveries.size" do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_no_difference "ActionMailer::Base.deliveries.size" do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_difference "ActionMailer::Base.deliveries.size", 1 do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", 1 do
assert_difference "ActionMailer::Base.deliveries.size", 2 do
perform_enqueued_jobs do
- post changeset_comment_path(changeset, :text => "This is a comment"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "This is a comment"), :headers => auth_header
assert_response :success
end
end
assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour do
1.upto(Settings.initial_changeset_comments_per_hour) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
assert_difference "ChangesetComment.count", Settings.max_changeset_comments_per_hour do
1.upto(Settings.max_changeset_comments_per_hour) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
assert_difference "ChangesetComment.count", Settings.initial_changeset_comments_per_hour / 2 do
1.upto(Settings.initial_changeset_comments_per_hour / 2) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
assert_difference "ChangesetComment.count", Settings.moderator_changeset_comments_per_hour do
1.upto(Settings.moderator_changeset_comments_per_hour) do |count|
- post changeset_comment_path(changeset, :text => "Comment #{count}"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "Comment #{count}"), :headers => auth_header
assert_response :success
end
end
assert_no_difference "ChangesetComment.count" do
- post changeset_comment_path(changeset, :text => "One comment too many"), :headers => auth_header
+ post api_changeset_changeset_comments_path(changeset, :text => "One comment too many"), :headers => auth_header
assert_response :too_many_requests
end
end
--- /dev/null
+require "test_helper"
+
+module Api
+ module Changesets
+ class DownloadsControllerTest < ActionDispatch::IntegrationTest
+ ##
+ # test all routes which lead to this controller
+ def test_routes
+ assert_routing(
+ { :path => "/api/0.6/changeset/1/download", :method => :get },
+ { :controller => "api/changesets/downloads", :action => "show", :changeset_id => "1" }
+ )
+ end
+
+ def test_show_empty
+ changeset = create(:changeset)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "create", 0
+ assert_dom "modify", 0
+ assert_dom "delete", 0
+ end
+ end
+
+ def test_show_created_elements
+ changeset = create(:changeset)
+ old_node1 = create(:old_node, :changeset => changeset, :version => 1, :latitude => (60.12345 * OldNode::SCALE).to_i, :longitude => (30.54321 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node1, :k => "highway", :v => "crossing")
+ create(:old_node_tag, :old_node => old_node1, :k => "crossing", :v => "marked")
+ old_node2 = create(:old_node, :changeset => changeset, :version => 1, :latitude => (60.23456 * OldNode::SCALE).to_i, :longitude => (30.65432 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node2, :k => "highway", :v => "traffic_signals")
+ old_way = create(:old_way, :changeset => changeset, :version => 1)
+ create(:old_way_tag, :old_way => old_way, :k => "highway", :v => "secondary")
+ create(:old_way_tag, :old_way => old_way, :k => "name", :v => "Some Street")
+ create(:old_way_node, :old_way => old_way, :node => old_node1.current_node, :sequence_id => 1)
+ create(:old_way_node, :old_way => old_way, :node => old_node2.current_node, :sequence_id => 2)
+ old_relation = create(:old_relation, :changeset => changeset, :version => 1)
+ create(:old_relation_tag, :old_relation => old_relation, :k => "type", :v => "restriction")
+ create(:old_relation_member, :old_relation => old_relation, :member => old_way.current_way, :member_role => "from", :sequence_id => 1)
+ create(:old_relation_member, :old_relation => old_relation, :member => old_node2.current_node, :member_role => "via", :sequence_id => 2)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "create", 4 do
+ assert_dom "node", 2
+ assert_dom "node[id='#{old_node1.node_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='crossing']"
+ assert_dom "tag[k='crossing'][v='marked']"
+ assert_dom "> @lat", "60.1234500"
+ assert_dom "> @lon", "30.5432100"
+ end
+ assert_dom "node[id='#{old_node2.node_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='highway'][v='traffic_signals']"
+ assert_dom "> @lat", "60.2345600"
+ assert_dom "> @lon", "30.6543200"
+ end
+ assert_dom "way", 1
+ assert_dom "way[id='#{old_way.way_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='secondary']"
+ assert_dom "tag[k='name'][v='Some Street']"
+ assert_dom "nd", 2 do |dom_nds|
+ assert_dom dom_nds[0], "> @ref", old_node1.node_id.to_s
+ assert_dom dom_nds[1], "> @ref", old_node2.node_id.to_s
+ end
+ end
+ assert_dom "relation", 1
+ assert_dom "relation[id='#{old_relation.relation_id}']", 1 do
+ assert_dom "> @version", "1"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='type'][v='restriction']"
+ assert_dom "member", 2 do |dom_members|
+ assert_dom dom_members[0], "> @type", "way"
+ assert_dom dom_members[0], "> @ref", old_way.way_id.to_s
+ assert_dom dom_members[0], "> @role", "from"
+ assert_dom dom_members[1], "> @type", "node"
+ assert_dom dom_members[1], "> @ref", old_node2.node_id.to_s
+ assert_dom dom_members[1], "> @role", "via"
+ end
+ end
+ end
+ end
+ end
+
+ def test_show_edited_elements
+ changeset = create(:changeset)
+ old_node1 = create(:old_node, :changeset => changeset, :version => 2, :latitude => (60.12345 * OldNode::SCALE).to_i, :longitude => (30.54321 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node1, :k => "highway", :v => "crossing")
+ create(:old_node_tag, :old_node => old_node1, :k => "crossing", :v => "marked")
+ old_node2 = create(:old_node, :changeset => changeset, :version => 2, :latitude => (60.23456 * OldNode::SCALE).to_i, :longitude => (30.65432 * OldNode::SCALE).to_i)
+ create(:old_node_tag, :old_node => old_node2, :k => "highway", :v => "traffic_signals")
+ old_way = create(:old_way, :changeset => changeset, :version => 2)
+ create(:old_way_tag, :old_way => old_way, :k => "highway", :v => "secondary")
+ create(:old_way_tag, :old_way => old_way, :k => "name", :v => "Some Street")
+ create(:old_way_node, :old_way => old_way, :node => old_node1.current_node, :sequence_id => 1)
+ create(:old_way_node, :old_way => old_way, :node => old_node2.current_node, :sequence_id => 2)
+ old_relation = create(:old_relation, :changeset => changeset, :version => 2)
+ create(:old_relation_tag, :old_relation => old_relation, :k => "type", :v => "restriction")
+ create(:old_relation_member, :old_relation => old_relation, :member => old_way.current_way, :member_role => "from", :sequence_id => 1)
+ create(:old_relation_member, :old_relation => old_relation, :member => old_node2.current_node, :member_role => "via", :sequence_id => 2)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "modify", 4 do
+ assert_dom "node", 2
+ assert_dom "node[id='#{old_node1.node_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='crossing']"
+ assert_dom "tag[k='crossing'][v='marked']"
+ assert_dom "> @lat", "60.1234500"
+ assert_dom "> @lon", "30.5432100"
+ end
+ assert_dom "node[id='#{old_node2.node_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='highway'][v='traffic_signals']"
+ assert_dom "> @lat", "60.2345600"
+ assert_dom "> @lon", "30.6543200"
+ end
+ assert_dom "way", 1
+ assert_dom "way[id='#{old_way.way_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 2
+ assert_dom "tag[k='highway'][v='secondary']"
+ assert_dom "tag[k='name'][v='Some Street']"
+ assert_dom "nd", 2 do |dom_nds|
+ assert_dom dom_nds[0], "> @ref", old_node1.node_id.to_s
+ assert_dom dom_nds[1], "> @ref", old_node2.node_id.to_s
+ end
+ end
+ assert_dom "relation", 1
+ assert_dom "relation[id='#{old_relation.relation_id}']", 1 do
+ assert_dom "> @version", "2"
+ assert_dom "> @visible", "true"
+ assert_dom "tag", 1
+ assert_dom "tag[k='type'][v='restriction']"
+ assert_dom "member", 2 do |dom_members|
+ assert_dom dom_members[0], "> @type", "way"
+ assert_dom dom_members[0], "> @ref", old_way.way_id.to_s
+ assert_dom dom_members[0], "> @role", "from"
+ assert_dom dom_members[1], "> @type", "node"
+ assert_dom dom_members[1], "> @ref", old_node2.node_id.to_s
+ assert_dom dom_members[1], "> @role", "via"
+ end
+ end
+ end
+ end
+ end
+
+ def test_show_deleted_elements
+ changeset = create(:changeset)
+ old_node1 = create(:old_node, :changeset => changeset, :version => 3, :visible => false)
+ old_node2 = create(:old_node, :changeset => changeset, :version => 3, :visible => false)
+ old_way = create(:old_way, :changeset => changeset, :version => 3, :visible => false)
+ old_relation = create(:old_relation, :changeset => changeset, :version => 3, :visible => false)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
+ assert_dom "delete", 4 do
+ assert_dom "node", 2
+ assert_dom "node[id='#{old_node1.node_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ assert_dom "node[id='#{old_node2.node_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ assert_dom "way", 1
+ assert_dom "way[id='#{old_way.way_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ assert_dom "relation", 1
+ assert_dom "relation[id='#{old_relation.relation_id}']", 1 do
+ assert_dom "> @version", "3"
+ assert_dom "> @visible", "false"
+ end
+ end
+ end
+ end
+
+ def test_show_should_sort_by_timestamp
+ changeset = create(:changeset)
+ node1 = create(:old_node, :version => 2, :timestamp => "2020-02-01", :changeset => changeset)
+ node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "modify", :count => 2 do |modify|
+ assert_dom modify[0], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node0.node_id.to_s
+ end
+ assert_dom modify[1], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node1.node_id.to_s
+ end
+ end
+ end
+
+ def test_show_should_sort_by_version
+ changeset = create(:changeset)
+ node1 = create(:old_node, :version => 3, :timestamp => "2020-01-01", :changeset => changeset)
+ node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
+
+ get api_changeset_download_path(changeset)
+
+ assert_response :success
+ assert_dom "modify", :count => 2 do |modify|
+ assert_dom modify[0], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node0.node_id.to_s
+ end
+ assert_dom modify[1], ">node", :count => 1 do |node|
+ assert_dom node, ">@id", node1.node_id.to_s
+ end
+ end
+ end
+
+ ##
+ # check that the changeset download for a changeset with a redacted
+ # element in it doesn't contain that element.
+ def test_show_redacted
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset)
+ end
+ end
+
+ def test_show_redacted_unauthorized
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset, :show_redactions => "true")
+ end
+ end
+
+ def test_show_redacted_normal_user
+ auth_header = bearer_authorization_header
+
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset, :show_redactions => "true"), :headers => auth_header
+ end
+ end
+
+ def test_show_redacted_moderator_without_show_redactions
+ auth_header = bearer_authorization_header create(:moderator_user)
+
+ check_redacted do |changeset|
+ get api_changeset_download_path(changeset), :headers => auth_header
+ end
+ end
+
+ def test_show_redacted_moderator
+ auth_header = bearer_authorization_header create(:moderator_user)
+
+ check_redacted(:redacted_included => true) do |changeset|
+ get api_changeset_download_path(changeset, :show_redactions => "true"), :headers => auth_header
+ end
+ end
+
+ private
+
+ def check_redacted(redacted_included: false)
+ redaction = create(:redaction)
+ changeset = create(:changeset)
+ node = create(:node, :with_history, :version => 2, :changeset => changeset)
+ node_v1 = node.old_nodes.find_by(:version => 1)
+ node_v1.redact!(redaction)
+ way = create(:way, :with_history, :version => 2, :changeset => changeset)
+ way_v1 = way.old_ways.find_by(:version => 1)
+ way_v1.redact!(redaction)
+ relation = create(:relation, :with_history, :version => 2, :changeset => changeset)
+ relation_v1 = relation.old_relations.find_by(:version => 1)
+ relation_v1.redact!(redaction)
+
+ yield changeset
+
+ assert_response :success
+ assert_dom "osmChange", 1 do
+ assert_dom "node[id='#{node.id}'][version='1']", redacted_included ? 1 : 0
+ assert_dom "node[id='#{node.id}'][version='2']", 1
+ assert_dom "way[id='#{way.id}'][version='1']", redacted_included ? 1 : 0
+ assert_dom "way[id='#{way.id}'][version='2']", 1
+ assert_dom "relation[id='#{relation.id}'][version='1']", redacted_included ? 1 : 0
+ assert_dom "relation[id='#{relation.id}'][version='2']", 1
+ end
+ end
+ end
+ end
+end
{ :path => "/api/0.6/changesets", :method => :post },
{ :controller => "api/changesets", :action => "create" }
)
- assert_routing(
- { :path => "/api/0.6/changeset/1/upload", :method => :post },
- { :controller => "api/changesets", :action => "upload", :id => "1" }
- )
- assert_routing(
- { :path => "/api/0.6/changeset/1/download", :method => :get },
- { :controller => "api/changesets", :action => "download", :id => "1" }
- )
assert_routing(
{ :path => "/api/0.6/changeset/1", :method => :get },
{ :controller => "api/changesets", :action => "show", :id => "1" }
{ :path => "/api/0.6/changeset/1.json", :method => :get },
{ :controller => "api/changesets", :action => "show", :id => "1", :format => "json" }
)
+ assert_routing(
+ { :path => "/api/0.6/changeset/1", :method => :put },
+ { :controller => "api/changesets", :action => "update", :id => "1" }
+ )
+ assert_routing(
+ { :path => "/api/0.6/changeset/1/upload", :method => :post },
+ { :controller => "api/changesets", :action => "upload", :id => "1" }
+ )
assert_routing(
{ :path => "/api/0.6/changeset/1/subscribe", :method => :post },
{ :controller => "api/changesets", :action => "subscribe", :id => "1" }
{ :path => "/api/0.6/changeset/1/unsubscribe.json", :method => :post },
{ :controller => "api/changesets", :action => "unsubscribe", :id => "1", :format => "json" }
)
- assert_routing(
- { :path => "/api/0.6/changeset/1", :method => :put },
- { :controller => "api/changesets", :action => "update", :id => "1" }
- )
assert_routing(
{ :path => "/api/0.6/changeset/1/close", :method => :put },
{ :controller => "api/changesets", :action => "close", :id => "1" }
def test_show
changeset = create(:changeset)
- get changeset_show_path(changeset)
+ get api_changeset_path(changeset)
assert_response :success, "cannot get first changeset"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
assert_dom "> discussion", 0
end
- get changeset_show_path(changeset), :params => { :include_discussion => true }
+ get api_changeset_path(changeset, :include_discussion => true)
assert_response :success, "cannot get first changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
changeset = create(:changeset, :closed)
comment1, comment2, comment3 = create_list(:changeset_comment, 3, :changeset_id => changeset.id)
- get changeset_show_path(changeset), :params => { :include_discussion => true }
+ get api_changeset_path(changeset, :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1 do
comment2.update(:visible => false)
changeset.reload
- get changeset_show_path(changeset), :params => { :include_discussion => true }
+ get api_changeset_path(changeset, :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
end
# one hidden comment not included because no permissions
- get changeset_show_path(changeset), :params => { :include_discussion => true, :show_hidden_comments => true }
+ get api_changeset_path(changeset, :include_discussion => true, :show_hidden_comments => true)
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
# one hidden comment shown to moderators
moderator_user = create(:moderator_user)
auth_header = bearer_authorization_header moderator_user
- get changeset_show_path(changeset), :params => { :include_discussion => true, :show_hidden_comments => true },
- :headers => auth_header
+ get api_changeset_path(changeset, :include_discussion => true, :show_hidden_comments => true), :headers => auth_header
assert_response :success, "cannot get closed changeset with comments"
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
create(:changeset_tag, :changeset => changeset, :k => "created_by", :v => "JOSM/1.5 (18364)")
create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "changeset comment")
- get changeset_show_path(changeset)
+ get api_changeset_path(changeset)
assert_response :success
assert_dom "osm[version='#{Settings.api_version}'][generator='#{Settings.generator}']", 1
def test_show_json
changeset = create(:changeset)
- get changeset_show_path(changeset), :params => { :format => "json" }
+ get api_changeset_path(changeset, :format => "json")
assert_response :success, "cannot get first changeset"
js = ActiveSupport::JSON.decode(@response.body)
assert_equal changeset.user.id, js["changeset"]["uid"]
assert_equal changeset.user.display_name, js["changeset"]["user"]
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true)
assert_response :success, "cannot get first changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
changeset = create(:changeset, :closed)
comment0, comment1, comment2 = create_list(:changeset_comment, 3, :changeset_id => changeset.id)
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
comment1.update(:visible => false)
changeset.reload
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true)
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
assert js["changeset"]["comments"][1]["visible"]
# one hidden comment not included because no permissions
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true, :show_hidden_comments => true }
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true, :show_hidden_comments => true)
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
# one hidden comment shown to moderators
moderator_user = create(:moderator_user)
auth_header = bearer_authorization_header moderator_user
- get changeset_show_path(changeset), :params => { :format => "json", :include_discussion => true, :show_hidden_comments => true },
- :headers => auth_header
+ get api_changeset_path(changeset, :format => "json", :include_discussion => true, :show_hidden_comments => true), :headers => auth_header
assert_response :success, "cannot get closed changeset with comments"
js = ActiveSupport::JSON.decode(@response.body)
create(:changeset_tag, :changeset => changeset, :k => "created_by", :v => "JOSM/1.5 (18364)")
create(:changeset_tag, :changeset => changeset, :k => "comment", :v => "changeset comment")
- get changeset_show_path(changeset, :format => "json")
+ get api_changeset_path(changeset, :format => "json")
assert_response :success
js = ActiveSupport::JSON.decode(@response.body)
changeset = create(:changeset, :min_lat => (-5 * GeoRecord::SCALE).round, :min_lon => (5 * GeoRecord::SCALE).round,
:max_lat => (15 * GeoRecord::SCALE).round, :max_lon => (12 * GeoRecord::SCALE).round)
- get changeset_show_path(changeset), :params => { :format => "json" }
+ get api_changeset_path(changeset, :format => "json")
assert_response :success, "cannot get first changeset"
js = ActiveSupport::JSON.decode(@response.body)
# check that a changeset that doesn't exist returns an appropriate message
def test_show_not_found
[0, -32, 233455644, "afg", "213"].each do |id|
- get changeset_show_path(id)
+ get api_changeset_path(id)
assert_response :not_found, "should get a not found"
rescue ActionController::UrlGenerationError => e
assert_match(/No route matches/, e.to_s)
assert_response :success,
"can't upload multiple versions of an element in a diff: #{@response.body}"
- get changeset_download_path(changeset_id)
+ get api_changeset_download_path(changeset_id)
assert_response :success
assert_select "osmChange", 1
assert_response :success,
"can't upload a diff from JOSM: #{@response.body}"
- get changeset_download_path(changeset_id)
+ get api_changeset_download_path(changeset_id)
assert_response :success
assert_select "osmChange", 1
assert_response :success,
"can't upload multiple versions of an element in a diff: #{@response.body}"
- get changeset_download_path(changeset_id)
+ get api_changeset_download_path(changeset_id)
assert_response :success
assert_select "osmChange", 1
assert_select "osmChange>modify>way", 1
end
- def test_changeset_download
- changeset = create(:changeset)
- node = create(:node, :with_history, :version => 1, :changeset => changeset)
- tag = create(:old_node_tag, :old_node => node.old_nodes.find_by(:version => 1))
- node2 = create(:node, :with_history, :version => 1, :changeset => changeset)
- _node3 = create(:node, :with_history, :deleted, :version => 1, :changeset => changeset)
- _relation = create(:relation, :with_history, :version => 1, :changeset => changeset)
- _relation2 = create(:relation, :with_history, :deleted, :version => 1, :changeset => changeset)
-
- get changeset_download_path(changeset)
-
- assert_response :success
-
- # FIXME: needs more assert_select tests
- assert_select "osmChange[version='#{Settings.api_version}'][generator='#{Settings.generator}']" do
- assert_select "create", :count => 5
- assert_select "create>node[id='#{node.id}'][visible='#{node.visible?}'][version='#{node.version}']" do
- assert_select "tag[k='#{tag.k}'][v='#{tag.v}']"
- end
- assert_select "create>node[id='#{node2.id}']"
- end
- end
-
- test "sorts downloaded elements by timestamp" do
- changeset = create(:changeset)
- node1 = create(:old_node, :version => 2, :timestamp => "2020-02-01", :changeset => changeset)
- node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
-
- get changeset_download_path(changeset)
- assert_response :success
- assert_dom "modify", :count => 2 do |modify|
- assert_dom modify[0], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node0.node_id.to_s
- end
- assert_dom modify[1], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node1.node_id.to_s
- end
- end
- end
-
- test "sorts downloaded elements by version" do
- changeset = create(:changeset)
- node1 = create(:old_node, :version => 3, :timestamp => "2020-01-01", :changeset => changeset)
- node0 = create(:old_node, :version => 2, :timestamp => "2020-01-01", :changeset => changeset)
-
- get changeset_download_path(changeset)
- assert_response :success
- assert_dom "modify", :count => 2 do |modify|
- assert_dom modify[0], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node0.node_id.to_s
- end
- assert_dom modify[1], ">node", :count => 1 do |node|
- assert_dom node, ">@id", node1.node_id.to_s
- end
- end
- end
-
##
# check that the bounding box of a changeset gets updated correctly
# FIXME: This should really be moded to a integration test due to the with_controller
end
# get the bounding box back from the changeset
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "Couldn't read back changeset."
assert_select "osm>changeset[min_lon='0.1000000']", 1
assert_select "osm>changeset[max_lon='0.1000000']", 1
end
# get the bounding box back from the changeset
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "Couldn't read back changeset for the second time."
assert_select "osm>changeset[min_lon='0.1000000']", 1
assert_select "osm>changeset[max_lon='0.2000000']", 1
end
# get the bounding box back from the changeset
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "Couldn't read back changeset for the third time."
assert_select "osm>changeset[min_lon='0.1000000']", 1
assert_select "osm>changeset[max_lon='0.3000000']", 1
new_changeset.find("//osm/changeset").first << new_tag
# try without any authorization
- put changeset_show_path(private_changeset), :params => new_changeset.to_s
+ put api_changeset_path(private_changeset), :params => new_changeset.to_s
assert_response :unauthorized
# try with the wrong authorization
auth_header = bearer_authorization_header
- put changeset_show_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :conflict
# now this should get an unauthorized
auth_header = bearer_authorization_header private_user
- put changeset_show_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(private_changeset), :params => new_changeset.to_s, :headers => auth_header
assert_require_public_data "user with their data non-public, shouldn't be able to edit their changeset"
## Now try with the public user
new_changeset.find("//osm/changeset").first << new_tag
# try without any authorization
- put changeset_show_path(changeset), :params => new_changeset.to_s
+ put api_changeset_path(changeset), :params => new_changeset.to_s
assert_response :unauthorized
# try with the wrong authorization
auth_header = bearer_authorization_header
- put changeset_show_path(changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :conflict
# now this should work...
auth_header = bearer_authorization_header user
- put changeset_show_path(changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :success
assert_select "osm>changeset[id='#{changeset.id}']", 1
new_tag["v"] = "testing"
new_changeset.find("//osm/changeset").first << new_tag
- put changeset_show_path(changeset), :params => new_changeset.to_s, :headers => auth_header
+ put api_changeset_path(changeset), :params => new_changeset.to_s, :headers => auth_header
assert_response :conflict
end
"element limit.")
end
- ##
- # check that the changeset download for a changeset with a redacted
- # element in it doesn't contain that element.
- def test_diff_download_redacted
- changeset = create(:changeset)
- node = create(:node, :with_history, :version => 2, :changeset => changeset)
- node_v1 = node.old_nodes.find_by(:version => 1)
- node_v1.redact!(create(:redaction))
-
- get changeset_download_path(changeset)
- assert_response :success
-
- assert_select "osmChange", 1
- # this changeset contains the node in versions 1 & 2, but 1 should
- # be hidden.
- assert_select "osmChange node[id='#{node.id}']", 1
- assert_select "osmChange node[id='#{node.id}'][version='1']", 0
- end
-
##
# test subscribe success
def test_subscribe_success
# now download the changeset to check its bounding box
with_controller(Api::ChangesetsController.new) do
- get changeset_show_path(changeset_id)
+ get api_changeset_path(changeset_id)
assert_response :success, "can't re-read changeset for modify test"
assert_select "osm>changeset", 1, "Changeset element doesn't exist in #{@response.body}"
assert_select "osm>changeset[id='#{changeset_id}']", 1, "Changeset id=#{changeset_id} doesn't exist in #{@response.body}"
user = create(:user)
moderator_user = create(:moderator_user)
administrator_user = create(:administrator_user)
- _suspended_user = create(:user, :suspended)
- _ip_user = create(:user, :creation_address => "1.2.3.4")
+ suspended_user = create(:user, :suspended)
+ name_user = create(:user, :display_name => "Test User")
+ email_user = create(:user, :email => "test@example.com")
+ ip_user = create(:user, :creation_address => "1.2.3.4")
- # There are now 7 users - the five above, plus two extra "granters" for the
+ # There are now 9 users - the 7 above, plus two extra "granters" for the
# moderator_user and administrator_user
- assert_equal 7, User.count
+ assert_equal 9, User.count
# Shouldn't work when not logged in
get users_list_path
get users_list_path
assert_response :success
assert_template :show
- assert_select "table#user_list tbody tr", :count => 7
+ assert_select "table#user_list tbody tr", :count => 9
# Should be able to limit by status
get users_list_path, :params => { :status => "suspended" }
assert_response :success
assert_template :show
- assert_select "table#user_list tbody tr", :count => 1
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(suspended_user)}']", :count => 1
+ end
+
+ # Should be able to limit by name
+ get users_list_path, :params => { :username => "Test User" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(name_user)}']", :count => 1
+ end
+
+ # Should be able to limit by name ignoring case
+ get users_list_path, :params => { :username => "test user" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(name_user)}']", :count => 1
+ end
+
+ # Should be able to limit by email
+ get users_list_path, :params => { :username => "test@example.com" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(email_user)}']", :count => 1
+ end
+
+ # Should be able to limit by email ignoring case
+ get users_list_path, :params => { :username => "TEST@example.com" }
+ assert_response :success
+ assert_template :show
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(email_user)}']", :count => 1
+ end
# Should be able to limit by IP address
get users_list_path, :params => { :ip => "1.2.3.4" }
assert_response :success
assert_template :show
- assert_select "table#user_list tbody tr", :count => 1
+ assert_select "table#user_list tbody tr", :count => 1 do
+ assert_select "a[href='#{user_path(ip_user)}']", :count => 1
+ end
end
def test_show_paginated
resolved "https://registry.yarnpkg.com/@eslint-community/regexpp/-/regexpp-4.12.1.tgz#cfc6cffe39df390a3841cde2abccf92eaa7ae0e0"
integrity sha512-CCZCDJuduB9OUkFkY2IgppNZMi2lBQgD2qzwXkEia16cge2pijY/aXi96CJMquDMn3nJdlPV1A5KrJEXwfLNzQ==
-"@eslint/config-array@^0.19.0":
- version "0.19.0"
- resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.0.tgz#3251a528998de914d59bb21ba4c11767cf1b3519"
- integrity sha512-zdHg2FPIFNKPdcHWtiNT+jEFCHYVplAXRDlQDyqy0zGx/q2parwh7brGJSiTxRk/TSMkbM//zt/f5CHgyTyaSQ==
+"@eslint/config-array@^0.19.2":
+ version "0.19.2"
+ resolved "https://registry.yarnpkg.com/@eslint/config-array/-/config-array-0.19.2.tgz#3060b809e111abfc97adb0bb1172778b90cb46aa"
+ integrity sha512-GNKqxfHG2ySmJOBSHg7LxeUx4xpuCoFjacmlCoYWEbaPXLwvfIjixRI12xCQZeULksQb23uiA8F40w5TojpV7w==
dependencies:
- "@eslint/object-schema" "^2.1.4"
+ "@eslint/object-schema" "^2.1.6"
debug "^4.3.1"
minimatch "^3.1.2"
-"@eslint/core@^0.10.0":
- version "0.10.0"
- resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.10.0.tgz#23727063c21b335f752dbb3a16450f6f9cbc9091"
- integrity sha512-gFHJ+xBOo4G3WRlR1e/3G8A6/KZAH6zcE/hkLRCZTi/B9avAG365QhFA8uOGzTMqgTghpn7/fSnscW++dpMSAw==
+"@eslint/core@^0.12.0":
+ version "0.12.0"
+ resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.12.0.tgz#5f960c3d57728be9f6c65bd84aa6aa613078798e"
+ integrity sha512-cmrR6pytBuSMTaBweKoGMwu3EiHiEC+DoyupPmlZ0HxBJBtIxwe+j/E4XPIKNx+Q74c8lXKPwYawBf5glsTkHg==
dependencies:
"@types/json-schema" "^7.0.15"
-"@eslint/core@^0.11.0":
- version "0.11.0"
- resolved "https://registry.yarnpkg.com/@eslint/core/-/core-0.11.0.tgz#7a9226e850922e42cbd2ba71361eacbe74352a12"
- integrity sha512-DWUB2pksgNEb6Bz2fggIy1wh6fGgZP4Xyy/Mt0QZPiloKKXerbqq9D3SBQTlCRYOrcRPu4vuz+CGjwdfqxnoWA==
- dependencies:
- "@types/json-schema" "^7.0.15"
-
-"@eslint/eslintrc@^3.2.0":
- version "3.2.0"
- resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.2.0.tgz#57470ac4e2e283a6bf76044d63281196e370542c"
- integrity sha512-grOjVNN8P3hjJn/eIETF1wwd12DdnwFDoyceUJLYYdkpbwq3nLi+4fqrTAONx7XDALqlL220wC/RHSC/QTI/0w==
+"@eslint/eslintrc@^3.3.0":
+ version "3.3.0"
+ resolved "https://registry.yarnpkg.com/@eslint/eslintrc/-/eslintrc-3.3.0.tgz#96a558f45842989cca7ea1ecd785ad5491193846"
+ integrity sha512-yaVPAiNAalnCZedKLdR21GOGILMLKPyqSLWaAjQFvYA2i/ciDi8ArYVr69Anohb6cH2Ukhqti4aFnYyPm8wdwQ==
dependencies:
ajv "^6.12.4"
debug "^4.3.2"
minimatch "^3.1.2"
strip-json-comments "^3.1.1"
-"@eslint/js@9.20.0":
- version "9.20.0"
- resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.20.0.tgz#7421bcbe74889fcd65d1be59f00130c289856eb4"
- integrity sha512-iZA07H9io9Wn836aVTytRaNqh00Sad+EamwOVJT12GTLw1VGMFV/4JaME+JjLtr9fiGaoWgYnS54wrfWsSs4oQ==
+"@eslint/js@9.21.0":
+ version "9.21.0"
+ resolved "https://registry.yarnpkg.com/@eslint/js/-/js-9.21.0.tgz#4303ef4e07226d87c395b8fad5278763e9c15c08"
+ integrity sha512-BqStZ3HX8Yz6LvsF5ByXYrtigrV5AXADWLAGc7PH/1SxOb7/FIYYMszZZWiUou/GB9P2lXWk2SV4d+Z8h0nknw==
-"@eslint/object-schema@^2.1.4":
- version "2.1.4"
- resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.4.tgz#9e69f8bb4031e11df79e03db09f9dbbae1740843"
- integrity sha512-BsWiH1yFGjXXS2yvrf5LyuoSIIbPrGUWob917o+BTKuZ7qJdxX8aJLRxs1fS9n6r7vESrq1OUqb68dANcFXuQQ==
+"@eslint/object-schema@^2.1.6":
+ version "2.1.6"
+ resolved "https://registry.yarnpkg.com/@eslint/object-schema/-/object-schema-2.1.6.tgz#58369ab5b5b3ca117880c0f6c0b0f32f6950f24f"
+ integrity sha512-RBMg5FRL0I0gs51M/guSAj5/e14VQ4tpZnQNWwuDT66P14I43ItmPfIZRhO9fUVIPOAQXU47atlywZ/czoqFPA==
-"@eslint/plugin-kit@^0.2.5":
- version "0.2.5"
- resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.5.tgz#ee07372035539e7847ef834e3f5e7b79f09e3a81"
- integrity sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==
+"@eslint/plugin-kit@^0.2.7":
+ version "0.2.7"
+ resolved "https://registry.yarnpkg.com/@eslint/plugin-kit/-/plugin-kit-0.2.7.tgz#9901d52c136fb8f375906a73dcc382646c3b6a27"
+ integrity sha512-JubJ5B2pJ4k4yGxaNLdbjrnk9d/iDz6/q8wOilpIowd6PJPgaxCuHBnBszq7Ce2TyMrywm5r4PnKm6V3iiZF+g==
dependencies:
- "@eslint/core" "^0.10.0"
+ "@eslint/core" "^0.12.0"
levn "^0.4.1"
"@humanfs/core@^0.19.1":
resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.3.1.tgz#c72a5c76a9fbaf3488e231b13dc52c0da7bab42a"
integrity sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA==
-"@humanwhocodes/retry@^0.4.1":
- version "0.4.1"
- resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.1.tgz#9a96ce501bc62df46c4031fbd970e3cc6b10f07b"
- integrity sha512-c7hNEllBlenFTHBky65mhq8WD2kbN9Q6gk0bTk8lSBvc554jpXSkST1iePudpt7+A/AQvuHs9EMqjHDXMY1lrA==
+"@humanwhocodes/retry@^0.4.2":
+ version "0.4.2"
+ resolved "https://registry.yarnpkg.com/@humanwhocodes/retry/-/retry-0.4.2.tgz#1860473de7dfa1546767448f333db80cb0ff2161"
+ integrity sha512-xeO57FpIu4p1Ri3Jq/EXq4ClRm86dVF2z/+kvFnyqVYRavTZmaFaUBbWCOuuTh0o/g7DSsk6kc2vrS4Vl5oPOQ==
"@stylistic/eslint-plugin-js@^4.0.0":
version "4.0.1"
integrity sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw==
eslint@^9.0.0:
- version "9.20.1"
- resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.20.1.tgz#923924c078f5226832449bac86662dd7e53c91d6"
- integrity sha512-m1mM33o6dBUjxl2qb6wv6nGNwCAsns1eKtaQ4l/NPHeTvhiUPbtdfMyktxN4B3fgHIgsYh1VT3V9txblpQHq+g==
+ version "9.21.0"
+ resolved "https://registry.yarnpkg.com/eslint/-/eslint-9.21.0.tgz#b1c9c16f5153ff219791f627b94ab8f11f811591"
+ integrity sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg==
dependencies:
"@eslint-community/eslint-utils" "^4.2.0"
"@eslint-community/regexpp" "^4.12.1"
- "@eslint/config-array" "^0.19.0"
- "@eslint/core" "^0.11.0"
- "@eslint/eslintrc" "^3.2.0"
- "@eslint/js" "9.20.0"
- "@eslint/plugin-kit" "^0.2.5"
+ "@eslint/config-array" "^0.19.2"
+ "@eslint/core" "^0.12.0"
+ "@eslint/eslintrc" "^3.3.0"
+ "@eslint/js" "9.21.0"
+ "@eslint/plugin-kit" "^0.2.7"
"@humanfs/node" "^0.16.6"
"@humanwhocodes/module-importer" "^1.0.1"
- "@humanwhocodes/retry" "^0.4.1"
+ "@humanwhocodes/retry" "^0.4.2"
"@types/estree" "^1.0.6"
"@types/json-schema" "^7.0.15"
ajv "^6.12.4"