autoprefixer-rails (10.4.19.0)
execjs (~> 2)
aws-eventstream (1.3.0)
- aws-partitions (1.1029.0)
+ aws-partitions (1.1032.0)
aws-sdk-core (3.214.1)
aws-eventstream (~> 1, >= 1.3.0)
aws-partitions (~> 1, >= 1.992.0)
aws-sdk-kms (1.96.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sigv4 (~> 1.5)
- aws-sdk-s3 (1.176.1)
+ aws-sdk-s3 (1.177.0)
aws-sdk-core (~> 3, >= 3.210.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.5)
doorkeeper (>= 5.5, < 5.9)
jwt (>= 2.5)
drb (2.2.1)
- dry-configurable (1.2.0)
- dry-core (~> 1.0, < 2)
+ dry-configurable (1.3.0)
+ dry-core (~> 1.1)
zeitwerk (~> 2.6)
- dry-core (1.0.2)
+ dry-core (1.1.0)
concurrent-ruby (~> 1.0)
logger
zeitwerk (~> 2.6)
- dry-inflector (1.1.0)
- dry-initializer (3.1.1)
- dry-logic (1.5.0)
+ dry-inflector (1.2.0)
+ dry-initializer (3.2.0)
+ dry-logic (1.6.0)
+ bigdecimal
concurrent-ruby (~> 1.0)
- dry-core (~> 1.0, < 2)
+ dry-core (~> 1.1)
zeitwerk (~> 2.6)
- dry-schema (1.13.4)
+ dry-schema (1.14.0)
concurrent-ruby (~> 1.0)
dry-configurable (~> 1.0, >= 1.0.1)
- dry-core (~> 1.0, < 2)
- dry-initializer (~> 3.0)
- dry-logic (>= 1.4, < 2)
- dry-types (>= 1.7, < 2)
+ dry-core (~> 1.1)
+ dry-initializer (~> 3.2)
+ dry-logic (~> 1.5)
+ dry-types (~> 1.8)
zeitwerk (~> 2.6)
- dry-types (1.7.2)
+ dry-types (1.8.0)
bigdecimal (~> 3.0)
concurrent-ruby (~> 1.0)
dry-core (~> 1.0)
dry-inflector (~> 1.0)
dry-logic (~> 1.4)
zeitwerk (~> 2.6)
- dry-validation (1.10.0)
+ dry-validation (1.11.0)
concurrent-ruby (~> 1.0)
- dry-core (~> 1.0, < 2)
- dry-initializer (~> 3.0)
- dry-schema (>= 1.12, < 2)
+ dry-core (~> 1.1)
+ dry-initializer (~> 3.2)
+ dry-schema (~> 1.14)
zeitwerk (~> 2.6)
- erb_lint (0.7.0)
+ erb_lint (0.8.0)
activesupport
better_html (>= 2.0.1)
parser (>= 2.7.1.4)
google-protobuf (3.25.5)
hashdiff (1.1.2)
hashie (5.0.0)
- highline (3.1.1)
+ highline (3.1.2)
reline
htmlentities (4.3.4)
http_accept_language (2.1.1)
logstasher (2.1.5)
activesupport (>= 5.2)
request_store
- loofah (2.23.1)
+ loofah (2.24.0)
crass (~> 1.0.2)
nokogiri (>= 1.12.0)
mail (2.8.1)
nap (1.1.0)
net-http (0.6.0)
uri
- net-imap (0.5.4)
+ net-imap (0.5.5)
date
net-protocol
net-pop (0.1.2)
rb-fsevent (0.11.2)
rb-inotify (0.11.1)
ffi (~> 1.0)
- rchardet (1.8.0)
+ rchardet (1.9.0)
rdoc (6.10.0)
psych (>= 4.0.0)
regexp_parser (2.10.0)
rubocop-minitest (0.36.0)
rubocop (>= 1.61, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
- rubocop-performance (1.23.0)
+ rubocop-performance (1.23.1)
rubocop (>= 1.48.1, < 2.0)
rubocop-ast (>= 1.31.1, < 2.0)
rubocop-rails (2.28.0)
ruby-vips (2.2.2)
ffi (~> 1.12)
logger
- rubyzip (2.3.2)
+ rubyzip (2.4.1)
sanitize (7.0.0)
crass (~> 1.0.2)
nokogiri (>= 1.16.8)
hashdiff (>= 0.4.0, < 2.0.0)
webrick (1.9.1)
websocket (1.2.11)
- websocket-driver (0.7.6)
+ websocket-driver (0.7.7)
+ base64
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.5)
xpath (3.2.0)
can :update, DiaryEntry, :user => user
can [:create], DiaryComment
can [:make_friend, :remove_friend], Friendship
- can [:read, :create, :reply, :inbox, :outbox, :muted, :mark, :unmute, :destroy], Message
+ can [:read, :create, :mark, :unmute, :destroy], Message
can [:close, :reopen], Note
can [:read, :update], :preference
can :update, :profile
OSM.Changeset = function (map) {
var page = {},
- content = $("#sidebar_content"),
- currentChangesetId;
+ content = $("#sidebar_content");
- page.pushstate = page.popstate = function (path, id) {
+ page.pushstate = page.popstate = function (path) {
OSM.loadSidebarContent(path, function () {
- page.load(path, id);
+ page.load();
});
};
- page.load = function (path, id) {
- if (id) currentChangesetId = id;
- initialize();
- addChangeset(currentChangesetId, true);
- };
+ page.load = function () {
+ const changesetData = content.find("[data-changeset]").data("changeset");
+ changesetData.type = "changeset";
- function addChangeset(id, center) {
- map.addObject({ type: "changeset", id: parseInt(id, 10) }, function (bounds) {
- if (!window.location.hash && bounds.isValid() &&
- (center || !map.getBounds().contains(bounds))) {
+ initialize();
+ map.addObject(changesetData, function (bounds) {
+ if (!window.location.hash && bounds.isValid()) {
OSM.router.withoutMoveListener(function () {
map.fitBounds(bounds);
});
}
});
- }
+ };
function updateChangeset(method, url, include_data) {
var data;
page.unload = function () {
map.removeLayer(group);
map.off("moveend", update);
+ map.off("zoomend", updateBounds);
};
return page;
this.removeObject();
- if (object.type === "note") {
+ if (object.type === "note" || object.type === "changeset") {
this._objectLoader = {
abort: function () {}
};
this._object = object;
this._objectLayer = L.featureGroup().addTo(this);
- L.circleMarker(object.latLng, haloStyle).addTo(this._objectLayer);
+ if (object.type === "note") {
+ L.circleMarker(object.latLng, haloStyle).addTo(this._objectLayer);
- if (object.icon) {
- L.marker(object.latLng, {
- icon: object.icon,
- opacity: 1,
- interactive: true
- }).addTo(this._objectLayer);
+ if (object.icon) {
+ L.marker(object.latLng, {
+ icon: object.icon,
+ opacity: 1,
+ interactive: true
+ }).addTo(this._objectLayer);
+ }
+ } else if (object.type === "changeset") {
+ if (object.bbox) {
+ L.rectangle([
+ [object.bbox.minlat, object.bbox.minlon],
+ [object.bbox.maxlat, object.bbox.maxlon]
+ ], changesetStyle).addTo(this._objectLayer);
+ }
}
if (callback) callback(this._objectLayer.getBounds());
- } else { // element or changeset handled by L.OSM.DataLayer
+ } else { // element handled by L.OSM.DataLayer
var map = this;
this._objectLoader = $.ajax({
url: OSM.apiUrl(object),
}
});
- map._objectLayer.interestingNode = function (node, ways, relations) {
+ map._objectLayer.interestingNode = function (node, wayNodes, relationNodes) {
if (object.type === "node") {
return true;
} else if (object.type === "relation") {
- for (var i = 0; i < relations.length; i++) {
- if (relations[i].members.indexOf(node) !== -1) return true;
- }
+ return Boolean(relationNodes[node.id]);
} else {
return false;
}
-module Account
+module Accounts
class DeletionsController < ApplicationController
layout "site"
helper_method :oauth_token
def self.allow_thirdparty_images(**options)
- content_security_policy(options) do |policy|
+ content_security_policy(**options) do |policy|
policy.img_src("*", :data)
end
end
before_action :lookup_user, :only => :index
before_action :check_database_writable, :only => [:create, :hide, :unhide]
- allow_thirdparty_images :only => :index
+ allow_thirdparty_images :only => [:index, :create]
def index
@title = t ".title", :user => @user.display_name
--- /dev/null
+class ElementsController < ApplicationController
+ layout :map_layout
+
+ before_action :authorize_web
+ before_action :set_locale
+ before_action -> { check_database_readable(:need_api => true) }
+ before_action :require_oauth
+
+ authorize_resource
+
+ around_action :web_timeout
+end
--- /dev/null
+module Messages
+ class RepliesController < ApplicationController
+ layout "site"
+
+ before_action :authorize_web
+ before_action :set_locale
+
+ authorize_resource :class => Message
+
+ before_action :check_database_readable
+ before_action :check_database_writable
+
+ allow_thirdparty_images
+
+ # Allow the user to reply to another message.
+ def new
+ message = Message.find(params[:message_id])
+
+ if message.recipient == current_user
+ message.update(:message_read => true)
+
+ @message = Message.new(
+ :recipient => message.sender,
+ :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
+ :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
+ )
+
+ @title = @message.title
+
+ render "messages/new"
+ elsif message.sender == current_user
+ @message = Message.new(
+ :recipient => message.recipient,
+ :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
+ :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
+ )
+
+ @title = @message.title
+
+ render "messages/new"
+ else
+ flash[:notice] = t ".wrong_user", :user => current_user.display_name
+ redirect_to login_path(:referer => request.fullpath)
+ end
+ rescue ActiveRecord::RecordNotFound
+ @title = t "messages.no_such_message.title"
+ render "messages/no_such_message", :status => :not_found
+ end
+ end
+end
before_action :lookup_user, :only => [:new, :create]
before_action :check_database_readable
- before_action :check_database_writable, :only => [:new, :create, :reply, :mark, :destroy]
+ before_action :check_database_writable, :only => [:new, :create, :mark, :destroy]
allow_thirdparty_images :only => [:new, :create, :show]
elsif @message.save
flash[:notice] = t ".message_sent"
UserMailer.message_notification(@message).deliver_later if @message.notify_recipient?
- redirect_to messages_inbox_path
+ redirect_to messages_outbox_path
else
@title = t "messages.new.title"
render :action => "new"
render :action => "no_such_message", :status => :not_found
end
- # Allow the user to reply to another message.
- def reply
- message = Message.find(params[:message_id])
-
- if message.recipient == current_user
- message.update(:message_read => true)
-
- @message = Message.new(
- :recipient => message.sender,
- :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
- :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
- )
-
- @title = @message.title
-
- render :action => "new"
- elsif message.sender == current_user
- @message = Message.new(
- :recipient => message.recipient,
- :title => "Re: #{message.title.sub(/^Re:\s*/, '')}",
- :body => "On #{message.sent_on} #{message.sender.display_name} wrote:\n\n#{message.body.gsub(/^/, '> ')}"
- )
-
- @title = @message.title
-
- render :action => "new"
- else
- flash[:notice] = t ".wrong_user", :user => current_user.display_name
- redirect_to login_path(:referer => request.fullpath)
- end
- rescue ActiveRecord::RecordNotFound
- @title = t "messages.no_such_message.title"
- render :action => "no_such_message", :status => :not_found
- end
-
# Set the message as being read or unread.
def mark
@message = current_user.messages.unscope(:where => :muted).find(params[:message_id])
-class NodesController < ApplicationController
- layout :map_layout
-
- before_action :authorize_web
- before_action :set_locale
- before_action -> { check_database_readable(:need_api => true) }
- before_action :require_oauth
-
- authorize_resource
-
- around_action :web_timeout
-
+class NodesController < ElementsController
def show
@type = "node"
@feature = Node.preload(:node_tags, :containing_relation_members, :changeset => [:changeset_tags, :user], :ways => :way_tags).find(params[:id])
- render "browse/feature"
rescue ActiveRecord::RecordNotFound
render "browse/not_found", :status => :not_found
end
--- /dev/null
+class OldElementsController < ApplicationController
+ layout :map_layout
+
+ before_action :authorize_web
+ before_action :set_locale
+ before_action -> { check_database_readable(:need_api => true) }
+ before_action :require_oauth
+
+ authorize_resource
+
+ before_action :require_moderator_for_unredacted_history
+ around_action :web_timeout
+
+ private
+
+ def require_moderator_for_unredacted_history
+ deny_access(nil) if params[:show_redactions] && !current_user&.moderator?
+ end
+end
-class OldNodesController < ApplicationController
- layout :map_layout
-
- before_action :authorize_web
- before_action :set_locale
- before_action -> { check_database_readable(:need_api => true) }
- before_action :require_oauth
-
- authorize_resource
-
- before_action :require_moderator_for_unredacted_history
- around_action :web_timeout
-
+class OldNodesController < OldElementsController
def index
@type = "node"
@feature = Node.preload(:node_tags, :old_nodes => [:old_tags, { :changeset => [:changeset_tags, :user] }]).find(params[:id])
- render "browse/history"
rescue ActiveRecord::RecordNotFound
render "browse/not_found", :status => :not_found
end
@type = "node"
@feature = OldNode.preload(:old_tags, :changeset => [:changeset_tags, :user]).find([params[:id], params[:version]])
rescue ActiveRecord::RecordNotFound
- render :action => "not_found", :status => :not_found
- end
-
- private
-
- def require_moderator_for_unredacted_history
- deny_access(nil) if params[:show_redactions] && !current_user&.moderator?
+ render "browse/not_found", :status => :not_found
end
end
-class OldRelationsController < ApplicationController
- layout :map_layout
-
- before_action :authorize_web
- before_action :set_locale
- before_action -> { check_database_readable(:need_api => true) }
- before_action :require_oauth
-
- authorize_resource
-
- before_action :require_moderator_for_unredacted_history
- around_action :web_timeout
-
+class OldRelationsController < OldElementsController
def index
@type = "relation"
@feature = Relation.preload(:relation_tags, :old_relations => [:old_tags, { :changeset => [:changeset_tags, :user], :old_members => :member }]).find(params[:id])
- render "browse/history"
rescue ActiveRecord::RecordNotFound
render "browse/not_found", :status => :not_found
end
@type = "relation"
@feature = OldRelation.preload(:old_tags, :changeset => [:changeset_tags, :user], :old_members => :member).find([params[:id], params[:version]])
rescue ActiveRecord::RecordNotFound
- render :action => "not_found", :status => :not_found
- end
-
- private
-
- def require_moderator_for_unredacted_history
- deny_access(nil) if params[:show_redactions] && !current_user&.moderator?
+ render "browse/not_found", :status => :not_found
end
end
-class OldWaysController < ApplicationController
- layout :map_layout
-
- before_action :authorize_web
- before_action :set_locale
- before_action -> { check_database_readable(:need_api => true) }
- before_action :require_oauth
-
- authorize_resource
-
- before_action :require_moderator_for_unredacted_history
- around_action :web_timeout
-
+class OldWaysController < OldElementsController
def index
@type = "way"
@feature = Way.preload(:way_tags, :old_ways => [:old_tags, { :changeset => [:changeset_tags, :user], :old_nodes => { :node => [:node_tags, :ways] } }]).find(params[:id])
- render "browse/history"
rescue ActiveRecord::RecordNotFound
render "browse/not_found", :status => :not_found
end
@type = "way"
@feature = OldWay.preload(:old_tags, :changeset => [:changeset_tags, :user], :old_nodes => { :node => [:node_tags, :ways] }).find([params[:id], params[:version]])
rescue ActiveRecord::RecordNotFound
- render :action => "not_found", :status => :not_found
- end
-
- private
-
- def require_moderator_for_unredacted_history
- deny_access(nil) if params[:show_redactions] && !current_user&.moderator?
+ render "browse/not_found", :status => :not_found
end
end
-class RelationsController < ApplicationController
- layout :map_layout
-
- before_action :authorize_web
- before_action :set_locale
- before_action -> { check_database_readable(:need_api => true) }
- before_action :require_oauth
-
- authorize_resource
-
- around_action :web_timeout
-
+class RelationsController < ElementsController
def show
@type = "relation"
@feature = Relation.preload(:relation_tags, :containing_relation_members, :changeset => [:changeset_tags, :user], :relation_members => :member).find(params[:id])
- render "browse/feature"
rescue ActiveRecord::RecordNotFound
render "browse/not_found", :status => :not_found
end
-class WaysController < ApplicationController
- layout :map_layout
-
- before_action :authorize_web
- before_action :set_locale
- before_action -> { check_database_readable(:need_api => true) }
- before_action :require_oauth
-
- authorize_resource
-
- around_action :web_timeout
-
+class WaysController < ElementsController
def show
@type = "way"
@feature = Way.preload(:way_tags, :containing_relation_members, :changeset => [:changeset_tags, :user], :nodes => [:node_tags, { :ways => :way_tags }]).find(params[:id])
- render "browse/feature"
rescue ActiveRecord::RecordNotFound
render "browse/not_found", :status => :not_found
end
t "changesets.index.title"
end
end
+
+ def changeset_data(changeset)
+ changeset_data = { :id => changeset.id }
+
+ if changeset.bbox_valid?
+ bbox = changeset.bbox.to_unscaled
+ changeset_data[:bbox] = {
+ :minlon => bbox.min_lon,
+ :minlat => bbox.min_lat,
+ :maxlon => bbox.max_lon,
+ :maxlat => bbox.max_lat
+ }
+ end
+
+ changeset_data
+ end
end
def block_short_status(block)
if block.active?
- if block.needs_view?
- if block.ends_at > Time.now.utc
- t("user_blocks.helper.short.active_unread")
- else
- t("user_blocks.helper.short.expired_unread")
- end
- else
+ if block.ends_at > Time.now.utc
t("user_blocks.helper.short.active")
+ else
+ t("user_blocks.helper.short.active_until_read")
end
else
if block.revoker_id.nil?
- if block.updated_at > block.ends_at
- t("user_blocks.helper.short.read_html", :time => block_short_time_in_past(block.updated_at))
+ if block.deactivates_at > block.ends_at
+ t("user_blocks.helper.short.read_html", :time => block_short_time_in_past(block.deactivates_at))
else
t("user_blocks.helper.short.ended")
end
@text = message.body
@title = message.title
@readurl = message_url(message)
- @replyurl = message_reply_url(message)
+ @replyurl = new_message_reply_url(message)
@author = @from_user
attach_user_avatar(message.sender)
<fieldset class="mb-3">
<label for="user_auth_provider" class="form-label"><%= t(".external auth") %></label>
<div class="row">
- <%= f.select(:auth_provider, { t("auth.providers.none") => "" }.merge(Auth.providers), :hide_label => true, :wrapper => { :class => "col-auto mb-0" }) %>
+ <%= f.select :auth_provider,
+ Auth.providers.map { |provider| [I18n.t("auth.providers.#{provider}"), provider] },
+ :include_blank => t("auth.providers.none"),
+ :hide_label => true,
+ :wrapper => { :class => "col-auto mb-0" } %>
<%= f.text_field(:auth_uid, :hide_label => true, :wrapper => { :class => "col mb-0" }) %>
</div>
<small class="form-text text-body-secondary">(<a href="<%= t ".openid.link" %>" target="_new"><%= t ".openid.link text" %></a>)</small>
-<% prefered_auth_button_available = @preferred_auth_provider != "openid" && Auth.providers.value?(@preferred_auth_provider) %>
+<% prefered_auth_button_available = @preferred_auth_provider != "openid" && Auth.providers.include?(@preferred_auth_provider) %>
<div>
<%= tag.div :id => "login_auth_buttons",
<% end %>
<div class="col justify-content-center d-flex align-items-center flex-wrap gap-2">
- <% Auth.providers.each_value do |provider| %>
+ <% Auth.providers.each do |provider| %>
<% if provider == "openid" %>
<%= button_tag image_tag("auth_providers/openid.svg",
:alt => t(".openid.alt"),
<%= render "sidebar_header", :title => t(".title") %>
-<div>
- <p><%= t ".sorry", :type => t(".type.#{@type}"), :id => params[:id] %>
-</div>
+<%= render "not_found_message" %>
-<% changeset_data = { :id => changeset.id }
-
- if changeset.bbox_valid?
- bbox = changeset.bbox.to_unscaled
- changeset_data[:bbox] = {
- :minlon => bbox.min_lon,
- :minlat => bbox.min_lat,
- :maxlon => bbox.max_lon,
- :maxlat => bbox.max_lat
- }
- end %>
-
-<%= tag.li :id => "changeset_#{changeset.id}", :data => { :changeset => changeset_data }, :class => "list-group-item list-group-item-action" do %>
+<%= tag.li :id => "changeset_#{changeset.id}", :data => { :changeset => changeset_data(changeset) }, :class => "list-group-item list-group-item-action" do %>
<p class="fs-6 text-truncate text-wrap">
<a class="changeset_id link-body-emphasis stretched-link" href="<%= changeset_path(changeset) %>">
<span><%= changeset.tags["comment"].to_s.presence || t("browse.no_comment") %></span>
--- /dev/null
+<div>
+ <p><%= t ".sorry", :id => params[:id] %></p>
+</div>
<p class="fs-6 overflow-x-auto">
<%= linkify(@changeset.tags["comment"].to_s.presence || t("browse.no_comment")) %>
</p>
- <p class="details"><%= changeset_details(@changeset) %></p>
+ <%= tag.p :class => "details", :data => { :changeset => changeset_data(@changeset) } do %>
+ <%= changeset_details(@changeset) %>
+ <% end %>
<%= render :partial => "browse/tag_details", :object => @changeset.tags.except("comment") %>
<div class="richtext text-break"><%= @message.body.to_html %></div>
<div>
- <%= link_to t(".reply_button"), message_reply_path(@message), :class => "btn btn-primary" %>
+ <%= link_to t(".reply_button"), new_message_reply_path(@message), :class => "btn btn-primary" %>
<% if current_user == @message.recipient %>
<%= link_to t(".unread_button"), message_mark_path(@message, :mark => "unread"), :method => "post", :class => "btn btn-primary" %>
<%= link_to t(".destroy_button"), message_path(@message), :method => "delete", :class => "btn btn-danger" %>
--- /dev/null
+<div>
+ <p><%= t ".sorry", :id => params[:id] %></p>
+</div>
--- /dev/null
+<div>
+ <p><%= t ".sorry", :id => params[:id] %></p>
+</div>
<% elsif current_user&.moderator? %>
·
<% if !params[:show_redactions] %>
- <%= link_to t("browse.view_redacted_data"), :params => { :show_redactions => true } %>
+ <%= link_to t(".view_redacted_data"), :params => { :show_redactions => true } %>
<% else %>
- <%= link_to t("browse.view_redaction_message") %>
+ <%= link_to t(".view_redaction_message") %>
<% end %>
<% end %>
</div>
-<% set_title(t("browse.#{@type}.history_title_html", :name => printable_element_name(@feature))) %>
+<% set_title(t(".#{@type}.title_html", :name => printable_element_name(@feature))) %>
-<%= render "sidebar_header", :title => t("browse.#{@type}.history_title_html", :name => printable_element_name(@feature)) %>
+<%= render "sidebar_header", :title => t(".#{@type}.title_html", :name => printable_element_name(@feature)) %>
<%= render :partial => "browse/#{@type}", :collection => @feature.send(:"old_#{@type}s").reverse %>
--- /dev/null
+<div>
+ <% if params[:version] %>
+ <p><%= t ".sorry", :id => params[:id], :version => params[:version] %></p>
+ <% else %>
+ <p><%= t "nodes.not_found_message.sorry", :id => params[:id] %></p>
+ <% end %>
+</div>
+++ /dev/null
-<% set_title(t("browse.not_found.title")) %>
-
-<%= render "sidebar_header", :title => t("browse.not_found.title") %>
-
-<div>
- <p><%= t ".sorry", :id => params[:id], :version => params[:version] %></p>
-</div>
<%= render :partial => "browse/node", :object => @feature %>
-<%= render :partial => "browse/version_actions" %>
+<%= render :partial => "actions" %>
--- /dev/null
+<div>
+ <% if params[:version] %>
+ <p><%= t ".sorry", :id => params[:id], :version => params[:version] %></p>
+ <% else %>
+ <p><%= t "relations.not_found_message.sorry", :id => params[:id] %></p>
+ <% end %>
+</div>
+++ /dev/null
-<% set_title(t("browse.not_found.title")) %>
-
-<%= render "sidebar_header", :title => t("browse.not_found.title") %>
-
-<div>
- <p><%= t ".sorry", :id => params[:id], :version => params[:version] %></p>
-</div>
<%= render :partial => "browse/relation", :object => @feature %>
-<%= render :partial => "browse/version_actions" %>
+<%= render :partial => "actions" %>
--- /dev/null
+<div>
+ <% if params[:version] %>
+ <p><%= t ".sorry", :id => params[:id], :version => params[:version] %></p>
+ <% else %>
+ <p><%= t "ways.not_found_message.sorry", :id => params[:id] %></p>
+ <% end %>
+</div>
+++ /dev/null
-<% set_title(t("browse.not_found.title")) %>
-
-<%= render "sidebar_header", :title => t("browse.not_found.title") %>
-
-<div>
- <p><%= t ".sorry", :id => params[:id], :version => params[:version] %></p>
-</div>
<%= render :partial => "browse/way", :object => @feature %>
-<%= render :partial => "browse/version_actions" %>
+<%= render :partial => "actions" %>
--- /dev/null
+<div>
+ <p><%= t ".sorry", :id => params[:id] %></p>
+</div>
--- /dev/null
+<div>
+ <p><%= t ".sorry", :id => params[:id] %></p>
+</div>
entry:
comment: Comment
full: Full note
- account:
- deletions:
- show:
- title: Delete My Account
- warning: Warning! The account deletion process is final, and cannot be reversed.
- delete_account: Delete Account
- delete_introduction: "You can delete your OpenStreetMap account using the button below. Please note the following details:"
- delete_profile: Your profile information, including your avatar, description and home location will be removed.
- delete_display_name: Your display name will be removed, and can be reused by other accounts.
- retain_caveats: "However, some information about you will be retained on OpenStreetMap, even after your account is deleted:"
- retain_edits: Your edits to the map database, if any, will be retained.
- retain_traces: Your uploaded traces, if any, will be retained.
- retain_diary_entries: Your diary entries and diary comments, if any, will be retained but hidden from view.
- retain_notes: Your map notes and note comments, if any, will be retained but hidden from view.
- retain_changeset_discussions: Your changeset discussions, if any, will be retained.
- retain_email: Your email address will be retained.
- recent_editing_html: "As you have edited recently your account cannot currently be deleted. Deletion will be possible in %{time}."
- confirm_delete: Are you sure?
- cancel: Cancel
accounts:
edit:
title: "Edit account"
success: "User information updated successfully."
destroy:
success: "Account Deleted."
+ deletions:
+ show:
+ title: Delete My Account
+ warning: Warning! The account deletion process is final, and cannot be reversed.
+ delete_account: Delete Account
+ delete_introduction: "You can delete your OpenStreetMap account using the button below. Please note the following details:"
+ delete_profile: Your profile information, including your avatar, description and home location will be removed.
+ delete_display_name: Your display name will be removed, and can be reused by other accounts.
+ retain_caveats: "However, some information about you will be retained on OpenStreetMap, even after your account is deleted:"
+ retain_edits: Your edits to the map database, if any, will be retained.
+ retain_traces: Your uploaded traces, if any, will be retained.
+ retain_diary_entries: Your diary entries and diary comments, if any, will be retained but hidden from view.
+ retain_notes: Your map notes and note comments, if any, will be retained but hidden from view.
+ retain_changeset_discussions: Your changeset discussions, if any, will be retained.
+ retain_email: Your email address will be retained.
+ recent_editing_html: "As you have edited recently your account cannot currently be deleted. Deletion will be possible in %{time}."
+ confirm_delete: Are you sure?
+ cancel: Cancel
browse:
deleted_ago_by_html: "Deleted %{time_ago} by %{user}"
edited_ago_by_html: "Edited %{time_ago} by %{user}"
view_history: "View History"
view_unredacted_history: "View Unredacted History"
view_details: "View Details"
- view_redacted_data: "View Redacted Data"
- view_redaction_message: "View Redaction Message"
location: "Location:"
common_details:
coordinates_html: "%{latitude}, %{longitude}"
node:
title_html: "Node: %{name}"
- history_title_html: "Node History: %{name}"
way:
title_html: "Way: %{name}"
- history_title_html: "Way History: %{name}"
nodes: "Nodes"
nodes_count:
one: "%{count} node"
other: "part of ways %{related_ways}"
relation:
title_html: "Relation: %{name}"
- history_title_html: "Relation History: %{name}"
members: "Members"
members_count:
one: "%{count} member"
entry_role_html: "%{relation_name} (as %{relation_role})"
not_found:
title: Not Found
- sorry: "Sorry, %{type} #%{id} could not be found."
- type:
- node: node
- way: way
- relation: relation
- changeset: changeset
- note: note
timeout:
title: Timeout Error
sorry: "Sorry, the data for the %{type} with the id %{id} took too long to retrieve."
introduction: "Click on the map to find nearby features."
nearby: "Nearby features"
enclosing: "Enclosing features"
+ old_elements:
+ index:
+ node:
+ title_html: "Node History: %{name}"
+ way:
+ title_html: "Way History: %{name}"
+ relation:
+ title_html: "Relation History: %{name}"
+ actions:
+ view_redacted_data: "View Redacted Data"
+ view_redaction_message: "View Redaction Message"
nodes:
+ not_found_message:
+ sorry: "Sorry, node #%{id} could not be found."
timeout:
sorry: "Sorry, the data for the node with the id %{id} took too long to retrieve."
old_nodes:
- not_found:
+ not_found_message:
sorry: "Sorry, node #%{id} version %{version} could not be found."
timeout:
sorry: "Sorry, the history of the node with the id %{id} took too long to retrieve."
ways:
+ not_found_message:
+ sorry: "Sorry, way #%{id} could not be found."
timeout:
sorry: "Sorry, the data for the way with the id %{id} took too long to retrieve."
old_ways:
- not_found:
+ not_found_message:
sorry: "Sorry, way #%{id} version %{version} could not be found."
timeout:
sorry: "Sorry, the history of the way with the id %{id} took too long to retrieve."
relations:
+ not_found_message:
+ sorry: "Sorry, relation #%{id} could not be found."
timeout:
sorry: "Sorry, the data for the relation with the id %{id} took too long to retrieve."
old_relations:
- not_found:
+ not_found_message:
sorry: "Sorry, relation #%{id} version %{version} could not be found."
timeout:
sorry: "Sorry, the history of the relation with the id %{id} took too long to retrieve."
ways_paginated: "Ways (%{x}-%{y} of %{count})"
relations: "Relations (%{count})"
relations_paginated: "Relations (%{x}-%{y} of %{count})"
+ not_found_message:
+ sorry: "Sorry, changeset #%{id} could not be found."
timeout:
sorry: "Sorry, the list of changesets you requested took too long to retrieve."
dashboards:
title: "No such message"
heading: "No such message"
body: "Sorry there is no message with that id."
- reply:
- wrong_user: "You are logged in as '%{user}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply."
show:
title: "Read message"
reply_button: "Reply"
people_mapping_nearby: "people mapping nearby"
message:
destroy_button: "Delete"
+ replies:
+ new:
+ wrong_user: "You are logged in as '%{user}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply."
passwords:
new:
title: "Lost password"
ended: "ended"
revoked_html: "revoked by %{name}"
active: "active"
- active_unread: "active unread"
- expired_unread: "expired unread"
+ active_until_read: "active until read"
read_html: "read at %{time}"
time_in_future_title: "%{time_absolute}; in %{time_relative}"
time_in_past_title: "%{time_absolute}; %{time_relative}"
showing_page: "Page %{page}"
next: "Next"
previous: "Previous"
+ not_found_message:
+ sorry: "Sorry, note #%{id} could not be found."
javascripts:
close: Close
share:
get "/user/:display_name/account", :to => redirect(:path => "/account/edit")
post "/user/:display_name/set_status" => "users#set_status", :as => :set_status_user
- resource :account, :only => [:edit, :update, :destroy]
-
- namespace :account do
- resource :deletion, :only => [:show]
+ resource :account, :only => [:edit, :update, :destroy] do
+ resource :deletion, :module => :accounts, :only => :show
end
+
resource :dashboard, :only => [:show]
resource :preferences, :only => [:show, :edit, :update]
resource :profile, :only => [:edit, :update]
post :mark
patch :unmute
- match :reply, :via => [:get, :post]
+ resource :reply, :module => :messages, :path_names => { :new => "new" }, :only => :new
end
namespace :messages, :path => "/messages" do
resource :inbox, :only => :show
get "/user/:display_name/outbox", :to => redirect(:path => "/messages/outbox")
get "/message/new/:display_name", :to => redirect(:path => "/messages/new/%{display_name}")
get "/message/read/:message_id", :to => redirect(:path => "/messages/%{message_id}")
+ get "/messages/:message_id/reply", :to => redirect(:path => "/messages/%{message_id}/reply/new")
# muting users
scope "/user/:display_name" do
module Auth
- @providers = {}
+ @providers = ["openid"]
+ @providers << "google" if Settings.key?(:google_auth_id)
+ @providers << "facebook" if Settings.key?(:facebook_auth_id)
+ @providers << "microsoft" if Settings.key?(:microsoft_auth_id)
+ @providers << "github" if Settings.key?(:github_auth_id)
+ @providers << "wikipedia" if Settings.key?(:wikipedia_auth_id)
+ @providers.freeze
def self.providers
- @providers[I18n.locale] ||= {
- I18n.t("auth.providers.openid") => "openid"
- }.tap do |providers|
- providers[I18n.t("auth.providers.google")] = "google" if Settings.key?(:google_auth_id)
- providers[I18n.t("auth.providers.facebook")] = "facebook" if Settings.key?(:facebook_auth_id)
- providers[I18n.t("auth.providers.microsoft")] = "microsoft" if Settings.key?(:microsoft_auth_id)
- providers[I18n.t("auth.providers.github")] = "github" if Settings.key?(:github_auth_id)
- providers[I18n.t("auth.providers.wikipedia")] = "wikipedia" if Settings.key?(:wikipedia_auth_id)
- end.freeze
+ @providers
end
end
end
assert_response :success
assert_template :new
+ assert_match(/img-src \* data:;/, @response.headers["Content-Security-Policy-Report-Only"])
# Now try again with the right id
assert_difference "ActionMailer::Base.deliveries.size", entry.subscribers.count do
--- /dev/null
+require "test_helper"
+
+module Messages
+ class RepliesControllerTest < ActionDispatch::IntegrationTest
+ ##
+ # test all routes which lead to this controller
+ def test_routes
+ assert_routing(
+ { :path => "/messages/1/reply/new", :method => :get },
+ { :controller => "messages/replies", :action => "new", :message_id => "1" }
+ )
+ end
+
+ def test_new
+ user = create(:user)
+ recipient_user = create(:user)
+ other_user = create(:user)
+ message = create(:message, :unread, :sender => user, :recipient => recipient_user)
+
+ # Check that the message reply page requires us to login
+ get new_message_reply_path(message)
+ assert_redirected_to login_path(:referer => new_message_reply_path(message))
+
+ # Login as the wrong user
+ session_for(other_user)
+
+ # Check that we can't reply to somebody else's message
+ get new_message_reply_path(message)
+ assert_redirected_to login_path(:referer => new_message_reply_path(message))
+ assert_equal "You are logged in as '#{other_user.display_name}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply.", flash[:notice]
+
+ # Login as the right user
+ session_for(recipient_user)
+
+ # Check that the message reply page loads
+ get new_message_reply_path(message)
+ assert_response :success
+ assert_template "new"
+ assert_select "title", "Re: #{message.title} | OpenStreetMap"
+ assert_select "form[action='/messages']", :count => 1 do
+ assert_select "input[type='hidden'][name='display_name'][value='#{user.display_name}']"
+ assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
+ assert_select "textarea#message_body", :count => 1
+ assert_select "input[type='submit'][value='Send']", :count => 1
+ end
+ assert Message.find(message.id).message_read
+
+ # Login as the sending user
+ session_for(user)
+
+ # Check that the message reply page loads
+ get new_message_reply_path(message)
+ assert_response :success
+ assert_template "new"
+ assert_select "title", "Re: #{message.title} | OpenStreetMap"
+ assert_select "form[action='/messages']", :count => 1 do
+ assert_select "input[type='hidden'][name='display_name'][value='#{recipient_user.display_name}']"
+ assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
+ assert_select "textarea#message_body", :count => 1
+ assert_select "input[type='submit'][value='Send']", :count => 1
+ end
+
+ # Asking to reply to a message with a bogus ID should fail
+ get new_message_reply_path(99999)
+ assert_response :not_found
+ assert_template "no_such_message"
+ end
+ end
+end
{ :path => "/messages/1/mark", :method => :post },
{ :controller => "messages", :action => "mark", :message_id => "1" }
)
- assert_routing(
- { :path => "/messages/1/reply", :method => :get },
- { :controller => "messages", :action => "reply", :message_id => "1" }
- )
- assert_routing(
- { :path => "/messages/1/reply", :method => :post },
- { :controller => "messages", :action => "reply", :message_id => "1" }
- )
assert_routing(
{ :path => "/messages/1", :method => :delete },
{ :controller => "messages", :action => "destroy", :id => "1" }
end
end
end
- assert_redirected_to messages_inbox_path
+ assert_redirected_to messages_outbox_path
assert_equal "Message sent", flash[:notice]
e = ActionMailer::Base.deliveries.first
assert_equal [recipient_user.email], e.to
end
end
- ##
- # test the reply action
- def test_reply
- user = create(:user)
- recipient_user = create(:user)
- other_user = create(:user)
- message = create(:message, :unread, :sender => user, :recipient => recipient_user)
-
- # Check that the message reply page requires us to login
- get message_reply_path(message)
- assert_redirected_to login_path(:referer => message_reply_path(message))
-
- # Login as the wrong user
- session_for(other_user)
-
- # Check that we can't reply to somebody else's message
- get message_reply_path(message)
- assert_redirected_to login_path(:referer => message_reply_path(message))
- assert_equal "You are logged in as '#{other_user.display_name}' but the message you have asked to reply to was not sent to that user. Please log in as the correct user in order to reply.", flash[:notice]
-
- # Login as the right user
- session_for(recipient_user)
-
- # Check that the message reply page loads
- get message_reply_path(message)
- assert_response :success
- assert_template "new"
- assert_select "title", "Re: #{message.title} | OpenStreetMap"
- assert_select "form[action='/messages']", :count => 1 do
- assert_select "input[type='hidden'][name='display_name'][value='#{user.display_name}']"
- assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
- assert_select "textarea#message_body", :count => 1
- assert_select "input[type='submit'][value='Send']", :count => 1
- end
- assert Message.find(message.id).message_read
-
- # Login as the sending user
- session_for(user)
-
- # Check that the message reply page loads
- get message_reply_path(message)
- assert_response :success
- assert_template "new"
- assert_select "title", "Re: #{message.title} | OpenStreetMap"
- assert_select "form[action='/messages']", :count => 1 do
- assert_select "input[type='hidden'][name='display_name'][value='#{recipient_user.display_name}']"
- assert_select "input#message_title[value='Re: #{message.title}']", :count => 1
- assert_select "textarea#message_body", :count => 1
- assert_select "input[type='submit'][value='Send']", :count => 1
- end
-
- # Asking to reply to a message with a bogus ID should fail
- get message_reply_path(99999)
- assert_response :not_found
- assert_template "no_such_message"
- end
-
##
# test the show action
def test_show
def test_show
node = create(:node)
- sidebar_browse_check :node_path, node.id, "browse/feature"
+ sidebar_browse_check :node_path, node.id, "elements/show"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_node_path node, 1}']", :text => "1", :count => 1
end
def test_show_multiple_versions
node = create(:node, :with_history, :version => 2)
- sidebar_browse_check :node_path, node.id, "browse/feature"
+ sidebar_browse_check :node_path, node.id, "elements/show"
assert_select ".secondary-actions a[href='#{node_history_path node}']", :count => 1
assert_select ".secondary-actions a[href='#{old_node_path node, 1}']", :count => 1
assert_select ".secondary-actions a[href='#{old_node_path node, 2}']", :count => 1
member = create(:node)
relation = create(:relation)
create(:relation_member, :relation => relation, :member => member)
- sidebar_browse_check :node_path, member.id, "browse/feature"
+ sidebar_browse_check :node_path, member.id, "elements/show"
assert_select "a[href='#{relation_path relation}']", :count => 1
end
def test_show_deleted
node = create(:node, :visible => false)
- sidebar_browse_check :node_path, node.id, "browse/feature"
+ sidebar_browse_check :node_path, node.id, "elements/show"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_node_path node, 1}']", :text => "1", :count => 1
end
get node_path(node)
assert_response :success
- assert_template "feature"
+ assert_template "elements/show"
# check that we don't show lat/lon for a redacted node.
assert_select ".browse-section", 1
def test_history
node = create(:node, :with_history)
- sidebar_browse_check :node_history_path, node.id, "browse/history"
+ sidebar_browse_check :node_history_path, node.id, "old_elements/index"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_node_path node, 1}']", :text => "1", :count => 1
end
get node_history_path(:id => node)
assert_response :success
- assert_template "browse/history"
+ assert_template "old_elements/index"
# there are 2 revisions of the redacted node, but only one
# should be showing details here.
get node_history_path(:id => node, :params => { :show_redactions => true })
assert_response :success
- assert_template "browse/history"
+ assert_template "old_elements/index"
assert_select ".browse-section", 2
assert_select ".browse-section.browse-redacted", 0
def test_not_found
get old_node_path(0, 0)
assert_response :not_found
- assert_template "old_nodes/not_found"
+ assert_template "browse/not_found"
assert_template :layout => "map"
assert_select "#sidebar_content", /node #0 version 0 could not be found/
end
def test_history
relation = create(:relation, :with_history)
- sidebar_browse_check :relation_history_path, relation.id, "browse/history"
+ sidebar_browse_check :relation_history_path, relation.id, "old_elements/index"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_relation_path relation, 1}']", :text => "1", :count => 1
end
get relation_history_path(:id => relation)
assert_response :success
- assert_template "browse/history"
+ assert_template "old_elements/index"
# there are 4 revisions of the redacted relation, but only 2
# should be showing details here.
get relation_history_path(:id => relation, :params => { :show_redactions => true })
assert_response :success
- assert_template "browse/history"
+ assert_template "old_elements/index"
assert_select ".browse-section", 4
assert_select ".browse-section.browse-redacted", 0
def test_not_found
get old_relation_path(0, 0)
assert_response :not_found
- assert_template "old_relations/not_found"
+ assert_template "browse/not_found"
assert_template :layout => "map"
assert_select "#sidebar_content", /relation #0 version 0 could not be found/
end
def test_history
way = create(:way, :with_history)
- sidebar_browse_check :way_history_path, way.id, "browse/history"
+ sidebar_browse_check :way_history_path, way.id, "old_elements/index"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_way_path way, 1}']", :text => "1", :count => 1
end
get way_history_path(:id => way)
assert_response :success
- assert_template "browse/history"
+ assert_template "old_elements/index"
# there are 4 revisions of the redacted way, but only 2
# should be showing details here.
get way_history_path(:id => way, :params => { :show_redactions => true })
assert_response :success
- assert_template "browse/history"
+ assert_template "old_elements/index"
assert_select ".browse-section", 4
assert_select ".browse-section.browse-redacted", 0
def test_not_found
get old_way_path(0, 0)
assert_response :not_found
- assert_template "old_ways/not_found"
+ assert_template "browse/not_found"
assert_template :layout => "map"
assert_select "#sidebar_content", /way #0 version 0 could not be found/
end
def test_show
relation = create(:relation)
- sidebar_browse_check :relation_path, relation.id, "browse/feature"
+ sidebar_browse_check :relation_path, relation.id, "elements/show"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_relation_path relation, 1}']", :text => "1", :count => 1
end
def test_show_multiple_versions
relation = create(:relation, :with_history, :version => 2)
- sidebar_browse_check :relation_path, relation.id, "browse/feature"
+ sidebar_browse_check :relation_path, relation.id, "elements/show"
assert_select ".secondary-actions a[href='#{relation_history_path relation}']", :count => 1
assert_select ".secondary-actions a[href='#{old_relation_path relation, 1}']", :count => 1
assert_select ".secondary-actions a[href='#{old_relation_path relation, 2}']", :count => 1
member = create(:relation)
relation = create(:relation)
create(:relation_member, :relation => relation, :member => member)
- sidebar_browse_check :relation_path, member.id, "browse/feature"
+ sidebar_browse_check :relation_path, member.id, "elements/show"
assert_select "a[href='#{relation_path relation}']", :count => 1
end
get new_user_path, :params => { :cookie_test => "true" }
assert_response :success
+ assert_no_match(/img-src \* data:;/, @response.headers["Content-Security-Policy-Report-Only"])
+
assert_select "html", :count => 1 do
assert_select "head", :count => 1 do
assert_select "title", :text => /Sign Up/, :count => 1
get user_path(user)
assert_response :success
+ assert_match(/img-src \* data:;/, @response.headers["Content-Security-Policy-Report-Only"])
assert_select "div.content-heading" do
assert_select "a[href^='/user/#{ERB::Util.u(user.display_name)}/history']", 1
assert_select "a[href='/user/#{ERB::Util.u(user.display_name)}/traces']", 1
def test_show
way = create(:way)
- sidebar_browse_check :way_path, way.id, "browse/feature"
+ sidebar_browse_check :way_path, way.id, "elements/show"
assert_select "h4", /^Version/ do
assert_select "a[href='#{old_way_path way, 1}']", :text => "1", :count => 1
end
def test_show_multiple_versions
way = create(:way, :with_history, :version => 2)
- sidebar_browse_check :way_path, way.id, "browse/feature"
+ sidebar_browse_check :way_path, way.id, "elements/show"
assert_select ".secondary-actions a[href='#{way_history_path way}']", :count => 1
assert_select ".secondary-actions a[href='#{old_way_path way, 1}']", :count => 1
assert_select ".secondary-actions a[href='#{old_way_path way, 2}']", :count => 1
member = create(:way)
relation = create(:relation)
create(:relation_member, :relation => relation, :member => member)
- sidebar_browse_check :way_path, member.id, "browse/feature"
+ sidebar_browse_check :way_path, member.id, "elements/show"
assert_select "a[href='#{relation_path relation}']", :count => 1
end
assert_match %r{^Ends in <time title=".* datetime=".*">about 1 hour</time>\.$}, block_status(block)
end
+ def test_block_short_status
+ freeze_time do
+ future_end_block = create(:user_block, :ends_at => Time.now.utc + 48.hours)
+ unread_future_end_block = create(:user_block, :needs_view, :ends_at => Time.now.utc + 48.hours)
+ past_end_block = create(:user_block, :ends_at => Time.now.utc + 1.hour)
+ unread_past_end_block = create(:user_block, :needs_view, :ends_at => Time.now.utc + 1.hour)
+
+ travel 24.hours
+
+ assert_equal "active", block_short_status(future_end_block)
+ assert_equal "active", block_short_status(unread_future_end_block)
+ assert_equal "ended", block_short_status(past_end_block)
+ assert_equal "active until read", block_short_status(unread_past_end_block)
+ end
+ end
+
+ def test_block_short_status_with_immediate_update
+ freeze_time do
+ block = UserBlock.new :user => create(:user),
+ :creator => create(:moderator_user),
+ :reason => "because",
+ :created_at => Time.now.utc,
+ :ends_at => Time.now.utc,
+ :deactivates_at => Time.now.utc,
+ :needs_view => false
+
+ travel 1.second
+
+ block.save
+
+ assert_equal "ended", block_short_status(block)
+ end
+ end
+
+ def test_block_short_status_read
+ freeze_time do
+ block = create(:user_block, :needs_view, :ends_at => Time.now.utc)
+
+ travel 24.hours
+
+ assert_equal "active until read", block_short_status(block)
+
+ block.update(:needs_view => false, :deactivates_at => Time.now.utc)
+
+ read_date = Time.now.utc.to_date.strftime
+ short_status_dom = Rails::Dom::Testing.html_document.parse(block_short_status(block))
+ assert_dom short_status_dom, ":root", :text => "read at #{read_date}"
+
+ travel 24.hours
+
+ block.update(:reason => "updated reason")
+
+ short_status_dom = Rails::Dom::Testing.html_document.parse(block_short_status(block))
+ assert_dom short_status_dom, ":root", :text => "read at #{read_date}"
+ end
+ end
+
def test_block_duration_in_words
words = block_duration_in_words(364.days)
assert_equal "11 months", words
--- /dev/null
+require "application_system_test_case"
+
+class BrowseTest < ApplicationSystemTestCase
+ test "relation member nodes should be visible on the map when viewing relations" do
+ relation = create(:relation)
+ node = create(:node)
+ create(:relation_member, :relation => relation, :member => node)
+
+ visit relation_path(relation)
+
+ assert_selector "#map .leaflet-overlay-pane path"
+ end
+end
ways = L.OSM.getWays(xml, nodes),
relations = L.OSM.getRelations(xml, nodes, ways);
+ var wayNodes = {}
+ for (var i = 0; i < ways.length; i++) {
+ var way = ways[i];
+ for (var j = 0; j < way.nodes.length; j++) {
+ wayNodes[way.nodes[j].id] = true
+ }
+ }
+
+ var relationNodes = {}
+ for (var i = 0; i < relations.length; i++){
+ var relation = relations[i];
+ for (var j = 0; j < relation.members.length; j++) {
+ relationNodes[relation.members[j].id] = true
+ }
+ }
+
for (var node_id in nodes) {
var node = nodes[node_id];
- if (this.interestingNode(node, ways, relations)) {
+ if (this.interestingNode(node, wayNodes, relationNodes)) {
features.push(node);
}
}
return false;
},
- interestingNode: function (node, ways, relations) {
- var used = false;
-
- for (var i = 0; i < ways.length; i++) {
- if (ways[i].nodes.indexOf(node) >= 0) {
- used = true;
- break;
- }
- }
-
- if (!used) {
- return true;
- }
-
- for (var i = 0; i < relations.length; i++) {
- if (relations[i].members.indexOf(node) >= 0)
- return true;
+ interestingNode: function (node, wayNodes, relationNodes) {
+ if (!wayNodes[node.id] || relationNodes[node.id]) {
+ return true
}
for (var key in node.tags) {
else // relation-way and relation-relation membership not implemented
rel_object.members[j] = null;
}
-
+ rel_object.members = rel_object.members.filter(i => i !== null && i !== undefined)
result.push(rel_object);
}