Merge remote-tracking branch 'upstream/pull/2296'

This commit is contained in:
Tom Hughes 2019-07-15 08:19:30 +01:00
commit c162c065c6
27 changed files with 313 additions and 76 deletions

1
.gitignore vendored
View file

@ -16,4 +16,5 @@ node_modules
public/assets
public/attachments
public/export
storage
tmp

View file

@ -25,6 +25,7 @@ before_script:
- psql -U postgres -c "CREATE FUNCTION tile_for_point(int4, int4) RETURNS int8 AS '/tmp/libpgosm', 'tile_for_point' LANGUAGE C STRICT" openstreetmap
- psql -U postgres -c "CREATE FUNCTION xid_to_int4(xid) RETURNS int4 AS '/tmp/libpgosm', 'xid_to_int4' LANGUAGE C STRICT" openstreetmap
- cp config/travis.database.yml config/database.yml
- cp config/example.storage.yml config/storage.yml
- touch config/settings.local.yml
- bundle exec rake db:migrate
- bundle exec rake i18n:js:export

View file

@ -126,6 +126,12 @@ gem "mimemagic"
# Used for browser detection
gem "browser"
# Used for S3 object storage
gem "aws-sdk-s3"
# Used to resize user images
gem "mini_magick"
# Gems useful for development
group :development do
gem "annotate"

View file

@ -60,6 +60,22 @@ GEM
ast (2.4.0)
autoprefixer-rails (8.6.5)
execjs
aws-eventstream (1.0.3)
aws-partitions (1.184.0)
aws-sdk-core (3.59.0)
aws-eventstream (~> 1.0, >= 1.0.2)
aws-partitions (~> 1.0)
aws-sigv4 (~> 1.1)
jmespath (~> 1.0)
aws-sdk-kms (1.23.0)
aws-sdk-core (~> 3, >= 3.58.0)
aws-sigv4 (~> 1.1)
aws-sdk-s3 (1.45.0)
aws-sdk-core (~> 3, >= 3.58.0)
aws-sdk-kms (~> 1)
aws-sigv4 (~> 1.1)
aws-sigv4 (1.1.0)
aws-eventstream (~> 1.0, >= 1.0.2)
better_errors (2.5.1)
coderay (>= 1.0.0)
erubi (>= 1.0.0)
@ -206,6 +222,7 @@ GEM
image_size (2.0.1)
in_threads (1.5.2)
jaro_winkler (1.5.3)
jmespath (1.4.0)
jquery-rails (4.3.5)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
@ -241,6 +258,7 @@ GEM
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mimemagic (0.3.3)
mini_magick (4.9.3)
mini_mime (1.0.1)
mini_portile2 (2.4.0)
minitest (5.11.3)
@ -446,6 +464,7 @@ DEPENDENCIES
activerecord-import
annotate
autoprefixer-rails (~> 8.6.3)
aws-sdk-s3
better_errors
bigdecimal (~> 1.1.0)
binding_of_caller
@ -482,6 +501,7 @@ DEPENDENCIES
listen
logstasher
mimemagic
mini_magick
minitest (~> 5.1)
oauth-plugin (>= 0.5.1)
omniauth

View file

