mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-23 23:58:31 -05:00
FEATURE: Profile Backgrounds
Shares a modified codebase with avatars called "user_image"
This commit is contained in:
parent
5e1019adba
commit
98c479c3c4
17 changed files with 292 additions and 39 deletions
|
@ -60,7 +60,20 @@ Discourse.User = Discourse.Model.extend({
|
|||
|
||||
return this.get('website').split("/")[2];
|
||||
}.property('website'),
|
||||
|
||||
/**
|
||||
This user's profile background(in CSS).
|
||||
|
||||
@property websiteName
|
||||
@type {String}
|
||||
**/
|
||||
profileBackground: function() {
|
||||
var background = this.get('profile_background');
|
||||
if(Em.isEmpty(background) || !Discourse.SiteSettings.allow_profile_backgrounds) { return; }
|
||||
|
||||
return 'background-image: url(' + background + ')';
|
||||
}.property('profile_background'),
|
||||
|
||||
statusIcon: function() {
|
||||
var desc;
|
||||
if(this.get('admin')) {
|
||||
|
@ -316,6 +329,22 @@ Discourse.User = Discourse.Model.extend({
|
|||
data: { use_uploaded_avatar: useUploadedAvatar }
|
||||
});
|
||||
},
|
||||
|
||||
/*
|
||||
Clear profile background
|
||||
|
||||
@method clearProfileBackground
|
||||
@returns {Promise} the result of the clear profile background request
|
||||
*/
|
||||
clearProfileBackground: function() {
|
||||
var user = this;
|
||||
return Discourse.ajax("/users/" + this.get("username_lower") + "/preferences/profile_background/clear", {
|
||||
type: 'PUT',
|
||||
data: { }
|
||||
}).then(function() {
|
||||
user.set('profile_background', null);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Determines whether the current user is allowed to upload a file.
|
||||
|
|
|
@ -43,6 +43,13 @@ Discourse.PreferencesRoute = Discourse.RestrictedUserRoute.extend({
|
|||
));
|
||||
user.set('avatar_template', avatarSelector.get('avatarTemplate'));
|
||||
avatarSelector.send('closeModal');
|
||||
},
|
||||
|
||||
showProfileBackgroundFileSelector: function() {
|
||||
$("#profile-background-input").click();
|
||||
},
|
||||
clearProfileBackground: function() {
|
||||
this.modelFor('user').clearProfileBackground();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
@ -73,6 +73,26 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{#if Discourse.SiteSettings.allow_profile_backgrounds}}
|
||||
<div class="control-group">
|
||||
<label class="control-label">{{i18n user.change_profile_background.title}}</label>
|
||||
<div class="controls">
|
||||
<input type="file" id="profile-background-input" accept="image/*" style="display:none" />
|
||||
<div id="profile-background-preview" class="input-xxlarge" {{bind-attr style="profileBackground"}}>
|
||||
<div id="profile-background-controls">
|
||||
<button {{action showProfileBackgroundFileSelector}} class="btn pad-left no-text"><i class="fa fa-picture-o"></i></button>
|
||||
{{#if profileBackground}}
|
||||
<button {{action clearProfileBackground}} class="btn btn-danger pad-left no-text"><i class="fa fa-trash-o"></i></button>
|
||||
{{/if}}
|
||||
{{#if view.uploading}}
|
||||
<span class="btn">{{i18n upload_selector.uploading}} {{view.uploadProgress}}%</span>
|
||||
{{/if}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if allowUserLocale}}
|
||||
<div class="control-group">
|
||||
|
|
|
@ -40,7 +40,7 @@
|
|||
</section>
|
||||
|
||||
<section class='user-main'>
|
||||
<section {{bind-attr class="collapsedInfo :about"}}>
|
||||
<section {{bind-attr class="collapsedInfo :about"}} {{bind-attr style="profileBackground"}}>
|
||||
|
||||
<div class='details'>
|
||||
<div class='primary'>
|
||||
|
|
|
@ -33,9 +33,10 @@ Discourse.AvatarSelectorView = Discourse.ModalBodyView.extend({
|
|||
|
||||
// define the upload endpoint
|
||||
$upload.fileupload({
|
||||
url: Discourse.getURL("/users/" + this.get("controller.username") + "/preferences/avatar"),
|
||||
url: Discourse.getURL("/users/" + this.get("controller.username") + "/preferences/user_image"),
|
||||
dataType: "json",
|
||||
fileInput: $upload
|
||||
fileInput: $upload,
|
||||
formData: { user_image_type: "avatar" }
|
||||
});
|
||||
|
||||
// when a file has been selected
|
||||
|
|
|
@ -8,7 +8,48 @@
|
|||
**/
|
||||
Discourse.PreferencesView = Discourse.View.extend({
|
||||
templateName: 'user/preferences',
|
||||
classNames: ['user-preferences']
|
||||
classNames: ['user-preferences'],
|
||||
|
||||
uploading: false,
|
||||
uploadProgress: 0,
|
||||
|
||||
didInsertElement: function() {
|
||||
var self = this;
|
||||
var $upload = $("#profile-background-input");
|
||||
|
||||
this._super();
|
||||
|
||||
$upload.fileupload({
|
||||
url: Discourse.getURL("/users/" + this.get('controller.model.username') + "/preferences/user_image"),
|
||||
dataType: "json",
|
||||
fileInput: $upload,
|
||||
formData: { user_image_type: "profile_background" }
|
||||
});
|
||||
|
||||
$upload.on("fileuploadadd", function() {
|
||||
self.set("uploading", true);
|
||||
});
|
||||
$upload.on("fileuploadprogressall", function(e, data) {
|
||||
var progress = parseInt(data.loaded / data.total * 100, 10);
|
||||
self.set("uploadProgress", progress);
|
||||
});
|
||||
$upload.on("fileuploaddone", function(e, data) {
|
||||
if(data.result.url) {
|
||||
self.set("controller.model.profile_background", data.result.url);
|
||||
} else {
|
||||
bootbox.alert(I18n.t('post.errors.upload'));
|
||||
}
|
||||
});
|
||||
$upload.on("fileuploadfail", function(e, data) {
|
||||
Discourse.Utilities.displayErrorForUpload(data);
|
||||
});
|
||||
$upload.on("fileuploadalways", function() {
|
||||
self.setProperties({ uploading: false, uploadProgress: 0});
|
||||
});
|
||||
},
|
||||
willDestroyElement: function() {
|
||||
$("#profile-background-input").fileupload("destroy");
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
|
|
|
@ -40,6 +40,19 @@
|
|||
width: 440px;
|
||||
}
|
||||
}
|
||||
|
||||
#profile-background-preview {
|
||||
height: 270px;
|
||||
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
|
||||
background-color: $secondary_background_color;
|
||||
}
|
||||
|
||||
#profile-background-controls {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
.static {
|
||||
color: $primary_text_color;
|
||||
|
@ -174,6 +187,9 @@
|
|||
|
||||
.about {
|
||||
background-color: $secondary_background_color;
|
||||
background-size: cover;
|
||||
background-position: center center;
|
||||
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
color: $secondary_text_color;
|
||||
|
|
|
@ -64,6 +64,13 @@
|
|||
width: 100%;
|
||||
padding: 5px 8px;
|
||||
}
|
||||
|
||||
#profile-background-preview {
|
||||
height: 150px;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
background-color: $secondary_background_color;
|
||||
}
|
||||
}
|
||||
|
||||
#about-me {
|
||||
|
@ -120,6 +127,8 @@
|
|||
|
||||
.about {
|
||||
background-color: $secondary_background_color;
|
||||
background-position: center center;
|
||||
background-size: cover;
|
||||
margin-bottom: 10px;
|
||||
overflow: hidden;
|
||||
color: $primary_text_color;
|
||||
|
|
|
@ -7,7 +7,7 @@ class UsersController < ApplicationController
|
|||
skip_before_filter :authorize_mini_profiler, only: [:avatar]
|
||||
skip_before_filter :check_xhr, only: [:show, :password_reset, :update, :activate_account, :authorize_email, :user_preferences_redirect, :avatar]
|
||||
|
||||
before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_avatar, :toggle_avatar, :destroy]
|
||||
before_filter :ensure_logged_in, only: [:username, :update, :change_email, :user_preferences_redirect, :upload_user_image, :toggle_avatar, :clear_profile_background, :destroy]
|
||||
before_filter :respond_to_suspicious_request, only: [:create]
|
||||
|
||||
# we need to allow account creation with bad CSRF tokens, if people are caching, the CSRF token on the
|
||||
|
@ -297,8 +297,16 @@ class UsersController < ApplicationController
|
|||
size = 128 if size > 128
|
||||
size
|
||||
end
|
||||
|
||||
|
||||
def upload_avatar
|
||||
params[:user_image_type] = "avatar"
|
||||
|
||||
upload_user_image
|
||||
|
||||
end
|
||||
|
||||
def upload_user_image
|
||||
params.require(:user_image_type)
|
||||
user = fetch_user_from_params
|
||||
guardian.ensure_can_edit!(user)
|
||||
|
||||
|
@ -308,17 +316,26 @@ class UsersController < ApplicationController
|
|||
# TODO: Does not protect from huge uploads
|
||||
# https://github.com/discourse/discourse/pull/1512
|
||||
# check the file size (note: this might also be done in the web server)
|
||||
avatar = build_avatar_from(file)
|
||||
avatar_policy = AvatarUploadPolicy.new(avatar)
|
||||
img = build_user_image_from(file)
|
||||
upload_policy = AvatarUploadPolicy.new(img)
|
||||
|
||||
if avatar_policy.too_big?
|
||||
if upload_policy.too_big?
|
||||
return render status: 413, text: I18n.t("upload.images.too_large",
|
||||
max_size_kb: avatar_policy.max_size_kb)
|
||||
max_size_kb: upload_policy.max_size_kb)
|
||||
end
|
||||
|
||||
raise FastImage::UnknownImageType unless SiteSetting.authorized_image?(avatar.file)
|
||||
|
||||
upload_avatar_for(user, avatar)
|
||||
raise FastImage::UnknownImageType unless SiteSetting.authorized_image?(img.file)
|
||||
|
||||
upload_type = params[:user_image_type]
|
||||
|
||||
if upload_type == "avatar"
|
||||
upload_avatar_for(user, img)
|
||||
elsif upload_type == "profile_background"
|
||||
upload_profile_background_for(user, img)
|
||||
else
|
||||
render status: 422, text: ""
|
||||
end
|
||||
|
||||
|
||||
rescue Discourse::InvalidParameters
|
||||
render status: 422, text: I18n.t("upload.images.unknown_image_type")
|
||||
|
@ -340,7 +357,17 @@ class UsersController < ApplicationController
|
|||
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
|
||||
def clear_profile_background
|
||||
user = fetch_user_from_params
|
||||
guardian.ensure_can_edit!(user)
|
||||
|
||||
user.profile_background = ""
|
||||
user.save!
|
||||
|
||||
render nothing: true
|
||||
end
|
||||
|
||||
def destroy
|
||||
@user = fetch_user_from_params
|
||||
guardian.ensure_can_delete_user!(@user)
|
||||
|
@ -364,7 +391,7 @@ class UsersController < ApplicationController
|
|||
challenge
|
||||
end
|
||||
|
||||
def build_avatar_from(file)
|
||||
def build_user_image_from(file)
|
||||
source = if file.is_a?(String)
|
||||
is_api? ? :url : (raise FastImage::UnknownImageType)
|
||||
else
|
||||
|
@ -380,7 +407,17 @@ class UsersController < ApplicationController
|
|||
Jobs.enqueue(:generate_avatars, user_id: user.id, upload_id: upload.id)
|
||||
render json: { url: upload.url, width: upload.width, height: upload.height }
|
||||
end
|
||||
|
||||
|
||||
def upload_profile_background_for(user, background)
|
||||
upload = Upload.create_for(user.id, background.file, background.filesize)
|
||||
user.profile_background = upload.url
|
||||
user.save!
|
||||
|
||||
# TODO: maybe add a resize job here
|
||||
|
||||
render json: { url: upload.url, width: upload.width, height: upload.height }
|
||||
end
|
||||
|
||||
def respond_to_suspicious_request
|
||||
if suspicious?(params)
|
||||
render(
|
||||
|
|
|
@ -8,11 +8,13 @@ module Jobs
|
|||
|
||||
uploads_used_in_posts = PostUpload.uniq.pluck(:upload_id)
|
||||
uploads_used_as_avatars = User.uniq.where('uploaded_avatar_id IS NOT NULL').pluck(:uploaded_avatar_id)
|
||||
|
||||
uploads_used_as_profile_backgrounds = User.uniq.where("profile_background IS NOT NULL AND profile_background != ''").pluck(:profile_background)
|
||||
|
||||
grace_period = [SiteSetting.clean_orphan_uploads_grace_period_hours, 1].max
|
||||
|
||||
Upload.where("created_at < ?", grace_period.hour.ago)
|
||||
.where("id NOT IN (?)", uploads_used_in_posts + uploads_used_as_avatars)
|
||||
.where("url NOT IN (?)", uploads_used_as_profile_backgrounds)
|
||||
.find_each do |upload|
|
||||
upload.destroy
|
||||
end
|
||||
|
|
|
@ -8,6 +8,7 @@ class UserSerializer < BasicUserSerializer
|
|||
:bio_cooked,
|
||||
:created_at,
|
||||
:website,
|
||||
:profile_background,
|
||||
:can_edit,
|
||||
:can_edit_username,
|
||||
:can_edit_email,
|
||||
|
|
|
@ -297,6 +297,9 @@ en:
|
|||
uploaded_avatar_empty: "Add a custom picture"
|
||||
upload_title: "Upload your picture"
|
||||
image_is_not_a_square: "Warning: we've cropped your image; it is not square."
|
||||
|
||||
change_profile_background:
|
||||
title: "Change Profile Background"
|
||||
|
||||
email:
|
||||
title: "Email"
|
||||
|
|
|
@ -809,7 +809,9 @@ en:
|
|||
|
||||
detect_custom_avatars: "Whether or not to check that users have uploaded custom avatars"
|
||||
max_daily_gravatar_crawls: "The maximum amount of times Discourse will check gravatar for custom avatars in a day"
|
||||
|
||||
|
||||
allow_profile_backgrounds: "Allows users to upload profile backgrounds"
|
||||
|
||||
sequential_replies_threshold: "The amount of posts a user has to make in a row in a topic before being notified"
|
||||
|
||||
enable_mobile_theme: "Mobile devices use a mobile-friendly theme, with the ability to switch to the full site. Disable this if you want to use a custom stylesheet that is fully responsive."
|
||||
|
|
|
@ -181,7 +181,9 @@ Discourse::Application.routes.draw do
|
|||
put "users/:username/preferences/username" => "users#username", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
get "users/:username/avatar(/:size)" => "users#avatar", constraints: {username: USERNAME_ROUTE_FORMAT} # LEGACY ROUTE
|
||||
post "users/:username/preferences/avatar" => "users#upload_avatar", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
post "users/:username/preferences/user_image" => "users#upload_user_image", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
put "users/:username/preferences/avatar/toggle" => "users#toggle_avatar", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
put "users/:username/preferences/profile_background/clear" => "users#clear_profile_background", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
get "users/:username/invited" => "users#invited", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
post "users/:username/send_activation_email" => "users#send_activation_email", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
get "users/:username/activity" => "users#show", constraints: {username: USERNAME_ROUTE_FORMAT}
|
||||
|
|
|
@ -270,6 +270,9 @@ files:
|
|||
default: ''
|
||||
enum: 'S3RegionSiteSetting'
|
||||
s3_upload_bucket: ''
|
||||
allow_profile_backgrounds:
|
||||
client: true
|
||||
default: true
|
||||
allow_uploaded_avatars:
|
||||
client: true
|
||||
default: true
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
class AddProfileBackgroundToUser < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :users, :profile_background, :string, limit: 255
|
||||
end
|
||||
end
|
|
@ -1092,55 +1092,65 @@ describe UsersController do
|
|||
end
|
||||
end
|
||||
|
||||
describe '.upload_avatar' do
|
||||
describe '.upload_user_image' do
|
||||
|
||||
it 'raises an error when not logged in' do
|
||||
lambda { xhr :put, :upload_avatar, username: 'asdf' }.should raise_error(Discourse::NotLoggedIn)
|
||||
lambda { xhr :put, :upload_user_image, username: 'asdf' }.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
|
||||
context 'while logged in' do
|
||||
|
||||
let!(:user) { log_in }
|
||||
|
||||
let(:avatar) do
|
||||
let(:user_image) do
|
||||
ActionDispatch::Http::UploadedFile.new({
|
||||
filename: 'logo.png',
|
||||
tempfile: File.new("#{Rails.root}/spec/fixtures/images/logo.png")
|
||||
})
|
||||
end
|
||||
|
||||
it 'raises an error without a user_image_type param' do
|
||||
lambda { xhr :put, :upload_user_image, username: user.username }.should raise_error(ActionController::ParameterMissing)
|
||||
end
|
||||
|
||||
describe "with uploaded file" do
|
||||
|
||||
it 'raises an error when you don\'t have permission to upload an avatar' do
|
||||
|
||||
it 'raises an error when you don\'t have permission to upload an user image' do
|
||||
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
|
||||
xhr :post, :upload_avatar, username: user.username
|
||||
xhr :post, :upload_user_image, username: user.username, user_image_type: "avatar"
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it 'rejects large images' do
|
||||
AvatarUploadPolicy.any_instance.stubs(:too_big?).returns(true)
|
||||
xhr :post, :upload_avatar, username: user.username, file: avatar
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "avatar"
|
||||
response.status.should eq 413
|
||||
end
|
||||
|
||||
it 'rejects unauthorized images' do
|
||||
SiteSetting.stubs(:authorized_image?).returns(false)
|
||||
xhr :post, :upload_avatar, username: user.username, file: avatar
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "avatar"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
it 'rejects requests with unknown user_image_type' do
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "asdf"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
it 'is successful' do
|
||||
it 'is successful for avatars' do
|
||||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
# enqueues the avatar generator job
|
||||
# enqueues the user_image generator job
|
||||
Jobs.expects(:enqueue).with(:generate_avatars, { user_id: user.id, upload_id: upload.id })
|
||||
xhr :post, :upload_avatar, username: user.username, file: avatar
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "avatar"
|
||||
user.reload
|
||||
# erase the previous template
|
||||
user.uploaded_avatar_template.should == nil
|
||||
# link to the right upload
|
||||
user.uploaded_avatar.id.should == upload.id
|
||||
# automatically set "use_uploaded_avatar"
|
||||
# automatically set "use_uploaded_user_image"
|
||||
user.use_uploaded_avatar.should == true
|
||||
# returns the url, width and height of the uploaded image
|
||||
json = JSON.parse(response.body)
|
||||
|
@ -1148,10 +1158,26 @@ describe UsersController do
|
|||
json['width'].should == 100
|
||||
json['height'].should == 200
|
||||
end
|
||||
|
||||
it 'is successful for profile backgrounds' do
|
||||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image, user_image_type: "profile_background"
|
||||
user.reload
|
||||
|
||||
user.profile_background.should == "/uploads/default/1/1234567890123456.jpg"
|
||||
|
||||
# returns the url, width and height of the uploaded image
|
||||
json = JSON.parse(response.body)
|
||||
json['url'].should == "/uploads/default/1/1234567890123456.jpg"
|
||||
json['width'].should == 100
|
||||
json['height'].should == 200
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe "with url" do
|
||||
let(:avatar_url) { "http://cdn.discourse.org/assets/logo.png" }
|
||||
let(:user_image_url) { "http://cdn.discourse.org/assets/logo.png" }
|
||||
|
||||
before :each do
|
||||
UsersController.any_instance.stubs(:is_api?).returns(true)
|
||||
|
@ -1161,40 +1187,63 @@ describe UsersController do
|
|||
before :each do
|
||||
UriAdapter.any_instance.stubs(:open).returns StringIO.new(fixture_file("images/logo.png"))
|
||||
end
|
||||
|
||||
|
||||
it 'rejects large images' do
|
||||
AvatarUploadPolicy.any_instance.stubs(:too_big?).returns(true)
|
||||
xhr :post, :upload_avatar, username: user.username, file: avatar_url
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "profile_background"
|
||||
response.status.should eq 413
|
||||
end
|
||||
|
||||
it 'rejects unauthorized images' do
|
||||
SiteSetting.stubs(:authorized_image?).returns(false)
|
||||
xhr :post, :upload_avatar, username: user.username, file: avatar_url
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "profile_background"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
it 'rejects requests with unknown user_image_type' do
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "asdf"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
it 'is successful' do
|
||||
it 'is successful for avatars' do
|
||||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
# enqueues the avatar generator job
|
||||
# enqueues the user_image generator job
|
||||
Jobs.expects(:enqueue).with(:generate_avatars, { user_id: user.id, upload_id: upload.id })
|
||||
xhr :post, :upload_avatar, username: user.username, file: avatar_url
|
||||
xhr :post, :upload_avatar, username: user.username, file: user_image_url, user_image_type: "avatar"
|
||||
user.reload
|
||||
# erase the previous template
|
||||
user.uploaded_avatar_template.should == nil
|
||||
# link to the right upload
|
||||
user.uploaded_avatar.id.should == upload.id
|
||||
# automatically set "use_uploaded_user_image"
|
||||
user.use_uploaded_avatar.should == true
|
||||
|
||||
# returns the url, width and height of the uploaded image
|
||||
json = JSON.parse(response.body)
|
||||
json['url'].should == "/uploads/default/1/1234567890123456.jpg"
|
||||
json['width'].should == 100
|
||||
json['height'].should == 200
|
||||
end
|
||||
|
||||
it 'is successful for profile backgrounds' do
|
||||
upload = Fabricate(:upload)
|
||||
Upload.expects(:create_for).returns(upload)
|
||||
xhr :post, :upload_user_image, username: user.username, file: user_image_url, user_image_type: "profile_background"
|
||||
user.reload
|
||||
|
||||
user.profile_background.should == "/uploads/default/1/1234567890123456.jpg"
|
||||
|
||||
# returns the url, width and height of the uploaded image
|
||||
json = JSON.parse(response.body)
|
||||
json['url'].should == "/uploads/default/1/1234567890123456.jpg"
|
||||
json['width'].should == 100
|
||||
json['height'].should == 200
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
it "should handle malformed urls" do
|
||||
xhr :post, :upload_avatar, username: user.username, file: "foobar"
|
||||
xhr :post, :upload_user_image, username: user.username, file: "foobar", user_image_type: "profile_background"
|
||||
response.status.should eq 422
|
||||
end
|
||||
|
||||
|
@ -1233,6 +1282,32 @@ describe UsersController do
|
|||
end
|
||||
|
||||
end
|
||||
|
||||
describe '.clear_profile_background' do
|
||||
|
||||
it 'raises an error when not logged in' do
|
||||
lambda { xhr :put, :clear_profile_background, username: 'asdf' }.should raise_error(Discourse::NotLoggedIn)
|
||||
end
|
||||
|
||||
context 'while logged in' do
|
||||
|
||||
let!(:user) { log_in }
|
||||
|
||||
it 'raises an error when you don\'t have permission to clear the profile background' do
|
||||
Guardian.any_instance.expects(:can_edit?).with(user).returns(false)
|
||||
xhr :put, :clear_profile_background, username: user.username
|
||||
response.should be_forbidden
|
||||
end
|
||||
|
||||
it 'it successful' do
|
||||
xhr :put, :clear_profile_background, username: user.username
|
||||
user.reload.profile_background.should == ""
|
||||
response.should be_success
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
describe '.destroy' do
|
||||
it 'raises an error when not logged in' do
|
||||
|
|
Loading…
Reference in a new issue