API: don't return default avatar

This commit is contained in:
Jonne Haß 2019-04-27 20:02:10 +02:00 committed by Jonne Haß
parent 214c2d7af7
commit 16e754f4c7
27 changed files with 137 additions and 85 deletions

View file

@ -18,7 +18,7 @@ Metrics/LineLength:
# Too short methods lead to extraction of single-use methods, which can make
# the code easier to read (by naming things), but can also clutter the class
Metrics/MethodLength:
Metrics/MethodLength:
Max: 20
# The guiding principle of classes is SRP, SRP can't be accurately measured by LoC
@ -26,11 +26,17 @@ Metrics/ClassLength:
Max: 1500
Metrics/ModuleLength:
Max: 1500
# Raise AbcSize from 15 to 20
# Raise complexity metrics
Metrics/AbcSize:
Max: 20
Metrics/CyclomaticComplexity:
Max: 20
Metrics/PerceivedComplexity:
Max: 20
# Some blocks are longer.
Metrics/BlockLength:
ExcludedMethods:
@ -88,7 +94,7 @@ Lint/AssignmentInCondition:
AllowSafeAssignment: false
# A specialized exception class will take one or more arguments and construct the message from it.
# So both variants make sense.
# So both variants make sense.
Style/RaiseArgs:
Enabled: false
@ -151,11 +157,11 @@ Lint/ShadowingOuterLocalVariable:
# Check with yard instead.
Style/Documentation:
Enabled: false
Enabled: false
# This is just silly. Calling the argument `other` in all cases makes no sense.
Naming/BinaryOperatorParameterName:
Enabled: false
Enabled: false
# There are valid cases, for example debugging Cucumber steps,
# also they'll fail CI anyway

View file

@ -35,8 +35,8 @@ module PeopleHelper
def person_image_tag(person, size = :thumb_small)
return "" if person.nil? || person.profile.nil?
image_tag(person.profile.image_url(size), alt: person.name, class: "avatar img-responsive center-block",
title: person.name, "data-person_id" => person.id)
image_tag(person.profile.image_url(size: size), alt: person.name, class: "avatar img-responsive center-block",
title: person.name, "data-person_id": person.id)
end
def person_image_link(person, opts={})

View file

@ -17,10 +17,10 @@ class Person < ApplicationRecord
person.diaspora_handle
}, :as => :diaspora_id
t.add lambda { |person|
{:small => person.profile.image_url(:thumb_small),
:medium => person.profile.image_url(:thumb_medium),
:large => person.profile.image_url(:thumb_large) }
}, :as => :avatar
{small: person.profile.image_url(size: :thumb_small),
medium: person.profile.image_url(size: :thumb_medium),
large: person.profile.image_url(size: :thumb_large)}
}, as: :avatar
end
has_one :profile, dependent: :destroy
@ -346,7 +346,7 @@ class Person < ApplicationRecord
id: id,
guid: guid,
name: name,
avatar: profile.image_url(:thumb_small),
avatar: profile.image_url(size: :thumb_small),
handle: diaspora_handle,
url: Rails.application.routes.url_helpers.person_path(self)
}

View file

@ -52,7 +52,7 @@ class Profile < ApplicationRecord
(self.person) ? self.person.diaspora_handle : self[:diaspora_handle]
end
def image_url(size=:thumb_large)
def image_url(size: :thumb_large, fallback_to_default: true)
result = if size == :thumb_medium && self[:image_url_medium]
self[:image_url_medium]
elsif size == :thumb_small && self[:image_url_small]
@ -67,7 +67,7 @@ class Profile < ApplicationRecord
else
result
end
else
elsif fallback_to_default
ActionController::Base.helpers.image_path("user/default.png")
end
end

View file

