Commit 2e3f250d4516c92adce5511747419d7f1fe04b97
1 parent
dba98240
Exists in
spb-stable
and in
3 other branches
Add website url to user
Showing
14 changed files
with
94 additions
and
9 deletions
Show diff stats
CHANGELOG
| ... | ... | @@ -16,6 +16,7 @@ v 6.5.0 |
| 16 | 16 | - Use jquery timeago plugin |
| 17 | 17 | - Fix 500 error for rdoc files |
| 18 | 18 | - Ability to customize merge commit message (sponsored by Say Media) |
| 19 | + - Add website url to user profile | |
| 19 | 20 | |
| 20 | 21 | v6.4.3 |
| 21 | 22 | - Don't use unicorn worker killer if PhusionPassenger is defined | ... | ... |
app/models/user.rb
| ... | ... | @@ -41,7 +41,8 @@ |
| 41 | 41 | # confirmed_at :datetime |
| 42 | 42 | # confirmation_sent_at :datetime |
| 43 | 43 | # unconfirmed_email :string(255) |
| 44 | -# hide_no_ssh_key :boolean default(FALSE), not null | |
| 44 | +# hide_no_ssh_key :boolean default(FALSE) | |
| 45 | +# website_url :string(255) default(""), not null | |
| 45 | 46 | # |
| 46 | 47 | |
| 47 | 48 | require 'carrierwave/orm/activerecord' |
| ... | ... | @@ -52,7 +53,7 @@ class User < ActiveRecord::Base |
| 52 | 53 | :recoverable, :rememberable, :trackable, :validatable, :omniauthable, :confirmable, :registerable |
| 53 | 54 | |
| 54 | 55 | attr_accessible :email, :password, :password_confirmation, :remember_me, :bio, :name, :username, |
| 55 | - :skype, :linkedin, :twitter, :color_scheme_id, :theme_id, :force_random_password, | |
| 56 | + :skype, :linkedin, :twitter, :website_url, :color_scheme_id, :theme_id, :force_random_password, | |
| 56 | 57 | :extern_uid, :provider, :password_expires_at, :avatar, :hide_no_ssh_key, |
| 57 | 58 | as: [:default, :admin] |
| 58 | 59 | |
| ... | ... | @@ -424,4 +425,14 @@ class User < ActiveRecord::Base |
| 424 | 425 | order('id DESC').limit(1000). |
| 425 | 426 | update_all(updated_at: Time.now) |
| 426 | 427 | end |
| 428 | + | |
| 429 | + def full_website_url | |
| 430 | + return "http://#{website_url}" if website_url !~ /^https?:\/\// | |
| 431 | + | |
| 432 | + website_url | |
| 433 | + end | |
| 434 | + | |
| 435 | + def short_website_url | |
| 436 | + website_url.gsub(/https?:\/\//, '') | |
| 437 | + end | |
| 427 | 438 | end | ... | ... |
app/views/admin/users/_form.html.haml
| ... | ... | @@ -80,6 +80,9 @@ |
| 80 | 80 | .form-group |
| 81 | 81 | = f.label :twitter, class: 'control-label' |
| 82 | 82 | .col-sm-10= f.text_field :twitter, class: 'form-control' |
| 83 | + .form-group | |
| 84 | + = f.label :website_url, class: 'control-label' | |
| 85 | + .col-sm-10= f.text_field :website_url, class: 'form-control' | |
| 83 | 86 | |
| 84 | 87 | .form-actions |
| 85 | 88 | - if @user.new_record? | ... | ... |
app/views/profiles/show.html.haml
| ... | ... | @@ -47,6 +47,9 @@ |
| 47 | 47 | = f.label :twitter, class: "control-label" |
| 48 | 48 | .col-sm-10= f.text_field :twitter, class: "form-control" |
| 49 | 49 | .form-group |
| 50 | + = f.label :website_url, class: "control-label" | |
| 51 | + .col-sm-10= f.text_field :website_url, class: "form-control" | |
| 52 | + .form-group | |
| 50 | 53 | = f.label :bio, class: "control-label" |
| 51 | 54 | .col-sm-10 |
| 52 | 55 | = f.text_area :bio, rows: 6, class: "form-control", maxlength: 250 | ... | ... |
app/views/users/_profile.html.haml
| ... | ... | @@ -17,6 +17,10 @@ |
| 17 | 17 | %li |
| 18 | 18 | %span.light Twitter: |
| 19 | 19 | %strong= link_to user.twitter, "http://www.twitter.com/#{user.twitter}" |
| 20 | + - unless user.website_url.blank? | |
| 21 | + %li | |
| 22 | + %span.light Website url: | |
| 23 | + %strong= link_to user.short_website_url, user.full_website_url | |
| 20 | 24 | - unless user.bio.blank? |
| 21 | 25 | %li |
| 22 | 26 | %span.light Bio: | ... | ... |
db/schema.rb
| ... | ... | @@ -11,7 +11,7 @@ |
| 11 | 11 | # |
| 12 | 12 | # It's strongly recommended that you check this file into your version control system. |
| 13 | 13 | |
| 14 | -ActiveRecord::Schema.define(version: 20131217102743) do | |
| 14 | +ActiveRecord::Schema.define(version: 20140116231608) do | |
| 15 | 15 | |
| 16 | 16 | create_table "broadcast_messages", force: true do |t| |
| 17 | 17 | t.text "message", null: false |
| ... | ... | @@ -301,6 +301,7 @@ ActiveRecord::Schema.define(version: 20131217102743) do |
| 301 | 301 | t.datetime "confirmation_sent_at" |
| 302 | 302 | t.string "unconfirmed_email" |
| 303 | 303 | t.boolean "hide_no_ssh_key", default: false |
| 304 | + t.string "website_url", default: "", null: false | |
| 304 | 305 | end |
| 305 | 306 | |
| 306 | 307 | add_index "users", ["admin"], name: "index_users_on_admin", using: :btree | ... | ... |
doc/api/session.md
doc/api/users.md
| ... | ... | @@ -20,6 +20,7 @@ GET /users |
| 20 | 20 | "skype": "", |
| 21 | 21 | "linkedin": "", |
| 22 | 22 | "twitter": "", |
| 23 | + "website_url": "", | |
| 23 | 24 | "extern_uid": "john.smith", |
| 24 | 25 | "provider": "provider_name", |
| 25 | 26 | "theme_id": 1, |
| ... | ... | @@ -38,6 +39,7 @@ GET /users |
| 38 | 39 | "skype": "", |
| 39 | 40 | "linkedin": "", |
| 40 | 41 | "twitter": "", |
| 42 | + "website_url": "", | |
| 41 | 43 | "extern_uid": "jack.smith", |
| 42 | 44 | "provider": "provider_name", |
| 43 | 45 | "theme_id": 1, |
| ... | ... | @@ -74,6 +76,7 @@ Parameters: |
| 74 | 76 | "skype": "", |
| 75 | 77 | "linkedin": "", |
| 76 | 78 | "twitter": "", |
| 79 | + "website_url": "", | |
| 77 | 80 | "extern_uid": "john.smith", |
| 78 | 81 | "provider": "provider_name", |
| 79 | 82 | "theme_id": 1, |
| ... | ... | @@ -102,6 +105,7 @@ Parameters: |
| 102 | 105 | + `skype` (optional) - Skype ID |
| 103 | 106 | + `linkedin` (optional) - Linkedin |
| 104 | 107 | + `twitter` (optional) - Twitter account |
| 108 | ++ `website_url` (optional) - Website url | |
| 105 | 109 | + `projects_limit` (optional) - Number of projects user can create |
| 106 | 110 | + `extern_uid` (optional) - External UID |
| 107 | 111 | + `provider` (optional) - External provider name |
| ... | ... | @@ -127,6 +131,7 @@ Parameters: |
| 127 | 131 | + `skype` - Skype ID |
| 128 | 132 | + `linkedin` - Linkedin |
| 129 | 133 | + `twitter` - Twitter account |
| 134 | ++ `website_url` - Website url | |
| 130 | 135 | + `projects_limit` - Limit projects each user can create |
| 131 | 136 | + `extern_uid` - External UID |
| 132 | 137 | + `provider` - External provider name |
| ... | ... | @@ -174,6 +179,7 @@ GET /user |
| 174 | 179 | "skype": "", |
| 175 | 180 | "linkedin": "", |
| 176 | 181 | "twitter": "", |
| 182 | + "website_url": "", | |
| 177 | 183 | "theme_id": 1, |
| 178 | 184 | "color_scheme_id": 2, |
| 179 | 185 | "is_admin": false, | ... | ... |
features/profile/profile.feature
| ... | ... | @@ -8,8 +8,8 @@ Feature: Profile |
| 8 | 8 | |
| 9 | 9 | Scenario: I edit profile |
| 10 | 10 | Given I visit profile page |
| 11 | - Then I change my contact info | |
| 12 | - And I should see new contact info | |
| 11 | + Then I change my profile info | |
| 12 | + And I should see new profile info | |
| 13 | 13 | |
| 14 | 14 | Scenario: I change my password without old one |
| 15 | 15 | Given I visit profile password page | ... | ... |
features/steps/profile/profile.rb
| ... | ... | @@ -6,18 +6,20 @@ class Profile < Spinach::FeatureSteps |
| 6 | 6 | page.should have_content "Profile settings" |
| 7 | 7 | end |
| 8 | 8 | |
| 9 | - step 'I change my contact info' do | |
| 9 | + step 'I change my profile info' do | |
| 10 | 10 | fill_in "user_skype", with: "testskype" |
| 11 | 11 | fill_in "user_linkedin", with: "testlinkedin" |
| 12 | 12 | fill_in "user_twitter", with: "testtwitter" |
| 13 | + fill_in "user_website_url", with: "testurl" | |
| 13 | 14 | click_button "Save changes" |
| 14 | 15 | @user.reload |
| 15 | 16 | end |
| 16 | 17 | |
| 17 | - step 'I should see new contact info' do | |
| 18 | + step 'I should see new profile info' do | |
| 18 | 19 | @user.skype.should == 'testskype' |
| 19 | 20 | @user.linkedin.should == 'testlinkedin' |
| 20 | 21 | @user.twitter.should == 'testtwitter' |
| 22 | + @user.website_url.should == 'testurl' | |
| 21 | 23 | end |
| 22 | 24 | |
| 23 | 25 | step 'I change my avatar' do | ... | ... |
lib/api/entities.rb
| 1 | 1 | module API |
| 2 | 2 | module Entities |
| 3 | 3 | class User < Grape::Entity |
| 4 | - expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, | |
| 4 | + expose :id, :username, :email, :name, :bio, :skype, :linkedin, :twitter, :website_url, | |
| 5 | 5 | :theme_id, :color_scheme_id, :state, :created_at, :extern_uid, :provider |
| 6 | 6 | expose :is_admin?, as: :is_admin |
| 7 | 7 | expose :can_create_group?, as: :can_create_group | ... | ... |
lib/api/users.rb
| ... | ... | @@ -36,6 +36,7 @@ module API |
| 36 | 36 | # skype - Skype ID |
| 37 | 37 | # linkedin - Linkedin |
| 38 | 38 | # twitter - Twitter account |
| 39 | + # website_url - Website url | |
| 39 | 40 | # projects_limit - Number of projects user can create |
| 40 | 41 | # extern_uid - External authentication provider UID |
| 41 | 42 | # provider - External provider |
| ... | ... | @@ -67,6 +68,7 @@ module API |
| 67 | 68 | # skype - Skype ID |
| 68 | 69 | # linkedin - Linkedin |
| 69 | 70 | # twitter - Twitter account |
| 71 | + # website_url - Website url | |
| 70 | 72 | # projects_limit - Limit projects each user can create |
| 71 | 73 | # extern_uid - External authentication provider UID |
| 72 | 74 | # provider - External provider |
| ... | ... | @@ -78,7 +80,7 @@ module API |
| 78 | 80 | put ":id" do |
| 79 | 81 | authenticated_as_admin! |
| 80 | 82 | |
| 81 | - attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :projects_limit, :username, :extern_uid, :provider, :bio, :can_create_group, :admin] | |
| 83 | + attrs = attributes_for_keys [:email, :name, :password, :skype, :linkedin, :twitter, :website_url, :projects_limit, :username, :extern_uid, :provider, :bio, :can_create_group, :admin] | |
| 82 | 84 | user = User.find(params[:id]) |
| 83 | 85 | not_found!("User not found") unless user |
| 84 | 86 | ... | ... |
spec/models/user_spec.rb
| ... | ... | @@ -41,6 +41,8 @@ |
| 41 | 41 | # confirmed_at :datetime |
| 42 | 42 | # confirmation_sent_at :datetime |
| 43 | 43 | # unconfirmed_email :string(255) |
| 44 | +# hide_no_ssh_key :boolean default(FALSE) | |
| 45 | +# website_url :string(255) default(""), not null | |
| 44 | 46 | # |
| 45 | 47 | |
| 46 | 48 | require 'spec_helper' |
| ... | ... | @@ -293,4 +295,48 @@ describe User do |
| 293 | 295 | user.avatar_type.should == ["only images allowed"] |
| 294 | 296 | end |
| 295 | 297 | end |
| 298 | + | |
| 299 | + describe '#full_website_url' do | |
| 300 | + let(:user) { create(:user) } | |
| 301 | + | |
| 302 | + it 'begins with http if website url omits it' do | |
| 303 | + user.website_url = 'test.com' | |
| 304 | + | |
| 305 | + expect(user.full_website_url).to eq 'http://test.com' | |
| 306 | + end | |
| 307 | + | |
| 308 | + it 'begins with http if website url begins with http' do | |
| 309 | + user.website_url = 'http://test.com' | |
| 310 | + | |
| 311 | + expect(user.full_website_url).to eq 'http://test.com' | |
| 312 | + end | |
| 313 | + | |
| 314 | + it 'begins with https if website url begins with https' do | |
| 315 | + user.website_url = 'https://test.com' | |
| 316 | + | |
| 317 | + expect(user.full_website_url).to eq 'https://test.com' | |
| 318 | + end | |
| 319 | + end | |
| 320 | + | |
| 321 | + describe '#short_website_url' do | |
| 322 | + let(:user) { create(:user) } | |
| 323 | + | |
| 324 | + it 'does not begin with http if website url omits it' do | |
| 325 | + user.website_url = 'test.com' | |
| 326 | + | |
| 327 | + expect(user.short_website_url).to eq 'test.com' | |
| 328 | + end | |
| 329 | + | |
| 330 | + it 'does not begin with http if website url begins with http' do | |
| 331 | + user.website_url = 'http://test.com' | |
| 332 | + | |
| 333 | + expect(user.short_website_url).to eq 'test.com' | |
| 334 | + end | |
| 335 | + | |
| 336 | + it 'does not begin with https if website url begins with https' do | |
| 337 | + user.website_url = 'https://test.com' | |
| 338 | + | |
| 339 | + expect(user.short_website_url).to eq 'test.com' | |
| 340 | + end | |
| 341 | + end | |
| 296 | 342 | end | ... | ... |