@ -124,6 +124,15 @@ We use [Yarn](https://yarnpkg.com/) to manage the Node.js modules required for t
bundle exec rake yarn:install
```
## Storage setup
The Rails port needs to be configured with an object storage facility - for
development and testing purposes you can use the example configuration:
```
cp config/example.storage.yml config/storage.yml
```
## Database setup
The Rails Port uses three databases - one for development, one for testing, and one for production. The database-specific configuration

View file

Before

Width:  |  Height:  |  Size: 489 B

After

Width:  |  Height:  |  Size: 489 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 311 B

After

Width:  |  Height:  |  Size: 311 B

Before After
Before After

View file

Before

Width:  |  Height:  |  Size: 6.1 KiB

After

Width:  |  Height:  |  Size: 6.1 KiB

Before After
Before After

View file

@ -85,8 +85,8 @@ $(document).ready(function () {
$("select#user_auth_provider").on("change", updateAuthUID);
$("input#user_image").on("change", function () {
$("#image_action_new").prop("checked", true);
$("input#user_avatar").on("change", function () {
$("#avatar_action_new").prop("checked", true);
});
function enableAuth() {

View file

@ -660,15 +660,15 @@ class UsersController < ApplicationController
user.languages = params[:user][:languages].split(",")
case params[:image_action]
case params[:avatar_action]
when "new" then
user.image = params[:user][:image]
user.avatar.attach(params[:user][:avatar])
user.image_use_gravatar = false
when "delete" then
user.image = nil
user.avatar.purge
user.image_use_gravatar = false
when "gravatar" then
user.image = nil
user.avatar.purge
user.image_use_gravatar = true
end

View file

@ -7,8 +7,12 @@ module UserHelper
if user.image_use_gravatar
user_gravatar_tag(user, options)
else
elsif user.avatar.attached?
image_tag user.avatar.variant(:resize => "100x100>"), options
elsif user.image.file?
image_tag user.image.url(:large), options
else
image_tag "avatar_large.png", options
end
end
@ -18,8 +22,12 @@ module UserHelper
if user.image_use_gravatar
user_gravatar_tag(user, options)
else
elsif user.avatar.attached?
image_tag user.avatar.variant(:resize => "50x50>"), options
elsif user.image.file?
image_tag user.image.url(:small), options
else
image_tag "avatar_small.png", options
end
end
@ -29,16 +37,24 @@ module UserHelper
if user.image_use_gravatar
user_gravatar_tag(user, options)
else
elsif user.avatar.attached?
image_tag user.avatar.variant(:resize => "50x50>"), options
elsif user.image.file?
image_tag user.image.url(:small), options
else
image_tag "avatar_small.png", options
end
end
def user_image_url(user, options = {})
if user.image_use_gravatar
user_gravatar_url(user, options)
else
elsif user.avatar.attached?
url_for(user.avatar.variant(:resize => "100x100>"))
elsif user.image.file?
image_url(user.image.url(:large))
else
image_url("avatar_large.png")
end
end
@ -65,7 +81,7 @@ module UserHelper
def user_gravatar_url(user, options = {})
size = options[:size] || 100
hash = Digest::MD5.hexdigest(user.email.downcase)
default_image_url = image_url("users/images/large.png")
default_image_url = image_url("avatar_large.png")
"#{request.protocol}www.gravatar.com/avatar/#{hash}.jpg?s=#{size}&d=#{u(default_image_url)}"
end

View file

@ -1,4 +1,6 @@
class Notifier < ActionMailer::Base
include ActionView::Helpers::AssetUrlHelper
default :from => Settings.email_from,
:return_path => Settings.email_return_path,
:auto_submitted => "auto-generated"
@ -177,7 +179,16 @@ class Notifier < ActionMailer::Base
end
def attach_user_avatar(user)
attachments.inline["avatar.png"] = File.read(user_avatar_file_path(user))
attachments.inline["avatar.png"] = user_avatar_file(user)
end
def user_avatar_file(user)
avatar = user&.avatar
if avatar&.attached?
return avatar.variant(:resize => "50x50>").blob.download
else
return File.read(user_avatar_file_path(user))
end
end
def user_avatar_file_path(user)
@ -185,7 +196,7 @@ class Notifier < ActionMailer::Base
if image&.file?
return image.path(:small)
else
return Rails.root.join("app", "assets", "images", "users", "images", "small.png")
return Rails.root.join("app", "assets", "images", "avatar_small.png")
end
end

View file

@ -85,6 +85,8 @@ class User < ActiveRecord::Base
scope :active, -> { where(:status => %w[active confirmed]) }
scope :identifiable, -> { where(:data_public => true) }
has_one_attached :avatar
has_attached_file :image,
:default_url => "/assets/:class/:attachment/:style.png",
:styles => { :large => "100x100>", :small => "50x50>" }
@ -267,6 +269,8 @@ class User < ActiveRecord::Base
##
# delete a user - leave the account but purge most personal data
def delete
avatar.purge
self.display_name = "user_#{id}"
self.description = ""
self.home_lat = nil
@ -277,6 +281,7 @@ class User < ActiveRecord::Base
self.auth_provider = nil
self.auth_uid = nil
self.status = "deleted"
save
end

View file

@ -8,7 +8,7 @@ xml.tag! "user", :id => user.id,
else
xml.tag! "contributor-terms", :agreed => user.terms_agreed.present?
end
xml.tag! "img", :href => user_image_url(user) if user.image.file? || user.image_use_gravatar
xml.tag! "img", :href => user_image_url(user) if user.avatar.attached? || user.image.file? || user.image_use_gravatar
xml.tag! "roles" do
user.roles.each do |role|
xml.tag! role.role

View file

@ -104,40 +104,40 @@
<label class="standard-label"><%= t ".image" %></label>
<%= user_image current_user %>
<ul class='form-list accountImage-options'>
<% if current_user.image.file? %>
<% if current_user.avatar.attached? || current_user.image.file? %>
<li>
<%= radio_button_tag "image_action", "keep", !current_user.image_use_gravatar %>
<label class='standard-label' for='image_action_keep'><%= t ".keep image" %></label>
<%= radio_button_tag "avatar_action", "keep", !current_user.image_use_gravatar %>
<label class='standard-label' for='avatar_action_keep'><%= t ".keep image" %></label>
</li>
<% end %>
<% if current_user.image.file? || current_user.image_use_gravatar? %>
<% if current_user.avatar.attached? || current_user.image.file? || current_user.image_use_gravatar? %>
<li>
<%= radio_button_tag "image_action", "delete" %>
<label class='standard-label' for='image_action_delete'><%= t ".delete image" %></label>
<%= radio_button_tag "avatar_action", "delete" %>
<label class='standard-label' for='avatar_action_delete'><%= t ".delete image" %></label>
</li>
<% end %>
<% if current_user.image.file? %>
<% if current_user.avatar.attached? || current_user.image.file? %>
<li>
<%= radio_button_tag "image_action", "new" %>
<label class='standard-label' for='image_action_new'>
<%= radio_button_tag "avatar_action", "new" %>
<label class='standard-label' for='avatar_action_new'>
<%= t ".replace image" %>
<span class="form-help deemphasize"><%= t ".image size hint" %></span>
</label>
<%= f.file_field :image %>
<%= f.file_field :avatar %>
</li>
<% else %>
<li>
<%= radio_button_tag "image_action", "new" %>
<label class='standard-label' for='image_action_new'>
<%= radio_button_tag "avatar_action", "new" %>
<label class='standard-label' for='avatar_action_new'>
<%= t ".new image" %>
<span class="form-help deemphasize"><%= t ".image size hint" %></span>
</label>
<%= f.file_field :image %>
<%= f.file_field :avatar %>
</li>
<% end %>
<li>
<%= radio_button_tag "image_action", "gravatar", current_user.image_use_gravatar %>
<label class='standard-label' for='image_action_gravatar'>
<%= radio_button_tag "avatar_action", "gravatar", current_user.image_use_gravatar %>
<label class='standard-label' for='avatar_action_gravatar'>
<%= t ".gravatar.gravatar" %>
<span class='form-help deemphasize'> (<a href="<%= t ".gravatar.link" %>" target="_new"><%= t ".gravatar.link text" %></a>)</span>
</label>

1
config/.gitignore vendored
View file

@ -1 +1,2 @@
database.yml
storage.yml

View file

@ -39,7 +39,7 @@ Rails.application.configure do
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Store uploaded files on the local file system (see config/storage.yml for options)
config.active_storage.service = :local
config.active_storage.service = Settings.storage_service.to_symbol
# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil

View file

@ -0,0 +1,7 @@
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>

View file

@ -0,0 +1,31 @@
Rails.configuration.after_initialize do
require "active_storage/service/s3_service"
require_dependency "active_storage/variant"
module OpenStreetMap
module ActiveStorage
module Variant
private
def upload(image)
File.open(image.path, "r") { |file| service.upload(key, file, :content_type => content_type) }
end
end
module S3Service
def upload(key, io, content_type:, **options)
@upload_options[:content_type] = content_type
super(key, io, **options)
@upload_options.delete(:content_type)
end
end
end
end
ActiveStorage::Variant.prepend(OpenStreetMap::ActiveStorage::Variant)
ActiveStorage::Service::S3Service.prepend(OpenStreetMap::ActiveStorage::S3Service)
ActiveSupport::Reloader.to_complete do
ActiveStorage::Variant.prepend(OpenStreetMap::ActiveStorage::Variant)
end
end

View file

@ -77,5 +77,6 @@ Config.setup do |config|
required(:api_timeout).filled(:int?)
required(:imagery_blacklist).maybe(:array?)
required(:status).filled(:str?, :included_in? => ALLOWED_STATUS)
required(:storage_service).filled(:str?)
end
end

View file

@ -21,6 +21,9 @@ csp_policy = {
csp_policy[:connect_src] << PIWIK["location"] if defined?(PIWIK)
csp_policy[:img_src] << PIWIK["location"] if defined?(PIWIK)
csp_policy[:script_src] << PIWIK["location"] if defined?(PIWIK)
csp_policy[:img_src] << Settings.storage_url if Settings.key?(:storage_url)
csp_policy[:report_uri] << Settings.csp_report_url if Settings.key?(:csp_report_url)
cookie_policy = {

View file

@ -122,3 +122,7 @@ fossgis_osrm_url: "https://routing.openstreetmap.de/"
csp_enforce: false
# URL for reporting Content-Security-Policy violations
#csp_report_url: ""
# Storage service to use in production mode
storage_service: "local"
# Root URL for storage service
# storage_url:

View file

@ -1,34 +0,0 @@
test:
service: Disk
root: <%= Rails.root.join("tmp/storage") %>
local:
service: Disk
root: <%= Rails.root.join("storage") %>
# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key)
# amazon:
# service: S3
# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %>
# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %>
# region: us-east-1
# bucket: your_own_bucket
# Remember not to checkin your GCS keyfile to a repository
# google:
# service: GCS
# project: your_project
# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %>
# bucket: your_own_bucket
# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key)
# microsoft:
# service: AzureStorage
# storage_account_name: your_account_name
# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %>
# container: your_container_name
# mirror:
# service: Mirror
# primary: local
# mirrors: [ amazon, google, microsoft ]

View file

@ -0,0 +1,27 @@
# This migration comes from active_storage (originally 20170806125915)
class CreateActiveStorageTables < ActiveRecord::Migration[5.2]
def change
create_table :active_storage_blobs do |t|
t.string :key, :null => false
t.string :filename, :null => false
t.string :content_type
t.text :metadata
t.bigint :byte_size, :null => false
t.string :checksum, :null => false
t.datetime :created_at, :null => false
t.index [:key], :unique => true
end
create_table :active_storage_attachments do |t|
t.string :name, :null => false
t.references :record, :null => false, :polymorphic => true, :index => false
t.references :blob, :null => false
t.datetime :created_at, :null => false
t.index [:record_type, :record_id, :name, :blob_id], :name => "index_active_storage_attachments_uniqueness", :unique => true
t.foreign_key :active_storage_blobs, :column => :blob_id
end
end
end

View file

@ -192,6 +192,74 @@ CREATE SEQUENCE public.acls_id_seq
ALTER SEQUENCE public.acls_id_seq OWNED BY public.acls.id;
--
-- Name: active_storage_attachments; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.active_storage_attachments (
id bigint NOT NULL,
name character varying NOT NULL,
record_type character varying NOT NULL,
record_id bigint NOT NULL,
blob_id bigint NOT NULL,
created_at timestamp without time zone NOT NULL
);
--
-- Name: active_storage_attachments_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.active_storage_attachments_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: active_storage_attachments_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.active_storage_attachments_id_seq OWNED BY public.active_storage_attachments.id;
--
-- Name: active_storage_blobs; Type: TABLE; Schema: public; Owner: -
--
CREATE TABLE public.active_storage_blobs (
id bigint NOT NULL,
key character varying NOT NULL,
filename character varying NOT NULL,
content_type character varying,
metadata text,
byte_size bigint NOT NULL,
checksum character varying NOT NULL,
created_at timestamp without time zone NOT NULL
);
--
-- Name: active_storage_blobs_id_seq; Type: SEQUENCE; Schema: public; Owner: -
--
CREATE SEQUENCE public.active_storage_blobs_id_seq
START WITH 1
INCREMENT BY 1
NO MINVALUE
NO MAXVALUE
CACHE 1;
--
-- Name: active_storage_blobs_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
--
ALTER SEQUENCE public.active_storage_blobs_id_seq OWNED BY public.active_storage_blobs.id;
--
-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -
--
@ -1363,6 +1431,20 @@ CREATE TABLE public.ways (
ALTER TABLE ONLY public.acls ALTER COLUMN id SET DEFAULT nextval('public.acls_id_seq'::regclass);
--
-- Name: active_storage_attachments id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.active_storage_attachments ALTER COLUMN id SET DEFAULT nextval('public.active_storage_attachments_id_seq'::regclass);
--
-- Name: active_storage_blobs id; Type: DEFAULT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.active_storage_blobs ALTER COLUMN id SET DEFAULT nextval('public.active_storage_blobs_id_seq'::regclass);
--
-- Name: changeset_comments id; Type: DEFAULT; Schema: public; Owner: -
--
@ -1546,6 +1628,22 @@ ALTER TABLE ONLY public.acls
ADD CONSTRAINT acls_pkey PRIMARY KEY (id);
--
-- Name: active_storage_attachments active_storage_attachments_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.active_storage_attachments
ADD CONSTRAINT active_storage_attachments_pkey PRIMARY KEY (id);
--
-- Name: active_storage_blobs active_storage_blobs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.active_storage_blobs
ADD CONSTRAINT active_storage_blobs_pkey PRIMARY KEY (id);
--
-- Name: ar_internal_metadata ar_internal_metadata_pkey; Type: CONSTRAINT; Schema: public; Owner: -
--
@ -2086,6 +2184,27 @@ CREATE INDEX index_acls_on_domain ON public.acls USING btree (domain);
CREATE INDEX index_acls_on_mx ON public.acls USING btree (mx);
--
-- Name: index_active_storage_attachments_on_blob_id; Type: INDEX; Schema: public; Owner: -
--
CREATE INDEX index_active_storage_attachments_on_blob_id ON public.active_storage_attachments USING btree (blob_id);
--
-- Name: index_active_storage_attachments_uniqueness; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX index_active_storage_attachments_uniqueness ON public.active_storage_attachments USING btree (record_type, record_id, name, blob_id);
--
-- Name: index_active_storage_blobs_on_key; Type: INDEX; Schema: public; Owner: -
--
CREATE UNIQUE INDEX index_active_storage_blobs_on_key ON public.active_storage_blobs USING btree (key);
--
-- Name: index_changeset_comments_on_created_at; Type: INDEX; Schema: public; Owner: -
--
@ -2598,6 +2717,14 @@ ALTER TABLE ONLY public.diary_entry_subscriptions
ADD CONSTRAINT diary_entry_subscriptions_user_id_fkey FOREIGN KEY (user_id) REFERENCES public.users(id);
--
-- Name: active_storage_attachments fk_rails_c3b3935057; Type: FK CONSTRAINT; Schema: public; Owner: -
--
ALTER TABLE ONLY public.active_storage_attachments
ADD CONSTRAINT fk_rails_c3b3935057 FOREIGN KEY (blob_id) REFERENCES public.active_storage_blobs(id);
--
-- Name: friends friends_friend_user_id_fkey; Type: FK CONSTRAINT; Schema: public; Owner: -
--
@ -2958,6 +3085,7 @@ INSERT INTO "schema_migrations" (version) VALUES
('20181031113522'),
('20190518115041'),
('20190623093642'),
('20190702193519'),
('21'),
('22'),
('23'),

View file

@ -876,28 +876,28 @@ class UsersControllerTest < ActionController::TestCase
# Changing to an uploaded image should work
image = Rack::Test::UploadedFile.new("test/gpx/fixtures/a.gif", "image/gif")
post :account, :params => { :display_name => user.display_name, :image_action => "new", :user => user.attributes.merge(:image => image) }, :session => { :user => user }
post :account, :params => { :display_name => user.display_name, :avatar_action => "new", :user => user.attributes.merge(:avatar => image) }, :session => { :user => user }
assert_response :success
assert_template :account
assert_select "div#errorExplanation", false
assert_select ".notice", /^User information updated successfully/
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=image_action][checked][value=?]", "keep"
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=avatar_action][checked][value=?]", "keep"
# Changing to a gravatar image should work
post :account, :params => { :display_name => user.display_name, :image_action => "gravatar", :user => user.attributes }, :session => { :user => user }
post :account, :params => { :display_name => user.display_name, :avatar_action => "gravatar", :user => user.attributes }, :session => { :user => user }
assert_response :success
assert_template :account
assert_select "div#errorExplanation", false
assert_select ".notice", /^User information updated successfully/
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=image_action][checked][value=?]", "gravatar"
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=avatar_action][checked][value=?]", "gravatar"
# Removing the image should work
post :account, :params => { :display_name => user.display_name, :image_action => "delete", :user => user.attributes }, :session => { :user => user }
post :account, :params => { :display_name => user.display_name, :avatar_action => "delete", :user => user.attributes }, :session => { :user => user }
assert_response :success
assert_template :account
assert_select "div#errorExplanation", false
assert_select ".notice", /^User information updated successfully/
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=image_action][checked]", false
assert_select "form#accountForm > fieldset > div.form-row.accountImage input[name=avatar_action][checked]", false
# Adding external authentication should redirect to the auth provider
post :account, :params => { :display_name => user.display_name, :user => user.attributes.merge(:auth_provider => "openid", :auth_uid => "gmail.com") }, :session => { :user => user }

View file

@ -8,10 +8,10 @@ class UserHelperTest < ActionView::TestCase
gravatar_user = create(:user, :image_use_gravatar => true)
image = user_image(user)
assert_match %r{^<img class="user_image" .* src="/assets/users/images/large-.*" />$}, image
assert_match %r{^<img class="user_image" .* src="/images/avatar_large.png" />$}, image
image = user_image(user, :class => "foo")
assert_match %r{^<img class="foo" .* src="/assets/users/images/large-.*" />$}, image
assert_match %r{^<img class="foo" .* src="/images/avatar_large.png" />$}, image
image = user_image(gravatar_user)
assert_match %r{^<img class="user_image" .* src="http://www.gravatar.com/avatar/.*" />$}, image
@ -25,10 +25,10 @@ class UserHelperTest < ActionView::TestCase
gravatar_user = create(:user, :image_use_gravatar => true)
image = user_thumbnail(user)
assert_match %r{^<img class="user_thumbnail" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="user_thumbnail" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail(user, :class => "foo")
assert_match %r{^<img class="foo" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="foo" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail(gravatar_user)
assert_match %r{^<img class="user_thumbnail" .* src="http://www.gravatar.com/avatar/.*" />$}, image
@ -42,10 +42,10 @@ class UserHelperTest < ActionView::TestCase
gravatar_user = create(:user, :image_use_gravatar => true)
image = user_thumbnail_tiny(user)
assert_match %r{^<img class="user_thumbnail_tiny" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="user_thumbnail_tiny" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail_tiny(user, :class => "foo")
assert_match %r{^<img class="foo" .* src="/assets/users/images/small-.*" />$}, image
assert_match %r{^<img class="foo" .* src="/images/avatar_small.png" />$}, image
image = user_thumbnail_tiny(gravatar_user)
assert_match %r{^<img class="user_thumbnail_tiny" .* src="http://www.gravatar.com/avatar/.*" />$}, image