@ -2,25 +2,25 @@
# frozen_string_literal: true
class AvatarPresenter < BasePresenter
DEFAULT_IMAGE = ActionController::Base.helpers.image_path("user/default.png")
def base_hash(with_default=false)
avatar = {
small: small(with_default),
medium: medium(with_default),
large: large(with_default)
}.compact
def base_hash
{
small: small,
medium: medium,
large: large
}
avatar unless avatar.empty?
end
def small
image_url(:thumb_small) || DEFAULT_IMAGE
def small(with_default=false)
image_url(size: :thumb_small, fallback_to_default: with_default)
end
def medium
image_url(:thumb_medium) || DEFAULT_IMAGE
def medium(with_default=false)
image_url(size: :thumb_medium, fallback_to_default: with_default)
end
def large
image_url || DEFAULT_IMAGE
def large(with_default=false)
image_url(fallback_to_default: with_default)
end
end

View file

@ -16,7 +16,7 @@ class PersonPresenter < BasePresenter
diaspora_id: diaspora_handle,
name: name,
avatar: AvatarPresenter.new(@presentable).medium
}
}.compact
end
def full_hash

View file

@ -12,7 +12,7 @@ class ProfilePresenter < BasePresenter
def public_hash
base_hash.merge(
avatar: AvatarPresenter.new(@presentable).base_hash,
avatar: AvatarPresenter.new(@presentable).base_hash(true),
tags: tags.pluck(:name)
)
end
@ -60,7 +60,7 @@ class ProfilePresenter < BasePresenter
diaspora_id: diaspora_handle,
avatar: AvatarPresenter.new(@presentable).base_hash,
tags: tags.pluck(:name)
}
}.compact
end
def added_details_api_json

View file

@ -4,7 +4,7 @@
- if @notification.try(:sender)
%td{width: "60px", style: "vertical-align: top"}>
%div{style: "background-color: #eee; height: 50px; width: 50px"}
= image_tag @notification.sender.profile.image_url(:thumb_small), alt: @notification.sender.name,
= image_tag @notification.sender.profile.image_url(size: :thumb_small), alt: @notification.sender.name,
style: "border: 0, display: block; top: 0; left: 0", height: "50px", width: "50px"
%td{style: "vertical-align: top"}
!= yield

View file

@ -13,7 +13,7 @@ atom_feed("xmlns:thr" => "http://purl.org/syndication/thread/1.0",
feed.tag! :generator, 'Diaspora', :uri => "#{AppConfig.pod_uri.to_s}"
feed.title "#{@user.name}'s Public Feed"
feed.subtitle "Updates from #{@user.name} on #{AppConfig.settings.pod_name}"
feed.logo "#{@user.image_url(:thumb_small)}"
feed.logo @user.image_url(size: :thumb_small)
feed.updated @posts[0].created_at if @posts.length > 0
feed.tag! :link, :rel => 'avatar', :type => 'image/jpeg', 'media:width' => '100',
'media:height' => '100', :href => "#{@user.image_url}"

View file

@ -46,8 +46,8 @@ DiasporaFederation.configure do |config|
full_name: "#{person.profile.first_name} #{person.profile.last_name}".strip,
url: AppConfig.pod_uri,
photo_large_url: person.image_url,
photo_medium_url: person.image_url(:thumb_medium),
photo_small_url: person.image_url(:thumb_small),
photo_medium_url: person.image_url(size: :thumb_medium),
photo_small_url: person.image_url(size: :thumb_small),
public_key: person.serialized_public_key,
searchable: person.searchable,
first_name: person.profile.first_name,

View file

@ -33,13 +33,18 @@
"format": "date-time"
},
"url": {
"type": "string",
"pattern": "^https?://"
},
"short_profile": {
"type": "object",
"properties": {
"guid": { "$ref": "#/definitions/guid" },
"diaspora_id": { "type": "string" },
"name": { "type": "string" },
"avatar": { "type": "string" }
"avatar": { "$ref": "#/definitions/url" }
},
"required": ["guid", "diaspora_id", "name"],
"additionalProperties": false
@ -203,9 +208,9 @@
"photo_sizes": {
"type": "object",
"properties": {
"large": { "type": "string" },
"medium": { "type": "string" },
"small": { "type": "string" }
"large": { "$ref": "#/definitions/url" },
"medium": { "$ref": "#/definitions/url" },
"small": { "$ref": "#/definitions/url" }
},
"required": ["large", "medium", "small"],
"additionalProperties": true

View file

@ -72,11 +72,15 @@ FactoryGirl.define do
password "bluepin7"
password_confirmation { |u| u.password }
serialized_private_key OpenSSL::PKey::RSA.generate(1024).export
after(:build) do |u|
transient do
profile nil
end
after(:build) do |u, e|
u.person = FactoryGirl.build(:person,
pod: nil,
serialized_public_key: u.encryption_key.public_key.export,
diaspora_handle: "#{u.username}#{User.diaspora_id_host}")
u.person.profile = e.profile if e.profile
end
after(:create) do |u|
u.person.save

View file

@ -52,8 +52,8 @@ describe "diaspora federation callbacks" do
expect(hcard.full_name).to eq("#{person.profile.first_name} #{person.profile.last_name}")
expect(hcard.url).to eq(AppConfig.pod_uri)
expect(hcard.photo_large_url).to eq(person.image_url)
expect(hcard.photo_medium_url).to eq(person.image_url(:thumb_medium))
expect(hcard.photo_small_url).to eq(person.image_url(:thumb_small))
expect(hcard.photo_medium_url).to eq(person.image_url(size: :thumb_medium))
expect(hcard.photo_small_url).to eq(person.image_url(size: :thumb_small))
expect(hcard.public_key).to eq(person.serialized_public_key)
expect(hcard.searchable).to eq(person.searchable)
expect(hcard.first_name).to eq(person.profile.first_name)

View file

@ -6,7 +6,8 @@ describe Api::V1::CommentsController do
let(:auth) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid public:read public:modify private:read interactions]
scopes: %w[openid public:read public:modify private:read interactions],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -21,12 +22,15 @@ describe Api::V1::CommentsController do
FactoryGirl.create(:auth_with_default_scopes)
}
let!(:access_token) { auth.create_access_token.to_s }
let!(:access_token) { auth.created_at_access_token.to_s }
let!(:access_token_public_only) { auth_public_only.create_access_token.to_s }
let!(:access_token_minimum_scopes) { auth_minimum_scopes.create_access_token.to_s }
let(:invalid_token) { SecureRandom.hex(9) }
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
eve.person.profile = FactoryGirl.create(:profile_with_image_url)
@status = alice.post(
"Post",
status_message: {text: "This is a status message"},
@ -446,7 +450,7 @@ describe Api::V1::CommentsController do
expect(author["guid"]).to eq(user.guid)
expect(author["diaspora_id"]).to eq(user.diaspora_handle)
expect(author["name"]).to eq(user.name)
expect(author["avatar"]).to eq(user.profile.image_url)
expect(author["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
# rubocop:enable Metrics/AbcSize
end

View file

@ -31,6 +31,7 @@ describe Api::V1::ContactsController do
auth.user.share_with(eve.person, @aspect1)
@aspect2 = auth.user.aspects.create(name: "another aspect")
@eve_aspect = eve.aspects.first
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
end
describe "#show" do
@ -263,7 +264,7 @@ describe Api::V1::ContactsController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
# rubocop:enable Metrics/AbcSize
end

View file

@ -6,7 +6,8 @@ describe Api::V1::ConversationsController do
let(:auth) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid conversations]
scopes: %w[openid conversations],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -24,6 +25,8 @@ describe Api::V1::ConversationsController do
let(:invalid_token) { SecureRandom.hex(9) }
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
auth.user.aspects.create(name: "first")
auth.user.share_with(alice.person, auth.user.aspects[0])
alice.share_with(auth.user.person, alice.aspects[0])
@ -390,7 +393,7 @@ describe Api::V1::ConversationsController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
# rubocop:enable Metrics/AbcSize
end

View file

@ -6,7 +6,8 @@ describe Api::V1::LikesController do
let(:auth) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid public:read public:modify private:read private:modify interactions]
scopes: %w[openid public:read public:modify private:read private:modify interactions],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -27,6 +28,9 @@ describe Api::V1::LikesController do
let(:invalid_token) { SecureRandom.hex(9) }
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
bob.person.profile = FactoryGirl.create(:profile_with_image_url)
@status = auth.user.post(
:status_message,
text: "This is a status message",
@ -263,7 +267,7 @@ describe Api::V1::LikesController do
author = like["author"]
expect(author["diaspora_id"]).to eq(user.diaspora_handle)
expect(author["name"]).to eq(user.name)
expect(author["avatar"]).to eq(user.profile.image_url)
expect(author["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
# rubocop:enable Metrics/AbcSize

View file

@ -6,7 +6,8 @@ describe Api::V1::MessagesController do
let(:auth) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid conversations]
scopes: %w[openid conversations],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -181,7 +182,7 @@ describe Api::V1::MessagesController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
# rubocop:enable Metrics/AbcSize
end

View file

@ -6,7 +6,8 @@ describe Api::V1::PostsController do
let(:auth) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid public:read public:modify private:read private:modify]
scopes: %w[openid public:read public:modify private:read private:modify],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -40,6 +41,10 @@ describe Api::V1::PostsController do
let(:invalid_token) { SecureRandom.hex(9) }
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
bob.person.profile = FactoryGirl.create(:profile_with_image_url)
eve.person.profile = FactoryGirl.create(:profile_with_image_url)
@alice_aspect = alice.aspects.first
@alice_photo1 = alice.post(:photo, pending: true, user_file: File.open(photo_fixture_name), to: @alice_aspect.id)
@alice_photo2 = alice.post(:photo, pending: true, user_file: File.open(photo_fixture_name), to: @alice_aspect.id)
@ -702,7 +707,7 @@ describe Api::V1::PostsController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
def confirm_poll(post_poll, ref_poll, expected_participation)

View file

@ -21,6 +21,8 @@ describe Api::V1::ResharesController do
let(:invalid_token) { SecureRandom.hex(9) }
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
@user_post = auth.user.post(
:status_message,
text: "This is a status message",
@ -226,7 +228,7 @@ describe Api::V1::ResharesController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
# rubocop:enable Metrics/AbcSize
end

View file

@ -6,21 +6,24 @@ describe Api::V1::StreamsController do
let(:auth_read_only) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid public:read private:read contacts:read tags:read]
scopes: %w[openid public:read private:read contacts:read tags:read],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
let(:auth_public_only_tags) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid public:read tags:read]
scopes: %w[openid public:read tags:read],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
let(:auth_public_only_read_only) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: %w[openid public:read]
scopes: %w[openid public:read],
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -425,7 +428,7 @@ describe Api::V1::StreamsController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
def confirm_poll(post_poll, ref_poll, expected_participation)

View file

@ -12,7 +12,8 @@ describe Api::V1::UsersController do
let(:auth) {
FactoryGirl.create(
:auth_with_default_scopes,
scopes: full_scopes
scopes: full_scopes,
user: FactoryGirl.create(:user, profile: FactoryGirl.create(:profile_with_image_url))
)
}
@ -47,6 +48,10 @@ describe Api::V1::UsersController do
let!(:access_token_minimum_scopes) { auth_minimum_scopes.create_access_token.to_s }
let(:invalid_token) { SecureRandom.hex(9) }
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
end
describe "#show" do
context "Current User" do
it "succeeds when logged in" do
@ -105,6 +110,7 @@ describe Api::V1::UsersController do
end
it "succeeds with limited data on non-public/not shared" do
eve.person.profile = FactoryGirl.create(:profile_with_image_url)
eve.profile[:public_details] = false
eve.profile.save
get(
@ -582,7 +588,7 @@ describe Api::V1::UsersController do
expect(post_person["guid"]).to eq(user.guid)
expect(post_person["diaspora_id"]).to eq(user.diaspora_handle)
expect(post_person["name"]).to eq(user.name)
expect(post_person["avatar"]).to eq(user.profile.image_url)
expect(post_person["avatar"]).to eq(user.profile.image_url(size: :thumb_medium))
end
def confirm_photos(photos)

View file

@ -657,14 +657,14 @@ describe Person, :type => :model do
describe '#as_json' do
it 'returns a hash representation of a person' do
expect(@person.as_json).to eq({
:id => @person.id,
:guid => @person.guid,
:name => @person.name,
:avatar => @person.profile.image_url(:thumb_medium),
:handle => @person.diaspora_handle,
:url => Rails.application.routes.url_helpers.person_path(@person),
})
expect(@person.as_json).to eq(
id: @person.id,
guid: @person.guid,
name: @person.name,
avatar: @person.profile.image_url(size: :thumb_medium),
handle: @person.diaspora_handle,
url: Rails.application.routes.url_helpers.person_path(@person)
)
end
it 'return tags if asked' do
expect(@person.as_json(:includes => "tags")).

View file

@ -176,8 +176,8 @@ describe Profile, :type => :model do
@profile[:image_url] = 'large'
@profile[:image_url_small] = nil
@profile[:image_url_medium] = nil
expect(@profile.image_url(:thumb_small)).to eq('large')
expect(@profile.image_url(:thumb_medium)).to eq('large')
expect(@profile.image_url(size: :thumb_small)).to eq("large")
expect(@profile.image_url(size: :thumb_medium)).to eq("large")
end
end

View file

@ -3,19 +3,16 @@
describe AvatarPresenter do
describe "#base_hash" do
it "calls image_url() for the avatars" do
@profile = FactoryGirl.create(:profile_with_image_url, person: alice.person)
@presenter = AvatarPresenter.new(@profile)
expect(@profile).to receive(:image_url).exactly(3).times
expect(@presenter.base_hash).to be_present
profile = FactoryGirl.create(:profile_with_image_url, person: alice.person)
presenter = AvatarPresenter.new(profile)
expect(profile).to receive(:image_url).exactly(3).times.and_call_original
expect(presenter.base_hash).to be_present
end
it "returns the default images if no images set" do
@profile = FactoryGirl.create(:profile, person: alice.person)
@presenter = AvatarPresenter.new(@profile)
expect(@presenter.base_hash.keys).to eq(%i[small medium large])
expect(@presenter.base_hash[:small]).to match(%r{/assets/user/default-[0-9a-f]{64}\.png})
expect(@presenter.base_hash[:medium]).to match(%r{/assets/user/default-[0-9a-f]{64}\.png})
expect(@presenter.base_hash[:large]).to match(%r{/assets/user/default-[0-9a-f]{64}\.png})
it "returns nothing if no images set" do
profile = FactoryGirl.create(:profile, person: alice.person)
presenter = AvatarPresenter.new(profile)
expect(presenter.base_hash).to be_nil
end
end
end

View file

@ -2,6 +2,7 @@
describe LikesPresenter do
before do
bob.person.profile = FactoryGirl.create(:profile_with_image_url)
@status = alice.post(
:status_message,
text: "This is a status message from alice",
@ -26,7 +27,7 @@ describe LikesPresenter do
expect(author).to include(guid: bob.guid)
expect(author).to include(diaspora_id: bob.diaspora_handle)
expect(author).to include(name: bob.name)
expect(author).to include(avatar: bob.profile.image_url)
expect(author).to include(avatar: bob.profile.image_url(size: :thumb_medium))
end
end
end

View file

@ -1,7 +1,10 @@
# frozen_string_literal: true
describe PersonPresenter do
let(:profile_user) { FactoryGirl.create(:user_with_aspect) }
let(:profile_user) {
FactoryGirl.create(:user_with_aspect,
profile: FactoryGirl.create(:profile_with_image_url))
}
let(:person) { profile_user.person }
let(:mutual_contact) {
@ -144,7 +147,14 @@ describe PersonPresenter do
end
describe "#profile_hash_as_api_json" do
let(:current_user) { FactoryGirl.create(:user) }
let(:current_user) {
FactoryGirl.create(:user,
profile: FactoryGirl.create(:profile_with_image_url))
}
before do
alice.person.profile = FactoryGirl.create(:profile_with_image_url)
end
it "contains internal profile if self" do
profile_hash = PersonPresenter.new(current_user.person, current_user).profile_hash_as_api_json