From 93a2b364051de08c1417e7ee01c88b31e1735e62 Mon Sep 17 00:00:00 2001 From: goobertron Date: Tue, 5 Aug 2014 23:32:45 +0100 Subject: [PATCH 001/785] Change default for jQuery CDN to false. --- config/defaults.yml | 2 +- config/diaspora.yml.example | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/config/defaults.yml b/config/defaults.yml index ccfd26341..aa2e543b9 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -41,7 +41,7 @@ defaults: embed_sidekiq_worker: false sidekiq_workers: 1 privacy: - jquery_cdn: true + jquery_cdn: false google_analytics_key: piwik: enable: false diff --git a/config/diaspora.yml.example b/config/diaspora.yml.example index 1ac63c2ba..fcb3be517 100644 --- a/config/diaspora.yml.example +++ b/config/diaspora.yml.example @@ -172,11 +172,11 @@ configuration: ## Section ## Settings potentially affecting the privacy of your users privacy: ## Section - ## Include jQuery from jquery.com's CDN (default=true) - ## This can save you some traffic and speeds up load time since most - ## clients already have this one cached. Set this to false if you want - ## the jQuery library to be loaded from your pod's own resources. - #jquery_cdn: true + ## Include jQuery from jquery.com's CDN (default=false) + ## Enabling this can reduce traffic and speed up load time since most + ## clients already have this one cached. When set to false (the default), + ## the jQuery library will be loaded from your pod's own resources. + #jquery_cdn: false ## Google Analytics (disabled by default) ## Provide a key to enable tracking by Google Analytics From 55f40a2b655dab0c0428c61ed0d5a92f0f54442d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 30 Aug 2013 23:53:41 +0200 Subject: [PATCH 002/785] update to rails 4 --- Gemfile | 73 +++++++------- Gemfile.lock | 274 ++++++++++++++++++++++++++------------------------- 2 files changed, 174 insertions(+), 173 deletions(-) diff --git a/Gemfile b/Gemfile index efca53b55..7a622cd34 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,12 @@ source 'https://rubygems.org' -gem 'rails', '3.2.19' +gem 'rails', '4.0.3' + +# Legacy Rails features, remove me! + +# caches_page +gem 'actionpack-action_caching' +gem 'actionpack-page_caching' # Appserver @@ -25,6 +31,10 @@ gem 'galetahub-simple_captcha', '0.1.5', :require => 'simple_captcha' gem 'sidekiq', '2.17.7' gem 'sinatra', '1.3.3' +# Compression + +gem 'uglifier', '2.5.0' + # Configuration gem 'configurate', '0.0.8' @@ -33,6 +43,12 @@ gem 'configurate', '0.0.8' gem 'rack-cors', '0.2.9', :require => 'rack/cors' +# CSS + +gem 'bootstrap-sass', '2.3.2.2' +gem 'compass-rails', '1.1.7' +gem 'sass-rails', '4.0.1' + # Database ENV['DB'] ||= 'mysql' @@ -40,7 +56,7 @@ ENV['DB'] ||= 'mysql' gem 'mysql2', '0.3.16' if ENV['DB'] == 'all' || ENV['DB'] == 'mysql' gem 'pg', '0.17.1' if ENV['DB'] == 'all' || ENV['DB'] == 'postgres' -gem 'activerecord-import', '0.3.1' +gem 'activerecord-import', '0.4.1' gem 'foreigner', '1.6.1' # File uploading @@ -53,11 +69,21 @@ gem 'remotipart', '1.2.1' # GUID generation gem 'uuid', '2.3.7' +# Icons + +gem 'entypo-rails', '2.2.1' + +# JavaScript + +gem 'backbone-on-rails', '1.1.1' +gem 'handlebars_assets', '0.12.0' +gem 'jquery-rails', '3.0.4' + # Localization gem 'http_accept_language', '1.0.2' gem 'i18n-inflector-rails', '1.0.7' -gem 'rails-i18n', '0.7.4' +gem 'rails-i18n', '4.0.1' # Mail @@ -74,10 +100,6 @@ gem 'ruby-oembed', '0.8.9' gem 'opengraph_parser', '0.2.3' -# Please remove when migrating to Rails 4 -gem 'strong_parameters', '0.2.3' - - # Services gem 'omniauth', '1.2.1' @@ -110,42 +132,19 @@ gem 'rails-timeago', '2.4.0' # https://github.com/rubyzip/rubyzip#important-note gem 'zip-zip' -### GROUPS #### -group :assets do +# Windows and OSX have an execjs compatible runtime built-in, Linux users should +# install Node.js or use 'therubyracer'. +# +# See https://github.com/sstephenson/execjs#readme for more supported runtimes - # Icons - gem 'entypo-rails', '2.2.1' - - # CSS - - gem 'bootstrap-sass', '2.2.2.0' - gem 'compass-rails', '1.1.7' - gem 'sass-rails', '3.2.6' - - # Compression - - gem 'uglifier', '2.5.0' - - # JavaScript - - gem 'backbone-on-rails', '1.1.1' - gem 'handlebars_assets', '0.12.0' - gem 'jquery-rails', '3.0.4' - - # Windows and OSX have an execjs compatible runtime built-in, Linux users should - # install Node.js or use 'therubyracer'. - # - # See https://github.com/sstephenson/execjs#readme for more supported runtimes - - # gem 'therubyracer', :platform => :ruby -end +# gem 'therubyracer', :platform => :ruby group :production do # we don't install these on travis to speed up test runs # Administration - gem 'rails_admin', '0.4.9' + gem 'rails_admin', '0.6.1' # Analytics @@ -213,6 +212,6 @@ group :development, :test do gem 'cucumber-rails', '1.4.1', :require => false # Jasmine (client side application tests (JS)) - gem 'jasmine', '1.3.2' + gem 'jasmine', '2.0.0' gem 'sinon-rails', '1.9.0' end diff --git a/Gemfile.lock b/Gemfile.lock index ac931b300..1ec15636e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,35 +1,40 @@ GEM remote: https://rubygems.org/ specs: - actionmailer (3.2.19) - actionpack (= 3.2.19) + actionmailer (4.0.3) + actionpack (= 4.0.3) mail (~> 2.5.4) - actionpack (3.2.19) - activemodel (= 3.2.19) - activesupport (= 3.2.19) - builder (~> 3.0.0) + actionpack (4.0.3) + activesupport (= 4.0.3) + builder (~> 3.1.0) erubis (~> 2.7.0) - journey (~> 1.0.4) - rack (~> 1.4.5) - rack-cache (~> 1.2) - rack-test (~> 0.6.1) - sprockets (~> 2.2.1) - activemodel (3.2.19) - activesupport (= 3.2.19) - builder (~> 3.0.0) - activerecord (3.2.19) - activemodel (= 3.2.19) - activesupport (= 3.2.19) - arel (~> 3.0.2) - tzinfo (~> 0.3.29) - activerecord-import (0.3.1) - activerecord (~> 3.0) - activeresource (3.2.19) - activemodel (= 3.2.19) - activesupport (= 3.2.19) - activesupport (3.2.19) + rack (~> 1.5.2) + rack-test (~> 0.6.2) + actionpack-action_caching (1.1.1) + actionpack (>= 4.0.0, < 5.0) + actionpack-page_caching (1.0.2) + actionpack (>= 4.0.0, < 5) + activemodel (4.0.3) + activesupport (= 4.0.3) + builder (~> 3.1.0) + activerecord (4.0.3) + activemodel (= 4.0.3) + activerecord-deprecated_finders (~> 1.0.2) + activesupport (= 4.0.3) + arel (~> 4.0.0) + activerecord-deprecated_finders (1.0.3) + activerecord-import (0.4.1) + activerecord (>= 3.0) + activeresource (4.0.0) + activemodel (~> 4.0) + activesupport (~> 4.0) + rails-observers (~> 0.1.1) + activesupport (4.0.3) i18n (~> 0.6, >= 0.6.4) - multi_json (~> 1.0) + minitest (~> 4.2) + multi_json (~> 1.3) + thread_safe (~> 0.1) + tzinfo (~> 0.3.37) acts-as-taggable-on (3.2.6) activerecord (>= 3, < 5) acts_as_api (0.4.2) @@ -37,7 +42,7 @@ GEM activesupport (>= 3.0.0) rack (>= 1.1.0) addressable (2.3.6) - arel (3.0.3) + arel (4.0.2) asset_sync (1.0.0) activemodel fog (>= 1.8.0) @@ -51,9 +56,9 @@ GEM jquery-rails railties bcrypt (3.1.7) - bootstrap-sass (2.2.2.0) + bootstrap-sass (2.3.2.2) sass (~> 3.2) - builder (3.0.4) + builder (3.1.4) capybara (2.2.1) mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -71,30 +76,30 @@ GEM ffi (~> 1.0, >= 1.0.11) chunky_png (1.3.1) coderay (1.1.0) - coffee-rails (3.2.2) + coffee-rails (4.0.1) coffee-script (>= 2.2.0) - railties (~> 3.2.0) + railties (>= 4.0.0, < 5.0) coffee-script (2.2.0) coffee-script-source execjs - coffee-script-source (1.7.0) - compass (0.12.6) + coffee-script-source (1.6.3) + compass (0.12.3) chunky_png (~> 1.2) fssm (>= 0.2.7) - sass (~> 3.2.19) + sass (= 3.2.14) compass-rails (1.1.7) compass (>= 0.12.2) sprockets (<= 2.11.0) configurate (0.0.8) - connection_pool (2.0.0) - crack (0.4.1) - safe_yaml (~> 0.9.0) + connection_pool (1.2.0) + crack (0.4.2) + safe_yaml (~> 1.0.0) cucumber (1.3.15) builder (>= 2.1.2) diff-lcs (>= 1.1.3) gherkin (~> 2.12) multi_json (>= 1.7.5, < 2.0) - multi_test (>= 0.1.1) + multi_test (>= 0.0.2) cucumber-rails (1.4.1) capybara (>= 1.1.2, < 3) cucumber (>= 1.3.8, < 2) @@ -125,10 +130,11 @@ GEM entypo-rails (2.2.1) railties (>= 3.1, <= 5) erubis (2.7.0) - ethon (0.7.0) + ethon (0.7.1) ffi (>= 1.3.0) - excon (0.34.0) - execjs (2.1.0) + excon (0.39.0) + execjs (1.4.0) + multi_json (~> 1.0) factory_girl (4.4.0) activesupport (>= 3.0.0) factory_girl_rails (4.4.1) @@ -148,19 +154,20 @@ GEM fog-json ipaddress (~> 0.5) nokogiri (~> 1.5, >= 1.5.11) - fog-brightbox (0.0.2) - fog-core + fog-brightbox (0.1.1) + fog-core (~> 1.22) fog-json - fog-core (1.22.0) + inflecto + fog-core (1.23.0) builder - excon (~> 0.33) + excon (~> 0.38) formatador (~> 0.2) mime-types net-scp (~> 1.1) net-ssh (>= 2.1.3) fog-json (1.0.0) multi_json (~> 1.0) - font-awesome-rails (3.2.1.2) + font-awesome-rails (4.0.3.1) railties (>= 3.2, < 5.0) foreigner (1.6.1) activerecord (>= 3.0.0) @@ -177,9 +184,9 @@ GEM gon (5.0.4) actionpack (>= 2.3.0) json - guard (2.6.1) + guard (2.2.5) formatador (>= 0.2.4) - listen (~> 2.7) + listen (~> 2.1) lumberjack (~> 1.0) pry (>= 0.9.12) thor (>= 0.18.1) @@ -199,43 +206,44 @@ GEM execjs (>= 1.2.9) sprockets (>= 2.0.3) tilt - hashie (2.1.1) + hashie (2.1.2) hike (1.2.3) http_accept_language (1.0.2) - i18n (0.6.9) + httpauth (0.2.0) + i18n (0.6.11) i18n-inflector (2.6.7) i18n (>= 0.4.1) i18n-inflector-rails (1.0.7) actionpack (>= 3.0.0) i18n-inflector (~> 2.6) railties (>= 3.0.0) + inflecto (0.0.2) ipaddress (0.8.0) - jasmine (1.3.2) - jasmine-core (~> 1.3.1) - rack (~> 1.0) - rspec (>= 1.3.1) - selenium-webdriver (>= 0.1.3) - jasmine-core (1.3.1) - journey (1.0.4) + jasmine (2.0.0) + jasmine-core (~> 2.0.0) + phantomjs + rack (>= 1.2.1) + rake + jasmine-core (2.0.0) jquery-rails (3.0.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) - jquery-ui-rails (3.0.1) - jquery-rails - railties (>= 3.1.0) + jquery-ui-rails (4.2.0) + railties (>= 3.2.16) json (1.8.1) - jwt (1.0.0) + jwt (0.1.10) + multi_json (>= 1.5) kaminari (0.15.1) actionpack (>= 3.0.0) activesupport (>= 3.0.0) kgio (2.9.2) - listen (2.7.5) + listen (2.4.0) celluloid (>= 0.15.2) rb-fsevent (>= 0.9.3) rb-inotify (>= 0.9) - lumberjack (1.0.6) - macaddr (1.6.1) - systemu (~> 2.5.0) + lumberjack (1.0.4) + macaddr (1.7.1) + systemu (~> 2.6.2) mail (2.5.4) mime-types (~> 1.16) treetop (~> 1.4.8) @@ -247,12 +255,12 @@ GEM mini_magick (3.7.0) subexec (~> 0.2.1) mini_portile (0.5.3) + minitest (4.7.5) mobile-fu (1.2.2) rack-mobile-detect rails multi_json (1.10.1) - multi_test (0.1.1) - multi_xml (0.5.5) + multi_test (0.0.3) multipart-post (1.2.0) mysql2 (0.3.16) nested_form (0.3.2) @@ -262,11 +270,11 @@ GEM nokogiri (1.6.1) mini_portile (~> 0.5.0) oauth (0.4.7) - oauth2 (0.9.4) - faraday (>= 0.8, < 0.10) - jwt (~> 1.0) - multi_json (~> 1.3) - multi_xml (~> 0.5) + oauth2 (0.8.1) + faraday (~> 0.8) + httpauth (~> 0.1) + jwt (~> 0.1.4) + multi_json (~> 1.0) rack (~> 1.2) omniauth (1.2.1) hashie (>= 1.2, < 3) @@ -276,11 +284,9 @@ GEM omniauth-oauth (1.0.1) oauth omniauth (~> 1.0) - omniauth-oauth2 (1.1.2) - faraday (>= 0.8, < 0.10) - multi_json (~> 1.3) - oauth2 (~> 0.9.3) - omniauth (~> 1.2) + omniauth-oauth2 (1.1.1) + oauth2 (~> 0.8.0) + omniauth (~> 1.0) omniauth-tumblr (1.1) omniauth-oauth (~> 1.0) omniauth-twitter (1.0.1) @@ -292,14 +298,13 @@ GEM addressable nokogiri orm_adapter (0.5.0) - polyglot (0.3.5) - pry (0.9.12.6) + phantomjs (1.9.2.1) + polyglot (0.3.4) + pry (0.9.12.4) coderay (~> 1.0) method_source (~> 0.8) slop (~> 3.4) - rack (1.4.5) - rack-cache (1.2) - rack (>= 0.4) + rack (1.5.2) rack-cors (0.2.9) rack-google-analytics (0.14.0) actionpack @@ -317,50 +322,48 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - rails (3.2.19) - actionmailer (= 3.2.19) - actionpack (= 3.2.19) - activerecord (= 3.2.19) - activeresource (= 3.2.19) - activesupport (= 3.2.19) - bundler (~> 1.0) - railties (= 3.2.19) - rails-i18n (0.7.4) - i18n (~> 0.5) + rails (4.0.3) + actionmailer (= 4.0.3) + actionpack (= 4.0.3) + activerecord (= 4.0.3) + activesupport (= 4.0.3) + bundler (>= 1.3.0, < 2.0) + railties (= 4.0.3) + sprockets-rails (~> 2.0.0) + rails-i18n (4.0.1) + i18n (~> 0.6) + rails (~> 4.0) + rails-observers (0.1.2) + activemodel (~> 4.0) rails-timeago (2.4.0) actionpack (>= 3.1) activesupport (>= 3.1) - rails_admin (0.4.9) - bootstrap-sass (~> 2.2) - builder (~> 3.0) - coffee-rails (>= 3.1, < 5) - font-awesome-rails (~> 3.0) + rails_admin (0.6.1) + builder (~> 3.1) + coffee-rails (~> 4.0) + font-awesome-rails (>= 3.0) haml (~> 4.0) - jquery-rails (>= 2.1, < 4) - jquery-ui-rails (~> 3.0) + jquery-rails (~> 3.0) + jquery-ui-rails (~> 4.0) kaminari (~> 0.14) nested_form (~> 0.3) - rack-pjax (~> 0.6) - rails (~> 3.1) + rack-pjax (~> 0.7) + rails (~> 4.0) remotipart (~> 1.0) - safe_yaml (~> 0.6) - sass-rails (~> 3.1) + safe_yaml (~> 1.0) + sass-rails (~> 4.0) rails_autolink (1.1.5) rails (> 3.1) - railties (3.2.19) - actionpack (= 3.2.19) - activesupport (= 3.2.19) - rack-ssl (~> 1.3.2) + railties (4.0.3) + actionpack (= 4.0.3) + activesupport (= 4.0.3) rake (>= 0.8.7) - rdoc (~> 3.4) - thor (>= 0.14.6, < 2.0) + thor (>= 0.18.1, < 2.0) raindrops (0.13.0) rake (10.3.2) rb-fsevent (0.9.4) rb-inotify (0.9.4) ffi (>= 0.5.0) - rdoc (3.12.2) - json (~> 1.4) redcarpet (3.1.2) redis (3.1.0) redis-namespace (1.5.1) @@ -388,13 +391,13 @@ GEM rspec-mocks (~> 2.14.0) ruby-oembed (0.8.9) ruby-progressbar (1.5.1) - rubyzip (1.1.4) - safe_yaml (0.9.7) - sass (3.2.19) - sass-rails (3.2.6) - railties (~> 3.2.0) + rubyzip (1.1.0) + safe_yaml (1.0.1) + sass (3.2.14) + sass-rails (4.0.1) + railties (>= 4.0.0, < 5.0) sass (>= 3.1.10) - tilt (~> 1.3) + sprockets-rails (~> 2.0.0) selenium-webdriver (2.42.0) childprocess (>= 0.5.0) multi_json (~> 1.0) @@ -413,20 +416,19 @@ GEM tilt (~> 1.3, >= 1.3.3) sinon-rails (1.9.0) railties (>= 3.1) - slop (3.5.0) + slop (3.4.7) spork (1.0.0rc4) - sprockets (2.2.2) + sprockets (2.11.0) hike (~> 1.2) multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - strong_parameters (0.2.3) - actionpack (~> 3.0) - activemodel (~> 3.0) - activesupport (~> 3.0) - railties (~> 3.0) + sprockets-rails (2.0.1) + actionpack (>= 3.0) + activesupport (>= 3.0) + sprockets (~> 2.8) subexec (0.2.3) - systemu (2.5.2) + systemu (2.6.4) test_after_commit (0.2.3) thor (0.19.1) thread_safe (0.3.4) @@ -442,7 +444,7 @@ GEM simple_oauth (~> 0.2) typhoeus (0.6.8) ethon (>= 0.7.0) - tzinfo (0.3.39) + tzinfo (0.3.40) uglifier (2.5.0) execjs (>= 0.3.0) json (>= 1.8.0) @@ -452,7 +454,6 @@ GEM raindrops (~> 0.7) uuid (2.3.7) macaddr (~> 1.0) - rack (>= 1.0) warden (1.2.3) rack (>= 1.0) webmock (1.18.0) @@ -462,20 +463,22 @@ GEM will_paginate (3.0.5) xpath (2.0.0) nokogiri (~> 1.3) - zip-zip (0.3) + zip-zip (0.2) rubyzip (>= 1.0.0) PLATFORMS ruby DEPENDENCIES - activerecord-import (= 0.3.1) + actionpack-action_caching + actionpack-page_caching + activerecord-import (= 0.4.1) acts-as-taggable-on (= 3.2.6) acts_as_api (= 0.4.2) addressable (= 2.3.6) asset_sync (= 1.0.0) backbone-on-rails (= 1.1.1) - bootstrap-sass (= 2.2.2.0) + bootstrap-sass (= 2.3.2.2) capybara (= 2.2.1) carrierwave (= 0.10.0) compass-rails (= 1.1.7) @@ -502,7 +505,7 @@ DEPENDENCIES handlebars_assets (= 0.12.0) http_accept_language (= 1.0.2) i18n-inflector-rails (= 1.0.7) - jasmine (= 1.3.2) + jasmine (= 2.0.0) jquery-rails (= 3.0.4) json (= 1.8.1) markerb (= 1.0.2) @@ -523,10 +526,10 @@ DEPENDENCIES rack-protection (= 1.2) rack-rewrite (= 1.5.0) rack-ssl (= 1.3.3) - rails (= 3.2.19) - rails-i18n (= 0.7.4) + rails (= 4.0.3) + rails-i18n (= 4.0.1) rails-timeago (= 2.4.0) - rails_admin (= 0.4.9) + rails_admin (= 0.6.1) rails_autolink (= 1.1.5) rb-fsevent (= 0.9.4) rb-inotify (= 0.9.4) @@ -536,13 +539,12 @@ DEPENDENCIES rspec-instafail (= 0.2.4) rspec-rails (= 2.14.2) ruby-oembed (= 0.8.9) - sass-rails (= 3.2.6) + sass-rails (= 4.0.1) selenium-webdriver (= 2.42.0) sidekiq (= 2.17.7) sinatra (= 1.3.3) sinon-rails (= 1.9.0) spork (= 1.0.0rc4) - strong_parameters (= 0.2.3) test_after_commit (= 0.2.3) timecop (= 0.7.1) twitter (= 4.8.1) From 59d60ff947e46fdc05a2e8df52d0b2fc8c066c48 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 30 Aug 2013 23:55:30 +0200 Subject: [PATCH 003/785] remove strong_parameters initializer --- config/initializers/strong_parameters.rb | 2 -- 1 file changed, 2 deletions(-) delete mode 100644 config/initializers/strong_parameters.rb diff --git a/config/initializers/strong_parameters.rb b/config/initializers/strong_parameters.rb deleted file mode 100644 index 69fdcd47c..000000000 --- a/config/initializers/strong_parameters.rb +++ /dev/null @@ -1,2 +0,0 @@ -# Please remove when migrating to Rails 4 -ActiveRecord::Base.send(:include, ActiveModel::ForbiddenAttributesProtection) From 467df1df779ddaeb25e85855db4d50d6d055a73f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 00:06:24 +0200 Subject: [PATCH 004/785] generate binstubs --- .gitignore | 1 - bin/autospec | 16 ++++++++++++++++ bin/bundle | 3 +++ bin/compass | 16 ++++++++++++++++ bin/cucumber | 16 ++++++++++++++++ bin/foreman | 16 ++++++++++++++++ bin/guard | 16 ++++++++++++++++ bin/rails | 4 ++++ bin/rake | 4 ++++ bin/rspec | 16 ++++++++++++++++ bin/sass | 16 ++++++++++++++++ bin/sass-convert | 16 ++++++++++++++++ bin/scss | 16 ++++++++++++++++ bin/spork | 16 ++++++++++++++++ 14 files changed, 171 insertions(+), 1 deletion(-) create mode 100755 bin/autospec create mode 100755 bin/bundle create mode 100755 bin/compass create mode 100755 bin/cucumber create mode 100755 bin/foreman create mode 100755 bin/guard create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/rspec create mode 100755 bin/sass create mode 100755 bin/sass-convert create mode 100755 bin/scss create mode 100755 bin/spork diff --git a/.gitignore b/.gitignore index 4daa11583..94b2a7bfc 100644 --- a/.gitignore +++ b/.gitignore @@ -58,7 +58,6 @@ tmp/ *.swp *~ *# -bin/* nbproject patches-* capybara-*.html diff --git a/bin/autospec b/bin/autospec new file mode 100755 index 000000000..64dcb9cb0 --- /dev/null +++ b/bin/autospec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'autospec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'autospec') diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..66e9889e8 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/compass b/bin/compass new file mode 100755 index 000000000..e1ac74938 --- /dev/null +++ b/bin/compass @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'compass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('compass', 'compass') diff --git a/bin/cucumber b/bin/cucumber new file mode 100755 index 000000000..caa06543c --- /dev/null +++ b/bin/cucumber @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'cucumber' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('cucumber', 'cucumber') diff --git a/bin/foreman b/bin/foreman new file mode 100755 index 000000000..586c07e08 --- /dev/null +++ b/bin/foreman @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'foreman' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('foreman', 'foreman') diff --git a/bin/guard b/bin/guard new file mode 100755 index 000000000..0c1a532bd --- /dev/null +++ b/bin/guard @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'guard' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('guard', 'guard') diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..728cd85aa --- /dev/null +++ b/bin/rails @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +APP_PATH = File.expand_path('../../config/application', __FILE__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..17240489f --- /dev/null +++ b/bin/rake @@ -0,0 +1,4 @@ +#!/usr/bin/env ruby +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/rspec b/bin/rspec new file mode 100755 index 000000000..0c86b5c6f --- /dev/null +++ b/bin/rspec @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'rspec' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('rspec-core', 'rspec') diff --git a/bin/sass b/bin/sass new file mode 100755 index 000000000..d65bb10a3 --- /dev/null +++ b/bin/sass @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'sass' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sass', 'sass') diff --git a/bin/sass-convert b/bin/sass-convert new file mode 100755 index 000000000..ddde743f3 --- /dev/null +++ b/bin/sass-convert @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'sass-convert' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sass', 'sass-convert') diff --git a/bin/scss b/bin/scss new file mode 100755 index 000000000..9f5e435d6 --- /dev/null +++ b/bin/scss @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'scss' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('sass', 'scss') diff --git a/bin/spork b/bin/spork new file mode 100755 index 000000000..a127260ef --- /dev/null +++ b/bin/spork @@ -0,0 +1,16 @@ +#!/usr/bin/env ruby +# +# This file was generated by Bundler. +# +# The application 'spork' is installed as part of a gem, and +# this file is here to facilitate running it. +# + +require 'pathname' +ENV['BUNDLE_GEMFILE'] ||= File.expand_path("../../Gemfile", + Pathname.new(__FILE__).realpath) + +require 'rubygems' +require 'bundler/setup' + +load Gem.bin_path('spork', 'spork') From d75632401be015b58359ee7811740d7ce0d3eae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 01:17:10 +0200 Subject: [PATCH 005/785] make everything boot again --- Changelog.md | 13 ++++++++++++ config/application.rb | 13 ++---------- config/boot.rb | 2 -- config/environments/development.rb | 13 +++++------- config/environments/integration.rb | 2 -- config/environments/production.rb | 21 ++++++++----------- config/environments/test.rb | 11 +++++----- .../initializers/filter_parameter_logging.rb | 4 ++++ config/initializers/load_libraries.rb | 1 - config/initializers/session_store.rb | 11 +--------- config/routes.rb | 20 +++++++++--------- lib/configuration_methods.rb | 2 +- lib/tasks/generate_session_secret.rake | 13 ++++++------ 13 files changed, 57 insertions(+), 69 deletions(-) create mode 100644 config/initializers/filter_parameter_logging.rb diff --git a/Changelog.md b/Changelog.md index 9dc39b2bc..3857127e3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -1,5 +1,18 @@ # Head +## Rails 4 - Manual action required +Please edit `config/initializers/secret_token.rb`, replacing `secret_token` with +`secret_key_base`. + +```ruby +# Old +Rails.application.config.secret_token = '***********...' + +# New +Diaspora::Application.config.secret_key_base = '*************...' +``` + + ## Refactor * Port help pages to Bootstrap [#5050](https://github.com/diaspora/diaspora/pull/5050) * Refactor Notification#notify [#4945](https://github.com/diaspora/diaspora/pull/4945) diff --git a/config/application.rb b/config/application.rb index a33413f0d..a54bdeb32 100644 --- a/config/application.rb +++ b/config/application.rb @@ -1,7 +1,7 @@ require_relative 'boot' require 'rails/all' -Bundler.require(*Rails.groups(:assets => %w(development test))) if defined?(Bundler) +Bundler.require(:default, Rails.env) # Load asset_sync early require_relative 'asset_sync' @@ -34,9 +34,6 @@ module Diaspora # Configure the default encoding used in templates for Ruby 1.9. config.encoding = "utf-8" - # Configure sensitive parameters which will be filtered from the log file. - config.filter_parameters += [:password, :xml,:message, :text, :bio] - # Enable escaping HTML in JSON. config.active_support.escape_html_entities_in_json = true @@ -45,12 +42,6 @@ module Diaspora # like if you have constraints or database-specific column types # config.active_record.schema_format = :sql - # Enforce whitelist mode for mass assignment. - # This will create an empty whitelist of attributes available for mass-assignment for all models - # in your app. As such, your models will need to explicitly whitelist or blacklist accessible - # parameters by using an attr_accessible or attr_protected declaration. - #config.active_record.whitelist_attributes = false - # Enable the asset pipeline config.assets.enabled = true @@ -59,7 +50,7 @@ module Diaspora # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added) config.assets.precompile += %w{ - aspect-contacts.js + aspect-contacts.js contact-list.js home.js ie.js diff --git a/config/boot.rb b/config/boot.rb index 0eee595af..6e3d23427 100644 --- a/config/boot.rb +++ b/config/boot.rb @@ -1,5 +1,3 @@ -require 'rubygems' - # Set up gems listed in the Gemfile. ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE']) diff --git a/config/environments/development.rb b/config/environments/development.rb index 309cbce28..138c8ccd5 100644 --- a/config/environments/development.rb +++ b/config/environments/development.rb @@ -6,8 +6,8 @@ Diaspora::Application.configure do # since you don't have to restart the web server when you make code changes. config.cache_classes = false - # Log error messages when you accidentally call methods on nil. - config.whiny_nils = true + # Do not eager load code on boot. + config.eager_load = false # Show full error reports and disable caching config.consider_all_requests_local = true @@ -16,18 +16,15 @@ Diaspora::Application.configure do # Don't care if the mailer can't send config.action_mailer.raise_delivery_errors = false + # Raise an error on page load if there are pending migrations + config.active_record.migration_error = :page_load + # Print deprecation notices to the Rails logger config.active_support.deprecation = :log # Only use best-standards-support built into browsers config.action_dispatch.best_standards_support = :builtin - # Raise exception on mass assignment protection for Active Record models - #config.active_record.mass_assignment_sanitizer = :strict - - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 # Do not compress assets config.assets.compress = false diff --git a/config/environments/integration.rb b/config/environments/integration.rb index 0a1b06f80..0fc42e916 100644 --- a/config/environments/integration.rb +++ b/config/environments/integration.rb @@ -1,6 +1,4 @@ require Rails.root.join('config', 'environment', 'development') Diaspora::Application.configure do - # Enable threaded mode - config.threadsafe! end diff --git a/config/environments/production.rb b/config/environments/production.rb index 666622309..2d54ebf5f 100644 --- a/config/environments/production.rb +++ b/config/environments/production.rb @@ -4,6 +4,12 @@ Diaspora::Application.configure do # Code is not reloaded between requests config.cache_classes = true + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both thread web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + # Full error reports are disabled and caching is turned on config.consider_all_requests_local = false config.action_controller.perform_caching = true @@ -11,8 +17,9 @@ Diaspora::Application.configure do # Disable Rails's static asset server (Apache or nginx will already do this) config.serve_static_assets = false - # Compress JavaScripts and CSS - config.assets.compress = true + # Compress JavaScripts and CSS. + config.assets.js_compressor = :uglifier + # config.assets.css_compressor = :sass # Don't fallback to assets pipeline if a precompiled asset is missed config.assets.compile = false @@ -20,9 +27,6 @@ Diaspora::Application.configure do # Generate digests for assets URLs config.assets.digest = true - # Defaults to nil and saved in location specified by config.assets.prefix - # config.assets.manifest = YOUR_PATH - # Specifies the header that your server uses for sending files # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx @@ -51,9 +55,6 @@ Diaspora::Application.configure do # Disable delivery errors, bad email addresses will be ignored # config.action_mailer.raise_delivery_errors = false - # Enable threaded mode - config.threadsafe! - # Enable autoload for rake tasks config.dependency_loading = true if $rails_rake_task @@ -64,10 +65,6 @@ Diaspora::Application.configure do # Send deprecation notices to registered listeners config.active_support.deprecation = :notify - # Log the query plan for queries taking more than this (works - # with SQLite, MySQL, and PostgreSQL) - # config.active_record.auto_explain_threshold_in_seconds = 0.5 - # For nginx: config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' diff --git a/config/environments/test.rb b/config/environments/test.rb index 074be4cca..60bef0305 100644 --- a/config/environments/test.rb +++ b/config/environments/test.rb @@ -7,13 +7,15 @@ Diaspora::Application.configure do # and recreated between test runs. Don't rely on the data there! config.cache_classes = true + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + # Configure static asset server for tests with Cache-Control for performance config.serve_static_assets = true config.static_cache_control = "public, max-age=3600" - # Log error messages when you accidentally call methods on nil - config.whiny_nils = true - # Show full error reports and disable caching config.consider_all_requests_local = true config.action_controller.perform_caching = false @@ -29,9 +31,6 @@ Diaspora::Application.configure do # ActionMailer::Base.deliveries array. config.action_mailer.delivery_method = :test - # Raise exception on mass assignment protection for Active Record models - #config.active_record.mass_assignment_sanitizer = :strict - # Print deprecation notices to the stderr config.active_support.deprecation = :stderr end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 000000000..cd871780d --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password, :xml,:message, :text, :bio] diff --git a/config/initializers/load_libraries.rb b/config/initializers/load_libraries.rb index 29ddab022..87f46ccad 100644 --- a/config/initializers/load_libraries.rb +++ b/config/initializers/load_libraries.rb @@ -3,7 +3,6 @@ require 'cgi' require 'uri' # Not auto required gems -require 'active_support/base64' require 'builder/xchar' require 'carrierwave/orm/activerecord' require 'erb' diff --git a/config/initializers/session_store.rb b/config/initializers/session_store.rb index e46823d17..d2e9c4e29 100644 --- a/config/initializers/session_store.rb +++ b/config/initializers/session_store.rb @@ -1,12 +1,3 @@ -# Copyright (c) 2010-2011, Diaspora Inc. This file is -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. - # Be sure to restart your server when you modify this file. -Rails.application.config.session_store :cookie_store, key: '_diaspora_session', httponly: false - -# Use the database for sessions instead of the cookie-based default, -# which shouldn't be used to store highly confidential information -# (create the session table with "rake db:sessions:create") -# Rails.application.config.session_store :active_record_store +Diaspora::Application.config.session_store :cookie_store, key: '_diaspora_session', httponly: false diff --git a/config/routes.rb b/config/routes.rb index 519a731f4..6bc3b0265 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -49,8 +49,8 @@ Diaspora::Application.routes.draw do end # Streams - get "participate" => "streams#activity", :as => "activity_stream" # legacy - get "explore" => "streams#multi", :as => "stream" # legacy + get "participate" => "streams#activity" # legacy + get "explore" => "streams#multi" # legacy get "activity" => "streams#activity", :as => "activity_stream" get "stream" => "streams#multi", :as => "stream" @@ -104,15 +104,15 @@ Diaspora::Application.routes.draw do controller :users do get 'public/:username' => :public, :as => 'users_public' - match 'getting_started' => :getting_started, :as => 'getting_started' - match 'privacy' => :privacy_settings, :as => 'privacy_settings' + get 'getting_started' => :getting_started, :as => 'getting_started' + get 'privacy' => :privacy_settings, :as => 'privacy_settings' get 'getting_started_completed' => :getting_started_completed get 'confirm_email/:token' => :confirm_email, :as => 'confirm_email' end # This is a hack to overide a route created by devise. # I couldn't find anything in devise to skip that route, see Bug #961 - match 'users/edit' => redirect('/user/edit') + get 'users/edit' => redirect('/user/edit') devise_for :users, :controllers => {:registrations => "registrations", :passwords => "passwords", @@ -122,14 +122,14 @@ Diaspora::Application.routes.draw do get 'users/invitation/accept' => 'invitations#edit' get 'invitations/email' => 'invitations#email', :as => 'invite_email' get 'users/invitations' => 'invitations#new', :as => 'new_user_invitation' - post 'users/invitations' => 'invitations#create', :as => 'new_user_invitation' + post 'users/invitations' => 'invitations#create', :as => 'user_invitation' get 'login' => redirect('/users/sign_in') # Admin backend routes scope 'admins', :controller => :admins do - match :user_search + match :user_search, via: [:get, :post] get :admin_inviter get :weekly_user_stats get :correlations @@ -193,8 +193,8 @@ Diaspora::Application.routes.draw do resources :services, :only => [:index, :destroy] controller :services do scope "/auth", :as => "auth" do - match ':provider/callback' => :create - match :failure + get ':provider/callback' => :create + get :failure end end @@ -214,7 +214,7 @@ Diaspora::Application.routes.draw do get 'mobile/toggle', :to => 'home#toggle_mobile', :as => 'toggle_mobile' - # help + # Help get 'help' => 'help#faq', :as => 'help' #Protocol Url diff --git a/lib/configuration_methods.rb b/lib/configuration_methods.rb index 5fcf4246e..19b852a42 100644 --- a/lib/configuration_methods.rb +++ b/lib/configuration_methods.rb @@ -47,7 +47,7 @@ module Configuration `bundle exec rake generate:secret_token` end require token_file - Rails.application.config.secret_token + Diaspora::Application.config.secret_key_base end end diff --git a/lib/tasks/generate_session_secret.rake b/lib/tasks/generate_session_secret.rake index 0d819ce67..cab226177 100644 --- a/lib/tasks/generate_session_secret.rake +++ b/lib/tasks/generate_session_secret.rake @@ -6,17 +6,18 @@ namespace :generate do secret = SecureRandom.hex(40) File.open(path, 'w') do |f| f.write <<"EOF" -# Copyright (c) 2010-2011, Diaspora Inc. This file is -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. - # Be sure to restart your server when you modify this file. -# Your secret key for verifying the integrity of signed cookies. +# Your secret key is used for verifying the integrity of signed cookies. # If you change this key, all old signed cookies will become invalid! + # Make sure the secret is at least 30 characters and all random, # no regular words or you'll be exposed to dictionary attacks. -Rails.application.config.secret_token = '#{secret}' +# You can use `rake secret` to generate a secure secret key. + +# Make sure your secret_key_base is kept private +# if you're sharing your code publicly. +Diaspora::Application.config.secret_key_base = '#{secret}' EOF end From 33c3b38f2f8c6ede39b1357eb3cb49f18543cdce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 13:34:17 +0200 Subject: [PATCH 006/785] replace deprecated finder and finder_options syntax --- app/controllers/admins_controller.rb | 4 ++-- app/controllers/notifications_controller.rb | 12 +++++------- app/controllers/tag_followings_controller.rb | 4 ++-- app/models/conversation.rb | 4 ++-- app/models/o_embed_cache.rb | 6 +++--- app/models/open_graph_cache.rb | 6 +++--- app/models/pod.rb | 6 +++--- app/models/role.rb | 4 ++-- app/models/share_visibility.rb | 6 +++++- app/models/status_message.rb | 2 +- app/models/user.rb | 6 +++--- app/models/user/connecting.rb | 4 ++-- app/workers/gather_o_embed_data.rb | 2 +- app/workers/gather_open_graph_data.rb | 2 +- features/step_definitions/user_steps.rb | 2 +- lib/diaspora/exporter.rb | 4 ++-- lib/diaspora/federated/request.rb | 4 ++-- lib/hydra_wrapper.rb | 2 +- lib/tasks/migrations.rake | 2 +- spec/lib/stream/multi_spec.rb | 2 +- spec/models/pod_spec.rb | 6 +++--- spec/models/user/connecting_spec.rb | 8 ++++---- spec/workers/gather_o_embed_data_spec.rb | 2 +- spec/workers/gather_open_graph_data_spec.rb | 2 +- 24 files changed, 52 insertions(+), 50 deletions(-) diff --git a/app/controllers/admins_controller.rb b/app/controllers/admins_controller.rb index 7bf3f6830..b9af10e9a 100644 --- a/app/controllers/admins_controller.rb +++ b/app/controllers/admins_controller.rb @@ -46,7 +46,7 @@ class AdminsController < Admin::AdminController end def stats - @popular_tags = ActsAsTaggableOn::Tagging.joins(:tag).limit(50).count(:group => :tag, :order => 'count(taggings.id) DESC') + @popular_tags = ActsAsTaggableOn::Tagging.joins(:tag).limit(50).order('count(taggings.id) DESC').group(:tag).count case params[:range] when "week" @@ -67,7 +67,7 @@ class AdminsController < Admin::AdminController create_hash(model, :range => range) end - @posts_per_day = Post.count(:group => "DATE(created_at)", :conditions => ["created_at >= ?", Date.today - 21.days], :order => "DATE(created_at) ASC") + @posts_per_day = Post.where("created_at >= ?", Date.today - 21.days).group("DATE(created_at)").order("DATE(created_at) ASC").count @most_posts_within = @posts_per_day.values.max.to_f @user_count = User.count diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index 4354093bc..ef98e5b14 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -33,13 +33,11 @@ class NotificationsController < ApplicationController page = params[:page] || 1 per_page = params[:per_page] || 25 @notifications = WillPaginate::Collection.create(page, per_page, Notification.where(conditions).count ) do |pager| - result = Notification.find(:all, - :conditions => conditions, - :order => 'created_at desc', - :include => [:target, {:actors => :profile}], - :limit => pager.per_page, - :offset => pager.offset - ) + result = Notification.where(conditions) + .includes(:target, :actors => :profile) + .order('created_at desc') + .limit(pager.per_page) + .offset(pager.offset) pager.replace(result) end diff --git a/app/controllers/tag_followings_controller.rb b/app/controllers/tag_followings_controller.rb index c447d9e92..94299bf8f 100644 --- a/app/controllers/tag_followings_controller.rb +++ b/app/controllers/tag_followings_controller.rb @@ -16,7 +16,7 @@ class TagFollowingsController < ApplicationController if name_normalized.nil? || name_normalized.empty? render :nothing => true, :status => 403 else - @tag = ActsAsTaggableOn::Tag.find_or_create_by_name(name_normalized) + @tag = ActsAsTaggableOn::Tag.find_or_create_by(name: name_normalized) @tag_following = current_user.tag_followings.new(:tag_id => @tag.id) if @tag_following.save @@ -31,7 +31,7 @@ class TagFollowingsController < ApplicationController # DELETE /tag_followings/1.xml def destroy tag_following = current_user.tag_followings.find_by_tag_id( params['id'] ) - + if tag_following && tag_following.destroy respond_to do |format| format.any(:js, :json) { render :nothing => true, :status => 204 } diff --git a/app/models/conversation.rb b/app/models/conversation.rb index fee57d81f..ae776cd54 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -68,10 +68,10 @@ class Conversation < ActiveRecord::Base end def receive(user, person) - cnv = Conversation.find_or_create_by_guid(self.attributes) + cnv = Conversation.find_or_create_by(self.attributes) self.participants.each do |participant| - ConversationVisibility.find_or_create_by_conversation_id_and_person_id(cnv.id, participant.id) + ConversationVisibility.find_or_create_by(conversation_id: cnv.id, person_id: participant.id) end self.messages.each do |msg| diff --git a/app/models/o_embed_cache.rb b/app/models/o_embed_cache.rb index 9aee6d00b..17e6f073f 100644 --- a/app/models/o_embed_cache.rb +++ b/app/models/o_embed_cache.rb @@ -10,10 +10,10 @@ class OEmbedCache < ActiveRecord::Base t.add :data end - def self.find_or_create_by_url(url) - cache = OEmbedCache.find_or_initialize_by_url(url) + def self.find_or_create_by(opts) + cache = OEmbedCache.find_or_initialize_by(opts) return cache if cache.persisted? - cache.fetch_and_save_oembed_data! + cache.fetch_and_save_oembed_data! # make after create callback and drop this method ? cache end diff --git a/app/models/open_graph_cache.rb b/app/models/open_graph_cache.rb index 8ec435719..e3b78e48a 100644 --- a/app/models/open_graph_cache.rb +++ b/app/models/open_graph_cache.rb @@ -21,10 +21,10 @@ class OpenGraphCache < ActiveRecord::Base t.add :url end - def self.find_or_create_by_url(url) - cache = OpenGraphCache.find_or_initialize_by_url(url) + def self.find_or_create_by(opts) + cache = OpenGraphCache.find_or_initialize_by(opts) cache.fetch_and_save_opengraph_data! unless cache.persisted? - cache if cache.persisted? + cache if cache.persisted? # Make this an after create callback and drop this method ? end def fetch_and_save_opengraph_data! diff --git a/app/models/pod.rb b/app/models/pod.rb index fb5f35477..dcd23b310 100644 --- a/app/models/pod.rb +++ b/app/models/pod.rb @@ -1,7 +1,7 @@ class Pod < ActiveRecord::Base - def self.find_or_create_by_url(url) - u = URI.parse(url) - pod = self.find_or_initialize_by_host(u.host) + def self.find_or_create_by(opts) # Rename this method to not override an AR method + u = URI.parse(opts.fetch(:url)) + pod = self.find_or_initialize_by(host: u.host) unless pod.persisted? pod.ssl = (u.scheme == 'https')? true : false pod.save diff --git a/app/models/role.rb b/app/models/role.rb index 40438a035..928035223 100644 --- a/app/models/role.rb +++ b/app/models/role.rb @@ -9,10 +9,10 @@ class Role < ActiveRecord::Base end def self.add_admin(person) - find_or_create_by_person_id_and_name(person.id, 'admin') + find_or_create_by(person_id: person.id, name: 'admin') end def self.add_spotlight(person) - find_or_create_by_person_id_and_name(person.id, 'spotlight') + find_or_create_by(person_id: person.id, name: 'spotlight') end end diff --git a/app/models/share_visibility.rb b/app/models/share_visibility.rb index 67f42661a..d2a92e2de 100644 --- a/app/models/share_visibility.rb +++ b/app/models/share_visibility.rb @@ -25,7 +25,11 @@ class ShareVisibility < ActiveRecord::Base if AppConfig.postgres? contact_ids.each do |contact_id| - ShareVisibility.find_or_create_by_contact_id_and_shareable_id_and_shareable_type(contact_id, share.id, share.class.base_class.to_s) + ShareVisibility.find_or_create_by( + contact_id: contact_id, + shareable_id: share.id, + shareable_type: share.class.base_class.to_s + ) end else new_share_visibilities_data = contact_ids.map do |contact_id| diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 5f10f6aef..80a43c62c 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -98,7 +98,7 @@ class StatusMessage < Post def create_mentions ppl = Diaspora::Mentionable.people_from_string(self.raw_message) ppl.each do |person| - self.mentions.find_or_create_by_person_id(person.id) + self.mentions.find_or_create_by(person_id: person.id) end end diff --git a/app/models/user.rb b/app/models/user.rb index 2e9168a80..4419058c2 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -102,7 +102,7 @@ class User < ActiveRecord::Base def invitation_code - InvitationCode.find_or_create_by_user_id(self.id) + InvitationCode.find_or_create_by(user_id: self.id) end def hidden_shareables @@ -163,14 +163,14 @@ class User < ActiveRecord::Base def update_user_preferences(pref_hash) if self.disable_mail - UserPreference::VALID_EMAIL_TYPES.each{|x| self.user_preferences.find_or_create_by_email_type(x)} + UserPreference::VALID_EMAIL_TYPES.each{|x| self.user_preferences.find_or_create_by(email_type: x)} self.disable_mail = false self.save end pref_hash.keys.each do |key| if pref_hash[key] == 'true' - self.user_preferences.find_or_create_by_email_type(key) + self.user_preferences.find_or_create_by(email_type: key) else block = self.user_preferences.where(:email_type => key).first if block diff --git a/app/models/user/connecting.rb b/app/models/user/connecting.rb index e90133330..6eaf55bef 100644 --- a/app/models/user/connecting.rb +++ b/app/models/user/connecting.rb @@ -8,7 +8,7 @@ module User::Connecting # @param [Aspect] aspect The aspect to add them to. # @return [Contact] The newly made contact for the passed in person. def share_with(person, aspect) - contact = self.contacts.find_or_initialize_by_person_id(person.id) + contact = self.contacts.find_or_initialize_by(person_id: person.id) return false unless contact.valid? unless contact.receiving? @@ -22,7 +22,7 @@ module User::Connecting if notification = Notification.where(:target_id => person.id).first notification.update_attributes(:unread=>false) end - + deliver_profile_update register_share_visibilities(contact) contact diff --git a/app/workers/gather_o_embed_data.rb b/app/workers/gather_o_embed_data.rb index 2f8c90119..cb0ad0819 100644 --- a/app/workers/gather_o_embed_data.rb +++ b/app/workers/gather_o_embed_data.rb @@ -9,7 +9,7 @@ module Workers def perform(post_id, url, retry_count=1) post = Post.find(post_id) - post.o_embed_cache = OEmbedCache.find_or_create_by_url(url) + post.o_embed_cache = OEmbedCache.find_or_create_by(url: url) post.save rescue ActiveRecord::RecordNotFound # User created a post and deleted it right afterwards before we diff --git a/app/workers/gather_open_graph_data.rb b/app/workers/gather_open_graph_data.rb index d73954d86..18c97ab8b 100644 --- a/app/workers/gather_open_graph_data.rb +++ b/app/workers/gather_open_graph_data.rb @@ -9,7 +9,7 @@ module Workers def perform(post_id, url, retry_count=1) post = Post.find(post_id) - post.open_graph_cache = OpenGraphCache.find_or_create_by_url(url) + post.open_graph_cache = OpenGraphCache.find_or_create_by(url: url) post.save rescue ActiveRecord::RecordNotFound # User created a post and deleted it right afterwards before we diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb index 89f49be03..b81869cd5 100644 --- a/features/step_definitions/user_steps.rb +++ b/features/step_definitions/user_steps.rb @@ -201,7 +201,7 @@ end Given /^I visit alice's invitation code url$/ do @alice ||= FactoryGirl.create(:user, :username => 'alice', :getting_started => false) - invite_code = InvitationCode.find_or_create_by_user_id(@alice.id) + invite_code = InvitationCode.find_or_create_by(user_id: @alice.id) visit invite_code_path(invite_code) end diff --git a/lib/diaspora/exporter.rb b/lib/diaspora/exporter.rb index 80f0814f1..6360d635c 100644 --- a/lib/diaspora/exporter.rb +++ b/lib/diaspora/exporter.rb @@ -37,7 +37,7 @@ module Diaspora #} xml.post_ids { - aspect.posts.find_all_by_author_id(user_person_id).each do |post| + aspect.posts.where(author_id: user_person_id).each do |post| xml.post_id post.id end } @@ -64,7 +64,7 @@ module Diaspora } xml.posts { - user.visible_shareables(Post).find_all_by_author_id(user_person_id).each do |post| + user.visible_shareables(Post).where(author_id: user_person_id).each do |post| #post.comments.each do |comment| # post_doc << comment.to_xml #end diff --git a/lib/diaspora/federated/request.rb b/lib/diaspora/federated/request.rb index 0b0f446b3..a920fba7c 100644 --- a/lib/diaspora/federated/request.rb +++ b/lib/diaspora/federated/request.rb @@ -75,10 +75,10 @@ class Request def receive(user, person) Rails.logger.info("event=receive payload_type=request sender=#{self.sender} to=#{self.recipient}") - contact = user.contacts.find_or_initialize_by_person_id(self.sender.id) + contact = user.contacts.find_or_initialize_by(person_id: self.sender.id) contact.sharing = true contact.save - + user.share_with(person, user.auto_follow_back_aspect) if user.auto_follow_back && !contact.receiving self diff --git a/lib/hydra_wrapper.rb b/lib/hydra_wrapper.rb index e22d94d7f..f7f3c7c2b 100644 --- a/lib/hydra_wrapper.rb +++ b/lib/hydra_wrapper.rb @@ -83,7 +83,7 @@ class HydraWrapper def prepare_request request, people_for_receive_url request.on_complete do |response| # Save the reference to the pod to the database if not already present - Pod.find_or_create_by_url response.effective_url + Pod.find_or_create_by(url: response.effective_url) if redirecting_to_https? response Person.url_batch_update people_for_receive_url, response.headers_hash['Location'] diff --git a/lib/tasks/migrations.rake b/lib/tasks/migrations.rake index f0b8498d0..20d7d42d8 100644 --- a/lib/tasks/migrations.rake +++ b/lib/tasks/migrations.rake @@ -82,7 +82,7 @@ namespace :migrations do puts "found #{evil_tags.count} tags to convert..." evil_tags.each_with_index do |tag, i| - good_tag = ActsAsTaggableOn::Tag.find_or_create_by_name(tag.name.mb_chars.downcase) + good_tag = ActsAsTaggableOn::Tag.first_or_create_by(name: tag.name.mb_chars.downcase) puts "++ '#{tag.name}' has #{tag.taggings.count} records attached" taggings = tag.taggings diff --git a/spec/lib/stream/multi_spec.rb b/spec/lib/stream/multi_spec.rb index 6b13c046f..bdee98683 100644 --- a/spec/lib/stream/multi_spec.rb +++ b/spec/lib/stream/multi_spec.rb @@ -40,7 +40,7 @@ describe Stream::Multi do describe "#publisher_prefill" do before do - @tag = ActsAsTaggableOn::Tag.find_or_create_by_name("cats") + @tag = ActsAsTaggableOn::Tag.find_or_create_by(name: "cats") @tag_following = alice.tag_followings.create(:tag_id => @tag.id) @stream = Stream::Multi.new(alice) diff --git a/spec/models/pod_spec.rb b/spec/models/pod_spec.rb index 5cee347e9..8a979a21f 100644 --- a/spec/models/pod_spec.rb +++ b/spec/models/pod_spec.rb @@ -1,14 +1,14 @@ require 'spec_helper' describe Pod do - describe '.find_or_create_by_url' do + describe '.find_or_create_by' do it 'takes a url, and makes one by host' do - pod = Pod.find_or_create_by_url('https://joindiaspora.com/maxwell') + pod = Pod.find_or_create_by(url: 'https://joindiaspora.com/maxwell') pod.host.should == 'joindiaspora.com' end it 'sets ssl boolean(side-effect)' do - pod = Pod.find_or_create_by_url('https://joindiaspora.com/maxwell') + pod = Pod.find_or_create_by(url: 'https://joindiaspora.com/maxwell') pod.ssl.should be_true end end diff --git a/spec/models/user/connecting_spec.rb b/spec/models/user/connecting_spec.rb index e01e679e8..5d64d172c 100644 --- a/spec/models/user/connecting_spec.rb +++ b/spec/models/user/connecting_spec.rb @@ -113,7 +113,7 @@ describe User::Connecting do it 'adds a contact to an aspect' do contact = alice.contacts.create(:person => eve.person) - alice.contacts.stub(:find_or_initialize_by_person_id).and_return(contact) + alice.contacts.stub(:find_or_initialize_by).and_return(contact) lambda { alice.share_with(eve.person, alice.aspects.first) @@ -128,7 +128,7 @@ describe User::Connecting do context 'dispatching' do it 'dispatches a request on initial request' do contact = alice.contacts.new(:person => eve.person) - alice.contacts.stub(:find_or_initialize_by_person_id).and_return(contact) + alice.contacts.stub(:find_or_initialize_by).and_return(contact) contact.should_receive(:dispatch_request) alice.share_with(eve.person, alice.aspects.first) @@ -138,7 +138,7 @@ describe User::Connecting do eve.share_with(alice.person, eve.aspects.first) contact = alice.contact_for(eve.person) - alice.contacts.stub(:find_or_initialize_by_person_id).and_return(contact) + alice.contacts.stub(:find_or_initialize_by).and_return(contact) contact.should_receive(:dispatch_request) alice.share_with(eve.person, alice.aspects.first) @@ -148,7 +148,7 @@ describe User::Connecting do a2 = alice.aspects.create(:name => "two") contact = alice.contacts.create(:person => eve.person, :receiving => true) - alice.contacts.stub(:find_or_initialize_by_person_id).and_return(contact) + alice.contacts.stub(:find_or_initialize_by).and_return(contact) contact.should_not_receive(:dispatch_request) alice.share_with(eve.person, a2) diff --git a/spec/workers/gather_o_embed_data_spec.rb b/spec/workers/gather_o_embed_data_spec.rb index 361502c0e..1593ed4e0 100644 --- a/spec/workers/gather_o_embed_data_spec.rb +++ b/spec/workers/gather_o_embed_data_spec.rb @@ -51,7 +51,7 @@ describe Workers::GatherOEmbedData do OEmbedCache.find_by_url(@flickr_photo_url).data.should == expected_data Workers::GatherOEmbedData.new.perform(@status_message.id, @flickr_photo_url) - OEmbedCache.count(:conditions => {:url => @flickr_photo_url}).should == 1 + OEmbedCache.where(url: @flickr_photo_url).count.should == 1 end it 'creates no cache entry for unsupported pages' do diff --git a/spec/workers/gather_open_graph_data_spec.rb b/spec/workers/gather_open_graph_data_spec.rb index c7a2a8f2b..dbe53ff81 100644 --- a/spec/workers/gather_open_graph_data_spec.rb +++ b/spec/workers/gather_open_graph_data_spec.rb @@ -51,7 +51,7 @@ describe Workers::GatherOpenGraphData do ogc.description.should == @ogsite_description Workers::GatherOpenGraphData.new.perform(@status_message.id, @ogsite_url) - OpenGraphCache.count(:conditions => {:url => @ogsite_url}).should == 1 + OpenGraphCache.where(url: @ogsite_url).count.should == 1 end it 'creates no cache entry for unsupported pages' do From 89afb616cfe2c52b10ff63875f600943097da563 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 13:46:47 +0200 Subject: [PATCH 007/785] replace deprecated scope syntax and unify it --- app/models/comment.rb | 4 ++-- app/models/contact.rb | 18 ++++++------------ app/models/person.rb | 28 ++++++++++++++++++---------- app/models/photo.rb | 9 +++++---- app/models/post.rb | 20 ++++++++++++++------ app/models/share_visibility.rb | 5 +++-- app/models/status_message.rb | 2 +- app/models/user.rb | 10 +++++----- lib/diaspora/shareable.rb | 2 +- 9 files changed, 55 insertions(+), 43 deletions(-) diff --git a/app/models/comment.rb b/app/models/comment.rb index 5fe754c8b..b71fcaa22 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -30,8 +30,8 @@ class Comment < ActiveRecord::Base validates :text, :presence => true, :length => {:maximum => 65535} validates :parent, :presence => true #should be in relayable (pending on fixing Message) - scope :including_author, includes(:author => :profile) - scope :for_a_stream, including_author.merge(order('created_at ASC')) + scope :including_author, -> { includes(:author => :profile) } + scope :for_a_stream, -> { including_author.merge(order('created_at ASC')) } before_save do self.text.strip! unless self.text.nil? diff --git a/app/models/contact.rb b/app/models/contact.rb index 1a428a898..1d7755784 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -7,7 +7,7 @@ class Contact < ActiveRecord::Base belongs_to :person validates :person, :presence => true - + delegate :name, :diaspora_handle, :guid, :first_name, to: :person, prefix: true @@ -26,26 +26,20 @@ class Contact < ActiveRecord::Base before_destroy :destroy_notifications - scope :all_contacts_of_person, lambda {|x| where(:person_id => x.id)} + scope :all_contacts_of_person, ->(x) { where(:person_id => x.id) } # contact.sharing is true when contact.person is sharing with contact.user - scope :sharing, lambda { - where(:sharing => true) - } + scope :sharing, -> { where(:sharing => true) } # contact.receiving is true when contact.user is sharing with contact.person - scope :receiving, lambda { - where(:receiving => true) - } + scope :receiving, -> { where(:receiving => true) } - scope :for_a_stream, lambda { + scope :for_a_stream, -> { includes(:aspects, :person => :profile). order('profiles.last_name ASC') } - scope :only_sharing, lambda { - sharing.where(:receiving => false) - } + scope :only_sharing, -> { sharing.where(:receiving => false) } def destroy_notifications Notification.where(:target_type => "Person", diff --git a/app/models/person.rb b/app/models/person.rb index 765a8539a..163f94e48 100644 --- a/app/models/person.rb +++ b/app/models/person.rb @@ -63,32 +63,40 @@ class Person < ActiveRecord::Base validates :serialized_public_key, :presence => true validates :diaspora_handle, :uniqueness => true - scope :searchable, joins(:profile).where(:profiles => {:searchable => true}) - scope :remote, where('people.owner_id IS NULL') - scope :local, where('people.owner_id IS NOT NULL') - scope :for_json, select('DISTINCT people.id, people.guid, people.diaspora_handle').includes(:profile) + scope :searchable, -> { joins(:profile).where(:profiles => {:searchable => true}) } + scope :remote, -> { where('people.owner_id IS NULL') } + scope :local, -> { where('people.owner_id IS NOT NULL') } + scope :for_json, -> { + select('DISTINCT people.id, people.guid, people.diaspora_handle') + .includes(:profile) + } # @note user is passed in here defensively - scope :all_from_aspects, lambda { |aspect_ids, user| + scope :all_from_aspects, ->(aspect_ids, user) { joins(:contacts => :aspect_memberships). where(:contacts => {:user_id => user.id}). where(:aspect_memberships => {:aspect_id => aspect_ids}) } - scope :unique_from_aspects, lambda{ |aspect_ids, user| + scope :unique_from_aspects, ->(aspect_ids, user) { all_from_aspects(aspect_ids, user).select('DISTINCT people.*') } #not defensive - scope :in_aspects, lambda { |aspect_ids| + scope :in_aspects, ->(aspect_ids) { joins(:contacts => :aspect_memberships). where(:aspect_memberships => {:aspect_id => aspect_ids}) } - scope :profile_tagged_with, lambda{|tag_name| joins(:profile => :tags).where(:tags => {:name => tag_name}).where('profiles.searchable IS TRUE') } + scope :profile_tagged_with, ->(tag_name) { + joins(:profile => :tags) + .where(:tags => {:name => tag_name}) + .where('profiles.searchable IS TRUE') + } - scope :who_have_reshared_a_users_posts, lambda{|user| - joins(:posts).where(:posts => {:root_guid => StatusMessage.guids_for_author(user.person), :type => 'Reshare'} ) + scope :who_have_reshared_a_users_posts, ->(user) { + joins(:posts) + .where(:posts => {:root_guid => StatusMessage.guids_for_author(user.person), :type => 'Reshare'} ) } def self.community_spotlight diff --git a/app/models/photo.rb b/app/models/photo.rb index 60494cc06..1c36cd641 100644 --- a/app/models/photo.rb +++ b/app/models/photo.rb @@ -48,8 +48,13 @@ class Photo < ActiveRecord::Base after_commit :on => :create do queue_processing_job if self.author.local? + end + scope :on_statuses, ->(post_guids) { + where(:status_message_guid => post_guids) + } + def clear_empty_status_message if self.status_message && self.status_message.text_and_photos_blank? self.status_message.destroy @@ -132,8 +137,4 @@ class Photo < ActiveRecord::Base def mutable? true end - - scope :on_statuses, lambda { |post_guids| - where(:status_message_guid => post_guids) - } end diff --git a/app/models/post.rb b/app/models/post.rb index 0cbc9f07d..832a7dbd6 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -31,14 +31,22 @@ class Post < ActiveRecord::Base end #scopes - scope :includes_for_a_stream, includes(:o_embed_cache, :open_graph_cache, {:author => :profile}, :mentions => {:person => :profile}) #note should include root and photos, but i think those are both on status_message - - - scope :commented_by, lambda { |person| - select('DISTINCT posts.*').joins(:comments).where(:comments => {:author_id => person.id}) + scope :includes_for_a_stream, -> { + includes(:o_embed_cache, + :open_graph_cache, + {:author => :profile}, + :mentions => {:person => :profile} + ) #note should include root and photos, but i think those are both on status_message } - scope :liked_by, lambda { |person| + + scope :commented_by, ->(person) { + select('DISTINCT posts.*') + .joins(:comments) + .where(:comments => {:author_id => person.id}) + } + + scope :liked_by, ->(person) { joins(:likes).where(:likes => {:author_id => person.id}) } diff --git a/app/models/share_visibility.rb b/app/models/share_visibility.rb index d2a92e2de..060f65cd2 100644 --- a/app/models/share_visibility.rb +++ b/app/models/share_visibility.rb @@ -6,10 +6,11 @@ class ShareVisibility < ActiveRecord::Base belongs_to :contact belongs_to :shareable, :polymorphic => :true - scope :for_a_users_contacts, lambda { |user| + scope :for_a_users_contacts, ->(user) { where(:contact_id => user.contacts.map {|c| c.id}) } - scope :for_contacts_of_a_person, lambda { |person| + + scope :for_contacts_of_a_person, ->(person) { where(:contact_id => person.contacts.map {|c| c.id}) } diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 80a43c62c..07ac062db 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -40,7 +40,7 @@ class StatusMessage < Post after_commit :queue_gather_open_graph_data, :on => :create, :if => :contains_open_graph_url_in_text? #scopes - scope :where_person_is_mentioned, lambda { |person| + scope :where_person_is_mentioned, ->(person) { joins(:mentions).where(:mentions => {:person_id => person.id}) } diff --git a/app/models/user.rb b/app/models/user.rb index 4419058c2..61d61b299 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -10,11 +10,11 @@ class User < ActiveRecord::Base apply_simple_captcha :message => I18n.t('simple_captcha.message.failed'), :add_to_base => true - scope :logged_in_since, lambda { |time| where('last_seen > ?', time) } - scope :monthly_actives, lambda { |time = Time.now| logged_in_since(time - 1.month) } - scope :daily_actives, lambda { |time = Time.now| logged_in_since(time - 1.day) } - scope :yearly_actives, lambda { |time = Time.now| logged_in_since(time - 1.year) } - scope :halfyear_actives, lambda { |time = Time.now| logged_in_since(time - 6.month) } + scope :logged_in_since, ->(time) { where('last_seen > ?', time) } + scope :monthly_actives, ->(time = Time.now) { logged_in_since(time - 1.month) } + scope :daily_actives, ->(time = Time.now) { logged_in_since(time - 1.day) } + scope :yearly_actives, ->(time = Time.now) { logged_in_since(time - 1.year) } + scope :halfyear_actives, ->(time = Time.now) { logged_in_since(time - 6.month) } devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable, diff --git a/lib/diaspora/shareable.rb b/lib/diaspora/shareable.rb index 6603a45b8..576c0dcce 100644 --- a/lib/diaspora/shareable.rb +++ b/lib/diaspora/shareable.rb @@ -19,7 +19,7 @@ module Diaspora delegate :id, :name, :first_name, to: :author, prefix: true #scopes - scope :all_public, where(:public => true, :pending => false) + scope :all_public, -> { where(:public => true, :pending => false) } def self.owned_or_visible_by_user(user) self.joins("LEFT OUTER JOIN share_visibilities ON share_visibilities.shareable_id = posts.id AND share_visibilities.shareable_type = 'Post'"). From 2f54d4f17de011865bbb7e10ad9997dbaa81f84e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 14:11:08 +0200 Subject: [PATCH 008/785] remove conditions on association deprecation warnings --- app/models/conversation.rb | 2 +- app/models/user.rb | 8 ++++---- lib/diaspora/likeable.rb | 8 ++++---- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/app/models/conversation.rb b/app/models/conversation.rb index ae776cd54..c620efe53 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -10,7 +10,7 @@ class Conversation < ActiveRecord::Base has_many :conversation_visibilities, :dependent => :destroy has_many :participants, :class_name => 'Person', :through => :conversation_visibilities, :source => :person - has_many :messages, :order => 'created_at ASC' + has_many :messages, -> { order('created_at ASC') } belongs_to :author, :class_name => 'Person' diff --git a/app/models/user.rb b/app/models/user.rb index 61d61b299..a37149603 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -44,7 +44,7 @@ class User < ActiveRecord::Base has_many :invitations_from_me, :class_name => 'Invitation', :foreign_key => :sender_id has_many :invitations_to_me, :class_name => 'Invitation', :foreign_key => :recipient_id - has_many :aspects, :order => 'order_id ASC' + has_many :aspects, -> { order('order_id ASC') } belongs_to :auto_follow_back_aspect, :class_name => 'Aspect' belongs_to :invited_by, :class_name => 'User' @@ -59,13 +59,13 @@ class User < ActiveRecord::Base has_many :user_preferences has_many :tag_followings - has_many :followed_tags, :through => :tag_followings, :source => :tag, :order => 'tags.name' + has_many :followed_tags, -> { order('tags.name') }, :through => :tag_followings, :source => :tag has_many :blocks has_many :ignored_people, :through => :blocks, :source => :person - has_many :conversation_visibilities, through: :person, order: 'updated_at DESC' - has_many :conversations, through: :conversation_visibilities, order: 'updated_at DESC' + has_many :conversation_visibilities, -> { order 'updated_at DESC' }, through: :person + has_many :conversations, -> { order 'updated_at DESC' }, through: :conversation_visibilities has_many :notifications, :foreign_key => :recipient_id diff --git a/lib/diaspora/likeable.rb b/lib/diaspora/likeable.rb index 9e05c79b3..bbb84d2ce 100644 --- a/lib/diaspora/likeable.rb +++ b/lib/diaspora/likeable.rb @@ -6,15 +6,15 @@ module Diaspora module Likeable def self.included(model) model.instance_eval do - has_many :likes, :conditions => {:positive => true}, :dependent => :delete_all, :as => :target - has_many :dislikes, :conditions => {:positive => false}, :class_name => 'Like', :dependent => :delete_all, :as => :target + has_many :likes, -> { where(positive: true) }, dependent: :delete_all, as: :target + has_many :dislikes, -> { where(positive: false) }, class_name: 'Like', dependent: :delete_all, as: :target end end # @return [Integer] def update_likes_counter - self.class.where(:id => self.id). - update_all(:likes_count => self.likes.count) + self.class.where(id: self.id). + update_all(likes_count: self.likes.count) end end end From cb195f4d55298f507f620fc9d456d63191eef0e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 14:16:03 +0200 Subject: [PATCH 009/785] access connection through class --- app/models/profile.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/profile.rb b/app/models/profile.rb index 3e0e425e1..83c603335 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -144,7 +144,7 @@ class Profile < ActiveRecord::Base if @tag_string @tag_string else - rows = connection.select_rows( self.tags.scoped.to_sql ) + rows = self.class.connection.select_rows( self.tags.scoped.to_sql ) rows.inject(""){|string, row| string << "##{row[1]} " } end end From 2cca5745c9fbc6a295c58d3dbea7889bc3074922 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 14:26:01 +0200 Subject: [PATCH 010/785] remove deprecated scoped --- app/models/post.rb | 4 ++-- app/models/profile.rb | 4 ++-- lib/stream/base.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index 832a7dbd6..1237e6871 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -85,7 +85,7 @@ class Post < ActiveRecord::Base def self.excluding_blocks(user) people = user.blocks.map{|b| b.person_id} - scope = scoped + scope = all if people.any? scope = scope.where("posts.author_id NOT IN (?)", people) @@ -95,7 +95,7 @@ class Post < ActiveRecord::Base end def self.excluding_hidden_shareables(user) - scope = scoped + scope = all if user.has_hidden_shareables_of_type? scope = scope.where('posts.id NOT IN (?)', user.hidden_shareables["#{self.base_class}"]) end diff --git a/app/models/profile.rb b/app/models/profile.rb index 83c603335..e3e543f29 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -144,8 +144,8 @@ class Profile < ActiveRecord::Base if @tag_string @tag_string else - rows = self.class.connection.select_rows( self.tags.scoped.to_sql ) - rows.inject(""){|string, row| string << "##{row[1]} " } + tags = self.tags.pluck(:name) + tags.inject(""){|string, tag| string << "##{tag} " } end end diff --git a/lib/stream/base.rb b/lib/stream/base.rb index 9a00ee173..77bbbe66a 100644 --- a/lib/stream/base.rb +++ b/lib/stream/base.rb @@ -32,7 +32,7 @@ class Stream::Base # @return [ActiveRecord::Relation] def posts - Post.scoped + Post.all end # @return [Array] From a9e107364a8df1c050ddaa863fc0bf2e18b1f257 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 15:33:38 +0200 Subject: [PATCH 011/785] make status message controller spec pass and deprecation free --- app/models/post.rb | 2 ++ app/models/status_message.rb | 2 +- app/models/user.rb | 2 +- app/workers/deferred_dispatch.rb | 2 +- lib/diaspora/shareable.rb | 2 +- spec/support/user_methods.rb | 1 - 6 files changed, 6 insertions(+), 5 deletions(-) diff --git a/app/models/post.rb b/app/models/post.rb index 1237e6871..18decbbc6 100644 --- a/app/models/post.rb +++ b/app/models/post.rb @@ -26,6 +26,8 @@ class Post < ActiveRecord::Base belongs_to :o_embed_cache belongs_to :open_graph_cache + validates_uniqueness_of :id + after_commit :on => :create do self.touch(:interacted_at) end diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 07ac062db..7269238c1 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -68,7 +68,7 @@ class StatusMessage < Post def attach_photos_by_ids(photo_ids) return [] unless photo_ids.present? - self.photos << Photo.where(:id => photo_ids, :author_id => self.author_id).all + self.photos << Photo.where(:id => photo_ids, :author_id => self.author_id) end def nsfw diff --git a/app/models/user.rb b/app/models/user.rb index a37149603..cd3da1146 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -83,7 +83,7 @@ class User < ActiveRecord::Base end def unread_message_count - ConversationVisibility.sum(:unread, :conditions => "person_id = #{self.person.id}") + ConversationVisibility.where(person_id: self.person_id).sum(:unread) end #@deprecated diff --git a/app/workers/deferred_dispatch.rb b/app/workers/deferred_dispatch.rb index 1833ce9b9..cbb87581a 100644 --- a/app/workers/deferred_dispatch.rb +++ b/app/workers/deferred_dispatch.rb @@ -10,7 +10,7 @@ module Workers user = User.find(user_id) object = object_class_name.constantize.find(object_id) opts = HashWithIndifferentAccess.new(opts) - opts[:services] = user.services.where(:type => opts.delete(:service_types)).all + opts[:services] = user.services.where(:type => opts.delete(:service_types)) if opts[:additional_subscribers].present? opts[:additional_subscribers] = Person.where(:id => opts[:additional_subscribers]) diff --git a/lib/diaspora/shareable.rb b/lib/diaspora/shareable.rb index 576c0dcce..5c34115f8 100644 --- a/lib/diaspora/shareable.rb +++ b/lib/diaspora/shareable.rb @@ -8,7 +8,7 @@ module Diaspora def self.included(model) model.instance_eval do - has_many :aspect_visibilities, :as => :shareable + has_many :aspect_visibilities, :as => :shareable, :validate => false has_many :aspects, :through => :aspect_visibilities has_many :share_visibilities, :as => :shareable diff --git a/spec/support/user_methods.rb b/spec/support/user_methods.rb index 2f2c4ea46..4d897f018 100644 --- a/spec/support/user_methods.rb +++ b/spec/support/user_methods.rb @@ -18,7 +18,6 @@ class User p = build_post(class_name, opts) p.aspects = aspects - if p.save! self.aspects.reload From dfa0245f4b9c4824a88eae1c02c1d40deb6d64f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 15:51:17 +0200 Subject: [PATCH 012/785] make assets:precompile work --- app/assets/stylesheets/vendor/blueprint/{LICENSE => LICENSE.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename app/assets/stylesheets/vendor/blueprint/{LICENSE => LICENSE.txt} (100%) diff --git a/app/assets/stylesheets/vendor/blueprint/LICENSE b/app/assets/stylesheets/vendor/blueprint/LICENSE.txt similarity index 100% rename from app/assets/stylesheets/vendor/blueprint/LICENSE rename to app/assets/stylesheets/vendor/blueprint/LICENSE.txt From 2f1193fa360ea2853f7bf75095aa47517bdd6402 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 17:56:19 +0200 Subject: [PATCH 013/785] Fix "prepared statements" errors See https://coderwall.com/p/45ombq --- app/controllers/conversations_controller.rb | 6 ++++-- app/models/user/querying.rb | 6 +++--- lib/evil_query.rb | 2 +- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index 180c42bf6..07ec4fd2b 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -83,8 +83,10 @@ class ConversationsController < ApplicationController def new all_contacts_and_ids = Contact.connection.select_rows( - current_user.contacts.where(:sharing => true).joins(:person => :profile). - select("contacts.id, profiles.first_name, profiles.last_name, people.diaspora_handle").to_sql + Contact.connection.unprepared_statement { + current_user.contacts.where(:sharing => true).joins(:person => :profile). + select("contacts.id, profiles.first_name, profiles.last_name, people.diaspora_handle").to_sql + } ).map{|r| {:value => r[0], :name => Person.name_from_attrs(r[1], r[2], r[3]).gsub(/(")/, "'")} } @contact_ids = "" diff --git a/app/models/user/querying.rb b/app/models/user/querying.rb index ac5a800df..257a07e56 100644 --- a/app/models/user/querying.rb +++ b/app/models/user/querying.rb @@ -27,7 +27,7 @@ module User::Querying opts[:klass] = klass opts[:by_members_of] ||= self.aspect_ids - post_ids = klass.connection.select_values(visible_shareable_sql(klass, opts)).map { |id| id.to_i } + post_ids = klass.connection.select_values(visible_shareable_sql(klass, opts)).map(&:to_i) post_ids += klass.connection.select_values("#{construct_public_followings_sql(opts).to_sql} LIMIT #{opts[:limit]}").map {|id| id.to_i } end @@ -88,9 +88,9 @@ module User::Querying end def construct_shareable_from_self_query(opts) - conditions = {:pending => false } + conditions = {:pending => false, :author_id => self.person_id } conditions[:type] = opts[:type] if opts.has_key?(:type) - query = self.person.send(opts[:klass].to_s.tableize).where(conditions) + query = opts[:klass].where(conditions) if opts[:by_members_of] query = query.joins(:aspect_visibilities).where(:aspect_visibilities => {:aspect_id => opts[:by_members_of]}) diff --git a/lib/evil_query.rb b/lib/evil_query.rb index a9923d4cd..395022b8b 100644 --- a/lib/evil_query.rb +++ b/lib/evil_query.rb @@ -6,7 +6,7 @@ module EvilQuery end def id_sql(relation, id_column) - relation.select(id_column).to_sql + @class.connection.unprepared_statement { relation.select(id_column).to_sql } end end From cc8a614c2910cacef0ab13b1ba133ada32ddf7ea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 17:57:05 +0200 Subject: [PATCH 014/785] Remove attr_accessible from OpenGraphCache --- app/models/open_graph_cache.rb | 6 ------ 1 file changed, 6 deletions(-) diff --git a/app/models/open_graph_cache.rb b/app/models/open_graph_cache.rb index e3b78e48a..8c6e32841 100644 --- a/app/models/open_graph_cache.rb +++ b/app/models/open_graph_cache.rb @@ -1,10 +1,4 @@ class OpenGraphCache < ActiveRecord::Base - attr_accessible :title - attr_accessible :ob_type - attr_accessible :image - attr_accessible :url - attr_accessible :description - validates :title, :presence => true validates :ob_type, :presence => true validates :image, :presence => true From 09f066522579a38500864a3c61ec3c4980a73d05 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 18:36:36 +0200 Subject: [PATCH 015/785] replace deprecated usages for all --- app/controllers/aspects_controller.rb | 6 +++--- app/models/conversation.rb | 2 +- app/models/user.rb | 2 +- app/models/user/connecting.rb | 2 -- app/presenters/post_presenter.rb | 2 +- lib/stream/base.rb | 2 +- spec/integration/account_deletion_spec.rb | 10 +++++----- spec/models/share_visibility_spec.rb | 12 ++++++------ 8 files changed, 18 insertions(+), 20 deletions(-) diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index 9ba5cf702..94460d09c 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -70,12 +70,12 @@ class AspectsController < ApplicationController def edit @aspect = current_user.aspects.where(:id => params[:id]).includes(:contacts => {:person => :profile}).first - @contacts_in_aspect = @aspect.contacts.includes(:aspect_memberships, :person => :profile).all.sort! { |x, y| x.person.name <=> y.person.name } + @contacts_in_aspect = @aspect.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } c = Contact.arel_table if @contacts_in_aspect.empty? - @contacts_not_in_aspect = current_user.contacts.includes(:aspect_memberships, :person => :profile).all.sort! { |x, y| x.person.name <=> y.person.name } + @contacts_not_in_aspect = current_user.contacts.includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } else - @contacts_not_in_aspect = current_user.contacts.where(c[:id].not_in(@contacts_in_aspect.map(&:id))).includes(:aspect_memberships, :person => :profile).all.sort! { |x, y| x.person.name <=> y.person.name } + @contacts_not_in_aspect = current_user.contacts.where(c[:id].not_in(@contacts_in_aspect.map(&:id))).includes(:aspect_memberships, :person => :profile).to_a.sort_by { |c| c.person.name } end @contacts = @contacts_in_aspect + @contacts_not_in_aspect diff --git a/app/models/conversation.rb b/app/models/conversation.rb index c620efe53..2217e2048 100644 --- a/app/models/conversation.rb +++ b/app/models/conversation.rb @@ -36,7 +36,7 @@ class Conversation < ActiveRecord::Base def first_unread_message(user) if visibility = self.conversation_visibilities.where(:person_id => user.person.id).where('unread > 0').first - self.messages.all[-visibility.unread] + self.messages.to_a[-visibility.unread] end end diff --git a/app/models/user.rb b/app/models/user.rb index cd3da1146..162bfdfa6 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -256,7 +256,7 @@ class User < ActiveRecord::Base if aspect_ids == "all" || aspect_ids == :all self.aspects else - aspects.where(:id => aspect_ids) + aspects.where(:id => aspect_ids).to_a end end diff --git a/app/models/user/connecting.rb b/app/models/user/connecting.rb index 6eaf55bef..507a27079 100644 --- a/app/models/user/connecting.rb +++ b/app/models/user/connecting.rb @@ -42,8 +42,6 @@ module User::Connecting end def remove_contact(contact, opts={:force => false, :retracted => false}) - posts = contact.posts.all - if !contact.mutual? || opts[:force] contact.destroy elsif opts[:retracted] diff --git a/app/presenters/post_presenter.rb b/app/presenters/post_presenter.rb index e95b05632..e6dd6fa31 100644 --- a/app/presenters/post_presenter.rb +++ b/app/presenters/post_presenter.rb @@ -99,7 +99,7 @@ class PostInteractionPresenter end def as_api(collection) - collection.includes(:author => :profile).all.map do |element| + collection.includes(:author => :profile).map do |element| element.as_api_response(:backbone) end end diff --git a/lib/stream/base.rb b/lib/stream/base.rb index 77bbbe66a..ceb835fd8 100644 --- a/lib/stream/base.rb +++ b/lib/stream/base.rb @@ -115,7 +115,7 @@ class Stream::Base # # @return [Array] def contacts_in_stream - @contacts_in_stream ||= Contact.where(:user_id => user.id, :person_id => people.map{|x| x.id}).all + @contacts_in_stream ||= Contact.where(:user_id => user.id, :person_id => people.map(&:id)).load end # @param post [Post] diff --git a/spec/integration/account_deletion_spec.rb b/spec/integration/account_deletion_spec.rb index ea578bff4..babc748f8 100644 --- a/spec/integration/account_deletion_spec.rb +++ b/spec/integration/account_deletion_spec.rb @@ -23,8 +23,8 @@ describe 'deleteing your account' do create_conversation_with_message(alice, @bob2.person, "Subject", "Hey @bob2") #join tables - @users_sv = ShareVisibility.where(:contact_id => @bobs_contact_ids).all - @persons_sv = ShareVisibility.where(:contact_id => bob.person.contacts.map(&:id)).all + @users_sv = ShareVisibility.where(:contact_id => @bobs_contact_ids).load + @persons_sv = ShareVisibility.where(:contact_id => bob.person.contacts.map(&:id)).load #user associated objects @prefs = [] @@ -86,8 +86,8 @@ describe 'deleteing your account' do @bob2.contacts.should be_empty end - - it "clears the account fields" do + + it "clears the account fields" do @bob2.send(:clearable_fields).each do |field| @bob2.reload[field].should be_blank end @@ -99,7 +99,7 @@ describe 'deleteing your account' do context 'remote person' do before do @person = remote_raphael - + #contacts @contacts = @person.contacts diff --git a/spec/models/share_visibility_spec.rb b/spec/models/share_visibility_spec.rb index 94aa0f832..bbd378465 100644 --- a/spec/models/share_visibility_spec.rb +++ b/spec/models/share_visibility_spec.rb @@ -39,18 +39,18 @@ describe ShareVisibility do end it 'searches for share visibilies for all users contacts' do - contact_ids = alice.contacts.map{|c| c.id} - ShareVisibility.for_a_users_contacts(alice).should == ShareVisibility.where(:contact_id => contact_ids).all + contact_ids = alice.contacts.map(&:id) + ShareVisibility.for_a_users_contacts(alice).should == ShareVisibility.where(:contact_id => contact_ids).to_a end end describe '.for_contacts_of_a_person' do it 'searches for share visibilties generated by a person' do - contact_ids = alice.person.contacts.map{|c| c.id} - - ShareVisibility.for_contacts_of_a_person(alice.person) == ShareVisibility.where(:contact_id => contact_ids).all - + contact_ids = alice.person.contacts.map(&:id) + + ShareVisibility.for_contacts_of_a_person(alice.person) == ShareVisibility.where(:contact_id => contact_ids).to_a + end end end From 76c6d95a0e9f3048aafc1b156d789668b3ef78d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 31 Aug 2013 19:11:38 +0200 Subject: [PATCH 016/785] replace deprecated disable_with option --- app/views/invitations/new.html.haml | 2 +- app/views/registrations/new.html.erb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/views/invitations/new.html.haml b/app/views/invitations/new.html.haml index ff972bf5a..b39bb12b0 100644 --- a/app/views/invitations/new.html.haml +++ b/app/views/invitations/new.html.haml @@ -26,4 +26,4 @@ .control-group .controls - = submit_tag t('.send_an_invitation'), :class => 'btn btn-primary creation', :disable_with => t('.sending_invitation') + = submit_tag t('.send_an_invitation'), class: 'btn btn-primary creation', data: {disable_with: t('.sending_invitation')} diff --git a/app/views/registrations/new.html.erb b/app/views/registrations/new.html.erb index e43a98c76..7cc3b57e5 100644 --- a/app/views/registrations/new.html.erb +++ b/app/views/registrations/new.html.erb @@ -73,7 +73,7 @@ <%= t('.terms', terms_link: link_to(t('.terms_link'), terms_path, target: "_blank")).html_safe %> <% end %> - <%= f.submit t('.continue'), :class => "new-btn", :disable_with => t('.submitting') %> + <%= f.submit t('.continue'), class: "new-btn", data: {disable_with: t('.submitting')} %> <% end %> From 659f0b96d4b486878036a9ec67acd17b497376f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 1 Sep 2013 14:12:40 +0200 Subject: [PATCH 017/785] do not pass relations to a method that expects a set of aspects ids or a single aspect --- spec/controllers/people_controller_spec.rb | 6 +++--- spec/integration/mentioning_spec.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index 881c198d8..bc11af200 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -263,7 +263,7 @@ describe PeopleController do end it "posts include reshares" do - reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspects) + reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) get :show, :id => @user.person.to_param assigns[:stream].posts.map { |x| x.id }.should include(reshare.id) end @@ -319,7 +319,7 @@ describe PeopleController do end it "posts include reshares" do - reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspects) + reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) get :show, :id => @user.person.to_param assigns[:stream].posts.map { |x| x.id }.should include(reshare.id) end @@ -361,7 +361,7 @@ describe PeopleController do end it "posts include reshares" do - reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspects) + reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) get :show, :id => @user.person.to_param assigns[:stream].posts.map { |x| x.id }.should include(reshare.id) end diff --git a/spec/integration/mentioning_spec.rb b/spec/integration/mentioning_spec.rb index dac2bcc0e..b3f10af06 100644 --- a/spec/integration/mentioning_spec.rb +++ b/spec/integration/mentioning_spec.rb @@ -3,7 +3,7 @@ require 'spec_helper' module MentioningSpecHelpers def default_aspect - @user1.aspects.where(name: 'generic') + @user1.aspects.where(name: 'generic').first end def text_mentioning(user) From dc12479070c75ddbf59f3cd8b57037bed537713c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 1 Sep 2013 15:59:35 +0200 Subject: [PATCH 018/785] Filter :id in User.build for now Rails 4 seem to allow setting the id through supplied parameters The controllers ported to strong_parameters should guard against attacks over this vector, but I didn't want to remove the specs that test this here --- app/models/user.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 162bfdfa6..9693b9ab3 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -355,7 +355,7 @@ class User < ActiveRecord::Base ###Helpers############ def self.build(opts = {}) - u = User.new(opts.except(:person)) + u = User.new(opts.except(:person, :id)) u.setup(opts) u end @@ -369,7 +369,7 @@ class User < ActiveRecord::Base errors = self.errors errors.delete :person return if errors.size > 0 - self.set_person(Person.new(opts[:person] || {} )) + self.set_person(Person.new((opts[:person] || {}).except(:id))) self.generate_keys self end From 7e7082a3bd78da46463692ae2d897483dbe1328e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 1 Sep 2013 16:01:10 +0200 Subject: [PATCH 019/785] Fix expectations for changes in generated HTML Just a minor change, supplied attributes now go before the standard ones --- lib/diaspora/taggable.rb | 2 +- spec/lib/diaspora/mentionable_spec.rb | 2 +- spec/shared_behaviors/taggable.rb | 6 +++--- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/diaspora/taggable.rb b/lib/diaspora/taggable.rb index 13c9bb811..bbf725532 100644 --- a/lib/diaspora/taggable.rb +++ b/lib/diaspora/taggable.rb @@ -50,7 +50,7 @@ module Diaspora url_bit = '<3' end - %{#{pre}#{clickable}} + %{#{pre}#{clickable}} }.html_safe end end diff --git a/spec/lib/diaspora/mentionable_spec.rb b/spec/lib/diaspora/mentionable_spec.rb index 6e60804a0..5d9bdcc45 100644 --- a/spec/lib/diaspora/mentionable_spec.rb +++ b/spec/lib/diaspora/mentionable_spec.rb @@ -48,7 +48,7 @@ STR fmt_msg = Diaspora::Mentionable.format(@status_msg.raw_message, @people) fmt_msg.should_not include(p.first_name) - fmt_msg.should include(">", "<", "'") # ">", "<", "'" + fmt_msg.should include(">", "<", "'") # ">", "<", "'" end end diff --git a/spec/shared_behaviors/taggable.rb b/spec/shared_behaviors/taggable.rb index 339556bf2..95b202352 100644 --- a/spec/shared_behaviors/taggable.rb +++ b/spec/shared_behaviors/taggable.rb @@ -52,9 +52,9 @@ shared_examples_for "it is taggable" do '#12345 tag' => "#{tag_link('12345')} tag", '#12cde tag' => "#{tag_link('12cde')} tag", '#abc45 tag' => "#{tag_link('abc45')} tag", - '#<3' => %{#<3}, - 'i #<3' => %{i #<3}, - 'i #<3 you' => %{i #<3 you}, + '#<3' => %{#<3}, + 'i #<3' => %{i #<3}, + 'i #<3 you' => %{i #<3 you}, '#<4' => '#<4', 'test#foo test' => 'test#foo test', 'test.#joo bar' => 'test.#joo bar', From 2d57e15d5df260043d9b5c13a3686aafb14c5691 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 1 Sep 2013 16:04:24 +0200 Subject: [PATCH 020/785] Remove :without_protection from call in the posts fetcher and fix a couple hundreds specs as a side effect Heisenbugs ftw. --- lib/diaspora/fetcher/public.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/diaspora/fetcher/public.rb b/lib/diaspora/fetcher/public.rb index 8f196c625..a849a9071 100644 --- a/lib/diaspora/fetcher/public.rb +++ b/lib/diaspora/fetcher/public.rb @@ -111,7 +111,7 @@ module Diaspora; module Fetcher; class Public :created_at => ActiveSupport::TimeZone.new('UTC').parse(post['created_at']).to_datetime, :interacted_at => ActiveSupport::TimeZone.new('UTC').parse(post['interacted_at']).to_datetime, :frame_name => post['frame_name'] - }, :without_protection => true) + }) entry.save # re-enable everything we disabled before From 645a4277989430e969e80d71b05e4f039ae0b898 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 21 Sep 2013 15:02:03 +0200 Subject: [PATCH 021/785] Fix account deleter by not relying on protected_atrributes --- app/models/profile.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/models/profile.rb b/app/models/profile.rb index e3e543f29..64b059bb9 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -186,7 +186,7 @@ class Profile < ActiveRecord::Base private def clearable_fields - self.attributes.keys - Profile.protected_attributes.to_a - ["created_at", "updated_at", "person_id"] + self.attributes.keys - ["id", "created_at", "updated_at", "person_id"] end def absolutify_local_url url From 21feb91d27f75f99a5e093f407cfba30b7f336f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 21 Sep 2013 15:58:25 +0200 Subject: [PATCH 022/785] always pass desired format in specs unless it's html --- spec/controllers/comments_controller_spec.rb | 4 ++-- .../conversations_controller_spec.rb | 17 +++++++++++------ .../notifications_controller_spec.rb | 12 ++++++------ spec/controllers/photos_controller_spec.rb | 8 ++++---- 4 files changed, 23 insertions(+), 18 deletions(-) diff --git a/spec/controllers/comments_controller_spec.rb b/spec/controllers/comments_controller_spec.rb index d4286de90..8c8f3142e 100644 --- a/spec/controllers/comments_controller_spec.rb +++ b/spec/controllers/comments_controller_spec.rb @@ -139,12 +139,12 @@ describe CommentsController do it 'returns all the comments for a post' do comments = [alice, bob, eve].map{ |u| u.comment!(@message, "hey") } - get :index, :post_id => @message.id, :format => 'js' + get :index, :post_id => @message.id, :format => :json assigns[:comments].map(&:id).should =~ comments.map(&:id) end it 'returns a 404 on a nonexistent post' do - get :index, :post_id => 235236, :format => 'js' + get :index, :post_id => 235236, :format => :json response.status.should == 404 end diff --git a/spec/controllers/conversations_controller_spec.rb b/spec/controllers/conversations_controller_spec.rb index 3c220c129..f1617cd95 100644 --- a/spec/controllers/conversations_controller_spec.rb +++ b/spec/controllers/conversations_controller_spec.rb @@ -53,20 +53,20 @@ describe ConversationsController do } @conversations = Array.new(3) { Conversation.create(hash) } end - + it 'succeeds' do get :index response.should be_success assigns[:conversations].should =~ @conversations end - + it 'succeeds with json' do get :index, :format => :json response.should be_success json = JSON.parse(response.body) json.first['conversation'].should be_present end - + it 'retrieves all conversations for a user' do get :index assigns[:conversations].count.should == 3 @@ -77,6 +77,7 @@ describe ConversationsController do context 'with a valid conversation' do before do @hash = { + :format => :js, :conversation => { :subject => "secret stuff", :text => 'text debug' @@ -131,6 +132,7 @@ describe ConversationsController do context 'with empty subject' do before do @hash = { + :format => :js, :conversation => { :subject => ' ', :text => 'text debug' @@ -162,6 +164,7 @@ describe ConversationsController do context 'with empty text' do before do @hash = { + :format => :js, :conversation => { :subject => 'secret stuff', :text => ' ' @@ -192,6 +195,7 @@ describe ConversationsController do context 'with empty contact' do before do @hash = { + :format => :js, :conversation => { :subject => 'secret stuff', :text => 'text debug' @@ -222,6 +226,7 @@ describe ConversationsController do context 'with nil contact' do before do @hash = { + :format => :js, :conversation => { :subject => 'secret stuff', :text => 'text debug' @@ -254,13 +259,13 @@ describe ConversationsController do } @conversation = Conversation.create(hash) end - + it 'succeeds with js' do get :show, :id => @conversation.id, :format => :js response.should be_success assigns[:conversation].should == @conversation end - + it 'succeeds with json' do get :show, :id => @conversation.id, :format => :json response.should be_success @@ -273,7 +278,7 @@ describe ConversationsController do response.should redirect_to(conversations_path(:conversation_id => @conversation.id)) assigns[:conversation].should == @conversation end - + it 'does not let you access conversations where you are not a recipient' do sign_in :user, eve diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index adb739df5..7ca9f7bda 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -14,20 +14,20 @@ describe NotificationsController do note = mock_model( Notification ) Notification.should_receive( :where ).and_return( [note] ) note.should_receive( :set_read_state ).with( true ) - get :update, "id" => note.id + get :update, "id" => note.id, :format => :json end it 'marks a notification as read if it is told to' do note = mock_model( Notification ) Notification.should_receive( :where ).and_return( [note] ) note.should_receive( :set_read_state ).with( true ) - get :update, "id" => note.id, :set_unread => "false" + get :update, "id" => note.id, :set_unread => "false", :format => :json end it 'marks a notification as unread if it is told to' do note = mock_model( Notification ) Notification.should_receive( :where ).and_return( [note] ) note.should_receive( :set_read_state ).with( false ) - get :update, "id" => note.id, :set_unread => "true" + get :update, "id" => note.id, :set_unread => "true", :format => :json end it 'only lets you read your own notifications' do @@ -36,7 +36,7 @@ describe NotificationsController do FactoryGirl.create(:notification, :recipient => alice) note = FactoryGirl.create(:notification, :recipient => user2) - get :update, "id" => note.id, :set_unread => "false" + get :update, "id" => note.id, :set_unread => "false", :format => :json Notification.find(note.id).unread.should == true end @@ -64,7 +64,7 @@ describe NotificationsController do get :index, :format => :mobile response.should be_success end - + it 'paginates the notifications' do 25.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } get :index @@ -76,7 +76,7 @@ describe NotificationsController do it "supports a limit per_page parameter" do 5.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } get :index, "per_page" => 5 - assigns[:notifications].count.should == 5 + assigns[:notifications].count.should == 5 end describe "special case for start sharing notifications" do diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 40d02acc3..dede4a72c 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -130,7 +130,7 @@ describe PhotosController do end it 'will let you delete your profile picture' do - get :make_profile_photo, :photo_id => @alices_photo.id + get :make_profile_photo, :photo_id => @alices_photo.id, :format => :js delete :destroy, :id => @alices_photo.id Photo.find_by_id(@alices_photo.id).should be_nil end @@ -155,21 +155,21 @@ describe PhotosController do describe "#update" do it "updates the caption of a photo" do - put :update, :id => @alices_photo.id, :photo => { :text => "now with lasers!" } + put :update, :id => @alices_photo.id, :photo => { :text => "now with lasers!" }, :format => :js @alices_photo.reload.text.should == "now with lasers!" end it "doesn't allow mass assignment of person" do new_user = FactoryGirl.create(:user) params = { :text => "now with lasers!", :author => new_user } - put :update, :id => @alices_photo.id, :photo => params + put :update, :id => @alices_photo.id, :photo => params, :format => :js @alices_photo.reload.author.should == alice.person end it "doesn't allow mass assignment of person_id" do new_user = FactoryGirl.create(:user) params = { :text => "now with lasers!", :author_id => new_user.id } - put :update, :id => @alices_photo.id, :photo => params + put :update, :id => @alices_photo.id, :photo => params, :format => :js @alices_photo.reload.author_id.should == alice.person.id end From ceee5baae6d0194264dc67c668b52b73016e543e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 21 Sep 2013 20:18:20 +0200 Subject: [PATCH 023/785] raise original exception in i18n interpolation fallback middleware --- lib/i18n_interpolation_fallbacks.rb | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/lib/i18n_interpolation_fallbacks.rb b/lib/i18n_interpolation_fallbacks.rb index f5af4b1de..d379a965e 100644 --- a/lib/i18n_interpolation_fallbacks.rb +++ b/lib/i18n_interpolation_fallbacks.rb @@ -5,17 +5,19 @@ module I18n default = extract_non_symbol_default!(options) if options[:default] options.merge!(:default => default) if default + original_exception = nil + I18n.fallbacks[locale].each do |fallback| begin result = super(fallback, key, options) return result unless result.nil? - rescue I18n::MissingInterpolationArgument - rescue I18n::InvalidPluralizationData + rescue I18n::MissingInterpolationArgument, I18n::InvalidPluralizationData => e + original_exception ||= e end end return super(locale, nil, options) if default - raise(I18n::MissingInterpolationArgument.new(key, options, locale)) + raise original_exception end end end From 244388fcb526f8c6cf0e8d5bb208d03eacc8187c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 21 Sep 2013 20:35:19 +0200 Subject: [PATCH 024/785] make aspect membership controller specs green --- app/controllers/aspect_memberships_controller.rb | 2 +- spec/controllers/aspect_memberships_controller_spec.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/aspect_memberships_controller.rb b/app/controllers/aspect_memberships_controller.rb index 2fd459828..ba0515bd1 100644 --- a/app/controllers/aspect_memberships_controller.rb +++ b/app/controllers/aspect_memberships_controller.rb @@ -31,7 +31,7 @@ class AspectMembershipsController < ApplicationController flash.now[:error] = I18n.t 'aspect_memberships.destroy.failure' end - respond_with do |format| + respond_to do |format| format.json do if success render :json => { diff --git a/spec/controllers/aspect_memberships_controller_spec.rb b/spec/controllers/aspect_memberships_controller_spec.rb index a3d4666c1..91a1b5c1f 100644 --- a/spec/controllers/aspect_memberships_controller_spec.rb +++ b/spec/controllers/aspect_memberships_controller_spec.rb @@ -90,7 +90,7 @@ describe AspectMembershipsController do delete :destroy, :format => :json, :id => membership.id response.should be_success @aspect1.reload - @aspect1.contacts.include?(@contact).should be false + @aspect1.contacts.to_a.should_not include @contact end it 'does not 500 on an html request' do @@ -98,7 +98,7 @@ describe AspectMembershipsController do delete :destroy, :id => membership.id response.should redirect_to :back @aspect1.reload - @aspect1.contacts.include?(@contact).should be false + @aspect1.contacts.to_a.should_not include @contact end it 'aspect membership does not exist' do From f33038f10570dfc8fc5ce7f7efba0d48087606e1 Mon Sep 17 00:00:00 2001 From: Niall Paterson Date: Sun, 17 Nov 2013 20:20:22 +0000 Subject: [PATCH 025/785] updated before_filters to before_actions as recommended for rails 4 --- app/controllers/application_controller.rb | 14 +++++++------- app/controllers/aspect_memberships_controller.rb | 2 +- app/controllers/aspects_controller.rb | 2 +- app/controllers/blocks_controller.rb | 2 +- app/controllers/comments_controller.rb | 2 +- app/controllers/contacts_controller.rb | 2 +- .../conversation_visibilities_controller.rb | 2 +- app/controllers/conversations_controller.rb | 2 +- app/controllers/invitation_codes_controller.rb | 2 +- app/controllers/invitations_controller.rb | 2 +- app/controllers/likes_controller.rb | 2 +- app/controllers/messages_controller.rb | 2 +- app/controllers/notifications_controller.rb | 2 +- app/controllers/people_controller.rb | 2 +- app/controllers/photos_controller.rb | 2 +- app/controllers/posts_controller.rb | 5 ++--- app/controllers/profiles_controller.rb | 4 ++-- app/controllers/publics_controller.rb | 8 ++++---- app/controllers/registrations_controller.rb | 4 ++-- app/controllers/reshares_controller.rb | 2 +- app/controllers/search_controller.rb | 2 +- app/controllers/services_controller.rb | 8 ++++---- app/controllers/share_visibilities_controller.rb | 2 +- app/controllers/status_messages_controller.rb | 4 ++-- app/controllers/streams_controller.rb | 6 +++--- app/controllers/tag_followings_controller.rb | 2 +- app/controllers/tags_controller.rb | 4 ++-- app/controllers/users_controller.rb | 4 ++-- 28 files changed, 48 insertions(+), 49 deletions(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 320ce93f0..73a3a35cf 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -6,13 +6,13 @@ class ApplicationController < ActionController::Base has_mobile_fu protect_from_forgery :except => :receive - before_filter :ensure_http_referer_is_set - before_filter :set_locale - before_filter :set_diaspora_header - before_filter :set_grammatical_gender - before_filter :mobile_switch - before_filter :gon_set_current_user - before_filter :gon_set_preloads + before_action :ensure_http_referer_is_set + before_action :set_locale + before_action :set_diaspora_header + before_action :set_grammatical_gender + before_action :mobile_switch + before_action :gon_set_current_user + before_action :gon_set_preloads inflection_method :grammatical_gender => :gender diff --git a/app/controllers/aspect_memberships_controller.rb b/app/controllers/aspect_memberships_controller.rb index ba0515bd1..5009902b9 100644 --- a/app/controllers/aspect_memberships_controller.rb +++ b/app/controllers/aspect_memberships_controller.rb @@ -4,7 +4,7 @@ # class AspectMembershipsController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :html, :json diff --git a/app/controllers/aspects_controller.rb b/app/controllers/aspects_controller.rb index 94460d09c..4afce2b8d 100644 --- a/app/controllers/aspects_controller.rb +++ b/app/controllers/aspects_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class AspectsController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :html, :js, diff --git a/app/controllers/blocks_controller.rb b/app/controllers/blocks_controller.rb index f6f13ed7c..bcea0e561 100644 --- a/app/controllers/blocks_controller.rb +++ b/app/controllers/blocks_controller.rb @@ -1,5 +1,5 @@ class BlocksController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :html, :json diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 18de5d16a..b368876d6 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -4,7 +4,7 @@ class CommentsController < ApplicationController include ApplicationHelper - before_filter :authenticate_user!, :except => [:index] + before_action :authenticate_user!, :except => [:index] respond_to :html, :mobile, diff --git a/app/controllers/contacts_controller.rb b/app/controllers/contacts_controller.rb index 68e3f6469..9508b4eb2 100644 --- a/app/controllers/contacts_controller.rb +++ b/app/controllers/contacts_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class ContactsController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! use_bootstrap_for :index, :spotlight diff --git a/app/controllers/conversation_visibilities_controller.rb b/app/controllers/conversation_visibilities_controller.rb index 125fdf985..24b4533ad 100644 --- a/app/controllers/conversation_visibilities_controller.rb +++ b/app/controllers/conversation_visibilities_controller.rb @@ -4,7 +4,7 @@ # class ConversationVisibilitiesController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! def destroy @vis = ConversationVisibility.where(:person_id => current_user.person.id, diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index 07ec4fd2b..58638651d 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -1,5 +1,5 @@ class ConversationsController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! layout ->(c) { request.format == :mobile ? "application" : "with_header" } use_bootstrap_for :index, :show, :new diff --git a/app/controllers/invitation_codes_controller.rb b/app/controllers/invitation_codes_controller.rb index d267db12f..896514739 100644 --- a/app/controllers/invitation_codes_controller.rb +++ b/app/controllers/invitation_codes_controller.rb @@ -1,5 +1,5 @@ class InvitationCodesController < ApplicationController - before_filter :ensure_valid_invite_code + before_action :ensure_valid_invite_code rescue_from ActiveRecord::RecordNotFound do redirect_to root_url, :notice => "That invite code is no longer valid" diff --git a/app/controllers/invitations_controller.rb b/app/controllers/invitations_controller.rb index ffcae4a0c..391c36cb5 100644 --- a/app/controllers/invitations_controller.rb +++ b/app/controllers/invitations_controller.rb @@ -4,7 +4,7 @@ class InvitationsController < ApplicationController - before_filter :authenticate_user!, :only => [:new, :create] + before_action :authenticate_user!, :only => [:new, :create] def new @invite_code = current_user.invitation_code diff --git a/app/controllers/likes_controller.rb b/app/controllers/likes_controller.rb index 8ab65b6ca..c5750bee5 100644 --- a/app/controllers/likes_controller.rb +++ b/app/controllers/likes_controller.rb @@ -4,7 +4,7 @@ class LikesController < ApplicationController include ApplicationHelper - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :html, :mobile, diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb index 752ffd573..e2f435af4 100644 --- a/app/controllers/messages_controller.rb +++ b/app/controllers/messages_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class MessagesController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :html, :mobile respond_to :json, :only => :show diff --git a/app/controllers/notifications_controller.rb b/app/controllers/notifications_controller.rb index ef98e5b14..2f5a92191 100644 --- a/app/controllers/notifications_controller.rb +++ b/app/controllers/notifications_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class NotificationsController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! layout ->(c) { request.format == :mobile ? "application" : "with_header_with_footer" } use_bootstrap_for :index diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 1616c80f2..df95f3d92 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class PeopleController < ApplicationController - before_filter :authenticate_user!, :except => [:show, :last_post] + before_action :authenticate_user!, :except => [:show, :last_post] use_bootstrap_for :index diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index 18203d8c9..7e1fad0a6 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. class PhotosController < ApplicationController - before_filter :authenticate_user!, :except => :show + before_action :authenticate_user!, :except => :show respond_to :html, :json diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 2f14fb638..56858f03e 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -5,9 +5,8 @@ class PostsController < ApplicationController include PostsHelper - before_filter :authenticate_user!, :except => [:show, :iframe, :oembed, :interactions] - before_filter :set_format_if_malformed_from_status_net, :only => :show - before_filter :find_post, :only => [:show, :interactions] + before_action :authenticate_user!, :except => [:show, :iframe, :oembed, :interactions] + before_action :set_format_if_malformed_from_status_net, :only => :show use_bootstrap_for :show diff --git a/app/controllers/profiles_controller.rb b/app/controllers/profiles_controller.rb index 4a78e21d4..1d1bcbf8d 100644 --- a/app/controllers/profiles_controller.rb +++ b/app/controllers/profiles_controller.rb @@ -3,8 +3,8 @@ # the COPYRIGHT file. class ProfilesController < ApplicationController - before_filter :authenticate_user!, :except => ['show'] - before_filter -> { @css_framework = :bootstrap }, only: [:show, :edit] + before_action :authenticate_user!, :except => ['show'] + before_action -> { @css_framework = :bootstrap }, only: [:show, :edit] layout ->(c) { request.format == :mobile ? "application" : "with_header_with_footer" }, only: [:show, :edit] diff --git a/app/controllers/publics_controller.rb b/app/controllers/publics_controller.rb index c0724190e..3609bdefa 100644 --- a/app/controllers/publics_controller.rb +++ b/app/controllers/publics_controller.rb @@ -5,10 +5,10 @@ class PublicsController < ApplicationController include Diaspora::Parser - skip_before_filter :set_header_data - skip_before_filter :set_grammatical_gender - before_filter :check_for_xml, :only => [:receive, :receive_public] - before_filter :authenticate_user!, :only => [:index] + skip_before_action :set_header_data + skip_before_action :set_grammatical_gender + before_action :check_for_xml, :only => [:receive, :receive_public] + before_action :authenticate_user!, :only => [:index] respond_to :html respond_to :xml, :only => :post diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb index c1e24e91e..ff3699a3f 100644 --- a/app/controllers/registrations_controller.rb +++ b/app/controllers/registrations_controller.rb @@ -3,10 +3,10 @@ # the COPYRIGHT file. class RegistrationsController < Devise::RegistrationsController - before_filter :check_registrations_open_or_valid_invite!, :check_valid_invite! + before_action :check_registrations_open_or_valid_invite!, :check_valid_invite! layout ->(c) { request.format == :mobile ? "application" : "with_header" }, :only => [:new] - before_filter -> { @css_framework = :bootstrap }, only: [:new, :create] + before_action -> { @css_framework = :bootstrap }, only: [:new, :create] def create @user = User.build(user_params) diff --git a/app/controllers/reshares_controller.rb b/app/controllers/reshares_controller.rb index 5748386e1..7fc4e815f 100644 --- a/app/controllers/reshares_controller.rb +++ b/app/controllers/reshares_controller.rb @@ -1,5 +1,5 @@ class ResharesController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :json def create diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index cc510215f..6c2f43474 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -1,5 +1,5 @@ class SearchController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! def search if search_query.starts_with?('#') diff --git a/app/controllers/services_controller.rb b/app/controllers/services_controller.rb index 69fc83a0e..8baa56cfd 100644 --- a/app/controllers/services_controller.rb +++ b/app/controllers/services_controller.rb @@ -5,10 +5,10 @@ class ServicesController < ApplicationController # We need to take a raw POST from an omniauth provider with no authenticity token. # See https://github.com/intridea/omniauth/issues/203 # See also http://www.communityguides.eu/articles/16 - skip_before_filter :verify_authenticity_token, :only => :create - before_filter :authenticate_user! - before_filter :abort_if_already_authorized, :abort_if_read_only_access, :only => :create - before_filter -> { @css_framework = :bootstrap }, only: [:index] + skip_before_action :verify_authenticity_token, :only => :create + before_action :authenticate_user! + before_action :abort_if_already_authorized, :abort_if_read_only_access, :only => :create + before_action -> { @css_framework = :bootstrap }, only: [:index] layout ->(c) { request.format == :mobile ? "application" : "with_header_with_footer" }, only: [:index] diff --git a/app/controllers/share_visibilities_controller.rb b/app/controllers/share_visibilities_controller.rb index 005b0288a..bbc7bba16 100644 --- a/app/controllers/share_visibilities_controller.rb +++ b/app/controllers/share_visibilities_controller.rb @@ -4,7 +4,7 @@ # class ShareVisibilitiesController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! def update #note :id references a postvisibility diff --git a/app/controllers/status_messages_controller.rb b/app/controllers/status_messages_controller.rb index 06790768b..76cfc55aa 100644 --- a/app/controllers/status_messages_controller.rb +++ b/app/controllers/status_messages_controller.rb @@ -3,9 +3,9 @@ # the COPYRIGHT file. class StatusMessagesController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! - before_filter :remove_getting_started, :only => [:create] + before_action :remove_getting_started, :only => [:create] use_bootstrap_for :bookmarklet diff --git a/app/controllers/streams_controller.rb b/app/controllers/streams_controller.rb index 6ce788a17..0e4c156ca 100644 --- a/app/controllers/streams_controller.rb +++ b/app/controllers/streams_controller.rb @@ -3,9 +3,9 @@ # the COPYRIGHT file. class StreamsController < ApplicationController - before_filter :authenticate_user! - before_filter :save_selected_aspects, :only => :aspects - before_filter :redirect_unless_admin, :only => :public + before_action :authenticate_user! + before_action :save_selected_aspects, :only => :aspects + before_action :redirect_unless_admin, :only => :public respond_to :html, :mobile, diff --git a/app/controllers/tag_followings_controller.rb b/app/controllers/tag_followings_controller.rb index 94299bf8f..34c35184f 100644 --- a/app/controllers/tag_followings_controller.rb +++ b/app/controllers/tag_followings_controller.rb @@ -4,7 +4,7 @@ # class TagFollowingsController < ApplicationController - before_filter :authenticate_user! + before_action :authenticate_user! respond_to :json diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 86b095975..44f44239c 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -3,8 +3,8 @@ # the COPYRIGHT file. class TagsController < ApplicationController - skip_before_filter :set_grammatical_gender - before_filter :ensure_page, :only => :show + skip_before_action :set_grammatical_gender + before_action :ensure_page, :only => :show helper_method :tag_followed? diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index ef0ec6d14..d31773443 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -3,8 +3,8 @@ # the COPYRIGHT file. class UsersController < ApplicationController - before_filter :authenticate_user!, :except => [:new, :create, :public, :user_photo] - before_filter -> { @css_framework = :bootstrap }, only: [:privacy_settings, :edit] + before_action :authenticate_user!, :except => [:new, :create, :public, :user_photo] + before_action -> { @css_framework = :bootstrap }, only: [:privacy_settings, :edit] layout ->(c) { request.format == :mobile ? "application" : "with_header_with_footer" }, only: [:privacy_settings, :edit] From 7fd2294111f0ca295ce0b6eefd59f2c8e0a03696 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 9 Feb 2014 20:47:22 +0100 Subject: [PATCH 026/785] switch to simple_captcha2 --- Gemfile | 2 +- Gemfile.lock | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 7a622cd34..265fc4e9d 100644 --- a/Gemfile +++ b/Gemfile @@ -24,7 +24,7 @@ gem 'devise_lastseenable', '0.0.4' # Captcha -gem 'galetahub-simple_captcha', '0.1.5', :require => 'simple_captcha' +gem 'simple_captcha2', '0.2.1', :require => 'simple_captcha' # Background processing diff --git a/Gemfile.lock b/Gemfile.lock index 1ec15636e..21598ae56 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -178,7 +178,6 @@ GEM fuubar (1.3.3) rspec (>= 2.14.0, < 3.1.0) ruby-progressbar (~> 1.4) - galetahub-simple_captcha (0.1.5) gherkin (2.12.2) multi_json (~> 1.3) gon (5.0.4) @@ -409,6 +408,8 @@ GEM json redis (>= 3.0.6) redis-namespace (>= 1.3.1) + simple_captcha2 (0.2.1) + rails (>= 3.1) simple_oauth (0.2.0) sinatra (1.3.3) rack (~> 1.3, >= 1.3.6) @@ -496,7 +497,6 @@ DEPENDENCIES foreigner (= 1.6.1) foreman (= 0.62) fuubar (= 1.3.3) - galetahub-simple_captcha (= 0.1.5) gon (= 5.0.4) guard-cucumber (= 1.4.1) guard-rspec (= 4.2.9) @@ -542,6 +542,7 @@ DEPENDENCIES sass-rails (= 4.0.1) selenium-webdriver (= 2.42.0) sidekiq (= 2.17.7) + simple_captcha2 (= 0.2.1) sinatra (= 1.3.3) sinon-rails (= 1.9.0) spork (= 1.0.0rc4) From da9c1db14f933640756dc4e8aa933ee7a8608012 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:13:41 +0100 Subject: [PATCH 027/785] before_action --- app/controllers/posts_controller.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 56858f03e..9ecd50c3a 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -7,6 +7,7 @@ class PostsController < ApplicationController before_action :authenticate_user!, :except => [:show, :iframe, :oembed, :interactions] before_action :set_format_if_malformed_from_status_net, :only => :show + before_action :find_post, :only => [:show, :interactions] use_bootstrap_for :show From 35b17d8c4f87d8db1cc02e84e87b8e968af0ce88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:14:20 +0100 Subject: [PATCH 028/785] Do not call self-modifying Enumerable methods on AR::Relation objects --- app/controllers/tags_controller.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 44f44239c..9cea03112 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -57,9 +57,9 @@ class TagsController < ApplicationController end def prep_tags_for_javascript - @tags.map! do |tag| + @tags = @tags.map {|tag| { :name => ("#" + tag.name) } - end + } @tags << { :name => ('#' + params[:q]) } @tags.uniq! From cb13d30a02c9653c32991bd05deca550e58fbbfd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:16:14 +0100 Subject: [PATCH 029/785] Directly query photos when doing an update_all For some reason it doesn't correctly set the bind variables when called through an association with non-standard keys. Probably a Rails bug. --- app/models/status_message.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/models/status_message.rb b/app/models/status_message.rb index 7269238c1..0695cdbdf 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -116,14 +116,14 @@ class StatusMessage < Post def update_and_dispatch_attached_photos(sender) if self.photos.any? - self.photos.update_all(:public => self.public) + Photo.where(status_message_guid: guid).update_all(:public => self.public) self.photos.each do |photo| if photo.pending sender.add_to_streams(photo, self.aspects) sender.dispatch_post(photo) end end - self.photos.update_all(:pending => false) + Photo.where(status_message_guid: guid).update_all(:pending => false) end end From 1b3a2185ebfa2a9304c773af09b2e737f62176af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:18:26 +0100 Subject: [PATCH 030/785] Fix and simplify current_page? check on profile page --- app/views/people/_sub_header.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/people/_sub_header.html.haml b/app/views/people/_sub_header.html.haml index a8e4f0575..56c9552d9 100644 --- a/app/views/people/_sub_header.html.haml +++ b/app/views/people/_sub_header.html.haml @@ -28,7 +28,7 @@ = t('.you_have_no_tags') %span.add_tags = link_to t('.add_some'), edit_profile_path - - if user_signed_in? && person == current_user.person && current_page?(controller: :people, action: :show) + - if user_signed_in? && current_page?(person_path current_user.person) %hr = render 'aspects/aspect_stream', :stream => @stream %hr From 0d42285496ca9f2c76d7e620eea69d815d152b6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:19:21 +0100 Subject: [PATCH 031/785] Do not update_attributes with a nil id Rails 4 accepts that as a parameter thus setting the id to nil thus thinking it'd be a new record when we just want to update it --- lib/diaspora/federated/shareable.rb | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/diaspora/federated/shareable.rb b/lib/diaspora/federated/shareable.rb index a2c4ce957..3921395cb 100644 --- a/lib/diaspora/federated/shareable.rb +++ b/lib/diaspora/federated/shareable.rb @@ -2,9 +2,9 @@ # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. -#this module attempts to be what you need to mix into +#this module attempts to be what you need to mix into # base level federation objects that are not relayable, and not persistable -#assumes there is an author, author_id, id, +#assumes there is an author, author_id, id, module Diaspora module Federated module Shareable @@ -85,7 +85,7 @@ module Diaspora known_shareable = user.find_visible_shareable_by_id(self.class.base_class, self.guid, :key => :guid) if known_shareable if known_shareable.mutable? - known_shareable.update_attributes(self.attributes) + known_shareable.update_attributes(self.attributes.except("id")) true else Rails.logger.info("event=receive payload_type=#{self.class} update=true status=abort sender=#{self.diaspora_handle} reason=immutable") #existing_shareable=#{known_shareable.id}") @@ -113,4 +113,4 @@ module Diaspora end end end -end \ No newline at end of file +end From b3e59dc3d57aee23b00dbfd0d056847c88dc919d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:20:37 +0100 Subject: [PATCH 032/785] fix PostsController specs by using explicit form of the sign_in helper --- spec/controllers/posts_controller_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index fb1145f62..80131206c 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -17,7 +17,7 @@ describe PostsController do describe '#show' do context 'user signed in' do before do - sign_in alice + sign_in :user, alice end it 'succeeds' do From 397606bc44871d9c6b4fbfec59517885ffdc3808 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 10 Feb 2014 01:23:58 +0100 Subject: [PATCH 033/785] turn parameter wrapping for AR::B#to_json back on --- config/initializers/wrap_parameters.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 config/initializers/wrap_parameters.rb diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 000000000..ddd9dd5ab --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] if respond_to?(:wrap_parameters) +end + +# To enable root element in JSON for ActiveRecord objects. +ActiveSupport.on_load(:active_record) do + self.include_root_in_json = true +end From 43f156420dcee490de7f3db6311ad3f2b1282d1b Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 1 Mar 2014 01:57:02 +0100 Subject: [PATCH 034/785] update jasmine mock-ajax, port SpecHelper to jasmine 2.0 - some tests should be passing again now --- spec/javascripts/helpers/SpecHelper.js | 79 ++--- spec/javascripts/helpers/mock-ajax.js | 398 +++++++++++++++---------- 2 files changed, 279 insertions(+), 198 deletions(-) diff --git a/spec/javascripts/helpers/SpecHelper.js b/spec/javascripts/helpers/SpecHelper.js index a58a1b6d7..92a22e0bb 100644 --- a/spec/javascripts/helpers/SpecHelper.js +++ b/spec/javascripts/helpers/SpecHelper.js @@ -1,18 +1,10 @@ -// Add custom matchers here, in a beforeEach block. Example: -//beforeEach(function() { -// this.addMatchers({ -// toBePlaying: function(expectedSong) { -// var player = this.actual; -// return player.currentlyPlayingSong === expectedSong -// && player.isPlaying; -// } -// }) -//}); +// for docs, see http://jasmine.github.io beforeEach(function() { $('#jasmine_content').html(spec.readFixture("underscore_templates")); - jasmine.Clock.useMock(); + jasmine.clock().install(); + jasmine.Ajax.install(); Diaspora.Pages.TestPage = function() { var self = this; @@ -29,43 +21,56 @@ beforeEach(function() { Diaspora.page = new Page(); Diaspora.page.publish("page/ready", [$(document.body)]); - - // matches flash messages with success/error and contained text - var flashMatcher = function(flash, id, text) { - textContained = true; - if( text ) { - textContained = (flash.text().indexOf(text) !== -1); - } - - return flash.is(id) && - flash.hasClass('expose') && - textContained; - }; - // add custom matchers for flash messages - this.addMatchers({ - toBeSuccessFlashMessage: function(containedText) { - var flash = this.actual; - return flashMatcher(flash, '#flash_notice', containedText); - }, - - toBeErrorFlashMessage: function(containedText) { - var flash = this.actual; - return flashMatcher(flash, '#flash_error', containedText); - } - }); - + jasmine.addMatchers(customMatchers); }); afterEach(function() { //spec.clearLiveEventBindings(); + + jasmine.clock().uninstall(); + jasmine.Ajax.uninstall(); + $("#jasmine_content").empty() expect(spec.loadFixtureCount).toBeLessThan(2); spec.loadFixtureCount = 0; }); + +// matches flash messages with success/error and contained text +var flashMatcher = function(flash, id, text) { + textContained = true; + if( text ) { + textContained = (flash.text().indexOf(text) !== -1); + } + + return flash.is(id) && + flash.hasClass('expose') && + textContained; +}; + var context = describe; var spec = {}; +var customMatchers = { + toBeSuccessFlashMessage: function(util) { + return { + compare: function(actual, expected) { + var result = {}; + result.pass = flashMatcher(actual, '#flash_notice', expected); + return result; + } + }; + }, + toBeErrorFlashMessage: function(util) { + return { + compare: function(actual, expected) { + var result = {}; + result.pass = flashMatcher(actual, '#flash_error', expected); + return result; + } + }; + } +}; window.stubView = function stubView(text){ var stubClass = Backbone.View.extend({ @@ -159,7 +164,7 @@ spec.retrieveFixture = function(fixtureName) { // retrieve the fixture markup via xhr request to jasmine server try { - xhr = new jasmine.XmlHttpRequest(); + xhr = new XMLHttpRequest(); xhr.open("GET", path, false); xhr.send(null); } catch(e) { diff --git a/spec/javascripts/helpers/mock-ajax.js b/spec/javascripts/helpers/mock-ajax.js index 249efc907..9bd8c3f54 100644 --- a/spec/javascripts/helpers/mock-ajax.js +++ b/spec/javascripts/helpers/mock-ajax.js @@ -1,207 +1,283 @@ /* - Jasmine-Ajax : a set of helpers for testing AJAX requests under the Jasmine - BDD framework for JavaScript. - Supports both Prototype.js and jQuery. +Jasmine-Ajax : a set of helpers for testing AJAX requests under the Jasmine +BDD framework for JavaScript. - http://github.com/pivotal/jasmine-ajax +http://github.com/pivotal/jasmine-ajax - Jasmine Home page: http://pivotal.github.com/jasmine +Jasmine Home page: http://pivotal.github.com/jasmine - Copyright (c) 2008-2010 Pivotal Labs +Copyright (c) 2008-2013 Pivotal Labs - Permission is hereby granted, free of charge, to any person obtaining - a copy of this software and associated documentation files (the - "Software"), to deal in the Software without restriction, including - without limitation the rights to use, copy, modify, merge, publish, - distribute, sublicense, and/or sell copies of the Software, and to - permit persons to whom the Software is furnished to do so, subject to - the following conditions: +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: - The above copyright notice and this permission notice shall be - included in all copies or substantial portions of the Software. +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. - THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, - EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND - NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE - LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION - OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION - WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ +*/ -// Jasmine-Ajax interface -var ajaxRequests = []; - -function mostRecentAjaxRequest() { - if (ajaxRequests.length > 0) { - return ajaxRequests[ajaxRequests.length - 1]; - } else { - return null; +(function() { + function extend(destination, source) { + for (var property in source) { + destination[property] = source[property]; + } + return destination; } -} -function clearAjaxRequests() { - ajaxRequests = []; -} + function MockAjax(global) { + var requestTracker = new RequestTracker(), + stubTracker = new StubTracker(), + realAjaxFunction = global.XMLHttpRequest, + mockAjaxFunction = fakeRequest(requestTracker, stubTracker); -// Fake XHR for mocking Ajax Requests & Responses -function FakeXMLHttpRequest() { - var extend = Object.extend || $.extend; - extend(this, { - requestHeaders: {}, + this.install = function() { + global.XMLHttpRequest = mockAjaxFunction; + }; - open: function() { - this.method = arguments[0]; - this.url = arguments[1]; - this.readyState = 1; - }, + this.uninstall = function() { + global.XMLHttpRequest = realAjaxFunction; - setRequestHeader: function(header, value) { - this.requestHeaders[header] = value; - }, + this.stubs.reset(); + this.requests.reset(); + }; - abort: function() { - this.readyState = 0; - }, + this.stubRequest = function(url, data) { + var stub = new RequestStub(url, data); + stubTracker.addStub(stub); + return stub; + }; - readyState: 0, + this.withMock = function(closure) { + this.install(); + try { + closure(); + } finally { + this.uninstall(); + } + }; - onreadystatechange: function(isTimeout) { - }, + this.requests = requestTracker; + this.stubs = stubTracker; + } - status: null, + function StubTracker() { + var stubs = []; - send: function(data) { - this.params = data; - this.readyState = 2; - }, + this.addStub = function(stub) { + stubs.push(stub); + }; - getResponseHeader: function(name) { - return this.responseHeaders[name]; - }, + this.reset = function() { + stubs = []; + }; - getAllResponseHeaders: function() { - var responseHeaders = []; - for (var i in this.responseHeaders) { - if (this.responseHeaders.hasOwnProperty(i)) { - responseHeaders.push(i + ': ' + this.responseHeaders[i]); + this.findStub = function(url, data) { + for (var i = stubs.length - 1; i >= 0; i--) { + var stub = stubs[i]; + if (stub.matches(url, data)) { + return stub; } } - return responseHeaders.join('\r\n'); - }, + }; + } - responseText: null, - - response: function(response) { - this.status = response.status; - this.responseText = response.responseText || ""; - this.readyState = 4; - this.responseHeaders = response.responseHeaders || - {"Content-type": response.contentType || "application/json" }; - // uncomment for jquery 1.3.x support - // jasmine.Clock.tick(20); - - this.onreadystatechange(); - }, - responseTimeout: function() { - this.readyState = 4; - jasmine.Clock.tick(jQuery.ajaxSettings.timeout || 30000); - this.onreadystatechange('timeout'); + function fakeRequest(requestTracker, stubTracker) { + function FakeXMLHttpRequest() { + requestTracker.track(this); + this.requestHeaders = {}; } - }); - return this; -} + extend(FakeXMLHttpRequest.prototype, window.XMLHttpRequest); + extend(FakeXMLHttpRequest.prototype, { + open: function() { + this.method = arguments[0]; + this.url = arguments[1]; + this.username = arguments[3]; + this.password = arguments[4]; + this.readyState = 1; + this.onreadystatechange(); + }, + setRequestHeader: function(header, value) { + this.requestHeaders[header] = value; + }, -jasmine.Ajax = { + abort: function() { + this.readyState = 0; + this.status = 0; + this.statusText = "abort"; + this.onreadystatechange(); + }, - isInstalled: function() { - return jasmine.Ajax.installed == true; - }, + readyState: 0, - assertInstalled: function() { - if (!jasmine.Ajax.isInstalled()) { - throw new Error("Mock ajax is not installed, use jasmine.Ajax.useMock()") - } - }, + onload: function() { + }, - useMock: function() { - if (!jasmine.Ajax.isInstalled()) { - var spec = jasmine.getEnv().currentSpec; - spec.after(jasmine.Ajax.uninstallMock); + onreadystatechange: function(isTimeout) { + }, - jasmine.Ajax.installMock(); - } - }, + status: null, - installMock: function() { - if (typeof jQuery != 'undefined') { - jasmine.Ajax.installJquery(); - } else if (typeof Prototype != 'undefined') { - jasmine.Ajax.installPrototype(); - } else { - throw new Error("jasmine.Ajax currently only supports jQuery and Prototype"); - } - jasmine.Ajax.installed = true; - }, + send: function(data) { + this.params = data; + this.readyState = 2; + this.onreadystatechange(); - installJquery: function() { - jasmine.Ajax.mode = 'jQuery'; - jasmine.Ajax.real = jQuery.ajaxSettings.xhr; - jQuery.ajaxSettings.xhr = jasmine.Ajax.jQueryMock; + var stub = stubTracker.findStub(this.url, data); + if (stub) { + this.response(stub); + } + }, - }, + data: function() { + var data = {}; + if (typeof this.params !== 'string') { return data; } + var params = this.params.split('&'); - installPrototype: function() { - jasmine.Ajax.mode = 'Prototype'; - jasmine.Ajax.real = Ajax.getTransport; + for (var i = 0; i < params.length; ++i) { + var kv = params[i].replace(/\+/g, ' ').split('='); + var key = decodeURIComponent(kv[0]); + data[key] = data[key] || []; + data[key].push(decodeURIComponent(kv[1])); + data[key].sort(); + } + return data; + }, - Ajax.getTransport = jasmine.Ajax.prototypeMock; - }, + getResponseHeader: function(name) { + return this.responseHeaders[name]; + }, - uninstallMock: function() { - jasmine.Ajax.assertInstalled(); - if (jasmine.Ajax.mode == 'jQuery') { - jQuery.ajaxSettings.xhr = jasmine.Ajax.real; - } else if (jasmine.Ajax.mode == 'Prototype') { - Ajax.getTransport = jasmine.Ajax.real; - } - jasmine.Ajax.reset(); - }, + getAllResponseHeaders: function() { + var responseHeaders = []; + for (var i in this.responseHeaders) { + if (this.responseHeaders.hasOwnProperty(i)) { + responseHeaders.push(i + ': ' + this.responseHeaders[i]); + } + } + return responseHeaders.join('\r\n'); + }, - reset: function() { - jasmine.Ajax.installed = false; - jasmine.Ajax.mode = null; - jasmine.Ajax.real = null; - }, + responseText: null, - jQueryMock: function() { - var newXhr = new FakeXMLHttpRequest(); - ajaxRequests.push(newXhr); - return newXhr; - }, + response: function(response) { + this.status = response.status; + this.statusText = response.statusText || ""; + this.responseText = response.responseText || ""; + this.readyState = 4; + this.responseHeaders = response.responseHeaders || + {"Content-type": response.contentType || "application/json" }; - prototypeMock: function() { - return new FakeXMLHttpRequest(); - }, + this.onload(); + this.onreadystatechange(); + }, - installed: false, - mode: null -} + responseTimeout: function() { + this.readyState = 4; + jasmine.clock().tick(30000); + this.onreadystatechange('timeout'); + } + }); + return FakeXMLHttpRequest; + } -// Jasmine-Ajax Glue code for Prototype.js -if (typeof Prototype != 'undefined' && Ajax && Ajax.Request) { - Ajax.Request.prototype.originalRequest = Ajax.Request.prototype.request; - Ajax.Request.prototype.request = function(url) { - this.originalRequest(url); - ajaxRequests.push(this); - }; + function RequestTracker() { + var requests = []; + + this.track = function(request) { + requests.push(request); + }; + + this.first = function() { + return requests[0]; + }; + + this.count = function() { + return requests.length; + }; + + this.reset = function() { + requests = []; + }; + + this.mostRecent = function() { + return requests[requests.length - 1]; + }; + + this.at = function(index) { + return requests[index]; + }; + + this.filter = function(url_to_match) { + if (requests.length == 0) return []; + var matching_requests = []; + + for (var i = 0; i < requests.length; i++) { + if (url_to_match instanceof RegExp && + url_to_match.test(requests[i].url)) { + matching_requests.push(requests[i]); + } else if (url_to_match instanceof Function && + url_to_match(requests[i])) { + matching_requests.push(requests[i]); + } else { + if (requests[i].url == url_to_match) { + matching_requests.push(requests[i]); + } + } + } + + return matching_requests; + }; + } + + function RequestStub(url, stubData) { + var split = url.split('?'); + this.url = split[0]; + + var normalizeQuery = function(query) { + return query ? query.split('&').sort().join('&') : undefined; + }; + + this.query = normalizeQuery(split[1]); + this.data = normalizeQuery(stubData); + + this.andReturn = function(options) { + this.status = options.status || 200; + + this.contentType = options.contentType; + this.responseText = options.responseText; + }; + + this.matches = function(fullUrl, data) { + var urlSplit = fullUrl.split('?'), + url = urlSplit[0], + query = urlSplit[1]; + return this.url === url && this.query === normalizeQuery(query) && (!this.data || this.data === normalizeQuery(data)); + }; + } + + if (typeof window === "undefined" && typeof exports === "object") { + exports.MockAjax = MockAjax; + jasmine.Ajax = new MockAjax(exports); + } else { + window.MockAjax = MockAjax; + jasmine.Ajax = new MockAjax(window); + } +}()); - Ajax.Request.prototype.response = function(responseOptions) { - return this.transport.response(responseOptions); - }; -} \ No newline at end of file From c81379d38f3f066f508abeb545e05dd98ce6308f Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 1 Mar 2014 13:04:31 +0100 Subject: [PATCH 035/785] port some more JS specs to jasmine 2.0... still a lot to do --- app/assets/javascripts/app/models/stream.js | 5 +- .../app/collections/aspects_spec.js | 28 +++---- .../app/models/post/interacations_spec.js | 38 +++++---- .../app/models/stream_aspects_spec.js | 2 +- spec/javascripts/app/models/stream_spec.js | 80 ++++++++++--------- spec/javascripts/helpers/factory.js | 4 +- 6 files changed, 79 insertions(+), 78 deletions(-) diff --git a/app/assets/javascripts/app/models/stream.js b/app/assets/javascripts/app/models/stream.js index 4cf5ff737..d38806f51 100644 --- a/app/assets/javascripts/app/models/stream.js +++ b/app/assets/javascripts/app/models/stream.js @@ -19,13 +19,12 @@ app.models.Stream = Backbone.Collection.extend({ var defaultOpts = { remove: false // tell backbone to keep existing items in the collection }; - return _.extend({}, defaultOpts, opts); + return _.extend({ url: this.url() }, defaultOpts, opts); }, fetch: function() { if( this.isFetching() ) return false; - var url = this.url(); - this.deferred = this.items.fetch(this._fetchOpts({url : url})) + this.deferred = this.items.fetch( this._fetchOpts() ) .done(_.bind(this.triggerFetchedEvents, this)); }, diff --git a/spec/javascripts/app/collections/aspects_spec.js b/spec/javascripts/app/collections/aspects_spec.js index 280dd7592..ab89a4206 100644 --- a/spec/javascripts/app/collections/aspects_spec.js +++ b/spec/javascripts/app/collections/aspects_spec.js @@ -1,13 +1,17 @@ describe("app.collections.Aspects", function(){ beforeEach(function(){ - Diaspora.I18n.load({ - 'and' : "and", - 'comma' : ",", - 'my_aspects' : "My Aspects" - }); - var my_aspects = [{ name: 'Work', selected: true }, - { name: 'Friends', selected: false }, - { name: 'Acquaintances', selected: false }] + var locale = { + and: 'and', + comma: ',', + my_aspects: 'My Aspects' + }; + var my_aspects = [ + { name: 'Work', selected: true }, + { name: 'Friends', selected: false }, + { name: 'Acquaintances', selected: false } + ]; + + Diaspora.I18n.load(locale); this.aspects = new app.collections.Aspects(my_aspects); }); @@ -44,25 +48,21 @@ describe("app.collections.Aspects", function(){ describe("#toSentence", function(){ describe('without aspects', function(){ beforeEach(function(){ - this.aspects = new app.collections.Aspects({ name: 'Work', selected: false }) - spyOn(this.aspects, 'selectedAspects').andCallThrough(); + this.aspects = new app.collections.Aspects([{ name: 'Work', selected: false }]); }); it("returns the name of the aspect", function(){ expect(this.aspects.toSentence()).toEqual('My Aspects'); - expect(this.aspects.selectedAspects).toHaveBeenCalled(); }); }); describe("with one aspect", function(){ beforeEach(function(){ - this.aspects = new app.collections.Aspects({ name: 'Work', selected: true }) - spyOn(this.aspects, 'selectedAspects').andCallThrough(); + this.aspects = new app.collections.Aspects([{ name: 'Work', selected: true }]); }); it("returns the name of the aspect", function(){ expect(this.aspects.toSentence()).toEqual('Work'); - expect(this.aspects.selectedAspects).toHaveBeenCalled(); }); }); diff --git a/spec/javascripts/app/models/post/interacations_spec.js b/spec/javascripts/app/models/post/interacations_spec.js index f6a5be3ad..a4e601727 100644 --- a/spec/javascripts/app/models/post/interacations_spec.js +++ b/spec/javascripts/app/models/post/interacations_spec.js @@ -1,45 +1,43 @@ describe("app.models.Post.Interactions", function(){ beforeEach(function(){ - this.interactions = factory.post() - this.interactions = this.interactions.interactions + this.interactions = factory.post().interactions; this.author = factory.author({guid: "loggedInAsARockstar"}) loginAs({guid: "loggedInAsARockstar"}) this.userLike = new app.models.Like({author : this.author}) - }) - + }); + describe("toggleLike", function(){ it("calls unliked when the user_like exists", function(){ + spyOn(this.interactions, "unlike").and.returnValue(true); this.interactions.likes.add(this.userLike) - spyOn(this.interactions, "unlike").andReturn(true); this.interactions.toggleLike(); + expect(this.interactions.unlike).toHaveBeenCalled(); - }) + }); it("calls liked when the user_like does not exist", function(){ + spyOn(this.interactions, "like").and.returnValue(true); this.interactions.likes.reset([]); - spyOn(this.interactions, "like").andReturn(true); this.interactions.toggleLike(); + expect(this.interactions.like).toHaveBeenCalled(); - }) - }) + }); + }); describe("like", function(){ it("calls create on the likes collection", function(){ - spyOn(this.interactions.likes, "create"); - this.interactions.like(); - expect(this.interactions.likes.create).toHaveBeenCalled(); - }) - }) + expect(this.interactions.likes.length).toEqual(1); + }); + }); describe("unlike", function(){ it("calls destroy on the likes collection", function(){ this.interactions.likes.add(this.userLike) - spyOn(this.userLike, "destroy"); - this.interactions.unlike(); - expect(this.userLike.destroy).toHaveBeenCalled(); - }) - }) -}) \ No newline at end of file + + expect(this.interactions.likes.length).toEqual(0); + }); + }); +}); diff --git a/spec/javascripts/app/models/stream_aspects_spec.js b/spec/javascripts/app/models/stream_aspects_spec.js index f6d99195c..35ba94a4e 100644 --- a/spec/javascripts/app/models/stream_aspects_spec.js +++ b/spec/javascripts/app/models/stream_aspects_spec.js @@ -6,7 +6,7 @@ describe("app.models.StreamAspects", function() { beforeEach(function(){ fetch = new $.Deferred(); stream = new app.models.StreamAspects([], {aspects_ids: [1,2]}); - spyOn(stream.items, "fetch").andCallFake(function(options){ + spyOn(stream.items, "fetch").and.callFake(function(options){ stream.items.set([{name: 'a'}, {name: 'b'}, {name: 'c'}], options); fetch.resolve(); return fetch; diff --git a/spec/javascripts/app/models/stream_spec.js b/spec/javascripts/app/models/stream_spec.js index 2b0094234..0778dbf1f 100644 --- a/spec/javascripts/app/models/stream_spec.js +++ b/spec/javascripts/app/models/stream_spec.js @@ -1,55 +1,59 @@ describe("app.models.Stream", function() { + var stream, + expectedPath; + beforeEach(function(){ - this.stream = new app.models.Stream(), - this.expectedPath = document.location.pathname; - }) - - describe(".fetch", function() { - var postFetch - beforeEach(function(){ - postFetch = new $.Deferred() - - spyOn(this.stream.items, "fetch").andCallFake(function(){ - return postFetch - }) - }) + stream = new app.models.Stream(); + expectedPath = document.location.pathname; + }); + describe("#_fetchOpts", function() { it("it fetches posts from the window's url, and ads them to the collection", function() { - this.stream.fetch() - expect(this.stream.items.fetch).toHaveBeenCalledWith({ remove: false, url: this.expectedPath}); + expect( stream._fetchOpts() ).toEqual({ remove: false, url: expectedPath}); }); it("returns the json path with max_time if the collection has models", function() { - var post = new app.models.Post(); - spyOn(post, "createdAt").andReturn(1234); - this.stream.add(post); + var post = new app.models.Post({created_at: 1234000}); + stream.add(post); - this.stream.fetch() - expect(this.stream.items.fetch).toHaveBeenCalledWith({ remove: false, url: this.expectedPath + "?max_time=1234"}); + expect( stream._fetchOpts() ).toEqual({ remove: false, url: expectedPath + "?max_time=1234"}); + }); + }); + + describe("events", function() { + var postFetch, + fetchedSpy; + + beforeEach(function(){ + postFetch = new $.Deferred(); + fetchedSpy = jasmine.createSpy(); + spyOn(stream.items, "fetch").and.callFake(function(){ + return postFetch; + }); }); it("triggers fetched on the stream when it is fetched", function(){ - var fetchedSpy = jasmine.createSpy() - this.stream.bind('fetched', fetchedSpy) - this.stream.fetch() - postFetch.resolve([1,2,3]) - expect(fetchedSpy).toHaveBeenCalled() - }) + stream.bind('fetched', fetchedSpy); + stream.fetch(); + postFetch.resolve([1,2,3]); + + expect(fetchedSpy).toHaveBeenCalled(); + }); it("triggers allItemsLoaded on the stream when zero posts are returned", function(){ - var fetchedSpy = jasmine.createSpy() - this.stream.bind('allItemsLoaded', fetchedSpy) - this.stream.fetch() - postFetch.resolve([]) - expect(fetchedSpy).toHaveBeenCalled() - }) + stream.bind('allItemsLoaded', fetchedSpy); + stream.fetch(); + postFetch.resolve([]); + + expect(fetchedSpy).toHaveBeenCalled(); + }); it("triggers allItemsLoaded on the stream when a Post is returned", function(){ - var fetchedSpy = jasmine.createSpy() - this.stream.bind('allItemsLoaded', fetchedSpy) - this.stream.fetch() - postFetch.resolve(factory.post().attributes) - expect(fetchedSpy).toHaveBeenCalled() - }) + stream.bind('allItemsLoaded', fetchedSpy); + stream.fetch(); + postFetch.resolve(factory.post().attributes); + + expect(fetchedSpy).toHaveBeenCalled(); + }); }); }); diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index b5dd63068..8f6be8b89 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -29,7 +29,7 @@ factory = { "id" : this.id.next(), "text" : "This is a comment!" } - + return new app.models.Comment(_.extend(defaultAttrs, overrides)) }, @@ -162,4 +162,4 @@ factory = { } } -factory.author = factory.userAttrs +factory.author = factory.userAttrs; From adf7aa98ddc2b2aa6f8a2d9000452ce897983818 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Wed, 5 Mar 2014 20:36:30 +0100 Subject: [PATCH 036/785] port router specs, don't test backbone - our own code is enough --- app/assets/javascripts/app/router.js | 8 ++-- spec/javascripts/app/router_spec.js | 55 +++++++++------------- spec/javascripts/helpers/factory.js | 21 ++++++--- spec/javascripts/helpers/jasmine-jquery.js | 2 +- 4 files changed, 43 insertions(+), 43 deletions(-) diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index d795f0e7d..4f6568b2c 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -59,7 +59,7 @@ app.Router = Backbone.Router.extend({ $("#main_stream").html(app.page.render().el); $('#selected_aspect_contacts .content').html(streamFacesView.render().el); - this.hideInactiveStreamLists(); + this._hideInactiveStreamLists(); }, photos : function() { @@ -84,7 +84,7 @@ app.Router = Backbone.Router.extend({ ); $("#author_info").prepend(followedTagsAction.render().el) } - this.hideInactiveStreamLists(); + this._hideInactiveStreamLists(); }, aspects : function(){ @@ -107,10 +107,10 @@ app.Router = Backbone.Router.extend({ $("#main_stream").html(app.page.render().el); $('#selected_aspect_contacts .content').html(streamFacesView.render().el); - this.hideInactiveStreamLists(); + this._hideInactiveStreamLists(); }, - hideInactiveStreamLists: function() { + _hideInactiveStreamLists: function() { if(this.aspects_list && Backbone.history.fragment != "aspects") this.aspects_list.hideAspectsList(); diff --git a/spec/javascripts/app/router_spec.js b/spec/javascripts/app/router_spec.js index 6371f34e1..74afd9190 100644 --- a/spec/javascripts/app/router_spec.js +++ b/spec/javascripts/app/router_spec.js @@ -1,33 +1,27 @@ describe('app.Router', function () { describe('followed_tags', function() { + beforeEach(function() { + factory.preloads({tagFollowings: []}); + }); + it('decodes name before passing it into TagFollowingAction', function () { - var followed_tags = spyOn(app.router, 'followed_tags').andCallThrough(); - var tag_following_action = spyOn(app.views, 'TagFollowingAction').andCallFake(function(data) { + var followed_tags = spyOn(app.router, 'followed_tags').and.callThrough(); + var tag_following_action = spyOn(app.views, 'TagFollowingAction').and.callFake(function(data) { return {render: function() { return {el: ""}}}; }); - spyOn(window.history, 'pushState').andCallFake(function (data, title, url) { - var route = app.router._routeToRegExp("tags/:name"); - var args = app.router._extractParameters(route, url.replace(/^\//, "")); - app.router.followed_tags(args[0]); - }); - window.preloads = {tagFollowings: []}; - app.router.navigate('/tags/'+encodeURIComponent('օբյեկտիվ')); + + app.router.followed_tags(encodeURIComponent('օբյեկտիվ')); expect(followed_tags).toHaveBeenCalled(); expect(tag_following_action).toHaveBeenCalledWith({tagText: 'օբյեկտիվ'}); }); it('navigates to the downcase version of the corresponding tag', function () { - var followed_tags = spyOn(app.router, 'followed_tags').andCallThrough(); - var tag_following_action = spyOn(app.views, 'TagFollowingAction').andCallFake(function(data) { + var followed_tags = spyOn(app.router, 'followed_tags').and.callThrough(); + var tag_following_action = spyOn(app.views, 'TagFollowingAction').and.callFake(function(data) { return {render: function() { return {el: ""}}}; }); - spyOn(window.history, 'pushState').andCallFake(function (data, title, url) { - var route = app.router._routeToRegExp("tags/:name"); - var args = app.router._extractParameters(route, url.replace(/^\//, "")); - app.router.followed_tags(args[0]); - }); - window.preloads = {tagFollowings: []}; - app.router.navigate('/tags/'+encodeURIComponent('SomethingWithCapitalLetters')); + + app.router.followed_tags('SomethingWithCapitalLetters'); expect(followed_tags).toHaveBeenCalled(); expect(tag_following_action).toHaveBeenCalledWith({tagText: 'somethingwithcapitalletters'}); }); @@ -42,31 +36,28 @@ describe('app.Router', function () { router = new app.Router(); }); - it('calls hideInactiveStreamLists', function () { - var hideInactiveStreamLists = spyOn(router, 'hideInactiveStreamLists').andCallThrough(); - - router.stream(); - expect(hideInactiveStreamLists).toHaveBeenCalled(); - }); - it('hides the aspects list', function(){ - aspects = new app.collections.Aspects([{ name: 'Work', selected: true }]); - var aspectsListView = new app.views.AspectsList({collection: aspects}); - var hideAspectsList = spyOn(aspectsListView, 'hideAspectsList').andCallThrough(); + setFixtures('
'); + aspects = new app.collections.Aspects([ + { name: 'Work', selected: true }, + { name: 'Fun', selected: false } + ]); + var aspectsListView = new app.views.AspectsList({collection: aspects}).render(); router.aspects_list = aspectsListView; + expect(aspectsListView.$el.html()).not.toBe(""); router.stream(); - expect(hideAspectsList).toHaveBeenCalled(); + expect(aspectsListView.$el.html()).toBe(""); }); it('hides the followed tags view', function(){ tagFollowings = new app.collections.TagFollowings(); - var followedTagsView = new app.views.TagFollowingList({collection: tagFollowings}); - var hideFollowedTags = spyOn(followedTagsView, 'hideFollowedTags').andCallThrough(); + var followedTagsView = new app.views.TagFollowingList({collection: tagFollowings}).render(); router.followedTagsView = followedTagsView; + expect(followedTagsView.$el.html()).not.toBe(""); router.stream(); - expect(hideFollowedTags).toHaveBeenCalled(); + expect(followedTagsView.$el.html()).toBe(""); }); }); diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index 8f6be8b89..1f1ae657c 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -151,14 +151,23 @@ factory = { comment: function(overrides) { var defaultAttrs = { - "text" : "This is an awesome comment!", - "created_at" : "2012-01-03T19:53:13Z", - "author" : this.author(), - "guid" : this.guid(), - "id": this.id.next() - } + id: this.id.next(), + guid: this.guid(), + text: "This is an awesome comment!", + author: this.author(), + created_at: "2012-01-03T19:53:13Z" + }; return new app.models.Comment(_.extend(defaultAttrs, overrides)) + }, + + preloads: function(overrides) { + var defaults = { + aspect_ids: [] + }; + + window.gon = { preloads: {} }; + _.extend(window.gon.preloads, defaults, overrides); } } diff --git a/spec/javascripts/helpers/jasmine-jquery.js b/spec/javascripts/helpers/jasmine-jquery.js index 0096c4fc5..5e659195e 100644 --- a/spec/javascripts/helpers/jasmine-jquery.js +++ b/spec/javascripts/helpers/jasmine-jquery.js @@ -200,4 +200,4 @@ beforeEach(function() { afterEach(function() { jasmine.getFixtures().cleanUp(); -}); \ No newline at end of file +}); From 4d3874cc2ed05a0f292051519659232d3ae02758 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Fri, 7 Mar 2014 16:22:41 +0100 Subject: [PATCH 037/785] port more specs, add aspect factory --- spec/javascripts/app/router_spec.js | 4 +- .../app/views/aspect_membership_view_spec.js | 71 +++++++++++-------- .../javascripts/app/views/aspect_view_spec.js | 6 +- .../app/views/aspects_list_view_spec.js | 4 +- .../app/views/comment_stream_view_spec.js | 27 ++++--- .../app/views/comment_view_spec.js | 12 ++-- spec/javascripts/helpers/factory.js | 14 ++++ 7 files changed, 81 insertions(+), 57 deletions(-) diff --git a/spec/javascripts/app/router_spec.js b/spec/javascripts/app/router_spec.js index 74afd9190..3beac1f07 100644 --- a/spec/javascripts/app/router_spec.js +++ b/spec/javascripts/app/router_spec.js @@ -39,8 +39,8 @@ describe('app.Router', function () { it('hides the aspects list', function(){ setFixtures('
'); aspects = new app.collections.Aspects([ - { name: 'Work', selected: true }, - { name: 'Fun', selected: false } + factory.aspectAttrs({selected:true}), + factory.aspectAttrs() ]); var aspectsListView = new app.views.AspectsList({collection: aspects}).render(); router.aspects_list = aspectsListView; diff --git a/spec/javascripts/app/views/aspect_membership_view_spec.js b/spec/javascripts/app/views/aspect_membership_view_spec.js index 5f5abe9bb..b04f57f59 100644 --- a/spec/javascripts/app/views/aspect_membership_view_spec.js +++ b/spec/javascripts/app/views/aspect_membership_view_spec.js @@ -1,9 +1,20 @@ describe("app.views.AspectMembership", function(){ + var resp_success = {status: 200, responseText: '{}'}; + var resp_fail = {status: 400}; + beforeEach(function() { // mock a dummy aspect dropdown spec.loadFixture("aspect_membership_dropdown_bootstrap"); this.view = new app.views.AspectMembership({el: $('.aspect_membership_dropdown')}); this.person_id = $('.dropdown-menu').data('person_id'); + Diaspora.I18n.load({ + aspect_dropdown: { + started_sharing_with: 'you started sharing with <%= name %>', + stopped_sharing_with: 'you stopped sharing with <%= name %>', + error: 'unable to add <%= name %>', + error_remove: 'unable to remove <%= name %>' + } + }); }); context('adding to aspects', function() { @@ -12,29 +23,30 @@ describe("app.views.AspectMembership", function(){ this.newAspectId = this.newAspect.data('aspect_id'); }); - it('calls "addMembership"', function() { - spyOn(this.view, "addMembership"); - this.newAspect.trigger('click'); + it('marks the aspect as selected', function() { + this.newAspect.trigger('click'); + jasmine.Ajax.requests.mostRecent().response(resp_success); - expect(this.view.addMembership).toHaveBeenCalledWith(this.person_id, this.newAspectId); + expect(this.newAspect.attr('class')).toContain('selected'); }); - it('tries to create a new AspectMembership', function() { - spyOn(app.models.AspectMembership.prototype, "save"); - this.view.addMembership(1, 2); + it('displays flash message when added to first aspect', function() { + spec.content().find('li').removeClass('selected'); + this.newAspect.trigger('click'); + jasmine.Ajax.requests.mostRecent().response(resp_success); - expect(app.models.AspectMembership.prototype.save).toHaveBeenCalled(); + expect($('[id^="flash"]')).toBeSuccessFlashMessage( + Diaspora.I18n.t('aspect_dropdown.started_sharing_with', {name: this.person.name}) + ); }); it('displays an error when it fails', function() { - spyOn(this.view, "_displayError"); - spyOn(app.models.AspectMembership.prototype, "save").andCallFake(function() { - this.trigger('error'); - }); + this.newAspect.trigger('click'); + jasmine.Ajax.requests.mostRecent().response(resp_fail); - this.view.addMembership(1, 2); - - expect(this.view._displayError).toHaveBeenCalledWith('aspect_dropdown.error'); + expect($('[id^="flash"]')).toBeErrorFlashMessage( + Diaspora.I18n.t('aspect_dropdown.error', {name: this.person.name}) + ); }); }); @@ -44,29 +56,30 @@ describe("app.views.AspectMembership", function(){ this.oldMembershipId = this.oldAspect.data('membership_id'); }); - it('calls "removeMembership"', function(){ - spyOn(this.view, "removeMembership"); + it('marks the aspect as unselected', function(){ this.oldAspect.trigger('click'); + jasmine.Ajax.requests.mostRecent().response(resp_success); - expect(this.view.removeMembership).toHaveBeenCalledWith(this.oldMembershipId); + expect(this.oldAspect.attr('class')).not.toContain('selected'); }); - it('tries to destroy an AspectMembership', function() { - spyOn(app.models.AspectMembership.prototype, "destroy"); - this.view.removeMembership(1); + it('displays a flash message when removed from last aspect', function() { + spec.content().find('li.selected:last').removeClass('selected'); + this.oldAspect.trigger('click'); + jasmine.Ajax.requests.mostRecent().response(resp_success); - expect(app.models.AspectMembership.prototype.destroy).toHaveBeenCalled(); + expect($('[id^="flash"]')).toBeSuccessFlashMessage( + Diaspora.I18n.t('aspect_dropdown.stopped_sharing_with', {name: this.person.name}) + ); }); it('displays an error when it fails', function() { - spyOn(this.view, "_displayError"); - spyOn(app.models.AspectMembership.prototype, "destroy").andCallFake(function() { - this.trigger('error'); - }); + this.oldAspect.trigger('click'); + jasmine.Ajax.requests.mostRecent().response(resp_fail); - this.view.removeMembership(1); - - expect(this.view._displayError).toHaveBeenCalledWith('aspect_dropdown.error_remove'); + expect($('[id^="flash"]')).toBeErrorFlashMessage( + Diaspora.I18n.t('aspect_dropdown.error_remove', {name: this.person.name}) + ); }); }); diff --git a/spec/javascripts/app/views/aspect_view_spec.js b/spec/javascripts/app/views/aspect_view_spec.js index 40839c922..1247d6ad6 100644 --- a/spec/javascripts/app/views/aspect_view_spec.js +++ b/spec/javascripts/app/views/aspect_view_spec.js @@ -1,6 +1,6 @@ describe("app.views.Aspect", function(){ beforeEach(function(){ - this.aspect = new app.models.Aspect({ name: 'Acquaintances', selected: true }); + this.aspect = factory.aspect({selected:true}); this.view = new app.views.Aspect({ model: this.aspect }); }); @@ -14,14 +14,14 @@ describe("app.views.Aspect", function(){ }); it('should show the name of the aspect', function(){ - expect(this.view.$el.children('a.selectable').text()).toMatch('Acquaintances'); + expect(this.view.$el.children('a.selectable').text()).toMatch(this.aspect.get('name')); }); describe('selecting aspects', function(){ beforeEach(function(){ app.router = new app.Router(); spyOn(app.router, 'aspects_stream'); - spyOn(this.view, 'toggleAspect').andCallThrough(); + spyOn(this.view, 'toggleAspect').and.callThrough(); this.view.delegateEvents(); }); diff --git a/spec/javascripts/app/views/aspects_list_view_spec.js b/spec/javascripts/app/views/aspects_list_view_spec.js index 81bc7b19f..e6bd915ec 100644 --- a/spec/javascripts/app/views/aspects_list_view_spec.js +++ b/spec/javascripts/app/views/aspects_list_view_spec.js @@ -40,8 +40,8 @@ describe("app.views.AspectsList", function(){ beforeEach(function(){ app.router = new app.Router(); spyOn(app.router, 'aspects_stream'); - spyOn(this.view, 'toggleAll').andCallThrough(); - spyOn(this.view, 'toggleSelector').andCallThrough(); + spyOn(this.view, 'toggleAll').and.callThrough(); + spyOn(this.view, 'toggleSelector').and.callThrough(); this.view.delegateEvents(); this.view.$('.toggle_selector').click(); }); diff --git a/spec/javascripts/app/views/comment_stream_view_spec.js b/spec/javascripts/app/views/comment_stream_view_spec.js index 38948d294..816ce35a2 100644 --- a/spec/javascripts/app/views/comment_stream_view_spec.js +++ b/spec/javascripts/app/views/comment_stream_view_spec.js @@ -18,20 +18,19 @@ describe("app.views.CommentStream", function(){ spyOn($.fn, "placeholder") this.view.postRenderTemplate() expect($.fn.placeholder).toHaveBeenCalled() - expect($.fn.placeholder.mostRecentCall.object.selector).toBe("textarea") + expect($.fn.placeholder.calls.mostRecent().object.selector).toBe("textarea") }); it("autoResizes the new comment textarea", function(){ spyOn($.fn, "autoResize") this.view.postRenderTemplate() expect($.fn.autoResize).toHaveBeenCalled() - expect($.fn.autoResize.mostRecentCall.object.selector).toBe("textarea") + expect($.fn.autoResize.calls.mostRecent().object.selector).toBe("textarea") }); }); describe("createComment", function() { beforeEach(function() { - jasmine.Ajax.useMock(); this.view.render(); this.view.expandComments(); }); @@ -41,7 +40,7 @@ describe("app.views.CommentStream", function(){ this.view.$(".comment_box").val('a new comment'); this.view.createComment(); - this.request = mostRecentAjaxRequest(); + this.request = jasmine.Ajax.requests.mostRecent(); }); it("fires an AJAX request", function() { @@ -90,28 +89,27 @@ describe("app.views.CommentStream", function(){ describe("expandComments", function() { it("refills the comment textbox on success", function() { - jasmine.Ajax.useMock(); - this.view.render(); - this.view.$("textarea").val("great post!"); - this.view.expandComments(); - mostRecentAjaxRequest().response({ - status: 200, - responseText: JSON.stringify([factory.comment()]) - }); + jasmine.Ajax.requests.mostRecent().response({ comments : [] }); expect(this.view.$("textarea").val()).toEqual("great post!"); }); }); describe("pressing a key when typing on the new comment box", function(){ + var submitCallback; + + beforeEach(function() { + submitCallback = jasmine.createSpy().and.returnValue(false); + }); + it("should not submit the form when enter key is pressed", function(){ this.view.render(); var form = this.view.$("form") - var submitCallback = jasmine.createSpy().andReturn(false);form.submit(submitCallback); + form.submit(submitCallback); var e = $.Event("keydown", { keyCode: 13 }); e.shiftKey = false; @@ -122,8 +120,7 @@ describe("app.views.CommentStream", function(){ it("should submit the form when enter is pressed with ctrl", function(){ this.view.render(); - var form = this.view.$("form") - var submitCallback = jasmine.createSpy().andReturn(false); + var form = this.view.$("form"); form.submit(submitCallback); var e = $.Event("keydown", { keyCode: 13 }); diff --git a/spec/javascripts/app/views/comment_view_spec.js b/spec/javascripts/app/views/comment_view_spec.js index 2b1676b9d..4ba3f708b 100644 --- a/spec/javascripts/app/views/comment_view_spec.js +++ b/spec/javascripts/app/views/comment_view_spec.js @@ -49,15 +49,15 @@ describe("app.views.Comment", function(){ describe("canRemove", function(){ context("is truthy", function(){ it("when ownComment is true", function(){ - spyOn(this.view, "ownComment").andReturn(true) - spyOn(this.view, "postOwner").andReturn(false) + spyOn(this.view, "ownComment").and.returnValue(true) + spyOn(this.view, "postOwner").and.returnValue(false) expect(this.view.canRemove()).toBe(true) }) it("when postOwner is true", function(){ - spyOn(this.view, "postOwner").andReturn(true) - spyOn(this.view, "ownComment").andReturn(false) + spyOn(this.view, "postOwner").and.returnValue(true) + spyOn(this.view, "ownComment").and.returnValue(false) expect(this.view.canRemove()).toBe(true) }) @@ -65,8 +65,8 @@ describe("app.views.Comment", function(){ context("is falsy", function(){ it("when postOwner and ownComment are both false", function(){ - spyOn(this.view, "postOwner").andReturn(false) - spyOn(this.view, "ownComment").andReturn(false) + spyOn(this.view, "postOwner").and.returnValue(false) + spyOn(this.view, "ownComment").and.returnValue(false) expect(this.view.canRemove()).toBe(false) }) diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index 1f1ae657c..b8e5d360b 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -161,6 +161,20 @@ factory = { return new app.models.Comment(_.extend(defaultAttrs, overrides)) }, + aspectAttrs: function(overrides) { + var names = ['Work','School','Family','Friends','Just following','People','Interesting']; + var defaultAttrs = { + name: names[Math.floor(Math.random()*names.length)]+' '+Math.floor(Math.random()*100), + selected: false + }; + + return _.extend({}, defaultAttrs, overrides); + }, + + aspect: function(overrides) { + return new app.models.Aspect(this.aspectAttrs(overrides)); + }, + preloads: function(overrides) { var defaults = { aspect_ids: [] From d4aca571ac604b2e52280cfacf74781bc373a813 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Fri, 14 Mar 2014 07:52:13 +0100 Subject: [PATCH 038/785] add jasmine-jquery gem and use it, port some more specs --- Gemfile | 1 + Gemfile.lock | 2 + .../app/views/feedback_view_spec.js | 6 +- spec/javascripts/helpers/SpecHelper.js | 4 +- spec/javascripts/helpers/jasmine-jquery.js | 203 ------------------ spec/javascripts/support/jasmine.yml | 1 + 6 files changed, 10 insertions(+), 207 deletions(-) delete mode 100644 spec/javascripts/helpers/jasmine-jquery.js diff --git a/Gemfile b/Gemfile index 265fc4e9d..759f9c4da 100644 --- a/Gemfile +++ b/Gemfile @@ -213,5 +213,6 @@ group :development, :test do # Jasmine (client side application tests (JS)) gem 'jasmine', '2.0.0' + gem 'jasmine-jquery-rails', '2.0.2' gem 'sinon-rails', '1.9.0' end diff --git a/Gemfile.lock b/Gemfile.lock index 21598ae56..ca6c3117b 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -224,6 +224,7 @@ GEM rack (>= 1.2.1) rake jasmine-core (2.0.0) + jasmine-jquery-rails (2.0.2) jquery-rails (3.0.4) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) @@ -506,6 +507,7 @@ DEPENDENCIES http_accept_language (= 1.0.2) i18n-inflector-rails (= 1.0.7) jasmine (= 2.0.0) + jasmine-jquery-rails (= 2.0.2) jquery-rails (= 3.0.4) json (= 1.8.1) markerb (= 1.0.2) diff --git a/spec/javascripts/app/views/feedback_view_spec.js b/spec/javascripts/app/views/feedback_view_spec.js index a8e57d8af..728ddc96f 100644 --- a/spec/javascripts/app/views/feedback_view_spec.js +++ b/spec/javascripts/app/views/feedback_view_spec.js @@ -41,7 +41,7 @@ describe("app.views.Feedback", function(){ context("when the user likes the post", function(){ it("the like action should be 'Unlike'", function(){ - spyOn(this.post.interactions, "userLike").andReturn(factory.like()); + spyOn(this.post.interactions, "userLike").and.returnValue(factory.like()); this.view.render() expect(this.link().text()).toContain(Diaspora.I18n.t('stream.unlike')) }) @@ -137,8 +137,8 @@ describe("app.views.Feedback", function(){ }) it("reshares the model", function(){ - spyOn(window, "confirm").andReturn(true); - spyOn(this.view.model.reshare(), "save").andReturn(new $.Deferred) + spyOn(window, "confirm").and.returnValue(true); + spyOn(this.view.model.reshare(), "save").and.returnValue(new $.Deferred) this.view.$("a.reshare").first().click(); expect(this.view.model.reshare().save).toHaveBeenCalled(); }) diff --git a/spec/javascripts/helpers/SpecHelper.js b/spec/javascripts/helpers/SpecHelper.js index 92a22e0bb..3b69d5dd5 100644 --- a/spec/javascripts/helpers/SpecHelper.js +++ b/spec/javascripts/helpers/SpecHelper.js @@ -1,5 +1,7 @@ // for docs, see http://jasmine.github.io +var realXMLHttpRequest = window.XMLHttpRequest; + beforeEach(function() { $('#jasmine_content').html(spec.readFixture("underscore_templates")); @@ -164,7 +166,7 @@ spec.retrieveFixture = function(fixtureName) { // retrieve the fixture markup via xhr request to jasmine server try { - xhr = new XMLHttpRequest(); + xhr = new realXMLHttpRequest(); xhr.open("GET", path, false); xhr.send(null); } catch(e) { diff --git a/spec/javascripts/helpers/jasmine-jquery.js b/spec/javascripts/helpers/jasmine-jquery.js deleted file mode 100644 index 5e659195e..000000000 --- a/spec/javascripts/helpers/jasmine-jquery.js +++ /dev/null @@ -1,203 +0,0 @@ -var readFixtures = function() { - return jasmine.getFixtures().proxyCallTo_('read', arguments); -}; - -var loadFixtures = function() { - jasmine.getFixtures().proxyCallTo_('load', arguments); -}; - -var setFixtures = function(html) { - jasmine.getFixtures().set(html); -} - -var sandbox = function(attributes) { - return jasmine.getFixtures().sandbox(attributes); -}; - -jasmine.getFixtures = function() { - return jasmine.currentFixtures_ = jasmine.currentFixtures_ || new jasmine.Fixtures(); -}; - -jasmine.Fixtures = function() { - this.containerId = 'jasmine-fixtures'; - this.fixturesCache_ = {}; -}; - -jasmine.Fixtures.prototype.set = function(html) { - this.cleanUp(); - this.createContainer_(html); -}; - -jasmine.Fixtures.prototype.load = function() { - this.cleanUp(); - this.createContainer_(this.read.apply(this, arguments)); -}; - -jasmine.Fixtures.prototype.read = function() { - var htmlChunks = []; - - var fixtureUrls = arguments; - for(var urlCount = fixtureUrls.length, urlIndex = 0; urlIndex < urlCount; urlIndex++) { - htmlChunks.push(this.getFixtureHtml_(fixtureUrls[urlIndex])); - } - - return htmlChunks.join(''); -}; - -jasmine.Fixtures.prototype.clearCache = function() { - this.fixturesCache_ = {}; -}; - -jasmine.Fixtures.prototype.cleanUp = function() { - $('#' + this.containerId).remove(); -}; - -jasmine.Fixtures.prototype.sandbox = function(attributes) { - var attributesToSet = attributes || {}; - return $('
').attr(attributesToSet); -}; - -jasmine.Fixtures.prototype.createContainer_ = function(html) { - var container = $('
'); - container.html(html); - $('body').append(container); -}; - -jasmine.Fixtures.prototype.getFixtureHtml_ = function(url) { - if (typeof this.fixturesCache_[url] == 'undefined') { - this.loadFixtureIntoCache_(url); - } - return this.fixturesCache_[url]; -}; - -jasmine.Fixtures.prototype.loadFixtureIntoCache_ = function(url) { - var self = this; - $.ajax({ - async: false, // must be synchronous to guarantee that no tests are run before fixture is loaded - cache: false, - dataType: 'html', - url: url, - success: function(data) { - self.fixturesCache_[url] = data; - } - }); -}; - -jasmine.Fixtures.prototype.proxyCallTo_ = function(methodName, passedArguments) { - return this[methodName].apply(this, passedArguments); -}; - - -jasmine.JQuery = function() {}; - -jasmine.JQuery.browserTagCaseIndependentHtml = function(html) { - return $('
').append(html).html(); -}; - -jasmine.JQuery.elementToString = function(element) { - return $('
').append(element.clone()).html(); -}; - -jasmine.JQuery.matchersClass = {}; - - -(function(){ - var jQueryMatchers = { - toHaveClass: function(className) { - return this.actual.hasClass(className); - }, - - toBeVisible: function() { - return this.actual.is(':visible'); - }, - - toBeHidden: function() { - return this.actual.is(':hidden'); - }, - - toBeSelected: function() { - return this.actual.is(':selected'); - }, - - toBeChecked: function() { - return this.actual.is(':checked'); - }, - - toBeEmpty: function() { - return this.actual.is(':empty'); - }, - - toExist: function() { - return this.actual.size() > 0; - }, - - toHaveAttr: function(attributeName, expectedAttributeValue) { - return hasProperty(this.actual.attr(attributeName), expectedAttributeValue); - }, - - toHaveId: function(id) { - return this.actual.attr('id') == id; - }, - - toHaveHtml: function(html) { - return this.actual.html() == jasmine.JQuery.browserTagCaseIndependentHtml(html); - }, - - toHaveText: function(text) { - return this.actual.text() == text; - }, - - toHaveValue: function(value) { - return this.actual.val() == value; - }, - - toHaveData: function(key, expectedValue) { - return hasProperty(this.actual.data(key), expectedValue); - }, - - toBe: function(selector) { - return this.actual.is(selector); - }, - - toContain: function(selector) { - return this.actual.find(selector).size() > 0; - } - }; - - var hasProperty = function(actualValue, expectedValue) { - if (expectedValue === undefined) { - return actualValue !== undefined; - } - return actualValue == expectedValue; - }; - - var bindMatcher = function(methodName) { - var builtInMatcher = jasmine.Matchers.prototype[methodName]; - - jasmine.JQuery.matchersClass[methodName] = function() { - if (this.actual instanceof jQuery) { - var result = jQueryMatchers[methodName].apply(this, arguments); - this.actual = jasmine.JQuery.elementToString(this.actual); - return result; - } - - if (builtInMatcher) { - return builtInMatcher.apply(this, arguments); - } - - return false; - }; - }; - - for(var methodName in jQueryMatchers) { - bindMatcher(methodName); - } -})(); - -beforeEach(function() { - this.addMatchers(jasmine.JQuery.matchersClass); -}); - -afterEach(function() { - jasmine.getFixtures().cleanUp(); -}); diff --git a/spec/javascripts/support/jasmine.yml b/spec/javascripts/support/jasmine.yml index 88ff13ea4..6b6ff197a 100644 --- a/spec/javascripts/support/jasmine.yml +++ b/spec/javascripts/support/jasmine.yml @@ -12,6 +12,7 @@ src_files: # Precompile all scripts together for the test environment - assets/jasmine-load-all.js + - assets/jasmine-jquery.js # stylesheets # From 304e560e43aa62caa0aa1506e1d34e5d263d18a1 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Wed, 19 Mar 2014 23:14:07 +0100 Subject: [PATCH 039/785] use new jasmine async code --- .../javascripts/app/views/header_view_spec.js | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/spec/javascripts/app/views/header_view_spec.js b/spec/javascripts/app/views/header_view_spec.js index 3b8d76ca0..dfa055d5a 100644 --- a/spec/javascripts/app/views/header_view_spec.js +++ b/spec/javascripts/app/views/header_view_spec.js @@ -82,20 +82,23 @@ describe("app.views.Header", function() { }); describe("focus", function() { - it("adds the class 'active' when the user focuses the text field", function() { + beforeEach(function(done){ input.trigger('focusin'); - waitsFor(function() { - return input.is('.active'); - }); - runs(function() { - expect(input).toHaveClass("active"); - }); + done(); + }); + + it("adds the class 'active' when the user focuses the text field", function() { + expect(input).toHaveClass("active"); }); }); describe("blur", function() { - it("removes the class 'active' when the user blurs the text field", function() { + beforeEach(function(done) { input.trigger('focusin').trigger('focusout'); + done(); + }); + + it("removes the class 'active' when the user blurs the text field", function() { expect(input).not.toHaveClass("active"); }); }); From 037671f1b6d6f93793ab94f85a4daa44688c1cce Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Thu, 20 Mar 2014 23:09:03 +0100 Subject: [PATCH 040/785] port remaining specs - jasmine is green again (non-CI) --- .../app/views/likes_info_view_spec.js | 6 +++--- .../app/views/publisher_view_spec.js | 4 ++-- .../javascripts/app/views/stream_post_spec.js | 4 ++-- .../javascripts/app/views/stream_view_spec.js | 19 ++++++++++--------- .../views/tag_following_action_view_spec.js | 10 +++++----- spec/javascripts/app/views_spec.js | 4 ++-- spec/javascripts/contact-list-spec.js | 2 +- spec/javascripts/widgets/back-to-top-spec.js | 6 +++--- .../widgets/flash-messages-spec.js | 2 +- .../javascripts/widgets/notifications-spec.js | 6 +++--- spec/javascripts/widgets/search-spec.js | 2 +- 11 files changed, 33 insertions(+), 32 deletions(-) diff --git a/spec/javascripts/app/views/likes_info_view_spec.js b/spec/javascripts/app/views/likes_info_view_spec.js index 2f33d6218..9f4648a20 100644 --- a/spec/javascripts/app/views/likes_info_view_spec.js +++ b/spec/javascripts/app/views/likes_info_view_spec.js @@ -16,13 +16,13 @@ describe("app.views.LikesInfo", function(){ describe(".render", function(){ it("displays a the like count if it is above zero", function() { - spyOn(this.view.model.interactions, "likesCount").andReturn(3); + spyOn(this.view.model.interactions, "likesCount").and.returnValue(3); this.view.render(); expect($(this.view.el).find(".expand_likes").length).toBe(1) }) it("does not display the like count if it is zero", function() { - spyOn(this.view.model.interactions, "likesCount").andReturn(0); + spyOn(this.view.model.interactions, "likesCount").and.returnValue(0); this.view.render(); expect($(this.view.el).html().trim()).toBe(""); }) @@ -36,7 +36,7 @@ describe("app.views.LikesInfo", function(){ describe("showAvatars", function(){ beforeEach(function(){ - spyOn(this.post.interactions, "fetch").andCallThrough() + spyOn(this.post.interactions, "fetch").and.callThrough() }) it("calls fetch on the model's like collection", function(){ diff --git a/spec/javascripts/app/views/publisher_view_spec.js b/spec/javascripts/app/views/publisher_view_spec.js index 8c0e1c6db..37e27fc45 100644 --- a/spec/javascripts/app/views/publisher_view_spec.js +++ b/spec/javascripts/app/views/publisher_view_spec.js @@ -166,7 +166,7 @@ describe("app.views.Publisher", function() { it("should submit the form when ctrl+enter is pressed", function(){ this.view.render(); var form = this.view.$("form") - var submitCallback = jasmine.createSpy().andReturn(false); + var submitCallback = jasmine.createSpy().and.returnValue(false); form.submit(submitCallback); var e = $.Event("keydown", { keyCode: 13 }); @@ -499,7 +499,7 @@ describe("app.views.Publisher", function() { '' ); - spyOn(jQuery, 'ajax').andCallFake(function(opts) { opts.success(); }); + spyOn(jQuery, 'ajax').and.callFake(function(opts) { opts.success(); }); this.view.el_photozone.find('.x').click(); }); diff --git a/spec/javascripts/app/views/stream_post_spec.js b/spec/javascripts/app/views/stream_post_spec.js index 7f7de9b5e..319b09871 100644 --- a/spec/javascripts/app/views/stream_post_spec.js +++ b/spec/javascripts/app/views/stream_post_spec.js @@ -174,12 +174,12 @@ describe("app.views.StreamPost", function(){ }) it("destroys the view when they delete a their post from the show page", function(){ - spyOn(window, "confirm").andReturn(true); + spyOn(window, "confirm").and.returnValue(true); this.view.$(".remove_post").click(); expect(window.confirm).toHaveBeenCalled(); - expect(this.view).not.toExist(); + expect(this.view.el).not.toBeInDOM(); }) }) diff --git a/spec/javascripts/app/views/stream_view_spec.js b/spec/javascripts/app/views/stream_view_spec.js index dac66b2fc..3935d13a2 100644 --- a/spec/javascripts/app/views/stream_view_spec.js +++ b/spec/javascripts/app/views/stream_view_spec.js @@ -40,20 +40,21 @@ describe("app.views.Stream", function() { describe("infScroll", function() { // NOTE: inf scroll happens at 500px beforeEach(function(){ - spyOn($.fn, "height").andReturn(0); - spyOn($.fn, "scrollTop").andReturn(100); + spyOn($.fn, "height").and.returnValue(0); + spyOn($.fn, "scrollTop").and.returnValue(100); spyOn(this.view.model, "fetch"); }); - it("fetches moar when the user is at the bottom of the page", function() { - this.view.infScroll(); + describe('fetching more', function() { + beforeEach(function(done) { + this.view.on('loadMore', function() { + done(); + }); + this.view.infScroll(); + }); - waitsFor(function(){ - return this.view.model.fetch.wasCalled - }, "the infinite scroll function didn't fetch the stream"); - - runs(function(){ + it("fetches moar when the user is at the bottom of the page", function() { expect(this.view.model.fetch).toHaveBeenCalled() }); }); diff --git a/spec/javascripts/app/views/tag_following_action_view_spec.js b/spec/javascripts/app/views/tag_following_action_view_spec.js index f82d60bb3..f2fbefc07 100644 --- a/spec/javascripts/app/views/tag_following_action_view_spec.js +++ b/spec/javascripts/app/views/tag_following_action_view_spec.js @@ -7,13 +7,13 @@ describe("app.views.TagFollowingAction", function(){ describe("render", function(){ it("shows the output of followString", function(){ - spyOn(this.view, "tag_is_followed").andReturn(false) - spyOn(this.view, "followString").andReturn("a_follow_string") + spyOn(this.view, "tag_is_followed").and.returnValue(false) + spyOn(this.view, "followString").and.returnValue("a_follow_string") expect(this.view.render().$('input').val()).toMatch(/^a_follow_string$/) }) it("should have the extra classes if the tag is followed", function(){ - spyOn(this.view, "tag_is_followed").andReturn(true) + spyOn(this.view, "tag_is_followed").and.returnValue(true) expect(this.view.render().$('input').hasClass("red_on_hover")).toBe(true) expect(this.view.render().$('input').hasClass("in_aspects")).toBe(true) }) @@ -26,7 +26,7 @@ describe("app.views.TagFollowingAction", function(){ this.view.model.set("id", 3); expect(this.view.tag_is_followed()).toBe(true); - spyOn(this.view.model, "destroy").andCallFake(_.bind(function(){ + spyOn(this.view.model, "destroy").and.callFake(_.bind(function(){ // model.destroy leads to collection.remove, which is bound to getTagFollowing this.view.getTagFollowing(); }, this) ) @@ -39,7 +39,7 @@ describe("app.views.TagFollowingAction", function(){ it("toggles the tagFollowed from unfollowed to followed", function(){ expect(this.view.tag_is_followed()).toBe(false); - spyOn(app.tagFollowings, "create").andCallFake(function(model){ + spyOn(app.tagFollowings, "create").and.callFake(function(model){ // 'save' the model by giving it an id model.set("id", 3) }) diff --git a/spec/javascripts/app/views_spec.js b/spec/javascripts/app/views_spec.js index e26eba16a..cf54c6eb0 100644 --- a/spec/javascripts/app/views_spec.js +++ b/spec/javascripts/app/views_spec.js @@ -66,7 +66,7 @@ describe("app.views.Base", function(){ spyOn($.fn, "timeago") this.view.render() expect($.fn.timeago).toHaveBeenCalled() - expect($.fn.timeago.mostRecentCall.object.selector).toBe("time") + expect($.fn.timeago.calls.mostRecent().object.selector).toBe("time") }) @@ -75,7 +75,7 @@ describe("app.views.Base", function(){ spyOn($.fn, "tooltip") this.view.render() - expect($.fn.tooltip.mostRecentCall.object.selector).toBe(".christopher_columbus, .barrack_obama, .block_user") + expect($.fn.tooltip.calls.mostRecent().object.selector).toBe(".christopher_columbus, .barrack_obama, .block_user") }) }) }) diff --git a/spec/javascripts/contact-list-spec.js b/spec/javascripts/contact-list-spec.js index cd15181a4..6bafe6653 100644 --- a/spec/javascripts/contact-list-spec.js +++ b/spec/javascripts/contact-list-spec.js @@ -10,7 +10,7 @@ describe("Contact List", function() { spyOn($,'ajax'); List.disconnectUser(id); expect($.ajax).toHaveBeenCalled(); - var option_hash = $.ajax.mostRecentCall.args[0]; + var option_hash = $.ajax.calls.mostRecent().args[0]; expect(option_hash.url).toEqual("/contacts/" + id); expect(option_hash.type).toEqual("DELETE"); expect(option_hash.success).toBeDefined(); diff --git a/spec/javascripts/widgets/back-to-top-spec.js b/spec/javascripts/widgets/back-to-top-spec.js index ea2e5337f..35543969a 100644 --- a/spec/javascripts/widgets/back-to-top-spec.js +++ b/spec/javascripts/widgets/back-to-top-spec.js @@ -33,13 +33,13 @@ describe("Diaspora.Widgets.BackToTop", function() { describe("toggleVisibility", function() { it("adds a visibility class to the button", function() { - var spy = spyOn(backToTop.body, "scrollTop").andReturn(999); + var spy = spyOn(backToTop.body, "scrollTop").and.returnValue(999); backToTop.toggleVisibility(); expect(backToTop.button.hasClass("visible")).toBe(false); - spy.andReturn(1001); + spy.and.returnValue(1001); backToTop.toggleVisibility(); @@ -50,4 +50,4 @@ describe("Diaspora.Widgets.BackToTop", function() { afterEach(function() { $.fx.off = false; }); -}); \ No newline at end of file +}); diff --git a/spec/javascripts/widgets/flash-messages-spec.js b/spec/javascripts/widgets/flash-messages-spec.js index 12bb2c0c2..f2e02bd9c 100644 --- a/spec/javascripts/widgets/flash-messages-spec.js +++ b/spec/javascripts/widgets/flash-messages-spec.js @@ -14,7 +14,7 @@ describe("Diaspora", function() { }); it("is called when the DOM is ready", function() { - spyOn(flashMessages, "animateMessages").andCallThrough(); + spyOn(flashMessages, "animateMessages").and.callThrough(); flashMessages.publish("widget/ready"); expect(flashMessages.animateMessages).toHaveBeenCalled(); }); diff --git a/spec/javascripts/widgets/notifications-spec.js b/spec/javascripts/widgets/notifications-spec.js index 84ded9b46..f67955f82 100644 --- a/spec/javascripts/widgets/notifications-spec.js +++ b/spec/javascripts/widgets/notifications-spec.js @@ -11,9 +11,9 @@ describe("Diaspora.Widgets.Notifications", function() { notifications = Diaspora.BaseWidget.instantiate("Notifications", this.view.$("#notification_badge .badge_count"), this.view.$(".notifications")); - changeNotificationCountSpy = spyOn(notifications, "changeNotificationCount").andCallThrough(); - incrementCountSpy = spyOn(notifications, "incrementCount").andCallThrough(); - decrementCountSpy = spyOn(notifications, "decrementCount").andCallThrough(); + changeNotificationCountSpy = spyOn(notifications, "changeNotificationCount").and.callThrough(); + incrementCountSpy = spyOn(notifications, "incrementCount").and.callThrough(); + decrementCountSpy = spyOn(notifications, "decrementCount").and.callThrough(); }); describe("clickSuccess", function(){ diff --git a/spec/javascripts/widgets/search-spec.js b/spec/javascripts/widgets/search-spec.js index 0e06516c2..e1f831af6 100644 --- a/spec/javascripts/widgets/search-spec.js +++ b/spec/javascripts/widgets/search-spec.js @@ -6,7 +6,7 @@ describe("Diaspora.Widgets.Search", function() { var search = Diaspora.BaseWidget.instantiate("Search", $("#jasmine_content > #searchForm")); var person = {"name": "", '"}]});alert(1);(function f() {var foo = [{b:"'].each do |xss| get :new, name: xss - response.body.should_not include xss + expect(response.body).not_to include xss end end end @@ -56,20 +56,20 @@ describe ConversationsController do it 'succeeds' do get :index - response.should be_success - assigns[:conversations].should =~ @conversations + expect(response).to be_success + expect(assigns[:conversations]).to match_array(@conversations) end it 'succeeds with json' do get :index, :format => :json - response.should be_success + expect(response).to be_success json = JSON.parse(response.body) - json.first['conversation'].should be_present + expect(json.first['conversation']).to be_present end it 'retrieves all conversations for a user' do get :index - assigns[:conversations].count.should == 3 + expect(assigns[:conversations].count).to eq(3) end end @@ -87,29 +87,29 @@ describe ConversationsController do end it 'creates a conversation' do - lambda { + expect { post :create, @hash - }.should change(Conversation, :count).by(1) + }.to change(Conversation, :count).by(1) end it 'creates a message' do - lambda { + expect { post :create, @hash - }.should change(Message, :count).by(1) + }.to change(Message, :count).by(1) end it 'should set response with success to true and message to success message' do post :create, @hash - assigns[:response][:success].should == true - assigns[:response][:message].should == I18n.t('conversations.create.sent') - assigns[:response][:conversation_id].should == Conversation.first.id + expect(assigns[:response][:success]).to eq(true) + expect(assigns[:response][:message]).to eq(I18n.t('conversations.create.sent')) + expect(assigns[:response][:conversation_id]).to eq(Conversation.first.id) end it 'sets the author to the current_user' do @hash[:author] = FactoryGirl.create(:user) post :create, @hash - Message.first.author.should == alice.person - Conversation.first.author.should == alice.person + expect(Message.first.author).to eq(alice.person) + expect(Conversation.first.author).to eq(alice.person) end it 'dispatches the conversation' do @@ -123,8 +123,8 @@ describe ConversationsController do ) p = Postzord::Dispatcher.build(alice, cnv) - p.class.stub(:new).and_return(p) - p.should_receive(:post) + allow(p.class).to receive(:new).and_return(p) + expect(p).to receive(:post) post :create, @hash end end @@ -142,22 +142,22 @@ describe ConversationsController do end it 'creates a conversation' do - lambda { + expect { post :create, @hash - }.should change(Conversation, :count).by(1) + }.to change(Conversation, :count).by(1) end it 'creates a message' do - lambda { + expect { post :create, @hash - }.should change(Message, :count).by(1) + }.to change(Message, :count).by(1) end it 'should set response with success to true and message to success message' do post :create, @hash - assigns[:response][:success].should == true - assigns[:response][:message].should == I18n.t('conversations.create.sent') - assigns[:response][:conversation_id].should == Conversation.first.id + expect(assigns[:response][:success]).to eq(true) + expect(assigns[:response][:message]).to eq(I18n.t('conversations.create.sent')) + expect(assigns[:response][:conversation_id]).to eq(Conversation.first.id) end end @@ -176,19 +176,19 @@ describe ConversationsController do it 'does not create a conversation' do count = Conversation.count post :create, @hash - Conversation.count.should == count + expect(Conversation.count).to eq(count) end it 'does not create a message' do count = Message.count post :create, @hash - Message.count.should == count + expect(Message.count).to eq(count) end it 'should set response with success to false and message to create fail' do post :create, @hash - assigns[:response][:success].should == false - assigns[:response][:message].should == I18n.t('conversations.create.fail') + expect(assigns[:response][:success]).to eq(false) + expect(assigns[:response][:message]).to eq(I18n.t('conversations.create.fail')) end end @@ -207,19 +207,19 @@ describe ConversationsController do it 'does not create a conversation' do count = Conversation.count post :create, @hash - Conversation.count.should == count + expect(Conversation.count).to eq(count) end it 'does not create a message' do count = Message.count post :create, @hash - Message.count.should == count + expect(Message.count).to eq(count) end it 'should set response with success to false and message to fail due to no contact' do post :create, @hash - assigns[:response][:success].should == false - assigns[:response][:message].should == I18n.t('conversations.create.no_contact') + expect(assigns[:response][:success]).to eq(false) + expect(assigns[:response][:message]).to eq(I18n.t('conversations.create.no_contact')) end end @@ -238,13 +238,13 @@ describe ConversationsController do it 'does not create a conversation' do count = Conversation.count post :create, @hash - Conversation.count.should == count + expect(Conversation.count).to eq(count) end it 'does not create a message' do count = Message.count post :create, @hash - Message.count.should == count + expect(Message.count).to eq(count) end end end @@ -262,28 +262,28 @@ describe ConversationsController do it 'succeeds with js' do xhr :get, :show, :id => @conversation.id, :format => :js - response.should be_success - assigns[:conversation].should == @conversation + expect(response).to be_success + expect(assigns[:conversation]).to eq(@conversation) end it 'succeeds with json' do get :show, :id => @conversation.id, :format => :json - response.should be_success - assigns[:conversation].should == @conversation - response.body.should include @conversation.guid + expect(response).to be_success + expect(assigns[:conversation]).to eq(@conversation) + expect(response.body).to include @conversation.guid end it 'redirects to index' do get :show, :id => @conversation.id - response.should redirect_to(conversations_path(:conversation_id => @conversation.id)) - assigns[:conversation].should == @conversation + expect(response).to redirect_to(conversations_path(:conversation_id => @conversation.id)) + expect(assigns[:conversation]).to eq(@conversation) end it 'does not let you access conversations where you are not a recipient' do sign_in :user, eve get :show, :id => @conversation.id - response.code.should redirect_to conversations_path + expect(response.code).to redirect_to conversations_path end end end diff --git a/spec/controllers/home_controller_spec.rb b/spec/controllers/home_controller_spec.rb index cd9a6958c..f34d3671e 100644 --- a/spec/controllers/home_controller_spec.rb +++ b/spec/controllers/home_controller_spec.rb @@ -4,12 +4,12 @@ require 'spec_helper' -describe HomeController do +describe HomeController, :type => :controller do describe '#show' do it 'does not redirect' do sign_out :user get :show - response.should_not be_redirect + expect(response).not_to be_redirect end context 'redirection' do @@ -19,7 +19,7 @@ describe HomeController do it 'points to the stream if a user has contacts' do get :show, :home => true - response.should redirect_to(stream_path) + expect(response).to redirect_to(stream_path) end end end @@ -28,13 +28,13 @@ describe HomeController do it 'changes :mobile to :html' do session[:mobile_view] = true get :toggle_mobile - session[:mobile_view].should be false + expect(session[:mobile_view]).to be false end it 'changes :html to :mobile' do session[:mobile_view] = nil get :toggle_mobile - session[:mobile_view].should be true + expect(session[:mobile_view]).to be true end end end diff --git a/spec/controllers/invitations_controller_spec.rb b/spec/controllers/invitations_controller_spec.rb index 852181ada..ee1d05009 100644 --- a/spec/controllers/invitations_controller_spec.rb +++ b/spec/controllers/invitations_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe InvitationsController do +describe InvitationsController, :type => :controller do before do AppConfig.settings.invitations.open = true @@ -15,7 +15,7 @@ describe InvitationsController do describe "#create" do before do sign_in :user, @user - @controller.stub(:current_user).and_return(@user) + allow(@controller).to receive(:current_user).and_return(@user) @referer = 'http://test.host/cats/foo' request.env["HTTP_REFERER"] = @referer end @@ -26,18 +26,18 @@ describe InvitationsController do end it 'does not create an EmailInviter' do - Workers::Mail::InviteEmail.should_not_receive(:perform_async) + expect(Workers::Mail::InviteEmail).not_to receive(:perform_async) post :create, @invite end it 'returns to the previous page' do post :create, @invite - response.should redirect_to @referer + expect(response).to redirect_to @referer end it 'flashes an error' do post :create, @invite - flash[:error].should == I18n.t("invitations.create.empty") + expect(flash[:error]).to eq(I18n.t("invitations.create.empty")) end end @@ -49,19 +49,19 @@ describe InvitationsController do it 'creates an InviteEmail worker' do inviter = double(:emails => [@emails], :send! => true) - Workers::Mail::InviteEmail.should_receive(:perform_async).with(@invite['email_inviter']['emails'], @user.id, @invite['email_inviter']) + expect(Workers::Mail::InviteEmail).to receive(:perform_async).with(@invite['email_inviter']['emails'], @user.id, @invite['email_inviter']) post :create, @invite end it 'returns to the previous page on success' do post :create, @invite - response.should redirect_to @referer + expect(response).to redirect_to @referer end it 'flashes a notice' do post :create, @invite expected = I18n.t('invitations.create.sent', :emails => @emails.split(',').join(', ')) - flash[:notice].should == expected + expect(flash[:notice]).to eq(expected) end end @@ -72,20 +72,20 @@ describe InvitationsController do end it 'does not create an InviteEmail worker' do - Workers::Mail::InviteEmail.should_not_receive(:perform_async) + expect(Workers::Mail::InviteEmail).not_to receive(:perform_async) post :create, @invite end it 'returns to the previous page' do post :create, @invite - response.should redirect_to @referer + expect(response).to redirect_to @referer end it 'flashes an error' do post :create, @invite expected = I18n.t('invitations.create.rejected') + @emails.split(',').join(', ') - flash[:error].should == expected + expect(flash[:error]).to eq(expected) end end @@ -99,13 +99,13 @@ describe InvitationsController do it 'creates an InviteEmail worker' do inviter = double(:emails => [@emails], :send! => true) - Workers::Mail::InviteEmail.should_receive(:perform_async).with(@valid_emails, @user.id, @invite['email_inviter']) + expect(Workers::Mail::InviteEmail).to receive(:perform_async).with(@valid_emails, @user.id, @invite['email_inviter']) post :create, @invite end it 'returns to the previous page' do post :create, @invite - response.should redirect_to @referer + expect(response).to redirect_to @referer end it 'flashes a notice' do @@ -114,7 +114,7 @@ describe InvitationsController do @valid_emails.split(',').join(', ')) + '. ' + I18n.t('invitations.create.rejected') + @invalid_emails.split(',').join(', ') - flash[:error].should == expected + expect(flash[:error]).to eq(expected) end end @@ -123,7 +123,7 @@ describe InvitationsController do AppConfig.settings.invitations.open = false post :create, @invite - response.should be_redirect + expect(response).to be_redirect AppConfig.settings.invitations.open = open_bit end end @@ -132,7 +132,7 @@ describe InvitationsController do it 'succeeds' do get :email, :invitation_code => "anycode" - response.should be_success + expect(response).to be_success end context 'legacy invite tokens' do @@ -146,14 +146,14 @@ describe InvitationsController do it 'redirects and flashes if the invitation token is invalid' do get_email - response.should be_redirect - response.should redirect_to root_url + expect(response).to be_redirect + expect(response).to redirect_to root_url end it 'flashes an error if the invitation token is invalid' do get_email - flash[:error].should == I18n.t("invitations.check_token.not_found") + expect(flash[:error]).to eq(I18n.t("invitations.check_token.not_found")) end end end @@ -169,50 +169,50 @@ describe InvitationsController do describe 'redirect logged out users to the sign in page' do it 'redriects #new' do get :new - response.should be_redirect - response.should redirect_to new_user_session_path + expect(response).to be_redirect + expect(response).to redirect_to new_user_session_path end it 'redirects #create' do post :create - response.should be_redirect - response.should redirect_to new_user_session_path + expect(response).to be_redirect + expect(response).to redirect_to new_user_session_path end end describe '.valid_email?' do it 'returns false for empty email' do - subject.send(:valid_email?, '').should be false + expect(subject.send(:valid_email?, '')).to be false end it 'returns false for email without @-sign' do - subject.send(:valid_email?, 'foo').should be false + expect(subject.send(:valid_email?, 'foo')).to be false end it 'returns true for valid email' do - subject.send(:valid_email?, 'foo@bar.com').should be true + expect(subject.send(:valid_email?, 'foo@bar.com')).to be true end end describe '.html_safe_string_from_session_array' do it 'returns "" for blank session[key]' do - subject.send(:html_safe_string_from_session_array, :blank).should eq "" + expect(subject.send(:html_safe_string_from_session_array, :blank)).to eq "" end it 'returns "" if session[key] is not an array' do session[:test_key] = "test" - subject.send(:html_safe_string_from_session_array, :test_key).should eq "" + expect(subject.send(:html_safe_string_from_session_array, :test_key)).to eq "" end it 'returns the correct value' do session[:test_key] = ["test", "foo"] - subject.send(:html_safe_string_from_session_array, :test_key).should eq "test, foo" + expect(subject.send(:html_safe_string_from_session_array, :test_key)).to eq "test, foo" end it 'sets session[key] to nil' do session[:test_key] = ["test"] subject.send(:html_safe_string_from_session_array, :test_key) - session[:test_key].should be nil + expect(session[:test_key]).to be nil end end end diff --git a/spec/controllers/jasmine_fixtures/aspects_spec.rb b/spec/controllers/jasmine_fixtures/aspects_spec.rb index 7cb66843b..4d2d68108 100644 --- a/spec/controllers/jasmine_fixtures/aspects_spec.rb +++ b/spec/controllers/jasmine_fixtures/aspects_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe StreamsController do +describe StreamsController, :type => :controller do describe '#aspects' do before do sign_in :user, alice @@ -15,7 +15,7 @@ describe StreamsController do context 'jasmine fixtures' do before do - Stream::Aspect.any_instance.stub(:ajax_stream?).and_return(false) + allow_any_instance_of(Stream::Aspect).to receive(:ajax_stream?).and_return(false) end it "generates a jasmine fixture", :fixture => true do diff --git a/spec/controllers/jasmine_fixtures/contacts_spec.rb b/spec/controllers/jasmine_fixtures/contacts_spec.rb index d2a5321de..127092daf 100644 --- a/spec/controllers/jasmine_fixtures/contacts_spec.rb +++ b/spec/controllers/jasmine_fixtures/contacts_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ContactsController do +describe ContactsController, :type => :controller do describe '#index' do before do sign_in :user, bob diff --git a/spec/controllers/jasmine_fixtures/notifications_spec.rb b/spec/controllers/jasmine_fixtures/notifications_spec.rb index 8851eb02d..771d99ec5 100644 --- a/spec/controllers/jasmine_fixtures/notifications_spec.rb +++ b/spec/controllers/jasmine_fixtures/notifications_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe NotificationsController do +describe NotificationsController, :type => :controller do describe '#index' do before do sign_in :user, alice diff --git a/spec/controllers/jasmine_fixtures/people_spec.rb b/spec/controllers/jasmine_fixtures/people_spec.rb index 5e8d3ed04..814dc66c3 100644 --- a/spec/controllers/jasmine_fixtures/people_spec.rb +++ b/spec/controllers/jasmine_fixtures/people_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PeopleController do +describe PeopleController, :type => :controller do describe '#index' do before do sign_in :user, bob diff --git a/spec/controllers/jasmine_fixtures/status_messages_spec.rb b/spec/controllers/jasmine_fixtures/status_messages_spec.rb index 90a2f9df6..56d36d800 100644 --- a/spec/controllers/jasmine_fixtures/status_messages_spec.rb +++ b/spec/controllers/jasmine_fixtures/status_messages_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe StatusMessagesController do +describe StatusMessagesController, :type => :controller do describe '#bookmarklet' do before do sign_in :user, bob diff --git a/spec/controllers/jasmine_fixtures/streams_spec.rb b/spec/controllers/jasmine_fixtures/streams_spec.rb index 2a3a8a1b8..94e0cbb03 100644 --- a/spec/controllers/jasmine_fixtures/streams_spec.rb +++ b/spec/controllers/jasmine_fixtures/streams_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe StreamsController do +describe StreamsController, :type => :controller do describe '#multi' do before do sign_in :user, alice @@ -53,7 +53,7 @@ TXT Timecop.travel(time) do get :multi, :format => :json - response.should be_success + expect(response).to be_success save_fixture(response.body, "stream_json") end end diff --git a/spec/controllers/likes_controller_spec.rb b/spec/controllers/likes_controller_spec.rb index dfaddc413..7cc8d3d39 100644 --- a/spec/controllers/likes_controller_spec.rb +++ b/spec/controllers/likes_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe LikesController do +describe LikesController, :type => :controller do before do @alices_aspect = alice.aspects.where(:name => "generic").first @bobs_aspect = bob.aspects.where(:name => "generic").first @@ -33,7 +33,7 @@ describe LikesController do @target = alice.post :status_message, :text => "AWESOME", :to => @alices_aspect.id @target = alice.comment!(@target, "hey") if class_const == Comment post :create, like_hash.merge(:format => :json) - response.code.should == '201' + expect(response.code).to eq('201') end end @@ -45,18 +45,18 @@ describe LikesController do it 'likes' do post :create, like_hash - response.code.should == '201' + expect(response.code).to eq('201') end it 'dislikes' do post :create, dislike_hash - response.code.should == '201' + expect(response.code).to eq('201') end it "doesn't post multiple times" do alice.like!(@target) post :create, dislike_hash - response.code.should == '422' + expect(response.code).to eq('422') end end @@ -67,9 +67,9 @@ describe LikesController do end it "doesn't post" do - alice.should_not_receive(:like!) + expect(alice).not_to receive(:like!) post :create, like_hash - response.code.should == '422' + expect(response.code).to eq('422') end end end @@ -94,12 +94,12 @@ describe LikesController do it 'returns an array of likes for a post' do like = bob.like!(@message) get :index, id_field => @message.id - assigns[:likes].map(&:id).should == @message.likes.map(&:id) + expect(assigns[:likes].map(&:id)).to eq(@message.likes.map(&:id)) end it 'returns an empty array for a post with no likes' do get :index, id_field => @message.id - assigns[:likes].should == [] + expect(assigns[:likes]).to eq([]) end end @@ -112,10 +112,10 @@ describe LikesController do it 'lets a user destroy their like' do current_user = controller.send(:current_user) - current_user.should_receive(:retract).with(@like) + expect(current_user).to receive(:retract).with(@like) delete :destroy, :format => :json, id_field => @like.target_id, :id => @like.id - response.status.should == 204 + expect(response.status).to eq(204) end it 'does not let a user destroy other likes' do @@ -126,7 +126,7 @@ describe LikesController do delete :destroy, :format => :json, id_field => like2.target_id, :id => like2.id }.to raise_error(ActiveRecord::RecordNotFound) - Like.count.should == like_count + expect(Like.count).to eq(like_count) end end diff --git a/spec/controllers/messages_controller_spec.rb b/spec/controllers/messages_controller_spec.rb index 4e3116cf2..c4364ef9e 100644 --- a/spec/controllers/messages_controller_spec.rb +++ b/spec/controllers/messages_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe MessagesController do +describe MessagesController, :type => :controller do before do sign_in :user, alice end @@ -33,11 +33,11 @@ describe MessagesController do end it 'redirects to conversation' do - lambda { + expect { post :create, @message_params - }.should change(Message, :count).by(1) - response.status.should == 302 - response.should redirect_to(conversations_path(:conversation_id => @conversation)) + }.to change(Message, :count).by(1) + expect(response.status).to eq(302) + expect(response).to redirect_to(conversations_path(:conversation_id => @conversation)) end end @@ -50,10 +50,10 @@ describe MessagesController do end it 'does not create the message' do - lambda { + expect { post :create, @message_params - }.should_not change(Message, :count) - flash[:error].should be_present + }.not_to change(Message, :count) + expect(flash[:error]).to be_present end end end @@ -70,8 +70,8 @@ describe MessagesController do it 'comments' do post :create, @message_params - response.status.should == 302 - response.should redirect_to(conversations_path(:conversation_id => @conversation)) + expect(response.status).to eq(302) + expect(response).to redirect_to(conversations_path(:conversation_id => @conversation)) end it "doesn't overwrite author_id" do @@ -80,7 +80,7 @@ describe MessagesController do post :create, @message_params created_message = Message.find_by_text(@message_params[:message][:text]) - created_message.author.should == alice.person + expect(created_message.author).to eq(alice.person) end it "doesn't overwrite id" do @@ -92,7 +92,7 @@ describe MessagesController do @message_params[:id] = old_message.id post :create, @message_params - old_message.reload.text.should == 'hello' + expect(old_message.reload.text).to eq('hello') end end @@ -109,10 +109,10 @@ describe MessagesController do end it 'does not create the message' do - lambda { + expect { post :create, @message_params - }.should_not change(Message, :count) - flash[:error].should be_present + }.not_to change(Message, :count) + expect(flash[:error]).to be_present end end end diff --git a/spec/controllers/notifications_controller_spec.rb b/spec/controllers/notifications_controller_spec.rb index 502d63363..b27b36da4 100644 --- a/spec/controllers/notifications_controller_spec.rb +++ b/spec/controllers/notifications_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe NotificationsController do +describe NotificationsController, :type => :controller do before do sign_in :user, alice end @@ -12,22 +12,22 @@ describe NotificationsController do describe '#update' do it 'marks a notification as read if it gets no other information' do note = FactoryGirl.create(:notification) - Notification.should_receive( :where ).and_return( [note] ) - note.should_receive( :set_read_state ).with( true ) + expect(Notification).to receive( :where ).and_return( [note] ) + expect(note).to receive( :set_read_state ).with( true ) get :update, "id" => note.id, :format => :json end it 'marks a notification as read if it is told to' do note = FactoryGirl.create(:notification) - Notification.should_receive( :where ).and_return( [note] ) - note.should_receive( :set_read_state ).with( true ) + expect(Notification).to receive( :where ).and_return( [note] ) + expect(note).to receive( :set_read_state ).with( true ) get :update, "id" => note.id, :set_unread => "false", :format => :json end it 'marks a notification as unread if it is told to' do note = FactoryGirl.create(:notification) - Notification.should_receive( :where ).and_return( [note] ) - note.should_receive( :set_read_state ).with( false ) + expect(Notification).to receive( :where ).and_return( [note] ) + expect(note).to receive( :set_read_state ).with( false ) get :update, "id" => note.id, :set_unread => "true", :format => :json end @@ -39,7 +39,7 @@ describe NotificationsController do get :update, "id" => note.id, :set_unread => "false", :format => :json - Notification.find(note.id).unread.should == true + expect(Notification.find(note.id).unread).to eq(true) end end @@ -51,33 +51,33 @@ describe NotificationsController do it 'succeeds' do get :index - response.should be_success - assigns[:notifications].count.should == 1 + expect(response).to be_success + expect(assigns[:notifications].count).to eq(1) end it 'succeeds for notification dropdown' do get :index, :format => :json - response.should be_success - response.body.should =~ /note_html/ + expect(response).to be_success + expect(response.body).to match(/note_html/) end it 'succeeds on mobile' do get :index, :format => :mobile - response.should be_success + expect(response).to be_success end it 'paginates the notifications' do 25.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } get :index - assigns[:notifications].count.should == 25 + expect(assigns[:notifications].count).to eq(25) get :index, "page" => 2 - assigns[:notifications].count.should == 1 + expect(assigns[:notifications].count).to eq(1) end it "supports a limit per_page parameter" do 5.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } get :index, "per_page" => 5 - assigns[:notifications].count.should == 5 + expect(assigns[:notifications].count).to eq(5) end describe "special case for start sharing notifications" do @@ -85,14 +85,14 @@ describe NotificationsController do 2.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } get :index, "per_page" => 5 - Nokogiri(response.body).css('.aspect_membership').should be_empty + expect(Nokogiri(response.body).css('.aspect_membership')).to be_empty end it "should provide a contacts menu for start sharing notifications" do 2.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } eve.share_with(alice.person, eve.aspects.first) get :index, "per_page" => 5 - Nokogiri(response.body).css('.aspect_membership').should_not be_empty + expect(Nokogiri(response.body).css('.aspect_membership')).not_to be_empty end end @@ -100,14 +100,14 @@ describe NotificationsController do it "supports filtering by notification type" do eve.share_with(alice.person, eve.aspects.first) get :index, "type" => "started_sharing" - assigns[:notifications].count.should == 1 + expect(assigns[:notifications].count).to eq(1) end it "supports filtering by read/unread" do get :read_all 2.times { FactoryGirl.create(:notification, :recipient => alice, :target => @post) } get :index, "show" => "unread" - assigns[:notifications].count.should == 2 + expect(assigns[:notifications].count).to eq(2) end end end @@ -118,44 +118,44 @@ describe NotificationsController do FactoryGirl.create(:notification, :recipient => alice) FactoryGirl.create(:notification, :recipient => alice) - Notification.where(:unread => true).count.should == 2 + expect(Notification.where(:unread => true).count).to eq(2) get :read_all - Notification.where(:unread => true).count.should == 0 + expect(Notification.where(:unread => true).count).to eq(0) end it 'marks all notifications in the current filter as read' do request.env["HTTP_REFERER"] = "I wish I were spelled right" FactoryGirl.create(:notification, :recipient => alice) eve.share_with(alice.person, eve.aspects.first) - Notification.where(:unread => true).count.should == 2 + expect(Notification.where(:unread => true).count).to eq(2) get :read_all, "type" => "started_sharing" - Notification.where(:unread => true).count.should == 1 + expect(Notification.where(:unread => true).count).to eq(1) end it "should redirect back in the html version if it has > 0 notifications" do FactoryGirl.create(:notification, :recipient => alice) eve.share_with(alice.person, eve.aspects.first) get :read_all, :format => :html, "type" => "started_sharing" - response.should redirect_to(notifications_path) + expect(response).to redirect_to(notifications_path) end it "should redirect back in the mobile version if it has > 0 notifications" do FactoryGirl.create(:notification, :recipient => alice) eve.share_with(alice.person, eve.aspects.first) get :read_all, :format => :mobile, "type" => "started_sharing" - response.should redirect_to(notifications_path) + expect(response).to redirect_to(notifications_path) end it "should redirect to stream in the html version if it has 0 notifications" do FactoryGirl.create(:notification, :recipient => alice) get :read_all, :format => :html - response.should redirect_to(stream_path) + expect(response).to redirect_to(stream_path) end it "should redirect back in the mobile version if it has 0 notifications" do FactoryGirl.create(:notification, :recipient => alice) get :read_all, :format => :mobile - response.should redirect_to(stream_path) + expect(response).to redirect_to(stream_path) end it "should return a dummy value in the json version" do FactoryGirl.create(:notification, :recipient => alice) get :read_all, :format => :json - response.should_not be_redirect + expect(response).not_to be_redirect end end end diff --git a/spec/controllers/passwords_controller_spec.rb b/spec/controllers/passwords_controller_spec.rb index b5d2880e8..3d00b17b8 100644 --- a/spec/controllers/passwords_controller_spec.rb +++ b/spec/controllers/passwords_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PasswordsController do +describe PasswordsController, :type => :controller do include Devise::TestHelpers before do @@ -15,21 +15,21 @@ describe PasswordsController do context "when there is no such user" do it "succeeds" do post :create, "user" => {"email" => "foo@example.com"} - response.should be_success + expect(response).to be_success end it "doesn't send email" do - Workers::ResetPassword.should_not_receive(:perform_async) + expect(Workers::ResetPassword).not_to receive(:perform_async) post :create, "user" => {"email" => "foo@example.com"} end end context "when there is a user with that email" do it "redirects to the login page" do post :create, "user" => {"email" => alice.email} - response.should redirect_to(new_user_session_path) + expect(response).to redirect_to(new_user_session_path) end it "sends email (enqueued to Sidekiq)" do - Workers::ResetPassword.should_receive(:perform_async).with(alice.id) + expect(Workers::ResetPassword).to receive(:perform_async).with(alice.id) post :create, "user" => {"email" => alice.email} end end diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index d1faab622..a89755a48 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PeopleController do +describe PeopleController, :type => :controller do before do @user = alice @aspect = @user.aspects.first @@ -22,17 +22,17 @@ describe PeopleController do describe 'via json' do it 'succeeds' do get :index, :q => "Korth", :format => 'json' - response.should be_success + expect(response).to be_success end it 'responds with json' do get :index, :q => "Korth", :format => 'json' - response.body.should == [@korth].to_json + expect(response.body).to eq([@korth].to_json) end it 'does not assign hashes' do get :index, :q => "Korth", :format => 'json' - assigns[:hashes].should be_nil + expect(assigns[:hashes]).to be_nil end end @@ -45,34 +45,34 @@ describe PeopleController do end it 'finds people even if they have searchable off' do get :index, :q => "eugene@example.org" - assigns[:people][0].id.should == @unsearchable_eugene.id + expect(assigns[:people][0].id).to eq(@unsearchable_eugene.id) end it 'downcases the query term' do get :index, :q => "Eugene@Example.ORG" - assigns[:people][0].id.should == @unsearchable_eugene.id + expect(assigns[:people][0].id).to eq(@unsearchable_eugene.id) end it 'does not the background query task if the user is found' do get :index, :q => "Eugene@Example.ORG" - assigns[:background_query].should == nil + expect(assigns[:background_query]).to eq(nil) end it 'sets background query task if the user is not found' do get :index, :q => "Eugene@Example1.ORG" - assigns[:background_query].should == "eugene@example1.org" + expect(assigns[:background_query]).to eq("eugene@example1.org") end end context 'query is not a tag or a diaspora ID' do it 'assigns hashes' do get :index, :q => "Korth" - assigns[:hashes].should_not be_nil + expect(assigns[:hashes]).not_to be_nil end it 'does not set the background query task' do get :index, :q => "Korth" - assigns[:background_query].should_not be_present + expect(assigns[:background_query]).not_to be_present end it "assigns people" do @@ -80,29 +80,29 @@ describe PeopleController do :profile => FactoryGirl.build(:profile, :first_name => "Eugene", :last_name => "w")) get :index, :q => "Eug" - assigns[:people].map { |x| x.id }.should =~ [@eugene.id, eugene2.id] + expect(assigns[:people].map { |x| x.id }).to match_array([@eugene.id, eugene2.id]) end it "succeeds if there is exactly one match" do get :index, :q => "Korth" - assigns[:people].length.should == 1 - response.should be_success + expect(assigns[:people].length).to eq(1) + expect(response).to be_success end it "succeeds if there are no matches" do get :index, :q => "Korthsauce" - assigns[:people].length.should == 0 - response.should be_success + expect(assigns[:people].length).to eq(0) + expect(response).to be_success end it 'succeeds if you search for the empty term' do get :index, :q => '' - response.should be_success + expect(response).to be_success end it 'succeeds if you search for punctuation' do get :index, :q => '+' - response.should be_success + expect(response).to be_success end it "excludes people who have searchable off" do @@ -110,7 +110,7 @@ describe PeopleController do :profile => FactoryGirl.build(:profile, :first_name => "Eugene", :last_name => "w", :searchable => false)) get :index, :q => "Eug" - assigns[:people].should_not =~ [eugene2] + expect(assigns[:people]).not_to match_array([eugene2]) end end end @@ -119,7 +119,7 @@ describe PeopleController do describe '#tag_index' do it 'works for js' do xhr :get, :tag_index, :name => 'jellybeans', :format => :js - response.should be_success + expect(response).to be_success end it 'returns awesome people who have that tag' do @@ -127,7 +127,7 @@ describe PeopleController do f.profile.tag_string = "#seeded" f.profile.save xhr :get, :tag_index, :name => 'seeded', :format => :js - assigns[:people].count.should == 1 + expect(assigns[:people].count).to eq(1) end end @@ -152,33 +152,33 @@ describe PeopleController do end it 'takes time' do - Benchmark.realtime { + expect(Benchmark.realtime { get :show, :id => @user.person.to_param - }.should < 1.0 + }).to be < 1.0 end end describe '#show' do it "404s if the id is invalid" do get :show, :id => 'delicious' - response.code.should == "404" + expect(response.code).to eq("404") end it "404s if no person is found via id" do get :show, :id => "3d920397846" - response.code.should == "404" + expect(response.code).to eq("404") end it "404s if no person is found via username" do get :show, :username => 'delicious' - response.code.should == "404" + expect(response.code).to eq("404") end it 'redirects home for closed account' do @person = FactoryGirl.create(:person, :closed_account => true) get :show, :id => @person.to_param - response.should be_redirect - flash[:notice].should_not be_blank + expect(response).to be_redirect + expect(flash[:notice]).not_to be_blank end it 'does not allow xss attacks' do @@ -186,8 +186,8 @@ describe PeopleController do profile = user2.profile profile.update_attribute(:first_name, "") get :show, :id => user2.person.to_param - response.should be_success - response.body.should_not include(profile.first_name) + expect(response).to be_success + expect(response.body).not_to include(profile.first_name) end it "doesn't leak photos in the sidebar" do @@ -197,41 +197,41 @@ describe PeopleController do sign_out :user get :show, id: @user.person.to_param - assigns(:photos).should_not include private_photo - assigns(:photos).should include public_photo + expect(assigns(:photos)).not_to include private_photo + expect(assigns(:photos)).to include public_photo end context "when the person is the current user" do it "succeeds" do get :show, :id => @user.person.to_param - response.should be_success + expect(response).to be_success end it 'succeeds on the mobile site' do get :show, :id => @user.person.to_param, :format => :mobile - response.should be_success + expect(response).to be_success end it "assigns the right person" do get :show, :id => @user.person.to_param - assigns(:person).should == @user.person + expect(assigns(:person)).to eq(@user.person) end it "assigns all the user's posts" do - @user.posts.should be_empty + expect(@user.posts).to be_empty @user.post(:status_message, :text => "to one aspect", :to => @aspect.id) @user.post(:status_message, :text => "to all aspects", :to => 'all') @user.post(:status_message, :text => "public", :to => 'all', :public => true) - @user.reload.posts.length.should == 3 + expect(@user.reload.posts.length).to eq(3) get :show, :id => @user.person.to_param - assigns(:stream).posts.map(&:id).should =~ @user.posts.map(&:id) + expect(assigns(:stream).posts.map(&:id)).to match_array(@user.posts.map(&:id)) end it "renders the comments on the user's posts" do message = @user.post :status_message, :text => 'test more', :to => @aspect.id @user.comment!(message, 'I mean it') get :show, :id => @user.person.to_param - response.should be_success + expect(response).to be_success end end @@ -243,12 +243,12 @@ describe PeopleController do it "succeeds" do get :show, :id => @person.to_param - response.status.should == 200 + expect(response.status).to eq(200) end it 'succeeds on the mobile site' do get :show, :id => @person.to_param, :format => :mobile - response.should be_success + expect(response).to be_success end context 'with posts' do @@ -265,17 +265,17 @@ describe PeopleController do it "posts include reshares" do reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) get :show, :id => @user.person.to_param - assigns[:stream].posts.map { |x| x.id }.should include(reshare.id) + expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) end it "assigns only public posts" do get :show, :id => @person.to_param - assigns[:stream].posts.map(&:id).should =~ @public_posts.map(&:id) + expect(assigns[:stream].posts.map(&:id)).to match_array(@public_posts.map(&:id)) end it 'is sorted by created_at desc' do get :show, :id => @person.to_param - assigns[:stream].stream_posts.should == @public_posts.sort_by { |p| p.created_at }.reverse + expect(assigns[:stream].stream_posts).to eq(@public_posts.sort_by { |p| p.created_at }.reverse) end end @@ -283,8 +283,8 @@ describe PeopleController do p = FactoryGirl.create(:person) get :show, :id => p.to_param - response.should be_redirect - response.should redirect_to new_user_session_path + expect(response).to be_redirect + expect(response).to redirect_to new_user_session_path end end @@ -295,16 +295,16 @@ describe PeopleController do it "succeeds" do get :show, :id => @person.to_param - response.should be_success + expect(response).to be_success end it 'succeeds on the mobile site' do get :show, :id => @person.to_param, :format => :mobile - response.should be_success + expect(response).to be_success end it "assigns only the posts the current user can see" do - bob.posts.should be_empty + expect(bob.posts).to be_empty posts_user_can_see = [] aspect_user_is_in = bob.aspects.where(:name => "generic").first aspect_user_is_not_in = bob.aspects.where(:name => "empty").first @@ -312,16 +312,16 @@ describe PeopleController do bob.post(:status_message, :text => "to an aspect @user is not in", :to => aspect_user_is_not_in.id) posts_user_can_see << bob.post(:status_message, :text => "to all aspects", :to => 'all') posts_user_can_see << bob.post(:status_message, :text => "public", :to => 'all', :public => true) - bob.reload.posts.length.should == 4 + expect(bob.reload.posts.length).to eq(4) get :show, :id => @person.to_param - assigns(:stream).posts.map(&:id).should =~ posts_user_can_see.map(&:id) + expect(assigns(:stream).posts.map(&:id)).to match_array(posts_user_can_see.map(&:id)) end it "posts include reshares" do reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) get :show, :id => @user.person.to_param - assigns[:stream].posts.map { |x| x.id }.should include(reshare.id) + expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) end it 'marks a corresponding notifications as read' do @@ -341,29 +341,29 @@ describe PeopleController do it "succeeds" do get :show, :id => @person.to_param - response.should be_success + expect(response).to be_success end it 'succeeds on the mobile site' do get :show, :id => @person.to_param, :format => :mobile - response.should be_success + expect(response).to be_success end it "assigns only public posts" do - eve.posts.should be_empty + expect(eve.posts).to be_empty eve.post(:status_message, :text => "to an aspect @user is not in", :to => eve.aspects.first.id) eve.post(:status_message, :text => "to all aspects", :to => 'all') public_post = eve.post(:status_message, :text => "public", :to => 'all', :public => true) - eve.reload.posts.length.should == 3 + expect(eve.reload.posts.length).to eq(3) get :show, :id => @person.to_param - assigns[:stream].posts.map(&:id).should =~ [public_post].map(&:id) + expect(assigns[:stream].posts.map(&:id)).to match_array([public_post].map(&:id)) end it "posts include reshares" do reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) get :show, :id => @user.person.to_param - assigns[:stream].posts.map { |x| x.id }.should include(reshare.id) + expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) end end end @@ -377,12 +377,12 @@ describe PeopleController do it 'redirects html requests' do get :hovercard, :person_id => @hover_test.guid - response.should redirect_to person_path(:id => @hover_test.guid) + expect(response).to redirect_to person_path(:id => @hover_test.guid) end it 'returns json with profile stuff' do get :hovercard, :person_id => @hover_test.guid, :format => 'json' - JSON.parse( response.body )['handle'].should == @hover_test.diaspora_handle + expect(JSON.parse( response.body )['handle']).to eq(@hover_test.diaspora_handle) end end @@ -397,16 +397,16 @@ describe PeopleController do describe 'via json' do it 'returns a zero count when a search fails' do get :refresh_search, :q => "weweweKorth", :format => 'json' - response.body.should == {:search_count=>0, :search_html=>""}.to_json + expect(response.body).to eq({:search_count=>0, :search_html=>""}.to_json) end it 'returns with a zero count unless a fully composed name is sent' do get :refresh_search, :q => "Korth" - response.body.should == {:search_count=>0, :search_html=>""}.to_json + expect(response.body).to eq({:search_count=>0, :search_html=>""}.to_json) end it 'returns with a found name' do get :refresh_search, :q => @korth.diaspora_handle - JSON.parse( response.body )["search_count"].should == 1 + expect(JSON.parse( response.body )["search_count"]).to eq(1) end end end @@ -417,48 +417,48 @@ describe PeopleController do contact = alice.contact_for(bob.person) contacts = contact.contacts get :contacts, :person_id => bob.person.to_param - assigns(:contacts_of_contact).should =~ contacts - response.should be_success + expect(assigns(:contacts_of_contact).to_a).to eq(contacts.to_a) + expect(response).to be_success end it 'shows an error when invalid person id' do get :contacts, :person_id => 'foo' - flash[:error].should be_present - response.should redirect_to people_path + expect(flash[:error]).to be_present + expect(response).to redirect_to people_path end end describe '#diaspora_id?' do it 'returns true for pods on urls' do - @controller.send(:diaspora_id?, "ilya_123@pod.geraspora.de").should be true + expect(@controller.send(:diaspora_id?, "ilya_123@pod.geraspora.de")).to be true end it 'returns true for pods on urls with port' do - @controller.send(:diaspora_id?, "ilya_123@pod.geraspora.de:12314").should be true + expect(@controller.send(:diaspora_id?, "ilya_123@pod.geraspora.de:12314")).to be true end it 'returns true for pods on localhost' do - @controller.send(:diaspora_id?, "ilya_123@localhost").should be true + expect(@controller.send(:diaspora_id?, "ilya_123@localhost")).to be true end it 'returns true for pods on localhost and port' do - @controller.send(:diaspora_id?, "ilya_123@localhost:1234").should be true + expect(@controller.send(:diaspora_id?, "ilya_123@localhost:1234")).to be true end it 'returns true for pods on ip' do - @controller.send(:diaspora_id?, "ilya_123@1.1.1.1").should be true + expect(@controller.send(:diaspora_id?, "ilya_123@1.1.1.1")).to be true end it 'returns true for pods on ip and port' do - @controller.send(:diaspora_id?, "ilya_123@1.2.3.4:1234").should be true + expect(@controller.send(:diaspora_id?, "ilya_123@1.2.3.4:1234")).to be true end it 'returns false for pods on with invalid url characters' do - @controller.send(:diaspora_id?, "ilya_123@join_diaspora.com").should be false + expect(@controller.send(:diaspora_id?, "ilya_123@join_diaspora.com")).to be false end it 'returns false for invalid usernames' do - @controller.send(:diaspora_id?, "ilya_2%3@joindiaspora.com").should be false + expect(@controller.send(:diaspora_id?, "ilya_2%3@joindiaspora.com")).to be false end end end diff --git a/spec/controllers/photos_controller_spec.rb b/spec/controllers/photos_controller_spec.rb index 75a6ece37..a2316b1b5 100644 --- a/spec/controllers/photos_controller_spec.rb +++ b/spec/controllers/photos_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PhotosController do +describe PhotosController, :type => :controller do before do @alices_photo = alice.post(:photo, :user_file => uploaded_photo, :to => alice.aspects.first.id, :public => false) @bobs_photo = bob.post(:photo, :user_file => uploaded_photo, :to => bob.aspects.first.id, :public => true) @@ -25,53 +25,53 @@ describe PhotosController do end it 'accepts a photo from a regular form submission' do - lambda { + expect { post :create, @params - }.should change(Photo, :count).by(1) + }.to change(Photo, :count).by(1) end it 'returns application/json when possible' do request.env['HTTP_ACCEPT'] = 'application/json' - post(:create, @params).headers['Content-Type'].should match 'application/json.*' + expect(post(:create, @params).headers['Content-Type']).to match 'application/json.*' end it 'returns text/html by default' do request.env['HTTP_ACCEPT'] = 'text/html,*/*' - post(:create, @params).headers['Content-Type'].should match 'text/html.*' + expect(post(:create, @params).headers['Content-Type']).to match 'text/html.*' end end describe '#create' do before do - @controller.stub(:file_handler).and_return(uploaded_photo) + allow(@controller).to receive(:file_handler).and_return(uploaded_photo) @params = {:photo => {:user_file => uploaded_photo, :aspect_ids => "all"} } end it "creates a photo" do - lambda { + expect { post :create, @params - }.should change(Photo, :count).by(1) + }.to change(Photo, :count).by(1) end it "doesn't allow mass assignment of person" do new_user = FactoryGirl.create(:user) @params[:photo][:author] = new_user post :create, @params - Photo.last.author.should == alice.person + expect(Photo.last.author).to eq(alice.person) end it "doesn't allow mass assignment of person_id" do new_user = FactoryGirl.create(:user) @params[:photo][:author_id] = new_user.id post :create, @params - Photo.last.author.should == alice.person + expect(Photo.last.author).to eq(alice.person) end it 'can set the photo as the profile photo' do old_url = alice.person.profile.image_url @params[:photo][:set_profile_photo] = true post :create, @params - alice.reload.person.profile.image_url.should_not == old_url + expect(alice.reload.person.profile.image_url).not_to eq(old_url) end end @@ -79,26 +79,26 @@ describe PhotosController do it "succeeds without any available pictures" do get :index, :person_id => FactoryGirl.create(:person).guid.to_s - response.should be_success + expect(response).to be_success end it "displays the logged in user's pictures" do get :index, :person_id => alice.person.guid.to_s - assigns[:person].should == alice.person - assigns[:posts].should == [@alices_photo] + expect(assigns[:person]).to eq(alice.person) + expect(assigns[:posts]).to eq([@alices_photo]) end it "displays another person's pictures" do get :index, :person_id => bob.person.guid.to_s - assigns[:person].should == bob.person - assigns[:posts].should == [@bobs_photo] + expect(assigns[:person]).to eq(bob.person) + expect(assigns[:posts]).to eq([@bobs_photo]) end it "returns json when requested" do request.env['HTTP_ACCEPT'] = 'application/json' get :index, :person_id => alice.person.guid.to_s - response.headers['Content-Type'].should match 'application/json.*' + expect(response.headers['Content-Type']).to match 'application/json.*' save_fixture(response.body, "photos_json") end @@ -107,88 +107,88 @@ describe PhotosController do get :index, person_id: bob.person.guid.to_s, max_time: max_time.to_i - assigns[:posts].should be_empty + expect(assigns[:posts]).to be_empty end end describe '#edit' do it "succeeds when user owns the photo" do get :edit, :id => @alices_photo.id - response.should be_success + expect(response).to be_success end it "redirects when the user does not own the photo" do get :edit, :id => @bobs_photo.id - response.should redirect_to(:action => :index, :person_id => alice.person.guid.to_s) + expect(response).to redirect_to(:action => :index, :person_id => alice.person.guid.to_s) end end describe '#destroy' do it 'let a user delete his message' do delete :destroy, :id => @alices_photo.id - Photo.find_by_id(@alices_photo.id).should be_nil + expect(Photo.find_by_id(@alices_photo.id)).to be_nil end it 'will let you delete your profile picture' do xhr :get, :make_profile_photo, :photo_id => @alices_photo.id, :format => :js delete :destroy, :id => @alices_photo.id - Photo.find_by_id(@alices_photo.id).should be_nil + expect(Photo.find_by_id(@alices_photo.id)).to be_nil end it 'sends a retraction on delete' do - @controller.stub(:current_user).and_return(alice) - alice.should_receive(:retract).with(@alices_photo) + allow(@controller).to receive(:current_user).and_return(alice) + expect(alice).to receive(:retract).with(@alices_photo) delete :destroy, :id => @alices_photo.id end it 'will not let you destroy posts visible to you' do delete :destroy, :id => @bobs_photo.id - Photo.find_by_id(@bobs_photo.id).should be_truthy + expect(Photo.find_by_id(@bobs_photo.id)).to be_truthy end it 'will not let you destroy posts you do not own' do eves_photo = eve.post(:photo, :user_file => uploaded_photo, :to => eve.aspects.first.id, :public => true) delete :destroy, :id => eves_photo.id - Photo.find_by_id(eves_photo.id).should be_truthy + expect(Photo.find_by_id(eves_photo.id)).to be_truthy end end describe "#update" do it "updates the caption of a photo" do put :update, :id => @alices_photo.id, :photo => { :text => "now with lasers!" }, :format => :js - @alices_photo.reload.text.should == "now with lasers!" + expect(@alices_photo.reload.text).to eq("now with lasers!") end it "doesn't allow mass assignment of person" do new_user = FactoryGirl.create(:user) params = { :text => "now with lasers!", :author => new_user } put :update, :id => @alices_photo.id, :photo => params, :format => :js - @alices_photo.reload.author.should == alice.person + expect(@alices_photo.reload.author).to eq(alice.person) end it "doesn't allow mass assignment of person_id" do new_user = FactoryGirl.create(:user) params = { :text => "now with lasers!", :author_id => new_user.id } put :update, :id => @alices_photo.id, :photo => params, :format => :js - @alices_photo.reload.author_id.should == alice.person.id + expect(@alices_photo.reload.author_id).to eq(alice.person.id) end it 'redirects if you do not have access to the post' do params = { :text => "now with lasers!" } put :update, :id => @bobs_photo.id, :photo => params - response.should redirect_to(:action => :index, :person_id => alice.person.guid.to_s) + expect(response).to redirect_to(:action => :index, :person_id => alice.person.guid.to_s) end end describe "#make_profile_photo" do it 'should return a 201 on a js success' do xhr :get, :make_profile_photo, :photo_id => @alices_photo.id, :format => 'js' - response.code.should == "201" + expect(response.code).to eq("201") end it 'should return a 422 on failure' do get :make_profile_photo, :photo_id => @bobs_photo.id - response.code.should == "422" + expect(response.code).to eq("422") end end @@ -201,7 +201,7 @@ describe PhotosController do it 'should return 200 for existing stuff on mobile devices' do get :show, :person_id => alice.person.guid, :id => @alices_photo.id, :format => 'mobile' - response.should be_success + expect(response).to be_success end it "doesn't leak private photos to the public" do diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index 0d424ecd2..e3f7a6071 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PostsController do +describe PostsController, :type => :controller do before do aspect = alice.aspects.first @message = alice.build_post :status_message, :text => "ohai", :to => aspect.id @@ -22,22 +22,22 @@ describe PostsController do it 'succeeds' do get :show, "id" => @message.id - response.should be_success + expect(response).to be_success end it 'succeeds on mobile' do get :show, "id" => @message.id - response.should be_success + expect(response).to be_success end it 'renders the application layout on mobile' do get :show, :id => @message.id, :format => :mobile - response.should render_template('layouts/application') + expect(response).to render_template('layouts/application') end it 'succeeds on mobile with a reshare' do get :show, "id" => FactoryGirl.create(:reshare, :author => alice.person).id, :format => :mobile - response.should be_success + expect(response).to be_success end it 'marks a corresponding notifications as read' do @@ -76,25 +76,25 @@ describe PostsController do it 'shows a public post' do get :show, :id => @status.id - response.status.should == 200 + expect(response.status).to eq(200) end it 'succeeds for statusnet' do @request.env["HTTP_ACCEPT"] = "application/html+xml,text/html" get :show, :id => @status.id - response.should be_success + expect(response).to be_success end it 'responds with diaspora xml if format is xml' do get :show, :id => @status.guid, :format => :xml - response.body.should == @status.to_diaspora_xml + expect(response.body).to eq(@status.to_diaspora_xml) end end it 'does not show a private post' do status = alice.post(:status_message, :text => "hello", :public => false, :to => 'all') get :show, :id => status.id - response.status.should == 404 + expect(response.status).to eq(404) end # We want to be using guids from now on for this post route, but do not want to break @@ -107,20 +107,20 @@ describe PostsController do it 'assumes guids less than 8 chars are ids and not guids' do p = Post.where(:id => @status.id.to_s) - Post.should_receive(:where) + expect(Post).to receive(:where) .with(hash_including(:id => @status.id.to_s)) .and_return(p) get :show, :id => @status.id - response.should be_success + expect(response).to be_success end it 'assumes guids more than (or equal to) 8 chars are actually guids' do p = Post.where(:guid => @status.guid) - Post.should_receive(:where) + expect(Post).to receive(:where) .with(hash_including(:guid => @status.guid)) .and_return(p) get :show, :id => @status.guid - response.should be_success + expect(response).to be_success end end end @@ -129,7 +129,7 @@ describe PostsController do describe 'iframe' do it 'contains an iframe' do get :iframe, :id => @message.id - response.body.should match /iframe/ + expect(response.body).to match /iframe/ end end @@ -137,12 +137,12 @@ describe PostsController do it 'works when you can see it' do sign_in alice get :oembed, :url => "/posts/#{@message.id}" - response.body.should match /iframe/ + expect(response.body).to match /iframe/ end it 'returns a 404 response when the post is not found' do get :oembed, :url => "/posts/#{@message.id}" - response.status.should == 404 + expect(response.status).to eq(404) end end @@ -154,28 +154,28 @@ describe PostsController do it 'let a user delete his message' do message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id) delete :destroy, :format => :js, :id => message.id - response.should be_success - StatusMessage.find_by_id(message.id).should be_nil + expect(response).to be_success + expect(StatusMessage.find_by_id(message.id)).to be_nil end it 'sends a retraction on delete' do - controller.stub(:current_user).and_return alice + allow(controller).to receive(:current_user).and_return alice message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id) - alice.should_receive(:retract).with(message) + expect(alice).to receive(:retract).with(message) delete :destroy, :format => :js, :id => message.id - response.should be_success + expect(response).to be_success end it 'will not let you destroy posts visible to you' do message = bob.post(:status_message, :text => "hey", :to => bob.aspects.first.id) expect { delete :destroy, :format => :js, :id => message.id }.to raise_error(ActiveRecord::RecordNotFound) - StatusMessage.exists?(message.id).should be true + expect(StatusMessage.exists?(message.id)).to be true end it 'will not let you destory posts you do not own' do message = eve.post(:status_message, :text => "hey", :to => eve.aspects.first.id) expect { delete :destroy, :format => :js, :id => message.id }.to raise_error(ActiveRecord::RecordNotFound) - StatusMessage.exists?(message.id).should be true + expect(StatusMessage.exists?(message.id)).to be true end end end diff --git a/spec/controllers/profiles_controller_spec.rb b/spec/controllers/profiles_controller_spec.rb index 6655e29c8..c32878c6e 100644 --- a/spec/controllers/profiles_controller_spec.rb +++ b/spec/controllers/profiles_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ProfilesController do +describe ProfilesController, :type => :controller do before do sign_in :user, eve end @@ -14,33 +14,33 @@ describe ProfilesController do let(:mock_presenter) { double(:as_json => {:rock_star => "Jamie Cai"})} it "returns a post Presenter" do - Person.should_receive(:find_by_guid!).with("12345").and_return(mock_person) - PersonPresenter.should_receive(:new).with(mock_person, eve).and_return(mock_presenter) + expect(Person).to receive(:find_by_guid!).with("12345").and_return(mock_person) + expect(PersonPresenter).to receive(:new).with(mock_person, eve).and_return(mock_presenter) get :show, :id => 12345, :format => :json - response.body.should == {:rock_star => "Jamie Cai"}.to_json + expect(response.body).to eq({:rock_star => "Jamie Cai"}.to_json) end end describe '#edit' do it 'succeeds' do get :edit - response.should be_success + expect(response).to be_success end it 'sets the profile to the current users profile' do get :edit - assigns[:profile].should == eve.person.profile + expect(assigns[:profile]).to eq(eve.person.profile) end it 'sets the aspect to "person_edit" ' do get :edit - assigns[:aspect].should == :person_edit + expect(assigns[:aspect]).to eq(:person_edit) end it 'sets the person to the current users person' do get :edit - assigns[:person].should == eve.person + expect(assigns[:person]).to eq(eve.person) end end @@ -51,22 +51,22 @@ describe ProfilesController do :first_name => "Will", :last_name => "Smith" } - flash[:notice].should_not be_blank + expect(flash[:notice]).not_to be_blank end it "sets nsfw" do - eve.person(true).profile.nsfw.should == false + expect(eve.person(true).profile.nsfw).to eq(false) put :update, :profile => { :id => eve.person.id, :nsfw => "1" } - eve.person(true).profile.nsfw.should == true + expect(eve.person(true).profile.nsfw).to eq(true) end it "unsets nsfw" do eve.person.profile.nsfw = true eve.person.profile.save - eve.person(true).profile.nsfw.should == true + expect(eve.person(true).profile.nsfw).to eq(true) put :update, :profile => { :id => eve.person.id } - eve.person(true).profile.nsfw.should == false + expect(eve.person(true).profile.nsfw).to eq(false) end it 'sets tags' do @@ -75,7 +75,7 @@ describe ProfilesController do :profile => {:tag_string => ''} } put :update, params - eve.person(true).profile.tag_list.to_set.should == ['apples', 'oranges'].to_set + expect(eve.person(true).profile.tag_list.to_set).to eq(['apples', 'oranges'].to_set) end it 'sets plaintext tags' do @@ -84,7 +84,7 @@ describe ProfilesController do :profile => {:tag_string => '#pears'} } put :update, params - eve.person(true).profile.tag_list.to_set.should == ['apples', 'oranges', 'pears'].to_set + expect(eve.person(true).profile.tag_list.to_set).to eq(['apples', 'oranges', 'pears'].to_set) end it 'sets plaintext tags without #' do @@ -93,7 +93,7 @@ describe ProfilesController do :profile => {:tag_string => 'bananas'} } put :update, params - eve.person(true).profile.tag_list.to_set.should == ['apples', 'oranges', 'bananas'].to_set + expect(eve.person(true).profile.tag_list.to_set).to eq(['apples', 'oranges', 'bananas'].to_set) end it 'sets valid birthday' do @@ -105,9 +105,9 @@ describe ProfilesController do :day => '28' } } } put :update, params - eve.person(true).profile.birthday.year.should == 2001 - eve.person(true).profile.birthday.month.should == 2 - eve.person(true).profile.birthday.day.should == 28 + expect(eve.person(true).profile.birthday.year).to eq(2001) + expect(eve.person(true).profile.birthday.month).to eq(2) + expect(eve.person(true).profile.birthday.day).to eq(28) end it 'displays error for invalid birthday' do @@ -119,7 +119,7 @@ describe ProfilesController do :day => '31' } } } put :update, params - flash[:error].should_not be_blank + expect(flash[:error]).not_to be_blank end context 'with a profile photo set' do @@ -138,7 +138,7 @@ describe ProfilesController do image_url = eve.person.profile.image_url put :update, @params - Person.find(eve.person.id).profile.image_url.should == image_url + expect(Person.find(eve.person.id).profile.image_url).to eq(image_url) end end @@ -153,12 +153,12 @@ describe ProfilesController do person = eve.person profile = person.profile put :update, @profile_params - profile.reload.person_id.should == person.id + expect(profile.reload.person_id).to eq(person.id) end it 'diaspora handle' do put :update, @profile_params - Person.find(eve.person.id).profile[:diaspora_handle].should_not == 'abc@a.com' + expect(Person.find(eve.person.id).profile[:diaspora_handle]).not_to eq('abc@a.com') end end end diff --git a/spec/controllers/publics_controller_spec.rb b/spec/controllers/publics_controller_spec.rb index 16df77950..08415577a 100644 --- a/spec/controllers/publics_controller_spec.rb +++ b/spec/controllers/publics_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PublicsController do +describe PublicsController, :type => :controller do let(:fixture_path) { Rails.root.join('spec', 'fixtures') } before do @user = alice @@ -14,8 +14,8 @@ describe PublicsController do describe '#host_meta' do it 'succeeds', :fixture => true do get :host_meta - response.should be_success - response.body.should =~ /webfinger/ + expect(response).to be_success + expect(response.body).to match(/webfinger/) save_fixture(response.body, "host-meta", fixture_path) end end @@ -23,17 +23,17 @@ describe PublicsController do describe '#receive_public' do it 'succeeds' do post :receive_public, :xml => "" - response.should be_success + expect(response).to be_success end it 'returns a 422 if no xml is passed' do post :receive_public - response.code.should == '422' + expect(response.code).to eq('422') end it 'enqueues a ReceiveUnencryptedSalmon job' do xml = "stuff" - Workers::ReceiveUnencryptedSalmon.should_receive(:perform_async).with(xml) + expect(Workers::ReceiveUnencryptedSalmon).to receive(:perform_async).with(xml) post :receive_public, :xml => xml end end @@ -43,11 +43,11 @@ describe PublicsController do it 'succeeds' do post :receive, "guid" => @user.person.guid.to_s, "xml" => xml - response.should be_success + expect(response).to be_success end it 'enqueues a receive job' do - Workers::ReceiveEncryptedSalmon.should_receive(:perform_async).with(@user.id, xml).once + expect(Workers::ReceiveEncryptedSalmon).to receive(:perform_async).with(@user.id, xml).once post :receive, "guid" => @user.person.guid.to_s, "xml" => xml end @@ -60,90 +60,90 @@ describe PublicsController do salmon_factory = Salmon::EncryptedSlap.create_by_user_and_activity(@user, xml2) enc_xml = salmon_factory.xml_for(user2.person) - Workers::ReceiveEncryptedSalmon.should_receive(:perform_async).with(@user.id, enc_xml).once + expect(Workers::ReceiveEncryptedSalmon).to receive(:perform_async).with(@user.id, enc_xml).once post :receive, "guid" => @user.person.guid.to_s, "xml" => CGI::escape(enc_xml) end it 'returns a 422 if no xml is passed' do post :receive, "guid" => @person.guid.to_s - response.code.should == '422' + expect(response.code).to eq('422') end it 'returns a 404 if no user is found' do post :receive, "guid" => @person.guid.to_s, "xml" => xml - response.should be_not_found + expect(response).to be_not_found end it 'returns a 404 if no person is found' do post :receive, :guid => '2398rq3948yftn', :xml => xml - response.should be_not_found + expect(response).to be_not_found end end describe '#hcard' do it "succeeds", :fixture => true do post :hcard, "guid" => @user.person.guid.to_s - response.should be_success + expect(response).to be_success save_fixture(response.body, "hcard", fixture_path) end it 'sets the person' do post :hcard, "guid" => @user.person.guid.to_s - assigns[:person].should == @user.person + expect(assigns[:person]).to eq(@user.person) end it 'does not query by user id' do post :hcard, "guid" => 90348257609247856.to_s - assigns[:person].should be_nil - response.should be_not_found + expect(assigns[:person]).to be_nil + expect(response).to be_not_found end it 'finds nothing for closed accounts' do @user.person.update_attributes(:closed_account => true) get :hcard, :guid => @user.person.guid.to_s - response.should be_not_found + expect(response).to be_not_found end end describe '#webfinger' do it "succeeds when the person and user exist locally", :fixture => true do post :webfinger, 'q' => @user.person.diaspora_handle - response.should be_success + expect(response).to be_success save_fixture(response.body, "webfinger", fixture_path) end it "404s when the person exists remotely because it is local only" do stub_success('me@mydiaspora.pod.com') post :webfinger, 'q' => 'me@mydiaspora.pod.com' - response.should be_not_found + expect(response).to be_not_found end it "404s when the person is local but doesn't have an owner" do post :webfinger, 'q' => @person.diaspora_handle - response.should be_not_found + expect(response).to be_not_found end it "404s when the person does not exist locally or remotely" do stub_failure('me@mydiaspora.pod.com') post :webfinger, 'q' => 'me@mydiaspora.pod.com' - response.should be_not_found + expect(response).to be_not_found end it 'has the users profile href' do get :webfinger, :q => @user.diaspora_handle - response.body.should include "http://webfinger.net/rel/profile-page" + expect(response.body).to include "http://webfinger.net/rel/profile-page" end it 'finds nothing for closed accounts' do @user.person.update_attributes(:closed_account => true) get :webfinger, :q => @user.diaspora_handle - response.should be_not_found + expect(response).to be_not_found end end describe '#hub' do it 'succeeds' do get :hub - response.should be_success + expect(response).to be_success end end end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index d6a9b28a4..2bc0ac92e 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe RegistrationsController do +describe RegistrationsController, :type => :controller do include Devise::TestHelpers before do @@ -30,25 +30,25 @@ describe RegistrationsController do it 'redirects #new to the login page' do get :new - flash[:error].should == I18n.t('registrations.closed') - response.should redirect_to new_user_session_path + expect(flash[:error]).to eq(I18n.t('registrations.closed')) + expect(response).to redirect_to new_user_session_path end it 'redirects #create to the login page' do post :create, @valid_params - flash[:error].should == I18n.t('registrations.closed') - response.should redirect_to new_user_session_path + expect(flash[:error]).to eq(I18n.t('registrations.closed')) + expect(response).to redirect_to new_user_session_path end it 'does not redirect if there is a valid invite token' do i = InvitationCode.create(:user => bob) get :new, :invite => {:token => i.token} - response.should_not be_redirect + expect(response).not_to be_redirect end it 'does redirect if there is an invalid invite token' do get :new, :invite => {:token => 'fssdfsd'} - response.should be_redirect + expect(response).to be_redirect end end @@ -59,29 +59,29 @@ describe RegistrationsController do before do AppConfig.settings.enable_registrations = true user = FactoryGirl.build(:user) - User.stub(:build).and_return(user) + allow(User).to receive(:build).and_return(user) end it "creates a user" do - lambda { + expect { get :create, @valid_params - }.should change(User, :count).by(1) + }.to change(User, :count).by(1) end it "assigns @user" do get :create, @valid_params - assigns(:user).should be_truthy + expect(assigns(:user)).to be_truthy end it "sets the flash" do get :create, @valid_params - flash[:notice].should_not be_blank + expect(flash[:notice]).not_to be_blank end it "redirects to the home path" do get :create, @valid_params - response.should be_redirect - response.location.should match /^#{stream_url}\??$/ + expect(response).to be_redirect + expect(response.location).to match /^#{stream_url}\??$/ end end @@ -92,21 +92,21 @@ describe RegistrationsController do end it "does not create a user" do - lambda { get :create, @invalid_params }.should_not change(User, :count) + expect { get :create, @invalid_params }.not_to change(User, :count) end it "does not create a person" do - lambda { get :create, @invalid_params }.should_not change(Person, :count) + expect { get :create, @invalid_params }.not_to change(Person, :count) end it "assigns @user" do get :create, @invalid_params - assigns(:user).should_not be_nil + expect(assigns(:user)).not_to be_nil end it "sets the flash error" do get :create, @invalid_params - flash[:error].should_not be_blank + expect(flash[:error]).not_to be_blank end it "renders new" do diff --git a/spec/controllers/report_controller_spec.rb b/spec/controllers/report_controller_spec.rb index 465bc6fd5..6e63902e2 100644 --- a/spec/controllers/report_controller_spec.rb +++ b/spec/controllers/report_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ReportController do +describe ReportController, :type => :controller do before do sign_in alice @message = alice.post(:status_message, :text => "hey", :to => alice.aspects.first.id) @@ -15,7 +15,7 @@ describe ReportController do context 'admin not signed in' do it 'is behind redirect_unless_admin' do get :index - response.should redirect_to stream_path + expect(response).to redirect_to stream_path end end @@ -25,7 +25,7 @@ describe ReportController do end it 'succeeds and renders index' do get :index - response.should render_template('index') + expect(response).to render_template('index') end end end @@ -39,15 +39,15 @@ describe ReportController do context 'report offensive post' do it 'succeeds' do put :create, :report => { :item_id => @message.id, :item_type => 'post', :text => 'offensive content' } - response.status.should == 200 - Report.exists?(:item_id => @message.id, :item_type => 'post').should be true + expect(response.status).to eq(200) + expect(Report.exists?(:item_id => @message.id, :item_type => 'post')).to be true end end context 'report offensive comment' do it 'succeeds' do put :create, :report => { :item_id => @comment.id, :item_type => 'comment', :text => 'offensive content' } - response.status.should == 200 - Report.exists?(:item_id => @comment.id, :item_type => 'comment').should be true + expect(response.status).to eq(200) + expect(Report.exists?(:item_id => @comment.id, :item_type => 'comment')).to be true end end end @@ -56,15 +56,15 @@ describe ReportController do context 'mark post report as user' do it 'is behind redirect_unless_admin' do put :update, :id => @message.id, :type => 'post' - response.should redirect_to stream_path - Report.where(:reviewed => false, :item_id => @message.id, :item_type => 'post').should be_truthy + expect(response).to redirect_to stream_path + expect(Report.where(:reviewed => false, :item_id => @message.id, :item_type => 'post')).to be_truthy end end context 'mark comment report as user' do it 'is behind redirect_unless_admin' do put :update, :id => @comment.id, :type => 'comment' - response.should redirect_to stream_path - Report.where(:reviewed => false, :item_id => @comment.id, :item_type => 'comment').should be_truthy + expect(response).to redirect_to stream_path + expect(Report.where(:reviewed => false, :item_id => @comment.id, :item_type => 'comment')).to be_truthy end end @@ -74,8 +74,8 @@ describe ReportController do end it 'succeeds' do put :update, :id => @message.id, :type => 'post' - response.status.should == 302 - Report.where(:reviewed => true, :item_id => @message.id, :item_type => 'post').should be_truthy + expect(response.status).to eq(302) + expect(Report.where(:reviewed => true, :item_id => @message.id, :item_type => 'post')).to be_truthy end end context 'mark comment report as admin' do @@ -84,8 +84,8 @@ describe ReportController do end it 'succeeds' do put :update, :id => @comment.id, :type => 'comment' - response.status.should == 302 - Report.where(:reviewed => true, :item_id => @comment.id, :item_type => 'comment').should be_truthy + expect(response.status).to eq(302) + expect(Report.where(:reviewed => true, :item_id => @comment.id, :item_type => 'comment')).to be_truthy end end end @@ -94,15 +94,15 @@ describe ReportController do context 'destroy post as user' do it 'is behind redirect_unless_admin' do delete :destroy, :id => @message.id, :type => 'post' - response.should redirect_to stream_path - Report.where(:reviewed => false, :item_id => @message.id, :item_type => 'post').should be_truthy + expect(response).to redirect_to stream_path + expect(Report.where(:reviewed => false, :item_id => @message.id, :item_type => 'post')).to be_truthy end end context 'destroy comment as user' do it 'is behind redirect_unless_admin' do delete :destroy, :id => @comment.id, :type => 'comment' - response.should redirect_to stream_path - Report.where(:reviewed => false, :item_id => @comment.id, :item_type => 'comment').should be_truthy + expect(response).to redirect_to stream_path + expect(Report.where(:reviewed => false, :item_id => @comment.id, :item_type => 'comment')).to be_truthy end end @@ -112,8 +112,8 @@ describe ReportController do end it 'succeeds' do delete :destroy, :id => @message.id, :type => 'post' - response.status.should == 302 - Report.where(:reviewed => true, :item_id => @message.id, :item_type => 'post').should be_truthy + expect(response.status).to eq(302) + expect(Report.where(:reviewed => true, :item_id => @message.id, :item_type => 'post')).to be_truthy end end context 'destroy comment as admin' do @@ -122,8 +122,8 @@ describe ReportController do end it 'succeeds' do delete :destroy, :id => @comment.id, :type => 'comment' - response.status.should == 302 - Report.where(:reviewed => true, :item_id => @comment.id, :item_type => 'comment').should be_truthy + expect(response.status).to eq(302) + expect(Report.where(:reviewed => true, :item_id => @comment.id, :item_type => 'comment')).to be_truthy end end end diff --git a/spec/controllers/reshares_controller_spec.rb b/spec/controllers/reshares_controller_spec.rb index 180f9f6e8..aa21badae 100644 --- a/spec/controllers/reshares_controller_spec.rb +++ b/spec/controllers/reshares_controller_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe ResharesController do +describe ResharesController, :type => :controller do describe '#create' do let(:post_request!) { post :create, :format => :json, :root_guid => @post_guid @@ -13,17 +13,17 @@ describe ResharesController do it 'requires authentication' do post_request! - response.should_not be_success + expect(response).not_to be_success end context 'with an authenticated user' do before do sign_in :user, bob - @controller.stub(:current_user).and_return(bob) + allow(@controller).to receive(:current_user).and_return(bob) end it 'succeeds' do - response.should be_success + expect(response).to be_success post_request! end @@ -34,12 +34,12 @@ describe ResharesController do end it 'after save, calls add to streams' do - bob.should_receive(:add_to_streams) + expect(bob).to receive(:add_to_streams) post_request! end it 'calls dispatch' do - bob.should_receive(:dispatch_post).with(anything, hash_including(:additional_subscribers)) + expect(bob).to receive(:dispatch_post).with(anything, hash_including(:additional_subscribers)) post_request! end @@ -50,8 +50,8 @@ describe ResharesController do it 'doesn\'t allow the user to reshare the post again' do post_request! - response.code.should == '422' - response.body.strip.should be_empty + expect(response.code).to eq('422') + expect(response.body.strip).to be_empty end end end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index e048c376d..5ec4baf6d 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe SearchController do +describe SearchController, :type => :controller do before do @user = alice @aspect = @user.aspects.first @@ -13,7 +13,7 @@ describe SearchController do :last_name => "w", :searchable => false)) it 'goes to people index page' do get :search, :q => 'eugene' - response.should be_redirect + expect(response).to be_redirect end end @@ -21,17 +21,17 @@ describe SearchController do describe 'query is a tag' do it 'goes to a tag page' do get :search, :q => '#cats' - response.should redirect_to(tag_path('cats')) + expect(response).to redirect_to(tag_path('cats')) end it 'removes dots from the query' do get :search, :q => '#cat.s' - response.should redirect_to(tag_path('cats')) + expect(response).to redirect_to(tag_path('cats')) end it 'stay on the page if you search for the empty hash' do get :search, :q => '#' - flash[:error].should be_present + expect(flash[:error]).to be_present end end diff --git a/spec/controllers/services_controller_spec.rb b/spec/controllers/services_controller_spec.rb index 0796a9f4e..89cbf8448 100644 --- a/spec/controllers/services_controller_spec.rb +++ b/spec/controllers/services_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ServicesController do +describe ServicesController, :type => :controller do let(:omniauth_auth) do { 'provider' => 'facebook', 'uid' => '2', @@ -15,7 +15,7 @@ describe ServicesController do before do sign_in :user, user - @controller.stub(:current_user).and_return(user) + allow(@controller).to receive(:current_user).and_return(user) end describe '#index' do @@ -25,7 +25,7 @@ describe ServicesController do it "displays user's connected services" do get :index - assigns[:services].should == user.services + expect(assigns[:services]).to eq(user.services) end end @@ -43,7 +43,7 @@ describe ServicesController do it 'saves the provider' do post :create, :provider => 'facebook' - user.reload.services.first.class.name.should == "Services::Facebook" + expect(user.reload.services.first.class.name).to eq("Services::Facebook") end context 'when service exists with the same uid' do @@ -52,13 +52,13 @@ describe ServicesController do it 'doesnt create a new service' do service_count = Service.count post :create, :provider => 'twitter' - Service.count.should == service_count + expect(Service.count).to eq(service_count) end it 'flashes an already_authorized error with the diaspora handle for the user' do post :create, :provider => 'twitter' - flash[:error].include?(user.profile.diaspora_handle).should be true - flash[:error].include?( 'already authorized' ).should be true + expect(flash[:error].include?(user.profile.diaspora_handle)).to be true + expect(flash[:error].include?( 'already authorized' )).to be true end end @@ -78,12 +78,12 @@ describe ServicesController do it 'doesnt create a new service' do service_count = Service.count post :create, :provider => 'twitter' - Service.count.should == service_count + expect(Service.count).to eq(service_count) end it 'flashes an read-only access error' do post :create, :provider => 'twitter' - flash[:error].include?( 'Access level is read-only' ).should be true + expect(flash[:error].include?( 'Access level is read-only' )).to be true end end end @@ -110,17 +110,17 @@ describe ServicesController do end it 'does not queue a job if the profile photo is set' do - @controller.stub(:no_profile_image?).and_return false + allow(@controller).to receive(:no_profile_image?).and_return false - Workers::FetchProfilePhoto.should_not_receive(:perform_async) + expect(Workers::FetchProfilePhoto).not_to receive(:perform_async) post :create, :provider => 'twitter' end it 'queues a job to save user photo if the photo does not exist' do - @controller.stub(:no_profile_image?).and_return true + allow(@controller).to receive(:no_profile_image?).and_return true - Workers::FetchProfilePhoto.should_receive(:perform_async).with(user.id, anything(), "https://service.com/fallback_lowres.jpg") + expect(Workers::FetchProfilePhoto).to receive(:perform_async).with(user.id, anything(), "https://service.com/fallback_lowres.jpg") post :create, :provider => 'twitter' end @@ -133,9 +133,9 @@ describe ServicesController do end it 'destroys a service selected by id' do - lambda{ + expect{ delete :destroy, :id => @service1.id - }.should change(user.services, :count).by(-1) + }.to change(user.services, :count).by(-1) end end end diff --git a/spec/controllers/sessions_controller_spec.rb b/spec/controllers/sessions_controller_spec.rb index 3efcb616b..fba0810f8 100644 --- a/spec/controllers/sessions_controller_spec.rb +++ b/spec/controllers/sessions_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe SessionsController do +describe SessionsController, :type => :controller do include Devise::TestHelpers let(:mock_access_token) { Object.new } @@ -20,15 +20,15 @@ describe SessionsController do describe "#create" do it "redirects to /stream for a non-mobile user" do post :create, {"user" => {"remember_me" => "0", "username" => @user.username, "password" => "evankorth"}} - response.should be_redirect - response.location.should match /^#{stream_url}\??$/ + expect(response).to be_redirect + expect(response.location).to match /^#{stream_url}\??$/ end it "redirects to /stream for a mobile user" do @request.env['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7' post :create, {"user" => {"remember_me" => "0", "username" => @user.username, "password" => "evankorth"}} - response.should be_redirect - response.location.should match /^#{stream_url}\??$/ + expect(response).to be_redirect + expect(response.location).to match /^#{stream_url}\??$/ end end @@ -38,13 +38,13 @@ describe SessionsController do end it "redirects to / for a non-mobile user" do delete :destroy - response.should redirect_to new_user_session_path + expect(response).to redirect_to new_user_session_path end it "redirects to / for a mobile user" do @request.env['HTTP_USER_AGENT'] = 'Mozilla/5.0 (iPhone; U; CPU iPhone OS 4_1 like Mac OS X; en-us) AppleWebKit/532.9 (KHTML, like Gecko) Version/4.0.5 Mobile/8B117 Safari/6531.22.7' delete :destroy - response.should redirect_to root_path + expect(response).to redirect_to root_path end end end diff --git a/spec/controllers/share_visibilities_controller_spec.rb b/spec/controllers/share_visibilities_controller_spec.rb index fce516f7b..5fe1bb11b 100644 --- a/spec/controllers/share_visibilities_controller_spec.rb +++ b/spec/controllers/share_visibilities_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ShareVisibilitiesController do +describe ShareVisibilitiesController, :type => :controller do before do @status = alice.post(:status_message, :text => "hello", :to => alice.aspects.first) sign_in :user, bob @@ -14,11 +14,11 @@ describe ShareVisibilitiesController do context "on a post you can see" do it 'succeeds' do put :update, :format => :js, :id => 42, :post_id => @status.id - response.should be_success + expect(response).to be_success end it 'it calls toggle_hidden_shareable' do - @controller.current_user.should_receive(:toggle_hidden_shareable).with(an_instance_of(Post)) + expect(@controller.current_user).to receive(:toggle_hidden_shareable).with(an_instance_of(Post)) put :update, :format => :js, :id => 42, :post_id => @status.id end end @@ -30,7 +30,7 @@ describe ShareVisibilitiesController do @controller.params[:post_id] = id @controller.params[:shareable_type] = 'Post' - Post.should_receive(:where).with(hash_including(:id => id)).once.and_return(double.as_null_object) + expect(Post).to receive(:where).with(hash_including(:id => id)).once.and_return(double.as_null_object) 2.times do |n| @controller.send(:accessible_post) end diff --git a/spec/controllers/statistics_controller_spec.rb b/spec/controllers/statistics_controller_spec.rb index 8fb06c122..6d7566714 100644 --- a/spec/controllers/statistics_controller_spec.rb +++ b/spec/controllers/statistics_controller_spec.rb @@ -4,19 +4,19 @@ require 'spec_helper' -describe StatisticsController do +describe StatisticsController, :type => :controller do describe '#statistics' do it 'responds to format json' do get :statistics, :format => 'json' - response.code.should == '200' + expect(response.code).to eq('200') end it 'contains json' do get :statistics, :format => 'json' json = JSON.parse(response.body) - json['name'].should be_present + expect(json['name']).to be_present end end diff --git a/spec/controllers/status_messages_controller_spec.rb b/spec/controllers/status_messages_controller_spec.rb index 061e3832c..cfeacd606 100644 --- a/spec/controllers/status_messages_controller_spec.rb +++ b/spec/controllers/status_messages_controller_spec.rb @@ -4,47 +4,47 @@ require 'spec_helper' -describe StatusMessagesController do +describe StatusMessagesController, :type => :controller do before do @aspect1 = alice.aspects.first request.env["HTTP_REFERER"] = "" sign_in :user, alice - @controller.stub(:current_user).and_return(alice) + allow(@controller).to receive(:current_user).and_return(alice) alice.reload end describe '#bookmarklet' do it 'succeeds' do get :bookmarklet - response.should be_success + expect(response).to be_success end it 'contains a complete html document' do get :bookmarklet doc = Nokogiri(response.body) - doc.xpath('//head').count.should equal 1 - doc.xpath('//body').count.should equal 1 + expect(doc.xpath('//head').count).to equal 1 + expect(doc.xpath('//body').count).to equal 1 end it 'accepts get params' do get :bookmarklet, { url: 'https://www.youtube.com/watch?v=0Bmhjf0rKe8', title: 'Surprised Kitty', notes: 'cute kitty' } - response.should be_success + expect(response).to be_success end end describe '#new' do it 'succeeds' do get :new, :person_id => bob.person.id - response.should be_success + expect(response).to be_success end it 'should redirect on desktop version' do get :new - response.should redirect_to(stream_path) + expect(response).to redirect_to(stream_path) end it 'generates a jasmine fixture', :fixture => true do @@ -68,51 +68,51 @@ describe StatusMessagesController do it 'creates with valid html' do post :create, status_message_hash - response.status.should == 302 - response.should be_redirect + expect(response.status).to eq(302) + expect(response).to be_redirect end it 'creates with invalid html' do post :create, status_message_hash.merge(:status_message => { :text => "0123456789" * 7000 }) - response.status.should == 302 - response.should be_redirect + expect(response.status).to eq(302) + expect(response).to be_redirect end it 'creates with valid json' do post :create, status_message_hash.merge(:format => 'json') - response.status.should == 201 + expect(response.status).to eq(201) end it 'creates with invalid json' do post :create, status_message_hash.merge(:status_message => { :text => "0123456789" * 7000 }, :format => 'json') - response.status.should == 403 + expect(response.status).to eq(403) end it 'creates with valid mobile' do post :create, status_message_hash.merge(:format => 'mobile') - response.status.should == 302 - response.should be_redirect + expect(response.status).to eq(302) + expect(response).to be_redirect end it 'creates with invalid mobile' do post :create, status_message_hash.merge(:status_message => { :text => "0123456789" * 7000 }, :format => 'mobile') - response.status.should == 302 - response.should be_redirect + expect(response.status).to eq(302) + expect(response).to be_redirect end it 'removes getting started from new users' do - @controller.should_receive(:remove_getting_started) + expect(@controller).to receive(:remove_getting_started) post :create, status_message_hash end it 'takes public in aspect ids' do post :create, status_message_hash.merge(:aspect_ids => ['public']) - response.status.should == 302 + expect(response.status).to eq(302) end it 'takes all_aspects in aspect ids' do post :create, status_message_hash.merge(:aspect_ids => ['all_aspects']) - response.status.should == 302 + expect(response.status).to eq(302) end it "dispatches the post to the specified services" do @@ -121,7 +121,7 @@ describe StatusMessagesController do alice.services << Services::Twitter.new status_message_hash[:services] = ['facebook'] service_types = Service.titles(status_message_hash[:services]) - alice.should_receive(:dispatch_post).with(anything(), hash_including(:service_types => service_types)) + expect(alice).to receive(:dispatch_post).with(anything(), hash_including(:service_types => service_types)) post :create, status_message_hash end @@ -129,7 +129,7 @@ describe StatusMessagesController do s1 = Services::Facebook.new alice.services << s1 status_message_hash[:services] = "facebook" - alice.should_receive(:dispatch_post).with(anything(), hash_including(:service_types => ["Services::Facebook"])) + expect(alice).to receive(:dispatch_post).with(anything(), hash_including(:service_types => ["Services::Facebook"])) post :create, status_message_hash end @@ -137,19 +137,19 @@ describe StatusMessagesController do status_message_hash[:status_message][:author_id] = bob.person.id post :create, status_message_hash new_message = StatusMessage.find_by_text(status_message_hash[:status_message][:text]) - new_message.author_id.should == alice.person.id + expect(new_message.author_id).to eq(alice.person.id) end it "doesn't overwrite id" do old_status_message = alice.post(:status_message, :text => "hello", :to => @aspect1.id) status_message_hash[:status_message][:id] = old_status_message.id post :create, status_message_hash - old_status_message.reload.text.should == 'hello' + expect(old_status_message.reload.text).to eq('hello') end it 'calls dispatch post once subscribers is set' do - alice.should_receive(:dispatch_post){|post, opts| - post.subscribers(alice).should == [bob.person] + expect(alice).to receive(:dispatch_post){|post, opts| + expect(post.subscribers(alice)).to eq([bob.person]) } post :create, status_message_hash end @@ -158,7 +158,7 @@ describe StatusMessagesController do status_message_hash.merge!(:aspect_ids => ['public']) status_message_hash[:status_message].merge!(:provider_display_name => "mobile") post :create, status_message_hash - StatusMessage.first.provider_display_name.should == 'mobile' + expect(StatusMessage.first.provider_display_name).to eq('mobile') end # disabled to fix federation @@ -182,12 +182,12 @@ describe StatusMessagesController do it "will post a photo without text" do @hash.delete :text post :create, @hash - response.should be_redirect + expect(response).to be_redirect end it "attaches all referenced photos" do post :create, @hash - assigns[:status_message].photos.map(&:id).should =~ [@photo1, @photo2].map(&:id) + expect(assigns[:status_message].photos.map(&:id)).to match_array([@photo1, @photo2].map(&:id)) end it "sets the pending bit of referenced photos" do @@ -195,8 +195,8 @@ describe StatusMessagesController do post :create, @hash end - @photo1.reload.pending.should be false - @photo2.reload.pending.should be false + expect(@photo1.reload.pending).to be false + expect(@photo2.reload.pending).to be false end end end diff --git a/spec/controllers/streams_controller_spec.rb b/spec/controllers/streams_controller_spec.rb index e6735f4a5..05440948f 100644 --- a/spec/controllers/streams_controller_spec.rb +++ b/spec/controllers/streams_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe StreamsController do +describe StreamsController, :type => :controller do before do sign_in alice end @@ -13,24 +13,24 @@ describe StreamsController do it 'will succeed if admin' do Role.add_admin(alice.person) get :public - response.should be_success + expect(response).to be_success end it 'will redirect if not' do get :public - response.should be_redirect + expect(response).to be_redirect end end describe '#multi' do it 'succeeds' do get :multi - response.should be_success + expect(response).to be_success end it 'succeeds on mobile' do get :multi, :format => :mobile - response.should be_success + expect(response).to be_success end end @@ -45,8 +45,8 @@ describe StreamsController do describe "a GET to #{stream_path}" do it 'assigns a stream of the proper class' do get stream_path - response.should be_success - assigns[:stream].should be_a stream_class + expect(response).to be_success + expect(assigns[:stream]).to be_a stream_class end end end diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb index 25c107b63..441d630e1 100644 --- a/spec/controllers/tags_controller_spec.rb +++ b/spec/controllers/tags_controller_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe TagsController do +describe TagsController, :type => :controller do describe '#index (search)' do before do sign_in :user, alice @@ -16,22 +16,22 @@ describe TagsController do it 'responds with json' do get :index, :q => "ra", :format => 'json' #parse json - response.body.should include("#rad") + expect(response.body).to include("#rad") end it 'requires at least two characters' do get :index, :q => "c", :format => 'json' - response.body.should_not include("#cats") + expect(response.body).not_to include("#cats") end it 'redirects the aimless to excellent parties' do get :index - response.should redirect_to tag_path('partytimeexcellent') + expect(response).to redirect_to tag_path('partytimeexcellent') end it 'does not allow json requestors to party' do get :index, :format => :json - response.status.should == 422 + expect(response.status).to eq(422) end end @@ -43,7 +43,7 @@ describe TagsController do it 'redirect to the downcase tag uri' do get :show, :name => 'DiasporaRocks!' - response.should redirect_to(:action => :show, :name => 'diasporarocks!') + expect(response).to redirect_to(:action => :show, :name => 'diasporarocks!') end end @@ -54,29 +54,29 @@ describe TagsController do it 'assigns a Stream::Tag object with the current_user' do get :show, :name => 'yes' - assigns[:stream].user.should == alice + expect(assigns[:stream].user).to eq(alice) end it 'succeeds' do get :show, :name => 'hellyes' - response.status.should == 200 + expect(response.status).to eq(200) end end context "not signed in" do it 'assigns a Stream::Tag object with no user' do get :show, :name => 'yes' - assigns[:stream].user.should be_nil + expect(assigns[:stream].user).to be_nil end it 'succeeds' do get :show, :name => 'hellyes' - response.status.should == 200 + expect(response.status).to eq(200) end it 'succeeds with mobile' do get :show, :name => 'foo', :format => :mobile - response.should be_success + expect(response).to be_success end end end @@ -86,17 +86,17 @@ describe TagsController do before do sign_in bob @tag = ActsAsTaggableOn::Tag.create!(:name => "partytimeexcellent") - @controller.stub(:current_user).and_return(bob) - @controller.stub(:params).and_return({:name => "PARTYTIMEexcellent"}) + allow(@controller).to receive(:current_user).and_return(bob) + allow(@controller).to receive(:params).and_return({:name => "PARTYTIMEexcellent"}) end it 'returns true if the following already exists and should be case insensitive' do TagFollowing.create!(:tag => @tag, :user => bob ) - @controller.send(:tag_followed?).should be true + expect(@controller.send(:tag_followed?)).to be true end it 'returns false if the following does not already exist' do - @controller.send(:tag_followed?).should be false + expect(@controller.send(:tag_followed?)).to be false end end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index ad24ece05..fb53282e0 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -4,36 +4,36 @@ require 'spec_helper' -describe UsersController do +describe UsersController, :type => :controller do before do @user = alice sign_in :user, @user - @controller.stub(:current_user).and_return(@user) + allow(@controller).to receive(:current_user).and_return(@user) end describe '#export' do it 'returns an xml file' do get :export - response.header["Content-Type"].should include "application/xml" + expect(response.header["Content-Type"]).to include "application/xml" end end describe '#export_photos' do it 'returns a tar file' do get :export_photos - response.header["Content-Type"].should include "application/octet-stream" + expect(response.header["Content-Type"]).to include "application/octet-stream" end end describe 'user_photo' do it 'should return the url of the users profile photo' do get :user_photo, :username => @user.username - response.should redirect_to(@user.profile.image_url) + expect(response).to redirect_to(@user.profile.image_url) end it 'should 404 if no user is found' do get :user_photo, :username => 'none' - response.should_not be_success + expect(response).not_to be_success end end @@ -41,7 +41,7 @@ describe UsersController do it 'renders xml if atom is requested' do sm = FactoryGirl.create(:status_message, :public => true, :author => @user.person) get :public, :username => @user.username, :format => :atom - response.body.should include(sm.raw_message) + expect(response.body).to include(sm.raw_message) end it 'renders xml if atom is requested with clickalbe urls' do @@ -51,13 +51,13 @@ describe UsersController do p.save end get :public, :username => @user.username, :format => :atom - response.body.should include('a href') + expect(response.body).to include('a href') end it 'includes reshares in the atom feed' do reshare = FactoryGirl.create(:reshare, :author => @user.person) get :public, :username => @user.username, :format => :atom - response.body.should include reshare.root.raw_message + expect(response.body).to include reshare.root.raw_message end it 'do not show reshares in atom feed if origin post is deleted' do @@ -65,17 +65,17 @@ describe UsersController do reshare = FactoryGirl.create(:reshare, :root => post, :author => @user.person) post.delete get :public, :username => @user.username, :format => :atom - response.code.should == '200' + expect(response.code).to eq('200') end it 'redirects to a profile page if html is requested' do get :public, :username => @user.username - response.should be_redirect + expect(response).to be_redirect end it 'redirects to a profile page if mobile is requested' do get :public, :username => @user.username, :format => :mobile - response.should be_redirect + expect(response).to be_redirect end end @@ -86,19 +86,19 @@ describe UsersController do end it "doesn't overwrite random attributes" do - lambda { + expect { put :update, @params - }.should_not change(@user, :diaspora_handle) + }.not_to change(@user, :diaspora_handle) end it 'redirects to the user edit page' do put :update, @params - response.should redirect_to edit_user_path + expect(response).to redirect_to edit_user_path end it 'responds with a 204 on a js request' do put :update, @params.merge(:format => :js) - response.status.should == 204 + expect(response.status).to eq(204) end context 'password updates' do @@ -109,8 +109,8 @@ describe UsersController do end it "uses devise's update with password" do - @user.should_receive(:update_with_password).with(hash_including(@password_params)) - @controller.stub(:current_user).and_return(@user) + expect(@user).to receive(:update_with_password).with(hash_including(@password_params)) + allow(@controller).to receive(:current_user).and_return(@user) put :update, :id => @user.id, :user => @password_params end end @@ -124,7 +124,7 @@ describe UsersController do { :language => "fr"} ) @user.reload - @user.language.should_not == old_language + expect(@user.language).not_to eq(old_language) end end @@ -133,35 +133,35 @@ describe UsersController do @user.email = "my@newemail.com" put(:update, :id => @user.id, :user => { :email => "my@newemail.com"}) @user.reload - @user.unconfirmed_email.should eql(nil) + expect(@user.unconfirmed_email).to eql(nil) end it 'allow the user to change his (unconfirmed) email' do put(:update, :id => @user.id, :user => { :email => "my@newemail.com"}) @user.reload - @user.unconfirmed_email.should eql("my@newemail.com") + expect(@user.unconfirmed_email).to eql("my@newemail.com") end it 'informs the user about success' do put(:update, :id => @user.id, :user => { :email => "my@newemail.com"}) - request.flash[:notice].should eql(I18n.t('users.update.unconfirmed_email_changed')) - request.flash[:error].should be_blank + expect(request.flash[:notice]).to eql(I18n.t('users.update.unconfirmed_email_changed')) + expect(request.flash[:error]).to be_blank end it 'informs the user about failure' do put(:update, :id => @user.id, :user => { :email => "my@newemailcom"}) - request.flash[:error].should eql(I18n.t('users.update.unconfirmed_email_not_changed')) - request.flash[:notice].should be_blank + expect(request.flash[:error]).to eql(I18n.t('users.update.unconfirmed_email_not_changed')) + expect(request.flash[:notice]).to be_blank end it 'allow the user to change his (unconfirmed) email to blank (= abort confirmation)' do put(:update, :id => @user.id, :user => { :email => ""}) @user.reload - @user.unconfirmed_email.should eql(nil) + expect(@user.unconfirmed_email).to eql(nil) end it 'sends out activation email on success' do - Workers::Mail::ConfirmEmail.should_receive(:perform_async).with(@user.id).once + expect(Workers::Mail::ConfirmEmail).to receive(:perform_async).with(@user.id).once put(:update, :id => @user.id, :user => { :email => "my@newemail.com"}) end end @@ -169,24 +169,24 @@ describe UsersController do describe 'email settings' do it 'lets the user turn off mail' do par = {:id => @user.id, :user => {:email_preferences => {'mentioned' => 'true'}}} - proc{ + expect{ put :update, par - }.should change(@user.user_preferences, :count).by(1) + }.to change(@user.user_preferences, :count).by(1) end it 'lets the user get mail again' do @user.user_preferences.create(:email_type => 'mentioned') par = {:id => @user.id, :user => {:email_preferences => {'mentioned' => 'false'}}} - proc{ + expect{ put :update, par - }.should change(@user.user_preferences, :count).by(-1) + }.to change(@user.user_preferences, :count).by(-1) end end describe 'getting started' do it 'can be reenabled' do put :update, user: {getting_started: true} - @user.reload.getting_started?.should be true + expect(@user.reload.getting_started?).to be true end end end @@ -194,43 +194,43 @@ describe UsersController do describe '#privacy_settings' do it "returns a 200" do get 'privacy_settings' - response.status.should == 200 + expect(response.status).to eq(200) end end describe '#edit' do it "returns a 200" do get 'edit', :id => @user.id - response.status.should == 200 + expect(response.status).to eq(200) end it 'set @email_pref to false when there is a user pref' do @user.user_preferences.create(:email_type => 'mentioned') get 'edit', :id => @user.id - assigns[:email_prefs]['mentioned'].should be false + expect(assigns[:email_prefs]['mentioned']).to be false end it 'does not allow token auth' do sign_out :user bob.reset_authentication_token! get :edit, :auth_token => bob.authentication_token - response.should redirect_to new_user_session_path + expect(response).to redirect_to new_user_session_path end end describe '#destroy' do it 'does nothing if the password does not match' do - Workers::DeleteAccount.should_not_receive(:perform_async) + expect(Workers::DeleteAccount).not_to receive(:perform_async) delete :destroy, :user => { :current_password => "stuff" } end it 'closes the account' do - alice.should_receive(:close_account!) + expect(alice).to receive(:close_account!) delete :destroy, :user => { :current_password => "bluepin7" } end it 'enqueues a delete job' do - Workers::DeleteAccount.should_receive(:perform_async).with(anything) + expect(Workers::DeleteAccount).to receive(:perform_async).with(anything) delete :destroy, :user => { :current_password => "bluepin7" } end end @@ -242,35 +242,35 @@ describe UsersController do it 'redirects to to the user edit page' do get 'confirm_email', :token => @user.confirm_email_token - response.should redirect_to edit_user_path + expect(response).to redirect_to edit_user_path end it 'confirms email' do get 'confirm_email', :token => @user.confirm_email_token @user.reload - @user.email.should eql('my@newemail.com') - request.flash[:notice].should eql(I18n.t('users.confirm_email.email_confirmed', :email => 'my@newemail.com')) - request.flash[:error].should be_blank + expect(@user.email).to eql('my@newemail.com') + expect(request.flash[:notice]).to eql(I18n.t('users.confirm_email.email_confirmed', :email => 'my@newemail.com')) + expect(request.flash[:error]).to be_blank end it 'does NOT confirm email with wrong token' do get 'confirm_email', :token => @user.confirm_email_token.reverse @user.reload - @user.email.should_not eql('my@newemail.com') - request.flash[:error].should eql(I18n.t('users.confirm_email.email_not_confirmed')) - request.flash[:notice].should be_blank + expect(@user.email).not_to eql('my@newemail.com') + expect(request.flash[:error]).to eql(I18n.t('users.confirm_email.email_not_confirmed')) + expect(request.flash[:notice]).to be_blank end end describe 'getting_started' do it 'does not fail miserably' do get :getting_started - response.should be_success + expect(response).to be_success end it 'does not fail miserably on mobile' do get :getting_started, :format => :mobile - response.should be_success + expect(response).to be_success end end end diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index 043fe0b22..b75db9533 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ApplicationHelper do +describe ApplicationHelper, :type => :helper do before do @user = alice @person = FactoryGirl.create(:person) @@ -19,12 +19,12 @@ describe ApplicationHelper do it 'links to community spotlight' do @current_user = FactoryGirl.create(:user) - contacts_link.should == community_spotlight_path + expect(contacts_link).to eq(community_spotlight_path) end it 'links to contacts#index' do @current_user = alice - contacts_link.should == contacts_path + expect(contacts_link).to eq(contacts_path) end end @@ -45,12 +45,12 @@ describe ApplicationHelper do it 'returns true if all networks are connected' do 3.times { |t| @current_user.services << FactoryGirl.build(:service) } - all_services_connected?.should be true + expect(all_services_connected?).to be true end it 'returns false if not all networks are connected' do @current_user.services.delete_all - all_services_connected?.should be false + expect(all_services_connected?).to be false end end @@ -61,11 +61,11 @@ describe ApplicationHelper do end it 'inclues jquery.js from jquery cdn' do - jquery_include_tag.should match(/jquery\.com/) + expect(jquery_include_tag).to match(/jquery\.com/) end it 'falls back to asset pipeline on cdn failure' do - jquery_include_tag.should match(/document\.write/) + expect(jquery_include_tag).to match(/document\.write/) end end @@ -75,17 +75,17 @@ describe ApplicationHelper do end it 'includes jquery.js from asset pipeline' do - jquery_include_tag.should match(/jquery\.js/) - jquery_include_tag.should_not match(/jquery\.com/) + expect(jquery_include_tag).to match(/jquery\.js/) + expect(jquery_include_tag).not_to match(/jquery\.com/) end end it 'inclues jquery_ujs.js' do - jquery_include_tag.should match(/jquery_ujs\.js/) + expect(jquery_include_tag).to match(/jquery_ujs\.js/) end it "disables ajax caching" do - jquery_include_tag.should match(/jQuery\.ajaxSetup/) + expect(jquery_include_tag).to match(/jQuery\.ajaxSetup/) end end @@ -93,14 +93,14 @@ describe ApplicationHelper do it 'defaults to master branch changleog' do old_revision = AppConfig.git_revision AppConfig.git_revision = nil - changelog_url.should == 'https://github.com/diaspora/diaspora/blob/master/Changelog.md' + expect(changelog_url).to eq('https://github.com/diaspora/diaspora/blob/master/Changelog.md') AppConfig.git_revision = old_revision end it 'displays the changelog for the current git revision if set' do old_revision = AppConfig.git_revision AppConfig.git_revision = '123' - changelog_url.should == 'https://github.com/diaspora/diaspora/blob/123/Changelog.md' + expect(changelog_url).to eq('https://github.com/diaspora/diaspora/blob/123/Changelog.md') AppConfig.git_revision = old_revision end @@ -108,13 +108,13 @@ describe ApplicationHelper do describe '#pod_name' do it 'defaults to Diaspora*' do - pod_name.should match /DIASPORA/i + expect(pod_name).to match /DIASPORA/i end it 'displays the supplied pod_name if it is set' do old_name = AppConfig.settings.pod_name.get AppConfig.settings.pod_name = "Catspora" - pod_name.should match "Catspora" + expect(pod_name).to match "Catspora" AppConfig.settings.pod_name = old_name end end @@ -124,7 +124,7 @@ describe ApplicationHelper do it 'displays the supplied pod_version if it is set' do old_version = AppConfig.version.number.get AppConfig.version.number = "0.0.1.0" - pod_version.should match "0.0.1.0" + expect(pod_version).to match "0.0.1.0" AppConfig.version.number = old_version end end diff --git a/spec/helpers/getting_started_helper_spec.rb b/spec/helpers/getting_started_helper_spec.rb index 731b38af8..fea1fcf89 100644 --- a/spec/helpers/getting_started_helper_spec.rb +++ b/spec/helpers/getting_started_helper_spec.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. require 'spec_helper' -describe GettingStartedHelper do +describe GettingStartedHelper, :type => :helper do before do @current_user = alice end @@ -16,13 +16,13 @@ describe GettingStartedHelper do it 'returns true if the current user has completed getting started' do @current_user.getting_started = false @current_user.save - has_completed_getting_started?.should be true + expect(has_completed_getting_started?).to be true end it 'returns false if the current user has not completed getting started' do @current_user.getting_started = true @current_user.save - has_completed_getting_started?.should be false + expect(has_completed_getting_started?).to be false end end end diff --git a/spec/helpers/interim_stream_hackiness_helper_spec.rb b/spec/helpers/interim_stream_hackiness_helper_spec.rb index 2212976f4..c0cbb0ba5 100644 --- a/spec/helpers/interim_stream_hackiness_helper_spec.rb +++ b/spec/helpers/interim_stream_hackiness_helper_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe InterimStreamHackinessHelper do +describe InterimStreamHackinessHelper, :type => :helper do describe 'commenting_disabled?' do include Devise::TestHelpers before do @@ -14,24 +14,24 @@ describe InterimStreamHackinessHelper do def user_signed_in? false end - commenting_disabled?(double).should == true + expect(commenting_disabled?(double)).to eq(true) end it 'returns true if @commenting_disabled is set' do @commenting_disabled = true - commenting_disabled?(double).should == true + expect(commenting_disabled?(double)).to eq(true) @commenting_disabled = false - commenting_disabled?(double).should == false + expect(commenting_disabled?(double)).to eq(false) end it 'returns @stream.can_comment? if @stream is set' do post = double @stream = double - @stream.should_receive(:can_comment?).with(post).and_return(true) - commenting_disabled?(post).should == false + expect(@stream).to receive(:can_comment?).with(post).and_return(true) + expect(commenting_disabled?(post)).to eq(false) - @stream.should_receive(:can_comment?).with(post).and_return(false) - commenting_disabled?(post).should == true + expect(@stream).to receive(:can_comment?).with(post).and_return(false) + expect(commenting_disabled?(post)).to eq(true) end end end diff --git a/spec/helpers/invitation_codes_helper_spec.rb b/spec/helpers/invitation_codes_helper_spec.rb index 56010b81c..5ebd8b1ef 100644 --- a/spec/helpers/invitation_codes_helper_spec.rb +++ b/spec/helpers/invitation_codes_helper_spec.rb @@ -10,6 +10,6 @@ require 'spec_helper' # end # end # end -describe InvitationCodesHelper do +describe InvitationCodesHelper, :type => :helper do skip "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/helpers/layout_helper_spec.rb b/spec/helpers/layout_helper_spec.rb index 33b3ae2e1..8810e9ee3 100644 --- a/spec/helpers/layout_helper_spec.rb +++ b/spec/helpers/layout_helper_spec.rb @@ -4,18 +4,18 @@ require 'spec_helper' -describe LayoutHelper do +describe LayoutHelper, :type => :helper do describe "#page_title" do context "passed blank text" do it "returns Diaspora*" do - page_title.to_s.should == pod_name + expect(page_title.to_s).to eq(pod_name) end end context "passed text" do it "returns the text" do text = "This is the title" - page_title(text).should == text + expect(page_title(text)).to eq(text) end end end diff --git a/spec/helpers/mobile_helper_spec.rb b/spec/helpers/mobile_helper_spec.rb index 18a870bdf..c506b3b3c 100644 --- a/spec/helpers/mobile_helper_spec.rb +++ b/spec/helpers/mobile_helper_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe MobileHelper do +describe MobileHelper, :type => :helper do describe "#aspect_select_options" do it "adds an all option to the list of aspects" do @@ -13,7 +13,7 @@ describe MobileHelper do n = FactoryGirl.create(:aspect) options = aspect_select_options([n], n).split('\n') - options.first.should =~ /All/ + expect(options.first).to match(/All/) end end end \ No newline at end of file diff --git a/spec/helpers/notifications_helper_spec.rb b/spec/helpers/notifications_helper_spec.rb index 94817dd0a..2e30be976 100644 --- a/spec/helpers/notifications_helper_spec.rb +++ b/spec/helpers/notifications_helper_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' -describe NotificationsHelper do +describe NotificationsHelper, :type => :helper do include ApplicationHelper before do @@ -38,28 +38,28 @@ describe NotificationsHelper do end it 'with two, does not comma seperate two actors' do - @note.stub(:actors).and_return([@max, @sarah]) - output.scan(/,/).should be_empty - output.scan(/and/).count.should be 1 + allow(@note).to receive(:actors).and_return([@max, @sarah]) + expect(output.scan(/,/)).to be_empty + expect(output.scan(/and/).count).to be 1 end it 'with three, comma seperates the first two, and and the last actor' do - @note.stub(:actors).and_return([@max, @sarah, @daniel]) - output.scan(/,/).count.should be 2 - output.scan(/and/).count.should be 1 + allow(@note).to receive(:actors).and_return([@max, @sarah, @daniel]) + expect(output.scan(/,/).count).to be 2 + expect(output.scan(/and/).count).to be 1 end it 'with more than three, lists the first three, then the others tag' do - @note.stub(:actors).and_return([@max, @sarah, @daniel, @ilya]) - output.scan(/,/).count.should be 3 - output.scan(/and/).count.should be 2 + allow(@note).to receive(:actors).and_return([@max, @sarah, @daniel, @ilya]) + expect(output.scan(/,/).count).to be 3 + expect(output.scan(/and/).count).to be 2 end end describe 'for a like' do it 'displays #{list of actors}' do output = notification_people_link(@notification) - output.should include @person2.name - output.should include @person.name + expect(output).to include @person2.name + expect(output).to include @person.name end end end @@ -69,12 +69,12 @@ describe NotificationsHelper do describe 'for a like' do it 'should include a link to the post' do output = object_link(@notification, notification_people_link(@notification)) - output.should include post_path(@post) + expect(output).to include post_path(@post) end it 'includes the boilerplate translation' do output = object_link(@notification, notification_people_link(@notification)) - output.should include I18n.t("#{@notification.popup_translation_key}", + expect(output).to include I18n.t("#{@notification.popup_translation_key}", :actors => notification_people_link(@notification), :count => @notification.actors.count, :post_link => link_to(post_page_title(@post), post_path(@post), 'data-ref' => @post.id, :class => 'hard_object_link').html_safe) @@ -88,7 +88,7 @@ describe NotificationsHelper do it 'displays that the post was deleted' do @post.destroy - object_link(@notification, notification_people_link(@notification)).should == t('notifications.liked_post_deleted.one', :actors => notification_people_link(@notification)) + expect(object_link(@notification, notification_people_link(@notification))).to eq(t('notifications.liked_post_deleted.one', :actors => notification_people_link(@notification))) end end end diff --git a/spec/helpers/notifier_helper_spec.rb b/spec/helpers/notifier_helper_spec.rb index 9f3e887e9..542f7a150 100644 --- a/spec/helpers/notifier_helper_spec.rb +++ b/spec/helpers/notifier_helper_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe NotifierHelper do +describe NotifierHelper, :type => :helper do describe '#post_message' do before do # post for truncate test @@ -19,12 +19,12 @@ describe NotifierHelper do it 'truncates in the post' do opts = {:length => @post.text.length - 10} - post_message(@post, opts).should == @truncated_post + expect(post_message(@post, opts)).to eq(@truncated_post) end it 'strip markdown in the post' do opts = {:length => @markdown_post.text.length} - post_message(@markdown_post, opts).should == @striped_markdown_post + expect(post_message(@markdown_post, opts)).to eq(@striped_markdown_post) end end @@ -42,12 +42,12 @@ describe NotifierHelper do it 'truncates in the comment' do opts = {:length => @comment.text.length - 10} - comment_message(@comment, opts).should == @truncated_comment + expect(comment_message(@comment, opts)).to eq(@truncated_comment) end it 'strip markdown in the comment' do opts = {:length => @markdown_comment.text.length} - comment_message(@markdown_comment, opts).should == @striped_markdown_comment + expect(comment_message(@markdown_comment, opts)).to eq(@striped_markdown_comment) end end end diff --git a/spec/helpers/o_embed_helper_spec.rb b/spec/helpers/o_embed_helper_spec.rb index 3668a6783..306860ebf 100644 --- a/spec/helpers/o_embed_helper_spec.rb +++ b/spec/helpers/o_embed_helper_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe OEmbedHelper do +describe OEmbedHelper, :type => :helper do describe 'o_embed_html' do scenarios = { "photo" => { @@ -112,15 +112,15 @@ describe OEmbedHelper do formatted = o_embed_html(cache).gsub('https://', 'http://') case type when 'photo' - formatted.should =~ /#{data['oembed_data']['url']}/ + expect(formatted).to match(/#{data['oembed_data']['url']}/) when 'unsupported' - formatted.should =~ /#{data['link_url']}/ + expect(formatted).to match(/#{data['link_url']}/) when 'secure_video', 'secure_rich' - formatted.should =~ /#{data['oembed_data']['html']}/ + expect(formatted).to match(/#{data['oembed_data']['html']}/) when 'unsecure_video', 'unsecure_rich' - formatted.should_not =~ /#{data['oembed_data']['html']}/ - formatted.should =~ /#{data['oembed_data']['title']}/ - formatted.should =~ /#{data['oembed_data']['url']}/ + expect(formatted).not_to match(/#{data['oembed_data']['html']}/) + expect(formatted).to match(/#{data['oembed_data']['title']}/) + expect(formatted).to match(/#{data['oembed_data']['url']}/) end end end diff --git a/spec/helpers/open_graph_helper_spec.rb b/spec/helpers/open_graph_helper_spec.rb index f6b72f1fa..2518ee061 100644 --- a/spec/helpers/open_graph_helper_spec.rb +++ b/spec/helpers/open_graph_helper_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe OpenGraphHelper do +describe OpenGraphHelper, :type => :helper do describe 'og_html' do scenarios = { "article" => { @@ -21,10 +21,10 @@ describe OpenGraphHelper do formatted = og_html(cache) - formatted.should =~ /#{data['url']}/ - formatted.should =~ /#{data['title']}/ - formatted.should =~ /#{data['image']}/ - formatted.should =~ /#{data['description']}/ + expect(formatted).to match(/#{data['url']}/) + expect(formatted).to match(/#{data['title']}/) + expect(formatted).to match(/#{data['image']}/) + expect(formatted).to match(/#{data['description']}/) end end end diff --git a/spec/helpers/people_helper_spec.rb b/spec/helpers/people_helper_spec.rb index f8ff42813..31976a4b5 100644 --- a/spec/helpers/people_helper_spec.rb +++ b/spec/helpers/people_helper_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PeopleHelper do +describe PeopleHelper, :type => :helper do before do @user = alice @person = FactoryGirl.create(:person) @@ -12,13 +12,13 @@ describe PeopleHelper do describe "#person_image_link" do it "returns an empty string if person is nil" do - person_image_link(nil).should == "" + expect(person_image_link(nil)).to eq("") end it "returns a link containing the person's photo" do - person_image_link(@person).should include(@person.profile.image_url) + expect(person_image_link(@person)).to include(@person.profile.image_url) end it "returns a link to the person's profile" do - person_image_link(@person).should include(person_path(@person)) + expect(person_image_link(@person)).to include(person_path(@person)) end end @@ -26,7 +26,7 @@ describe PeopleHelper do it "should not allow basic XSS/HTML" do @person.profile.first_name = "I'm

Evil" @person.profile.last_name = "I'm

Evil" - person_image_tag(@person).should_not include("

") + expect(person_image_tag(@person)).not_to include("

") end end @@ -36,31 +36,31 @@ describe PeopleHelper do end it 'includes the name of the person if they have a first name' do - person_link(@person).should include @person.profile.first_name + expect(person_link(@person)).to include @person.profile.first_name end it 'uses diaspora handle if the person has no first or last name' do @person.profile.first_name = nil @person.profile.last_name = nil - person_link(@person).should include @person.diaspora_handle + expect(person_link(@person)).to include @person.diaspora_handle end it 'uses diaspora handle if first name and first name are rails#blank?' do @person.profile.first_name = " " @person.profile.last_name = " " - person_link(@person).should include @person.diaspora_handle + expect(person_link(@person)).to include @person.diaspora_handle end it "should not allow basic XSS/HTML" do @person.profile.first_name = "I'm

Evil" @person.profile.last_name = "I'm

Evil" - person_link(@person).should_not include("

") + expect(person_link(@person)).not_to include("

") end it 'links by id for a local user' do - person_link(@user.person).should include "href='#{person_path(@user.person)}'" + expect(person_link(@user.person)).to include "href='#{person_path(@user.person)}'" end end @@ -68,13 +68,13 @@ describe PeopleHelper do it "calls local_or_remote_person_path and passes through the options" do opts = {:absolute => true} - self.should_receive(:local_or_remote_person_path).with(@person, opts).exactly(1).times + expect(self).to receive(:local_or_remote_person_path).with(@person, opts).exactly(1).times person_href(@person, opts) end it "returns a href attribute" do - person_href(@person).should include "href=" + expect(person_href(@person)).to include "href=" end end @@ -85,20 +85,20 @@ describe PeopleHelper do it "links by id if there is a period in the user's username" do @user.username = "invalid.username" - @user.save(:validate => false).should == true + expect(@user.save(:validate => false)).to eq(true) person = @user.person person.diaspora_handle = "#{@user.username}@#{AppConfig.pod_uri.authority}" person.save! - local_or_remote_person_path(@user.person).should == person_path(@user.person) + expect(local_or_remote_person_path(@user.person)).to eq(person_path(@user.person)) end it 'links by username for a local user' do - local_or_remote_person_path(@user.person).should == user_profile_path(:username => @user.username) + expect(local_or_remote_person_path(@user.person)).to eq(user_profile_path(:username => @user.username)) end it 'links by id for a remote person' do - local_or_remote_person_path(@person).should == person_path(@person) + expect(local_or_remote_person_path(@person)).to eq(person_path(@person)) end end @@ -110,16 +110,16 @@ describe PeopleHelper do context 'when the contact is sharing' do it 'shows the sharing message' do message = I18n.t('people.helper.is_sharing', :name => @person.name) - @contact.stub(:sharing?).and_return(true) - sharing_message(@person, @contact).should include(message) + allow(@contact).to receive(:sharing?).and_return(true) + expect(sharing_message(@person, @contact)).to include(message) end end context 'when the contact is not sharing' do it 'does show the not sharing message' do message = I18n.t('people.helper.is_not_sharing', :name => @person.name) - @contact.stub(:sharing?).and_return(false) - sharing_message(@person, @contact).should include(message) + allow(@contact).to receive(:sharing?).and_return(false) + expect(sharing_message(@person, @contact)).to include(message) end end end diff --git a/spec/helpers/posts_helper_spec.rb b/spec/helpers/posts_helper_spec.rb index 1d1d6edee..d1624f8dc 100644 --- a/spec/helpers/posts_helper_spec.rb +++ b/spec/helpers/posts_helper_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe PostsHelper do +describe PostsHelper, :type => :helper do describe '#post_page_title' do before do @@ -14,7 +14,7 @@ describe PostsHelper do context 'with posts with text' do it "delegates to message.title" do message = double - message.should_receive(:title) + expect(message).to receive(:title) post = double(message: message) post_page_title(post) end @@ -28,11 +28,11 @@ describe PostsHelper do end it "returns an iframe tag" do - post_iframe_url(@post.id).should include "iframe" + expect(post_iframe_url(@post.id)).to include "iframe" end it "returns an iframe containing the post" do - post_iframe_url(@post.id).should include "src='http://localhost:9887#{post_path(@post)}'" + expect(post_iframe_url(@post.id)).to include "src='http://localhost:9887#{post_path(@post)}'" end end end diff --git a/spec/helpers/stream_helper_spec.rb b/spec/helpers/stream_helper_spec.rb index b44b54d1c..b7c39ce10 100644 --- a/spec/helpers/stream_helper_spec.rb +++ b/spec/helpers/stream_helper_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe StreamHelper do +describe StreamHelper, :type => :helper do describe "next_page_path" do def build_controller controller_class controller_class.new.tap {|c| c.request = controller.request } @@ -14,29 +14,29 @@ describe StreamHelper do end it 'works for public page' do - helper.stub(:controller).and_return(build_controller(PostsController)) - helper.next_page_path.should include '/public' + allow(helper).to receive(:controller).and_return(build_controller(PostsController)) + expect(helper.next_page_path).to include '/public' end it 'works for stream page when current page is stream' do - helper.stub(:current_page?).and_return(false) - helper.should_receive(:current_page?).with(:stream).and_return(true) - helper.stub(:controller).and_return(build_controller(StreamsController)) - helper.next_page_path.should include stream_path + allow(helper).to receive(:current_page?).and_return(false) + expect(helper).to receive(:current_page?).with(:stream).and_return(true) + allow(helper).to receive(:controller).and_return(build_controller(StreamsController)) + expect(helper.next_page_path).to include stream_path end it 'works for aspects page when current page is aspects' do - helper.stub(:current_page?).and_return(false) - helper.should_receive(:current_page?).with(:aspects_stream).and_return(true) - helper.stub(:controller).and_return(build_controller(StreamsController)) - helper.next_page_path.should include aspects_stream_path + allow(helper).to receive(:current_page?).and_return(false) + expect(helper).to receive(:current_page?).with(:aspects_stream).and_return(true) + allow(helper).to receive(:controller).and_return(build_controller(StreamsController)) + expect(helper.next_page_path).to include aspects_stream_path end it 'works for activity page when current page is not stream or aspects' do - helper.stub(:current_page?).and_return(false) - helper.stub(:controller).and_return(build_controller(StreamsController)) + allow(helper).to receive(:current_page?).and_return(false) + allow(helper).to receive(:controller).and_return(build_controller(StreamsController)) # binding.pry - helper.next_page_path.should include activity_stream_path + expect(helper.next_page_path).to include activity_stream_path end end end diff --git a/spec/helpers/tags_helper_spec.rb b/spec/helpers/tags_helper_spec.rb index f62edef90..e48990a82 100644 --- a/spec/helpers/tags_helper_spec.rb +++ b/spec/helpers/tags_helper_spec.rb @@ -1,20 +1,20 @@ require 'spec_helper' -describe TagsHelper do +describe TagsHelper, :type => :helper do describe '#looking_for_tag_link' do it 'returns nil if there is a @ in the query' do - helper.stub(:search_query).and_return('foo@bar.com') - helper.looking_for_tag_link.should be_nil + allow(helper).to receive(:search_query).and_return('foo@bar.com') + expect(helper.looking_for_tag_link).to be_nil end it 'returns nil if it normalizes to blank' do - helper.stub(:search_query).and_return('++') - helper.looking_for_tag_link.should be_nil + allow(helper).to receive(:search_query).and_return('++') + expect(helper.looking_for_tag_link).to be_nil end it 'returns a link to the tag otherwise' do - helper.stub(:search_query).and_return('foo') - helper.looking_for_tag_link.should include(helper.tag_link) + allow(helper).to receive(:search_query).and_return('foo') + expect(helper.looking_for_tag_link).to include(helper.tag_link) end end end diff --git a/spec/integration/account_deletion_spec.rb b/spec/integration/account_deletion_spec.rb index babc748f8..71e52786e 100644 --- a/spec/integration/account_deletion_spec.rb +++ b/spec/integration/account_deletion_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe 'deleteing your account' do +describe 'deleteing your account', :type => :request do context "user" do before do @bob2 = bob @@ -54,42 +54,42 @@ describe 'deleteing your account' do end it "deletes all of the user's preferences" do - UserPreference.where(:id => @prefs.map{|pref| pref.id}).should be_empty + expect(UserPreference.where(:id => @prefs.map{|pref| pref.id})).to be_empty end it "deletes all of the user's notifications" do - Notification.where(:id => @notifications.map{|n| n.id}).should be_empty + expect(Notification.where(:id => @notifications.map{|n| n.id})).to be_empty end it "deletes all of the users's blocked users" do - Block.where(:id => @block.id).should be_empty + expect(Block.where(:id => @block.id)).to be_empty end it "deletes all of the user's services" do - Service.where(:id => @services.map{|s| s.id}).should be_empty + expect(Service.where(:id => @services.map{|s| s.id})).to be_empty end it 'deletes all of @bob2s share visiblites' do - ShareVisibility.where(:id => @users_sv.map{|sv| sv.id}).should be_empty - ShareVisibility.where(:id => @persons_sv.map{|sv| sv.id}).should be_empty + expect(ShareVisibility.where(:id => @users_sv.map{|sv| sv.id})).to be_empty + expect(ShareVisibility.where(:id => @persons_sv.map{|sv| sv.id})).to be_empty end it 'deletes all of @bob2s aspect visiblites' do - AspectVisibility.where(:id => @aspect_vis.map(&:id)).should be_empty + expect(AspectVisibility.where(:id => @aspect_vis.map(&:id))).to be_empty end it 'deletes all aspects' do - @bob2.aspects.should be_empty + expect(@bob2.aspects).to be_empty end it 'deletes all user contacts' do - @bob2.contacts.should be_empty + expect(@bob2.contacts).to be_empty end it "clears the account fields" do @bob2.send(:clearable_fields).each do |field| - @bob2.reload[field].should be_blank + expect(@bob2.reload[field]).to be_blank end end diff --git a/spec/integration/attack_vectors_spec.rb b/spec/integration/attack_vectors_spec.rb index 8683d866a..284823f4e 100644 --- a/spec/integration/attack_vectors_spec.rb +++ b/spec/integration/attack_vectors_spec.rb @@ -39,7 +39,7 @@ def expect_error(partial_message, &block)# DOES NOT REQUIRE ERROR!! begin yield rescue => e - e.message.should match partial_message + expect(e.message).to match partial_message ensure raise "no error occured where expected" unless e.present? @@ -53,7 +53,7 @@ def bogus_retraction(&block) end def user_should_not_see_guid(user, guid) - user.reload.visible_shareables(Post).where(:guid => guid).should be_blank + expect(user.reload.visible_shareables(Post).where(:guid => guid)).to be_blank end #returns the message def legit_post_from_user1_to_user2(user1, user2) @@ -62,7 +62,7 @@ def legit_post_from_user1_to_user2(user1, user2) original_message end -describe "attack vectors" do +describe "attack vectors", :type => :request do let(:eves_aspect) { eve.aspects.find_by_name("generic") } let(:alices_aspect) { alice.aspects.find_by_name("generic") } diff --git a/spec/integration/contact_deleting_spec.rb b/spec/integration/contact_deleting_spec.rb index a1c83fd72..255680d08 100644 --- a/spec/integration/contact_deleting_spec.rb +++ b/spec/integration/contact_deleting_spec.rb @@ -4,13 +4,13 @@ require 'spec_helper' -describe 'disconnecting a contact' do +describe 'disconnecting a contact', :type => :request do it 'removes the aspect membership' do @user = alice @user2 = bob - lambda{ + expect{ @user.disconnect(@user.contact_for(@user2.person)) - }.should change(AspectMembership, :count).by(-1) + }.to change(AspectMembership, :count).by(-1) end end diff --git a/spec/integration/dispatching_spec.rb b/spec/integration/dispatching_spec.rb index af967a66c..83d4f0e32 100644 --- a/spec/integration/dispatching_spec.rb +++ b/spec/integration/dispatching_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe "Dispatching" do +describe "Dispatching", :type => :request do context "a comment retraction on a public post" do it "should trigger a private dispatch" do luke, leia, raph = set_up_friends @@ -11,8 +11,8 @@ describe "Dispatching" do inlined_jobs do # Luke now retracts his comment - Postzord::Dispatcher::Public.should_not_receive(:new) - Postzord::Dispatcher::Private.should_receive(:new).and_return(double(:post => true)) + expect(Postzord::Dispatcher::Public).not_to receive(:new) + expect(Postzord::Dispatcher::Private).to receive(:new).and_return(double(:post => true)) luke.retract(comment) end end diff --git a/spec/integration/mentioning_spec.rb b/spec/integration/mentioning_spec.rb index aab37d79f..d8e851660 100644 --- a/spec/integration/mentioning_spec.rb +++ b/spec/integration/mentioning_spec.rb @@ -26,7 +26,7 @@ module MentioningSpecHelpers end -describe 'mentioning' do +describe 'mentioning', :type => :request do include MentioningSpecHelpers before do @@ -39,20 +39,20 @@ describe 'mentioning' do # see: https://github.com/diaspora/diaspora/issues/4160 it 'only mentions people that are in the target aspect' do - users_connected?(@user1, @user2).should be true - users_connected?(@user1, @user3).should be false + expect(users_connected?(@user1, @user2)).to be true + expect(users_connected?(@user1, @user3)).to be false status_msg = nil - lambda do + expect do status_msg = @user1.post(:status_message, {text: text_mentioning(@user3), to: default_aspect}) - end.should change(Post, :count).by(1) + end.to change(Post, :count).by(1) - status_msg.should_not be_nil - status_msg.public?.should be false - status_msg.text.should include(@user3.name) + expect(status_msg).not_to be_nil + expect(status_msg.public?).to be false + expect(status_msg.text).to include(@user3.name) - notifications_about_mentioning(@user3).should be_empty - stream_for(@user3).map { |item| item.id }.should_not include(status_msg.id) + expect(notifications_about_mentioning(@user3)).to be_empty + expect(stream_for(@user3).map { |item| item.id }).not_to include(status_msg.id) end end diff --git a/spec/integration/receiving_spec.rb b/spec/integration/receiving_spec.rb index 99060afaf..1d31116e9 100644 --- a/spec/integration/receiving_spec.rb +++ b/spec/integration/receiving_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe 'a user receives a post' do +describe 'a user receives a post', :type => :request do def receive_with_zord(user, person, xml) zord = Postzord::Receiver::Private.new(user, :person => person) @@ -26,9 +26,9 @@ describe 'a user receives a post' do bob.delete status_message.destroy - lambda { + expect { receive_with_zord(alice, bob.person, xml) - }.should change(Post,:count).by(1) + }.to change(Post,:count).by(1) end it 'should not create new aspects on message receive' do @@ -38,7 +38,7 @@ describe 'a user receives a post' do status_message = bob.post :status_message, :text => "store this #{n}!", :to => @bobs_aspect.id end - alice.aspects.size.should == num_aspects + expect(alice.aspects.size).to eq(num_aspects) end it "should show bob's post to alice" do @@ -51,13 +51,13 @@ describe 'a user receives a post' do bob.dispatch_post(sm, :to => @bobs_aspect) end - alice.visible_shareables(Post).count(:all).should == 1 + expect(alice.visible_shareables(Post).count(:all)).to eq(1) end context 'with mentions, ' do it 'adds the notifications for the mentioned users regardless of the order they are received' do - Notification.should_receive(:notify).with(alice, anything(), bob.person) - Notification.should_receive(:notify).with(eve, anything(), bob.person) + expect(Notification).to receive(:notify).with(alice, anything(), bob.person) + expect(Notification).to receive(:notify).with(eve, anything(), bob.person) @sm = bob.build_post(:status_message, :text => "@{#{alice.name}; #{alice.diaspora_handle}} stuff @{#{eve.name}; #{eve.diaspora_handle}}") bob.add_to_streams(@sm, [bob.aspects.first]) @@ -74,7 +74,7 @@ describe 'a user receives a post' do @remote_person = FactoryGirl.create(:person, :diaspora_handle => "foobar@foobar.com") Contact.create!(:user => alice, :person => @remote_person, :aspects => [@alices_aspect]) - Notification.should_receive(:notify).with(alice, anything(), @remote_person) + expect(Notification).to receive(:notify).with(alice, anything(), @remote_person) @sm = FactoryGirl.create(:status_message, :text => "hello @{#{alice.name}; #{alice.diaspora_handle}}", :diaspora_handle => @remote_person.diaspora_handle, :author => @remote_person) @sm.save @@ -84,7 +84,7 @@ describe 'a user receives a post' do end it 'does not notify the mentioned user if the mentioned user is not friends with the post author' do - Notification.should_not_receive(:notify).with(alice, anything(), eve.person) + expect(Notification).not_to receive(:notify).with(alice, anything(), eve.person) @sm = eve.build_post(:status_message, :text => "should not notify @{#{alice.name}; #{alice.diaspora_handle}}") eve.add_to_streams(@sm, [eve.aspects.first]) @@ -103,7 +103,7 @@ describe 'a user receives a post' do receive_with_zord(bob, alice.person, xml) - status.reload.text.should == 'store this!' + expect(status.reload.text).to eq('store this!') end it 'updates posts marked as mutable' do @@ -114,7 +114,7 @@ describe 'a user receives a post' do receive_with_zord(bob, alice.person, xml) - photo.reload.text.should match(/foo/) + expect(photo.reload.text).to match(/foo/) end end @@ -127,7 +127,7 @@ describe 'a user receives a post' do p.tag_string = "#big #rafi #style" p.receive(luke, raph) - p.tags(true).count.should == 3 + expect(p.tags(true).count).to eq(3) end end @@ -140,14 +140,14 @@ describe 'a user receives a post' do end it "adds a received post to the the contact" do - alice.visible_shareables(Post).should include(@status_message) - @contact.posts.should include(@status_message) + expect(alice.visible_shareables(Post)).to include(@status_message) + expect(@contact.posts).to include(@status_message) end it 'removes posts upon forceful removal' do alice.remove_contact(@contact, :force => true) alice.reload - alice.visible_shareables(Post).should_not include @status_message + expect(alice.visible_shareables(Post)).not_to include @status_message end context 'dependent delete' do @@ -156,16 +156,16 @@ describe 'a user receives a post' do alice.contacts.create(:person => @person, :aspects => [@alices_aspect]) @post = FactoryGirl.create(:status_message, :author => @person) - @post.share_visibilities.should be_empty + expect(@post.share_visibilities).to be_empty receive_with_zord(alice, @person, @post.to_diaspora_xml) @contact = alice.contact_for(@person) @contact.share_visibilities.reset - @contact.posts(true).should include(@post) + expect(@contact.posts(true)).to include(@post) @post.share_visibilities.reset - lambda { + expect { alice.disconnected_by(@person) - }.should change{@post.share_visibilities(true).count}.by(-1) + }.to change{@post.share_visibilities(true).count}.by(-1) end end end @@ -200,21 +200,21 @@ describe 'a user receives a post' do end it 'should receive a relayed comment with leading whitespace' do - eve.reload.visible_shareables(Post).size.should == 1 + expect(eve.reload.visible_shareables(Post).size).to eq(1) post_in_db = StatusMessage.find(@post.id) - post_in_db.comments.should == [] + expect(post_in_db.comments).to eq([]) receive_with_zord(eve, alice.person, @xml_with_whitespace) - post_in_db.comments(true).first.guid.should == @guid_with_whitespace + expect(post_in_db.comments(true).first.guid).to eq(@guid_with_whitespace) end it 'should correctly attach the user already on the pod' do - bob.reload.visible_shareables(Post).size.should == 1 + expect(bob.reload.visible_shareables(Post).size).to eq(1) post_in_db = StatusMessage.find(@post.id) - post_in_db.comments.should == [] + expect(post_in_db.comments).to eq([]) receive_with_zord(bob, alice.person, @xml) - post_in_db.comments(true).first.author.should == eve.person + expect(post_in_db.comments(true).first.author).to eq(eve.person) end it 'should correctly marshal a stranger for the downstream user' do @@ -226,18 +226,18 @@ describe 'a user receives a post' do remote_person.attributes.delete(:id) # leaving a nil id causes it to try to save with id set to NULL in postgres m = double() - Webfinger.should_receive(:new).twice.with(eve.person.diaspora_handle).and_return(m) + expect(Webfinger).to receive(:new).twice.with(eve.person.diaspora_handle).and_return(m) remote_person.save(:validate => false) remote_person.profile = FactoryGirl.create(:profile, :person => remote_person) - m.should_receive(:fetch).twice.and_return(remote_person) + expect(m).to receive(:fetch).twice.and_return(remote_person) - bob.reload.visible_shareables(Post).size.should == 1 + expect(bob.reload.visible_shareables(Post).size).to eq(1) post_in_db = StatusMessage.find(@post.id) - post_in_db.comments.should == [] + expect(post_in_db.comments).to eq([]) receive_with_zord(bob, alice.person, @xml) - post_in_db.comments(true).first.author.should == remote_person + expect(post_in_db.comments(true).first.author).to eq(remote_person) end end @@ -279,8 +279,8 @@ describe 'a user receives a post' do receive_with_zord(@local_luke, @remote_raphael, xml) old_time = Time.now+1 receive_with_zord(@local_leia, @remote_raphael, xml) - (Post.find_by_guid @post.guid).updated_at.should be < old_time - (Post.find_by_guid @post.guid).created_at.should be < old_time + expect((Post.find_by_guid @post.guid).updated_at).to be < old_time + expect((Post.find_by_guid @post.guid).created_at).to be < old_time end it 'does not update the post if a new one is sent with a new created_at' do @@ -290,7 +290,7 @@ describe 'a user receives a post' do receive_with_zord(@local_luke, @remote_raphael, xml) @post = FactoryGirl.build(:status_message, :text => 'hey', :guid => '12313123', :author => @remote_raphael, :created_at => 2.days.ago) receive_with_zord(@local_luke, @remote_raphael, xml) - (Post.find_by_guid @post.guid).created_at.day.should == old_time.day + expect((Post.find_by_guid @post.guid).created_at.day).to eq(old_time.day) end end @@ -305,7 +305,7 @@ describe 'a user receives a post' do zord = Postzord::Receiver::Private.new(bob, :salmon_xml => salmon_xml) zord.perform! - bob.visible_shareables(Post).include?(post).should be true + expect(bob.visible_shareables(Post).include?(post)).to be true end end @@ -366,8 +366,8 @@ describe 'a user receives a post' do #Check that marshaled profile is the same as old profile person = Person.find(person.id) - person.profile.first_name.should == new_profile.first_name - person.profile.last_name.should == new_profile.last_name - person.profile.image_url.should == new_profile.image_url + expect(person.profile.first_name).to eq(new_profile.first_name) + expect(person.profile.last_name).to eq(new_profile.last_name) + expect(person.profile.image_url).to eq(new_profile.image_url) end end diff --git a/spec/integration/tag_people_spec.rb b/spec/integration/tag_people_spec.rb index 049ef9375..cf4e2e186 100644 --- a/spec/integration/tag_people_spec.rb +++ b/spec/integration/tag_people_spec.rb @@ -1,28 +1,28 @@ require 'spec_helper' -describe TagsController, type: :controller do +describe TagsController do describe 'will_paginate people on the tag page' do let(:people) { (1..2).map { FactoryGirl.create(:person) } } let(:tag) { "diaspora" } before do Stream::Tag.any_instance.stub(people_per_page: 1) - Person.should_receive(:profile_tagged_with).with(/#{tag}/).twice.and_return(people) + expect(Person).to receive(:profile_tagged_with).with(/#{tag}/).twice.and_return(people) end it 'paginates the people set' do get "/tags/#{tag}" expect(response.status).to eq(200) - response.body.should match(/div class="pagination"/) - response.body.should match(/href="\/tags\/#{tag}\?page=2"/) + expect(response.body).to match(/div class="pagination"/) + expect(response.body).to match(/href="\/tags\/#{tag}\?page=2"/) end it 'fetches the second page' do get "/tags/#{tag}", page: 2 expect(response.status).to eq(200) - response.body.should match(/2<\/em>/) + expect(response.body).to match(/2<\/em>/) end end end diff --git a/spec/lib/account_deleter_spec.rb b/spec/lib/account_deleter_spec.rb index 339224c48..7c890757e 100644 --- a/spec/lib/account_deleter_spec.rb +++ b/spec/lib/account_deleter_spec.rb @@ -11,8 +11,8 @@ describe AccountDeleter do end it "attaches the user" do - AccountDeleter.new(bob.person.diaspora_handle).user.should == bob - AccountDeleter.new(remote_raphael.diaspora_handle).user.should == nil + expect(AccountDeleter.new(bob.person.diaspora_handle).user).to eq(bob) + expect(AccountDeleter.new(remote_raphael.diaspora_handle).user).to eq(nil) end describe '#perform' do @@ -38,7 +38,7 @@ describe AccountDeleter do (user_removal_methods + person_removal_methods).each do |method| it "calls ##{method.to_s}" do - @account_deletion.should_receive(method) + expect(@account_deletion).to receive(method) end end end @@ -55,14 +55,14 @@ describe AccountDeleter do (user_removal_methods).each do |method| it "does not call ##{method.to_s}" do - @person_deletion.should_not_receive(method) + expect(@person_deletion).not_to receive(method) end end (person_removal_methods).each do |method| it "calls ##{method.to_s}" do - @person_deletion.should_receive(method) + expect(@person_deletion).to receive(method) end end end @@ -73,8 +73,8 @@ describe AccountDeleter do it 'removes all standard user associaltions' do @account_deletion.normal_ar_user_associates_to_delete.each do |asso| association_double = double - association_double.should_receive(:destroy) - bob.should_receive(asso).and_return([association_double]) + expect(association_double).to receive(:destroy) + expect(bob).to receive(asso).and_return([association_double]) end @account_deletion.delete_standard_user_associations @@ -88,8 +88,8 @@ describe AccountDeleter do it 'removes all standard person associaltions' do @account_deletion.normal_ar_person_associates_to_delete.each do |asso| association_double = double - association_double.should_receive(:destroy_all) - bob.person.should_receive(asso).and_return(association_double) + expect(association_double).to receive(:destroy_all) + expect(bob.person).to receive(asso).and_return(association_double) end @account_deletion.delete_standard_person_associations @@ -99,8 +99,8 @@ describe AccountDeleter do describe "#disassociate_invitations" do it "sets invitations_from_me to be admin invitations" do invites = [double] - bob.stub(:invitations_from_me).and_return(invites) - invites.first.should_receive(:convert_to_admin!) + allow(bob).to receive(:invitations_from_me).and_return(invites) + expect(invites.first).to receive(:convert_to_admin!) @account_deletion.disassociate_invitations end end @@ -108,7 +108,7 @@ describe AccountDeleter do context 'person associations' do describe '#disconnect_contacts' do it "deletes all of user's contacts" do - bob.contacts.should_receive(:destroy_all) + expect(bob.contacts).to receive(:destroy_all) @account_deletion.disconnect_contacts end end @@ -116,28 +116,28 @@ describe AccountDeleter do describe '#delete_contacts_of_me' do it 'deletes all the local contact objects where deleted account is the person' do contacts = double - Contact.should_receive(:all_contacts_of_person).with(bob.person).and_return(contacts) - contacts.should_receive(:destroy_all) + expect(Contact).to receive(:all_contacts_of_person).with(bob.person).and_return(contacts) + expect(contacts).to receive(:destroy_all) @account_deletion.delete_contacts_of_me end end describe '#tombstone_person_and_profile' do it 'calls clear_profile! on person' do - @account_deletion.person.should_receive(:clear_profile!) + expect(@account_deletion.person).to receive(:clear_profile!) @account_deletion.tombstone_person_and_profile end it 'calls lock_access! on person' do - @account_deletion.person.should_receive(:lock_access!) + expect(@account_deletion.person).to receive(:lock_access!) @account_deletion.tombstone_person_and_profile end end describe "#remove_conversation_visibilities" do it "removes the conversation visibility for the deleted user" do vis = double - ConversationVisibility.should_receive(:where).with(hash_including(:person_id => bob.person.id)).and_return(vis) - vis.should_receive(:destroy_all) + expect(ConversationVisibility).to receive(:where).with(hash_including(:person_id => bob.person.id)).and_return(vis) + expect(vis).to receive(:destroy_all) @account_deletion.remove_conversation_visibilities end end @@ -146,8 +146,8 @@ describe AccountDeleter do describe "#remove_person_share_visibilities" do it 'removes the share visibilities for a person ' do @s_vis = double - ShareVisibility.should_receive(:for_contacts_of_a_person).with(bob.person).and_return(@s_vis) - @s_vis.should_receive(:destroy_all) + expect(ShareVisibility).to receive(:for_contacts_of_a_person).with(bob.person).and_return(@s_vis) + expect(@s_vis).to receive(:destroy_all) @account_deletion.remove_share_visibilities_on_persons_posts end @@ -156,8 +156,8 @@ describe AccountDeleter do describe "#remove_share_visibilities_by_contacts_of_user" do it 'removes the share visibilities for a user' do @s_vis = double - ShareVisibility.should_receive(:for_a_users_contacts).with(bob).and_return(@s_vis) - @s_vis.should_receive(:destroy_all) + expect(ShareVisibility).to receive(:for_a_users_contacts).with(bob).and_return(@s_vis) + expect(@s_vis).to receive(:destroy_all) @account_deletion.remove_share_visibilities_on_contacts_posts end @@ -165,19 +165,19 @@ describe AccountDeleter do describe "#tombstone_user" do it 'calls strip_model on user' do - bob.should_receive(:clear_account!) + expect(bob).to receive(:clear_account!) @account_deletion.tombstone_user end end it 'has all user association keys accounted for' do all_keys = (@account_deletion.normal_ar_user_associates_to_delete + @account_deletion.special_ar_user_associations + @account_deletion.ignored_ar_user_associations) - all_keys.sort{|x, y| x.to_s <=> y.to_s}.should == User.reflections.keys.sort{|x, y| x.to_s <=> y.to_s} + expect(all_keys.sort{|x, y| x.to_s <=> y.to_s}).to eq(User.reflections.keys.sort{|x, y| x.to_s <=> y.to_s}) end it 'has all person association keys accounted for' do all_keys = (@account_deletion.normal_ar_person_associates_to_delete + @account_deletion.ignored_or_special_ar_person_associations) - all_keys.sort{|x, y| x.to_s <=> y.to_s}.should == Person.reflections.keys.sort{|x, y| x.to_s <=> y.to_s} + expect(all_keys.sort{|x, y| x.to_s <=> y.to_s}).to eq(Person.reflections.keys.sort{|x, y| x.to_s <=> y.to_s}) end end diff --git a/spec/lib/configuration_methods_spec.rb b/spec/lib/configuration_methods_spec.rb index 654dc4933..5ca9e3ca2 100644 --- a/spec/lib/configuration_methods_spec.rb +++ b/spec/lib/configuration_methods_spec.rb @@ -17,37 +17,37 @@ describe Configuration::Methods do it "properly parses the pod url" do @settings.environment.url = "http://example.org/" - @settings.pod_uri.scheme.should == "http" - @settings.pod_uri.host.should == "example.org" + expect(@settings.pod_uri.scheme).to eq("http") + expect(@settings.pod_uri.host).to eq("example.org") end it "adds a trailing slash if there isn't one" do @settings.environment.url = "http://example.org" - @settings.pod_uri.to_s.should == "http://example.org/" + expect(@settings.pod_uri.to_s).to eq("http://example.org/") end it "does not add an extra trailing slash" do @settings.environment.url = "http://example.org/" - @settings.pod_uri.to_s.should == "http://example.org/" + expect(@settings.pod_uri.to_s).to eq("http://example.org/") end it "adds http:// on the front if it's missing" do @settings.environment.url = "example.org/" - @settings.pod_uri.to_s.should == "http://example.org/" + expect(@settings.pod_uri.to_s).to eq("http://example.org/") end it "does not add a prefix if there already is https:// on the front" do @settings.environment.url = "https://example.org/" - @settings.pod_uri.to_s.should == "https://example.org/" + expect(@settings.pod_uri.to_s).to eq("https://example.org/") end end describe "#bare_pod_uri" do it 'is #pod_uri.authority stripping www.' do pod_uri = double - @settings.stub(:pod_uri).and_return(pod_uri) - pod_uri.should_receive(:authority).and_return("www.example.org") - @settings.bare_pod_uri.should == 'example.org' + allow(@settings).to receive(:pod_uri).and_return(pod_uri) + expect(pod_uri).to receive(:authority).and_return("www.example.org") + expect(@settings.bare_pod_uri).to eq('example.org') end end @@ -55,44 +55,44 @@ describe Configuration::Methods do it "includes the enabled services only" do services = double enabled = double - enabled.stub(:enable?).and_return(true) + allow(enabled).to receive(:enable?).and_return(true) disabled = double - disabled.stub(:enable?).and_return(false) - services.stub(:twitter).and_return(enabled) - services.stub(:tumblr).and_return(enabled) - services.stub(:facebook).and_return(disabled) - services.stub(:wordpress).and_return(disabled) - @settings.stub(:services).and_return(services) - @settings.configured_services.should include :twitter - @settings.configured_services.should include :tumblr - @settings.configured_services.should_not include :facebook - @settings.configured_services.should_not include :wordpress + allow(disabled).to receive(:enable?).and_return(false) + allow(services).to receive(:twitter).and_return(enabled) + allow(services).to receive(:tumblr).and_return(enabled) + allow(services).to receive(:facebook).and_return(disabled) + allow(services).to receive(:wordpress).and_return(disabled) + allow(@settings).to receive(:services).and_return(services) + expect(@settings.configured_services).to include :twitter + expect(@settings.configured_services).to include :tumblr + expect(@settings.configured_services).not_to include :facebook + expect(@settings.configured_services).not_to include :wordpress end end describe "#version_string" do before do @version = double - @version.stub(:number).and_return("0.0.0.0") - @version.stub(:release?).and_return(true) - @settings.stub(:version).and_return(@version) - @settings.stub(:git_available?).and_return(false) + allow(@version).to receive(:number).and_return("0.0.0.0") + allow(@version).to receive(:release?).and_return(true) + allow(@settings).to receive(:version).and_return(@version) + allow(@settings).to receive(:git_available?).and_return(false) @settings.instance_variable_set(:@version_string, nil) end it "includes the version" do - @settings.version_string.should include @version.number + expect(@settings.version_string).to include @version.number end context "with git available" do before do - @settings.stub(:git_available?).and_return(true) - @settings.stub(:git_revision).and_return("1234567890") + allow(@settings).to receive(:git_available?).and_return(true) + allow(@settings).to receive(:git_revision).and_return("1234567890") end it "includes the 'patchlevel'" do - @settings.version_string.should include "-p#{@settings.git_revision[0..7]}" - @settings.version_string.should_not include @settings.git_revision[0..8] + expect(@settings.version_string).to include "-p#{@settings.git_revision[0..7]}" + expect(@settings.version_string).not_to include @settings.git_revision[0..8] end end end @@ -104,7 +104,7 @@ describe Configuration::Methods do end it "uses that" do - @settings.get_redis_options[:url].should match "myserver" + expect(@settings.get_redis_options[:url]).to match "myserver" end end @@ -115,7 +115,7 @@ describe Configuration::Methods do end it "uses that" do - @settings.get_redis_options[:url].should match "yourserver" + expect(@settings.get_redis_options[:url]).to match "yourserver" end end @@ -127,7 +127,7 @@ describe Configuration::Methods do end it "uses that" do - @settings.get_redis_options[:url].should match "ourserver" + expect(@settings.get_redis_options[:url]).to match "ourserver" end end @@ -139,7 +139,7 @@ describe Configuration::Methods do end it "uses that" do - @settings.get_redis_options[:url].should match "/tmp/redis.sock" + expect(@settings.get_redis_options[:url]).to match "/tmp/redis.sock" end end end @@ -148,9 +148,9 @@ describe Configuration::Methods do context "with a relative log set" do it "joins that with Rails.root" do path = "/some/path/" - Rails.stub(:root).and_return(double(join: path)) + allow(Rails).to receive(:root).and_return(double(join: path)) @settings.environment.sidekiq.log = "relative_path" - @settings.sidekiq_log.should match path + expect(@settings.sidekiq_log).to match path end end @@ -158,7 +158,7 @@ describe Configuration::Methods do it "just returns that" do path = "/foobar.log" @settings.environment.sidekiq.log = path - @settings.sidekiq_log.should == path + expect(@settings.sidekiq_log).to eq(path) end end end diff --git a/spec/lib/diaspora/encryptable_spec.rb b/spec/lib/diaspora/encryptable_spec.rb index 1fefbf403..7419b7f61 100644 --- a/spec/lib/diaspora/encryptable_spec.rb +++ b/spec/lib/diaspora/encryptable_spec.rb @@ -11,19 +11,19 @@ describe Diaspora::Encryptable do describe '#sign_with_key' do it 'signs the object with RSA256 signature' do sig = @comment.sign_with_key bob.encryption_key - bob.public_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(sig), @comment.signable_string).should be true + expect(bob.public_key.verify(OpenSSL::Digest::SHA256.new, Base64.decode64(sig), @comment.signable_string)).to be true end end describe '#verify_signature' do it 'verifies SHA256 signatures' do sig = @comment.sign_with_key bob.encryption_key - @comment.verify_signature(sig, bob.person).should be true + expect(@comment.verify_signature(sig, bob.person)).to be true end it 'does not verify the fallback after rollout window' do sig = Base64.strict_encode64(bob.encryption_key.sign( "SHA", @comment.signable_string )) - @comment.verify_signature(sig, bob.person).should be false + expect(@comment.verify_signature(sig, bob.person)).to be false end end end diff --git a/spec/lib/diaspora/exporter_spec.rb b/spec/lib/diaspora/exporter_spec.rb index 9db71fbfe..63d3c2316 100644 --- a/spec/lib/diaspora/exporter_spec.rb +++ b/spec/lib/diaspora/exporter_spec.rb @@ -55,8 +55,8 @@ describe Diaspora::Exporter do let(:aspects_xml) { exported.xpath('//aspects').to_s } it 'includes the post_ids' do - aspects_xml.should include @status_message1.id.to_s - aspects_xml.should include @status_message2.id.to_s + expect(aspects_xml).to include @status_message1.id.to_s + expect(aspects_xml).to include @status_message2.id.to_s end end @@ -71,14 +71,14 @@ describe Diaspora::Exporter do let(:contacts_xml) {exported.xpath('//contacts').to_s} it "includes a person's guid" do - contacts_xml.should include @user3.person.guid + expect(contacts_xml).to include @user3.person.guid end it "includes the names of all aspects they are in" do #contact specific xml needs to be tested - @user1.contacts.find_by_person_id(@user3.person.id).aspects.count.should > 0 + expect(@user1.contacts.find_by_person_id(@user3.person.id).aspects.count).to be > 0 @user1.contacts.find_by_person_id(@user3.person.id).aspects.each { |aspect| - contacts_xml.should include aspect.name + expect(contacts_xml).to include aspect.name } end end @@ -87,29 +87,29 @@ describe Diaspora::Exporter do let(:people_xml) {exported.xpath('//people').to_s} it 'includes their guid' do - people_xml.should include @user3.person.guid + expect(people_xml).to include @user3.person.guid end it 'includes their profile' do - people_xml.should include @user3.person.profile.first_name - people_xml.should include @user3.person.profile.last_name + expect(people_xml).to include @user3.person.profile.first_name + expect(people_xml).to include @user3.person.profile.last_name end it 'includes their public key' do - people_xml.should include @user3.person.exported_key + expect(people_xml).to include @user3.person.exported_key end it 'includes their diaspora handle' do - people_xml.should include @user3.person.diaspora_handle + expect(people_xml).to include @user3.person.diaspora_handle end end context '' do let(:posts_xml) {exported.xpath('//posts').to_s} it "includes many posts' xml" do - posts_xml.should include @status_message1.text - posts_xml.should include @status_message2.text - posts_xml.should_not include @status_message3.text + expect(posts_xml).to include @status_message1.text + expect(posts_xml).to include @status_message2.text + expect(posts_xml).not_to include @status_message3.text end it "includes the post's created at time" do @@ -120,7 +120,7 @@ describe Diaspora::Exporter do status.to_s.include?(@status_message1.guid) end.xpath('created_at').text - Time.zone.parse(created_at_text).to_i.should == @status_message1.created_at.to_i + expect(Time.zone.parse(created_at_text).to_i).to eq(@status_message1.created_at.to_i) end end end diff --git a/spec/lib/diaspora/federated/relayable_retraction_spec.rb b/spec/lib/diaspora/federated/relayable_retraction_spec.rb index ad9888e3c..baf88a6eb 100644 --- a/spec/lib/diaspora/federated/relayable_retraction_spec.rb +++ b/spec/lib/diaspora/federated/relayable_retraction_spec.rb @@ -20,14 +20,14 @@ describe RelayableRetraction do describe "#parent" do it "delegates to to target" do - @retraction.target.should_receive(:parent) + expect(@retraction.target).to receive(:parent) @retraction.parent end end describe "#parent_author" do it "delegates to target" do - @retraction.target.should_receive(:parent_author) + expect(@retraction.target).to receive(:parent_author) @retraction.parent_author end end @@ -35,7 +35,7 @@ describe RelayableRetraction do describe '#subscribers' do it 'delegates it to target' do arg = double() - @retraction.target.should_receive(:subscribers).with(arg) + expect(@retraction.target).to receive(:subscribers).with(arg) @retraction.subscribers(arg) end end @@ -48,7 +48,7 @@ describe RelayableRetraction do @retraction.instance_variable_set(:@target, nil) @retraction.target_guid = '135245' - @retraction.should_not_receive(:perform) + expect(@retraction).not_to receive(:perform) @retraction.receive(@local_luke, @remote_raphael) end @@ -60,21 +60,21 @@ describe RelayableRetraction do end it 'signs' do - @retraction.should_receive(:sign_with_key) do |key| - key.to_s.should == @recipient.encryption_key.to_s + expect(@retraction).to receive(:sign_with_key) do |key| + expect(key.to_s).to eq(@recipient.encryption_key.to_s) end @retraction.receive(@recipient, @comment.author) end it 'dispatches' do zord = double() - zord.should_receive(:post) - Postzord::Dispatcher.should_receive(:build).with(@local_luke, @retraction).and_return zord + expect(zord).to receive(:post) + expect(Postzord::Dispatcher).to receive(:build).with(@local_luke, @retraction).and_return zord @retraction.receive(@recipient, @comment.author) end it 'performs' do - @retraction.should_receive(:perform).with(@local_luke) + expect(@retraction).to receive(:perform).with(@local_luke) @retraction.receive(@recipient, @comment.author) end end @@ -85,17 +85,17 @@ describe RelayableRetraction do @retraction = described_class.allocate @retraction.sender = @remote_raphael @retraction.target = @comment - @retraction.stub(:parent_author_signature_valid?).and_return(true) + allow(@retraction).to receive(:parent_author_signature_valid?).and_return(true) @recipient = @local_luke end it 'performs' do - @retraction.should_receive(:perform).with(@recipient) + expect(@retraction).to receive(:perform).with(@recipient) @retraction.receive(@recipient, @remote_raphael) end it 'does not dispatch' do - Postzord::Dispatcher.should_not_receive(:build) + expect(Postzord::Dispatcher).not_to receive(:build) @retraction.receive(@recipient, @remote_raphael) end end @@ -112,20 +112,20 @@ describe RelayableRetraction do describe '#to_xml' do it 'serializes target_guid' do - @xml.should include(@comment.guid) + expect(@xml).to include(@comment.guid) end it 'serializes target_type' do - @xml.should include(@comment.class.to_s) + expect(@xml).to include(@comment.class.to_s) end it 'serializes sender_handle' do - @xml.should include(@local_leia.diaspora_handle) + expect(@xml).to include(@local_leia.diaspora_handle) end it 'serializes signatures' do - @xml.should include('TARGETSIGNATURE') - @xml.should include('PARENTSIGNATURE') + expect(@xml).to include('TARGETSIGNATURE') + expect(@xml).to include('PARENTSIGNATURE') end end @@ -135,16 +135,16 @@ describe RelayableRetraction do end it 'marshals the target' do - @marshalled.target.should == @comment + expect(@marshalled.target).to eq(@comment) end it 'marshals the sender' do - @marshalled.sender.should == @local_leia.person + expect(@marshalled.sender).to eq(@local_leia.person) end it 'marshals the signature' do - @marshalled.target_author_signature.should == 'TARGETSIGNATURE' - @marshalled.parent_author_signature.should == 'PARENTSIGNATURE' + expect(@marshalled.target_author_signature).to eq('TARGETSIGNATURE') + expect(@marshalled.parent_author_signature).to eq('PARENTSIGNATURE') end end end diff --git a/spec/lib/diaspora/federated/request_spec.rb b/spec/lib/diaspora/federated/request_spec.rb index a0d77a237..c6b1fe1a1 100644 --- a/spec/lib/diaspora/federated/request_spec.rb +++ b/spec/lib/diaspora/federated/request_spec.rb @@ -15,35 +15,35 @@ describe Request do end it 'is valid' do - @request.sender.should == alice.person - @request.recipient.should == eve.person - @request.aspect.should == @aspect - @request.should be_valid + expect(@request.sender).to eq(alice.person) + expect(@request.recipient).to eq(eve.person) + expect(@request.aspect).to eq(@aspect) + expect(@request).to be_valid end it 'is from a person' do @request.sender = nil - @request.should_not be_valid + expect(@request).not_to be_valid end it 'is to a person' do @request.recipient = nil - @request.should_not be_valid + expect(@request).not_to be_valid end it 'is not necessarily into an aspect' do @request.aspect = nil - @request.should be_valid + expect(@request).to be_valid end it 'is not from an existing friend' do Contact.create(:user => eve, :person => alice.person, :aspects => [eve.aspects.first]) - @request.should_not be_valid + expect(@request).not_to be_valid end it 'is not to yourself' do @request = described_class.diaspora_initialize(:from => alice.person, :to => alice.person, :into => @aspect) - @request.should_not be_valid + expect(@request).not_to be_valid end end @@ -54,23 +54,23 @@ describe Request do request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) alice.contacts.create(:person_id => person.id) - request.notification_type(alice, person).should == Notifications::StartedSharing + expect(request.notification_type(alice, person)).to eq(Notifications::StartedSharing) end end describe '#subscribers' do it 'returns an array with to field on a request' do request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) - request.subscribers(alice).should =~ [eve.person] + expect(request.subscribers(alice)).to match_array([eve.person]) end end describe '#receive' do it 'creates a contact' do request = described_class.diaspora_initialize(:from => alice.person, :to => eve.person, :into => @aspect) - lambda{ + expect{ request.receive(eve, alice.person) - }.should change{ + }.to change{ eve.contacts(true).size }.by(1) end @@ -78,10 +78,10 @@ describe Request do it 'sets mutual if a contact already exists' do alice.share_with(eve.person, alice.aspects.first) - lambda { + expect { described_class.diaspora_initialize(:from => eve.person, :to => alice.person, :into => eve.aspects.first).receive(alice, eve.person) - }.should change { + }.to change { alice.contacts.find_by_person_id(eve.person.id).mutual? }.from(false).to(true) @@ -90,7 +90,7 @@ describe Request do it 'sets sharing' do described_class.diaspora_initialize(:from => eve.person, :to => alice.person, :into => eve.aspects.first).receive(alice, eve.person) - alice.contact_for(eve.person).should be_sharing + expect(alice.contact_for(eve.person)).to be_sharing end it 'shares back if auto_following is enabled' do @@ -101,7 +101,7 @@ describe Request do described_class.diaspora_initialize(:from => eve.person, :to => alice.person, :into => eve.aspects.first).receive(alice, eve.person) - eve.contact_for( alice.person ).should be_sharing + expect(eve.contact_for( alice.person )).to be_sharing end it 'shares not back if auto_following is not enabled' do @@ -112,7 +112,7 @@ describe Request do described_class.diaspora_initialize(:from => eve.person, :to => alice.person, :into => eve.aspects.first).receive(alice, eve.person) - eve.contact_for(alice.person).should be_nil + expect(eve.contact_for(alice.person)).to be_nil end it 'shares not back if already sharing' do @@ -124,7 +124,7 @@ describe Request do :receiving => true, :sharing => false contact.save - alice.should_not_receive(:share_with) + expect(alice).not_to receive(:share_with) described_class.diaspora_initialize(:from => eve.person, :to => alice.person, :into => eve.aspects.first).receive(alice, eve.person) @@ -139,10 +139,10 @@ describe Request do describe 'serialization' do it 'produces valid xml' do - @xml.should include alice.person.diaspora_handle - @xml.should include eve.person.diaspora_handle - @xml.should_not include alice.person.exported_key - @xml.should_not include alice.person.profile.first_name + expect(@xml).to include alice.person.diaspora_handle + expect(@xml).to include eve.person.diaspora_handle + expect(@xml).not_to include alice.person.exported_key + expect(@xml).not_to include alice.person.profile.first_name end end @@ -150,9 +150,9 @@ describe Request do it 'produces a request object' do marshalled = described_class.from_xml @xml - marshalled.sender.should == alice.person - marshalled.recipient.should == eve.person - marshalled.aspect.should be_nil + expect(marshalled.sender).to eq(alice.person) + expect(marshalled.recipient).to eq(eve.person) + expect(marshalled.aspect).to be_nil end end end diff --git a/spec/lib/diaspora/federated/retraction_spec.rb b/spec/lib/diaspora/federated/retraction_spec.rb index 8f556d47e..11b1c49f9 100644 --- a/spec/lib/diaspora/federated/retraction_spec.rb +++ b/spec/lib/diaspora/federated/retraction_spec.rb @@ -15,7 +15,7 @@ describe Retraction do it 'should have a post id after serialization' do retraction = described_class.for(@post) xml = retraction.to_xml.to_s - xml.include?(@post.guid.to_s).should == true + expect(xml.include?(@post.guid.to_s)).to eq(true) end end @@ -28,7 +28,7 @@ describe Retraction do end it 'returns the subscribers to the post for all objects other than person' do - @retraction.subscribers(alice).map(&:id).should =~ @wanted_subscribers.map(&:id) + expect(@retraction.subscribers(alice).map(&:id)).to match_array(@wanted_subscribers.map(&:id)) end it 'does not return the authors of reshares' do @@ -36,7 +36,7 @@ describe Retraction do @post.save! @wanted_subscribers -= [bob.person] - @retraction.subscribers(alice).map(&:id).should =~ @wanted_subscribers.map(&:id) + expect(@retraction.subscribers(alice).map(&:id)).to match_array(@wanted_subscribers.map(&:id)) end end @@ -45,15 +45,15 @@ describe Retraction do retraction = described_class.for(alice) obj = retraction.instance_variable_get(:@object) - lambda { + expect { retraction.subscribers(alice) - }.should raise_error + }.to raise_error end it 'returns manually set subscribers' do retraction = described_class.for(alice) retraction.subscribers = "fooey" - retraction.subscribers(alice).should == 'fooey' + expect(retraction.subscribers(alice)).to eq('fooey') end end end diff --git a/spec/lib/diaspora/federated/signed_retraction_spec.rb b/spec/lib/diaspora/federated/signed_retraction_spec.rb index 55433a0ab..332e9e9c4 100644 --- a/spec/lib/diaspora/federated/signed_retraction_spec.rb +++ b/spec/lib/diaspora/federated/signed_retraction_spec.rb @@ -11,11 +11,11 @@ describe SignedRetraction do it "dispatches the retraction onward to recipients of the recipient's reshare" do retraction = described_class.build(bob, @post) onward_retraction = retraction.dup - retraction.should_receive(:dup).and_return(onward_retraction) + expect(retraction).to receive(:dup).and_return(onward_retraction) dis = double - Postzord::Dispatcher.should_receive(:build).with(@resharer, onward_retraction).and_return(dis) - dis.should_receive(:post) + expect(Postzord::Dispatcher).to receive(:build).with(@resharer, onward_retraction).and_return(dis) + expect(dis).to receive(:post) retraction.perform(@resharer) end @@ -28,19 +28,19 @@ describe SignedRetraction do r.target_type = remote_post.type r.target_guid = remote_post.guid r.sender = remote_post.author - r.stub(:target_author_signature_valid?).and_return(true) + allow(r).to receive(:target_author_signature_valid?).and_return(true) } remote_retraction.dup.perform(bob) - Post.exists?(:id => remote_post.id).should be false + expect(Post.exists?(:id => remote_post.id)).to be false dis = double - Postzord::Dispatcher.should_receive(:build){ |sender, retraction| - sender.should == alice - retraction.sender.should == alice.person + expect(Postzord::Dispatcher).to receive(:build){ |sender, retraction| + expect(sender).to eq(alice) + expect(retraction.sender).to eq(alice.person) dis } - dis.should_receive(:post) + expect(dis).to receive(:post) remote_retraction.perform(alice) end end diff --git a/spec/lib/diaspora/federated_base_spec.rb b/spec/lib/diaspora/federated_base_spec.rb index a3fbcbacc..a2621e3c6 100644 --- a/spec/lib/diaspora/federated_base_spec.rb +++ b/spec/lib/diaspora/federated_base_spec.rb @@ -13,7 +13,7 @@ describe Diaspora::Federated::Base do f = Foo.new - proc{ f.subscribers(1)}.should raise_error /override subscribers/ + expect{ f.subscribers(1)}.to raise_error /override subscribers/ end end end diff --git a/spec/lib/diaspora/fetcher/public_spec.rb b/spec/lib/diaspora/fetcher/public_spec.rb index 0ad5381b4..43f249cab 100644 --- a/spec/lib/diaspora/fetcher/public_spec.rb +++ b/spec/lib/diaspora/fetcher/public_spec.rb @@ -36,16 +36,16 @@ describe Diaspora::Fetcher::Public do it "sets the operation status on the person" do @person.reload - @person.fetch_status.should_not eql(Diaspora::Fetcher::Public::Status_Initial) - @person.fetch_status.should eql(Diaspora::Fetcher::Public::Status_Fetched) + expect(@person.fetch_status).not_to eql(Diaspora::Fetcher::Public::Status_Initial) + expect(@person.fetch_status).to eql(Diaspora::Fetcher::Public::Status_Fetched) end it "sets the @data variable to the parsed JSON data" do data = @fetcher.instance_eval { @data } - data.should_not be_nil - data.size.should eql JSON.parse(@fixture).size + expect(data).not_to be_nil + expect(data.size).to eql JSON.parse(@fixture).size end end @@ -66,7 +66,7 @@ describe Diaspora::Fetcher::Public do process_posts } after_count = Post.count - after_count.should eql(before_count + 10) + expect(after_count).to eql(before_count + 10) end it 'sets the operation status on the person' do @@ -75,8 +75,8 @@ describe Diaspora::Fetcher::Public do } @person.reload - @person.fetch_status.should_not eql(Diaspora::Fetcher::Public::Status_Initial) - @person.fetch_status.should eql(Diaspora::Fetcher::Public::Status_Processed) + expect(@person.fetch_status).not_to eql(Diaspora::Fetcher::Public::Status_Initial) + expect(@person.fetch_status).to eql(Diaspora::Fetcher::Public::Status_Processed) end context 'created post' do @@ -100,14 +100,14 @@ describe Diaspora::Fetcher::Public do date = ActiveSupport::TimeZone.new('UTC').parse(post['created_at']).to_i entry = StatusMessage.find_by_guid(post['guid']) - entry.created_at.to_i.should eql(date) + expect(entry.created_at.to_i).to eql(date) end end it 'copied the text correctly' do @data.each do |post| entry = StatusMessage.find_by_guid(post['guid']) - entry.raw_message.should eql(post['text']) + expect(entry.raw_message).to eql(post['text']) end end @@ -116,7 +116,7 @@ describe Diaspora::Fetcher::Public do date = @now.to_i entry = StatusMessage.find_by_guid(post['guid']) - entry.interacted_at.to_i.should eql(date) + expect(entry.interacted_at.to_i).to eql(date) end end end @@ -127,46 +127,46 @@ describe Diaspora::Fetcher::Public do describe '#qualifies_for_fetching?' do it "raises an error if the person doesn't exist" do - lambda { + expect { public_fetcher.instance_eval { @person = Person.by_account_identifier "someone@unknown.com" qualifies_for_fetching? } - }.should raise_error ActiveRecord::RecordNotFound + }.to raise_error ActiveRecord::RecordNotFound end it 'returns false if the person is unfetchable' do - public_fetcher.instance_eval { + expect(public_fetcher.instance_eval { @person = FactoryGirl.create(:person, {:fetch_status => Diaspora::Fetcher::Public::Status_Unfetchable}) qualifies_for_fetching? - }.should be false + }).to be false end it 'returns false and sets the person unfetchable for a local account' do user = FactoryGirl.create(:user) - public_fetcher.instance_eval { + expect(public_fetcher.instance_eval { @person = user.person qualifies_for_fetching? - }.should be false - user.person.fetch_status.should eql Diaspora::Fetcher::Public::Status_Unfetchable + }).to be false + expect(user.person.fetch_status).to eql Diaspora::Fetcher::Public::Status_Unfetchable end it 'returns false if the person is processing already (or has been processed)' do person = FactoryGirl.create(:person) person.fetch_status = Diaspora::Fetcher::Public::Status_Fetched person.save - public_fetcher.instance_eval { + expect(public_fetcher.instance_eval { @person = person qualifies_for_fetching? - }.should be false + }).to be false end it "returns true, if the user is remote and hasn't been fetched" do person = FactoryGirl.create(:person, {:diaspora_handle => 'neo@theone.net'}) - public_fetcher.instance_eval { + expect(public_fetcher.instance_eval { @person = person qualifies_for_fetching? - }.should be true + }).to be true end end @@ -177,35 +177,35 @@ describe Diaspora::Fetcher::Public do @person = person set_fetch_status Diaspora::Fetcher::Public::Status_Unfetchable } - @person.fetch_status.should eql Diaspora::Fetcher::Public::Status_Unfetchable + expect(@person.fetch_status).to eql Diaspora::Fetcher::Public::Status_Unfetchable public_fetcher.instance_eval { set_fetch_status Diaspora::Fetcher::Public::Status_Initial } - @person.fetch_status.should eql Diaspora::Fetcher::Public::Status_Initial + expect(@person.fetch_status).to eql Diaspora::Fetcher::Public::Status_Initial end end describe '#validate' do it "calls all validation helper methods" do - public_fetcher.should_receive(:check_existing).and_return(true) - public_fetcher.should_receive(:check_author).and_return(true) - public_fetcher.should_receive(:check_public).and_return(true) - public_fetcher.should_receive(:check_type).and_return(true) + expect(public_fetcher).to receive(:check_existing).and_return(true) + expect(public_fetcher).to receive(:check_author).and_return(true) + expect(public_fetcher).to receive(:check_public).and_return(true) + expect(public_fetcher).to receive(:check_type).and_return(true) - public_fetcher.instance_eval { validate({}) }.should be true + expect(public_fetcher.instance_eval { validate({}) }).to be true end end describe '#check_existing' do it 'returns false if a post with the same guid exists' do post = {'guid' => FactoryGirl.create(:status_message).guid} - public_fetcher.instance_eval { check_existing post }.should be false + expect(public_fetcher.instance_eval { check_existing post }).to be false end it 'returns true if the guid cannot be found' do post = {'guid' => SecureRandom.hex(8)} - public_fetcher.instance_eval { check_existing post }.should be true + expect(public_fetcher.instance_eval { check_existing post }).to be true end end @@ -219,36 +219,36 @@ describe Diaspora::Fetcher::Public do it "returns false if the person doesn't match" do post = { 'author' => { 'guid' => SecureRandom.hex(8) } } - public_fetcher.instance_eval { check_author post }.should be false + expect(public_fetcher.instance_eval { check_author post }).to be false end it "returns true if the persons match" do post = { 'author' => { 'guid' => some_person.guid } } - public_fetcher.instance_eval { check_author post }.should be true + expect(public_fetcher.instance_eval { check_author post }).to be true end end describe '#check_public' do it "returns false if the post is not public" do post = {'public' => false} - public_fetcher.instance_eval { check_public post }.should be false + expect(public_fetcher.instance_eval { check_public post }).to be false end it "returns true if the post is public" do post = {'public' => true} - public_fetcher.instance_eval { check_public post }.should be true + expect(public_fetcher.instance_eval { check_public post }).to be true end end describe '#check_type' do it "returns false if the type is anything other that 'StatusMessage'" do post = {'post_type'=>'Reshare'} - public_fetcher.instance_eval { check_type post }.should be false + expect(public_fetcher.instance_eval { check_type post }).to be false end it "returns true if the type is 'StatusMessage'" do post = {'post_type'=>'StatusMessage'} - public_fetcher.instance_eval { check_type post }.should be true + expect(public_fetcher.instance_eval { check_type post }).to be true end end end diff --git a/spec/lib/diaspora/markdownify_email_spec.rb b/spec/lib/diaspora/markdownify_email_spec.rb index f27d0afb1..6a64f7f1d 100644 --- a/spec/lib/diaspora/markdownify_email_spec.rb +++ b/spec/lib/diaspora/markdownify_email_spec.rb @@ -8,17 +8,17 @@ describe Diaspora::Markdownify::Email do it 'should autolink a hashtag' do markdownified = @html.preprocess("#tag") - markdownified.should == "[#tag](http://localhost:9887/tags/tag)" + expect(markdownified).to eq("[#tag](http://localhost:9887/tags/tag)") end it 'should autolink multiple hashtags' do markdownified = @html.preprocess("There are #two #Tags") - markdownified.should == "There are [#two](http://localhost:9887/tags/two) [#Tags](http://localhost:9887/tags/tags)" + expect(markdownified).to eq("There are [#two](http://localhost:9887/tags/two) [#Tags](http://localhost:9887/tags/tags)") end it 'should not autolink headers' do markdownified = @html.preprocess("# header") - markdownified.should == "# header" + expect(markdownified).to eq("# header") end end @@ -30,7 +30,7 @@ describe Diaspora::Markdownify::Email do it 'should render the message' do rendered = @markdown.render(@sample_text).strip - rendered.should == "

Header

\n\n

#messages containing #hashtags should render properly

" + expect(rendered).to eq("

Header

\n\n

#messages containing #hashtags should render properly

") end end end \ No newline at end of file diff --git a/spec/lib/diaspora/markdownify_spec.rb b/spec/lib/diaspora/markdownify_spec.rb index 41e6b28a2..143a62f31 100644 --- a/spec/lib/diaspora/markdownify_spec.rb +++ b/spec/lib/diaspora/markdownify_spec.rb @@ -12,7 +12,7 @@ describe Diaspora::Markdownify::HTML do link = doc.css("a") - link.attr("target").value.should == "_blank" + expect(link.attr("target").value).to eq("_blank") end end end \ No newline at end of file diff --git a/spec/lib/diaspora/mentionable_spec.rb b/spec/lib/diaspora/mentionable_spec.rb index 5d9bdcc45..d8f5235de 100644 --- a/spec/lib/diaspora/mentionable_spec.rb +++ b/spec/lib/diaspora/mentionable_spec.rb @@ -27,7 +27,7 @@ STR fmt_msg = Diaspora::Mentionable.format(@status_msg.raw_message, @people) @people.each do |person| - fmt_msg.should include person_link(person, class: 'mention hovercardable') + expect(fmt_msg).to include person_link(person, class: 'mention hovercardable') end end @@ -36,7 +36,7 @@ STR fmt_msg = Diaspora::Mentionable.format(CGI::escapeHTML(raw_msg), @people) @people.each do |person| - fmt_msg.should include person_link(person, class: 'mention hovercardable') + expect(fmt_msg).to include person_link(person, class: 'mention hovercardable') end end @@ -47,8 +47,8 @@ STR fmt_msg = Diaspora::Mentionable.format(@status_msg.raw_message, @people) - fmt_msg.should_not include(p.first_name) - fmt_msg.should include(">", "<", "'") # ">", "<", "'" + expect(fmt_msg).not_to include(p.first_name) + expect(fmt_msg).to include(">", "<", "'") # ">", "<", "'" end end @@ -57,33 +57,33 @@ STR fmt_msg = Diaspora::Mentionable.format(@status_msg.raw_message, @people, plain_text: true) @people.each do |person| - fmt_msg.should include person.first_name + expect(fmt_msg).to include person.first_name end - fmt_msg.should_not include "", "hovercardable" + expect(fmt_msg).not_to include "", "hovercardable" end end it 'leaves the name of people that cannot be found' do fmt_msg = Diaspora::Mentionable.format(@status_msg.raw_message, []) - fmt_msg.should eql @test_txt_plain + expect(fmt_msg).to eql @test_txt_plain end end describe '#people_from_string' do it 'extracts the mentioned people from the text' do ppl = Diaspora::Mentionable.people_from_string(@test_txt) - ppl.should include(*@people) + expect(ppl).to include(*@people) end describe 'returns an empty array if nobody was found' do it 'gets a post without mentions' do ppl = Diaspora::Mentionable.people_from_string("post w/o mentions") - ppl.should be_empty + expect(ppl).to be_empty end it 'gets a post with invalid handles' do ppl = Diaspora::Mentionable.people_from_string("@{a; xxx@xxx.xx} @{b; yyy@yyyy.yyy}") - ppl.should be_empty + expect(ppl).to be_empty end end end @@ -111,25 +111,25 @@ STR aspect_id = @user_A.aspects.where(name: 'generic').first.id txt = Diaspora::Mentionable.filter_for_aspects(@test_txt_C, @user_A, aspect_id) - txt.should include(@user_C.person.name) - txt.should include(local_or_remote_person_path(@user_C.person)) - txt.should_not include("href") - txt.should_not include(@mention_C) + expect(txt).to include(@user_C.person.name) + expect(txt).to include(local_or_remote_person_path(@user_C.person)) + expect(txt).not_to include("href") + expect(txt).not_to include(@mention_C) end it 'leaves mention, if contact is in a given aspect' do aspect_id = @user_A.aspects.where(name: 'generic').first.id txt = Diaspora::Mentionable.filter_for_aspects(@test_txt_B, @user_A, aspect_id) - txt.should include("user B") - txt.should include(@mention_B) + expect(txt).to include("user B") + expect(txt).to include(@mention_B) end it 'recognizes "all" as keyword for aspects' do txt = Diaspora::Mentionable.filter_for_aspects(@test_txt_BC, @user_A, "all") - txt.should include(@mention_B) - txt.should include(@mention_C) + expect(txt).to include(@mention_B) + expect(txt).to include(@mention_C) end end end diff --git a/spec/lib/diaspora/parser_spec.rb b/spec/lib/diaspora/parser_spec.rb index 4a7e6cf38..c84ef4c17 100644 --- a/spec/lib/diaspora/parser_spec.rb +++ b/spec/lib/diaspora/parser_spec.rb @@ -24,10 +24,10 @@ describe Diaspora::Parser do comment.delete xml = comment.to_diaspora_xml comment_from_xml = Diaspora::Parser.from_xml(xml) - comment_from_xml.diaspora_handle.should == @person.diaspora_handle - comment_from_xml.post.should == post - comment_from_xml.text.should == "Freedom!" - comment_from_xml.should_not be comment + expect(comment_from_xml.diaspora_handle).to eq(@person.diaspora_handle) + expect(comment_from_xml.post).to eq(post) + expect(comment_from_xml.text).to eq("Freedom!") + expect(comment_from_xml).not_to be comment end end end diff --git a/spec/lib/direction_detector_spec.rb b/spec/lib/direction_detector_spec.rb index 81c00cd2d..b19e854db 100644 --- a/spec/lib/direction_detector_spec.rb +++ b/spec/lib/direction_detector_spec.rb @@ -26,65 +26,65 @@ describe String do describe "#stats_with_rtl_char?" do it 'returns true or false correctly' do - english.starts_with_rtl_char?.should be false - chinese.starts_with_rtl_char?.should be false - arabic.starts_with_rtl_char?.should be true - hebrew.starts_with_rtl_char?.should be true - hebrew_arabic.starts_with_rtl_char?.should be true + expect(english.starts_with_rtl_char?).to be false + expect(chinese.starts_with_rtl_char?).to be false + expect(arabic.starts_with_rtl_char?).to be true + expect(hebrew.starts_with_rtl_char?).to be true + expect(hebrew_arabic.starts_with_rtl_char?).to be true end it 'only looks at the first char' do - english_chinese.starts_with_rtl_char?.should be false - chinese_english.starts_with_rtl_char?.should be false - english_arabic.starts_with_rtl_char?.should be false - hebrew_english.starts_with_rtl_char?.should be true - arabic_chinese.starts_with_rtl_char?.should be true + expect(english_chinese.starts_with_rtl_char?).to be false + expect(chinese_english.starts_with_rtl_char?).to be false + expect(english_arabic.starts_with_rtl_char?).to be false + expect(hebrew_english.starts_with_rtl_char?).to be true + expect(arabic_chinese.starts_with_rtl_char?).to be true end it 'ignores whitespaces' do - " \n \r \t".starts_with_rtl_char?.should be false - " #{arabic} ".starts_with_rtl_char?.should be true + expect(" \n \r \t".starts_with_rtl_char?).to be false + expect(" #{arabic} ".starts_with_rtl_char?).to be true end end describe "#is_rtl?" do it 'returns true or false correctly' do - english.is_rtl?.should be false - chinese.is_rtl?.should be false - arabic.is_rtl?.should be true - hebrew.is_rtl?.should be true + expect(english.is_rtl?).to be false + expect(chinese.is_rtl?).to be false + expect(arabic.is_rtl?).to be true + expect(hebrew.is_rtl?).to be true end it 'respects all words' do - chinese_arabic.is_rtl?.should be true - chinese_hebrew.is_rtl?.should be true - english_hebrew.is_rtl?.should be false - hebrew_arabic.is_rtl?.should be true - "#{english} #{arabic} #{chinese}".is_rtl?.should be false - "Translated to arabic, Hello World means: #{arabic}".is_rtl?.should be false - "#{english} #{arabic} #{arabic}".is_rtl?.should be true + expect(chinese_arabic.is_rtl?).to be true + expect(chinese_hebrew.is_rtl?).to be true + expect(english_hebrew.is_rtl?).to be false + expect(hebrew_arabic.is_rtl?).to be true + expect("#{english} #{arabic} #{chinese}".is_rtl?).to be false + expect("Translated to arabic, Hello World means: #{arabic}".is_rtl?).to be false + expect("#{english} #{arabic} #{arabic}".is_rtl?).to be true end it "fallbacks to the first word if there's no majority" do - hebrew_english.is_rtl?.should be true - english_hebrew.is_rtl?.should be false - arabic_english.is_rtl?.should be true - english_arabic.is_rtl?.should be false + expect(hebrew_english.is_rtl?).to be true + expect(english_hebrew.is_rtl?).to be false + expect(arabic_english.is_rtl?).to be true + expect(english_arabic.is_rtl?).to be false end it 'ignores whitespaces' do - " \n \r \t".is_rtl?.should be false - " #{arabic} ".is_rtl?.should be true + expect(" \n \r \t".is_rtl?).to be false + expect(" #{arabic} ".is_rtl?).to be true end end describe '#cleaned_is_rtl?' do it 'should clean the string' do - "RT: #{arabic}".cleaned_is_rtl?.should be true - "#{hebrew} RT: #{arabic}".cleaned_is_rtl?.should be true - "@foo #{arabic}".cleaned_is_rtl?.should be true - "#{hebrew} #example".cleaned_is_rtl?.should be true - "♺: #{arabic} ♻: #{hebrew}".cleaned_is_rtl?.should be true + expect("RT: #{arabic}".cleaned_is_rtl?).to be true + expect("#{hebrew} RT: #{arabic}".cleaned_is_rtl?).to be true + expect("@foo #{arabic}".cleaned_is_rtl?).to be true + expect("#{hebrew} #example".cleaned_is_rtl?).to be true + expect("♺: #{arabic} ♻: #{hebrew}".cleaned_is_rtl?).to be true end end end diff --git a/spec/lib/email_inviter_spec.rb b/spec/lib/email_inviter_spec.rb index 6220864ae..68cd1197c 100644 --- a/spec/lib/email_inviter_spec.rb +++ b/spec/lib/email_inviter_spec.rb @@ -9,53 +9,53 @@ describe EmailInviter do it 'has a list of emails' do inviter = EmailInviter.new(@emails, @user) - inviter.emails.should_not be_empty + expect(inviter.emails).not_to be_empty end it 'should parse three emails' do inviter = EmailInviter.new(@emails, @user) - inviter.emails.count.should == 3 + expect(inviter.emails.count).to eq(3) end it 'has an inviter' do inviter = EmailInviter.new(@emails, @user) - inviter.inviter.should_not be_nil + expect(inviter.inviter).not_to be_nil end it 'can have a message' do message = "you guys suck hard" inviter = EmailInviter.new("emails", @user, :message => message) - inviter.message.should == message + expect(inviter.message).to eq(message) end describe '#emails' do it 'rejects the inviter email if present' do inviter = EmailInviter.new(@emails + " #{@user.email}", @user) - inviter.emails.should_not include(@user.email) + expect(inviter.emails).not_to include(@user.email) end end describe 'language' do it 'defaults to english' do inviter = EmailInviter.new(@emails, @user) - inviter.locale.should == 'en' + expect(inviter.locale).to eq('en') end it 'should symbolize keys' do inviter = EmailInviter.new(@emails, @user, 'locale' => 'es') - inviter.locale.should == 'es' + expect(inviter.locale).to eq('es') end it 'listens to the langauge option' do inviter = EmailInviter.new(@emails, @user, :locale => 'es') - inviter.locale.should == 'es' + expect(inviter.locale).to eq('es') end end describe '#invitation_code' do it 'delegates to the user' do inviter = EmailInviter.new(@emails, @user) - inviter.invitation_code.should == @user.invitation_code + expect(inviter.invitation_code).to eq(@user.invitation_code) end end end diff --git a/spec/lib/encryptor_spec.rb b/spec/lib/encryptor_spec.rb index afc3c6005..a4d8a709a 100644 --- a/spec/lib/encryptor_spec.rb +++ b/spec/lib/encryptor_spec.rb @@ -14,8 +14,8 @@ describe 'user encryption' do it 'should encrypt a string' do string = "Secretsauce" ciphertext = @user.person.encrypt string - ciphertext.include?(string).should be false - @user.decrypt(ciphertext).should == string + expect(ciphertext.include?(string)).to be false + expect(@user.decrypt(ciphertext)).to eq(string) end end end diff --git a/spec/lib/evil_query_spec.rb b/spec/lib/evil_query_spec.rb index c77cb9163..29c69d0d2 100644 --- a/spec/lib/evil_query_spec.rb +++ b/spec/lib/evil_query_spec.rb @@ -16,12 +16,12 @@ describe EvilQuery::Participation do it "includes posts liked by the user" do alice.like!(@status_message) - EvilQuery::Participation.new(alice).posts.should include(@status_message) + expect(EvilQuery::Participation.new(alice).posts).to include(@status_message) end it "includes posts commented by the user" do alice.comment!(@status_message, "hey") - EvilQuery::Participation.new(alice).posts.should include(@status_message) + expect(EvilQuery::Participation.new(alice).posts).to include(@status_message) end it "should include your statusMessages" do @@ -55,12 +55,12 @@ describe EvilQuery::Participation do let(:posts) {EvilQuery::Participation.new(alice).posts} it "doesn't include Posts that aren't acted on" do - posts.map(&:id).should_not include(@status_messageD.id) - posts.map(&:id).should =~ [@status_messageA.id, @status_messageB.id, @status_messageE.id] + expect(posts.map(&:id)).not_to include(@status_messageD.id) + expect(posts.map(&:id)).to match_array([@status_messageA.id, @status_messageB.id, @status_messageE.id]) end it "returns the posts that the user has commented on or liked with the most recently acted on ones first" do - posts.map(&:id).should == [@status_messageE.id, @status_messageA.id, @status_messageB.id] + expect(posts.map(&:id)).to eq([@status_messageE.id, @status_messageA.id, @status_messageB.id]) end end end diff --git a/spec/lib/hcard_spec.rb b/spec/lib/hcard_spec.rb index 4a898d9fb..86cab268b 100644 --- a/spec/lib/hcard_spec.rb +++ b/spec/lib/hcard_spec.rb @@ -8,12 +8,12 @@ describe HCard do it 'should parse an hcard' do raw_hcard = hcard_response hcard = HCard.build raw_hcard - hcard[:family_name].include?("Hamiltom").should be true - hcard[:given_name].include?("Alex").should be true - hcard[:photo].include?("thumb_large").should be true - hcard[:photo_medium].include?("thumb_medium").should be true - hcard[:photo_small].include?("thumb_small").should be true - hcard[:url].should == "http://localhost:3000/" - hcard[:searchable].should == "false" + expect(hcard[:family_name].include?("Hamiltom")).to be true + expect(hcard[:given_name].include?("Alex")).to be true + expect(hcard[:photo].include?("thumb_large")).to be true + expect(hcard[:photo_medium].include?("thumb_medium")).to be true + expect(hcard[:photo_small].include?("thumb_small")).to be true + expect(hcard[:url]).to eq("http://localhost:3000/") + expect(hcard[:searchable]).to eq("false") end end diff --git a/spec/lib/hydra_wrapper_spec.rb b/spec/lib/hydra_wrapper_spec.rb index de9f722fc..5a303052e 100644 --- a/spec/lib/hydra_wrapper_spec.rb +++ b/spec/lib/hydra_wrapper_spec.rb @@ -17,9 +17,9 @@ describe HydraWrapper do dispatcher_class = "Postzord::Dispatcher::Private" wrapper = HydraWrapper.new user, @people, encoded_object_xml, dispatcher_class - wrapper.user.should == user - wrapper.people.should == @people - wrapper.encoded_object_xml.should == encoded_object_xml + expect(wrapper.user).to eq(user) + expect(wrapper.people).to eq(@people) + expect(wrapper.encoded_object_xml).to eq(encoded_object_xml) end end @@ -27,16 +27,16 @@ describe HydraWrapper do it 'delegates #run to the @hydra' do hydra = double.as_null_object @wrapper.instance_variable_set :@hydra, hydra - hydra.should_receive :run + expect(hydra).to receive :run @wrapper.run end end describe '#xml_factory' do it 'calls the salmon method on the dispatcher class (and memoizes)' do - Base64.stub(:decode64).and_return "#{@wrapper.encoded_object_xml} encoded" + allow(Base64).to receive(:decode64).and_return "#{@wrapper.encoded_object_xml} encoded" decoded = Base64.decode64 @wrapper.encoded_object_xml - @wrapper.dispatcher_class.should_receive(:salmon).with(@wrapper.user, decoded).once.and_return true + expect(@wrapper.dispatcher_class).to receive(:salmon).with(@wrapper.user, decoded).once.and_return true @wrapper.send :xml_factory @wrapper.send :xml_factory end @@ -44,32 +44,32 @@ describe HydraWrapper do describe '#grouped_people' do it 'groups people given their receive_urls' do - @wrapper.dispatcher_class.should_receive(:receive_url_for).and_return "foo.com", "bar.com", "bar.com" + expect(@wrapper.dispatcher_class).to receive(:receive_url_for).and_return "foo.com", "bar.com", "bar.com" - @wrapper.send(:grouped_people).should == {"foo.com" => [@people[0]], "bar.com" => @people[1,2]} + expect(@wrapper.send(:grouped_people)).to eq({"foo.com" => [@people[0]], "bar.com" => @people[1,2]}) end end describe '#enqueue_batch' do it 'calls #grouped_people' do - @wrapper.should_receive(:grouped_people).and_return [] + expect(@wrapper).to receive(:grouped_people).and_return [] @wrapper.enqueue_batch end it 'inserts a job for every group of people' do - Base64.stub(:decode64) + allow(Base64).to receive(:decode64) @wrapper.dispatcher_class = double salmon: double(xml_for: "") - @wrapper.stub(:grouped_people).and_return('https://foo.com' => @wrapper.people) - @wrapper.people.should_receive(:first).once - @wrapper.should_receive(:insert_job).with('https://foo.com', "", @wrapper.people).once + allow(@wrapper).to receive(:grouped_people).and_return('https://foo.com' => @wrapper.people) + expect(@wrapper.people).to receive(:first).once + expect(@wrapper).to receive(:insert_job).with('https://foo.com', "", @wrapper.people).once @wrapper.enqueue_batch end it 'does not insert a job for a person whos xml returns false' do - Base64.stub(:decode64) - @wrapper.stub(:grouped_people).and_return('https://foo.com' => [double]) + allow(Base64).to receive(:decode64) + allow(@wrapper).to receive(:grouped_people).and_return('https://foo.com' => [double]) @wrapper.dispatcher_class = double salmon: double(xml_for: false) - @wrapper.should_not_receive :insert_job + expect(@wrapper).not_to receive :insert_job @wrapper.enqueue_batch end @@ -78,7 +78,7 @@ describe HydraWrapper do describe '#redirecting_to_https?!' do it 'does not execute unless response has a 3xx code' do resp = double code: 200 - @wrapper.send(:redirecting_to_https?, resp).should be false + expect(@wrapper.send(:redirecting_to_https?, resp)).to be false end it "returns true if just the protocol is different" do @@ -91,7 +91,7 @@ describe HydraWrapper do } ) - @wrapper.send(:redirecting_to_https?, resp).should be true + expect(@wrapper.send(:redirecting_to_https?, resp)).to be true end it "returns false if not just the protocol is different" do @@ -104,7 +104,7 @@ describe HydraWrapper do } ) - @wrapper.send(:redirecting_to_https?, resp).should be false + expect(@wrapper.send(:redirecting_to_https?, resp)).to be false end end end diff --git a/spec/lib/i18n_interpolation_fallbacks_spec.rb b/spec/lib/i18n_interpolation_fallbacks_spec.rb index 56a05e1c3..d8569b05a 100644 --- a/spec/lib/i18n_interpolation_fallbacks_spec.rb +++ b/spec/lib/i18n_interpolation_fallbacks_spec.rb @@ -7,20 +7,20 @@ require 'spec_helper' describe "i18n interpolation fallbacks" do describe "when string does not require interpolation arguments" do it "works normally" do - I18n.t('user.invalid', + expect(I18n.t('user.invalid', :resource_name => "user", :scope => "devise.failure", - :default => [:invalid, "invalid"]).should == "Invalid username or password." + :default => [:invalid, "invalid"])).to eq("Invalid username or password.") end end describe "when string requires interpolation arguments" do context "current locale has no fallbacks" do # ago: "%{time} ago" (in en.yml) it "returns the translation when all arguments are provided" do - I18n.t('ago', :time => "2 months").should == "2 months ago" + expect(I18n.t('ago', :time => "2 months")).to eq("2 months ago") end it "returns the translation without substitution when all arguments are omitted" do - I18n.t('ago').should == "%{time} ago" + expect(I18n.t('ago')).to eq("%{time} ago") end it "raises a MissingInterpolationArgument when arguments are wrong" do expect { I18n.t('ago', :not_time => "2 months") }.to raise_exception(I18n::MissingInterpolationArgument) @@ -37,19 +37,19 @@ describe "i18n interpolation fallbacks" do end describe "when all arguments are provided" do it "returns the locale's translation" do - I18n.t('nonexistant_key', :random_key => "Hi Alex,").should == "Hi Alex, here is some Italian" + expect(I18n.t('nonexistant_key', :random_key => "Hi Alex,")).to eq("Hi Alex, here is some Italian") end end describe "when no arguments are provided" do it "returns the locale's translation without substitution" do - I18n.t('nonexistant_key').should == "%{random_key} here is some Italian" + expect(I18n.t('nonexistant_key')).to eq("%{random_key} here is some Italian") end end describe "when arguments are wrong" do describe "when the English translation works" do it "falls back to English" do I18n.backend.store_translations('en', {"nonexistant_key" => "Working English translation"}) - I18n.t('nonexistant_key', :hey => "what").should == "Working English translation" + expect(I18n.t('nonexistant_key', :hey => "what")).to eq("Working English translation") end end describe "when the English translation does not work" do diff --git a/spec/lib/postzord/dispatcher_spec.rb b/spec/lib/postzord/dispatcher_spec.rb index b3605837e..d54d7bb81 100644 --- a/spec/lib/postzord/dispatcher_spec.rb +++ b/spec/lib/postzord/dispatcher_spec.rb @@ -9,31 +9,31 @@ describe Postzord::Dispatcher do @sm = FactoryGirl.create(:status_message, :public => true, :author => alice.person) @subscribers = [] 5.times{@subscribers << FactoryGirl.create(:person)} - @sm.stub(:subscribers).and_return(@subscribers) + allow(@sm).to receive(:subscribers).and_return(@subscribers) @xml = @sm.to_diaspora_xml end describe '.initialize' do it 'sets @sender, @object, @xml' do zord = Postzord::Dispatcher.build(alice, @sm) - zord.sender.should == alice - zord.object.should == @sm - zord.xml.should == @sm.to_diaspora_xml + expect(zord.sender).to eq(alice) + expect(zord.object).to eq(@sm) + expect(zord.xml).to eq(@sm.to_diaspora_xml) end context 'setting @subscribers' do it 'sets @subscribers from object' do - @sm.should_receive(:subscribers).and_return(@subscribers) + expect(@sm).to receive(:subscribers).and_return(@subscribers) zord = Postzord::Dispatcher.build(alice, @sm) - zord.subscribers.should == @subscribers + expect(zord.subscribers).to eq(@subscribers) end it 'accepts additional subscribers from opts' do new_person = FactoryGirl.create(:person) - @sm.should_receive(:subscribers).and_return(@subscribers) + expect(@sm).to receive(:subscribers).and_return(@subscribers) zord = Postzord::Dispatcher.build(alice, @sm, :additional_subscribers => new_person) - zord.subscribers.should == @subscribers | [new_person] + expect(zord.subscribers).to eq(@subscribers | [new_person]) end end @@ -55,17 +55,17 @@ describe Postzord::Dispatcher do describe '#post' do it 'calls Array#partition on subscribers' do @zord.instance_variable_set(:@subscribers, @subscribers) - @subscribers.should_receive(:partition).and_return([@remote_people, @local_people]) + expect(@subscribers).to receive(:partition).and_return([@remote_people, @local_people]) @zord.post end it 'calls #deliver_to_local with local people' do - @zord.should_receive(:deliver_to_local).with(@local_people) + expect(@zord).to receive(:deliver_to_local).with(@local_people) @zord.post end it 'calls #deliver_to_remote with remote people' do - @zord.should_receive(:deliver_to_remote).with(@remote_people) + expect(@zord).to receive(:deliver_to_remote).with(@remote_people) @zord.post end end @@ -90,17 +90,17 @@ describe Postzord::Dispatcher do end it 'calls deliver_to_local with local_luke' do - @mailman.should_receive(:deliver_to_local).with([@local_luke.person]) + expect(@mailman).to receive(:deliver_to_local).with([@local_luke.person]) @mailman.post end it 'calls deliver_to_remote with nobody' do - @mailman.should_receive(:deliver_to_remote).with([]) + expect(@mailman).to receive(:deliver_to_remote).with([]) @mailman.post end it 'does not call notify_users' do - @mailman.should_not_receive(:notify_users) + expect(@mailman).not_to receive(:notify_users) @mailman.post end end @@ -110,17 +110,17 @@ describe Postzord::Dispatcher do end it 'does not call deliver_to_local' do - @mailman.should_not_receive(:deliver_to_local) + expect(@mailman).not_to receive(:deliver_to_local) @mailman.post end it 'calls deliver_to_remote with remote raphael' do - @mailman.should_receive(:deliver_to_remote).with([@remote_raphael]) + expect(@mailman).to receive(:deliver_to_remote).with([@remote_raphael]) @mailman.post end it 'calls notify_users' do - @mailman.should_receive(:notify_users).with([@local_leia]) + expect(@mailman).to receive(:notify_users).with([@local_leia]) @mailman.post end end @@ -134,17 +134,17 @@ describe Postzord::Dispatcher do end it 'does not call deliver_to_local' do - @mailman.should_not_receive(:deliver_to_local) + expect(@mailman).not_to receive(:deliver_to_local) @mailman.post end it 'calls deliver_to_remote with remote_raphael' do - @mailman.should_receive(:deliver_to_remote).with([@remote_raphael]) + expect(@mailman).to receive(:deliver_to_remote).with([@remote_raphael]) @mailman.post end it 'calls notify_users' do - @mailman.should_receive(:notify_users).with([@local_leia]) + expect(@mailman).to receive(:notify_users).with([@local_leia]) @mailman.post end end @@ -157,17 +157,17 @@ describe Postzord::Dispatcher do end it 'does not call deliver_to_local' do - @mailman.should_not_receive(:deliver_to_local) + expect(@mailman).not_to receive(:deliver_to_local) @mailman.post end it 'calls deliver_to_remote with remote_raphael' do - @mailman.should_receive(:deliver_to_remote).with([@remote_raphael]) + expect(@mailman).to receive(:deliver_to_remote).with([@remote_raphael]) @mailman.post end it 'calls notify_users' do - @mailman.should_receive(:notify_users).with([@local_leia]) + expect(@mailman).to receive(:notify_users).with([@local_leia]) @mailman.post end end @@ -182,17 +182,17 @@ describe Postzord::Dispatcher do end it 'calls deliver_to_remote with remote_raphael' do - @mailman.should_receive(:deliver_to_remote).with([@remote_raphael]) + expect(@mailman).to receive(:deliver_to_remote).with([@remote_raphael]) @mailman.post end it 'calls deliver_to_local with nobody' do - @mailman.should_receive(:deliver_to_local).with([]) + expect(@mailman).to receive(:deliver_to_local).with([]) @mailman.post end it 'does not call notify_users' do - @mailman.should_not_receive(:notify_users) + expect(@mailman).not_to receive(:notify_users) @mailman.post end end @@ -204,15 +204,15 @@ describe Postzord::Dispatcher do @remote_people << alice.person @mailman = Postzord::Dispatcher.build(alice, @sm) @hydra = double() - Typhoeus::Hydra.stub(:new).and_return(@hydra) + allow(Typhoeus::Hydra).to receive(:new).and_return(@hydra) end it 'should queue an HttpMultiJob for the remote people' do - Postzord::Dispatcher::Public.any_instance.unstub(:deliver_to_remote) - Workers::HttpMulti.should_receive(:perform_async).with(alice.id, anything, @remote_people.map{|p| p.id}, anything).once + allow_any_instance_of(Postzord::Dispatcher::Public).to receive(:deliver_to_remote).and_call_original + expect(Workers::HttpMulti).to receive(:perform_async).with(alice.id, anything, @remote_people.map{|p| p.id}, anything).once @mailman.send(:deliver_to_remote, @remote_people) - Postzord::Dispatcher::Public.stub(:deliver_to_remote) + allow(Postzord::Dispatcher::Public).to receive(:deliver_to_remote) end end @@ -224,18 +224,18 @@ describe Postzord::Dispatcher do it 'queues a batch receive' do local_people = [] local_people << alice.person - Workers::ReceiveLocalBatch.should_receive(:perform_async).with(@sm.class.to_s, @sm.id, [alice.id]).once + expect(Workers::ReceiveLocalBatch).to receive(:perform_async).with(@sm.class.to_s, @sm.id, [alice.id]).once @mailman.send(:deliver_to_local, local_people) end it 'returns if people are empty' do - Workers::ReceiveLocalBatch.should_not_receive(:perform_async) + expect(Workers::ReceiveLocalBatch).not_to receive(:perform_async) @mailman.send(:deliver_to_local, []) end it 'returns if the object is a profile' do @mailman.instance_variable_set(:@object, Profile.new) - Workers::ReceiveLocalBatch.should_not_receive(:perform_async) + expect(Workers::ReceiveLocalBatch).not_to receive(:perform_async) @mailman.send(:deliver_to_local, [1]) end end @@ -243,28 +243,28 @@ describe Postzord::Dispatcher do describe '#object_should_be_processed_as_public?' do it 'returns true with a comment on a public post' do f = FactoryGirl.create(:comment, :post => FactoryGirl.build(:status_message, :public => true)) - Postzord::Dispatcher.object_should_be_processed_as_public?(f).should be true + expect(Postzord::Dispatcher.object_should_be_processed_as_public?(f)).to be true end it 'returns false with a comment on a private post' do f = FactoryGirl.create(:comment, :post => FactoryGirl.build(:status_message, :public => false)) - Postzord::Dispatcher.object_should_be_processed_as_public?(f).should be false + expect(Postzord::Dispatcher.object_should_be_processed_as_public?(f)).to be false end it 'returns true with a like on a comment on a public post' do f = FactoryGirl.create(:like, :target => FactoryGirl.build(:comment, :post => FactoryGirl.build(:status_message, :public => true))) - Postzord::Dispatcher.object_should_be_processed_as_public?(f).should be true + expect(Postzord::Dispatcher.object_should_be_processed_as_public?(f)).to be true end it 'returns false with a like on a comment on a private post' do f = FactoryGirl.create(:like, :target => FactoryGirl.build(:comment, :post => FactoryGirl.build(:status_message, :public => false))) - Postzord::Dispatcher.object_should_be_processed_as_public?(f).should be false + expect(Postzord::Dispatcher.object_should_be_processed_as_public?(f)).to be false end it 'returns false for a relayable_retraction' do f = RelayableRetraction.new f.target = FactoryGirl.create(:status_message, :public => true) - Postzord::Dispatcher.object_should_be_processed_as_public?(f).should be false + expect(Postzord::Dispatcher.object_should_be_processed_as_public?(f)).to be false end end @@ -277,8 +277,8 @@ describe Postzord::Dispatcher do end it 'queues a job to notify the hub' do - Workers::PostToService.stub(:perform_async).with(anything, anything, anything) - Workers::PublishToHub.should_receive(:perform_async).with(alice.public_url) + allow(Workers::PostToService).to receive(:perform_async).with(anything, anything, anything) + expect(Workers::PublishToHub).to receive(:perform_async).with(alice.public_url) @zord.send(:deliver_to_services, nil, []) end @@ -286,7 +286,7 @@ describe Postzord::Dispatcher do @sm = FactoryGirl.create(:status_message) mailman = Postzord::Dispatcher.build(alice, @sm, :url => "http://joindiaspora.com/p/123") - mailman.should_not_receive(:deliver_to_hub) + expect(mailman).not_to receive(:deliver_to_hub) mailman.post end @@ -297,17 +297,17 @@ describe Postzord::Dispatcher do alice.services << @s2 mailman = Postzord::Dispatcher.build(alice, FactoryGirl.create(:status_message), :url => "http://joindiaspora.com/p/123", :services => [@s1]) - Workers::PublishToHub.stub(:perform_async).with(anything) - Workers::HttpMulti.stub(:perform_async).with(anything, anything, anything) - Workers::PostToService.should_receive(:perform_async).with(@s1.id, anything, anything) + allow(Workers::PublishToHub).to receive(:perform_async).with(anything) + allow(Workers::HttpMulti).to receive(:perform_async).with(anything, anything, anything) + expect(Workers::PostToService).to receive(:perform_async).with(@s1.id, anything, anything) mailman.post end it 'does not push to services if none are specified' do mailman = Postzord::Dispatcher.build(alice, FactoryGirl.create(:status_message), :url => "http://joindiaspora.com/p/123") - Workers::PublishToHub.stub(:perform_async).with(anything) - Workers::PostToService.should_not_receive(:perform_async).with(anything, anything, anything) + allow(Workers::PublishToHub).to receive(:perform_async).with(anything) + expect(Workers::PostToService).not_to receive(:perform_async).with(anything, anything, anything) mailman.post end @@ -315,7 +315,7 @@ describe Postzord::Dispatcher do retraction = SignedRetraction.build(alice, FactoryGirl.create(:status_message)) mailman = Postzord::Dispatcher.build(alice, retraction, :url => "http://joindiaspora.com/p/123", :services => [@service]) - Workers::DeletePostFromService.should_receive(:perform_async).with(anything, anything) + expect(Workers::DeletePostFromService).to receive(:perform_async).with(anything, anything) mailman.post end @@ -323,14 +323,14 @@ describe Postzord::Dispatcher do describe '#and_notify_local_users' do it 'calls notifiy_users' do - @zord.should_receive(:notify_users).with([bob]) + expect(@zord).to receive(:notify_users).with([bob]) @zord.send(:notify_local_users, [bob.person]) end end describe '#notify_users' do it 'enqueues a NotifyLocalUsers job' do - Workers::NotifyLocalUsers.should_receive(:perform_async).with([bob.id], @zord.object.class.to_s, @zord.object.id, @zord.object.author.id) + expect(Workers::NotifyLocalUsers).to receive(:perform_async).with([bob.id], @zord.object.class.to_s, @zord.object.id, @zord.object.author.id) @zord.send(:notify_users, [bob]) end end diff --git a/spec/lib/postzord/receiver/local_batch_spec.rb b/spec/lib/postzord/receiver/local_batch_spec.rb index ad1ef7115..1a6c8e2fe 100644 --- a/spec/lib/postzord/receiver/local_batch_spec.rb +++ b/spec/lib/postzord/receiver/local_batch_spec.rb @@ -11,31 +11,31 @@ describe Postzord::Receiver::LocalBatch do describe '.initialize' do it 'sets @post, @recipient_user_ids, and @user' do [:object, :recipient_user_ids, :users].each do |instance_var| - receiver.send(instance_var).should_not be_nil + expect(receiver.send(instance_var)).not_to be_nil end end end describe '#receive!' do it 'calls .create_share_visibilities' do - receiver.should_receive(:create_share_visibilities) + expect(receiver).to receive(:create_share_visibilities) receiver.receive! end it 'notifies mentioned users' do - receiver.should_receive(:notify_mentioned_users) + expect(receiver).to receive(:notify_mentioned_users) receiver.receive! end it 'notifies users' do - receiver.should_receive(:notify_users) + expect(receiver).to receive(:notify_users) receiver.receive! end end describe '#create_share_visibilities' do it 'calls sharevisibility.batch_import with hashes' do - ShareVisibility.should_receive(:batch_import).with(instance_of(Array), @object) + expect(ShareVisibility).to receive(:batch_import).with(instance_of(Array), @object) receiver.create_share_visibilities end end @@ -47,12 +47,12 @@ describe Postzord::Receiver::LocalBatch do :text => "Hey @{Bob; #{bob.diaspora_handle}}") receiver2 = Postzord::Receiver::LocalBatch.new(sm, @ids) - Notification.should_receive(:notify).with(bob, anything, alice.person) + expect(Notification).to receive(:notify).with(bob, anything, alice.person) receiver2.notify_mentioned_users end it 'does not call notify person for a non-mentioned person' do - Notification.should_not_receive(:notify) + expect(Notification).not_to receive(:notify) receiver.notify_mentioned_users end end @@ -60,7 +60,7 @@ describe Postzord::Receiver::LocalBatch do describe '#notify_users' do it 'calls notify for posts with notification type' do reshare = FactoryGirl.create(:reshare) - Notification.should_receive(:notify) + expect(Notification).to receive(:notify) receiver = Postzord::Receiver::LocalBatch.new(reshare, @ids) receiver.notify_users end @@ -68,7 +68,7 @@ describe Postzord::Receiver::LocalBatch do it 'calls notify for posts with notification type' do sm = FactoryGirl.create(:status_message, :author => alice.person) receiver = Postzord::Receiver::LocalBatch.new(sm, @ids) - Notification.should_not_receive(:notify) + expect(Notification).not_to receive(:notify) receiver.notify_users end end @@ -80,13 +80,13 @@ describe Postzord::Receiver::LocalBatch do end it 'calls notify_users' do - receiver.should_receive(:notify_users) + expect(receiver).to receive(:notify_users) receiver.perform! end it 'does not call create_visibilities and notify_mentioned_users' do - receiver.should_not_receive(:notify_mentioned_users) - receiver.should_not_receive(:create_share_visibilities) + expect(receiver).not_to receive(:notify_mentioned_users) + expect(receiver).not_to receive(:create_share_visibilities) receiver.perform! end end diff --git a/spec/lib/postzord/receiver/private_spec.rb b/spec/lib/postzord/receiver/private_spec.rb index 352c91d40..645cc7d00 100644 --- a/spec/lib/postzord/receiver/private_spec.rb +++ b/spec/lib/postzord/receiver/private_spec.rb @@ -13,27 +13,27 @@ describe Postzord::Receiver::Private do describe '.initialize' do it 'valid for local' do - Webfinger.should_not_receive(:new) - Salmon::EncryptedSlap.should_not_receive(:from_xml) + expect(Webfinger).not_to receive(:new) + expect(Salmon::EncryptedSlap).not_to receive(:from_xml) zord = Postzord::Receiver::Private.new(bob, :person => alice.person, :object => @alices_post) - zord.instance_variable_get(:@user).should_not be_nil - zord.instance_variable_get(:@sender).should_not be_nil - zord.instance_variable_get(:@object).should_not be_nil + expect(zord.instance_variable_get(:@user)).not_to be_nil + expect(zord.instance_variable_get(:@sender)).not_to be_nil + expect(zord.instance_variable_get(:@object)).not_to be_nil end it 'valid for remote' do salmon_double = double() web_double = double() - web_double.should_receive(:fetch).and_return true - salmon_double.should_receive(:author_id).and_return(true) - Salmon::EncryptedSlap.should_receive(:from_xml).with(@salmon_xml, bob).and_return(salmon_double) - Webfinger.should_receive(:new).and_return(web_double) + expect(web_double).to receive(:fetch).and_return true + expect(salmon_double).to receive(:author_id).and_return(true) + expect(Salmon::EncryptedSlap).to receive(:from_xml).with(@salmon_xml, bob).and_return(salmon_double) + expect(Webfinger).to receive(:new).and_return(web_double) zord = Postzord::Receiver::Private.new(bob, :salmon_xml => @salmon_xml) - zord.instance_variable_get(:@user).should_not be_nil - zord.instance_variable_get(:@sender).should_not be_nil - zord.instance_variable_get(:@salmon_xml).should_not be_nil + expect(zord.instance_variable_get(:@user)).not_to be_nil + expect(zord.instance_variable_get(:@sender)).not_to be_nil + expect(zord.instance_variable_get(:@salmon_xml)).not_to be_nil end end @@ -46,24 +46,24 @@ describe Postzord::Receiver::Private do context 'returns false' do it 'if the salmon author does not exist' do @zord.instance_variable_set(:@sender, nil) - @zord.receive!.should == false + expect(@zord.receive!).to eq(false) end it 'if the author does not match the signature' do @zord.instance_variable_set(:@sender, FactoryGirl.create(:person)) - @zord.receive!.should == false + expect(@zord.receive!).to eq(false) end end context 'returns the sent object' do it 'returns the received object on success' do @zord.receive! - @zord.instance_variable_get(:@object).should respond_to(:to_diaspora_xml) + expect(@zord.instance_variable_get(:@object)).to respond_to(:to_diaspora_xml) end end it 'parses the salmon object' do - Diaspora::Parser.should_receive(:from_xml).with(@salmon.parsed_data).and_return(@alices_post) + expect(Diaspora::Parser).to receive(:from_xml).with(@salmon.parsed_data).and_return(@alices_post) @zord.receive! end end @@ -76,20 +76,20 @@ describe Postzord::Receiver::Private do it 'calls Notification.notify if object responds to notification_type' do cm = Comment.new - cm.stub(:receive).and_return(cm) + allow(cm).to receive(:receive).and_return(cm) - Notification.should_receive(:notify).with(bob, cm, alice.person) + expect(Notification).to receive(:notify).with(bob, cm, alice.person) zord = Postzord::Receiver::Private.new(bob, :person => alice.person, :object => cm) zord.receive_object end it 'does not call Notification.notify if object does not respond to notification_type' do - Notification.should_not_receive(:notify) + expect(Notification).not_to receive(:notify) @zord.receive_object end it 'calls receive on @object' do - obj = @zord.instance_variable_get(:@object).should_receive(:receive) + obj = expect(@zord.instance_variable_get(:@object)).to receive(:receive) @zord.receive_object end end diff --git a/spec/lib/postzord/receiver/public_spec.rb b/spec/lib/postzord/receiver/public_spec.rb index 45e44ba86..4507af473 100644 --- a/spec/lib/postzord/receiver/public_spec.rb +++ b/spec/lib/postzord/receiver/public_spec.rb @@ -31,7 +31,7 @@ describe Postzord::Receiver::Public do describe '#initialize' do it 'creates a Salmon instance variable' do receiver = Postzord::Receiver::Public.new(@xml) - receiver.salmon.should_not be_nil + expect(receiver.salmon).not_to be_nil end end @@ -41,28 +41,28 @@ describe Postzord::Receiver::Public do end it 'calls verify_signature' do - @receiver.should_receive(:verified_signature?) + expect(@receiver).to receive(:verified_signature?) @receiver.perform! end it 'returns false if signature is not verified' do - @receiver.should_receive(:verified_signature?).and_return(false) - @receiver.perform!.should be false + expect(@receiver).to receive(:verified_signature?).and_return(false) + expect(@receiver.perform!).to be false end context 'if signature is valid' do it 'calls recipient_user_ids' do - @receiver.should_receive(:recipient_user_ids) + expect(@receiver).to receive(:recipient_user_ids) @receiver.perform! end it 'saves the parsed object' do - @receiver.should_receive(:save_object) + expect(@receiver).to receive(:save_object) @receiver.perform! end - it 'enqueues a Workers::ReceiveLocalBatch' do - Workers::ReceiveLocalBatch.should_receive(:perform_async).with(anything, anything, anything) + it 'enqueues a Workers::ReceiveLocalBatch' do + expect(Workers::ReceiveLocalBatch).to receive(:perform_async).with(anything, anything, anything) @receiver.perform! end @@ -77,14 +77,14 @@ describe Postzord::Receiver::Public do describe '#verify_signature?' do it 'calls Slap#verified_for_key?' do receiver = Postzord::Receiver::Public.new(@xml) - receiver.salmon.should_receive(:verified_for_key?).with(instance_of(OpenSSL::PKey::RSA)) + expect(receiver.salmon).to receive(:verified_for_key?).with(instance_of(OpenSSL::PKey::RSA)) receiver.verified_signature? end end describe '#recipient_user_ids' do it 'calls User.all_sharing_with_person' do - User.should_receive(:all_sharing_with_person).and_return(double(:pluck => [])) + expect(User).to receive(:all_sharing_with_person).and_return(double(:pluck => [])) receiver = Postzord::Receiver::Public.new(@xml) receiver.perform! end @@ -104,7 +104,7 @@ describe Postzord::Receiver::Public do comment = double.as_null_object @receiver.instance_variable_set(:@object, comment) - comment.should_receive(:receive) + expect(comment).to receive(:receive) @receiver.receive_relayable end @@ -113,8 +113,8 @@ describe Postzord::Receiver::Public do @receiver.instance_variable_set(:@object, comment) local_batch_receiver = double.as_null_object - Postzord::Receiver::LocalBatch.stub(:new).and_return(local_batch_receiver) - local_batch_receiver.should_receive(:notify_users) + allow(Postzord::Receiver::LocalBatch).to receive(:new).and_return(local_batch_receiver) + expect(local_batch_receiver).to receive(:notify_users) @receiver.receive_relayable end end diff --git a/spec/lib/postzord/receiver_spec.rb b/spec/lib/postzord/receiver_spec.rb index 5ac6dbf9a..a7dca6b1d 100644 --- a/spec/lib/postzord/receiver_spec.rb +++ b/spec/lib/postzord/receiver_spec.rb @@ -11,11 +11,11 @@ describe Postzord::Receiver do describe "#perform!" do before do - @receiver.stub(:receive!).and_return(true) + allow(@receiver).to receive(:receive!).and_return(true) end it 'calls receive!' do - @receiver.should_receive(:receive!) + expect(@receiver).to receive(:receive!) @receiver.perform! end end diff --git a/spec/lib/publisher_spec.rb b/spec/lib/publisher_spec.rb index b83554ebf..7bb7a7c5d 100644 --- a/spec/lib/publisher_spec.rb +++ b/spec/lib/publisher_spec.rb @@ -8,29 +8,29 @@ describe Publisher do describe "#prefill" do it 'defaults to nothing' do - @publisher.prefill.should be_blank + expect(@publisher.prefill).to be_blank end it 'is settable' do - Publisher.new(alice, :prefill => "party!").prefill.should == "party!" + expect(Publisher.new(alice, :prefill => "party!").prefill).to eq("party!") end end describe '#text' do it 'is a formatted version of the prefill' do p = Publisher.new(alice, :prefill => "@{alice; alice@pod.com}") - p.text.should == "alice" + expect(p.text).to eq("alice") end end ["open", "public", "explain"].each do |property| describe "##{property}?" do it 'defaults to closed' do - @publisher.send("#{property}?".to_sym).should be_falsey + expect(@publisher.send("#{property}?".to_sym)).to be_falsey end it 'listens to the opts' do - Publisher.new(alice, {property.to_sym => true}).send("#{property}?".to_sym).should be true + expect(Publisher.new(alice, {property.to_sym => true}).send("#{property}?".to_sym)).to be true end end end diff --git a/spec/lib/pubsubhubbub_spec.rb b/spec/lib/pubsubhubbub_spec.rb index c486f0377..896e08279 100644 --- a/spec/lib/pubsubhubbub_spec.rb +++ b/spec/lib/pubsubhubbub_spec.rb @@ -12,7 +12,7 @@ describe Pubsubhubbub do body = {'hub.url' => feed, 'hub.mode' => 'publish'} stub_request(:post, "http://hubzord.com/").to_return(:status => [202, 'you are awesome']) - Pubsubhubbub.new(hub).publish(feed).should be_success + expect(Pubsubhubbub.new(hub).publish(feed)).to be_success end end end diff --git a/spec/lib/rack/chrome_frame_spec.rb b/spec/lib/rack/chrome_frame_spec.rb index 965a56431..e3ae4a714 100644 --- a/spec/lib/rack/chrome_frame_spec.rb +++ b/spec/lib/rack/chrome_frame_spec.rb @@ -19,8 +19,8 @@ describe Rack::ChromeFrame do let(:ua_string) { "another browser chromeframe" } it "shouldn't complain about the browser" do - subject.body.should_not =~ /chrome=1/ - subject.body.should_not =~ /Diaspora doesn't support your version of Internet Explorer/ + expect(subject.body).not_to match(/chrome=1/) + expect(subject.body).not_to match(/Diaspora doesn't support your version of Internet Explorer/) end end @@ -28,8 +28,8 @@ describe Rack::ChromeFrame do let(:ua_string) { "MSIE 8" } it "shouldn't complain about the browser" do - subject.body.should_not =~ /chrome=1/ - subject.body.should_not =~ /Diaspora doesn't support your version of Internet Explorer/ + expect(subject.body).not_to match(/chrome=1/) + expect(subject.body).not_to match(/Diaspora doesn't support your version of Internet Explorer/) end end @@ -37,19 +37,19 @@ describe Rack::ChromeFrame do let(:ua_string) { "MSIE 7" } it "shouldn't complain about the browser" do - subject.body.should_not =~ /chrome=1/ - subject.body.should =~ /Diaspora doesn't support your version of Internet Explorer/ + expect(subject.body).not_to match(/chrome=1/) + expect(subject.body).to match(/Diaspora doesn't support your version of Internet Explorer/) end - specify {@response.headers["Content-Length"].should == @response.body.length.to_s} + specify {expect(@response.headers["Content-Length"]).to eq(@response.body.length.to_s)} end context "any IE with chromeframe" do let(:ua_string) { "MSIE number chromeframe" } it "shouldn't complain about the browser" do - subject.body.should =~ /chrome=1/ - subject.body.should_not =~ /Diaspora doesn't support your version of Internet Explorer/ + expect(subject.body).to match(/chrome=1/) + expect(subject.body).not_to match(/Diaspora doesn't support your version of Internet Explorer/) end - specify {@response.headers["Content-Length"].should == @response.body.length.to_s} + specify {expect(@response.headers["Content-Length"]).to eq(@response.body.length.to_s)} end end diff --git a/spec/lib/rake_helper_spec.rb b/spec/lib/rake_helper_spec.rb index 1f8001fbd..1bc16079a 100644 --- a/spec/lib/rake_helper_spec.rb +++ b/spec/lib/rake_helper_spec.rb @@ -23,7 +23,7 @@ describe RakeHelpers do it 'should send emails to each email' do - EmailInviter.should_receive(:new).exactly(3).times.and_return(double.as_null_object) + expect(EmailInviter).to receive(:new).exactly(3).times.and_return(double.as_null_object) process_emails(@csv, 100, 1, false) end end diff --git a/spec/lib/salmon/encrypted_slap_spec.rb b/spec/lib/salmon/encrypted_slap_spec.rb index 90ed786a7..ba297edcf 100644 --- a/spec/lib/salmon/encrypted_slap_spec.rb +++ b/spec/lib/salmon/encrypted_slap_spec.rb @@ -14,12 +14,12 @@ describe Salmon::EncryptedSlap do it 'makes the data in the signature encrypted with that key' do key_hash = {'key' => @created_salmon.aes_key, 'iv' => @created_salmon.iv} decoded_string = Salmon::EncryptedSlap.decode64url(@created_salmon.magic_sig.data) - alice.aes_decrypt(decoded_string, key_hash).should == @post.to_diaspora_xml + expect(alice.aes_decrypt(decoded_string, key_hash)).to eq(@post.to_diaspora_xml) end it 'sets aes and iv key' do - @created_salmon.aes_key.should_not be_nil - @created_salmon.iv.should_not be_nil + expect(@created_salmon.aes_key).not_to be_nil + expect(@created_salmon.iv).not_to be_nil end end @@ -30,15 +30,15 @@ describe Salmon::EncryptedSlap do end it 'sets the author id' do - @new_slap.author_id.should == alice.diaspora_handle + expect(@new_slap.author_id).to eq(alice.diaspora_handle) end it 'sets the aes_key' do - @new_slap.aes_key.should == @created_salmon.aes_key + expect(@new_slap.aes_key).to eq(@created_salmon.aes_key) end it 'sets the aes_key' do - @new_slap.iv.should == @created_salmon.iv + expect(@new_slap.iv).to eq(@created_salmon.iv) end end @@ -47,15 +47,15 @@ describe Salmon::EncryptedSlap do let(:parsed_salmon) { Salmon::EncryptedSlap.from_xml(xml, alice)} it 'should parse out the aes key' do - parsed_salmon.aes_key.should == @created_salmon.aes_key + expect(parsed_salmon.aes_key).to eq(@created_salmon.aes_key) end it 'should parse out the iv' do - parsed_salmon.iv.should == @created_salmon.iv + expect(parsed_salmon.iv).to eq(@created_salmon.iv) end it 'contains the original data' do - parsed_salmon.parsed_data.should == @post.to_diaspora_xml + expect(parsed_salmon.parsed_data).to eq(@post.to_diaspora_xml) end end @@ -66,7 +66,7 @@ describe Salmon::EncryptedSlap do it 'has a encrypted header field' do doc = Nokogiri::XML(@xml) - doc.find("encrypted_header").should_not be_blank + expect(doc.find("encrypted_header")).not_to be_blank end context "encrypted header" do @@ -77,15 +77,15 @@ describe Salmon::EncryptedSlap do end it 'contains the aes key' do - @dh_doc.search('aes_key').map(&:text).should == [@created_salmon.aes_key] + expect(@dh_doc.search('aes_key').map(&:text)).to eq([@created_salmon.aes_key]) end it 'contains the initialization vector' do - @dh_doc.search('iv').map(&:text).should == [@created_salmon.iv] + expect(@dh_doc.search('iv').map(&:text)).to eq([@created_salmon.iv]) end it 'contains the author id' do - @dh_doc.search('author_id').map(&:text).should == [alice.diaspora_handle] + expect(@dh_doc.search('author_id').map(&:text)).to eq([alice.diaspora_handle]) end end end diff --git a/spec/lib/salmon/slap_spec.rb b/spec/lib/salmon/slap_spec.rb index 32da4e720..d3a6851af 100644 --- a/spec/lib/salmon/slap_spec.rb +++ b/spec/lib/salmon/slap_spec.rb @@ -8,11 +8,11 @@ describe Salmon::Slap do describe '#create' do it 'has data in the magic envelope' do - @created_salmon.magic_sig.data.should_not be nil + expect(@created_salmon.magic_sig.data).not_to be nil end it 'has no parsed_data' do - @created_salmon.parsed_data.should be nil + expect(@created_salmon.parsed_data).to be nil end end @@ -20,13 +20,13 @@ describe Salmon::Slap do it 'works' do salmon_string = @created_salmon.xml_for(nil) salmon = Salmon::Slap.from_xml(salmon_string) - salmon.author.should == alice.person - salmon.parsed_data.should == @post.to_diaspora_xml + expect(salmon.author).to eq(alice.person) + expect(salmon.parsed_data).to eq(@post.to_diaspora_xml) end describe '#from_xml' do it 'procsses the header' do - Salmon::Slap.any_instance.should_receive(:process_header) + expect_any_instance_of(Salmon::Slap).to receive(:process_header) Salmon::Slap.from_xml(@created_salmon.xml_for(eve.person)) end end @@ -35,7 +35,7 @@ describe Salmon::Slap do it 'sets the author id' do slap = Salmon::Slap.new slap.process_header(Nokogiri::XML(@created_salmon.plaintext_header)) - slap.author_id.should == alice.diaspora_handle + expect(slap.author_id).to eq(alice.diaspora_handle) end end @@ -44,7 +44,7 @@ describe Salmon::Slap do let(:parsed_salmon) { Salmon::Slap.from_xml(xml, alice)} it 'should reference a local author' do - parsed_salmon.author.should == alice.person + expect(parsed_salmon.author).to eq(alice.person) end it 'should fail if no author is found' do @@ -60,19 +60,19 @@ describe Salmon::Slap do let(:parsed_salmon) { Salmon::Slap.from_xml(xml)} it 'should parse out the authors diaspora_handle' do - parsed_salmon.author_id.should == alice.person.diaspora_handle + expect(parsed_salmon.author_id).to eq(alice.person.diaspora_handle) end it 'verifies the signature for the sender' do - parsed_salmon.verified_for_key?(alice.public_key).should be true + expect(parsed_salmon.verified_for_key?(alice.public_key)).to be true end it 'verifies the signature for the sender' do - parsed_salmon.verified_for_key?(FactoryGirl.create(:person).public_key).should be false + expect(parsed_salmon.verified_for_key?(FactoryGirl.create(:person).public_key)).to be false end it 'contains the original data' do - parsed_salmon.parsed_data.should == @post.to_diaspora_xml + expect(parsed_salmon.parsed_data).to eq(@post.to_diaspora_xml) end end @@ -83,12 +83,12 @@ describe Salmon::Slap do it "has diaspora as the root" do doc = Nokogiri::XML(@xml) - doc.root.name.should == "diaspora" + expect(doc.root.name).to eq("diaspora") end it "it has the descrypted header" do doc = Nokogiri::XML(@xml) - doc.search("header").should_not be_blank + expect(doc.search("header")).not_to be_blank end context "header" do @@ -96,14 +96,14 @@ describe Salmon::Slap do it "it has author_id node " do doc = Nokogiri::XML(@xml) search = doc.search("header").search("author_id") - search.map(&:text).should == [alice.diaspora_handle] + expect(search.map(&:text)).to eq([alice.diaspora_handle]) end end it "it has the magic envelope " do doc = Nokogiri::XML(@xml) - doc.find("/me:env").should_not be_blank + expect(doc.find("/me:env")).not_to be_blank end end end diff --git a/spec/lib/statistics_spec.rb b/spec/lib/statistics_spec.rb index 6ce40e5e3..93a98d9a3 100644 --- a/spec/lib/statistics_spec.rb +++ b/spec/lib/statistics_spec.rb @@ -3,12 +3,12 @@ require 'spec_helper' describe Statistics do def result_should_equal( actual ) - actual.count.should == @result.count + expect(actual.count).to eq(@result.count) @result.each do |expected_hash| - actual.find { |actual_hash| + expect(actual.find { |actual_hash| actual_hash['id'].to_i == expected_hash['id'].to_i && actual_hash['count'].to_i == expected_hash['count'].to_i - }.should_not be_nil + }).not_to be_nil end end @@ -98,7 +98,7 @@ describe Statistics do {"id" => local_luke.id , "count" => 0, "connected" => 0 }, {"id" => local_leia.id , "count" => 0, "connected" => 0 }] - @stats.fb_connected_distribution.should =~ @result + expect(@stats.fb_connected_distribution).to match_array(@result) end end @@ -106,15 +106,15 @@ describe Statistics do "mentions_count", "sign_in_count", "contacts_sharing_with_count" ].each do |method| it "#{method}_sql calls where_sql" do - @stats.should_receive(:where_clause_sql) + expect(@stats).to receive(:where_clause_sql) @stats.send("#{method}_sql".to_sym) end if !["sign_in_count", "tags_followed_count"].include?(method) it "#generate_correlations calls correlate with #{method} and sign_in_count" do - @stats.stub(:correlate).and_return(0.5) - @stats.should_receive(:correlate).with(method.to_sym,:sign_in_count).and_return(0.75) + allow(@stats).to receive(:correlate).and_return(0.5) + expect(@stats).to receive(:correlate).with(method.to_sym,:sign_in_count).and_return(0.75) @stats.generate_correlations end end @@ -123,8 +123,8 @@ describe Statistics do describe "#correlation" do it 'returns the correlation coefficient' do - @stats.correlation([1,2],[1,2]).to_s.should == 1.0.to_s - @stats.correlation([1,2,1,2],[1,1,2,2]).to_s.should == 0.0.to_s + expect(@stats.correlation([1,2],[1,2]).to_s).to eq(1.0.to_s) + expect(@stats.correlation([1,2,1,2],[1,1,2,2]).to_s).to eq(0.0.to_s) end end describe "#generate_correlations" do @@ -133,21 +133,21 @@ describe Statistics do bob.post(:status_message, :text => "here is a message") bob.save! - c = @stats.generate_correlations[:posts_count].round(1).should == 1.0 + c = expect(@stats.generate_correlations[:posts_count].round(1)).to eq(1.0) end end describe "#correlate" do it 'calls correlation with post' do - User.connection.should_receive(:select_all).and_return([{"id"=> 1, "count" => 7}, + expect(User.connection).to receive(:select_all).and_return([{"id"=> 1, "count" => 7}, {"id" => 2, "count" => 8}, {"id" => 3, "count" => 9}], [{"id"=> 1, "count" => 17}, {"id" => 3, "count" => 19}] ) - @stats.should_receive(:correlation).with([7,9],[17,19]).and_return(0.5) - @stats.correlate(:posts_count,:sign_in_count).should == 0.5 + expect(@stats).to receive(:correlation).with([7,9],[17,19]).and_return(0.5) + expect(@stats.correlate(:posts_count,:sign_in_count)).to eq(0.5) end end diff --git a/spec/lib/stream/aspect_spec.rb b/spec/lib/stream/aspect_spec.rb index 1ec82d1bd..96c8ce7c4 100644 --- a/spec/lib/stream/aspect_spec.rb +++ b/spec/lib/stream/aspect_spec.rb @@ -10,7 +10,7 @@ describe Stream::Aspect do alice = double.as_null_object stream = Stream::Aspect.new(alice, [1,2,3]) - alice.aspects.should_receive(:where) + expect(alice.aspects).to receive(:where) stream.aspects end @@ -18,16 +18,16 @@ describe Stream::Aspect do alice = double.as_null_object stream = Stream::Aspect.new(alice, []) - alice.aspects.should_not_receive(:where) + expect(alice.aspects).not_to receive(:where) stream.aspects end it 'filters aspects given a user' do alice = double(:aspects => [double(:id => 1)]) - alice.aspects.stub(:where).and_return(alice.aspects) + allow(alice.aspects).to receive(:where).and_return(alice.aspects) stream = Stream::Aspect.new(alice, [1,2,3]) - stream.aspects.should == alice.aspects + expect(stream.aspects).to eq(alice.aspects) end end @@ -38,8 +38,8 @@ describe Stream::Aspect do stream = Stream::Aspect.new(alice, [1,2]) - stream.should_receive(:aspects).and_return(aspects) - aspects.should_receive(:map) + expect(stream).to receive(:aspects).and_return(aspects) + expect(aspects).to receive(:map) stream.aspect_ids end end @@ -52,33 +52,33 @@ describe Stream::Aspect do it 'calls visible posts for the given user' do stream = Stream::Aspect.new(@alice, [1,2]) - @alice.should_receive(:visible_shareables).and_return(double.as_null_object) + expect(@alice).to receive(:visible_shareables).and_return(double.as_null_object) stream.posts end it 'is called with 2 types' do stream = Stream::Aspect.new(@alice, [1,2], :order => 'created_at') - @alice.should_receive(:visible_shareables).with(Post, hash_including(:type=> ['StatusMessage', 'Reshare'])).and_return(double.as_null_object) + expect(@alice).to receive(:visible_shareables).with(Post, hash_including(:type=> ['StatusMessage', 'Reshare'])).and_return(double.as_null_object) stream.posts end it 'respects ordering' do stream = Stream::Aspect.new(@alice, [1,2], :order => 'created_at') - @alice.should_receive(:visible_shareables).with(Post, hash_including(:order => 'created_at DESC')).and_return(double.as_null_object) + expect(@alice).to receive(:visible_shareables).with(Post, hash_including(:order => 'created_at DESC')).and_return(double.as_null_object) stream.posts end it 'respects max_time' do stream = Stream::Aspect.new(@alice, [1,2], :max_time => 123) - @alice.should_receive(:visible_shareables).with(Post, hash_including(:max_time => instance_of(Time))).and_return(double.as_null_object) + expect(@alice).to receive(:visible_shareables).with(Post, hash_including(:max_time => instance_of(Time))).and_return(double.as_null_object) stream.posts end it 'passes for_all_aspects to visible posts' do stream = Stream::Aspect.new(@alice, [1,2], :max_time => 123) all_aspects = double - stream.stub(:for_all_aspects?).and_return(all_aspects) - @alice.should_receive(:visible_shareables).with(Post, hash_including(:all_aspects? => all_aspects)).and_return(double.as_null_object) + allow(stream).to receive(:for_all_aspects?).and_return(all_aspects) + expect(@alice).to receive(:visible_shareables).with(Post, hash_including(:all_aspects? => all_aspects)).and_return(double.as_null_object) stream.posts end end @@ -91,8 +91,8 @@ describe Stream::Aspect do aspect_ids = [1,2,3] stream = Stream::Aspect.new(alice, []) - stream.stub(:aspect_ids).and_return(aspect_ids) - Person.should_receive(:unique_from_aspects).with(stream.aspect_ids, alice).and_return(double(:includes => :profile)) + allow(stream).to receive(:aspect_ids).and_return(aspect_ids) + expect(Person).to receive(:unique_from_aspects).with(stream.aspect_ids, alice).and_return(double(:includes => :profile)) stream.people end end @@ -104,31 +104,31 @@ describe Stream::Aspect do end it "returns an aspect if the stream is not for all the user's aspects" do - @stream.stub(:for_all_aspects?).and_return(false) - @stream.aspect.should_not be_nil + allow(@stream).to receive(:for_all_aspects?).and_return(false) + expect(@stream.aspect).not_to be_nil end it "returns nothing if the stream is not for all the user's aspects" do - @stream.stub(:for_all_aspects?).and_return(true) - @stream.aspect.should be_nil + allow(@stream).to receive(:for_all_aspects?).and_return(true) + expect(@stream.aspect).to be_nil end end describe 'for_all_aspects?' do before do alice = double.as_null_object - alice.aspects.stub(:size).and_return(2) + allow(alice.aspects).to receive(:size).and_return(2) @stream = Stream::Aspect.new(alice, [1,2]) end it "is true if the count of aspect_ids is equal to the size of the user's aspect count" do - @stream.aspect_ids.stub(:length).and_return(2) - @stream.should be_for_all_aspects + allow(@stream.aspect_ids).to receive(:length).and_return(2) + expect(@stream).to be_for_all_aspects end it "is false if the count of aspect_ids is not equal to the size of the user's aspect count" do - @stream.aspect_ids.stub(:length).and_return(1) - @stream.should_not be_for_all_aspects + allow(@stream.aspect_ids).to receive(:length).and_return(1) + expect(@stream).not_to be_for_all_aspects end end diff --git a/spec/lib/stream/base_spec.rb b/spec/lib/stream/base_spec.rb index 09f2cf6bb..2f5c2435e 100644 --- a/spec/lib/stream/base_spec.rb +++ b/spec/lib/stream/base_spec.rb @@ -8,17 +8,17 @@ describe Stream::Base do describe '#contacts_link' do it 'should default to your contacts page' do - @stream.contacts_link.should =~ /contacts/ + expect(@stream.contacts_link).to match(/contacts/) end end describe '#stream_posts' do it "should returns the posts.for_a_stream" do posts = double - @stream.stub(:posts).and_return(posts) - @stream.stub(:like_posts_for_stream!) + allow(@stream).to receive(:posts).and_return(posts) + allow(@stream).to receive(:like_posts_for_stream!) - posts.should_receive(:for_a_stream).with(anything, anything, alice).and_return(posts) + expect(posts).to receive(:for_a_stream).with(anything, anything, alice).and_return(posts) @stream.stream_posts end @@ -30,7 +30,7 @@ describe Stream::Base do end it "marks the posts as liked" do - @stream.stream_posts.first.user_like.id.should == @like.id + expect(@stream.stream_posts.first.user_like.id).to eq(@like.id) end end end @@ -38,39 +38,39 @@ describe Stream::Base do describe '.can_comment?' do before do @person = FactoryGirl.create(:person) - @stream.stub(:people).and_return([bob.person, eve.person, @person]) + allow(@stream).to receive(:people).and_return([bob.person, eve.person, @person]) end it 'allows me to comment on my local contacts post' do post = FactoryGirl.create(:status_message, :author => bob.person) - @stream.can_comment?(post).should be true + expect(@stream.can_comment?(post)).to be true end it 'allows me to comment on my own post' do post = FactoryGirl.create(:status_message, :author => alice.person) - @stream.can_comment?(post).should be true + expect(@stream.can_comment?(post)).to be true end it 'allows me to comment on any local public post' do post = FactoryGirl.create(:status_message, :author => eve.person) - @stream.can_comment?(post).should be true + expect(@stream.can_comment?(post)).to be true end it 'allows me to comment on a remote contacts post' do Contact.create!(:user => @stream.user, :person => @person) post = FactoryGirl.create(:status_message, :author => @person) - @stream.can_comment?(post).should be true + expect(@stream.can_comment?(post)).to be true end it 'returns false if person is remote and not a contact' do post = FactoryGirl.create(:status_message, :author => @person) - @stream.can_comment?(post).should be false + expect(@stream.can_comment?(post)).to be false end end describe '#people' do it 'excludes blocked people' do - @stream.should_receive(:stream_posts).and_return(double.as_null_object) + expect(@stream).to receive(:stream_posts).and_return(double.as_null_object) @stream.people end end diff --git a/spec/lib/stream/followed_tag_spec.rb b/spec/lib/stream/followed_tag_spec.rb index 832847d32..f46d49a70 100644 --- a/spec/lib/stream/followed_tag_spec.rb +++ b/spec/lib/stream/followed_tag_spec.rb @@ -4,7 +4,7 @@ require Rails.root.join('spec', 'shared_behaviors', 'stream') describe Stream::FollowedTag do before do @stream = Stream::FollowedTag.new(alice, :max_time => Time.now, :order => 'updated_at') - @stream.stub(:tag_string).and_return("foo") + allow(@stream).to receive(:tag_string).and_return("foo") end describe 'shared behaviors' do diff --git a/spec/lib/stream/multi_spec.rb b/spec/lib/stream/multi_spec.rb index a0a833608..2f77fc180 100644 --- a/spec/lib/stream/multi_spec.rb +++ b/spec/lib/stream/multi_spec.rb @@ -12,11 +12,11 @@ describe Stream::Multi do describe "#posts" do it "calls EvilQuery::MultiStream with correct parameters" do - ::EvilQuery::MultiStream.should_receive(:new) + expect(::EvilQuery::MultiStream).to receive(:new) .with(alice, 'updated_at', @stream.max_time, AppConfig.settings.community_spotlight.enable? && alice.show_community_spotlight_in_stream?) - .and_return(double.tap { |m| m.stub(:make_relation!)}) + .and_return(double.tap { |m| allow(m).to receive(:make_relation!)}) @stream.posts end end @@ -24,17 +24,17 @@ describe Stream::Multi do describe '#publisher_opts' do it 'prefills, sets public, and autoexpands if welcome? is set' do prefill_text = "sup?" - @stream.stub(:welcome?).and_return(true) - @stream.stub(:publisher_prefill).and_return(prefill_text) - @stream.send(:publisher_opts).should == {:open => true, + allow(@stream).to receive(:welcome?).and_return(true) + allow(@stream).to receive(:publisher_prefill).and_return(prefill_text) + expect(@stream.send(:publisher_opts)).to eq({:open => true, :prefill => prefill_text, - :public => true} + :public => true}) end it 'provides no opts if welcome? is not set' do prefill_text = "sup?" - @stream.stub(:welcome?).and_return(false) - @stream.send(:publisher_opts).should == {} + allow(@stream).to receive(:welcome?).and_return(false) + expect(@stream.send(:publisher_opts)).to eq({}) end end @@ -47,11 +47,11 @@ describe Stream::Multi do end it 'returns includes new user hashtag' do - @stream.send(:publisher_prefill).should match(/#NewHere/i) + expect(@stream.send(:publisher_prefill)).to match(/#NewHere/i) end it 'includes followed hashtags' do - @stream.send(:publisher_prefill).should include("#cats") + expect(@stream.send(:publisher_prefill)).to include("#cats") end context 'when invited by another user' do @@ -64,7 +64,7 @@ describe Stream::Multi do it 'includes a mention of the inviter' do mention = "@{#{@inviter.name} ; #{@inviter.diaspora_handle}}" - @stream.send(:publisher_prefill).should include(mention) + expect(@stream.send(:publisher_prefill)).to include(mention) end end end @@ -76,12 +76,12 @@ describe Stream::Multi do it 'returns true if user is getting started' do alice.getting_started = true - @stream.send(:welcome?).should be true + expect(@stream.send(:welcome?)).to be true end it 'returns false if user is getting started' do alice.getting_started = false - @stream.send(:welcome?).should be false + expect(@stream.send(:welcome?)).to be false end end end diff --git a/spec/lib/stream/person_spec.rb b/spec/lib/stream/person_spec.rb index 8f8ecdc73..f5eb10224 100644 --- a/spec/lib/stream/person_spec.rb +++ b/spec/lib/stream/person_spec.rb @@ -28,7 +28,7 @@ describe Stream::Person do posts = posts.reverse.slice(0..14) fetched_posts = fetched_posts.slice(0..14) - fetched_posts.should == posts + expect(fetched_posts).to eq(posts) end end diff --git a/spec/lib/stream/tag_spec.rb b/spec/lib/stream/tag_spec.rb index e82e59ad4..ea74fec62 100644 --- a/spec/lib/stream/tag_spec.rb +++ b/spec/lib/stream/tag_spec.rb @@ -14,30 +14,30 @@ describe Stream::Tag do it 'displays your own post' do my_post = alice.post(:status_message, :text => "#what", :to => 'all') - @stream.posts.should == [my_post] + expect(@stream.posts).to eq([my_post]) end it "displays a friend's post" do other_post = bob.post(:status_message, :text => "#what", :to => 'all') - @stream.posts.should == [other_post] + expect(@stream.posts).to eq([other_post]) end it 'displays a public post' do other_post = eve.post(:status_message, :text => "#what", :public => true, :to => 'all') - @stream.posts.should == [other_post] + expect(@stream.posts).to eq([other_post]) end it 'displays a public post that was sent to no one' do stranger = FactoryGirl.create(:user_with_aspect) stranger_post = stranger.post(:status_message, :text => "#what", :public => true, :to => 'all') - @stream.posts.should == [stranger_post] + expect(@stream.posts).to eq([stranger_post]) end it 'displays a post with a comment containing the tag search' do skip "this code is way too slow. need to re-implement in a way that doesn't suck" other_post = bob.post(:status_message, :text => "sup y'all", :to => 'all') FactoryGirl.create(:comment, :text => "#what", :post => other_post) - @stream.posts.should == [other_post] + expect(@stream.posts).to eq([other_post]) end end @@ -50,7 +50,7 @@ describe Stream::Tag do it "displays only public posts with the tag" do stream = Stream::Tag.new(nil, "what") - stream.posts.should == [@post] + expect(stream.posts).to eq([@post]) end end @@ -58,7 +58,7 @@ describe Stream::Tag do it "assigns the set of people who authored a post containing the tag" do alice.post(:status_message, :text => "#what", :public => true, :to => 'all') stream = Stream::Tag.new(nil, "what") - stream.people.should == [alice.person] + expect(stream.people).to eq([alice.person]) end end @@ -68,7 +68,7 @@ describe Stream::Tag do alice.profile.tag_string = "#whatevs" alice.profile.build_tags alice.profile.save! - stream.tagged_people.should == [alice.person] + expect(stream.tagged_people).to eq([alice.person]) end end @@ -81,7 +81,7 @@ describe Stream::Tag do it 'returns posts regardless of the tag case' do stream = Stream::Tag.new(nil, "newhere") - stream.posts.should =~ [@post_lc, @post_uc, @post_cp] + expect(stream.posts).to match_array([@post_lc, @post_uc, @post_cp]) end end @@ -95,18 +95,18 @@ describe Stream::Tag do describe '#tag_name=' do it 'downcases the tag' do stream = Stream::Tag.new(nil, "WHAT") - stream.tag_name.should == 'what' + expect(stream.tag_name).to eq('what') end it 'removes #es' do stream = Stream::Tag.new(nil, "#WHAT") - stream.tag_name.should == 'what' + expect(stream.tag_name).to eq('what') end end describe "#publisher" do it 'creates a publisher with the tag prefill' do - Publisher.should_receive(:new).with(anything(), anything) + expect(Publisher).to receive(:new).with(anything(), anything) @stream = Stream::Tag.new(alice, "what") end end diff --git a/spec/lib/webfinger_profile_spec.rb b/spec/lib/webfinger_profile_spec.rb index aa42d2d64..51991f084 100644 --- a/spec/lib/webfinger_profile_spec.rb +++ b/spec/lib/webfinger_profile_spec.rb @@ -11,22 +11,22 @@ describe WebfingerProfile do describe '#valid_diaspora_profile?' do it 'should check all of the required fields' do - manual_nil_check(profile).should == profile.valid_diaspora_profile? + expect(manual_nil_check(profile)).to eq(profile.valid_diaspora_profile?) end end describe '#set_fields' do it 'should check to make sure it has a the right webfinger profile' do - proc{ WebfingerProfile.new("nottom@tom.joindiaspora.com", webfinger_profile)}.should raise_error + expect{ WebfingerProfile.new("nottom@tom.joindiaspora.com", webfinger_profile)}.to raise_error end it 'should handle a non-diaspora profile without blowing up' do - proc{ WebfingerProfile.new("evan@status.net", not_diaspora_webfinger)}.should_not raise_error + expect{ WebfingerProfile.new("evan@status.net", not_diaspora_webfinger)}.not_to raise_error end [:links, :hcard, :guid, :seed_location, :public_key].each do |field| it 'should sets the #{field} field' do - profile.send(field).should be_present + expect(profile.send(field)).to be_present end end end diff --git a/spec/lib/webfinger_spec.rb b/spec/lib/webfinger_spec.rb index ad1d667d5..25104bb37 100644 --- a/spec/lib/webfinger_spec.rb +++ b/spec/lib/webfinger_spec.rb @@ -16,23 +16,23 @@ describe Webfinger do describe '#intialize' do it 'sets account ' do n = Webfinger.new("mbs348@gmail.com") - n.account.should_not be nil + expect(n.account).not_to be nil end it "downcases account and strips whitespace, and gsub 'acct:'" do n = Webfinger.new("acct:BIGBOY@Example.Org ") - n.account.should == 'bigboy@example.org' + expect(n.account).to eq('bigboy@example.org') end it 'should set ssl as the default' do foo = Webfinger.new(account) - foo.ssl.should be true + expect(foo.ssl).to be true end end describe '.in_background' do it 'enqueues a Workers::FetchWebfinger job' do - Workers::FetchWebfinger.should_receive(:perform_async).with(account) + expect(Workers::FetchWebfinger).to receive(:perform_async).with(account) Webfinger.in_background(account) end end @@ -40,12 +40,12 @@ describe Webfinger do describe '#fetch' do it 'works' do finger = Webfinger.new(account_in_fixtures) - finger.stub(:host_meta_xrd).and_return(host_meta_xrd) - finger.stub(:hcard_xrd).and_return(hcard_xml) - finger.stub(:webfinger_profile_xrd).and_return(webfinger_xrd) + allow(finger).to receive(:host_meta_xrd).and_return(host_meta_xrd) + allow(finger).to receive(:hcard_xrd).and_return(hcard_xml) + allow(finger).to receive(:webfinger_profile_xrd).and_return(webfinger_xrd) person = finger.fetch - person.should be_valid - person.should be_a Person + expect(person).to be_valid + expect(person).to be_a Person end end @@ -56,7 +56,7 @@ describe Webfinger do stub_request(:get, url). to_return(:status => 200, :body => host_meta_xrd) - finger.get(url).should == host_meta_xrd + expect(finger.get(url)).to eq(host_meta_xrd) end it 'follows redirects' do @@ -70,7 +70,7 @@ describe Webfinger do finger.host_meta_xrd - a_request(:get, redirect_url).should have_been_made + expect(a_request(:get, redirect_url)).to have_been_made end it 'returns false on 404' do @@ -78,36 +78,36 @@ describe Webfinger do stub_request(:get, url). to_return(:status => 404, :body => nil) - finger.get(url).should_not == nil - finger.get(url).should == false + expect(finger.get(url)).not_to eq(nil) + expect(finger.get(url)).to eq(false) end end describe 'existing_person_with_profile?' do it 'returns true if cached_person is present and has a profile' do - finger.should_receive(:cached_person).twice.and_return(FactoryGirl.create(:person)) - finger.existing_person_with_profile?.should be true + expect(finger).to receive(:cached_person).twice.and_return(FactoryGirl.create(:person)) + expect(finger.existing_person_with_profile?).to be true end it 'returns false if it has no person' do - finger.stub(:cached_person).and_return false - finger.existing_person_with_profile?.should be false + allow(finger).to receive(:cached_person).and_return false + expect(finger.existing_person_with_profile?).to be false end it 'returns false if the person has no profile' do p = FactoryGirl.create(:person) p.profile = nil - finger.stub(:cached_person).and_return(p) - finger.existing_person_with_profile?.should be false + allow(finger).to receive(:cached_person).and_return(p) + expect(finger.existing_person_with_profile?).to be false end end describe 'cached_person' do it 'sets the person by looking up the account from Person.by_account_identifier' do person = double - Person.should_receive(:by_account_identifier).with(account).and_return(person) - finger.cached_person.should == person - finger.person.should == person + expect(Person).to receive(:by_account_identifier).with(account).and_return(person) + expect(finger.cached_person).to eq(person) + expect(finger.person).to eq(person) end end @@ -116,16 +116,16 @@ describe Webfinger do context 'with a cached_person' do it 'calls Person#assign_new_profile_from_hcard with the fetched hcard' do finger.hcard_xrd = hcard_xml - finger.stub(:person).and_return(bob.person) - bob.person.should_receive(:assign_new_profile_from_hcard).with(finger.hcard) + allow(finger).to receive(:person).and_return(bob.person) + expect(bob.person).to receive(:assign_new_profile_from_hcard).with(finger.hcard) finger.create_or_update_person_from_webfinger_profile! end end context 'with no cached person' do it 'sets person based on make_person_from_webfinger' do - finger.stub(:person).and_return(nil) - finger.should_receive(:make_person_from_webfinger) + allow(finger).to receive(:person).and_return(nil) + expect(finger).to receive(:make_person_from_webfinger) finger.create_or_update_person_from_webfinger_profile! end end @@ -133,67 +133,67 @@ describe Webfinger do describe '#host_meta_xrd' do it 'calls #get with host_meta_url' do - finger.stub(:host_meta_url).and_return('meta') - finger.should_receive(:get).with('meta') + allow(finger).to receive(:host_meta_url).and_return('meta') + expect(finger).to receive(:get).with('meta') finger.host_meta_xrd end it 'should retry with ssl off a second time' do - finger.should_receive(:get).and_raise(StandardError) - finger.should_receive(:get) + expect(finger).to receive(:get).and_raise(StandardError) + expect(finger).to receive(:get) finger.host_meta_xrd - finger.ssl.should be false + expect(finger.ssl).to be false end end describe '#hcard' do it 'calls HCard.build' do - finger.stub(:hcard_xrd).and_return(hcard_xml) - HCard.should_receive(:build).with(hcard_xml).and_return true - finger.hcard.should_not be_nil + allow(finger).to receive(:hcard_xrd).and_return(hcard_xml) + expect(HCard).to receive(:build).with(hcard_xml).and_return true + expect(finger.hcard).not_to be_nil end end describe '#webfinger_profile' do it 'constructs a new WebfingerProfile object' do - finger.stub(:webfinger_profile_xrd).and_return(webfinger_xrd) - WebfingerProfile.should_receive(:new).with(account, webfinger_xrd) + allow(finger).to receive(:webfinger_profile_xrd).and_return(webfinger_xrd) + expect(WebfingerProfile).to receive(:new).with(account, webfinger_xrd) finger.webfinger_profile end end describe '#webfinger_profile_url' do it 'returns the llrd link for a valid host meta' do - finger.stub(:host_meta_xrd).and_return(host_meta_xrd) - finger.webfinger_profile_url.should_not be_nil + allow(finger).to receive(:host_meta_xrd).and_return(host_meta_xrd) + expect(finger.webfinger_profile_url).not_to be_nil end it 'returns nil if no link is found' do - finger.stub(:host_meta_xrd).and_return(nil) - finger.webfinger_profile_url.should be_nil + allow(finger).to receive(:host_meta_xrd).and_return(nil) + expect(finger.webfinger_profile_url).to be_nil end end describe '#webfinger_profile_xrd' do it 'calls #get with the hcard_url' do - finger.stub(:hcard_url).and_return("url") - finger.should_receive(:get).with("url") + allow(finger).to receive(:hcard_url).and_return("url") + expect(finger).to receive(:get).with("url") finger.hcard_xrd end end describe '#make_person_from_webfinger' do it 'with an hcard and a webfinger_profile, it calls Person.create_from_webfinger' do - finger.stub(:hcard).and_return("hcard") - finger.stub(:webfinger_profile_xrd).and_return("webfinger_profile_xrd") - finger.stub(:webfinger_profile).and_return("webfinger_profile") - Person.should_receive(:create_from_webfinger).with("webfinger_profile", "hcard") + allow(finger).to receive(:hcard).and_return("hcard") + allow(finger).to receive(:webfinger_profile_xrd).and_return("webfinger_profile_xrd") + allow(finger).to receive(:webfinger_profile).and_return("webfinger_profile") + expect(Person).to receive(:create_from_webfinger).with("webfinger_profile", "hcard") finger.make_person_from_webfinger end it 'with an false xrd it does not call Person.create_from_webfinger' do - finger.stub(:webfinger_profile_xrd).and_return(false) - Person.should_not_receive(:create_from_webfinger) + allow(finger).to receive(:webfinger_profile_xrd).and_return(false) + expect(Person).not_to receive(:create_from_webfinger) finger.make_person_from_webfinger end end @@ -203,18 +203,18 @@ describe Webfinger do describe '#host_meta_url' do it 'should return canonical host-meta url for http' do finger.ssl = false - finger.host_meta_url.should == "http://bar.com/.well-known/host-meta" + expect(finger.host_meta_url).to eq("http://bar.com/.well-known/host-meta") end it 'can return the https version' do - finger.host_meta_url.should == "https://bar.com/.well-known/host-meta" + expect(finger.host_meta_url).to eq("https://bar.com/.well-known/host-meta") end end describe 'swizzle' do it 'gsubs out {uri} for the account' do string = "{uri} is the coolest" - finger.swizzle(string).should == "#{finger.account} is the coolest" + expect(finger.swizzle(string)).to eq("#{finger.account} is the coolest") end end end diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb index 1f59a4bb2..327880780 100644 --- a/spec/mailers/notifier_spec.rb +++ b/spec/mailers/notifier_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Notifier do +describe Notifier, :type => :mailer do let(:person) { FactoryGirl.create(:person) } before do @@ -10,11 +10,11 @@ describe Notifier do describe '.administrative' do it 'mails a user' do mails = Notifier.admin("Welcome to bureaucracy!", [bob]) - mails.length.should == 1 + expect(mails.length).to eq(1) mail = mails.first - mail.to.should == [bob.email] - mail.body.encoded.should match /Welcome to bureaucracy!/ - mail.body.encoded.should match /#{bob.username}/ + expect(mail.to).to eq([bob.email]) + expect(mail.body.encoded).to match /Welcome to bureaucracy!/ + expect(mail.body.encoded).to match /#{bob.username}/ end context 'mails a bunch of users' do @@ -26,19 +26,19 @@ describe Notifier do end it 'has a body' do mails = Notifier.admin("Welcome to bureaucracy!", @users) - mails.length.should == 5 + expect(mails.length).to eq(5) mails.each{|mail| this_user = @users.detect{|u| mail.to == [u.email]} - mail.body.encoded.should match /Welcome to bureaucracy!/ - mail.body.encoded.should match /#{this_user.username}/ + expect(mail.body.encoded).to match /Welcome to bureaucracy!/ + expect(mail.body.encoded).to match /#{this_user.username}/ } end it "has attachments" do mails = Notifier.admin("Welcome to bureaucracy!", @users, :attachments => [{:name => "retention stats", :file => "here is some file content"}]) - mails.length.should == 5 + expect(mails.length).to eq(5) mails.each{|mail| - mail.attachments.count.should == 1 + expect(mail.attachments.count).to eq(1) } end end @@ -47,19 +47,19 @@ describe Notifier do describe '.single_admin' do it 'mails a user' do mail = Notifier.single_admin("Welcome to bureaucracy!", bob) - mail.to.should == [bob.email] - mail.body.encoded.should match /Welcome to bureaucracy!/ - mail.body.encoded.should match /#{bob.username}/ + expect(mail.to).to eq([bob.email]) + expect(mail.body.encoded).to match /Welcome to bureaucracy!/ + expect(mail.body.encoded).to match /#{bob.username}/ end it 'has the layout' do mail = Notifier.single_admin("Welcome to bureaucracy!", bob) - mail.body.encoded.should match /change your notification settings/ + expect(mail.body.encoded).to match /change your notification settings/ end it 'has an optional attachment' do mail = Notifier.single_admin("Welcome to bureaucracy!", bob, :attachments => [{:name => "retention stats", :file => "here is some file content"}]) - mail.attachments.length.should == 1 + expect(mail.attachments.length).to eq(1) end end @@ -67,11 +67,11 @@ describe Notifier do let!(:request_mail) { Notifier.started_sharing(bob.id, person.id) } it 'goes to the right person' do - request_mail.to.should == [bob.email] + expect(request_mail.to).to eq([bob.email]) end it 'has the name of person sending the request' do - request_mail.body.encoded.include?(person.name).should be true + expect(request_mail.body.encoded.include?(person.name)).to be true end it 'has the css' do @@ -89,19 +89,19 @@ describe Notifier do end it 'TO: goes to the right person' do - @mail.to.should == [@user.email] + expect(@mail.to).to eq([@user.email]) end it 'SUBJECT: has the name of person mentioning in the subject' do - @mail.subject.should include(@sm.author.name) + expect(@mail.subject).to include(@sm.author.name) end it 'has the post text in the body' do - @mail.body.encoded.should include(@sm.text) + expect(@mail.body.encoded).to include(@sm.text) end it 'should not include translation fallback' do - @mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared') + expect(@mail.body.encoded).not_to include(I18n.translate 'notifier.a_post_you_shared') end end @@ -113,19 +113,19 @@ describe Notifier do end it 'TO: goes to the right person' do - @mail.to.should == [alice.email] + expect(@mail.to).to eq([alice.email]) end it 'BODY: contains the truncated original post' do - @mail.body.encoded.should include(@sm.message.plain_text) + expect(@mail.body.encoded).to include(@sm.message.plain_text) end it 'BODY: contains the name of person liking' do - @mail.body.encoded.should include(@like.author.name) + expect(@mail.body.encoded).to include(@like.author.name) end it 'should not include translation fallback' do - @mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared') + expect(@mail.body.encoded).not_to include(I18n.translate 'notifier.a_post_you_shared') end it 'can handle a reshare' do @@ -143,19 +143,19 @@ describe Notifier do end it 'TO: goes to the right person' do - @mail.to.should == [alice.email] + expect(@mail.to).to eq([alice.email]) end it 'BODY: contains the truncated original post' do - @mail.body.encoded.should include(@sm.message.plain_text) + expect(@mail.body.encoded).to include(@sm.message.plain_text) end it 'BODY: contains the name of person liking' do - @mail.body.encoded.should include(@reshare.author.name) + expect(@mail.body.encoded).to include(@reshare.author.name) end it 'should not include translation fallback' do - @mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared') + expect(@mail.body.encoded).not_to include(I18n.translate 'notifier.a_post_you_shared') end end @@ -178,30 +178,30 @@ describe Notifier do end it 'TO: goes to the right person' do - @mail.to.should == [bob.email] + expect(@mail.to).to eq([bob.email]) end it "FROM: contains the sender's name" do - @mail["From"].to_s.should == "\"#{@cnv.author.name} (diaspora*)\" <#{AppConfig.mail.sender_address}>" + expect(@mail["From"].to_s).to eq("\"#{@cnv.author.name} (diaspora*)\" <#{AppConfig.mail.sender_address}>") end it 'SUBJECT: has a snippet of the post contents' do - @mail.subject.should == @cnv.subject + expect(@mail.subject).to eq(@cnv.subject) end it 'SUBJECT: has "Re:" if not the first message in a conversation' do @cnv.messages << Message.new(:text => 'yo', :author => eve.person) @mail = Notifier.private_message(bob.id, @cnv.author.id, @cnv.messages.last.id) - @mail.subject.should == "Re: #{@cnv.subject}" + expect(@mail.subject).to eq("Re: #{@cnv.subject}") end it 'BODY: contains the message text' do - @mail.body.encoded.should include(@cnv.messages.first.text) + expect(@mail.body.encoded).to include(@cnv.messages.first.text) end it 'should not include translation fallback' do - @mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared') + expect(@mail.body.encoded).not_to include(I18n.translate 'notifier.a_post_you_shared') end end @@ -213,28 +213,28 @@ describe Notifier do let(:comment_mail) {Notifier.comment_on_post(bob.id, person.id, comment.id).deliver} it 'TO: goes to the right person' do - comment_mail.to.should == [bob.email] + expect(comment_mail.to).to eq([bob.email]) end it "FROM: contains the sender's name" do - comment_mail["From"].to_s.should == "\"#{eve.name} (diaspora*)\" <#{AppConfig.mail.sender_address}>" + expect(comment_mail["From"].to_s).to eq("\"#{eve.name} (diaspora*)\" <#{AppConfig.mail.sender_address}>") end it 'SUBJECT: has a snippet of the post contents, without markdown and without newlines' do - comment_mail.subject.should == "Re: Headline" + expect(comment_mail.subject).to eq("Re: Headline") end context 'BODY' do it "contains the comment" do - comment_mail.body.encoded.should include(comment.text) + expect(comment_mail.body.encoded).to include(comment.text) end it "contains the original post's link" do - comment_mail.body.encoded.include?("#{comment.post.id.to_s}").should be true + expect(comment_mail.body.encoded.include?("#{comment.post.id.to_s}")).to be true end it 'should not include translation fallback' do - comment_mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared') + expect(comment_mail.body.encoded).not_to include(I18n.translate 'notifier.a_post_you_shared') end end @@ -242,9 +242,9 @@ describe Notifier do context post_type.to_s do let(:commented_post) { FactoryGirl.create(post_type, :author => bob.person) } it 'succeeds' do - proc { + expect { comment_mail - }.should_not raise_error + }.not_to raise_error end end end @@ -254,37 +254,37 @@ describe Notifier do let(:comment_mail) { Notifier.also_commented(bob.id, person.id, comment.id) } it 'TO: goes to the right person' do - comment_mail.to.should == [bob.email] + expect(comment_mail.to).to eq([bob.email]) end it 'FROM: has the name of person commenting as the sender' do - comment_mail["From"].to_s.should == "\"#{eve.name} (diaspora*)\" <#{AppConfig.mail.sender_address}>" + expect(comment_mail["From"].to_s).to eq("\"#{eve.name} (diaspora*)\" <#{AppConfig.mail.sender_address}>") end it 'SUBJECT: has a snippet of the post contents, without markdown and without newlines' do - comment_mail.subject.should == "Re: Headline" + expect(comment_mail.subject).to eq("Re: Headline") end context 'BODY' do it "contains the comment" do - comment_mail.body.encoded.should include(comment.text) + expect(comment_mail.body.encoded).to include(comment.text) end it "contains the original post's link" do - comment_mail.body.encoded.include?("#{comment.post.id.to_s}").should be true + expect(comment_mail.body.encoded.include?("#{comment.post.id.to_s}")).to be true end it 'should not include translation fallback' do - comment_mail.body.encoded.should_not include(I18n.translate 'notifier.a_post_you_shared') + expect(comment_mail.body.encoded).not_to include(I18n.translate 'notifier.a_post_you_shared') end end [:reshare].each do |post_type| context post_type.to_s do let(:commented_post) { FactoryGirl.create(post_type, :author => bob.person) } it 'succeeds' do - proc { + expect { comment_mail - }.should_not raise_error + }.not_to raise_error end end end @@ -297,23 +297,23 @@ describe Notifier do end it 'goes to the right person' do - @confirm_email.to.should == [bob.unconfirmed_email] + expect(@confirm_email.to).to eq([bob.unconfirmed_email]) end it 'has the unconfirmed emil in the subject' do - @confirm_email.subject.should include(bob.unconfirmed_email) + expect(@confirm_email.subject).to include(bob.unconfirmed_email) end it 'has the unconfirmed emil in the body' do - @confirm_email.body.encoded.should include(bob.unconfirmed_email) + expect(@confirm_email.body.encoded).to include(bob.unconfirmed_email) end it 'has the receivers name in the body' do - @confirm_email.body.encoded.should include(bob.person.profile.first_name) + expect(@confirm_email.body.encoded).to include(bob.person.profile.first_name) end it 'has the activation link in the body' do - @confirm_email.body.encoded.should include(confirm_email_url(:token => bob.confirm_email_token)) + expect(@confirm_email.body.encoded).to include(confirm_email_url(:token => bob.confirm_email_token)) end end end @@ -321,9 +321,9 @@ describe Notifier do describe 'hashtags' do it 'escapes hashtags' do mails = Notifier.admin("#Welcome to bureaucracy!", [bob]) - mails.length.should == 1 + expect(mails.length).to eq(1) mail = mails.first - mail.body.encoded.should match "

#Welcome to bureaucracy!

" + expect(mail.body.encoded).to match "

#Welcome to bureaucracy!

" end end end diff --git a/spec/mailers/report_spec.rb b/spec/mailers/report_spec.rb index 9b41750a5..10edd0dae 100644 --- a/spec/mailers/report_spec.rb +++ b/spec/mailers/report_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Report do +describe Report, :type => :mailer do describe '#make_notification' do before do @remote = FactoryGirl.create(:person, :diaspora_handle => "remote@remote.net") diff --git a/spec/misc_spec.rb b/spec/misc_spec.rb index 58eb63958..e714d839d 100644 --- a/spec/misc_spec.rb +++ b/spec/misc_spec.rb @@ -8,12 +8,12 @@ describe 'making sure the spec runner works' do it 'factory creates a user with a person saved' do user = FactoryGirl.create(:user) loaded_user = User.find(user.id) - loaded_user.person.owner_id.should == user.id + expect(loaded_user.person.owner_id).to eq(user.id) end describe 'fixtures' do it 'loads fixtures' do - User.count.should_not == 0 + expect(User.count).not_to eq(0) end end @@ -30,31 +30,31 @@ describe 'making sure the spec runner works' do it 'connects the first user to the second' do contact = @user1.contact_for @user2.person - contact.should_not be_nil - @user1.contacts.reload.include?(contact).should be true - @aspect1.contacts.include?(contact).should be true - contact.aspects.include?(@aspect1).should be true + expect(contact).not_to be_nil + expect(@user1.contacts.reload.include?(contact)).to be true + expect(@aspect1.contacts.include?(contact)).to be true + expect(contact.aspects.include?(@aspect1)).to be true end it 'connects the second user to the first' do contact = @user2.contact_for @user1.person - contact.should_not be_nil - @user2.contacts.reload.include?(contact).should be true - @aspect2.contacts.include?(contact).should be true - contact.aspects.include?(@aspect2).should be true + expect(contact).not_to be_nil + expect(@user2.contacts.reload.include?(contact)).to be true + expect(@aspect2.contacts.include?(contact)).to be true + expect(contact.aspects.include?(@aspect2)).to be true end it 'allows posting after running' do message = @user1.post(:status_message, :text => "Connection!", :to => @aspect1.id) - @user2.reload.visible_shareables(Post).should include message + expect(@user2.reload.visible_shareables(Post)).to include message end end describe '#post' do it 'creates a notification with a mention' do - lambda{ + expect{ alice.post(:status_message, :text => "@{Bob Grimn; #{bob.person.diaspora_handle}} you are silly", :to => alice.aspects.find_by_name('generic')) - }.should change(Notification, :count).by(1) + }.to change(Notification, :count).by(1) end end @@ -62,9 +62,9 @@ describe 'making sure the spec runner works' do it 'creates a conversation and a message' do conversation = create_conversation_with_message(alice, bob.person, "Subject", "Hey Bob") - conversation.participants.should == [alice.person, bob.person] - conversation.subject.should == "Subject" - conversation.messages.first.text.should == "Hey Bob" + expect(conversation.participants).to eq([alice.person, bob.person]) + expect(conversation.subject).to eq("Subject") + expect(conversation.messages.first.text).to eq("Hey Bob") end end end diff --git a/spec/models/account_deletion_spec.rb b/spec/models/account_deletion_spec.rb index e1c1cf4f8..00a165185 100644 --- a/spec/models/account_deletion_spec.rb +++ b/spec/models/account_deletion_spec.rb @@ -4,14 +4,14 @@ require 'spec_helper' -describe AccountDeletion do +describe AccountDeletion, :type => :model do it 'assigns the diaspora_handle from the person object' do a = AccountDeletion.new(:person => alice.person) - a.diaspora_handle.should == alice.person.diaspora_handle + expect(a.diaspora_handle).to eq(alice.person.diaspora_handle) end it 'fires a job after creation'do - Workers::DeleteAccount.should_receive(:perform_async).with(anything) + expect(Workers::DeleteAccount).to receive(:perform_async).with(anything) AccountDeletion.create(:person => alice.person) end @@ -22,18 +22,18 @@ describe AccountDeletion do end it 'creates a deleter' do - AccountDeleter.should_receive(:new).with(alice.person.diaspora_handle).and_return(double(:perform! => true)) + expect(AccountDeleter).to receive(:new).with(alice.person.diaspora_handle).and_return(double(:perform! => true)) @ad.perform! end it 'dispatches the account deletion if the user exists' do - @ad.should_receive(:dispatch) + expect(@ad).to receive(:dispatch) @ad.perform! end it 'does not dispatch an account deletion for non-local people' do deletion = AccountDeletion.new(:person => remote_raphael) - deletion.should_not_receive(:dispatch) + expect(deletion).not_to receive(:dispatch) deletion.perform! end @@ -51,7 +51,7 @@ describe AccountDeletion do end it 'creates a public postzord' do - Postzord::Dispatcher::Public.should_receive(:new).and_return(double.as_null_object) + expect(Postzord::Dispatcher::Public).to receive(:new).and_return(double.as_null_object) @ad = AccountDeletion.new(:person => alice.person) @ad.send(:dispatch) end @@ -62,7 +62,7 @@ describe AccountDeletion do @ad = AccountDeletion.new(:person => alice.person) alice.share_with(remote_raphael, alice.aspects.first) - @ad.subscribers(alice).should == [remote_raphael] + expect(@ad.subscribers(alice)).to eq([remote_raphael]) end it 'includes remote resharers' do @@ -71,7 +71,7 @@ describe AccountDeletion do r1 = FactoryGirl.create( :reshare, :author => remote_raphael, :root => sm) r2 = FactoryGirl.create( :reshare, :author => local_luke.person, :root => sm) - @ad.subscribers(alice).should == [remote_raphael] + expect(@ad.subscribers(alice)).to eq([remote_raphael]) end end @@ -82,11 +82,11 @@ describe AccountDeletion do end it 'should have a diaspora_handle' do - @xml.include?(alice.person.diaspora_handle).should == true + expect(@xml.include?(alice.person.diaspora_handle)).to eq(true) end it 'marshals the xml' do - AccountDeletion.from_xml(@xml).should be_valid + expect(AccountDeletion.from_xml(@xml)).to be_valid end end end diff --git a/spec/models/acts_as_taggable_on_tag_spec.rb b/spec/models/acts_as_taggable_on_tag_spec.rb index a54276661..159c7c035 100644 --- a/spec/models/acts_as_taggable_on_tag_spec.rb +++ b/spec/models/acts_as_taggable_on_tag_spec.rb @@ -1,23 +1,23 @@ require 'spec_helper' -describe ActsAsTaggableOn::Tag do +describe ActsAsTaggableOn::Tag, :type => :model do describe '.autocomplete' do before do @tag = ActsAsTaggableOn::Tag.create(:name => "cats") end it 'downcases the tag name' do - ActsAsTaggableOn::Tag.autocomplete("CATS").should == [@tag] + expect(ActsAsTaggableOn::Tag.autocomplete("CATS")).to eq([@tag]) end it 'does an end where on tags' do - ActsAsTaggableOn::Tag.autocomplete("CAT").should == [@tag] + expect(ActsAsTaggableOn::Tag.autocomplete("CAT")).to eq([@tag]) end end describe ".normalize" do it "removes leading hash symbols" do - ActsAsTaggableOn::Tag.normalize("#mytag").should == "mytag" + expect(ActsAsTaggableOn::Tag.normalize("#mytag")).to eq("mytag") end it "removes punctuation and whitespace" do @@ -33,13 +33,13 @@ describe ActsAsTaggableOn::Tag do 'hash#inside' => 'hashinside', 'f!u@n#k$y%-^h&a*r(a)c{t}e[r]s' => 'funky-characters' }.each do |invalid, normalized| - ActsAsTaggableOn::Tag.normalize(invalid).should == normalized + expect(ActsAsTaggableOn::Tag.normalize(invalid)).to eq(normalized) end end it 'allows for love' do - ActsAsTaggableOn::Tag.normalize("<3").should == "<3" - ActsAsTaggableOn::Tag.normalize("#<3").should == "<3" + expect(ActsAsTaggableOn::Tag.normalize("<3")).to eq("<3") + expect(ActsAsTaggableOn::Tag.normalize("#<3")).to eq("<3") end end end diff --git a/spec/models/aspect_membership_spec.rb b/spec/models/aspect_membership_spec.rb index 7f4bc65f3..12b01fe24 100644 --- a/spec/models/aspect_membership_spec.rb +++ b/spec/models/aspect_membership_spec.rb @@ -4,7 +4,7 @@ # require 'spec_helper' -describe AspectMembership do +describe AspectMembership, :type => :model do describe '#before_destroy' do before do @@ -12,17 +12,17 @@ describe AspectMembership do @contact = alice.contact_for(bob.person) @am = alice.aspects.where(:name => "generic").first.aspect_memberships.first - @am.stub(:user).and_return(alice) + allow(@am).to receive(:user).and_return(alice) end it 'calls disconnect if its the last aspect for the contact' do - alice.should_receive(:disconnect).with(@contact) + expect(alice).to receive(:disconnect).with(@contact) @am.destroy end it 'does not call disconnect if its not the last aspect for the contact' do - alice.should_not_receive(:disconnect) + expect(alice).not_to receive(:disconnect) alice.add_contact_to_aspect(@contact, @aspect) @am.destroy diff --git a/spec/models/aspect_spec.rb b/spec/models/aspect_spec.rb index a9aac12f8..4315345ae 100644 --- a/spec/models/aspect_spec.rb +++ b/spec/models/aspect_spec.rb @@ -4,40 +4,40 @@ require 'spec_helper' -describe Aspect do +describe Aspect, :type => :model do describe 'creation' do before do @name = alice.aspects.first.name end it 'does not allow duplicate names' do - lambda { + expect { invalid_aspect = alice.aspects.create(:name => @name) - }.should_not change(Aspect, :count) + }.not_to change(Aspect, :count) end it 'validates case insensitiveness on names' do - lambda { + expect { invalid_aspect = alice.aspects.create(:name => @name.titleize) - }.should_not change(Aspect, :count) + }.not_to change(Aspect, :count) end it 'has a 20 character limit on names' do aspect = Aspect.new(:name => "this name is really too too too too too long") - aspect.valid?.should == false + expect(aspect.valid?).to eq(false) end it 'is able to have other users as contacts' do aspect = alice.aspects.create(:name => 'losers') Contact.create(:user => alice, :person => eve.person, :aspects => [aspect]) - aspect.contacts.where(:person_id => alice.person.id).should be_empty - aspect.contacts.where(:person_id => eve.person.id).should_not be_empty - aspect.contacts.size.should == 1 + expect(aspect.contacts.where(:person_id => alice.person.id)).to be_empty + expect(aspect.contacts.where(:person_id => eve.person.id)).not_to be_empty + expect(aspect.contacts.size).to eq(1) end it 'has a contacts_visible? method' do - alice.aspects.first.contacts_visible?.should be true + expect(alice.aspects.first.contacts_visible?).to be true end end @@ -45,7 +45,7 @@ describe Aspect do it 'has no uniqueness of name between users' do aspect = alice.aspects.create(:name => "New Aspect") aspect2 = eve.aspects.create(:name => aspect.name) - aspect2.should be_valid + expect(aspect2).to be_valid end end end diff --git a/spec/models/block_spec.rb b/spec/models/block_spec.rb index 5e3986aca..e8b3683a6 100644 --- a/spec/models/block_spec.rb +++ b/spec/models/block_spec.rb @@ -1,10 +1,10 @@ require 'spec_helper' -describe Block do +describe Block, :type => :model do describe 'validations' do it 'doesnt allow you to block yourself' do block = alice.blocks.create(:person => alice.person) - block.errors[:person_id].size.should == 1 + expect(block.errors[:person_id].size).to eq(1) end end end \ No newline at end of file diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index fdb06639b..a377d142a 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' require Rails.root.join("spec", "shared_behaviors", "relayable") -describe Comment do +describe Comment, :type => :model do before do @alices_aspect = alice.aspects.first @status = bob.post(:status_message, :text => "hello", :to => bob.aspects.first.id) @@ -14,12 +14,12 @@ describe Comment do describe 'comment#notification_type' do it "returns 'comment_on_post' if the comment is on a post you own" do comment = alice.comment!(@status, "why so formal?") - comment.notification_type(bob, alice.person).should == Notifications::CommentOnPost + expect(comment.notification_type(bob, alice.person)).to eq(Notifications::CommentOnPost) end it 'returns false if the comment is not on a post you own and no one "also_commented"' do comment = alice.comment!(@status, "I simply felt like issuing a greeting. Do step off.") - comment.notification_type(eve, alice.person).should be false + expect(comment.notification_type(eve, alice.person)).to be false end context "also commented" do @@ -29,11 +29,11 @@ describe Comment do end it 'does not return also commented if the user commented' do - @comment.notification_type(eve, alice.person).should == false + expect(@comment.notification_type(eve, alice.person)).to eq(false) end it "returns 'also_commented' if another person commented on a post you commented on" do - @comment.notification_type(alice, alice.person).should == Notifications::AlsoCommented + expect(@comment.notification_type(alice, alice.person)).to eq(Notifications::AlsoCommented) end end end @@ -41,26 +41,26 @@ describe Comment do describe 'User#comment' do it "should be able to comment on one's own status" do alice.comment!(@status, "Yeah, it was great") - @status.reload.comments.first.text.should == "Yeah, it was great" + expect(@status.reload.comments.first.text).to eq("Yeah, it was great") end it "should be able to comment on a contact's status" do bob.comment!(@status, "sup dog") - @status.reload.comments.first.text.should == "sup dog" + expect(@status.reload.comments.first.text).to eq("sup dog") end it 'does not multi-post a comment' do - lambda { + expect { alice.comment!(@status, 'hello') - }.should change { Comment.count }.by(1) + }.to change { Comment.count }.by(1) end end describe 'counter cache' do it 'increments the counter cache on its post' do - lambda { + expect { alice.comment!(@status, "oh yeah") - }.should change{ + }.to change{ @status.reload.comments_count }.by(1) end @@ -77,11 +77,11 @@ describe Comment do end it 'serializes the sender handle' do - @xml.include?(@commenter.diaspora_handle).should be true + expect(@xml.include?(@commenter.diaspora_handle)).to be true end it 'serializes the post_guid' do - @xml.should include(@post.guid) + expect(@xml).to include(@post.guid) end describe 'marshalling' do @@ -90,11 +90,11 @@ describe Comment do end it 'marshals the author' do - @marshalled_comment.author.should == @commenter.person + expect(@marshalled_comment.author).to eq(@commenter.person) end it 'marshals the post' do - @marshalled_comment.post.should == @post + expect(@marshalled_comment.post).to eq(@post) end end end diff --git a/spec/models/contact_spec.rb b/spec/models/contact_spec.rb index bb6dbd448..9f8370952 100644 --- a/spec/models/contact_spec.rb +++ b/spec/models/contact_spec.rb @@ -4,12 +4,12 @@ require 'spec_helper' -describe Contact do +describe Contact, :type => :model do describe 'aspect_memberships' do it 'deletes dependent aspect memberships' do - lambda{ + expect{ alice.contact_for(bob.person).destroy - }.should change(AspectMembership, :count).by(-1) + }.to change(AspectMembership, :count).by(-1) end end @@ -18,12 +18,12 @@ describe Contact do it 'requires a user' do contact.valid? - contact.errors.full_messages.should include "User can't be blank" + expect(contact.errors.full_messages).to include "User can't be blank" end it 'requires a person' do contact.valid? - contact.errors.full_messages.should include "Person can't be blank" + expect(contact.errors.full_messages).to include "Person can't be blank" end it 'ensures user is not making a contact for himself' do @@ -31,18 +31,18 @@ describe Contact do contact.user = alice contact.valid? - contact.errors.full_messages.should include "Cannot create self-contact" + expect(contact.errors.full_messages).to include "Cannot create self-contact" end it 'validates uniqueness' do person = FactoryGirl.create(:person) contact2 = alice.contacts.create(:person=>person) - contact2.should be_valid + expect(contact2).to be_valid contact.user = alice contact.person = person - contact.should_not be_valid + expect(contact).not_to be_valid end it "validates that the person's account is not closed" do @@ -50,18 +50,18 @@ describe Contact do contact = alice.contacts.new(:person=>person) - contact.should_not be_valid - contact.errors.full_messages.should include "Cannot be in contact with a closed account" + expect(contact).not_to be_valid + expect(contact.errors.full_messages).to include "Cannot be in contact with a closed account" end end context 'scope' do describe 'sharing' do it 'returns contacts with sharing true' do - lambda { + expect { alice.contacts.create!(:sharing => true, :person => FactoryGirl.create(:person)) alice.contacts.create!(:sharing => false, :person => FactoryGirl.create(:person)) - }.should change{ + }.to change{ Contact.sharing.count }.by(1) end @@ -69,10 +69,10 @@ describe Contact do describe 'receiving' do it 'returns contacts with sharing true' do - lambda { + expect { alice.contacts.create!(:receiving => true, :person => FactoryGirl.build(:person)) alice.contacts.create!(:receiving => false, :person => FactoryGirl.build(:person)) - }.should change{ + }.to change{ Contact.receiving.count }.by(1) end @@ -80,12 +80,12 @@ describe Contact do describe 'only_sharing' do it 'returns contacts with sharing true and receiving false' do - lambda { + expect { alice.contacts.create!(:receiving => true, :sharing => true, :person => FactoryGirl.build(:person)) alice.contacts.create!(:receiving => false, :sharing => true, :person => FactoryGirl.build(:person)) alice.contacts.create!(:receiving => false, :sharing => true, :person => FactoryGirl.build(:person)) alice.contacts.create!(:receiving => true, :sharing => false, :person => FactoryGirl.build(:person)) - }.should change{ + }.to change{ Contact.receiving.count }.by(2) end @@ -97,7 +97,7 @@ describe Contact do contact1 = FactoryGirl.create(:contact, :person => person) contact2 = FactoryGirl.create(:contact) contacts = Contact.all_contacts_of_person(person) - contacts.should == [contact1] + expect(contacts).to eq([contact1]) end end end @@ -137,19 +137,19 @@ describe Contact do end it "returns the target local user's contacts that are in the same aspect" do - @contact.contacts.map{|p| p.id}.should =~ [@eve.person].concat(@people1).map{|p| p.id} + expect(@contact.contacts.map{|p| p.id}).to match_array([@eve.person].concat(@people1).map{|p| p.id}) end it 'returns nothing if contacts_visible is false in that aspect' do @original_aspect.contacts_visible = false @original_aspect.save - @contact.contacts.should == [] + expect(@contact.contacts).to eq([]) end it 'returns no duplicate contacts' do [@alice, @eve].each {|c| @bob.add_contact_to_aspect(@bob.contact_for(c.person), @bob.aspects.last)} contact_ids = @contact.contacts.map{|p| p.id} - contact_ids.uniq.should == contact_ids + expect(contact_ids.uniq).to eq(contact_ids) end end @@ -158,7 +158,7 @@ describe Contact do @contact = @bob.contact_for @people1.first end it 'returns an empty array' do - @contact.contacts.should == [] + expect(@contact.contacts).to eq([]) end end end @@ -175,20 +175,20 @@ describe Contact do describe '#generate_request' do it 'makes a request' do - @contact.stub(:user).and_return(@user) + allow(@contact).to receive(:user).and_return(@user) request = @contact.generate_request - request.sender.should == @user.person - request.recipient.should == @person + expect(request.sender).to eq(@user.person) + expect(request.recipient).to eq(@person) end end describe '#dispatch_request' do it 'pushes to people' do - @contact.stub(:user).and_return(@user) + allow(@contact).to receive(:user).and_return(@user) m = double() - m.should_receive(:post) - Postzord::Dispatcher.should_receive(:build).and_return(m) + expect(m).to receive(:post) + expect(Postzord::Dispatcher).to receive(:build).and_return(m) @contact.dispatch_request end end @@ -200,7 +200,7 @@ describe Contact do end it "is called on validate" do - @contact.should_receive(:not_blocked_user) + expect(@contact).to receive(:not_blocked_user) @contact.valid? end @@ -209,11 +209,11 @@ describe Contact do block = alice.blocks.create(:person => person) bad_contact = alice.contacts.create(:person => person) - bad_contact.send(:not_blocked_user).should be false + expect(bad_contact.send(:not_blocked_user)).to be false end it "does not add to errors" do - @contact.send(:not_blocked_user).should be true + expect(@contact.send(:not_blocked_user)).to be true end end end diff --git a/spec/models/conversation_spec.rb b/spec/models/conversation_spec.rb index 69a54ea53..3a1c727aa 100644 --- a/spec/models/conversation_spec.rb +++ b/spec/models/conversation_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Conversation do +describe Conversation, :type => :model do before do @user1 = alice @user2 = bob @@ -19,16 +19,16 @@ describe Conversation do end it 'creates a message on create' do - lambda{ + expect{ Conversation.create(@create_hash) - }.should change(Message, :count).by(1) + }.to change(Message, :count).by(1) end describe '#last_author' do it 'returns the last author to a conversation' do cnv = Conversation.create(@create_hash) Message.create(:author => @user2.person, :created_at => Time.now + 100, :text => "last", :conversation_id => cnv.id) - cnv.reload.last_author.id.should == @user2.person.id + expect(cnv.reload.last_author.id).to eq(@user2.person.id) end end @@ -45,7 +45,7 @@ describe Conversation do it 'returns nil if there are no unread messages in a conversation' do @cnv.conversation_visibilities.where(:person_id => @user1.person.id).first.tap { |cv| cv.unread = 0 }.save - @cnv.first_unread_message(@user1).should be_nil + expect(@cnv.first_unread_message(@user1)).to be_nil end end @@ -58,23 +58,23 @@ describe Conversation do describe 'serialization' do it 'serializes the message' do - @xml.gsub(/\s/, '').should include(@message.to_xml.to_s.gsub(/\s/, '')) + expect(@xml.gsub(/\s/, '')).to include(@message.to_xml.to_s.gsub(/\s/, '')) end it 'serializes the participants' do @create_hash[:participant_ids].each{|id| - @xml.should include(Person.find(id).diaspora_handle) + expect(@xml).to include(Person.find(id).diaspora_handle) } end it 'serializes the created_at time' do - @xml.should include(@message.created_at.to_s) + expect(@xml).to include(@message.created_at.to_s) end end describe '#subscribers' do it 'returns the recipients for the post owner' do - @cnv.subscribers(@user1).should == @user1.contacts.map{|c| c.person} + expect(@cnv.subscribers(@user1)).to eq(@user1.contacts.map{|c| c.person}) end end @@ -85,25 +85,25 @@ describe Conversation do end it 'creates a message' do - lambda{ + expect{ Diaspora::Parser.from_xml(@xml).receive(@user1, @user2.person) - }.should change(Message, :count).by(1) + }.to change(Message, :count).by(1) end it 'creates a conversation' do - lambda{ + expect{ Diaspora::Parser.from_xml(@xml).receive(@user1, @user2.person) - }.should change(Conversation, :count).by(1) + }.to change(Conversation, :count).by(1) end it 'creates appropriate visibilities' do - lambda{ + expect{ Diaspora::Parser.from_xml(@xml).receive(@user1, @user2.person) - }.should change(ConversationVisibility, :count).by(@participant_ids.size) + }.to change(ConversationVisibility, :count).by(@participant_ids.size) end it 'does not save before receive' do - Diaspora::Parser.from_xml(@xml).persisted?.should be false + expect(Diaspora::Parser.from_xml(@xml).persisted?).to be false end it 'notifies for the message' do - Notification.should_receive(:notify).once + expect(Notification).to receive(:notify).once Diaspora::Parser.from_xml(@xml).receive(@user1, @user2.person) end end diff --git a/spec/models/invitation_code_spec.rb b/spec/models/invitation_code_spec.rb index 9596952dd..9e3e95185 100644 --- a/spec/models/invitation_code_spec.rb +++ b/spec/models/invitation_code_spec.rb @@ -1,13 +1,13 @@ require 'spec_helper' -describe InvitationCode do +describe InvitationCode, :type => :model do it 'has a valid factory' do - FactoryGirl.build(:invitation_code).should be_valid + expect(FactoryGirl.build(:invitation_code)).to be_valid end it 'sets the count to a default value' do code = FactoryGirl.create(:invitation_code) - code.count.should > 0 + expect(code.count).to be > 0 end describe '#use!' do @@ -31,12 +31,12 @@ describe InvitationCode do end it 'grabs the set admin account for the pod...' do - InvitationCode.default_inviter_or(alice).username.should == 'bob' + expect(InvitationCode.default_inviter_or(alice).username).to eq('bob') end it '..or the given user' do AppConfig.admins.account = '' - InvitationCode.default_inviter_or(alice).username.should == 'alice' + expect(InvitationCode.default_inviter_or(alice).username).to eq('alice') end end end diff --git a/spec/models/invitation_spec.rb b/spec/models/invitation_spec.rb index 8701bc50b..539b61582 100644 --- a/spec/models/invitation_spec.rb +++ b/spec/models/invitation_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Invitation do +describe Invitation, :type => :model do let(:user) { alice } before do @@ -17,35 +17,35 @@ describe Invitation do end it 'is valid' do - @invitation.sender.should == user - @invitation.recipient.should == nil - @invitation.aspect.should == user.aspects.first - @invitation.language.should == "de" - @invitation.should be_valid + expect(@invitation.sender).to eq(user) + expect(@invitation.recipient).to eq(nil) + expect(@invitation.aspect).to eq(user.aspects.first) + expect(@invitation.language).to eq("de") + expect(@invitation).to be_valid end it 'ensures the sender is placing the recipient into one of his aspects' do @invitation.aspect = FactoryGirl.build(:aspect) - @invitation.should_not be_valid + expect(@invitation).not_to be_valid end end describe '#language' do it 'returns the correct language if the language is set' do @invitation = FactoryGirl.build(:invitation, :sender => user, :recipient => eve, :aspect => user.aspects.first, :language => "de") - @invitation.language.should == "de" + expect(@invitation.language).to eq("de") end it 'returns en if no language is set' do @invitation = FactoryGirl.build(:invitation, :sender => user, :recipient => eve, :aspect => user.aspects.first) - @invitation.language.should == "en" + expect(@invitation.language).to eq("en") end end it 'has a message' do @invitation = FactoryGirl.build(:invitation, :sender => user, :recipient => eve, :aspect => user.aspects.first, :language => user.language) @invitation.message = "!" - @invitation.message.should == "!" + expect(@invitation.message).to eq("!") end @@ -57,8 +57,8 @@ describe Invitation do it 'returns an array of invites based on the emails passed in' do invites = Invitation.batch_invite(@emails, @opts) - invites.count.should be 2 - invites.all?{|x| x.persisted?}.should be true + expect(invites.count).to be 2 + expect(invites.all?{|x| x.persisted?}).to be true end it 'shares with people who are already on the pod' do @@ -67,7 +67,7 @@ describe Invitation do expect{ invites = Invitation.batch_invite(@emails, @opts) }.to change(eve.contacts, :count).by(1) - invites.count.should be 2 + expect(invites.count).to be 2 end end diff --git a/spec/models/like_spec.rb b/spec/models/like_spec.rb index 657a0a37e..11532bff6 100644 --- a/spec/models/like_spec.rb +++ b/spec/models/like_spec.rb @@ -5,13 +5,13 @@ require 'spec_helper' require Rails.root.join("spec", "shared_behaviors", "relayable") -describe Like do +describe Like, :type => :model do before do @status = bob.post(:status_message, :text => "hello", :to => bob.aspects.first.id) end it 'has a valid factory' do - FactoryGirl.build(:like).should be_valid + expect(FactoryGirl.build(:like)).to be_valid end describe '#notification_type' do @@ -20,30 +20,30 @@ describe Like do end it 'should be notifications liked if you are the post owner' do - @like.notification_type(bob, alice.person).should be Notifications::Liked + expect(@like.notification_type(bob, alice.person)).to be Notifications::Liked end it 'should not notify you if you are the like-r' do - @like.notification_type(alice, alice.person).should be_nil + expect(@like.notification_type(alice, alice.person)).to be_nil end it 'should not notify you if you did not create the post' do - @like.notification_type(eve, alice.person).should be_nil + expect(@like.notification_type(eve, alice.person)).to be_nil end end describe 'counter cache' do it 'increments the counter cache on its post' do - lambda { + expect { alice.like!(@status) - }.should change{ @status.reload.likes_count }.by(1) + }.to change{ @status.reload.likes_count }.by(1) end it 'increments the counter cache on its comment' do comment = FactoryGirl.create(:comment, :post => @status) - lambda { + expect { alice.like!(comment) - }.should change{ comment.reload.likes_count }.by(1) + }.to change{ comment.reload.likes_count }.by(1) end end @@ -59,20 +59,20 @@ describe Like do @xml = @like.to_xml.to_s end it 'serializes the sender handle' do - @xml.include?(@liker.diaspora_handle).should be true + expect(@xml.include?(@liker.diaspora_handle)).to be true end it' serializes the post_guid' do - @xml.should include(@post.guid) + expect(@xml).to include(@post.guid) end describe 'marshalling' do before do @marshalled_like = Like.from_xml(@xml) end it 'marshals the author' do - @marshalled_like.author.should == @liker.person + expect(@marshalled_like.author).to eq(@liker.person) end it 'marshals the post' do - @marshalled_like.target.should == @post + expect(@marshalled_like.target).to eq(@post) end end end diff --git a/spec/models/location_spec.rb b/spec/models/location_spec.rb index f3c45d654..94eb12a08 100644 --- a/spec/models/location_spec.rb +++ b/spec/models/location_spec.rb @@ -1,15 +1,15 @@ require 'spec_helper' -describe Location do +describe Location, :type => :model do describe 'before validation' do it 'should create new location when it has coordinates' do location = Location.new(coordinates:'1,2') - location.save.should be true + expect(location.save).to be true end it 'should not create new location when it does not have coordinates' do location = Location.new() - location.save.should be false + expect(location.save).to be false end end end diff --git a/spec/models/mention_spec.rb b/spec/models/mention_spec.rb index bb4b9e507..27444cbc5 100644 --- a/spec/models/mention_spec.rb +++ b/spec/models/mention_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Mention do +describe Mention, :type => :model do describe "#notify_recipient" do before do @user = alice @@ -14,12 +14,12 @@ describe Mention do it 'notifies the person being mentioned' do sm = @user.build_post(:status_message, :text => "hi @{#{bob.name}; #{bob.diaspora_handle}}", :to => @user.aspects.first) - Notification.should_receive(:notify).with(bob, anything(), sm.author) + expect(Notification).to receive(:notify).with(bob, anything(), sm.author) sm.receive(bob, alice.person) end it 'should not notify a user if they do not see the message' do - Notification.should_not_receive(:notify).with(alice, anything(), bob.person) + expect(Notification).not_to receive(:notify).with(alice, anything(), bob.person) sm2 = bob.build_post(:status_message, :text => "stuff @{#{alice.name}; #{alice.diaspora_handle}}", :to => bob.aspects.first) sm2.receive(eve, bob.person) end @@ -27,7 +27,7 @@ describe Mention do describe '#notification_type' do it "returns 'mentioned'" do - Mention.new.notification_type.should == Notifications::Mentioned + expect(Mention.new.notification_type).to eq(Notifications::Mentioned) end end @@ -40,9 +40,9 @@ describe Mention do @m = Mention.create!(:person => @mentioned_user.person, :post => @sm) @m.notify_recipient - lambda{ + expect{ @m.destroy - }.should change(Notification, :count).by(-1) + }.to change(Notification, :count).by(-1) end end end diff --git a/spec/models/message_spec.rb b/spec/models/message_spec.rb index 08b718c69..327348125 100644 --- a/spec/models/message_spec.rb +++ b/spec/models/message_spec.rb @@ -5,7 +5,7 @@ require 'spec_helper' require Rails.root.join("spec", "shared_behaviors", "relayable") -describe Message do +describe Message, :type => :model do before do @create_hash = { :author => bob.person, @@ -21,44 +21,44 @@ describe Message do it 'validates that the author is a participant in the conversation' do message = Message.new(:text => 'yo', :author => eve.person, :conversation_id => @conversation.id) - message.should_not be_valid + expect(message).not_to be_valid end describe '#notification_type' do it 'does not return anything for the author' do - @message.notification_type(bob, bob.person).should be_nil + expect(@message.notification_type(bob, bob.person)).to be_nil end it 'returns private mesage for an actual receiver' do - @message.notification_type(alice, bob.person).should == Notifications::PrivateMessage + expect(@message.notification_type(alice, bob.person)).to eq(Notifications::PrivateMessage) end end describe '#before_create' do it 'signs the message' do - @message.author_signature.should_not be_blank + expect(@message.author_signature).not_to be_blank end it 'signs the message author if author of conversation' do - @message.parent_author_signature.should_not be_blank + expect(@message.parent_author_signature).not_to be_blank end end describe 'serialization' do it 'serializes the text' do - @xml.should include(@message.text) + expect(@xml).to include(@message.text) end it 'serializes the author_handle' do - @xml.should include(@message.author.diaspora_handle) + expect(@xml).to include(@message.author.diaspora_handle) end it 'serializes the created_at time' do - @xml.should include(@message.created_at.to_s) + expect(@xml).to include(@message.created_at.to_s) end it 'serializes the conversation_guid time' do - @xml.should include(@message.conversation.guid) + expect(@xml).to include(@message.conversation.guid) end end @@ -98,12 +98,12 @@ describe Message do describe '#increase_unread' do it 'increments the conversation visiblity for the conversation' do - ConversationVisibility.where(:conversation_id => @object_by_recipient.reload.conversation.id, - :person_id => @local_luke.person.id).first.unread.should == 0 + expect(ConversationVisibility.where(:conversation_id => @object_by_recipient.reload.conversation.id, + :person_id => @local_luke.person.id).first.unread).to eq(0) @object_by_recipient.increase_unread(@local_luke) - ConversationVisibility.where(:conversation_id => @object_by_recipient.reload.conversation.id, - :person_id => @local_luke.person.id).first.unread.should == 1 + expect(ConversationVisibility.where(:conversation_id => @object_by_recipient.reload.conversation.id, + :person_id => @local_luke.person.id).first.unread).to eq(1) end end end diff --git a/spec/models/notification_spec.rb b/spec/models/notification_spec.rb index a0ec2c641..e3644db8c 100644 --- a/spec/models/notification_spec.rb +++ b/spec/models/notification_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Notification do +describe Notification, :type => :model do before do @sm = FactoryGirl.create(:status_message) @person = FactoryGirl.create(:person) @@ -21,7 +21,7 @@ describe Notification do it 'destoys the associated notification_actor' do @note.save - lambda{@note.destroy}.should change(NotificationActor, :count).by(-1) + expect{@note.destroy}.to change(NotificationActor, :count).by(-1) end describe '.for' do @@ -34,7 +34,7 @@ describe Notification do @opts.delete(:recipient_id) Notification.create(@opts.merge(:recipient_id => user2.id)) - Notification.for(@user).count.should == 4 + expect(Notification.for(@user).count).to eq(4) end end @@ -42,12 +42,12 @@ describe Notification do it "should set an unread notification to read" do @note.unread = true @note.set_read_state( true ) - @note.unread.should == false + expect(@note.unread).to eq(false) end it "should set an read notification to unread" do @note.unread = false @note.set_read_state( false ) - @note.unread.should == true + expect(@note.unread).to eq(true) end end @@ -57,9 +57,9 @@ describe Notification do it 'creates a new notificiation if the notification does not exist, or if it is unread' do @note.unread = false @note.save - Notification.count.should == 1 + expect(Notification.count).to eq(1) Notification.concatenate_or_create(@note.recipient, @note.target, @note.actors.first, Notifications::CommentOnPost) - Notification.count.should == 2 + expect(Notification.count).to eq(2) end end describe '.notify' do @@ -69,7 +69,7 @@ describe Notification do end it 'calls Notification.create if the object has a notification_type' do - Notification.should_receive(:make_notification).once + expect(Notification).to receive(:make_notification).once Notification.notify(@user, @request, @person) end @@ -80,9 +80,9 @@ describe Notification do :recipient_id => @user.id} n = Notifications::StartedSharing.new(opts) - n.stub(:recipient).and_return @user + allow(n).to receive(:recipient).and_return @user - @user.should_receive(:mail) + expect(@user).to receive(:mail) n.email_the_user(@request, @person) end end @@ -93,7 +93,7 @@ describe Notification do person2 = FactoryGirl.build(:person) notification = Notification.notify(@user, FactoryGirl.build(:like, :author => @person, :target => p), @person) notification2 = Notification.notify(@user, FactoryGirl.build(:like, :author => person2, :target => p), person2) - notification.id.should == notification2.id + expect(notification.id).to eq(notification2.id) end end @@ -103,7 +103,7 @@ describe Notification do person2 = FactoryGirl.build(:person) notification = Notification.notify(@user, FactoryGirl.build(:comment, :author => @person, :post => p), @person) notification2 = Notification.notify(@user, FactoryGirl.build(:comment, :author => person2, :post => p), person2) - notification.id.should == notification2.id + expect(notification.id).to eq(notification2.id) end end @@ -116,12 +116,12 @@ describe Notification do end it "updates the notification with a more people if one already exists" do - Notification.where(:recipient_id => @user3.id, :target_type => @sm.class.base_class, :target_id => @sm.id).first.actors.count.should == 2 + expect(Notification.where(:recipient_id => @user3.id, :target_type => @sm.class.base_class, :target_id => @sm.id).first.actors.count).to eq(2) end it 'handles double comments from the same person without raising' do Postzord::Receiver::Private.new(@user3, :person => @user2.person, :object => @user2.comment!(@sm, "hey")).receive_object - Notification.where(:recipient_id => @user3.id, :target_type => @sm.class.base_class, :target_id => @sm.id).first.actors.count.should == 2 + expect(Notification.where(:recipient_id => @user3.id, :target_type => @sm.class.base_class, :target_id => @sm.id).first.actors.count).to eq(2) end end end diff --git a/spec/models/notifications/private_message_spec.rb b/spec/models/notifications/private_message_spec.rb index f9ccffd14..60c62b8aa 100644 --- a/spec/models/notifications/private_message_spec.rb +++ b/spec/models/notifications/private_message_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Notifications::PrivateMessage do +describe Notifications::PrivateMessage, :type => :model do before do @user1 = alice @user2 = bob @@ -22,9 +22,9 @@ describe Notifications::PrivateMessage do describe '#make_notifiaction' do it 'does not save the notification' do - lambda{ + expect{ Notification.notify(@user2, @msg, @user1.person) - }.should_not change(Notification, :count) + }.not_to change(Notification, :count) end it 'does email the user' do @@ -33,11 +33,11 @@ describe Notifications::PrivateMessage do :recipient_id => @user2.id} n = Notifications::PrivateMessage.new(opts) - Notifications::PrivateMessage.stub(:make_notification).and_return(n) + allow(Notifications::PrivateMessage).to receive(:make_notification).and_return(n) Notification.notify(@user2, @msg, @user1.person) - n.stub(:recipient).and_return @user2 + allow(n).to receive(:recipient).and_return @user2 - @user2.should_receive(:mail) + expect(@user2).to receive(:mail) n.email_the_user(@msg, @user1.person) end @@ -49,8 +49,8 @@ describe Notifications::PrivateMessage do message.save n = Notifications::PrivateMessage.make_notification(@user2, message, @user1.person, Notifications::PrivateMessage) - ConversationVisibility.where(:conversation_id => message.reload.conversation.id, - :person_id => @user2.person.id).first.unread.should == 1 + expect(ConversationVisibility.where(:conversation_id => message.reload.conversation.id, + :person_id => @user2.person.id).first.unread).to eq(1) end it 'increases user unread count - author user 2' do @@ -61,8 +61,8 @@ describe Notifications::PrivateMessage do message.save n = Notifications::PrivateMessage.make_notification(@user1, message, @user2.person, Notifications::PrivateMessage) - ConversationVisibility.where(:conversation_id => message.reload.conversation.id, - :person_id => @user1.person.id).first.unread.should == 1 + expect(ConversationVisibility.where(:conversation_id => message.reload.conversation.id, + :person_id => @user1.person.id).first.unread).to eq(1) end end diff --git a/spec/models/notifications/reshared_spec.rb b/spec/models/notifications/reshared_spec.rb index fdd709f82..58836069c 100644 --- a/spec/models/notifications/reshared_spec.rb +++ b/spec/models/notifications/reshared_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Notifications::Reshared do +describe Notifications::Reshared, :type => :model do before do @sm = FactoryGirl.build(:status_message, :author => alice.person, :public => true) @reshare1 = FactoryGirl.build(:reshare, :root => @sm) @@ -13,7 +13,7 @@ describe Notifications::Reshared do describe 'Notification.notify' do it 'calls concatenate_or_create with root post' do - Notifications::Reshared.should_receive(:concatenate_or_create).with(alice, @reshare1.root, @reshare1.author, Notifications::Reshared) + expect(Notifications::Reshared).to receive(:concatenate_or_create).with(alice, @reshare1.root, @reshare1.author, Notifications::Reshared) Notification.notify(alice, @reshare1, @reshare1.author) end @@ -21,23 +21,23 @@ describe Notifications::Reshared do describe '#mail_job' do it "does not raise" do - lambda{ + expect{ Notifications::Reshared.new.mail_job - }.should_not raise_error + }.not_to raise_error end end describe '#concatenate_or_create' do it 'creates a new notification if one does not already exist' do - Notifications::Reshared.should_receive(:make_notification).with(alice, @reshare1.root, @reshare1.author, Notifications::Reshared) + expect(Notifications::Reshared).to receive(:make_notification).with(alice, @reshare1.root, @reshare1.author, Notifications::Reshared) Notifications::Reshared.concatenate_or_create(alice, @reshare1.root, @reshare1.author, Notifications::Reshared) end it "appends the actors to the aldeady existing notification" do note = Notifications::Reshared.make_notification(alice, @reshare1.root, @reshare1.author, Notifications::Reshared) - lambda{ + expect{ Notifications::Reshared.concatenate_or_create(alice, @reshare2.root, @reshare2.author, Notifications::Reshared) - }.should change(note.actors, :count).by(1) + }.to change(note.actors, :count).by(1) end end end diff --git a/spec/models/participation_spec.rb b/spec/models/participation_spec.rb index af93bc105..658c0cc8e 100644 --- a/spec/models/participation_spec.rb +++ b/spec/models/participation_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe Participation do +describe Participation, :type => :model do describe 'it is relayable' do before do @status = bob.post(:status_message, :text => "hello", :to => bob.aspects.first.id) diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb index 809435b3b..f6bc6f123 100644 --- a/spec/models/person_spec.rb +++ b/spec/models/person_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Person do +describe Person, :type => :model do before do @user = bob @@ -12,20 +12,20 @@ describe Person do end it 'always has a profile' do - Person.new.profile.should_not be_nil + expect(Person.new.profile).not_to be_nil end it 'does not save automatically' do - Person.new.persisted?.should be false - Person.new.profile.persisted?.should be false + expect(Person.new.persisted?).to be false + expect(Person.new.profile.persisted?).to be false end context 'scopes' do describe '.for_json' do it 'does not select public keys' do - proc { + expect { Person.for_json.first.serialized_public_key - }.should raise_error ActiveModel::MissingAttributeError + }.to raise_error ActiveModel::MissingAttributeError end it 'selects distinct people' do @@ -35,7 +35,7 @@ describe Person do where(:contacts => {:user_id => bob.id}, :aspect_memberships => {:aspect_id => bob.aspect_ids}).map{|p| p.id} - person_ids.uniq.should == person_ids + expect(person_ids.uniq).to eq(person_ids) end end @@ -53,11 +53,11 @@ describe Person do describe '.find_person_from_guid_or_username' do it 'searchs for a person if id is passed' do - Person.find_from_guid_or_username(:id => @person.guid).id.should == @person.id + expect(Person.find_from_guid_or_username(:id => @person.guid).id).to eq(@person.id) end it 'searchs a person from a user if username is passed' do - Person.find_from_guid_or_username(:username => @user.username).id.should == @user.person.id + expect(Person.find_from_guid_or_username(:username => @user.username).id).to eq(@user.person.id) end it 'throws active record not found exceptions if no person is found via id' do @@ -76,17 +76,17 @@ describe Person do describe '.all_from_aspects' do it "pulls back the right people given all a user's aspects" do aspect_ids = bob.aspects.map(&:id) - Person.all_from_aspects(aspect_ids, bob).map(&:id).should =~ bob.contacts.includes(:person).map{|c| c.person.id} + expect(Person.all_from_aspects(aspect_ids, bob).map(&:id)).to match_array(bob.contacts.includes(:person).map{|c| c.person.id}) end it "pulls back the right people given a subset of aspects" do aspect_ids = bob.aspects.first.id - Person.all_from_aspects(aspect_ids, bob).map(&:id).should =~ bob.aspects.first.contacts.includes(:person).map{|c| c.person.id} + expect(Person.all_from_aspects(aspect_ids, bob).map(&:id)).to match_array(bob.aspects.first.contacts.includes(:person).map{|c| c.person.id}) end it "respects aspects given a user" do aspect_ids = alice.aspects.map(&:id) - Person.all_from_aspects(aspect_ids, bob).map(&:id).should == [] + expect(Person.all_from_aspects(aspect_ids, bob).map(&:id)).to eq([]) end end @@ -94,33 +94,33 @@ describe Person do it 'pulls back users who reshared the status message of a user' do sm = FactoryGirl.create(:status_message, :author => alice.person, :public => true) reshare = FactoryGirl.create(:reshare, :root => sm) - Person.who_have_reshared_a_users_posts(alice).should == [reshare.author] + expect(Person.who_have_reshared_a_users_posts(alice)).to eq([reshare.author]) end end end describe "delegating" do it "delegates last_name to the profile" do - @person.last_name.should == @person.profile.last_name + expect(@person.last_name).to eq(@person.profile.last_name) @person.profile.update_attributes(:last_name => "Heathers") - @person.reload.last_name.should == "Heathers" + expect(@person.reload.last_name).to eq("Heathers") end end describe "valid url" do it 'should allow for https urls' do person = FactoryGirl.build(:person, :url => "https://example.com") - person.should be_valid + expect(person).to be_valid end it 'should always return the correct receive url' do person = FactoryGirl.build(:person, :url => "https://example.com/a/bit/messed/up") - person.receive_url.should == "https://example.com/receive/users/#{person.guid}/" + expect(person.receive_url).to eq("https://example.com/receive/users/#{person.guid}/") end it 'should allow ports in the url' do person = FactoryGirl.build(:person, :url => "https://example.com:3000/") - person.url.should == "https://example.com:3000/" + expect(person.url).to eq("https://example.com:3000/") end end @@ -128,31 +128,31 @@ describe Person do context 'local people' do it 'uses the pod config url to set the diaspora_handle' do new_person = User.build(:username => "foo123", :email => "foo123@example.com", :password => "password", :password_confirmation => "password").person - new_person.diaspora_handle.should == "foo123#{User.diaspora_id_host}" + expect(new_person.diaspora_handle).to eq("foo123#{User.diaspora_id_host}") end it 'does not include www if it is set in app config' do - AppConfig.stub(:pod_uri).and_return(Addressable::URI.parse('https://www.foobar.com/')) + allow(AppConfig).to receive(:pod_uri).and_return(Addressable::URI.parse('https://www.foobar.com/')) new_person = User.build(:username => "foo123", :email => "foo123@example.com", :password => "password", :password_confirmation => "password").person - new_person.diaspora_handle.should == "foo123@foobar.com" + expect(new_person.diaspora_handle).to eq("foo123@foobar.com") end end context 'remote people' do it 'stores the diaspora_handle in the database' do - @person.diaspora_handle.include?(AppConfig.pod_uri.host).should be false + expect(@person.diaspora_handle.include?(AppConfig.pod_uri.host)).to be false end end describe 'validation' do it 'is unique' do person_two = FactoryGirl.build(:person, :diaspora_handle => @person.diaspora_handle) - person_two.should_not be_valid + expect(person_two).not_to be_valid end it 'is case insensitive' do person_two = FactoryGirl.build(:person, :diaspora_handle => @person.diaspora_handle.upcase) - person_two.should_not be_valid + expect(person_two).not_to be_valid end end end @@ -165,25 +165,25 @@ describe Person do context 'with only first name' do it 'should return their first name for name' do - Person.name_from_attrs(@profile.first_name, nil, @profile.diaspora_handle).should == @profile.first_name.strip + expect(Person.name_from_attrs(@profile.first_name, nil, @profile.diaspora_handle)).to eq(@profile.first_name.strip) end end context 'with only last name' do it 'should return their last name for name' do - Person.name_from_attrs(nil, @profile.last_name, @profile.diaspora_handle).should == @profile.last_name.strip + expect(Person.name_from_attrs(nil, @profile.last_name, @profile.diaspora_handle)).to eq(@profile.last_name.strip) end end context 'with both first and last name' do it 'should return their composed name for name' do - Person.name_from_attrs(@profile.first_name, @profile.last_name, @profile.diaspora_handle).should == "#{@profile.first_name.strip} #{@profile.last_name.strip}" + expect(Person.name_from_attrs(@profile.first_name, @profile.last_name, @profile.diaspora_handle)).to eq("#{@profile.first_name.strip} #{@profile.last_name.strip}") end end context 'without first nor last name' do it 'should display their diaspora handle' do - Person.name_from_attrs(nil, nil, @profile.diaspora_handle).should == @profile.diaspora_handle + expect(Person.name_from_attrs(nil, nil, @profile.diaspora_handle)).to eq(@profile.diaspora_handle) end end end @@ -191,7 +191,7 @@ describe Person do describe '#name' do it 'calls Person.name_from_attrs' do profile = alice.person.profile - Person.should_receive(:name_from_attrs).with(profile.first_name, profile.last_name, profile.person.diaspora_handle) + expect(Person).to receive(:name_from_attrs).with(profile.first_name, profile.last_name, profile.person.diaspora_handle) alice.name end @@ -199,7 +199,7 @@ describe Person do profile = alice.person.profile profile.first_name = "maxwell " profile.last_name = "salzberg " - alice.name.should == "maxwell salzberg" + expect(alice.name).to eq("maxwell salzberg") end end @@ -209,11 +209,11 @@ describe Person do end it 'should serialize to xml' do - @xml.include?("person").should == true + expect(@xml.include?("person")).to eq(true) end it 'should have a profile in its xml' do - @xml.include?("first_name").should == true + expect(@xml.include?("first_name")).to eq(true) end end @@ -222,8 +222,8 @@ describe Person do person_message = FactoryGirl.create(:status_message, :author => @person) person_two = FactoryGirl.create(:person) - @person.owns?(person_message).should be true - person_two.owns?(person_message).should be false + expect(@person.owns?(person_message)).to be true + expect(person_two.owns?(person_message)).to be false end describe "disconnecting" do @@ -235,31 +235,31 @@ describe Person do it 'should not delete an orphaned contact' do @user.contacts.create(:person => @person, :aspects => [@aspect]) - lambda { @user.disconnect(@user.contact_for(@person)) }.should_not change(Person, :count) + expect { @user.disconnect(@user.contact_for(@person)) }.not_to change(Person, :count) end it 'should not delete an un-orphaned contact' do @user.contacts.create(:person => @person, :aspects => [@aspect]) @user2.contacts.create(:person => @person, :aspects => [@aspect2]) - lambda { @user.disconnect(@user.contact_for(@person)) }.should_not change(Person, :count) + expect { @user.disconnect(@user.contact_for(@person)) }.not_to change(Person, :count) end end describe "#first_name" do it 'returns username if first_name is not present in profile' do alice.person.profile.update_attributes(:first_name => "") - alice.person.first_name.should == alice.username + expect(alice.person.first_name).to eq(alice.username) end it 'returns first words in first_name if first_name is present' do alice.person.profile.update_attributes(:first_name => "First Mid Last") - alice.person.first_name.should == "First Mid" + expect(alice.person.first_name).to eq("First Mid") end it 'returns first word in first_name if first_name is present' do alice.person.profile.update_attributes(:first_name => "Alice") - alice.person.first_name.should == "Alice" + expect(alice.person.first_name).to eq("Alice") end end @@ -311,49 +311,49 @@ describe Person do @casey_grippi.profile.save! people = Person.search("AAA", @user) - people.map { |p| p.name }.should == [@yevgeniy_dodis, @robert_grimm, @casey_grippi, @eugene_weinstein].map { |p| p.name } + expect(people.map { |p| p.name }).to eq([@yevgeniy_dodis, @robert_grimm, @casey_grippi, @eugene_weinstein].map { |p| p.name }) end it 'returns nothing on an empty query' do people = Person.search("", @user) - people.should be_empty + expect(people).to be_empty end it 'returns nothing on a one-character query' do people = Person.search("i", @user) - people.should be_empty + expect(people).to be_empty end it 'returns results for partial names' do people = Person.search("Eug", @user) - people.count.should == 1 - people.first.should == @eugene_weinstein + expect(people.count).to eq(1) + expect(people.first).to eq(@eugene_weinstein) people = Person.search("wEi", @user) - people.count.should == 1 - people.first.should == @eugene_weinstein + expect(people.count).to eq(1) + expect(people.first).to eq(@eugene_weinstein) people = Person.search("gri", @user) - people.count.should == 2 - people.first.should == @robert_grimm - people.second.should == @casey_grippi + expect(people.count).to eq(2) + expect(people.first).to eq(@robert_grimm) + expect(people.second).to eq(@casey_grippi) end it 'returns results for full names' do people = Person.search("Casey Grippi", @user) - people.count.should == 1 - people.first.should == @casey_grippi + expect(people.count).to eq(1) + expect(people.first).to eq(@casey_grippi) end it 'only displays searchable people' do invisible_person = FactoryGirl.build(:person, :profile => FactoryGirl.build(:profile, :searchable => false, :first_name => "johnson")) - Person.search("johnson", @user).should_not include invisible_person - Person.search("", @user).should_not include invisible_person + expect(Person.search("johnson", @user)).not_to include invisible_person + expect(Person.search("", @user)).not_to include invisible_person end it 'returns results for Diaspora handles' do people = Person.search(@robert_grimm.diaspora_handle, @user) - people.should == [@robert_grimm] + expect(people).to eq([@robert_grimm]) end it "puts the searching user's contacts first" do @@ -372,7 +372,7 @@ describe Person do @user.contacts.create(:person => @casey_grippi, :aspects => [@user.aspects.first]) people = Person.search("AAA", @user) - people.map { |p| p.name }.should == [@casey_grippi, @yevgeniy_dodis, @robert_grimm, @eugene_weinstein].map { |p| p.name } + expect(people.map { |p| p.name }).to eq([@casey_grippi, @yevgeniy_dodis, @robert_grimm, @eugene_weinstein].map { |p| p.name }) end end @@ -383,29 +383,29 @@ describe Person do describe '.by_account_identifier' do it 'should find a local users person' do p = Person.by_account_identifier(user.diaspora_handle) - p.should == user.person + expect(p).to eq(user.person) end it 'should find remote users person' do p = Person.by_account_identifier(person.diaspora_handle) - p.should == person + expect(p).to eq(person) end it 'should downcase and strip the diaspora_handle' do dh_upper = " " + user.diaspora_handle.upcase + " " - Person.by_account_identifier(dh_upper).should == user.person + expect(Person.by_account_identifier(dh_upper)).to eq(user.person) end it "finds a local person with a mixed-case username" do user = FactoryGirl.create(:user, :username => "SaMaNtHa") person = Person.by_account_identifier(user.person.diaspora_handle) - person.should == user.person + expect(person).to eq(user.person) end it "is case insensitive" do user1 = FactoryGirl.create(:user, :username => "SaMaNtHa") person = Person.by_account_identifier(user1.person.diaspora_handle.upcase) - person.should == user1.person + expect(person).to eq(user1.person) end it 'should only find people who are exact matches (1/2)' do @@ -413,14 +413,14 @@ describe Person do person = FactoryGirl.create(:person, :diaspora_handle => "tomtom@tom.joindiaspora.com") user.person.diaspora_handle = "tom@tom.joindiaspora.com" user.person.save - Person.by_account_identifier("tom@tom.joindiaspora.com").diaspora_handle.should == "tom@tom.joindiaspora.com" + expect(Person.by_account_identifier("tom@tom.joindiaspora.com").diaspora_handle).to eq("tom@tom.joindiaspora.com") end it 'should only find people who are exact matches (2/2)' do person = FactoryGirl.create(:person, :diaspora_handle => "tomtom@tom.joindiaspora.com") person1 = FactoryGirl.create(:person, :diaspora_handle => "tom@tom.joindiaspora.comm") f = Person.by_account_identifier("tom@tom.joindiaspora.com") - f.should be nil + expect(f).to be nil end @@ -429,46 +429,46 @@ describe Person do describe '.local_by_account_identifier' do it 'should find local users people' do p = Person.local_by_account_identifier(user.diaspora_handle) - p.should == user.person + expect(p).to eq(user.person) end it 'should not find a remote person' do p = Person.local_by_account_identifier(@person.diaspora_handle) - p.should be nil + expect(p).to be nil end it 'should call .by_account_identifier' do - Person.should_receive(:by_account_identifier) + expect(Person).to receive(:by_account_identifier) Person.local_by_account_identifier(@person.diaspora_handle) end end end describe '#has_photos?' do it 'returns false if the user has no photos' do - alice.person.has_photos?.should be false + expect(alice.person.has_photos?).to be false end it 'returns true if the user has photos' do alice.post(:photo, :user_file => uploaded_photo, :to => alice.aspects.first.id) - alice.person.has_photos?.should be true + expect(alice.person.has_photos?).to be true end end describe '#as_json' do it 'returns a hash representation of a person' do - @person.as_json.should == { + 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), - } + }) end it 'return tags if asked' do - @person.as_json(:includes => "tags"). - should == @person.as_json.merge(:tags => @person.profile.tags.map { |t| "##{t.name}" }) + expect(@person.as_json(:includes => "tags")). + to eq(@person.as_json.merge(:tags => @person.profile.tags.map { |t| "##{t.name}" })) end end @@ -476,11 +476,11 @@ describe Person do describe "when the pod owner hasn't set up any community spotlight members" do it 'returns people with the community spotlight role' do Role.add_spotlight(bob.person) - Person.community_spotlight.should be_present + expect(Person.community_spotlight).to be_present end it "returns an empty array" do - Person.community_spotlight.should == [] + expect(Person.community_spotlight).to eq([]) end end end @@ -494,7 +494,7 @@ describe Person do it "calls #update_person_url given an array of users and a url" do people = [double.as_null_object, double.as_null_object, double.as_null_object] people.each do |person| - person.should_receive(:update_url).with(@url) + expect(person).to receive(:update_url).with(@url) end Person.url_batch_update(people, @url) end @@ -514,7 +514,7 @@ describe Person do describe '#lock_access!' do it 'sets the closed_account flag' do @person.lock_access! - @person.reload.closed_account.should be true + expect(@person.reload.closed_account).to be true end end @@ -524,7 +524,7 @@ describe Person do end it 'calls Profile#tombstone!' do - @person.profile.should_receive(:tombstone!) + expect(@person.profile).to receive(:tombstone!) @person.clear_profile! end end diff --git a/spec/models/photo_spec.rb b/spec/models/photo_spec.rb index d6c1fd13d..5b568f401 100644 --- a/spec/models/photo_spec.rb +++ b/spec/models/photo_spec.rb @@ -11,7 +11,7 @@ def with_carrierwave_processing(&block) val end -describe Photo do +describe Photo, :type => :model do before do @user = alice @aspect = @user.aspects.first @@ -28,18 +28,18 @@ describe Photo do describe 'after_create' do it 'calls #queue_processing_job' do - @photo.should_receive(:queue_processing_job) + expect(@photo).to receive(:queue_processing_job) @photo.save! end end it 'is mutable' do - @photo.mutable?.should == true + expect(@photo.mutable?).to eq(true) end it 'has a random string key' do - @photo2.random_string.should_not be nil + expect(@photo2.random_string).not_to be nil end describe '#diaspora_initialize' do @@ -50,13 +50,13 @@ describe Photo do end it 'sets the persons diaspora handle' do - @photo.diaspora_handle.should == @user.person.diaspora_handle + expect(@photo.diaspora_handle).to eq(@user.person.diaspora_handle) end it 'sets the random prefix' do photo_double = double.as_null_object - photo_double.should_receive(:random_string=) - Photo.stub(:new).and_return(photo_double) + expect(photo_double).to receive(:random_string=) + allow(Photo).to receive(:new).and_return(photo_double) Photo.diaspora_initialize( :author => @user.person, :user_file => @image) @@ -64,8 +64,8 @@ describe Photo do context "with user file" do it 'builds the photo without saving' do - @photo.created_at.nil?.should be true - @photo.unprocessed_image.read.nil?.should be false + expect(@photo.created_at.nil?).to be true + expect(@photo.unprocessed_image.read.nil?).to be false end end @@ -74,8 +74,8 @@ describe Photo do url = "https://service.com/user/profile_image" photo_double = double.as_null_object - photo_double.should_receive(:remote_unprocessed_image_url=).with(url) - Photo.stub(:new).and_return(photo_double) + expect(photo_double).to receive(:remote_unprocessed_image_url=).with(url) + allow(Photo).to receive(:new).and_return(photo_double) Photo.diaspora_initialize( :author => @user.person, :image_url => url) @@ -94,19 +94,19 @@ describe Photo do it 'sets a remote url' do @photo.update_remote_path - @photo.remote_photo_path.should include("http") - @photo.remote_photo_name.should include(".png") + expect(@photo.remote_photo_path).to include("http") + expect(@photo.remote_photo_name).to include(".png") end end it 'should save a photo' do @photo.unprocessed_image.store! File.open(@fixture_name) - @photo.save.should == true + expect(@photo.save).to eq(true) binary = @photo.unprocessed_image.read.force_encoding('BINARY') fixture_binary = File.read(@fixture_name).force_encoding('BINARY') - binary.should == fixture_binary + expect(binary).to eq(fixture_binary) end context 'with a saved photo' do @@ -117,7 +117,7 @@ describe Photo do end it 'should have text' do @photo.text= "cool story, bro" - @photo.save.should be true + expect(@photo.save).to be true end it 'should remove its reference in user profile if it is referred' do @@ -126,26 +126,26 @@ describe Photo do @user.profile.image_url = @photo.url(:thumb_large) @user.person.save @photo.destroy - Person.find(@user.person.id).profile[:image_url].should be_nil + expect(Person.find(@user.person.id).profile[:image_url]).to be_nil end it 'should not use the imported filename as the url' do - @photo.url.should_not include @fixture_filename - @photo.url(:thumb_medium).should_not include ("/" + @fixture_filename) + expect(@photo.url).not_to include @fixture_filename + expect(@photo.url(:thumb_medium)).not_to include ("/" + @fixture_filename) end it 'should save the image dimensions' do - @photo.width.should == 40 - @photo.height.should == 40 + expect(@photo.width).to eq(40) + expect(@photo.height).to eq(40) end end describe 'non-image files' do it 'should not store' do file = File.open(@fail_fixture_name) - lambda { + expect { @photo.unprocessed_image.store! file - }.should raise_error CarrierWave::IntegrityError, 'You are not allowed to upload "xml" files, allowed types: jpg, jpeg, png, gif' + }.to raise_error CarrierWave::IntegrityError, 'You are not allowed to upload "xml" files, allowed types: jpg, jpeg, png, gif' end end @@ -159,18 +159,18 @@ describe Photo do end it 'serializes the url' do - @xml.include?(@saved_photo.remote_photo_path).should be true - @xml.include?(@saved_photo.remote_photo_name).should be true + expect(@xml.include?(@saved_photo.remote_photo_path)).to be true + expect(@xml.include?(@saved_photo.remote_photo_name)).to be true end it 'serializes the diaspora_handle' do - @xml.include?(@user.diaspora_handle).should be true + expect(@xml.include?(@user.diaspora_handle)).to be true end it 'serializes the height and width' do - @xml.should include 'height' - @xml.include?('width').should be true - @xml.include?('40').should be true + expect(@xml).to include 'height' + expect(@xml.include?('width')).to be true + expect(@xml.include?('40')).to be true end end @@ -195,21 +195,21 @@ describe Photo do zord.parse_and_receive(xml) new_photo = Photo.where(:guid => @saved_photo.guid).first - new_photo.url.nil?.should be false - new_photo.url.include?(url).should be true - new_photo.url(:thumb_medium).include?(thumb_url).should be true + expect(new_photo.url.nil?).to be false + expect(new_photo.url.include?(url)).to be true + expect(new_photo.url(:thumb_medium).include?(thumb_url)).to be true end end context "commenting" do it "accepts comments if there is no parent status message" do - proc{ @user.comment!(@photo, "big willy style") }.should change(@photo.comments, :count).by(1) + expect{ @user.comment!(@photo, "big willy style") }.to change(@photo.comments, :count).by(1) end end describe '#queue_processing_job' do it 'should queue a job to process the images' do - Workers::ProcessPhoto.should_receive(:perform_async).with(@photo.id) + expect(Workers::ProcessPhoto).to receive(:perform_async).with(@photo.id) @photo.queue_processing_job end end diff --git a/spec/models/pod_spec.rb b/spec/models/pod_spec.rb index 2e1b8e0b3..7aee2dfa2 100644 --- a/spec/models/pod_spec.rb +++ b/spec/models/pod_spec.rb @@ -1,15 +1,15 @@ require 'spec_helper' -describe Pod do +describe Pod, :type => :model do describe '.find_or_create_by' do it 'takes a url, and makes one by host' do pod = Pod.find_or_create_by(url: 'https://joindiaspora.com/maxwell') - pod.host.should == 'joindiaspora.com' + expect(pod.host).to eq('joindiaspora.com') end it 'sets ssl boolean(side-effect)' do pod = Pod.find_or_create_by(url: 'https://joindiaspora.com/maxwell') - pod.ssl.should be true + expect(pod.ssl).to be true end end end diff --git a/spec/models/poll_answer_spec.rb b/spec/models/poll_answer_spec.rb index 2f592fc05..4249a6af9 100644 --- a/spec/models/poll_answer_spec.rb +++ b/spec/models/poll_answer_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe PollAnswer do +describe PollAnswer, :type => :model do before do @status = FactoryGirl.create(:status_message_with_poll) @user = alice @@ -9,9 +9,9 @@ describe PollAnswer do describe 'counter cache' do it 'increments the counter cache on the answer' do - lambda { + expect { alice.participate_in_poll!(@status, @answer) - }.should change{ + }.to change{ @answer.reload.vote_count }.by(1) end @@ -22,12 +22,12 @@ describe PollAnswer do it 'should validate pressence of answer' do answer = PollAnswer.new answer.valid? - answer.errors.should have_key(:answer) + expect(answer.errors).to have_key(:answer) end it 'answer should not empty' do answer = PollAnswer.new answer: ' ' answer.valid? - answer.errors.should have_key(:answer) + expect(answer.errors).to have_key(:answer) end end diff --git a/spec/models/poll_participation_spec.rb b/spec/models/poll_participation_spec.rb index 8f8819e8a..3caa16e25 100644 --- a/spec/models/poll_participation_spec.rb +++ b/spec/models/poll_participation_spec.rb @@ -1,7 +1,7 @@ require 'spec_helper' require Rails.root.join("spec", "shared_behaviors", "relayable") -describe PollParticipation do +describe PollParticipation, :type => :model do before do @alices_aspect = alice.aspects.first @@ -44,19 +44,19 @@ describe PollParticipation do end it 'serializes the class name' do - @xml.include?(PollParticipation.name.underscore.to_s).should be true + expect(@xml.include?(PollParticipation.name.underscore.to_s)).to be true end it 'serializes the sender handle' do - @xml.include?(@poll_participation.diaspora_handle).should be true + expect(@xml.include?(@poll_participation.diaspora_handle)).to be true end it 'serializes the poll_guid' do - @xml.should include(@poll.guid) + expect(@xml).to include(@poll.guid) end it 'serializes the poll_answer_guid' do - @xml.should include(@poll_participation.poll_answer.guid) + expect(@xml).to include(@poll_participation.poll_answer.guid) end describe 'marshalling' do @@ -65,15 +65,15 @@ describe PollParticipation do end it 'marshals the author' do - @marshalled_poll_participation.author.should == @poll_participant.person + expect(@marshalled_poll_participation.author).to eq(@poll_participant.person) end it 'marshals the answer' do - @marshalled_poll_participation.poll_answer.should == @poll_participation.poll_answer + expect(@marshalled_poll_participation.poll_answer).to eq(@poll_participation.poll_answer) end it 'marshals the poll' do - @marshalled_poll_participation.poll.should == @poll + expect(@marshalled_poll_participation.poll).to eq(@poll) end end end @@ -94,8 +94,8 @@ describe PollParticipation do it 'is saved without errors in a simulated A-B node environment' do #stubs needed because the poll participation is already saved in the test db. This is just a simulated federation! - PollParticipation.any_instance.stub(:save!).and_return(true) - Person.any_instance.stub(:local?).and_return(false) + allow_any_instance_of(PollParticipation).to receive(:save!).and_return(true) + allow_any_instance_of(Person).to receive(:local?).and_return(false) expect{ salmon = Salmon::Slap.create_by_user_and_activity(alice, @poll_participation_alice.to_diaspora_xml).xml_for(@poll_participant) Postzord::Receiver::Public.new(salmon).save_object diff --git a/spec/models/poll_spec.rb b/spec/models/poll_spec.rb index 8970fe0ff..14e7af31a 100644 --- a/spec/models/poll_spec.rb +++ b/spec/models/poll_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Poll do +describe Poll, :type => :model do before do @poll = Poll.new(:question => "What do you think about apples?") end @@ -8,19 +8,19 @@ describe Poll do describe 'validation' do it 'should not create a poll when it has less than two answers' do @poll.poll_answers.build(:answer => '1') - @poll.should_not be_valid + expect(@poll).not_to be_valid end it 'should create a poll when it has more than two answers' do @poll.poll_answers.build(:answer => '1') @poll.poll_answers.build(:answer => '2') - @poll.should be_valid + expect(@poll).to be_valid end it 'should not create a poll when question in blank' do @poll.question = ' ' @poll.valid? - @poll.errors.should have_key(:question) + expect(@poll.errors).to have_key(:question) end end end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index aa2cb29d6..14137d2a3 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Post do +describe Post, :type => :model do before do @user = alice @aspect = @user.aspects.create(:name => "winners") @@ -21,29 +21,29 @@ describe Post do end it 'returns post from your contacts' do - StatusMessage.owned_or_visible_by_user(@you).should include(@post_from_contact) + expect(StatusMessage.owned_or_visible_by_user(@you)).to include(@post_from_contact) end it 'returns your posts' do - StatusMessage.owned_or_visible_by_user(@you).should include(@your_post) + expect(StatusMessage.owned_or_visible_by_user(@you)).to include(@your_post) end it 'returns public posts' do - StatusMessage.owned_or_visible_by_user(@you).should include(@public_post) + expect(StatusMessage.owned_or_visible_by_user(@you)).to include(@public_post) end it 'returns public post from your contact' do sm = FactoryGirl.create(:status_message, :author => eve.person, :public => true) - StatusMessage.owned_or_visible_by_user(@you).should include(sm) + expect(StatusMessage.owned_or_visible_by_user(@you)).to include(sm) end it 'does not return non contacts, non-public post' do - StatusMessage.owned_or_visible_by_user(@you).should_not include(@post_from_stranger) + expect(StatusMessage.owned_or_visible_by_user(@you)).not_to include(@post_from_stranger) end it 'should return the three visible posts' do - StatusMessage.owned_or_visible_by_user(@you).count(:all).should == 3 + expect(StatusMessage.owned_or_visible_by_user(@you).count(:all)).to eq(3) end end @@ -51,17 +51,17 @@ describe Post do describe '.for_a_stream' do it 'calls #for_visible_shareable_sql' do time, order = double, double - Post.should_receive(:for_visible_shareable_sql).with(time, order).and_return(Post) + expect(Post).to receive(:for_visible_shareable_sql).with(time, order).and_return(Post) Post.for_a_stream(time, order) end it 'calls includes_for_a_stream' do - Post.should_receive(:includes_for_a_stream) + expect(Post).to receive(:includes_for_a_stream) Post.for_a_stream(double, double) end it 'calls excluding_blocks if a user is present' do - Post.should_receive(:excluding_blocks).with(alice).and_return(Post) + expect(Post).to receive(:excluding_blocks).with(alice).and_return(Post) Post.for_a_stream(double, double, alice) end end @@ -75,15 +75,15 @@ describe Post do end it 'does not included blocked users posts' do - Post.excluding_blocks(bob).should_not include(@post) + expect(Post.excluding_blocks(bob)).not_to include(@post) end it 'includes not blocked users posts' do - Post.excluding_blocks(bob).should include(@other_post) + expect(Post.excluding_blocks(bob)).to include(@other_post) end it 'returns posts if you dont have any blocks' do - Post.excluding_blocks(alice).count.should == 2 + expect(Post.excluding_blocks(alice).count).to eq(2) end end @@ -94,17 +94,17 @@ describe Post do bob.toggle_hidden_shareable(@post) end it 'excludes posts the user has hidden' do - Post.excluding_hidden_shareables(bob).should_not include(@post) + expect(Post.excluding_hidden_shareables(bob)).not_to include(@post) end it 'includes posts the user has not hidden' do - Post.excluding_hidden_shareables(bob).should include(@other_post) + expect(Post.excluding_hidden_shareables(bob)).to include(@other_post) end end describe '.excluding_hidden_content' do it 'calls excluding_blocks and excluding_hidden_shareables' do - Post.should_receive(:excluding_blocks).and_return(Post) - Post.should_receive(:excluding_hidden_shareables) + expect(Post).to receive(:excluding_blocks).and_return(Post) + expect(Post).to receive(:excluding_hidden_shareables) Post.excluding_hidden_content(bob) end end @@ -127,8 +127,8 @@ describe Post do describe '.by_max_time' do it 'returns the posts ordered and limited by unix time' do - Post.for_a_stream(Time.now + 1, "created_at").should == @posts - Post.for_a_stream(Time.now + 1, "updated_at").should == @posts.reverse + expect(Post.for_a_stream(Time.now + 1, "created_at")).to eq(@posts) + expect(Post.for_a_stream(Time.now + 1, "updated_at")).to eq(@posts.reverse) end end @@ -136,15 +136,15 @@ describe Post do describe '.for_visible_shareable_sql' do it 'calls max_time' do time = Time.now + 1 - Post.should_receive(:by_max_time).with(time, 'created_at').and_return(Post) + expect(Post).to receive(:by_max_time).with(time, 'created_at').and_return(Post) Post.for_visible_shareable_sql(time, 'created_at') end it 'defaults to 15 posts' do chain = double.as_null_object - Post.stub(:by_max_time).and_return(chain) - chain.should_receive(:limit).with(15).and_return(Post) + allow(Post).to receive(:by_max_time).and_return(chain) + expect(chain).to receive(:limit).with(15).and_return(Post) Post.for_visible_shareable_sql(Time.now + 1, "created_at") end @@ -153,15 +153,15 @@ describe Post do # @posts[0] is the newest, @posts[5] is the oldest describe ".newer" do it 'returns the next post in the array' do - @posts[3].created_at.should < @posts[2].created_at #post 2 is newer - Post.newer(@posts[3]).created_at.to_s.should == @posts[2].created_at.to_s #its the newer post, not the newest + expect(@posts[3].created_at).to be < @posts[2].created_at #post 2 is newer + expect(Post.newer(@posts[3]).created_at.to_s).to eq(@posts[2].created_at.to_s) #its the newer post, not the newest end end describe ".older" do it 'returns the previous post in the array' do - Post.older(@posts[3]).created_at.to_s.should == @posts[4].created_at.to_s #its the older post, not the oldest - @posts[3].created_at.should > @posts[4].created_at #post 4 is older + expect(Post.older(@posts[3]).created_at.to_s).to eq(@posts[4].created_at.to_s) #its the older post, not the oldest + expect(@posts[3].created_at).to be > @posts[4].created_at #post 4 is older end end end @@ -170,14 +170,14 @@ describe Post do describe 'validations' do it 'validates uniqueness of guid and does not throw a db error' do message = FactoryGirl.create(:status_message) - FactoryGirl.build(:status_message, :guid => message.guid).should_not be_valid + expect(FactoryGirl.build(:status_message, :guid => message.guid)).not_to be_valid end end describe 'post_type' do it 'returns the class constant' do status_message = FactoryGirl.create(:status_message) - status_message.post_type.should == "StatusMessage" + expect(status_message.post_type).to eq("StatusMessage") end end @@ -186,8 +186,8 @@ describe Post do post = FactoryGirl.create(:status_message, :author => @user.person) @user.comment!(post, "hey") post.destroy - Post.where(:id => post.id).empty?.should == true - Comment.where(:text => "hey").empty?.should == true + expect(Post.where(:id => post.id).empty?).to eq(true) + expect(Comment.where(:text => "hey").empty?).to eq(true) end end @@ -196,22 +196,22 @@ describe Post do post = @user.post :status_message, :text => "hello", :to => @aspect.id xml = post.to_diaspora_xml - xml.include?("person_id").should be false - xml.include?(@user.person.diaspora_handle).should be true + expect(xml.include?("person_id")).to be false + expect(xml.include?(@user.person.diaspora_handle)).to be true end end describe '.diaspora_initialize' do it 'takes provider_display_name' do sm = FactoryGirl.create(:status_message, :provider_display_name => 'mobile') - StatusMessage.diaspora_initialize(sm.attributes.merge(:author => bob.person)).provider_display_name.should == 'mobile' + expect(StatusMessage.diaspora_initialize(sm.attributes.merge(:author => bob.person)).provider_display_name).to eq('mobile') end end describe '#mutable?' do it 'should be false by default' do post = @user.post :status_message, :text => "hello", :to => @aspect.id - post.mutable?.should == false + expect(post.mutable?).to eq(false) end end @@ -219,13 +219,13 @@ describe Post do it 'returns the people contained in the aspects the post appears in' do post = @user.post :status_message, :text => "hello", :to => @aspect.id - post.subscribers(@user).should == [] + expect(post.subscribers(@user)).to eq([]) end it 'returns all a users contacts if the post is public' do post = @user.post :status_message, :text => "hello", :to => @aspect.id, :public => true - post.subscribers(@user).to_set.should == @user.contact_people.to_set + expect(post.subscribers(@user).to_set).to eq(@user.contact_people.to_set) end end @@ -237,17 +237,17 @@ describe Post do it 'does not update updated_at' do old_time = Time.zone.now - 10000 Post.where(:id => @post.id).update_all(:updated_at => old_time) - @post.reload.updated_at.to_i.should == old_time.to_i + expect(@post.reload.updated_at.to_i).to eq(old_time.to_i) @post.update_likes_counter - @post.reload.updated_at.to_i.should == old_time.to_i + expect(@post.reload.updated_at.to_i).to eq(old_time.to_i) end end describe "#receive" do it 'returns false if the post does not verify' do @post = FactoryGirl.create(:status_message, :author => bob.person) - @post.should_receive(:verify_persisted_shareable).and_return(false) - @post.receive(bob, eve.person).should == false + expect(@post).to receive(:verify_persisted_shareable).and_return(false) + expect(@post.receive(bob, eve.person)).to eq(false) end end @@ -255,42 +255,42 @@ describe Post do before do @post = FactoryGirl.create(:status_message, :author => bob.person) @known_post = Post.new - bob.stub(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) + allow(bob).to receive(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) end context "user knows about the post" do before do - bob.stub(:find_visible_shareable_by_id).and_return(@known_post) + allow(bob).to receive(:find_visible_shareable_by_id).and_return(@known_post) end it 'updates attributes only if mutable' do - @known_post.stub(:mutable?).and_return(true) - @known_post.should_receive(:update_attributes) - @post.send(:receive_persisted, bob, eve.person, @known_post).should == true + allow(@known_post).to receive(:mutable?).and_return(true) + expect(@known_post).to receive(:update_attributes) + expect(@post.send(:receive_persisted, bob, eve.person, @known_post)).to eq(true) end it 'returns false if trying to update a non-mutable object' do - @known_post.stub(:mutable?).and_return(false) - @known_post.should_not_receive(:update_attributes) - @post.send(:receive_persisted, bob, eve.person, @known_post).should == false + allow(@known_post).to receive(:mutable?).and_return(false) + expect(@known_post).not_to receive(:update_attributes) + expect(@post.send(:receive_persisted, bob, eve.person, @known_post)).to eq(false) end end context "the user does not know about the post" do before do - bob.stub(:find_visible_shareable_by_id).and_return(nil) - bob.stub(:notify_if_mentioned).and_return(true) + allow(bob).to receive(:find_visible_shareable_by_id).and_return(nil) + allow(bob).to receive(:notify_if_mentioned).and_return(true) end it "receives the post from the contact of the author" do - @post.send(:receive_persisted, bob, eve.person, @known_post).should == true + expect(@post.send(:receive_persisted, bob, eve.person, @known_post)).to eq(true) end it 'notifies the user if they are mentioned' do - bob.stub(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) - bob.should_receive(:notify_if_mentioned).and_return(true) + allow(bob).to receive(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) + expect(bob).to receive(:notify_if_mentioned).and_return(true) - @post.send(:receive_persisted, bob, eve.person, @known_post).should == true + expect(@post.send(:receive_persisted, bob, eve.person, @known_post)).to eq(true) end end end @@ -299,25 +299,25 @@ describe Post do context "the user does not know about the post" do before do @post = FactoryGirl.create(:status_message, :author => bob.person) - bob.stub(:find_visible_shareable_by_id).and_return(nil) - bob.stub(:notify_if_mentioned).and_return(true) + allow(bob).to receive(:find_visible_shareable_by_id).and_return(nil) + allow(bob).to receive(:notify_if_mentioned).and_return(true) end it "it receives the post from the contact of the author" do - bob.should_receive(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) - @post.send(:receive_non_persisted, bob, eve.person).should == true + expect(bob).to receive(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) + expect(@post.send(:receive_non_persisted, bob, eve.person)).to eq(true) end it 'notifies the user if they are mentioned' do - bob.stub(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) - bob.should_receive(:notify_if_mentioned).and_return(true) + allow(bob).to receive(:contact_for).with(eve.person).and_return(double(:receive_shareable => true)) + expect(bob).to receive(:notify_if_mentioned).and_return(true) - @post.send(:receive_non_persisted, bob, eve.person).should == true + expect(@post.send(:receive_non_persisted, bob, eve.person)).to eq(true) end it 'returns false if the post does not save' do - @post.stub(:save).and_return(false) - @post.send(:receive_non_persisted, bob, eve.person).should == false + allow(@post).to receive(:save).and_return(false) + expect(@post.send(:receive_non_persisted, bob, eve.person)).to eq(false) end end end @@ -325,40 +325,40 @@ describe Post do describe '#reshares_count' do before :each do @post = @user.post :status_message, :text => "hello", :to => @aspect.id, :public => true - @post.reshares.size.should == 0 + expect(@post.reshares.size).to eq(0) end describe 'when post has not been reshared' do it 'returns zero' do - @post.reshares_count.should == 0 + expect(@post.reshares_count).to eq(0) end end describe 'when post has been reshared exactly 1 time' do before :each do - @post.reshares.size.should == 0 + expect(@post.reshares.size).to eq(0) @reshare = FactoryGirl.create(:reshare, :root => @post) @post.reload - @post.reshares.size.should == 1 + expect(@post.reshares.size).to eq(1) end it 'returns 1' do - @post.reshares_count.should == 1 + expect(@post.reshares_count).to eq(1) end end describe 'when post has been reshared more than once' do before :each do - @post.reshares.size.should == 0 + expect(@post.reshares.size).to eq(0) FactoryGirl.create(:reshare, :root => @post) FactoryGirl.create(:reshare, :root => @post) FactoryGirl.create(:reshare, :root => @post) @post.reload - @post.reshares.size.should == 3 + expect(@post.reshares.size).to eq(3) end it 'returns the number of reshares' do - @post.reshares_count.should == 3 + expect(@post.reshares_count).to eq(3) end end end @@ -366,25 +366,25 @@ describe Post do describe "#after_create" do it "sets #interacted_at" do post = FactoryGirl.create(:status_message) - post.interacted_at.should_not be_blank + expect(post.interacted_at).not_to be_blank end end describe "#find_by_guid_or_id_with_user" do it "succeeds with an id" do post = FactoryGirl.create :status_message, public: true - Post.find_by_guid_or_id_with_user(post.id).should == post + expect(Post.find_by_guid_or_id_with_user(post.id)).to eq(post) end it "succeeds with an guid" do post = FactoryGirl.create :status_message, public: true - Post.find_by_guid_or_id_with_user(post.guid).should == post + expect(Post.find_by_guid_or_id_with_user(post.guid)).to eq(post) end it "looks up on the passed user object if it's non-nil" do post = FactoryGirl.create :status_message user = double - user.should_receive(:find_visible_shareable_by_id).with(Post, post.id, key: :id).and_return(post) + expect(user).to receive(:find_visible_shareable_by_id).with(Post, post.id, key: :id).and_return(post) Post.find_by_guid_or_id_with_user post.id, user end diff --git a/spec/models/profile_spec.rb b/spec/models/profile_spec.rb index 4d152589d..b9406c5f3 100644 --- a/spec/models/profile_spec.rb +++ b/spec/models/profile_spec.rb @@ -4,28 +4,28 @@ require 'spec_helper' -describe Profile do +describe Profile, :type => :model do describe 'validation' do describe "of first_name" do it "strips leading and trailing whitespace" do profile = FactoryGirl.build(:profile, :first_name => " Shelly ") - profile.should be_valid - profile.first_name.should == "Shelly" + expect(profile).to be_valid + expect(profile.first_name).to eq("Shelly") end it "can be 32 characters long" do profile = FactoryGirl.build(:profile, :first_name => "Hexagoooooooooooooooooooooooooon") - profile.should be_valid + expect(profile).to be_valid end it "cannot be 33 characters" do profile = FactoryGirl.build(:profile, :first_name => "Hexagooooooooooooooooooooooooooon") - profile.should_not be_valid + expect(profile).not_to be_valid end it 'cannot have ;' do profile = FactoryGirl.build(:profile, :first_name => "Hex;agon") - profile.should_not be_valid + expect(profile).not_to be_valid end end @@ -36,19 +36,19 @@ describe Profile do it 'outputs a hash that can update a diaspora profile' do profile = Profile.new - profile.from_omniauth_hash(@from_omniauth)['bio'].should == 'this is my bio' + expect(profile.from_omniauth_hash(@from_omniauth)['bio']).to eq('this is my bio') end it 'does not overwrite any exsisting profile fields' do profile = Profile.new(:first_name => 'maxwell') - profile.from_omniauth_hash(@from_omniauth)['first_name'].should == 'maxwell' + expect(profile.from_omniauth_hash(@from_omniauth)['first_name']).to eq('maxwell') end it 'sets full name to first name' do @from_omniauth = {'name' => 'bob jones', 'description' => 'this is my bio', 'location' => 'sf', 'image' => 'http://cats.com/gif.gif'} profile = Profile.new - profile.from_omniauth_hash(@from_omniauth)['first_name'].should == 'bob jones' + expect(profile.from_omniauth_hash(@from_omniauth)['first_name']).to eq('bob jones') end end @@ -58,9 +58,9 @@ describe Profile do profile.first_name = "casimiro" profile.last_name = nil - profile.full_name.should_not == "casimiro" + expect(profile.full_name).not_to eq("casimiro") profile.save - profile.full_name.should == "casimiro" + expect(profile.full_name).to eq("casimiro") end it 'generates a full name given only last name' do @@ -68,9 +68,9 @@ describe Profile do profile.first_name = nil profile.last_name = "grippi" - profile.full_name.should_not == "grippi" + expect(profile.full_name).not_to eq("grippi") profile.save - profile.full_name.should == "grippi" + expect(profile.full_name).to eq("grippi") end it 'generates a full name given first and last names' do @@ -78,36 +78,36 @@ describe Profile do profile.first_name = "casimiro" profile.last_name = "grippi" - profile.full_name.should_not == "casimiro grippi" + expect(profile.full_name).not_to eq("casimiro grippi") profile.save - profile.full_name.should == "casimiro grippi" + expect(profile.full_name).to eq("casimiro grippi") end end describe "of last_name" do it "strips leading and trailing whitespace" do profile = FactoryGirl.build(:profile, :last_name => " Ohba ") - profile.should be_valid - profile.last_name.should == "Ohba" + expect(profile).to be_valid + expect(profile.last_name).to eq("Ohba") end it "can be 32 characters long" do profile = FactoryGirl.build(:profile, :last_name => "Hexagoooooooooooooooooooooooooon") - profile.should be_valid + expect(profile).to be_valid end it "cannot be 33 characters" do profile = FactoryGirl.build(:profile, :last_name => "Hexagooooooooooooooooooooooooooon") - profile.should_not be_valid + expect(profile).not_to be_valid end it 'cannot have ;' do profile = FactoryGirl.build(:profile, :last_name => "Hex;agon") - profile.should_not be_valid + expect(profile).not_to be_valid end it 'disallows ; with a newline in the string' do profile = FactoryGirl.build(:profile, :last_name => "H\nex;agon") - profile.should_not be_valid + expect(profile).not_to be_valid end end end @@ -120,17 +120,17 @@ describe Profile do end it 'ignores an empty string' do - lambda {@profile.image_url = ""}.should_not change(@profile, :image_url) + expect {@profile.image_url = ""}.not_to change(@profile, :image_url) end it 'makes relative urls absolute' do @profile.image_url = "/relative/url" - @profile.image_url.should == "#{@pod_url}/relative/url" + expect(@profile.image_url).to eq("#{@pod_url}/relative/url") end it "doesn't change absolute urls" do @profile.image_url = "http://not/a/relative/url" - @profile.image_url.should == "http://not/a/relative/url" + expect(@profile.image_url).to eq("http://not/a/relative/url") end end @@ -141,8 +141,8 @@ describe Profile do xml = @profile.to_xml new_profile = Profile.from_xml(xml.to_s) - new_profile.tag_string.should_not be_blank - new_profile.tag_string.should include('#rafi') + expect(new_profile.tag_string).not_to be_blank + expect(new_profile.tag_string).to include('#rafi') end end @@ -151,7 +151,7 @@ describe Profile do it 'should include persons diaspora handle' do xml = person.profile.to_diaspora_xml - xml.should include "foobar" + expect(xml).to include "foobar" end it 'includes tags' do @@ -159,14 +159,14 @@ describe Profile do person.profile.build_tags person.profile.save xml = person.profile.to_diaspora_xml - xml.should include "#one" + expect(xml).to include "#one" end it 'includes location' do person.profile.location = 'Dark Side, Moon' person.profile.save xml = person.profile.to_diaspora_xml - xml.should include "Dark Side, Moon" + expect(xml).to include "Dark Side, Moon" end end @@ -177,7 +177,7 @@ describe Profile do it 'returns a default rather than nil' do @profile.image_url = nil - @profile.image_url.should_not be_nil + expect(@profile.image_url).not_to be_nil end it 'falls back to the large thumbnail if the small thumbnail is nil' do @@ -185,14 +185,14 @@ describe Profile do @profile[:image_url] = 'large' @profile[:image_url_small] = nil @profile[:image_url_medium] = nil - @profile.image_url(:thumb_small).should == 'large' - @profile.image_url(:thumb_medium).should == 'large' + expect(@profile.image_url(:thumb_small)).to eq('large') + expect(@profile.image_url(:thumb_medium)).to eq('large') end end describe '#subscribers' do it 'returns all non-pending contacts for a user' do - bob.profile.subscribers(bob).map{|s| s.id}.should =~ [alice.person, eve.person].map{|s| s.id} + expect(bob.profile.subscribers(bob).map{|s| s.id}).to match_array([alice.person, eve.person].map{|s| s.id}) end end @@ -202,43 +202,43 @@ describe Profile do it 'accepts form data' do profile.birthday = nil profile.date = { 'year' => '2000', 'month' => '01', 'day' => '01' } - profile.birthday.year.should == 2000 - profile.birthday.month.should == 1 - profile.birthday.day.should == 1 + expect(profile.birthday.year).to eq(2000) + expect(profile.birthday.month).to eq(1) + expect(profile.birthday.day).to eq(1) end it 'unsets the birthday' do profile.birthday = Date.new(2000, 1, 1) profile.date = { 'year' => '', 'month' => '', 'day' => ''} - profile.birthday.should == nil + expect(profile.birthday).to eq(nil) end it 'does not change with blank month and day values' do profile.birthday = Date.new(2000, 1, 1) profile.date = { 'year' => '2001', 'month' => '', 'day' => ''} - profile.birthday.year.should == 2000 - profile.birthday.month.should == 1 - profile.birthday.day.should == 1 + expect(profile.birthday.year).to eq(2000) + expect(profile.birthday.month).to eq(1) + expect(profile.birthday.day).to eq(1) end it 'does not accept blank initial values' do profile.birthday = nil profile.date = { 'year' => '2001', 'month' => '', 'day' => ''} - profile.birthday.should == nil + expect(profile.birthday).to eq(nil) end it 'does not accept invalid dates' do profile.birthday = nil profile.date = { 'year' => '2001', 'month' => '02', 'day' => '31' } - profile.birthday.should == nil + expect(profile.birthday).to eq(nil) end it 'does not change with invalid dates' do profile.birthday = Date.new(2000, 1, 1) profile.date = { 'year' => '2001', 'month' => '02', 'day' => '31' } - profile.birthday.year.should == 2000 - profile.birthday.month.should == 1 - profile.birthday.day.should == 1 + expect(profile.birthday.year).to eq(2000) + expect(profile.birthday.month).to eq(1) + expect(profile.birthday.day).to eq(1) end end @@ -253,12 +253,12 @@ describe Profile do @object.valid? @object.errors.full_messages - @object.should be_valid + expect(@object).to be_valid end it 'strips more than 5 tags' do @object.tag_string = '#one #two #three #four #five #six' @object.save - @object.tags.count.should == 5 + expect(@object.tags.count).to eq(5) end it_should_behave_like 'it is taggable' end @@ -271,18 +271,18 @@ describe Profile do end it 'returns a formatted date' do - @profile.formatted_birthday.should == "January 1, 2000" + expect(@profile.formatted_birthday).to eq("January 1, 2000") end it 'removes nil year birthdays' do @profile_hash.delete('year') @profile.date = @profile_hash - @profile.formatted_birthday.should == 'January 1' + expect(@profile.formatted_birthday).to eq('January 1') end it 'retuns nil if no birthday is set' do @profile.date = {} - @profile.formatted_birthday.should == nil + expect(@profile.formatted_birthday).to eq(nil) end end @@ -291,10 +291,10 @@ describe Profile do it 'updates the profile in place' do local_luke, local_leia, remote_raphael = set_up_friends new_profile = FactoryGirl.build :profile - lambda{ + expect{ new_profile.receive(local_leia, remote_raphael) - }.should_not change(Profile, :count) - remote_raphael.last_name.should == new_profile.last_name + }.not_to change(Profile, :count) + expect(remote_raphael.last_name).to eq(new_profile.last_name) end end @@ -309,12 +309,12 @@ describe Profile do @profile.tombstone! @profile.reload attributes.each{ |attr| - @profile[attr.to_sym].should be_blank + expect(@profile[attr.to_sym]).to be_blank } end it 'removes all the tags from the profile' do - @profile.taggings.should_receive(:delete_all) + expect(@profile.taggings).to receive(:delete_all) @profile.tombstone! end end @@ -322,7 +322,7 @@ describe Profile do describe "#clearable_fields" do it 'returns the current profile fields' do profile = FactoryGirl.build :profile - profile.send(:clearable_fields).sort.should == + expect(profile.send(:clearable_fields).sort).to eq( ["diaspora_handle", "first_name", "last_name", @@ -336,6 +336,7 @@ describe Profile do "nsfw", "location", "full_name"].sort + ) end end end diff --git a/spec/models/report_spec.rb b/spec/models/report_spec.rb index 3595a6a1a..7bbce6502 100644 --- a/spec/models/report_spec.rb +++ b/spec/models/report_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe Report do +describe Report, :type => :model do before do #:report => { :item_id => @message.id, :item_type => 'post', :text => 'offensive content' } @user = bob @@ -27,34 +27,34 @@ describe Report do it 'validates that post ID is required' do report = @valid_post_report report.delete(:item_id) - @user.reports.build(report).should_not be_valid + expect(@user.reports.build(report)).not_to be_valid end it 'validates that post type is required' do report = @valid_post_report report.delete(:item_type) - @user.reports.build(report).should_not be_valid + expect(@user.reports.build(report)).not_to be_valid end it 'validates that post does exist' do report = @valid_post_report report[:item_id] = 666; - @user.reports.build(report).should_not be_valid + expect(@user.reports.build(report)).not_to be_valid end it 'validates that comment does exist' do report = @valid_comment_report report[:item_id] = 666; - @user.reports.build(report).should_not be_valid + expect(@user.reports.build(report)).not_to be_valid end it 'validates that entry does not exist' do - @user.reports.build(@valid_post_report).should be_valid + expect(@user.reports.build(@valid_post_report)).to be_valid end it 'validates that entry does exist' do @user.reports.create(@valid_post_report) - @user.reports.build(@valid_post_report).should_not be_valid + expect(@user.reports.build(@valid_post_report)).not_to be_valid end end diff --git a/spec/models/reshare_spec.rb b/spec/models/reshare_spec.rb index e82613cb5..89dfd85f6 100644 --- a/spec/models/reshare_spec.rb +++ b/spec/models/reshare_spec.rb @@ -1,25 +1,25 @@ require 'spec_helper' -describe Reshare do +describe Reshare, :type => :model do include Rails.application.routes.url_helpers it 'has a valid Factory' do - FactoryGirl.build(:reshare).should be_valid + expect(FactoryGirl.build(:reshare)).to be_valid end it 'requires root' do reshare = FactoryGirl.build(:reshare, :root => nil) - reshare.should_not be_valid + expect(reshare).not_to be_valid end it 'require public root' do reshare = FactoryGirl.build(:reshare, :root => FactoryGirl.create(:status_message, :public => false)) - reshare.should_not be_valid - reshare.errors[:base].should include('Only posts which are public may be reshared.') + expect(reshare).not_to be_valid + expect(reshare.errors[:base]).to include('Only posts which are public may be reshared.') end it 'forces public' do - FactoryGirl.create(:reshare, :public => false).public.should be true + expect(FactoryGirl.create(:reshare, :public => false).public).to be true end describe "#receive" do @@ -32,20 +32,20 @@ describe Reshare do it 'increments the reshare count' do receive_reshare - @root.resharers.count.should == 1 + expect(@root.resharers.count).to eq(1) end it 'adds the resharer to the re-sharers of the post' do receive_reshare - @root.resharers.should include(@reshare.author) + expect(@root.resharers).to include(@reshare.author) end it 'does not error if the root author has a contact for the resharer' do bob.share_with @reshare.author, bob.aspects.first - proc { + expect { Timeout.timeout(5) do receive_reshare #This doesn't ever terminate on my machine before it was fixed. end - }.should_not raise_error + }.not_to raise_error end end @@ -58,8 +58,8 @@ describe Reshare do end it 'deletates #nsfw to the root post' do - @sfw_reshare.nsfw.should_not be true - @nsfw_reshare.nsfw.should be_truthy + expect(@sfw_reshare.nsfw).not_to be true + expect(@nsfw_reshare.nsfw).to be_truthy end end @@ -69,11 +69,11 @@ describe Reshare do @reshare = FactoryGirl.build(:reshare, :root => sm) end it 'does not return anything for non-author of the original post' do - @reshare.notification_type(bob, @reshare.author).should be_nil + expect(@reshare.notification_type(bob, @reshare.author)).to be_nil end it 'returns "Reshared" for the original post author' do - @reshare.notification_type(alice, @reshare.author).should == Notifications::Reshared + expect(@reshare.notification_type(alice, @reshare.author)).to eq(Notifications::Reshared) end end @@ -92,7 +92,7 @@ describe Reshare do end it 'resolves root posts to the top level' do - @rs3.absolute_root.should == @sm + expect(@rs3.absolute_root).to eq(@sm) end it 'can handle deleted reshares' do @@ -125,13 +125,13 @@ describe Reshare do context 'serialization' do it 'serializes root_diaspora_id' do - @xml.should include("root_diaspora_id") - @xml.should include(@reshare.author.diaspora_handle) + expect(@xml).to include("root_diaspora_id") + expect(@xml).to include(@reshare.author.diaspora_handle) end it 'serializes root_guid' do - @xml.should include("root_guid") - @xml.should include(@reshare.root.guid) + expect(@xml).to include("root_guid") + expect(@xml).to include(@reshare.root.guid) end end @@ -143,15 +143,15 @@ describe Reshare do end it 'marshals the guid' do - Reshare.from_xml(@xml).root_guid.should == @root_object.guid + expect(Reshare.from_xml(@xml).root_guid).to eq(@root_object.guid) end it 'fetches the root post from root_guid' do - Reshare.from_xml(@xml).root.should == @root_object + expect(Reshare.from_xml(@xml).root).to eq(@root_object) end it 'fetches the root author from root_diaspora_id' do - Reshare.from_xml(@xml).root.author.should == @original_author + expect(Reshare.from_xml(@xml).root.author).to eq(@original_author) end end @@ -171,8 +171,8 @@ describe Reshare do @root_object = @reshare.root @root_object.delete @response = double - @response.stub(:status).and_return(200) - @response.stub(:success?).and_return(true) + allow(@response).to receive(:status).and_return(200) + allow(@response).to receive(:success?).and_return(true) end it 'fetches the root author from root_diaspora_id' do @@ -184,19 +184,19 @@ describe Reshare do @original_author.profile = @original_profile wf_prof_double = double - wf_prof_double.should_receive(:fetch).and_return(@original_author) - Webfinger.should_receive(:new).and_return(wf_prof_double) + expect(wf_prof_double).to receive(:fetch).and_return(@original_author) + expect(Webfinger).to receive(:new).and_return(wf_prof_double) - @response.stub(:body).and_return(@root_object.to_diaspora_xml) + allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml) - Faraday.default_connection.should_receive(:get).with(@original_author.url + short_post_path(@root_object.guid, :format => "xml")).and_return(@response) + expect(Faraday.default_connection).to receive(:get).with(@original_author.url + short_post_path(@root_object.guid, :format => "xml")).and_return(@response) Reshare.from_xml(@xml) end context "fetching post" do it "doesn't error out if the post is not found" do - @response.stub(:status).and_return(404) - Faraday.default_connection.should_receive(:get).and_return(@response) + allow(@response).to receive(:status).and_return(404) + expect(Faraday.default_connection).to receive(:get).and_return(@response) expect { Reshare.from_xml(@xml) @@ -204,9 +204,9 @@ describe Reshare do end it "raises if there's another error receiving the post" do - @response.stub(:status).and_return(500) - @response.stub(:success?).and_return(false) - Faraday.default_connection.should_receive(:get).and_return(@response) + allow(@response).to receive(:status).and_return(500) + allow(@response).to receive(:success?).and_return(false) + expect(Faraday.default_connection).to receive(:get).and_return(@response) expect { Reshare.from_xml(@xml) @@ -216,25 +216,25 @@ describe Reshare do context 'saving the post' do before do - @response.stub(:body).and_return(@root_object.to_diaspora_xml) - Faraday.default_connection.stub(:get).with(@reshare.root.author.url + short_post_path(@root_object.guid, :format => "xml")).and_return(@response) + allow(@response).to receive(:body).and_return(@root_object.to_diaspora_xml) + allow(Faraday.default_connection).to receive(:get).with(@reshare.root.author.url + short_post_path(@root_object.guid, :format => "xml")).and_return(@response) end it 'fetches the root post from root_guid' do root = Reshare.from_xml(@xml).root [:text, :guid, :diaspora_handle, :type, :public].each do |attr| - root.send(attr).should == @reshare.root.send(attr) + expect(root.send(attr)).to eq(@reshare.root.send(attr)) end end it 'correctly saves the type' do - Reshare.from_xml(@xml).root.reload.type.should == "StatusMessage" + expect(Reshare.from_xml(@xml).root.reload.type).to eq("StatusMessage") end it 'correctly sets the author' do @original_author = @reshare.root.author - Reshare.from_xml(@xml).root.reload.author.reload.should == @original_author + expect(Reshare.from_xml(@xml).root.reload.author.reload).to eq(@original_author) end it 'verifies that the author of the post received is the same as the author in the reshare xml' do @@ -244,14 +244,14 @@ describe Reshare do different_person = FactoryGirl.build(:person) wf_prof_double = double - wf_prof_double.should_receive(:fetch).and_return(different_person) - Webfinger.should_receive(:new).and_return(wf_prof_double) + expect(wf_prof_double).to receive(:fetch).and_return(different_person) + expect(Webfinger).to receive(:new).and_return(wf_prof_double) - different_person.stub(:url).and_return(@original_author.url) + allow(different_person).to receive(:url).and_return(@original_author.url) - lambda{ + expect{ Reshare.from_xml(@xml) - }.should raise_error /^Diaspora ID \(.+\) in the root does not match the Diaspora ID \(.+\) specified in the reshare!$/ + }.to raise_error /^Diaspora ID \(.+\) in the root does not match the Diaspora ID \(.+\) specified in the reshare!$/ end end end diff --git a/spec/models/role_spec.rb b/spec/models/role_spec.rb index 23a3e742c..59ddaeb60 100644 --- a/spec/models/role_spec.rb +++ b/spec/models/role_spec.rb @@ -1,5 +1,5 @@ require 'spec_helper' -describe Role do +describe Role, :type => :model do skip "add some examples to (or delete) #{__FILE__}" end diff --git a/spec/models/service_spec.rb b/spec/models/service_spec.rb index 069c8811a..a7aa8a3e6 100644 --- a/spec/models/service_spec.rb +++ b/spec/models/service_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Service do +describe Service, :type => :model do before do @post = alice.post(:status_message, :text => "hello", :to => alice.aspects.first.id) @@ -15,7 +15,7 @@ describe Service do alice.services << second_service alice.services.last.save - alice.services.last.should be_invalid + expect(alice.services.last).to be_invalid end it 'by default has no profile photo url' do diff --git a/spec/models/services/facebook_spec.rb b/spec/models/services/facebook_spec.rb index fb2a7f854..adb4fc8bc 100644 --- a/spec/models/services/facebook_spec.rb +++ b/spec/models/services/facebook_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Services::Facebook do +describe Services::Facebook, :type => :model do before do @user = alice @@ -26,7 +26,7 @@ describe Services::Facebook do it 'removes text formatting markdown from post text' do message = double - message.should_receive(:plain_text_without_markdown).and_return("") + expect(message).to receive(:plain_text_without_markdown).and_return("") post = double(message: message, photos: []) post_params = @service.create_post_params(post) end @@ -35,14 +35,14 @@ describe Services::Facebook do message = "Some text." post = double(message: double(plain_text_without_markdown: message), photos: []) post_params = @service.create_post_params(post) - post_params[:message].should_not include "http" + expect(post_params[:message]).not_to include "http" end it 'sets facebook id on post' do stub_request(:post, "https://graph.facebook.com/me/feed"). to_return(:status => 200, :body => '{"id": "12345"}', :headers => {}) @service.post(@post) - @post.facebook_id.should match "12345" + expect(@post.facebook_id).to match "12345" end end @@ -63,7 +63,7 @@ describe Services::Facebook do it "should include post url in message with photos" do post_params = @service.create_post_params(@status_message) - post_params[:message].should include 'http' + expect(post_params[:message]).to include 'http' end end @@ -72,8 +72,9 @@ describe Services::Facebook do it 'returns a large profile photo url' do @service.uid = "abc123" @service.access_token = "token123" - @service.profile_photo_url.should == + expect(@service.profile_photo_url).to eq( "https://graph.facebook.com/abc123/picture?type=large&access_token=token123" + ) end end @@ -82,7 +83,7 @@ describe Services::Facebook do @post.facebook_id = "2345" url="https://graph.facebook.com/#{@post.facebook_id}/" stub_request(:delete, "#{url}?access_token=#{@service.access_token}").to_return(:status => 200) - @service.should_receive(:delete_from_facebook).with(url, {access_token: @service.access_token}) + expect(@service).to receive(:delete_from_facebook).with(url, {access_token: @service.access_token}) @service.delete_post(@post) end diff --git a/spec/models/services/tumblr_spec.rb b/spec/models/services/tumblr_spec.rb index f60c2c32a..c6ecb9c3e 100644 --- a/spec/models/services/tumblr_spec.rb +++ b/spec/models/services/tumblr_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Services::Tumblr do +describe Services::Tumblr, :type => :model do before do @user = alice @@ -12,16 +12,16 @@ describe Services::Tumblr do describe '#post' do it 'posts a status message to tumblr and saves the returned ids' do response = double(body: '{"response": {"user": {"blogs": [{"url": "http://foo.tumblr.com"}]}}}') - OAuth::AccessToken.any_instance.should_receive(:get) + expect_any_instance_of(OAuth::AccessToken).to receive(:get) .with("/v2/user/info") .and_return(response) response = double(code: "201", body: '{"response": {"id": "bla"}}') - OAuth::AccessToken.any_instance.should_receive(:post) + expect_any_instance_of(OAuth::AccessToken).to receive(:post) .with("/v2/blog/foo.tumblr.com/post", @service.build_tumblr_post(@post, '')) .and_return(response) - @post.should_receive(:tumblr_ids=).with({"foo.tumblr.com" => "bla"}.to_json) + expect(@post).to receive(:tumblr_ids=).with({"foo.tumblr.com" => "bla"}.to_json) @service.post(@post) end diff --git a/spec/models/services/twitter_spec.rb b/spec/models/services/twitter_spec.rb index 351c8d6ef..c111f6c34 100644 --- a/spec/models/services/twitter_spec.rb +++ b/spec/models/services/twitter_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Services::Twitter do +describe Services::Twitter, :type => :model do before do @user = alice @@ -12,34 +12,34 @@ describe Services::Twitter do describe '#post' do before do - Twitter::Client.any_instance.stub(:update) { Twitter::Tweet.new(id: "1234") } + allow_any_instance_of(Twitter::Client).to receive(:update) { Twitter::Tweet.new(id: "1234") } end it 'posts a status message to twitter' do - Twitter::Client.any_instance.should_receive(:update).with(instance_of(String)) + expect_any_instance_of(Twitter::Client).to receive(:update).with(instance_of(String)) @service.post(@post) end it 'sets the tweet_id on the post' do @service.post(@post) - @post.tweet_id.should match "1234" + expect(@post.tweet_id).to match "1234" end it 'swallows exception raised by twitter always being down' do skip - Twitter::Client.any_instance.should_receive(:update).and_raise(StandardError) + expect_any_instance_of(Twitter::Client).to receive(:update).and_raise(StandardError) @service.post(@post) end it 'should call build_twitter_post' do url = "foo" - @service.should_receive(:build_twitter_post).with(@post, 0) + expect(@service).to receive(:build_twitter_post).with(@post, 0) @service.post(@post, url) end it 'removes text formatting markdown from post text' do message = double - message.should_receive(:plain_text_without_markdown).and_return("") + expect(message).to receive(:plain_text_without_markdown).and_return("") post = double(message: message, photos: []) @service.send(:build_twitter_post, post) end @@ -55,13 +55,13 @@ describe Services::Twitter do it "should not truncate a short message" do short_message = SecureRandom.hex(20) short_post = double(message: double(plain_text_without_markdown: short_message), photos: []) - @service.send(:build_twitter_post, short_post).should match short_message + expect(@service.send(:build_twitter_post, short_post)).to match short_message end it "should truncate a long message" do long_message = SecureRandom.hex(220) long_post = double(message: double(plain_text_without_markdown: long_message), id: 1, photos: []) - @service.send(:build_twitter_post, long_post).length.should be < long_message.length + expect(@service.send(:build_twitter_post, long_post).length).to be < long_message.length end it "should not truncate a long message with an http url" do @@ -70,7 +70,7 @@ describe Services::Twitter do @post.text = long_message answer = @service.send(:build_twitter_post, @post) - answer.should_not match /\.\.\./ + expect(answer).not_to match /\.\.\./ end it "should not cut links when truncating a post" do @@ -78,8 +78,8 @@ describe Services::Twitter do long_post = double(message: double(plain_text_without_markdown: long_message), id: 1, photos: []) answer = @service.send(:build_twitter_post, long_post) - answer.should match /\.\.\./ - answer.should match /shortened\.html/ + expect(answer).to match /\.\.\./ + expect(answer).to match /shortened\.html/ end it "should append the otherwise-cut link when truncating a post" do @@ -87,15 +87,15 @@ describe Services::Twitter do long_post = double(message: double(plain_text_without_markdown: long_message), id: 1, photos: []) answer = @service.send(:build_twitter_post, long_post) - answer.should match /\.\.\./ - answer.should match /shortened\.html/ + expect(answer).to match /\.\.\./ + expect(answer).to match /shortened\.html/ end it "should not truncate a long message with an https url" do long_message = " https://joindiaspora.com/a-very-long-url-name-that-will-be-shortened.html " + @long_message_end @post.text = long_message answer = @service.send(:build_twitter_post, @post) - answer.should_not match /\.\.\./ + expect(answer).not_to match /\.\.\./ end it "should truncate a long message with an ftp url" do @@ -103,7 +103,7 @@ describe Services::Twitter do long_post = double(message: double(plain_text_without_markdown: long_message), id: 1, photos: []) answer = @service.send(:build_twitter_post, long_post) - answer.should match /\.\.\./ + expect(answer).to match /\.\.\./ end it "should not truncate a message of maximum length" do @@ -111,7 +111,7 @@ describe Services::Twitter do exact_size_post = double(message: double(plain_text_without_markdown: exact_size_message), id: 1, photos: []) answer = @service.send(:build_twitter_post, exact_size_post) - answer.should match exact_size_message + expect(answer).to match exact_size_message end end @@ -132,7 +132,7 @@ describe Services::Twitter do it "should include post url in short message with photos" do answer = @service.send(:build_twitter_post, @status_message) - answer.should include 'http' + expect(answer).to include 'http' end end @@ -140,11 +140,11 @@ describe Services::Twitter do describe "#profile_photo_url" do it 'returns the original profile photo url' do user_double = double - user_double.should_receive(:profile_image_url_https).with("original").and_return("http://a2.twimg.com/profile_images/uid/avatar.png") - Twitter::Client.any_instance.should_receive(:user).with("joindiaspora").and_return(user_double) + expect(user_double).to receive(:profile_image_url_https).with("original").and_return("http://a2.twimg.com/profile_images/uid/avatar.png") + expect_any_instance_of(Twitter::Client).to receive(:user).with("joindiaspora").and_return(user_double) @service.nickname = "joindiaspora" - @service.profile_photo_url.should == "http://a2.twimg.com/profile_images/uid/avatar.png" + expect(@service.profile_photo_url).to eq("http://a2.twimg.com/profile_images/uid/avatar.png") end end end diff --git a/spec/models/services/wordpress_spec.rb b/spec/models/services/wordpress_spec.rb index fd970d839..945285979 100644 --- a/spec/models/services/wordpress_spec.rb +++ b/spec/models/services/wordpress_spec.rb @@ -1,6 +1,6 @@ require 'spec_helper' -describe Services::Wordpress do +describe Services::Wordpress, :type => :model do before do @user = alice @@ -23,10 +23,10 @@ describe Services::Wordpress do describe "#post_body" do it "truncates content for use in title" do - @service.post_body(@post)[:title].should eq("Hello there. This is a Wordpress post...") + expect(@service.post_body(@post)[:title]).to eq("Hello there. This is a Wordpress post...") end it "converts markdown tags" do - @service.post_body(@post)[:content].should match("Wordpress") + expect(@service.post_body(@post)[:content]).to match("Wordpress") end end diff --git a/spec/models/share_visibility_spec.rb b/spec/models/share_visibility_spec.rb index d93a42d20..fe2674fe3 100644 --- a/spec/models/share_visibility_spec.rb +++ b/spec/models/share_visibility_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe ShareVisibility do +describe ShareVisibility, :type => :model do describe '.batch_import' do before do @post = FactoryGirl.create(:status_message, :author => alice.person) @@ -14,22 +14,22 @@ describe ShareVisibility do it 'returns false if share is public' do @post.public = true @post.save - ShareVisibility.batch_import([@contact.id], @post).should be false + expect(ShareVisibility.batch_import([@contact.id], @post)).to be false end it 'creates a visibility for each user' do - lambda { + expect { ShareVisibility.batch_import([@contact.id], @post) - }.should change { + }.to change { ShareVisibility.exists?(:contact_id => @contact.id, :shareable_id => @post.id, :shareable_type => 'Post') }.from(false).to(true) end it 'does not raise if a visibility already exists' do ShareVisibility.create!(:contact_id => @contact.id, :shareable_id => @post.id, :shareable_type => 'Post') - lambda { + expect { ShareVisibility.batch_import([@contact.id], @post) - }.should_not raise_error + }.not_to raise_error end context "scopes" do @@ -40,7 +40,7 @@ describe ShareVisibility do it 'searches for share visibilies for all users contacts' do contact_ids = alice.contacts.map(&:id) - ShareVisibility.for_a_users_contacts(alice).should == ShareVisibility.where(:contact_id => contact_ids).to_a + expect(ShareVisibility.for_a_users_contacts(alice)).to eq(ShareVisibility.where(:contact_id => contact_ids).to_a) end end diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index e91677f30..28c0411be 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe StatusMessage do +describe StatusMessage, :type => :model do include PeopleHelper before do @@ -22,7 +22,7 @@ describe StatusMessage do FactoryGirl.create(:status_message, :text => @test_string ) FactoryGirl.create(:status_message) - StatusMessage.where_person_is_mentioned(@bo).count.should == 2 + expect(StatusMessage.where_person_is_mentioned(@bo).count).to eq(2) end end @@ -39,21 +39,21 @@ describe StatusMessage do describe '.tag_steam' do it 'returns status messages tagged with the tag' do tag_stream = StatusMessage.send(:tag_stream, [@tag_id]) - tag_stream.should include @sm1 - tag_stream.should include @sm2 + expect(tag_stream).to include @sm1 + expect(tag_stream).to include @sm2 end end describe '.public_tag_stream' do it 'returns public status messages tagged with the tag' do - StatusMessage.public_tag_stream([@tag_id]).should == [@sm1] + expect(StatusMessage.public_tag_stream([@tag_id])).to eq([@sm1]) end end describe '.user_tag_stream' do - it 'returns tag stream thats owned or visibile by' do - StatusMessage.should_receive(:owned_or_visible_by_user).with(bob).and_return(StatusMessage) - StatusMessage.should_receive(:tag_stream).with([@tag_id]) + it 'returns tag stream thats owned or visible by' do + expect(StatusMessage).to receive(:owned_or_visible_by_user).with(bob).and_return(StatusMessage) + expect(StatusMessage).to receive(:tag_stream).with([@tag_id]) StatusMessage.user_tag_stream(bob, [@tag_id]) end @@ -66,20 +66,20 @@ describe StatusMessage do sm1 = FactoryGirl.create(:status_message, :author => alice.person) sm2 = FactoryGirl.create(:status_message, :author => bob.person) guids = StatusMessage.guids_for_author(alice.person) - guids.should == [sm1.guid] + expect(guids).to eq([sm1.guid]) end end describe '.before_create' do it 'calls build_tags' do status = FactoryGirl.build(:status_message) - status.should_receive(:build_tags) + expect(status).to receive(:build_tags) status.save end it 'calls filter_mentions' do status = FactoryGirl.build(:status_message) - status.should_receive(:filter_mentions) + expect(status).to receive(:filter_mentions) status.save end end @@ -87,7 +87,7 @@ describe StatusMessage do describe '.after_create' do it 'calls create_mentions' do status = FactoryGirl.build(:status_message, text: "text @{Test; #{alice.diaspora_handle}}") - status.should_receive(:create_mentions).and_call_original + expect(status).to receive(:create_mentions).and_call_original status.save end end @@ -97,33 +97,33 @@ describe StatusMessage do person = FactoryGirl.create(:person) post = FactoryGirl.build(:status_message, :author => @user.person) post.diaspora_handle = person.diaspora_handle - post.author.should == person + expect(post.author).to eq(person) end end context "emptyness" do it "needs either a message or at least one photo" do n = @user.build_post(:status_message, :text => nil) - n.should_not be_valid + expect(n).not_to be_valid n.text = "" - n.should_not be_valid + expect(n).not_to be_valid n.text = "wales" - n.should be_valid + expect(n).to be_valid n.text = nil photo = @user.build_post(:photo, :user_file => uploaded_photo, :to => @aspect.id) photo.save! n.photos << photo - n.should be_valid - n.errors.full_messages.should == [] + expect(n).to be_valid + expect(n.errors.full_messages).to eq([]) end it "doesn't check for content when author is remote (federation...)" do p = FactoryGirl.build(:status_message, text: nil) - p.should be_valid + expect(p).to be_valid end end @@ -131,13 +131,13 @@ describe StatusMessage do message = "Users do things" status = @user.post(:status_message, :text => message, :to => @aspect.id) db_status = StatusMessage.find(status.id) - db_status.text.should == message + expect(db_status.text).to eq(message) end it 'should require status messages not be more than 65535 characters long' do message = 'a' * (65535+1) status_message = FactoryGirl.build(:status_message, :text => message) - status_message.should_not be_valid + expect(status_message).not_to be_valid end describe 'mentions' do @@ -152,10 +152,10 @@ STR describe '#create_mentions' do it 'creates a mention for everyone mentioned in the message' do - Diaspora::Mentionable.should_receive(:people_from_string).and_return(@people) + expect(Diaspora::Mentionable).to receive(:people_from_string).and_return(@people) @sm.mentions.delete_all @sm.create_mentions - @sm.mentions(true).map{|m| m.person}.to_set.should == @people.to_set + expect(@sm.mentions(true).map{|m| m.person}.to_set).to eq(@people.to_set) end it 'does not barf if it gets called twice' do @@ -170,32 +170,32 @@ STR describe '#mentioned_people' do it 'calls create_mentions if there are no mentions in the db' do @sm.mentions.delete_all - @sm.should_receive(:create_mentions) + expect(@sm).to receive(:create_mentions) @sm.mentioned_people end it 'returns the mentioned people' do @sm.mentions.delete_all - @sm.mentioned_people.to_set.should == @people.to_set + expect(@sm.mentioned_people.to_set).to eq(@people.to_set) end it 'does not call create_mentions if there are mentions in the db' do - @sm.should_not_receive(:create_mentions) + expect(@sm).not_to receive(:create_mentions) @sm.mentioned_people end end describe "#mentions?" do it 'returns true if the person was mentioned' do - @sm.mentions?(@people[0]).should be true + expect(@sm.mentions?(@people[0])).to be true end it 'returns false if the person was not mentioned' do - @sm.mentions?(FactoryGirl.build(:person)).should be false + expect(@sm.mentions?(FactoryGirl.build(:person))).to be false end end describe "#notify_person" do it 'notifies the person mentioned' do - Notification.should_receive(:notify).with(alice, anything, anything) + expect(Notification).to receive(:notify).with(alice, anything, anything) @sm.notify_person(alice.person) end end @@ -208,7 +208,7 @@ STR author_usr = msg.author.owner aspect_id = author_usr.aspects.first.id - Diaspora::Mentionable.should_receive(:filter_for_aspects) + expect(Diaspora::Mentionable).to receive(:filter_for_aspects) .with(msg_txt, author_usr, aspect_id) msg.send(:filter_mentions) @@ -216,7 +216,7 @@ STR it "doesn't do anything when public" do msg = FactoryGirl.build(:status_message, public: true) - Diaspora::Mentionable.should_not_receive(:filter_for_aspects) + expect(Diaspora::Mentionable).not_to receive(:filter_for_aspects) msg.send(:filter_mentions) end @@ -226,12 +226,12 @@ STR describe "#nsfw" do it 'returns MatchObject (true) if the post contains #nsfw (however capitalised)' do status = FactoryGirl.build(:status_message, :text => "This message is #nSFw") - status.nsfw.should be_truthy + expect(status.nsfw).to be_truthy end it 'returns nil (false) if the post does not contain #nsfw' do status = FactoryGirl.build(:status_message, :text => "This message is #sFW") - status.nsfw.should be false + expect(status.nsfw).to be false end end @@ -264,15 +264,15 @@ STR it 'serializes the escaped, unprocessed message' do text = "[url](http://example.org)" @message.text = text - @message.to_xml.to_s.should include Builder::XChar.encode(text) + expect(@message.to_xml.to_s).to include Builder::XChar.encode(text) end it 'serializes the message' do - @xml.should include "I hate WALRUSES!" + expect(@xml).to include "I hate WALRUSES!" end it 'serializes the author address' do - @xml.should include(@user.person.diaspora_handle) + expect(@xml).to include(@user.person.diaspora_handle) end describe '.from_xml' do @@ -280,16 +280,16 @@ STR @marshalled = StatusMessage.from_xml(@xml) end it 'marshals the message' do - @marshalled.text.should == "I hate WALRUSES!" + expect(@marshalled.text).to eq("I hate WALRUSES!") end it 'marshals the guid' do - @marshalled.guid.should == @message.guid + expect(@marshalled.guid).to eq(@message.guid) end it 'marshals the author' do - @marshalled.author.should == @message.author + expect(@marshalled.author).to eq(@message.author) end it 'marshals the diaspora_handle' do - @marshalled.diaspora_handle.should == @message.diaspora_handle + expect(@marshalled.diaspora_handle).to eq(@message.diaspora_handle) end end @@ -301,8 +301,8 @@ STR end it 'serializes the photos' do - @xml.should include "photo" - @xml.should include @message.photos.first.remote_photo_path + expect(@xml).to include "photo" + expect(@xml).to include @message.photos.first.remote_photo_path end describe '.from_xml' do @@ -311,7 +311,7 @@ STR end it 'marshals the photos' do - @marshalled.photos.size.should == 2 + expect(@marshalled.photos.size).to eq(2) end end end @@ -323,9 +323,9 @@ STR end it 'serializes the location' do - @xml.should include "location" - @xml.should include "lat" - @xml.should include "lng" + expect(@xml).to include "location" + expect(@xml).to include "lat" + expect(@xml).to include "lng" end describe ".from_xml" do @@ -334,7 +334,7 @@ STR end it 'marshals the location' do - @marshalled.location.should be_present + expect(@marshalled.location).to be_present end end end @@ -346,9 +346,9 @@ STR end it 'serializes the poll' do - @xml.should include "poll" - @xml.should include "question" - @xml.should include "poll_answer" + expect(@xml).to include "poll" + expect(@xml).to include "question" + expect(@xml).to include "poll_answer" end describe ".from_xml" do @@ -357,11 +357,11 @@ STR end it 'marshals the poll' do - @marshalled.poll.should be_present + expect(@marshalled.poll).to be_present end it 'marshals the poll answers' do - @marshalled.poll.poll_answers.size.should == 2 + expect(@marshalled.poll.poll_answers.size).to eq(2) end end end @@ -384,10 +384,10 @@ STR end it 'sets pending to false on any attached photos' do @status_message.after_dispatch(alice) - @photos.all?{|p| p.reload.pending}.should be false + expect(@photos.all?{|p| p.reload.pending}).to be false end it 'dispatches any attached photos' do - alice.should_receive(:dispatch_post).twice + expect(alice).to receive(:dispatch_post).twice @status_message.after_dispatch(alice) end end @@ -400,15 +400,15 @@ STR it 'should queue a GatherOembedData if it includes a link' do sm = FactoryGirl.build(:status_message, :text => @message_text) - Workers::GatherOEmbedData.should_receive(:perform_async).with(instance_of(Fixnum), instance_of(String)) + expect(Workers::GatherOEmbedData).to receive(:perform_async).with(instance_of(Fixnum), instance_of(String)) sm.save end describe '#contains_oembed_url_in_text?' do it 'returns the oembed urls found in the raw message' do sm = FactoryGirl.build(:status_message, :text => @message_text) - sm.contains_oembed_url_in_text?.should_not be_nil - sm.oembed_url.should == @youtube_url + expect(sm.contains_oembed_url_in_text?).not_to be_nil + expect(sm.oembed_url).to eq(@youtube_url) end end end @@ -423,20 +423,20 @@ STR it 'should queue a GatherOpenGraphData if it includes a link' do sm = FactoryGirl.build(:status_message, :text => @message_text) - Workers::GatherOpenGraphData.should_receive(:perform_async).with(instance_of(Fixnum), instance_of(String)) + expect(Workers::GatherOpenGraphData).to receive(:perform_async).with(instance_of(Fixnum), instance_of(String)) sm.save end describe '#contains_open_graph_url_in_text?' do it 'returns the opengraph urls found in the raw message' do sm = FactoryGirl.build(:status_message, :text => @message_text) - sm.contains_open_graph_url_in_text?.should_not be_nil - sm.open_graph_url.should == @ninegag_url + expect(sm.contains_open_graph_url_in_text?).not_to be_nil + expect(sm.open_graph_url).to eq(@ninegag_url) end it 'returns nil if the link is from trusted oembed provider' do sm = FactoryGirl.build(:status_message, :text => @oemessage_text) - sm.contains_open_graph_url_in_text?.should be_nil - sm.open_graph_url.should be_nil + expect(sm.contains_open_graph_url_in_text?).to be_nil + expect(sm.open_graph_url).to be_nil end end end diff --git a/spec/models/tag_following_spec.rb b/spec/models/tag_following_spec.rb index d3f7463ce..af7879215 100644 --- a/spec/models/tag_following_spec.rb +++ b/spec/models/tag_following_spec.rb @@ -1,25 +1,25 @@ require 'spec_helper' -describe TagFollowing do +describe TagFollowing, :type => :model do before do @tag = FactoryGirl.build(:tag) TagFollowing.create!(:tag => @tag, :user => alice) end it 'validates uniqueness of tag_following scoped through user' do - TagFollowing.new(:tag => @tag, :user => alice).valid?.should be false + expect(TagFollowing.new(:tag => @tag, :user => alice).valid?).to be false end it 'allows multiple tag followings for different users' do - TagFollowing.new(:tag => @tag, :user => bob).valid?.should be true + expect(TagFollowing.new(:tag => @tag, :user => bob).valid?).to be true end it 'user is following a tag' do - TagFollowing.user_is_following?(alice, @tag.name).should be true + expect(TagFollowing.user_is_following?(alice, @tag.name)).to be true end it 'user not following a tag' do - TagFollowing.user_is_following?(bob, @tag.name).should be false + expect(TagFollowing.user_is_following?(bob, @tag.name)).to be false end end diff --git a/spec/models/user/connecting_spec.rb b/spec/models/user/connecting_spec.rb index cc8a1ad00..1cfad5c14 100644 --- a/spec/models/user/connecting_spec.rb +++ b/spec/models/user/connecting_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe User::Connecting do +describe User::Connecting, :type => :model do let(:aspect) { alice.aspects.first } let(:aspect1) { alice.aspects.create(:name => 'other') } @@ -20,37 +20,37 @@ describe User::Connecting do describe '#remove_contact' do it 'removed non mutual contacts' do alice.share_with(eve.person, alice.aspects.first) - lambda { + expect { alice.remove_contact alice.contact_for(eve.person) - }.should change { + }.to change { alice.contacts(true).count }.by(-1) end it 'removes a contacts receiving flag' do - bob.contacts.find_by_person_id(alice.person.id).should be_receiving + expect(bob.contacts.find_by_person_id(alice.person.id)).to be_receiving bob.remove_contact(bob.contact_for(alice.person)) - bob.contacts(true).find_by_person_id(alice.person.id).should_not be_receiving + expect(bob.contacts(true).find_by_person_id(alice.person.id)).not_to be_receiving end end describe '#disconnected_by' do it 'calls remove contact' do - bob.should_receive(:remove_contact).with(bob.contact_for(alice.person), :retracted => true) + expect(bob).to receive(:remove_contact).with(bob.contact_for(alice.person), :retracted => true) bob.disconnected_by(alice.person) end it 'removes contact sharing flag' do - bob.contacts.find_by_person_id(alice.person.id).should be_sharing + expect(bob.contacts.find_by_person_id(alice.person.id)).to be_sharing bob.disconnected_by(alice.person) - bob.contacts.find_by_person_id(alice.person.id).should_not be_sharing + expect(bob.contacts.find_by_person_id(alice.person.id)).not_to be_sharing end it 'removes notitications' do alice.share_with(eve.person, alice.aspects.first) - Notifications::StartedSharing.where(:recipient_id => eve.id).first.should_not be_nil + expect(Notifications::StartedSharing.where(:recipient_id => eve.id).first).not_to be_nil eve.disconnected_by(alice.person) - Notifications::StartedSharing.where(:recipient_id => eve.id).first.should be_nil + expect(Notifications::StartedSharing.where(:recipient_id => eve.id).first).to be_nil end end @@ -58,14 +58,14 @@ describe User::Connecting do it 'calls remove contact' do contact = bob.contact_for(alice.person) - bob.should_receive(:remove_contact).with(contact, {}) + expect(bob).to receive(:remove_contact).with(contact, {}) bob.disconnect(contact) end it 'dispatches a retraction' do p = double() - Postzord::Dispatcher.should_receive(:build).and_return(p) - p.should_receive(:post) + expect(Postzord::Dispatcher).to receive(:build).and_return(p) + expect(p).to receive(:post) bob.disconnect bob.contact_for(eve.person) end @@ -75,9 +75,9 @@ describe User::Connecting do new_aspect = alice.aspects.create(:name => 'new') alice.add_contact_to_aspect(contact, new_aspect) - lambda { + expect { alice.disconnect(contact) - }.should change(contact.aspects(true), :count).from(2).to(0) + }.to change(contact.aspects(true), :count).from(2).to(0) end end end @@ -94,43 +94,43 @@ describe User::Connecting do describe '#share_with' do it 'finds or creates a contact' do - lambda { + expect { alice.share_with(eve.person, alice.aspects.first) - }.should change(alice.contacts, :count).by(1) + }.to change(alice.contacts, :count).by(1) end it 'does not set mutual on intial share request' do alice.share_with(eve.person, alice.aspects.first) - alice.contacts.find_by_person_id(eve.person.id).should_not be_mutual + expect(alice.contacts.find_by_person_id(eve.person.id)).not_to be_mutual end it 'does set mutual on share-back request' do eve.share_with(alice.person, eve.aspects.first) alice.share_with(eve.person, alice.aspects.first) - alice.contacts.find_by_person_id(eve.person.id).should be_mutual + expect(alice.contacts.find_by_person_id(eve.person.id)).to be_mutual end it 'adds a contact to an aspect' do contact = alice.contacts.create(:person => eve.person) - alice.contacts.stub(:find_or_initialize_by).and_return(contact) + allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) - lambda { + expect { alice.share_with(eve.person, alice.aspects.first) - }.should change(contact.aspects, :count).by(1) + }.to change(contact.aspects, :count).by(1) end it 'calls #register_share_visibilities with a contact' do - eve.should_receive(:register_share_visibilities) + expect(eve).to receive(:register_share_visibilities) eve.share_with(alice.person, eve.aspects.first) end context 'dispatching' do it 'dispatches a request on initial request' do contact = alice.contacts.new(:person => eve.person) - alice.contacts.stub(:find_or_initialize_by).and_return(contact) + allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) - contact.should_receive(:dispatch_request) + expect(contact).to receive(:dispatch_request) alice.share_with(eve.person, alice.aspects.first) end @@ -138,9 +138,9 @@ describe User::Connecting do eve.share_with(alice.person, eve.aspects.first) contact = alice.contact_for(eve.person) - alice.contacts.stub(:find_or_initialize_by).and_return(contact) + allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) - contact.should_receive(:dispatch_request) + expect(contact).to receive(:dispatch_request) alice.share_with(eve.person, alice.aspects.first) end @@ -148,31 +148,31 @@ describe User::Connecting do a2 = alice.aspects.create(:name => "two") contact = alice.contacts.create(:person => eve.person, :receiving => true) - alice.contacts.stub(:find_or_initialize_by).and_return(contact) + allow(alice.contacts).to receive(:find_or_initialize_by).and_return(contact) - contact.should_not_receive(:dispatch_request) + expect(contact).not_to receive(:dispatch_request) alice.share_with(eve.person, a2) end it 'posts profile' do m = double() - Postzord::Dispatcher.should_receive(:build).twice.and_return(m) - m.should_receive(:post).twice + expect(Postzord::Dispatcher).to receive(:build).twice.and_return(m) + expect(m).to receive(:post).twice alice.share_with(eve.person, alice.aspects.first) end end it 'sets receiving' do alice.share_with(eve.person, alice.aspects.first) - alice.contact_for(eve.person).should be_receiving + expect(alice.contact_for(eve.person)).to be_receiving end it "should mark the corresponding notification as 'read'" do notification = FactoryGirl.create(:notification, :target => eve.person) - Notification.where(:target_id => eve.person.id).first.unread.should be true + expect(Notification.where(:target_id => eve.person.id).first.unread).to be true alice.share_with(eve.person, aspect) - Notification.where(:target_id => eve.person.id).first.unread.should be false + expect(Notification.where(:target_id => eve.person.id).first.unread).to be false end end end diff --git a/spec/models/user/posting_spec.rb b/spec/models/user/posting_spec.rb index 08544e024..5966ba2bf 100644 --- a/spec/models/user/posting_spec.rb +++ b/spec/models/user/posting_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe User do +describe User, :type => :model do before do @aspect = alice.aspects.first @aspect1 = alice.aspects.create(:name => 'other') @@ -20,48 +20,49 @@ describe User do end it 'saves post into visible post ids' do - lambda { + expect { alice.add_to_streams(@post, @aspects) - }.should change{alice.visible_shareables(Post, :by_members_of => @aspects).length}.by(1) - alice.visible_shareables(Post, :by_members_of => @aspects).should include @post + }.to change{alice.visible_shareables(Post, :by_members_of => @aspects).length}.by(1) + expect(alice.visible_shareables(Post, :by_members_of => @aspects)).to include @post end it 'saves post into each aspect in aspect_ids' do alice.add_to_streams(@post, @aspects) - @aspect.reload.post_ids.should include @post.id - @aspect1.reload.post_ids.should include @post.id + expect(@aspect.reload.post_ids).to include @post.id + expect(@aspect1.reload.post_ids).to include @post.id end end describe '#aspects_from_ids' do it 'returns a list of all valid aspects a alice can post to' do aspect_ids = Aspect.all.map(&:id) - alice.aspects_from_ids(aspect_ids).map{|a| a}.should == - alice.aspects.map{|a| a} #RSpec matchers ftw + expect(alice.aspects_from_ids(aspect_ids).map{|a| a}).to eq( + alice.aspects.map{|a| a} + ) #RSpec matchers ftw end it "lets you post to your own aspects" do - alice.aspects_from_ids([@aspect.id]).should == [@aspect] - alice.aspects_from_ids([@aspect1.id]).should == [@aspect1] + expect(alice.aspects_from_ids([@aspect.id])).to eq([@aspect]) + expect(alice.aspects_from_ids([@aspect1.id])).to eq([@aspect1]) end it 'removes aspects that are not yours' do - alice.aspects_from_ids(eve.aspects.first.id).should == [] + expect(alice.aspects_from_ids(eve.aspects.first.id)).to eq([]) end end describe '#build_post' do it 'sets status_message#text' do post = alice.build_post(:status_message, :text => "hey", :to => @aspect.id) - post.text.should == "hey" + expect(post.text).to eq("hey") end it 'does not save a status_message' do post = alice.build_post(:status_message, :text => "hey", :to => @aspect.id) - post.should_not be_persisted + expect(post).not_to be_persisted end it 'does not save a photo' do post = alice.build_post(:photo, :user_file => uploaded_photo, :to => @aspect.id) - post.should_not be_persisted + expect(post).not_to be_persisted end end @@ -71,7 +72,7 @@ describe User do update_hash = {:text => "New caption"} alice.update_post(photo, update_hash) - photo.text.should match(/New/) + expect(photo.text).to match(/New/) end end end diff --git a/spec/models/user/querying_spec.rb b/spec/models/user/querying_spec.rb index ec3bec853..8a3eecee0 100644 --- a/spec/models/user/querying_spec.rb +++ b/spec/models/user/querying_spec.rb @@ -4,7 +4,7 @@ require 'spec_helper' -describe User::Querying do +describe User::Querying, :type => :model do before do @alices_aspect = alice.aspects.where(:name => "generic").first @eves_aspect = eve.aspects.where(:name => "generic").first @@ -14,12 +14,12 @@ describe User::Querying do describe "#visible_shareable_ids" do it "contains your public posts" do public_post = alice.post(:status_message, :text => "hi", :to => @alices_aspect.id, :public => true) - alice.visible_shareable_ids(Post).should include(public_post.id) + expect(alice.visible_shareable_ids(Post)).to include(public_post.id) end it "contains your non-public posts" do private_post = alice.post(:status_message, :text => "hi", :to => @alices_aspect.id, :public => false) - alice.visible_shareable_ids(Post).should include(private_post.id) + expect(alice.visible_shareable_ids(Post)).to include(private_post.id) end it "contains public posts from people you're following" do @@ -30,37 +30,37 @@ describe User::Querying do eves_public_post = eve.post(:status_message, :text => "hello", :to => 'all', :public => true) # Alice should see it - alice.visible_shareable_ids(Post).should include(eves_public_post.id) + expect(alice.visible_shareable_ids(Post)).to include(eves_public_post.id) end it "does not contain non-public posts from people who are following you" do eve.share_with(alice.person, @eves_aspect) eves_post = eve.post(:status_message, :text => "hello", :to => @eves_aspect.id) - alice.visible_shareable_ids(Post).should_not include(eves_post.id) + expect(alice.visible_shareable_ids(Post)).not_to include(eves_post.id) end it "does not contain non-public posts from aspects you're not in" do dogs = bob.aspects.create(:name => "dogs") invisible_post = bob.post(:status_message, :text => "foobar", :to => dogs.id) - alice.visible_shareable_ids(Post).should_not include(invisible_post.id) + expect(alice.visible_shareable_ids(Post)).not_to include(invisible_post.id) end it "does not contain pending posts" do pending_post = bob.post(:status_message, :text => "hey", :public => true, :to => @bobs_aspect.id, :pending => true) - pending_post.should be_pending - alice.visible_shareable_ids(Post).should_not include pending_post.id + expect(pending_post).to be_pending + expect(alice.visible_shareable_ids(Post)).not_to include pending_post.id end it "does not contain pending photos" do pending_photo = bob.post(:photo, :pending => true, :user_file=> File.open(photo_fixture_name), :to => @bobs_aspect) - alice.visible_shareable_ids(Photo).should_not include pending_photo.id + expect(alice.visible_shareable_ids(Photo)).not_to include pending_photo.id end it "respects the :type option" do post = bob.post(:status_message, :text => "hey", :public => true, :to => @bobs_aspect.id, :pending => false) reshare = bob.post(:reshare, :pending => false, :root_guid => post.guid, :to => @bobs_aspect) - alice.visible_shareable_ids(Post, :type => "Reshare").should include(reshare.id) - alice.visible_shareable_ids(Post, :type => 'StatusMessage').should_not include(reshare.id) + expect(alice.visible_shareable_ids(Post, :type => "Reshare")).to include(reshare.id) + expect(alice.visible_shareable_ids(Post, :type => 'StatusMessage')).not_to include(reshare.id) end it "does not contain duplicate posts" do @@ -70,8 +70,8 @@ describe User::Querying do bobs_post = bob.post(:status_message, :text => "hai to all my people", :to => [@bobs_aspect.id, bobs_other_aspect.id]) - alice.visible_shareable_ids(Post).length.should == 1 - alice.visible_shareable_ids(Post).should include(bobs_post.id) + expect(alice.visible_shareable_ids(Post).length).to eq(1) + expect(alice.visible_shareable_ids(Post)).to include(bobs_post.id) end describe 'hidden posts' do @@ -81,13 +81,13 @@ describe User::Querying do end it "pulls back non hidden posts" do - alice.visible_shareable_ids(Post).include?(@status.id).should be true + expect(alice.visible_shareable_ids(Post).include?(@status.id)).to be true end it "does not pull back hidden posts" do visibility = @status.share_visibilities(Post).where(:contact_id => alice.contact_for(bob.person).id).first visibility.update_attributes(:hidden => true) - alice.visible_shareable_ids(Post).include?(@status.id).should be false + expect(alice.visible_shareable_ids(Post).include?(@status.id)).to be false end end end @@ -95,8 +95,8 @@ describe User::Querying do describe "#prep_opts" do it "defaults the opts" do time = Time.now - Time.stub(:now).and_return(time) - alice.send(:prep_opts, Post, {}).should == { + allow(Time).to receive(:now).and_return(time) + expect(alice.send(:prep_opts, Post, {})).to eq({ :type => Stream::Base::TYPES_OF_POST_IN_STREAM, :order => 'created_at DESC', :limit => 15, @@ -104,14 +104,14 @@ describe User::Querying do :order_field => :created_at, :order_with_table => "posts.created_at DESC", :max_time => time + 1 - } + }) end end describe "#visible_shareables" do it 'never contains posts from people not in your aspects' do FactoryGirl.create(:status_message, :public => true) - bob.visible_shareables(Post).count(:all).should == 0 + expect(bob.visible_shareables(Post).count(:all)).to eq(0) end context 'with two posts with the same timestamp' do @@ -124,8 +124,8 @@ describe User::Querying do end it "returns them in reverse creation order" do - bob.visible_shareables(Post).first.text.should == "second" - bob.visible_shareables(Post).last.text.should == "first" + expect(bob.visible_shareables(Post).first.text).to eq("second") + expect(bob.visible_shareables(Post).last.text).to eq("first") end end @@ -146,40 +146,40 @@ describe User::Querying do end it 'works' do # The set up takes a looong time, so to save time we do several tests in one - bob.visible_shareables(Post).length.should == 15 #it returns 15 by default - bob.visible_shareables(Post).map(&:id).should == bob.visible_shareables(Post, :by_members_of => bob.aspects.map { |a| a.id }).map(&:id) # it is the same when joining through aspects + expect(bob.visible_shareables(Post).length).to eq(15) #it returns 15 by default + expect(bob.visible_shareables(Post).map(&:id)).to eq(bob.visible_shareables(Post, :by_members_of => bob.aspects.map { |a| a.id }).map(&:id)) # it is the same when joining through aspects # checks the default sort order - bob.visible_shareables(Post).sort_by { |p| p.created_at }.map { |p| p.id }.should == bob.visible_shareables(Post).map { |p| p.id }.reverse #it is sorted updated_at desc by default + expect(bob.visible_shareables(Post).sort_by { |p| p.created_at }.map { |p| p.id }).to eq(bob.visible_shareables(Post).map { |p| p.id }.reverse) #it is sorted updated_at desc by default # It should respect the order option opts = {:order => 'created_at DESC'} - bob.visible_shareables(Post, opts).first.created_at.should > bob.visible_shareables(Post, opts).last.created_at + expect(bob.visible_shareables(Post, opts).first.created_at).to be > bob.visible_shareables(Post, opts).last.created_at # It should respect the order option opts = {:order => 'updated_at DESC'} - bob.visible_shareables(Post, opts).first.updated_at.should > bob.visible_shareables(Post, opts).last.updated_at + expect(bob.visible_shareables(Post, opts).first.updated_at).to be > bob.visible_shareables(Post, opts).last.updated_at # It should respect the limit option opts = {:limit => 40} - bob.visible_shareables(Post, opts).length.should == 40 - bob.visible_shareables(Post, opts).map(&:id).should == bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map(&:id) - bob.visible_shareables(Post, opts).sort_by { |p| p.created_at }.map { |p| p.id }.should == bob.visible_shareables(Post, opts).map { |p| p.id }.reverse + expect(bob.visible_shareables(Post, opts).length).to eq(40) + expect(bob.visible_shareables(Post, opts).map(&:id)).to eq(bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map(&:id)) + expect(bob.visible_shareables(Post, opts).sort_by { |p| p.created_at }.map { |p| p.id }).to eq(bob.visible_shareables(Post, opts).map { |p| p.id }.reverse) # It should paginate using a datetime timestamp last_time_of_last_page = bob.visible_shareables(Post).last.created_at opts = {:max_time => last_time_of_last_page} - bob.visible_shareables(Post, opts).length.should == 15 - bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id } - bob.visible_shareables(Post, opts).sort_by { |p| p.created_at}.map { |p| p.id }.should == bob.visible_shareables(Post, opts).map { |p| p.id }.reverse - bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, :limit => 40)[15...30].map { |p| p.id } #pagination should return the right posts + expect(bob.visible_shareables(Post, opts).length).to eq(15) + expect(bob.visible_shareables(Post, opts).map { |p| p.id }).to eq(bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id }) + expect(bob.visible_shareables(Post, opts).sort_by { |p| p.created_at}.map { |p| p.id }).to eq(bob.visible_shareables(Post, opts).map { |p| p.id }.reverse) + expect(bob.visible_shareables(Post, opts).map { |p| p.id }).to eq(bob.visible_shareables(Post, :limit => 40)[15...30].map { |p| p.id }) #pagination should return the right posts # It should paginate using an integer timestamp opts = {:max_time => last_time_of_last_page.to_i} - bob.visible_shareables(Post, opts).length.should == 15 - bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id } - bob.visible_shareables(Post, opts).sort_by { |p| p.created_at}.map { |p| p.id }.should == bob.visible_shareables(Post, opts).map { |p| p.id }.reverse - bob.visible_shareables(Post, opts).map { |p| p.id }.should == bob.visible_shareables(Post, :limit => 40)[15...30].map { |p| p.id } #pagination should return the right posts + expect(bob.visible_shareables(Post, opts).length).to eq(15) + expect(bob.visible_shareables(Post, opts).map { |p| p.id }).to eq(bob.visible_shareables(Post, opts.merge(:by_members_of => bob.aspects.map { |a| a.id })).map { |p| p.id }) + expect(bob.visible_shareables(Post, opts).sort_by { |p| p.created_at}.map { |p| p.id }).to eq(bob.visible_shareables(Post, opts).map { |p| p.id }.reverse) + expect(bob.visible_shareables(Post, opts).map { |p| p.id }).to eq(bob.visible_shareables(Post, :limit => 40)[15...30].map { |p| p.id }) #pagination should return the right posts end end end @@ -187,19 +187,19 @@ describe User::Querying do describe '#find_visible_shareable_by_id' do it "returns a post if you can see it" do bobs_post = bob.post(:status_message, :text => "hi", :to => @bobs_aspect.id, :public => false) - alice.find_visible_shareable_by_id(Post, bobs_post.id).should == bobs_post + expect(alice.find_visible_shareable_by_id(Post, bobs_post.id)).to eq(bobs_post) end it "returns nil if you can't see that post" do dogs = bob.aspects.create(:name => "dogs") invisible_post = bob.post(:status_message, :text => "foobar", :to => dogs.id) - alice.find_visible_shareable_by_id(Post, invisible_post.id).should be_nil + expect(alice.find_visible_shareable_by_id(Post, invisible_post.id)).to be_nil end end context 'with two users' do describe '#people_in_aspects' do it 'returns people objects for a users contact in each aspect' do - alice.people_in_aspects([@alices_aspect]).should == [bob.person] + expect(alice.people_in_aspects([@alices_aspect])).to eq([bob.person]) end it 'returns local/remote people objects for a users contact in each aspect' do @@ -220,22 +220,22 @@ describe User::Querying do local_person.save local_person.reload - alice.people_in_aspects([@alices_aspect]).count.should == 4 - alice.people_in_aspects([@alices_aspect], :type => 'remote').count.should == 1 - alice.people_in_aspects([@alices_aspect], :type => 'local').count.should == 3 + expect(alice.people_in_aspects([@alices_aspect]).count).to eq(4) + expect(alice.people_in_aspects([@alices_aspect], :type => 'remote').count).to eq(1) + expect(alice.people_in_aspects([@alices_aspect], :type => 'local').count).to eq(3) end it 'does not return people not connected to user on same pod' do 3.times { FactoryGirl.create(:user) } - alice.people_in_aspects([@alices_aspect]).count.should == 1 + expect(alice.people_in_aspects([@alices_aspect]).count).to eq(1) end it "only returns non-pending contacts" do - alice.people_in_aspects([@alices_aspect]).should == [bob.person] + expect(alice.people_in_aspects([@alices_aspect])).to eq([bob.person]) end it "returns an empty array when passed an aspect the user doesn't own" do - alice.people_in_aspects([@eves_aspect]).should == [] + expect(alice.people_in_aspects([@eves_aspect])).to eq([]) end end end @@ -250,7 +250,7 @@ describe User::Querying do it 'returns a contact' do contact = Contact.create(:user => alice, :person => person_one, :aspects => [aspect]) alice.contacts << contact - alice.contact_for_person_id(person_one.id).should be_truthy + expect(alice.contact_for_person_id(person_one.id)).to be_truthy end it 'returns the correct contact' do @@ -263,28 +263,28 @@ describe User::Querying do contact3 = Contact.create(:user => alice, :person => person_three, :aspects => [aspect]) alice.contacts << contact3 - alice.contact_for_person_id(person_two.id).person.should == person_two + expect(alice.contact_for_person_id(person_two.id).person).to eq(person_two) end it 'returns nil for a non-contact' do - alice.contact_for_person_id(person_one.id).should be_nil + expect(alice.contact_for_person_id(person_one.id)).to be_nil end it 'returns nil when someone else has contact with the target' do contact = Contact.create(:user => alice, :person => person_one, :aspects => [aspect]) alice.contacts << contact - eve.contact_for_person_id(person_one.id).should be_nil + expect(eve.contact_for_person_id(person_one.id)).to be_nil end end describe '#contact_for' do it 'takes a person_id and returns a contact' do - alice.should_receive(:contact_for_person_id).with(person_one.id) + expect(alice).to receive(:contact_for_person_id).with(person_one.id) alice.contact_for(person_one) end it 'returns nil if the input is nil' do - alice.contact_for(nil).should be_nil + expect(alice.contact_for(nil)).to be_nil end end @@ -294,7 +294,7 @@ describe User::Querying do end it 'should return the aspects with given contact' do - alice.aspects_with_person(@connected_person).should == [@alices_aspect] + expect(alice.aspects_with_person(@connected_person)).to eq([@alices_aspect]) end it 'returns multiple aspects if the person is there' do @@ -302,7 +302,7 @@ describe User::Querying do contact = alice.contact_for(@connected_person) alice.add_contact_to_aspect(contact, aspect2) - alice.aspects_with_person(@connected_person).to_set.should == alice.aspects.to_set + expect(alice.aspects_with_person(@connected_person).to_set).to eq(alice.aspects.to_set) end end end @@ -317,11 +317,11 @@ describe User::Querying do end it 'displays public posts for a non-contact' do - alice.posts_from(@user3.person).should include @public_message + expect(alice.posts_from(@user3.person)).to include @public_message end it 'does not display private posts for a non-contact' do - alice.posts_from(@user3.person).should_not include @private_message + expect(alice.posts_from(@user3.person)).not_to include @private_message end it 'displays private and public posts for a non-contact after connecting' do @@ -330,8 +330,8 @@ describe User::Querying do alice.reload - alice.posts_from(@user3.person).should include @public_message - alice.posts_from(@user3.person).should include new_message + expect(alice.posts_from(@user3.person)).to include @public_message + expect(alice.posts_from(@user3.person)).to include new_message end it 'displays recent posts first' do @@ -342,7 +342,7 @@ describe User::Querying do msg4.created_at = Time.now+14 msg4.save! - alice.posts_from(@user3.person).map { |p| p.id }.should == [msg4, msg3, @public_message].map { |p| p.id } + expect(alice.posts_from(@user3.person).map { |p| p.id }).to eq([msg4, msg3, @public_message].map { |p| p.id }) end end end diff --git a/spec/models/user/social_actions_spec.rb b/spec/models/user/social_actions_spec.rb index de486010d..74a67608b 100644 --- a/spec/models/user/social_actions_spec.rb +++ b/spec/models/user/social_actions_spec.rb @@ -1,6 +1,6 @@ require "spec_helper" -describe User::SocialActions do +describe User::SocialActions, :type => :model do before do @bobs_aspect = bob.aspects.where(:name => "generic").first @status = bob.post(:status_message, :text => "hello", :to => @bobs_aspect.id) @@ -8,39 +8,39 @@ describe User::SocialActions do describe 'User#comment!' do it "sets the comment text" do - alice.comment!(@status, "unicorn_mountain").text.should == "unicorn_mountain" + expect(alice.comment!(@status, "unicorn_mountain").text).to eq("unicorn_mountain") end it "creates a partcipation" do - lambda{ alice.comment!(@status, "bro") }.should change(Participation, :count).by(1) - alice.participations.last.target.should == @status + expect{ alice.comment!(@status, "bro") }.to change(Participation, :count).by(1) + expect(alice.participations.last.target).to eq(@status) end it "creates the comment" do - lambda{ alice.comment!(@status, "bro") }.should change(Comment, :count).by(1) + expect{ alice.comment!(@status, "bro") }.to change(Comment, :count).by(1) end it "federates" do - Participation::Generator.any_instance.stub(:create!) - Postzord::Dispatcher.should_receive(:defer_build_and_post) + allow_any_instance_of(Participation::Generator).to receive(:create!) + expect(Postzord::Dispatcher).to receive(:defer_build_and_post) alice.comment!(@status, "omg") end end describe 'User#like!' do it "creates a partcipation" do - lambda{ alice.like!(@status) }.should change(Participation, :count).by(1) - alice.participations.last.target.should == @status + expect{ alice.like!(@status) }.to change(Participation, :count).by(1) + expect(alice.participations.last.target).to eq(@status) end it "creates the like" do - lambda{ alice.like!(@status) }.should change(Like, :count).by(1) + expect{ alice.like!(@status) }.to change(Like, :count).by(1) end it "federates" do #participation and like - Participation::Generator.any_instance.stub(:create!) - Postzord::Dispatcher.should_receive(:defer_build_and_post) + allow_any_instance_of(Participation::Generator).to receive(:create!) + expect(Postzord::Dispatcher).to receive(:defer_build_and_post) alice.like!(@status) end end @@ -52,27 +52,27 @@ describe User::SocialActions do end it "creates a partcipation" do - lambda{ alice.like!(@status) }.should change(Participation, :count).by(1) + expect{ alice.like!(@status) }.to change(Participation, :count).by(1) end it "creates the like" do - lambda{ alice.like!(@status) }.should change(Like, :count).by(1) + expect{ alice.like!(@status) }.to change(Like, :count).by(1) end it "federates" do #participation and like - Postzord::Dispatcher.should_receive(:defer_build_and_post).twice + expect(Postzord::Dispatcher).to receive(:defer_build_and_post).twice alice.like!(@status) end it "should be able to like on one's own status" do like = alice.like!(@status) - @status.reload.likes.first.should == like + expect(@status.reload.likes.first).to eq(like) end it "should be able to like on a contact's status" do like = bob.like!(@status) - @status.reload.likes.first.should == like + expect(@status.reload.likes.first).to eq(like) end it "does not allow multiple likes" do @@ -80,7 +80,7 @@ describe User::SocialActions do likes = @status.likes expect { alice.like!(@status) }.to raise_error - @status.reload.likes.should == likes + expect(@status.reload.likes).to eq(likes) end end @@ -93,21 +93,21 @@ describe User::SocialActions do end it "federates" do - Participation::Generator.any_instance.stub(:create!) - Postzord::Dispatcher.should_receive(:defer_build_and_post) + allow_any_instance_of(Participation::Generator).to receive(:create!) + expect(Postzord::Dispatcher).to receive(:defer_build_and_post) alice.participate_in_poll!(@status, @answer) end it "creates a partcipation" do - lambda{ alice.participate_in_poll!(@status, @answer) }.should change(Participation, :count).by(1) + expect{ alice.participate_in_poll!(@status, @answer) }.to change(Participation, :count).by(1) end it "creates the poll participation" do - lambda{ alice.participate_in_poll!(@status, @answer) }.should change(PollParticipation, :count).by(1) + expect{ alice.participate_in_poll!(@status, @answer) }.to change(PollParticipation, :count).by(1) end it "sets the poll answer id" do - alice.participate_in_poll!(@status, @answer).poll_answer.should == @answer + expect(alice.participate_in_poll!(@status, @answer).poll_answer).to eq(@answer) end end end \ No newline at end of file diff --git a/spec/models/user_preference_spec.rb b/spec/models/user_preference_spec.rb index 25bbe15d2..022b54db8 100644 --- a/spec/models/user_preference_spec.rb +++ b/spec/models/user_preference_spec.rb @@ -1,9 +1,9 @@ require 'spec_helper' -describe UserPreference do +describe UserPreference, :type => :model do it 'should only allow valid email types to exist' do pref = alice.user_preferences.new(:email_type => 'not_valid') - pref.should_not be_valid + expect(pref).not_to be_valid end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 07ed9d905..1f52e78b7 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -4,18 +4,18 @@ require 'spec_helper' -describe User do +describe User, :type => :model do context "relations" do context "#conversations" do it "doesn't find anything when there is nothing to find" do u = FactoryGirl.create(:user) - u.conversations.should be_empty + expect(u.conversations).to be_empty end it "finds the users conversations" do c = FactoryGirl.create(:conversation, { author: alice.person }) - alice.conversations.should include c + expect(alice.conversations).to include c end it "doesn't find other users conversations" do @@ -23,23 +23,23 @@ describe User do c2 = FactoryGirl.create(:conversation) c_own = FactoryGirl.create(:conversation, { author: alice.person }) - alice.conversations.should include c_own - alice.conversations.should_not include c1 - alice.conversations.should_not include c2 + expect(alice.conversations).to include c_own + expect(alice.conversations).not_to include c1 + expect(alice.conversations).not_to include c2 end end end describe "private key" do it 'has a key' do - alice.encryption_key.should_not be nil + expect(alice.encryption_key).not_to be nil end it 'marshalls the key to and from the db correctly' do user = User.build(:username => 'max', :email => 'foo@bar.com', :password => 'password', :password_confirmation => 'password') user.save! - user.serialized_private_key.should be_present + expect(user.serialized_private_key).to be_present expect{ user.reload.encryption_key @@ -52,14 +52,14 @@ describe User do user = FactoryGirl.build(:user) user.last_seen = Time.now - 1.month user.save - User.yearly_actives.should include user + expect(User.yearly_actives).to include user end it 'returns list which does not include users seen within last year' do user = FactoryGirl.build(:user) user.last_seen = Time.now - 2.year user.save - User.yearly_actives.should_not include user + expect(User.yearly_actives).not_to include user end end @@ -68,14 +68,14 @@ describe User do user = FactoryGirl.build(:user) user.last_seen = Time.now - 1.day user.save - User.monthly_actives.should include user + expect(User.monthly_actives).to include user end it 'returns list which does not include users seen within last month' do user = FactoryGirl.build(:user) user.last_seen = Time.now - 2.month user.save - User.monthly_actives.should_not include user + expect(User.monthly_actives).not_to include user end end @@ -84,14 +84,14 @@ describe User do user = FactoryGirl.build(:user) user.last_seen = Time.now - 1.hour user.save - User.daily_actives.should include(user) + expect(User.daily_actives).to include(user) end it 'returns list which does not include users seen within last day' do user = FactoryGirl.build(:user) user.last_seen = Time.now - 2.day user.save - User.daily_actives.should_not include(user) + expect(User.daily_actives).not_to include(user) end end @@ -100,14 +100,14 @@ describe User do user = FactoryGirl.build(:user) user.last_seen = Time.now - 4.month user.save - User.halfyear_actives.should include user + expect(User.halfyear_actives).to include user end it 'returns list which does not include users seen within the last half a year' do user = FactoryGirl.build(:user) user.last_seen = Time.now - 7.month user.save - User.halfyear_actives.should_not include user + expect(User.halfyear_actives).not_to include user end end @@ -115,12 +115,12 @@ describe User do describe '#save_person!' do it 'saves the corresponding user if it has changed' do alice.person.url = "http://stuff.com" - Person.any_instance.should_receive(:save) + expect_any_instance_of(Person).to receive(:save) alice.save end it 'does not save the corresponding user if it has not changed' do - Person.any_instance.should_not_receive(:save) + expect_any_instance_of(Person).not_to receive(:save) alice.save end end @@ -134,13 +134,13 @@ describe User do end it 'is a hash' do - alice.hidden_shareables.should == {} + expect(alice.hidden_shareables).to eq({}) end describe '#add_hidden_shareable' do it 'adds the share id to an array which is keyed by the objects class' do alice.add_hidden_shareable(@sm_class, @sm_id) - alice.hidden_shareables['Post'].should == [@sm_id] + expect(alice.hidden_shareables['Post']).to eq([@sm_id]) end it 'handles having multiple posts' do @@ -148,7 +148,7 @@ describe User do alice.add_hidden_shareable(@sm_class, @sm_id) alice.add_hidden_shareable(sm2.class.base_class.to_s, sm2.id.to_s) - alice.hidden_shareables['Post'].should =~ [@sm_id, sm2.id.to_s] + expect(alice.hidden_shareables['Post']).to match_array([@sm_id, sm2.id.to_s]) end it 'handles having multiple shareable types' do @@ -156,7 +156,7 @@ describe User do alice.add_hidden_shareable(photo.class.base_class.to_s, photo.id.to_s) alice.add_hidden_shareable(@sm_class, @sm_id) - alice.hidden_shareables['Photo'].should == [photo.id.to_s] + expect(alice.hidden_shareables['Photo']).to eq([photo.id.to_s]) end end @@ -164,20 +164,20 @@ describe User do it 'removes the id from the hash if it is there' do alice.add_hidden_shareable(@sm_class, @sm_id) alice.remove_hidden_shareable(@sm_class, @sm_id) - alice.hidden_shareables['Post'].should == [] + expect(alice.hidden_shareables['Post']).to eq([]) end end describe 'toggle_hidden_shareable' do it 'calls add_hidden_shareable if the key does not exist, and returns true' do - alice.should_receive(:add_hidden_shareable).with(@sm_class, @sm_id) - alice.toggle_hidden_shareable(@sm).should be true + expect(alice).to receive(:add_hidden_shareable).with(@sm_class, @sm_id) + expect(alice.toggle_hidden_shareable(@sm)).to be true end it 'calls remove_hidden_shareable if the key exists' do - alice.should_receive(:remove_hidden_shareable).with(@sm_class, @sm_id) + expect(alice).to receive(:remove_hidden_shareable).with(@sm_class, @sm_id) alice.add_hidden_shareable(@sm_class, @sm_id) - alice.toggle_hidden_shareable(@sm).should be false + expect(alice.toggle_hidden_shareable(@sm)).to be false end end @@ -185,12 +185,12 @@ describe User do it 'returns true if the shareable is hidden' do post = FactoryGirl.create(:status_message) bob.toggle_hidden_shareable(post) - bob.is_shareable_hidden?(post).should be true + expect(bob.is_shareable_hidden?(post)).to be true end it 'returns false if the shareable is not present' do post = FactoryGirl.create(:status_message) - bob.is_shareable_hidden?(post).should be false + expect(bob.is_shareable_hidden?(post)).to be false end end end @@ -198,9 +198,9 @@ describe User do describe 'overwriting people' do it 'does not overwrite old users with factory' do - lambda { + expect { new_user = FactoryGirl.create(:user, :id => alice.id) - }.should raise_error ActiveRecord::StatementInvalid + }.to raise_error ActiveRecord::StatementInvalid end it 'does not overwrite old users with create' do @@ -217,8 +217,8 @@ describe User do params[:id] = alice.id new_user = User.build(params) new_user.save - new_user.persisted?.should be true - new_user.id.should_not == alice.id + expect(new_user.persisted?).to be true + expect(new_user.id).not_to eq(alice.id) end end @@ -226,81 +226,81 @@ describe User do describe "of associated person" do it "fails if person is not valid" do user = alice - user.should be_valid + expect(user).to be_valid user.person.serialized_public_key = nil - user.person.should_not be_valid - user.should_not be_valid + expect(user.person).not_to be_valid + expect(user).not_to be_valid - user.errors.full_messages.count.should == 1 - user.errors.full_messages.first.should =~ /Person is invalid/i + expect(user.errors.full_messages.count).to eq(1) + expect(user.errors.full_messages.first).to match(/Person is invalid/i) end end describe "of username" do it "requires presence" do alice.username = nil - alice.should_not be_valid + expect(alice).not_to be_valid end it "requires uniqueness" do alice.username = eve.username - alice.should_not be_valid + expect(alice).not_to be_valid end it 'requires uniqueness also amount Person objects with diaspora handle' do p = FactoryGirl.create(:person, :diaspora_handle => "jimmy#{User.diaspora_id_host}") alice.username = 'jimmy' - alice.should_not be_valid + expect(alice).not_to be_valid end it "downcases username" do user = FactoryGirl.build(:user, :username => "WeIrDcAsE") - user.should be_valid - user.username.should == "weirdcase" + expect(user).to be_valid + expect(user.username).to eq("weirdcase") end it "fails if the requested username is only different in case from an existing username" do alice.username = eve.username.upcase - alice.should_not be_valid + expect(alice).not_to be_valid end it "strips leading and trailing whitespace" do user = FactoryGirl.build(:user, :username => " janie ") - user.should be_valid - user.username.should == "janie" + expect(user).to be_valid + expect(user.username).to eq("janie") end it "fails if there's whitespace in the middle" do alice.username = "bobby tables" - alice.should_not be_valid + expect(alice).not_to be_valid end it 'can not contain non url safe characters' do alice.username = "kittens;" - alice.should_not be_valid + expect(alice).not_to be_valid end it 'should not contain periods' do alice.username = "kittens." - alice.should_not be_valid + expect(alice).not_to be_valid end it "can be 32 characters long" do alice.username = "hexagoooooooooooooooooooooooooon" - alice.should be_valid + expect(alice).to be_valid end it "cannot be 33 characters" do alice.username = "hexagooooooooooooooooooooooooooon" - alice.should_not be_valid + expect(alice).not_to be_valid end it "cannot be one of the blacklist names" do ['hostmaster', 'postmaster', 'root', 'webmaster'].each do |username| alice.username = username - alice.should_not be_valid + expect(alice).not_to be_valid end end end @@ -308,37 +308,37 @@ describe User do describe "of email" do it "requires email address" do alice.email = nil - alice.should_not be_valid + expect(alice).not_to be_valid end it "requires a unique email address" do alice.email = eve.email - alice.should_not be_valid + expect(alice).not_to be_valid end it "requires a valid email address" do alice.email = "somebody@anywhere" - alice.should_not be_valid + expect(alice).not_to be_valid end end describe "of unconfirmed_email" do it "unconfirmed_email address can be nil/blank" do alice.unconfirmed_email = nil - alice.should be_valid + expect(alice).to be_valid alice.unconfirmed_email = "" - alice.should be_valid + expect(alice).to be_valid end it "does NOT require a unique unconfirmed_email address" do eve.update_attribute :unconfirmed_email, "new@email.com" alice.unconfirmed_email = "new@email.com" - alice.should be_valid + expect(alice).to be_valid end it "requires a valid unconfirmed_email address" do alice.unconfirmed_email = "somebody@anywhere" - alice.should_not be_valid + expect(alice).not_to be_valid end end @@ -349,19 +349,19 @@ describe User do it "requires availability" do alice.language = 'some invalid language' - alice.should_not be_valid + expect(alice).not_to be_valid end it "should save with current language if blank" do I18n.locale = :fr user = User.build(:username => 'max', :email => 'foo@bar.com', :password => 'password', :password_confirmation => 'password') - user.language.should == 'fr' + expect(user.language).to eq('fr') end it "should save with language what is set" do I18n.locale = :fr user = User.build(:username => 'max', :email => 'foo@bar.com', :password => 'password', :password_confirmation => 'password', :language => 'de') - user.language.should == 'de' + expect(user.language).to eq('de') end end end @@ -384,17 +384,17 @@ describe User do end it "does not save" do - @user.persisted?.should be false - @user.person.persisted?.should be false - User.find_by_username("ohai").should be_nil + expect(@user.persisted?).to be false + expect(@user.person.persisted?).to be false + expect(User.find_by_username("ohai")).to be_nil end it 'saves successfully' do - @user.should be_valid - @user.save.should be true - @user.persisted?.should be true - @user.person.persisted?.should be true - User.find_by_username("ohai").should == @user + expect(@user).to be_valid + expect(@user.save).to be true + expect(@user.persisted?).to be true + expect(@user.person.persisted?).to be true + expect(User.find_by_username("ohai")).to eq(@user) end end @@ -409,19 +409,19 @@ describe User do end it "raises no error" do - lambda { User.build(@invalid_params) }.should_not raise_error + expect { User.build(@invalid_params) }.not_to raise_error end it "does not save" do - User.build(@invalid_params).save.should be false + expect(User.build(@invalid_params).save).to be false end it 'does not save a person' do - lambda { User.build(@invalid_params) }.should_not change(Person, :count) + expect { User.build(@invalid_params) }.not_to change(Person, :count) end it 'does not generate a key' do - User.should_receive(:generate_key).exactly(0).times + expect(User).to receive(:generate_key).exactly(0).times User.build(@invalid_params) end end @@ -443,7 +443,7 @@ describe User do end it "does not assign it to the person" do - User.build(@invalid_params).person.id.should_not == person.id + expect(User.build(@invalid_params).person.id).not_to eq(person.id) end end end @@ -453,7 +453,7 @@ describe User do inv = InvitationCode.create(:user => bob) user = FactoryGirl.build(:user) user.process_invite_acceptence(inv) - user.invited_by_id.should == bob.id + expect(user.invited_by_id).to eq(bob.id) end end @@ -474,27 +474,27 @@ describe User do expect { alice.update_user_preferences({'mentioned' => false}) }.to change(alice.user_preferences, :count).by(@pref_count-1) - alice.reload.disable_mail.should be false + expect(alice.reload.disable_mail).to be false end end describe ".find_for_database_authentication" do it 'finds a user' do - User.find_for_database_authentication(:username => alice.username).should == alice + expect(User.find_for_database_authentication(:username => alice.username)).to eq(alice) end it 'finds a user by email' do - User.find_for_database_authentication(:username => alice.email).should == alice + expect(User.find_for_database_authentication(:username => alice.email)).to eq(alice) end it "does not preserve case" do - User.find_for_database_authentication(:username => alice.username.upcase).should == alice + expect(User.find_for_database_authentication(:username => alice.username.upcase)).to eq(alice) end it 'errors out when passed a non-hash' do - lambda { + expect { User.find_for_database_authentication(alice.username) - }.should raise_error + }.to raise_error end end @@ -509,26 +509,26 @@ describe User do it 'dispatches the profile when tags are set' do @params = {:tag_string => '#what #hey'} mailman = Postzord::Dispatcher.build(alice, Profile.new) - Postzord::Dispatcher.should_receive(:build).and_return(mailman) - alice.update_profile(@params).should be true + expect(Postzord::Dispatcher).to receive(:build).and_return(mailman) + expect(alice.update_profile(@params)).to be true end it 'sends a profile to their contacts' do mailman = Postzord::Dispatcher.build(alice, Profile.new) - Postzord::Dispatcher.should_receive(:build).and_return(mailman) - alice.update_profile(@params).should be true + expect(Postzord::Dispatcher).to receive(:build).and_return(mailman) + expect(alice.update_profile(@params)).to be true end it 'updates names' do - alice.update_profile(@params).should be true - alice.reload.profile.first_name.should == 'bob' + expect(alice.update_profile(@params)).to be true + expect(alice.reload.profile.first_name).to eq('bob') end it 'updates image_url' do params = {:image_url => "http://clown.com"} - alice.update_profile(params).should be true - alice.reload.profile.image_url.should == "http://clown.com" + expect(alice.update_profile(params)).to be true + expect(alice.reload.profile.image_url).to eq("http://clown.com") end context 'passing in a photo' do @@ -542,20 +542,20 @@ describe User do end it 'updates image_url' do - alice.update_profile(@params).should be true + expect(alice.update_profile(@params)).to be true alice.reload - alice.profile.image_url.should =~ Regexp.new(@photo.url(:thumb_large)) - alice.profile.image_url_medium.should =~ Regexp.new(@photo.url(:thumb_medium)) - alice.profile.image_url_small.should =~ Regexp.new(@photo.url(:thumb_small)) + expect(alice.profile.image_url).to match(Regexp.new(@photo.url(:thumb_large))) + expect(alice.profile.image_url_medium).to match(Regexp.new(@photo.url(:thumb_medium))) + expect(alice.profile.image_url_small).to match(Regexp.new(@photo.url(:thumb_small))) end it 'unpends the photo' do @photo.pending = true @photo.save! @photo.reload - alice.update_profile(@params).should be true - @photo.reload.pending.should be false + expect(alice.update_profile(@params)).to be true + expect(@photo.reload.pending).to be false end end end @@ -563,7 +563,7 @@ describe User do describe '#update_post' do it 'should dispatch post' do photo = alice.build_post(:photo, :user_file => uploaded_photo, :text => "hello", :to => alice.aspects.first.id) - alice.should_receive(:dispatch_post).with(photo) + expect(alice).to receive(:dispatch_post).with(photo) alice.update_post(photo, :text => 'hellp') end end @@ -574,23 +574,23 @@ describe User do end it 'notifies the user if the incoming post mentions them' do - @post.should_receive(:mentions?).with(alice.person).and_return(true) - @post.should_receive(:notify_person).with(alice.person) + expect(@post).to receive(:mentions?).with(alice.person).and_return(true) + expect(@post).to receive(:notify_person).with(alice.person) alice.notify_if_mentioned(@post) end it 'does not notify the user if the incoming post does not mention them' do - @post.should_receive(:mentions?).with(alice.person).and_return(false) - @post.should_not_receive(:notify_person) + expect(@post).to receive(:mentions?).with(alice.person).and_return(false) + expect(@post).not_to receive(:notify_person) alice.notify_if_mentioned(@post) end it 'does not notify the user if the post author is not a contact' do @post = FactoryGirl.build(:status_message, :author => eve.person) - @post.stub(:mentions?).and_return(true) - @post.should_not_receive(:notify_person) + allow(@post).to receive(:mentions?).and_return(true) + expect(@post).not_to receive(:notify_person) alice.notify_if_mentioned(@post) end @@ -600,23 +600,23 @@ describe User do describe '#destroy' do it 'removes invitations from the user' do FactoryGirl.create(:invitation, :sender => alice) - lambda { + expect { alice.destroy - }.should change {alice.invitations_from_me(true).count }.by(-1) + }.to change {alice.invitations_from_me(true).count }.by(-1) end it 'removes invitations to the user' do Invitation.new(:sender => eve, :recipient => alice, :identifier => alice.email, :aspect => eve.aspects.first).save(:validate => false) - lambda { + expect { alice.destroy - }.should change {alice.invitations_to_me(true).count }.by(-1) + }.to change {alice.invitations_to_me(true).count }.by(-1) end it 'removes all service connections' do Services::Facebook.create(:access_token => 'what', :user_id => alice.id) - lambda { + expect { alice.destroy - }.should change { + }.to change { alice.services.count }.by(-1) end @@ -628,13 +628,13 @@ describe User do alice.disable_mail = false alice.save - Workers::Mail::StartedSharing.should_receive(:perform_async).with(alice.id, 'contactrequestid').once + expect(Workers::Mail::StartedSharing).to receive(:perform_async).with(alice.id, 'contactrequestid').once alice.mail(Workers::Mail::StartedSharing, alice.id, 'contactrequestid') end it 'does not enqueue a mail job if the correct corresponding job has a preference entry' do alice.user_preferences.create(:email_type => 'started_sharing') - Workers::Mail::StartedSharing.should_not_receive(:perform_async) + expect(Workers::Mail::StartedSharing).not_to receive(:perform_async) alice.mail(Workers::Mail::StartedSharing, alice.id, 'contactrequestid') end @@ -642,7 +642,7 @@ describe User do alice.disable_mail = true alice.save alice.reload - Workers::Mail::StartedSharing.should_not_receive(:perform_async) + expect(Workers::Mail::StartedSharing).not_to receive(:perform_async) alice.mail(Workers::Mail::StartedSharing, alice.id, 'contactrequestid') end end @@ -656,13 +656,13 @@ describe User do describe "#add_contact_to_aspect" do it 'adds the contact to the aspect' do - lambda { + expect { alice.add_contact_to_aspect(@contact, @new_aspect) - }.should change(@new_aspect.contacts, :count).by(1) + }.to change(@new_aspect.contacts, :count).by(1) end it 'returns true if they are already in the aspect' do - alice.add_contact_to_aspect(@contact, @original_aspect).should be true + expect(alice.add_contact_to_aspect(@contact, @original_aspect)).to be true end end end @@ -679,23 +679,23 @@ describe User do describe '#like_for' do it 'returns the correct like' do - alice.like_for(@message).should == @like - bob.like_for(@message).should == @like2 + expect(alice.like_for(@message)).to eq(@like) + expect(bob.like_for(@message)).to eq(@like2) end it "returns nil if there's no like" do - alice.like_for(@message2).should be_nil + expect(alice.like_for(@message2)).to be_nil end end describe '#liked?' do it "returns true if there's a like" do - alice.liked?(@message).should be true - bob.liked?(@message).should be true + expect(alice.liked?(@message)).to be true + expect(bob.liked?(@message)).to be true end it "returns false if there's no like" do - alice.liked?(@message2).should be false + expect(alice.liked?(@message2)).to be false end end end @@ -705,47 +705,47 @@ describe User do describe "#unconfirmed_email" do it "is nil by default" do - user.unconfirmed_email.should eql(nil) + expect(user.unconfirmed_email).to eql(nil) end it "forces blank to nil" do user.unconfirmed_email = "" user.save! - user.unconfirmed_email.should eql(nil) + expect(user.unconfirmed_email).to eql(nil) end it "is ignored if it equals email" do user.unconfirmed_email = user.email user.save! - user.unconfirmed_email.should eql(nil) + expect(user.unconfirmed_email).to eql(nil) end it "allows change to valid new email" do user.unconfirmed_email = "alice@newmail.com" user.save! - user.unconfirmed_email.should eql("alice@newmail.com") + expect(user.unconfirmed_email).to eql("alice@newmail.com") end end describe "#confirm_email_token" do it "is nil by default" do - user.confirm_email_token.should eql(nil) + expect(user.confirm_email_token).to eql(nil) end it "is autofilled when unconfirmed_email is set to new email" do user.unconfirmed_email = "alice@newmail.com" user.save! - user.confirm_email_token.should_not be_blank - user.confirm_email_token.size.should eql(30) + expect(user.confirm_email_token).not_to be_blank + expect(user.confirm_email_token.size).to eql(30) end it "is set back to nil when unconfirmed_email is empty" do user.unconfirmed_email = "alice@newmail.com" user.save! - user.confirm_email_token.should_not be_blank + expect(user.confirm_email_token).not_to be_blank user.unconfirmed_email = nil user.save! - user.confirm_email_token.should eql(nil) + expect(user.confirm_email_token).to eql(nil) end it "generates new token on every new unconfirmed_email" do @@ -754,21 +754,21 @@ describe User do first_token = user.confirm_email_token user.unconfirmed_email = "alice@andanotherone.com" user.save! - user.confirm_email_token.should_not eql(first_token) - user.confirm_email_token.size.should eql(30) + expect(user.confirm_email_token).not_to eql(first_token) + expect(user.confirm_email_token.size).to eql(30) end end describe '#mail_confirm_email' do it 'enqueues a mail job on user with unconfirmed email' do user.update_attribute(:unconfirmed_email, "alice@newmail.com") - Workers::Mail::ConfirmEmail.should_receive(:perform_async).with(alice.id).once - alice.mail_confirm_email.should eql(true) + expect(Workers::Mail::ConfirmEmail).to receive(:perform_async).with(alice.id).once + expect(alice.mail_confirm_email).to eql(true) end it 'enqueues NO mail job on user without unconfirmed email' do - Workers::Mail::ConfirmEmail.should_not_receive(:perform_async).with(alice.id) - alice.mail_confirm_email.should eql(false) + expect(Workers::Mail::ConfirmEmail).not_to receive(:perform_async).with(alice.id) + expect(alice.mail_confirm_email).to eql(false) end end @@ -779,54 +779,54 @@ describe User do end it 'confirms email and set the unconfirmed_email to email on valid token' do - user.confirm_email(user.confirm_email_token).should eql(true) - user.email.should eql("alice@newmail.com") - user.unconfirmed_email.should eql(nil) - user.confirm_email_token.should eql(nil) + expect(user.confirm_email(user.confirm_email_token)).to eql(true) + expect(user.email).to eql("alice@newmail.com") + expect(user.unconfirmed_email).to eql(nil) + expect(user.confirm_email_token).to eql(nil) end it 'returns false and does not change anything on wrong token' do - user.confirm_email(user.confirm_email_token.reverse).should eql(false) - user.email.should_not eql("alice@newmail.com") - user.unconfirmed_email.should_not eql(nil) - user.confirm_email_token.should_not eql(nil) + expect(user.confirm_email(user.confirm_email_token.reverse)).to eql(false) + expect(user.email).not_to eql("alice@newmail.com") + expect(user.unconfirmed_email).not_to eql(nil) + expect(user.confirm_email_token).not_to eql(nil) end it 'returns false and does not change anything on blank token' do - user.confirm_email("").should eql(false) - user.email.should_not eql("alice@newmail.com") - user.unconfirmed_email.should_not eql(nil) - user.confirm_email_token.should_not eql(nil) + expect(user.confirm_email("")).to eql(false) + expect(user.email).not_to eql("alice@newmail.com") + expect(user.unconfirmed_email).not_to eql(nil) + expect(user.confirm_email_token).not_to eql(nil) end it 'returns false and does not change anything on blank token' do - user.confirm_email(nil).should eql(false) - user.email.should_not eql("alice@newmail.com") - user.unconfirmed_email.should_not eql(nil) - user.confirm_email_token.should_not eql(nil) + expect(user.confirm_email(nil)).to eql(false) + expect(user.email).not_to eql("alice@newmail.com") + expect(user.unconfirmed_email).not_to eql(nil) + expect(user.confirm_email_token).not_to eql(nil) end end context 'on user without unconfirmed email' do it 'returns false and does not change anything on any token' do - user.confirm_email("12345"*6).should eql(false) - user.email.should_not eql("alice@newmail.com") - user.unconfirmed_email.should eql(nil) - user.confirm_email_token.should eql(nil) + expect(user.confirm_email("12345"*6)).to eql(false) + expect(user.email).not_to eql("alice@newmail.com") + expect(user.unconfirmed_email).to eql(nil) + expect(user.confirm_email_token).to eql(nil) end it 'returns false and does not change anything on blank token' do - user.confirm_email("").should eql(false) - user.email.should_not eql("alice@newmail.com") - user.unconfirmed_email.should eql(nil) - user.confirm_email_token.should eql(nil) + expect(user.confirm_email("")).to eql(false) + expect(user.email).not_to eql("alice@newmail.com") + expect(user.unconfirmed_email).to eql(nil) + expect(user.confirm_email_token).to eql(nil) end it 'returns false and does not change anything on blank token' do - user.confirm_email(nil).should eql(false) - user.email.should_not eql("alice@newmail.com") - user.unconfirmed_email.should eql(nil) - user.confirm_email_token.should eql(nil) + expect(user.confirm_email(nil)).to eql(false) + expect(user.email).not_to eql("alice@newmail.com") + expect(user.unconfirmed_email).to eql(nil) + expect(user.confirm_email_token).to eql(nil) end end end @@ -841,14 +841,14 @@ describe User do context "posts" do before do - SignedRetraction.stub(:build).and_return(@retraction) - @retraction.stub(:perform) + allow(SignedRetraction).to receive(:build).and_return(@retraction) + allow(@retraction).to receive(:perform) end it 'sends a retraction' do dispatcher = double - Postzord::Dispatcher.should_receive(:build).with(bob, @retraction, anything()).and_return(dispatcher) - dispatcher.should_receive(:post) + expect(Postzord::Dispatcher).to receive(:build).with(bob, @retraction, anything()).and_return(dispatcher) + expect(dispatcher).to receive(:post) bob.retract(@post) end @@ -859,8 +859,8 @@ describe User do @post.reshares << reshare dispatcher = double - Postzord::Dispatcher.should_receive(:build).with(bob, @retraction, {:additional_subscribers => [person], :services => anything}).and_return(dispatcher) - dispatcher.should_receive(:post) + expect(Postzord::Dispatcher).to receive(:build).with(bob, @retraction, {:additional_subscribers => [person], :services => anything}).and_return(dispatcher) + expect(dispatcher).to receive(:post) bob.retract(@post) end @@ -870,7 +870,7 @@ describe User do describe "#send_reset_password_instructions" do it "queues up a job to send the reset password instructions" do user = FactoryGirl.create :user - Workers::ResetPassword.should_receive(:perform_async).with(user.id) + expect(Workers::ResetPassword).to receive(:perform_async).with(user.id) user.send_reset_password_instructions end end @@ -886,7 +886,7 @@ describe User do [I18n.t('aspects.seed.family'), I18n.t('aspects.seed.friends'), I18n.t('aspects.seed.work'), I18n.t('aspects.seed.acquaintances')].each do |aspect_name| it "creates an aspect named #{aspect_name} for the user" do - user.aspects.find_by_name(aspect_name).should_not be_nil + expect(user.aspects.find_by_name(aspect_name)).not_to be_nil end end end @@ -912,8 +912,8 @@ describe User do AppConfig.settings.autofollow_on_join_user = 'one' wf_double = double - wf_double.should_receive(:fetch) - Webfinger.should_receive(:new).with('one').and_return(wf_double) + expect(wf_double).to receive(:fetch) + expect(Webfinger).to receive(:new).with('one').and_return(wf_double) user.seed_aspects end @@ -923,7 +923,7 @@ describe User do it "should not start sharing with the diasporahq account" do AppConfig.settings.autofollow_on_join = false - Webfinger.should_not_receive(:new) + expect(Webfinger).not_to receive(:new) user.seed_aspects end @@ -939,7 +939,7 @@ describe User do describe "#close_account!" do it 'locks the user out' do @user.close_account! - @user.reload.access_locked?.should be true + expect(@user.reload.access_locked?).to be true end it 'creates an account deletion' do @@ -949,7 +949,7 @@ describe User do end it 'calls person#lock_access!' do - @user.person.should_receive(:lock_access!) + expect(@user.person).to receive(:lock_access!) @user.close_account! end end @@ -957,7 +957,7 @@ describe User do describe "#clear_account!" do it 'resets the password to a random string' do random_pass = "12345678909876543210" - SecureRandom.should_receive(:hex).and_return(random_pass) + expect(SecureRandom).to receive(:hex).and_return(random_pass) @user.clear_account! @user.valid_password?(random_pass) end @@ -969,7 +969,7 @@ describe User do @user.reload attributes.each do |attr| - @user.send(attr.to_sym).should be_blank + expect(@user.send(attr.to_sym)).to be_blank end end end @@ -977,7 +977,7 @@ describe User do describe "#clearable_attributes" do it 'returns the clearable fields' do user = FactoryGirl.create :user - user.send(:clearable_fields).sort.should == %w{ + expect(user.send(:clearable_fields).sort).to eq(%w{ language invitation_token invitation_sent_at @@ -1001,7 +1001,7 @@ describe User do unconfirmed_email confirm_email_token last_seen - }.sort + }.sort) end end end @@ -1025,13 +1025,13 @@ describe User do it "saves with captcha off" do AppConfig.settings.captcha.enable = false - @user.should_receive(:save).and_return(true) + expect(@user).to receive(:save).and_return(true) @user.sign_up end it "saves with captcha on" do AppConfig.settings.captcha.enable = true - @user.should_receive(:save_with_captcha).and_return(true) + expect(@user).to receive(:save_with_captcha).and_return(true) @user.sign_up end end diff --git a/spec/presenters/aspect_presenter_spec.rb b/spec/presenters/aspect_presenter_spec.rb index d38b97f42..ba2bb5b4a 100644 --- a/spec/presenters/aspect_presenter_spec.rb +++ b/spec/presenters/aspect_presenter_spec.rb @@ -7,7 +7,7 @@ describe AspectPresenter do describe '#to_json' do it 'works' do - @presenter.to_json.should be_present + expect(@presenter.to_json).to be_present end end end \ No newline at end of file diff --git a/spec/presenters/o_embed_presenter_spec.rb b/spec/presenters/o_embed_presenter_spec.rb index d343ba96c..bf8192675 100644 --- a/spec/presenters/o_embed_presenter_spec.rb +++ b/spec/presenters/o_embed_presenter_spec.rb @@ -5,31 +5,31 @@ describe OEmbedPresenter do end it 'is a hash' do - @oembed.as_json.should be_a Hash + expect(@oembed.as_json).to be_a Hash end context 'required options from oembed spec' do it 'supports maxheight + maxwidth(required)' do oembed = OEmbedPresenter.new(FactoryGirl.create(:status_message), :maxwidth => 200, :maxheight => 300).as_json - oembed[:width].should == 200 - oembed[:height].should == 300 + expect(oembed[:width]).to eq(200) + expect(oembed[:height]).to eq(300) end end describe '#iframe_html' do it 'passes the height options to post_iframe_url' do - @oembed.should_receive(:post_iframe_url).with(instance_of(Fixnum), instance_of(Hash)) + expect(@oembed).to receive(:post_iframe_url).with(instance_of(Fixnum), instance_of(Hash)) @oembed.iframe_html end end describe '.id_from_url' do it 'takes a long post url and gives you the id' do - OEmbedPresenter.id_from_url('http://localhost:400/posts/1').should == "1" + expect(OEmbedPresenter.id_from_url('http://localhost:400/posts/1')).to eq("1") end it 'takes a short post url and gives you the id' do - OEmbedPresenter.id_from_url('http://localhost:400/p/1').should == "1" + expect(OEmbedPresenter.id_from_url('http://localhost:400/p/1')).to eq("1") end end end \ No newline at end of file diff --git a/spec/presenters/person_presenter_spec.rb b/spec/presenters/person_presenter_spec.rb index 4eb502f0a..433b08bbf 100644 --- a/spec/presenters/person_presenter_spec.rb +++ b/spec/presenters/person_presenter_spec.rb @@ -7,7 +7,7 @@ describe PersonPresenter do describe "#as_json" do context "with no current_user" do it "returns the user's public information if a user is not logged in" do - PersonPresenter.new(person, nil).as_json.should include(person.as_api_response(:backbone)) + expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone)) end end @@ -16,16 +16,16 @@ describe PersonPresenter do let(:presenter){ PersonPresenter.new(person, current_user) } it "doesn't share private information when the users aren't connected" do - presenter.as_json.should_not have_key(:location) + expect(presenter.as_json).not_to have_key(:location) end it "has private information when the person is sharing with the current user" do - person.should_receive(:shares_with).with(current_user).and_return(true) - presenter.as_json.should have_key(:location) + expect(person).to receive(:shares_with).with(current_user).and_return(true) + expect(presenter.as_json).to have_key(:location) end it "returns the user's private information if a user is logged in as herself" do - PersonPresenter.new(current_user.person, current_user).as_json.should have_key(:location) + expect(PersonPresenter.new(current_user.person, current_user).as_json).to have_key(:location) end end end diff --git a/spec/presenters/post_presenter_spec.rb b/spec/presenters/post_presenter_spec.rb index e487465e1..293f0337c 100644 --- a/spec/presenters/post_presenter_spec.rb +++ b/spec/presenters/post_presenter_spec.rb @@ -9,38 +9,38 @@ describe PostPresenter do end it 'takes a post and an optional user' do - @presenter.should_not be_nil + expect(@presenter).not_to be_nil end describe '#as_json' do it 'works with a user' do - @presenter.as_json.should be_a Hash + expect(@presenter.as_json).to be_a Hash end it 'works without a user' do - @unauthenticated_presenter.as_json.should be_a Hash + expect(@unauthenticated_presenter.as_json).to be_a Hash end end describe '#user_like' do it 'includes the users like' do bob.like!(@sm) - @presenter.user_like.should be_present + expect(@presenter.user_like).to be_present end it 'is nil if the user is not authenticated' do - @unauthenticated_presenter.user_like.should be_nil + expect(@unauthenticated_presenter.user_like).to be_nil end end describe '#user_reshare' do it 'includes the users reshare' do bob.reshare!(@sm) - @presenter.user_reshare.should be_present + expect(@presenter.user_reshare).to be_present end it 'is nil if the user is not authenticated' do - @unauthenticated_presenter.user_reshare.should be_nil + expect(@unauthenticated_presenter.user_reshare).to be_nil end end @@ -68,7 +68,7 @@ describe PostPresenter do context 'with posts with text' do it "delegates to message.title" do message = double(present?: true) - message.should_receive(:title) + expect(message).to receive(:title) @presenter.post = double(message: message) @presenter.title end @@ -78,7 +78,7 @@ describe PostPresenter do it ' displays a messaage with the post class' do @sm = double(message: double(present?: false), author: bob.person, author_name: bob.person.name) @presenter.post = @sm - @presenter.title.should == "A post from #{@sm.author.name}" + expect(@presenter.title).to eq("A post from #{@sm.author.name}") end end end @@ -86,7 +86,7 @@ describe PostPresenter do describe '#poll' do it 'works without a user' do presenter = PostPresenter.new(@sm_with_poll) - presenter.as_json.should be_a(Hash) + expect(presenter.as_json).to be_a(Hash) end end end diff --git a/spec/presenters/service_presenter_spec.rb b/spec/presenters/service_presenter_spec.rb index 62c959af9..046645552 100644 --- a/spec/presenters/service_presenter_spec.rb +++ b/spec/presenters/service_presenter_spec.rb @@ -4,7 +4,7 @@ describe ServicePresenter do describe '#as_json' do it 'includes the provider name of the json' do presenter = ServicePresenter.new(double(:provider => "fakebook")) - presenter.as_json[:provider].should == 'fakebook' + expect(presenter.as_json[:provider]).to eq('fakebook') end end end \ No newline at end of file diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index e1d17103b..61359752e 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -7,8 +7,8 @@ describe StatisticsPresenter do describe '#as_json' do it 'works' do - @presenter.as_json.should be_present - @presenter.as_json.should be_a Hash + expect(@presenter.as_json).to be_present + expect(@presenter.as_json).to be_a Hash end end @@ -19,12 +19,12 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.post_counts = false AppConfig.privacy.statistics.comment_counts = false AppConfig.services = {"facebook" => nil} - @presenter.as_json.should == { + expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, "facebook" => false - } + }) end context 'when services are enabled' do @@ -41,7 +41,7 @@ describe StatisticsPresenter do end it 'provides generic pod data and counts in json' do - @presenter.as_json.should == { + expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, @@ -54,7 +54,7 @@ describe StatisticsPresenter do "twitter" => true, "tumblr" => false, "wordpress" => false - } + }) end end diff --git a/spec/presenters/user_presenter_spec.rb b/spec/presenters/user_presenter_spec.rb index 04b57b4c1..aa9ecf7ce 100644 --- a/spec/presenters/user_presenter_spec.rb +++ b/spec/presenters/user_presenter_spec.rb @@ -7,31 +7,31 @@ describe UserPresenter do describe '#to_json' do it 'works' do - @presenter.to_json.should be_present + expect(@presenter.to_json).to be_present end end describe '#aspects' do it 'provides an array of the jsonified aspects' do aspect = bob.aspects.first - @presenter.aspects.first[:id].should == aspect.id - @presenter.aspects.first[:name].should == aspect.name + expect(@presenter.aspects.first[:id]).to eq(aspect.id) + expect(@presenter.aspects.first[:name]).to eq(aspect.name) end end describe '#services' do it 'provides an array of jsonifed services' do fakebook = double(:provider => 'fakebook') - bob.stub(:services).and_return([fakebook]) - @presenter.services.should include(:provider => 'fakebook') + allow(bob).to receive(:services).and_return([fakebook]) + expect(@presenter.services).to include(:provider => 'fakebook') end end describe '#configured_services' do it 'displays a list of the users configured services' do fakebook = double(:provider => 'fakebook') - bob.stub(:services).and_return([fakebook]) - @presenter.configured_services.should include("fakebook") + allow(bob).to receive(:services).and_return([fakebook]) + expect(@presenter.configured_services).to include("fakebook") end end end diff --git a/spec/shared_behaviors/account_deletion.rb b/spec/shared_behaviors/account_deletion.rb index 4d5d3c46d..027442b14 100644 --- a/spec/shared_behaviors/account_deletion.rb +++ b/spec/shared_behaviors/account_deletion.rb @@ -6,34 +6,34 @@ require 'spec_helper' shared_examples_for 'it removes the person associations' do it "removes all of the person's posts" do - Post.where(:author_id => @person.id).count.should == 0 + expect(Post.where(:author_id => @person.id).count).to eq(0) end it 'deletes all person contacts' do - Contact.where(:person_id => @person.id).should be_empty + expect(Contact.where(:person_id => @person.id)).to be_empty end it 'deletes all mentions' do - @person.mentions.should be_empty + expect(@person.mentions).to be_empty end it "removes all of the person's photos" do - Photo.where(:author_id => @person.id).should be_empty + expect(Photo.where(:author_id => @person.id)).to be_empty end it 'sets the person object as closed and the profile is cleared' do - @person.reload.closed_account.should be true + expect(@person.reload.closed_account).to be true - @person.profile.reload.first_name.should be_blank - @person.profile.reload.last_name.should be_blank + expect(@person.profile.reload.first_name).to be_blank + expect(@person.profile.reload.last_name).to be_blank end it 'deletes only the converersation visibility for the deleted user' do - ConversationVisibility.where(:person_id => alice.person.id).should_not be_empty - ConversationVisibility.where(:person_id => @person.id).should be_empty + expect(ConversationVisibility.where(:person_id => alice.person.id)).not_to be_empty + expect(ConversationVisibility.where(:person_id => @person.id)).to be_empty end it "deletes the share visibilities on the person's posts" do - ShareVisibility.for_contacts_of_a_person(@person).should be_empty + expect(ShareVisibility.for_contacts_of_a_person(@person)).to be_empty end end diff --git a/spec/shared_behaviors/relayable.rb b/spec/shared_behaviors/relayable.rb index fdd4b484e..6973f6e1f 100644 --- a/spec/shared_behaviors/relayable.rb +++ b/spec/shared_behaviors/relayable.rb @@ -12,7 +12,7 @@ shared_examples_for "it is relayable" do relayable = build_object relayable.save if relayable.parent.respond_to?(:interacted_at) #I'm sorry. - relayable.parent.interacted_at.to_i.should == relayable.created_at.to_i + expect(relayable.parent.interacted_at.to_i).to eq(relayable.created_at.to_i) end end end @@ -27,14 +27,14 @@ shared_examples_for "it is relayable" do end it "is invalid" do - @relayable.should_not be_valid - @relayable.errors[:author_id].size.should == 1 + expect(@relayable).not_to be_valid + expect(@relayable.errors[:author_id].size).to eq(1) end it "sends a retraction for the object" do skip 'need to figure out how to test this' - RelayableRetraction.should_receive(:build) - Postzord::Dispatcher.should_receive(:build) + expect(RelayableRetraction).to receive(:build) + expect(Postzord::Dispatcher).to receive(:build) @relayable.valid? end @@ -49,7 +49,7 @@ shared_examples_for "it is relayable" do relayable = build_object relayable.save! bob.blocks.create(:person => alice.person) - relayable.should be_valid + expect(relayable).to be_valid end end end @@ -58,26 +58,26 @@ shared_examples_for "it is relayable" do context 'encryption' do describe '#parent_author_signature' do it 'should sign the object if the user is the post author' do - @object_by_parent_author.verify_parent_author_signature.should be true + expect(@object_by_parent_author.verify_parent_author_signature).to be true end it 'does not sign as the parent author is not parent' do @object_by_recipient.author_signature = @object_by_recipient.send(:sign_with_key, @local_leia.encryption_key) - @object_by_recipient.verify_parent_author_signature.should be false + expect(@object_by_recipient.verify_parent_author_signature).to be false end it 'should verify a object made on a remote post by a different contact' do @object_by_recipient.author_signature = @object_by_recipient.send(:sign_with_key, @local_leia.encryption_key) @object_by_recipient.parent_author_signature = @object_by_recipient.send(:sign_with_key, @local_luke.encryption_key) - @object_by_recipient.verify_parent_author_signature.should be true + expect(@object_by_recipient.verify_parent_author_signature).to be true end end describe '#author_signature' do it 'should sign as the object author' do - @object_on_remote_parent.signature_valid?.should be true - @object_by_parent_author.signature_valid?.should be true - @object_by_recipient.signature_valid?.should be true + expect(@object_on_remote_parent.signature_valid?).to be true + expect(@object_by_parent_author.signature_valid?).to be true + expect(@object_by_recipient.signature_valid?).to be true end end end @@ -93,36 +93,36 @@ shared_examples_for "it is relayable" do it 'does not process if post_creator_signature is invalid' do @object_by_parent_author.delete # remove object from db so we set a creator sig @dup_object_by_parent_author.parent_author_signature = "dsfadsfdsa" - @dup_object_by_parent_author.receive(@local_leia, @local_luke.person).should == nil + expect(@dup_object_by_parent_author.receive(@local_leia, @local_luke.person)).to eq(nil) end it 'signs when the person receiving is the parent author' do @object_by_recipient.save @object_by_recipient.receive(@local_luke, @local_leia.person) - @object_by_recipient.reload.parent_author_signature.should_not be_blank + expect(@object_by_recipient.reload.parent_author_signature).not_to be_blank end it 'dispatches when the person receiving is the parent author' do p = Postzord::Dispatcher.build(@local_luke, @object_by_recipient) - p.should_receive(:post) - p.class.stub(:new).and_return(p) + expect(p).to receive(:post) + allow(p.class).to receive(:new).and_return(p) @object_by_recipient.receive(@local_luke, @local_leia.person) end it 'calls after_receive callback' do - @object_by_recipient.should_receive(:after_receive) - @object_by_recipient.class.stub(:where).and_return([@object_by_recipient]) + expect(@object_by_recipient).to receive(:after_receive) + allow(@object_by_recipient.class).to receive(:where).and_return([@object_by_recipient]) @object_by_recipient.receive(@local_luke, @local_leia.person) end end describe '#subscribers' do it 'returns the posts original audience, if the post is owned by the user' do - @object_by_parent_author.subscribers(@local_luke).map(&:id).should =~ [@local_leia.person, @remote_raphael].map(&:id) + expect(@object_by_parent_author.subscribers(@local_luke).map(&:id)).to match_array([@local_leia.person, @remote_raphael].map(&:id)) end it 'returns the owner of the original post, if the user owns the object' do - @object_by_recipient.subscribers(@local_leia).map(&:id).should =~ [@local_luke.person].map(&:id) + expect(@object_by_recipient.subscribers(@local_leia).map(&:id)).to match_array([@local_luke.person].map(&:id)) end end end diff --git a/spec/shared_behaviors/stream.rb b/spec/shared_behaviors/stream.rb index 9207be34e..d49233588 100644 --- a/spec/shared_behaviors/stream.rb +++ b/spec/shared_behaviors/stream.rb @@ -3,41 +3,41 @@ require 'spec_helper' shared_examples_for 'it is a stream' do context 'required methods for display' do it '#title' do - @stream.title.should_not be_nil + expect(@stream.title).not_to be_nil end it '#posts' do - @stream.posts.should_not be_nil + expect(@stream.posts).not_to be_nil end it '#people' do - @stream.people.should_not be_nil + expect(@stream.people).not_to be_nil end it '#publisher_opts' do - @stream.send(:publisher_opts).should_not be_nil + expect(@stream.send(:publisher_opts)).not_to be_nil end it 'has a #contacts title' do - @stream.contacts_title.should_not be_nil + expect(@stream.contacts_title).not_to be_nil end it 'has a contacts link' do - @stream.contacts_link.should_not be_nil + expect(@stream.contacts_link).not_to be_nil end it 'should make the stream a time object' do @stream.max_time = 123 - @stream.max_time.should be_a(Time) + expect(@stream.max_time).to be_a(Time) end it 'should always have an order (default created_at)' do @stream.order=nil - @stream.order.should_not be_nil + expect(@stream.order).not_to be_nil end it 'initializes a publisher' do - @stream.publisher.should be_a(Publisher) + expect(@stream.publisher).to be_a(Publisher) end end end diff --git a/spec/shared_behaviors/taggable.rb b/spec/shared_behaviors/taggable.rb index 95b202352..0eddd92cb 100644 --- a/spec/shared_behaviors/taggable.rb +++ b/spec/shared_behaviors/taggable.rb @@ -21,18 +21,18 @@ shared_examples_for "it is taggable" do end it "supports non-ascii characters" do - @object.tags(true).map(&:name).should include('vöglein') + expect(@object.tags(true).map(&:name)).to include('vöglein') end it 'links each tag' do formatted_string = Diaspora::Taggable.format_tags(@str) - formatted_string.should include(tag_link('what')) - formatted_string.should include(tag_link('hey')) - formatted_string.should include(tag_link('vöglein')) + expect(formatted_string).to include(tag_link('what')) + expect(formatted_string).to include(tag_link('hey')) + expect(formatted_string).to include(tag_link('vöglein')) end it 'responds to plain_text' do - Diaspora::Taggable.format_tags(@str, :plain_text => true).should == @str + expect(Diaspora::Taggable.format_tags(@str, :plain_text => true)).to eq(@str) end it "doesn't mangle text when tags are involved" do @@ -78,7 +78,7 @@ shared_examples_for "it is taggable" do } expected.each do |input,output| - Diaspora::Taggable.format_tags(input).should == output + expect(Diaspora::Taggable.format_tags(input)).to eq(output) end end end @@ -87,10 +87,10 @@ shared_examples_for "it is taggable" do it 'builds the tags' do @object.send(@object.class.field_with_tags_setter, '#what') @object.build_tags - @object.tag_list.should == ['what'] - lambda { + expect(@object.tag_list).to eq(['what']) + expect { @object.save - }.should change{@object.tags.count}.by(1) + }.to change{@object.tags.count}.by(1) end end @@ -100,7 +100,7 @@ shared_examples_for "it is taggable" do arr = ['what', 'hey', 'that', 'THATWASMYBIKE', 'vöglein', '135440we', 'abc', 'h', 'ok', 'see', 're'] @object.send(@object.class.field_with_tags_setter, str) - @object.tag_strings.should =~ arr + expect(@object.tag_strings).to match_array(arr) end it 'extracts tags despite surrounding text' do @@ -143,7 +143,7 @@ shared_examples_for "it is taggable" do expected.each do |text,hashtag| @object.send @object.class.field_with_tags_setter, text - @object.tag_strings.should == [hashtag].compact + expect(@object.tag_strings).to eq([hashtag].compact) end end @@ -152,7 +152,7 @@ shared_examples_for "it is taggable" do arr = ['what','whaaaaaaaaaat'] @object.send(@object.class.field_with_tags_setter, str) - @object.tag_strings.should =~ arr + expect(@object.tag_strings).to match_array(arr) end it 'is case insensitive' do @@ -160,7 +160,7 @@ shared_examples_for "it is taggable" do arr = ['what'] @object.send(@object.class.field_with_tags_setter, str) - @object.tag_strings.should =~ arr + expect(@object.tag_strings).to match_array(arr) end end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 8f67a0335..63c056554 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -83,8 +83,8 @@ prefork = proc do stub_request(:post, "https://pubsubhubbub.appspot.com/") disable_typhoeus $process_queue = false - Postzord::Dispatcher::Public.any_instance.stub(:deliver_to_remote) - Postzord::Dispatcher::Private.any_instance.stub(:deliver_to_remote) + allow_any_instance_of(Postzord::Dispatcher::Public).to receive(:deliver_to_remote) + allow_any_instance_of(Postzord::Dispatcher::Private).to receive(:deliver_to_remote) end diff --git a/spec/workers/delete_account_spec.rb b/spec/workers/delete_account_spec.rb index 5f374cfd3..dd604f7d8 100644 --- a/spec/workers/delete_account_spec.rb +++ b/spec/workers/delete_account_spec.rb @@ -8,8 +8,8 @@ describe Workers::DeleteAccount do describe '#perform' do it 'performs the account deletion' do account_deletion = double - AccountDeletion.stub(:find).and_return(account_deletion) - account_deletion.should_receive(:perform!) + allow(AccountDeletion).to receive(:find).and_return(account_deletion) + expect(account_deletion).to receive(:perform!) Workers::DeleteAccount.new.perform(1) end diff --git a/spec/workers/delete_post_from_service_spec.rb b/spec/workers/delete_post_from_service_spec.rb index b941335c1..75e902034 100644 --- a/spec/workers/delete_post_from_service_spec.rb +++ b/spec/workers/delete_post_from_service_spec.rb @@ -9,8 +9,8 @@ describe Workers::DeletePostFromService do it 'calls service#delete_post with given service' do m = double() url = "foobar" - m.should_receive(:delete_post) - Service.stub(:find_by_id).and_return(m) + expect(m).to receive(:delete_post) + allow(Service).to receive(:find_by_id).and_return(m) Workers::DeletePostFromService.new.perform("123", @post.id.to_s) end end diff --git a/spec/workers/fetch_profile_photo_spec.rb b/spec/workers/fetch_profile_photo_spec.rb index 24afa1d70..0b118ce7e 100644 --- a/spec/workers/fetch_profile_photo_spec.rb +++ b/spec/workers/fetch_profile_photo_spec.rb @@ -7,36 +7,36 @@ describe Workers::FetchProfilePhoto do @url = "https://service.com/user/profile_image" - @service.stub(:profile_photo_url).and_return(@url) - @user.stub(:update_profile) + allow(@service).to receive(:profile_photo_url).and_return(@url) + allow(@user).to receive(:update_profile) - User.stub(:find).and_return(@user) - Service.stub(:find).and_return(@service) + allow(User).to receive(:find).and_return(@user) + allow(Service).to receive(:find).and_return(@service) @photo_double = double - @photo_double.stub(:save!).and_return(true) - @photo_double.stub(:url).and_return("image.jpg") + allow(@photo_double).to receive(:save!).and_return(true) + allow(@photo_double).to receive(:url).and_return("image.jpg") end it 'saves the profile image' do - @photo_double.should_receive(:save!).and_return(true) - Photo.should_receive(:diaspora_initialize).with(hash_including(:author => @user.person, :image_url => @url, :pending => true)).and_return(@photo_double) + expect(@photo_double).to receive(:save!).and_return(true) + expect(Photo).to receive(:diaspora_initialize).with(hash_including(:author => @user.person, :image_url => @url, :pending => true)).and_return(@photo_double) Workers::FetchProfilePhoto.new.perform(@user.id, @service.id) end context "service does not have a profile_photo_url" do it "does nothing without fallback" do - @service.stub(:profile_photo_url).and_return(nil) - Photo.should_not_receive(:diaspora_initialize) + allow(@service).to receive(:profile_photo_url).and_return(nil) + expect(Photo).not_to receive(:diaspora_initialize) Workers::FetchProfilePhoto.new.perform(@user.id, @service.id) end it "fetches fallback if it's provided" do - @photo_double.should_receive(:save!).and_return(true) - @service.stub(:profile_photo_url).and_return(nil) - Photo.should_receive(:diaspora_initialize).with(hash_including(:author => @user.person, :image_url => "https://service.com/fallback_lowres.jpg", :pending => true)).and_return(@photo_double) + expect(@photo_double).to receive(:save!).and_return(true) + allow(@service).to receive(:profile_photo_url).and_return(nil) + expect(Photo).to receive(:diaspora_initialize).with(hash_including(:author => @user.person, :image_url => "https://service.com/fallback_lowres.jpg", :pending => true)).and_return(@photo_double) Workers::FetchProfilePhoto.new.perform(@user.id, @service.id, "https://service.com/fallback_lowres.jpg") end @@ -44,10 +44,10 @@ describe Workers::FetchProfilePhoto do it 'updates the profile' do - @photo_double.stub(:url).and_return("large.jpg", "medium.jpg", "small.jpg") + allow(@photo_double).to receive(:url).and_return("large.jpg", "medium.jpg", "small.jpg") - Photo.should_receive(:diaspora_initialize).and_return(@photo_double) - @user.should_receive(:update_profile).with(hash_including({ + expect(Photo).to receive(:diaspora_initialize).and_return(@photo_double) + expect(@user).to receive(:update_profile).with(hash_including({ :image_url => "large.jpg", :image_url_medium => "medium.jpg", :image_url_small => "small.jpg" diff --git a/spec/workers/gather_o_embed_data_spec.rb b/spec/workers/gather_o_embed_data_spec.rb index 1593ed4e0..97177d7de 100644 --- a/spec/workers/gather_o_embed_data_spec.rb +++ b/spec/workers/gather_o_embed_data_spec.rb @@ -32,7 +32,7 @@ describe Workers::GatherOEmbedData do it 'requests not data from the internet' do Workers::GatherOEmbedData.new.perform(@status_message.id, @flickr_photo_url) - a_request(:get, @flickr_oembed_get_request).should have_been_made + expect(a_request(:get, @flickr_oembed_get_request)).to have_been_made end it 'requests not data from the internet only once' do @@ -40,7 +40,7 @@ describe Workers::GatherOEmbedData do Workers::GatherOEmbedData.new.perform(@status_message.id, @flickr_photo_url) end - a_request(:get, @flickr_oembed_get_request).should have_been_made.times(1) + expect(a_request(:get, @flickr_oembed_get_request)).to have_been_made.times(1) end it 'creates one cache entry' do @@ -48,16 +48,16 @@ describe Workers::GatherOEmbedData do expected_data = @flickr_oembed_data expected_data['trusted_endpoint_url'] = @flickr_oembed_url - OEmbedCache.find_by_url(@flickr_photo_url).data.should == expected_data + expect(OEmbedCache.find_by_url(@flickr_photo_url).data).to eq(expected_data) Workers::GatherOEmbedData.new.perform(@status_message.id, @flickr_photo_url) - OEmbedCache.where(url: @flickr_photo_url).count.should == 1 + expect(OEmbedCache.where(url: @flickr_photo_url).count).to eq(1) end it 'creates no cache entry for unsupported pages' do Workers::GatherOEmbedData.new.perform(@status_message.id, @no_oembed_url) - OEmbedCache.find_by_url(@no_oembed_url).should be_nil + expect(OEmbedCache.find_by_url(@no_oembed_url)).to be_nil end it 'gracefully handles a deleted post' do diff --git a/spec/workers/gather_open_graph_data_spec.rb b/spec/workers/gather_open_graph_data_spec.rb index dbe53ff81..7c2397e4f 100644 --- a/spec/workers/gather_open_graph_data_spec.rb +++ b/spec/workers/gather_open_graph_data_spec.rb @@ -28,7 +28,7 @@ describe Workers::GatherOpenGraphData do it 'requests not data from the internet' do Workers::GatherOpenGraphData.new.perform(@status_message.id, @ogsite_url) - a_request(:get, @ogsite_url).should have_been_made + expect(a_request(:get, @ogsite_url)).to have_been_made end it 'requests not data from the internet only once' do @@ -36,7 +36,7 @@ describe Workers::GatherOpenGraphData do Workers::GatherOpenGraphData.new.perform(@status_message.id, @ogsite_url) end - a_request(:get, @ogsite_url).should have_been_made.times(1) + expect(a_request(:get, @ogsite_url)).to have_been_made.times(1) end it 'creates one cache entry' do @@ -44,20 +44,20 @@ describe Workers::GatherOpenGraphData do ogc = OpenGraphCache.find_by_url(@ogsite_url) - ogc.title.should == @ogsite_title - ogc.ob_type.should == @ogsite_type - ogc.image.should == @ogsite_url + @ogsite_image - ogc.url.should == @ogsite_url - ogc.description.should == @ogsite_description + expect(ogc.title).to eq(@ogsite_title) + expect(ogc.ob_type).to eq(@ogsite_type) + expect(ogc.image).to eq(@ogsite_url + @ogsite_image) + expect(ogc.url).to eq(@ogsite_url) + expect(ogc.description).to eq(@ogsite_description) Workers::GatherOpenGraphData.new.perform(@status_message.id, @ogsite_url) - OpenGraphCache.where(url: @ogsite_url).count.should == 1 + expect(OpenGraphCache.where(url: @ogsite_url).count).to eq(1) end it 'creates no cache entry for unsupported pages' do Workers::GatherOpenGraphData.new.perform(@status_message.id, @no_open_graph_url) - OpenGraphCache.find_by_url(@no_open_graph_url).should be_nil + expect(OpenGraphCache.find_by_url(@no_open_graph_url)).to be_nil end it 'gracefully handles a deleted post' do diff --git a/spec/workers/http_multi_spec.rb b/spec/workers/http_multi_spec.rb index b78088e8f..05e70d2f2 100644 --- a/spec/workers/http_multi_spec.rb +++ b/spec/workers/http_multi_spec.rb @@ -16,11 +16,11 @@ describe Workers::HttpMulti do @post_xml = Base64.encode64 "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAH" @hydra = Typhoeus::Hydra.new - Typhoeus::Hydra.stub(:new).and_return(@hydra) + allow(Typhoeus::Hydra).to receive(:new).and_return(@hydra) @salmon = Salmon::EncryptedSlap.create_by_user_and_activity bob, Base64.decode64(@post_xml) - Salmon::EncryptedSlap.stub(:create_by_user_and_activity).and_return @salmon + allow(Salmon::EncryptedSlap).to receive(:create_by_user_and_activity).and_return @salmon @body = "encrypted things" - @salmon.stub(:xml_for).and_return @body + allow(@salmon).to receive(:xml_for).and_return @body @response = Typhoeus::Response.new( code: 200, @@ -57,8 +57,8 @@ describe Workers::HttpMulti do Typhoeus.stub(person.receive_url).and_return @response end - @hydra.should_receive(:queue).twice - @hydra.should_receive(:run).once + expect(@hydra).to receive(:queue).twice + expect(@hydra).to receive(:run).once Workers::HttpMulti.new.perform bob.id, @post_xml, @people.map(&:id), "Postzord::Dispatcher::Private" end @@ -68,7 +68,7 @@ describe Workers::HttpMulti do Typhoeus.stub(person.receive_url).and_return @failed_response - Workers::HttpMulti.should_receive(:perform_in).with(1.hour, bob.id, @post_xml, [person.id], anything, 1).once + expect(Workers::HttpMulti).to receive(:perform_in).with(1.hour, bob.id, @post_xml, [person.id], anything, 1).once Workers::HttpMulti.new.perform bob.id, @post_xml, [person.id], "Postzord::Dispatcher::Private" end @@ -77,7 +77,7 @@ describe Workers::HttpMulti do Typhoeus.stub(person.receive_url).and_return @unable_to_resolve_response - Workers::HttpMulti.should_receive(:perform_in).with(1.hour, bob.id, @post_xml, [person.id], anything, 1).once + expect(Workers::HttpMulti).to receive(:perform_in).with(1.hour, bob.id, @post_xml, [person.id], anything, 1).once Workers::HttpMulti.new.perform bob.id, @post_xml, [person.id], "Postzord::Dispatcher::Private" end @@ -86,7 +86,7 @@ describe Workers::HttpMulti do Typhoeus.stub(person.receive_url).and_return @ssl_error_response - Workers::HttpMulti.should_not_receive(:perform_in) + expect(Workers::HttpMulti).not_to receive(:perform_in) Workers::HttpMulti.new.perform bob.id, @post_xml, [person.id], "Postzord::Dispatcher::Private" end @@ -95,7 +95,7 @@ describe Workers::HttpMulti do Typhoeus.stub(person.receive_url).and_return @failed_response - Workers::HttpMulti.should_not_receive :perform_in + expect(Workers::HttpMulti).not_to receive :perform_in Workers::HttpMulti.new.perform bob.id, @post_xml, [person.id], "Postzord::Dispatcher::Private", 3 end @@ -103,7 +103,7 @@ describe Workers::HttpMulti do person = @people.first Typhoeus.stub(person.receive_url).and_return @response - @salmon.should_receive(:xml_for).and_return @body + expect(@salmon).to receive(:xml_for).and_return @body Workers::HttpMulti.new.perform bob.id, @post_xml, [person.id], "Postzord::Dispatcher::Private" end @@ -124,7 +124,7 @@ describe Workers::HttpMulti do Workers::HttpMulti.new.perform bob.id, @post_xml, [person.id], "Postzord::Dispatcher::Private" person.reload - person.url.should == "https://remote.net/" + expect(person.url).to eq("https://remote.net/") end it 'only sends to users with valid RSA keys' do @@ -138,7 +138,7 @@ describe Workers::HttpMulti do Typhoeus.stub(person.receive_url).and_return @response Typhoeus.stub(@people[1].receive_url).and_return @response - @hydra.should_receive(:queue).once + expect(@hydra).to receive(:queue).once Workers::HttpMulti.new.perform bob.id, @post_xml, @people.map(&:id), "Postzord::Dispatcher::Private" end end diff --git a/spec/workers/mail/invite_email_spec.rb b/spec/workers/mail/invite_email_spec.rb index ca0a2d6e2..6c94460e9 100644 --- a/spec/workers/mail/invite_email_spec.rb +++ b/spec/workers/mail/invite_email_spec.rb @@ -6,9 +6,9 @@ describe Workers::Mail::InviteEmail do let(:email_inviter) { double('EmailInviter') } it 'creates a new email inviter' do - EmailInviter.should_receive(:new).with(emails, alice, message: message) + expect(EmailInviter).to receive(:new).with(emails, alice, message: message) .and_return(email_inviter) - email_inviter.should_receive(:send!) + expect(email_inviter).to receive(:send!) Workers::Mail::InviteEmail.new.perform(emails, alice, message: message) end end diff --git a/spec/workers/mail/mentioned_spec.rb b/spec/workers/mail/mentioned_spec.rb index 332f8cdda..ac7e787b2 100644 --- a/spec/workers/mail/mentioned_spec.rb +++ b/spec/workers/mail/mentioned_spec.rb @@ -12,8 +12,8 @@ describe Workers::Mail::Mentioned do m = Mention.new(:person => user.person, :post=> sm) mail_double = double() - mail_double.should_receive(:deliver) - Notifier.should_receive(:mentioned).with(user.id, sm.author.id, m.id).and_return(mail_double) + expect(mail_double).to receive(:deliver) + expect(Notifier).to receive(:mentioned).with(user.id, sm.author.id, m.id).and_return(mail_double) Workers::Mail::Mentioned.new.perform(user.id, sm.author.id, m.id) end diff --git a/spec/workers/mail/private_message_spec.rb b/spec/workers/mail/private_message_spec.rb index 3fa271342..9ee1c0fbf 100644 --- a/spec/workers/mail/private_message_spec.rb +++ b/spec/workers/mail/private_message_spec.rb @@ -18,8 +18,8 @@ describe Workers::Mail::PrivateMessage do message = cnv.messages.first mail_double = double() - mail_double.should_receive(:deliver) - Notifier.should_receive(:mentioned).with(user2.id, user1.person.id, message.id).and_return(mail_double) + expect(mail_double).to receive(:deliver) + expect(Notifier).to receive(:mentioned).with(user2.id, user1.person.id, message.id).and_return(mail_double) Workers::Mail::Mentioned.new.perform(user2.id, user1.person.id, message.id) end diff --git a/spec/workers/mail/reshared_spec.rb b/spec/workers/mail/reshared_spec.rb index 478cd5a96..016d75b43 100644 --- a/spec/workers/mail/reshared_spec.rb +++ b/spec/workers/mail/reshared_spec.rb @@ -11,8 +11,8 @@ describe Workers::Mail::Reshared do reshare = FactoryGirl.build(:reshare, :author => alice.person, :root=> sm) mail_double = double() - mail_double.should_receive(:deliver) - Notifier.should_receive(:reshared).with(bob.id, reshare.author.id, reshare.id).and_return(mail_double) + expect(mail_double).to receive(:deliver) + expect(Notifier).to receive(:reshared).with(bob.id, reshare.author.id, reshare.id).and_return(mail_double) Workers::Mail::Reshared.new.perform(bob.id, reshare.author.id, reshare.id) end diff --git a/spec/workers/notify_local_users_spec.rb b/spec/workers/notify_local_users_spec.rb index b058d0f77..6f89e1ed5 100644 --- a/spec/workers/notify_local_users_spec.rb +++ b/spec/workers/notify_local_users_spec.rb @@ -10,9 +10,9 @@ describe Workers::NotifyLocalUsers do person = FactoryGirl.create :person post = FactoryGirl.create :status_message - StatusMessage.should_receive(:find_by_id).with(post.id).and_return(post) + expect(StatusMessage).to receive(:find_by_id).with(post.id).and_return(post) #User.should_receive(:where).and_return([alice, eve]) - Notification.should_receive(:notify).with(instance_of(User), instance_of(StatusMessage), instance_of(Person)).twice + expect(Notification).to receive(:notify).with(instance_of(User), instance_of(StatusMessage), instance_of(Person)).twice Workers::NotifyLocalUsers.new.perform([alice.id, eve.id], post.class.to_s, post.id, person.id) end diff --git a/spec/workers/post_to_service_spec.rb b/spec/workers/post_to_service_spec.rb index 4ba8c4767..e75578079 100644 --- a/spec/workers/post_to_service_spec.rb +++ b/spec/workers/post_to_service_spec.rb @@ -5,11 +5,11 @@ describe Workers::PostToService do user = alice aspect = user.aspects.create(:name => "yeah") post = user.post(:status_message, :text => 'foo', :to => aspect.id) - User.stub(:find_by_id).with(user.id.to_s).and_return(user) + allow(User).to receive(:find_by_id).with(user.id.to_s).and_return(user) m = double() url = "foobar" - m.should_receive(:post).with(anything, url) - Service.stub(:find_by_id).and_return(m) + expect(m).to receive(:post).with(anything, url) + allow(Service).to receive(:find_by_id).and_return(m) Workers::PostToService.new.perform("123", post.id.to_s, url) end end diff --git a/spec/workers/process_photo_spec.rb b/spec/workers/process_photo_spec.rb index 5b07b4316..8294902ca 100644 --- a/spec/workers/process_photo_spec.rb +++ b/spec/workers/process_photo_spec.rb @@ -12,14 +12,14 @@ describe Workers::ProcessPhoto do end it 'saves the processed image' do - @saved_photo.processed_image.path.should be_nil + expect(@saved_photo.processed_image.path).to be_nil result = Workers::ProcessPhoto.new.perform(@saved_photo.id) @saved_photo.reload - @saved_photo.processed_image.path.should_not be_nil - result.should be true + expect(@saved_photo.processed_image.path).not_to be_nil + expect(result).to be true end context 'when trying to process a photo that has already been processed' do @@ -35,8 +35,8 @@ describe Workers::ProcessPhoto do @saved_photo.reload - @saved_photo.processed_image.path.should == processed_image_path - result.should be false + expect(@saved_photo.processed_image.path).to eq(processed_image_path) + expect(result).to be false end end @@ -50,8 +50,8 @@ describe Workers::ProcessPhoto do it 'does not process the gif' do result = Workers::ProcessPhoto.new.perform(@saved_gif.id) - @saved_gif.reload.processed_image.path.should be_nil - result.should be false + expect(@saved_gif.reload.processed_image.path).to be_nil + expect(result).to be false end end diff --git a/spec/workers/publish_to_hub_spec.rb b/spec/workers/publish_to_hub_spec.rb index 47cb4a9a4..d864ae2c9 100644 --- a/spec/workers/publish_to_hub_spec.rb +++ b/spec/workers/publish_to_hub_spec.rb @@ -10,8 +10,8 @@ describe Workers::PublishToHub do url = "http://publiczone.com/" m = double() - m.should_receive(:publish).with(url+'.atom') - Pubsubhubbub.should_receive(:new).with(AppConfig.environment.pubsub_server).and_return(m) + expect(m).to receive(:publish).with(url+'.atom') + expect(Pubsubhubbub).to receive(:new).with(AppConfig.environment.pubsub_server).and_return(m) Workers::PublishToHub.new.perform(url) end end diff --git a/spec/workers/receive_salmon_spec.rb b/spec/workers/receive_salmon_spec.rb index 84e598e33..a57bc6fbc 100644 --- a/spec/workers/receive_salmon_spec.rb +++ b/spec/workers/receive_salmon_spec.rb @@ -4,7 +4,7 @@ describe Workers::ReceiveEncryptedSalmon do before do @user = alice @xml = '' - User.stub(:find){ |id| + allow(User).to receive(:find){ |id| if id == @user.id @user else @@ -15,8 +15,8 @@ describe Workers::ReceiveEncryptedSalmon do it 'calls receive_salmon' do zord = double - zord.should_receive(:perform!) - Postzord::Receiver::Private.should_receive(:new).with(@user, hash_including(:salmon_xml => @xml)).and_return(zord) + expect(zord).to receive(:perform!) + expect(Postzord::Receiver::Private).to receive(:new).with(@user, hash_including(:salmon_xml => @xml)).and_return(zord) Workers::ReceiveEncryptedSalmon.new.perform(@user.id, @xml) end diff --git a/spec/workers/receive_spec.rb b/spec/workers/receive_spec.rb index dda95c890..0ee0b0a53 100644 --- a/spec/workers/receive_spec.rb +++ b/spec/workers/receive_spec.rb @@ -5,7 +5,7 @@ describe Workers::Receive do @user = alice @person = FactoryGirl.create(:person) @xml = '' - User.stub(:find){ |id| + allow(User).to receive(:find){ |id| if id == @user.id @user else @@ -16,8 +16,8 @@ describe Workers::Receive do it 'calls receive' do zord_double = double() - zord_double.should_receive(:parse_and_receive).with(@xml) - Postzord::Receiver::Private.should_receive(:new).with(@user, anything).and_return(zord_double) + expect(zord_double).to receive(:parse_and_receive).with(@xml) + expect(Postzord::Receiver::Private).to receive(:new).with(@user, anything).and_return(zord_double) Workers::Receive.new.perform(@user.id, @xml, @person.id) end end diff --git a/spec/workers/resend_invitation_spec.rb b/spec/workers/resend_invitation_spec.rb index a0e0afd33..002cf78a5 100644 --- a/spec/workers/resend_invitation_spec.rb +++ b/spec/workers/resend_invitation_spec.rb @@ -9,8 +9,8 @@ describe Workers::ResendInvitation do it 'should call .resend on the object' do invite = FactoryGirl.build(:invitation, :service => 'email', :identifier => 'foo@bar.com') - Invitation.stub(:find).and_return(invite) - invite.should_receive(:resend) + allow(Invitation).to receive(:find).and_return(invite) + expect(invite).to receive(:resend) Workers::ResendInvitation.new.perform(invite.id) end end diff --git a/spec/workers/reset_password_spec.rb b/spec/workers/reset_password_spec.rb index eed8697d7..f0f393f75 100644 --- a/spec/workers/reset_password_spec.rb +++ b/spec/workers/reset_password_spec.rb @@ -11,8 +11,8 @@ describe Workers::ResetPassword do it "correctly sets the message parameters" do Workers::ResetPassword.new.perform(alice.id) mail = Devise.mailer.deliveries.last - mail.to.should == [alice.email] - mail.body.should include("change your password") + expect(mail.to).to eq([alice.email]) + expect(mail.body).to include("change your password") end end end From 4edd824d3c896f5bb8dffac30729de3627202956 Mon Sep 17 00:00:00 2001 From: khall Date: Mon, 25 Aug 2014 13:34:27 -0700 Subject: [PATCH 114/785] No deprecation warnings, but one spec still fails (but only when I run all the specs, not when I run just the one spec) --- spec/controllers/registrations_controller_spec.rb | 2 +- spec/controllers/services_controller_spec.rb | 2 +- spec/integration/tag_people_spec.rb | 4 ++-- spec/models/post_spec.rb | 2 +- spec/models/user/connecting_spec.rb | 2 +- spec/workers/http_multi_spec.rb | 3 +-- 6 files changed, 7 insertions(+), 8 deletions(-) diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index 2bc0ac92e..f70fad126 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -16,7 +16,7 @@ describe RegistrationsController, :type => :controller do :password_confirmation => "password" } } - Webfinger.stub_chain(:new, :fetch).and_return(FactoryGirl.create(:person)) + allow(Webfinger).to receive_message_chain(:new, :fetch).and_return(FactoryGirl.create(:person)) end describe '#check_registrations_open!' do diff --git a/spec/controllers/services_controller_spec.rb b/spec/controllers/services_controller_spec.rb index 89cbf8448..1dd5396c6 100644 --- a/spec/controllers/services_controller_spec.rb +++ b/spec/controllers/services_controller_spec.rb @@ -71,7 +71,7 @@ describe ServicesController, :type => :controller do let(:provider) { {'provider' => 'twitter'} } before do - access_token.stub_chain(:response, :header).and_return header + allow(access_token).to receive_message_chain(:response, :header).and_return header request.env['omniauth.auth'] = omniauth_auth.merge!( provider).merge!( extra ) end diff --git a/spec/integration/tag_people_spec.rb b/spec/integration/tag_people_spec.rb index cf4e2e186..86c86eb56 100644 --- a/spec/integration/tag_people_spec.rb +++ b/spec/integration/tag_people_spec.rb @@ -1,12 +1,12 @@ require 'spec_helper' -describe TagsController do +describe TagsController, :type => :request do describe 'will_paginate people on the tag page' do let(:people) { (1..2).map { FactoryGirl.create(:person) } } let(:tag) { "diaspora" } before do - Stream::Tag.any_instance.stub(people_per_page: 1) + allow_any_instance_of(Stream::Tag).to receive_messages(people_per_page: 1) expect(Person).to receive(:profile_tagged_with).with(/#{tag}/).twice.and_return(people) end diff --git a/spec/models/post_spec.rb b/spec/models/post_spec.rb index 14137d2a3..da641ff26 100644 --- a/spec/models/post_spec.rb +++ b/spec/models/post_spec.rb @@ -396,7 +396,7 @@ describe Post, :type => :model do end it "raises Diaspora::NonPublic for a non-existing id without a user" do - Post.stub where: double(includes: double(first: nil)) + allow(Post).to receive_messages where: double(includes: double(first: nil)) expect { Post.find_by_guid_or_id_with_user 123 }.to raise_error Diaspora::NonPublic diff --git a/spec/models/user/connecting_spec.rb b/spec/models/user/connecting_spec.rb index 1cfad5c14..155dff64b 100644 --- a/spec/models/user/connecting_spec.rb +++ b/spec/models/user/connecting_spec.rb @@ -84,7 +84,7 @@ describe User::Connecting, :type => :model do describe '#register_share_visibilities' do it 'creates post visibilites for up to 100 posts' do - Post.stub_chain(:where, :limit).and_return([FactoryGirl.create(:status_message)]) + allow(Post).to receive_message_chain(:where, :limit).and_return([FactoryGirl.create(:status_message)]) c = Contact.create!(:user_id => alice.id, :person_id => eve.person.id) expect{ alice.register_share_visibilities(c) diff --git a/spec/workers/http_multi_spec.rb b/spec/workers/http_multi_spec.rb index 05e70d2f2..594f107eb 100644 --- a/spec/workers/http_multi_spec.rb +++ b/spec/workers/http_multi_spec.rb @@ -132,8 +132,7 @@ describe Workers::HttpMulti do person.serialized_public_key = "-----BEGIN RSA PUBLIC KEY-----\nPsych!\n-----END RSA PUBLIC KEY-----" person.save - # Should be possible to drop when converting should_receive to expect(...).to - RSpec::Mocks.proxy_for(Salmon::EncryptedSlap).reset + allow(@salmon).to receive(:xml_for).and_call_original Typhoeus.stub(person.receive_url).and_return @response Typhoeus.stub(@people[1].receive_url).and_return @response From c27b38d69af21d5618f476707e2197d50e6570f1 Mon Sep 17 00:00:00 2001 From: khall Date: Mon, 25 Aug 2014 13:58:39 -0700 Subject: [PATCH 115/785] Merge branch 'develop' into issue_5149 Conflicts: spec/controllers/aspects_controller_spec.rb spec/controllers/conversations_controller_spec.rb spec/controllers/people_controller_spec.rb spec/controllers/photos_controller_spec.rb spec/integration/receiving_spec.rb spec/lib/postzord/receiver/public_spec.rb spec/models/post_spec.rb spec/models/user/querying_spec.rb --- spec/lib/postzord/receiver/public_spec.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/spec/lib/postzord/receiver/public_spec.rb b/spec/lib/postzord/receiver/public_spec.rb index 4507af473..a1eaab462 100644 --- a/spec/lib/postzord/receiver/public_spec.rb +++ b/spec/lib/postzord/receiver/public_spec.rb @@ -61,7 +61,7 @@ describe Postzord::Receiver::Public do @receiver.perform! end - it 'enqueues a Workers::ReceiveLocalBatch' do + it 'enqueues a Workers::ReceiveLocalBatch' do expect(Workers::ReceiveLocalBatch).to receive(:perform_async).with(anything, anything, anything) @receiver.perform! end From de3e0bd91ad8c7208ae9cbf1493db0fec58b7236 Mon Sep 17 00:00:00 2001 From: khall Date: Mon, 25 Aug 2014 15:26:03 -0700 Subject: [PATCH 116/785] Updating cucumber features --- features/step_definitions/custom_web_steps.rb | 12 ++++++------ features/step_definitions/posts_steps.rb | 2 +- features/step_definitions/web_steps.rb | 4 ++-- features/support/application_cuke_helpers.rb | 2 +- features/support/publishing_cuke_helpers.rb | 2 +- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index ac06e50cb..0660b918e 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -150,12 +150,12 @@ end Then /^(?:|I )should not see a "([^\"]*)"(?: within "([^\"]*)")?$/ do |selector, scope_selector| with_scope(scope_selector) do - current_scope.has_css?(selector, :visible => true).should be_false + current_scope.has_css?(selector, :visible => true).should be false end end Then /^page should (not )?have "([^\"]*)"$/ do |negate, selector| - page.has_css?(selector).should ( negate ? be_false : be_true ) + page.has_css?(selector).should ( negate ? (be false) : (be true) ) end When /^I have turned off jQuery effects$/ do @@ -178,7 +178,7 @@ Then /^the "([^"]*)" field(?: within "([^"]*)")? should be filled with "([^"]*)" end Then /^I should see (\d+) contacts$/ do |n_posts| - has_css?("#people_stream .stream_element", :count => n_posts.to_i).should be_true + has_css?("#people_stream .stream_element", :count => n_posts.to_i).should be true end And /^I scroll down$/ do @@ -217,15 +217,15 @@ And /^I click close on all the popovers$/ do end Then /^I should see a flash message indicating success$/ do - flash_message_success?.should be_true + flash_message_success?.should be true end Then /^I should see a flash message indicating failure$/ do - flash_message_failure?.should be_true + flash_message_failure?.should be true end Then /^I should see a flash message with a warning$/ do - flash_message_alert?.should be_true + flash_message_alert?.should be true end Then /^I should see a flash message containing "(.+)"$/ do |text| diff --git a/features/step_definitions/posts_steps.rb b/features/step_definitions/posts_steps.rb index 5388619cc..5537c4b92 100644 --- a/features/step_definitions/posts_steps.rb +++ b/features/step_definitions/posts_steps.rb @@ -19,7 +19,7 @@ Then /^I should not see any posts in my stream$/ do end Then /^I should not be able to submit the publisher$/ do - expect(publisher_submittable?).to be_false + expect(publisher_submittable?).to be false end Given /^"([^"]*)" has a public post with text "([^"]*)"$/ do |email, text| diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 49f20ddc2..4f414a41c 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -157,14 +157,14 @@ end Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should be checked$/ do |label, selector| with_scope(selector) do field_checked = find_field(label)['checked'] - field_checked.should be_true + field_checked.should eq('true') end end Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector| with_scope(selector) do field_checked = find_field(label)['checked'] - field_checked.should be_false + field_checked.should be false end end diff --git a/features/support/application_cuke_helpers.rb b/features/support/application_cuke_helpers.rb index 9cc3736d6..c99ee66bc 100644 --- a/features/support/application_cuke_helpers.rb +++ b/features/support/application_cuke_helpers.rb @@ -23,7 +23,7 @@ module ApplicationCukeHelpers def confirm_form_validation_error(element) is_invalid = page.evaluate_script("$('#{element}').is(':invalid')") - is_invalid.should be_true + is_invalid.should be true end def check_fields_validation_error(field_list) diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb index 4765603a6..316941f14 100644 --- a/features/support/publishing_cuke_helpers.rb +++ b/features/support/publishing_cuke_helpers.rb @@ -42,7 +42,7 @@ module PublishingCukeHelpers def expand_first_post within(".stream_element", match: :first) do find(".expander").click - has_css?(".expander").should be_false + has_css?(".expander").should be false end end From 875895f2d0c2ff06b4e6d8309fb90327d920575a Mon Sep 17 00:00:00 2001 From: khall Date: Mon, 25 Aug 2014 15:27:48 -0700 Subject: [PATCH 117/785] Convert specs to RSpec 3.0.4 syntax with Transpec This conversion is done by Transpec 2.3.6 with the following command: transpec features * 19 conversions from: obj.should to: expect(obj).to * 1 conversion from: == expected to: eq(expected) For more details: https://github.com/yujinakayama/transpec#supported-conversions --- features/step_definitions/aspects_steps.rb | 4 ++-- features/support/application_cuke_helpers.rb | 4 ++-- features/support/paths.rb | 2 +- features/support/publishing_cuke_helpers.rb | 20 ++++++++++---------- features/support/user_cuke_helpers.rb | 8 ++++---- 5 files changed, 19 insertions(+), 19 deletions(-) diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb index 83539e80f..dc19ae17f 100644 --- a/features/step_definitions/aspects_steps.rb +++ b/features/step_definitions/aspects_steps.rb @@ -6,12 +6,12 @@ module AspectCukeHelpers def toggle_aspect(a_name) a_id = @me.aspects.where(name: a_name).pluck(:id).first aspect_css = ".dropdown li[data-aspect_id='#{a_id}']" - page.should have_selector(aspect_css) + expect(page).to have_selector(aspect_css) find(aspect_css).click end def aspect_dropdown_visible? - find('.aspect_membership.dropdown.active').should be_visible + expect(find('.aspect_membership.dropdown.active')).to be_visible end end World(AspectCukeHelpers) diff --git a/features/support/application_cuke_helpers.rb b/features/support/application_cuke_helpers.rb index c99ee66bc..f45054494 100644 --- a/features/support/application_cuke_helpers.rb +++ b/features/support/application_cuke_helpers.rb @@ -12,7 +12,7 @@ module ApplicationCukeHelpers end def flash_message_containing?(text) - flash_message(text: text).should be_visible + expect(flash_message(text: text)).to be_visible end def flash_message(opts={}) @@ -23,7 +23,7 @@ module ApplicationCukeHelpers def confirm_form_validation_error(element) is_invalid = page.evaluate_script("$('#{element}').is(':invalid')") - is_invalid.should be true + expect(is_invalid).to be true end def check_fields_validation_error(field_list) diff --git a/features/support/paths.rb b/features/support/paths.rb index df6774164..adc69649e 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -71,7 +71,7 @@ module NavigationHelpers def confirm_on_page(page_name) current_path = URI.parse(current_url).path - current_path.should == path_to(page_name) + expect(current_path).to eq(path_to(page_name)) end end diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb index 316941f14..5e7e14e3e 100644 --- a/features/support/publishing_cuke_helpers.rb +++ b/features/support/publishing_cuke_helpers.rb @@ -8,7 +8,7 @@ module PublishingCukeHelpers elem.native.send_keys(' ' + txt) # make sure the other text field got the new contents - find('#status_message_text', visible: false).value.should include(txt) + expect(find('#status_message_text', visible: false).value).to include(txt) end def make_post(text) @@ -19,7 +19,7 @@ module PublishingCukeHelpers def submit_publisher txt = find('#publisher #status_message_fake_text').value find('#publisher .creation').click - page.should have_content(txt) unless page.has_css?('.nsfw-shield') + expect(page).to have_content(txt) unless page.has_css?('.nsfw-shield') end def click_and_post(text) @@ -42,19 +42,19 @@ module PublishingCukeHelpers def expand_first_post within(".stream_element", match: :first) do find(".expander").click - has_css?(".expander").should be false + expect(has_css?(".expander")).to be false end end def first_post_collapsed? - find(".stream_element .collapsible", match: :first).should have_css(".expander") - page.should have_css(".stream_element .collapsible.collapsed", match: :first) + expect(find(".stream_element .collapsible", match: :first)).to have_css(".expander") + expect(page).to have_css(".stream_element .collapsible.collapsed", match: :first) end def first_post_expanded? - page.should have_no_css(".stream_element .expander", match: :first) - page.should have_no_css(".stream_element .collapsible.collapsed", match: :first) - page.should have_css(".stream_element .collapsible.opened", match: :first) + expect(page).to have_no_css(".stream_element .expander", match: :first) + expect(page).to have_no_css(".stream_element .collapsible.collapsed", match: :first) + expect(page).to have_css(".stream_element .collapsible.opened", match: :first) end def first_post_text @@ -74,7 +74,7 @@ module PublishingCukeHelpers end def find_post_by_text(text) - page.should have_text(text) + expect(page).to have_text(text) find(".stream_element", text: text) end @@ -119,7 +119,7 @@ module PublishingCukeHelpers def assert_nsfw(text) post = find_post_by_text(text) - post.find(".nsfw-shield").should be_present + expect(post.find(".nsfw-shield")).to be_present end end diff --git a/features/support/user_cuke_helpers.rb b/features/support/user_cuke_helpers.rb index 0113dd076..056b12db9 100644 --- a/features/support/user_cuke_helpers.rb +++ b/features/support/user_cuke_helpers.rb @@ -105,12 +105,12 @@ module UserCukeHelpers end def confirm_getting_started_contents - page.should have_content("Well, hello there!") - page.should have_content("Who are you?") - page.should have_content("What are you into?") + expect(page).to have_content("Well, hello there!") + expect(page).to have_content("Who are you?") + expect(page).to have_content("What are you into?") # the username that was just entered for registration - page.should have_field("profile_first_name", with: @username) + expect(page).to have_field("profile_first_name", with: @username) end end From 087dbd4acf41606aef36c051d192b4474691ef36 Mon Sep 17 00:00:00 2001 From: khall Date: Mon, 25 Aug 2014 17:02:37 -0700 Subject: [PATCH 118/785] Bumping rspec to 3.0.2 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 2413d544a..dce6d8e54 100644 --- a/Gemfile +++ b/Gemfile @@ -212,7 +212,7 @@ end group :development, :test do # RSpec (unit tests, some integration tests) - gem 'rspec-rails', '3.0.0' + gem 'rspec-rails', '3.0.2' # Cucumber (integration tests) gem 'cucumber-rails', '1.4.1', :require => false diff --git a/Gemfile.lock b/Gemfile.lock index 9b55ad466..55775a5a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -405,7 +405,7 @@ GEM rspec rspec-mocks (3.0.4) rspec-support (~> 3.0.0) - rspec-rails (3.0.0) + rspec-rails (3.0.2) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) @@ -572,7 +572,7 @@ DEPENDENCIES remotipart (= 1.2.1) roxml (= 3.1.6) rspec-instafail (= 0.2.5) - rspec-rails (= 3.0.0) + rspec-rails (= 3.0.2) ruby-oembed (= 0.8.10) sass-rails (= 4.0.3) selenium-webdriver (= 2.42.0) From b7c68031facd6eb4d2d8e5c924362b4f9769046a Mon Sep 17 00:00:00 2001 From: khall Date: Mon, 25 Aug 2014 18:38:19 -0700 Subject: [PATCH 119/785] Last rspec fix brought to you by jhass --- features/step_definitions/web_steps.rb | 2 +- spec/models/status_message_spec.rb | 5 +++-- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/features/step_definitions/web_steps.rb b/features/step_definitions/web_steps.rb index 4f414a41c..a9ed77abf 100644 --- a/features/step_definitions/web_steps.rb +++ b/features/step_definitions/web_steps.rb @@ -164,7 +164,7 @@ end Then /^the "([^"]*)" checkbox(?: within "([^"]*)")? should not be checked$/ do |label, selector| with_scope(selector) do field_checked = find_field(label)['checked'] - field_checked.should be false + field_checked.should be_falsey end end diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index 28c0411be..fc0ac505b 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -52,8 +52,9 @@ describe StatusMessage, :type => :model do describe '.user_tag_stream' do it 'returns tag stream thats owned or visible by' do - expect(StatusMessage).to receive(:owned_or_visible_by_user).with(bob).and_return(StatusMessage) - expect(StatusMessage).to receive(:tag_stream).with([@tag_id]) + relation = double + expect(StatusMessage).to receive(:owned_or_visible_by_user).with(bob).and_return(relation) + expect(relation).to receive(:tag_stream).with([@tag_id]) StatusMessage.user_tag_stream(bob, [@tag_id]) end From fe492c6fb821a94ee06044de5f6c181c81480a31 Mon Sep 17 00:00:00 2001 From: khall Date: Tue, 26 Aug 2014 17:39:13 -0700 Subject: [PATCH 120/785] Fixing a .should test to expect(), adding suggested line to spec_helper to prevent the use of .should in the future --- db/schema.rb | 132 +++++++++++++-------------- spec/models/account_deletion_spec.rb | 2 +- spec/spec_helper.rb | 4 +- 3 files changed, 70 insertions(+), 68 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index f8f12929b..a74fa2724 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -22,8 +22,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "aspect_memberships", force: true do |t| t.integer "aspect_id", null: false t.integer "contact_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "aspect_memberships", ["aspect_id", "contact_id"], name: "index_aspect_memberships_on_aspect_id_and_contact_id", unique: true, using: :btree @@ -33,8 +33,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "aspect_visibilities", force: true do |t| t.integer "shareable_id", null: false t.integer "aspect_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "shareable_type", default: "Post", null: false end @@ -45,8 +45,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "aspects", force: true do |t| t.string "name", null: false t.integer "user_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "contacts_visible", default: true, null: false t.integer "order_id" end @@ -66,21 +66,21 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "guid", null: false t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "likes_count", default: 0, null: false t.string "commentable_type", limit: 60, default: "Post", null: false end - add_index "comments", ["author_id"], name: "index_comments_on_author_id", using: :btree + add_index "comments", ["author_id"], name: "index_comments_on_person_id", using: :btree add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree add_index "comments", ["guid"], name: "index_comments_on_guid", unique: true, using: :btree create_table "contacts", force: true do |t| t.integer "user_id", null: false t.integer "person_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "sharing", default: false, null: false t.boolean "receiving", default: false, null: false end @@ -92,8 +92,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "conversation_id", null: false t.integer "person_id", null: false t.integer "unread", default: 0, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "conversation_visibilities", ["conversation_id", "person_id"], name: "index_conversation_visibilities_usefully", unique: true, using: :btree @@ -104,8 +104,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "subject" t.string "guid", null: false t.integer "author_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "conversations", ["author_id"], name: "conversations_author_id_fk", using: :btree @@ -114,8 +114,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "token" t.integer "user_id" t.integer "count" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "invitations", force: true do |t| @@ -123,8 +123,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "sender_id" t.integer "recipient_id" t.integer "aspect_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "service" t.string "identifier" t.boolean "admin", default: false @@ -142,23 +142,23 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "guid" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "target_type", limit: 60, null: false end add_index "likes", ["author_id"], name: "likes_author_id_fk", using: :btree add_index "likes", ["guid"], name: "index_likes_on_guid", unique: true, using: :btree add_index "likes", ["target_id", "author_id", "target_type"], name: "index_likes_on_target_id_and_author_id_and_target_type", unique: true, using: :btree - add_index "likes", ["target_id"], name: "index_likes_on_target_id", using: :btree + add_index "likes", ["target_id"], name: "index_likes_on_post_id", using: :btree create_table "locations", force: true do |t| t.string "address" t.string "lat" t.string "lng" t.integer "status_message_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "mentions", force: true do |t| @@ -175,8 +175,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "author_id", null: false t.string "guid", null: false t.text "text", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "author_signature" t.text "parent_author_signature" end @@ -187,8 +187,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "notification_actors", force: true do |t| t.integer "notification_id" t.integer "person_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "notification_actors", ["notification_id", "person_id"], name: "index_notification_actors_on_notification_id_and_person_id", unique: true, using: :btree @@ -200,8 +200,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "target_id" t.integer "recipient_id", null: false t.boolean "unread", default: true, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "type" end @@ -231,8 +231,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "author_id" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "participations", ["guid"], name: "index_participations_on_guid", using: :btree @@ -244,8 +244,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "diaspora_handle", null: false t.text "serialized_public_key", null: false t.integer "owner_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "closed_account", default: false t.integer "fetch_status", default: 0 end @@ -280,8 +280,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "pods", force: true do |t| t.string "host" t.boolean "ssl" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "poll_answers", force: true do |t| @@ -300,8 +300,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "guid" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "poll_participations", ["poll_id"], name: "index_poll_participations_on_poll_id", using: :btree @@ -311,8 +311,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "status_message_id", null: false t.boolean "status" t.string "guid" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "polls", ["status_message_id"], name: "index_polls_on_status_message_id", using: :btree @@ -329,8 +329,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "remote_photo_name" t.string "random_string" t.string "processed_image" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "unprocessed_image" t.string "object_url" t.string "image_url" @@ -355,7 +355,7 @@ ActiveRecord::Schema.define(version: 20140826165533) do end add_index "posts", ["author_id", "root_guid"], name: "index_posts_on_author_id_and_root_guid", unique: true, using: :btree - add_index "posts", ["author_id"], name: "index_posts_on_author_id", using: :btree + add_index "posts", ["author_id"], name: "index_posts_on_person_id", using: :btree add_index "posts", ["guid"], name: "index_posts_on_guid", unique: true, using: :btree add_index "posts", ["id", "type", "created_at"], name: "index_posts_on_id_and_type_and_created_at", using: :btree add_index "posts", ["root_guid"], name: "index_posts_on_root_guid", using: :btree @@ -376,8 +376,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.text "bio" t.boolean "searchable", default: true, null: false t.integer "person_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "location" t.string "full_name", limit: 70 t.boolean "nsfw", default: false @@ -394,8 +394,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "table" t.integer "month", limit: 2 t.integer "year", limit: 8 - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "rails_admin_histories", ["item", "table", "month", "year"], name: "index_rails_admin_histories", using: :btree @@ -405,18 +405,18 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "item_type", null: false t.boolean "reviewed", default: false t.text "text" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "user_id", null: false end - add_index "reports", ["item_id"], name: "index_reports_on_item_id", using: :btree + add_index "reports", ["item_id"], name: "index_post_reports_on_post_id", using: :btree create_table "roles", force: true do |t| t.integer "person_id" t.string "name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "services", force: true do |t| @@ -426,8 +426,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "access_token" t.string "access_secret" t.string "nickname" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "services", ["type", "uid"], name: "index_services_on_type_and_uid", using: :btree @@ -435,23 +435,23 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "share_visibilities", force: true do |t| t.integer "shareable_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "hidden", default: false, null: false t.integer "contact_id", null: false t.string "shareable_type", limit: 60, default: "Post", null: false end - add_index "share_visibilities", ["contact_id"], name: "index_share_visibilities_on_contact_id", using: :btree + add_index "share_visibilities", ["contact_id"], name: "index_post_visibilities_on_contact_id", using: :btree add_index "share_visibilities", ["shareable_id", "shareable_type", "contact_id"], name: "shareable_and_contact_id", using: :btree add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "contact_id"], name: "shareable_and_hidden_and_contact_id", using: :btree - add_index "share_visibilities", ["shareable_id"], name: "index_share_visibilities_on_post_id", using: :btree + add_index "share_visibilities", ["shareable_id"], name: "index_post_visibilities_on_post_id", using: :btree create_table "simple_captcha_data", force: true do |t| t.string "key", limit: 40 t.string "value", limit: 12 - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "simple_captcha_data", ["key"], name: "idx_key", using: :btree @@ -459,8 +459,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "tag_followings", force: true do |t| t.integer "tag_id", null: false t.integer "user_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "tag_followings", ["tag_id", "user_id"], name: "index_tag_followings_on_tag_id_and_user_id", unique: true, using: :btree @@ -492,8 +492,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "user_preferences", force: true do |t| t.string "email_type" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "users", force: true do |t| @@ -513,8 +513,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "invitation_service", limit: 127 t.string "invitation_identifier", limit: 127 t.integer "invitation_limit" diff --git a/spec/models/account_deletion_spec.rb b/spec/models/account_deletion_spec.rb index 00a165185..576d58c57 100644 --- a/spec/models/account_deletion_spec.rb +++ b/spec/models/account_deletion_spec.rb @@ -40,7 +40,7 @@ describe AccountDeletion, :type => :model do it 'marks an AccountDeletion as completed when successful' do ad = AccountDeletion.create(:person => alice.person) ad.perform! - ad.reload.completed_at.should_not be_nil + expect(ad.reload.completed_at).not_to be_nil end end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 63c056554..e4c762b41 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -87,7 +87,9 @@ prefork = proc do allow_any_instance_of(Postzord::Dispatcher::Private).to receive(:deliver_to_remote) end - + config.expect_with :rspec do |expect_config| + expect_config.syntax = :expect + end config.after(:all) do `rm -rf #{Rails.root}/tmp/uploads/*` From 1dbce6d84d5f04a426c06309b753d86e4a769557 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Mon, 21 Jul 2014 21:31:29 +0200 Subject: [PATCH 121/785] Improve profile page design on mobile --- Changelog.md | 1 + app/assets/stylesheets/mobile/mobile.css.scss | 49 +++++++++++++------ app/views/people/_sub_header.html.haml | 2 +- app/views/people/show.mobile.haml | 4 ++ 4 files changed, 39 insertions(+), 17 deletions(-) diff --git a/Changelog.md b/Changelog.md index d7ddd7e64..10419cbd0 100644 --- a/Changelog.md +++ b/Changelog.md @@ -17,6 +17,7 @@ The default for including jQuery from a CDN has changed. If you want to continue ## Refactor * Redesign contacts page [#5153](https://github.com/diaspora/diaspora/pull/5153) +* Improve profile page design on mobile ## Bug fixes * orca cannot see 'Add Contact' button [#5158](https://github.com/diaspora/diaspora/pull/5158) diff --git a/app/assets/stylesheets/mobile/mobile.css.scss b/app/assets/stylesheets/mobile/mobile.css.scss index c536cd28e..29a5b9a71 100644 --- a/app/assets/stylesheets/mobile/mobile.css.scss +++ b/app/assets/stylesheets/mobile/mobile.css.scss @@ -48,9 +48,10 @@ h3 { position: relative; text-align: left; padding: 10px 0; - * { - max-width: 100%; } min-height: 34px; + + * { max-width: 100%; } + .avatar { @include border-radius(4px); @@ -151,7 +152,8 @@ h3 { } } -.stream_element, #login_form { +.stream_element, +#login_form { @include border-radius(5px); @include box-shadow(0, 1px, 2px, rgba(0, 0, 0, 0.2)); @@ -297,27 +299,42 @@ h3 { } #author_info { - height: 100%; - position: relative; + margin: -10px; + margin-bottom: 10px; + padding-top: 5px; + background-color: #fff; + border-bottom: 1px solid #aaa; word-wrap: break-word; img { - height: 90px; - width: 90px; - margin-right: 10px; + @include border-radius(4px); + + height: 70px; + width: 70px; + margin: 10px; float: left; } .content { - padding-left: 100px; - } + padding-left: 90px; + + h2 { + font-size: 20px; + line-height: 20px; + margin-bottom: 0px; + } - .description { - font: { - weight: normal; - size: small; - }; - color: $text-grey; + .description { + font: { + weight: normal; + size: small; + }; + color: $text-grey; + } + } + + .bottom_bar { + position: static; } } diff --git a/app/views/people/_sub_header.html.haml b/app/views/people/_sub_header.html.haml index 56c9552d9..4aef4bd72 100644 --- a/app/views/people/_sub_header.html.haml +++ b/app/views/people/_sub_header.html.haml @@ -19,7 +19,7 @@ .description - if !person.tag_string.blank? && user_signed_in? = Diaspora::Taggable.format_tags(person.profile.tag_string) - - if user_signed_in? && person == current_user.person + - if person == current_user.person %span.hover_edit = link_to t('.edit'), edit_profile_path - else diff --git a/app/views/people/show.mobile.haml b/app/views/people/show.mobile.haml index f7fdd3233..dfb55e289 100644 --- a/app/views/people/show.mobile.haml +++ b/app/views/people/show.mobile.haml @@ -10,6 +10,10 @@ = @person.name %span.description = @person.diaspora_handle + .clear + .bottom_bar + - if !@person.tag_string.blank? && user_signed_in? + = Diaspora::Taggable.format_tags(@person.profile.tag_string) .span12.profile_stream - if @stream.stream_posts.length > 0 From b83295b4e4484d4811e687f54313d7c6029a6666 Mon Sep 17 00:00:00 2001 From: Flaburgan Date: Fri, 16 May 2014 13:04:32 +0200 Subject: [PATCH 122/785] Polish conversation view --- app/views/conversations/_conversation.haml | 3 ++- app/views/conversations/_show.haml | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/views/conversations/_conversation.haml b/app/views/conversations/_conversation.haml index 97077e322..bcc528ec5 100644 --- a/app/views/conversations/_conversation.haml +++ b/app/views/conversations/_conversation.haml @@ -30,7 +30,8 @@ = authors[conversation.id].name .last_message - if conversation.messages.present? - = '»' + conversation.messages.last.text + '«' + %em + = conversation.messages.last.text - if other_participants.count > 1 .participants - other_participants.drop(1).take(15).each do |participant| diff --git a/app/views/conversations/_show.haml b/app/views/conversations/_show.haml index 4609379fd..bbc699cb9 100644 --- a/app/views/conversations/_show.haml +++ b/app/views/conversations/_show.haml @@ -27,4 +27,4 @@ .bd = form_for [conversation, Message.new] do |message| = message.text_area :text, :class => 'span12', :rows => 5, :tabindex => 1 - = message.submit t('.reply').capitalize, 'data-disable-with' => t('.replying'), :class => 'btn btn-primary creation', :tabindex => 2 + = message.submit t('.reply').capitalize, 'data-disable-with' => t('.replying'), class: 'btn btn-primary pull-right creation', tabindex: 2 From 856386bf389bb0be44d238312878370629baff46 Mon Sep 17 00:00:00 2001 From: khall Date: Wed, 27 Aug 2014 07:27:58 -0700 Subject: [PATCH 123/785] undoing my changes picked up during migration --- db/schema.rb | 132 +++++++++++++++++++++++++-------------------------- 1 file changed, 66 insertions(+), 66 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index a74fa2724..f8f12929b 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -22,8 +22,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "aspect_memberships", force: true do |t| t.integer "aspect_id", null: false t.integer "contact_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "aspect_memberships", ["aspect_id", "contact_id"], name: "index_aspect_memberships_on_aspect_id_and_contact_id", unique: true, using: :btree @@ -33,8 +33,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "aspect_visibilities", force: true do |t| t.integer "shareable_id", null: false t.integer "aspect_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "shareable_type", default: "Post", null: false end @@ -45,8 +45,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "aspects", force: true do |t| t.string "name", null: false t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "contacts_visible", default: true, null: false t.integer "order_id" end @@ -66,21 +66,21 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "guid", null: false t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "likes_count", default: 0, null: false t.string "commentable_type", limit: 60, default: "Post", null: false end - add_index "comments", ["author_id"], name: "index_comments_on_person_id", using: :btree + add_index "comments", ["author_id"], name: "index_comments_on_author_id", using: :btree add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree add_index "comments", ["guid"], name: "index_comments_on_guid", unique: true, using: :btree create_table "contacts", force: true do |t| t.integer "user_id", null: false t.integer "person_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "sharing", default: false, null: false t.boolean "receiving", default: false, null: false end @@ -92,8 +92,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "conversation_id", null: false t.integer "person_id", null: false t.integer "unread", default: 0, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "conversation_visibilities", ["conversation_id", "person_id"], name: "index_conversation_visibilities_usefully", unique: true, using: :btree @@ -104,8 +104,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "subject" t.string "guid", null: false t.integer "author_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "conversations", ["author_id"], name: "conversations_author_id_fk", using: :btree @@ -114,8 +114,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "token" t.integer "user_id" t.integer "count" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "invitations", force: true do |t| @@ -123,8 +123,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "sender_id" t.integer "recipient_id" t.integer "aspect_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "service" t.string "identifier" t.boolean "admin", default: false @@ -142,23 +142,23 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "guid" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "target_type", limit: 60, null: false end add_index "likes", ["author_id"], name: "likes_author_id_fk", using: :btree add_index "likes", ["guid"], name: "index_likes_on_guid", unique: true, using: :btree add_index "likes", ["target_id", "author_id", "target_type"], name: "index_likes_on_target_id_and_author_id_and_target_type", unique: true, using: :btree - add_index "likes", ["target_id"], name: "index_likes_on_post_id", using: :btree + add_index "likes", ["target_id"], name: "index_likes_on_target_id", using: :btree create_table "locations", force: true do |t| t.string "address" t.string "lat" t.string "lng" t.integer "status_message_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "mentions", force: true do |t| @@ -175,8 +175,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "author_id", null: false t.string "guid", null: false t.text "text", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.text "author_signature" t.text "parent_author_signature" end @@ -187,8 +187,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "notification_actors", force: true do |t| t.integer "notification_id" t.integer "person_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "notification_actors", ["notification_id", "person_id"], name: "index_notification_actors_on_notification_id_and_person_id", unique: true, using: :btree @@ -200,8 +200,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "target_id" t.integer "recipient_id", null: false t.boolean "unread", default: true, null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "type" end @@ -231,8 +231,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "author_id" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "participations", ["guid"], name: "index_participations_on_guid", using: :btree @@ -244,8 +244,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "diaspora_handle", null: false t.text "serialized_public_key", null: false t.integer "owner_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "closed_account", default: false t.integer "fetch_status", default: 0 end @@ -280,8 +280,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "pods", force: true do |t| t.string "host" t.boolean "ssl" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "poll_answers", force: true do |t| @@ -300,8 +300,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "guid" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "poll_participations", ["poll_id"], name: "index_poll_participations_on_poll_id", using: :btree @@ -311,8 +311,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.integer "status_message_id", null: false t.boolean "status" t.string "guid" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "polls", ["status_message_id"], name: "index_polls_on_status_message_id", using: :btree @@ -329,8 +329,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "remote_photo_name" t.string "random_string" t.string "processed_image" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "unprocessed_image" t.string "object_url" t.string "image_url" @@ -355,7 +355,7 @@ ActiveRecord::Schema.define(version: 20140826165533) do end add_index "posts", ["author_id", "root_guid"], name: "index_posts_on_author_id_and_root_guid", unique: true, using: :btree - add_index "posts", ["author_id"], name: "index_posts_on_person_id", using: :btree + add_index "posts", ["author_id"], name: "index_posts_on_author_id", using: :btree add_index "posts", ["guid"], name: "index_posts_on_guid", unique: true, using: :btree add_index "posts", ["id", "type", "created_at"], name: "index_posts_on_id_and_type_and_created_at", using: :btree add_index "posts", ["root_guid"], name: "index_posts_on_root_guid", using: :btree @@ -376,8 +376,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.text "bio" t.boolean "searchable", default: true, null: false t.integer "person_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "location" t.string "full_name", limit: 70 t.boolean "nsfw", default: false @@ -394,8 +394,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "table" t.integer "month", limit: 2 t.integer "year", limit: 8 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "rails_admin_histories", ["item", "table", "month", "year"], name: "index_rails_admin_histories", using: :btree @@ -405,18 +405,18 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "item_type", null: false t.boolean "reviewed", default: false t.text "text" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.integer "user_id", null: false end - add_index "reports", ["item_id"], name: "index_post_reports_on_post_id", using: :btree + add_index "reports", ["item_id"], name: "index_reports_on_item_id", using: :btree create_table "roles", force: true do |t| t.integer "person_id" t.string "name" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "services", force: true do |t| @@ -426,8 +426,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.string "access_token" t.string "access_secret" t.string "nickname" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "services", ["type", "uid"], name: "index_services_on_type_and_uid", using: :btree @@ -435,23 +435,23 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "share_visibilities", force: true do |t| t.integer "shareable_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.boolean "hidden", default: false, null: false t.integer "contact_id", null: false t.string "shareable_type", limit: 60, default: "Post", null: false end - add_index "share_visibilities", ["contact_id"], name: "index_post_visibilities_on_contact_id", using: :btree + add_index "share_visibilities", ["contact_id"], name: "index_share_visibilities_on_contact_id", using: :btree add_index "share_visibilities", ["shareable_id", "shareable_type", "contact_id"], name: "shareable_and_contact_id", using: :btree add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "contact_id"], name: "shareable_and_hidden_and_contact_id", using: :btree - add_index "share_visibilities", ["shareable_id"], name: "index_post_visibilities_on_post_id", using: :btree + add_index "share_visibilities", ["shareable_id"], name: "index_share_visibilities_on_post_id", using: :btree create_table "simple_captcha_data", force: true do |t| t.string "key", limit: 40 t.string "value", limit: 12 - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "simple_captcha_data", ["key"], name: "idx_key", using: :btree @@ -459,8 +459,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "tag_followings", force: true do |t| t.integer "tag_id", null: false t.integer "user_id", null: false - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end add_index "tag_followings", ["tag_id", "user_id"], name: "index_tag_followings_on_tag_id_and_user_id", unique: true, using: :btree @@ -492,8 +492,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "user_preferences", force: true do |t| t.string "email_type" t.integer "user_id" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" end create_table "users", force: true do |t| @@ -513,8 +513,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.datetime "created_at" + t.datetime "updated_at" t.string "invitation_service", limit: 127 t.string "invitation_identifier", limit: 127 t.integer "invitation_limit" From 2348fb9d09d187b0479d8d1ad6a5b25c44debe92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 17:00:21 +0200 Subject: [PATCH 124/785] drop firefox addon from travis.yml Travis build environment was updated to FF 31 --- .travis.yml | 3 --- 1 file changed, 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 05eaf0491..5a36ee594 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,9 +18,6 @@ env: bundler_args: "--without development production heroku" script: "./script/ci/build.sh" -addons: - firefox: "31.0" - notifications: irc: channels: From de9acef27f4bf63771800b5718f0c4469c81b987 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 18:25:28 +0200 Subject: [PATCH 125/785] add changelog entry for rspec 3 port --- Changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/Changelog.md b/Changelog.md index a5e6c780e..5c4fc0683 100644 --- a/Changelog.md +++ b/Changelog.md @@ -18,6 +18,7 @@ The default for including jQuery from a CDN has changed. If you want to continue ## Refactor * Redesign contacts page [#5153](https://github.com/diaspora/diaspora/pull/5153) * Improve profile page design on mobile [#5084](https://github.com/diaspora/diaspora/pull/5084) +* Port testsuite to RSpec 3 [#5170](https://github.com/diaspora/diaspora/pull/5170) ## Bug fixes * orca cannot see 'Add Contact' button [#5158](https://github.com/diaspora/diaspora/pull/5158) From 6fef1cf990d8a9eac0b2fb27e589b79a57fef985 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 18:32:50 +0200 Subject: [PATCH 126/785] bump gon --- Gemfile | 2 +- Gemfile.lock | 9 ++------- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index dce6d8e54..c11c70b6a 100644 --- a/Gemfile +++ b/Gemfile @@ -128,7 +128,7 @@ gem 'typhoeus', '0.6.9' # Views -gem 'gon', '5.1.2' +gem 'gon', '5.2.0' gem 'haml', '4.0.5' gem 'mobile-fu', '1.3.1' gem 'will_paginate', '3.0.7' diff --git a/Gemfile.lock b/Gemfile.lock index 55775a5a6..40eb614a6 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -186,16 +186,11 @@ GEM ruby-progressbar (~> 1.4) gherkin (2.12.2) multi_json (~> 1.3) - gon (5.1.2) + gon (5.2.0) actionpack (>= 2.3.0) - formatador (>= 0.2.4) json - listen (~> 2.7) - lumberjack (~> 1.0) multi_json - pry (>= 0.9.12) request_store (>= 1.0.5) - thor (>= 0.18.1) guard (2.6.1) formatador (>= 0.2.4) listen (~> 2.7) @@ -529,7 +524,7 @@ DEPENDENCIES foreigner (= 1.6.1) foreman (= 0.62) fuubar (= 2.0.0) - gon (= 5.1.2) + gon (= 5.2.0) guard-cucumber (= 1.4.1) guard-rspec (= 4.3.1) guard-spork (= 1.5.1) From bb51752d334248e772e861effdc90c1d713d0979 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 18:33:14 +0200 Subject: [PATCH 127/785] bump font-awesome-rails --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 40eb614a6..57f311215 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -173,7 +173,7 @@ GEM fog-softlayer (0.3.15) fog-core fog-json - font-awesome-rails (4.1.0.0) + font-awesome-rails (4.2.0.0) railties (>= 3.2, < 5.0) foreigner (1.6.1) activerecord (>= 3.0.0) From 0675337dab92b5a1fbaceced76bf3f4500ba7dac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 18:34:00 +0200 Subject: [PATCH 128/785] bump fog-core --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 57f311215..4fb830a3e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -161,7 +161,7 @@ GEM fog-core (~> 1.22) fog-json inflecto - fog-core (1.23.0) + fog-core (1.24.0) builder excon (~> 0.38) formatador (~> 0.2) From 3387bbca742dabaafc656030503778b443822809 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 18:37:14 +0200 Subject: [PATCH 129/785] skip assets precompilation for regular run --- lib/tasks/tests.rake | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index faabcfafd..b6e04e4e7 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -1,16 +1,13 @@ namespace :ci do namespace :travis do desc "Run everyhting except cucumber" - task :other => [ :prepare, "tests:generate_fixtures", :spec, "jasmine:ci" ] + task :other => [ :prepare_db, "tests:generate_fixtures", :spec, "jasmine:ci" ] desc "Run cucumber" - task :cucumber => [ :prepare, "rake:cucumber" ] + task :cucumber => [ :prepare_db, "assets:precompile", "rake:cucumber" ] desc "Prepare db" task :prepare_db => [ "db:create", "db:test:load"] - - desc "Prepare" - task :prepare => [:prepare_db, "assets:precompile"] end end From 1b0de7f7cc19c0b5d573a56d4808b7c053532ece Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Wed, 27 Aug 2014 18:38:43 +0200 Subject: [PATCH 130/785] skip assets precompilation for cucumber run --- lib/tasks/tests.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/tasks/tests.rake b/lib/tasks/tests.rake index b6e04e4e7..7750f3b61 100644 --- a/lib/tasks/tests.rake +++ b/lib/tasks/tests.rake @@ -4,7 +4,7 @@ namespace :ci do task :other => [ :prepare_db, "tests:generate_fixtures", :spec, "jasmine:ci" ] desc "Run cucumber" - task :cucumber => [ :prepare_db, "assets:precompile", "rake:cucumber" ] + task :cucumber => [ :prepare_db, "rake:cucumber" ] desc "Prepare db" task :prepare_db => [ "db:create", "db:test:load"] From 28a71a46aaf306809822a5c71eb610216d4e4a31 Mon Sep 17 00:00:00 2001 From: Remco Huijdts Date: Thu, 28 Aug 2014 12:28:06 +0200 Subject: [PATCH 131/785] Consolidate migrations --- db/migrate/0000_create_schema.rb | 650 +++++++++++++----- .../20110105051803_create_import_tables.rb | 199 ------ ...19060243_add_index_to_post_visibilities.rb | 9 - db/migrate/20110119221746_add_indicies.rb | 29 - .../20110120181553_create_statistics.rb | 15 - .../20110120182100_create_data_points.rb | 17 - .../20110123210746_alter_string_columns.rb | 37 - .../20110125190034_unique_index_on_profile.rb | 37 - ...rvice_and_invitation_identifier_to_user.rb | 13 - .../20110126200714_add_contacts_visible.rb | 17 - ...2_remove_unique_index_on_email_on_users.rb | 11 - ...vice_and_invitation_identifier_to_users.rb | 11 - .../20110127000931_drop_extra_columns.rb | 10 - .../20110127000953_make_fields_not_null.rb | 39 -- ...0130072907_notification_multiple_people.rb | 70 -- .../20110202015222_add_open_to_aspects.rb | 9 - db/migrate/20110209204702_create_mentions.rb | 15 - ...110211021926_fix_target_on_notification.rb | 29 - ...11204804_unique_index_post_visibilities.rb | 39 -- .../20110213052742_add_more_indicies.rb | 19 - .../20110217044519_undo_adding_indicies.rb | 10 - ...ersations_and_messages_and_visibilities.rb | 39 -- .../20110228180709_notification_subclasses.rb | 31 - .../20110228201109_foreign_key_constraints.rb | 63 -- ...me_post_to_parent_and_creator_to_author.rb | 11 - ...0110228233419_add_signatures_to_message.rb | 11 - .../20110301014507_rename_person_to_author.rb | 19 - db/migrate/20110301202619_drop_statistics.rb | 9 - ...311000150_acts_as_taggable_on_migration.rb | 28 - .../20110311183826_create_user_preferences.rb | 14 - db/migrate/20110311220249_downcase_tags.rb | 26 - .../20110313015438_rename_text_fields.rb | 12 - .../20110314043119_drop_import_tables.rb | 10 - db/migrate/20110317222802_guid_is_unique.rb | 36 - .../20110318000734_create_service_users.rb | 23 - ...12008_delete_disconnected_notifications.rb | 11 - .../20110319005509_add_processed_to_post.rb | 9 - db/migrate/20110319172136_add_likes.rb | 26 - ...110321205715_unprocessed_image_uploader.rb | 14 - .../20110323213655_add_location_to_profile.rb | 9 - ...8175936_add_hidden_to_post_visibilities.rb | 11 - ...328202414_post_visibilities_on_contacts.rb | 97 --- db/migrate/20110330175950_tag_uniqueness.rb | 24 - db/migrate/20110330230206_pm_foreign_keys.rb | 53 -- .../20110331004720_add_hidden_indicies.rb | 12 - .../20110405170101_fix_stream_queries.rb | 11 - ...emove_pending_add_sharing_and_receiving.rb | 61 -- .../20110406202932_drop_requests_table.rb | 40 -- .../20110406203720_tag_name_uniqueness.rb | 45 -- .../20110421120744_downcase_usernames.rb | 15 - ...07212759_remove_type_null_notifications.rb | 13 - ...0513175000_eliminate_stray_user_records.rb | 32 - .../20110514182918_update_devise_invitable.rb | 13 - ...48_delete_all_new_request_notifications.rb | 14 - ...rd_reset_for_accounts_without_usernames.rb | 16 - .../20110518184453_add_token_auth_to_user.rb | 11 - ...3_add_column_for_activity_streams_photo.rb | 21 - .../20110524184202_add_object_id_to_post.rb | 11 - .../20110525213325_add_root_id_to_posts.rb | 9 - ...hoto_status_message_association_on_guid.rb | 46 -- ...01083310_add_unconfirmed_email_to_users.rb | 9 - ...091059_add_confirm_email_token_to_users.rb | 9 - db/migrate/20110603181015_lockable_users.rb | 9 - .../20110603212633_likes_dependent_delete.rb | 15 - .../20110603233202_drop_aspects_open.rb | 10 - .../20110604012703_drop_mongo_remains.rb | 18 - .../20110604204533_index_on_remember_token.rb | 9 - db/migrate/20110606192307_drop_mongo_ids.rb | 29 - .../20110623210918_add_o_auth2_support.rb | 65 -- .../20110701215925_create_tag_followings.rb | 14 - ...10705003445_counter_cache_on_post_likes.rb | 14 - ...0110707221112_index_taggings_created_at.rb | 8 - .../20110707234802_likes_on_comments.rb | 39 -- .../20110710102747_add_order_id_to_aspects.rb | 9 - ...20110729045734_add_full_name_to_profile.rb | 29 - db/migrate/20110730173137_create_pods.rb | 14 - db/migrate/20110730173443_create_pod_stats.rb | 16 - ...812175614_add_username_to_service_users.rb | 9 - ...5210933_remove_invite_counter_from_user.rb | 9 - ...0110816061820_add_fields_to_invitations.rb | 17 - ..._add_identifier_to_existing_invitations.rb | 20 - .../20110830170929_remove_pod_stats_table.rb | 16 - .../20110907205720_add_indexes_to_serivces.rb | 11 - ...11213207_counter_cache_on_post_comments.rb | 15 - .../20110924112840_create_o_embed_caches.rb | 14 - .../20110926120220_fix_indexes_to_serivces.rb | 14 - ...0930182048_add_root_guid_index_to_posts.rb | 9 - ...ata_type_for_activity_streams_object_id.rb | 11 - .../20111003232053_add_index_for_reshares.rb | 9 - ...0111011193702_add_oembed_cache_to_posts.rb | 9 - db/migrate/20111011194702_comment_anything.rb | 18 - db/migrate/20111011195702_share_anything.rb | 114 --- ...12215141_move_photos_to_their_own_table.rb | 161 ----- ...11016145626_add_language_to_invitations.rb | 9 - db/migrate/20111018010003_add_back_indexes.rb | 15 - ...019013244_postgresql_photos_id_seq_init.rb | 11 - ...84041_add_community_spotlight_in_stream.rb | 14 - ...1023230730_fix_photo_share_visibilities.rb | 40 -- ...3547_add_missing_tag_followings_indices.rb | 34 - db/migrate/20111101202137_create_blocks.rb | 12 - ...84050_add_closed_account_flag_to_person.rb | 9 - ...20111109023618_create_account_deletions.rb | 12 - ...11025358_counter_cache_on_post_reshares.rb | 35 - ...114173111_add_auto_follow_back_to_users.rb | 11 - ...add_oauth_redirect_uri_to_oauth_clients.rb | 9 - ...ove_low_length_limits_from_oauth_tables.rb | 19 - .../20111211213438_create_invitation_codes.rb | 15 - ...7042006_add_photo_counter_cache_to_post.rb | 15 - ...0942_move_recently_hidden_posts_to_user.rb | 28 - ...114191018_remove_photos_count_from_post.rb | 13 - .../20120127235102_add_nsfw_to_profiles.rb | 9 - ...190701_remove_public_share_visibilities.rb | 59 -- ...120203220932_add_interacted_at_to_posts.rb | 9 - .../20120208231253_create_participations.rb | 17 - .../20120301143226_remove_youtube_titles.rb | 11 - ...120322223517_add_template_name_to_posts.rb | 5 - ...5842_remove_invitation_email_from_users.rb | 17 - ...20120330103021_indexes_on_participation.rb | 6 - db/migrate/20120330144057_indexes_on_posts.rb | 5 - db/migrate/20120405170105_create_locations.rb | 12 - ...5431_create_rails_admin_histories_table.rb | 18 - ...20185823_add_width_and_height_to_photos.rb | 6 - .../20120422072257_add_favorite_to_post.rb | 5 - db/migrate/20120427152648_create_roles.rb | 10 - ...20120506053156_add_wallpaper_to_profile.rb | 5 - .../20120510184853_drop_service_users.rb | 24 - db/migrate/20120517014034_remove_oauth.rb | 57 -- ...5723_remove_multi_photo_frame_reference.rb | 8 - .../20120521191429_remove_rich_media_type.rb | 8 - ...120803143552_add_fetch_status_to_people.rb | 5 - db/migrate/20120906162503_update_devise.rb | 11 - ...909053122_remove_wallpaper_from_profile.rb | 9 - db/schema.rb | 119 ++-- 133 files changed, 529 insertions(+), 3220 deletions(-) delete mode 100644 db/migrate/20110105051803_create_import_tables.rb delete mode 100644 db/migrate/20110119060243_add_index_to_post_visibilities.rb delete mode 100644 db/migrate/20110119221746_add_indicies.rb delete mode 100644 db/migrate/20110120181553_create_statistics.rb delete mode 100644 db/migrate/20110120182100_create_data_points.rb delete mode 100644 db/migrate/20110123210746_alter_string_columns.rb delete mode 100644 db/migrate/20110125190034_unique_index_on_profile.rb delete mode 100644 db/migrate/20110126015407_add_invitation_service_and_invitation_identifier_to_user.rb delete mode 100644 db/migrate/20110126200714_add_contacts_visible.rb delete mode 100644 db/migrate/20110126225202_remove_unique_index_on_email_on_users.rb delete mode 100644 db/migrate/20110126232040_add_unique_index_on_invitation_service_and_invitation_identifier_to_users.rb delete mode 100644 db/migrate/20110127000931_drop_extra_columns.rb delete mode 100644 db/migrate/20110127000953_make_fields_not_null.rb delete mode 100644 db/migrate/20110130072907_notification_multiple_people.rb delete mode 100644 db/migrate/20110202015222_add_open_to_aspects.rb delete mode 100644 db/migrate/20110209204702_create_mentions.rb delete mode 100644 db/migrate/20110211021926_fix_target_on_notification.rb delete mode 100644 db/migrate/20110211204804_unique_index_post_visibilities.rb delete mode 100644 db/migrate/20110213052742_add_more_indicies.rb delete mode 100644 db/migrate/20110217044519_undo_adding_indicies.rb delete mode 100644 db/migrate/20110225190919_create_conversations_and_messages_and_visibilities.rb delete mode 100644 db/migrate/20110228180709_notification_subclasses.rb delete mode 100644 db/migrate/20110228201109_foreign_key_constraints.rb delete mode 100644 db/migrate/20110228220810_rename_post_to_parent_and_creator_to_author.rb delete mode 100644 db/migrate/20110228233419_add_signatures_to_message.rb delete mode 100644 db/migrate/20110301014507_rename_person_to_author.rb delete mode 100644 db/migrate/20110301202619_drop_statistics.rb delete mode 100644 db/migrate/20110311000150_acts_as_taggable_on_migration.rb delete mode 100644 db/migrate/20110311183826_create_user_preferences.rb delete mode 100644 db/migrate/20110311220249_downcase_tags.rb delete mode 100644 db/migrate/20110313015438_rename_text_fields.rb delete mode 100644 db/migrate/20110314043119_drop_import_tables.rb delete mode 100644 db/migrate/20110317222802_guid_is_unique.rb delete mode 100644 db/migrate/20110318000734_create_service_users.rb delete mode 100644 db/migrate/20110318012008_delete_disconnected_notifications.rb delete mode 100644 db/migrate/20110319005509_add_processed_to_post.rb delete mode 100644 db/migrate/20110319172136_add_likes.rb delete mode 100644 db/migrate/20110321205715_unprocessed_image_uploader.rb delete mode 100644 db/migrate/20110323213655_add_location_to_profile.rb delete mode 100644 db/migrate/20110328175936_add_hidden_to_post_visibilities.rb delete mode 100644 db/migrate/20110328202414_post_visibilities_on_contacts.rb delete mode 100644 db/migrate/20110330175950_tag_uniqueness.rb delete mode 100644 db/migrate/20110330230206_pm_foreign_keys.rb delete mode 100644 db/migrate/20110331004720_add_hidden_indicies.rb delete mode 100644 db/migrate/20110405170101_fix_stream_queries.rb delete mode 100644 db/migrate/20110405171412_contact_remove_pending_add_sharing_and_receiving.rb delete mode 100644 db/migrate/20110406202932_drop_requests_table.rb delete mode 100644 db/migrate/20110406203720_tag_name_uniqueness.rb delete mode 100644 db/migrate/20110421120744_downcase_usernames.rb delete mode 100644 db/migrate/20110507212759_remove_type_null_notifications.rb delete mode 100644 db/migrate/20110513175000_eliminate_stray_user_records.rb delete mode 100644 db/migrate/20110514182918_update_devise_invitable.rb delete mode 100644 db/migrate/20110517180148_delete_all_new_request_notifications.rb delete mode 100644 db/migrate/20110518010050_disable_password_reset_for_accounts_without_usernames.rb delete mode 100644 db/migrate/20110518184453_add_token_auth_to_user.rb delete mode 100644 db/migrate/20110518222303_add_column_for_activity_streams_photo.rb delete mode 100644 db/migrate/20110524184202_add_object_id_to_post.rb delete mode 100644 db/migrate/20110525213325_add_root_id_to_posts.rb delete mode 100644 db/migrate/20110527135552_photo_status_message_association_on_guid.rb delete mode 100644 db/migrate/20110601083310_add_unconfirmed_email_to_users.rb delete mode 100644 db/migrate/20110601091059_add_confirm_email_token_to_users.rb delete mode 100644 db/migrate/20110603181015_lockable_users.rb delete mode 100644 db/migrate/20110603212633_likes_dependent_delete.rb delete mode 100644 db/migrate/20110603233202_drop_aspects_open.rb delete mode 100644 db/migrate/20110604012703_drop_mongo_remains.rb delete mode 100644 db/migrate/20110604204533_index_on_remember_token.rb delete mode 100644 db/migrate/20110606192307_drop_mongo_ids.rb delete mode 100644 db/migrate/20110623210918_add_o_auth2_support.rb delete mode 100644 db/migrate/20110701215925_create_tag_followings.rb delete mode 100644 db/migrate/20110705003445_counter_cache_on_post_likes.rb delete mode 100644 db/migrate/20110707221112_index_taggings_created_at.rb delete mode 100644 db/migrate/20110707234802_likes_on_comments.rb delete mode 100644 db/migrate/20110710102747_add_order_id_to_aspects.rb delete mode 100644 db/migrate/20110729045734_add_full_name_to_profile.rb delete mode 100644 db/migrate/20110730173137_create_pods.rb delete mode 100644 db/migrate/20110730173443_create_pod_stats.rb delete mode 100644 db/migrate/20110812175614_add_username_to_service_users.rb delete mode 100644 db/migrate/20110815210933_remove_invite_counter_from_user.rb delete mode 100644 db/migrate/20110816061820_add_fields_to_invitations.rb delete mode 100644 db/migrate/20110818212541_add_identifier_to_existing_invitations.rb delete mode 100644 db/migrate/20110830170929_remove_pod_stats_table.rb delete mode 100644 db/migrate/20110907205720_add_indexes_to_serivces.rb delete mode 100644 db/migrate/20110911213207_counter_cache_on_post_comments.rb delete mode 100644 db/migrate/20110924112840_create_o_embed_caches.rb delete mode 100644 db/migrate/20110926120220_fix_indexes_to_serivces.rb delete mode 100644 db/migrate/20110930182048_add_root_guid_index_to_posts.rb delete mode 100644 db/migrate/20111002013921_fix_data_type_for_activity_streams_object_id.rb delete mode 100644 db/migrate/20111003232053_add_index_for_reshares.rb delete mode 100644 db/migrate/20111011193702_add_oembed_cache_to_posts.rb delete mode 100644 db/migrate/20111011194702_comment_anything.rb delete mode 100644 db/migrate/20111011195702_share_anything.rb delete mode 100644 db/migrate/20111012215141_move_photos_to_their_own_table.rb delete mode 100644 db/migrate/20111016145626_add_language_to_invitations.rb delete mode 100644 db/migrate/20111018010003_add_back_indexes.rb delete mode 100644 db/migrate/20111019013244_postgresql_photos_id_seq_init.rb delete mode 100644 db/migrate/20111021184041_add_community_spotlight_in_stream.rb delete mode 100644 db/migrate/20111023230730_fix_photo_share_visibilities.rb delete mode 100644 db/migrate/20111026173547_add_missing_tag_followings_indices.rb delete mode 100644 db/migrate/20111101202137_create_blocks.rb delete mode 100644 db/migrate/20111103184050_add_closed_account_flag_to_person.rb delete mode 100644 db/migrate/20111109023618_create_account_deletions.rb delete mode 100644 db/migrate/20111111025358_counter_cache_on_post_reshares.rb delete mode 100644 db/migrate/20111114173111_add_auto_follow_back_to_users.rb delete mode 100644 db/migrate/20111207230506_add_oauth_redirect_uri_to_oauth_clients.rb delete mode 100644 db/migrate/20111207233503_remove_low_length_limits_from_oauth_tables.rb delete mode 100644 db/migrate/20111211213438_create_invitation_codes.rb delete mode 100644 db/migrate/20111217042006_add_photo_counter_cache_to_post.rb delete mode 100644 db/migrate/20120107220942_move_recently_hidden_posts_to_user.rb delete mode 100644 db/migrate/20120114191018_remove_photos_count_from_post.rb delete mode 100644 db/migrate/20120127235102_add_nsfw_to_profiles.rb delete mode 100644 db/migrate/20120202190701_remove_public_share_visibilities.rb delete mode 100644 db/migrate/20120203220932_add_interacted_at_to_posts.rb delete mode 100644 db/migrate/20120208231253_create_participations.rb delete mode 100644 db/migrate/20120301143226_remove_youtube_titles.rb delete mode 100644 db/migrate/20120322223517_add_template_name_to_posts.rb delete mode 100644 db/migrate/20120328025842_remove_invitation_email_from_users.rb delete mode 100644 db/migrate/20120330103021_indexes_on_participation.rb delete mode 100644 db/migrate/20120330144057_indexes_on_posts.rb delete mode 100644 db/migrate/20120405170105_create_locations.rb delete mode 100644 db/migrate/20120414005431_create_rails_admin_histories_table.rb delete mode 100644 db/migrate/20120420185823_add_width_and_height_to_photos.rb delete mode 100644 db/migrate/20120422072257_add_favorite_to_post.rb delete mode 100644 db/migrate/20120427152648_create_roles.rb delete mode 100644 db/migrate/20120506053156_add_wallpaper_to_profile.rb delete mode 100644 db/migrate/20120510184853_drop_service_users.rb delete mode 100644 db/migrate/20120517014034_remove_oauth.rb delete mode 100644 db/migrate/20120519015723_remove_multi_photo_frame_reference.rb delete mode 100644 db/migrate/20120521191429_remove_rich_media_type.rb delete mode 100644 db/migrate/20120803143552_add_fetch_status_to_people.rb delete mode 100644 db/migrate/20120906162503_update_devise.rb delete mode 100644 db/migrate/20120909053122_remove_wallpaper_from_profile.rb diff --git a/db/migrate/0000_create_schema.rb b/db/migrate/0000_create_schema.rb index c6057bcce..43d1f608c 100644 --- a/db/migrate/0000_create_schema.rb +++ b/db/migrate/0000_create_schema.rb @@ -1,181 +1,479 @@ class CreateSchema < ActiveRecord::Migration - def self.up - create_table :aspects do |t| - t.string :name - t.integer :user_id - t.timestamps - end - add_index :aspects, :user_id - - create_table :aspect_memberships do |t| - t.integer :aspect_id - t.integer :contact_id - t.timestamps - end - add_index :aspect_memberships, :aspect_id - add_index :aspect_memberships, [:aspect_id, :contact_id], :unique => true - add_index :aspect_memberships, :contact_id - - create_table :comments do |t| - t.text :text - t.integer :post_id - t.integer :person_id - t.string :guid - t.text :creator_signature - t.text :post_creator_signature - t.text :youtube_titles - t.timestamps - end - add_index :comments, :guid, :unique => true - add_index :comments, :post_id - - create_table :contacts do |t| - t.integer :user_id - t.integer :person_id - t.boolean :pending, :default => true - t.timestamps - end - add_index :contacts, [:user_id, :pending] - add_index :contacts, [:person_id, :pending] - add_index :contacts, [:user_id, :person_id], :unique => true - - create_table :invitations do |t| - t.text :message - t.integer :sender_id - t.integer :recipient_id - t.integer :aspect_id - t.timestamps - end - add_index :invitations, :sender_id - - create_table :notifications do |t| - t.string :target_type - t.integer :target_id - t.integer :recipient_id - t.integer :actor_id - t.string :action - t.boolean :unread, :default => true - t.timestamps - end - add_index :notifications, [:target_type, :target_id] - - create_table :people do |t| - t.string :guid - t.text :url - t.string :diaspora_handle - t.text :serialized_public_key - t.integer :owner_id - t.timestamps - end - add_index :people, :guid, :unique => true - add_index :people, :owner_id, :unique => true - add_index :people, :diaspora_handle, :unique => true - - create_table :posts do |t| - t.integer :person_id - t.boolean :public, :default => false - t.string :diaspora_handle - t.string :guid - t.boolean :pending, :default => false - t.string :type - - t.text :message - - t.integer :status_message_id - t.text :caption - t.text :remote_photo_path - t.string :remote_photo_name - t.string :random_string - t.string :image #carrierwave's column - t.text :youtube_titles - - t.timestamps - end - add_index :posts, :type - add_index :posts, :person_id - add_index :posts, :guid - - create_table :post_visibilities do |t| - t.integer :aspect_id - t.integer :post_id - t.timestamps - end - add_index :post_visibilities, :aspect_id - add_index :post_visibilities, :post_id - - create_table :profiles do |t| - t.string :diaspora_handle - t.string :first_name, :limit => 127 - t.string :last_name, :limit => 127 - t.string :image_url - t.string :image_url_small - t.string :image_url_medium - t.date :birthday - t.string :gender - t.text :bio - t.boolean :searchable, :default => true - t.integer :person_id - t.timestamps - end - add_index :profiles, [:first_name, :searchable] - add_index :profiles, [:last_name, :searchable] - add_index :profiles, [:first_name, :last_name, :searchable] - add_index :profiles, :person_id - - create_table :requests do |t| - t.integer :sender_id - t.integer :recipient_id - t.integer :aspect_id - t.timestamps - end - add_index :requests, :sender_id - add_index :requests, :recipient_id - add_index :requests, [:sender_id, :recipient_id], :unique => true - - create_table :services do |t| - t.string :type, :limit => 127 - t.integer :user_id - t.string :provider - t.string :uid, :limit => 127 - t.string :access_token - t.string :access_secret - t.string :nickname - t.timestamps - end - add_index :services, :user_id - - create_table :users do |t| - t.string :username - t.text :serialized_private_key - t.integer :invites, :default => 0 - t.boolean :getting_started, :default => true - t.boolean :disable_mail, :default => false - t.string :language - - t.string :email, :null => false, :default => "" - t.string :encrypted_password, :null => false, :default => "" - - t.string :invitation_token, :limit => 60 - t.datetime :invitation_sent_at - - t.string :reset_password_token - t.datetime :remember_created_at - t.string :remember_token - t.integer :sign_in_count, :default => 0 - t.datetime :current_sign_in_at - t.datetime :last_sign_in_at - t.string :current_sign_in_ip - t.string :last_sign_in_ip - - t.timestamps - end - add_index :users, :username, :unique => true - add_index :users, :email, :unique => true - add_index :users, :invitation_token - + create_table "account_deletions", :force => true do |t| + t.string "diaspora_handle" + t.integer "person_id" end - def self.down - raise "irreversable migration!" + create_table "aspect_memberships", :force => true do |t| + t.integer "aspect_id", :null => false + t.integer "contact_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end + + add_index "aspect_memberships", ["aspect_id", "contact_id"], :name => "index_aspect_memberships_on_aspect_id_and_contact_id", :unique => true + add_index "aspect_memberships", ["aspect_id"], :name => "index_aspect_memberships_on_aspect_id" + add_index "aspect_memberships", ["contact_id"], :name => "index_aspect_memberships_on_contact_id" + + create_table "aspect_visibilities", :force => true do |t| + t.integer "shareable_id", :null => false + t.integer "aspect_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "shareable_type", :default => "Post", :null => false + end + + add_index "aspect_visibilities", ["aspect_id"], :name => "index_aspect_visibilities_on_aspect_id" + add_index "aspect_visibilities", ["shareable_id", "shareable_type", "aspect_id"], :name => "shareable_and_aspect_id" + add_index "aspect_visibilities", ["shareable_id", "shareable_type"], :name => "index_aspect_visibilities_on_shareable_id_and_shareable_type" + + create_table "aspects", :force => true do |t| + t.string "name", :null => false + t.integer "user_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "contacts_visible", :default => true, :null => false + t.integer "order_id" + end + + add_index "aspects", ["user_id", "contacts_visible"], :name => "index_aspects_on_user_id_and_contacts_visible" + add_index "aspects", ["user_id"], :name => "index_aspects_on_user_id" + + create_table "blocks", :force => true do |t| + t.integer "user_id" + t.integer "person_id" + end + + create_table "comments", :force => true do |t| + t.text "text", :null => false + t.integer "commentable_id", :null => false + t.integer "author_id", :null => false + t.string "guid", :null => false + t.text "author_signature" + t.text "parent_author_signature" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.integer "likes_count", :default => 0, :null => false + t.string "commentable_type", :limit => 60, :default => "Post", :null => false + end + + add_index "comments", ["author_id"], :name => "index_comments_on_person_id" + add_index "comments", ["commentable_id", "commentable_type"], :name => "index_comments_on_commentable_id_and_commentable_type" + add_index "comments", ["guid"], :name => "index_comments_on_guid", :unique => true + + create_table "contacts", :force => true do |t| + t.integer "user_id", :null => false + t.integer "person_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "sharing", :default => false, :null => false + t.boolean "receiving", :default => false, :null => false + end + + add_index "contacts", ["person_id"], :name => "index_contacts_on_person_id" + add_index "contacts", ["user_id", "person_id"], :name => "index_contacts_on_user_id_and_person_id", :unique => true + + create_table "conversation_visibilities", :force => true do |t| + t.integer "conversation_id", :null => false + t.integer "person_id", :null => false + t.integer "unread", :default => 0, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "conversation_visibilities", ["conversation_id", "person_id"], :name => "index_conversation_visibilities_usefully", :unique => true + add_index "conversation_visibilities", ["conversation_id"], :name => "index_conversation_visibilities_on_conversation_id" + add_index "conversation_visibilities", ["person_id"], :name => "index_conversation_visibilities_on_person_id" + + create_table "conversations", :force => true do |t| + t.string "subject" + t.string "guid", :null => false + t.integer "author_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "conversations", ["author_id"], :name => "conversations_author_id_fk" + + create_table "invitation_codes", :force => true do |t| + t.string "token" + t.integer "user_id" + t.integer "count" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "invitations", :force => true do |t| + t.text "message" + t.integer "sender_id" + t.integer "recipient_id" + t.integer "aspect_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "service" + t.string "identifier" + t.boolean "admin", :default => false + t.string "language", :default => "en" + end + + add_index "invitations", ["aspect_id"], :name => "index_invitations_on_aspect_id" + add_index "invitations", ["recipient_id"], :name => "index_invitations_on_recipient_id" + add_index "invitations", ["sender_id"], :name => "index_invitations_on_sender_id" + + create_table "likes", :force => true do |t| + t.boolean "positive", :default => true + t.integer "target_id" + t.integer "author_id" + t.string "guid" + t.text "author_signature" + t.text "parent_author_signature" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "target_type", :limit => 60, :null => false + end + + add_index "likes", ["author_id"], :name => "likes_author_id_fk" + add_index "likes", ["guid"], :name => "index_likes_on_guid", :unique => true + add_index "likes", ["target_id", "author_id", "target_type"], :name => "index_likes_on_target_id_and_author_id_and_target_type", :unique => true + add_index "likes", ["target_id"], :name => "index_likes_on_post_id" + + create_table "mentions", :force => true do |t| + t.integer "post_id", :null => false + t.integer "person_id", :null => false + end + + add_index "mentions", ["person_id", "post_id"], :name => "index_mentions_on_person_id_and_post_id", :unique => true + add_index "mentions", ["person_id"], :name => "index_mentions_on_person_id" + add_index "mentions", ["post_id"], :name => "index_mentions_on_post_id" + + create_table "messages", :force => true do |t| + t.integer "conversation_id", :null => false + t.integer "author_id", :null => false + t.string "guid", :null => false + t.text "text", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.text "author_signature" + t.text "parent_author_signature" + end + + add_index "messages", ["author_id"], :name => "index_messages_on_author_id" + add_index "messages", ["conversation_id"], :name => "messages_conversation_id_fk" + + create_table "notification_actors", :force => true do |t| + t.integer "notification_id" + t.integer "person_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "notification_actors", ["notification_id", "person_id"], :name => "index_notification_actors_on_notification_id_and_person_id", :unique => true + add_index "notification_actors", ["notification_id"], :name => "index_notification_actors_on_notification_id" + add_index "notification_actors", ["person_id"], :name => "index_notification_actors_on_person_id" + + create_table "notifications", :force => true do |t| + t.string "target_type" + t.integer "target_id" + t.integer "recipient_id", :null => false + t.boolean "unread", :default => true, :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "type" + end + + add_index "notifications", ["recipient_id"], :name => "index_notifications_on_recipient_id" + add_index "notifications", ["target_id"], :name => "index_notifications_on_target_id" + add_index "notifications", ["target_type", "target_id"], :name => "index_notifications_on_target_type_and_target_id" + + create_table "o_embed_caches", :force => true do |t| + t.string "url", :limit => 1024, :null => false + t.text "data", :null => false + end + + add_index "o_embed_caches", ["url"], :name => "index_o_embed_caches_on_url", :length => {"url"=>255} + + create_table "participations", :force => true do |t| + t.string "guid" + t.integer "target_id" + t.string "target_type", :limit => 60, :null => false + t.integer "author_id" + t.text "author_signature" + t.text "parent_author_signature" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "participations", ["guid"], :name => "index_participations_on_guid" + add_index "participations", ["target_id", "target_type", "author_id"], :name => "index_participations_on_target_id_and_target_type_and_author_id" + + create_table "people", :force => true do |t| + t.string "guid", :null => false + t.text "url", :null => false + t.string "diaspora_handle", :null => false + t.text "serialized_public_key", :null => false + t.integer "owner_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "closed_account", :default => false + t.integer "fetch_status", :default => 0 + end + + add_index "people", ["diaspora_handle"], :name => "index_people_on_diaspora_handle", :unique => true + add_index "people", ["guid"], :name => "index_people_on_guid", :unique => true + add_index "people", ["owner_id"], :name => "index_people_on_owner_id", :unique => true + + create_table "photos", :force => true do |t| + t.integer "tmp_old_id" + t.integer "author_id", :null => false + t.boolean "public", :default => false, :null => false + t.string "diaspora_handle" + t.string "guid", :null => false + t.boolean "pending", :default => false, :null => false + t.text "text" + t.text "remote_photo_path" + t.string "remote_photo_name" + t.string "random_string" + t.string "processed_image" + t.datetime "created_at" + t.datetime "updated_at" + t.string "unprocessed_image" + t.string "status_message_guid" + t.integer "comments_count" + t.integer "height" + t.integer "width" + end + + add_index "photos", ["status_message_guid"], :name => "index_photos_on_status_message_guid" + + create_table "pods", :force => true do |t| + t.string "host" + t.boolean "ssl" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "posts", :force => true do |t| + t.integer "author_id", :null => false + t.boolean "public", :default => false, :null => false + t.string "diaspora_handle" + t.string "guid", :null => false + t.boolean "pending", :default => false, :null => false + t.string "type", :limit => 40, :null => false + t.text "text" + t.text "remote_photo_path" + t.string "remote_photo_name" + t.string "random_string" + t.string "processed_image" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "unprocessed_image" + t.string "object_url" + t.string "image_url" + t.integer "image_height" + t.integer "image_width" + t.string "provider_display_name" + t.string "actor_url" + t.string "objectId" + t.string "root_guid", :limit => 30 + t.string "status_message_guid" + t.integer "likes_count", :default => 0 + t.integer "comments_count", :default => 0 + t.integer "o_embed_cache_id" + t.integer "reshares_count", :default => 0 + t.datetime "interacted_at" + t.string "frame_name" + t.boolean "favorite", :default => false + end + + add_index "posts", ["author_id", "root_guid"], :name => "index_posts_on_author_id_and_root_guid", :unique => true + add_index "posts", ["author_id"], :name => "index_posts_on_person_id" + add_index "posts", ["guid"], :name => "index_posts_on_guid", :unique => true + add_index "posts", ["id", "type", "created_at"], :name => "index_posts_on_id_and_type_and_created_at" + add_index "posts", ["root_guid"], :name => "index_posts_on_root_guid" + add_index "posts", ["status_message_guid", "pending"], :name => "index_posts_on_status_message_guid_and_pending" + add_index "posts", ["status_message_guid"], :name => "index_posts_on_status_message_guid" + add_index "posts", ["type", "pending", "id"], :name => "index_posts_on_type_and_pending_and_id" + + create_table "profiles", :force => true do |t| + t.string "diaspora_handle" + t.string "first_name", :limit => 127 + t.string "last_name", :limit => 127 + t.string "image_url" + t.string "image_url_small" + t.string "image_url_medium" + t.date "birthday" + t.string "gender" + t.text "bio" + t.boolean "searchable", :default => true, :null => false + t.integer "person_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "location" + t.string "full_name", :limit => 70 + t.boolean "nsfw", :default => false + end + + add_index "profiles", ["full_name", "searchable"], :name => "index_profiles_on_full_name_and_searchable" + add_index "profiles", ["full_name"], :name => "index_profiles_on_full_name" + add_index "profiles", ["person_id"], :name => "index_profiles_on_person_id" + + create_table "rails_admin_histories", :force => true do |t| + t.text "message" + t.string "username" + t.integer "item" + t.string "table" + t.integer "month", :limit => 2 + t.integer "year", :limit => 8 + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "rails_admin_histories", ["item", "table", "month", "year"], :name => "index_rails_admin_histories" + + create_table "roles", :force => true do |t| + t.integer "person_id" + t.string "name" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "services", :force => true do |t| + t.string "type", :limit => 127, :null => false + t.integer "user_id", :null => false + t.string "uid", :limit => 127 + t.string "access_token" + t.string "access_secret" + t.string "nickname" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "services", ["type", "uid"], :name => "index_services_on_type_and_uid" + add_index "services", ["user_id"], :name => "index_services_on_user_id" + + create_table "share_visibilities", :force => true do |t| + t.integer "shareable_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.boolean "hidden", :default => false, :null => false + t.integer "contact_id", :null => false + t.string "shareable_type", :limit => 60, :default => "Post", :null => false + end + + add_index "share_visibilities", ["contact_id"], :name => "index_post_visibilities_on_contact_id" + add_index "share_visibilities", ["shareable_id", "shareable_type", "contact_id"], :name => "shareable_and_contact_id" + add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "contact_id"], :name => "shareable_and_hidden_and_contact_id" + add_index "share_visibilities", ["shareable_id"], :name => "index_post_visibilities_on_post_id" + + create_table "tag_followings", :force => true do |t| + t.integer "tag_id", :null => false + t.integer "user_id", :null => false + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + add_index "tag_followings", ["tag_id", "user_id"], :name => "index_tag_followings_on_tag_id_and_user_id", :unique => true + add_index "tag_followings", ["tag_id"], :name => "index_tag_followings_on_tag_id" + add_index "tag_followings", ["user_id"], :name => "index_tag_followings_on_user_id" + + create_table "taggings", :force => true do |t| + t.integer "tag_id" + t.integer "taggable_id" + t.string "taggable_type", :limit => 127 + t.integer "tagger_id" + t.string "tagger_type", :limit => 127 + t.string "context", :limit => 127 + t.datetime "created_at" + end + + add_index "taggings", ["created_at"], :name => "index_taggings_on_created_at" + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" + add_index "taggings", ["taggable_id", "taggable_type", "context"], :name => "index_taggings_on_taggable_id_and_taggable_type_and_context" + add_index "taggings", ["taggable_id", "taggable_type", "tag_id"], :name => "index_taggings_uniquely", :unique => true + + create_table "tags", :force => true do |t| + t.string "name" + end + + add_index "tags", ["name"], :name => "index_tags_on_name", :unique => true + + create_table "user_preferences", :force => true do |t| + t.string "email_type" + t.integer "user_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + + create_table "users", :force => true do |t| + t.string "username" + t.text "serialized_private_key" + t.boolean "getting_started", :default => true, :null => false + t.boolean "disable_mail", :default => false, :null => false + t.string "language" + t.string "email", :default => "", :null => false + t.string "encrypted_password", :default => "", :null => false + t.string "invitation_token", :limit => 60 + t.datetime "invitation_sent_at" + t.string "reset_password_token" + t.datetime "remember_created_at" + t.integer "sign_in_count", :default => 0 + t.datetime "current_sign_in_at" + t.datetime "last_sign_in_at" + t.string "current_sign_in_ip" + t.string "last_sign_in_ip" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + t.string "invitation_service", :limit => 127 + t.string "invitation_identifier", :limit => 127 + t.integer "invitation_limit" + t.integer "invited_by_id" + t.string "invited_by_type" + t.string "authentication_token", :limit => 30 + t.string "unconfirmed_email" + t.string "confirm_email_token", :limit => 30 + t.datetime "locked_at" + t.boolean "show_community_spotlight_in_stream", :default => true, :null => false + t.boolean "auto_follow_back", :default => false + t.integer "auto_follow_back_aspect_id" + t.text "hidden_shareables" + t.datetime "reset_password_sent_at" + end + + add_index "users", ["authentication_token"], :name => "index_users_on_authentication_token", :unique => true + add_index "users", ["email"], :name => "index_users_on_email" + add_index "users", ["invitation_service", "invitation_identifier"], :name => "index_users_on_invitation_service_and_invitation_identifier", :unique => true + add_index "users", ["invitation_token"], :name => "index_users_on_invitation_token" + add_index "users", ["username"], :name => "index_users_on_username", :unique => true + + add_foreign_key "aspect_memberships", "aspects", :name => "aspect_memberships_aspect_id_fk", :dependent => :delete + add_foreign_key "aspect_memberships", "contacts", :name => "aspect_memberships_contact_id_fk", :dependent => :delete + + add_foreign_key "aspect_visibilities", "aspects", :name => "aspect_visibilities_aspect_id_fk", :dependent => :delete + + add_foreign_key "comments", "people", :name => "comments_author_id_fk", :column => "author_id", :dependent => :delete + + add_foreign_key "contacts", "people", :name => "contacts_person_id_fk", :dependent => :delete + + add_foreign_key "conversation_visibilities", "conversations", :name => "conversation_visibilities_conversation_id_fk", :dependent => :delete + add_foreign_key "conversation_visibilities", "people", :name => "conversation_visibilities_person_id_fk", :dependent => :delete + + add_foreign_key "conversations", "people", :name => "conversations_author_id_fk", :column => "author_id", :dependent => :delete + + add_foreign_key "invitations", "users", :name => "invitations_recipient_id_fk", :column => "recipient_id", :dependent => :delete + add_foreign_key "invitations", "users", :name => "invitations_sender_id_fk", :column => "sender_id", :dependent => :delete + + add_foreign_key "likes", "people", :name => "likes_author_id_fk", :column => "author_id", :dependent => :delete + + add_foreign_key "messages", "conversations", :name => "messages_conversation_id_fk", :dependent => :delete + add_foreign_key "messages", "people", :name => "messages_author_id_fk", :column => "author_id", :dependent => :delete + + add_foreign_key "notification_actors", "notifications", :name => "notification_actors_notification_id_fk", :dependent => :delete + + add_foreign_key "posts", "people", :name => "posts_author_id_fk", :column => "author_id", :dependent => :delete + + add_foreign_key "profiles", "people", :name => "profiles_person_id_fk", :dependent => :delete + + add_foreign_key "services", "users", :name => "services_user_id_fk", :dependent => :delete + + add_foreign_key "share_visibilities", "contacts", :name => "post_visibilities_contact_id_fk", :dependent => :delete end diff --git a/db/migrate/20110105051803_create_import_tables.rb b/db/migrate/20110105051803_create_import_tables.rb deleted file mode 100644 index 6e676951d..000000000 --- a/db/migrate/20110105051803_create_import_tables.rb +++ /dev/null @@ -1,199 +0,0 @@ -class CreateImportTables < ActiveRecord::Migration - def self.up - [:aspects, :comments, :contacts, :invitations, :notifications, :people, :posts, :profiles, :requests, :services, :users].each do |table| - add_column(table, :mongo_id, :string) - add_index(table, :mongo_id) - end - - add_column(:aspects, :user_mongo_id, :string) - create_table :mongo_aspects do |t| - t.string :mongo_id - t.string :name - t.string :user_mongo_id - t.timestamps - end - add_index :mongo_aspects, :user_mongo_id - - create_table :mongo_aspect_memberships do |t| - t.string :aspect_mongo_id - t.string :contact_mongo_id - t.timestamps - end - add_index :mongo_aspect_memberships, :aspect_mongo_id - add_index :mongo_aspect_memberships, :contact_mongo_id - - create_table :mongo_comments do |t| - t.text :text - t.string :mongo_id - t.string :post_mongo_id - t.string :person_mongo_id - t.string :guid - t.text :creator_signature - t.text :post_creator_signature - t.text :youtube_titles - t.timestamps - end - add_index :mongo_comments, :guid, :unique => true - add_index :mongo_comments, :post_mongo_id - - create_table :mongo_contacts do |t| - t.string :mongo_id - t.string :user_mongo_id - t.string :person_mongo_id - t.boolean :pending, :default => true - t.timestamps - end - add_index :mongo_contacts, [:user_mongo_id, :pending] - add_index :mongo_contacts, [:person_mongo_id, :pending] - - create_table :mongo_people do |t| - t.string :mongo_id - t.string :guid - t.text :url - t.string :diaspora_handle - t.text :serialized_public_key - t.string :owner_mongo_id - t.timestamps - end - add_index :mongo_people, :guid, :unique => true - add_index :mongo_people, :owner_mongo_id, :unique => true - add_index :mongo_people, :diaspora_handle, :unique => true - - create_table :mongo_posts do |t| - t.string :person_mongo_id - t.boolean :public, :default => false - t.string :diaspora_handle - t.string :guid - t.string :mongo_id - t.boolean :pending, :default => false - t.string :type - - t.text :message - - t.string :status_message_mongo_id - t.text :caption - t.text :remote_photo_path - t.string :remote_photo_name - t.string :random_string - t.string :image #carrierwave's column - t.text :youtube_titles - - t.timestamps - end - add_index :mongo_posts, :type - add_index :mongo_posts, :person_mongo_id - add_index :mongo_posts, :guid - - create_table :mongo_invitations do |t| - t.string :mongo_id - t.text :message - t.string :sender_mongo_id - t.string :recipient_mongo_id - t.string :aspect_mongo_id - t.timestamps - end - add_index :mongo_invitations, :sender_mongo_id - create_table :mongo_notifications do |t| - t.string :mongo_id - t.string :target_type, :limit => 127 - t.string :target_mongo_id, :limit => 127 - t.string :recipient_mongo_id - t.string :actor_mongo_id - t.string :action - t.boolean :unread, :default => true - t.timestamps - end - add_index :mongo_notifications, [:target_type, :target_mongo_id] - create_table :mongo_post_visibilities do |t| - t.string :aspect_mongo_id - t.string :post_mongo_id - t.timestamps - end - add_index :mongo_post_visibilities, :aspect_mongo_id - add_index :mongo_post_visibilities, :post_mongo_id - - create_table :mongo_profiles do |t| - t.string :diaspora_handle - t.string :first_name, :limit => 127 - t.string :last_name, :limit => 127 - t.string :image_url - t.string :image_url_small - t.string :image_url_medium - t.date :birthday - t.string :gender - t.text :bio - t.boolean :searchable, :default => true - t.string :person_mongo_id - t.timestamps - end - add_index :mongo_profiles, [:first_name, :searchable] - add_index :mongo_profiles, [:last_name, :searchable] - add_index :mongo_profiles, [:first_name, :last_name, :searchable] - add_index :mongo_profiles, :person_mongo_id, :unique => true - - - create_table :mongo_requests do |t| - t.string :mongo_id - t.string :sender_mongo_id, :limit => 127 - t.string :recipient_mongo_id, :limit => 127 - t.string :aspect_mongo_id - t.timestamps - end - add_index :mongo_requests, :sender_mongo_id - add_index :mongo_requests, :recipient_mongo_id - add_index :mongo_requests, [:sender_mongo_id, :recipient_mongo_id], :unique => true - - add_column(:services, :user_mongo_id, :string) - create_table :mongo_services do |t| - t.string :mongo_id - t.string :type - t.string :user_mongo_id - t.string :provider - t.string :uid - t.string :access_token - t.string :access_secret - t.string :nickname - t.timestamps - end - add_index :mongo_services, :user_mongo_id - - create_table :mongo_users do |t| - t.string :username - t.text :serialized_private_key - t.integer :invites - t.boolean :getting_started - t.boolean :disable_mail - t.string :language - t.string :email, :null => false, :default => "" - t.string :encrypted_password, :null => false, :default => "" - t.string :reset_password_token - t.datetime :reset_password_sent_at - t.datetime :remember_created_at - t.integer :sign_in_count, :default => 0 - t.datetime :current_sign_in_at - t.datetime :last_sign_in_at - t.string :current_sign_in_ip - t.string :last_sign_in_ip - - - t.timestamps - t.string :mongo_id - end - add_index :mongo_users, :mongo_id, :unique => true - end - - def self.down - execute 'DROP TABLE mongo_users' - execute 'DROP TABLE mongo_services' - execute 'DROP TABLE mongo_requests' - execute 'DROP TABLE mongo_post_visibilities' - execute 'DROP TABLE mongo_invitations' - execute 'DROP TABLE mongo_contacts' - execute 'DROP TABLE mongo_comments' - execute 'DROP TABLE mongo_profiles' - execute 'DROP TABLE mongo_people' - execute 'DROP TABLE mongo_posts' - execute 'DROP TABLE mongo_aspect_memberships' - execute 'DROP TABLE mongo_aspects' - end -end diff --git a/db/migrate/20110119060243_add_index_to_post_visibilities.rb b/db/migrate/20110119060243_add_index_to_post_visibilities.rb deleted file mode 100644 index a2e682941..000000000 --- a/db/migrate/20110119060243_add_index_to_post_visibilities.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddIndexToPostVisibilities < ActiveRecord::Migration - def self.up - add_index :post_visibilities, [:aspect_id, :post_id] - end - - def self.down - remove_index :post_visibilities, [:aspect_id, :post_id] - end -end diff --git a/db/migrate/20110119221746_add_indicies.rb b/db/migrate/20110119221746_add_indicies.rb deleted file mode 100644 index 13fe89a22..000000000 --- a/db/migrate/20110119221746_add_indicies.rb +++ /dev/null @@ -1,29 +0,0 @@ -class AddIndicies < ActiveRecord::Migration - def self.up - add_index :comments, :person_id - - add_index :invitations, :recipient_id - add_index :invitations, :aspect_id - - add_index :notifications, :target_id - add_index :notifications, :recipient_id - - add_index :posts, :status_message_id - add_index :posts, [:status_message_id, :pending] - add_index :posts, [:type, :pending, :id] - end - - def self.down - remove_index :comments, :person_id - - remove_index :invitations, :recipient_id - remove_index :invitations, :aspect_id - - remove_index :notifications, :target_id - remove_index :notifications, :recipient_id - - remove_index :posts, :status_message_id - remove_index :posts, [:status_message_id, :pending] - remove_index :posts, [:type, :pending, :id] - end -end diff --git a/db/migrate/20110120181553_create_statistics.rb b/db/migrate/20110120181553_create_statistics.rb deleted file mode 100644 index bf0fe9910..000000000 --- a/db/migrate/20110120181553_create_statistics.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateStatistics < ActiveRecord::Migration - def self.up - create_table :statistics do |t| - t.integer :average - t.string :type - t.datetime :time - - t.timestamps - end - end - - def self.down - drop_table :statistcs - end -end diff --git a/db/migrate/20110120182100_create_data_points.rb b/db/migrate/20110120182100_create_data_points.rb deleted file mode 100644 index d12351bed..000000000 --- a/db/migrate/20110120182100_create_data_points.rb +++ /dev/null @@ -1,17 +0,0 @@ -class CreateDataPoints < ActiveRecord::Migration - def self.up - create_table :data_points do |t| - t.string :key - t.integer :value - t.integer :statistic_id - - t.timestamps - end - add_index :data_points, :statistic_id - end - - def self.down - remove_index :data_points, :statistic_id - drop_table :data_points - end -end diff --git a/db/migrate/20110123210746_alter_string_columns.rb b/db/migrate/20110123210746_alter_string_columns.rb deleted file mode 100644 index 895c98438..000000000 --- a/db/migrate/20110123210746_alter_string_columns.rb +++ /dev/null @@ -1,37 +0,0 @@ -class AlterStringColumns < ActiveRecord::Migration - # This alters the tables to avoid a mysql bug - # See http://bugs.joindiaspora.com/issues/835 - def self.up - remove_index :profiles, :column => [:first_name, :searchable] - remove_index :profiles, :column => [:last_name, :searchable] - remove_index :profiles, :column => [:first_name, :last_name, :searchable] - change_column(:profiles, :first_name, :string, :limit => 127) - change_column(:profiles, :last_name, :string, :limit => 127) - add_index :profiles, [:first_name, :searchable] - add_index :profiles, [:last_name, :searchable] - add_index :profiles, [:first_name, :last_name, :searchable] - - remove_index :mongo_notifications, :column => [:target_type, :target_mongo_id] - change_column(:mongo_notifications, :target_type, :string, :limit => 127) - change_column(:mongo_notifications, :target_mongo_id, :string, :limit => 127) - add_index :mongo_notifications, [:target_type, :target_mongo_id] - - remove_index :mongo_profiles, :column => [:first_name, :searchable] - remove_index :mongo_profiles, :column => [:last_name, :searchable] - remove_index :mongo_profiles, :column => [:first_name, :last_name, :searchable] - change_column(:mongo_profiles, :first_name, :string, :limit => 127) - change_column(:mongo_profiles, :last_name, :string, :limit => 127) - add_index :mongo_profiles, [:first_name, :searchable] - add_index :mongo_profiles, [:last_name, :searchable] - add_index :mongo_profiles, [:first_name, :last_name, :searchable] - - remove_index :mongo_requests, :column => :sender_mongo_id - remove_index :mongo_requests, :column => :recipient_mongo_id - remove_index :mongo_requests, :column => [:sender_mongo_id, :recipient_mongo_id] - change_column(:mongo_requests, :sender_mongo_id, :string, :limit => 127) - change_column(:mongo_requests, :recipient_mongo_id, :string, :limit => 127) - add_index :mongo_requests, :sender_mongo_id - add_index :mongo_requests, :recipient_mongo_id - add_index :mongo_requests, [:sender_mongo_id, :recipient_mongo_id], :unique => true - end -end diff --git a/db/migrate/20110125190034_unique_index_on_profile.rb b/db/migrate/20110125190034_unique_index_on_profile.rb deleted file mode 100644 index de27e44d3..000000000 --- a/db/migrate/20110125190034_unique_index_on_profile.rb +++ /dev/null @@ -1,37 +0,0 @@ -class UniqueIndexOnProfile < ActiveRecord::Migration - class Profile < ActiveRecord::Base; end - def self.up - if Profile.count > 0 - conn = ActiveRecord::Base.connection - columns = conn.columns("profiles").map{|c| c.name} - ["id", "created_at", "updated_at"].each{|n| columns.delete(n)} - - sql = <<-SQL - SELECT profiles.person_id FROM profiles - GROUP BY #{columns.join(',')} - HAVING COUNT(*)>1 AND profiles.person_id IS NOT NULL; - SQL - result = conn.execute(sql) - duplicate_person_ids = result.to_a.flatten - - undesired_profile_ids = [] - duplicate_person_ids.each do |person_id| - profile_ids = conn.execute(" - SELECT profiles.id FROM profiles - WHERE profiles.person_id = #{person_id};").to_a.flatten - profile_ids.pop - undesired_profile_ids.concat(profile_ids) - end - conn.execute("DELETE FROM profiles - WHERE profiles.id IN (#{undesired_profile_ids.join(",")});") unless undesired_profile_ids.empty? - end - - remove_index :profiles, :person_id - add_index :profiles, :person_id, :unique => true - end - - def self.down - remove_index :profiles, :person_id - add_index :profiles, :person_id - end -end diff --git a/db/migrate/20110126015407_add_invitation_service_and_invitation_identifier_to_user.rb b/db/migrate/20110126015407_add_invitation_service_and_invitation_identifier_to_user.rb deleted file mode 100644 index f3017f3be..000000000 --- a/db/migrate/20110126015407_add_invitation_service_and_invitation_identifier_to_user.rb +++ /dev/null @@ -1,13 +0,0 @@ -class AddInvitationServiceAndInvitationIdentifierToUser < ActiveRecord::Migration - def self.up - add_column(:users, :invitation_service, :string) - add_column(:users, :invitation_identifier, :string) - - execute("UPDATE users SET invitation_service='email', invitation_identifier= email WHERE invitation_token IS NOT NULL;") - end - - def self.down - remove_column(:users, :invitation_service, :string) - remove_column(:users, :invitation_identifier, :string) - end -end diff --git a/db/migrate/20110126200714_add_contacts_visible.rb b/db/migrate/20110126200714_add_contacts_visible.rb deleted file mode 100644 index b75d52329..000000000 --- a/db/migrate/20110126200714_add_contacts_visible.rb +++ /dev/null @@ -1,17 +0,0 @@ -class AddContactsVisible < ActiveRecord::Migration - def self.up - add_column :aspects, :contacts_visible, :boolean, :default => true, :null => false - add_index :aspects, [:user_id, :contacts_visible] - - ActiveRecord::Base.connection.execute <<-SQL - UPDATE aspects - SET contacts_visible = false - WHERE contacts_visible IS NULL - SQL - end - - def self.down - remove_index :aspects, [:user_id, :contacts_visible] - remove_column :aspects, :contacts_visible - end -end diff --git a/db/migrate/20110126225202_remove_unique_index_on_email_on_users.rb b/db/migrate/20110126225202_remove_unique_index_on_email_on_users.rb deleted file mode 100644 index 28f620683..000000000 --- a/db/migrate/20110126225202_remove_unique_index_on_email_on_users.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RemoveUniqueIndexOnEmailOnUsers < ActiveRecord::Migration - def self.up - remove_index :users, :email - add_index :users, :email - end - - def self.down - remove_index :users, :email - add_index :users, :email, :unique => true - end -end diff --git a/db/migrate/20110126232040_add_unique_index_on_invitation_service_and_invitation_identifier_to_users.rb b/db/migrate/20110126232040_add_unique_index_on_invitation_service_and_invitation_identifier_to_users.rb deleted file mode 100644 index 8445447b2..000000000 --- a/db/migrate/20110126232040_add_unique_index_on_invitation_service_and_invitation_identifier_to_users.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddUniqueIndexOnInvitationServiceAndInvitationIdentifierToUsers < ActiveRecord::Migration - def self.up - change_column(:users, :invitation_service, :string, :limit => 127) - change_column(:users, :invitation_identifier, :string, :limit => 127) - add_index(:users, [:invitation_service, :invitation_identifier], :unique => true) - end - - def self.down - remove_index(:users, [:invitation_service, :invitation_identifier]) - end -end diff --git a/db/migrate/20110127000931_drop_extra_columns.rb b/db/migrate/20110127000931_drop_extra_columns.rb deleted file mode 100644 index e228ca96b..000000000 --- a/db/migrate/20110127000931_drop_extra_columns.rb +++ /dev/null @@ -1,10 +0,0 @@ -class DropExtraColumns < ActiveRecord::Migration - def self.up - remove_column :services, :provider - remove_column :statistics, :type - end - - def self.down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20110127000953_make_fields_not_null.rb b/db/migrate/20110127000953_make_fields_not_null.rb deleted file mode 100644 index 6a4fe84e5..000000000 --- a/db/migrate/20110127000953_make_fields_not_null.rb +++ /dev/null @@ -1,39 +0,0 @@ -class MakeFieldsNotNull < ActiveRecord::Migration - def self.non_nullable_fields - fields = { - :aspect_memberships => [:aspect_id, :contact_id], - :aspects => [:user_id, :name], - :comments => [:text, :post_id, :person_id, :guid], - :contacts => [:user_id, :person_id, :pending], - :data_points => [:key, :value, :statistic_id], - :invitations => [:recipient_id, :sender_id], - :notifications => [:recipient_id, :actor_id, :action, :unread], - :people => [:guid, :url, :diaspora_handle, :serialized_public_key], - :post_visibilities => [:aspect_id, :post_id], - :posts => [:person_id, :public, :guid, :pending, :type], - :profiles => [:person_id, :searchable], - :requests => [:sender_id, :recipient_id], - :services => [:type, :user_id], - :statistics => [:time], - :users => [:getting_started, :invites, :disable_mail] - } - end - - def self.up - remove_index(:profiles, :person_id) - non_nullable_fields.each_pair do |table, columns| - columns.each do |column| - change_column_null(table, column, false) - end - end - add_index :profiles, :person_id - end - - def self.down - non_nullable_fields.each_pair do |table, columns| - columns.each do |column| - change_column_null(table, column, true) - end - end - end -end diff --git a/db/migrate/20110130072907_notification_multiple_people.rb b/db/migrate/20110130072907_notification_multiple_people.rb deleted file mode 100644 index 883eb310f..000000000 --- a/db/migrate/20110130072907_notification_multiple_people.rb +++ /dev/null @@ -1,70 +0,0 @@ -class NotificationMultiplePeople < ActiveRecord::Migration - def self.up - create_table :notification_actors do |t| - t.integer :notification_id - t.integer :person_id - t.timestamps - end - - add_index :notification_actors, :notification_id - add_index :notification_actors, [:notification_id, :person_id] , :unique => true - add_index :notification_actors, :person_id ## if i am not mistaken we don't need this one because we won't query person.notifications - - note_ids = execute('select id from notifications').to_a - unless note_ids.empty? - #make the notification actors table - execute "INSERT INTO notification_actors (notification_id, person_id) " + - " SELECT id , actor_id " + - " FROM notifications" - - #update the notifications to reference the post - execute "UPDATE notifications, comments " + - "SET notifications.target_id = comments.post_id, " + - "target_type = 'Post' " + - "WHERE (notifications.target_id = comments.id " + - "AND (notifications.action = 'comment_on_post' " + - "OR notifications.action = 'also_commented'))" - - #select all the notifications to keep - execute "CREATE TEMPORARY TABLE keep_table " + - "(SELECT id as keep_id, actor_id , target_type , target_id , recipient_id , action " + - "FROM notifications WHERE action = 'comment_on_post' OR action = 'also_commented' " + - "GROUP BY target_type , target_id , recipient_id , action) " - - #get a table of with ids of the notifications that need to be deleted and with the ones that need - #to replace them - execute "CREATE TEMPORARY TABLE keep_delete " + - "( SELECT n1.keep_id, n2.id as delete_id, " + - "n2.actor_id, n1.target_type, n1.target_id, n1.recipient_id, n1.action " + - "FROM keep_table n1, notifications n2 " + - "WHERE n1.keep_id != n2.id " + - "AND n1.actor_id != n2.actor_id "+ - "AND n1.target_type = n2.target_type AND n1.target_id = n2.target_id " + - "AND n1.recipient_id = n2.recipient_id AND n1.action = n2.action " + - "AND (n1.action = 'comment_on_post' OR n1.action = 'also_commented') "+ - "GROUP BY n2.actor_id , n2.target_type , n2.target_id , n2.recipient_id , n2.action)" - - #have the notifications actors reference the notifications that need to be kept - execute "UPDATE notification_actors, keep_delete "+ - "SET notification_actors.notification_id = keep_delete.keep_id "+ - "WHERE notification_actors.notification_id = keep_delete.delete_id" - - #delete all the notifications that need to be deleted - execute "DELETE notifications.* " + - "FROM notifications, keep_delete " + - "WHERE notifications.id != keep_delete.keep_id AND "+ - "notifications.target_type = keep_delete.target_type AND "+ - "notifications.target_id = keep_delete.target_id AND "+ - "notifications.recipient_id = keep_delete.recipient_id AND "+ - "notifications.action = keep_delete.action" - end - - - remove_column :notifications, :actor_id - remove_column :notifications, :mongo_id - end - - def self.down - raise ActiveRecord::IrreversibleMigration.new - end -end diff --git a/db/migrate/20110202015222_add_open_to_aspects.rb b/db/migrate/20110202015222_add_open_to_aspects.rb deleted file mode 100644 index cf5905c3d..000000000 --- a/db/migrate/20110202015222_add_open_to_aspects.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddOpenToAspects < ActiveRecord::Migration - def self.up - add_column(:aspects, :open, :boolean, :default => false) - end - - def self.down - remove_column(:aspects, :open) - end -end diff --git a/db/migrate/20110209204702_create_mentions.rb b/db/migrate/20110209204702_create_mentions.rb deleted file mode 100644 index d4bbbf39e..000000000 --- a/db/migrate/20110209204702_create_mentions.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateMentions < ActiveRecord::Migration - def self.up - create_table :mentions do |t| - t.integer :post_id, :null => false - t.integer :person_id, :null => false - end - add_index :mentions, :post_id - add_index :mentions, :person_id - add_index :mentions, [:person_id, :post_id], :unique => true - end - - def self.down - drop_table :mentions - end -end diff --git a/db/migrate/20110211021926_fix_target_on_notification.rb b/db/migrate/20110211021926_fix_target_on_notification.rb deleted file mode 100644 index e79ea402b..000000000 --- a/db/migrate/20110211021926_fix_target_on_notification.rb +++ /dev/null @@ -1,29 +0,0 @@ -class FixTargetOnNotification < ActiveRecord::Migration - def self.up - note_ids = execute('select id from notifications').to_a - unless note_ids.empty? - execute("UPDATE notifications " + - "SET target_type='Post' " + - "WHERE action = 'comment_on_post' OR action = 'also_commented'") - - execute("UPDATE notifications " + - "SET target_type='Request' " + - "WHERE action = 'new_request' OR action = 'request_accepted'") - - execute("UPDATE notifications " + - "SET target_type='Mention' " + - "WHERE action = 'mentioned'") - - execute("create temporary table t1 "+ - "(select notifications.id as n_id " + - "from notifications LEFT JOIN mentions "+ - "ON notifications.target_id = mentions.id "+ - "WHERE notifications.action = 'mentioned' AND mentions.id IS NULL)") - - execute("DELETE notifications.* FROM notifications, t1 WHERE notifications.id = t1.n_id") - end - end - - def self.down - end -end diff --git a/db/migrate/20110211204804_unique_index_post_visibilities.rb b/db/migrate/20110211204804_unique_index_post_visibilities.rb deleted file mode 100644 index 9c61da28a..000000000 --- a/db/migrate/20110211204804_unique_index_post_visibilities.rb +++ /dev/null @@ -1,39 +0,0 @@ -class UniqueIndexPostVisibilities < ActiveRecord::Migration - def self.up - visibility_ids = execute('select id from post_visibilities').to_a - unless visibility_ids.empty? - sql = <<-SQL - SELECT `post_visibilities`.post_id, `post_visibilities`.aspect_id FROM `post_visibilities` - GROUP BY post_id, aspect_id - HAVING COUNT(*)>1; - SQL - - result = execute(sql) - dup_pvs = result.to_a - undesired_ids = [] - - dup_pvs.each do |arr| - post_id, aspect_id = arr - pv_ids = execute(" - SELECT `post_visibilities`.id FROM `post_visibilities` - WHERE `post_visibilities`.post_id = #{post_id} - AND `post_visibilities`.aspect_id = #{aspect_id};" - ).to_a.flatten! - pv_ids.pop - undesired_ids.concat(pv_ids) - end - execute("DELETE FROM `post_visibilities` WHERE `post_visibilities`.id IN (#{undesired_ids.join(",")});") unless undesired_ids.empty? - - new_result = execute(sql) - raise "Not all violating visibilities deleted, try migrating again if this is the first occurence" unless new_result.to_a.empty? - end - - remove_index :post_visibilities, [:aspect_id, :post_id] - add_index :post_visibilities, [:aspect_id, :post_id], :unique => true - end - - def self.down - remove_index :post_visibilities, [:aspect_id, :post_id] - add_index :post_visibilities, [:aspect_id, :post_id] - end -end diff --git a/db/migrate/20110213052742_add_more_indicies.rb b/db/migrate/20110213052742_add_more_indicies.rb deleted file mode 100644 index 5cd3666b1..000000000 --- a/db/migrate/20110213052742_add_more_indicies.rb +++ /dev/null @@ -1,19 +0,0 @@ -class AddMoreIndicies < ActiveRecord::Migration - def self.up - #For making validates_uniqueness_of, :case_sensitive => false, fast - add_index :users, [:id, :username], :unique => true - add_index :users, [:id, :email] - add_index :people, [:id, :diaspora_handle], :unique => true - - #For the includes of photos in the stream - add_index :posts, [:id, :type] - end - - def self.down - remove_index :users, [:id, :username] - remove_index :users, [:id, :email] - remove_index :people, [:id, :diaspora_handle] - - remove_index :posts, [:id, :type] - end -end diff --git a/db/migrate/20110217044519_undo_adding_indicies.rb b/db/migrate/20110217044519_undo_adding_indicies.rb deleted file mode 100644 index a5a8c7ccf..000000000 --- a/db/migrate/20110217044519_undo_adding_indicies.rb +++ /dev/null @@ -1,10 +0,0 @@ -class UndoAddingIndicies < ActiveRecord::Migration - require Rails.root.join('db', 'migrate', '20110213052742_add_more_indicies') - def self.up - AddMoreIndicies.down - end - - def self.down - AddMoreIndicies.up - end -end diff --git a/db/migrate/20110225190919_create_conversations_and_messages_and_visibilities.rb b/db/migrate/20110225190919_create_conversations_and_messages_and_visibilities.rb deleted file mode 100644 index b9c7b9bf9..000000000 --- a/db/migrate/20110225190919_create_conversations_and_messages_and_visibilities.rb +++ /dev/null @@ -1,39 +0,0 @@ -class CreateConversationsAndMessagesAndVisibilities < ActiveRecord::Migration - def self.up - create_table :messages do |t| - t.integer :conversation_id, :null => false - t.integer :author_id, :null => false - t.string :guid, :null => false - t.text :text, :null => false - - t.timestamps - end - - create_table :conversation_visibilities do |t| - t.integer :conversation_id, :null => false - t.integer :person_id, :null => false - t.integer :unread, :null => false, :default => 0 - - t.timestamps - end - - create_table :conversations do |t| - t.string :subject - t.string :guid, :null => false - t.integer :author_id, :null => false - - t.timestamps - end - - add_index :conversation_visibilities, :person_id - add_index :conversation_visibilities, :conversation_id - add_index :conversation_visibilities, [:conversation_id, :person_id], :unique => true, :name => 'index_conversation_visibilities_usefully' - add_index :messages, :author_id - end - - def self.down - drop_table :messages - drop_table :conversations - drop_table :conversation_visibilities - end -end diff --git a/db/migrate/20110228180709_notification_subclasses.rb b/db/migrate/20110228180709_notification_subclasses.rb deleted file mode 100644 index 18d210ac1..000000000 --- a/db/migrate/20110228180709_notification_subclasses.rb +++ /dev/null @@ -1,31 +0,0 @@ -class NotificationSubclasses < ActiveRecord::Migration - def self.up - add_column :notifications, :type, :string, :null => :false - {:new_request => 'Notifications::NewRequest', - :request_accepted => 'Notifications::RequestAccepted', - :comment_on_post => 'Notifications::CommentOnPost', - :also_commented => 'Notifications::AlsoCommented', - :mentioned => 'Notifications::Mentioned' - }.each_pair do |key, value| - execute("UPDATE notifications - set type = '#{value}' - where action = '#{key.to_s}'") - end - remove_column :notifications, :action - end - - def self.down - add_column :notifications, :action, :string - {:new_request => 'Notifications::NewRequest', - :request_accepted => 'Notifications::RequestAccepted', - :comment_on_post => 'Notifications::CommentOnPost', - :also_commented => 'Notifications::AlsoCommented', - :mentioned => 'Notifications::Mentioned' - }.each_pair do |key, value| - execute("UPDATE notifications - set action = '#{key.to_s}' - where type = '#{value}'") - end - remove_column :notifications, :type - end -end diff --git a/db/migrate/20110228201109_foreign_key_constraints.rb b/db/migrate/20110228201109_foreign_key_constraints.rb deleted file mode 100644 index 9904e1daa..000000000 --- a/db/migrate/20110228201109_foreign_key_constraints.rb +++ /dev/null @@ -1,63 +0,0 @@ -class ForeignKeyConstraints < ActiveRecord::Migration - def self.disconnected_records dependent_table, dep_column, parent_table - result = execute < :delete) - add_foreign_key(:aspect_memberships, :aspects, :dependent => :restrict) - - add_foreign_key(:comments, :posts, :dependent => :delete) - add_foreign_key(:comments, :people, :dependent => :delete) - - add_foreign_key(:posts, :people, :dependent => :delete) - - add_foreign_key(:contacts, :people, :dependent => :delete) - - add_foreign_key(:invitations, :users, :dependent => :delete, :column => :sender_id) - add_foreign_key(:invitations, :users, :dependent => :delete, :column => :recipient_id) - - add_foreign_key(:notification_actors, :notifications, :dependent => :delete) - - add_foreign_key(:profiles, :people, :dependent => :delete) - - add_foreign_key(:requests, :people, :dependent => :delete, :column => :sender_id) - add_foreign_key(:requests, :people, :dependent => :delete, :column => :recipient_id) - - add_foreign_key(:services, :users, :dependent => :delete) - end - - def self.down - end -end diff --git a/db/migrate/20110228220810_rename_post_to_parent_and_creator_to_author.rb b/db/migrate/20110228220810_rename_post_to_parent_and_creator_to_author.rb deleted file mode 100644 index ef43ad57a..000000000 --- a/db/migrate/20110228220810_rename_post_to_parent_and_creator_to_author.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RenamePostToParentAndCreatorToAuthor < ActiveRecord::Migration - def self.up - rename_column :comments, :creator_signature, :author_signature - rename_column :comments, :post_creator_signature, :parent_author_signature - end - - def self.down - rename_column :comments, :author_signature, :creator_signature - rename_column :comments, :parent_author_signature, :post_creator_signature - end -end diff --git a/db/migrate/20110228233419_add_signatures_to_message.rb b/db/migrate/20110228233419_add_signatures_to_message.rb deleted file mode 100644 index e6c72e761..000000000 --- a/db/migrate/20110228233419_add_signatures_to_message.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddSignaturesToMessage < ActiveRecord::Migration - def self.up - add_column(:messages, :author_signature, :text) - add_column(:messages, :parent_author_signature, :text) - end - - def self.down - remove_column(:messages, :author_signature) - remove_column(:messages, :parent_author_signature) - end -end diff --git a/db/migrate/20110301014507_rename_person_to_author.rb b/db/migrate/20110301014507_rename_person_to_author.rb deleted file mode 100644 index 123392445..000000000 --- a/db/migrate/20110301014507_rename_person_to_author.rb +++ /dev/null @@ -1,19 +0,0 @@ -class RenamePersonToAuthor < ActiveRecord::Migration - def self.up - remove_foreign_key(:comments, :people) - remove_foreign_key(:posts, :people) - rename_column :comments, :person_id, :author_id - rename_column :posts, :person_id, :author_id - add_foreign_key(:comments, :people, :column => :author_id, :dependent => :delete) - add_foreign_key(:posts, :people, :column => :author_id, :dependent => :delete) - end - - def self.down - remove_foreign_key(:comments, :people, :column => :author_id) - remove_foreign_key(:posts, :people, :column => :author_id) - rename_column :comments, :author_id, :person_id - rename_column :posts, :author_id, :person_id - add_foreign_key(:comments, :people, :dependent => :delete) - add_foreign_key(:posts, :people, :dependent => :delete) - end -end diff --git a/db/migrate/20110301202619_drop_statistics.rb b/db/migrate/20110301202619_drop_statistics.rb deleted file mode 100644 index 15ec9e366..000000000 --- a/db/migrate/20110301202619_drop_statistics.rb +++ /dev/null @@ -1,9 +0,0 @@ -class DropStatistics < ActiveRecord::Migration - def self.up - execute 'DROP TABLE statistics' - execute 'DROP TABLE data_points' - end - - def self.down - end -end diff --git a/db/migrate/20110311000150_acts_as_taggable_on_migration.rb b/db/migrate/20110311000150_acts_as_taggable_on_migration.rb deleted file mode 100644 index 7c07fef22..000000000 --- a/db/migrate/20110311000150_acts_as_taggable_on_migration.rb +++ /dev/null @@ -1,28 +0,0 @@ -class ActsAsTaggableOnMigration < ActiveRecord::Migration - def self.up - create_table :tags do |t| - t.string :name - end - - create_table :taggings do |t| - t.references :tag - - # You should make sure that the column created is - # long enough to store the required class names. - t.references :taggable, :polymorphic => {:limit => 127} - t.references :tagger, :polymorphic => {:limit => 127} - - t.string :context, :limit => 127 - - t.datetime :created_at - end - - add_index :taggings, :tag_id - add_index :taggings, [:taggable_id, :taggable_type, :context] - end - - def self.down - drop_table :taggings - drop_table :tags - end -end diff --git a/db/migrate/20110311183826_create_user_preferences.rb b/db/migrate/20110311183826_create_user_preferences.rb deleted file mode 100644 index a8c942693..000000000 --- a/db/migrate/20110311183826_create_user_preferences.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateUserPreferences < ActiveRecord::Migration - def self.up - create_table :user_preferences do |t| - t.string :email_type - t.integer :user_id - - t.timestamps - end - end - - def self.down - drop_table :user_preferences - end -end diff --git a/db/migrate/20110311220249_downcase_tags.rb b/db/migrate/20110311220249_downcase_tags.rb deleted file mode 100644 index 0a85f528d..000000000 --- a/db/migrate/20110311220249_downcase_tags.rb +++ /dev/null @@ -1,26 +0,0 @@ -class DowncaseTags < ActiveRecord::Migration - def self.consolidate_tags_with_name(name) - tags = execute("SELECT * FROM tags WHERE tags.name = '#{name}';").to_a - keep_tag = tags.pop - tags.each do |bad_tag| - execute("UPDATE taggings - SET taggings.tag_id = #{keep_tag.first} - WHERE taggings.tag_id = #{bad_tag.first};") - execute("DELETE FROM tags WHERE tags.id = #{bad_tag.first};") - end - end - def self.up - execute('UPDATE tags - SET name = LOWER(tags.name);') - - names_with_duplicates = execute('SELECT name FROM tags - GROUP BY name - HAVING COUNT(*)>1;').to_a.flatten! - names_with_duplicates.each do |name| - consolidate_tags_with_name(name) - end unless names_with_duplicates.blank? - end - - def self.down - end -end diff --git a/db/migrate/20110313015438_rename_text_fields.rb b/db/migrate/20110313015438_rename_text_fields.rb deleted file mode 100644 index 07019a5da..000000000 --- a/db/migrate/20110313015438_rename_text_fields.rb +++ /dev/null @@ -1,12 +0,0 @@ -class RenameTextFields < ActiveRecord::Migration - def self.up - rename_column :posts, :message, :text - execute("UPDATE posts - SET text = posts.caption - WHERE posts.caption IS NOT NULL;") - remove_column :posts, :caption - end - - def self.down - end -end diff --git a/db/migrate/20110314043119_drop_import_tables.rb b/db/migrate/20110314043119_drop_import_tables.rb deleted file mode 100644 index c5dea3567..000000000 --- a/db/migrate/20110314043119_drop_import_tables.rb +++ /dev/null @@ -1,10 +0,0 @@ -require Rails.root.join('db', 'migrate', '20110105051803_create_import_tables') -class DropImportTables < ActiveRecord::Migration - def self.up - CreateImportTables.down - end - - def self.down - CreateImportTables.up - end -end diff --git a/db/migrate/20110317222802_guid_is_unique.rb b/db/migrate/20110317222802_guid_is_unique.rb deleted file mode 100644 index ccda882ff..000000000 --- a/db/migrate/20110317222802_guid_is_unique.rb +++ /dev/null @@ -1,36 +0,0 @@ -class GuidIsUnique < ActiveRecord::Migration - def self.consolidate_post(guid) - post_ids = execute("select posts.id from posts where posts.guid = '#{guid}'").to_a.flatten! - keep_id = post_ids.pop - execute("UPDATE comments - SET comments.post_id = #{keep_id} - WHERE comments.post_id IN (#{post_ids.join(',')})") - - execute("UPDATE posts - SET posts.status_message_id = #{keep_id} - WHERE posts.status_message_id IN (#{post_ids.join(',')})") - - execute("DELETE FROM post_visibilities WHERE post_visibilities.post_id IN (#{post_ids.join(',')})") - execute("DELETE FROM mentions WHERE mentions.post_id IN (#{post_ids.join(',')})") - execute("DELETE FROM posts WHERE posts.id IN (#{post_ids.join(',')})") - end - def self.up - sql = <<-SQL - SELECT posts.guid FROM posts - GROUP BY posts.guid - HAVING COUNT(*)>1; - SQL - duplicated_guids = execute(sql).to_a.flatten! - - duplicated_guids.each do |guid| - consolidate_post(guid) - end if duplicated_guids - remove_index :posts, :guid - add_index :posts, :guid, :unique => true - end - - def self.down - remove_index :posts, :column => :guid - add_index :posts, :guid - end -end diff --git a/db/migrate/20110318000734_create_service_users.rb b/db/migrate/20110318000734_create_service_users.rb deleted file mode 100644 index 7ac30e697..000000000 --- a/db/migrate/20110318000734_create_service_users.rb +++ /dev/null @@ -1,23 +0,0 @@ -class CreateServiceUsers < ActiveRecord::Migration - def self.up - create_table :service_users do |t| - t.string :uid, :null => false - t.string :name, :null => false - t.string :photo_url, :null => false - t.integer :service_id, :null => false - t.integer :person_id - t.integer :contact_id - t.integer :request_id - t.integer :invitation_id - - t.timestamps - end - - add_index :service_users, :service_id - add_index :service_users, [:uid, :service_id], :unique => true - end - - def self.down - drop_table :service_users - end -end diff --git a/db/migrate/20110318012008_delete_disconnected_notifications.rb b/db/migrate/20110318012008_delete_disconnected_notifications.rb deleted file mode 100644 index 71579127e..000000000 --- a/db/migrate/20110318012008_delete_disconnected_notifications.rb +++ /dev/null @@ -1,11 +0,0 @@ -class DeleteDisconnectedNotifications < ActiveRecord::Migration - def self.up - result = execute("SELECT notifications.id FROM notifications - LEFT OUTER JOIN posts ON posts.id = notifications.target_id - WHERE posts.id IS NULL AND notifications.target_id IS NOT NULL AND notifications.target_type = 'Post'").to_a.flatten! - execute("DELETE FROM notifications WHERE notifications.id IN (#{result.join(',')})") if result - end - - def self.down - end -end diff --git a/db/migrate/20110319005509_add_processed_to_post.rb b/db/migrate/20110319005509_add_processed_to_post.rb deleted file mode 100644 index 2d63adb38..000000000 --- a/db/migrate/20110319005509_add_processed_to_post.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddProcessedToPost < ActiveRecord::Migration - def self.up - add_column(:posts, :processed, :boolean, :default => true) - end - - def self.down - remove_column(:posts, :processed) - end -end diff --git a/db/migrate/20110319172136_add_likes.rb b/db/migrate/20110319172136_add_likes.rb deleted file mode 100644 index 096636f5d..000000000 --- a/db/migrate/20110319172136_add_likes.rb +++ /dev/null @@ -1,26 +0,0 @@ -class AddLikes < ActiveRecord::Migration - def self.up - result = execute("SELECT version FROM schema_migrations WHERE version = '201110319172136'") - if result.count > 0 - execute("DELETE FROM schema_migrations WHERE version = '201110319172136'") - else - create_table :likes do |t| - t.boolean :positive, :default => true - t.integer :post_id - t.integer :author_id - t.string :guid - t.text :author_signature - t.text :parent_author_signature - t.timestamps - end - add_index :likes, :guid, :unique => true - add_index :likes, :post_id - add_foreign_key(:likes, :posts) - add_foreign_key(:likes, :people, :column => :author_id) - end - end - - def self.down - drop_table :likes - end -end diff --git a/db/migrate/20110321205715_unprocessed_image_uploader.rb b/db/migrate/20110321205715_unprocessed_image_uploader.rb deleted file mode 100644 index 8cf85d7db..000000000 --- a/db/migrate/20110321205715_unprocessed_image_uploader.rb +++ /dev/null @@ -1,14 +0,0 @@ -require Rails.root.join('db', 'migrate', '20110319005509_add_processed_to_post') -class UnprocessedImageUploader < ActiveRecord::Migration - def self.up - AddProcessedToPost.down - rename_column :posts, :image, :processed_image - add_column :posts, :unprocessed_image, :string - end - - def self.down - remove_column :posts, :unprocessed_image - rename_column :posts, :processed_image, :image - AddProcessedToPost.up - end -end diff --git a/db/migrate/20110323213655_add_location_to_profile.rb b/db/migrate/20110323213655_add_location_to_profile.rb deleted file mode 100644 index 1c3776212..000000000 --- a/db/migrate/20110323213655_add_location_to_profile.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddLocationToProfile < ActiveRecord::Migration - def self.up - add_column :profiles, :location, :string - end - - def self.down - remove_column :profiles, :location - end -end diff --git a/db/migrate/20110328175936_add_hidden_to_post_visibilities.rb b/db/migrate/20110328175936_add_hidden_to_post_visibilities.rb deleted file mode 100644 index d663001be..000000000 --- a/db/migrate/20110328175936_add_hidden_to_post_visibilities.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddHiddenToPostVisibilities < ActiveRecord::Migration - def self.up - add_column :post_visibilities, :hidden, :boolean, :default => false, :null => false - add_index :post_visibilities, :hidden - end - - def self.down - remove_index :post_visibilities, :hidden - remove_column :post_visibilities, :hidden - end -end diff --git a/db/migrate/20110328202414_post_visibilities_on_contacts.rb b/db/migrate/20110328202414_post_visibilities_on_contacts.rb deleted file mode 100644 index 1445f3a9f..000000000 --- a/db/migrate/20110328202414_post_visibilities_on_contacts.rb +++ /dev/null @@ -1,97 +0,0 @@ -class PostVisibilitiesOnContacts < ActiveRecord::Migration - class PostVisibility < ActiveRecord::Base; end - def self.move_author_pvs_to_aspect_pvs - where_clause = <1; -SQL - duplicate_rows.each do |row| - count = row.first - contact_id = row[1] - post_id = row.last - - execute < false - t.integer :aspect_id, :null => false - t.timestamps - end - add_index :aspect_visibilities, [:post_id, :aspect_id], :unique => true - add_index :aspect_visibilities, [:aspect_id] - add_index :aspect_visibilities, [:post_id] - add_foreign_key :aspect_visibilities, :aspects, :dependent => :delete - add_foreign_key :aspect_visibilities, :posts, :dependent => :delete - - delete_disconnected_pvs if pv_count > 0 - - add_column :post_visibilities, :contact_id, :integer, :null => false - - move_author_pvs_to_aspect_pvs if pv_count > 0 - set_pv_contact_ids if pv_count > 0 - - delete_duplicate_pvs if pv_count > 0 - - remove_index :post_visibilities, [:aspect_id, :post_id] - remove_column :post_visibilities, :aspect_id - - add_index :post_visibilities, [:contact_id, :post_id], :unique => true - add_index :post_visibilities, [:contact_id] - add_foreign_key :post_visibilities, :contacts, :dependent => :delete - add_foreign_key :post_visibilities, :posts, :dependent => :delete - end - - def self.down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20110330175950_tag_uniqueness.rb b/db/migrate/20110330175950_tag_uniqueness.rb deleted file mode 100644 index bd4a4cd55..000000000 --- a/db/migrate/20110330175950_tag_uniqueness.rb +++ /dev/null @@ -1,24 +0,0 @@ -class TagUniqueness < ActiveRecord::Migration - def self.delete_duplicate_taggings - duplicate_rows = execute <1; -SQL - duplicate_rows.each do |row| - execute < true, :name => 'index_taggings_uniquely' - end - - def self.down - remove_index :taggings, :name => 'index_taggings_uniquely' - end -end diff --git a/db/migrate/20110330230206_pm_foreign_keys.rb b/db/migrate/20110330230206_pm_foreign_keys.rb deleted file mode 100644 index a9218eb83..000000000 --- a/db/migrate/20110330230206_pm_foreign_keys.rb +++ /dev/null @@ -1,53 +0,0 @@ -class PmForeignKeys < ActiveRecord::Migration - class Message < ActiveRecord::Base - end - - def self.delete_disconnected_cvs - execute < 0 - delete_disconnected_conversations - delete_disconnected_messages - delete_disconnected_cvs - end - - add_foreign_key :conversation_visibilities, :conversations, :dependent => :delete - add_foreign_key :conversation_visibilities, :people, :dependent => :delete - - add_foreign_key :messages, :conversations, :dependent => :delete - add_foreign_key :messages, :people, :column => :author_id, :dependent => :delete - - add_foreign_key :conversations, :people, :column => :author_id, :dependent => :delete - end - - def self.down - remove_foreign_key :conversation_visibilities, :conversations - remove_foreign_key :conversation_visibilities, :people - - remove_foreign_key :messages, :conversations - remove_foreign_key :messages, :column => :author_id - - remove_foreign_key :conversations, :column => :author_id - end -end diff --git a/db/migrate/20110331004720_add_hidden_indicies.rb b/db/migrate/20110331004720_add_hidden_indicies.rb deleted file mode 100644 index 3c9779646..000000000 --- a/db/migrate/20110331004720_add_hidden_indicies.rb +++ /dev/null @@ -1,12 +0,0 @@ -class AddHiddenIndicies < ActiveRecord::Migration - def self.up - remove_index :post_visibilities, :hidden - add_index :post_visibilities, [:post_id, :hidden, :contact_id], :unique => true - end - - - def self.down - remove_index :post_visibilities, :column => [:post_id, :hidden, :contact_id] - add_index :post_visibilities, :hidden - end -end diff --git a/db/migrate/20110405170101_fix_stream_queries.rb b/db/migrate/20110405170101_fix_stream_queries.rb deleted file mode 100644 index 4d5d2463f..000000000 --- a/db/migrate/20110405170101_fix_stream_queries.rb +++ /dev/null @@ -1,11 +0,0 @@ -class FixStreamQueries < ActiveRecord::Migration - def self.up - change_column :posts, :type, :string, :limit => 40 - remove_index :posts, :type - end - - def self.down - add_index :posts, :type - change_column :posts, :type, :string, :limit => 127 - end -end diff --git a/db/migrate/20110405171412_contact_remove_pending_add_sharing_and_receiving.rb b/db/migrate/20110405171412_contact_remove_pending_add_sharing_and_receiving.rb deleted file mode 100644 index 4a18d85ef..000000000 --- a/db/migrate/20110405171412_contact_remove_pending_add_sharing_and_receiving.rb +++ /dev/null @@ -1,61 +0,0 @@ -class ContactRemovePendingAddSharingAndReceiving < ActiveRecord::Migration - class Contact < ActiveRecord::Base; end - - def self.up - add_column :contacts, :sharing, :boolean, :default => false, :null => false - add_column :contacts, :receiving, :boolean, :default => false, :null => false - - if Contact.count > 0 - execute( < "contacts_person_id_fk", :dependent => :delete - - remove_column :contacts, :pending - - remove_foreign_key :aspect_memberships, :aspects - add_foreign_key :aspect_memberships, :aspects, :dependent => :delete - end - - def self.down - - remove_foreign_key "contacts", "people" - remove_index :contacts, :person_id - - add_column :contacts, :pending, :default => true, :null => false - add_index :contacts, [:user_id, :pending] - - add_index :contacts, [:person_id, :pending] - add_foreign_key "contacts", "people", :name => "contacts_person_id_fk", :dependent => :delete - - execute( < :recipient_id - remove_foreign_key :requests, :column => :sender_id - - remove_index :requests, :mongo_id - remove_index :requests, :recipient_id - remove_index :requests, [:sender_id, :recipient_id] - remove_index :requests, :sender_id - - execute 'DROP TABLE requests' - - execute( < 0 - end - - def self.down - create_table :requests, :force => true do |t| - t.integer :sender_id, :null => false - t.integer :recipient_id, :null => false - t.integer :aspect_id - t.datetime :created_at - t.datetime :updated_at - t.string :mongo_id - end - - add_index :requests, ["mongo_id"], :name => "index_requests_on_mongo_id" - add_index :requests, ["recipient_id"], :name => "index_requests_on_recipient_id" - add_index :requests, ["sender_id", "recipient_id"], :name => "index_requests_on_sender_id_and_recipient_id", :unique => true - add_index :requests, ["sender_id"], :name => "index_requests_on_sender_id" - - add_foreign_key :requests, :people, :column => "recipient_id", :dependent => :delete - add_foreign_key :requests, :people, :column => "sender_id", :dependent => :delete - end -end diff --git a/db/migrate/20110406203720_tag_name_uniqueness.rb b/db/migrate/20110406203720_tag_name_uniqueness.rb deleted file mode 100644 index 7b3ed72d5..000000000 --- a/db/migrate/20110406203720_tag_name_uniqueness.rb +++ /dev/null @@ -1,45 +0,0 @@ -class TagNameUniqueness < ActiveRecord::Migration - class Tag < ActiveRecord::Base; end - - def self.downcase_tags - execute < 1 -SQL - duplicate_rows.each do |row| - name = row.last - tag_ids = execute("SELECT tags.id FROM tags WHERE tags.name = '#{name}'").to_a.flatten! - id_to_keep = tag_ids.pop - execute < 0 - downcase_tags - consolidate_duplicate_tags - end - add_index :tags, :name, :unique => true - end - - def self.down - raise ActiveRecord::IrreversibleMigration.new - end -end diff --git a/db/migrate/20110421120744_downcase_usernames.rb b/db/migrate/20110421120744_downcase_usernames.rb deleted file mode 100644 index 34582eb63..000000000 --- a/db/migrate/20110421120744_downcase_usernames.rb +++ /dev/null @@ -1,15 +0,0 @@ -class DowncaseUsernames < ActiveRecord::Migration - class User < ActiveRecord::Base; end - - def self.up - execute < 0 - UPDATE users - SET users.username = LOWER(users.username) - WHERE users.username != LOWER(users.username) -SQL - end - - def self.down - raise ActiveRecord::IrreversibleMigration.new - end -end diff --git a/db/migrate/20110507212759_remove_type_null_notifications.rb b/db/migrate/20110507212759_remove_type_null_notifications.rb deleted file mode 100644 index e2e023f9f..000000000 --- a/db/migrate/20110507212759_remove_type_null_notifications.rb +++ /dev/null @@ -1,13 +0,0 @@ -class RemoveTypeNullNotifications < ActiveRecord::Migration - def self.up - execute < 0 - duplicated_emails = execute("SELECT LOWER(email) from users WHERE users.email != '' GROUP BY LOWER(email) HAVING COUNT(*) > 1").to_a - duplicated_emails.each do |email| - records = execute("SELECT users.id, users.username, users.created_at from users WHERE LOWER(users.email) = '#{email}'").to_a - with_username = records.select { |r| !r[1].blank? } - if with_username.length == 1 - execute("DELETE FROM users WHERE LOWER(users.email) = '#{email}' AND users.username IS NULL") - end - if with_username.length == 0 && !email.blank? - newest_record = records.sort_by{|r| r[2].to_i}.last - execute("DELETE FROM users WHERE LOWER(users.email) = '#{email}' AND users.id != #{newest_record[0]}") - end - end - execute < 0 - DELETE notifications.* FROM notifications - WHERE notifications.type = 'Notifications::NewRequest' - OR notifications.type = 'Notifications::RequestAccepted' -SQL - end - - def self.down - raise ActiveRecord::IrreversibleMigration.new - end -end diff --git a/db/migrate/20110518010050_disable_password_reset_for_accounts_without_usernames.rb b/db/migrate/20110518010050_disable_password_reset_for_accounts_without_usernames.rb deleted file mode 100644 index d8dce2ba3..000000000 --- a/db/migrate/20110518010050_disable_password_reset_for_accounts_without_usernames.rb +++ /dev/null @@ -1,16 +0,0 @@ -class DisablePasswordResetForAccountsWithoutUsernames < ActiveRecord::Migration - class User < ActiveRecord::Base; end - def self.up - execute < 0 - UPDATE users - SET email = "" - WHERE username IS NULL - AND invitation_identifier IS NOT NULL - AND invitation_service = 'email' -SQL - end - - def self.down - raise ActiveRecord::IrreversibleMigration.new - end -end diff --git a/db/migrate/20110518184453_add_token_auth_to_user.rb b/db/migrate/20110518184453_add_token_auth_to_user.rb deleted file mode 100644 index 8e7831291..000000000 --- a/db/migrate/20110518184453_add_token_auth_to_user.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddTokenAuthToUser < ActiveRecord::Migration - def self.up - add_column(:users, :authentication_token, :string, :limit => 30) - add_index(:users, :authentication_token, :unique => true) - end - - def self.down - remove_index(:users, :column => :authentication_token) - remove_column(:users, :authentication_token) - end -end diff --git a/db/migrate/20110518222303_add_column_for_activity_streams_photo.rb b/db/migrate/20110518222303_add_column_for_activity_streams_photo.rb deleted file mode 100644 index 0927da02e..000000000 --- a/db/migrate/20110518222303_add_column_for_activity_streams_photo.rb +++ /dev/null @@ -1,21 +0,0 @@ -class AddColumnForActivityStreamsPhoto < ActiveRecord::Migration - def self.up - add_column(:posts, :object_url, :string) - add_column(:posts, :image_url, :string) - add_column(:posts, :image_height, :integer) - add_column(:posts, :image_width, :integer) - - add_column(:posts, :provider_display_name, :string) - add_column(:posts, :actor_url, :string) - end - - def self.down - remove_column(:posts, :actor_url) - remove_column(:posts, :provider_display_name) - - remove_column(:posts, :image_width) - remove_column(:posts, :image_height) - remove_column(:posts, :image_url) - remove_column(:posts, :object_url) - end -end diff --git a/db/migrate/20110524184202_add_object_id_to_post.rb b/db/migrate/20110524184202_add_object_id_to_post.rb deleted file mode 100644 index 5245032da..000000000 --- a/db/migrate/20110524184202_add_object_id_to_post.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddObjectIdToPost < ActiveRecord::Migration - class Post < ActiveRecord::Base; end - def self.up - add_column(:posts, :objectId, :integer) - execute("UPDATE posts SET objectId = object_url") if Post.count > 0 - end - - def self.down - remove_column(:posts, :objectId, :integer) - end -end diff --git a/db/migrate/20110525213325_add_root_id_to_posts.rb b/db/migrate/20110525213325_add_root_id_to_posts.rb deleted file mode 100644 index 8deeed9d4..000000000 --- a/db/migrate/20110525213325_add_root_id_to_posts.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddRootIdToPosts < ActiveRecord::Migration - def self.up - add_column :posts, :root_guid, :string, :limit => 30 - end - - def self.down - remove_column :posts, :root_guid - end -end diff --git a/db/migrate/20110527135552_photo_status_message_association_on_guid.rb b/db/migrate/20110527135552_photo_status_message_association_on_guid.rb deleted file mode 100644 index a48759d71..000000000 --- a/db/migrate/20110527135552_photo_status_message_association_on_guid.rb +++ /dev/null @@ -1,46 +0,0 @@ -class PhotoStatusMessageAssociationOnGuid < ActiveRecord::Migration - class Post < ActiveRecord::Base - attr_accessible :id, :guid, :status_message_id, :status_message_guid - self.inheritance_column = :_type_disabled - end - - def self.up - add_column :posts, :status_message_guid, :string - - Post.record_timestamps = false - photos = Post.where(Post.arel_table[:status_message_id].not_eq(nil).and(Post.arel_table[:type].eq('Photo'))) - photos.each do |photo| - if Post.where(:id => photo.status_message_id).exists? - status_message = Post.find(photo.status_message_id) - photo.update_attributes(:status_message_guid => status_message.guid) - end - end - - remove_index :posts, [:status_message_id] - remove_index :posts, [:status_message_id, :pending] - add_index :posts, :status_message_guid - add_index :posts, [:status_message_guid, :pending] - - remove_column :posts, :status_message_id - end - - def self.down - add_column :posts, :status_message_id, :integer - - Post.record_timestamps = false - photos = Post.where(Post.arel_table[:status_message_guid].not_eq(nil).and(Post.arel_table[:type].eq('Photo'))) - photos.each do |photo| - if Post.where(:guid => photo.status_message_guid).exists? - status_message = Post.where(:guid => photo.status_message_guid).first - photo.update_attributes(:status_message_id => status_message.id) - end - end - - remove_index :posts, [:status_message_guid, :pending] - remove_index :posts, :status_message_guid - add_index :posts, :status_message_id - add_index :posts, [:status_message_id, :pending] - - remove_column :posts, :status_message_guid - end -end diff --git a/db/migrate/20110601083310_add_unconfirmed_email_to_users.rb b/db/migrate/20110601083310_add_unconfirmed_email_to_users.rb deleted file mode 100644 index 9c295e557..000000000 --- a/db/migrate/20110601083310_add_unconfirmed_email_to_users.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddUnconfirmedEmailToUsers < ActiveRecord::Migration - def self.up - add_column :users, :unconfirmed_email, :string, :default => nil, :null => true - end - - def self.down - remove_column :users, :unconfirmed_email - end -end diff --git a/db/migrate/20110601091059_add_confirm_email_token_to_users.rb b/db/migrate/20110601091059_add_confirm_email_token_to_users.rb deleted file mode 100644 index 4c71e97b2..000000000 --- a/db/migrate/20110601091059_add_confirm_email_token_to_users.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddConfirmEmailTokenToUsers < ActiveRecord::Migration - def self.up - add_column :users, :confirm_email_token, :string, :limit => 30 - end - - def self.down - remove_column :users, :confirm_email_token - end -end diff --git a/db/migrate/20110603181015_lockable_users.rb b/db/migrate/20110603181015_lockable_users.rb deleted file mode 100644 index 9aaba72e0..000000000 --- a/db/migrate/20110603181015_lockable_users.rb +++ /dev/null @@ -1,9 +0,0 @@ -class LockableUsers < ActiveRecord::Migration - def self.up - add_column :users, :locked_at, :datetime - end - - def self.down - remove_column :users, :locked_at - end -end diff --git a/db/migrate/20110603212633_likes_dependent_delete.rb b/db/migrate/20110603212633_likes_dependent_delete.rb deleted file mode 100644 index 9ec425b20..000000000 --- a/db/migrate/20110603212633_likes_dependent_delete.rb +++ /dev/null @@ -1,15 +0,0 @@ -class LikesDependentDelete < ActiveRecord::Migration - def self.up - remove_foreign_key :likes, :column => :author_id - remove_foreign_key :likes, :post - add_foreign_key(:likes, :posts, :dependent => :delete) - add_foreign_key(:likes, :people, :column => :author_id, :dependent => :delete) - end - - def self.down - remove_foreign_key(:likes, :posts) - remove_foreign_key(:likes, :people, :column => :author_id) - add_foreign_key :likes, :people, :column => :author_id - add_foreign_key :likes, :post - end -end diff --git a/db/migrate/20110603233202_drop_aspects_open.rb b/db/migrate/20110603233202_drop_aspects_open.rb deleted file mode 100644 index 19f2adde0..000000000 --- a/db/migrate/20110603233202_drop_aspects_open.rb +++ /dev/null @@ -1,10 +0,0 @@ -class DropAspectsOpen < ActiveRecord::Migration - require Rails.root.join("db", "migrate", "20110202015222_add_open_to_aspects") - def self.up - AddOpenToAspects.down - end - - def self.down - AddOpenToAspects.up - end -end diff --git a/db/migrate/20110604012703_drop_mongo_remains.rb b/db/migrate/20110604012703_drop_mongo_remains.rb deleted file mode 100644 index 212702d29..000000000 --- a/db/migrate/20110604012703_drop_mongo_remains.rb +++ /dev/null @@ -1,18 +0,0 @@ -class DropMongoRemains < ActiveRecord::Migration - def self.up - remove_index :aspects, :mongo_id - remove_index :comments, :mongo_id - remove_index :contacts, :mongo_id - remove_index :invitations, :mongo_id - remove_index :people, :mongo_id - remove_index :posts, :mongo_id - remove_index :profiles, :mongo_id - remove_index :services, :mongo_id - remove_index :users, :mongo_id - - execute 'DROP TABLE mongo_notifications' - end - - def self.down - end -end diff --git a/db/migrate/20110604204533_index_on_remember_token.rb b/db/migrate/20110604204533_index_on_remember_token.rb deleted file mode 100644 index 6351a6a99..000000000 --- a/db/migrate/20110604204533_index_on_remember_token.rb +++ /dev/null @@ -1,9 +0,0 @@ -class IndexOnRememberToken < ActiveRecord::Migration - def self.up - add_index :users, :remember_token, :unique => true - end - - def self.down - remove_index :users, :column => :remember_token - end -end diff --git a/db/migrate/20110606192307_drop_mongo_ids.rb b/db/migrate/20110606192307_drop_mongo_ids.rb deleted file mode 100644 index 159a1f07e..000000000 --- a/db/migrate/20110606192307_drop_mongo_ids.rb +++ /dev/null @@ -1,29 +0,0 @@ -class DropMongoIds < ActiveRecord::Migration - def self.up - remove_column :aspects, :mongo_id - remove_column :aspects, :user_mongo_id - remove_column :comments, :mongo_id - remove_column :contacts, :mongo_id - remove_column :invitations, :mongo_id - remove_column :people, :mongo_id - remove_column :posts, :mongo_id - remove_column :profiles, :mongo_id - remove_column :services, :mongo_id - remove_column :services, :user_mongo_id - remove_column :users, :mongo_id - end - - def self.down - add_column :users, :mongo_id - add_column :services, :user_mongo_id - add_column :services, :mongo_id - add_column :profiles, :mongo_id - add_column :posts, :mongo_id - add_column :people, :mongo_id - add_column :invitations, :mongo_id - add_column :contacts, :mongo_id - add_column :comments, :mongo_id - add_column :aspects, :user_mongo_id - add_column :aspects, :mongo_id - end -end diff --git a/db/migrate/20110623210918_add_o_auth2_support.rb b/db/migrate/20110623210918_add_o_auth2_support.rb deleted file mode 100644 index 3118a56b4..000000000 --- a/db/migrate/20110623210918_add_o_auth2_support.rb +++ /dev/null @@ -1,65 +0,0 @@ -class AddOAuth2Support < ActiveRecord::Migration - def self.up - create_table 'oauth_clients', :force => true do |t| - t.string 'name', :limit => 127, :null => false - t.text 'description', :null => false - t.string 'application_base_url', :limit => 127, :null => false - t.string 'icon_url', :limit => 127, :null => false - - t.string 'oauth_identifier', :limit => 32, :null => false - t.string 'oauth_secret', :limit => 32, :null => false - t.string 'nonce', :limit => 64 - t.text 'public_key', :null => false - t.text 'permissions_overview', :null => false - end - - add_index :oauth_clients, :name, :unique => true - add_index :oauth_clients, :application_base_url, :unique => true - add_index :oauth_clients, :nonce, :unique => true - - create_table 'oauth_authorization_codes', :force => true do |t| - t.integer 'authorization_id', :null => false - t.string 'code', :limit => 32, :null => false - t.datetime 'expires_at' - t.datetime 'created_at' - t.datetime 'updated_at' - t.string 'redirect_uri' - end - - create_table 'oauth_authorizations', :force => true do |t| - t.integer 'client_id', :null => false - t.integer 'resource_owner_id' - t.string 'resource_owner_type', :limit => 32 - t.string 'scope' - t.datetime 'expires_at' - end - - create_table 'oauth_access_tokens', :force => true do |t| - t.integer 'authorization_id', :null => false - t.string 'access_token', :limit => 32, :null => false - t.string 'refresh_token', :limit => 32 - t.datetime 'expires_at' - t.datetime 'created_at' - t.datetime 'updated_at' - end - - add_index "oauth_authorizations", ["resource_owner_id", "resource_owner_type", "client_id"], :unique => true, :name => "index_oauth_authorizations_on_resource_owner_and_client_id" - end - - def self.down - remove_index "oauth_authorizations", :name => "index_oauth_authorizations_on_resource_owner_and_client_id" - - drop_table 'oauth_access_tokens' - - drop_table 'oauth_authorizations' - - drop_table 'oauth_authorization_codes' - - remove_index :oauth_clients, :column => :nonce - remove_index :oauth_clients, :column => :application_base_url - remove_index :oauth_clients, :column => :name - - drop_table 'oauth_clients' - end - -end diff --git a/db/migrate/20110701215925_create_tag_followings.rb b/db/migrate/20110701215925_create_tag_followings.rb deleted file mode 100644 index aa5443702..000000000 --- a/db/migrate/20110701215925_create_tag_followings.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateTagFollowings < ActiveRecord::Migration - def self.up - create_table :tag_followings do |t| - t.integer :tag_id, :null => false - t.integer :user_id, :null => false - - t.timestamps - end - end - - def self.down - drop_table :tag_followings - end -end diff --git a/db/migrate/20110705003445_counter_cache_on_post_likes.rb b/db/migrate/20110705003445_counter_cache_on_post_likes.rb deleted file mode 100644 index 6e08f5577..000000000 --- a/db/migrate/20110705003445_counter_cache_on_post_likes.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CounterCacheOnPostLikes < ActiveRecord::Migration - class Post < ActiveRecord::Base; end - def self.up - add_column :posts, :likes_count, :integer, :default => 0 - execute < 0 - UPDATE posts - SET posts.likes_count = (SELECT COUNT(*) FROM likes WHERE likes.post_id = posts.id) -SQL - end - - def self.down - remove_column :posts, :likes_count - end -end diff --git a/db/migrate/20110707221112_index_taggings_created_at.rb b/db/migrate/20110707221112_index_taggings_created_at.rb deleted file mode 100644 index 136d72d44..000000000 --- a/db/migrate/20110707221112_index_taggings_created_at.rb +++ /dev/null @@ -1,8 +0,0 @@ -class IndexTaggingsCreatedAt < ActiveRecord::Migration - def self.up - add_index :taggings, :created_at - end - - def self.down - end -end diff --git a/db/migrate/20110707234802_likes_on_comments.rb b/db/migrate/20110707234802_likes_on_comments.rb deleted file mode 100644 index 67b039332..000000000 --- a/db/migrate/20110707234802_likes_on_comments.rb +++ /dev/null @@ -1,39 +0,0 @@ -class LikesOnComments < ActiveRecord::Migration - class Like < ActiveRecord::Base; end - def self.up - remove_foreign_key :likes, :posts - - add_column :likes, :target_type, :string, :limit => 60, :null => false - rename_column :likes, :post_id, :target_id - - add_column :comments, :likes_count, :integer, :default => 0, :null => false - - execute < 0 - keeper_likes = Like.group(:target_id, :author_id, :target_type).having('COUNT(*) > 1') - keeper_likes.each do |like| - l = Like.arel_table - Like.where(:target_id => like.target_id, :author_id => like.author_id, :target_type => like.target_type).where(l[:id].not_eq(like.id)).delete_all - end - end - add_index :likes, [:target_id, :author_id, :target_type], :unique => true - end - - def self.down - remove_column :comments, :likes_count - - remove_column :likes, :target_type - rename_column :likes, :target_id, :post_id - add_index :likes, :post_id - remove_index :likes, :target_id - end -end diff --git a/db/migrate/20110710102747_add_order_id_to_aspects.rb b/db/migrate/20110710102747_add_order_id_to_aspects.rb deleted file mode 100644 index ab70b1d32..000000000 --- a/db/migrate/20110710102747_add_order_id_to_aspects.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddOrderIdToAspects < ActiveRecord::Migration - def self.up - add_column :aspects, :order_id, :integer - end - - def self.down - remove_column :aspects, :order_id - end -end diff --git a/db/migrate/20110729045734_add_full_name_to_profile.rb b/db/migrate/20110729045734_add_full_name_to_profile.rb deleted file mode 100644 index aa79ae78f..000000000 --- a/db/migrate/20110729045734_add_full_name_to_profile.rb +++ /dev/null @@ -1,29 +0,0 @@ -class AddFullNameToProfile < ActiveRecord::Migration - class Profile < ActiveRecord::Base; end - def self.up - add_column :profiles, :full_name, :string, :limit => 70 - - add_index :profiles, :full_name - add_index :profiles, [:full_name, :searchable] - remove_index :profiles, [:first_name, :last_name, :searchable] - remove_index :profiles, [:first_name, :searchable] - remove_index :profiles, [:last_name, :searchable] - - if Profile.count > 0 - if AppConfig.postgres? - execute("UPDATE profiles SET full_name=LOWER(first_name || ' ' || last_name)") - else - execute("UPDATE profiles SET full_name=LOWER(CONCAT(first_name, ' ', last_name))") - end - end - end - - def self.down - remove_index :profiles, :column => :full_name - remove_column :profiles, :full_name - - add_index :profiles, [:first_name, :searchable] - add_index :profiles, [:last_name, :searchable] - add_index :profiles, [:first_name, :last_name, :searchable] - end -end diff --git a/db/migrate/20110730173137_create_pods.rb b/db/migrate/20110730173137_create_pods.rb deleted file mode 100644 index 8fdb6c010..000000000 --- a/db/migrate/20110730173137_create_pods.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreatePods < ActiveRecord::Migration - def self.up - create_table :pods do |t| - t.string :host - t.boolean :ssl - - t.timestamps - end - end - - def self.down - drop_table :pods - end -end diff --git a/db/migrate/20110730173443_create_pod_stats.rb b/db/migrate/20110730173443_create_pod_stats.rb deleted file mode 100644 index 506b60727..000000000 --- a/db/migrate/20110730173443_create_pod_stats.rb +++ /dev/null @@ -1,16 +0,0 @@ -class CreatePodStats < ActiveRecord::Migration - def self.up - create_table :pod_stats do |t| - t.integer :error_code - t.integer :person_id - t.text :error_message - t.integer :pod_id - - t.timestamps - end - end - - def self.down - drop_table :pod_stats - end -end diff --git a/db/migrate/20110812175614_add_username_to_service_users.rb b/db/migrate/20110812175614_add_username_to_service_users.rb deleted file mode 100644 index c2a9fc715..000000000 --- a/db/migrate/20110812175614_add_username_to_service_users.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddUsernameToServiceUsers < ActiveRecord::Migration - def self.up - add_column :service_users, :username, :string, :limit => 127 - end - - def self.down - remove_column :service_users, :username - end -end diff --git a/db/migrate/20110815210933_remove_invite_counter_from_user.rb b/db/migrate/20110815210933_remove_invite_counter_from_user.rb deleted file mode 100644 index 819216353..000000000 --- a/db/migrate/20110815210933_remove_invite_counter_from_user.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveInviteCounterFromUser < ActiveRecord::Migration - def self.up - remove_column :users, :invites - end - - def self.down - add_column :users, :invites, :integer, :default => 0 - end -end diff --git a/db/migrate/20110816061820_add_fields_to_invitations.rb b/db/migrate/20110816061820_add_fields_to_invitations.rb deleted file mode 100644 index f8005ef0c..000000000 --- a/db/migrate/20110816061820_add_fields_to_invitations.rb +++ /dev/null @@ -1,17 +0,0 @@ -class AddFieldsToInvitations < ActiveRecord::Migration - def self.up - add_column :invitations, :service, :string - add_column :invitations, :identifier, :string - add_column :invitations, :admin, :boolean, :default => false - change_column :invitations, :recipient_id, :integer, :null => true - change_column :invitations, :sender_id, :integer, :null => true - end - - def self.down - remove_column :invitations, :service - remove_column :invitations, :identifier - remove_column :invitations, :admin - change_column :invitations, :recipient_id, :integer, :null => false - change_column :invitations, :sender_id, :integer, :null => false - end -end diff --git a/db/migrate/20110818212541_add_identifier_to_existing_invitations.rb b/db/migrate/20110818212541_add_identifier_to_existing_invitations.rb deleted file mode 100644 index 02c2524f0..000000000 --- a/db/migrate/20110818212541_add_identifier_to_existing_invitations.rb +++ /dev/null @@ -1,20 +0,0 @@ -class AddIdentifierToExistingInvitations < ActiveRecord::Migration - class Invitation < ActiveRecord::Base; end - def self.up - execute < 127) - change_column(:services, :uid, :string, :limit => 127) - add_index :services, [:type, :uid] - end - - def self.down - remove_index :services, :column => [:type, :uid] - end -end diff --git a/db/migrate/20110911213207_counter_cache_on_post_comments.rb b/db/migrate/20110911213207_counter_cache_on_post_comments.rb deleted file mode 100644 index 4eee63e35..000000000 --- a/db/migrate/20110911213207_counter_cache_on_post_comments.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CounterCacheOnPostComments < ActiveRecord::Migration - class Post < ActiveRecord::Base; end - - def self.up - add_column :posts, :comments_count, :integer, :default => 0 - execute < 0 - UPDATE posts - SET comments_count = (SELECT COUNT(*) FROM comments WHERE comments.post_id = posts.id) -SQL - end - - def self.down - remove_column :posts, :comments_count - end -end diff --git a/db/migrate/20110924112840_create_o_embed_caches.rb b/db/migrate/20110924112840_create_o_embed_caches.rb deleted file mode 100644 index 294a8656f..000000000 --- a/db/migrate/20110924112840_create_o_embed_caches.rb +++ /dev/null @@ -1,14 +0,0 @@ -class CreateOEmbedCaches < ActiveRecord::Migration - def self.up - create_table :o_embed_caches do |t| - t.string :url, :limit => 1024, :null => false, :unique => true - t.text :data, :null => false - end - add_index :o_embed_caches, :url, :length => { :url => 255 } - end - - def self.down - remove_index :o_embed_caches, :column => :url - drop_table :o_embed_caches - end -end diff --git a/db/migrate/20110926120220_fix_indexes_to_serivces.rb b/db/migrate/20110926120220_fix_indexes_to_serivces.rb deleted file mode 100644 index 1d2fa1d16..000000000 --- a/db/migrate/20110926120220_fix_indexes_to_serivces.rb +++ /dev/null @@ -1,14 +0,0 @@ -class FixIndexesToSerivces < ActiveRecord::Migration - # This alters the tables to avoid a mysql bug - # See http://bugs.joindiaspora.com/issues/835 - def self.up - remove_index :services, :column => [:type, :uid] - change_column(:services, :type, :string, :limit => 127) - change_column(:services, :uid, :string, :limit => 127) - add_index :services, [:type, :uid] - end - - def self.down - remove_index :services, :column => [:type, :uid] - end -end diff --git a/db/migrate/20110930182048_add_root_guid_index_to_posts.rb b/db/migrate/20110930182048_add_root_guid_index_to_posts.rb deleted file mode 100644 index ce3e9bdf5..000000000 --- a/db/migrate/20110930182048_add_root_guid_index_to_posts.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddRootGuidIndexToPosts < ActiveRecord::Migration - def self.up - add_index :posts, :root_guid - end - - def self.down - remove_index :posts, :column => :root_guid - end -end diff --git a/db/migrate/20111002013921_fix_data_type_for_activity_streams_object_id.rb b/db/migrate/20111002013921_fix_data_type_for_activity_streams_object_id.rb deleted file mode 100644 index 99181ae35..000000000 --- a/db/migrate/20111002013921_fix_data_type_for_activity_streams_object_id.rb +++ /dev/null @@ -1,11 +0,0 @@ -class FixDataTypeForActivityStreamsObjectId < ActiveRecord::Migration - def self.up - change_table :posts do |t| - t.change :objectId, :string - end - end - - def self.down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20111003232053_add_index_for_reshares.rb b/db/migrate/20111003232053_add_index_for_reshares.rb deleted file mode 100644 index d99694fd9..000000000 --- a/db/migrate/20111003232053_add_index_for_reshares.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddIndexForReshares < ActiveRecord::Migration - def self.up - add_index :posts, [:author_id, :root_guid], :unique => true - end - - def self.down - remove_index :posts, :column => [:author_id, :root_guid] - end -end diff --git a/db/migrate/20111011193702_add_oembed_cache_to_posts.rb b/db/migrate/20111011193702_add_oembed_cache_to_posts.rb deleted file mode 100644 index 371faef7c..000000000 --- a/db/migrate/20111011193702_add_oembed_cache_to_posts.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddOembedCacheToPosts < ActiveRecord::Migration - def self.up - add_column :posts, :o_embed_cache_id, :integer - end - - def self.down - remove_column :posts, :o_embed_cache_id - end -end diff --git a/db/migrate/20111011194702_comment_anything.rb b/db/migrate/20111011194702_comment_anything.rb deleted file mode 100644 index d79da4afd..000000000 --- a/db/migrate/20111011194702_comment_anything.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CommentAnything < ActiveRecord::Migration - def self.up - remove_foreign_key :comments, :posts - remove_index :comments, :post_id - change_table :comments do |t| - t.rename :post_id, :commentable_id - t.string :commentable_type, :default => 'Post', :null => false, :limit => 60 - end - end - - def self.down - rename_column :comments, :commentable_id, :post_id - add_foreign_key :comments, :posts, :dependent => :delete - add_index :comments, :post_id - - remove_column :comments, :commentable_type - end -end diff --git a/db/migrate/20111011195702_share_anything.rb b/db/migrate/20111011195702_share_anything.rb deleted file mode 100644 index 810e73825..000000000 --- a/db/migrate/20111011195702_share_anything.rb +++ /dev/null @@ -1,114 +0,0 @@ -class ShareAnything < ActiveRecord::Migration - def self.up - remove_foreign_key :aspect_visibilities, :posts - - if AppConfig.postgres? - execute "DROP INDEX index_aspect_visibilities_on_post_id_and_aspect_id" - execute "DROP INDEX index_aspect_visibilities_on_post_id" - execute "ALTER TABLE aspect_visibilities RENAME COLUMN post_id TO shareable_id" - execute "ALTER TABLE aspect_visibilities ADD COLUMN shareable_type VARCHAR(255) NOT NULL DEFAULT 'Post'" - execute "CREATE INDEX shareable_and_aspect_id ON aspect_visibilities ( shareable_id, shareable_type, aspect_id )" - execute "CREATE INDEX index_aspect_visibilities_on_shareable_id_and_shareable_type ON aspect_visibilities ( shareable_id, shareable_type )" - else - start_sql = "ALTER TABLE aspect_visibilities " - sql = [] - - #remove_index :aspect_visibilities, :post_id_and_aspect_id - sql << "DROP INDEX `index_aspect_visibilities_on_post_id_and_aspect_id`" - - #remove_index :aspect_visibilities, :post_id - sql << "DROP INDEX `index_aspect_visibilities_on_post_id`" - - - - # change_table :aspect_visibilities do |t| - - # t.rename :post_id, :shareable_id - # t.string :shareable_type, :default => 'Post', :null => false - # end - - sql << "CHANGE COLUMN post_id shareable_id int NOT NULL" - sql << "ADD shareable_type varchar(255) NOT NULL DEFAULT 'Post'" - - - # add_index :aspect_visibilities, [:shareable_id, :shareable_type, :aspect_id], :name => 'shareable_and_aspect_id' - # add_index :aspect_visibilities, [:shareable_id, :shareable_type] - - sql << "add index `shareable_and_aspect_id` (`shareable_id`, `shareable_type`, `aspect_id`)" - sql << "add index `index_aspect_visibilities_on_shareable_id_and_shareable_type` (`shareable_id`, `shareable_type`)" - - - execute(start_sql + sql.join(', ') + ';') - end - - - - remove_foreign_key :post_visibilities, :posts - rename_table :post_visibilities, :share_visibilities - - if AppConfig.postgres? - execute "DROP INDEX index_post_visibilities_on_contact_id_and_post_id" - execute "DROP INDEX index_post_visibilities_on_post_id_and_hidden_and_contact_id" - execute "ALTER TABLE share_visibilities RENAME COLUMN post_id TO shareable_id" - execute "ALTER TABLE share_visibilities ADD COLUMN shareable_type VARCHAR(60) NOT NULL DEFAULT 'Post'" - execute "CREATE INDEX shareable_and_contact_id ON share_visibilities ( shareable_id, shareable_type, contact_id )" - execute "CREATE INDEX shareable_and_hidden_and_contact_id ON share_visibilities ( shareable_id, shareable_type, hidden, contact_id )" - else - start_sql = "ALTER TABLE share_visibilities " - sql = [] - - #remove_index :post_visibilities, :contact_id_and_post_id - #remove_index :post_visibilities, :post_id_and_hidden_and_contact_id - - sql << "DROP INDEX `index_post_visibilities_on_contact_id_and_post_id`" - sql << "DROP INDEX `index_post_visibilities_on_post_id_and_hidden_and_contact_id`" - - #change_table :post_visibilities do |t| - # t.rename :post_id, :shareable_id - # t.string :shareable_type, :default => 'Post', :null => false - #end - - sql << "CHANGE COLUMN post_id shareable_id int NOT NULL" - sql << "ADD shareable_type varchar(60) NOT NULL DEFAULT 'Post'" - - #add_index :share_visibilities, [:shareable_id, :shareable_type, :contact_id], :name => 'shareable_and_contact_id' - #add_index :share_visibilities, [:shareable_id, :shareable_type, :hidden, :contact_id], :name => 'shareable_and_hidden_and_contact_id' - - sql << "add index `shareable_and_contact_id` (`shareable_id`, `shareable_type`, `contact_id`)" - sql << "add index `shareable_and_hidden_and_contact_id` (`shareable_id`, `shareable_type`, `hidden`, `contact_id`)" - - execute(start_sql + sql.join(', ') + ';') - end - - end - - - def self.down - remove_index :share_visibilities, :name => 'shareable_and_hidden_and_contact_id' - remove_index :share_visibilities, :name => 'shareable_and_contact_id' - rename_table :share_visibilities, :post_visibilities - - change_table :post_visibilities do |t| - t.remove :shareable_type - t.rename :shareable_id, :post_id - end - - add_index :post_visibilities, [:post_id, :hidden, :contact_id], :unique => true - add_index :post_visibilities, [:contact_id, :post_id], :unique => true - add_foreign_key :post_visibilities, :posts, :dependent => :delete - - - remove_index :aspect_visibilities, [:shareable_id, :shareable_type] - remove_index :aspect_visibilities, :name => 'shareable_and_aspect_id' - - change_table :aspect_visibilities do |t| - t.remove :shareable_type - t.rename :shareable_id, :post_id - end - - add_index :aspect_visibilities, :post_id - add_index :aspect_visibilities, [:post_id, :aspect_id], :unique => true - add_foreign_key :aspect_visibilities, :posts, :dependent => :delete - - end -end diff --git a/db/migrate/20111012215141_move_photos_to_their_own_table.rb b/db/migrate/20111012215141_move_photos_to_their_own_table.rb deleted file mode 100644 index ffbc16999..000000000 --- a/db/migrate/20111012215141_move_photos_to_their_own_table.rb +++ /dev/null @@ -1,161 +0,0 @@ -class MovePhotosToTheirOwnTable < ActiveRecord::Migration - def self.up - create_table "photos", :force => true do |t| - t.integer "tmp_old_id", :null => true - t.integer "author_id", :null => false - t.boolean "public", :default => false, :null => false - t.string "diaspora_handle" - t.string "guid", :null => false - t.boolean "pending", :default => false, :null => false - t.text "text" - t.text "remote_photo_path" - t.string "remote_photo_name" - t.string "random_string" - t.string "processed_image" - t.datetime "created_at" - t.datetime "updated_at" - t.string "unprocessed_image" - t.string "status_message_guid" - t.integer "comments_count" - end - - if AppConfig.postgres? - execute %{ - INSERT INTO photos ( - tmp_old_id - , author_id - , public - , diaspora_handle - , guid - , pending - , text - , remote_photo_path - , remote_photo_name - , random_string - , processed_image - , created_at - , updated_at - , unprocessed_image - , status_message_guid - , comments_count - ) SELECT - id - , author_id - , public - , diaspora_handle - , guid - , pending - , text - , remote_photo_path - , remote_photo_name - , random_string - , processed_image - , created_at - , updated_at - , unprocessed_image - , status_message_guid - , comments_count - FROM - posts - WHERE - type = 'Photo' - } - - execute "UPDATE aspect_visibilities SET shareable_type='Photo' FROM photos WHERE shareable_id=photos.id" - execute "UPDATE share_visibilities SET shareable_type='Photo' FROM photos WHERE shareable_id=photos.id" - else - execute < "en" - end - - def self.down - remove_column :invitations, :language - end -end diff --git a/db/migrate/20111018010003_add_back_indexes.rb b/db/migrate/20111018010003_add_back_indexes.rb deleted file mode 100644 index 878cc526a..000000000 --- a/db/migrate/20111018010003_add_back_indexes.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddBackIndexes < ActiveRecord::Migration - def self.up - # reduce index size - - add_index :photos, :status_message_guid - add_index :comments, [:commentable_id, :commentable_type] - end - - def self.down - remove_index :comments, :column => [:commentable_id, :commentable_type] - remove_index :photos, :column => :status_message_guid - - # reduce index size - end -end diff --git a/db/migrate/20111019013244_postgresql_photos_id_seq_init.rb b/db/migrate/20111019013244_postgresql_photos_id_seq_init.rb deleted file mode 100644 index 8250b4eb7..000000000 --- a/db/migrate/20111019013244_postgresql_photos_id_seq_init.rb +++ /dev/null @@ -1,11 +0,0 @@ -class PostgresqlPhotosIdSeqInit < ActiveRecord::Migration - def self.up - if AppConfig.postgres? - execute "SELECT setval('photos_id_seq', COALESCE( ( SELECT MAX(id)+1 FROM photos ), 1 ) )" - end - end - - def self.down - # No reason or need to migrate this down. - end -end diff --git a/db/migrate/20111021184041_add_community_spotlight_in_stream.rb b/db/migrate/20111021184041_add_community_spotlight_in_stream.rb deleted file mode 100644 index 25143ff1f..000000000 --- a/db/migrate/20111021184041_add_community_spotlight_in_stream.rb +++ /dev/null @@ -1,14 +0,0 @@ -class AddCommunitySpotlightInStream < ActiveRecord::Migration - def self.up - add_column :users, :show_community_spotlight_in_stream, :boolean, :null => false, :default => true - - ActiveRecord::Base.connection.execute <1; -SQL - duplicate_rows.each do |row| - count = row.first - user_id = row[1] - tag_id = row.last - - execute < true - end - - def self.down - remove_index :tag_followings, :column => [:tag_id, :user_id] - remove_index :tag_followings, :column => :user_id - remove_index :tag_followings, :column => :tag_id - end -end diff --git a/db/migrate/20111101202137_create_blocks.rb b/db/migrate/20111101202137_create_blocks.rb deleted file mode 100644 index 31e451740..000000000 --- a/db/migrate/20111101202137_create_blocks.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateBlocks < ActiveRecord::Migration - def self.up - create_table :blocks do |t| - t.integer :user_id - t.integer :person_id - end - end - - def self.down - drop_table :blocks - end -end diff --git a/db/migrate/20111103184050_add_closed_account_flag_to_person.rb b/db/migrate/20111103184050_add_closed_account_flag_to_person.rb deleted file mode 100644 index 0a845f835..000000000 --- a/db/migrate/20111103184050_add_closed_account_flag_to_person.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddClosedAccountFlagToPerson < ActiveRecord::Migration - def self.up - add_column :people, :closed_account, :boolean, :default => false - end - - def self.down - remove_column :people, :closed_account - end -end diff --git a/db/migrate/20111109023618_create_account_deletions.rb b/db/migrate/20111109023618_create_account_deletions.rb deleted file mode 100644 index 6e2d1f9da..000000000 --- a/db/migrate/20111109023618_create_account_deletions.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateAccountDeletions < ActiveRecord::Migration - def self.up - create_table :account_deletions do |t| - t.string :diaspora_handle - t.integer :person_id - end - end - - def self.down - drop_table :account_deletions - end -end diff --git a/db/migrate/20111111025358_counter_cache_on_post_reshares.rb b/db/migrate/20111111025358_counter_cache_on_post_reshares.rb deleted file mode 100644 index a6c0e73c0..000000000 --- a/db/migrate/20111111025358_counter_cache_on_post_reshares.rb +++ /dev/null @@ -1,35 +0,0 @@ -class CounterCacheOnPostReshares < ActiveRecord::Migration - class Post < ActiveRecord::Base; end - - def self.up - add_column :posts, :reshares_count, :integer, :default => 0 - - if AppConfig.postgres? - execute %{ - UPDATE posts - SET reshares_count = ( - SELECT COUNT(*) - FROM posts p2 - WHERE - p2.type = 'Reshare' - AND p2.root_guid = posts.guid - ) - } - else # mysql - execute "CREATE TEMPORARY TABLE posts_reshared SELECT * FROM posts WHERE type = 'Reshare'" - execute %{ - UPDATE posts p1 - SET reshares_count = ( - SELECT COUNT(*) - FROM posts_reshared p2 - WHERE p2.root_guid = p1.guid - ) - } - end - - end - - def self.down - remove_column :posts, :reshares_count - end -end diff --git a/db/migrate/20111114173111_add_auto_follow_back_to_users.rb b/db/migrate/20111114173111_add_auto_follow_back_to_users.rb deleted file mode 100644 index 165691b23..000000000 --- a/db/migrate/20111114173111_add_auto_follow_back_to_users.rb +++ /dev/null @@ -1,11 +0,0 @@ -class AddAutoFollowBackToUsers < ActiveRecord::Migration - def self.up - add_column :users, :auto_follow_back, :boolean, :default => false - add_column :users, :auto_follow_back_aspect_id, :integer - end - - def self.down - remove_column :users, :auto_follow_back - remove_column :users, :auto_follow_back_aspect - end -end diff --git a/db/migrate/20111207230506_add_oauth_redirect_uri_to_oauth_clients.rb b/db/migrate/20111207230506_add_oauth_redirect_uri_to_oauth_clients.rb deleted file mode 100644 index e89ed5f8c..000000000 --- a/db/migrate/20111207230506_add_oauth_redirect_uri_to_oauth_clients.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddOauthRedirectUriToOauthClients < ActiveRecord::Migration - def self.up - add_column :oauth_clients, :oauth_redirect_uri, :string - end - - def self.down - remove_column :oauth_clients, :oauth_redirect_uri - end -end diff --git a/db/migrate/20111207233503_remove_low_length_limits_from_oauth_tables.rb b/db/migrate/20111207233503_remove_low_length_limits_from_oauth_tables.rb deleted file mode 100644 index 1d3d81e81..000000000 --- a/db/migrate/20111207233503_remove_low_length_limits_from_oauth_tables.rb +++ /dev/null @@ -1,19 +0,0 @@ -class RemoveLowLengthLimitsFromOauthTables < ActiveRecord::Migration - def self.up - change_column :oauth_clients, :oauth_identifier, :string, :limit => 127 - change_column :oauth_clients, :oauth_secret, :string, :limit => 127 - change_column :oauth_clients, :nonce, :string, :limit => 127 - change_column :oauth_authorization_codes, :code, :string, :limit => 127 - change_column :oauth_access_tokens, :access_token, :string, :limit => 127 - change_column :oauth_access_tokens, :refresh_token, :string, :limit => 127 - end - - def self.down - change_column :oauth_clients, :oauth_identifier, :string, :limit => 32 - change_column :oauth_clients, :oauth_secret, :string, :limit => 32 - change_column :oauth_clients, :nonce, :string, :limit => 64 - change_column :oauth_authorization_codes, :code, :string, :limit => 32 - change_column :oauth_access_tokens, :access_token, :string, :limit => 32 - change_column :oauth_access_tokens, :refresh_token, :string, :limit => 32 - end -end diff --git a/db/migrate/20111211213438_create_invitation_codes.rb b/db/migrate/20111211213438_create_invitation_codes.rb deleted file mode 100644 index f2bdde858..000000000 --- a/db/migrate/20111211213438_create_invitation_codes.rb +++ /dev/null @@ -1,15 +0,0 @@ -class CreateInvitationCodes < ActiveRecord::Migration - def self.up - create_table :invitation_codes do |t| - t.string :token - t.integer :user_id - t.integer :count - - t.timestamps - end - end - - def self.down - drop_table :invitation_codes - end -end diff --git a/db/migrate/20111217042006_add_photo_counter_cache_to_post.rb b/db/migrate/20111217042006_add_photo_counter_cache_to_post.rb deleted file mode 100644 index a614f26d8..000000000 --- a/db/migrate/20111217042006_add_photo_counter_cache_to_post.rb +++ /dev/null @@ -1,15 +0,0 @@ -class AddPhotoCounterCacheToPost < ActiveRecord::Migration - class Post < ActiveRecord::Base; end - - def self.up - add_column :posts, :photos_count, :integer, :default => 0 - execute < 0 - UPDATE posts - SET photos_count = (SELECT COUNT(*) FROM photos WHERE photos.status_message_guid = posts.guid) -SQL - end - - def self.down - remove_column :posts, :photos_count - end -end diff --git a/db/migrate/20120107220942_move_recently_hidden_posts_to_user.rb b/db/migrate/20120107220942_move_recently_hidden_posts_to_user.rb deleted file mode 100644 index a1b24243c..000000000 --- a/db/migrate/20120107220942_move_recently_hidden_posts_to_user.rb +++ /dev/null @@ -1,28 +0,0 @@ -class Person < ActiveRecord::Base - belongs_to :owner, :class_name => 'User' -end - -class User < ActiveRecord::Base - serialize :hidden_shareables, Hash -end - -class Contact < ActiveRecord::Base - belongs_to :user -end - -class ShareVisibility < ActiveRecord::Base - belongs_to :contact -end - -require Rails.root.join('lib', 'share_visibility_converter') - -class MoveRecentlyHiddenPostsToUser < ActiveRecord::Migration - def self.up - add_column :users, :hidden_shareables, :text - ShareVisibilityConverter.copy_hidden_share_visibilities_to_users(true) - end - - def self.down - remove_column :users, :hidden_shareables - end -end \ No newline at end of file diff --git a/db/migrate/20120114191018_remove_photos_count_from_post.rb b/db/migrate/20120114191018_remove_photos_count_from_post.rb deleted file mode 100644 index 968e51401..000000000 --- a/db/migrate/20120114191018_remove_photos_count_from_post.rb +++ /dev/null @@ -1,13 +0,0 @@ -class RemovePhotosCountFromPost < ActiveRecord::Migration - def self.up - remove_column :posts, :photos_count - end - - def self.down - add_column :posts, :photos_count, :integer, :default => 0 - execute < 0 - UPDATE posts - SET photos_count = (SELECT COUNT(*) FROM photos WHERE photos.status_message_guid = posts.guid) -SQL - end -end diff --git a/db/migrate/20120127235102_add_nsfw_to_profiles.rb b/db/migrate/20120127235102_add_nsfw_to_profiles.rb deleted file mode 100644 index 582a0ecd4..000000000 --- a/db/migrate/20120127235102_add_nsfw_to_profiles.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddNsfwToProfiles < ActiveRecord::Migration - def self.up - add_column :profiles, :nsfw, :boolean, :default => false - end - - def self.down - remove_column :profiles, :nsfw - end -end diff --git a/db/migrate/20120202190701_remove_public_share_visibilities.rb b/db/migrate/20120202190701_remove_public_share_visibilities.rb deleted file mode 100644 index caa42d8c9..000000000 --- a/db/migrate/20120202190701_remove_public_share_visibilities.rb +++ /dev/null @@ -1,59 +0,0 @@ -# NOTE: this migration will remove a lot of unused rows. It is highly suggested -# that you run `OPTIMIZE TABLE share_visibilities` after this -# `OPTIMIZE NO_WRITE_TO_BINLOG TABLE share_visibilities;` will run faster but has a greater chance of corrupting data -# and will only work on an unsharded database (which should be the case for everyone right now) -# you probably want to backup your db before you do any of this. - - -# migration is complete. -# -# caution: you may want to take your pod offline during the OPTIMIZE command. - -class RemovePublicShareVisibilities < ActiveRecord::Migration - def self.up - %w{Post Photo}.each do |type| - - index = 0 - - table_name = type.tableize - if AppConfig.postgres? - shareable_size = ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM #{table_name}").first['count'].to_i - else - shareable_size = ActiveRecord::Base.connection.execute("SELECT COUNT(*) FROM #{table_name}").first.first - end - - while index < shareable_size + 100 do - if AppConfig.postgres? - sql = <<-SQL - DELETE - FROM share_visibilities AS sv - USING #{table_name} as p - WHERE sv.shareable_id = p.id - AND sv.shareable_type = '#{type}' - AND p.public IS TRUE - AND p.id < #{index}; - SQL - else - sql = <<-SQL - DELETE sv - FROM share_visibilities AS sv - INNER JOIN #{table_name} - ON sv.shareable_id = #{table_name}.id - WHERE sv.shareable_type = "#{type}" - AND #{table_name}.public IS TRUE - AND #{table_name}.id < #{index}; - SQL - end - - puts "deleted public share vis up to #{index} of #{type}" - ActiveRecord::Base.connection.execute(sql) - - index += 100 - end - end - end - - def self.down - raise ActiveRecord::IrreversibleMigration - end -end diff --git a/db/migrate/20120203220932_add_interacted_at_to_posts.rb b/db/migrate/20120203220932_add_interacted_at_to_posts.rb deleted file mode 100644 index e8df0e579..000000000 --- a/db/migrate/20120203220932_add_interacted_at_to_posts.rb +++ /dev/null @@ -1,9 +0,0 @@ -class AddInteractedAtToPosts < ActiveRecord::Migration - def self.up - add_column :posts, :interacted_at, :datetime - end - - def self.down - remove_column :posts, :interacted_at - end -end diff --git a/db/migrate/20120208231253_create_participations.rb b/db/migrate/20120208231253_create_participations.rb deleted file mode 100644 index 62f840bc6..000000000 --- a/db/migrate/20120208231253_create_participations.rb +++ /dev/null @@ -1,17 +0,0 @@ -class CreateParticipations < ActiveRecord::Migration - def self.up - create_table "participations", :force => true do |t| - t.string "guid" - t.integer "target_id" - t.string "target_type", :limit => 60, :null => false - t.integer "author_id" - t.text "author_signature" - t.text "parent_author_signature" - t.timestamps - end - end - - def self.down - drop_table :participations - end -end diff --git a/db/migrate/20120301143226_remove_youtube_titles.rb b/db/migrate/20120301143226_remove_youtube_titles.rb deleted file mode 100644 index fbe3a213e..000000000 --- a/db/migrate/20120301143226_remove_youtube_titles.rb +++ /dev/null @@ -1,11 +0,0 @@ -class RemoveYoutubeTitles < ActiveRecord::Migration - def self.up - remove_column :comments, :youtube_titles - remove_column :posts, :youtube_titles - end - - def self.down - add_column :comments, :youtube_titles, :text - add_column :posts, :youtube_titles, :text - end -end \ No newline at end of file diff --git a/db/migrate/20120322223517_add_template_name_to_posts.rb b/db/migrate/20120322223517_add_template_name_to_posts.rb deleted file mode 100644 index cedd5951c..000000000 --- a/db/migrate/20120322223517_add_template_name_to_posts.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddTemplateNameToPosts < ActiveRecord::Migration - def change # thanks josh susser - add_column :posts, :frame_name, :string - end -end diff --git a/db/migrate/20120328025842_remove_invitation_email_from_users.rb b/db/migrate/20120328025842_remove_invitation_email_from_users.rb deleted file mode 100644 index 17e516361..000000000 --- a/db/migrate/20120328025842_remove_invitation_email_from_users.rb +++ /dev/null @@ -1,17 +0,0 @@ -class RemoveInvitationEmailFromUsers < ActiveRecord::Migration - def self.up - execute <<-SQL - UPDATE users - SET email = 'invitemail_' || id || '@example.org' - WHERE invitation_token IS NOT NULL - SQL - end - - def self.down - execute <<-SQL - UPDATE users - SET email = (SELECT identifier FROM invitations WHERE invitations.recipient_id = users.id) - WHERE invitation_token IS NOT NULL - SQL - end -end diff --git a/db/migrate/20120330103021_indexes_on_participation.rb b/db/migrate/20120330103021_indexes_on_participation.rb deleted file mode 100644 index 4535aa2d3..000000000 --- a/db/migrate/20120330103021_indexes_on_participation.rb +++ /dev/null @@ -1,6 +0,0 @@ -class IndexesOnParticipation < ActiveRecord::Migration - def change - add_index(:participations, [:target_id, :target_type, :author_id]) - add_index(:participations, :guid) - end -end diff --git a/db/migrate/20120330144057_indexes_on_posts.rb b/db/migrate/20120330144057_indexes_on_posts.rb deleted file mode 100644 index 523ba6c7a..000000000 --- a/db/migrate/20120330144057_indexes_on_posts.rb +++ /dev/null @@ -1,5 +0,0 @@ -class IndexesOnPosts < ActiveRecord::Migration - def change - add_index(:posts, [:id, :type, :created_at]) - end -end diff --git a/db/migrate/20120405170105_create_locations.rb b/db/migrate/20120405170105_create_locations.rb deleted file mode 100644 index f46d76860..000000000 --- a/db/migrate/20120405170105_create_locations.rb +++ /dev/null @@ -1,12 +0,0 @@ -class CreateLocations < ActiveRecord::Migration - def change - create_table :locations do |t| - t.string :address - t.string :lat - t.string :lng - t.integer :status_message_id - - t.timestamps - end - end -end diff --git a/db/migrate/20120414005431_create_rails_admin_histories_table.rb b/db/migrate/20120414005431_create_rails_admin_histories_table.rb deleted file mode 100644 index 3c743aa28..000000000 --- a/db/migrate/20120414005431_create_rails_admin_histories_table.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateRailsAdminHistoriesTable < ActiveRecord::Migration - def self.up - create_table :rails_admin_histories do |t| - t.text :message # title, name, or object_id - t.string :username - t.integer :item - t.string :table - t.integer :month, :limit => 2 - t.integer :year, :limit => 5 - t.timestamps - end - add_index(:rails_admin_histories, [:item, :table, :month, :year], :name => 'index_rails_admin_histories' ) - end - - def self.down - drop_table :rails_admin_histories - end -end diff --git a/db/migrate/20120420185823_add_width_and_height_to_photos.rb b/db/migrate/20120420185823_add_width_and_height_to_photos.rb deleted file mode 100644 index ebe77913e..000000000 --- a/db/migrate/20120420185823_add_width_and_height_to_photos.rb +++ /dev/null @@ -1,6 +0,0 @@ -class AddWidthAndHeightToPhotos < ActiveRecord::Migration - def change - add_column :photos, :height, :integer - add_column :photos, :width, :integer - end -end diff --git a/db/migrate/20120422072257_add_favorite_to_post.rb b/db/migrate/20120422072257_add_favorite_to_post.rb deleted file mode 100644 index bc929124c..000000000 --- a/db/migrate/20120422072257_add_favorite_to_post.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddFavoriteToPost < ActiveRecord::Migration - def change - add_column :posts, :favorite, :boolean, :default => false - end -end diff --git a/db/migrate/20120427152648_create_roles.rb b/db/migrate/20120427152648_create_roles.rb deleted file mode 100644 index 8f7dcdd56..000000000 --- a/db/migrate/20120427152648_create_roles.rb +++ /dev/null @@ -1,10 +0,0 @@ -class CreateRoles < ActiveRecord::Migration - def change - create_table :roles do |t| - t.integer :person_id - t.string :name - - t.timestamps - end - end -end diff --git a/db/migrate/20120506053156_add_wallpaper_to_profile.rb b/db/migrate/20120506053156_add_wallpaper_to_profile.rb deleted file mode 100644 index b190cb8b6..000000000 --- a/db/migrate/20120506053156_add_wallpaper_to_profile.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddWallpaperToProfile < ActiveRecord::Migration - def change - add_column :profiles, :wallpaper, :string - end -end diff --git a/db/migrate/20120510184853_drop_service_users.rb b/db/migrate/20120510184853_drop_service_users.rb deleted file mode 100644 index 717981605..000000000 --- a/db/migrate/20120510184853_drop_service_users.rb +++ /dev/null @@ -1,24 +0,0 @@ -class DropServiceUsers < ActiveRecord::Migration - def up - drop_table :service_users - - end - - def down - create_table :service_users do |t| - t.string :uid, :null => false - t.string :name, :null => false - t.string :photo_url, :null => false - t.integer :service_id, :null => false - t.integer :person_id - t.integer :contact_id - t.integer :request_id - t.integer :invitation_id - - t.timestamps - end - - add_index :service_users, :service_id - add_index :service_users, [:uid, :service_id], :unique => true - end -end diff --git a/db/migrate/20120517014034_remove_oauth.rb b/db/migrate/20120517014034_remove_oauth.rb deleted file mode 100644 index 876d92fb5..000000000 --- a/db/migrate/20120517014034_remove_oauth.rb +++ /dev/null @@ -1,57 +0,0 @@ -class RemoveOauth < ActiveRecord::Migration - def up - drop_table 'oauth_access_tokens' - drop_table "oauth_authorization_codes" - drop_table "oauth_authorizations" - drop_table "oauth_clients" - - end - - def down - create_table "oauth_access_tokens", :force => true do |t| - t.integer "authorization_id", :null => false - t.string "access_token", :limit => 127, :null => false - t.string "refresh_token", :limit => 127 - t.datetime "expires_at" - t.datetime "created_at" - t.datetime "updated_at" - end - - create_table "oauth_authorization_codes", :force => true do |t| - t.integer "authorization_id", :null => false - t.string "code", :limit => 127, :null => false - t.datetime "expires_at" - t.datetime "created_at" - t.datetime "updated_at" - t.string "redirect_uri" - end - - create_table "oauth_authorizations", :force => true do |t| - t.integer "client_id", :null => false - t.integer "resource_owner_id" - t.string "resource_owner_type", :limit => 32 - t.string "scope" - t.datetime "expires_at" - end - - add_index "oauth_authorizations", ["resource_owner_id", "resource_owner_type", "client_id"], :name => "index_oauth_authorizations_on_resource_owner_and_client_id", :unique => true - - create_table "oauth_clients", :force => true do |t| - t.string "name", :limit => 127, :null => false - t.text "description", :null => false - t.string "application_base_url", :limit => 127, :null => false - t.string "icon_url", :limit => 127, :null => false - t.string "oauth_identifier", :limit => 127, :null => false - t.string "oauth_secret", :limit => 127, :null => false - t.string "nonce", :limit => 127 - t.text "public_key", :null => false - t.text "permissions_overview", :null => false - t.string "oauth_redirect_uri" - end - - add_index "oauth_clients", ["application_base_url"], :name => "index_oauth_clients_on_application_base_url", :unique => true - add_index "oauth_clients", ["name"], :name => "index_oauth_clients_on_name", :unique => true - add_index "oauth_clients", ["nonce"], :name => "index_oauth_clients_on_nonce", :unique => true - - end -end diff --git a/db/migrate/20120519015723_remove_multi_photo_frame_reference.rb b/db/migrate/20120519015723_remove_multi_photo_frame_reference.rb deleted file mode 100644 index f509d9096..000000000 --- a/db/migrate/20120519015723_remove_multi_photo_frame_reference.rb +++ /dev/null @@ -1,8 +0,0 @@ -class RemoveMultiPhotoFrameReference < ActiveRecord::Migration - def up - execute("UPDATE posts SET frame_name='Day' WHERE frame_name='multi-photo'") - end - - def down - end -end diff --git a/db/migrate/20120521191429_remove_rich_media_type.rb b/db/migrate/20120521191429_remove_rich_media_type.rb deleted file mode 100644 index c2dc44236..000000000 --- a/db/migrate/20120521191429_remove_rich_media_type.rb +++ /dev/null @@ -1,8 +0,0 @@ -class RemoveRichMediaType < ActiveRecord::Migration - def up - execute("UPDATE posts SET frame_name='Night' WHERE frame_name='rich-media'") - end - - def down - end -end diff --git a/db/migrate/20120803143552_add_fetch_status_to_people.rb b/db/migrate/20120803143552_add_fetch_status_to_people.rb deleted file mode 100644 index 20eca8f27..000000000 --- a/db/migrate/20120803143552_add_fetch_status_to_people.rb +++ /dev/null @@ -1,5 +0,0 @@ -class AddFetchStatusToPeople < ActiveRecord::Migration - def change - add_column :people, :fetch_status, :integer, :default => 0 - end -end diff --git a/db/migrate/20120906162503_update_devise.rb b/db/migrate/20120906162503_update_devise.rb deleted file mode 100644 index 3e5196895..000000000 --- a/db/migrate/20120906162503_update_devise.rb +++ /dev/null @@ -1,11 +0,0 @@ -class UpdateDevise < ActiveRecord::Migration - def up - remove_column :users, :remember_token - add_column :users, :reset_password_sent_at, :datetime - end - - def down - add_column :users, :remember_token, :string - remove_column :users, :reset_password_sent_at - end -end diff --git a/db/migrate/20120909053122_remove_wallpaper_from_profile.rb b/db/migrate/20120909053122_remove_wallpaper_from_profile.rb deleted file mode 100644 index de903ae8a..000000000 --- a/db/migrate/20120909053122_remove_wallpaper_from_profile.rb +++ /dev/null @@ -1,9 +0,0 @@ -class RemoveWallpaperFromProfile < ActiveRecord::Migration - def up - remove_column :profiles, :wallpaper - end - - def down - add_column :profiles, :wallpaper, :string - end -end diff --git a/db/schema.rb b/db/schema.rb index 007a4077f..854ea9f02 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -22,8 +22,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "aspect_memberships", force: true do |t| t.integer "aspect_id", null: false t.integer "contact_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "aspect_memberships", ["aspect_id", "contact_id"], name: "index_aspect_memberships_on_aspect_id_and_contact_id", unique: true, using: :btree @@ -33,8 +33,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "aspect_visibilities", force: true do |t| t.integer "shareable_id", null: false t.integer "aspect_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "shareable_type", default: "Post", null: false end @@ -45,8 +45,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "aspects", force: true do |t| t.string "name", null: false t.integer "user_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "contacts_visible", default: true, null: false t.integer "order_id" end @@ -66,21 +66,21 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "guid", null: false t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.integer "likes_count", default: 0, null: false t.string "commentable_type", limit: 60, default: "Post", null: false end - add_index "comments", ["author_id"], name: "index_comments_on_author_id", using: :btree + add_index "comments", ["author_id"], name: "index_comments_on_person_id", using: :btree add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type", using: :btree add_index "comments", ["guid"], name: "index_comments_on_guid", unique: true, using: :btree create_table "contacts", force: true do |t| t.integer "user_id", null: false t.integer "person_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "sharing", default: false, null: false t.boolean "receiving", default: false, null: false end @@ -92,8 +92,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.integer "conversation_id", null: false t.integer "person_id", null: false t.integer "unread", default: 0, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "conversation_visibilities", ["conversation_id", "person_id"], name: "index_conversation_visibilities_usefully", unique: true, using: :btree @@ -104,8 +104,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "subject" t.string "guid", null: false t.integer "author_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "conversations", ["author_id"], name: "conversations_author_id_fk", using: :btree @@ -114,8 +114,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "token" t.integer "user_id" t.integer "count" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "invitations", force: true do |t| @@ -123,8 +123,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.integer "sender_id" t.integer "recipient_id" t.integer "aspect_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "service" t.string "identifier" t.boolean "admin", default: false @@ -142,24 +142,15 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "guid" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "target_type", limit: 60, null: false end add_index "likes", ["author_id"], name: "likes_author_id_fk", using: :btree add_index "likes", ["guid"], name: "index_likes_on_guid", unique: true, using: :btree add_index "likes", ["target_id", "author_id", "target_type"], name: "index_likes_on_target_id_and_author_id_and_target_type", unique: true, using: :btree - add_index "likes", ["target_id"], name: "index_likes_on_target_id", using: :btree - - create_table "locations", force: true do |t| - t.string "address" - t.string "lat" - t.string "lng" - t.integer "status_message_id" - t.datetime "created_at" - t.datetime "updated_at" - end + add_index "likes", ["target_id"], name: "index_likes_on_post_id", using: :btree create_table "mentions", force: true do |t| t.integer "post_id", null: false @@ -175,8 +166,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.integer "author_id", null: false t.string "guid", null: false t.text "text", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.text "author_signature" t.text "parent_author_signature" end @@ -187,8 +178,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "notification_actors", force: true do |t| t.integer "notification_id" t.integer "person_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "notification_actors", ["notification_id", "person_id"], name: "index_notification_actors_on_notification_id_and_person_id", unique: true, using: :btree @@ -200,8 +191,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.integer "target_id" t.integer "recipient_id", null: false t.boolean "unread", default: true, null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "type" end @@ -231,8 +222,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.integer "author_id" t.text "author_signature" t.text "parent_author_signature" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "participations", ["guid"], name: "index_participations_on_guid", using: :btree @@ -244,8 +235,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "diaspora_handle", null: false t.text "serialized_public_key", null: false t.integer "owner_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "closed_account", default: false t.integer "fetch_status", default: 0 end @@ -280,8 +271,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "pods", force: true do |t| t.string "host" t.boolean "ssl" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "poll_answers", force: true do |t| @@ -329,8 +320,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "remote_photo_name" t.string "random_string" t.string "processed_image" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "unprocessed_image" t.string "object_url" t.string "image_url" @@ -355,7 +346,7 @@ ActiveRecord::Schema.define(version: 20140824230505) do end add_index "posts", ["author_id", "root_guid"], name: "index_posts_on_author_id_and_root_guid", unique: true, using: :btree - add_index "posts", ["author_id"], name: "index_posts_on_author_id", using: :btree + add_index "posts", ["author_id"], name: "index_posts_on_person_id", using: :btree add_index "posts", ["guid"], name: "index_posts_on_guid", unique: true, using: :btree add_index "posts", ["id", "type", "created_at"], name: "index_posts_on_id_and_type_and_created_at", using: :btree add_index "posts", ["root_guid"], name: "index_posts_on_root_guid", using: :btree @@ -376,8 +367,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.text "bio" t.boolean "searchable", default: true, null: false t.integer "person_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "location" t.string "full_name", limit: 70 t.boolean "nsfw", default: false @@ -394,8 +385,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "table" t.integer "month", limit: 2 t.integer "year", limit: 8 - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "rails_admin_histories", ["item", "table", "month", "year"], name: "index_rails_admin_histories", using: :btree @@ -415,8 +406,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "roles", force: true do |t| t.integer "person_id" t.string "name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "services", force: true do |t| @@ -426,8 +417,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.string "access_token" t.string "access_secret" t.string "nickname" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "services", ["type", "uid"], name: "index_services_on_type_and_uid", using: :btree @@ -435,17 +426,17 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "share_visibilities", force: true do |t| t.integer "shareable_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.boolean "hidden", default: false, null: false t.integer "contact_id", null: false t.string "shareable_type", limit: 60, default: "Post", null: false end - add_index "share_visibilities", ["contact_id"], name: "index_share_visibilities_on_contact_id", using: :btree + add_index "share_visibilities", ["contact_id"], name: "index_post_visibilities_on_contact_id", using: :btree add_index "share_visibilities", ["shareable_id", "shareable_type", "contact_id"], name: "shareable_and_contact_id", using: :btree add_index "share_visibilities", ["shareable_id", "shareable_type", "hidden", "contact_id"], name: "shareable_and_hidden_and_contact_id", using: :btree - add_index "share_visibilities", ["shareable_id"], name: "index_share_visibilities_on_post_id", using: :btree + add_index "share_visibilities", ["shareable_id"], name: "index_post_visibilities_on_post_id", using: :btree create_table "simple_captcha_data", force: true do |t| t.string "key", limit: 40 @@ -459,8 +450,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "tag_followings", force: true do |t| t.integer "tag_id", null: false t.integer "user_id", null: false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end add_index "tag_followings", ["tag_id", "user_id"], name: "index_tag_followings_on_tag_id_and_user_id", unique: true, using: :btree @@ -492,8 +483,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do create_table "user_preferences", force: true do |t| t.string "email_type" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "users", force: true do |t| @@ -513,8 +504,8 @@ ActiveRecord::Schema.define(version: 20140824230505) do t.datetime "last_sign_in_at" t.string "current_sign_in_ip" t.string "last_sign_in_ip" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false t.string "invitation_service", limit: 127 t.string "invitation_identifier", limit: 127 t.integer "invitation_limit" From 858551387f35f0e15850d349bc66ac18508ed7ef Mon Sep 17 00:00:00 2001 From: Remco Huijdts Date: Thu, 28 Aug 2014 13:23:24 +0200 Subject: [PATCH 132/785] correct initial schema --- db/migrate/0000_create_schema.rb | 45 +++++++++++++++++++------------- 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/db/migrate/0000_create_schema.rb b/db/migrate/0000_create_schema.rb index 43d1f608c..c9fe48356 100644 --- a/db/migrate/0000_create_schema.rb +++ b/db/migrate/0000_create_schema.rb @@ -137,6 +137,15 @@ class CreateSchema < ActiveRecord::Migration add_index "likes", ["target_id", "author_id", "target_type"], :name => "index_likes_on_target_id_and_author_id_and_target_type", :unique => true add_index "likes", ["target_id"], :name => "index_likes_on_post_id" + create_table "locations", :force => true do |t| + t.string "address" + t.string "lat" + t.string "lng" + t.integer "status_message_id" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false + end + create_table "mentions", :force => true do |t| t.integer "post_id", :null => false t.integer "person_id", :null => false @@ -445,35 +454,35 @@ class CreateSchema < ActiveRecord::Migration add_index "users", ["invitation_token"], :name => "index_users_on_invitation_token" add_index "users", ["username"], :name => "index_users_on_username", :unique => true - add_foreign_key "aspect_memberships", "aspects", :name => "aspect_memberships_aspect_id_fk", :dependent => :delete - add_foreign_key "aspect_memberships", "contacts", :name => "aspect_memberships_contact_id_fk", :dependent => :delete + add_foreign_key "aspect_memberships", "aspects", name: "aspect_memberships_aspect_id_fk", dependent: :delete + add_foreign_key "aspect_memberships", "contacts", name: "aspect_memberships_contact_id_fk", dependent: :delete - add_foreign_key "aspect_visibilities", "aspects", :name => "aspect_visibilities_aspect_id_fk", :dependent => :delete + add_foreign_key "aspect_visibilities", "aspects", name: "aspect_visibilities_aspect_id_fk", dependent: :delete - add_foreign_key "comments", "people", :name => "comments_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "comments", "people", name: "comments_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "contacts", "people", :name => "contacts_person_id_fk", :dependent => :delete + add_foreign_key "contacts", "people", name: "contacts_person_id_fk", dependent: :delete - add_foreign_key "conversation_visibilities", "conversations", :name => "conversation_visibilities_conversation_id_fk", :dependent => :delete - add_foreign_key "conversation_visibilities", "people", :name => "conversation_visibilities_person_id_fk", :dependent => :delete + add_foreign_key "conversation_visibilities", "conversations", name: "conversation_visibilities_conversation_id_fk", dependent: :delete + add_foreign_key "conversation_visibilities", "people", name: "conversation_visibilities_person_id_fk", dependent: :delete - add_foreign_key "conversations", "people", :name => "conversations_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "conversations", "people", name: "conversations_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "invitations", "users", :name => "invitations_recipient_id_fk", :column => "recipient_id", :dependent => :delete - add_foreign_key "invitations", "users", :name => "invitations_sender_id_fk", :column => "sender_id", :dependent => :delete + add_foreign_key "invitations", "users", name: "invitations_recipient_id_fk", column: "recipient_id", dependent: :delete + add_foreign_key "invitations", "users", name: "invitations_sender_id_fk", column: "sender_id", dependent: :delete - add_foreign_key "likes", "people", :name => "likes_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "likes", "people", name: "likes_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "messages", "conversations", :name => "messages_conversation_id_fk", :dependent => :delete - add_foreign_key "messages", "people", :name => "messages_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "messages", "conversations", name: "messages_conversation_id_fk", dependent: :delete + add_foreign_key "messages", "people", name: "messages_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "notification_actors", "notifications", :name => "notification_actors_notification_id_fk", :dependent => :delete + add_foreign_key "notification_actors", "notifications", name: "notification_actors_notification_id_fk", dependent: :delete - add_foreign_key "posts", "people", :name => "posts_author_id_fk", :column => "author_id", :dependent => :delete + add_foreign_key "posts", "people", name: "posts_author_id_fk", column: "author_id", dependent: :delete - add_foreign_key "profiles", "people", :name => "profiles_person_id_fk", :dependent => :delete + add_foreign_key "profiles", "people", name: "profiles_person_id_fk", dependent: :delete - add_foreign_key "services", "users", :name => "services_user_id_fk", :dependent => :delete + add_foreign_key "services", "users", name: "services_user_id_fk", dependent: :delete - add_foreign_key "share_visibilities", "contacts", :name => "post_visibilities_contact_id_fk", :dependent => :delete + add_foreign_key "share_visibilities", "contacts", name: "post_visibilities_contact_id_fk", dependent: :delete end From 3f3087c77f5bfa92147fc29c77d0a3f4b14a2273 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Fri, 22 Aug 2014 03:26:31 +0200 Subject: [PATCH 133/785] Port tags page to Bootstrap --- Changelog.md | 1 + .../app/views/tag_following_action_view.js | 12 +- app/assets/stylesheets/application.css.sass | 10 +- app/assets/stylesheets/comments.css.scss | 41 +++ app/assets/stylesheets/default.css.scss | 1 - app/assets/stylesheets/new-templates.css.scss | 4 + .../stylesheets/new_styles/_buttons.css.scss | 26 ++ .../stylesheets/new_styles/_interactions.scss | 230 ++----------- .../stylesheets/single-post-view.css.scss | 85 +---- app/assets/stylesheets/stream.css.scss | 6 + .../stylesheets/stream_element.css.scss | 308 +++++------------- .../stream_element_blueprint.css.scss | 288 ++++++++++++++++ app/assets/stylesheets/tag.css.scss | 4 + app/assets/stylesheets/tags.css.scss | 20 -- app/assets/templates/likes-info_tpl.jst.hbs | 2 +- .../tag_following_action_tpl.jst.hbs | 12 +- app/controllers/tags_controller.rb | 3 + app/views/people/_index.html.haml | 20 +- app/views/people/tag_index.js.erb | 2 +- .../publisher/_publisher_bootstrap.html.haml | 2 +- app/views/tags/show.haml | 47 ++- features/step_definitions/custom_web_steps.rb | 2 +- spec/integration/tag_people_spec.rb | 2 +- .../views/tag_following_action_view_spec.js | 4 +- 24 files changed, 532 insertions(+), 600 deletions(-) create mode 100644 app/assets/stylesheets/comments.css.scss create mode 100644 app/assets/stylesheets/stream.css.scss create mode 100644 app/assets/stylesheets/stream_element_blueprint.css.scss delete mode 100644 app/assets/stylesheets/tags.css.scss diff --git a/Changelog.md b/Changelog.md index 5c4fc0683..98f8ae0ba 100644 --- a/Changelog.md +++ b/Changelog.md @@ -19,6 +19,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Redesign contacts page [#5153](https://github.com/diaspora/diaspora/pull/5153) * Improve profile page design on mobile [#5084](https://github.com/diaspora/diaspora/pull/5084) * Port testsuite to RSpec 3 [#5170](https://github.com/diaspora/diaspora/pull/5170) +* Port tag stream to Bootstrap [#5138](https://github.com/diaspora/diaspora/pull/5138) ## Bug fixes * orca cannot see 'Add Contact' button [#5158](https://github.com/diaspora/diaspora/pull/5158) diff --git a/app/assets/javascripts/app/views/tag_following_action_view.js b/app/assets/javascripts/app/views/tag_following_action_view.js index fbfe2bae2..ce8dc8e30 100644 --- a/app/assets/javascripts/app/views/tag_following_action_view.js +++ b/app/assets/javascripts/app/views/tag_following_action_view.js @@ -3,9 +3,9 @@ app.views.TagFollowingAction = app.views.Base.extend({ templateName: "tag_following_action", events : { - "mouseenter .button.red_on_hover": "mouseIn", - "mouseleave .button.red_on_hover": "mouseOut", - "click .button": "tagAction" + "mouseenter .btn.followed": "mouseIn", + "mouseleave .btn.followed": "mouseOut", + "click .btn": "tagAction" }, initialize : function(options){ @@ -41,12 +41,12 @@ app.views.TagFollowingAction = app.views.Base.extend({ }, mouseIn : function(){ - this.$("input").removeClass("in_aspects"); + this.$("input").removeClass("green").addClass("btn-danger"); this.$("input").val( Diaspora.I18n.t('stream.tags.stop_following', {tag: this.model.attributes.name} ) ); }, mouseOut : function() { - this.$("input").addClass("in_aspects"); + this.$("input").removeClass("btn-danger").addClass("green"); this.$("input").val( Diaspora.I18n.t('stream.tags.following', {"tag" : this.model.attributes.name} ) ); }, @@ -59,4 +59,4 @@ app.views.TagFollowingAction = app.views.Base.extend({ app.tagFollowings.create(this.model); } } -}); \ No newline at end of file +}); diff --git a/app/assets/stylesheets/application.css.sass b/app/assets/stylesheets/application.css.sass index cbe7ee39f..376babb34 100644 --- a/app/assets/stylesheets/application.css.sass +++ b/app/assets/stylesheets/application.css.sass @@ -19,7 +19,7 @@ @import 'aspects' @import 'stream-faces' @import 'popover' -@import 'stream_element' +@import 'stream_element_blueprint' @import 'report' @import 'new_styles/_forms' @import 'tag' @@ -769,12 +769,10 @@ ul#press_logos :color $text-grey .likes - .icons-heart - :height 12px - :width 13px - :display inline-block + .entypo.heart + :font-size 16px + :line-height 16px :vertical-align top - :margin-top 3px :margin-right 5px .bd diff --git a/app/assets/stylesheets/comments.css.scss b/app/assets/stylesheets/comments.css.scss new file mode 100644 index 000000000..681bca066 --- /dev/null +++ b/app/assets/stylesheets/comments.css.scss @@ -0,0 +1,41 @@ +.comment_stream { + .show_comments { + margin-top: 5px; + border-top: 1px solid $border-grey; + a { + color: $text-grey; + font-size: 13px; + } + .media { margin-top: 10px; } + } + .comments > .comment { + .avatar { + height: 30px; + width: 30px; + } + margin: 0; + border-top: 1px dotted $border-grey; + &.no-border { border: none; } + padding: 10px 0; + .comment-content p:last-of-type { margin-bottom: 0; } + + .info { + margin-top: 5px; + font-size: 11px; + line-height: 11px; + } + + >.highlighted { + border-left: 3px solid $blue; + padding-left: 3px; + } + } + .submit_button { + input { + float: right; + } + padding-left: 12px; + width: 95%; + } + .comment_box { width: 95%; } +} diff --git a/app/assets/stylesheets/default.css.scss b/app/assets/stylesheets/default.css.scss index d981555da..5dd0f979a 100644 --- a/app/assets/stylesheets/default.css.scss +++ b/app/assets/stylesheets/default.css.scss @@ -3,7 +3,6 @@ *= require lightbox *= require autocomplete *= require mentions -*= require tags *= require hovercard *= require vendor/interim-bootstrap diff --git a/app/assets/stylesheets/new-templates.css.scss b/app/assets/stylesheets/new-templates.css.scss index e98b7bc6b..98b38fdc3 100644 --- a/app/assets/stylesheets/new-templates.css.scss +++ b/app/assets/stylesheets/new-templates.css.scss @@ -10,6 +10,7 @@ @import 'new_styles/base'; @import 'new_styles/buttons'; +@import 'new_styles/interactions'; /* font overrides */ @import 'new_styles/typography'; @@ -62,6 +63,9 @@ /* stream */ @import 'tag'; @import 'stream-faces'; +@import 'stream'; +@import 'stream_element'; +@import 'comments'; /* contacts */ @import 'contacts'; diff --git a/app/assets/stylesheets/new_styles/_buttons.css.scss b/app/assets/stylesheets/new_styles/_buttons.css.scss index 2b0817086..b8257ca8f 100644 --- a/app/assets/stylesheets/new_styles/_buttons.css.scss +++ b/app/assets/stylesheets/new_styles/_buttons.css.scss @@ -29,3 +29,29 @@ } .btn.delete { color: desaturate($red,10%); } + +// TODO remove this when everything has been ported to Bootstrap +.button.creation { + $button-border-color: #aaa; + @include border-radius(3px); + @include box-shadow(0,1px,1px,#cfcfcf); + @include transition(border); + @include button-gradient($creation-blue); + font: { + size: 12px; + } + color: #fff; + padding: 4px 9px; + min-width: 90px; + min-height: 10px; + border: 1px solid darken($button-border-color,20%); + + cursor: pointer; + white-space: nowrap; + + &:hover { + @include button-gradient-hover($creation-blue); + border: 1px solid darken($button-border-color,35%); + text-decoration: none; + } + } diff --git a/app/assets/stylesheets/new_styles/_interactions.scss b/app/assets/stylesheets/new_styles/_interactions.scss index a0e12d638..63858cb6b 100644 --- a/app/assets/stylesheets/new_styles/_interactions.scss +++ b/app/assets/stylesheets/new_styles/_interactions.scss @@ -1,224 +1,32 @@ -@import '../mixins'; - -#post-info { - text-align: center; - z-index: 10; - - margin-top: -33px; - - #post-info-container { - @include info-container(); - } - - .well { - -webkit-box-shadow: inset 0 2px 2px rgba(0,0,0,0.10); - -moz-box-shadow: inset 0 2px 2px rgba(0,0,0,0.10); - box-shadow: inset 0 2px 2px rgba(0,0,0,0.10); - - margin: 5px; - padding: 5px; - text-align: left; - - max-height: 20px; - overflow: hidden; - - background: { - color: #222; - color: rgba(0,0,0,0.2); - } - - border: { - left: 1px solid #444; - right: 1px solid #444; - bottom: 1px solid #555; - top: 1px solid #111; - } - - .img { - margin-right: 5px; - } - - i { - margin-top: 1px; - } - - .avatar { - @include border-radius(); - margin-right: 0; - } - } - - #post-comments { - text-align: left; - padding-top: 0; - } - - #new-post-comment-container { - position: relative; - - padding: 10px; - - textarea{ - height: 18px; - width: 318px; - padding: 4px; - } - - form { - margin-bottom: 0; - } - - .btn { - position: absolute; - right: 10px; - bottom: 10px; - font-size: 11px; - line-height: 16px; - padding: 5px 9px; - } - } -} - -.comment-content h1, .comment-content h2, .comment-content h3, .comment-content h4, .comment-content h5, .comment-content h6 { - color: white; - text-shadow: 1px 1px black; - text-rendering: optimizelegibility; -} - -.post-comment { - -moz-box-shadow: 0 1px 2px -2px #999; - -webkit-box-shadow: 0 1px 2px -2px #999; - box-shadow: 0 1px 2px -2px #999; - - border-bottom: 1px solid #333; - - p:last-child { - margin-bottom: 0; - } - - &:last-child { - box-shadow: none; - border-bottom: none; - } - - padding: 10px; - padding-right: 40px; - margin: 0px; - - .avatar { - @include border-radius(); - - border: { - top: 1px solid #222; - right: 1px solid #444; - left: 1px solid #444; - bottom: 1px solid $text-dark-grey; - } - } - - text-shadow: 0 1px 3px rgba(0,0,0,0.3); - - a:hover { - color: #99CCFF - } - - time { - color: $text-dark-grey; - font-size: smaller; - } - +.stream_container, #single-post-interactions { .controls { - @include transition(opacity); - @include opacity(0); - + z-index: 6; float: right; - margin-right: -40px; - - a { - padding: 3px 5px; - &:hover { - text-decoration: none; + .comment_report { + display: inline-block; + .icons-report { + height: 14px; + width: 14px; } } - } - - &:hover { - .controls { - @include opacity(0.4); - - &:hover { - @include opacity(1); + .delete { + display: inline-block; + .icons-deletelabel { + height: 14px; + width: 14px; } } - } -} - -.permalink-wrapper, -#user-controls { - height: 30px; - - .avatar { - vertical-align: top; - height: 27px; - width: 27px; - } - - a { - @include opacity(0.6); - @include transition(opacity, 0.3s); - - position: relative; - - z-index: 20; - - padding: 1px 4px 0; - margin-right: 5px; - line-height: 24px; - - i { - padding: 0; - margin: 0; - } - - color: #fff; - - &.label { - @include box-shadow(0, 0, 2px, rgba(255,255,255,0.9)); - background-color: #000; - } - - &.comment { - padding-right: 5px; - margin-right: 0; - } - - &:hover { - @include opacity(1); + & > a:hover { text-decoration: none; } } -} -/* stream specific wrapper */ -#stream-interactions { - position : fixed; - top : 0; - bottom : 0; - overflow-y : auto; + .stream_element, .comment, .stream_element:hover .comment { + .controls > a { @include opacity(0); } - #post-info { - text-align : left; - margin-top : 10px; - } - - #user-controls { - padding : 7px; + &:hover .controls { + & > a { @include opacity(0.3); } + & > a:hover { @include opacity(1); } + } } } - -.permalink-wrapper { - float : right; - margin-top : 9px; - margin-right : -5px; - margin-left : 4px; -} diff --git a/app/assets/stylesheets/single-post-view.css.scss b/app/assets/stylesheets/single-post-view.css.scss index cf6ffa3d6..2fbb51001 100644 --- a/app/assets/stylesheets/single-post-view.css.scss +++ b/app/assets/stylesheets/single-post-view.css.scss @@ -135,9 +135,11 @@ padding-left: 15px; .comments .comment { + border-top: none; border-bottom: solid 1px #cccccc; padding-top: 10px; padding-bottom: 10px; + margin: 10px; p { margin: 0 0 1em 0; word-wrap: break-word; @@ -145,6 +147,10 @@ margin-bottom: 0; } } + .avatar { + height: 35px; + width: 35px; + } } .no_comments { padding-top: 10px; @@ -155,18 +161,12 @@ margin-bottom: 30px; } - textarea { - width: 95%; - } .new_comment_form_wrapper { border-bottom: none; } a { color: #3f8fba; } - .timeago { - font-size: smaller; - } .count { i { display: inline-block; @@ -186,76 +186,3 @@ margin-bottom: 8px; } } - -.comment { - &:hover { - .controls { - @include opacity(0.3); - } - } - - >.highlighted { - border-left: 3px solid $blue; - padding-left: 3px; - } - - .controls { - @include transition(opacity); - @include opacity(0); - z-index: 6; - float: right; - &:hover { - @include opacity(1); - } - .comment_report { - display: inline-block; - .icons-report { - height: 14px; - width: 14px; - } - } - .delete { - display: inline-block; - .icons-deletelabel { - height: 14px; - width: 14px; - } - } - a:hover { - text-decoration: none; - } - } - .submit_button { - input { - float: right; - } - padding-left: 12px; - width: 95%; - } - - .button.creation { - $button-border-color: #aaa; - @include border-radius(3px); - @include box-shadow(0,1px,1px,#cfcfcf); - @include transition(border); - @include button-gradient($creation-blue); - font: { - size: 12px; - } - color: #fff; - padding: 4px 9px; - min-width: 90px; - min-height: 10px; - border: 1px solid darken($button-border-color,20%); - - cursor: pointer; - white-space: nowrap; - - &:hover { - @include button-gradient-hover($creation-blue); - border: 1px solid darken($button-border-color,35%); - text-decoration: none; - } - } -} - diff --git a/app/assets/stylesheets/stream.css.scss b/app/assets/stylesheets/stream.css.scss new file mode 100644 index 000000000..ca012bfe3 --- /dev/null +++ b/app/assets/stylesheets/stream.css.scss @@ -0,0 +1,6 @@ +.stream_container { + #publisher { + margin-bottom: 30px; + } + .well#ignore-info { text-align: center; } +} diff --git a/app/assets/stylesheets/stream_element.css.scss b/app/assets/stylesheets/stream_element.css.scss index 249bab9db..f40c606bf 100644 --- a/app/assets/stylesheets/stream_element.css.scss +++ b/app/assets/stylesheets/stream_element.css.scss @@ -1,251 +1,91 @@ -.stream { - audio { - display: block; - margin: 5px 0; - } +#main_stream .stream_element { + padding: 10px; + border-bottom: 1px solid $border-grey; - .stream_element { - border-bottom: 1px solid $border-grey; - - h1, h2, h3, h4, h5, h6 { - word-wrap: break-word; - word-break: break-word; + & > .media { + margin: 0; + & > .img > .avatar.small { + height: 50px; + width: 50px; } - - p { - &:last-child { - padding-bottom: 0; - margin-bottom: 0; + .author { + font-weight: bold; + margin-bottom: 4px; + unicode-bidi: bidi-override; + } + .feedback { + margin-top: 5px; + font-size: 11px; + line-height: 11px; + } + .likes { + margin-top: 10px; + font-size: 12px; + line-height: 16px; + .bd { display: inline-block; } + .entypo.heart { + display: inline-block; + font-size: 16px; + vertical-align: top; + margin-top: -2px; + margin-right: 5px; } } - - &:first-child { - border-top: none; - } - - ul { - li { - list-style: disc; - } - } - .youtube-player, .vimeo-player { border: none; height: 304px; width: 410px; } - } -} - -.stream_element { - &.highlighted { border-left: 3px solid $blue; } - - a.author { - font-weight: bold; - unicode-bidi: bidi-override; + .photo_attachments { + margin-top: 7px; + padding-bottom: 10px; + text-align: center; + img { + &.big_stream_photo { + display: block; + max-width: 90%; + } + &.thumb_small { + display: inline; + max-width: 50px; + max-height: 50px; + } + margin-left: auto; + margin-right: auto; + padding-bottom: 5px; + } + } + .stream_photo { + float: left; + margin-top: 6px; + } + .status-message-location .near-from { + font-size: 11px; + color: $text-grey; + } + .grey { color: $text-grey; } + .post-content p:last-of-type { margin-bottom: 0; } + .nsfw-shield { + color: $text-grey; + padding: 5px 10px; + background-color: $background-grey; + border: 1px solid $border-grey; + border-radius: 3px; + } } - .photo_attachments { - margin-top: 7px; - } - - img { - max-width: 100%; - } - - .bd { - > img { + .reshare > .media { + border-left: 2px solid $border-grey; + .avatar { height: 30px; width: 30px; - float: left; - margin-right: 10px; } } - .info { - font-size: 11px; - } - - .stream_photo { - float: left; - margin-top: 6px; - } - - .controls:first-child { - .control_icon { - @include transition(opacity); - @include opacity(0); - } - } - - &:hover { - .controls:first-child { - .control_icon { - @include opacity(0.3); - } - .control_icon:hover { - @include opacity(1); - } - } - } -} - -.status_message_show { - .comment_box { - width: 653px; - margin-bottom: 5px; - } -} - -.post_scope { - cursor: default; -} - -.stream_element .reshare, -.comment { - .avatar { - width: 30px; - height: 30px; - } -} - -.likes, -.stream_element div.reshare { - font-size: 12px; -} - -.comment, .stream_element { - >.highlighted { - border-left: 3px solid $blue; - padding-left: 3px; - } -} - -.comment.no-border { - &.media { - border: none; - padding: 0; - } -} - -.comment { - &.media { - margin-left: 0; - margin-right: 0; - - border-top: 1px dotted #aaa; - - padding-top: 10px; - - .controls { - .comment_delete, .comment_report { - @include transition(opacity); - @include opacity(0); - } - } - &:hover { - .controls { - .comment_delete, .comment_report { - @include opacity(0.3); - } - .comment_delete:hover, .comment_report:hover { - @include opacity(1); - } - } - } - } - - .youtube-player, .vimeo-player { - border: none; - height: 250px; - width: 400px; - } - - .ltr { - ol, ul { - padding-left: 2em; - li { - padding: 0px; - border: none; - list-style: inherit; - } - } - } - - .right { - right: 4px; - } -} - -.stream_element { - .new_comment_form_wrapper { - width: 415px; - } -} - -.stream_element .bd { - & > .likes, & > .comments { - margin-right: 15px; - } -} - -.status-message-location { - .near-from { - font-size: smaller; - color: #aaa; - width: 100%; - float: left; - } - .address { - font-size: 11px; - color: #bbb; - } -} - -.stream_element .post-content .reshare { - border-left: 2px solid $border-grey; -} - -.stream_element.loaded .media .bd .feedback { - clear: both; -} - -form.new_comment { - input { - display: none; - } - - textarea { - height: 21px; - font-size: 12px; - width: 364px; - } - - &.open { - input { - display: block; - } - } -} - -.stream_element { - .subject { - font-size: 13px; - font-weight: bold; - color: #444; - overflow: hidden; - white-space: nowrap; - } - - .last_author { - font-size: 12px; - color: $text-dark-grey; - } - .collapsible { overflow: hidden; position: relative; - + p { margin: 0 0 0.8em; } @@ -285,4 +125,14 @@ form.new_comment { } } } + + &.highlighted { + padding-left: 8px; + border-left: 3px solid $creation-blue; + } + + &.post_preview { + background-color: lighten($creation-blue,45%); + border: 1px solid $creation-blue; + } } diff --git a/app/assets/stylesheets/stream_element_blueprint.css.scss b/app/assets/stylesheets/stream_element_blueprint.css.scss new file mode 100644 index 000000000..0867dc5c4 --- /dev/null +++ b/app/assets/stylesheets/stream_element_blueprint.css.scss @@ -0,0 +1,288 @@ +.stream { + audio { + display: block; + margin: 5px 0; + } + + .stream_element { + border-bottom: 1px solid $border-grey; + + h1, h2, h3, h4, h5, h6 { + word-wrap: break-word; + word-break: break-word; + } + + p { + &:last-child { + padding-bottom: 0; + margin-bottom: 0; + } + } + + &:first-child { + border-top: none; + } + + ul { + li { + list-style: disc; + } + } + + .youtube-player, .vimeo-player { + border: none; + height: 304px; + width: 410px; + } + } +} + +.stream_element { + &.highlighted { border-left: 3px solid $blue; } + + a.author { + font-weight: bold; + unicode-bidi: bidi-override; + } + + .photo_attachments { + margin-top: 7px; + } + + img { + max-width: 100%; + } + + .bd { + > img { + height: 30px; + width: 30px; + float: left; + margin-right: 10px; + } + } + + .info { + font-size: 11px; + } + + .stream_photo { + float: left; + margin-top: 6px; + } + + .controls:first-child { + .control_icon { + @include transition(opacity); + @include opacity(0); + } + } + + &:hover { + .controls:first-child { + .control_icon { + @include opacity(0.3); + } + .control_icon:hover { + @include opacity(1); + } + } + } +} + +.status_message_show { + .comment_box { + width: 653px; + margin-bottom: 5px; + } +} + +.post_scope { + cursor: default; +} + +.stream_element .reshare, +.comment { + .avatar { + width: 30px; + height: 30px; + } +} + +.likes, +.stream_element div.reshare { + font-size: 12px; +} + +.comment, .stream_element { + >.highlighted { + border-left: 3px solid $blue; + padding-left: 3px; + } +} + +.comment.no-border { + &.media { + border: none; + padding: 0; + } +} + +.comment { + &.media { + margin-left: 0; + margin-right: 0; + + border-top: 1px dotted #aaa; + + padding-top: 10px; + + .controls { + .comment_delete, .comment_report { + @include transition(opacity); + @include opacity(0); + } + } + &:hover { + .controls { + .comment_delete, .comment_report { + @include opacity(0.3); + } + .comment_delete:hover, .comment_report:hover { + @include opacity(1); + } + } + } + } + + .youtube-player, .vimeo-player { + border: none; + height: 250px; + width: 400px; + } + + .ltr { + ol, ul { + padding-left: 2em; + li { + padding: 0px; + border: none; + list-style: inherit; + } + } + } + + .right { + right: 4px; + } +} + +.stream_element { + .new_comment_form_wrapper { + width: 415px; + } +} + +.stream_element .bd { + & > .likes, & > .comments { + margin-right: 15px; + } +} + +.status-message-location { + .near-from { + font-size: smaller; + color: #aaa; + width: 100%; + float: left; + } + .address { + font-size: 11px; + color: #bbb; + } +} + +.stream_element .post-content .reshare { + border-left: 2px solid $border-grey; +} + +.stream_element.loaded .media .bd .feedback { + clear: both; +} + +form.new_comment { + input { + display: none; + } + + textarea { + height: 21px; + font-size: 12px; + width: 364px; + } + + &.open { + input { + display: block; + } + } +} + +.stream_element { + .subject { + font-size: 13px; + font-weight: bold; + color: #444; + overflow: hidden; + white-space: nowrap; + } + + .last_author { + font-size: 12px; + color: $text-dark-grey; + } + + .collapsible { + overflow: hidden; + position: relative; + + p { + margin: 0 0 0.8em; + } + p:last-of-type { + margin: 0; + } + + .expander { + position: absolute; + bottom: 0; + left: 0; + right: 0; + height: 30px; + text-align: center; + line-height: 48px; + font-size: .8em; + color: $grey; + text-shadow: 0 0 7px #FFF; + cursor: pointer; + border-bottom: 2px solid $border-grey; + @include border-radius(0, 0, 3px, 3px); + @include linear-gradient(rgba(255,255,255,0) , #EEE, 0%, 95%); + background-color: transparent; + } + + .oembed { + background: image-url('ajax-loader2.gif') no-repeat center center; + float: left; + width: 100%; + + .thumb { + @include video-overlay(); + } + + iframe, .thumb img { + width: 100%; + } + } + } +} diff --git a/app/assets/stylesheets/tag.css.scss b/app/assets/stylesheets/tag.css.scss index 3c5b54cc5..1ee8427bb 100644 --- a/app/assets/stylesheets/tag.css.scss +++ b/app/assets/stylesheets/tag.css.scss @@ -20,3 +20,7 @@ h1.tag { &:hover { border-bottom: 1px solid $border-dark-grey; } } } + +#tags_show { + .span3 { border-right: 1px solid $border-grey; } +} diff --git a/app/assets/stylesheets/tags.css.scss b/app/assets/stylesheets/tags.css.scss deleted file mode 100644 index 189531472..000000000 --- a/app/assets/stylesheets/tags.css.scss +++ /dev/null @@ -1,20 +0,0 @@ -// Copyright (c) 2010-2011, Diaspora Inc. This file is -// licensed under the Affero General Public License version 3 or later. See -// the COPYRIGHT file. - -.tags_show { - .side_stream { - .stream_element { - .add_contact { - display: inline; - float: right; - font-size: 10px; - .button { - padding: 5px 1px 4px 1px; - margin-right: 3px; - font-size: 10px; - } - } - } - } -} diff --git a/app/assets/templates/likes-info_tpl.jst.hbs b/app/assets/templates/likes-info_tpl.jst.hbs index 0af32bb90..c9cfceee1 100644 --- a/app/assets/templates/likes-info_tpl.jst.hbs +++ b/app/assets/templates/likes-info_tpl.jst.hbs @@ -1,7 +1,7 @@ {{#if likesCount}}
-
+
{{#unless likes_fetched}} diff --git a/app/assets/templates/tag_following_action_tpl.jst.hbs b/app/assets/templates/tag_following_action_tpl.jst.hbs index 606f6778f..134996113 100644 --- a/app/assets/templates/tag_following_action_tpl.jst.hbs +++ b/app/assets/templates/tag_following_action_tpl.jst.hbs @@ -1,10 +1,12 @@ -
+
-
-
\ No newline at end of file +
diff --git a/app/controllers/tags_controller.rb b/app/controllers/tags_controller.rb index 9cea03112..0ac704c32 100644 --- a/app/controllers/tags_controller.rb +++ b/app/controllers/tags_controller.rb @@ -6,6 +6,9 @@ class TagsController < ApplicationController skip_before_action :set_grammatical_gender before_action :ensure_page, :only => :show + layout ->(c) { request.format == :mobile ? "application" : "with_header_with_footer" }, :only => [:show] + use_bootstrap_for :show + helper_method :tag_followed? respond_to :html, :only => [:show] diff --git a/app/views/people/_index.html.haml b/app/views/people/_index.html.haml index 0c90823e6..82c069364 100644 --- a/app/views/people/_index.html.haml +++ b/app/views/people/_index.html.haml @@ -1,11 +1,13 @@ -.people_stream +#people_stream - people.each do |person| - .stream_element{:id => person.id} - .media - .img - = person_image_tag(person) - .bg - %span.from - = person_link(person, :class => "hovercardable") + .media.stream_element{:id => person.id} + .media-object.pull-left + = person_image_link(person, :size => :thumb_small) + .media-body + = person_link(person, :class => 'name') + .info.diaspora_handle + = person.diaspora_handle + .info.tags + = Diaspora::Taggable.format_tags(person.profile.tag_string) - = will_paginate people, :inner_window => 3 + = will_paginate people, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer diff --git a/app/views/people/tag_index.js.erb b/app/views/people/tag_index.js.erb index a683b2227..c30450e3e 100644 --- a/app/views/people/tag_index.js.erb +++ b/app/views/people/tag_index.js.erb @@ -1 +1 @@ -$(".people_stream").html("<%= escape_javascript(render("index", :people => @people)) %>"); +$("#people_stream").html("<%= escape_javascript(render("index", :people => @people)) %>"); diff --git a/app/views/publisher/_publisher_bootstrap.html.haml b/app/views/publisher/_publisher_bootstrap.html.haml index 3c2478cb9..627f7258e 100644 --- a/app/views/publisher/_publisher_bootstrap.html.haml +++ b/app/views/publisher/_publisher_bootstrap.html.haml @@ -57,7 +57,7 @@ = image_tag 'ajax-loader.gif' .row-fluid.options_and_submit .public_toggle - %button.btn.btn-default.pull-left#hide_publisher{:title => t('shared.publisher.discard_post')} + .btn.btn-default.pull-left#hide_publisher{:title => t('shared.publisher.discard_post')} %span.text =t('cancel') diff --git a/app/views/tags/show.haml b/app/views/tags/show.haml index 4f0cc3469..d403efba8 100644 --- a/app/views/tags/show.haml +++ b/app/views/tags/show.haml @@ -8,37 +8,30 @@ - else = t('.whatup', :pod => @pod_url) +.container-fluid#tags_show + .row-fluid + .span3.offset1 + %h3 + = t('people', :count => @stream.tagged_people_count) -- content_for :body_class do - = "tags_show" + .side_stream.stream + = render :partial => 'people/index', :locals => {:people => @stream.tagged_people} -#leftNavBar - %h3 - = t('people', :count => @stream.tagged_people_count) + .span7 + .stream_container + #author_info + %h2 + = @stream.display_tag_name - .side_stream.stream - = render :partial => 'people/index', :locals => {:people => @stream.tagged_people} + - if current_user + = render 'publisher/publisher', :selected_aspects => @stream.aspect_ids, :aspect_ids => @stream.aspect_ids, :aspect => @stream.aspect - %br + %hr - - if user_signed_in? - = render "tags/followed_tags_listings" + #main_stream.stream -.span-15.last - .stream_container - #author_info - %h2 - = @stream.display_tag_name + #paginate + %span.loader.hidden - - if current_user - = render 'publisher/publisher', :selected_aspects => @stream.aspect_ids, :aspect_ids => @stream.aspect_ids, :aspect => @stream.aspect - - %hr - - #main_stream.stream - - #paginate - %span.loader.hidden - - %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} - ⇧ + %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} + ⇧ diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index 0660b918e..e74f7168f 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -165,7 +165,7 @@ end When /^I search for "([^\"]*)"$/ do |search_term| fill_in "q", :with => search_term find_field("q").native.send_key(:enter) - find("#leftNavBar") + find("#tags_show .span3") end Then /^the "([^"]*)" field(?: within "([^"]*)")? should be filled with "([^"]*)"$/ do |field, selector, value| diff --git a/spec/integration/tag_people_spec.rb b/spec/integration/tag_people_spec.rb index 86c86eb56..9dc6db029 100644 --- a/spec/integration/tag_people_spec.rb +++ b/spec/integration/tag_people_spec.rb @@ -22,7 +22,7 @@ describe TagsController, :type => :request do get "/tags/#{tag}", page: 2 expect(response.status).to eq(200) - expect(response.body).to match(/2<\/em>/) + expect(response.body).to match(/
  • 2<\/a><\/li>/) end end end diff --git a/spec/javascripts/app/views/tag_following_action_view_spec.js b/spec/javascripts/app/views/tag_following_action_view_spec.js index f2fbefc07..29f8b275c 100644 --- a/spec/javascripts/app/views/tag_following_action_view_spec.js +++ b/spec/javascripts/app/views/tag_following_action_view_spec.js @@ -14,8 +14,8 @@ describe("app.views.TagFollowingAction", function(){ it("should have the extra classes if the tag is followed", function(){ spyOn(this.view, "tag_is_followed").and.returnValue(true) - expect(this.view.render().$('input').hasClass("red_on_hover")).toBe(true) - expect(this.view.render().$('input').hasClass("in_aspects")).toBe(true) + expect(this.view.render().$('input').hasClass("followed")).toBe(true) + expect(this.view.render().$('input').hasClass("green")).toBe(true) }) }) From 462198799b90ca110ac565793fcf486290cb85c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Thu, 28 Aug 2014 21:04:29 +0200 Subject: [PATCH 134/785] Dynamic asset paths everywhere * Use asset pipeline aware helpers in CSS files * Add js_image_paths to push image asset names to the client side JS --- Changelog.md | 2 ++ Gemfile | 1 + Gemfile.lock | 3 +++ app/assets/javascripts/app/app.js | 9 ++----- .../app/helpers/handlebars-helpers.js | 4 +-- .../javascripts/app/views/location_view.js | 4 +-- app/assets/javascripts/inbox.js | 2 +- app/assets/javascripts/main.js | 1 + app/assets/javascripts/mobile.js | 6 ++--- app/assets/javascripts/view.js | 2 +- .../javascripts/widgets/infinite-scroll.js | 2 +- app/assets/javascripts/widgets/lightbox.js | 2 +- app/assets/stylesheets/header.css.scss | 2 +- app/assets/stylesheets/mobile/header.css.scss | 26 +++++++++---------- .../{autoSuggest.css => autoSuggest.css.erb} | 18 ++++++------- app/helpers/layout_helper.rb | 9 ------- app/models/profile.rb | 2 +- app/views/layouts/application.html.haml | 1 - 18 files changed, 44 insertions(+), 52 deletions(-) rename app/assets/stylesheets/vendor/{autoSuggest.css => autoSuggest.css.erb} (92%) diff --git a/Changelog.md b/Changelog.md index 5c4fc0683..b0f05a979 100644 --- a/Changelog.md +++ b/Changelog.md @@ -12,6 +12,8 @@ Rails.application.config.secret_token = '***********...' Diaspora::Application.config.secret_key_base = '*************...' ``` +You also need to take care to set `RAILS_ENV` while precompiling assets: `RAILS_ENV=production bundle exec rake assets:precompile` + ## Change in defaults.yml The default for including jQuery from a CDN has changed. If you want to continue to include it from a CDN, please explicitly set the `jquery_cdn` setting to `true` in diaspora.yml. diff --git a/Gemfile b/Gemfile index c11c70b6a..446db2647 100644 --- a/Gemfile +++ b/Gemfile @@ -79,6 +79,7 @@ gem 'entypo-rails', '2.2.2' gem 'backbone-on-rails', '1.1.1' gem 'handlebars_assets', '0.12.0' gem 'jquery-rails', '3.0.4' +gem 'js_image_paths', '0.0.1' # jQuery plugins diff --git a/Gemfile.lock b/Gemfile.lock index 4fb830a3e..a1815d67c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -237,6 +237,8 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (4.2.1) railties (>= 3.2.16) + js_image_paths (0.0.1) + rails (~> 4.0) json (1.8.1) jwt (1.0.0) kaminari (0.16.1) @@ -535,6 +537,7 @@ DEPENDENCIES jasmine (= 2.0.2) jasmine-jquery-rails (= 2.0.3) jquery-rails (= 3.0.4) + js_image_paths (= 0.0.1) json (= 1.8.1) markerb (= 1.0.2) messagebus_ruby_api (= 1.0.3) diff --git a/app/assets/javascripts/app/app.js b/app/assets/javascripts/app/app.js index 1af41169f..1b0fddee1 100644 --- a/app/assets/javascripts/app/app.js +++ b/app/assets/javascripts/app/app.js @@ -37,11 +37,6 @@ var app = { return this._user || false }, - baseImageUrl: function(baseUrl){ - if(baseUrl) { return this._baseImageUrl = baseUrl } - return this._baseImageUrl || "assets/" - }, - initialize: function() { app.router = new app.Router(); @@ -91,8 +86,8 @@ var app = { }, setupFacebox: function() { - $.facebox.settings.closeImage = app.baseImageUrl()+'facebox/closelabel.png'; - $.facebox.settings.loadingImage = app.baseImageUrl()+'facebox/loading.gif'; + $.facebox.settings.closeImage = ImagePaths.get('facebox/closelabel.png'); + $.facebox.settings.loadingImage = ImagePaths.get('facebox/loading.gif'); $.facebox.settings.opacity = 0.75; }, diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index a289b5a64..617db4cb0 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -3,7 +3,7 @@ Handlebars.registerHelper('t', function(scope, values) { }); Handlebars.registerHelper('imageUrl', function(path){ - return app.baseImageUrl() + path; + return ImagePaths.get(path); }); Handlebars.registerHelper('linkToPerson', function(context, block) { @@ -43,4 +43,4 @@ Handlebars.registerHelper('personImage', function(person, size, imageClass) { Handlebars.registerHelper('localTime', function(timestamp) { return new Date(timestamp).toLocaleString(); -}); \ No newline at end of file +}); diff --git a/app/assets/javascripts/app/views/location_view.js b/app/assets/javascripts/app/views/location_view.js index 20a7e580a..9d2fa6564 100644 --- a/app/assets/javascripts/app/views/location_view.js +++ b/app/assets/javascripts/app/views/location_view.js @@ -8,7 +8,7 @@ app.views.Location = Backbone.View.extend({ }, render: function(){ - $(this.el).append('delete location'); + $(this.el).append('delete location'); }, getLocation: function(e){ @@ -18,7 +18,7 @@ app.views.Location = Backbone.View.extend({ locator.getAddress(function(address, latlng){ $(element).html(''); $('#location_coords').val(latlng.latitude + "," + latlng.longitude); - $(element).append('delete location'); + $(element).append('delete location'); }); }, }); diff --git a/app/assets/javascripts/inbox.js b/app/assets/javascripts/inbox.js index 3ab0c4cf5..5992ca488 100644 --- a/app/assets/javascripts/inbox.js +++ b/app/assets/javascripts/inbox.js @@ -81,7 +81,7 @@ $(document).ready(function(){ debug: false, donetext: "no more.", loadingText: "", - loadingImg: '/assets/ajax-loader.gif' + loadingImg: ImagePaths.get('ajax-loader.gif') }, function(){ $('.conversation-wrapper', '.stream').bind('mousedown', function(){ bindIt($(this)); diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index 483ee493c..a7be4a603 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -2,6 +2,7 @@ * licensed under the Affero General Public License version 3 or later. See * the COPYRIGHT file. */ +//= require js_image_paths //= require underscore //= require backbone //= require jquery.hotkeys diff --git a/app/assets/javascripts/mobile.js b/app/assets/javascripts/mobile.js index 0ba372480..8f82388b0 100644 --- a/app/assets/javascripts/mobile.js +++ b/app/assets/javascripts/mobile.js @@ -31,12 +31,12 @@ $(document).ready(function(){ evt.preventDefault(); $("#app").toggleClass('draw'); }); - + /* Show / hide aspects in the drawer */ $('#all_aspects').bind("tap click", function(evt){ evt.preventDefault(); $("#all_aspects + li").toggleClass('hide'); - }); + }); /* Heart toggle */ $(".like_action", ".stream").bind("tap click", function(evt){ @@ -319,7 +319,7 @@ function createUploader(){ $('#publisher_textarea_wrapper').addClass("with_attachments"); $('#photodropzone').append( "
  • " + - "Ajax-loader2" + + "Ajax-loader2" + "
  • " ); }, diff --git a/app/assets/javascripts/view.js b/app/assets/javascripts/view.js index f7517b114..9d9dcf646 100644 --- a/app/assets/javascripts/view.js +++ b/app/assets/javascripts/view.js @@ -115,7 +115,7 @@ var View = { avatars: { fallback: function(evt) { - $(this).attr("src", "/assets/user/default.png"); + $(this).attr("src", ImagePaths.get("user/default.png")); }, selector: "img.avatar" } diff --git a/app/assets/javascripts/widgets/infinite-scroll.js b/app/assets/javascripts/widgets/infinite-scroll.js index dbf78b937..d0d8b472c 100644 --- a/app/assets/javascripts/widgets/infinite-scroll.js +++ b/app/assets/javascripts/widgets/infinite-scroll.js @@ -11,7 +11,7 @@ debug: false, donetext: Diaspora.I18n.t("infinite_scroll.no_more"), loadingText: "", - loadingImg: "/assets/ajax-loader.gif", + loadingImg: ImagePaths.get("ajax-loader.gif"), navSelector: "#pagination", nextSelector: ".paginate", itemSelector: ".stream_element", diff --git a/app/assets/javascripts/widgets/lightbox.js b/app/assets/javascripts/widgets/lightbox.js index d896937fc..ae9497716 100644 --- a/app/assets/javascripts/widgets/lightbox.js +++ b/app/assets/javascripts/widgets/lightbox.js @@ -176,7 +176,7 @@ jQuery.fn.center = (function() { this.resetLightbox = function() { self.lightbox.hide(); self.body.removeClass("lightboxed"); - self.image.attr("src", "assets/ajax-loader2.gif"); + self.image.attr("src", ImagePaths.get("ajax-loader2.gif")); self.imageset.html(""); }; diff --git a/app/assets/stylesheets/header.css.scss b/app/assets/stylesheets/header.css.scss index ba5c8f3f9..afe12944f 100644 --- a/app/assets/stylesheets/header.css.scss +++ b/app/assets/stylesheets/header.css.scss @@ -5,7 +5,7 @@ body > header { @include box-shadow(0,1px,3px,rgba(0,0,0,0.9)); - background: url('header-bg.png') rgb(40,35,35); + background: image-url('header-bg.png') rgb(40,35,35); z-index: 1001; padding: 6px 0; color: #CCC; diff --git a/app/assets/stylesheets/mobile/header.css.scss b/app/assets/stylesheets/mobile/header.css.scss index 20e537941..8e89ba9f5 100644 --- a/app/assets/stylesheets/mobile/header.css.scss +++ b/app/assets/stylesheets/mobile/header.css.scss @@ -5,13 +5,13 @@ header { height: 45px; top: 0px; z-index: 10; - background: url('../header-bg-long.jpg') rgb(40,35,35); + background: image-url('header-bg-long.jpg') rgb(40,35,35); @include box-shadow(0, 1px, 2px, #333); border-bottom: 1px solid #222; } #main_nav { - width: 100%; + width: 100%; #header_title { display: inline-block; @@ -32,7 +32,7 @@ header { font-weight: bold; font-size: smaller; background-color: transparent; - + img { height: 30px; width: 30px; @@ -48,7 +48,7 @@ header { background-color: $red; margin-left: -8px; } - + #conversation_icon { height: 18px; } @@ -62,7 +62,7 @@ header { width: 100%; left: 100%; background-color: #444; - + box-shadow: -2px 0px 2px 1px #333; -o-box-shadow: -2px 0px 2px 1px #333; -ms-box-shadow: -2px 0px 2px 1px #333; @@ -73,7 +73,7 @@ header { position: static; left: 100%; right: -80%; - + #global_search { position: relative; @@ -109,7 +109,7 @@ header { } } } - + nav { position: absolute; top: 45px; @@ -124,7 +124,7 @@ header { color: $light-grey; border-bottom: solid rgb(53, 53, 53) 2px; } - + li:hover { background-color: $link-grey; } @@ -132,21 +132,21 @@ header { .no_border { padding: 0px; border-bottom: 0px; - + &:hover { background-color: transparent; } - + > ul > li > a { font-size: 14px; padding: 8px 42px; } } - + .hide { display: none; } - + .avatar { height: 35px; width: 35px; @@ -154,7 +154,7 @@ header { float: right; } } - + a { display: block; color: $light-grey; diff --git a/app/assets/stylesheets/vendor/autoSuggest.css b/app/assets/stylesheets/vendor/autoSuggest.css.erb similarity index 92% rename from app/assets/stylesheets/vendor/autoSuggest.css rename to app/assets/stylesheets/vendor/autoSuggest.css.erb index 1f8df0659..96d214775 100644 --- a/app/assets/stylesheets/vendor/autoSuggest.css +++ b/app/assets/stylesheets/vendor/autoSuggest.css.erb @@ -9,13 +9,13 @@ ul.as-selections { border-radius: 3px; -webkit-border-radius: 3px; -moz-border-radius: 3px; - /* 1% padding (all sides) + 98% width = 100% */ + /* 1% padding (all sides) + 98% width = 100% */ padding: 1%; width: 98%; } ul.as-selections.loading { - background: url("/assets/ajax-loader.gif") right center no-repeat; + background: url('<%= image_path("ajax-loader.gif") %>') right center no-repeat; } ul.as-selections li { @@ -171,20 +171,20 @@ li.as-result-item.active { text-shadow: 0 1px 2px #122042; } -li.as-result-item em { - font-style: normal; - background: #444; +li.as-result-item em { + font-style: normal; + background: #444; padding: 0 2px; color: #fff; } -li.as-result-item.active em { - background: #253f7a; +li.as-result-item.active em { + background: #253f7a; color: #fff; } /* Webkit Hacks */ -@media screen and (-webkit-min-device-pixel-ratio:0) { +@media screen and (-webkit-min-device-pixel-ratio:0) { ul.as-selections li.as-selection-item { padding-top: 6px; padding-bottom: 6px; @@ -218,7 +218,7 @@ ul.as-selections li.as-selection-item a.as-close { } /* Firefox 3.0 Hacks */ -ul.as-list, x:-moz-any-link, x:default { +ul.as-list, x:-moz-any-link, x:default { border: 1px solid #ccc; } BODY:first-of-type ul.as-list, x:-moz-any-link, x:default { /* Target FF 3.5+ */ diff --git a/app/helpers/layout_helper.rb b/app/helpers/layout_helper.rb index 346046511..9e9bbdf1a 100644 --- a/app/helpers/layout_helper.rb +++ b/app/helpers/layout_helper.rb @@ -19,15 +19,6 @@ module LayoutHelper pod_name end - def set_asset_host - path = AppConfig.environment.assets.host.to_s + '/assets/' - content_tag(:script) do - <<-JS.html_safe - if(window.app) app.baseImageUrl("#{path}") - JS - end - end - def load_javascript_locales(section = 'javascripts') content_tag(:script) do <<-JS.html_safe diff --git a/app/models/profile.rb b/app/models/profile.rb index 2ea8bca79..bb73d7d72 100644 --- a/app/models/profile.rb +++ b/app/models/profile.rb @@ -74,7 +74,7 @@ class Profile < ActiveRecord::Base else self[:image_url] end - result || '/assets/user/default.png' + result || ActionController::Base.helpers.image_path('user/default.png') end def from_omniauth_hash(omniauth_user_hash) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 0bac3a096..7f6a6d9fb 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -40,7 +40,6 @@ = javascript_include_tag :main, :templates = load_javascript_locales - = set_asset_host = translation_missing_warnings = current_user_atom_tag From 79e1a9aafd9da995ae85d1fbfeddfd7a02aea08f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 29 Aug 2014 01:42:16 +0200 Subject: [PATCH 135/785] port notify local users worker spec to doubles --- spec/workers/notify_local_users_spec.rb | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/spec/workers/notify_local_users_spec.rb b/spec/workers/notify_local_users_spec.rb index 6f89e1ed5..f49383e46 100644 --- a/spec/workers/notify_local_users_spec.rb +++ b/spec/workers/notify_local_users_spec.rb @@ -7,14 +7,13 @@ require 'spec_helper' describe Workers::NotifyLocalUsers do describe '#perfom' do it 'should call Notification.notify for each participant user' do - person = FactoryGirl.create :person - post = FactoryGirl.create :status_message + post = double(id: 1234, author: double(diaspora_handle: "foo@bar")) + klass_name = double(constantize: double(find_by_id: post)) + person = double(id: 4321) + allow(Person).to receive(:find_by_id).and_return(person) + expect(Notification).to receive(:notify).with(instance_of(User), post, person).twice - expect(StatusMessage).to receive(:find_by_id).with(post.id).and_return(post) - #User.should_receive(:where).and_return([alice, eve]) - expect(Notification).to receive(:notify).with(instance_of(User), instance_of(StatusMessage), instance_of(Person)).twice - - Workers::NotifyLocalUsers.new.perform([alice.id, eve.id], post.class.to_s, post.id, person.id) + Workers::NotifyLocalUsers.new.perform([alice.id, eve.id], klass_name, post.id, person.id) end end end From 0ca59e828ac1a3f69435ef6530378c7a15def13e Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Fri, 29 Aug 2014 14:45:16 +0200 Subject: [PATCH 136/785] Rounded contact search input --- app/views/contacts/_header.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/contacts/_header.html.haml b/app/views/contacts/_header.html.haml index e51c36957..1d3ec7e46 100644 --- a/app/views/contacts/_header.html.haml +++ b/app/views/contacts/_header.html.haml @@ -13,7 +13,7 @@ = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete', id: 'delete_aspect' do %i.entypo.trash.contacts-header-icon{:title => t('delete')} .pull-right - = search_field_tag :contact_search, "", id: "contact_list_search", placeholder: t('contacts.index.user_search') + = search_field_tag :contact_search, "", id: "contact_list_search", class: "search-query", placeholder: t('contacts.index.user_search') %h3 %span#aspect_name = @aspect.name From edae90585920d6e1110f44300c9f2cb3da553c29 Mon Sep 17 00:00:00 2001 From: Remco Huijdts Date: Fri, 29 Aug 2014 14:55:40 +0200 Subject: [PATCH 137/785] Add correct schema --- db/schema.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/db/schema.rb b/db/schema.rb index 854ea9f02..98b77d69e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -152,6 +152,15 @@ ActiveRecord::Schema.define(version: 20140824230505) do add_index "likes", ["target_id", "author_id", "target_type"], name: "index_likes_on_target_id_and_author_id_and_target_type", unique: true, using: :btree add_index "likes", ["target_id"], name: "index_likes_on_post_id", using: :btree + create_table "locations", force: true do |t| + t.string "address" + t.string "lat" + t.string "lng" + t.integer "status_message_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "mentions", force: true do |t| t.integer "post_id", null: false t.integer "person_id", null: false From 201b5904231afd41ed8ea2260993998f22aa1bf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 29 Aug 2014 22:56:47 +0200 Subject: [PATCH 138/785] drop Ruby 1.9 support, recommend Ruby 2.1 --- .ruby-version | 2 +- .travis.yml | 4 ++-- Changelog.md | 7 +++++++ 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/.ruby-version b/.ruby-version index cd5ac039d..879b416e6 100644 --- a/.ruby-version +++ b/.ruby-version @@ -1 +1 @@ -2.0 +2.1 diff --git a/.travis.yml b/.travis.yml index 5a36ee594..e44cf2707 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,8 +5,8 @@ branches: language: ruby rvm: - - 2.0.0 - - 1.9.3 + - 2.1 + - 2.0 env: - DB=postgres BUILD_TYPE=other diff --git a/Changelog.md b/Changelog.md index cd218f19b..e05bd710e 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,13 @@ Diaspora::Application.config.secret_key_base = '*************...' You also need to take care to set `RAILS_ENV` while precompiling assets: `RAILS_ENV=production bundle exec rake assets:precompile` +## Supported Ruby versions +This release drops official support for the Ruby 1.9 series. This means we will no longer test against this Ruby version or take care to choose libraries +that work with it. However that doesn't mean we won't accept patches that improve running diaspora* on it. + +At the same time we adopt support for the Ruby 2.1 series and recommend running on the latest Ruby version of that branch. We continue to support the Ruby 2.0 +series and run our comphrensive testsuite against it. + ## Change in defaults.yml The default for including jQuery from a CDN has changed. If you want to continue to include it from a CDN, please explicitly set the `jquery_cdn` setting to `true` in diaspora.yml. From a90627467b4b4683e256e13f2324d763f0e5be0b Mon Sep 17 00:00:00 2001 From: goobertron Date: Fri, 29 Aug 2014 17:37:42 +0100 Subject: [PATCH 139/785] Add sign-up tests for mobile, minor adjustments to other mobile tests --- features/desktop/signs_up.feature | 5 ++- features/mobile/activity_stream.feature | 4 +-- features/mobile/conversations.feature | 4 +-- features/mobile/getting_started.feature | 19 ++++++++--- features/mobile/multiphoto.feature | 4 +-- features/mobile/posts_from_main_page.feature | 15 +++++---- features/mobile/reactions.feature | 2 +- features/mobile/signs_up.feature | 34 ++++++++++++++++++++ features/mobile/tags.feature | 4 +-- features/step_definitions/mobile_steps.rb | 22 +++++++------ features/step_definitions/posts_steps.rb | 2 +- 11 files changed, 82 insertions(+), 33 deletions(-) create mode 100644 features/mobile/signs_up.feature diff --git a/features/desktop/signs_up.feature b/features/desktop/signs_up.feature index ce8fb7d08..1af82b89c 100644 --- a/features/desktop/signs_up.feature +++ b/features/desktop/signs_up.feature @@ -4,7 +4,7 @@ Feature: new user registration Background: When I go to the new user registration page And I fill in the new user form - And I press "Continue" + And I submit the form Then I should be on the getting started page Then I should see the 'getting started' contents @@ -22,7 +22,6 @@ Feature: new user registration And I focus the "follow_tags" field Then I should see a flash message containing "Hey, ", '"}]});alert(1);(function f() {var foo = [{b:"'].each do |xss| - get :new, name: xss + get :new, :facebox => true, name: xss expect(response.body).not_to include xss end end @@ -44,7 +51,7 @@ describe ConversationsController, :type => :controller do xss = "" contact = alice.contacts.first contact.person.profile.update_attribute(:first_name, xss) - get :new + get :new, :facebox => true json = JSON.parse(assigns(:contacts_json)).first expect(json['value'].to_s).to eq(contact.id.to_s) expect(json['name']).to_not include(xss) From 9870069c56acebd2f6d90eb2a5d12febab5c38c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 5 Sep 2014 23:46:56 +0200 Subject: [PATCH 152/785] bump rspec --- Gemfile | 2 +- Gemfile.lock | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/Gemfile b/Gemfile index 4936acef8..ca4d58e68 100644 --- a/Gemfile +++ b/Gemfile @@ -213,7 +213,7 @@ end group :development, :test do # RSpec (unit tests, some integration tests) - gem 'rspec-rails', '3.0.2' + gem 'rspec-rails', '3.1.0' # Cucumber (integration tests) gem 'cucumber-rails', '1.4.1', :require => false diff --git a/Gemfile.lock b/Gemfile.lock index 512e96bde..c3737e688 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -390,28 +390,28 @@ GEM roxml (3.1.6) activesupport (>= 2.3.0) nokogiri (>= 1.3.3) - rspec (3.0.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) - rspec-core (3.0.4) - rspec-support (~> 3.0.0) - rspec-expectations (3.0.4) + rspec (3.1.0) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-core (3.1.1) + rspec-support (~> 3.1.0) + rspec-expectations (3.1.0) diff-lcs (>= 1.2.0, < 2.0) - rspec-support (~> 3.0.0) + rspec-support (~> 3.1.0) rspec-instafail (0.2.5) rspec - rspec-mocks (3.0.4) - rspec-support (~> 3.0.0) - rspec-rails (3.0.2) + rspec-mocks (3.1.0) + rspec-support (~> 3.1.0) + rspec-rails (3.1.0) actionpack (>= 3.0) activesupport (>= 3.0) railties (>= 3.0) - rspec-core (~> 3.0.0) - rspec-expectations (~> 3.0.0) - rspec-mocks (~> 3.0.0) - rspec-support (~> 3.0.0) - rspec-support (3.0.4) + rspec-core (~> 3.1.0) + rspec-expectations (~> 3.1.0) + rspec-mocks (~> 3.1.0) + rspec-support (~> 3.1.0) + rspec-support (3.1.0) ruby-oembed (0.8.10) ruby-progressbar (1.5.1) rubyzip (1.1.6) @@ -571,7 +571,7 @@ DEPENDENCIES remotipart (= 1.2.1) roxml (= 3.1.6) rspec-instafail (= 0.2.5) - rspec-rails (= 3.0.2) + rspec-rails (= 3.1.0) ruby-oembed (= 0.8.10) sass-rails (= 4.0.3) selenium-webdriver (= 2.42.0) From ef501f755cb960cc492fb1d51f1fca5e681ebf00 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 5 Sep 2014 23:51:33 +0200 Subject: [PATCH 153/785] bump jquery-rails --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index ca4d58e68..2ffba2886 100644 --- a/Gemfile +++ b/Gemfile @@ -78,7 +78,7 @@ gem 'entypo-rails', '2.2.2' gem 'backbone-on-rails', '1.1.1' gem 'handlebars_assets', '0.17.1' -gem 'jquery-rails', '3.1.1' +gem 'jquery-rails', '3.1.2' gem 'rails-assets-jquery', '1.11.1' # Should be kept in sync with jquery-rails gem 'js_image_paths', '0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index c3737e688..d85ad392f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -233,7 +233,7 @@ GEM rake jasmine-core (2.0.2) jasmine-jquery-rails (2.0.3) - jquery-rails (3.1.1) + jquery-rails (3.1.2) railties (>= 3.0, < 5.0) thor (>= 0.14, < 2.0) jquery-ui-rails (4.2.1) @@ -537,7 +537,7 @@ DEPENDENCIES i18n-inflector-rails (= 1.0.7) jasmine (= 2.0.2) jasmine-jquery-rails (= 2.0.3) - jquery-rails (= 3.1.1) + jquery-rails (= 3.1.2) js_image_paths (= 0.0.1) json (= 1.8.1) markerb (= 1.0.2) From 3a7b0db67b4e78a18769384b6e1833a9a1dcb394 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 5 Sep 2014 23:52:17 +0200 Subject: [PATCH 154/785] bump rails-i18n --- Gemfile | 2 +- Gemfile.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/Gemfile b/Gemfile index 2ffba2886..dacd60d99 100644 --- a/Gemfile +++ b/Gemfile @@ -90,7 +90,7 @@ gem 'rails-assets-perfect-scrollbar', '0.4.11' gem 'http_accept_language', '2.0.2' gem 'i18n-inflector-rails', '1.0.7' -gem 'rails-i18n', '4.0.2' +gem 'rails-i18n', '4.0.3' # Mail diff --git a/Gemfile.lock b/Gemfile.lock index d85ad392f..971d4dc7a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -347,9 +347,9 @@ GEM rails-assets-jquery (1.11.1) rails-assets-perfect-scrollbar (0.4.11) rails-assets-jquery (>= 1.10) - rails-i18n (4.0.2) + rails-i18n (4.0.3) i18n (~> 0.6) - rails (>= 4.0) + railties (~> 4.0) rails-observers (0.1.2) activemodel (~> 4.0) rails-timeago (2.11.0) @@ -449,7 +449,7 @@ GEM multi_json (~> 1.0) rack (~> 1.0) tilt (~> 1.1, != 1.3.0) - sprockets-rails (2.1.3) + sprockets-rails (2.1.4) actionpack (>= 3.0) activesupport (>= 3.0) sprockets (~> 2.8) @@ -561,7 +561,7 @@ DEPENDENCIES rails (= 4.1.5) rails-assets-jquery (= 1.11.1) rails-assets-perfect-scrollbar (= 0.4.11) - rails-i18n (= 4.0.2) + rails-i18n (= 4.0.3) rails-timeago (= 2.11.0) rails_admin (= 0.6.3) rails_autolink (= 1.1.6) From fb058609e363369034cdb9fe7ba7ae0bfd7779a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 00:17:36 +0200 Subject: [PATCH 155/785] bump test_after_commit --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index dacd60d99..d733084ef 100644 --- a/Gemfile +++ b/Gemfile @@ -195,7 +195,7 @@ group :test do gem 'fixture_builder', '0.3.6' gem 'fuubar', '2.0.0' gem 'rspec-instafail', '0.2.5', :require => false - gem 'test_after_commit', '0.2.5' + gem 'test_after_commit', '0.2.6' # Cucumber (integration tests) diff --git a/Gemfile.lock b/Gemfile.lock index 971d4dc7a..404232978 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -455,7 +455,7 @@ GEM sprockets (~> 2.8) subexec (0.2.3) systemu (2.6.4) - test_after_commit (0.2.5) + test_after_commit (0.2.6) activerecord (>= 3.2) thor (0.19.1) thread_safe (0.3.4) @@ -580,7 +580,7 @@ DEPENDENCIES sinatra (= 1.3.3) sinon-rails (= 1.10.3) spork (= 1.0.0rc4) - test_after_commit (= 0.2.5) + test_after_commit (= 0.2.6) timecop (= 0.7.1) twitter (= 4.8.1) typhoeus (= 0.6.9) From 0af37d5d0bf8f76da8bdbee0173e01ad701e361f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 00:18:20 +0200 Subject: [PATCH 156/785] bump celluloid --- Gemfile.lock | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/Gemfile.lock b/Gemfile.lock index 404232978..f7983980c 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,8 +74,8 @@ GEM activesupport (>= 3.2.0) json (>= 1.7) mime-types (>= 1.16) - celluloid (0.15.2) - timers (~> 1.1.0) + celluloid (0.16.0) + timers (~> 4.0.0) childprocess (0.5.3) ffi (~> 1.0, >= 1.0.11) chunky_png (1.3.1) @@ -216,6 +216,7 @@ GEM tilt hashie (3.3.1) hike (1.2.3) + hitimes (1.2.2) http_accept_language (2.0.2) i18n (0.6.11) i18n-inflector (2.6.7) @@ -461,7 +462,8 @@ GEM thread_safe (0.3.4) tilt (1.4.1) timecop (0.7.1) - timers (1.1.0) + timers (4.0.0) + hitimes treetop (1.4.15) polyglot polyglot (>= 0.3.1) From dac5bbbd964ee697a3b20986c6ff1ab78accae10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 00:19:53 +0200 Subject: [PATCH 157/785] bump fog-brightbox --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index f7983980c..27fb15667 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -157,7 +157,7 @@ GEM fog-softlayer ipaddress (~> 0.5) nokogiri (~> 1.5, >= 1.5.11) - fog-brightbox (0.4.1) + fog-brightbox (0.5.0) fog-core (~> 1.22) fog-json inflecto From 476376dcb0b886fef92b4add3757993f5ce66a8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 03:26:07 +0200 Subject: [PATCH 158/785] Don't retry Diaspora::AuthorXMLAuthorMismatch They're not healable and seem to only occur on Friendica posts --- app/workers/base.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/app/workers/base.rb b/app/workers/base.rb index 1e6d4718e..c43f60929 100644 --- a/app/workers/base.rb +++ b/app/workers/base.rb @@ -12,7 +12,9 @@ module Workers def suppress_annoying_errors(&block) yield rescue Diaspora::ContactRequiredUnlessRequest, - Diaspora::RelayableObjectWithoutParent => e + Diaspora::RelayableObjectWithoutParent, + # Friendica seems to provoke these + Diaspora::AuthorXMLAuthorMismatch => e Rails.logger.info("error on receive: #{e.class}") rescue ActiveRecord::RecordInvalid => e Rails.logger.info("failed to save received object: #{e.record.errors.full_messages}") From 01e012728722ea75faae9be9307d74fcce8ee770 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 04:52:18 +0200 Subject: [PATCH 159/785] Ignore embedded photos if invalid For example if they're already present Also refactor StatusMessage XML specs --- app/models/status_message.rb | 5 ++ lib/diaspora/guid.rb | 2 +- spec/factories.rb | 5 ++ spec/models/status_message_spec.rb | 82 +++++++++++++----------------- 4 files changed, 46 insertions(+), 48 deletions(-) diff --git a/app/models/status_message.rb b/app/models/status_message.rb index e817b8507..fa04daf4d 100644 --- a/app/models/status_message.rb +++ b/app/models/status_message.rb @@ -187,5 +187,10 @@ class StatusMessage < Post def self.tag_stream(tag_ids) joins(:taggings).where('taggings.tag_id IN (?)', tag_ids) end + + def after_parse + # Make sure already received photos don't invalidate the model + self.photos = photos.select(&:valid?) + end end diff --git a/lib/diaspora/guid.rb b/lib/diaspora/guid.rb index 6f509a543..baf840a1f 100644 --- a/lib/diaspora/guid.rb +++ b/lib/diaspora/guid.rb @@ -4,7 +4,7 @@ module Diaspora::Guid # Creates a before_create callback which calls #set_guid and makes the guid serialize in to_xml def self.included(model) model.class_eval do - before_create :set_guid + after_initialize :set_guid xml_attr :guid validates :guid, :uniqueness => true diff --git a/spec/factories.rb b/spec/factories.rb index ac040e185..c7d5b18c0 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -113,6 +113,11 @@ FactoryGirl.define do end end + factory(:location) do + lat 1 + lng 2 + end + factory(:poll) do sequence(:question) { |n| "What do you think about #{n} ninjas?" } after(:build) do |p| diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb index fc0ac505b..95c7531dc 100644 --- a/spec/models/status_message_spec.rb +++ b/spec/models/status_message_spec.rb @@ -258,116 +258,104 @@ STR end describe "XML" do - before do - @message = FactoryGirl.build(:status_message, :text => "I hate WALRUSES!", :author => @user.person) - @xml = @message.to_xml.to_s - end + let(:message) { FactoryGirl.build(:status_message, text: "I hate WALRUSES!", author: @user.person) } + let(:xml) { message.to_xml.to_s } + let(:marshalled) { StatusMessage.from_xml(xml) } + it 'serializes the escaped, unprocessed message' do text = "[url](http://example.org)" - @message.text = text - expect(@message.to_xml.to_s).to include Builder::XChar.encode(text) + message.text = text + expect(xml).to include Builder::XChar.encode(text) end it 'serializes the message' do - expect(@xml).to include "I hate WALRUSES!" + expect(xml).to include "I hate WALRUSES!" end it 'serializes the author address' do - expect(@xml).to include(@user.person.diaspora_handle) + expect(xml).to include(@user.person.diaspora_handle) end describe '.from_xml' do - before do - @marshalled = StatusMessage.from_xml(@xml) - end it 'marshals the message' do - expect(@marshalled.text).to eq("I hate WALRUSES!") + expect(marshalled.text).to eq("I hate WALRUSES!") end + it 'marshals the guid' do - expect(@marshalled.guid).to eq(@message.guid) + expect(marshalled.guid).to eq(message.guid) end + it 'marshals the author' do - expect(@marshalled.author).to eq(@message.author) + expect(marshalled.author).to eq(message.author) end + it 'marshals the diaspora_handle' do - expect(@marshalled.diaspora_handle).to eq(@message.diaspora_handle) + expect(marshalled.diaspora_handle).to eq(message.diaspora_handle) end end context 'with some photos' do before do - @message.photos << FactoryGirl.build(:photo) - @message.photos << FactoryGirl.build(:photo) - @xml = @message.to_xml.to_s + message.photos << FactoryGirl.build(:photo) + message.photos << FactoryGirl.build(:photo) end it 'serializes the photos' do - expect(@xml).to include "photo" - expect(@xml).to include @message.photos.first.remote_photo_path + expect(xml).to include "photo" + expect(xml).to include message.photos.first.remote_photo_path end describe '.from_xml' do - before do - @marshalled = StatusMessage.from_xml(@xml) + it 'marshals the photos' do + expect(marshalled.photos.size).to eq(2) end - it 'marshals the photos' do - expect(@marshalled.photos.size).to eq(2) + it 'handles existing photos' do + message.photos.each(&:save!) + expect(marshalled).to be_valid end end end context 'with a location' do before do - @message.location = Location.new(coordinates: "1, 2").tap(&:save) - @xml = @message.to_xml.to_s + message.location = FactoryGirl.build(:location) end it 'serializes the location' do - expect(@xml).to include "location" - expect(@xml).to include "lat" - expect(@xml).to include "lng" + expect(xml).to include "location" + expect(xml).to include "lat" + expect(xml).to include "lng" end describe ".from_xml" do - before do - @marshalled = StatusMessage.from_xml(@xml) - end - it 'marshals the location' do - expect(@marshalled.location).to be_present + expect(marshalled.location).to be_present end end end context 'with a poll' do before do - @message.poll = FactoryGirl.create(:poll, :status_message => @message) - @xml = @message.to_xml.to_s + message.poll = FactoryGirl.build(:poll) end it 'serializes the poll' do - expect(@xml).to include "poll" - expect(@xml).to include "question" - expect(@xml).to include "poll_answer" + expect(xml).to include "poll" + expect(xml).to include "question" + expect(xml).to include "poll_answer" end describe ".from_xml" do - before do - @marshalled = StatusMessage.from_xml(@xml) - end - it 'marshals the poll' do - expect(@marshalled.poll).to be_present + expect(marshalled.poll).to be_present end it 'marshals the poll answers' do - expect(@marshalled.poll.poll_answers.size).to eq(2) + expect(marshalled.poll.poll_answers.size).to eq(2) end end end - - end describe '#after_dispatch' do From 642e5ab45b1a011ac0ad6ff63f4786e2c2d51d30 Mon Sep 17 00:00:00 2001 From: jaideng123 Date: Sat, 6 Sep 2014 14:44:54 -0500 Subject: [PATCH 160/785] Fixed Open Graph db insertion --- app/models/open_graph_cache.rb | 2 +- db/migrate/20140906192846_fix_open_graph_data.rb | 10 ++++++++++ db/schema.rb | 8 ++++---- 3 files changed, 15 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20140906192846_fix_open_graph_data.rb diff --git a/app/models/open_graph_cache.rb b/app/models/open_graph_cache.rb index 8c6e32841..d0c94362e 100644 --- a/app/models/open_graph_cache.rb +++ b/app/models/open_graph_cache.rb @@ -26,7 +26,7 @@ class OpenGraphCache < ActiveRecord::Base return if response.blank? || response.type.blank? - self.title = response.title + self.title = response.title.truncate(255) self.ob_type = response.type self.image = response.images[0] self.url = response.url diff --git a/db/migrate/20140906192846_fix_open_graph_data.rb b/db/migrate/20140906192846_fix_open_graph_data.rb new file mode 100644 index 000000000..54959931d --- /dev/null +++ b/db/migrate/20140906192846_fix_open_graph_data.rb @@ -0,0 +1,10 @@ +class FixOpenGraphData < ActiveRecord::Migration + def self.up + change_column :open_graph_caches, :url, :text + change_column :open_graph_caches, :image, :text + end + def self.down + change_column :open_graph_caches, :url, :string + change_column :open_graph_caches, :image, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index aa8406d86..80202933c 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140826165533) do +ActiveRecord::Schema.define(version: 20140906192846) do create_table "account_deletions", force: true do |t| t.string "diaspora_handle" @@ -219,8 +219,8 @@ ActiveRecord::Schema.define(version: 20140826165533) do create_table "open_graph_caches", force: true do |t| t.string "title" t.string "ob_type" - t.string "image" - t.string "url" + t.text "image" + t.text "url" t.text "description" end @@ -570,4 +570,4 @@ ActiveRecord::Schema.define(version: 20140826165533) do add_foreign_key "share_visibilities", "contacts", name: "post_visibilities_contact_id_fk", dependent: :delete -end +end \ No newline at end of file From c225bb17ce8d40fe2f61d83990436a93c1164adf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 23:13:53 +0200 Subject: [PATCH 161/785] add pry and pry-debundle to the Gemfile If you now install pry-byebug and pry-stackexplorer, you'll get a nice debugger --- Gemfile | 4 ++++ Gemfile.lock | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/Gemfile b/Gemfile index d733084ef..931bd87fc 100644 --- a/Gemfile +++ b/Gemfile @@ -187,6 +187,10 @@ group :development do gem 'guard-spork', '1.5.1' gem 'spork', '1.0.0rc4' + + # Debugging + gem 'pry' + gem 'pry-debundle' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index 27fb15667..648273b2a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -317,6 +317,8 @@ GEM coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) + pry-debundle (0.8) + pry rack (1.5.2) rack-cors (0.2.9) rack-google-analytics (1.2.0) @@ -554,6 +556,8 @@ DEPENDENCIES omniauth-twitter (= 1.0.1) omniauth-wordpress (= 0.2.1) opengraph_parser (= 0.2.3) + pry + pry-debundle rack-cors (= 0.2.9) rack-google-analytics (= 1.2.0) rack-piwik (= 0.3.0) From 9c88fde82139ee8a094932e35fa49c4e00b6fb0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 23:15:44 +0200 Subject: [PATCH 162/785] Switch Faraday adapter to typhoeus It uses curl which has less problems connecting to a missconfigured IPv6 host (falls back to v4) --- config/initializers/faraday.rb | 7 +++++++ spec/lib/diaspora/fetcher/public_spec.rb | 2 +- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/config/initializers/faraday.rb b/config/initializers/faraday.rb index ad1384f6d..d22e92e35 100644 --- a/config/initializers/faraday.rb +++ b/config/initializers/faraday.rb @@ -1,6 +1,13 @@ # Copyright (c) 2010-2011, Diaspora Inc. This file is # licensed under the Affero General Public License version 3 or later. See # the COPYRIGHT file. + +# Use net_http in test, that's better supported by webmock +unless Rails.env.test? + require 'typhoeus/adapters/faraday' + Faraday.default_adapter = :typhoeus +end + options = { request: { timeout: 25 diff --git a/spec/lib/diaspora/fetcher/public_spec.rb b/spec/lib/diaspora/fetcher/public_spec.rb index 43f249cab..28726b2e4 100644 --- a/spec/lib/diaspora/fetcher/public_spec.rb +++ b/spec/lib/diaspora/fetcher/public_spec.rb @@ -19,7 +19,7 @@ describe Diaspora::Fetcher::Public do stub_request(:get, /remote-testpod.net\/people\/.*/) .with(headers: { - 'Accept'=>'application/json', + 'Accept'=>'application/json', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'diaspora-fetcher' }).to_return(:body => @fixture) From 777e3123d6968fe4f6c5c2f4032220918c59d3de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 6 Sep 2014 23:19:57 +0200 Subject: [PATCH 163/785] Try fetching missing parent of relayables * Extract post fetching logic from Reshare into its own module * raise proper error message when fetching fails * raise proper error message when parent is still missing We can't skip fetch failures or missing parents and still need to retry them in case we're sent the parent later on --- app/models/reshare.rb | 31 +++++-------------------- lib/diaspora/exceptions.rb | 7 +++++- lib/diaspora/fetcher.rb | 1 + lib/diaspora/fetcher/single.rb | 41 +++++++++++++++++++++++++++++++++ lib/diaspora/relayable.rb | 17 ++++++++++++-- lib/federated/relayable.rb | 6 ++++- lib/postzord/receiver/public.rb | 9 ++++++++ spec/models/comment_spec.rb | 7 ++++++ spec/models/reshare_spec.rb | 6 ++--- 9 files changed, 93 insertions(+), 32 deletions(-) create mode 100644 lib/diaspora/fetcher/single.rb diff --git a/app/models/reshare.rb b/app/models/reshare.rb index 5bb5326d5..33581d05e 100644 --- a/app/models/reshare.rb +++ b/app/models/reshare.rb @@ -74,35 +74,16 @@ class Reshare < Post private def after_parse - root_author = Webfinger.new(@root_diaspora_id).fetch - root_author.save! unless root_author.persisted? - - return if Post.exists?(:guid => self.root_guid) - - fetched_post = self.class.fetch_post(root_author, self.root_guid) - - if fetched_post - #Why are we checking for this? - if root_author.diaspora_handle != fetched_post.diaspora_handle - raise "Diaspora ID (#{fetched_post.diaspora_handle}) in the root does not match the Diaspora ID (#{root_author.diaspora_handle}) specified in the reshare!" + if root.blank? + self.root = Diaspora::Fetcher::Single.find_or_fetch_from_remote root_guid, @root_diaspora_id do |fetched_post, author| + # why do we check this? + if fetched_post.diaspora_handle != author.diaspora_handle + raise Diaspora::PostNotFetchable, "Diaspora ID (#{fetched_post.diaspora_handle}) in the root does not match the Diaspora ID (#{author.diaspora_handle}) specified in the reshare!" + end end - - fetched_post.save! end end - # Fetch a remote public post, used for receiving reshares of unknown posts - # @param [Person] author the remote post's author - # @param [String] guid the remote post's guid - # @return [Post] an unsaved remote post or false if the post was not found - def self.fetch_post author, guid - url = author.url + "/p/#{guid}.xml" - response = Faraday.get(url) - return false if response.status == 404 # Old pod, friendika - raise "Failed to get #{url}" unless response.success? # Other error, N/A for example - Diaspora::Parser.from_xml(response.body) - end - def root_must_be_public if self.root && !self.root.public errors[:base] << "Only posts which are public may be reshared." diff --git a/lib/diaspora/exceptions.rb b/lib/diaspora/exceptions.rb index eba8366e0..2a9da47a2 100644 --- a/lib/diaspora/exceptions.rb +++ b/lib/diaspora/exceptions.rb @@ -16,7 +16,6 @@ module Diaspora # that prevents further execution class NotMine < StandardError end - # Received a message without having a contact class ContactRequiredUnlessRequest < StandardError @@ -30,4 +29,10 @@ module Diaspora # original XML message class AuthorXMLAuthorMismatch < StandardError end + + # Tried to fetch a post but it was deleted, not valid + # or the remote end doesn't support post fetching + class PostNotFetchable < StandardError + end + end diff --git a/lib/diaspora/fetcher.rb b/lib/diaspora/fetcher.rb index adb82e552..a27831e2f 100644 --- a/lib/diaspora/fetcher.rb +++ b/lib/diaspora/fetcher.rb @@ -1,5 +1,6 @@ module Diaspora module Fetcher require 'diaspora/fetcher/public' + require 'diaspora/fetcher/single' end end diff --git a/lib/diaspora/fetcher/single.rb b/lib/diaspora/fetcher/single.rb new file mode 100644 index 000000000..5dfeb7f73 --- /dev/null +++ b/lib/diaspora/fetcher/single.rb @@ -0,0 +1,41 @@ +module Diaspora + module Fetcher + module Single + module_function + + # Fetch and store a remote public post + # @param [String] guid the remote posts guid + # @param [String] author_id Diaspora ID of a user known to have the post, + # preferably the author + # @yield [Post, Person] If a block is given it is yielded the post + # and the author prior save + # @return a saved post + def find_or_fetch_from_remote guid, author_id + post = Post.where(guid: guid).first + return post if post + + post_author = Webfinger.new(author_id).fetch + post_author.save! unless post_author.persisted? + + if fetched_post = fetch_post(post_author, guid) + yield fetched_post, post_author if block_given? + raise Diaspora::PostNotFetchable unless fetched_post.save + end + + fetched_post + end + + # Fetch a remote public post, used for receiving of unknown public posts + # @param [Person] author the remote post's author + # @param [String] guid the remote post's guid + # @return [Post] an unsaved remote post or false if the post was not found + def fetch_post author, guid + url = author.url + "/p/#{guid}.xml" + response = Faraday.get(url) + raise Diaspora::PostNotFetchable if response.status == 404 # Old pod, Friendika, deleted + raise "Failed to get #{url}" unless response.success? # Other error, N/A for example + Diaspora::Parser.from_xml(response.body) + end + end + end +end diff --git a/lib/diaspora/relayable.rb b/lib/diaspora/relayable.rb index d0db312b7..4f43ed402 100644 --- a/lib/diaspora/relayable.rb +++ b/lib/diaspora/relayable.rb @@ -51,7 +51,8 @@ module Diaspora end def parent_guid= new_parent_guid - self.parent = parent_class.where(:guid => new_parent_guid).first + @parent_guid = new_parent_guid + self.parent = parent_class.where(guid: new_parent_guid).first end # @return [Array] @@ -66,7 +67,7 @@ module Diaspora end def receive(user, person=nil) - comment_or_like = self.class.where(:guid => self.guid).first || self + comment_or_like = self.class.where(guid: self.guid).first || self # Check to make sure the signature of the comment or like comes from the person claiming to author it unless comment_or_like.parent_author == user.person || comment_or_like.verify_parent_author_signature @@ -134,5 +135,17 @@ module Diaspora def parent= parent raise NotImplementedError.new('you must override parent= in order to enable relayable on this model') end + + # ROXML hook ensuring our own hooks are called + def after_parse + if @parent_guid + self.parent ||= fetch_parent(@parent_guid) + end + end + + # Childs should override this to support fetching a missing parent + # @param guid the parents guid + def fetch_parent guid + end end end diff --git a/lib/federated/relayable.rb b/lib/federated/relayable.rb index d852a4dcd..a6cf6bf83 100644 --- a/lib/federated/relayable.rb +++ b/lib/federated/relayable.rb @@ -38,5 +38,9 @@ module Federated def parent= parent self.target = parent end + + def fetch_parent guid + Diaspora::Fetcher::Single.find_or_fetch_from_remote guid, diaspora_handle + end end -end \ No newline at end of file +end diff --git a/lib/postzord/receiver/public.rb b/lib/postzord/receiver/public.rb index 686e9a5b3..0243b72f5 100644 --- a/lib/postzord/receiver/public.rb +++ b/lib/postzord/receiver/public.rb @@ -57,6 +57,7 @@ class Postzord::Receiver::Public < Postzord::Receiver def save_object @object = Diaspora::Parser::from_xml(@salmon.parsed_data) raise "Object is not public" if object_can_be_public_and_it_is_not? + raise Diaspora::RelayableObjectWithoutParent if object_must_have_parent_and_does_not? raise Diaspora::AuthorXMLAuthorMismatch if author_does_not_match_xml_author? @object.save! if @object && @object.respond_to?(:save!) @object @@ -88,4 +89,12 @@ class Postzord::Receiver::Public < Postzord::Receiver def object_can_be_public_and_it_is_not? @object.respond_to?(:public) && !@object.public? end + + def object_must_have_parent_and_does_not? + if @object.respond_to?(:relayable?) # comment, like + @object.parent.nil? + else + false + end + end end diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb index a377d142a..efc7eacdc 100644 --- a/spec/models/comment_spec.rb +++ b/spec/models/comment_spec.rb @@ -96,6 +96,13 @@ describe Comment, :type => :model do it 'marshals the post' do expect(@marshalled_comment.post).to eq(@post) end + + it 'tries to fetch a missing parent' do + guid = @post.guid + @post.destroy + expect_any_instance_of(Comment).to receive(:fetch_parent).with(guid).and_return(nil) + Comment.from_xml(@xml) + end end end diff --git a/spec/models/reshare_spec.rb b/spec/models/reshare_spec.rb index 89dfd85f6..ce05d3b6b 100644 --- a/spec/models/reshare_spec.rb +++ b/spec/models/reshare_spec.rb @@ -83,7 +83,7 @@ describe Reshare, :type => :model do rs1 = FactoryGirl.build(:reshare, :root=>@sm) rs2 = FactoryGirl.build(:reshare, :root=>rs1) @rs3 = FactoryGirl.build(:reshare, :root=>rs2) - + sm = FactoryGirl.create(:status_message, :author => alice.person, :public => true) rs1 = FactoryGirl.create(:reshare, :root => sm) @of_deleted = FactoryGirl.build(:reshare, :root => rs1) @@ -194,13 +194,13 @@ describe Reshare, :type => :model do end context "fetching post" do - it "doesn't error out if the post is not found" do + it "raises if the post is not found" do allow(@response).to receive(:status).and_return(404) expect(Faraday.default_connection).to receive(:get).and_return(@response) expect { Reshare.from_xml(@xml) - }.to_not raise_error + }.to raise_error(Diaspora::PostNotFetchable) end it "raises if there's another error receiving the post" do From 619bc3f5379dad2f7f49e3fd2b8a8b4d2e5d296d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 7 Sep 2014 00:45:12 +0200 Subject: [PATCH 164/785] A reshares root may be already gone when generating the notification --- app/models/reshare.rb | 2 +- spec/models/reshare_spec.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/models/reshare.rb b/app/models/reshare.rb index 33581d05e..869d73351 100644 --- a/app/models/reshare.rb +++ b/app/models/reshare.rb @@ -62,7 +62,7 @@ class Reshare < Post end def notification_type(user, person) - Notifications::Reshared if root.author == user.person + Notifications::Reshared if root.try(:author) == user.person end def absolute_root diff --git a/spec/models/reshare_spec.rb b/spec/models/reshare_spec.rb index ce05d3b6b..929ded2b9 100644 --- a/spec/models/reshare_spec.rb +++ b/spec/models/reshare_spec.rb @@ -75,6 +75,13 @@ describe Reshare, :type => :model do it 'returns "Reshared" for the original post author' do expect(@reshare.notification_type(alice, @reshare.author)).to eq(Notifications::Reshared) end + + it 'does not error out if the root was deleted' do + @reshare.root = nil + expect { + @reshare.notification_type(alice, @reshare.author) + }.to_not raise_error + end end describe '#absolute_root' do From d16eabae21f98ba570bf652cffadb3e82c6955e8 Mon Sep 17 00:00:00 2001 From: jaideng123 Date: Sun, 7 Sep 2014 20:28:02 -0500 Subject: [PATCH 165/785] Added test for truncation to gather OG data spec --- spec/workers/gather_open_graph_data_spec.rb | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/spec/workers/gather_open_graph_data_spec.rb b/spec/workers/gather_open_graph_data_spec.rb index 7c2397e4f..3416047c4 100644 --- a/spec/workers/gather_open_graph_data_spec.rb +++ b/spec/workers/gather_open_graph_data_spec.rb @@ -16,12 +16,25 @@ describe Workers::GatherOpenGraphData do " + @oglong_title = "D" * 256 + @oglong_url = 'http://www.we-are-too-long.com' + @oglong_body = + "#{@oglong_title} + + + + + + " + @no_open_graph_url = 'http://www.we-do-not-support-open-graph.com/index.html' @status_message = FactoryGirl.create(:status_message) stub_request(:get, @ogsite_url).to_return(:status => 200, :body => @ogsite_body) stub_request(:get, @no_open_graph_url).to_return(:status => 200, :body => 'hello there') + stub_request(:get, @oglong_url).to_return(:status => 200, :body => @oglong_body) + end describe '.perform' do @@ -65,5 +78,11 @@ describe Workers::GatherOpenGraphData do Workers::GatherOpenGraphData.new.perform(0, @ogsite_url) }.to_not raise_error end + it 'truncates + inserts titles that are too long' do + Workers::GatherOpenGraphData.new.perform(@status_message.id, @oglong_url) + ogc = OpenGraphCache.find_by_url(@oglong_url) + expect(ogc).to be_truthy + expect(ogc.title.length).to be <= 255 + end end end From 9f125058f788700c4fb6e328979f15d8c201fa9c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 21:49:09 +0200 Subject: [PATCH 166/785] bump rails --- Gemfile | 2 +- Gemfile.lock | 63 ++++++++++++++++++++++++---------------------------- 2 files changed, 30 insertions(+), 35 deletions(-) diff --git a/Gemfile b/Gemfile index d733084ef..0ca4d0a58 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' source 'https://rails-assets.org' -gem 'rails', '4.1.5' +gem 'rails', '4.1.6' # Legacy Rails features, remove me! diff --git a/Gemfile.lock b/Gemfile.lock index 27fb15667..c80415fd3 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -2,29 +2,29 @@ GEM remote: https://rubygems.org/ remote: https://rails-assets.org/ specs: - actionmailer (4.1.5) - actionpack (= 4.1.5) - actionview (= 4.1.5) - mail (~> 2.5.4) - actionpack (4.1.5) - actionview (= 4.1.5) - activesupport (= 4.1.5) + actionmailer (4.1.6) + actionpack (= 4.1.6) + actionview (= 4.1.6) + mail (~> 2.5, >= 2.5.4) + actionpack (4.1.6) + actionview (= 4.1.6) + activesupport (= 4.1.6) rack (~> 1.5.2) rack-test (~> 0.6.2) actionpack-action_caching (1.1.1) actionpack (>= 4.0.0, < 5.0) actionpack-page_caching (1.0.2) actionpack (>= 4.0.0, < 5) - actionview (4.1.5) - activesupport (= 4.1.5) + actionview (4.1.6) + activesupport (= 4.1.6) builder (~> 3.1) erubis (~> 2.7.0) - activemodel (4.1.5) - activesupport (= 4.1.5) + activemodel (4.1.6) + activesupport (= 4.1.6) builder (~> 3.1) - activerecord (4.1.5) - activemodel (= 4.1.5) - activesupport (= 4.1.5) + activerecord (4.1.6) + activemodel (= 4.1.6) + activesupport (= 4.1.6) arel (~> 5.0.0) activerecord-import (0.5.0) activerecord (>= 3.0) @@ -32,7 +32,7 @@ GEM activemodel (~> 4.0) activesupport (~> 4.0) rails-observers (~> 0.1.1) - activesupport (4.1.5) + activesupport (4.1.6) i18n (~> 0.6, >= 0.6.9) json (~> 1.7, >= 1.7.7) minitest (~> 5.1) @@ -254,9 +254,8 @@ GEM lumberjack (1.0.9) macaddr (1.7.1) systemu (~> 2.6.2) - mail (2.5.4) - mime-types (~> 1.16) - treetop (~> 1.4.8) + mail (2.6.1) + mime-types (>= 1.16, < 3) markerb (1.0.2) redcarpet (>= 2.0) messagebus_ruby_api (1.0.3) @@ -312,7 +311,6 @@ GEM nokogiri orm_adapter (0.5.0) phantomjs (1.9.7.1) - polyglot (0.3.5) pry (0.10.1) coderay (~> 1.1.0) method_source (~> 0.8.1) @@ -335,15 +333,15 @@ GEM rack rack-test (0.6.2) rack (>= 1.0) - rails (4.1.5) - actionmailer (= 4.1.5) - actionpack (= 4.1.5) - actionview (= 4.1.5) - activemodel (= 4.1.5) - activerecord (= 4.1.5) - activesupport (= 4.1.5) + rails (4.1.6) + actionmailer (= 4.1.6) + actionpack (= 4.1.6) + actionview (= 4.1.6) + activemodel (= 4.1.6) + activerecord (= 4.1.6) + activesupport (= 4.1.6) bundler (>= 1.3.0, < 2.0) - railties (= 4.1.5) + railties (= 4.1.6) sprockets-rails (~> 2.0) rails-assets-jquery (1.11.1) rails-assets-perfect-scrollbar (0.4.11) @@ -372,9 +370,9 @@ GEM sass-rails (~> 4.0) rails_autolink (1.1.6) rails (> 3.1) - railties (4.1.5) - actionpack (= 4.1.5) - activesupport (= 4.1.5) + railties (4.1.6) + actionpack (= 4.1.6) + activesupport (= 4.1.6) rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) raindrops (0.13.0) @@ -464,9 +462,6 @@ GEM timecop (0.7.1) timers (4.0.0) hitimes - treetop (1.4.15) - polyglot - polyglot (>= 0.3.1) twitter (4.8.1) faraday (~> 0.8, < 0.10) multi_json (~> 1.0) @@ -560,7 +555,7 @@ DEPENDENCIES rack-protection (= 1.2) rack-rewrite (= 1.5.0) rack-ssl (= 1.4.1) - rails (= 4.1.5) + rails (= 4.1.6) rails-assets-jquery (= 1.11.1) rails-assets-perfect-scrollbar (= 0.4.11) rails-i18n (= 4.0.3) From a6ad721b8e9064815a3c8cbd0372db7ad0952769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 21:52:43 +0200 Subject: [PATCH 167/785] bump handlebars_assets --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 0ca4d0a58..1e49cd85b 100644 --- a/Gemfile +++ b/Gemfile @@ -77,7 +77,7 @@ gem 'entypo-rails', '2.2.2' # JavaScript gem 'backbone-on-rails', '1.1.1' -gem 'handlebars_assets', '0.17.1' +gem 'handlebars_assets', '0.18.0' gem 'jquery-rails', '3.1.2' gem 'rails-assets-jquery', '1.11.1' # Should be kept in sync with jquery-rails gem 'js_image_paths', '0.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index c80415fd3..de2ed877a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -209,7 +209,7 @@ GEM spork (>= 0.8.4) haml (4.0.5) tilt - handlebars_assets (0.17.1) + handlebars_assets (0.18) execjs (>= 1.2.9) multi_json sprockets (>= 2.0.3) @@ -529,7 +529,7 @@ DEPENDENCIES guard-rspec (= 4.3.1) guard-spork (= 1.5.1) haml (= 4.0.5) - handlebars_assets (= 0.17.1) + handlebars_assets (= 0.18.0) http_accept_language (= 2.0.2) i18n-inflector-rails (= 1.0.7) jasmine (= 2.0.2) From ba70f2293e34eca4348d6869fcf3f830867130f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 21:57:00 +0200 Subject: [PATCH 168/785] bump mini_magick --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 1e49cd85b..8700f37da 100644 --- a/Gemfile +++ b/Gemfile @@ -64,7 +64,7 @@ gem 'foreigner', '1.6.1' gem 'carrierwave', '0.10.0' gem 'fog', '1.23.0' -gem 'mini_magick', '3.8.0' +gem 'mini_magick', '3.8.1' gem 'remotipart', '1.2.1' # GUID generation diff --git a/Gemfile.lock b/Gemfile.lock index de2ed877a..4a5470b38 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -261,7 +261,7 @@ GEM messagebus_ruby_api (1.0.3) method_source (0.8.2) mime-types (1.25.1) - mini_magick (3.8.0) + mini_magick (3.8.1) subexec (~> 0.2.1) mini_portile (0.5.3) minitest (5.4.1) @@ -539,7 +539,7 @@ DEPENDENCIES json (= 1.8.1) markerb (= 1.0.2) messagebus_ruby_api (= 1.0.3) - mini_magick (= 3.8.0) + mini_magick (= 3.8.1) mobile-fu (= 1.3.1) mysql2 (= 0.3.16) nokogiri (= 1.6.1) From 743fc709990483577988d0aeb01980e2bd469515 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 21:59:19 +0200 Subject: [PATCH 169/785] bump selenium-webdriver --- Gemfile | 2 +- Gemfile.lock | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Gemfile b/Gemfile index 8700f37da..98237968c 100644 --- a/Gemfile +++ b/Gemfile @@ -201,7 +201,7 @@ group :test do gem 'capybara', '2.4.1' gem 'database_cleaner', '1.3.0' - gem 'selenium-webdriver', '2.42.0' + gem 'selenium-webdriver', '2.43.0' # General helpers diff --git a/Gemfile.lock b/Gemfile.lock index 4a5470b38..5d94af88e 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -421,11 +421,11 @@ GEM sass (~> 3.2.0) sprockets (~> 2.8, <= 2.11.0) sprockets-rails (~> 2.0) - selenium-webdriver (2.42.0) - childprocess (>= 0.5.0) + selenium-webdriver (2.43.0) + childprocess (~> 0.5) multi_json (~> 1.0) rubyzip (~> 1.0) - websocket (~> 1.0.4) + websocket (~> 1.0) sidekiq (3.2.3) celluloid (>= 0.15.2) connection_pool (>= 2.0.0) @@ -487,7 +487,7 @@ GEM webmock (1.18.0) addressable (>= 2.3.6) crack (>= 0.3.2) - websocket (1.0.7) + websocket (1.2.1) will_paginate (3.0.7) xpath (2.0.0) nokogiri (~> 1.3) @@ -571,7 +571,7 @@ DEPENDENCIES rspec-rails (= 3.1.0) ruby-oembed (= 0.8.10) sass-rails (= 4.0.3) - selenium-webdriver (= 2.42.0) + selenium-webdriver (= 2.43.0) sidekiq (= 3.2.3) simple_captcha2 (= 0.3.2) sinatra (= 1.3.3) From f3d980ba5df5d6429580f856e229c60d453803f6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 22:00:38 +0200 Subject: [PATCH 170/785] bump sidekiq --- Gemfile | 2 +- Gemfile.lock | 14 ++++++-------- 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/Gemfile b/Gemfile index 98237968c..dfbc7fcf3 100644 --- a/Gemfile +++ b/Gemfile @@ -29,7 +29,7 @@ gem 'simple_captcha2', '0.3.2', :require => 'simple_captcha' # Background processing -gem 'sidekiq', '3.2.3' +gem 'sidekiq', '3.2.5' gem 'sinatra', '1.3.3' # Compression diff --git a/Gemfile.lock b/Gemfile.lock index 5d94af88e..f1e2f1719 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -74,8 +74,8 @@ GEM activesupport (>= 3.2.0) json (>= 1.7) mime-types (>= 1.16) - celluloid (0.16.0) - timers (~> 4.0.0) + celluloid (0.15.2) + timers (~> 1.1.0) childprocess (0.5.3) ffi (~> 1.0, >= 1.0.11) chunky_png (1.3.1) @@ -216,7 +216,6 @@ GEM tilt hashie (3.3.1) hike (1.2.3) - hitimes (1.2.2) http_accept_language (2.0.2) i18n (0.6.11) i18n-inflector (2.6.7) @@ -426,8 +425,8 @@ GEM multi_json (~> 1.0) rubyzip (~> 1.0) websocket (~> 1.0) - sidekiq (3.2.3) - celluloid (>= 0.15.2) + sidekiq (3.2.5) + celluloid (= 0.15.2) connection_pool (>= 2.0.0) json redis (>= 3.0.6) @@ -460,8 +459,7 @@ GEM thread_safe (0.3.4) tilt (1.4.1) timecop (0.7.1) - timers (4.0.0) - hitimes + timers (1.1.0) twitter (4.8.1) faraday (~> 0.8, < 0.10) multi_json (~> 1.0) @@ -572,7 +570,7 @@ DEPENDENCIES ruby-oembed (= 0.8.10) sass-rails (= 4.0.3) selenium-webdriver (= 2.43.0) - sidekiq (= 3.2.3) + sidekiq (= 3.2.5) simple_captcha2 (= 0.3.2) sinatra (= 1.3.3) sinon-rails (= 1.10.3) From 52f3e8d01d97deadb660d29b53f49232ba0832de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 22:01:39 +0200 Subject: [PATCH 171/785] bump test_after_commit --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index dfbc7fcf3..9f348605e 100644 --- a/Gemfile +++ b/Gemfile @@ -195,7 +195,7 @@ group :test do gem 'fixture_builder', '0.3.6' gem 'fuubar', '2.0.0' gem 'rspec-instafail', '0.2.5', :require => false - gem 'test_after_commit', '0.2.6' + gem 'test_after_commit', '0.2.7' # Cucumber (integration tests) diff --git a/Gemfile.lock b/Gemfile.lock index f1e2f1719..f2973e449 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -453,7 +453,7 @@ GEM sprockets (~> 2.8) subexec (0.2.3) systemu (2.6.4) - test_after_commit (0.2.6) + test_after_commit (0.2.7) activerecord (>= 3.2) thor (0.19.1) thread_safe (0.3.4) @@ -575,7 +575,7 @@ DEPENDENCIES sinatra (= 1.3.3) sinon-rails (= 1.10.3) spork (= 1.0.0rc4) - test_after_commit (= 0.2.6) + test_after_commit (= 0.2.7) timecop (= 0.7.1) twitter (= 4.8.1) typhoeus (= 0.6.9) From c555cd29dd197ffb5afa85c8b811a39ea3964bc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 22:02:25 +0200 Subject: [PATCH 172/785] bump rspec-core --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index f2973e449..9eec47732 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -392,7 +392,7 @@ GEM rspec-core (~> 3.1.0) rspec-expectations (~> 3.1.0) rspec-mocks (~> 3.1.0) - rspec-core (3.1.1) + rspec-core (3.1.2) rspec-support (~> 3.1.0) rspec-expectations (3.1.0) diff-lcs (>= 1.2.0, < 2.0) From f964d3793b62f06c698445576fb8a3545b67ab77 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 12 Sep 2014 22:03:06 +0200 Subject: [PATCH 173/785] bump fog-softlayer --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 9eec47732..483a6fc24 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -170,7 +170,7 @@ GEM net-ssh (>= 2.1.3) fog-json (1.0.0) multi_json (~> 1.0) - fog-softlayer (0.3.16) + fog-softlayer (0.3.17) fog-core fog-json font-awesome-rails (4.2.0.0) From d00d69814eae2273d0aa6c9a43e7eef615b207cf Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Fri, 29 Aug 2014 21:29:59 +0200 Subject: [PATCH 174/785] port profile page to backbone.js --- app/assets/javascripts/app/pages/profile.js | 44 +++++++++++++++++++++ app/assets/javascripts/app/router.js | 21 +++++++--- app/assets/javascripts/people.js | 25 ------------ app/views/contacts/index.html.haml | 3 -- app/views/contacts/index.mobile.haml | 3 -- app/views/contacts/spotlight.haml | 3 -- app/views/people/index.html.haml | 1 - app/views/people/show.html.haml | 1 - 8 files changed, 60 insertions(+), 41 deletions(-) create mode 100644 app/assets/javascripts/app/pages/profile.js delete mode 100644 app/assets/javascripts/people.js diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js new file mode 100644 index 000000000..a47a4542c --- /dev/null +++ b/app/assets/javascripts/app/pages/profile.js @@ -0,0 +1,44 @@ + +// TODO: this view should be model-driven an re-render when it was updated, +// instead of changing classes/attributes on elements. +app.pages.Profile = Backbone.View.extend({ + events: { + 'click #block_user_button': 'blockPerson' + }, + + initialize: function(opts) { + // cache element references + this.el_profile_btns = this.$('#profile_buttons'); + this.el_sharing_msg = this.$('#sharing_message'); + + // init tooltips + this.el_profile_btns.find('.profile_button div, .sharin_message_container') + .tooltip({placement: 'bottom'}); + + // respond to global events + var person_id = this.$('#profile .avatar:first').data('person_id'); + app.events.on('person:block:'+person_id, this._markBlocked, this); + }, + + blockPerson: function(evt) { + if( !confirm(Diaspora.I18n.t('ignore_user')) ) return; + + var person_id = $(evt.target).data('person-id'); + var block = new app.models.Block({block: {person_id: person_id}}); + block.save() + .done(function() { app.events.trigger('person:block:'+person_id); }) + .fail(function() { Diaspora.page.flashMessages.render({ + success: false, + notice: Diaspora.I18n.t('ignore_failed') + }); }); + + return false; + }, + + _markBlocked: function() { + this.el_profile_btns.attr('class', 'blocked'); + this.el_sharing_msg.attr('class', 'icons-circle'); + + this.el_profile_btns.find('.profile_button, .white_bar').remove(); + } +}); diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 6012183a9..21d90707d 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -22,8 +22,8 @@ app.Router = Backbone.Router.extend({ "tags/:name": "followed_tags", "people/:id/photos": "photos", - "people/:id": "stream", - "u/:name": "stream" + "people/:id": "profile", + "u/:name": "profile" }, initialize: function() { @@ -52,9 +52,13 @@ app.Router = Backbone.Router.extend({ }, renderPage : function(pageConstructor){ - app.page && app.page.unbind && app.page.unbind() //old page might mutate global events $(document).keypress, so unbind before creating - app.page = pageConstructor() //create new page after the world is clean (like that will ever happen) - $("#container").html(app.page.render().el) + app.page && app.page.unbind && app.page.unbind(); //old page might mutate global events $(document).keypress, so unbind before creating + app.page = pageConstructor(); //create new page after the world is clean (like that will ever happen) + + if( !$.contains(document, app.page.el) ) { + // view element isn't already attached to the DOM, insert it + $("#container").empty().append(app.page.render().el); + } }, //below here is oldness @@ -133,6 +137,13 @@ app.Router = Backbone.Router.extend({ app.bookmarklet = new app.views.Bookmarklet( _.extend({}, {el: $('#bookmarklet')}, contents) ).render(); + }, + + profile: function() { + this.renderPage(function() { return new app.pages.Profile({ + el: $('body > .container') + }); }); + // TODO call `this.stream()` } }); diff --git a/app/assets/javascripts/people.js b/app/assets/javascripts/people.js deleted file mode 100644 index 78f1e519e..000000000 --- a/app/assets/javascripts/people.js +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (c) 2010-2011, Diaspora Inc. This file is - * licensed under the Affero General Public License version 3 or later. See - * the COPYRIGHT file. - */ -//= require fileuploader-custom -//= require jquery.autoSuggest.custom - -$(document).ready(function() { - $('#profile_buttons .profile_button div').tooltip({placement: 'bottom'}); - $('#profile_buttons .sharing_message_container').tooltip({placement: 'bottom'}); - $("#block_user_button").click(function(evt) { - if(!confirm(Diaspora.I18n.t('ignore_user'))) { return; } - var personId = $(this).data('person-id'); - var block = new app.models.Block(); - block.save({block : {person_id : personId}}, { - success: function() { - $('#profile_buttons').attr('class', 'blocked'); - $('#sharing_message').attr('class', 'icons-circle'); - $('.profile_button, .white_bar').remove(); - } - }); - - return false; - }); -}); diff --git a/app/views/contacts/index.html.haml b/app/views/contacts/index.html.haml index d2a6b7743..4878f1da5 100644 --- a/app/views/contacts/index.html.haml +++ b/app/views/contacts/index.html.haml @@ -1,9 +1,6 @@ - content_for :page_title do = t('.title') -- content_for :head do - = javascript_include_tag :people - .container-fluid#contacts_container .row-fluid .span3 diff --git a/app/views/contacts/index.mobile.haml b/app/views/contacts/index.mobile.haml index 788a116d8..3bf6e537e 100644 --- a/app/views/contacts/index.mobile.haml +++ b/app/views/contacts/index.mobile.haml @@ -5,9 +5,6 @@ - content_for :page_title do = t('.title') -- content_for :head do - = javascript_include_tag :people - #section_header %h2 = t('.title') diff --git a/app/views/contacts/spotlight.haml b/app/views/contacts/spotlight.haml index 0ad67fc04..3b69b12f0 100644 --- a/app/views/contacts/spotlight.haml +++ b/app/views/contacts/spotlight.haml @@ -1,9 +1,6 @@ - content_for :page_title do = t('contacts.spotlight.community_spotlight') -- content_for :head do - = javascript_include_tag :people - .container-fluid#contacts_container .row-fluid diff --git a/app/views/people/index.html.haml b/app/views/people/index.html.haml index ced29ec28..a4a90ee7c 100644 --- a/app/views/people/index.html.haml +++ b/app/views/people/index.html.haml @@ -6,7 +6,6 @@ = t('search') - content_for :head do - = javascript_include_tag :people = javascript_include_tag 'contact-list' .container-fluid#people_search diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index cfa4994a3..b0999b504 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -4,7 +4,6 @@ - content_for :head do - = javascript_include_tag :people - if user_signed_in? && @person != current_user.person :javascript Mentions.options.prefillMention = Mentions._contactToMention(#{j @person.to_json}); From fba3092c614dc17f64a3f469372ea183614e965a Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 6 Sep 2014 00:55:57 +0200 Subject: [PATCH 175/785] * cleanup people_controller#show, add people_controller#stream for json * introduce new presenters and extend the functionality of the BasePresenter * add a handlebars template for the profile sidebar, render it everytime we need to update * introduce a 'aspect_membership:update' global event --- .../app/helpers/handlebars-helpers.js | 27 ++++++-- app/assets/javascripts/app/models/person.js | 39 +++++++++++ app/assets/javascripts/app/pages/profile.js | 49 +++++++------- app/assets/javascripts/app/router.js | 3 +- app/assets/javascripts/app/views.js | 1 + .../views/aspect_membership_blueprint_view.js | 14 ++-- .../app/views/aspect_membership_view.js | 14 ++-- .../app/views/profile_sidebar_view.js | 18 +++++ app/assets/stylesheets/profile.css.scss | 10 +-- .../templates/profile_sidebar_tpl.jst.hbs | 36 ++++++++++ app/controllers/people_controller.rb | 53 +++++++++------ app/helpers/people_helper.rb | 4 +- app/presenters/avatar_presenter.rb | 12 ++++ app/presenters/base_presenter.rb | 28 +++++++- app/presenters/person_presenter.rb | 65 ++++++++++++++----- app/presenters/profile_presenter.rb | 18 +++++ app/views/people/_profile_sidebar.html.haml | 36 +++++----- config/locales/javascript/javascript.en.yml | 5 ++ config/routes.rb | 1 + 19 files changed, 333 insertions(+), 100 deletions(-) create mode 100644 app/assets/javascripts/app/models/person.js create mode 100644 app/assets/javascripts/app/views/profile_sidebar_view.js create mode 100644 app/assets/templates/profile_sidebar_tpl.jst.hbs create mode 100644 app/presenters/avatar_presenter.rb create mode 100644 app/presenters/profile_presenter.rb diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index 617db4cb0..fd8bd0657 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -7,6 +7,7 @@ Handlebars.registerHelper('imageUrl', function(path){ }); Handlebars.registerHelper('linkToPerson', function(context, block) { + if( !context ) context = this; var html = ""; @@ -16,6 +17,22 @@ Handlebars.registerHelper('linkToPerson', function(context, block) { return html }); +// relationship indicator for profile page +Handlebars.registerHelper('sharingBadge', function(person) { + var i18n_scope = 'people.helper.is_not_sharing'; + var icon = 'icons-circle'; + if( person.is_sharing ) { + i18n_scope = 'people.helper.is_sharing'; + icon = 'icons-check_yes_ok'; + } + + var title = Diaspora.I18n.t(i18n_scope, {name: person.name}); + var html = ''; + return html; +}); + // allow hovercards for users that are not the current user. // returns the html class name used to trigger hovercards. @@ -29,15 +46,17 @@ Handlebars.registerHelper('hovercardable', function(person) { Handlebars.registerHelper('personImage', function(person, size, imageClass) { /* we return here if person.avatar is blank, because this happens when a * user is unauthenticated. we don't know why this happens... */ - if( _.isUndefined(person.avatar) ) { return } + var avatar = person.avatar || person.profile.avatar; + if( !avatar ) return; + var name = ( person.name ) ? person.name : 'avatar'; size = ( !_.isString(size) ) ? "small" : size; imageClass = ( !_.isString(imageClass) ) ? size : imageClass; - return _.template('', { - 'src': person.avatar[size], + return _.template('<%= title %>', { + 'src': avatar[size], 'img_class': imageClass, - 'title': _.escape(person.name) + 'title': _.escape(name) }); }); diff --git a/app/assets/javascripts/app/models/person.js b/app/assets/javascripts/app/models/person.js new file mode 100644 index 000000000..cae208afa --- /dev/null +++ b/app/assets/javascripts/app/models/person.js @@ -0,0 +1,39 @@ +app.models.Person = Backbone.Model.extend({ + urlRoot: '/people', + + url: function() { + return this.urlRoot + '/' + this.get('guid'); + }, + + initialize: function() { + if( this.get('profile') ) + this.profile = new app.models.Profile(this.get('profile')); + }, + + isSharing: function() { + var rel = this.get('relationship'); + return (rel == 'mutual' || rel == 'sharing'); + }, + + isReceiving: function() { + var rel = this.get('relationship'); + return (rel == 'mutual' || rel == 'receiving'); + }, + + isMutual: function() { + return (this.get('relationship') == 'mutual'); + }, + + isBlocked: function() { + return (this.get('relationship') == 'blocked'); + }, + + block: function() { + var self = this; + var block = new app.models.Block({block: {person_id: this.id}}); + + // return the jqXHR with Promise interface + return block.save() + .done(function() { app.events.trigger('person:block:'+self.id); }); + } +}); diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index a47a4542c..f856d2d48 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -1,44 +1,47 @@ -// TODO: this view should be model-driven an re-render when it was updated, -// instead of changing classes/attributes on elements. -app.pages.Profile = Backbone.View.extend({ +// TODO: update the aspect_membership dropdown, too, every time we render the view... +app.pages.Profile = app.views.Base.extend({ events: { 'click #block_user_button': 'blockPerson' }, + subviews: { + '#profile .badge': 'sidebarView' + }, + + tooltipSelector: '.profile_button div, .sharing_message_container', + initialize: function(opts) { - // cache element references - this.el_profile_btns = this.$('#profile_buttons'); - this.el_sharing_msg = this.$('#sharing_message'); + if( app.hasPreload('person') ) + this.model = new app.models.Person(app.parsePreload('person')); - // init tooltips - this.el_profile_btns.find('.profile_button div, .sharin_message_container') - .tooltip({placement: 'bottom'}); + this.model.on('change', this.render, this); - // respond to global events - var person_id = this.$('#profile .avatar:first').data('person_id'); - app.events.on('person:block:'+person_id, this._markBlocked, this); + // bind to global events + var id = this.model.get('id'); + app.events.on('person:block:'+id, this.reload, this); + app.events.on('aspect_membership:update', this.reload, this); + }, + + sidebarView: function() { + return new app.views.ProfileSidebar({model: this.model}); }, blockPerson: function(evt) { if( !confirm(Diaspora.I18n.t('ignore_user')) ) return; - var person_id = $(evt.target).data('person-id'); - var block = new app.models.Block({block: {person_id: person_id}}); - block.save() - .done(function() { app.events.trigger('person:block:'+person_id); }) - .fail(function() { Diaspora.page.flashMessages.render({ + var block = this.model.block(); + block.fail(function() { + Diaspora.page.flashMessages.render({ success: false, notice: Diaspora.I18n.t('ignore_failed') - }); }); + }); + }); return false; }, - _markBlocked: function() { - this.el_profile_btns.attr('class', 'blocked'); - this.el_sharing_msg.attr('class', 'icons-circle'); - - this.el_profile_btns.find('.profile_button, .white_bar').remove(); + reload: function() { + this.model.fetch(); } }); diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 21d90707d..706eecf1a 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -54,10 +54,11 @@ app.Router = Backbone.Router.extend({ renderPage : function(pageConstructor){ app.page && app.page.unbind && app.page.unbind(); //old page might mutate global events $(document).keypress, so unbind before creating app.page = pageConstructor(); //create new page after the world is clean (like that will ever happen) + app.page.render(); if( !$.contains(document, app.page.el) ) { // view element isn't already attached to the DOM, insert it - $("#container").empty().append(app.page.render().el); + $("#container").empty().append(app.page.el); } }, diff --git a/app/assets/javascripts/app/views.js b/app/assets/javascripts/app/views.js index 80c40b3a5..ea61a1a8d 100644 --- a/app/assets/javascripts/app/views.js +++ b/app/assets/javascripts/app/views.js @@ -38,6 +38,7 @@ app.views.Base = Backbone.View.extend({ this.template = HandlebarsTemplates[this.templateName+"_tpl"] if(!this.template) { console.log(this.templateName ? ("no template for " + this.templateName) : "no templateName specified") + return; } this.$el diff --git a/app/assets/javascripts/app/views/aspect_membership_blueprint_view.js b/app/assets/javascripts/app/views/aspect_membership_blueprint_view.js index 985dd93cc..40b45d312 100644 --- a/app/assets/javascripts/app/views/aspect_membership_blueprint_view.js +++ b/app/assets/javascripts/app/views/aspect_membership_blueprint_view.js @@ -23,6 +23,7 @@ app.views.AspectMembershipBlueprint = Backbone.View.extend({ // -> addMembership // -> removeMembership _clickHandler: function(evt) { + var promise = null; this.list_item = $(evt.target); this.dropdown = this.list_item.parent(); @@ -30,13 +31,18 @@ app.views.AspectMembershipBlueprint = Backbone.View.extend({ if( this.list_item.is('.selected') ) { var membership_id = this.list_item.data('membership_id'); - this.removeMembership(membership_id); + promise = this.removeMembership(membership_id); } else { var aspect_id = this.list_item.data('aspect_id'); var person_id = this.dropdown.data('person_id'); - this.addMembership(person_id, aspect_id); + promise = this.addMembership(person_id, aspect_id); } + promise && promise.always(function() { + // trigger a global event + app.events.trigger('aspect_membership:update'); + }); + return false; // stop the event }, @@ -57,7 +63,7 @@ app.views.AspectMembershipBlueprint = Backbone.View.extend({ this._displayError('aspect_dropdown.error'); }, this); - aspect_membership.save(); + return aspect_membership.save(); }, _successSaveCb: function(aspect_membership) { @@ -100,7 +106,7 @@ app.views.AspectMembershipBlueprint = Backbone.View.extend({ this._displayError('aspect_dropdown.error_remove'); }, this); - aspect_membership.destroy(); + return aspect_membership.destroy(); }, _successDestroyCb: function(aspect_membership) { diff --git a/app/assets/javascripts/app/views/aspect_membership_view.js b/app/assets/javascripts/app/views/aspect_membership_view.js index b299fcb00..85b2391e6 100644 --- a/app/assets/javascripts/app/views/aspect_membership_view.js +++ b/app/assets/javascripts/app/views/aspect_membership_view.js @@ -23,6 +23,7 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({ // -> addMembership // -> removeMembership _clickHandler: function(evt) { + var promise = null; this.list_item = $(evt.target).closest('li.aspect_selector'); this.dropdown = this.list_item.parent(); @@ -30,13 +31,18 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({ if( this.list_item.is('.selected') ) { var membership_id = this.list_item.data('membership_id'); - this.removeMembership(membership_id); + promise = this.removeMembership(membership_id); } else { var aspect_id = this.list_item.data('aspect_id'); var person_id = this.dropdown.data('person_id'); - this.addMembership(person_id, aspect_id); + promise = this.addMembership(person_id, aspect_id); } + promise && promise.always(function() { + // trigger a global event + app.events.trigger('aspect_membership:update'); + }); + return false; // stop the event }, @@ -57,7 +63,7 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({ this._displayError('aspect_dropdown.error'); }, this); - aspect_membership.save(); + return aspect_membership.save(); }, _successSaveCb: function(aspect_membership) { @@ -99,7 +105,7 @@ app.views.AspectMembership = app.views.AspectsDropdown.extend({ this._displayError('aspect_dropdown.error_remove'); }, this); - aspect_membership.destroy(); + return aspect_membership.destroy(); }, _successDestroyCb: function(aspect_membership) { diff --git a/app/assets/javascripts/app/views/profile_sidebar_view.js b/app/assets/javascripts/app/views/profile_sidebar_view.js new file mode 100644 index 000000000..ea318d2f4 --- /dev/null +++ b/app/assets/javascripts/app/views/profile_sidebar_view.js @@ -0,0 +1,18 @@ + +app.views.ProfileSidebar = app.views.Base.extend({ + templateName: 'profile_sidebar', + + presenter: function() { + return _.extend({}, this.defaultPresenter(), { + do_profile_btns: this._shouldDoProfileBtns(), + is_sharing: this.model.isSharing(), + is_receiving: this.model.isReceiving(), + is_mutual: this.model.isMutual(), + is_not_blocked: !this.model.isBlocked() + }); + }, + + _shouldDoProfileBtns: function() { + return (app.currentUser.authenticated() && !this.model.get('is_own_profile')); + }, +}); diff --git a/app/assets/stylesheets/profile.css.scss b/app/assets/stylesheets/profile.css.scss index a826ca2ba..de1dfe8cc 100644 --- a/app/assets/stylesheets/profile.css.scss +++ b/app/assets/stylesheets/profile.css.scss @@ -44,7 +44,7 @@ width: 50px; } } - .only_sharing { + .sharing { background-color: rgb(142, 222, 61); .profile_button { width: 150px; @@ -77,7 +77,7 @@ background-color: white; @include border-bottom-left-radius(8px); } - + .profile_button { display: inline-block; text-align: center; @@ -85,13 +85,13 @@ a { @include opacity(0.5); } a:hover { @include opacity(1); } - - .icons-check_yes_ok { + + .icons-check_yes_ok { display: inline-block; height: 18px; width: 18px; } - .icons-circle { + .icons-circle { display: inline-block; height: 18px; width: 18px; diff --git a/app/assets/templates/profile_sidebar_tpl.jst.hbs b/app/assets/templates/profile_sidebar_tpl.jst.hbs new file mode 100644 index 000000000..70240e169 --- /dev/null +++ b/app/assets/templates/profile_sidebar_tpl.jst.hbs @@ -0,0 +1,36 @@ + +
    + {{#linkToPerson this}} + {{{personImage this "l"}}} + {{/linkToPerson}} +
    + +{{#if do_profile_btns}} +
    + {{{sharingBadge this}}} + + {{#if is_receiving}} + + {{/if}} + + {{#if is_mutual}} +
    + +
    +
    +
    + {{/if}} + + {{#if is_not_blocked}} +
    + +
    +
    +
    + {{/if}} +
    +{{/if}} diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f160c5992..59f8c5862 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -76,36 +76,51 @@ class PeopleController < ApplicationController def show @person = Person.find_from_guid_or_username(params) + # view this profile on the home pod, if you don't want to sign in... authenticate_user! if remote_profile_with_no_user_session? raise Diaspora::AccountClosed if @person.closed_account? mark_corresponding_notifications_read if user_signed_in? - @post_type = :all - @aspect = :profile - @stream = Stream::Person.new(current_user, @person, :max_time => max_time) - @profile = @person.profile - @photos = photos_from(@person) - - unless params[:format] == "json" # hovercard - if current_user - @block = current_user.blocks.where(:person_id => @person.id).first - @contact = current_user.contact_for(@person) - if @contact && !params[:only_posts] - @contacts_of_contact_count = @contact.contacts.count(:all) - @contacts_of_contact = @contact.contacts.limit(8) - else - @contact ||= Contact.new - end - end - end + @aspect = :profile # what does this do? + @post_type = :all # for mobile + @person_json = PersonPresenter.new(@person, current_user).full_hash_with_profile respond_to do |format| format.all do + @profile = @person.profile + @photos = photos_from(@person) + if current_user + @block = current_user.blocks.where(:person_id => @person.id).first + @contact = current_user.contact_for(@person) + if @contact && !params[:only_posts] + @contacts_of_contact_count = @contact.contacts.count(:all) + @contacts_of_contact = @contact.contacts.limit(8) + else + @contact ||= Contact.new + end + end + + gon.preloads[:person] = @person_json respond_with @person, :locals => {:post_type => :all} end - format.json { render :json => @stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) }} + format.json { render :json => @person_json } + end + end + + def stream + @person = Person.find_from_guid_or_username(params) + + authenticate_user! if remote_profile_with_no_user_session? + raise Diaspora::AccountClosed if @person.closed_account? + + respond_to do |format| + format.all { redirect_to person_path(@person) } + format.json do + @stream = Stream::Person.new(current_user, @person, max_time: max_time) + render json: @stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) } + end end end diff --git a/app/helpers/people_helper.rb b/app/helpers/people_helper.rb index fd426f9f6..75a63cd88 100644 --- a/app/helpers/people_helper.rb +++ b/app/helpers/people_helper.rb @@ -14,7 +14,7 @@ module PeopleHelper end end end - + def birthday_format(bday) if bday.year == 1000 I18n.l bday, :format => I18n.t('date.formats.birthday') @@ -96,7 +96,7 @@ module PeopleHelper elsif contact.mutual? 'mutual' elsif contact.sharing? - 'only_sharing' + 'sharing' elsif contact.receiving? 'receiving' else diff --git a/app/presenters/avatar_presenter.rb b/app/presenters/avatar_presenter.rb new file mode 100644 index 000000000..10cabb949 --- /dev/null +++ b/app/presenters/avatar_presenter.rb @@ -0,0 +1,12 @@ + +class AvatarPresenter < BasePresenter + + DEFAULT_IMAGE = ActionController::Base.helpers.image_path('user/default.png') + + def base_hash + { s: image_url_small || DEFAULT_IMAGE, + m: image_url_medium || DEFAULT_IMAGE, + l: image_url || DEFAULT_IMAGE + } + end +end diff --git a/app/presenters/base_presenter.rb b/app/presenters/base_presenter.rb index 8f83962e9..86845a8b4 100644 --- a/app/presenters/base_presenter.rb +++ b/app/presenters/base_presenter.rb @@ -1,5 +1,29 @@ class BasePresenter - def self.as_collection(collection) - collection.map{|object| self.new(object).as_json} + attr_reader :current_user + + class << self + def new(*args) + return NilPresenter.new if args[0].nil? + super *args + end + + def as_collection(collection, method=:as_json, *args) + collection.map{|object| self.new(object, *args).send(method) } + end + end + + def initialize(presentable, curr_user=nil) + @presentable = presentable + @current_user = curr_user + end + + def method_missing(method, *args) + @presentable.send(method, *args) if @presentable.respond_to?(method) + end + + class NilPresenter + def method_missing(method, *args) + nil + end end end diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index 7b635125a..46b3839f1 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -1,33 +1,64 @@ -class PersonPresenter - def initialize(person, current_user = nil) - @person = person - @current_user = current_user +class PersonPresenter < BasePresenter + def base_hash + { id: id, + guid: guid, + name: name, + diaspora_id: diaspora_handle + } + end + + def full_hash + base_hash.merge({ + relationship: relationship, + is_own_profile: own_profile? + }) + end + + def full_hash_with_avatar + full_hash.merge({avatar: AvatarPresenter.new(profile).base_hash}) + end + + def full_hash_with_profile + full_hash.merge({profile: ProfilePresenter.new(profile).full_hash}) end def as_json(options={}) - attrs = @person.as_api_response(:backbone).merge( - { - :is_own_profile => is_own_profile - }) + attrs = full_hash_with_avatar - if is_own_profile || person_is_following_current_user + if own_profile? || person_is_following_current_user attrs.merge!({ - :location => @person.location, - :birthday => @person.formatted_birthday, - :bio => @person.bio + :location => @presentable.location, + :birthday => @presentable.formatted_birthday, + :bio => @presentable.bio }) end attrs end - def is_own_profile - @current_user.try(:person) == @person - end - protected + def own_profile? + current_user.try(:person) == @presentable + end + + def relationship + contact = current_user.contact_for(@presentable) + + is_blocked = current_user.blocks.where(person_id: id).limit(1).any? + is_mutual = contact ? contact.mutual? : false + is_sharing = contact ? contact.sharing? : false + is_receiving = contact ? contact.receiving? : false + + if is_blocked then :blocked + elsif is_mutual then :mutual + elsif is_sharing then :sharing + elsif is_receiving then :receiving + else :not_sharing + end + end + def person_is_following_current_user - @person.shares_with(@current_user) + @presentable.shares_with(@current_user) end end diff --git a/app/presenters/profile_presenter.rb b/app/presenters/profile_presenter.rb new file mode 100644 index 000000000..8f916431a --- /dev/null +++ b/app/presenters/profile_presenter.rb @@ -0,0 +1,18 @@ +class ProfilePresenter < BasePresenter + def base_hash + { id: id, + tags: tag_string, + bio: bio, + location: location, + gender: gender, + birthday: formatted_birthday, + searchable: searchable + } + end + + def full_hash + base_hash.merge({ + avatar: AvatarPresenter.new(@presentable).base_hash, + }) + end +end diff --git a/app/views/people/_profile_sidebar.html.haml b/app/views/people/_profile_sidebar.html.haml index 46a43376a..d84c79c1c 100644 --- a/app/views/people/_profile_sidebar.html.haml +++ b/app/views/people/_profile_sidebar.html.haml @@ -3,31 +3,29 @@ -# the COPYRIGHT file. #profile - .profile_photo - = person_image_link(person, :size => :thumb_large, :to => :photos) + .badge + .profile_photo + = person_image_link(person, :size => :thumb_large, :to => :photos) - - if user_signed_in? - - if person != current_user.person - %div#profile_buttons{ :class => profile_buttons_class(@contact, @block) } - = sharing_message(@person, @contact) + - if user_signed_in? + - if person != current_user.person + %div#profile_buttons{ :class => profile_buttons_class(@contact, @block) } + = sharing_message(@person, @contact) - - if @contact.receiving? - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-mention', :title => t('people.show.mention'), :id => 'mention_button'), new_status_message_path(:person_id => @person.id), :rel => 'facebox' - .white_bar + - if @contact.receiving? + .profile_button + = link_to content_tag(:div, nil, :class => 'icons-mention', :title => t('people.show.mention'), :id => 'mention_button'), new_status_message_path(:person_id => @person.id), :rel => 'facebox' + .white_bar - - if @contact.mutual? + - if @contact.mutual? + .profile_button + = link_to content_tag(:div, nil, :class => 'icons-message', :title => t('people.show.message'), :id => 'message_button'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :facebox => true), :rel => 'facebox' + .white_bar + .profile_button - = link_to content_tag(:div, nil, :class => 'icons-message', :title => t('people.show.message'), :id => 'message_button'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :facebox => true), :rel => 'facebox' - .white_bar - - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? - - - %br + = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? -if contact.sharing? || person == current_user.person %ul#profile_information diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index 6cd153fd8..9adceca69 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -115,6 +115,11 @@ en: wasnt_that_interesting: "OK, I suppose #<%= tagName %> wasn't all that interesting..." people: not_found: "and no one was found..." + mention: "Mention" + message: "Message" + helper: + is_sharing: "<%= name %> is sharing with you" + is_not_sharing: "<%= name %> is not sharing with you" conversation: participants: "Participants" diff --git a/config/routes.rb b/config/routes.rb index e32770a80..dbb06bde4 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -159,6 +159,7 @@ Diaspora::Application.routes.draw do resources :photos get :contacts get "aspect_membership_button" => :aspect_membership_dropdown, :as => "aspect_membership_button" + get :stream get :hovercard member do From 0092c9c48347b2f005516345070a70379a919cf4 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 6 Sep 2014 16:38:19 +0200 Subject: [PATCH 176/785] * create a handlebars view for the profile header * unblock the user via ajax --- app/assets/javascripts/app/models/person.js | 12 ++++++++++ app/assets/javascripts/app/pages/profile.js | 22 +++++++++++++++++-- .../app/views/profile_stream_view.js | 10 +++++++++ .../templates/profile_sidebar_tpl.jst.hbs | 4 ++-- .../templates/profile_stream_tpl.jst.hbs | 22 +++++++++++++++++++ app/presenters/block_presenter.rb | 6 +++++ app/presenters/person_presenter.rb | 16 +++++++++++--- app/views/aspects/_aspect_stream.haml | 13 ++++++++++- config/locales/javascript/javascript.en.yml | 3 +++ 9 files changed, 100 insertions(+), 8 deletions(-) create mode 100644 app/assets/javascripts/app/views/profile_stream_view.js create mode 100644 app/assets/templates/profile_stream_tpl.jst.hbs create mode 100644 app/presenters/block_presenter.rb diff --git a/app/assets/javascripts/app/models/person.js b/app/assets/javascripts/app/models/person.js index cae208afa..634f6b6f0 100644 --- a/app/assets/javascripts/app/models/person.js +++ b/app/assets/javascripts/app/models/person.js @@ -35,5 +35,17 @@ app.models.Person = Backbone.Model.extend({ // return the jqXHR with Promise interface return block.save() .done(function() { app.events.trigger('person:block:'+self.id); }); + }, + + unblock: function() { + var self = this; + if( !this.get('block') ) { + var def = $.Deferred(); + return def.reject(); + } + + var block = new app.models.Block({id: this.get('block').id}); + return block.destroy() + .done(function() { app.events.trigger('person:unblock:'+self.id); }); } }); diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index f856d2d48..86182b580 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -2,11 +2,13 @@ // TODO: update the aspect_membership dropdown, too, every time we render the view... app.pages.Profile = app.views.Base.extend({ events: { - 'click #block_user_button': 'blockPerson' + 'click #block_user_button': 'blockPerson', + 'click #unblock_user_button': 'unblockPerson' }, subviews: { - '#profile .badge': 'sidebarView' + '#profile .badge': 'sidebarView', + '.stream_container': 'streamView' }, tooltipSelector: '.profile_button div, .sharing_message_container', @@ -20,6 +22,7 @@ app.pages.Profile = app.views.Base.extend({ // bind to global events var id = this.model.get('id'); app.events.on('person:block:'+id, this.reload, this); + app.events.on('person:unblock:'+id, this.reload, this); app.events.on('aspect_membership:update', this.reload, this); }, @@ -27,6 +30,10 @@ app.pages.Profile = app.views.Base.extend({ return new app.views.ProfileSidebar({model: this.model}); }, + streamView: function() { + return new app.views.ProfileStream({model: this.model}); + }, + blockPerson: function(evt) { if( !confirm(Diaspora.I18n.t('ignore_user')) ) return; @@ -41,6 +48,17 @@ app.pages.Profile = app.views.Base.extend({ return false; }, + unblockPerson: function(evt) { + var block = this.model.unblock(); + block.fail(function() { + Diaspora.page.flashMessages.render({ + success: false, + notice: Diaspora.I18.t('unblock_failed') + }); + }); + return false; + }, + reload: function() { this.model.fetch(); } diff --git a/app/assets/javascripts/app/views/profile_stream_view.js b/app/assets/javascripts/app/views/profile_stream_view.js new file mode 100644 index 000000000..d11fc2047 --- /dev/null +++ b/app/assets/javascripts/app/views/profile_stream_view.js @@ -0,0 +1,10 @@ + +app.views.ProfileStream = app.views.Base.extend({ + templateName: 'profile_stream', + + presenter: function() { + return _.extend({}, this.defaultPresenter(), { + is_blocked: this.model.isBlocked() + }); + } +}); diff --git a/app/assets/templates/profile_sidebar_tpl.jst.hbs b/app/assets/templates/profile_sidebar_tpl.jst.hbs index 70240e169..a3a3b7bea 100644 --- a/app/assets/templates/profile_sidebar_tpl.jst.hbs +++ b/app/assets/templates/profile_sidebar_tpl.jst.hbs @@ -11,7 +11,7 @@ {{#if is_receiving}} @@ -19,7 +19,7 @@ {{#if is_mutual}} diff --git a/app/assets/templates/profile_stream_tpl.jst.hbs b/app/assets/templates/profile_stream_tpl.jst.hbs new file mode 100644 index 000000000..78572f9f1 --- /dev/null +++ b/app/assets/templates/profile_stream_tpl.jst.hbs @@ -0,0 +1,22 @@ +
    +
    + {{#if loggedIn}} + {{#if is_own_profile}} + {{!-- can't block myself, so don't check it here --}} + {{t 'people.edit_my_profile'}} + {{/if}} + {{#if is_blocked}} + {{t 'people.stop_ignoring'}} + {{else}} +
    + {{/if}} + {{/if}} +
    + +

    {{name}}

    + {{diaspora_id}} + +
    + +
    +
    diff --git a/app/presenters/block_presenter.rb b/app/presenters/block_presenter.rb new file mode 100644 index 000000000..937d057b6 --- /dev/null +++ b/app/presenters/block_presenter.rb @@ -0,0 +1,6 @@ + +class BlockPresenter < BasePresenter + def base_hash + { id: id } + end +end diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index 46b3839f1..cb48f5b20 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -10,6 +10,7 @@ class PersonPresenter < BasePresenter def full_hash base_hash.merge({ relationship: relationship, + block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false, is_own_profile: own_profile? }) end @@ -45,12 +46,11 @@ class PersonPresenter < BasePresenter def relationship contact = current_user.contact_for(@presentable) - is_blocked = current_user.blocks.where(person_id: id).limit(1).any? is_mutual = contact ? contact.mutual? : false is_sharing = contact ? contact.sharing? : false is_receiving = contact ? contact.receiving? : false - if is_blocked then :blocked + if is_blocked? then :blocked elsif is_mutual then :mutual elsif is_sharing then :sharing elsif is_receiving then :receiving @@ -59,6 +59,16 @@ class PersonPresenter < BasePresenter end def person_is_following_current_user - @presentable.shares_with(@current_user) + @presentable.shares_with(current_user) + end + + private + + def current_user_person_block + @block ||= current_user.blocks.where(person_id: id).limit(1).first + end + + def is_blocked? + current_user_person_block.present? end end diff --git a/app/views/aspects/_aspect_stream.haml b/app/views/aspects/_aspect_stream.haml index 46528920c..2f6d7c72e 100644 --- a/app/views/aspects/_aspect_stream.haml +++ b/app/views/aspects/_aspect_stream.haml @@ -6,7 +6,18 @@ %h3#aspect_stream_header.stream_title = stream.title -= render 'publisher/publisher', :selected_aspects => stream.aspects, :aspect_ids => stream.aspect_ids, :aspect => stream.aspect +- aspects = current_user.aspects +- aspect = aspects.first +- aspect_ids = aspects.map { |a| a.id } +- if stream + - aspects = stream.aspects + - aspect = stream.aspect + - aspect_ids = stream.aspect_ids + += render 'publisher/publisher', + selected_aspects: aspects, + aspect_ids: aspect_ids, + aspect: aspect = render 'aspects/no_posts_message' #gs-shim{:title => popover_with_close_html("3. #{t('.stay_updated')}"), 'data-content' => t('.stay_updated_explanation')} diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index 9adceca69..688568c1f 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -17,6 +17,7 @@ en: exists: "The report already exists" ignore_user: "Ignore this user?" ignore_failed: "Unable to ignore this user" + unblock_failed: "Unblocking this user has failed" and: "and" comma: "," edit: "Edit" @@ -117,6 +118,8 @@ en: not_found: "and no one was found..." mention: "Mention" message: "Message" + edit_my_profile: "Edit my profile" + stop_ignoring: "Stop ignoring" helper: is_sharing: "<%= name %> is sharing with you" is_not_sharing: "<%= name %> is not sharing with you" From 9a16560d8d3abd41d8774c71cb2cf6a2ae943343 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 6 Sep 2014 19:18:08 +0200 Subject: [PATCH 177/785] * rename profile header view to make name more accurate * include 'js-routes' for rails routes in javascript (TODO: config options?) * add handlebars helper for rails routes --- Gemfile | 1 + Gemfile.lock | 4 + .../app/helpers/handlebars-helpers.js | 9 ++ app/assets/javascripts/app/pages/profile.js | 7 +- .../javascripts/app/views/hovercard_view.js | 1 + .../app/views/profile_header_view.js | 25 ++++ .../app/views/profile_sidebar_view.js | 5 + .../app/views/profile_stream_view.js | 10 -- app/assets/javascripts/main.js | 1 + ...tpl.jst.hbs => profile_header_tpl.jst.hbs} | 13 +- .../templates/profile_sidebar_tpl.jst.hbs | 7 +- app/controllers/people_controller.rb | 6 +- app/presenters/person_presenter.rb | 7 +- app/views/people/_profile_sidebar.html.haml | 112 +++++++++--------- app/views/people/show.html.haml | 4 +- 15 files changed, 131 insertions(+), 81 deletions(-) create mode 100644 app/assets/javascripts/app/views/profile_header_view.js delete mode 100644 app/assets/javascripts/app/views/profile_stream_view.js rename app/assets/templates/{profile_stream_tpl.jst.hbs => profile_header_tpl.jst.hbs} (69%) diff --git a/Gemfile b/Gemfile index 9f348605e..213b31301 100644 --- a/Gemfile +++ b/Gemfile @@ -81,6 +81,7 @@ gem 'handlebars_assets', '0.18.0' gem 'jquery-rails', '3.1.2' gem 'rails-assets-jquery', '1.11.1' # Should be kept in sync with jquery-rails gem 'js_image_paths', '0.0.1' +gem 'js-routes', '0.9.9' # jQuery plugins diff --git a/Gemfile.lock b/Gemfile.lock index 483a6fc24..b13a4a6d0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -238,6 +238,9 @@ GEM thor (>= 0.14, < 2.0) jquery-ui-rails (4.2.1) railties (>= 3.2.16) + js-routes (0.9.9) + railties (>= 3.2) + sprockets-rails js_image_paths (0.0.1) rails (~> 4.0) json (1.8.1) @@ -533,6 +536,7 @@ DEPENDENCIES jasmine (= 2.0.2) jasmine-jquery-rails (= 2.0.3) jquery-rails (= 3.1.2) + js-routes (= 0.9.9) js_image_paths (= 0.0.1) json (= 1.8.1) markerb (= 1.0.2) diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index fd8bd0657..ebb1e132b 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -6,6 +6,15 @@ Handlebars.registerHelper('imageUrl', function(path){ return ImagePaths.get(path); }); +Handlebars.registerHelper('urlTo', function(path_helper, id, data){ + if( !data ) { + // only one argument given to helper, mangle parameters + data = id; + return Routes[path_helper+'_path'](data.hash); + } + return Routes[path_helper+'_path'](id, data.hash); +}); + Handlebars.registerHelper('linkToPerson', function(context, block) { if( !context ) context = this; var html = "{{t 'people.edit_my_profile'}} - {{/if}} - {{#if is_blocked}} + {{t 'people.edit_my_profile'}} + {{else}} {{#if is_blocked}} {{t 'people.stop_ignoring'}} {{else}}
    - {{/if}} + {{/if}}{{/if}} {{/if}}
    @@ -17,6 +16,10 @@ {{diaspora_id}}
    - + {{#if loggedIn}} + TODO + {{/if}}
    + +
    diff --git a/app/assets/templates/profile_sidebar_tpl.jst.hbs b/app/assets/templates/profile_sidebar_tpl.jst.hbs index a3a3b7bea..4d0bba7cc 100644 --- a/app/assets/templates/profile_sidebar_tpl.jst.hbs +++ b/app/assets/templates/profile_sidebar_tpl.jst.hbs @@ -10,22 +10,25 @@ {{{sharingBadge this}}} {{#if is_receiving}} + {{!-- create status message with mention --}} {{/if}} {{#if is_mutual}} + {{!-- create private conversation with person --}} {{/if}} {{#if is_not_blocked}} + {{!-- ignore the person --}}
    diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 59f8c5862..e8d569ec3 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -82,8 +82,8 @@ class PeopleController < ApplicationController mark_corresponding_notifications_read if user_signed_in? - @aspect = :profile # what does this do? - @post_type = :all # for mobile + @aspect = :profile # let aspect dropdown create new aspects + @post_type = :all # for mobile @person_json = PersonPresenter.new(@person, current_user).full_hash_with_profile respond_to do |format| @@ -179,7 +179,9 @@ class PeopleController < ApplicationController return render :text => I18n.t('people.person.thats_you') if @person == current_user.person @contact = current_user.contact_for(@person) || Contact.new + @aspect = :profile if params[:create] # let aspect dropdown create new aspects bootstrap = params[:bootstrap] || false + render :partial => 'aspect_membership_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left', :bootstrap => bootstrap} end diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index cb48f5b20..7c0f30466 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -11,6 +11,7 @@ class PersonPresenter < BasePresenter base_hash.merge({ relationship: relationship, block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false, + contact: { id: current_user_person_contact.id }, is_own_profile: own_profile? }) end @@ -44,7 +45,7 @@ class PersonPresenter < BasePresenter end def relationship - contact = current_user.contact_for(@presentable) + contact = current_user_person_contact is_mutual = contact ? contact.mutual? : false is_sharing = contact ? contact.sharing? : false @@ -68,6 +69,10 @@ class PersonPresenter < BasePresenter @block ||= current_user.blocks.where(person_id: id).limit(1).first end + def current_user_person_contact + @contact ||= current_user.contact_for(@presentable) + end + def is_blocked? current_user_person_block.present? end diff --git a/app/views/people/_profile_sidebar.html.haml b/app/views/people/_profile_sidebar.html.haml index d84c79c1c..f94dd9aec 100644 --- a/app/views/people/_profile_sidebar.html.haml +++ b/app/views/people/_profile_sidebar.html.haml @@ -27,64 +27,64 @@ .profile_button = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? - -if contact.sharing? || person == current_user.person - %ul#profile_information + -if contact.sharing? || person == current_user.person + %ul#profile_information - - unless person.bio.blank? - %li - %h4 - =t('.bio') - %div{ :class => direction_for(person.bio) } - = person.profile.bio_message.markdownified - - unless person.profile.location.blank? - %li - %h4 - =t('.location') - %div{ :class => direction_for(person.location) } - = person.profile.location_message.markdownified + - unless person.bio.blank? + %li + %h4 + =t('.bio') + %div{ :class => direction_for(person.bio) } + = person.profile.bio_message.markdownified + - unless person.profile.location.blank? + %li + %h4 + =t('.location') + %div{ :class => direction_for(person.location) } + = person.profile.location_message.markdownified - - unless person.gender.blank? - %li - %h4 - =t('.gender') - = person.gender + - unless person.gender.blank? + %li + %h4 + =t('.gender') + = person.gender - - unless person.birthday.blank? - %li - %h4 - =t('.born') - = birthday_format(person.birthday) - - if @photos.present? - %li.image_list - %h4 - = t('.photos') - .item_count - = "#{@photos.count(:all)}" - - @photos.limit(8).each do |photo| - = image_tag(photo.url(:thumb_small)) - %br - = link_to t('layouts.header.view_all'), person_photos_path(person) + - unless person.birthday.blank? + %li + %h4 + =t('.born') + = birthday_format(person.birthday) + - if @photos.present? + %li.image_list + %h4 + = t('.photos') + .item_count + = "#{@photos.count(:all)}" + - @photos.limit(8).each do |photo| + = image_tag(photo.url(:thumb_small)) + %br + = link_to t('layouts.header.view_all'), person_photos_path(person) - - if person == current_user.person - %li.image_list - %h4 - = t('_contacts') - .item_count - = all_contacts_count - .section.contact_pictures - - current_user.contacts.limit(8).each do |contact| - = person_image_link contact.person, :size => :thumb_small - %p.see_all= link_to t('layouts.header.view_all'), contacts_path - - elsif @contact.persisted? && @contacts_of_contact_count > 0 - %li.image_list - %h4 - = t('_contacts') - .item_count - = @contacts_of_contact_count - .section.contact_pictures - -@contacts_of_contact.limit(8).each do |person| - = person_image_link person, :size => :thumb_small - %p.see_all= link_to t('layouts.header.view_all'), person_contacts_path(@person) + - if person == current_user.person + %li.image_list + %h4 + = t('_contacts') + .item_count + = all_contacts_count + .section.contact_pictures + - current_user.contacts.limit(8).each do |contact| + = person_image_link contact.person, :size => :thumb_small + %p.see_all= link_to t('layouts.header.view_all'), contacts_path + - elsif @contact.persisted? && @contacts_of_contact_count > 0 + %li.image_list + %h4 + = t('_contacts') + .item_count + = @contacts_of_contact_count + .section.contact_pictures + -@contacts_of_contact.limit(8).each do |person| + = person_image_link person, :size => :thumb_small + %p.see_all= link_to t('layouts.header.view_all'), person_contacts_path(@person) - %br - %br + %br + %br diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index b0999b504..54a37c870 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -15,9 +15,11 @@ = render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact } .span-18.last - .stream_container + .profile_header = render 'people/sub_header', :person => @person, :contact => @contact + .stream_container + #main_stream.stream - if @block.present? .dull From 2572fb77fc96e988620305ac36cbefc4aa1e9b76 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Mon, 8 Sep 2014 03:35:40 +0200 Subject: [PATCH 178/785] * refactored text direction detector into helper (also for handlebars) * added handlebars helper for markdown formatting * finished port of profile sidebar view to handlebars template * people_controller refactoring --- .../app/helpers/direction_detector.js | 52 +++++++++++++++ .../app/helpers/handlebars-helpers.js | 8 +++ .../javascripts/app/helpers/text_formatter.js | 2 +- app/assets/javascripts/app/pages/profile.js | 12 +++- .../app/views/profile_sidebar_view.js | 24 ++++++- .../javascripts/widgets/direction-detector.js | 47 ++------------ .../templates/profile_sidebar_tpl.jst.hbs | 65 ++++++++++++++++++- app/controllers/people_controller.rb | 55 ++++++++++------ app/presenters/base_presenter.rb | 2 +- app/presenters/person_presenter.rb | 6 +- app/presenters/photo_presenter.rb | 16 +++++ app/presenters/profile_presenter.rb | 6 ++ config/locales/javascript/javascript.en.yml | 7 ++ 13 files changed, 232 insertions(+), 70 deletions(-) create mode 100644 app/assets/javascripts/app/helpers/direction_detector.js create mode 100644 app/presenters/photo_presenter.rb diff --git a/app/assets/javascripts/app/helpers/direction_detector.js b/app/assets/javascripts/app/helpers/direction_detector.js new file mode 100644 index 000000000..ee1495718 --- /dev/null +++ b/app/assets/javascripts/app/helpers/direction_detector.js @@ -0,0 +1,52 @@ +(function() { + app.helpers.txtDirection = { + setCssFor: function(str, on_element) { + if( this.isRTL(str) ) { + $(on_element).css('direction', 'rtl'); + } else { + $(on_element).css('direction', 'ltr'); + } + }, + + classFor: function(str) { + if( this.isRTL(str) ) return 'rtl'; + return 'ltr'; + }, + + isRTL: function(str) { + if(typeof str !== "string" || str.length < 1) { + return false; + } + + var charCode = str.charCodeAt(0); + if(charCode >= 1536 && charCode <= 1791) // Sarabic, Persian, ... + return true; + + else if(charCode >= 65136 && charCode <= 65279) // Arabic present 1 + return true; + + else if(charCode >= 64336 && charCode <= 65023) // Arabic present 2 + return true; + + else if(charCode>=1424 && charCode<=1535) // Hebrew + return true; + + else if(charCode>=64256 && charCode<=64335) // Hebrew present + return true; + + else if(charCode>=1792 && charCode<=1871) // Syriac + return true; + + else if(charCode>=1920 && charCode<=1983) // Thaana + return true; + + else if(charCode>=1984 && charCode<=2047) // NKo + return true; + + else if(charCode>=11568 && charCode<=11647) // Tifinagh + return true; + + return false; + } + }; +})(); diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index ebb1e132b..3affa6cdc 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -2,6 +2,10 @@ Handlebars.registerHelper('t', function(scope, values) { return Diaspora.I18n.t(scope, values.hash) }); +Handlebars.registerHelper('txtDirClass', function(str) { + return app.helpers.txtDirection.classFor(str); +}); + Handlebars.registerHelper('imageUrl', function(path){ return ImagePaths.get(path); }); @@ -72,3 +76,7 @@ Handlebars.registerHelper('personImage', function(person, size, imageClass) { Handlebars.registerHelper('localTime', function(timestamp) { return new Date(timestamp).toLocaleString(); }); + +Handlebars.registerHelper('fmtText', function(text) { + return new Handlebars.SafeString(app.helpers.textFormatter(text, null)); +}); diff --git a/app/assets/javascripts/app/helpers/text_formatter.js b/app/assets/javascripts/app/helpers/text_formatter.js index 9f27029c6..6e15e2ed3 100644 --- a/app/assets/javascripts/app/helpers/text_formatter.js +++ b/app/assets/javascripts/app/helpers/text_formatter.js @@ -7,7 +7,7 @@ $(function() { (function(){ //make it so I take text and mentions rather than the modelapp.helpers.textFormatter( var textFormatter = function textFormatter(text, model) { - var mentions = model.get("mentioned_people"); + var mentions = model ? model.get("mentioned_people") : []; return textFormatter.mentionify( textFormatter.hashtagify( diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 8c622ddcf..65bb87eb0 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -6,7 +6,7 @@ app.pages.Profile = app.views.Base.extend({ }, subviews: { - '#profile .badge': 'sidebarView', + '#profile': 'sidebarView', '.profile_header': 'headerView' }, @@ -15,6 +15,10 @@ app.pages.Profile = app.views.Base.extend({ initialize: function(opts) { if( app.hasPreload('person') ) this.model = new app.models.Person(app.parsePreload('person')); + if( app.hasPreload('photos') ) + this.photos = app.parsePreload('photos'); // we don't interact with it, so no model + if( app.hasPreload('contacts') ) + this.contacts = app.parsePreload('contacts'); // we don't interact with it, so no model this.model.on('change', this.render, this); @@ -26,7 +30,11 @@ app.pages.Profile = app.views.Base.extend({ }, sidebarView: function() { - return new app.views.ProfileSidebar({model: this.model}); + return new app.views.ProfileSidebar({ + model: this.model, + photos: this.photos, + contacts: this.contacts + }); }, headerView: function() { diff --git a/app/assets/javascripts/app/views/profile_sidebar_view.js b/app/assets/javascripts/app/views/profile_sidebar_view.js index 9190bd544..f45f18f33 100644 --- a/app/assets/javascripts/app/views/profile_sidebar_view.js +++ b/app/assets/javascripts/app/views/profile_sidebar_view.js @@ -2,13 +2,23 @@ app.views.ProfileSidebar = app.views.Base.extend({ templateName: 'profile_sidebar', + initialize: function(opts) { + this.photos = _.has(opts, 'photos') ? opts.photos : null; + this.contacts = _.has(opts, 'contacts') ? opts.contacts : null; + }, + presenter: function() { return _.extend({}, this.defaultPresenter(), { do_profile_btns: this._shouldDoProfileBtns(), + do_profile_info: this._shouldDoProfileInfo(), + do_photos: this._shouldDoPhotos(), + do_contacts: this._shouldDoContacts(), is_sharing: this.model.isSharing(), is_receiving: this.model.isReceiving(), is_mutual: this.model.isMutual(), - is_not_blocked: !this.model.isBlocked() + is_not_blocked: !this.model.isBlocked(), + photos: this.photos, + contacts: this.contacts }); }, @@ -16,6 +26,18 @@ app.views.ProfileSidebar = app.views.Base.extend({ return (app.currentUser.authenticated() && !this.model.get('is_own_profile')); }, + _shouldDoProfileInfo: function() { + return (this.model.isSharing() || this.model.get('is_own_profile')); + }, + + _shouldDoPhotos: function() { + return (this.photos && this.photos.items.length > 0); + }, + + _shouldDoContacts: function() { + return (this.contacts && this.contacts.items.length > 0); + }, + postRenderTemplate: function() { // UGLY (re-)attach the facebox this.$('a[rel*=facebox]').facebox(); diff --git a/app/assets/javascripts/widgets/direction-detector.js b/app/assets/javascripts/widgets/direction-detector.js index 8c886e6f3..2db21a1f7 100644 --- a/app/assets/javascripts/widgets/direction-detector.js +++ b/app/assets/javascripts/widgets/direction-detector.js @@ -11,47 +11,13 @@ this.subscribe("widget/ready", function() { self.updateBinds(); - + self.globalSubscribe("stream/scrolled", function() { self.updateBinds(); }); }); - this.isRTL = function(str) { - if(typeof str !== "string" || str.length < 1) { - return false; - } - - var charCode = str.charCodeAt(0); - if(charCode >= 1536 && charCode <= 1791) // Sarabic, Persian, ... - return true; - - else if(charCode >= 65136 && charCode <= 65279) // Arabic present 1 - return true; - - else if(charCode >= 64336 && charCode <= 65023) // Arabic present 2 - return true; - - else if(charCode>=1424 && charCode<=1535) // Hebrew - return true; - - else if(charCode>=64256 && charCode<=64335) // Hebrew present - return true; - - else if(charCode>=1792 && charCode<=1871) // Syriac - return true; - - else if(charCode>=1920 && charCode<=1983) // Thaana - return true; - - else if(charCode>=1984 && charCode<=2047) // NKo - return true; - - else if(charCode>=11568 && charCode<=11647) // Tifinagh - return true; - - return false; - }; + this.isRTL = app.helpers.txtDirection; this.updateBinds = function() { $.each(self.binds, function(index, bind) { @@ -71,14 +37,9 @@ this.updateDirection = function() { var textArea = $(this), - cleaned = textArea.val().replace(self.cleaner, "").replace(/^[ ]+/, ""); + cleaned = textArea.val().replace(self.cleaner, "").replace(/^[ ]+/, ""); - if(self.isRTL(cleaned)) { - textArea.css("direction", "rtl"); - } - else { - textArea.css("direction", "ltr"); - } + app.helpers.txtDirection.setCssFor(cleaned, textArea); }; }; diff --git a/app/assets/templates/profile_sidebar_tpl.jst.hbs b/app/assets/templates/profile_sidebar_tpl.jst.hbs index 4d0bba7cc..e65cfd9ae 100644 --- a/app/assets/templates/profile_sidebar_tpl.jst.hbs +++ b/app/assets/templates/profile_sidebar_tpl.jst.hbs @@ -1,5 +1,5 @@ -
    +
    {{#linkToPerson this}} {{{personImage this "l"}}} {{/linkToPerson}} @@ -37,3 +37,66 @@ {{/if}}
    {{/if}} + +{{#if do_profile_info}} +
    +{{/if}} diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index e8d569ec3..bdef09e2c 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,7 +3,8 @@ # the COPYRIGHT file. class PeopleController < ApplicationController - before_action :authenticate_user!, :except => [:show, :last_post] + before_action :authenticate_user!, except: [:show, :last_post] + before_action :find_person, only: [:show, :stream] use_bootstrap_for :index @@ -74,12 +75,6 @@ class PeopleController < ApplicationController # renders the persons user profile page def show - @person = Person.find_from_guid_or_username(params) - - # view this profile on the home pod, if you don't want to sign in... - authenticate_user! if remote_profile_with_no_user_session? - raise Diaspora::AccountClosed if @person.closed_account? - mark_corresponding_notifications_read if user_signed_in? @aspect = :profile # let aspect dropdown create new aspects @@ -89,19 +84,26 @@ class PeopleController < ApplicationController respond_to do |format| format.all do @profile = @person.profile - @photos = photos_from(@person) if current_user @block = current_user.blocks.where(:person_id => @person.id).first @contact = current_user.contact_for(@person) if @contact && !params[:only_posts] - @contacts_of_contact_count = @contact.contacts.count(:all) - @contacts_of_contact = @contact.contacts.limit(8) + @contacts_of_contact_count = contact_contacts.count(:all) + @contacts_of_contact = contact_contacts.limit(8) else @contact ||= Contact.new end end gon.preloads[:person] = @person_json + gon.preloads[:photos] = { + count: photos_from(@person).count(:all), + items: PhotoPresenter.as_collection(photos_from(@person).limit(8), :base_hash) + } + gon.preloads[:contacts] = { + count: contact_contacts.count(:all), + items: PersonPresenter.as_collection(contact_contacts.limit(8), :full_hash_with_avatar, current_user) + } respond_with @person, :locals => {:post_type => :all} end @@ -110,11 +112,6 @@ class PeopleController < ApplicationController end def stream - @person = Person.find_from_guid_or_username(params) - - authenticate_user! if remote_profile_with_no_user_session? - raise Diaspora::AccountClosed if @person.closed_account? - respond_to do |format| format.all { redirect_to person_path(@person) } format.json do @@ -161,8 +158,8 @@ class PeopleController < ApplicationController if @person @contact = current_user.contact_for(@person) @aspect = :profile - @contacts_of_contact = @contact.contacts.paginate(:page => params[:page], :per_page => (params[:limit] || 15)) - @contacts_of_contact_count = @contact.contacts.count(:all) + @contacts_of_contact = contact_contacts.paginate(:page => params[:page], :per_page => (params[:limit] || 15)) + @contacts_of_contact_count = contact_contacts.count(:all) @hashes = hashes_for_people @contacts_of_contact, @aspects else flash[:error] = I18n.t 'people.show.does_not_exist' @@ -187,6 +184,14 @@ class PeopleController < ApplicationController private + def find_person + @person = Person.find_from_guid_or_username(params) + + # view this profile on the home pod, if you don't want to sign in... + authenticate_user! if remote_profile_with_no_user_session? + raise Diaspora::AccountClosed if @person.closed_account? + end + def hashes_for_people(people, aspects) ids = people.map{|p| p.id} contacts = {} @@ -214,13 +219,23 @@ class PeopleController < ApplicationController end def photos_from(person) - photos = if user_signed_in? + @photos ||= if user_signed_in? current_user.photos_from(person) else Photo.where(author_id: person.id, public: true) - end + end.order('created_at desc') + end - photos.order('created_at desc') + # given a `@person` find the contacts that person has in that aspect(?) + # or use your own contacts if it's yourself + # see: `Contact#contacts` + def contact_contacts + @contact_contacts ||= if @person == current_user.person + current_user.contact_people + else + contact = current_user.contact_for(@person) + contact.try(:contacts) || Contact.none + end end def mark_corresponding_notifications_read diff --git a/app/presenters/base_presenter.rb b/app/presenters/base_presenter.rb index 86845a8b4..122a505b6 100644 --- a/app/presenters/base_presenter.rb +++ b/app/presenters/base_presenter.rb @@ -18,7 +18,7 @@ class BasePresenter end def method_missing(method, *args) - @presentable.send(method, *args) if @presentable.respond_to?(method) + @presentable.public_send(method, *args) end class NilPresenter diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index 7c0f30466..2b15f4d4e 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -11,7 +11,7 @@ class PersonPresenter < BasePresenter base_hash.merge({ relationship: relationship, block: is_blocked? ? BlockPresenter.new(current_user_person_block).base_hash : false, - contact: { id: current_user_person_contact.id }, + contact: (!own_profile? && has_contact?) ? { id: current_user_person_contact.id } : false, is_own_profile: own_profile? }) end @@ -73,6 +73,10 @@ class PersonPresenter < BasePresenter @contact ||= current_user.contact_for(@presentable) end + def has_contact? + current_user_person_contact.present? + end + def is_blocked? current_user_person_block.present? end diff --git a/app/presenters/photo_presenter.rb b/app/presenters/photo_presenter.rb new file mode 100644 index 000000000..59993733b --- /dev/null +++ b/app/presenters/photo_presenter.rb @@ -0,0 +1,16 @@ +class PhotoPresenter < BasePresenter + def base_hash + { id: id, + guid: guid, + dimensions: { + h: height, + w: width + }, + sizes: { + s: url(:thumb_small), + m: url(:thumb_medium), + l: url(:scaled_full) + } + } + end +end diff --git a/app/presenters/profile_presenter.rb b/app/presenters/profile_presenter.rb index 8f916431a..24f8624f7 100644 --- a/app/presenters/profile_presenter.rb +++ b/app/presenters/profile_presenter.rb @@ -1,4 +1,6 @@ class ProfilePresenter < BasePresenter + include PeopleHelper + def base_hash { id: id, tags: tag_string, @@ -15,4 +17,8 @@ class ProfilePresenter < BasePresenter avatar: AvatarPresenter.new(@presentable).base_hash, }) end + + def formatted_birthday + birthday_format(birthday) if birthday + end end diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index 688568c1f..d9a783c35 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -123,6 +123,13 @@ en: helper: is_sharing: "<%= name %> is sharing with you" is_not_sharing: "<%= name %> is not sharing with you" + profile: + bio: 'Bio' + location: "Location" + gender: "Gender" + born: "Birthday" + photos: "Photos" + contacts: "Contacts" conversation: participants: "Participants" From 1f724dd12313aaf2fdcef313a91332ee57a4c2fd Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Mon, 8 Sep 2014 17:45:44 +0200 Subject: [PATCH 179/785] * add a (hash)tag helper for handlebars * re-add stream on profile page * more controller refactoring --- .../app/helpers/handlebars-helpers.js | 9 ++++++ app/assets/javascripts/app/models/stream.js | 7 ++-- app/assets/javascripts/app/pages/profile.js | 17 +++++++++- app/assets/javascripts/app/router.js | 1 - .../app/views/profile_header_view.js | 7 +++- .../templates/profile_header_tpl.jst.hbs | 32 +++++++++++++------ app/controllers/people_controller.rb | 6 +++- app/presenters/person_presenter.rb | 5 +-- app/presenters/profile_presenter.rb | 2 +- app/views/people/_profile_sidebar.html.haml | 2 +- app/views/people/show.html.haml | 4 +-- config/locales/javascript/javascript.en.yml | 6 +++- 12 files changed, 76 insertions(+), 22 deletions(-) diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index 3affa6cdc..bfc718ba3 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -77,6 +77,15 @@ Handlebars.registerHelper('localTime', function(timestamp) { return new Date(timestamp).toLocaleString(); }); +Handlebars.registerHelper('fmtTags', function(tags) { + var links = _.map(tags, function(tag) { + return '' + + ' #' + tag + + ''; + }).join(' '); + return new Handlebars.SafeString(links); +}); + Handlebars.registerHelper('fmtText', function(text) { return new Handlebars.SafeString(app.helpers.textFormatter(text, null)); }); diff --git a/app/assets/javascripts/app/models/stream.js b/app/assets/javascripts/app/models/stream.js index d38806f51..e38b1bf35 100644 --- a/app/assets/javascripts/app/models/stream.js +++ b/app/assets/javascripts/app/models/stream.js @@ -2,7 +2,10 @@ //= require ../collections/photos app.models.Stream = Backbone.Collection.extend({ initialize : function(models, options){ - var collectionClass = options && options.collection || app.collections.Posts; + if( options ) { + var collectionClass = options.collection || app.collections.Posts; + this.streamPath = options.basePath; + } this.items = new collectionClass([], this.collectionOptions()); }, @@ -42,7 +45,7 @@ app.models.Stream = Backbone.Collection.extend({ }, basePath : function(){ - return document.location.pathname; + return this.streamPath || document.location.pathname; }, timeFilteredPath : function(){ diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 65bb87eb0..6d07d5271 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -7,7 +7,8 @@ app.pages.Profile = app.views.Base.extend({ subviews: { '#profile': 'sidebarView', - '.profile_header': 'headerView' + '.profile_header': 'headerView', + '#main_stream': 'streamView' }, tooltipSelector: '.profile_button div, .sharing_message_container', @@ -41,6 +42,20 @@ app.pages.Profile = app.views.Base.extend({ return new app.views.ProfileHeader({model: this.model}); }, + streamView: function() { + if( this.model.isBlocked() ) { + $('#main_stream').empty().html( + '
    '+ + Diaspora.I18n.t('profile.ignoring', {name: this.model.get('name')}) + + '
    '); + return false; + } + + app.stream = new app.models.Stream(null, {basePath: Routes.person_stream_path(app.page.model.get('guid'))}); + app.stream.fetch(); + return new app.views.Stream({model: app.stream}); + }, + blockPerson: function(evt) { if( !confirm(Diaspora.I18n.t('ignore_user')) ) return; diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 706eecf1a..89e0fa8ac 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -144,7 +144,6 @@ app.Router = Backbone.Router.extend({ this.renderPage(function() { return new app.pages.Profile({ el: $('body > .container') }); }); - // TODO call `this.stream()` } }); diff --git a/app/assets/javascripts/app/views/profile_header_view.js b/app/assets/javascripts/app/views/profile_header_view.js index 2c3271224..e0ecdf522 100644 --- a/app/assets/javascripts/app/views/profile_header_view.js +++ b/app/assets/javascripts/app/views/profile_header_view.js @@ -4,10 +4,15 @@ app.views.ProfileHeader = app.views.Base.extend({ presenter: function() { return _.extend({}, this.defaultPresenter(), { - is_blocked: this.model.isBlocked() + is_blocked: this.model.isBlocked(), + has_tags: this._hasTags() }); }, + _hasTags: function() { + return (this.model.get('profile')['tags'].length > 0); + }, + postRenderTemplate: function() { var self = this; var dropdownEl = this.$('.aspect_membership_dropdown.placeholder'); diff --git a/app/assets/templates/profile_header_tpl.jst.hbs b/app/assets/templates/profile_header_tpl.jst.hbs index 64ddda0db..9b2832d27 100644 --- a/app/assets/templates/profile_header_tpl.jst.hbs +++ b/app/assets/templates/profile_header_tpl.jst.hbs @@ -1,6 +1,6 @@
    -
    - {{#if loggedIn}} + {{#if loggedIn}} +
    {{#if is_own_profile}} {{!-- can't block myself, so don't check it here --}} {{t 'people.edit_my_profile'}} @@ -9,17 +9,31 @@ {{else}}
    {{/if}}{{/if}} - {{/if}} -
    +
    + {{/if}}

    {{name}}

    {{diaspora_id}} -
    - {{#if loggedIn}} - TODO - {{/if}} -
    + {{#if loggedIn}} +
    + {{#if has_tags}} + {{fmtTags profile.tags}} + {{#if is_own_profile}} + + {{t 'profile.edit'}} + + {{/if}} + {{else}} + {{#if is_own_profile}} + {{t 'profile.you_have_no_tags'}} + + {{t 'profile.add_some'}} + + {{/if}} + {{/if}} +
    + {{/if}}

    diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index bdef09e2c..814675819 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -185,7 +185,8 @@ class PeopleController < ApplicationController private def find_person - @person = Person.find_from_guid_or_username(params) + person_id = params[:id] || params[:person_id] + @person = Person.find_from_guid_or_username({id: person_id}) # view this profile on the home pod, if you don't want to sign in... authenticate_user! if remote_profile_with_no_user_session? @@ -219,6 +220,7 @@ class PeopleController < ApplicationController end def photos_from(person) + return Photo.none unless user_signed_in? @photos ||= if user_signed_in? current_user.photos_from(person) else @@ -230,6 +232,8 @@ class PeopleController < ApplicationController # or use your own contacts if it's yourself # see: `Contact#contacts` def contact_contacts + return Contact.none unless user_signed_in? + @contact_contacts ||= if @person == current_user.person current_user.contact_people else diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index 2b15f4d4e..5c5dc23fd 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -45,6 +45,7 @@ class PersonPresenter < BasePresenter end def relationship + return false unless current_user contact = current_user_person_contact is_mutual = contact ? contact.mutual? : false @@ -66,11 +67,11 @@ class PersonPresenter < BasePresenter private def current_user_person_block - @block ||= current_user.blocks.where(person_id: id).limit(1).first + @block ||= (current_user ? current_user.blocks.where(person_id: id).limit(1).first : Block.none) end def current_user_person_contact - @contact ||= current_user.contact_for(@presentable) + @contact ||= (current_user ? current_user.contact_for(@presentable) : Contact.none) end def has_contact? diff --git a/app/presenters/profile_presenter.rb b/app/presenters/profile_presenter.rb index 24f8624f7..047955e71 100644 --- a/app/presenters/profile_presenter.rb +++ b/app/presenters/profile_presenter.rb @@ -3,7 +3,7 @@ class ProfilePresenter < BasePresenter def base_hash { id: id, - tags: tag_string, + tags: tags.pluck(:name), bio: bio, location: location, gender: gender, diff --git a/app/views/people/_profile_sidebar.html.haml b/app/views/people/_profile_sidebar.html.haml index f94dd9aec..46730119a 100644 --- a/app/views/people/_profile_sidebar.html.haml +++ b/app/views/people/_profile_sidebar.html.haml @@ -27,7 +27,7 @@ .profile_button = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? - -if contact.sharing? || person == current_user.person + -if user_signed_in? && (contact.sharing? || person == current_user.person) %ul#profile_information - unless person.bio.blank? diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 54a37c870..88971289a 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -16,12 +16,12 @@ .span-18.last .profile_header - = render 'people/sub_header', :person => @person, :contact => @contact + -# = render 'people/sub_header', :person => @person, :contact => @contact .stream_container #main_stream.stream - - if @block.present? + -# - if @block.present? .dull = t('.ignoring', :name => @person.first_name) diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index d9a783c35..e84e0b4a8 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -124,7 +124,11 @@ en: is_sharing: "<%= name %> is sharing with you" is_not_sharing: "<%= name %> is not sharing with you" profile: - bio: 'Bio' + edit: "edit" + add_some: "add some" + you_have_no_tags: "you have no tags!" + ignoring: "You are ignoring all posts from <%= name %>." + bio: "Bio" location: "Location" gender: "Gender" born: "Birthday" From e4ee28885a63ce5d300adc3642ee943633f025c5 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Mon, 8 Sep 2014 18:53:58 +0200 Subject: [PATCH 180/785] make photos page work with backbone --- app/assets/javascripts/app/pages/profile.js | 26 ++++++++++++++++++--- app/assets/javascripts/app/router.js | 13 +++++++---- 2 files changed, 32 insertions(+), 7 deletions(-) diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 6d07d5271..a19499848 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -14,13 +14,23 @@ app.pages.Profile = app.views.Base.extend({ tooltipSelector: '.profile_button div, .sharing_message_container', initialize: function(opts) { - if( app.hasPreload('person') ) + if( app.hasPreload('person') ) { this.model = new app.models.Person(app.parsePreload('person')); + } else if(opts && opts.person_id) { + this.model = new app.models.Person({guid: opts.person_id}); + this.model.fetch(); + } else { + throw new Error("unable to load person"); + } + if( app.hasPreload('photos') ) this.photos = app.parsePreload('photos'); // we don't interact with it, so no model if( app.hasPreload('contacts') ) this.contacts = app.parsePreload('contacts'); // we don't interact with it, so no model + this.streamCollection = _.has(opts, 'streamCollection') ? opts.streamCollection : null; + this.streamViewClass = _.has(opts, 'streamView') ? opts.streamView : null; + this.model.on('change', this.render, this); // bind to global events @@ -31,6 +41,7 @@ app.pages.Profile = app.views.Base.extend({ }, sidebarView: function() { + if( !this.model.has('profile') ) return false; return new app.views.ProfileSidebar({ model: this.model, photos: this.photos, @@ -39,10 +50,12 @@ app.pages.Profile = app.views.Base.extend({ }, headerView: function() { + if( !this.model.has('profile') ) return false; return new app.views.ProfileHeader({model: this.model}); }, streamView: function() { + if( !this.model.has('profile') ) return false; if( this.model.isBlocked() ) { $('#main_stream').empty().html( '
    '+ @@ -51,9 +64,16 @@ app.pages.Profile = app.views.Base.extend({ return false; } - app.stream = new app.models.Stream(null, {basePath: Routes.person_stream_path(app.page.model.get('guid'))}); + // a collection is set, this means we want to view photos + var route = this.streamCollection ? 'person_photos_path' : 'person_stream_path'; + var view = this.streamViewClass ? this.streamViewClass : app.views.Stream; + + app.stream = new app.models.Stream(null, { + basePath: Routes[route](app.page.model.get('guid')), + collection: this.streamCollection + }); app.stream.fetch(); - return new app.views.Stream({model: app.stream}); + return new view({model: app.stream}); }, blockPerson: function(evt) { diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 89e0fa8ac..55943e94e 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -77,10 +77,15 @@ app.Router = Backbone.Router.extend({ this._hideInactiveStreamLists(); }, - photos : function() { - app.photos = new app.models.Stream([], {collection: app.collections.Photos}); - app.page = new app.views.Photos({model : app.photos}); - $("#main_stream").html(app.page.render().el); + photos : function(guid) { + this.renderPage(function() { + return new app.pages.Profile({ + person_id: guid, + el: $('body > .container'), + streamCollection: app.collections.Photos, + streamView: app.views.Photos + }); + }); }, followed_tags : function(name) { From 89d468cdcc05bb662c468fe6cad8642652312755 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Wed, 10 Sep 2014 03:33:43 +0200 Subject: [PATCH 181/785] first round of specs and code cleanups/fixes --- app/assets/javascripts/app/models/stream.js | 5 +- app/assets/javascripts/app/pages/profile.js | 1 + .../app/views/profile_header_view.js | 9 +- app/controllers/people_controller.rb | 42 ++--- app/helpers/aspect_global_helper.rb | 16 ++ app/models/user/querying.rb | 7 +- app/presenters/person_presenter.rb | 2 +- app/views/aspects/_aspect_stream.haml | 13 +- app/views/aspects/create.js.erb | 4 +- app/views/people/_profile_sidebar.html.haml | 146 +++++++-------- app/views/people/show.html.haml | 3 +- app/views/people/show.mobile.haml | 6 +- spec/controllers/people_controller_spec.rb | 168 +++++++++++------- spec/presenters/person_presenter_spec.rb | 44 ++++- 14 files changed, 277 insertions(+), 189 deletions(-) diff --git a/app/assets/javascripts/app/models/stream.js b/app/assets/javascripts/app/models/stream.js index e38b1bf35..30b94c8ff 100644 --- a/app/assets/javascripts/app/models/stream.js +++ b/app/assets/javascripts/app/models/stream.js @@ -2,9 +2,10 @@ //= require ../collections/photos app.models.Stream = Backbone.Collection.extend({ initialize : function(models, options){ + var collectionClass = app.collections.Posts if( options ) { - var collectionClass = options.collection || app.collections.Posts; - this.streamPath = options.basePath; + options.collection && (collectionClass = options.collection); + options.basePath && (this.streamPath = options.basePath); } this.items = new collectionClass([], this.collectionOptions()); }, diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index a19499848..1c1a7e5f3 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -37,6 +37,7 @@ app.pages.Profile = app.views.Base.extend({ var id = this.model.get('id'); app.events.on('person:block:'+id, this.reload, this); app.events.on('person:unblock:'+id, this.reload, this); + app.events.on('aspect:create', this.reload, this); app.events.on('aspect_membership:update', this.reload, this); }, diff --git a/app/assets/javascripts/app/views/profile_header_view.js b/app/assets/javascripts/app/views/profile_header_view.js index e0ecdf522..26cdebef8 100644 --- a/app/assets/javascripts/app/views/profile_header_view.js +++ b/app/assets/javascripts/app/views/profile_header_view.js @@ -2,6 +2,10 @@ app.views.ProfileHeader = app.views.Base.extend({ templateName: 'profile_header', + initialize: function() { + app.events.on('aspect:create', this.postRenderTemplate, this); + }, + presenter: function() { return _.extend({}, this.defaultPresenter(), { is_blocked: this.model.isBlocked(), @@ -25,6 +29,9 @@ app.views.ProfileHeader = app.views.Base.extend({ $.get(href, function(resp) { dropdownEl.html(resp); new app.views.AspectMembership({el: dropdownEl}); - }) + + // UGLY (re-)attach the facebox + self.$('a[rel*=facebox]').facebox(); + }); } }); diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index 814675819..bfbb17379 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -3,8 +3,8 @@ # the COPYRIGHT file. class PeopleController < ApplicationController - before_action :authenticate_user!, except: [:show, :last_post] - before_action :find_person, only: [:show, :stream] + before_action :authenticate_user!, except: [:show, :stream, :last_post] + before_action :find_person, only: [:show, :stream, :hovercard] use_bootstrap_for :index @@ -78,23 +78,10 @@ class PeopleController < ApplicationController mark_corresponding_notifications_read if user_signed_in? @aspect = :profile # let aspect dropdown create new aspects - @post_type = :all # for mobile @person_json = PersonPresenter.new(@person, current_user).full_hash_with_profile respond_to do |format| format.all do - @profile = @person.profile - if current_user - @block = current_user.blocks.where(:person_id => @person.id).first - @contact = current_user.contact_for(@person) - if @contact && !params[:only_posts] - @contacts_of_contact_count = contact_contacts.count(:all) - @contacts_of_contact = contact_contacts.limit(8) - else - @contact ||= Contact.new - end - end - gon.preloads[:person] = @person_json gon.preloads[:photos] = { count: photos_from(@person).count(:all), @@ -104,29 +91,31 @@ class PeopleController < ApplicationController count: contact_contacts.count(:all), items: PersonPresenter.as_collection(contact_contacts.limit(8), :full_hash_with_avatar, current_user) } - respond_with @person, :locals => {:post_type => :all} + respond_with @person end - format.json { render :json => @person_json } + format.mobile do + @post_type = :all + person_stream + respond_with @person + end + + format.json { render json: @person_json } end end def stream respond_to do |format| format.all { redirect_to person_path(@person) } - format.json do - @stream = Stream::Person.new(current_user, @person, max_time: max_time) - render json: @stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) } - end + format.json { + render json: person_stream.stream_posts.map { |p| LastThreeCommentsDecorator.new(PostPresenter.new(p, current_user)) } + } end end # hovercards fetch some the persons public profile data via json and display # it next to the avatar image in a nice box def hovercard - @person = Person.find_from_guid_or_username({:id => params[:person_id]}) - raise Diaspora::AccountClosed if @person.closed_account? - respond_to do |format| format.all do redirect_to :action => "show", :id => params[:person_id] @@ -220,7 +209,6 @@ class PeopleController < ApplicationController end def photos_from(person) - return Photo.none unless user_signed_in? @photos ||= if user_signed_in? current_user.photos_from(person) else @@ -247,4 +235,8 @@ class PeopleController < ApplicationController n.set_read_state( true ) end end + + def person_stream + @stream ||= Stream::Person.new(current_user, @person, max_time: max_time) + end end diff --git a/app/helpers/aspect_global_helper.rb b/app/helpers/aspect_global_helper.rb index e9c8a2255..c35131e0b 100644 --- a/app/helpers/aspect_global_helper.rb +++ b/app/helpers/aspect_global_helper.rb @@ -51,4 +51,20 @@ LISTITEM end options end + + def publisher_aspects_for(stream=nil) + if stream + aspects = stream.aspects + aspect = stream.aspect + aspect_ids = stream.aspect_ids + elsif current_user + aspects = current_user.aspects + aspect = aspects.first + aspect_ids = current_user.aspect_ids + else + return {} + end + + { aspects: aspects, aspect: aspect, aspect_ids: aspect_ids } + end end diff --git a/app/models/user/querying.rb b/app/models/user/querying.rb index 257a07e56..663564b25 100644 --- a/app/models/user/querying.rb +++ b/app/models/user/querying.rb @@ -69,7 +69,7 @@ module User::Querying def construct_public_followings_sql(opts) Rails.logger.debug("[EVIL-QUERY] user.construct_public_followings_sql") - + # For PostgreSQL and MySQL/MariaDB we use a different query # see issue: https://github.com/diaspora/diaspora/issues/5014 if AppConfig.postgres? @@ -104,6 +104,11 @@ module User::Querying contact_for_person_id(person.id) end + def block_for(person) + return nil unless person + self.blocks.where(person_id: person.id).limit(1).first + end + def aspects_with_shareable(base_class_name_or_class, shareable_id) base_class_name = base_class_name_or_class base_class_name = base_class_name_or_class.base_class.to_s if base_class_name_or_class.is_a?(Class) diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index 5c5dc23fd..77dfd3928 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -67,7 +67,7 @@ class PersonPresenter < BasePresenter private def current_user_person_block - @block ||= (current_user ? current_user.blocks.where(person_id: id).limit(1).first : Block.none) + @block ||= (current_user ? current_user.block_for(@presentable) : Block.none) end def current_user_person_contact diff --git a/app/views/aspects/_aspect_stream.haml b/app/views/aspects/_aspect_stream.haml index 2f6d7c72e..87e6af915 100644 --- a/app/views/aspects/_aspect_stream.haml +++ b/app/views/aspects/_aspect_stream.haml @@ -6,18 +6,7 @@ %h3#aspect_stream_header.stream_title = stream.title -- aspects = current_user.aspects -- aspect = aspects.first -- aspect_ids = aspects.map { |a| a.id } -- if stream - - aspects = stream.aspects - - aspect = stream.aspect - - aspect_ids = stream.aspect_ids - -= render 'publisher/publisher', - selected_aspects: aspects, - aspect_ids: aspect_ids, - aspect: aspect += render 'publisher/publisher', publisher_aspects_for(stream) = render 'aspects/no_posts_message' #gs-shim{:title => popover_with_close_html("3. #{t('.stay_updated')}"), 'data-content' => t('.stay_updated_explanation')} diff --git a/app/views/aspects/create.js.erb b/app/views/aspects/create.js.erb index 71976d074..0004d8e52 100644 --- a/app/views/aspects/create.js.erb +++ b/app/views/aspects/create.js.erb @@ -12,6 +12,8 @@ if( app.aspectMemberships ) { app.aspectMemberships.dropdown = dropdown; app.aspectMemberships.updateSummary(); - $.facebox.close(); $('#profile .dropdown').toggleClass("active"); } + +$.facebox.close(); +app.events.trigger('aspect:create', "<%= escape_javascript(@aspect.id) =>"); diff --git a/app/views/people/_profile_sidebar.html.haml b/app/views/people/_profile_sidebar.html.haml index 46730119a..aedc740d3 100644 --- a/app/views/people/_profile_sidebar.html.haml +++ b/app/views/people/_profile_sidebar.html.haml @@ -2,89 +2,89 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. -#profile - .badge - .profile_photo - = person_image_link(person, :size => :thumb_large, :to => :photos) - - if user_signed_in? - - if person != current_user.person - %div#profile_buttons{ :class => profile_buttons_class(@contact, @block) } - = sharing_message(@person, @contact) +.badge + .profile_photo + = person_image_link(person, :size => :thumb_large, :to => :photos) - - if @contact.receiving? - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-mention', :title => t('people.show.mention'), :id => 'mention_button'), new_status_message_path(:person_id => @person.id), :rel => 'facebox' - .white_bar + - if user_signed_in? + - if person != current_user.person + %div#profile_buttons{ :class => profile_buttons_class(@contact, @block) } + = sharing_message(@person, @contact) - - if @contact.mutual? + - if @contact.receiving? + .profile_button + = link_to content_tag(:div, nil, :class => 'icons-mention', :title => t('people.show.mention'), :id => 'mention_button'), new_status_message_path(:person_id => @person.id), :rel => 'facebox' + .white_bar + - if @contact.mutual? - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-message', :title => t('people.show.message'), :id => 'message_button'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :facebox => true), :rel => 'facebox' - .white_bar .profile_button - = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? + = link_to content_tag(:div, nil, :class => 'icons-message', :title => t('people.show.message'), :id => 'message_button'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :facebox => true), :rel => 'facebox' + .white_bar - -if user_signed_in? && (contact.sharing? || person == current_user.person) - %ul#profile_information + .profile_button + = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? - - unless person.bio.blank? - %li - %h4 - =t('.bio') - %div{ :class => direction_for(person.bio) } - = person.profile.bio_message.markdownified - - unless person.profile.location.blank? - %li - %h4 - =t('.location') - %div{ :class => direction_for(person.location) } - = person.profile.location_message.markdownified +-if user_signed_in? && (contact.sharing? || person == current_user.person) + %ul#profile_information - - unless person.gender.blank? - %li - %h4 - =t('.gender') - = person.gender + - unless person.bio.blank? + %li + %h4 + =t('.bio') + %div{ :class => direction_for(person.bio) } + = person.profile.bio_message.markdownified + - unless person.profile.location.blank? + %li + %h4 + =t('.location') + %div{ :class => direction_for(person.location) } + = person.profile.location_message.markdownified - - unless person.birthday.blank? - %li - %h4 - =t('.born') - = birthday_format(person.birthday) - - if @photos.present? - %li.image_list - %h4 - = t('.photos') - .item_count - = "#{@photos.count(:all)}" - - @photos.limit(8).each do |photo| - = image_tag(photo.url(:thumb_small)) - %br - = link_to t('layouts.header.view_all'), person_photos_path(person) + - unless person.gender.blank? + %li + %h4 + =t('.gender') + = person.gender - - if person == current_user.person - %li.image_list - %h4 - = t('_contacts') - .item_count - = all_contacts_count - .section.contact_pictures - - current_user.contacts.limit(8).each do |contact| - = person_image_link contact.person, :size => :thumb_small - %p.see_all= link_to t('layouts.header.view_all'), contacts_path - - elsif @contact.persisted? && @contacts_of_contact_count > 0 - %li.image_list - %h4 - = t('_contacts') - .item_count - = @contacts_of_contact_count - .section.contact_pictures - -@contacts_of_contact.limit(8).each do |person| - = person_image_link person, :size => :thumb_small - %p.see_all= link_to t('layouts.header.view_all'), person_contacts_path(@person) + - unless person.birthday.blank? + %li + %h4 + =t('.born') + = birthday_format(person.birthday) + - if @photos.present? + %li.image_list + %h4 + = t('.photos') + .item_count + = "#{@photos.count(:all)}" + - @photos.limit(8).each do |photo| + = image_tag(photo.url(:thumb_small)) + %br + = link_to t('layouts.header.view_all'), person_photos_path(person) - %br - %br + - if person == current_user.person + %li.image_list + %h4 + = t('_contacts') + .item_count + = all_contacts_count + .section.contact_pictures + - current_user.contacts.limit(8).each do |contact| + = person_image_link contact.person, :size => :thumb_small + %p.see_all= link_to t('layouts.header.view_all'), contacts_path + - elsif @contact.persisted? && @contacts_of_contact_count > 0 + %li.image_list + %h4 + = t('_contacts') + .item_count + = @contacts_of_contact_count + .section.contact_pictures + -@contacts_of_contact.limit(8).each do |person| + = person_image_link person, :size => :thumb_small + %p.see_all= link_to t('layouts.header.view_all'), person_contacts_path(@person) + + %br + %br diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 88971289a..e65ad4f8c 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -12,7 +12,8 @@ = @person.name .span-6 - = render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact } + #profile + -# = render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact } .span-18.last .profile_header diff --git a/app/views/people/show.mobile.haml b/app/views/people/show.mobile.haml index dfb55e289..3794a2c94 100644 --- a/app/views/people/show.mobile.haml +++ b/app/views/people/show.mobile.haml @@ -13,7 +13,7 @@ .clear .bottom_bar - if !@person.tag_string.blank? && user_signed_in? - = Diaspora::Taggable.format_tags(@person.profile.tag_string) + = Diaspora::Taggable.format_tags(@person.tag_string) .span12.profile_stream - if @stream.stream_posts.length > 0 @@ -29,6 +29,8 @@ - else #main_stream .dull - - if user_signed_in? && (current_user.person != @person) + - if @block.present? + = t('.ignoring', :name => @person.first_name) + - elsif user_signed_in? && (current_user.person != @person) = t('.has_not_shared_with_you_yet', :name => @person.first_name) diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index a89755a48..3e854f084 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -193,10 +193,12 @@ describe PeopleController, :type => :controller do it "doesn't leak photos in the sidebar" do private_photo = @user.post(:photo, user_file: uploaded_photo, to: @aspect.id, public: false) public_photo = @user.post(:photo, user_file: uploaded_photo, to: @aspect.id, public: true) + allow(@user.person).to receive(:remote?) { false } sign_out :user get :show, id: @user.person.to_param + expect(response).to be_success expect(assigns(:photos)).not_to include private_photo expect(assigns(:photos)).to include public_photo end @@ -216,23 +218,6 @@ describe PeopleController, :type => :controller do get :show, :id => @user.person.to_param expect(assigns(:person)).to eq(@user.person) end - - it "assigns all the user's posts" do - expect(@user.posts).to be_empty - @user.post(:status_message, :text => "to one aspect", :to => @aspect.id) - @user.post(:status_message, :text => "to all aspects", :to => 'all') - @user.post(:status_message, :text => "public", :to => 'all', :public => true) - expect(@user.reload.posts.length).to eq(3) - get :show, :id => @user.person.to_param - expect(assigns(:stream).posts.map(&:id)).to match_array(@user.posts.map(&:id)) - end - - it "renders the comments on the user's posts" do - message = @user.post :status_message, :text => 'test more', :to => @aspect.id - @user.comment!(message, 'I mean it') - get :show, :id => @user.person.to_param - expect(response).to be_success - end end context "with no user signed in" do @@ -251,34 +236,6 @@ describe PeopleController, :type => :controller do expect(response).to be_success end - context 'with posts' do - before do - @public_posts = [] - @public_posts << bob.post(:status_message, :text => "first public ", :to => bob.aspects[0].id, :public => true) - bob.post(:status_message, :text => "to an aspect @user is not in", :to => bob.aspects[1].id) - bob.post(:status_message, :text => "to all aspects", :to => 'all') - @public_posts << bob.post(:status_message, :text => "public", :to => 'all', :public => true) - @public_posts.first.created_at -= 1000 - @public_posts.first.save - end - - it "posts include reshares" do - reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) - get :show, :id => @user.person.to_param - expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) - end - - it "assigns only public posts" do - get :show, :id => @person.to_param - expect(assigns[:stream].posts.map(&:id)).to match_array(@public_posts.map(&:id)) - end - - it 'is sorted by created_at desc' do - get :show, :id => @person.to_param - expect(assigns[:stream].stream_posts).to eq(@public_posts.sort_by { |p| p.created_at }.reverse) - end - end - it 'forces to sign in if the person is remote' do p = FactoryGirl.create(:person) @@ -303,27 +260,6 @@ describe PeopleController, :type => :controller do expect(response).to be_success end - it "assigns only the posts the current user can see" do - expect(bob.posts).to be_empty - posts_user_can_see = [] - aspect_user_is_in = bob.aspects.where(:name => "generic").first - aspect_user_is_not_in = bob.aspects.where(:name => "empty").first - posts_user_can_see << bob.post(:status_message, :text => "to an aspect @user is in", :to => aspect_user_is_in.id) - bob.post(:status_message, :text => "to an aspect @user is not in", :to => aspect_user_is_not_in.id) - posts_user_can_see << bob.post(:status_message, :text => "to all aspects", :to => 'all') - posts_user_can_see << bob.post(:status_message, :text => "public", :to => 'all', :public => true) - expect(bob.reload.posts.length).to eq(4) - - get :show, :id => @person.to_param - expect(assigns(:stream).posts.map(&:id)).to match_array(posts_user_can_see.map(&:id)) - end - - it "posts include reshares" do - reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) - get :show, :id => @user.person.to_param - expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) - end - it 'marks a corresponding notifications as read' do note = FactoryGirl.create(:notification, :recipient => @user, :target => @person, :unread => true) @@ -348,6 +284,67 @@ describe PeopleController, :type => :controller do get :show, :id => @person.to_param, :format => :mobile expect(response).to be_success end + end + end + + describe '#stream' do + it "redirects non-json requests" do + get :stream, person_id: @user.person.to_param + expect(response).to be_redirect + end + + context "person is current user" do + it "assigns all the user's posts" do + expect(@user.posts).to be_empty + @user.post(:status_message, :text => "to one aspect", :to => @aspect.id) + @user.post(:status_message, :text => "to all aspects", :to => 'all') + @user.post(:status_message, :text => "public", :to => 'all', :public => true) + expect(@user.reload.posts.length).to eq(3) + get :stream, person_id: @user.person.to_param, format: :json + expect(assigns(:stream).posts.map(&:id)).to match_array(@user.posts.map(&:id)) + end + + it "renders the comments on the user's posts" do + cmmt = 'I mean it' + message = @user.post :status_message, :text => 'test more', :to => @aspect.id + @user.comment!(message, cmmt) + get :stream, person_id: @user.person.to_param, format: :json + expect(response).to be_success + expect(response.body).to include(cmmt) + end + end + + context "person is contact of current user" do + before do + @person = bob.person + end + + it "includes reshares" do + reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) + get :stream, person_id: @user.person.to_param, format: :json + expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) + end + + it "assigns only the posts the current user can see" do + expect(bob.posts).to be_empty + posts_user_can_see = [] + aspect_user_is_in = bob.aspects.where(:name => "generic").first + aspect_user_is_not_in = bob.aspects.where(:name => "empty").first + posts_user_can_see << bob.post(:status_message, :text => "to an aspect @user is in", :to => aspect_user_is_in.id) + bob.post(:status_message, :text => "to an aspect @user is not in", :to => aspect_user_is_not_in.id) + posts_user_can_see << bob.post(:status_message, :text => "to all aspects", :to => 'all') + posts_user_can_see << bob.post(:status_message, :text => "public", :to => 'all', :public => true) + expect(bob.reload.posts.length).to eq(4) + + get :stream, person_id: @person.to_param, format: :json + expect(assigns(:stream).posts.map(&:id)).to match_array(posts_user_can_see.map(&:id)) + end + end + + context "person is not contact of current user" do + before do + @person = eve.person + end it "assigns only public posts" do expect(eve.posts).to be_empty @@ -356,16 +353,51 @@ describe PeopleController, :type => :controller do public_post = eve.post(:status_message, :text => "public", :to => 'all', :public => true) expect(eve.reload.posts.length).to eq(3) - get :show, :id => @person.to_param + get :stream, person_id: @person.to_param, format: :json expect(assigns[:stream].posts.map(&:id)).to match_array([public_post].map(&:id)) end it "posts include reshares" do reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) - get :show, :id => @user.person.to_param + get :stream, person_id: @user.person.to_param, format: :json expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) end end + + context "logged out" do + before do + sign_out :user + @person = bob.person + end + + context 'with posts' do + before do + @public_posts = [] + @public_posts << bob.post(:status_message, :text => "first public ", :to => bob.aspects[0].id, :public => true) + bob.post(:status_message, :text => "to an aspect @user is not in", :to => bob.aspects[1].id) + bob.post(:status_message, :text => "to all aspects", :to => 'all') + @public_posts << bob.post(:status_message, :text => "public", :to => 'all', :public => true) + @public_posts.first.created_at -= 1000 + @public_posts.first.save + end + + it "posts include reshares" do + reshare = @user.post(:reshare, :public => true, :root_guid => FactoryGirl.create(:status_message, :public => true).guid, :to => alice.aspect_ids) + get :stream, person_id: @user.person.to_param, format: :json + expect(assigns[:stream].posts.map { |x| x.id }).to include(reshare.id) + end + + it "assigns only public posts" do + get :stream, person_id: @person.to_param, format: :json + expect(assigns[:stream].posts.map(&:id)).to match_array(@public_posts.map(&:id)) + end + + it 'is sorted by created_at desc' do + get :stream, person_id: @person.to_param, format: :json + expect(assigns[:stream].stream_posts).to eq(@public_posts.sort_by { |p| p.created_at }.reverse) + end + end + end end describe '#hovercard' do diff --git a/spec/presenters/person_presenter_spec.rb b/spec/presenters/person_presenter_spec.rb index 433b08bbf..6010da5d5 100644 --- a/spec/presenters/person_presenter_spec.rb +++ b/spec/presenters/person_presenter_spec.rb @@ -7,7 +7,7 @@ describe PersonPresenter do describe "#as_json" do context "with no current_user" do it "returns the user's public information if a user is not logged in" do - expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone)) + expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone).reject { |k,v| k == :avatar }) end end @@ -29,4 +29,44 @@ describe PersonPresenter do end end end -end \ No newline at end of file + + describe "#full_hash" do + let(:current_user) { FactoryGirl.create(:user) } + let(:m_contact) { double(:id => 1, :mutual? => true, :sharing? => true, :receiving? => true ) } + let(:r_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => true) } + let(:s_contact) { double(:id => 1, :mutual? => false, :sharing? => true, :receiving? => false) } + let(:n_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => false) } + + before do + @p = PersonPresenter.new(person, current_user) + end + + context "relationship" do + it "is blocked?" do + allow(current_user).to receive(:block_for) { double(id: 1) } + allow(current_user).to receive(:contact_for) { n_contact } + expect(@p.full_hash[:relationship]).to be(:blocked) + end + + it "is mutual?" do + allow(current_user).to receive(:contact_for) { m_contact } + expect(@p.full_hash[:relationship]).to be(:mutual) + end + + it "is receiving?" do + allow(current_user).to receive(:contact_for) { r_contact } + expect(@p.full_hash[:relationship]).to be(:receiving) + end + + it "is sharing?" do + allow(current_user).to receive(:contact_for) { s_contact } + expect(@p.full_hash[:relationship]).to be(:sharing) + end + + it "isn't sharing?" do + allow(current_user).to receive(:contact_for) { n_contact } + expect(@p.full_hash[:relationship]).to be(:not_sharing) + end + end + end +end From be86014540cf9e0e00e83c6a964ac343f112f7f4 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Thu, 11 Sep 2014 19:44:07 +0200 Subject: [PATCH 182/785] rspec should now be running a green build --- app/assets/javascripts/app/models/person.js | 4 +--- .../templates/profile_sidebar_tpl.jst.hbs | 6 +++--- app/helpers/aspect_global_helper.rb | 2 +- app/models/user/querying.rb | 2 +- app/presenters/avatar_presenter.rb | 6 +++--- app/presenters/person_presenter.rb | 16 ++++++--------- app/presenters/photo_presenter.rb | 10 +++++----- app/views/people/show.html.haml | 8 +++----- spec/models/user/querying_spec.rb | 14 +++++++++++++ spec/presenters/person_presenter_spec.rb | 20 +++++++++---------- 10 files changed, 47 insertions(+), 41 deletions(-) diff --git a/app/assets/javascripts/app/models/person.js b/app/assets/javascripts/app/models/person.js index 634f6b6f0..de68510d7 100644 --- a/app/assets/javascripts/app/models/person.js +++ b/app/assets/javascripts/app/models/person.js @@ -1,8 +1,6 @@ app.models.Person = Backbone.Model.extend({ - urlRoot: '/people', - url: function() { - return this.urlRoot + '/' + this.get('guid'); + return Routes.person_path(this.get('guid')); }, initialize: function() { diff --git a/app/assets/templates/profile_sidebar_tpl.jst.hbs b/app/assets/templates/profile_sidebar_tpl.jst.hbs index e65cfd9ae..5f70552e7 100644 --- a/app/assets/templates/profile_sidebar_tpl.jst.hbs +++ b/app/assets/templates/profile_sidebar_tpl.jst.hbs @@ -1,7 +1,7 @@
    {{#linkToPerson this}} - {{{personImage this "l"}}} + {{{personImage this "large"}}} {{/linkToPerson}}
    @@ -74,7 +74,7 @@

    {{#each photos.items}} - {{guid}} + {{guid}} {{/each}}

    @@ -90,7 +90,7 @@

    {{#each contacts.items}} - {{#linkToPerson this}}{{{personImage this "s"}}}{{/linkToPerson}} + {{#linkToPerson this}}{{{personImage this "small"}}}{{/linkToPerson}} {{/each}}

    diff --git a/app/helpers/aspect_global_helper.rb b/app/helpers/aspect_global_helper.rb index c35131e0b..fa47ccc05 100644 --- a/app/helpers/aspect_global_helper.rb +++ b/app/helpers/aspect_global_helper.rb @@ -65,6 +65,6 @@ LISTITEM return {} end - { aspects: aspects, aspect: aspect, aspect_ids: aspect_ids } + { selected_aspects: aspects, aspect: aspect, aspect_ids: aspect_ids } end end diff --git a/app/models/user/querying.rb b/app/models/user/querying.rb index 663564b25..e10fbe036 100644 --- a/app/models/user/querying.rb +++ b/app/models/user/querying.rb @@ -106,7 +106,7 @@ module User::Querying def block_for(person) return nil unless person - self.blocks.where(person_id: person.id).limit(1).first + self.blocks.where(person_id: person.id).first end def aspects_with_shareable(base_class_name_or_class, shareable_id) diff --git a/app/presenters/avatar_presenter.rb b/app/presenters/avatar_presenter.rb index 10cabb949..5cb0060d8 100644 --- a/app/presenters/avatar_presenter.rb +++ b/app/presenters/avatar_presenter.rb @@ -4,9 +4,9 @@ class AvatarPresenter < BasePresenter DEFAULT_IMAGE = ActionController::Base.helpers.image_path('user/default.png') def base_hash - { s: image_url_small || DEFAULT_IMAGE, - m: image_url_medium || DEFAULT_IMAGE, - l: image_url || DEFAULT_IMAGE + { small: image_url_small || DEFAULT_IMAGE, + medium: image_url_medium || DEFAULT_IMAGE, + large: image_url || DEFAULT_IMAGE } end end diff --git a/app/presenters/person_presenter.rb b/app/presenters/person_presenter.rb index 77dfd3928..37f759353 100644 --- a/app/presenters/person_presenter.rb +++ b/app/presenters/person_presenter.rb @@ -46,18 +46,14 @@ class PersonPresenter < BasePresenter def relationship return false unless current_user + return :blocked if is_blocked? + contact = current_user_person_contact + return :not_sharing unless contact - is_mutual = contact ? contact.mutual? : false - is_sharing = contact ? contact.sharing? : false - is_receiving = contact ? contact.receiving? : false - - if is_blocked? then :blocked - elsif is_mutual then :mutual - elsif is_sharing then :sharing - elsif is_receiving then :receiving - else :not_sharing - end + [:mutual, :sharing, :receiving].find do |status| + contact.public_send("#{status}?") + end || :not_sharing end def person_is_following_current_user diff --git a/app/presenters/photo_presenter.rb b/app/presenters/photo_presenter.rb index 59993733b..defed1d9b 100644 --- a/app/presenters/photo_presenter.rb +++ b/app/presenters/photo_presenter.rb @@ -3,13 +3,13 @@ class PhotoPresenter < BasePresenter { id: id, guid: guid, dimensions: { - h: height, - w: width + height: height, + width: width }, sizes: { - s: url(:thumb_small), - m: url(:thumb_medium), - l: url(:scaled_full) + small: url(:thumb_small), + medium: url(:thumb_medium), + large: url(:scaled_full) } } end diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index e65ad4f8c..fed0296f7 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -13,18 +13,16 @@ .span-6 #profile - -# = render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact } + -# here be JS .span-18.last .profile_header - -# = render 'people/sub_header', :person => @person, :contact => @contact + -# more JS .stream_container #main_stream.stream - -# - if @block.present? - .dull - = t('.ignoring', :name => @person.first_name) + -# JS #paginate diff --git a/spec/models/user/querying_spec.rb b/spec/models/user/querying_spec.rb index 8a3eecee0..9d8a0ff14 100644 --- a/spec/models/user/querying_spec.rb +++ b/spec/models/user/querying_spec.rb @@ -307,6 +307,20 @@ describe User::Querying, :type => :model do end end + describe "#block_for" do + let(:person) { FactoryGirl.create :person } + + before do + eve.blocks.create({person: person}) + end + + it 'returns the block' do + block = eve.block_for(person) + expect(block).to be_present + expect(block.person.id).to be person.id + end + end + describe '#posts_from' do before do @user3 = FactoryGirl.create(:user) diff --git a/spec/presenters/person_presenter_spec.rb b/spec/presenters/person_presenter_spec.rb index 6010da5d5..97f01887c 100644 --- a/spec/presenters/person_presenter_spec.rb +++ b/spec/presenters/person_presenter_spec.rb @@ -7,7 +7,7 @@ describe PersonPresenter do describe "#as_json" do context "with no current_user" do it "returns the user's public information if a user is not logged in" do - expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone).reject { |k,v| k == :avatar }) + expect(PersonPresenter.new(person, nil).as_json).to include(person.as_api_response(:backbone).except(:avatar)) end end @@ -32,10 +32,10 @@ describe PersonPresenter do describe "#full_hash" do let(:current_user) { FactoryGirl.create(:user) } - let(:m_contact) { double(:id => 1, :mutual? => true, :sharing? => true, :receiving? => true ) } - let(:r_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => true) } - let(:s_contact) { double(:id => 1, :mutual? => false, :sharing? => true, :receiving? => false) } - let(:n_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => false) } + let(:mutual_contact) { double(:id => 1, :mutual? => true, :sharing? => true, :receiving? => true ) } + let(:receiving_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => true) } + let(:sharing_contact) { double(:id => 1, :mutual? => false, :sharing? => true, :receiving? => false) } + let(:non_contact) { double(:id => 1, :mutual? => false, :sharing? => false, :receiving? => false) } before do @p = PersonPresenter.new(person, current_user) @@ -44,27 +44,27 @@ describe PersonPresenter do context "relationship" do it "is blocked?" do allow(current_user).to receive(:block_for) { double(id: 1) } - allow(current_user).to receive(:contact_for) { n_contact } + allow(current_user).to receive(:contact_for) { non_contact } expect(@p.full_hash[:relationship]).to be(:blocked) end it "is mutual?" do - allow(current_user).to receive(:contact_for) { m_contact } + allow(current_user).to receive(:contact_for) { mutual_contact } expect(@p.full_hash[:relationship]).to be(:mutual) end it "is receiving?" do - allow(current_user).to receive(:contact_for) { r_contact } + allow(current_user).to receive(:contact_for) { receiving_contact } expect(@p.full_hash[:relationship]).to be(:receiving) end it "is sharing?" do - allow(current_user).to receive(:contact_for) { s_contact } + allow(current_user).to receive(:contact_for) { sharing_contact } expect(@p.full_hash[:relationship]).to be(:sharing) end it "isn't sharing?" do - allow(current_user).to receive(:contact_for) { n_contact } + allow(current_user).to receive(:contact_for) { non_contact } expect(@p.full_hash[:relationship]).to be(:not_sharing) end end From 10609c3692475087aec689075b7374e0f6863b00 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Fri, 12 Sep 2014 03:18:34 +0200 Subject: [PATCH 183/785] fix jasmine and add some specs for direction detection --- .../app/helpers/direction_detector.js | 41 ++++++++++++++++++- .../app/helpers/handlebars-helpers.js | 3 +- app/assets/javascripts/jasmine-load-all.js | 1 - .../app/helpers/direction_detector_spec.js | 37 +++++++++++++++++ .../app/views/aspects_dropdown_view_spec.js | 11 +++-- spec/javascripts/app/views/poll_view_spec.js | 2 +- 6 files changed, 88 insertions(+), 7 deletions(-) create mode 100644 spec/javascripts/app/helpers/direction_detector_spec.js diff --git a/app/assets/javascripts/app/helpers/direction_detector.js b/app/assets/javascripts/app/helpers/direction_detector.js index ee1495718..768aeb8b3 100644 --- a/app/assets/javascripts/app/helpers/direction_detector.js +++ b/app/assets/javascripts/app/helpers/direction_detector.js @@ -18,7 +18,7 @@ return false; } - var charCode = str.charCodeAt(0); + var charCode = this._fixedCharCodeAt(str, 0); if(charCode >= 1536 && charCode <= 1791) // Sarabic, Persian, ... return true; @@ -34,6 +34,12 @@ else if(charCode>=64256 && charCode<=64335) // Hebrew present return true; + else if(charCode>=68096 && charCode<=68184) // Kharoshthi + return true; + + else if(charCode>=67840 && charCode<=67871) // Phoenician + return true; + else if(charCode>=1792 && charCode<=1871) // Syriac return true; @@ -47,6 +53,39 @@ return true; return false; + }, + + // source: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/charCodeAt + _fixedCharCodeAt: function(str, idx) { + str += ''; + var code, + end = str.length; + + var surrogatePairs = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g; + while ((surrogatePairs.exec(str)) != null) { + var li = surrogatePairs.lastIndex; + if (li - 2 < idx) { + idx++; + } + else { + break; + } + } + + if (idx >= end || idx < 0) { + return NaN; + } + + code = str.charCodeAt(idx); + + var hi, low; + if (0xD800 <= code && code <= 0xDBFF) { + hi = code; + low = str.charCodeAt(idx+1); + // Go one further, since one of the "characters" is part of a surrogate pair + return ((hi - 0xD800) * 0x400) + (low - 0xDC00) + 0x10000; + } + return code; } }; })(); diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index bfc718ba3..1be1cd98d 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -59,8 +59,9 @@ Handlebars.registerHelper('hovercardable', function(person) { Handlebars.registerHelper('personImage', function(person, size, imageClass) { /* we return here if person.avatar is blank, because this happens when a * user is unauthenticated. we don't know why this happens... */ + if( !person.avatar && + !(person.profile && person.profile.avatar) ) return; var avatar = person.avatar || person.profile.avatar; - if( !avatar ) return; var name = ( person.name ) ? person.name : 'avatar'; size = ( !_.isString(size) ) ? "small" : size; diff --git a/app/assets/javascripts/jasmine-load-all.js b/app/assets/javascripts/jasmine-load-all.js index 8d777a10c..eda5e0faa 100644 --- a/app/assets/javascripts/jasmine-load-all.js +++ b/app/assets/javascripts/jasmine-load-all.js @@ -6,6 +6,5 @@ //= require inbox //= require mobile //= require profile -//= require people //= require contact-list //= require sinon diff --git a/spec/javascripts/app/helpers/direction_detector_spec.js b/spec/javascripts/app/helpers/direction_detector_spec.js new file mode 100644 index 000000000..6ade3d00b --- /dev/null +++ b/spec/javascripts/app/helpers/direction_detector_spec.js @@ -0,0 +1,37 @@ +describe("app.helpers.txtDirection", function() { + context("#isRTL", function() { + beforeEach(function() { + this.samples = { + "ثم بغزو ناجازاكي الأوروبي بال, ": "rtl", // arabic + "אם ברית מחליטה זכר, צ'ט לשון": "rtl", // hebrew + "ߊߍߌߐߎ": "rtl", // n'ko + "𐨙𐨜𐨪𐨭𐨢": "rtl", // Kharoshthi + "𐤂𐤃𐤄𐤅𐤆𐤇𐤈𐤉𐤊": "rtl", // Phoenecian + "ܫܠܡܐ": "rtl", //syriac + "ހަށް ގޮސް އުޅޭ އިރު": "rtl", // thaana + "ⴻⴼⴽⵄⵅⵆⵇ": "rtl", // Tifinagh + "ᚳᚴᚵᚶᚷᚸᚹᛅᛆᛇᛈᛉᛊᛋ": "ltr", // Runes + "ΘΛΞΠΣΦΨΩέαβγζλφχψϖϗ": "ltr", // Greek + "経担裁洋府時話家": "ltr", // Chinese + "Анёмал зэнтынтиаэ": "ltr", // Cyrillic + "उपेक्ष सोफ़्टवेर विचारशिलता": "ltr", // Hindi + "選そ前制数えほ長春セ名": "ltr", // Japanese + "ascii text": "ltr", + }; + }); + + it("detects the right text direction", function() { + _.each(this.samples, function(dir, str) { + var result = app.helpers.txtDirection.isRTL(str); + if( result ) { + expect(dir).toEqual('rtl'); + } else { + expect(dir).toEqual('ltr'); + } + }); + }); + }); +}); + + +101 diff --git a/spec/javascripts/app/views/aspects_dropdown_view_spec.js b/spec/javascripts/app/views/aspects_dropdown_view_spec.js index 326d6a583..605a92df3 100644 --- a/spec/javascripts/app/views/aspects_dropdown_view_spec.js +++ b/spec/javascripts/app/views/aspects_dropdown_view_spec.js @@ -1,10 +1,15 @@ describe("app.views.AspectsDropdown", function(){ beforeEach(function() { spec.loadFixture("bookmarklet"); - Diaspora.I18n.load({ + Diaspora.I18n.reset({ 'aspect_dropdown': { - 'select_aspects': "Select aspects" - }); + 'select_aspects': "Select aspects", + 'all_aspects': "All Aspects", + 'toggle': { + 'zero': "Select aspects", + 'one': "In <%= count %> aspect", + 'other': "In <%= count %> aspects" + }}}); this.view = new app.views.AspectsDropdown({el: $('.aspect_dropdown')}); }); diff --git a/spec/javascripts/app/views/poll_view_spec.js b/spec/javascripts/app/views/poll_view_spec.js index d2b30e889..ee5143165 100644 --- a/spec/javascripts/app/views/poll_view_spec.js +++ b/spec/javascripts/app/views/poll_view_spec.js @@ -29,7 +29,7 @@ describe("app.views.Poll", function(){ this.view.vote(answer.id); - var obj = jasmine.Ajax.requests.mostRecent().params); + var obj = JSON.parse(jasmine.Ajax.requests.mostRecent().params); expect(obj.poll_id).toBe(poll.poll_id); expect(obj.poll_answer_id).toBe(answer.id); }) From a5da2ca48cf24f6642ab1835d74947634e5344d3 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Sat, 13 Sep 2014 23:46:26 +0200 Subject: [PATCH 184/785] small fixes and more jasmine specs --- app/assets/javascripts/app/pages/profile.js | 20 ++++-- .../javascripts/widgets/direction-detector.js | 2 +- .../app/helpers/direction_detector_spec.js | 3 - spec/javascripts/app/models/person_spec.js | 69 +++++++++++++++++++ spec/javascripts/app/pages/profile_spec.js | 24 +++++++ .../app/views/profile_header_view_spec.js | 26 +++++++ .../app/views/profile_sidebar_view_spec.js | 42 +++++++++++ spec/javascripts/helpers/factory.js | 37 ++++++++-- spec/presenters/base_presenter_spec.rb | 25 +++++++ 9 files changed, 233 insertions(+), 15 deletions(-) create mode 100644 spec/javascripts/app/models/person_spec.js create mode 100644 spec/javascripts/app/pages/profile_spec.js create mode 100644 spec/javascripts/app/views/profile_header_view_spec.js create mode 100644 spec/javascripts/app/views/profile_sidebar_view_spec.js create mode 100644 spec/presenters/base_presenter_spec.rb diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 1c1a7e5f3..17a21ea3b 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -14,13 +14,8 @@ app.pages.Profile = app.views.Base.extend({ tooltipSelector: '.profile_button div, .sharing_message_container', initialize: function(opts) { - if( app.hasPreload('person') ) { - this.model = new app.models.Person(app.parsePreload('person')); - } else if(opts && opts.person_id) { - this.model = new app.models.Person({guid: opts.person_id}); - this.model.fetch(); - } else { - throw new Error("unable to load person"); + if( !this.model ) { + this._populateModel(opts); } if( app.hasPreload('photos') ) @@ -41,6 +36,17 @@ app.pages.Profile = app.views.Base.extend({ app.events.on('aspect_membership:update', this.reload, this); }, + _populateModel: function(opts) { + if( app.hasPreload('person') ) { + this.model = new app.models.Person(app.parsePreload('person')); + } else if(opts && opts.person_id) { + this.model = new app.models.Person({guid: opts.person_id}); + this.model.fetch(); + } else { + throw new Error("unable to load person"); + } + }, + sidebarView: function() { if( !this.model.has('profile') ) return false; return new app.views.ProfileSidebar({ diff --git a/app/assets/javascripts/widgets/direction-detector.js b/app/assets/javascripts/widgets/direction-detector.js index 2db21a1f7..101c1e50a 100644 --- a/app/assets/javascripts/widgets/direction-detector.js +++ b/app/assets/javascripts/widgets/direction-detector.js @@ -17,7 +17,7 @@ }); }); - this.isRTL = app.helpers.txtDirection; + this.isRTL = app.helpers.txtDirection.isRTL; this.updateBinds = function() { $.each(self.binds, function(index, bind) { diff --git a/spec/javascripts/app/helpers/direction_detector_spec.js b/spec/javascripts/app/helpers/direction_detector_spec.js index 6ade3d00b..2067530d8 100644 --- a/spec/javascripts/app/helpers/direction_detector_spec.js +++ b/spec/javascripts/app/helpers/direction_detector_spec.js @@ -32,6 +32,3 @@ describe("app.helpers.txtDirection", function() { }); }); }); - - -101 diff --git a/spec/javascripts/app/models/person_spec.js b/spec/javascripts/app/models/person_spec.js new file mode 100644 index 000000000..b36b8beb6 --- /dev/null +++ b/spec/javascripts/app/models/person_spec.js @@ -0,0 +1,69 @@ + +describe("app.models.Person", function() { + beforeEach(function() { + this.mutual_contact = factory.person({relationship: 'mutual'}); + this.sharing_contact = factory.person({relationship :'sharing'}); + this.receiving_contact = factory.person({relationship: 'receiving'}); + this.blocked_contact = factory.person({relationship: 'blocked', block: {id: 1}}); + }); + + context("#isSharing", function() { + it("indicates if the person is sharing", function() { + expect(this.mutual_contact.isSharing()).toBeTruthy(); + expect(this.sharing_contact.isSharing()).toBeTruthy(); + + expect(this.receiving_contact.isSharing()).toBeFalsy(); + expect(this.blocked_contact.isSharing()).toBeFalsy(); + }); + }); + + context("#isReceiving", function() { + it("indicates if the person is receiving", function() { + expect(this.mutual_contact.isReceiving()).toBeTruthy(); + expect(this.receiving_contact.isReceiving()).toBeTruthy(); + + expect(this.sharing_contact.isReceiving()).toBeFalsy(); + expect(this.blocked_contact.isReceiving()).toBeFalsy(); + }); + }); + + context("#isMutual", function() { + it("indicates if we share mutually with the person", function() { + expect(this.mutual_contact.isMutual()).toBeTruthy(); + + expect(this.receiving_contact.isMutual()).toBeFalsy(); + expect(this.sharing_contact.isMutual()).toBeFalsy(); + expect(this.blocked_contact.isMutual()).toBeFalsy(); + }); + }); + + context("#isBlocked", function() { + it("indicates whether we blocked the person", function() { + expect(this.blocked_contact.isBlocked()).toBeTruthy(); + + expect(this.mutual_contact.isBlocked()).toBeFalsy(); + expect(this.receiving_contact.isBlocked()).toBeFalsy(); + expect(this.sharing_contact.isBlocked()).toBeFalsy(); + }); + }); + + context("#block", function() { + it("POSTs a block to the server", function() { + this.sharing_contact.block(); + var request = jasmine.Ajax.requests.mostRecent(); + + expect(request.method).toEqual("POST"); + expect($.parseJSON(request.params).block.person_id).toEqual(this.sharing_contact.id); + }); + }); + + context("#unblock", function() { + it("DELETEs a block from the server", function(){ + this.blocked_contact.unblock(); + var request = jasmine.Ajax.requests.mostRecent(); + + expect(request.method).toEqual("DELETE"); + expect(request.url).toEqual(Routes.block_path(this.blocked_contact.get('block').id)); + }); + }); +}); diff --git a/spec/javascripts/app/pages/profile_spec.js b/spec/javascripts/app/pages/profile_spec.js new file mode 100644 index 000000000..bd5277371 --- /dev/null +++ b/spec/javascripts/app/pages/profile_spec.js @@ -0,0 +1,24 @@ + +describe("app.pages.Profile", function() { + beforeEach(function() { + this.model = factory.person(); + spyOn(this.model, 'block').and.returnValue($.Deferred()); + spyOn(this.model, 'unblock').and.returnValue($.Deferred()); + this.view = new app.pages.Profile({model: this.model}); + }); + + context("#blockPerson", function() { + it("calls person#block", function() { + spyOn(window, 'confirm').and.returnValue(true); + this.view.blockPerson(); + expect(this.model.block).toHaveBeenCalled(); + }); + }); + + context("#unblockPerson", function() { + it("calls person#unblock", function() { + this.view.unblockPerson(); + expect(this.model.unblock).toHaveBeenCalled(); + }); + }); +}); diff --git a/spec/javascripts/app/views/profile_header_view_spec.js b/spec/javascripts/app/views/profile_header_view_spec.js new file mode 100644 index 000000000..82a746c2d --- /dev/null +++ b/spec/javascripts/app/views/profile_header_view_spec.js @@ -0,0 +1,26 @@ + +describe("app.views.ProfileHeader", function() { + beforeEach(function() { + this.model = factory.personWithProfile({ + diaspora_id: "my@pod", + name: "User Name", + profile: { tags: ['test'] } + }); + this.view = new app.views.ProfileHeader({model: this.model}); + }); + + context("#presenter", function() { + it("contains necessary elements", function() { + expect(this.view.presenter()).toEqual(jasmine.objectContaining({ + diaspora_id: "my@pod", + name: "User Name", + is_blocked: false, + is_own_profile: false, + has_tags: true, + profile: jasmine.objectContaining({ + tags: ['test'] + }) + })); + }); + }); +}); diff --git a/spec/javascripts/app/views/profile_sidebar_view_spec.js b/spec/javascripts/app/views/profile_sidebar_view_spec.js new file mode 100644 index 000000000..d241dc7ce --- /dev/null +++ b/spec/javascripts/app/views/profile_sidebar_view_spec.js @@ -0,0 +1,42 @@ + +describe("app.views.ProfileSidebar", function() { + beforeEach(function() { + this.model = factory.personWithProfile({ + diaspora_id: "alice@umbrella.corp", + name: "Project Alice", + relationship: 'mutual', + profile: { + bio: "confidential", + location: "underground", + gender: "female", + birthday: "2012-09-14", + tags: ['zombies', 'evil', 'blood', 'gore'] + + } + }); + this.view = new app.views.ProfileSidebar({model: this.model}); + + loginAs(factory.userAttrs()); + }); + + context("#presenter", function() { + it("contains necessary elements", function() { + console.log(this.view.presenter()); + expect(this.view.presenter()).toEqual(jasmine.objectContaining({ + relationship: 'mutual', + do_profile_btns: true, + do_profile_info: true, + is_sharing: true, + is_receiving: true, + is_mutual: true, + is_not_blocked: true, + profile: jasmine.objectContaining({ + bio: "confidential", + location: "underground", + gender: "female", + birthday: "2012-09-14" + }) + })); + }); + }); +}); diff --git a/spec/javascripts/helpers/factory.js b/spec/javascripts/helpers/factory.js index b8e5d360b..b0e27ef87 100644 --- a/spec/javascripts/helpers/factory.js +++ b/spec/javascripts/helpers/factory.js @@ -79,8 +79,8 @@ factory = { } }, - profile : function(overrides) { - var id = overrides && overrides.id || factory.id.next() + profileAttrs: function(overrides) { + var id = (overrides && overrides.id) ? overrides.id : factory.id.next(); var defaults = { "bio": "I am a cat lover and I love to run", "birthday": "2012-04-17", @@ -99,9 +99,38 @@ factory = { "person_id": "person" + id, "searchable": true, "updated_at": "2012-04-17T23:48:36Z" - } + }; + return _.extend({}, defaults, overrides); + }, - return new app.models.Profile(_.extend(defaults, overrides)) + profile : function(overrides) { + return new app.models.Profile(factory.profileAttrs(overrides)); + }, + + personAttrs: function(overrides) { + var id = (overrides && overrides.id) ? overrides.id : factory.id.next(); + var defaults = { + "id": id, + "guid": factory.guid(), + "name": "Bob Grimm", + "diaspora_id": "bob@localhost:3000", + "relationship": "sharing", + "is_own_profile": false + }; + return _.extend({}, defaults, overrides); + }, + + person: function(overrides) { + return new app.models.Person(factory.personAttrs(overrides)); + }, + + personWithProfile: function(overrides) { + var profile_overrides = _.clone(overrides.profile); + delete overrides.profile; + var defaults = { + profile: factory.profileAttrs(profile_overrides) + }; + return factory.person(_.extend({}, defaults, overrides)); }, photoAttrs : function(overrides){ diff --git a/spec/presenters/base_presenter_spec.rb b/spec/presenters/base_presenter_spec.rb new file mode 100644 index 000000000..561d1993f --- /dev/null +++ b/spec/presenters/base_presenter_spec.rb @@ -0,0 +1,25 @@ +require "spec_helper" + +describe BasePresenter do + it "falls back to nil" do + p = BasePresenter.new(nil) + expect(p.anything).to be(nil) + expect { p.otherthing }.not_to raise_error + end + + it "calls methods on the wrapped object" do + obj = double(hello: "world") + p = BasePresenter.new(obj) + + expect(p.hello).to eql("world") + expect(obj).to have_received(:hello) + end + + describe "#as_collection" do + it "returns an array of data" do + coll = [double(data: "one"), double(data: "two"), double(data: "three")] + res = BasePresenter.as_collection(coll, :data) + expect(res).to eql(["one", "two", "three"]) + end + end +end From 300496090bcfce5c1209d38df58105c78819099b Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Tue, 16 Sep 2014 02:16:14 +0200 Subject: [PATCH 185/785] add the publisher back to ones own profile, fix some cukes --- app/assets/javascripts/app/pages/profile.js | 5 +++++ app/views/people/show.html.haml | 4 ++++ features/desktop/blocks_user.feature | 4 +--- features/desktop/post_preview.feature | 2 +- features/desktop/posts_from_main_page.feature | 14 +++++++------- features/desktop/posts_from_profile_page.feature | 10 ++++------ features/step_definitions/posts_steps.rb | 6 +++++- features/support/publishing_cuke_helpers.rb | 10 +++++++++- 8 files changed, 36 insertions(+), 19 deletions(-) diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 17a21ea3b..716baa906 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -80,6 +80,11 @@ app.pages.Profile = app.views.Base.extend({ collection: this.streamCollection }); app.stream.fetch(); + + if( this.model.get('is_own_profile') ) { + app.publisher = new app.views.Publisher({collection : app.stream.items}); + } + return new view({model: app.stream}); }, diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index fed0296f7..937cb4bd4 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -21,10 +21,14 @@ .stream_container + -if user_signed_in? && current_page?(person_path(current_user.person)) + = render 'publisher/publisher', publisher_aspects_for(nil) + #main_stream.stream -# JS #paginate + %span.loader.hidden %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} ⇧ diff --git a/features/desktop/blocks_user.feature b/features/desktop/blocks_user.feature index 6057252a7..84e2b66af 100644 --- a/features/desktop/blocks_user.feature +++ b/features/desktop/blocks_user.feature @@ -18,9 +18,7 @@ Feature: Blocking a user from the stream Then I should not see any posts in my stream Scenario: Blocking a user from the profile page - When I am on the home page - And I follow "Alice Smith" + When I am on "alice@alice.alice"'s page When I click on the profile block button And I confirm the alert - And I am on the home page Then I should not see any posts in my stream diff --git a/features/desktop/post_preview.feature b/features/desktop/post_preview.feature index e587a2e51..b6b4bf15c 100644 --- a/features/desktop/post_preview.feature +++ b/features/desktop/post_preview.feature @@ -42,7 +42,7 @@ Feature: preview posts in the stream Scenario: preview a photo with text Given I expand the publisher - When I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher When I fill in the following: | status_message_fake_text | Look at this dog | And I press "Preview" diff --git a/features/desktop/posts_from_main_page.feature b/features/desktop/posts_from_main_page.feature index 0da96f25f..0e4023424 100644 --- a/features/desktop/posts_from_main_page.feature +++ b/features/desktop/posts_from_main_page.feature @@ -69,7 +69,7 @@ Feature: posting from the main page Scenario: post a photo with text Given I expand the publisher - When I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher When I write the status message "Look at this dog" And I submit the publisher And I go to the aspects page @@ -83,7 +83,7 @@ Feature: posting from the main page Scenario: post a photo without text Given I expand the publisher - When I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher Then I should see an uploaded image within the photo drop zone When I press "Share" And I go to the aspects page @@ -96,10 +96,10 @@ Feature: posting from the main page Scenario: back out of posting a photo-only post Given I expand the publisher And I have turned off jQuery effects - When I attach the file "spec/fixtures/bad_urls.txt" to "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher And I confirm the alert Then I should not see an uploaded image within the photo drop zone - When I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher And I click to delete the first uploaded photo Then I should not see an uploaded image within the photo drop zone And I should not be able to submit the publisher @@ -108,7 +108,7 @@ Feature: posting from the main page Given I expand the publisher And I have turned off jQuery effects When I write the status message "I am eating a yogurt" - And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher And I click to delete the first uploaded photo Then I should not see an uploaded image within the photo drop zone And the publisher should be expanded @@ -117,8 +117,8 @@ Feature: posting from the main page Given I expand the publisher And I have turned off jQuery effects When I write the status message "I am eating a yogurt" - And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" - And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher + And I attach "spec/fixtures/button.png" to the publisher And I click to delete the first uploaded photo Then I should see an uploaded image within the photo drop zone And the publisher should be expanded diff --git a/features/desktop/posts_from_profile_page.feature b/features/desktop/posts_from_profile_page.feature index cd968d5b2..96ee0404a 100644 --- a/features/desktop/posts_from_profile_page.feature +++ b/features/desktop/posts_from_profile_page.feature @@ -34,11 +34,9 @@ Feature: posting from own profile page Scenario: post a photo with text Given I expand the publisher - When I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" - When I fill in the following: - | status_message_fake_text | who am I? | - - And I press "Share" + When I write the status message "who am I?" + And I attach "spec/fixtures/button.png" to the publisher + And I submit the publisher When I am on the home page Then I should see a "img" within ".stream_element div.photo_attachments" @@ -47,6 +45,6 @@ Feature: posting from own profile page Scenario: back out of posting a photo-only post Given I expand the publisher And I have turned off jQuery effects - When I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I attach "spec/fixtures/button.png" to the publisher And I click to delete the first uploaded photo Then I should not see an uploaded image within the photo drop zone diff --git a/features/step_definitions/posts_steps.rb b/features/step_definitions/posts_steps.rb index 98e2cff05..0bcb3ef34 100644 --- a/features/step_definitions/posts_steps.rb +++ b/features/step_definitions/posts_steps.rb @@ -15,7 +15,7 @@ Then /^I should not see an uploaded image within the photo drop zone$/ do end Then /^I should not see any posts in my stream$/ do - all(".stream_element").should be_empty + page.assert_selector(".stream_element", count: 0) end Then /^I should not be able to submit the publisher$/ do @@ -83,6 +83,10 @@ When /^I append "([^"]*)" to the mobile publisher$/ do |text| append_to_publisher(text, '#status_message_text') end +When /^I attach "([^"]*)" to the publisher$/ do |path| + upload_file_with_publisher(path) +end + When /^I open the show page of the "([^"]*)" post$/ do |post_text| visit post_path_by_content(post_text) end diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb index 5e7e14e3e..cfebf3a95 100644 --- a/features/support/publishing_cuke_helpers.rb +++ b/features/support/publishing_cuke_helpers.rb @@ -4,13 +4,21 @@ module PublishingCukeHelpers end def append_to_publisher(txt, input_selector='#status_message_fake_text') - elem = find(input_selector) + elem = find(input_selector, visible: false) elem.native.send_keys(' ' + txt) # make sure the other text field got the new contents expect(find('#status_message_text', visible: false).value).to include(txt) end + def upload_file_with_publisher(path) + page.execute_script(%q{$("input[name='file']").css("opacity", '1');}) + with_scope("#publisher_textarea_wrapper") do + attach_file("file", Rails.root.join(path).to_s) + page.assert_selector(".publisher_photo.loading", count: 0) + end + end + def make_post(text) write_in_publisher(text) submit_publisher From fe0f8df9c97e62aaa46bdccff1f4d35caa033035 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Wed, 17 Sep 2014 14:36:04 +0200 Subject: [PATCH 186/785] add a 'css mutex' for cuke failures --- app/assets/javascripts/app/pages/profile.js | 11 ++++++++++- .../javascripts/app/views/profile_header_view.js | 10 +++++++++- features/step_definitions/aspects_steps.rb | 13 +++++++++++++ features/step_definitions/user_steps.rb | 8 +------- features/support/publishing_cuke_helpers.rb | 2 ++ 5 files changed, 35 insertions(+), 9 deletions(-) diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 716baa906..3aa9fb101 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -27,6 +27,7 @@ app.pages.Profile = app.views.Base.extend({ this.streamViewClass = _.has(opts, 'streamView') ? opts.streamView : null; this.model.on('change', this.render, this); + this.model.on('sync', this._done, this); // bind to global events var id = this.model.get('id'); @@ -114,6 +115,14 @@ app.pages.Profile = app.views.Base.extend({ }, reload: function() { - this.model.fetch(); + this.$('#profile').addClass('loading'); + + this.asyncSubHeader = $.Deferred(); + $.when(this.model.fetch(), this.asyncSubHeader) + .done(_.bind(this._done, this)); + }, + + _done: function() { + this.$('#profile').removeClass('loading'); } }); diff --git a/app/assets/javascripts/app/views/profile_header_view.js b/app/assets/javascripts/app/views/profile_header_view.js index 26cdebef8..971cfacce 100644 --- a/app/assets/javascripts/app/views/profile_header_view.js +++ b/app/assets/javascripts/app/views/profile_header_view.js @@ -20,7 +20,10 @@ app.views.ProfileHeader = app.views.Base.extend({ postRenderTemplate: function() { var self = this; var dropdownEl = this.$('.aspect_membership_dropdown.placeholder'); - if( dropdownEl.length == 0 ) return; + if( dropdownEl.length == 0 ) { + this._done(); + return; + } // TODO render me client side!!! var href = this.model.url() + '/aspect_membership_button?create=true'; @@ -32,6 +35,11 @@ app.views.ProfileHeader = app.views.Base.extend({ // UGLY (re-)attach the facebox self.$('a[rel*=facebox]').facebox(); + this._done(); }); + }, + + _done: function() { + app.page.asyncSubHeader && app.page.asyncSubHeader.resovle(); } }); diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb index e7fa34bfd..e0f827f4a 100644 --- a/features/step_definitions/aspects_steps.rb +++ b/features/step_definitions/aspects_steps.rb @@ -10,6 +10,19 @@ module AspectCukeHelpers find(aspect_css).click end + def toggle_aspect_via_ui(aspect_name) + aspects_dropdown = find(".aspect_membership .toggle.button", match: :first) + aspects_dropdown.click + aspect = find(".dropdown.active .dropdown_list li", text: aspect_name) + aspect.click + aspect.parent.should have_no_css(".loading") + + # close dropdown + page.should have_no_css('#profile.loading') + aspects_dropdown.click if aspects_dropdown.has_xpath?("..[contains(@class, 'active')]", wait: 3) + aspects_dropdown.should have_no_xpath("..[contains(@class, 'active')]") + end + def aspect_dropdown_visible? expect(find('.aspect_membership.dropdown.active')).to be_visible end diff --git a/features/step_definitions/user_steps.rb b/features/step_definitions/user_steps.rb index d410163ee..37e555755 100644 --- a/features/step_definitions/user_steps.rb +++ b/features/step_definitions/user_steps.rb @@ -119,13 +119,7 @@ Then /^I should have (\d) contacts? in "([^"]*)"$/ do |n_contacts, aspect_name| end When /^I (?:add|remove) the person (?:to|from) my "([^\"]*)" aspect$/ do |aspect_name| - aspects_dropdown = find(".aspect_membership .toggle.button", match: :first) - aspects_dropdown.click - aspect = find(".dropdown.active .dropdown_list li", text: aspect_name) - aspect.click - aspect.parent.has_css?(".loading") - aspect.parent.should_not have_css(".loading") - aspects_dropdown.click + toggle_aspect_via_ui(aspect_name) end When /^I post a status with the text "([^\"]*)"$/ do |text| diff --git a/features/support/publishing_cuke_helpers.rb b/features/support/publishing_cuke_helpers.rb index cfebf3a95..863f29f7b 100644 --- a/features/support/publishing_cuke_helpers.rb +++ b/features/support/publishing_cuke_helpers.rb @@ -15,6 +15,7 @@ module PublishingCukeHelpers page.execute_script(%q{$("input[name='file']").css("opacity", '1');}) with_scope("#publisher_textarea_wrapper") do attach_file("file", Rails.root.join(path).to_s) + # wait for the image to be ready page.assert_selector(".publisher_photo.loading", count: 0) end end @@ -27,6 +28,7 @@ module PublishingCukeHelpers def submit_publisher txt = find('#publisher #status_message_fake_text').value find('#publisher .creation').click + # wait for the content to appear expect(page).to have_content(txt) unless page.has_css?('.nsfw-shield') end From 0bbf304e0364700a81f634ff2bc16f63a9e0b797 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Wed, 17 Sep 2014 18:38:27 +0200 Subject: [PATCH 187/785] fix the last of the failing cukes (hopefully) --- features/desktop/posts_from_main_page.feature | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/features/desktop/posts_from_main_page.feature b/features/desktop/posts_from_main_page.feature index 0e4023424..fd829e4eb 100644 --- a/features/desktop/posts_from_main_page.feature +++ b/features/desktop/posts_from_main_page.feature @@ -95,12 +95,8 @@ Feature: posting from the main page Scenario: back out of posting a photo-only post Given I expand the publisher - And I have turned off jQuery effects And I attach "spec/fixtures/button.png" to the publisher - And I confirm the alert - Then I should not see an uploaded image within the photo drop zone - And I attach "spec/fixtures/button.png" to the publisher - And I click to delete the first uploaded photo + When I click to delete the first uploaded photo Then I should not see an uploaded image within the photo drop zone And I should not be able to submit the publisher From 6e1bd7216d726ff40e6f6b41e33bec52bc51bcac Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Wed, 17 Sep 2014 21:39:04 +0200 Subject: [PATCH 188/785] fix /u/[username] route --- app/controllers/people_controller.rb | 6 ++++-- spec/controllers/people_controller_spec.rb | 5 +++++ 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index bfbb17379..f0782d70a 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -174,8 +174,10 @@ class PeopleController < ApplicationController private def find_person - person_id = params[:id] || params[:person_id] - @person = Person.find_from_guid_or_username({id: person_id}) + @person = Person.find_from_guid_or_username({ + id: params[:id] || params[:person_id], + username: params[:username] + }) # view this profile on the home pod, if you don't want to sign in... authenticate_user! if remote_profile_with_no_user_session? diff --git a/spec/controllers/people_controller_spec.rb b/spec/controllers/people_controller_spec.rb index 3e854f084..734c19e9e 100644 --- a/spec/controllers/people_controller_spec.rb +++ b/spec/controllers/people_controller_spec.rb @@ -174,6 +174,11 @@ describe PeopleController, :type => :controller do expect(response.code).to eq("404") end + it 'finds a person via username' do + get :show, username: @user.username + expect(assigns(:person)).to eq(@user.person) + end + it 'redirects home for closed account' do @person = FactoryGirl.create(:person, :closed_account => true) get :show, :id => @person.to_param From b448f92c612950d382b78f16a81610dddaed97b7 Mon Sep 17 00:00:00 2001 From: jaideng123 Date: Wed, 17 Sep 2014 21:10:25 -0500 Subject: [PATCH 189/785] Fixed deformation of getting started popovers --- .../app/views/publisher/getting_started_view.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/app/assets/javascripts/app/views/publisher/getting_started_view.js b/app/assets/javascripts/app/views/publisher/getting_started_view.js index f3e6142cd..fd0f921bf 100644 --- a/app/assets/javascripts/app/views/publisher/getting_started_view.js +++ b/app/assets/javascripts/app/views/publisher/getting_started_view.js @@ -21,21 +21,24 @@ app.views.PublisherGettingStarted = Backbone.View.extend({ offset: 30, id: 'first_message_explain', placement: 'right', - html: true + html: true, + container: 'body' }, 600); this._addPopover(this.el_visibility, { trigger: 'manual', offset: 10, id: 'message_visibility_explain', placement: 'bottom', - html: true + html: true, + container: 'body' }, 1000); this._addPopover(this.el_stream, { trigger: 'manual', offset: -5, id: 'stream_explain', placement: 'left', - html: true + html: true, + container: 'body' }, 1400); // hide some popovers when a post is created From 7da650160208a1ab0af29bff3c1f6b320429416f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Thu, 18 Sep 2014 12:39:16 +0200 Subject: [PATCH 190/785] let tags controller spec generate offending query for #5228 --- spec/controllers/tags_controller_spec.rb | 52 +++++++++++++----------- 1 file changed, 29 insertions(+), 23 deletions(-) diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb index 441d630e1..f2eef5b72 100644 --- a/spec/controllers/tags_controller_spec.rb +++ b/spec/controllers/tags_controller_spec.rb @@ -47,36 +47,42 @@ describe TagsController, :type => :controller do end end - context 'signed in' do + context 'with a tagged post' do before do - sign_in :user, alice + eve.post(:status_message, text: "#what #yes #hellyes #foo", public: true, to: 'all') end - it 'assigns a Stream::Tag object with the current_user' do - get :show, :name => 'yes' - expect(assigns[:stream].user).to eq(alice) + context 'signed in' do + before do + sign_in :user, alice + end + + it 'assigns a Stream::Tag object with the current_user' do + get :show, :name => 'yes' + expect(assigns[:stream].user).to eq(alice) + end + + it 'succeeds' do + get :show, :name => 'hellyes' + expect(response.status).to eq(200) + end end - it 'succeeds' do - get :show, :name => 'hellyes' - expect(response.status).to eq(200) - end - end + context "not signed in" do + it 'assigns a Stream::Tag object with no user' do + get :show, :name => 'yes' + expect(assigns[:stream].user).to be_nil + end - context "not signed in" do - it 'assigns a Stream::Tag object with no user' do - get :show, :name => 'yes' - expect(assigns[:stream].user).to be_nil - end + it 'succeeds' do + get :show, :name => 'hellyes' + expect(response.status).to eq(200) + end - it 'succeeds' do - get :show, :name => 'hellyes' - expect(response.status).to eq(200) - end - - it 'succeeds with mobile' do - get :show, :name => 'foo', :format => :mobile - expect(response).to be_success + it 'succeeds with mobile' do + get :show, :name => 'foo', :format => :mobile + expect(response).to be_success + end end end end From 926556c145f43638208dd681c0f7b8b772640ff2 Mon Sep 17 00:00:00 2001 From: Florian Staudacher Date: Thu, 18 Sep 2014 22:30:28 +0200 Subject: [PATCH 191/785] fix profile badge too much margin [ci skip] --- app/assets/stylesheets/profile.css.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/assets/stylesheets/profile.css.scss b/app/assets/stylesheets/profile.css.scss index de1dfe8cc..bf2338591 100644 --- a/app/assets/stylesheets/profile.css.scss +++ b/app/assets/stylesheets/profile.css.scss @@ -13,6 +13,8 @@ padding: 0; } + .avatar.large { margin-bottom: 0; } + ul#profile_information { margin: 1em 0; > li { From 93c6159c56aef7a5d4e1b78b8a35601c86905aab Mon Sep 17 00:00:00 2001 From: "taro@diasporajp" Date: Fri, 19 Sep 2014 16:33:55 +0900 Subject: [PATCH 192/785] fix locale of invitation email subject #5231 --- app/mailers/notifier.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb index 00dd5e109..e92795a18 100644 --- a/app/mailers/notifier.rb +++ b/app/mailers/notifier.rb @@ -43,11 +43,11 @@ class Notifier < ActionMailer::Base @locale = locale @invitation_code = invitation_code - mail_opts = {:to => email, :from => AppConfig.mail.sender_address, + I18n.with_locale(locale) do + mail_opts = {:to => email, :from => AppConfig.mail.sender_address, :subject => I18n.t('notifier.invited_you', :name => @inviter.name), :host => AppConfig.pod_uri.host} - I18n.with_locale(locale) do mail(mail_opts) do |format| format.text { render :layout => nil } format.html { render :layout => nil } From 2d2217b677710e65c1808f26fa8747eb22867ce6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 03:01:43 +0200 Subject: [PATCH 193/785] Monkey patch Sidekiq logger Sidekiq 3.0 initialized the logger early before we had a chance to set the logfile. Then we set a new logfile causing the old logger to be closed. Since the default logger points to stdout, it got closed causing all kinds of issues. --- config/initializers/sidekiq.rb | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index a1ff43592..c0c6da556 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -11,6 +11,9 @@ if AppConfig.environment.single_process_mode? && Rails.env != "test" require 'sidekiq/testing/inline' end +def (Sidekiq::Logging).logger + defined?(@logger) ? @logger : (AppConfig.heroku? ? initialize_logger : initialize_logger(AppConfig.sidekiq_log)) +end Sidekiq.configure_server do |config| config.redis = AppConfig.get_redis_options @@ -36,8 +39,6 @@ Sidekiq.configure_server do |config| chain.add SidekiqMiddlewares::CleanAndShortBacktraces end - Sidekiq::Logging.initialize_logger AppConfig.sidekiq_log unless AppConfig.heroku? - # Set connection pool on Heroku database_url = ENV['DATABASE_URL'] if(database_url) From 5133458d30e0f9e8cc131f1a9613745beeaf5f75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 04:05:57 +0200 Subject: [PATCH 194/785] Start converting IDN emails --- Changelog.md | 1 + app/mailers/notification_mailers/base.rb | 2 +- spec/mailers/notifier_spec.rb | 10 ++++++++++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index 5cbb40ed5..810003230 100644 --- a/Changelog.md +++ b/Changelog.md @@ -49,6 +49,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Handle long URLs and titles in OpenGraph descriptions [#5208](https://github.com/diaspora/diaspora/pull/5208) * Fix deformed getting started popover [#5227](https://github.com/diaspora/diaspora/pull/5227) * Use correct locale for invitation subject [#5232](https://github.com/diaspora/diaspora/pull/5232) +* Initial support for IDN emails ## Features * Don't pull jQuery from a CDN by default [#5105](https://github.com/diaspora/diaspora/pull/5105) diff --git a/app/mailers/notification_mailers/base.rb b/app/mailers/notification_mailers/base.rb index ec2950bfb..086228b06 100644 --- a/app/mailers/notification_mailers/base.rb +++ b/app/mailers/notification_mailers/base.rb @@ -23,7 +23,7 @@ module NotificationMailers end def name_and_address(name, email) - address = Mail::Address.new email + address = Mail::Address.new Addressable::IDNA.to_ascii(email) address.display_name = name address.format end diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb index 327880780..c5296b5c6 100644 --- a/spec/mailers/notifier_spec.rb +++ b/spec/mailers/notifier_spec.rb @@ -326,4 +326,14 @@ describe Notifier, :type => :mailer do expect(mail.body.encoded).to match "

    #Welcome to bureaucracy!

    " end end + + describe "base" do + it "handles idn addresses" do + # user = FactoryGirl.create(:user, email: "ŧoo@ŧexample.com") + bob.update_attribute(:email, "ŧoo@ŧexample.com") + expect { + Notifier.started_sharing(bob.id, person.id) + }.to_not raise_error + end + end end From 4b754b51f9007772eb52177c291dac5811dba25c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 13:39:09 +0200 Subject: [PATCH 195/785] Discard dispatch jobs of already deleted records --- app/workers/deferred_dispatch.rb | 1 + spec/workers/deferred_dispatch_spec.rb | 9 +++++++++ 2 files changed, 10 insertions(+) create mode 100644 spec/workers/deferred_dispatch_spec.rb diff --git a/app/workers/deferred_dispatch.rb b/app/workers/deferred_dispatch.rb index cbb87581a..46fa894c3 100644 --- a/app/workers/deferred_dispatch.rb +++ b/app/workers/deferred_dispatch.rb @@ -17,6 +17,7 @@ module Workers end Postzord::Dispatcher.build(user, object, opts).post + rescue ActiveRecord::RecordNotFound # The target got deleted before the job was run end end end diff --git a/spec/workers/deferred_dispatch_spec.rb b/spec/workers/deferred_dispatch_spec.rb new file mode 100644 index 000000000..f0a20d768 --- /dev/null +++ b/spec/workers/deferred_dispatch_spec.rb @@ -0,0 +1,9 @@ +require 'spec_helper' + +describe Workers::DeferredDispatch do + it "handles non existing records gracefully" do + expect { + described_class.new.perform(alice.id, 'Comment', 0, {}) + }.to_not raise_error + end +end From 5ca1c1d2951f35d2443eebc2e7f456eee2fc907d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 13:47:52 +0200 Subject: [PATCH 196/785] Raise on 404 during Webfinger That's at least readable, return false just causes silly follow up errors --- lib/webfinger.rb | 4 +++- spec/lib/webfinger_spec.rb | 13 +++++++------ 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/lib/webfinger.rb b/lib/webfinger.rb index 93e2cf5f6..385c2b40b 100644 --- a/lib/webfinger.rb +++ b/lib/webfinger.rb @@ -31,7 +31,9 @@ class Webfinger Rails.logger.info("Getting: #{url} for #{account}") begin res = Faraday.get(url) - return false if res.status == 404 + unless res.success? + raise "Failed to fetch #{url}: #{res.status}" + end res.body rescue OpenSSL::SSL::SSLError => e Rails.logger.info "Failed to fetch #{url}: SSL setup invalid" diff --git a/spec/lib/webfinger_spec.rb b/spec/lib/webfinger_spec.rb index 25104bb37..c3515bebe 100644 --- a/spec/lib/webfinger_spec.rb +++ b/spec/lib/webfinger_spec.rb @@ -36,7 +36,7 @@ describe Webfinger do Webfinger.in_background(account) end end - + describe '#fetch' do it 'works' do finger = Webfinger.new(account_in_fixtures) @@ -72,14 +72,15 @@ describe Webfinger do expect(a_request(:get, redirect_url)).to have_been_made end - - it 'returns false on 404' do + + it 'raises on 404' do url ="https://bar.com/.well-known/host-meta" stub_request(:get, url). to_return(:status => 404, :body => nil) - expect(finger.get(url)).not_to eq(nil) - expect(finger.get(url)).to eq(false) + expect { + expect(finger.get(url)).to eq(false) + }.to raise_error end end @@ -190,7 +191,7 @@ describe Webfinger do expect(Person).to receive(:create_from_webfinger).with("webfinger_profile", "hcard") finger.make_person_from_webfinger end - + it 'with an false xrd it does not call Person.create_from_webfinger' do allow(finger).to receive(:webfinger_profile_xrd).and_return(false) expect(Person).not_to receive(:create_from_webfinger) From 499ff6e0f463d7fdd53119d76b1aa444f0ddd7c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 15:03:53 +0200 Subject: [PATCH 197/785] Fix receiving a relayable retraction through the public route --- lib/diaspora/federated/relayable_retraction.rb | 4 ++++ lib/postzord/receiver/public.rb | 10 +++++----- .../diaspora/federated/relayable_retraction_spec.rb | 7 +++++++ 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/lib/diaspora/federated/relayable_retraction.rb b/lib/diaspora/federated/relayable_retraction.rb index ab7be6528..3d48f6763 100644 --- a/lib/diaspora/federated/relayable_retraction.rb +++ b/lib/diaspora/federated/relayable_retraction.rb @@ -60,4 +60,8 @@ class RelayableRetraction < SignedRetraction def parent_author_signature_valid? verify_signature(self.parent_author_signature, self.parent.author) end + + def parent_diaspora_handle + target.author.diaspora_handle + end end diff --git a/lib/postzord/receiver/public.rb b/lib/postzord/receiver/public.rb index 0243b72f5..d3f27be77 100644 --- a/lib/postzord/receiver/public.rb +++ b/lib/postzord/receiver/public.rb @@ -26,15 +26,15 @@ class Postzord::Receiver::Public < Postzord::Receiver return false unless save_object FEDERATION_LOGGER.info("received a #{@object.inspect}") - if @object.respond_to?(:relayable?) - receive_relayable - elsif @object.is_a?(AccountDeletion) - #nothing - elsif @object.is_a?(SignedRetraction) # feels like a hack + if @object.is_a?(SignedRetraction) # feels like a hack self.recipient_user_ids.each do |user_id| user = User.where(id: user_id).first @object.perform user if user end + elsif @object.respond_to?(:relayable?) + receive_relayable + elsif @object.is_a?(AccountDeletion) + #nothing else Workers::ReceiveLocalBatch.perform_async(@object.class.to_s, @object.id, self.recipient_user_ids) true diff --git a/spec/lib/diaspora/federated/relayable_retraction_spec.rb b/spec/lib/diaspora/federated/relayable_retraction_spec.rb index baf88a6eb..6e8635a24 100644 --- a/spec/lib/diaspora/federated/relayable_retraction_spec.rb +++ b/spec/lib/diaspora/federated/relayable_retraction_spec.rb @@ -98,6 +98,13 @@ describe RelayableRetraction do expect(Postzord::Dispatcher).not_to receive(:build) @retraction.receive(@recipient, @remote_raphael) end + + it 'performs through postzord' do + xml = Salmon::Slap.create_by_user_and_activity(@local_luke, @retraction.to_diaspora_xml).xml_for(nil) + expect { + Postzord::Receiver::Public.new(xml).perform! + }.to change(Comment, :count).by(-1) + end end end From d6f5368474240a394a5c952769480cad69093a89 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 15:12:56 +0200 Subject: [PATCH 198/785] Handle already deleted photos gracefully in process photo job --- app/workers/process_photo.rb | 1 + spec/workers/process_photo_spec.rb | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/workers/process_photo.rb b/app/workers/process_photo.rb index 00d959962..2fcdd3943 100644 --- a/app/workers/process_photo.rb +++ b/app/workers/process_photo.rb @@ -16,6 +16,7 @@ module Workers photo.processed_image.store!(unprocessed_image) photo.save! + rescue ActiveRecord::RecordNotFound # Deleted before the job was run end end end diff --git a/spec/workers/process_photo_spec.rb b/spec/workers/process_photo_spec.rb index 8294902ca..8e28fba74 100644 --- a/spec/workers/process_photo_spec.rb +++ b/spec/workers/process_photo_spec.rb @@ -61,6 +61,12 @@ describe Workers::ProcessPhoto do expect{ result = Workers::ProcessPhoto.new.perform(p.id) }.to_not raise_error - + + end + + it 'handles already deleted photos gracefully' do + expect { + Workers::ProcessPhoto.new.perform(0) + }.to_not raise_error end end From 9520d06c7bc1a2e2001820245b8147084f4d7d94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sat, 20 Sep 2014 15:26:31 +0200 Subject: [PATCH 199/785] Handle already deleted items gracefully in receive local batch job --- app/workers/receive_local_batch.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/app/workers/receive_local_batch.rb b/app/workers/receive_local_batch.rb index 81d8a9ecf..adcf312aa 100644 --- a/app/workers/receive_local_batch.rb +++ b/app/workers/receive_local_batch.rb @@ -10,6 +10,7 @@ module Workers object = object_class_string.constantize.find(object_id) receiver = Postzord::Receiver::LocalBatch.new(object, recipient_user_ids) receiver.perform! + rescue ActiveRecord::NotFound # Already deleted before the job could run end end end From 430d5bd2e9d7b8fdccfbc4135201e981a3a53763 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 26 Sep 2014 22:14:09 +0200 Subject: [PATCH 200/785] bump configurate --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index 213b31301..888aa426c 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem 'uglifier', '2.5.3' # Configuration -gem 'configurate', '0.0.8' +gem 'configurate', '0.1.0' # Cross-origin resource sharing diff --git a/Gemfile.lock b/Gemfile.lock index b13a4a6d0..939351764 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -93,7 +93,7 @@ GEM sass (~> 3.2.19) compass-rails (2.0.0) compass (>= 0.12.2) - configurate (0.0.8) + configurate (0.1.0) connection_pool (2.0.0) crack (0.4.2) safe_yaml (~> 1.0.0) @@ -511,7 +511,7 @@ DEPENDENCIES capybara (= 2.4.1) carrierwave (= 0.10.0) compass-rails (= 2.0.0) - configurate (= 0.0.8) + configurate (= 0.1.0) cucumber-rails (= 1.4.1) database_cleaner (= 1.3.0) devise (= 3.3.0) From baacefbd92f1c0511ab4a619051d6fdeaa600f7b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Sun, 28 Sep 2014 16:34:50 +0200 Subject: [PATCH 201/785] look for hashed version of default.css in script/server fixes #5254 --- script/server | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/server b/script/server index 4652e04b6..faf43111e 100755 --- a/script/server +++ b/script/server @@ -117,7 +117,7 @@ then fi # Check if assets are precompiled -if [ "$RAILS_ENV" = "production" -a ! -e "public/assets/default.css" ] +if [ "$RAILS_ENV" = "production" -a -z "$(find public/assets -maxdepth 1 -name 'default-*.css' -print -quit)" ] then fatal "You're running in production mode without having assets precompiled. Now and after each update before you restart the From 4a87e7d72eb1d213ed2301c8692189ea5184cb5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Mon, 29 Sep 2014 16:10:51 +0200 Subject: [PATCH 202/785] bump acts-as-taggable-on, closes #5228, #5234 --- Gemfile | 2 +- Gemfile.lock | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Gemfile b/Gemfile index 0c57be00e..8660d6b50 100644 --- a/Gemfile +++ b/Gemfile @@ -119,7 +119,7 @@ gem 'omniauth-wordpress','0.2.1' # Tags -gem 'acts-as-taggable-on', '3.4.1' +gem 'acts-as-taggable-on', '3.4.2' # URIs and HTTP diff --git a/Gemfile.lock b/Gemfile.lock index 2eeb0e039..f1251cf6a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -38,7 +38,7 @@ GEM minitest (~> 5.1) thread_safe (~> 0.1) tzinfo (~> 1.1) - acts-as-taggable-on (3.4.1) + acts-as-taggable-on (3.4.2) activerecord (>= 3.2, < 5) acts_as_api (0.4.2) activemodel (>= 3.0.0) @@ -266,7 +266,7 @@ GEM mini_magick (3.8.1) subexec (~> 0.2.1) mini_portile (0.5.3) - minitest (5.4.1) + minitest (5.4.2) mobile-fu (1.3.1) rack-mobile-detect rails @@ -504,7 +504,7 @@ DEPENDENCIES actionpack-action_caching actionpack-page_caching activerecord-import (= 0.5.0) - acts-as-taggable-on (= 3.4.1) + acts-as-taggable-on (= 3.4.2) acts_as_api (= 0.4.2) addressable (= 2.3.6) asset_sync (= 1.1.0) From 2b6ac9261b0a2588614b6db0aa9a4d142c05786e Mon Sep 17 00:00:00 2001 From: jaideng123 Date: Sat, 20 Sep 2014 17:42:25 -0500 Subject: [PATCH 203/785] Notifications Dropdown now infinite scrolls --- .../widgets/notifications-badge.js | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/app/assets/javascripts/widgets/notifications-badge.js b/app/assets/javascripts/widgets/notifications-badge.js index 0509d0adc..fc2c1d3c4 100644 --- a/app/assets/javascripts/widgets/notifications-badge.js +++ b/app/assets/javascripts/widgets/notifications-badge.js @@ -1,6 +1,9 @@ (function() { var NotificationDropdown = function() { var self = this; + var currentPage = 2; + var notificationsLoaded = 10; + var isLoading = false; this.subscribe("widget/ready",function(evt, badge, dropdown) { $.extend(self, { @@ -43,8 +46,8 @@ self.ajaxLoader.show(); self.badge.addClass("active"); self.dropdown.css("display", "block"); - self.getNotifications(); + }; this.hideDropdown = function() { @@ -53,8 +56,17 @@ $('.notifications').perfectScrollbar('destroy'); }; + this.getMoreNotifications = function() { + $.getJSON("/notifications?per_page=5&page="+currentPage, function(notifications) { + for(var i = 0; i < notifications.length; ++i) + self.notifications.push(notifications[i]); + notificationsLoaded += 5; + self.renderNotifications(); + }); + }; + this.getNotifications = function() { - $.getJSON("/notifications?per_page=15", function(notifications) { + $.getJSON("/notifications?per_page="+notificationsLoaded, function(notifications) { self.notifications = notifications; self.renderNotifications(); }); @@ -62,10 +74,10 @@ this.renderNotifications = function() { self.dropdownNotifications.empty(); - $.each(self.notifications, function(index, notifications) { $.each(notifications, function(index, notification) { - self.dropdownNotifications.append(notification.note_html); + if($.inArray(notification, notifications) === -1) + self.dropdownNotifications.append(notification.note_html); }); }); self.dropdownNotifications.find("time.timeago").timeago(); @@ -76,9 +88,20 @@ self.dropdownNotifications.find('.read').each(function(index) { Diaspora.page.header.notifications.setUpRead( $(this) ); }); + $('.notifications').perfectScrollbar('destroy'); $('.notifications').perfectScrollbar(); - $(".notifications").scrollTop(0); self.ajaxLoader.hide(); + isLoading = false; + //Infinite Scrolling + $('.notifications').scroll(function(e) { + var bottom = $('.notifications').prop('scrollHeight') - $('.notifications').height(); + var currentPosition = $('.notifications').scrollTop(); + if (currentPosition + 50 >= bottom && notificationsLoaded <= self.notifications.length && !isLoading) { + isLoading = true; + ++currentPage; + self.getMoreNotifications(); + } + }); }; }; From 10feffada439a59d5b363c283d17692318446238 Mon Sep 17 00:00:00 2001 From: Sandip Trivedi Date: Tue, 30 Sep 2014 16:16:52 -0400 Subject: [PATCH 204/785] Replaced punycode.js vendored asset with a bower package #5194 --- Gemfile | 13 +- Gemfile.lock | 2 + vendor/assets/javascripts/punycode.js | 512 -------------------------- 3 files changed, 9 insertions(+), 518 deletions(-) delete mode 100644 vendor/assets/javascripts/punycode.js diff --git a/Gemfile b/Gemfile index 8660d6b50..77f0c9448 100644 --- a/Gemfile +++ b/Gemfile @@ -76,12 +76,13 @@ gem 'entypo-rails', '2.2.2' # JavaScript -gem 'backbone-on-rails', '1.1.1' -gem 'handlebars_assets', '0.18.0' -gem 'jquery-rails', '3.1.2' -gem 'rails-assets-jquery', '1.11.1' # Should be kept in sync with jquery-rails -gem 'js_image_paths', '0.0.1' -gem 'js-routes', '0.9.9' +gem 'backbone-on-rails', '1.1.1' +gem 'handlebars_assets', '0.18.0' +gem 'jquery-rails', '3.1.2' +gem 'rails-assets-jquery', '1.11.1' # Should be kept in sync with jquery-rails +gem 'js_image_paths', '0.0.1' +gem 'js-routes', '0.9.9' +gem 'rails-assets-punycode', '1.3.1' # jQuery plugins diff --git a/Gemfile.lock b/Gemfile.lock index f1251cf6a..f6f3e1d09 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -350,6 +350,7 @@ GEM rails-assets-jquery (1.11.1) rails-assets-perfect-scrollbar (0.4.11) rails-assets-jquery (>= 1.10) + rails-assets-punycode (1.3.1) rails-i18n (4.0.3) i18n (~> 0.6) railties (~> 4.0) @@ -564,6 +565,7 @@ DEPENDENCIES rails (= 4.1.6) rails-assets-jquery (= 1.11.1) rails-assets-perfect-scrollbar (= 0.4.11) + rails-assets-punycode (= 1.3.1) rails-i18n (= 4.0.3) rails-timeago (= 2.11.0) rails_admin (= 0.6.3) diff --git a/vendor/assets/javascripts/punycode.js b/vendor/assets/javascripts/punycode.js deleted file mode 100644 index 8688f2efd..000000000 --- a/vendor/assets/javascripts/punycode.js +++ /dev/null @@ -1,512 +0,0 @@ -/*! http://mths.be/punycode by @mathias */ -;(function(root) { - - /** - * The `punycode` object. - * @name punycode - * @type Object - */ - var punycode, - - /** Detect free variables `define`, `exports`, `module` and `require` */ - freeDefine = typeof define == 'function' && typeof define.amd == 'object' && - define.amd && define, - freeExports = typeof exports == 'object' && exports, - freeModule = typeof module == 'object' && module, - freeRequire = typeof require == 'function' && require, - - /** Highest positive signed 32-bit float value */ - maxInt = 2147483647, // aka. 0x7FFFFFFF or 2^31-1 - - /** Bootstring parameters */ - base = 36, - tMin = 1, - tMax = 26, - skew = 38, - damp = 700, - initialBias = 72, - initialN = 128, // 0x80 - delimiter = '-', // '\x2D' - - /** Regular expressions */ - regexNonASCII = /[^ -~]/, // unprintable ASCII chars + non-ASCII chars - regexPunycode = /^xn--/, - - /** Error messages */ - errors = { - 'overflow': 'Overflow: input needs wider integers to process.', - 'ucs2decode': 'UCS-2(decode): illegal sequence', - 'ucs2encode': 'UCS-2(encode): illegal value', - 'not-basic': 'Illegal input >= 0x80 (not a basic code point)', - 'invalid-input': 'Invalid input' - }, - - /** Convenience shortcuts */ - baseMinusTMin = base - tMin, - floor = Math.floor, - stringFromCharCode = String.fromCharCode, - - /** Temporary variable */ - key; - - /*--------------------------------------------------------------------------*/ - - /** - * A generic error utility function. - * @private - * @param {String} type The error type. - * @returns {Error} Throws a `RangeError` with the applicable error message. - */ - function error(type) { - throw RangeError(errors[type]); - } - - /** - * A generic `Array#map` utility function. - * @private - * @param {Array} array The array to iterate over. - * @param {Function} callback The function that gets called for every array - * item. - * @returns {Array} A new array of values returned by the callback function. - */ - function map(array, fn) { - var length = array.length; - while (length--) { - array[length] = fn(array[length]); - } - return array; - } - - /** - * A simple `Array#map`-like wrapper to work with domain name strings. - * @private - * @param {String} domain The domain name. - * @param {Function} callback The function that gets called for every - * character. - * @returns {Array} A new string of characters returned by the callback - * function. - */ - function mapDomain(string, fn) { - var glue = '.'; - return map(string.split(glue), fn).join(glue); - } - - /** - * Creates an array containing the decimal code points of each Unicode - * character in the string. While JavaScript uses UCS-2 internally, - * this function will convert a pair of surrogate halves (each of which - * UCS-2 exposes as separate characters) into a single code point, - * matching UTF-16. - * @see `punycode.ucs2.encode` - * @see - * @memberOf punycode.ucs2 - * @name decode - * @param {String} string The Unicode input string (UCS-2). - * @returns {Array} The new array of code points. - */ - function ucs2decode(string) { - var output = [], - counter = 0, - length = string.length, - value, - extra; - while (counter < length) { - value = string.charCodeAt(counter++); - if ((value & 0xF800) == 0xD800) { - extra = string.charCodeAt(counter++); - if ((value & 0xFC00) != 0xD800 || (extra & 0xFC00) != 0xDC00) { - error('ucs2decode'); - } - value = ((value & 0x3FF) << 10) + (extra & 0x3FF) + 0x10000; - } - output.push(value); - } - return output; - } - - /** - * Creates a string based on an array of decimal code points. - * @see `punycode.ucs2.decode` - * @memberOf punycode.ucs2 - * @name encode - * @param {Array} codePoints The array of decimal code points. - * @returns {String} The new Unicode string (UCS-2). - */ - function ucs2encode(array) { - return map(array, function(value) { - var output = ''; - if ((value & 0xF800) == 0xD800) { - error('ucs2encode'); - } - if (value > 0xFFFF) { - value -= 0x10000; - output += stringFromCharCode(value >>> 10 & 0x3FF | 0xD800); - value = 0xDC00 | value & 0x3FF; - } - output += stringFromCharCode(value); - return output; - }).join(''); - } - - /** - * Converts a basic code point into a digit/integer. - * @see `digitToBasic()` - * @private - * @param {Number} codePoint The basic (decimal) code point. - * @returns {Number} The numeric value of a basic code point (for use in - * representing integers) in the range `0` to `base - 1`, or `base` if - * the code point does not represent a value. - */ - function basicToDigit(codePoint) { - return codePoint - 48 < 10 - ? codePoint - 22 - : codePoint - 65 < 26 - ? codePoint - 65 - : codePoint - 97 < 26 - ? codePoint - 97 - : base; - } - - /** - * Converts a digit/integer into a basic code point. - * @see `basicToDigit()` - * @private - * @param {Number} digit The numeric value of a basic code point. - * @returns {Number} The basic code point whose value (when used for - * representing integers) is `digit`, which needs to be in the range - * `0` to `base - 1`. If `flag` is non-zero, the uppercase form is - * used; else, the lowercase form is used. The behavior is undefined - * if flag is non-zero and `digit` has no uppercase form. - */ - function digitToBasic(digit, flag) { - // 0..25 map to ASCII a..z or A..Z - // 26..35 map to ASCII 0..9 - return digit + 22 + 75 * (digit < 26) - ((flag != 0) << 5); - } - - /** - * Bias adaptation function as per section 3.4 of RFC 3492. - * http://tools.ietf.org/html/rfc3492#section-3.4 - * @private - */ - function adapt(delta, numPoints, firstTime) { - var k = 0; - delta = firstTime ? floor(delta / damp) : delta >> 1; - delta += floor(delta / numPoints); - for (/* no initialization */; delta > baseMinusTMin * tMax >> 1; k += base) { - delta = floor(delta / baseMinusTMin); - } - return floor(k + (baseMinusTMin + 1) * delta / (delta + skew)); - } - - /** - * Converts a basic code point to lowercase is `flag` is falsy, or to - * uppercase if `flag` is truthy. The code point is unchanged if it's - * caseless. The behavior is undefined if `codePoint` is not a basic code - * point. - * @private - * @param {Number} codePoint The numeric value of a basic code point. - * @returns {Number} The resulting basic code point. - */ - function encodeBasic(codePoint, flag) { - codePoint -= (codePoint - 97 < 26) << 5; - return codePoint + (!flag && codePoint - 65 < 26) << 5; - } - - /** - * Converts a Punycode string of ASCII code points to a string of Unicode - * code points. - * @memberOf punycode - * @param {String} input The Punycode string of ASCII code points. - * @returns {String} The resulting string of Unicode code points. - */ - function decode(input) { - // Don't use UCS-2 - var output = [], - inputLength = input.length, - out, - i = 0, - n = initialN, - bias = initialBias, - basic, - j, - index, - oldi, - w, - k, - digit, - t, - length, - /** Cached calculation results */ - baseMinusT; - - // Handle the basic code points: let `basic` be the number of input code - // points before the last delimiter, or `0` if there is none, then copy - // the first basic code points to the output. - - basic = input.lastIndexOf(delimiter); - if (basic < 0) { - basic = 0; - } - - for (j = 0; j < basic; ++j) { - // if it's not a basic code point - if (input.charCodeAt(j) >= 0x80) { - error('not-basic'); - } - output.push(input.charCodeAt(j)); - } - - // Main decoding loop: start just after the last delimiter if any basic code - // points were copied; start at the beginning otherwise. - - for (index = basic > 0 ? basic + 1 : 0; index < inputLength; /* no final expression */) { - - // `index` is the index of the next character to be consumed. - // Decode a generalized variable-length integer into `delta`, - // which gets added to `i`. The overflow checking is easier - // if we increase `i` as we go, then subtract off its starting - // value at the end to obtain `delta`. - for (oldi = i, w = 1, k = base; /* no condition */; k += base) { - - if (index >= inputLength) { - error('invalid-input'); - } - - digit = basicToDigit(input.charCodeAt(index++)); - - if (digit >= base || digit > floor((maxInt - i) / w)) { - error('overflow'); - } - - i += digit * w; - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - - if (digit < t) { - break; - } - - baseMinusT = base - t; - if (w > floor(maxInt / baseMinusT)) { - error('overflow'); - } - - w *= baseMinusT; - - } - - out = output.length + 1; - bias = adapt(i - oldi, out, oldi == 0); - - // `i` was supposed to wrap around from `out` to `0`, - // incrementing `n` each time, so we'll fix that now: - if (floor(i / out) > maxInt - n) { - error('overflow'); - } - - n += floor(i / out); - i %= out; - - // Insert `n` at position `i` of the output - output.splice(i++, 0, n); - - } - - return ucs2encode(output); - } - - /** - * Converts a string of Unicode code points to a Punycode string of ASCII - * code points. - * @memberOf punycode - * @param {String} input The string of Unicode code points. - * @returns {String} The resulting Punycode string of ASCII code points. - */ - function encode(input) { - var n, - delta, - handledCPCount, - basicLength, - bias, - j, - m, - q, - k, - t, - currentValue, - output = [], - /** `inputLength` will hold the number of code points in `input`. */ - inputLength, - /** Cached calculation results */ - handledCPCountPlusOne, - baseMinusT, - qMinusT; - - // Convert the input in UCS-2 to Unicode - input = ucs2decode(input); - - // Cache the length - inputLength = input.length; - - // Initialize the state - n = initialN; - delta = 0; - bias = initialBias; - - // Handle the basic code points - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue < 0x80) { - output.push(stringFromCharCode(currentValue)); - } - } - - handledCPCount = basicLength = output.length; - - // `handledCPCount` is the number of code points that have been handled; - // `basicLength` is the number of basic code points. - - // Finish the basic string - if it is not empty - with a delimiter - if (basicLength) { - output.push(delimiter); - } - - // Main encoding loop: - while (handledCPCount < inputLength) { - - // All non-basic code points < n have been handled already. Find the next - // larger one: - for (m = maxInt, j = 0; j < inputLength; ++j) { - currentValue = input[j]; - if (currentValue >= n && currentValue < m) { - m = currentValue; - } - } - - // Increase `delta` enough to advance the decoder's state to , - // but guard against overflow - handledCPCountPlusOne = handledCPCount + 1; - if (m - n > floor((maxInt - delta) / handledCPCountPlusOne)) { - error('overflow'); - } - - delta += (m - n) * handledCPCountPlusOne; - n = m; - - for (j = 0; j < inputLength; ++j) { - currentValue = input[j]; - - if (currentValue < n && ++delta > maxInt) { - error('overflow'); - } - - if (currentValue == n) { - // Represent delta as a generalized variable-length integer - for (q = delta, k = base; /* no condition */; k += base) { - t = k <= bias ? tMin : (k >= bias + tMax ? tMax : k - bias); - if (q < t) { - break; - } - qMinusT = q - t; - baseMinusT = base - t; - output.push( - stringFromCharCode(digitToBasic(t + qMinusT % baseMinusT, 0)) - ); - q = floor(qMinusT / baseMinusT); - } - - output.push(stringFromCharCode(digitToBasic(q, 0))); - bias = adapt(delta, handledCPCountPlusOne, handledCPCount == basicLength); - delta = 0; - ++handledCPCount; - } - } - - ++delta; - ++n; - - } - return output.join(''); - } - - /** - * Converts a Punycode string representing a domain name to Unicode. Only the - * Punycoded parts of the domain name will be converted, i.e. it doesn't - * matter if you call it on a string that has already been converted to - * Unicode. - * @memberOf punycode - * @param {String} domain The Punycode domain name to convert to Unicode. - * @returns {String} The Unicode representation of the given Punycode - * string. - */ - function toUnicode(domain) { - return mapDomain(domain, function(string) { - return regexPunycode.test(string) - ? decode(string.slice(4).toLowerCase()) - : string; - }); - } - - /** - * Converts a Unicode string representing a domain name to Punycode. Only the - * non-ASCII parts of the domain name will be converted, i.e. it doesn't - * matter if you call it with a domain that's already in ASCII. - * @memberOf punycode - * @param {String} domain The domain name to convert, as a Unicode string. - * @returns {String} The Punycode representation of the given domain name. - */ - function toASCII(domain) { - return mapDomain(domain, function(string) { - return regexNonASCII.test(string) - ? 'xn--' + encode(string) - : string; - }); - } - - /*--------------------------------------------------------------------------*/ - - /** Define the public API */ - punycode = { - /** - * A string representing the current Punycode.js version number. - * @memberOf punycode - * @type String - */ - 'version': '1.0.0', - /** - * An object of methods to convert from JavaScript's internal character - * representation (UCS-2) to decimal Unicode code points, and back. - * @see - * @memberOf punycode - * @type Object - */ - 'ucs2': { - 'decode': ucs2decode, - 'encode': ucs2encode - }, - 'decode': decode, - 'encode': encode, - 'toASCII': toASCII, - 'toUnicode': toUnicode - }; - - /** Expose `punycode` */ - if (freeExports) { - if (freeModule && freeModule.exports == freeExports) { - // in Node.js or Ringo 0.8+ - freeModule.exports = punycode; - } else { - // in Narwhal or Ringo 0.7- - for (key in punycode) { - punycode.hasOwnProperty(key) && (freeExports[key] = punycode[key]); - } - } - } else if (freeDefine) { - // via curl.js or RequireJS - define('punycode', punycode); - } else { - // in a browser or Rhino - root.punycode = punycode; - } - -}(this)); \ No newline at end of file From 976ff0fcdadeef676837db19ce6fe6d79fa825be Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Fri, 19 Sep 2014 20:08:36 +0200 Subject: [PATCH 205/785] Redesign profile page and port to Bootstrap --- Changelog.md | 1 + ...-s729fe6854c.png => icons-s71323e8d98.png} | Bin 50791 -> 50590 bytes app/assets/images/icons/circle.png | Bin 255 -> 0 bytes .../app/helpers/handlebars-helpers.js | 27 ++- app/assets/javascripts/app/pages/profile.js | 10 +- app/assets/javascripts/app/router.js | 5 +- .../app/views/conversations_form_view.js | 27 +++ .../app/views/conversations_view.js | 17 +- .../app/views/profile_header_view.js | 32 ++- .../app/views/profile_sidebar_view.js | 35 +-- app/assets/javascripts/inbox.js | 1 - app/assets/stylesheets/application.css.sass | 1 - app/assets/stylesheets/comments.css.scss | 1 + app/assets/stylesheets/contacts.css.scss | 3 +- app/assets/stylesheets/conversations.css.scss | 29 +-- app/assets/stylesheets/new-templates.css.scss | 1 + .../stylesheets/new_styles/_interactions.scss | 2 +- app/assets/stylesheets/new_styles/_navs.scss | 5 +- app/assets/stylesheets/profile.css.scss | 223 +++++++++--------- .../stylesheets/single-post-view.css.scss | 2 +- .../stylesheets/stream_element.css.scss | 3 +- app/assets/stylesheets/tag.css.scss | 2 + .../templates/profile_header_tpl.jst.hbs | 119 +++++++--- .../templates/profile_sidebar_tpl.jst.hbs | 67 +----- app/controllers/conversations_controller.rb | 2 +- app/controllers/people_controller.rb | 42 ++-- app/controllers/photos_controller.rb | 25 +- app/helpers/aspect_global_helper.rb | 17 +- app/helpers/contacts_helper.rb | 6 +- app/helpers/people_helper.rb | 26 -- app/models/contact.rb | 11 + .../_aspect_membership_dropdown.html.haml | 2 +- app/views/contacts/_header.html.haml | 7 +- app/views/contacts/index.html.haml | 7 + app/views/conversations/new.html.haml | 11 + .../{new.haml => new.mobile.haml} | 5 +- app/views/notifications/index.html.haml | 5 +- .../people/_aspect_membership_dropdown.haml | 2 +- app/views/people/_profile_sidebar.html.haml | 90 ------- app/views/people/_sub_header.html.haml | 34 --- app/views/people/contacts.haml | 48 ++-- app/views/people/show.html.haml | 48 ++-- app/views/status_messages/new.html.haml | 22 +- config/locales/javascript/javascript.en.yml | 1 + features/desktop/connects_users.feature | 14 +- features/desktop/contacts.feature | 11 +- .../mentions_from_profile_page.feature | 12 +- features/desktop/profile_photos.feature | 22 +- features/step_definitions/aspects_steps.rb | 10 +- features/step_definitions/custom_web_steps.rb | 8 +- features/step_definitions/posts_steps.rb | 2 +- features/support/paths.rb | 4 +- .../conversations_controller_spec.rb | 14 +- spec/helpers/people_helper_spec.rb | 22 -- .../app/views/profile_header_view_spec.js | 7 + .../app/views/profile_sidebar_view_spec.js | 7 +- .../app/views/publisher_view_spec.js | 12 +- 57 files changed, 538 insertions(+), 631 deletions(-) rename app/assets/images/{icons-s729fe6854c.png => icons-s71323e8d98.png} (56%) delete mode 100644 app/assets/images/icons/circle.png create mode 100644 app/assets/javascripts/app/views/conversations_form_view.js create mode 100644 app/views/conversations/new.html.haml rename app/views/conversations/{new.haml => new.mobile.haml} (93%) delete mode 100644 app/views/people/_profile_sidebar.html.haml delete mode 100644 app/views/people/_sub_header.html.haml diff --git a/Changelog.md b/Changelog.md index 9a2b9a8bc..c5311e21c 100644 --- a/Changelog.md +++ b/Changelog.md @@ -42,6 +42,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Display new conversation form on conversations/index [#5178](https://github.com/diaspora/diaspora/pull/5178) * Port profile page to Backbone [#5180](https://github.com/diaspora/diaspora/pull/5180) * Pull punycode.js from rails-assets.org [#5263](https://github.com/diaspora/diaspora/pull/5263) +* Redesign profile page and port to Bootstrap [#4657](https://github.com/diaspora/diaspora/pull/4657) ## Bug fixes diff --git a/app/assets/images/icons-s729fe6854c.png b/app/assets/images/icons-s71323e8d98.png similarity index 56% rename from app/assets/images/icons-s729fe6854c.png rename to app/assets/images/icons-s71323e8d98.png index 5e134f8093273d5cc08e084b74508eff123bc303..026503b9a05591e4716e27fcc3e4fbb7f385f46e 100644 GIT binary patch delta 21538 zcmYhi1z1#F)HX~EtvC!I3J3!XT~Y#)14Ea9g0zy-AzeoXDNz`PZl#fuq1!;|E@>o` zMq2tiJn#R#|94$n!`XS(-e>K#*S_zy|GXv4iYCO+QF47h`CI7)nJS`}e-^p-MK1cL4iY&!vj3Qd;%hM}n*25j zNfgKNET5c959UwJ&4R#ep3nRE+)lQk9T{Q-ty(K>-^BMX|MYj9H~olZuDG)8zYlS5MNB1< zbE@ENxrAM&ADHc*DwprA^u#Mc+b6M%J0BCg8$KFVxNQBbTq?2*`t>zzl$8`%3{;~R zb6D<*MhUk5TNIk*gCL1MFe~d&AF+_;mkV9gMk`Q%gjDB%!uWql9qTw-ERFi(g?4QnC4~aG2 zc=1+0wWxRdz#b+I3Ku1-_9mXiofaq({N^AYy=z3eNUG+UqN@><+&H9cNleDayn<61#=p3ctg5oI9#s}r z+pRYk|HYk+q7!vP^4&n=#nCi({Ej;#|FT%g3&W4kzlA4xmnjHRt_~1DqMnMft#*}* z|2_D{aV9irTBZKJXkt6rHexAW!h_F(lJSK?mCF0^=YhA;C|ZB?bWQk>fQK{)kLl@OdpXGHW_9-vipD%l3-1HqiJRv#ej+7S}>5L(K?bpLS-A=xJ zKtIJkTw>9|yB^CKKjceo@4>sikG{MCe&h}tTAAXSvwWo%^SExEaZ>K()J=M1hQ;W{ zUn<&scK>2S+++;9Vjr;iJt`aksag%qM%>W+(G!tFKcuVfwt@6CX7mz2-F@|m# z*#G9D%ySbTklw#hLyD?^8^5G^Qpc0QXgY*0qD560(AL6LDBbel{@IFxE372)caU!u zCmojYI>>W;IyLlTK4vagII8~nwKDY1r@ROPeP9~v) z`Pxl|rv_hiz^KL%s(p4x12i>^ssu4qdG*Wkut5abbzEYG zZ#j+wOh-}VthRSQBvfDc##ARgtQA&n+Oi0gjHVei1^sJHMqp6l08z}BvNOM?%w{?A+W_fgT{VAusz z7i7D3i65|%)z=bN>Ift7AxM}!h5(It1y>~?)sw(Lpb#}YBL>M5l9%9 z0rLNrLDZn_a5AhsH~Ih942@7l!&T9UM``heUaY`q(Q`AOS+DCnSd5O`#b_iv!-y1( z_%&Du0WJXQKI+4to-4lm6-Jl#azJK6eCgsf8FkE5#WV`qF92~*M%ZPz zhgX~-de|nBs80$+L&tr8{wNi_g6j&Z#WKnCI@is5_mWk>Jhx{~QhHFETK_I@>(R{x1No$}VXuTy&uuEo%!vcnf>tkj2q`VoQlnR>GV~iol z3_-PA<#*D4ajW0yETjw4!{DTgFVw2<4^TKyRSSVddp0q6X}WpO>d?{t@=z5uoXc#Z z^u5BG@KK(Qa}(R%lsLOCJY^*J3?gWjA2;#_NJ_R#4!CRrNq4$FQV2 ziL_kuG36Fd7g<)Ju~IwkKvwm>{}SdGCn;9KCg=ef%wa@A+jX%oe0V_9dV=hD zrdH_^c6)<@PM|suQwRz-#Hprxn)rV7LOk*Q2&&7gr1`P7Bpm#;FK`9`lJilGQg_Mu|GgExAA`%|f2=)<=I3Ya1V9k-_OzcOS+ zx1{dvXg6oA8V@?YK$hcP)bWT*qMMBVtAuLOK9YXg`cP@f*NFYmsAJ!U?3eLun6T^V z)1AKnhCy53gz`V!@Kw6lZ6^)C-sbL9n-2=aU5-sqn^dX0CxSS zT{OX~chW`A5+)sQ#um9B?SD@;Cx>P^&Vr*!8QPI+Sbm^aIma?VZEhoJuFEX%NdLo* zCDIZ1W)5$3Fvr}6EJy&s2+9V1b87kq@V{;}L3cI4k8C1)dqqxj_+_c> zT1cqgsAC;ZebEGq0509-Hd_9Lu4@l|9G|MUK@u&)pJ~Qo;5*-mIQ@w@)8Wp(FXOIC zaxc{yTKcg4zJ8sH*~<~? z3$!3$mpCH}t+TIz*%4=CcozzOppC3Xr0>P(NoKl zvU%sX;auf9FB>cZ?jKzK0KxREfJUR4Qk>SRcF0Qz_g5FXS#Gy-c-WfvP$t0yDR$t$ zjBL2y>U9Q$Y+`G8z_Sn!>9OjKFQE**2f5R=lx3V9P+r*)fuEpGyt_)q_59}5&OX%$ z|Hr45Icry+FB)jC@Ytum?{$*dJ8Pa)mZdc=KJ!^?HLkJGgOOb53gtIY)9b3KYH=PdAU%5(Wd{#2Z%Ug`q-i(aslKwLLcGeVpE~4uRu>Iy(@2sf(D{RLAb`N&p| z6j3=9BKyA#S)@XfS&(aE7r7t#eby{(2)K(96pv$$7v-W@*FJ;Y~#QAqRo?NGV?6_%#Eh8uZspn ze}Yl)xt`i3B5u{|jCw7MRil|?i_v=4H)A<#eq`~@62Gc)a2xs_J;pvdM z$F%=6Un-80EdsmC!E@SIzZt06I#%72R^%qUQnwD%q6O>WIyr;A3!OKFgU0!4K43|Q zG-S;Yy5{4_-5$-Occo#Z+qBkGy{U~we844h;>s3lw}2WOpw3~>i}n1dS2oq6|7YN8 z7gy_SujG~uH(#Uo<11+*b&u~9Qp)qyefU%gl_G$11|prB0HO@_YM2Q`qsFq$8yNqb%J6kP9J>o9 zh2LFWpyQIqy=7OXoN|E)nNS8hJwJIIb^CdY31aAprIZ%23k_FR_+;gsFb?N$ z$1EF|yK*>phnhjE+9O{*eh#?0n3uV{tAjVg+4-}gm1jQBegtV!>(U}4Bh#V>ZVRse z0-Q`|s8_lZ1Kzuj6znvgZ8ybU>}Oxis8ofNKu*+`@3_qeF_)XwZ3ACROG}?-?sASZ zO$ivWbMW)?s~yc=wCn4L(W?2gkku-Q&Rb92*U*QR^49z1PdnZBI$%JgxXpVNy~lk@$w zC~grnMvnYUi%!tdbmA0lUuCPgo0`g5YF738aAM9kx0jnU6F4}vFU+*PIQ~v2m{_{& z^815g;z5ey-Mhcf_XmL0*~1Oa;lPDAtTM0qx0$FJ7))x^6X`*JIk`~3PzJov$Cr)8&AW4zofz;6;~bDTX>y_UfqeS64%ArLti zu+!q)mnMESe_35kGG16vTfdC!nS)7AS=-tgU@x-f4S)(JKi8|vWM{CQ-db>Kqt|+~ zr2FPint^)vY9N^7IS0B#!Owk;}(r)_+uO`xVYWshR#@>*E=d@3Wu3`Atr(t*swR2mbqX^{QS%Usgz{C3v=R zY1?-pL616#oyj_v{s88@cLnl%qzqK*M)FoCa zTz8O$iYxNm18Y5${hRB_Y0u8{deyIwvPgU3L950}C_@e4);Ie%oiq@2W=NDM5>Y1p z{wT7@7zHqMiz+Q!L(8*JxA~zEB-{sC?|$dG7-{_TWa@a=WXbsLcxs^j35F((C1>H7 z>N&c%;4Uk9FmoJ2_3UU%|94+{GS5brs7i7C$F^H(EPD4(_TIgR)PdcmQVH#0YKZp5vs@#{UTiI}|v9iL8%3K^`@Y3Dj$T7LUl?v{=S%9~hM z%{CelWOL}8R?xm$0&HoEphDoa2rCpU6v56x66PmL219hgj50N~^qj<0bnO4Iiz?BO zTWa7?2z!>2i>)HmOWL#+*f+5v$sALR{4arM7S=bHdNr>mN=)y)s0|e9=>K5_{f0!p zjuf7uw6aUeBRD^PvraxK#qrSPld z-s`NEaF&HvaLM5~UIVa;wdm`P{G$G_;UT}~Cciw}=f#Ie-k!%p1>Xak;U@0mQ9&V~ zAqVy-2%-2$k5~ASui($$?EVhFe&}G;t4RLnRO*cm&#>-l-Z#pbz}aW%@cYV+eM37IL_1%Hk}aS>x#A5`(^ptsD#q zge=s%p<20Ezc9wTsYnM3`RdiAr?204v^D+Cnpy)#j)jxH-taDaTB)!B6QE!tT}Cb7 zK6y5jE-za*nvoLx`dMuszcYM4IgAQX0T`84SBqL?%M5q+_8xe}ef0v;$xX6XZJrnF z1kMV8%~k()Jzsmm#BW|R{mb^?79rSdIr7e_q5eu_yOVC3o6*k|v})V*utrv7TtHoP z&sPDOW$?6FRm~OF{Ke)u9ogRgfZQ3m8`t1>3IPf!BWNFEr>-wSa#+pu6L3Nh?r6B4 z=WrR%;wkEK;h!=E@X|=4n`o#6TvxAiINgk%G7p0ucyd_oBe11u8IL)^E&DZ_U&J@* z;cB8}th0E=`L7$z{EZ}}q)eL3RAD#Ks&t=uHt*l)wEEWZea%E~h<6u3jtiG<>AJy1s!&FSmNkB_ z}V9fO;3`TR{8_} zy;3S5g#iL?IP=ctbQeDQ1APz^c4>pp6Fa;ixs&8=B(cxyl zeakL-tZYvVX<1zn)t0t z@GXlYTr~t2-g@@+reGA364K>5)KePr3V{E@DZBU4*Mq8TZbUr9tLpyF_hu^vKl(2N zdX+j)BD>sb6NV~-v&V_y<>*0`n+edbL#QgirS@J4H#ZG;#6v?|t0Ugf9D0gc-@L~4 z9E-rI%Q1&;X}gD!!%2{Dj45%%5{;^YTcx^#lAidi2GHy2t@&??f%lKl7%}jy_$pNz z{OzRgy@G&Kj@OwEx4tP4R+OJ3VsT8kahkw^N`+g$!{!E_?1?H=gLSz4e534W$k2@J z^DUOR7B1K_xD59me|+3^{Km4;@VidtL$4RFUz8vZgiO@Vl5DYk>Ea@-A5#Xq?x#o! zt4DhV&D0`+P~uaH0~_ie#0J{kK#cl;a{WK z@I?;o{v!-s$7TXF1PvLy`{=-{`;_TcAD8KEO2Kfz_GY<3!z0Xl*_uM*8i&@Nugz(_ zf?;#_D!^3SfF_wPm+JfJC!@(>hlrBL#d@BimZqi)(aPNk|D^!SP68PXb$Q ztGyQf%D(i9Kf6mxMhbh=z5C@OUGFWER@`akevbXqV(uI~^lM!34*AQgUIDDyc2y?_ z*bB6iBPji*SYh^0VqMTQ+W_$$zs>9$FSiW3IF3{Ic4?`Ipa@NT!O3Nfk)2ICejFKG z^^SL*D5jG#sP9QD$-CK#c=H{rP^{!dptaXXyF8 ze5W^tkReEXYNk_AijL`SxxxeY2GAcE8Scr-uJ9Z2slbcr=cv--6#6$*h7SC+?zgco zcD0{*17l@i^EY=I5~ulGrs=Qkg!cz>0>w2m*2wX@v3)JrQr%7`)*3SLJDD7$9yDeT z;-+4IiPeUoqTPWl0~VE`&kHIMWP3-rjt2E7H|{6Q;iF&ZUTUqQjPp~f$U>QOA7i41 z?ZOu$zQpSCL|!i9!QaB$HcemXrX=6Mirp|P<)XI!UQSf4EX1a;+CufMzKn|oVY8!d zoO?&|qWwX5T$?UmXUMkz`o?i&k%xW zJR?FR+*S46uM#oP7-H=XaJC5C(&qx!dvA*e0%&X#w#AF7%i1`PmHFz(_E2ZH*!Ggk zV{ZYEAXfdNj;lfM&@sJZAs;Hvr9X@BhLV0wRi*2Zq

    N*tVjP&3I!AB-B2LUl3=V z8H7}Y%f1B)EbnvCAQ@Gjlib0ILE9^h6u)z=zGO%ftNuO2Nsf=~q(`o@LDIy0U*APC zCW{^9XN5JKpMqcTHYh0AEFym+L9OCk^i|gpwB64r_tUrG=yfIvcw{b)SihPz(yF0& z5~E;qvsfh1D72@Jbdif(iciM3h!m{BwfPC~bU9^-3|-+m-={wn){%#T8$%59N5wA` zp_BuI_(9T~_%YOo`!vn(SO31XYisHf)pY2730q)9lAqyGg`R${MBgvE1x4JrK|})K zE-3x-UKZp|ZmffD1AaJ~5WOt_oa8W0>~kEN=KFiuaC9ge5%=c*KA2VkV7m@-y`M&e zUGxj8NKr@Wq07t2RIx{#spDT|VGLT+Z<;OzsPpD01(in$QT_xTV-&2QEnO?cU$}$x z-K2pcB1*sDDavE+-{-q`ygG(Ue;udQenEt$5LB0>dkI)I{5?0vpPNPQ#81)Smr23VH;SiYnTQ zG`H6tjs`6>xC&?F-Qn(KBYM=0er-$b0=v!sFyG;M)=mT|6#}E>`8C|2Mqn}gIn}d) z8=;KaRESl&4ZqfXPn;Ty2#JTpW6Yq_f2tmr5{qsI?(0`8B#^?eTJ^425}^aVa`Unr zxKA7$|DaW^WQtCNj~zvxS@*Bn!PyrdGfkxH>F|EBlf$@Ic|?N!p0Hj^;4Fbo4>=_* zLL%K$ecQ}>|9LT^((YHSS0J@C)Rv`FeT8YL1a}riS2VcZZ4DuiE}8Ve_=iJ2YAH?x zqyUV#1v@g;&v7Fd0wE&|WyVMD$v^v>>)nvIp|k;-&K{13n>kh&bJyivWW;g==w+7l z`w2`?MC>F=1YDe;^VrE@DBds+0SiH6MG(q-C=+q+f4!&aR)Xd-P9U=58?ytRFsZyd zsil#@{|*)Vu3R%?iX70TY9mNOLnL7*TfGHeTDz@AuXj7Z z-!DDOOHb2ajQo*+HTw1ZM7eWjX6BaE3A;&(FBQA2?3^{@!-PA$8fJ#LWbdYdQ_fKY~HYk_UFvBhAk~sj9BUG z>76n^^eoEnMs#GChqZXN4BKmixLjeDze7F_gkChH+&%-x4WL6&U_VmODq!H@fs?FL zqR=;}Ev5m{8nM*W)E`(ry<)w59uHq>EwY%~))VDsj`@x?`Udey&}lenZ3gEIPT zEE*39;{&+a@xJnk&_vH7a8s!gn2 zf{@ceYL)G5lhxUgFm9V#NhCa+X0PCRC~>;~!KUBUf(p|Kh66G|3d5jo6VChY_X!pT zA5E5R=<7|X*Y)HcqZ}s6TXvSgkAn-CD6cRL*s9?cWd_kxyt?_oeZDS^m)14sp|@m# zRp;^2)P~E`jql7lQvpjIBOVJbNP@5?z9SOZdADyjtM9-`@y^**eWK!E_AqC5?_oYX zfGo#j6mtimtCN%8E}BOCSx_~+oga3}^v4weV=qto_xd+JM5rJUMYseAf5Nt05F+sZ zQs6XlYBD7WR##_^5#{fjh+ODUsXV~Yck`sWy2Q8?zM*Mzf_ej}k}J8ngN7apSG*<) zCJ&W+$zG0gjKv*2xc9-gtz8i2_(IsN3jU_Gq#+_x$n&ZSCa8Xp?E993u#O@}vyR>G z@uE%CtT$DK5qqfZb>6DY{5<=1r6ac6oB!(#&){G=IhS$BO|p)B#7El}Q37zfD{*8BW;v_*8a$r2Jhemkh6~&|4o7Dz&pO zk7vjC2V^1;q-aL*dH)TeX$vNyugOp57-i@|_ej#?X9WcU2?d#MNJwCJ$aOW4M1CXz zvh7F=A;>zH3WMGC6ILgb~v#CL|s3>nIqCsSKot!UQ-I%w8J3i zV$9HB|94*;2xdHu`P>D3QKCyMLfq?@o5ukU;HuU=&wZ-YA7i<*g9_x5Eg)!AD`P&3 z+Fv(6c}!$-ZXUauw)XGj5cm+gikkY~&-ci41t{WlnTt#f6gjQKlM3O#!lkYDn6ex& zXHgyP(PhNKNx&$Zn4AQNB(y!wgC-2o83K<<%DsPGP_Gb!Rz)+CF7in3v8fF{ghvJ} zcSeBJ`*s4GAQlf@Z%lbTd@$?bbQ9^<$q0BS6}e#vI5QYRZ~`R%_u;b`8cqTy^}zez zf53GTd*Pr|NaAI=?r0n?*4DH|ECi;2`UC&TwDy+$5NmATS*FO zn8B7`MQ&Nr9?2|r;>Wc9djLDd(>AM>u;lY`Jp#TygYGM);VUczy*VBAT;v za;7uQHl^=R*Bz@NlgUl_BS~*UGgtyevi@%1caUR~iZk_hOZ1{7n>Pz4nlCeGOVN?Ex z>rT&A0Z##7h|8JR|6LIno&UQcAmp4RAf5sSd!XwRM@L6l!O#^@?^ey+B~!1Jp3|lN z(qASH0H5WDnika5)R;gGBh|-j{QOwacG~SQ*DMLPhxAZMoCwyh=D-s3zMcFrIT|2_ zL^(-rx)?;M3$IiS9Q@gfmdA7^=ZYf8m;`Q-!gf6psu5jXUFX73MB_3S*e!!-qy;G& zmCeY`(gljVpCW)pRWN?%j_Uq0#;XAaze&DPge`-C6J5I3UlA>#7n6gzUL->vG|JZn zhMl@lHBiq@*;RrOWX2>A_gKagFyy2?(_DN{jM#;~*=-yPR35U7TR5j2PB-CE36K7|np}7!uadE4Ubwa^)4tHmv ze!;(_5W22}@c+`0-W3EJ8p#6uw4e~I1{lyJc#rK=i4DV>V(nVqMP|n2Mxa`Du z1RkixF5fiB*}4*yS_0B53PC=cWQbo?*Q+7{#N^VqXB$%~|72Gnk6x|P<=vkx0Rgp< z+yI}K!DmOZ+^c#aB}7#CXpz^hKd6Ic7M>#a;w#d)NJhC{gD6aX{9Kwcp#BI0#>8aQ z*i6^or%l+R2Kp{w`$Z#C?2&6$lB)(h7=kna1K~H}`Q_2l)a32I8?;H2p z+1ma%Klzg#g=>~!V*_&Y83V|$uN)z9)N}h6v2wDFpeIpGqAsVsDR?m<2eP znr2Mmg3jjaoTtZS&4jzhou~U#uP%-im!*875uSCQPtcpQO?Ali@SEcK`T5^p{3yyu zsNTq-5ZtWu-kS0-uMjWzW@Pv7+`9{_Bknvmvj@h2Wc8�A}m!+?W2Wlx*0myEVgk zfwQvjzrICK6K4BtPdy2mO198`==smhIY`NP>Bl>h$Hk_8+qGNM16|$SdyJsp_7x1* zG=YR+(DRhwB6R z+A#Rp(GI{aBvhF@P8Z^g)$Ij6*$75y-}}D@S^|2EuumRSa`$WHt0#(nyODS8CX33R zEVG-`I;q9Sw^_bV2ScJxoQma?ITHBOF~NVI$pKWqBc*rU-AU3j+wrZyxg04n%oB^IpH-!jtT3&;h8pnyZ2F}w0jJq>0xup?A3UDX=!>^%+e>ku}=}0KHR(8#@Y6P+85J zc=OFZf(-5KzmEP)3(9*BJyTWP8)()h$4iZbl1;rQ2?2`R0*nRvgx~)$x4ipstw^O$ z8}=+JcXwUa8K07f2&XyyY(5zoF|J!TguT8@bmrUGk9b#;1@eB|Wkm$4GT7$l7pFSY-kU!)gge40*k3ZL>d3LGSXwUr zQZzEs0fyf$kR#{(H_8%3(!`l-tnJb4SAGTyA!GQLqs@>(DD z+o_6`Gw;{%1?k|Z9QNq$V|rTU<$7Jq7RHG>lRB3hUL?n) zpm9!+_1J6UFClF7-g+qgX}?FX&B<-|JDuavom>`=gXAUIxFtbw2}ogI?Gv4>=Eh<{ zGRZulRA^zZN03<-oJ(R{c{T$Oc_RRfVvj}`6{y~*-^BHV1AASZ{#AdSPv$nwTl|M+ z3BZ7mS)MY^GiZ!KjZZb^e3#xy#4YO>2@JlQumFO( zMFym+P>p*0mR5jOGK6e#S`NG=;BhLGc54RS$+{+-n0QzXk~wAMn=giPlsKgV7^zr3 zS>UuwM|q-O$hs-g@rwQZwcWIH^ltD13@|ub)%y0?`(&ohaiZLc;EcVBaq#`g=Up^J z`}7$?zxf_cO)i#XxV3GIUvG{f1V|_Y=~+7qMQP!YTE@mx)@PJW zx41j+`Vf)AKqvrTW4q;ej%JB@FKcgDLvZLj0YtYzGt;3viPz3jIx9Rx#j)vd)4n;$ zMwpUGbXKtGtpVXNxrc%tRx%^ir~_B(xMC$W%ds)vy(lwTm&!pnK`!jPZJNktwD;pB z%*-Ypm}Be0Y7QIm*|VQ9C0OYR%3K8+Q_gUzI@#LZ)p6P^V{H$^iYeczICkz?(nVgf zxW}q`lrV~DQugJoefC1PxBoDpqVkOFa#bdZike)GoBGz>AFR}F&w2K+Td1P@vJ8x+ zP{*u^*sZV3Ks36caaN8=LL`>_S2y=J6(f#-js)Ji5nt&-joqyG9o}m*spEvlq^xEi zh0QDK(l|Ldw5wGkg$f!2V~)LAx)aneN|H-Ja9$c?(>s^j_3F?rCPQ^Phm;gO74n1S zpDA~Oj=sqW)pQ&eWYELNa1YgD?(vy)fa*n$TyC#mi4H$f>AS<3+BU55*N1+pgP%ISfoBNE9ews9t4@RgP<=jM>Uy*V1zP#4*f87?8Q2&)Uqno7Wx$djc%i7qT~YRT_y3N*F-< zm|zprvmfu_n$;{7Qxrv3>VYo3s@{B$ULu^d$znhnT}B2nt*gtt$9$sE(oCDgp%$uE zz2OygAu`QMDq)66LvBR(?Pe=l2*f=c~Mb{o5*}bFkWUso;R;9-3svZ-VjI)|2>t@tmX326&n5dY90S2yn)VatYr7)R$ z7f?((CH}|&R!KQO!(AwxY&)beF!HN1LDcE)ZezxRU_R5>RWq-9yHb(Ai47?%HF84f z&U)5eq9Wd1X+7qB;UJG`LkyiE6qOQmY#Qd5g$Jp?WeJG_!(523)fv?3|559&6focC z+Mysxp2V%M98v2U6C2B11AxHh6TcJuBM~@We?J^#^)_@smsJUbfUm}ze%WPujen26 z&7Y=74IX9UdUZ9He|}^R20ec}dU2Q10gstPa4|IQ>Z}khm?Oa*=Eqot1#ke~){^~H zck$dOGcCjKcdA-6o#33JNQfg5Xe#vTci+*Aou;>Dh&*_31W*N76nHiqji44Bkk!1j z)YLC)c6FHPHB-eL$5(5CAx&_-fbO@jprqu9@ly8qpZ0}JtPzvT*vG_^UlGh0$P9Pn zrG*)Fz6O=6W?q&G^d4rqyk2vV;(ecS#FNwA08?fvxT zK`UP*|767TGrLlbA~L0X9*EfWqhM}z@DP_|Rd>gY@iMXa8KzDIotbCc$$CizC?CHn z2H{idIHApc(k8FvF=>;W3I=L`w?RxW?+Jibi$d+p$JhWutmn?$#rslOqzJl%i0nS- zzg+5t79ox`Hv9Ygvy`a`&=3})Q$n*w&&iEL|H8nNm1K>(+mtc4^ImcOyMNKfd9|-F z{d_?7%DJ=EJCtNjF1vt;(+(P>KRR~Q7_-;c`K#Vf(kc3b{g-0&>IMb6>g%08au}du zL)676(`&JVxbY+R3=tiuzK^CR>T)zFit8CDLylZ0gm{0Rf%SD7&S$b;7`x@b{rbs= z!;BGT+?mGJN}cY}p3GVl+BAp(Bjj=sCu;_G5BFYWddrE(HN<^=+(CzcIu3Yw1~$9LAhnNM45uT zU2{Hdk$(l_7Tg90d>_0B3fZiHpWPZ9h4!HtyU1Y!(+ZINM+@!qm^90EPI1z?u#fJ;F4N`X;ub5Th3z7&&6GGQ^6Oi#TR7^?AROBE9Gdamcjm|Mj*UZd+$mA4Hmra zDDpBaJ0V-puVpSBSZ=?<{3a9!FDd!|{Z~@(LoT{2><4gSI4K}xwy5<@YT%0v8lsBv zMJ`fCJ&ocsxe>&4@z^9I0O2|Q{p_n}86G2VWcO}Erq~09EB3hx1ieO{Myb%H)W#{| zxtvK#xpx`Gz&=(0{@EmW8D&Q+jc>~zPy zPaCoQu%)f7tE#pD!9G&$+o&duhgaJwM-TY>+a3Tiq2?Mn(Jie#=IfQN5N8t5S{}03 zszK(IB*rL#73rqmgLE6KHgk86yk)$jFU&w$7R7#LD;j21t_%(}$Nuaf9^82f#y*=t z`TKQ*E_n@_6puJ3^=?qc<-VCcGzQ)D5uza%ed?ubuI)q21uwfNdVMe*?eFCDD47D} zUROVP2bF!v{Q+=``xceo-WXG8)gSv8@y%{}o(OQOhCi%zc#Q&@;5&B_U3g2(lvkP< zMt@D`D7u?VxX(mru3M9{rO|J%INpylGBaF_yiVM#|N1W?Z4?y6m=L7hqT$9?tEihH zU*5P*&K7=t_Fd?xa;j{&>CX)Vh#^_d>gR94-XDUiGPUR@&kh_CDb20xrRohZc)Xi8 z@PSuwQGD=R0P+{tKk_sn`IjUMAJbdZiPDi_8h9{SKuCL-rRKHNCYmwr=;75o4m+8f z0JjmL(AAO9FRn?$5qS^Qnlods!snby)$~KDiHfOgTa0C|7@7yE8K=LevCgsu5mn1_ z?&Y=^bvTqI1og^7Ap)e2b5wp>|^UewR;OBH}eEg-Qk;6@_ zvn$1!R}|l5vbsp9KG7s^^mpW4CF;=2dF7M(xZi|z6JVeRR^w()g_Wb#d9t4cws$w$ zX+$7dR@G~!r`f})G|(=t{pEkso{PV@FkH%3s%+W46)h*=?d`QB8Y8DF5^B}-)B{}@Ml;6~Wg8v@0ujd0IHaB5#0T~?BJVeM zCUIIj85^E?Q9pp(`*pyVH;t}!fw6|jP&Sdyr%_3)?ZJ{=UUPhz^&e{5RVNEve;nQv z>ni({yp(k3ikB9TkyBNtDLp?rsTSTR>T$;$Rv!K1#$OQH^DOdzChGFcawGHP+|{Wt z6*RM^c4(#)TwULT%VS!m9qmS!iR}qk+FeHONY7Z?ZcE$F2YmzxtN5#O2HxrYgUyxu635KW*vFl>GQ^4#dT6AQP!pVo>_ROM@rnfIsR6#HN#td>4#t! z%kju#a9<5JYHbb|my#-82ckG_eYQP5Xx~2GUt|W-T0zk6R4(``DA(N3Oid#sfQZ|o zH8AY7>rkIT+}@*7oYxW1G&QvZ!-djDOP_31Wdo<&QMLqz6dr1Is#zb~ z$xr<}hVD(xMvd=t&v(dPlMrO+2+3=^v$fP3p0_bS}A(_|2m1R{stqsS3f#FPGYZHlWS=gttyKW$@d<%4J9FS8!>%M2@_oRe@+r4K;;oqa_Hc;*b>SH{qbmktr z_a|jyu0>)+7?hY_{18YsmEM{5+gCP_{;+st@TX>I5?Ui58FF1^?_^o0BRi;Ha_(nJ ziVK~o=MbZ-fr0uQa^O7$ z|A3E=%eqHDfL!dy$Hg9PG|LwJ8OK{GV4T7Do7iZP>yY&i?js}RQwfdF3Hu-}g2Rbx z&R{&Nk>5)9EmX=17*_vKHBO^>!398u-?)oA8IZd=_XgQ>pIBzO;3n&LltmD(`Ujw0^yu7?-(-!~3h^3{a!|xd_p1F}w&aftKkQJYh)wX!lY2xxF z(X6x%jDf8a2PyAPuL(2p;IFUA6m6!TMeVb`I4w}62Y7yg&$Ct_O{{#UurBjI@4yu+N@8UL7#&L!LyKBt09%yw-!Kg8^hdIo3Z ztKZ-SB}w2N8gEO-(8Q_k(G2?9sE!;7j!%u zRAN}c#6B%-&jXUjXM8qN>eS0KTo9j%yE~iV1N_>b3k)PHgF89>L$jEl^JyKa%t?W-$!1e_=icIcw zAMi%Z17w<-DfKoU|F~FuB%($MD-L?p9+G{;F4TF2?FAW>!$8wI2)GIG&X&2bsl;sZ zi*=#WC}$9z)ZWXHa}25XpMNE~I6X|?`${2bU20TiOWsG~@(~%+170vc_A)g!-2t&h z>DTZDb@0Tz&JoRva2e8V`Eb?--t8X{d+`vAOkq{=F>2=UrGAEY}yEwC*)Huef&9Ll#^e#q)AKOUkzJ3a?WLcF}6I%kj zm$fHl6aRzfI2$Hf^Q0`|!`ioCuE53^d)j7eZQ_; z$u(zeIYOb4BS%Rj*K+&6_5FVTzsF;b?eTa&KHDDK=ks~LUeD`=+o6B|Ip%chq-K*> z>`0rlC*WR~sjOW##W zwNvP;gkge1SgTS~vG%&^4xhN^=#IX{yBRPYB2(_Ad?~*2nomXZV!r2BTGS=X8(xC( z&u@GF(vw|@)DL07uW5F0rLi{aE({)WJ4V{P64l|9&eq^;M>ap$&^$p88G)CXp-qRK z_|O+^Pu+EI@l^NypQfc{BIeUto?xujNq6|wo zGaph}3~R$L74$a_Sr>eL>Z5T~#+IfT>#?Hq~u^La^yOgES#gLyjO&vH~podil?_^<1atR61~ zF_Y%|U378rkPNplNyF^L-UDq|y9xIJB_v_2B1P7FH@*Hygr7Y7$RRsB4o5uG5YS>|IpMn9Aq_Q0DN*!-YhLScqP;pkpv?;+)=7Q)=hwAZ{}u6>C#dv>-N znwpfEguOZunqw!WPvv{g)z^iyqagi-^91)x+dz)zrvC8ogVV-a{RtuT^{X2 zQa%AM0Xh6vQzACXpf~Qb5C~^SLkU5=wq$*)98vUN4cc^Vl|~3224dqCl$OCL+`_Z1gkf@Tj;M-KnEHQ0%4@=oRq6;Z(CYg;NT?ts%waR zM~)_BrSQ9U+I7- z(Stg62pWWS(-KS8@qUqP^^x1Ufb^404m& zO89u=mxztxM`Qbz%|9OOpg)6WZ9V&XF-x9COiyX3K<0X4*J45N%~WfzxzyY4^ktyZ!UL5Va!8NK zI$B198S)**T1+x@Mhz%gmcVAET1ZqXurm5GslhU?l>m!%Ru}hbof#ySl9^&P9rSUt zytmzrqi91NCBZ=If&Yh|hS89Cx|W&NJ;l*aY5u6t zO*9Iy=wZ>{rtWK5f^OC7vESRw1sImTbaUeT+=NGd!s24!Ts|1%0E91htRXW*KA#~E zT44V6SG{bKNUq3tDVLw$`&E>c>)+=QR@`-oP`^AcxSOF-jgo=O! zC7Tmh_|Vj#&-&UZ>zQ@39>l#q-Y%(|_iB~AsYGz@D$-moZtx$ocQkC1(|cd+GdNKB zbA5&F-L-iT{h|fg(}kCpHS-0 z227^h!OIfm7Yw7lEkWY7l@z*V31e68DF-D8Auvgp;1tr5R`s9!sooCr5LB8wWi!V6 zk93{-9RA775cqTd2iAcTvOxXYA0yDh+&+b~%^i-DAHA$`cHH<|Hd6@LM?`(^s+)%C6Zva@xJ4f02!Q@eSXT2s z)pC)N>Oq0beI&fo_ut+WFd|J0jiD*ivG&(`gkf>sAR*Gh#*glBgyT+?vyOR&Ou3JF zbRUy_?JVf($ir^U&QI~F^{0)r=Kk>N#PO|I<0?&g>2|eo$0CweNhb9A!sU1zFM|?f zU0C68fJ;u4cC>ri%-wi`XYR`;VUWfFsunjPm6eq@*NfbV;4@!hSVvj-2dssyS1=tG z^{v;4zL}`wDfi@ixa1sMX6jT5{v-JP+3G@^O-l&}tY6v8Kae!9+(=CgM) zD408g*PHfIjjA~wCN;<8aHD|^(ljIfu@~WAl~(k_S;9cb<8TKL<0A#ob-oU}`_~!C zXU@k89F=)>IP{}O{*LXOG|sYTG|ufn!d3BKU9n#8Hn$*KdA-ag<3?wDIW$2fwWvU^UnOK)`-!8~;9m^j$+? z&IdpHlHk#({)$UkIfNB~RuNGo=5%v+u1LOP$;9>i9_ou)Gu5E(e7m{ZO(O+>&n!Wm z9tC!XnHH$UQYwXMtC?n*aPF6p9(b}mZL4psO^})**OZR>xkShV7tu3fe|h~ahk{|V zLJ`mayS64CTMgpIaI5p|ST~zBN^k4|I=E3ZiD?u0;DItZN8z~Vb58BMFfdjCb1rb= zefH1s+E9_ldv$zkZW?&?HpJ)J(+Zrs{$@i7*aXr-el=R;l?`G_GZ}~`QJGm;DTx6? zh84*b0bQ%4pWoR$qR$I?<53;0)-8FH&KktZKnqZI^DncVU#p_c9P-~tDk^@=HIne9 zL>u@FR3@XjV+R;J$Go_}l6nOb{r%#!XLI?Dufwl>ltfT?(cb=;*Bi6CEBYb&(0?kC zpt!SLx4YfI*@%?G_7kyv?&g4S3Nm+2Y;ZuDEiLA;BXjc`kela(W6oG_+~C{O8Z-PA z*gvZpx{xxwL7S)h0r3^f3N&_3YRGKd7>J^hm)e>ePpysnj-))>S+mQe{K=$Vv$GF_ zcct91H?vbtwrBSSBz|KzP-#`L4``j={7}pHN{;LsD6Me3t$D$QA%?sP;`AA)MuVl2 zl^ZW{6#Wd#*hMYE0Yhd+g<~s5A^K0vj-<~Z;JZ7{`9P~MXjiYmI~X!skGMQy?5QcE z2cCE$OMPXQDY(bkPHN8g198cx-<)N9UJR{TN-QZaW7Z* zORMXI$RoVua9`yi%`IN#^Y7?J4V+E?-=_1e{Lvq9J5a1n3yk= zgic9QLD1-j-V39CZmYAE3UL&^@?6Z&dUIt+$3)NA3PzS}xRa&=EBmh5lU52R2szrJ&;CWq0uL9DBIxUtaoMh^Mb z!cnz=r6Qya>OXn4e{qo9#~V0)1fSG)RPL1>a~*5cvhB?Q{V5tOPuis{d7og6tV3iQ z-vD-R{*dpqAOaL6w=MqJf`lBNi=-ifbVr0MY5#Ob79KDcT;_ZV&C^Y{CnWG0Xy9SjA&0ZT(2IW>x(fIbwun(?MSLWt9|| zVIq;Z12O8ZtH6Bihm>g!R*ZH5pj34B(&xao^}y(cC8X4~O*a@tr2l7YdzSEsIh8nkZIt&x3YlLW0 zrTTPi1at<%e3#NCX7Xxs>6S6>`#NmW3#+#M2;s~iL8;h<6Xq~;(&RARZSn#NF*L1q z$Dw630r#WVr0jcz$?zE-U)~BXI{OI2Lvv3S>N#|)wp)Tf(>z8=eDpsB_#YXVBaJ!K zr8egx@aru6D?7jr(_y$wl;Z$gn0r<6C%_x-g0S+-Fc(Bf`sWP+f2yOGboMR+m;?$l MGqJ|y8U0TGKlQJhSO5S3 delta 21608 zcmeFZXH*p3(=SRGvLXxuk_Q-a5&=mPMg|zNfPmyjGJ@nF$%a8B!;mv5SxJ&}P?0Dg zIS0uZL2^9J^MBuWopnFl4`-ck_pT*9-8)q8y}PP*)vs!s8IHRafs3Igl_bQ+!oqr@ zA2W=F)xlrRrs4>ww&fI7;Gav-VPNm%JqQ;HVZ?P<6-0N!=vczCqjJ!V*M$r3b3VW} z*TuNQNWK*kqKWxK&|xGnoYG>PFkYeyc6>tSfZVOt+D6*6e2R*K#?5rc-RJH)?#n)( z;w~IUi}Zf~s)Yb&D@kLM)>&#)2r^IQpj*M9M}WFcVS$*}0sRjyJT>2%pNlB}N} z;+zC8NOuVy;Q(7w=5hGU*lz zy!hg8009u`0!qXAYEpPH>-B4ylG$lNFv3L}rK*PlgkU>S^Nxsp%P6c=&D?)#(c#{* zWQs}^9y?Pw3nZ!*Nvb385mf>q;dqHVT~UY}0eiK1`a$Th<$Iox7zKr!aU0RPr7`a}Y z&7CBa;>u=dNl;CX)<|5NGb>3C@{U*JK*LI+A!ppKGdYR0x&-9tyHe#D{uUPwfFv>-%*vlP|ZDL1ym7YZ( zz}tR1-Sgcfszcf-wxJ?ZMV`%Qc7=x#15e31KOCVwLJ!MYGAB}X4tO?6(ARe$2(nH~ zN+YRH)faj4%_cG2s$+y)%PHHmh;-ADtv}?Hd7ROgk0wRXVvNl$c}ZbMr1hD9xO)e~ z&an)JA4-!TjN)_-@jtw$I^tGYcV+(l4>-1GBWv0tLSUb|mcsEayEtiAaX{|xm~N@j zq^JsW5>GgOnNo-r0%sPBVb%a6*>RvZIJDu0!)j=23Q$bP!)d;`c5W*d<0=-RGw-pzFq)sQ}eR}&)3U5T@_ zg_OuLUCLURBB@g@%sWd?V1^IZlh@cp)}b zyu89k5Gz|x1l={Bi{ZSzCCuh%X&Don;a!el2cJ_&ve(;tByg3S_@JL$U_|ltu;X5C zz6?J&?XoNY<;JD<|39Nx z`2Y)qi>piVgxLHl>WaszyLGUub^i;H)wvWR(_j&WqF&xtR7}RdOPjpq*un+XZaz9s zF1K3hh+O@x82ooS@La}z<-h0F}d2_y{_Pv9v3!7Xo@XcX+yhD=6N`_}&4<%2}A=CI}ZrslmJ(GY3Wc%_B ziW<-TrkvvM&*shU4DF6E0JwV+i=PnwD9ZNW%r8?r1}$zWUN_Ar$}3DGYZbk!;fVzp z5!g9|$bv#DfK9n-S{|Gp3o7*A*=XZ&dECwhnE^Ylk_nP}Niw>_?cn)226GH#>VqU2dF1su8MQCI*#UVot1`eL@UZ7tiQpl5N8 zL^dYOO-itOn$0~>r@i50*X*Z*I-h&bIB!3}=UM&@Zv8ypl~2zdkvQ>TFzmzj(NaC~ zMq{^vwn=pSv)j>#>0zMT9)lS;Ys6aV4%D+;PLZ&ne+y2Cpi?`Wz}1m%m$pCoz8i~d zJwObVmH(2(dNRuyk-IjH-D8ZAtyQTc@;8SJBK%{FSRs)Re9ojhi*zw`ws9(Uo+a}~ zS87VFagYxvV_qrp>bD{9G^^GQ*Iz21mFQy0e?~m~G<@7O<~?>F8qExiCrv*C6!uhH~_J3U){TArj$ zw+y6bZ<(No9A+{uX5y6E2{UO*45Q%TbkaZ zpm0TR-$YqKI*EaUp!>fAo*IWc&Nm<<1O-_XL?#otCgHQJ@?H)OrJtq>2LpcgrPcNb zQs%uWQ>8!;3!(7%TGSR^#kmz9-ncf;nZxbiUEalR)vvso=Vs?-X08l@Gqxh-qs_^w zYN%I}FteC3CLFGSdVW|)pXmNfD5Q&7seJ@f2rr6bI|e#CI--8||MXR=iHuod4-+0? zTChhT!^|xwx4)DmQhFOn0WSL^qs`C_TE)g-oP`M%se8pL7l$85u@G3`KQhP%G4%cX zp{Ts>HXZbf#OkS~eP8&Npkm1{K07Wo{8A{KnfaxagTtK6(u^TKnjGSRW-AJT-e;ULzT7z)zC^d^{%xEQ?^pUmd;V^8P<>r`KMVjS^R?% zKb=X~yp`>9y4xbroM~)RDoxDJmcNc`+0IoghK&}i5b?Z?ba}WBj*NRL*h(uKUt*O~ zBfHD(Vw<70tOT%-NK5@p75@5MTU~Ya`I$h1vdX5pEi*IoV7(#(_a4c;roW9qr_2(O z{{@8R=4?%=&#>x2g;#H);UgiTqSe*q)Ay~N9Y3TDK56Coq*dGOuNpcwAN`TJIUA4y zr>2YVA9rGP%pN^@6l*!p5G{TEh9oBUUaY?zL=)Q} z-KEE`XuMclvEf;HU#iFj_$q*}?__&2u8;uE#-@LlPUQUUPO8YxSc#$MaY!c<6U#h} zswasNbJtzbnP=9$V^&z!AwG+lY8obVHU_BR;h zPhy0+!`$Vx8l7lmwvG3_=<8I5v zrHI{_kyg3ckLJ!=8$s*+Z$VXzVy2kd`L{lHy}BjWwW6#`bMCgbB?GO0zKzRA9Zyb9 z>R7g})#?-}%!@cJ1kpWqXp(I(%|~3Fm#HzzNRJA=#3>=@r$$!1^SnIWkCxsa(Jo<= zJA9FrI>qs4%9;(ZySdI4`SeL|ld`yji_6ua>H7Tl3@)}F<;J*)&rS=Ckd@Kfljf7C zi7GGG*5cw~Zi0J^hfHMD*0E3uAvzJ8hrh>s_WW$x+{g2V?H9Na@g)3p|3q8r;|g4K z%9wPcH1>FmOM{#0>jkx3pXlaz?3~P{32*3i(?@LMc@mic4A+mjROB%$IUe*1f686g z`gfH7u4t_FXIN9O_%zk?;0SdMk}-StK9&1{`nW+nV%2~Wx?Z~~2z#h)OBqbW(z^V% z;=%j-@(R;xSv^haQ(BfZ?AZ}H`q@TgXO^4GchAG^<%JRoc^y&Hr16$A-~0 zELTDfx7u@VV4W#rGBsnvLp}voL(eoMoELSyfA(zZ0tyd>BG3&w&paZAdC+dP*{p%T zO1QIBvv=lF^F#hYESF6@BtAGOQmVRQ3%`@Y#qx~oYz5wH2J6!-y%RtG9ToHL;}h~^ z#Q9)#SV(E&HKW4N{TMF7co{;dEgEIusJcV0SsijsEv;o6*3}I&k_zQDU?oJ$UZb6s z9)5cjcausJhn+@^2f@aIV1sw}asTTVa4Ld*5|%@L-DCX*Nl_C*-oKP)QNr|RNEU#9 zqH1H>Hc>7dY5}UufJ@7S^tis_}mPdC}^M9_F0XynK$N*Rk zdPWPkIAzhnu!)~fa&FETQ=sd*~Y+2655_8ozK7xHL`)Z998ndS0Cd6RfDja|aw zbKY>IO91S5gQ@&krtu{;ki<5%vLqmgEQYNZ&3MR@%3}WDIXEt3L5MVD&j0$ue$&8R zR9D9F2wmWgVf3tLI@oCXZu*!UrdD=Y4C`QTee)URZIQ!wGACKglMT>J1W6n!-V%B; z@RuB<05-xsOTa?YhdN@hw1O3^ldm866B457{b4{*5O#<^%&QFxDT{gd;|2h0 zD=`ekxv{aax|RhzcHbP?4~0@w2XlfgE4sn2siv$PHu?d93%cG!Y#bb&#rl;Ufc;ce zx5R!sg_?`YqiihnJFdCDST+?^P@((H@)LW3gR)6dv5P-H+On$+KZhV-Mzx?e?z5k+ z=|ep(hZn(!(6V(7;|D9f)%?FJ9-?JUAp9gMNxjNSN*||#U}RB|bfV|{cU|=#Ac)VC zMti!t{v1uRMs9E0n^JQb)dHXDjzUeS63^SmcNW3!kSzK{la;|mokj)+g`0;?U^mjx zkAR3y6zV6{3Q2QaX6giEk#Vr0yB~CV3a9guf?Qo)tEYqDgRl@c z?BYez@BTQCeT~wi)*eNyg|Q%Jq}_6hF)Xv|In5(5P4*DdUEB)%<=G$E@?EqT(-=~V zyRw)^A6-^@T7crOZ+IaAWWsh%(YOfz;sBWJm@FC04hxMD!9sM=`ok>lhPWUa+%}*w z9E0iNuDlia7(_PAZhbiIr#~7tLd(3KgLl51PbyE2u(5$K+d+PLb+|#LU|jKV{PIM?%vlc#5y3$&0T@n`R9Zm9`w`7 zXUI{*%+9!kR&wG?V+{%=*K#>_H z9Mlb5H?N63=Ieu}J$`NGtHbp%?&U*Qi+HMy^Sakd9YEv}^?EORL^Zcp`n5NqA_??R zuRo_uVXVl2n|SXVCym?N^4LrTq8%8~L)!}fp|B3NR_OylQ#I>& z=}qqR0klRXE+1hCzgHT!BA*oGC6Z!F+$?F5qYw$rN`YoS13kE+Tmh0TCEe;*qw6;9 zb#-mV&btw;s1`u#o-q~w?mvnNfoLjvHq!Pr;hgyVJuTX@3*O)ShLJAd3%!hhr5!qo&!qd>``p$isR4|cJ}Db#wQ2CQnb)z4 zMKDl>CgYe?bX!}sZ4BsJP=E^1eqcuSF*bw?^*ANrxKtpms>qWu7Do6kJLz54`7S;y z`UMN|B&Zqb=T(dkdZW%PC?El7i@0mP;1q+=K?fejS*EGX6zv7~(Se)aWk>CRJ1y!S(mNU{m zkz5<5&5I!Xc%pD;sRrblky##_NUh~%^JzMTYlU*y1?g_S$bYmSn@ZegzMl)nWicXT z0OaXl@z+8VNWeq=z?ddNoLhB*W)^v0HU_hUp#lbbQ)9Z0{peKO9_CB$X{Kv7m=>tj zTxSkZm(Q?w@QhlX#>@@V@2rFKoX39t)v0i!txovzg-k ztJMKtmxomZ2>PJ8LptBpE%|=h^M|QG*w+uwAkOqZ82&+linr71E@e*Pz-ybaU#W^& zoRC|6`Z1c!W^94n3gT=u_AAMoYVBZaOC?wz9O!Mg#8Pec=F?#q`?MU{nq}l7sfxfS zA6|c0R1dA{U>GcF*LxUVk2j#??+W4C#YNuP z#O);h_CXrt(TDfx$#UZ>@B`1=V$cr@?|~Za0Wm44C4VrCD2`z%5^F&N&%u(Y`?+=h zbK~0g2)IvA&x3Ndz6-bWXT=*V-nUuvVX+#M&9E>axj@+qzvkIJZ&bx#7sya+-Xq%} z>e3MiS!Zc3uEYm1o!{l!pvhB#k9!9j@vZHPn=DxczU)^}y~gv$obxM!hR2Dv@rOCa7z3it#pNS&`u&Bi5`BrvUN{Q@AUz5YpFcKx2$TNDY5t z|1+0^a)t*_weTn96xHSKQ*B6$`29&K6HL#&&(+V0_pBfN&WgeTn#e1W_sThQFPM-V zj!|>__P)k_VCDTwqJIYN1k$UM!`G>|yz(zpE0hF<2wcRTV}98mbPOrh#k>eXH;Dn- zRZrsyp|NUpj#^lPhgzj3CD|~~7!V3;QJVH%6Xaz>5@*z&=BDm=VPmH8G~Hf(80um- z_^B`~#>VhSi{}#}roa*}m>8O_){u9|SAO>8c~tD1-|VtT!t8a^0Y%By&Y2hfu(OY% zUwx~IDtU0w%UNnI>S^1Ja8*#J5CMTE-L}@&pgiKB-vxY)_J`rY9-eA88Vwy~AAzfC zNx|STSgmP#TfdAK$b^j`#;83|zDKClW}lt%?zV%MMI2A+yg3e7Nd~_I(m2nQdn#MaV67~~y@$vC8w$e@+uvkH;BN)@1zP{M5yyrOEP~8)dPCuJ3scLU; z|NSoAW24KZXqmY`r*Rr{e-{?M3bExliBrumhlDKDTmM-ImPwKJ`_lDtad9!i;$9Xk zz)YHlr?>b;Jy7xE9T7#oPT`C40{e5c6-1Blk=4&+P^dH*A7JESieG}BAuv;E9Zjw> zRmj<}H*N~3C5yfMMnWg*us!kt5h!D$>{JDdWiuPt7+f0TGpu<|*!3}mm6`dgk=Lls zjhEL5Cxza}Z}DyW-2EW5kv8i(??>I!xi8EnW^8%meE1Ut4wQc_Z^erL-YlSAkQy4DAC?5^wW^j02}h%f&Q?PR*iv3d09 zqZXTXkwNv@-Dt^vct@vcNoRh3KIs#u1zEZTr6?JF5}yrk%c1mz7YOwy`|Y18d2~L< zmpf+d0j^qFv9^QRL1p0yv9V_T_OnyZ<6m?CSmiTR_3)@Ehlf80O|AxdMh$Ir4&G$F z>l*Eb!476L{=tR`pK(J~A87V-u!r3@DLZNSq+O7Ds+=%4(%T#><*Qd+HJy+WvmfUh ztp5OnbMMd!bNVbw?)kR*U3lE6A-eD1`rbh3GcIOkZGk<;_=u0|kNFmObc=1KJlFr= zo;+>aM|UahG6w8!Z?oQ=eL}GC1AQUQR!K>_bSmUHtX&Ar^p^CMy__W%=8A3 zop15m+nuT8kW+7CK!;!v~5>Q!3JR{KrY5LfI{$P2xHfBzs~X{m!wV0ZQ+ z^W#0~Q${tyQgS#flo!ACe9A6M?dEhTZ7eU}1H|hU_d-XC^c)BF!H=U~mMLZ0wE4M6 z>t8m;cBudTUO!fCwd>W8-^uJ6@OrW$uYNVvuANDvW150v$mJFb4r=5*#+Nqr*{QC2 z03*b@WJ3vr4nk?53~V01c(DMYY?qP52P}invLoB?q~f;;pc307q34WiWo%HkQp_o4 z6&oU$UxGAW0v>(&+!;T*_e0&q#E&wgEedJUL3u`GlGm|u5 zzb=4h#y#NNf2f9kOV3v20MkwaZQN!tsZ^%wyDb~+ZE01Ru^oqxZX3L#QN=>oYq7nb znv}B^-tdPlaFZi^|L!s}WDHpsGc3T~$f)ke4aA86@leo>9E;6U@!N{j)>2hgCa#3T z2sxKHRKM)j?@1>t|EiJPtNZS~x=|1VW=br*PjiqkyCBI?IIHNfGw);}LcmNt3(C~;~)TSCoqPLu1lz@s)B+MakBQ9bz^7o6p#{3ptO0FRtks# z?_~!Y7eE}65sn}u)W&R0d=`+onRzw(nG);|=_MCC8<0Mkd6babt8cA;Jb(`gwHM!Z z&`nW(w6hd_w000Ki|I*V5(achguz7^u_?ZU6B!UdoTKT3z({s`hRb~<6s!j$>EQH(;trF&06xCE;-D4#)YOre z!>V2dO;1*CT)fz#NH5-|iT-)EN>`-Qo5(IMKB+wiz6_ZT%Q5jC%+1d`n~TxRye-Lv zF{!1k8seM4wL#2sOpR3pqq)zcLHZCF;*%3k(j^>2KMBU`2a5nJy zIg!?{ZB6Ly%Q9f|KQjzRerj`qG_$oZZGU2i;vwRoLq^1CqGb>ZDZvHNAjQTT&8M+g z$k+H>(H#9Ej*k|Yjd^9~pUhLV;S zb%|>UWQr>bq>hUV6a`RlOlGD7pMJwg?VK3fkKEkcH#U?I?3b7Ch{mK&W(#8Jr##je zJYNhvxe~tRz!|4uHAQ>ij!xuc;$E~dde!TK)qqpRQ&@-3#VEEVXE7%AYlc*H25TJTY=2l6_W%5l-#!M=gU?+7w>M-Zan1>} zfNVR-|D)l5+L4K)bMx|;31BFb^{vR2c3#h0ZmkK|nK=nzB@k1_h|l|)SHGGZf^%^A z^caE+8$w|*5-yNBQYAbu`KU+xw&ebDj_t5-Z(F!U4=AeOGqO=H;D}8nF+Lm)hHrVg zs(@%2>1|j2Th`y8Sq^z^dCS;Hl30*aKHd4v`TF*yCYWElI{Hdr6H4^EEt7;Aux}JJ z7Y>R>2rXhcw{~b~h}hM){8r4k5yYud%1>|QhhjOc-Zebci}+tzA%;FM(Mr9Ql|0zj z?<&eFu^-(1*P$<$ZBAsAQBeQFJ{a3^TaC0R9ITVpCv9-W49l%DE?fIqFAYXU!Y+h_%-wwQloJ?F{f;&RT-W-1Dz$@2@2Ol> z#IZy4z+KN*$Z;;>$kw*NYI~ZRCmFOo==fGED=W>fFaHi8_2*&}5`a;KC@ChTHW73e z(calL81*q|eS2lgqNo}~OxXnLa}v6-B2g)R{(k$pnw>om_t{D3qOk;nLDoMnt}k95 zWJn^R4TcN82#>wFS+Unw=UYOL9+?T7KUYzo^V$_(yYr&bN{y{-oNjofYFGhie6z1e zC;IwTrQ^KxKz<}0P&PeVJSlWA>JA!sCK$@rtFiNiuYsWf1Ck!Q#Ue|U1Nrn~Z@y%< zu$1UmT9p*(6&?4Dy`Jvx>h9jB7jyb>P+{2%Lg#f)F}RbHv$-`PL^Ds~i(g)=YB;{A zRnK6GD$#fKefsoU)N4r(x98$+trp~Q&+89vx;KOWeIdZD^SP?4uTN^*|Mc{Yc7b{Z zSE!OwYv1YRUk%UQnNRv1Ina%AN*-N%B_T8qWU|t8FFZ6f)VR8Z&^|80tj2!wk^Rl} zl_0P?XWSiIob7^gcKEDY@|ni!VIN^BS?=V1r@&m3m+SlVOC6lqVo=Q)eUee&cwU^0 zsRwSb$bnVNlYM9Bi?l44o&jN2a2`|Db_I`LO*m~%&CJ*xTUwkVF{L`ITzm#iaI=xA zmeT`Ig29S2Ojjd9YTCH74MV$K`&fl9t=) zt7ux0SIOqlQpbVXhBZx!(q#oiUvt5u zOSSTPK*YP%X1aU{t*IfC(Icm|V1NKU3(eni7kjNf2R?gO^Vh}25)w_uS&t*4qg${$xpN@it?$ zQKO|w;9WXVQp`_sx(DTH85yr}?rADf^PEhiitNo`5|2M`NAHX_p72R}?p=F--JWb6 zieGqxczd?rSql0hI&RGdE-qGJsFCsX_2}ony4UAhc+TbJ;+>2>+W-TdmUgF&)KH~f z8Dbv9#Yi#B&^9ru7_V)ew8|@d5 zjT@!!b~(Qt$P8Q^$hsK;GkDF%iVZy_(f&M;{V8Lv9W6eix<3sv9^0q(r+ZBzri_sW zcgGm>&@uY8OyC-qq~*flUB49=7hU3+nyz)cnIq87{}l@=fqt>05y!``XOd%Dd^{;B zWjABukG97AM#}BRrDMhW^T zuC(X3J>S|ocwpJv0t))4Slix@Z!Gjd#Z)VEy%1>G^p3!YIV633t~-uH=CV!hUdES~ z-`|^<_=GWWb;P*?FxT}8^$ZDD{*BQslPl8OX(2bJYxl0t{;rvNUHD^v2lohvu9?FKQd=9u4KCOsqOql-Vr!pwEbWO;JIq!%TMjA!GZui8|#5X>Zz z;W1?!2n9Va5$oL@;K{YT840ylMQnH9lk*^8$IB2`}5w4_ohx?@ixG)zB(pa=DMzSe9KP`qR%U6 z6!eVdIW48aa-F(a2L1R=b~wLTp=6yR#&$UWC@${iu0F#^rS(8eKt`6|vHsHEeo2kW zPO-Z&<{#)!KGFk9WhTuSNV-55C_-83adCgsEg}&~MlRi58^Z;niSAc3F8~V^=o@Op zS*CCcu74vDpg;Q^%(U6}O?26(^5Sqq&XWXm4c&^WR$usnsqoR4>p9W1YpbjMQ1L1{ z5y`@fQJvgmwu?q%-~At~1*$17<@RHHce9DU4x&-VVsh^uX-w!p$Mx9baGK?!>bzOB;MG863hA*n~~Z& zsbC2Ff`67{K7|==r1m#p36Gp8@o;Ngz)8l9c$(q== z(W|(kgcZ*kR4FZ`mf8Yvd2l5SK(X!XXADLXZYLE}@KpCaO}#hs>xVLlZ{1Rqq%W(R z%-M3>TkqkAUyP+s_9iRW>e}9R^IizsNINyb0^+0}bl-P;XFoKs^i&=PEcyM|%F>dL zl)pc)Q6J0~v6u&1{Fs6W56IQ<2+iVRVgyH9zVFHryL1?1qahE3ZGJ5_?l$m@o(4A+ zNZ(xkbt}h0#M=%Rq=hALr#y%*P+AzA3im#FY|{Hk|KcRggxUmE6ySp=&MrPl|Fgf; zQGZP5pghhY?#R({zh-+H85dxOm$Kg{%B>i-99h8T-NOzvE5@>>M_gg;#TkIQ`Lq8wjiOQktO^r z>tu2B5yVi6%0brZ;Doe`?2uulWA_Aelh`Xm8wsZbm{9AvvcMYq3$6Dd^oA}Glhk%+ zj>&6`VqXB!e62i&jwNyZuoH+>jpE5}6=R(u*@l+RAMa)nDM3N!Z26}Vg4N5eO=Vj; zAD^OmxoK|xvWl!sl(w|81WmC2OxJ&aYVKbVk3E=BdzKl#K4IjL!#^1dG{7(vR;I+pLe)0YgVAL}O)> z$sYANZ)p2~Fc+wEVzPtU8(j`WlL+q!4mO6KKh!BkX4~(vb-KmZA;t;@i^24g<##f= zRB_9>GTr^OTksCl`V;*WC?8vC!a95BNc;-jK}MyeAGsQdLl^9vYC2AbG~=Kfm1N)duxK%&KA;};`-?h2m8 zsE7c(KPU+Ei5ZjiUb>5mwqVKdJYIhzphlujZ6Wt;%tl~;QS&XJOBWh;d@hknmCoO# z)wnBWvPr_%GTrSGz+3VV&(AUx`}hJ`m3DMjjUmWZMFVtUs%4A&2gz9KIzlFnE}0G zyQb0twlU^ahVD)6^N}~oV_eW-i+LH#dEZnTdY%wIrT4sUgx$RrPt=|UH*ZWdOYe6oxb0)=ZWR+;YInzrUOBBI zZz7+eK8EQZ8C;x&?K`olsSUfQOVOqesHsmJo9W(8*%oBfI{p48E=*nr;;;1X@=<)} zzfa}?paQhV&v`p{>g(&v9^5>a#@eL>oj>cRU?j4m)U@^5*k_u_WBk+Er-IDXCY!-* zw^Sk!FAMn)_e~8?)%M1%BbZmOg^@%Q3?9>`ADyzaXvbLkIXP)8izfcrUn_#N$Au(l)7 zawp!M?^jt(wATl4^R~LaJVW7tdAjA7qDWtgmZP2NlLnn4-HkP1>VgqipQ*1*k@Vz` z^_RpWvN~Aqu8);3mE5TsKBUCI!b!4Eu^cT&m7 z;DlVi_I3tyIvvW!C3h+Zqz%70d4gcN{FASW>o-!zS=N$KZ#GjL<&NEHB~CNFK-m)y zTu;j`{W9(z@2Jbz+1F=ocn6d}N~EbNSvqBhtu6)-BITf$|@lOxG-&UFWFINsspW=1jTOC6eQo+kMKNvYi1p()&Yc`xQ1FmQ=mnWH~kILN@8tP`31&ySfFD~Z7+U^ z;A$=}FfUJ3dR}|7MdEQzcjFWXd^#={n3%+G8$_q`I>)su7?S!u+?10nx*RCgD2++B zwq6Z>-?V)!48@EQPyMUi|zBA#&)F7#m)BK9GCzN zrt$2?_P1WNG^>UG73eb^_%NQZ{<3VZD#?4h2r-RK&x2wOErAAjlB?GOavT4Q)1R9$ zH2=H^YBr9ZwFjudvAj_`UHg^5@mkzXcrWm{9Q#m`N{vvR8X5kVBH|`&v=npIU2|Vf zZn@CGvsriW-GUpUYIN*YnE<*zkX4KYL6#rhw>l6U% zxdIdCjFwu73Pm~zI&Oqt>PYg7Tz_Ogio6LM`v-NKLa#T1p9TbCHw-K$}Ai>%U!NLL4$Y zFpWCz9;!O#RC|#XG#GShHe}_St+jej1@5k$q#7}lRljICVN<)S{u6e7_|KoTyhG+s z4p7JYi>)6;>9&52fO7aMSiela>jq!o5Yp*Up09L*GQ}<#2)(p%94j~AvB=6iC9nV@ zikbEo;sN`U37I7ya0}xKNneuq>!WRmIXbS{0}Ts}M1#QPsp)TTjad|r^9Fw|JV$u+ znrS{$7;OJ=Q;U#x_;A*?BLZ4X%i4kKTN6`sH0Q4n%nl5-xs69jMI#`0${+xDZegnADFKv7MPdjR%3ya(R8luGi|h# z-(7UH3l8>;D#Jwk~r$;ebmzuR;`;@+f~!kaU)hrsQ{hL|9iz4 zzjQMEb76u%F@1rCIjB}SJLToQK7vvzq{T1&Id_{-s{jTTg;M)r$u$WE+wA>$&Yyte zm+akXw)rKUUkhD#9+_lE5|-LePP z-nH7uj^snBL_T?+^lmF#5ci3gE*ZmT#s`sf$rIj+%r|t?HdaobVR~sF2=cdIS4Q6W z1t~Vhl}=Y*R40Q65{Ox5bIL6Cb-Eto_Q99pZc6C@zZ=|PSYAx`L^B7okkH>V<3^8+ zq3ztb(ua(dwtKr$`GzO0X=qYDY^PWFwpGqc9b7y~0**cpIXW-v?Z%^bBt18+FZWm> zPGv9}8k+B`fY1p)Is7cyJgU1SmTYgf?xozUfb^Ap2T@Vs#@|?Q&m)f`5dM|S-L&CGA+RV)C zB=hd(cuq>&j=Z-{D7KdC9W@P&vJZO2R&Rmx$qCX7N%vCyqA_D(iaG;~zNxQQ>-|kp z>)qZ6M-Qz^orE~OQjqTTZ-VZ;dUy4fgprN2(`MSYsYqL#+z>| z6}Hw#v?A9+z+BVCW5+q804vbEaIp$LwxfOg>ToZ4Vxn_pNqSbd#47Saps7x86Zo9K zqXCX=6rJvJ(A}B!tLf~UKmB7RaB=WE#|rl)`yi!M7K7j9MF7*I3l#+A^tc&S|XQn46pNOI*yjuDx+}dE|PJ z@yY6V0?&AZjPI}>fK!XebmEN>QscwrS!iML18u{bm>Q}(OY^jElLjT(GgDm*iHOqVR(_9LRoUXGJlf z|NZ@4yPG}Wrt#wlCw1|Q@Y0KGsE503#DcpoA2oslzV?iFji?(8caOgv!87^dOq2dVTD^uG^DlI<3wOnUYdf0 zf8vO3Y5*;26`RLSX|QIt$E)s`IY5U=!p%m0!@*eC`*6KQD^4|kqfHI{+AM|;{Eu25KM@oDa zb-TGmZbI=v$C(1Tyv`Ob3LjHe#SDzUi-WYeqeJfK^)8Bsy29Nex&cMnisoq4w+uH> zfw2UrKP&k@GfzQ7H8p+cvfBxD>^XO@P)+oEl0~{pffRa&aw;u;%h!9c@)tP#gwWr! zy%fbisy{S1IFp}zOVEd3x@FcK+NuCqXD_Ne95ndNr7zPbouBA8fi)@m^w?RHVMZ^v zH?&n3vi?dXTdyKj34pXREo&?RI&|Q9oN_jO4i_U>k;>C!rudMgWcbBJk23+7kkABk zsQ?jTA2zqDT?6s`wXO<>5c*URH`tPf$M5SX-#ukGwx|V|pDd!a_$G7}%H4GWEn>T7 z|0tAp$^Gc`eZ%yLa=wac{1MP~On+-mh4g%I51u=DV+yFB|8^O&?mBQgD=ybId++=9 zS&a;HjIHVHxq(@FyNs=ZQw1yz{vK78n9Q~R(bzoKuH3;oGRosOqrmjhTO~Tl#wW_) z0Wmx;ji;uK$6wk@paQl@$`)@F6XWDV&Y)X?yKy7J*Vc*-aXZ5x^j!sWiS^l0Y4|Iw zkD6iGZvggXShYl*KG4@r^~1B2jCiuV_;Bi20v|}qtScl6W;ICjP(0{>@|}1a3lf)-cCDpWl4ux+(w8QM#GEEw z0cSdfQLWQBHeau6nl&6*HtjhiOtyGa$!B08{lV4qr%dsm1wNXWN#E%q1txk;?ZxAz zpq)bz3;2ktt*Q=_);5zChN{-Q=F1rq-HO)l{_@}%qA6pEuO{=a1?V6<C`fYtU)qOr@1+?EqvtmR zwI!T1=j|`zje+$%ljiWZjmClNlqGB6rwoUAcOMHbG5sjgj^0F)db2)rWHdMy^tNvP z*iN+s{N}hl|8?j*)#ow3X)IZ_RsHp}Om{YAzA*oZpOnD+RK4Ln^w7f9d?VyFB1X zuhwz?EnOdB6eS4M3JG!eK zY463GN=DCzLiG)z)UT;6#OF>qY)-rRXO2=1!HkP6>EO&~{$`BeY2*j4ry;YDP&#>> z3|@zb<{jpYNhuVVoVdV_AkFv_U~fjUFWM+urZ$EpN&@v=B;a5946nuw@_rzW!2|cE zI*M5e`1|f070MYtT&H{(h*X4sq``_Z3B-~`Kw_p?9sUH~ds}&aGC#ew20H)zZ}x+z z0f|Y032Y}XeEnt#kK^sh)nGglU#1(6#n6Udr4PX4JEtD)KWL)g|F0shJ)Y^kkFVL> zA7(=3w$>yPMG<;1rsfhw5r)&;(jkmc(odt9B)43TTa-G;!J$Qwh%HaKmAO+Jk)e^o zG|xA6Ugw{^_WHcG@Ams`pX>Ym{%rl!AO)C!+@6N^()*XmUS85ZH@88oSF!_LC|SV! zyZv9miaN-Qx;#0}Z2G{NP>lLVoV{(*g6lkhP3_JP(0TD=Bc#y%#%{L{S*ToopbqL| z8QfmTnEyiAI6V7|48egGgb1=t+7SOdKiXJsMcVVQm6M2}Xzdf3ufTIn-pYtvJ~DDp zL_s1gJw0^#kgx-k-PYD774?<-@P47s_bx7%yXsM85d7l}Xbw}o;Pbn!hP}~7EBpmH zqw(NY=cTExZ?`4_2Z~w}Cp$BjGnbY4XCPOpk-?YZ6Ll5Y!Lu+?EN5zJhmD2A(g?{_ z9K}IF{Jh8h?DnJQQJx_My^L>h`@WgL@LN+q6!DrrJ?}{L>7*wj|3w*3NKun?1=HOssHey3c`Bkgee%6N(d-~qth)uRp8 z5Nt?+QHl1ne)~6sTx~U}Z{#%_e2;8Bu{D^6DZU=*NYlYN4PWOA)7Us);vXoiF#F_l zIcoNPz%DcU+ zFc&y{&R4$zt66|aEHS^#Ox?@!)aUVdQ=YLRd0*#-`=~LPEruTQh5+iBRt&BS0+WGhSFyBmA-mI(RSgc&i!S8t#U`6^hrj2Iav$&EqE*~ zbg1Yp&$2dbl7&R1m?1N2S>2Qg6Z}}zMs)3`$Kzk3F}?$z-`@v1!Kt~3G2X@UA1}K1 z_YS&a%HAsa3&6k1xo)}<;Na+Zd}wX?sAuC1z+N$@P-?cXbz4lG1QbkHdiR+YN_QnZ zG0Y1{L;eRSIx9GrnlKG02k1%uz+Eo%8q{gdev@z1V;zGjJ{KVYXkfpT&ZWrrR%S5W z9}vMNPJj`OF$N6XS#dVBytJxvJ6<6YPDL<7>a{#FAMBp3vKiTv#x3!0Sq6oU!j26a zll0}`fqcyOEzJ1lxA|LeFL*a{^eby8NR{)V+W-qMa3K!6Ay* z2Bily7v4uYi<1>Nn#b<#Z|w7q3Ubjd_HO|NloIO|If>W&UO&w9PezZ86O^j9U@HA!6ffUlYytHbf__@Qh|7x9H2iS_k62roiGG6BIUN`QpGluRN zh#2%{n59a^VB&WTo-GP5S)3;4Yw;d(0q#&)V%So--MiwMq`H*^&7P2ELr6Ofpb9&b zAurVDfGe*1{jTDyOLhAG+I(Lk3D@zc)TQOlp@cuy*_PDUnzaVP%hrfX$+eAcnoQkX zd6G+MCv&5on6j&!jYC_6ml3Z(T6}(INbNZf5X0(mjtA3;wkgZ6&f?!0+*Cx6HA3z8PU@j5780o9f{eu$Wi$G#xC?HCml=bt>4fj_7~ zKM*_OQzb3UC}yk$q!Rozb9^M?Fca4JhM`%udBjkfR=*auvw!i@0U(Yq$HOo|cwd_@ z^^GT?R%*o1#e{y$jJGtjb>2sl+ zfsljS>5qg{Wt*EtKc|X8C7;Pr!-|w7JUZAXRa;%~HrQPw)x42Zn}Pu2WRGd(uxIHi znlv#W>H(!UXQ!B6CYappWSY6Ch7SimhI%do_+H#l(^*6dE0VJLpBGnS5NMFnq_GFh z6gPiJ;3Bt$fx-VTE7A;z_1}HCGrKE&T;u{EfE{NIU^y>?bDIKFO7Lgp$L`obxylH=kKeShI&Wt#VS3bqXj zk<^F)Jjq*s8p(U>>0D*^ga_!(JB-7*@Kmn^`{arWaP*D?WICe-T(=4y=NS3PAYi3i z@SX2AKm54simq2XM?Y}*YQvSuR|04dpX2qesu?Rnw@1xs=Yv*K+RxXwAiFxqvrO4I zqJPzk^+@om^bG-+EWm6;$8p2elkJB^b%8-8QnwX6ag3W%aZqiHWU#0~kzF~-oZ5-$b|?qmNM zm$5TRg$JBIW#su=gMrf}68T2kEShfpB2Sa4ZOHbGvD?N=t8XOQO}|eQ*@gGF0v&!s0oSOL>`5Cu+dvw+ z*SmciYug4S5ta*j%H8;+=-$~-%vxfdquN+?Bk7v<=^&aFS`KLPOEB#wt9AUa27-=p ziEZYJj=QE=N^2u&pPEWWwnk6l6dYlwbcbxTNjEx+?4cUn3;6rVq#Mjk2H7Dcyu zhgBrIq)P-3Tv!bnC8S%N62q!L_NZ$p&US%H%~URO2YAg(Q?L2AeB;l3A}c!zQ}z^q z?K`E6#R##26LAk@aE%oLFGc+ThOR*223C}C{696v8eAH0I>v5|1E6s9(#NjxcqLTe zcEZQD-UH5+uRW_`wGY{IVPJ_)fV|Ca4Ug0og!II3zfuZ_K(7cXAEXY61w$Fw!s6Yi zXzKpA2+W4$ixaXjR}g0(h?#l(uuSZ+G_p7jTa;E7V;IjUqP z6xpjJpyY?Dz0ngGOqf{qU2{XuY{kXv_Ir$-3+jtrV&Ep6@G9bIB@KjzXIGosw4(}D zLQP%+CoYX0t=yrAi?3#FsE0V7aEDI}VU=O{7Xf)e3LJx>(Lc@Pt)%|6nCc4yCwy_3 zzf>>U$h~m7h-eW0Z8juVYD6=^BOmIud2(&9%e69?P}UXI{iGIn7VGCCH%bXWzNAkf zv?t+I*uS|KJR{t}bXY$H0BM_e)UXD+i%8m69lKk|K;kZC-5qp%5mCd=_zz)a%;&GE zl9K2T0f>04rTBvp>1g8!lSDo?T+baC7?*eGy*{OI+ zoczo#joy|yD#?G{xm;M-=jMF9l5;O-d{(1uO!H*tqG}aH_C8A z{;UxgJu{Sk7pKo30XLRiJOilwZ{~a0e|1^JOBPSU@aCnTeQwFz{;zLO05|~xd+U%) zR7(d!S0ZLsmq<@HjZ_@nS9B8zBt{F?sX$$v48JG>LLN}KHaPwKSWEdhxKfPdPiEbT zT-9n|*r=CM=3Y{)dB zBa>}6Xp(zh$iO$H2^}#w8$?r*^|_QsNLt$!@|eLx13iPBcOt=!wgvr;>k|`Ynfwum zAu2IgvrO;*yv9_APl*OMbE7h+;4FoiC@htw{p#ZQEwnVVzRVwZb~BDCXEmSkZm`CL z<_lcgAx+B#^Wz5m8}bP0l+XkK^*2?d diff --git a/app/assets/javascripts/app/helpers/handlebars-helpers.js b/app/assets/javascripts/app/helpers/handlebars-helpers.js index 1be1cd98d..cea31311a 100644 --- a/app/assets/javascripts/app/helpers/handlebars-helpers.js +++ b/app/assets/javascripts/app/helpers/handlebars-helpers.js @@ -31,18 +31,18 @@ Handlebars.registerHelper('linkToPerson', function(context, block) { }); // relationship indicator for profile page -Handlebars.registerHelper('sharingBadge', function(person) { +Handlebars.registerHelper('sharingMessage', function(person) { var i18n_scope = 'people.helper.is_not_sharing'; - var icon = 'icons-circle'; + var icon = "circle"; if( person.is_sharing ) { i18n_scope = 'people.helper.is_sharing'; - icon = 'icons-check_yes_ok'; + icon = "entypo check"; } var title = Diaspora.I18n.t(i18n_scope, {name: person.name}); - var html = '

    '; + var html = ''; return html; }); @@ -90,3 +90,18 @@ Handlebars.registerHelper('fmtTags', function(tags) { Handlebars.registerHelper('fmtText', function(text) { return new Handlebars.SafeString(app.helpers.textFormatter(text, null)); }); + +Handlebars.registerHelper('isCurrentPage', function(path_helper, id, options){ + var currentPage = "/"+Backbone.history.fragment; + if (currentPage == Handlebars.helpers.urlTo(path_helper, id, options.data)) { + return options.fn(this); + } else { + return options.inverse(this); + } +}); + +Handlebars.registerHelper('isCurrentProfilePage', function(id, diaspora_handle, options){ + var username = diaspora_handle.split("@")[0]; + return Handlebars.helpers.isCurrentPage('person', id, options) || + Handlebars.helpers.isCurrentPage('user_profile', username, options); +}); diff --git a/app/assets/javascripts/app/pages/profile.js b/app/assets/javascripts/app/pages/profile.js index 3aa9fb101..32298e364 100644 --- a/app/assets/javascripts/app/pages/profile.js +++ b/app/assets/javascripts/app/pages/profile.js @@ -11,7 +11,7 @@ app.pages.Profile = app.views.Base.extend({ '#main_stream': 'streamView' }, - tooltipSelector: '.profile_button div, .sharing_message_container', + tooltipSelector: '.profile_button .profile-header-icon, .sharing_message_container', initialize: function(opts) { if( !this.model ) { @@ -52,14 +52,16 @@ app.pages.Profile = app.views.Base.extend({ if( !this.model.has('profile') ) return false; return new app.views.ProfileSidebar({ model: this.model, - photos: this.photos, - contacts: this.contacts }); }, headerView: function() { if( !this.model.has('profile') ) return false; - return new app.views.ProfileHeader({model: this.model}); + return new app.views.ProfileHeader({ + model: this.model, + photos: this.photos, + contacts: this.contacts + }); }, streamView: function() { diff --git a/app/assets/javascripts/app/router.js b/app/assets/javascripts/app/router.js index 55943e94e..df6e4ff73 100644 --- a/app/assets/javascripts/app/router.js +++ b/app/assets/javascripts/app/router.js @@ -21,6 +21,7 @@ app.Router = Backbone.Router.extend({ "followed_tags": "followed_tags", "tags/:name": "followed_tags", "people/:id/photos": "photos", + "people/:id/contacts": "profile", "people/:id": "profile", "u/:name": "profile" @@ -81,7 +82,7 @@ app.Router = Backbone.Router.extend({ this.renderPage(function() { return new app.pages.Profile({ person_id: guid, - el: $('body > .container'), + el: $('body > .container-fluid'), streamCollection: app.collections.Photos, streamView: app.views.Photos }); @@ -147,7 +148,7 @@ app.Router = Backbone.Router.extend({ profile: function() { this.renderPage(function() { return new app.pages.Profile({ - el: $('body > .container') + el: $('body > .container-fluid') }); }); } }); diff --git a/app/assets/javascripts/app/views/conversations_form_view.js b/app/assets/javascripts/app/views/conversations_form_view.js new file mode 100644 index 000000000..4134a303e --- /dev/null +++ b/app/assets/javascripts/app/views/conversations_form_view.js @@ -0,0 +1,27 @@ +app.views.ConversationsForm = Backbone.View.extend({ + + initialize: function(opts) { + this.contacts = _.has(opts, 'contacts') ? opts.contacts : null; + this.prefill = []; + if (_.has(opts, 'prefillName') && _.has(opts, 'prefillValue')) { + this.prefill = [{name : opts.prefillName, + value : opts.prefillValue}]; + } + this.autocompleteInput = $("#contact_autocomplete"); + this.prepareAutocomplete(this.contacts); + }, + + prepareAutocomplete: function(data){ + this.autocompleteInput.autoSuggest(data, { + selectedItemProp: "name", + searchObjProps: "name", + asHtmlID: "contact_ids", + retrieveLimit: 10, + minChars: 1, + keyDelay: 0, + startText: '', + emptyText: Diaspora.I18n.t('no_results'), + preFill: this.prefill + }).focus(); + } +}); diff --git a/app/assets/javascripts/app/views/conversations_view.js b/app/assets/javascripts/app/views/conversations_view.js index c2701efa4..b697d37c1 100644 --- a/app/assets/javascripts/app/views/conversations_view.js +++ b/app/assets/javascripts/app/views/conversations_view.js @@ -13,8 +13,8 @@ app.views.Conversations = Backbone.View.extend({ if ($('#first_unread').length > 0) { $("html").scrollTop($('#first_unread').offset().top-50); } - this.autocompleteInput = $("#contact_autocomplete"); - this.prepareAutocomplete(gon.contacts); + + new app.views.ConversationsForm({contacts: gon.contacts}); $('.timeago').each(function(i,e) { var jqe = $(e); @@ -30,18 +30,5 @@ app.views.Conversations = Backbone.View.extend({ showParticipants: function(e){ $(e.currentTarget).find('.participants').slideDown('300'); - }, - - prepareAutocomplete: function(data){ - this.autocompleteInput.autoSuggest(data, { - selectedItemProp: "name", - searchObjProps: "name", - asHtmlID: "contact_ids", - retrieveLimit: 10, - minChars: 1, - keyDelay: 0, - startText: '', - emptyText: Diaspora.I18n.t('no_results'), - }).focus(); } }); diff --git a/app/assets/javascripts/app/views/profile_header_view.js b/app/assets/javascripts/app/views/profile_header_view.js index 971cfacce..656c3dabd 100644 --- a/app/assets/javascripts/app/views/profile_header_view.js +++ b/app/assets/javascripts/app/views/profile_header_view.js @@ -2,14 +2,24 @@ app.views.ProfileHeader = app.views.Base.extend({ templateName: 'profile_header', - initialize: function() { + initialize: function(opts) { app.events.on('aspect:create', this.postRenderTemplate, this); + this.photos = _.has(opts, 'photos') ? opts.photos : null; + this.contacts = _.has(opts, 'contacts') ? opts.contacts : null; }, presenter: function() { return _.extend({}, this.defaultPresenter(), { + show_profile_btns: this._shouldShowProfileBtns(), + show_photos: this._shouldShowPhotos(), + show_contacts: this._shouldShowContacts(), is_blocked: this.model.isBlocked(), - has_tags: this._hasTags() + is_sharing: this.model.isSharing(), + is_receiving: this.model.isReceiving(), + is_mutual: this.model.isMutual(), + has_tags: this._hasTags(), + contacts: this.contacts, + photos: this.photos }); }, @@ -17,6 +27,18 @@ app.views.ProfileHeader = app.views.Base.extend({ return (this.model.get('profile')['tags'].length > 0); }, + _shouldShowProfileBtns: function() { + return (app.currentUser.authenticated() && !this.model.get('is_own_profile')); + }, + + _shouldShowPhotos: function() { + return (this.photos && this.photos.count > 0); + }, + + _shouldShowContacts: function() { + return (this.contacts && this.contacts.count > 0); + }, + postRenderTemplate: function() { var self = this; var dropdownEl = this.$('.aspect_membership_dropdown.placeholder'); @@ -26,16 +48,16 @@ app.views.ProfileHeader = app.views.Base.extend({ } // TODO render me client side!!! - var href = this.model.url() + '/aspect_membership_button?create=true'; + var href = this.model.url() + '/aspect_membership_button?create=true&size=normal'; if( gon.bootstrap ) href += '&bootstrap=true'; $.get(href, function(resp) { dropdownEl.html(resp); - new app.views.AspectMembership({el: dropdownEl}); + new app.views.AspectMembership({el: $('.aspect_dropdown',dropdownEl)}); // UGLY (re-)attach the facebox self.$('a[rel*=facebox]').facebox(); - this._done(); + self._done(); }); }, diff --git a/app/assets/javascripts/app/views/profile_sidebar_view.js b/app/assets/javascripts/app/views/profile_sidebar_view.js index f45f18f33..d94871cf3 100644 --- a/app/assets/javascripts/app/views/profile_sidebar_view.js +++ b/app/assets/javascripts/app/views/profile_sidebar_view.js @@ -2,44 +2,13 @@ app.views.ProfileSidebar = app.views.Base.extend({ templateName: 'profile_sidebar', - initialize: function(opts) { - this.photos = _.has(opts, 'photos') ? opts.photos : null; - this.contacts = _.has(opts, 'contacts') ? opts.contacts : null; - }, - presenter: function() { return _.extend({}, this.defaultPresenter(), { - do_profile_btns: this._shouldDoProfileBtns(), - do_profile_info: this._shouldDoProfileInfo(), - do_photos: this._shouldDoPhotos(), - do_contacts: this._shouldDoContacts(), - is_sharing: this.model.isSharing(), - is_receiving: this.model.isReceiving(), - is_mutual: this.model.isMutual(), - is_not_blocked: !this.model.isBlocked(), - photos: this.photos, - contacts: this.contacts + show_profile_info: this._shouldShowProfileInfo(), }); }, - _shouldDoProfileBtns: function() { - return (app.currentUser.authenticated() && !this.model.get('is_own_profile')); - }, - - _shouldDoProfileInfo: function() { + _shouldShowProfileInfo: function() { return (this.model.isSharing() || this.model.get('is_own_profile')); - }, - - _shouldDoPhotos: function() { - return (this.photos && this.photos.items.length > 0); - }, - - _shouldDoContacts: function() { - return (this.contacts && this.contacts.items.length > 0); - }, - - postRenderTemplate: function() { - // UGLY (re-)attach the facebox - this.$('a[rel*=facebox]').facebox(); } }); diff --git a/app/assets/javascripts/inbox.js b/app/assets/javascripts/inbox.js index c7892eb34..4b7488bd0 100644 --- a/app/assets/javascripts/inbox.js +++ b/app/assets/javascripts/inbox.js @@ -2,7 +2,6 @@ * licensed under the Affero General Public License version 3 or later. See * the COPYRIGHT file. */ -//= require jquery.autoSuggest.custom $(document).ready(function(){ $(document).on('click', '.conversation-wrapper', function(){ diff --git a/app/assets/stylesheets/application.css.sass b/app/assets/stylesheets/application.css.sass index 376babb34..5e52dbd1a 100644 --- a/app/assets/stylesheets/application.css.sass +++ b/app/assets/stylesheets/application.css.sass @@ -13,7 +13,6 @@ @import 'opengraph' @import 'poll' @import 'help' -@import 'profile' @import 'publisher_blueprint' @import 'facebox' @import 'aspects' diff --git a/app/assets/stylesheets/comments.css.scss b/app/assets/stylesheets/comments.css.scss index 681bca066..5d4e45361 100644 --- a/app/assets/stylesheets/comments.css.scss +++ b/app/assets/stylesheets/comments.css.scss @@ -38,4 +38,5 @@ width: 95%; } .comment_box { width: 95%; } + .comment_box:focus { min-height: 100px; } } diff --git a/app/assets/stylesheets/contacts.css.scss b/app/assets/stylesheets/contacts.css.scss index fe872dd27..56ad441d3 100644 --- a/app/assets/stylesheets/contacts.css.scss +++ b/app/assets/stylesheets/contacts.css.scss @@ -19,7 +19,8 @@ width: 150px; &:focus { width: 250px; } } - & > a, #aspect_controls > a { + #aspect_controls > .contacts_button { + cursor: pointer; text-decoration: none; margin-right: 25px; } diff --git a/app/assets/stylesheets/conversations.css.scss b/app/assets/stylesheets/conversations.css.scss index 313c72eab..72fe60ce9 100644 --- a/app/assets/stylesheets/conversations.css.scss +++ b/app/assets/stylesheets/conversations.css.scss @@ -210,32 +210,5 @@ #new_conversation_pane { ul.as-selections { width: 100% !important; } input#contact_ids { box-shadow: none; } - textarea { width: 98%; } - - .bottom_submit_section { - text-align: right; - } - - .button.creation { - $button-border-color: #aaa; - @include border-radius(3px); - @include box-shadow(0,1px,1px,#cfcfcf); - @include transition(border); - @include button-gradient($creation-blue); - font-size: 12px; - color: #fff; - padding: 4px 9px; - min-width: 90px; - min-height: 10px; - border: 1px solid darken($button-border-color,20%); - - cursor: pointer; - white-space: nowrap; - - &:hover { - @include button-gradient-hover($creation-blue); - border: 1px solid darken($button-border-color,35%); - text-decoration: none; - } - } + label { font-weight: bold; } } diff --git a/app/assets/stylesheets/new-templates.css.scss b/app/assets/stylesheets/new-templates.css.scss index 98b38fdc3..63ccacb28 100644 --- a/app/assets/stylesheets/new-templates.css.scss +++ b/app/assets/stylesheets/new-templates.css.scss @@ -59,6 +59,7 @@ /* people */ @import 'people'; @import 'invitations'; +@import 'profile'; /* stream */ @import 'tag'; diff --git a/app/assets/stylesheets/new_styles/_interactions.scss b/app/assets/stylesheets/new_styles/_interactions.scss index 63858cb6b..1f3c57c42 100644 --- a/app/assets/stylesheets/new_styles/_interactions.scss +++ b/app/assets/stylesheets/new_styles/_interactions.scss @@ -21,7 +21,7 @@ } } - .stream_element, .comment, .stream_element:hover .comment { + .stream_element, .comment, .photo, .stream_element:hover .comment { .controls > a { @include opacity(0); } &:hover .controls { diff --git a/app/assets/stylesheets/new_styles/_navs.scss b/app/assets/stylesheets/new_styles/_navs.scss index f433eebf1..d93871c92 100644 --- a/app/assets/stylesheets/new_styles/_navs.scss +++ b/app/assets/stylesheets/new_styles/_navs.scss @@ -1,14 +1,15 @@ .nav.nav-tabs{ li > a { color: $text-dark-grey; - .entypo { + .entypo, .mentionIcon { color: $text-dark-grey; margin-right: 5px; } + .mentionIcon { font-weight: 700; } } li.active > a { background-color: $background-grey; color: $black; - .entypo { color: $black; } + .entypo, .mentionIcon { color: $black; } } } diff --git a/app/assets/stylesheets/profile.css.scss b/app/assets/stylesheets/profile.css.scss index bf2338591..aabcb0e2e 100644 --- a/app/assets/stylesheets/profile.css.scss +++ b/app/assets/stylesheets/profile.css.scss @@ -1,127 +1,122 @@ +#profile_container { + .profile_header { + border-bottom: 1px solid $border-grey; + margin-bottom: 20px; -.profile_photo { - img { - height: auto; - width: 200px; - } -} + #edit_profile, #unblock_user_button, .aspect_dropdown { + margin-top: 5px; + margin-right: 10px; + } -#profile { - h3 { margin-bottom: 0; } - ul { - margin: 0; - padding: 0; - } - - .avatar.large { margin-bottom: 0; } - - ul#profile_information { - margin: 1em 0; - > li { - margin-bottom: 2em; - margin-right: 2em; - h4 { font-weight: bold; } + #author_info { + h2 { + line-height: 35px; + margin-top: 10px; + margin-bottom: 0px; + } + #name { + font-weight: 700; + } + #diaspora_handle { + color: $text-grey; + font-size: 20px; + } + #sharing_message { + cursor: default; + font-size: 20px; + &.circle { + color: $light-grey; + &:before { content: '\26aa'; } + } + &.entypo.check { color: darken($green,20%); } + } + .description { + margin-bottom: 20px; + .tag { + background-color: transparent; + font-size: 14px; + } + .tag:not(.entypo) { + font-weight: 700; + } + .entypo.tag { + margin: 0 5px; + font-weight: normal; + &:hover {text-decoration: none;} + } } - } - - .image_list { - .section { - margin-bottom: 4px; } - img { - height: 45px; - width: 45px; + + #profile_horizontal_bar { + border-top: 1px dashed $border-grey; + min-height: 50px; + margin-top: 10px; + #profile_buttons { + padding: 10px 0; + > .profile_button { + text-decoration: none; + cursor: pointer; + margin-right: 25px; + .entypo.profile-header-icon, .profile-header-icon { + font-size: 24.5px; + line-height: 30px; + color: lighten($black,75%); + &:hover { color: $black; } + } + #mention_button { font-weight: 700; } + } + } + + ul#profile_nav { + list-style: none; + margin: 0; + > li { + display: inline-block; + &.active { + border-bottom: 3px solid $creation-blue; + a { + color: $black; + .entypo { color: $black; } + } + } + a { + padding: 10px 15px; + font-size: 16px; + line-height: 46px; + color: lighten($black,50%); + .entypo { + color: lighten($black,50%); + margin-right: 2px; + } + &:hover { + color: $black; + .entypo { color: $black; } + text-decoration: none; + } + } + } + } } } - .blocked { - background-color: rgb(244, 42, 42); - .profile_button { - width: 150px; - } - } - .mutual { - background-color: rgb(142, 222, 61); - .profile_button { - width: 50px; - } - } - .sharing { - background-color: rgb(142, 222, 61); - .profile_button { - width: 150px; - } - } - .receiving { - background-color: rgb(211, 211, 211); - .profile_button { - width: 75px; - } - } - .not_sharing { - background-color: rgb(211, 211, 211); - .profile_button { - width: 150px; - } - } - - #profile_buttons { - width: 190px; - padding-right: 10px; - height: 28px; - text-align: center; - @include border-bottom-radius(8px); - - .sharing_message_container { - float: left; - padding: 5px 1px; - @include opacity(0.3); - background-color: white; - @include border-bottom-left-radius(8px); - } - - .profile_button { - display: inline-block; + #profile { + border-right: 1px solid $border-grey; + padding: 10px 20px; + #profile_photo { + margin-top: 10px; + padding-bottom: 10px; + border-bottom: 1px dashed $border-grey; text-align: center; } - a { @include opacity(0.5); } - a:hover { @include opacity(1); } + ul#profile_information { + margin: 0; + list-style: none; + > li { + margin-bottom: 2em; + h4 { font-weight: bold; } + } + } - .icons-check_yes_ok { - display: inline-block; - height: 18px; - width: 18px; - } - .icons-circle { - display: inline-block; - height: 18px; - width: 18px; - } - .icons-ignoreuser { - display: inline-block; - height: 14px; - width: 14px; - margin: 7px 0; - } - .icons-mention { - display: inline-block; - height: 18px; - width: 19px; - margin: 5px 0; - } - .icons-message { - display: inline-block; - height: 18px; - width: 25px; - margin: 5px 0; - } - .white_bar { - display: inline-block; - height: 18px; - width: 1px; - background-color: white; - margin: 5px 0; - } } } diff --git a/app/assets/stylesheets/single-post-view.css.scss b/app/assets/stylesheets/single-post-view.css.scss index 2fbb51001..bcf104320 100644 --- a/app/assets/stylesheets/single-post-view.css.scss +++ b/app/assets/stylesheets/single-post-view.css.scss @@ -165,7 +165,7 @@ border-bottom: none; } a { - color: #3f8fba; + color: $blue; } .count { i { diff --git a/app/assets/stylesheets/stream_element.css.scss b/app/assets/stylesheets/stream_element.css.scss index f40c606bf..16c29e736 100644 --- a/app/assets/stylesheets/stream_element.css.scss +++ b/app/assets/stylesheets/stream_element.css.scss @@ -1,4 +1,4 @@ -#main_stream .stream_element { +#main_stream .stream_element, #main_stream .photo { padding: 10px; border-bottom: 1px solid $border-grey; @@ -13,6 +13,7 @@ margin-bottom: 4px; unicode-bidi: bidi-override; } + a.author { color: $blue; } .feedback { margin-top: 5px; font-size: 11px; diff --git a/app/assets/stylesheets/tag.css.scss b/app/assets/stylesheets/tag.css.scss index 1ee8427bb..5e99f9247 100644 --- a/app/assets/stylesheets/tag.css.scss +++ b/app/assets/stylesheets/tag.css.scss @@ -7,6 +7,8 @@ } } +a.tag { color: $blue; } + h1.tag { border-bottom: 2px dotted $blue; &:hover { border-bottom: 2px dotted $blue; } diff --git a/app/assets/templates/profile_header_tpl.jst.hbs b/app/assets/templates/profile_header_tpl.jst.hbs index 9b2832d27..516ae8345 100644 --- a/app/assets/templates/profile_header_tpl.jst.hbs +++ b/app/assets/templates/profile_header_tpl.jst.hbs @@ -1,39 +1,104 @@ +{{#if loggedIn}} +
    + {{#if is_own_profile}} + {{!-- can't block myself, so don't check it here --}} + {{t 'people.edit_my_profile'}} + {{else}} {{#if is_blocked}} + {{t 'people.stop_ignoring'}} + {{else}} +
    + {{/if}}{{/if}} +
    +{{/if}} +
    - {{#if loggedIn}} -
    - {{#if is_own_profile}} - {{!-- can't block myself, so don't check it here --}} - {{t 'people.edit_my_profile'}} - {{else}} {{#if is_blocked}} - {{t 'people.stop_ignoring'}} - {{else}} -
    - {{/if}}{{/if}} -
    - {{/if}} - -

    {{name}}

    - {{diaspora_id}} +

    + {{name}} + {{diaspora_id}} + {{#if show_profile_btns}} + {{{sharingMessage this}}} + {{/if}} +

    {{#if loggedIn}} -
    - {{#if has_tags}} + {{#if has_tags}} +
    + {{fmtTags profile.tags}} - {{#if is_own_profile}} - - {{t 'profile.edit'}} - - {{/if}} - {{else}} - {{#if is_own_profile}} +
    + {{else}} + {{#if is_own_profile}} +
    {{t 'profile.you_have_no_tags'}} {{t 'profile.add_some'}} - {{/if}} +
    {{/if}} -
    + {{/if}} {{/if}}
    -
    +{{#if loggedIn}} +
    + {{#if show_profile_btns}} +
    + {{#if is_receiving}} + {{!-- create status message with mention --}} + + @ + + {{/if}} + + {{#if is_mutual}} + {{!-- create private conversation with person --}} + + + + {{/if}} + + {{#unless is_blocked}} + {{!-- ignore the person --}} + + + + {{/unless}} +
    + {{/if}} + +
    +
    +{{/if}} diff --git a/app/assets/templates/profile_sidebar_tpl.jst.hbs b/app/assets/templates/profile_sidebar_tpl.jst.hbs index 5f70552e7..69cc76d83 100644 --- a/app/assets/templates/profile_sidebar_tpl.jst.hbs +++ b/app/assets/templates/profile_sidebar_tpl.jst.hbs @@ -5,40 +5,7 @@ {{/linkToPerson}}
    -{{#if do_profile_btns}} -
    - {{{sharingBadge this}}} - - {{#if is_receiving}} - {{!-- create status message with mention --}} -
    - -
    -
    -
    - {{/if}} - - {{#if is_mutual}} - {{!-- create private conversation with person --}} -
    - -
    -
    -
    - {{/if}} - - {{#if is_not_blocked}} - {{!-- ignore the person --}} -
    - -
    -
    -
    - {{/if}} -
    -{{/if}} - -{{#if do_profile_info}} +{{#if show_profile_info}}
      {{#with profile}} {{#if bio}} @@ -66,37 +33,5 @@ {{/if}} {{/with}} - {{#if do_photos}} -
    • -

      - {{t 'profile.photos'}} -
      {{photos.count}}
      -

      -
      - {{#each photos.items}} - {{guid}} - {{/each}} -
      -

      - {{t 'header.view_all'}} -

      -
    • - {{/if}} - {{#if do_contacts}} -
    • -

      - {{t 'profile.contacts'}} -
      {{contacts.count}}
      -

      -
      - {{#each contacts.items}} - {{#linkToPerson this}}{{{personImage this "small"}}}{{/linkToPerson}} - {{/each}} -
      -

      - {{t 'header.view_all'}} -

      -
    • - {{/if}}
    {{/if}} diff --git a/app/controllers/conversations_controller.rb b/app/controllers/conversations_controller.rb index 7a175d315..59c8c7496 100644 --- a/app/controllers/conversations_controller.rb +++ b/app/controllers/conversations_controller.rb @@ -84,7 +84,7 @@ class ConversationsController < ApplicationController end def new - if !params[:facebox] && !session[:mobile_view] && request.format.html? + if !params[:modal] && !session[:mobile_view] && request.format.html? redirect_to conversations_path return end diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index f0782d70a..ff2783c6a 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -6,7 +6,8 @@ class PeopleController < ApplicationController before_action :authenticate_user!, except: [:show, :stream, :last_post] before_action :find_person, only: [:show, :stream, :hovercard] - use_bootstrap_for :index + layout ->(c){ request.format == :mobile ? "application" : "with_header_with_footer" } + use_bootstrap_for :index, :show, :contacts respond_to :html, :except => [:tag_index] respond_to :json, :only => [:index, :show] @@ -77,19 +78,19 @@ class PeopleController < ApplicationController def show mark_corresponding_notifications_read if user_signed_in? - @aspect = :profile # let aspect dropdown create new aspects @person_json = PersonPresenter.new(@person, current_user).full_hash_with_profile respond_to do |format| format.all do + if user_signed_in? + @contact = current_user.contact_for(@person) + end gon.preloads[:person] = @person_json gon.preloads[:photos] = { count: photos_from(@person).count(:all), - items: PhotoPresenter.as_collection(photos_from(@person).limit(8), :base_hash) } gon.preloads[:contacts] = { - count: contact_contacts.count(:all), - items: PersonPresenter.as_collection(contact_contacts.limit(8), :full_hash_with_avatar, current_user) + count: Contact.contact_contacts_for(current_user, @person).count(:all), } respond_with @person end @@ -144,12 +145,20 @@ class PeopleController < ApplicationController def contacts @person = Person.find_by_guid(params[:person_id]) + if @person @contact = current_user.contact_for(@person) - @aspect = :profile - @contacts_of_contact = contact_contacts.paginate(:page => params[:page], :per_page => (params[:limit] || 15)) - @contacts_of_contact_count = contact_contacts.count(:all) + @contacts_of_contact = Contact.contact_contacts_for(current_user, @person) @hashes = hashes_for_people @contacts_of_contact, @aspects + gon.preloads[:person] = PersonPresenter.new(@person, current_user).full_hash_with_profile + gon.preloads[:photos] = { + count: photos_from(@person).count(:all), + } + gon.preloads[:contacts] = { + count: @contacts_of_contact.count(:all), + } + @contacts_of_contact = @contacts_of_contact.paginate(:page => params[:page], :per_page => (params[:limit] || 15)) + respond_with @person else flash[:error] = I18n.t 'people.show.does_not_exist' redirect_to people_path @@ -167,8 +176,9 @@ class PeopleController < ApplicationController @contact = current_user.contact_for(@person) || Contact.new @aspect = :profile if params[:create] # let aspect dropdown create new aspects bootstrap = params[:bootstrap] || false + size = params[:size] || "small" - render :partial => 'aspect_membership_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left', :bootstrap => bootstrap} + render :partial => 'aspect_membership_dropdown', :locals => {:contact => @contact, :person => @person, :hang => 'left', :bootstrap => bootstrap, :size => size} end private @@ -218,20 +228,6 @@ class PeopleController < ApplicationController end.order('created_at desc') end - # given a `@person` find the contacts that person has in that aspect(?) - # or use your own contacts if it's yourself - # see: `Contact#contacts` - def contact_contacts - return Contact.none unless user_signed_in? - - @contact_contacts ||= if @person == current_user.person - current_user.contact_people - else - contact = current_user.contact_for(@person) - contact.try(:contacts) || Contact.none - end - end - def mark_corresponding_notifications_read Notification.where(recipient_id: current_user.id, target_type: "Person", target_id: @person.id, unread: true).each do |n| n.set_read_state( true ) diff --git a/app/controllers/photos_controller.rb b/app/controllers/photos_controller.rb index bce6c7865..8a55700d3 100644 --- a/app/controllers/photos_controller.rb +++ b/app/controllers/photos_controller.rb @@ -5,6 +5,8 @@ class PhotosController < ApplicationController before_action :authenticate_user!, :except => :show + layout ->(c){ request.format == :mobile ? "application" : "with_header_with_footer" } + use_bootstrap_for :index respond_to :html, :json def show @@ -23,21 +25,20 @@ class PhotosController < ApplicationController if @person @contact = current_user.contact_for(@person) - - if @contact - @contacts_of_contact = @contact.contacts - @contacts_of_contact_count = @contact.contacts.count(:all) - else - @contact = Contact.new - end - - @posts = current_user.photos_from(@person, max_time: max_time) - + @posts = current_user.photos_from(@person, max_time: max_time).order('created_at desc') respond_to do |format| - format.all { render 'people/show' } + format.all do + gon.preloads[:person] = PersonPresenter.new(@person, current_user).full_hash_with_profile + gon.preloads[:photos] = { + count: @posts.count(:all), + } + gon.preloads[:contacts] = { + count: Contact.contact_contacts_for(current_user, @person).count(:all), + } + render 'people/show' + end format.json{ render_for_api :backbone, :json => @posts, :root => :photos } end - else flash[:error] = I18n.t 'people.show.does_not_exist' redirect_to people_path diff --git a/app/helpers/aspect_global_helper.rb b/app/helpers/aspect_global_helper.rb index fa47ccc05..5f8f0d9ca 100644 --- a/app/helpers/aspect_global_helper.rb +++ b/app/helpers/aspect_global_helper.rb @@ -3,7 +3,7 @@ # the COPYRIGHT file. module AspectGlobalHelper - def aspect_membership_dropdown(contact, person, hang, aspect=nil, force_bootstrap=false) + def aspect_membership_dropdown(contact, person, hang, aspect=nil, force_bootstrap=false, size="small") aspect_membership_ids = {} selected_aspects = all_aspects.select{|aspect| contact.in_aspect?(aspect)} @@ -12,13 +12,26 @@ module AspectGlobalHelper aspect_membership_ids[a.id] = record.id end + button_class = selected_aspects.size>0 ? "green" : "btn-default" + button_class << case size + when "small" + " btn-small" + when "normal" + "" + when "large" + " btn-large" + else + rase ArgumentError, "unknown size #{size}" + end + if bootstrap? || force_bootstrap render "aspect_memberships/aspect_membership_dropdown", :selected_aspects => selected_aspects, :aspect_membership_ids => aspect_membership_ids, :person => person, :hang => hang, - :dropdown_class => "aspect_membership" + :dropdown_class => "aspect_membership", + :button_class => button_class else render "aspect_memberships/aspect_membership_dropdown_blueprint", :selected_aspects => selected_aspects, diff --git a/app/helpers/contacts_helper.rb b/app/helpers/contacts_helper.rb index 379a073df..5ea96b5a2 100644 --- a/app/helpers/contacts_helper.rb +++ b/app/helpers/contacts_helper.rb @@ -24,11 +24,11 @@ module ContactsHelper def start_a_conversation_link(aspect, contacts_size) suggested_limit = 16 - conv_opts = { class: "conversation_button", rel: "facebox"} + conv_opts = { class: "conversation_button contacts_button"} conv_opts[:title] = t('.many_people_are_you_sure', suggested_limit: suggested_limit) if contacts_size > suggested_limit - link_to new_conversation_path(aspect_id: aspect.id, name: aspect.name, facebox: true), conv_opts do - content_tag(:i, nil, :class => 'entypo mail contacts-header-icon', :title => t('contacts.index.start_a_conversation')) + content_tag :span, conv_opts do + content_tag(:i, nil, :class => 'entypo mail contacts-header-icon', :title => t('contacts.index.start_a_conversation'), 'data-toggle' => 'modal', 'data-target' => '#conversationModal') end end end diff --git a/app/helpers/people_helper.rb b/app/helpers/people_helper.rb index 75a63cd88..63d39af21 100644 --- a/app/helpers/people_helper.rb +++ b/app/helpers/people_helper.rb @@ -77,30 +77,4 @@ module PeopleHelper return Rails.application.routes.url_helpers.person_path(person, opts) end end - - def sharing_message(person, contact) - if contact.sharing? - content_tag(:div, :class => 'sharing_message_container', :title => I18n.t('people.helper.is_sharing', :name => person.name)) do - content_tag(:div, nil, :class => 'icons-check_yes_ok', :id => 'sharing_message') - end - else - content_tag(:div, :class => 'sharing_message_container', :title => I18n.t('people.helper.is_not_sharing', :name => person.name)) do - content_tag(:div, nil, :class => 'icons-circle', :id => 'sharing_message') - end - end - end - - def profile_buttons_class(contact, block) - if block.present? - 'blocked' - elsif contact.mutual? - 'mutual' - elsif contact.sharing? - 'sharing' - elsif contact.receiving? - 'receiving' - else - 'not_sharing' - end - end end diff --git a/app/models/contact.rb b/app/models/contact.rb index 1d7755784..861ec0771 100644 --- a/app/models/contact.rb +++ b/app/models/contact.rb @@ -89,6 +89,17 @@ class Contact < ActiveRecord::Base end end + def self.contact_contacts_for(user, person) + return none unless user + + if person == user.person + user.contact_people + else + contact = user.contact_for(person) + contact.try(:contacts) || none + end + end + private def not_contact_with_closed_account if person_id && person.closed_account? diff --git a/app/views/aspect_memberships/_aspect_membership_dropdown.html.haml b/app/views/aspect_memberships/_aspect_membership_dropdown.html.haml index 7d1cab891..04650a4d8 100644 --- a/app/views/aspect_memberships/_aspect_membership_dropdown.html.haml +++ b/app/views/aspect_memberships/_aspect_membership_dropdown.html.haml @@ -1,5 +1,5 @@ .btn-group.aspect_dropdown.aspect_membership_dropdown - %button.btn.btn-small.dropdown-toggle{:class => selected_aspects.size>0 ? "green" : "btn-default", "data-toggle" => "dropdown", :tabindex => '0'} + %button.btn.dropdown-toggle{:class => button_class, "data-toggle" => "dropdown", :tabindex => '0'} %span.text - if selected_aspects.size == all_aspects.size = t('all_aspects') diff --git a/app/views/contacts/_header.html.haml b/app/views/contacts/_header.html.haml index 1d3ec7e46..ef49831fa 100644 --- a/app/views/contacts/_header.html.haml +++ b/app/views/contacts/_header.html.haml @@ -4,20 +4,20 @@ - if @contacts_size > 0 && @contacts_size < 20 = start_a_conversation_link(@aspect, @contacts_size) - = link_to aspect_toggle_contact_visibility_path(@aspect), id: "contacts_visibility_toggle", method: :put, remote: true do + = link_to aspect_toggle_contact_visibility_path(@aspect), id: "contacts_visibility_toggle", class: "contacts_button", method: :put, remote: true do -if @aspect.contacts_visible? %i.entypo.lock-open.contacts-header-icon{:title => t('aspects.edit.aspect_list_is_visible')} -else %i.entypo.lock.contacts-header-icon{:title => t('aspects.edit.aspect_list_is_not_visible')} - = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete', id: 'delete_aspect' do + = link_to @aspect, method: "delete", data: { confirm: t('aspects.edit.confirm_remove_aspect') }, class: 'delete contacts_button', id: 'delete_aspect' do %i.entypo.trash.contacts-header-icon{:title => t('delete')} .pull-right = search_field_tag :contact_search, "", id: "contact_list_search", class: "search-query", placeholder: t('contacts.index.user_search') %h3 %span#aspect_name = @aspect.name - %span#change_aspect_name + %span#change_aspect_name.contacts_button %i.entypo.pencil.contacts-header-icon{:title => t('aspects.edit.rename')} #aspect_name_form = form_for @aspect, :remote => true do |aspect| @@ -33,4 +33,3 @@ = t('contacts.index.all_contacts') - else = t('contacts.index.my_contacts') - diff --git a/app/views/contacts/index.html.haml b/app/views/contacts/index.html.haml index 4878f1da5..6bf43a513 100644 --- a/app/views/contacts/index.html.haml +++ b/app/views/contacts/index.html.haml @@ -20,3 +20,10 @@ %p != t('.no_contacts_message', :community_spotlight => link_to(t('.community_spotlight'), community_spotlight_path)) + +-if @aspect + #new_conversation_pane + = render 'shared/modal', + :path => new_conversation_path(:aspect_id => @aspect.id, :name => @aspect.name, :modal => true), + :title => t('conversations.index.new_conversation'), + :id => 'conversationModal' diff --git a/app/views/conversations/new.html.haml b/app/views/conversations/new.html.haml new file mode 100644 index 000000000..8462a3990 --- /dev/null +++ b/app/views/conversations/new.html.haml @@ -0,0 +1,11 @@ +:javascript + $(document).ready(function () { + var data = $.parseJSON( "#{escape_javascript(@contacts_json)}" ); + new app.views.ConversationsForm({ + contacts: data, + prefillName: "#{h params[:name]}", + prefillValue: "#{@contact_ids}" + }); + }); + += render 'conversations/new' diff --git a/app/views/conversations/new.haml b/app/views/conversations/new.mobile.haml similarity index 93% rename from app/views/conversations/new.haml rename to app/views/conversations/new.mobile.haml index 4d65275cd..59ea5328a 100644 --- a/app/views/conversations/new.haml +++ b/app/views/conversations/new.mobile.haml @@ -2,9 +2,8 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. -- if in_mobile_view? - = javascript_include_tag :jquery - = javascript_include_tag :mobile += javascript_include_tag :jquery += javascript_include_tag :mobile :javascript $(document).ready(function () { diff --git a/app/views/notifications/index.html.haml b/app/views/notifications/index.html.haml index 19033fe7a..541d030aa 100644 --- a/app/views/notifications/index.html.haml +++ b/app/views/notifications/index.html.haml @@ -20,11 +20,12 @@ - when 'liked' %i.entypo.heart - when 'mentioned' - %i.entypo.pencil + %span.mentionIcon + @ - when 'reshared' %i.entypo.retweet - when 'started_sharing' - %i.entypo.users + %i.entypo.add-user = t('.'+key) .span9.stream.notifications diff --git a/app/views/people/_aspect_membership_dropdown.haml b/app/views/people/_aspect_membership_dropdown.haml index 7efd9f1f3..5bd80d4b3 100644 --- a/app/views/people/_aspect_membership_dropdown.haml +++ b/app/views/people/_aspect_membership_dropdown.haml @@ -1 +1 @@ -= aspect_membership_dropdown(@contact, @person, 'left', nil, bootstrap) += aspect_membership_dropdown(@contact, @person, 'right', nil, bootstrap, size) diff --git a/app/views/people/_profile_sidebar.html.haml b/app/views/people/_profile_sidebar.html.haml deleted file mode 100644 index aedc740d3..000000000 --- a/app/views/people/_profile_sidebar.html.haml +++ /dev/null @@ -1,90 +0,0 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - - -.badge - .profile_photo - = person_image_link(person, :size => :thumb_large, :to => :photos) - - - if user_signed_in? - - if person != current_user.person - %div#profile_buttons{ :class => profile_buttons_class(@contact, @block) } - = sharing_message(@person, @contact) - - - if @contact.receiving? - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-mention', :title => t('people.show.mention'), :id => 'mention_button'), new_status_message_path(:person_id => @person.id), :rel => 'facebox' - .white_bar - - - if @contact.mutual? - - - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-message', :title => t('people.show.message'), :id => 'message_button'), new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :facebox => true), :rel => 'facebox' - .white_bar - - .profile_button - = link_to content_tag(:div, nil, :class => 'icons-ignoreuser block_user', :title => t('ignore'), :id => 'block_user_button', :data => { :person_id => @person.id }), '#', :rel => "nofollow" if @block.blank? - --if user_signed_in? && (contact.sharing? || person == current_user.person) - %ul#profile_information - - - unless person.bio.blank? - %li - %h4 - =t('.bio') - %div{ :class => direction_for(person.bio) } - = person.profile.bio_message.markdownified - - unless person.profile.location.blank? - %li - %h4 - =t('.location') - %div{ :class => direction_for(person.location) } - = person.profile.location_message.markdownified - - - unless person.gender.blank? - %li - %h4 - =t('.gender') - = person.gender - - - unless person.birthday.blank? - %li - %h4 - =t('.born') - = birthday_format(person.birthday) - - if @photos.present? - %li.image_list - %h4 - = t('.photos') - .item_count - = "#{@photos.count(:all)}" - - @photos.limit(8).each do |photo| - = image_tag(photo.url(:thumb_small)) - %br - = link_to t('layouts.header.view_all'), person_photos_path(person) - - - if person == current_user.person - %li.image_list - %h4 - = t('_contacts') - .item_count - = all_contacts_count - .section.contact_pictures - - current_user.contacts.limit(8).each do |contact| - = person_image_link contact.person, :size => :thumb_small - %p.see_all= link_to t('layouts.header.view_all'), contacts_path - - elsif @contact.persisted? && @contacts_of_contact_count > 0 - %li.image_list - %h4 - = t('_contacts') - .item_count - = @contacts_of_contact_count - .section.contact_pictures - -@contacts_of_contact.limit(8).each do |person| - = person_image_link person, :size => :thumb_small - %p.see_all= link_to t('layouts.header.view_all'), person_contacts_path(@person) - - %br - %br diff --git a/app/views/people/_sub_header.html.haml b/app/views/people/_sub_header.html.haml deleted file mode 100644 index 4aef4bd72..000000000 --- a/app/views/people/_sub_header.html.haml +++ /dev/null @@ -1,34 +0,0 @@ -#author_info - .right - - if user_signed_in? && current_user.person != person - - if @block.present? - = link_to t('users.privacy_settings.stop_ignoring'), block_path(@block), - :method => :delete, - :class => "button" - - - else - = aspect_membership_dropdown(contact, person, 'right') - - elsif user_signed_in? && current_user.person == person - = link_to t('people.profile_sidebar.edit_my_profile'), edit_profile_path, :class => 'button creation' - - %h2 - = person.name - %span.diaspora_handle - = person.diaspora_handle - - .description - - if !person.tag_string.blank? && user_signed_in? - = Diaspora::Taggable.format_tags(person.profile.tag_string) - - if person == current_user.person - %span.hover_edit - = link_to t('.edit'), edit_profile_path - - else - - if user_signed_in? && person == current_user.person - %i - = t('.you_have_no_tags') - %span.add_tags - = link_to t('.add_some'), edit_profile_path - - if user_signed_in? && current_page?(person_path current_user.person) - %hr - = render 'aspects/aspect_stream', :stream => @stream -%hr diff --git a/app/views/people/contacts.haml b/app/views/people/contacts.haml index c53f15781..90d89e6eb 100644 --- a/app/views/people/contacts.haml +++ b/app/views/people/contacts.haml @@ -1,21 +1,41 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - - +-# TODO this should happen in the js app - content_for :head do - = javascript_include_tag :people + - if user_signed_in? && @person != current_user.person + :javascript + Mentions.options.prefillMention = Mentions._contactToMention(#{j @person.to_json}); - content_for :page_title do = @person.name -.span-6 - = render :partial => 'people/profile_sidebar', :locals => {:person => @person, :contact => @contact } +.container-fluid#profile_container + .row-fluid + .span3 + #profile + -# here be JS -.span-18.last - = render 'people/sub_header', :person => @person, :contact => @contact + .span9 + .profile_header + -# more JS - #people_stream.stream - - @hashes.each do |hash| - = render :partial => 'people/person', :locals => hash - = will_paginate @contacts_of_contact + .stream_container + #people_stream.stream + - @hashes.each do |hash| + = render :partial => 'people/person', :locals => hash + = will_paginate @contacts_of_contact + + %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} + ⇧ + +-if user_signed_in? && @person + #new_status_message_pane + = render 'shared/modal', + :path => new_status_message_path(:person_id => @person.id), + :title => t('status_messages.new.mentioning', :person => @person.name), + :id => 'mentionModal' + + -if @contact + #new_conversation_pane + = render 'shared/modal', + :path => new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :modal => true), + :title => t('conversations.index.new_conversation'), + :id => 'conversationModal' diff --git a/app/views/people/show.html.haml b/app/views/people/show.html.haml index 937cb4bd4..235c22ccc 100644 --- a/app/views/people/show.html.haml +++ b/app/views/people/show.html.haml @@ -2,7 +2,7 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. - +-# TODO this should happen in the js app - content_for :head do - if user_signed_in? && @person != current_user.person :javascript @@ -11,24 +11,40 @@ - content_for :page_title do = @person.name -.span-6 - #profile - -# here be JS +.container-fluid#profile_container + .row-fluid + .span3 + #profile + -# here be JS -.span-18.last - .profile_header - -# more JS + .span9 + .profile_header + -# more JS - .stream_container + .stream_container - -if user_signed_in? && current_page?(person_path(current_user.person)) - = render 'publisher/publisher', publisher_aspects_for(nil) + -if user_signed_in? && current_page?(person_path(current_user.person)) + = render 'publisher/publisher', publisher_aspects_for(nil) - #main_stream.stream - -# JS + #main_stream.stream + -# JS - #paginate - %span.loader.hidden + #paginate + %span.loader.hidden - %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} - ⇧ + %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} + ⇧ + +-if user_signed_in? && @person + #new_status_message_pane + = render 'shared/modal', + :path => new_status_message_path(:person_id => @person.id), + :title => t('status_messages.new.mentioning', :person => @person.name), + :id => 'mentionModal' + + -if @contact + #new_conversation_pane + = render 'shared/modal', + :path => new_conversation_path(:contact_id => @contact.id, :name => @contact.person.name, :modal => true), + :title => t('conversations.index.new_conversation'), + :id => 'conversationModal' diff --git a/app/views/status_messages/new.html.haml b/app/views/status_messages/new.html.haml index 44a50b7bd..1e6008944 100644 --- a/app/views/status_messages/new.html.haml +++ b/app/views/status_messages/new.html.haml @@ -1,21 +1,19 @@ --# Copyright (c) 2010-2011, Diaspora Inc. This file is --# licensed under the Affero General Public License version 3 or later. See --# the COPYRIGHT file. - = javascript_include_tag :home -#new_status_message_pane - .span-15.last - #facebox_header - %h3 - = t('.mentioning', :person => @person.name) - - = render :partial => 'publisher/publisher', :locals => { :aspect => @aspect, :aspect_ids => @aspect_ids, :selected_aspects => @aspects_with_person, :person => @person} += render :partial => 'publisher/publisher_bootstrap', + :locals => { :aspect => @aspect, + :aspect_ids => @aspect_ids, + :selected_aspects => @aspects_with_person, + :person => @person } :javascript $(function() { app.publisher = new app.views.Publisher({ standalone: true }); - $("#publisher").bind('ajax:success', function(){ location.reload(); }); + app.publisher.open(); + $("#publisher").bind('ajax:success', function(){ + $("#mentionModal").modal('hide'); + location.reload(); + }); }); diff --git a/config/locales/javascript/javascript.en.yml b/config/locales/javascript/javascript.en.yml index e84e0b4a8..57b5da00b 100644 --- a/config/locales/javascript/javascript.en.yml +++ b/config/locales/javascript/javascript.en.yml @@ -134,6 +134,7 @@ en: born: "Birthday" photos: "Photos" contacts: "Contacts" + posts: "Posts" conversation: participants: "Participants" diff --git a/features/desktop/connects_users.feature b/features/desktop/connects_users.feature index efa6f4a05..e90c5cbda 100644 --- a/features/desktop/connects_users.feature +++ b/features/desktop/connects_users.feature @@ -83,7 +83,7 @@ Feature: following and being followed When I sign in as "alice@alice.alice" And I am on "bob@bob.bob"'s page - And I press the first ".toggle.button" + And I press the first ".aspect_membership_dropdown .dropdown-toggle" And I press the first "a" within ".add_aspect" And I fill in "Name" with "Super People" in the modal window @@ -101,16 +101,16 @@ Feature: following and being followed And I am on "alice@alice.alice"'s page Then I should see "Besties" - Then I should see a "#mention_button" within "#profile" - Then I should not see a "#message_button" within "#profile" + Then I should see a "#mention_button" within "#profile_buttons" + Then I should not see a "#message_button" within "#profile_buttons" Scenario: interacting with the profile page of someone who follows you but who you do not follow Given I sign in as "alice@alice.alice" And I am on "bob@bob.bob"'s page Then I should see "Add contact" - Then I should not see a "#mention_button" within "#profile" - Then I should not see a "#message_button" within "#profile" + Then I should not see a "#mention_button" within "#profile_buttons" + Then I should not see a "#message_button" within "#profile_buttons" Scenario: interacting with the profile page of someone you follow who also follows you Given I sign in as "alice@alice.alice" @@ -121,5 +121,5 @@ Feature: following and being followed When I go to "bob@bob.bob"'s page Then I should see "All Aspects" - Then I should see a "#mention_button" within "#profile" - Then I should see a "#message_button" within "#profile" + Then I should see a "#mention_button" within "#profile_buttons" + Then I should see a "#message_button" within "#profile_buttons" diff --git a/features/desktop/contacts.feature b/features/desktop/contacts.feature index 33639826e..97bc87a1b 100644 --- a/features/desktop/contacts.feature +++ b/features/desktop/contacts.feature @@ -13,8 +13,8 @@ Feature: show contacts Scenario: see own contacts on profile When I am on "robert@grimm.grimm"'s page - And I press the first "a" within ".section.contact_pictures" - Then I should see "Alice Smith" + And I press the first "#contacts_link" + Then I should be on the contacts page Scenario: see contacts of a visible aspect list When I am on "bob@bob.bob"'s page @@ -22,7 +22,10 @@ Feature: show contacts And I sign out And I sign in as "alice@alice.alice" And I am on "robert@grimm.grimm"'s page - And I press the first "a" within ".section.contact_pictures" + Then I should see "Contacts" within "#profile_horizontal_bar" + + When I press the first "#contacts_link" + And I press the first "a" within "#people_stream .media-body" Then I should see "Bob Jones" Scenario: don't see contacts of an invisible aspect list @@ -35,4 +38,4 @@ Feature: show contacts And I sign in as "alice@alice.alice" And I am on "robert@grimm.grimm"'s page - Then I should not see "Contacts" within "#profile_information" + Then I should not see "Contacts" within "#profile_horizontal_bar" diff --git a/features/desktop/mentions_from_profile_page.feature b/features/desktop/mentions_from_profile_page.feature index b999523f0..962e8c5e7 100644 --- a/features/desktop/mentions_from_profile_page.feature +++ b/features/desktop/mentions_from_profile_page.feature @@ -23,10 +23,9 @@ Feature: mentioning a contact from their profile page Scenario: mentioning while posting to all aspects Given I am on "alice@alice.alice"'s page - And I have turned off jQuery effects And I want to mention her from the profile And I append "I am eating a yogurt" to the publisher - And I press "Share" in the modal window + And I press "Share" in the mention modal When I am on the aspects page And I follow "PostingTo" within "#aspects_list" Then I should see "I am eating a yogurt" @@ -37,13 +36,12 @@ Feature: mentioning a contact from their profile page Scenario: mentioning while posting to just one aspect Given I am on "alice@alice.alice"'s page - And I have turned off jQuery effects And I want to mention her from the profile - And I press the aspect dropdown in the modal window - And I toggle the aspect "NotPostingThingsHere" in the modal window - And I press the aspect dropdown in the modal window + And I press the aspect dropdown in the mention modal + And I toggle the aspect "NotPostingThingsHere" in the mention modal + And I press the aspect dropdown in the mention modal And I append "I am eating a yogurt" to the publisher - And I press "Share" in the modal window + And I press "Share" in the mention modal When I am on the aspects page And I select only "PostingTo" aspect diff --git a/features/desktop/profile_photos.feature b/features/desktop/profile_photos.feature index 2d7dc10bc..275e31b32 100644 --- a/features/desktop/profile_photos.feature +++ b/features/desktop/profile_photos.feature @@ -10,27 +10,25 @@ Feature: show photos And I sign in as "robert@grimm.grimm" Given I expand the publisher - And I have turned off jQuery effects - And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" - And I press "Share" + And I have turned off jQuery effects + And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" + And I press "Share" Scenario: see my own photos When I am on "robert@grimm.grimm"'s page #TODO: find out why images don't show on first load And I am on "robert@grimm.grimm"'s page - And I follow "View all" within ".image_list" + And I press the first "#photos_link" Then I should be on person_photos page Scenario: I cannot see photos of people who don't share with me When I sign in as "alice@alice.alice" And I am on "robert@grimm.grimm"'s page - Then I should not see "photos" within "div#profile" + Then I should not see "Photos" within "#profile_horizontal_bar" - Scenario: I delete a photo - Given I am on "robert@grimm.grimm"'s photos page - When I delete a photo - And I confirm the alert - Then I should not see "photos" within "div#profile" - - + When I am on "robert@grimm.grimm"'s photos page + And I delete a photo + And I confirm the alert + And I am on "robert@grimm.grimm"'s page + Then I should not see "Photos" within "#profile_horizontal_bar" diff --git a/features/step_definitions/aspects_steps.rb b/features/step_definitions/aspects_steps.rb index e0f827f4a..ad0234174 100644 --- a/features/step_definitions/aspects_steps.rb +++ b/features/step_definitions/aspects_steps.rb @@ -1,19 +1,21 @@ module AspectCukeHelpers def click_aspect_dropdown - find('.dropdown .button').click + # blueprint: .dropdown .button, bootstrap: .aspect_dropdown .dropdown-toggle + find('.dropdown .button, .aspect_dropdown .dropdown-toggle').click end def toggle_aspect(a_name) + # blueprint: .dropdown li, bootstrap: .aspect_dropdown li a_id = @me.aspects.where(name: a_name).pluck(:id).first - aspect_css = ".dropdown li[data-aspect_id='#{a_id}']" + aspect_css = ".dropdown li[data-aspect_id='#{a_id}'], .aspect_dropdown li[data-aspect_id='#{a_id}']" expect(page).to have_selector(aspect_css) find(aspect_css).click end def toggle_aspect_via_ui(aspect_name) - aspects_dropdown = find(".aspect_membership .toggle.button", match: :first) + aspects_dropdown = find(".aspect_membership_dropdown .dropdown-toggle", match: :first) aspects_dropdown.click - aspect = find(".dropdown.active .dropdown_list li", text: aspect_name) + aspect = find(".aspect_membership_dropdown.open .dropdown-menu li", text: aspect_name) aspect.click aspect.parent.should have_no_css(".loading") diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index e74f7168f..ca82cdcf6 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -74,7 +74,7 @@ end And /^I want to mention (?:him|her) from the profile$/ do find('#mention_button').click - within('#facebox') do + within('#mentionModal') do click_publisher end end @@ -130,6 +130,12 @@ When /^(.*) in the modal window$/ do |action| end end +When /^(.*) in the mention modal$/ do |action| + within('#mentionModal') do + step action + end +end + When /^I press the first "([^"]*)"(?: within "([^"]*)")?$/ do |link_selector, within_selector| with_scope(within_selector) do current_scope.find(link_selector, match: :first).click diff --git a/features/step_definitions/posts_steps.rb b/features/step_definitions/posts_steps.rb index 0bcb3ef34..69c86f80b 100644 --- a/features/step_definitions/posts_steps.rb +++ b/features/step_definitions/posts_steps.rb @@ -93,7 +93,7 @@ end When /^I select "([^"]*)" on the aspect dropdown$/ do |text| page.execute_script( - "$('#publisher .dropdown .dropdown_list') + "$('#publisher .dropdown .dropdown_list, #publisher .aspect_dropdown .dropdown-menu') .find('li').each(function(i,el){ var elem = $(el); if ('" + text + "' == $.trim(elem.text()) ) { diff --git a/features/support/paths.rb b/features/support/paths.rb index adc69649e..0f5bf7ba2 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -28,8 +28,8 @@ module NavigationHelpers when /^"([^\"]*)"'s page$/ p = User.find_by_email($1).person { path: person_path(p), - # '.diaspora_handle' on desktop, '.description' on mobile - special_elem: { selector: '.diaspora_handle, .description', text: p.diaspora_handle } + # '#diaspora_handle' on desktop, '.description' on mobile + special_elem: { selector: '#diaspora_handle, .description', text: p.diaspora_handle } } when /^"([^\"]*)"'s photos page$/ p = User.find_by_email($1).person diff --git a/spec/controllers/conversations_controller_spec.rb b/spec/controllers/conversations_controller_spec.rb index 60f363e93..ae07609fc 100644 --- a/spec/controllers/conversations_controller_spec.rb +++ b/spec/controllers/conversations_controller_spec.rb @@ -16,33 +16,33 @@ describe ConversationsController, :type => :controller do end end - describe '#new facebox' do + describe '#new modal' do it 'succeeds' do - get :new, :facebox => true + get :new, :modal => true expect(response).to be_success end it "assigns a json list of contacts that are sharing with the person" do - get :new, :facebox => true + get :new, :modal => true expect(assigns(:contacts_json)).to include(alice.contacts.where(:sharing => true).first.person.name) alice.contacts << Contact.new(:person_id => eve.person.id, :user_id => alice.id, :sharing => false, :receiving => true) expect(assigns(:contacts_json)).not_to include(alice.contacts.where(:sharing => false).first.person.name) end it "assigns a contact if passed a contact id" do - get :new, :contact_id => alice.contacts.first.id, :facebox => true + get :new, :contact_id => alice.contacts.first.id, :modal => true expect(assigns(:contact_ids)).to eq(alice.contacts.first.id) end it "assigns a set of contacts if passed an aspect id" do - get :new, :aspect_id => alice.aspects.first.id, :facebox => true + get :new, :aspect_id => alice.aspects.first.id, :modal => true expect(assigns(:contact_ids)).to eq(alice.aspects.first.contacts.map(&:id).join(',')) end it "does not allow XSS via the name parameter" do ["", '"}]});alert(1);(function f() {var foo = [{b:"'].each do |xss| - get :new, :facebox => true, name: xss + get :new, :modal => true, name: xss expect(response.body).not_to include xss end end @@ -51,7 +51,7 @@ describe ConversationsController, :type => :controller do xss = "" contact = alice.contacts.first contact.person.profile.update_attribute(:first_name, xss) - get :new, :facebox => true + get :new, :modal => true json = JSON.parse(assigns(:contacts_json)).first expect(json['value'].to_s).to eq(contact.id.to_s) expect(json['name']).to_not include(xss) diff --git a/spec/helpers/people_helper_spec.rb b/spec/helpers/people_helper_spec.rb index 31976a4b5..6d633097d 100644 --- a/spec/helpers/people_helper_spec.rb +++ b/spec/helpers/people_helper_spec.rb @@ -101,26 +101,4 @@ describe PeopleHelper, :type => :helper do expect(local_or_remote_person_path(@person)).to eq(person_path(@person)) end end - - describe '#sharing_message' do - before do - @contact = FactoryGirl.create(:contact, :person => @person) - end - - context 'when the contact is sharing' do - it 'shows the sharing message' do - message = I18n.t('people.helper.is_sharing', :name => @person.name) - allow(@contact).to receive(:sharing?).and_return(true) - expect(sharing_message(@person, @contact)).to include(message) - end - end - - context 'when the contact is not sharing' do - it 'does show the not sharing message' do - message = I18n.t('people.helper.is_not_sharing', :name => @person.name) - allow(@contact).to receive(:sharing?).and_return(false) - expect(sharing_message(@person, @contact)).to include(message) - end - end - end end diff --git a/spec/javascripts/app/views/profile_header_view_spec.js b/spec/javascripts/app/views/profile_header_view_spec.js index 82a746c2d..724cc7260 100644 --- a/spec/javascripts/app/views/profile_header_view_spec.js +++ b/spec/javascripts/app/views/profile_header_view_spec.js @@ -4,9 +4,11 @@ describe("app.views.ProfileHeader", function() { this.model = factory.personWithProfile({ diaspora_id: "my@pod", name: "User Name", + relationship: 'mutual', profile: { tags: ['test'] } }); this.view = new app.views.ProfileHeader({model: this.model}); + loginAs(factory.userAttrs()); }); context("#presenter", function() { @@ -17,6 +19,11 @@ describe("app.views.ProfileHeader", function() { is_blocked: false, is_own_profile: false, has_tags: true, + show_profile_btns: true, + relationship: 'mutual', + is_sharing: true, + is_receiving: true, + is_mutual: true, profile: jasmine.objectContaining({ tags: ['test'] }) diff --git a/spec/javascripts/app/views/profile_sidebar_view_spec.js b/spec/javascripts/app/views/profile_sidebar_view_spec.js index d241dc7ce..7a6e7e055 100644 --- a/spec/javascripts/app/views/profile_sidebar_view_spec.js +++ b/spec/javascripts/app/views/profile_sidebar_view_spec.js @@ -24,12 +24,7 @@ describe("app.views.ProfileSidebar", function() { console.log(this.view.presenter()); expect(this.view.presenter()).toEqual(jasmine.objectContaining({ relationship: 'mutual', - do_profile_btns: true, - do_profile_info: true, - is_sharing: true, - is_receiving: true, - is_mutual: true, - is_not_blocked: true, + show_profile_info: true, profile: jasmine.objectContaining({ bio: "confidential", location: "underground", diff --git a/spec/javascripts/app/views/publisher_view_spec.js b/spec/javascripts/app/views/publisher_view_spec.js index 2a86fce7c..87eda3116 100644 --- a/spec/javascripts/app/views/publisher_view_spec.js +++ b/spec/javascripts/app/views/publisher_view_spec.js @@ -247,8 +247,8 @@ describe("app.views.Publisher", function() { spec.loadFixture('status_message_new'); Diaspora.I18n.load({ stream: { public: 'Public' }}); - this.radio_els = $('#publisher .dropdown li.radio'); - this.check_els = $('#publisher .dropdown li.aspect_selector'); + this.radio_els = $('#publisher .aspect_dropdown li.radio'); + this.check_els = $('#publisher .aspect_dropdown li.aspect_selector'); this.visibility_icon = $('#visibility-icon'); this.view = new app.views.Publisher(); @@ -310,8 +310,8 @@ describe("app.views.Publisher", function() { describe("hidden form elements", function(){ beforeEach(function(){ - this.li = $('
  • '); - this.view.$('.dropdown_list').append(this.li); + this.li = $('
  • '); + this.view.$('.dropdown-menu').append(this.li); }); it("removes a previous selection and inserts the current one", function() { @@ -337,8 +337,8 @@ describe("app.views.Publisher", function() { }); it("keeps other fields with different values", function() { - var li2 = $("
  • "); - this.view.$('.dropdown_list').append(li2); + var li2 = $('
  • '); + this.view.$('.dropdown-menu').append(li2); this.li.trigger('click'); li2.trigger('click'); From 805e476c347b58d61d5fa889ddfecdba00d32930 Mon Sep 17 00:00:00 2001 From: Brandon Date: Wed, 1 Oct 2014 06:41:25 -0400 Subject: [PATCH 206/785] Fixed typo From "Seams" to "Seems" --- config/locales/diaspora/en.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/locales/diaspora/en.yml b/config/locales/diaspora/en.yml index cbd2ed9c1..014841156 100644 --- a/config/locales/diaspora/en.yml +++ b/config/locales/diaspora/en.yml @@ -922,7 +922,7 @@ en: review_link: "Mark as reviewed" delete_link: "Delete item" confirm_deletion: "Are you sure to delete the item?" - not_found: "The post/comment was not found. It seams that it was deleted by the user!" + not_found: "The post/comment was not found. It seems that it was deleted by the user!" status: marked: "The report was marked as reviewed" destroyed: "The post was destroyed" From f9564af0ba2f23f9172bb5aff18ed340c4064381 Mon Sep 17 00:00:00 2001 From: Brent Bartlett Date: Wed, 1 Oct 2014 21:51:29 -0700 Subject: [PATCH 207/785] moved hoverable class from
  • to --- app/views/streams/main_stream.html.haml | 13 ++++++------- 1 file changed, 6 insertions(+), 7 deletions(-) diff --git a/app/views/streams/main_stream.html.haml b/app/views/streams/main_stream.html.haml index 82458ace6..03d977bf4 100644 --- a/app/views/streams/main_stream.html.haml +++ b/app/views/streams/main_stream.html.haml @@ -2,7 +2,6 @@ -# licensed under the Affero General Public License version 3 or later. See -# the COPYRIGHT file. - - content_for :head do = javascript_include_tag :home @@ -29,12 +28,12 @@ = link_to current_user.first_name, local_or_remote_person_path(current_user.person) %ul#stream_selection - %li.hoverable{:data => {:stream => 'stream'}} - = link_to t("streams.multi.title"), stream_path, :rel => 'backbone' - %li.hoverable{:data => {:stream => 'activity'}} - = link_to t("streams.activity.title"), activity_stream_path, :rel => 'backbone' - %li.hoverable{:data => {:stream => 'mentions'}} - = link_to t('streams.mentions.title'), mentioned_stream_path, :rel => 'backbone' + %li{:data => {:stream => 'stream'}} + = link_to t("streams.multi.title"), stream_path, :rel => 'backbone', :class => 'hoverable' + %li{:data => {:stream => 'activity'}} + = link_to t("streams.activity.title"), activity_stream_path, :rel => 'backbone', :class => 'hoverable' + %li{:data => {:stream => 'mentions'}} + = link_to t('streams.mentions.title'), mentioned_stream_path, :rel => 'backbone', :class => 'hoverable' %li.all_aspects = render 'aspects/aspect_listings', :stream => @stream %li From 309e690a66bb6fa8a200990df7fb42e2887dad7b Mon Sep 17 00:00:00 2001 From: Jason Robinson Date: Mon, 22 Sep 2014 22:44:22 +0300 Subject: [PATCH 208/785] Fix services in statistics.json. Currently there is a bug in configurate that reports incorrectly the services settings if they are set as ENV variables, instead of diaspora.yml settings. This commit works around that issue by changing the way the setting is fetched. --- Changelog.md | 1 + app/presenters/statistics_presenter.rb | 4 +--- spec/presenters/statistics_presenter_spec.rb | 6 ++++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/Changelog.md b/Changelog.md index 754f3c230..d1454b9e1 100644 --- a/Changelog.md +++ b/Changelog.md @@ -51,6 +51,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Fix deformed getting started popover [#5227](https://github.com/diaspora/diaspora/pull/5227) * Use correct locale for invitation subject [#5232](https://github.com/diaspora/diaspora/pull/5232) * Initial support for IDN emails +* Fix services settings reported by statistics.json [#5256](https://github.com/diaspora/diaspora/pull/5256) ## Features * Don't pull jQuery from a CDN by default [#5105](https://github.com/diaspora/diaspora/pull/5105) diff --git a/app/presenters/statistics_presenter.rb b/app/presenters/statistics_presenter.rb index e07dcc6e0..b264fc3af 100644 --- a/app/presenters/statistics_presenter.rb +++ b/app/presenters/statistics_presenter.rb @@ -17,10 +17,8 @@ class StatisticsPresenter if AppConfig.privacy.statistics.comment_counts? result['local_comments'] = self.local_comments end - AppConfig.services.each do |service, options| - result[service] = options ? !!options["enable"] : false - + result[service] = AppConfig["services.#{service}.enable"] end result diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index 61359752e..a223ecb66 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -18,12 +18,14 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.user_counts = false AppConfig.privacy.statistics.post_counts = false AppConfig.privacy.statistics.comment_counts = false - AppConfig.services = {"facebook" => nil} expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, - "facebook" => false + "facebook" => true, + "twitter" => false, + "tumblr" => false, + "wordpress" => false, }) end From 66c2f7f869e222de474c5185fbd9dc10e9997ec4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Thu, 2 Oct 2014 22:22:03 +0300 Subject: [PATCH 209/785] Fix statistics_presenter_spec --- app/presenters/statistics_presenter.rb | 6 +++--- lib/configuration_methods.rb | 4 +++- spec/presenters/statistics_presenter_spec.rb | 21 +++++++++++++++----- 3 files changed, 22 insertions(+), 9 deletions(-) diff --git a/app/presenters/statistics_presenter.rb b/app/presenters/statistics_presenter.rb index b264fc3af..a3bcb8b32 100644 --- a/app/presenters/statistics_presenter.rb +++ b/app/presenters/statistics_presenter.rb @@ -17,8 +17,8 @@ class StatisticsPresenter if AppConfig.privacy.statistics.comment_counts? result['local_comments'] = self.local_comments end - AppConfig.services.each do |service, options| - result[service] = AppConfig["services.#{service}.enable"] + Configuration::KNOWN_SERVICES.each do |service, options| + result[service.to_s] = AppConfig["services.#{service}.enable"] end result @@ -31,5 +31,5 @@ class StatisticsPresenter def local_comments Comment.joins(:author).where("owner_id IS NOT null").count end - + end diff --git a/lib/configuration_methods.rb b/lib/configuration_methods.rb index 19b852a42..de99b40c8 100644 --- a/lib/configuration_methods.rb +++ b/lib/configuration_methods.rb @@ -1,4 +1,6 @@ module Configuration + KNOWN_SERVICES = [:twitter, :tumblr, :facebook, :wordpress].freeze + module Methods def pod_uri return @pod_uri unless @pod_uri.nil? @@ -24,7 +26,7 @@ module Configuration return @configured_services unless @configured_services.nil? @configured_services = [] - [:twitter, :tumblr, :facebook, :wordpress].each do |service| + KNOWN_SERVICES.each do |service| @configured_services << service if services.send(service).enable? end diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index a223ecb66..99877d5b0 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -13,11 +13,17 @@ describe StatisticsPresenter do end describe '#statistics contents' do - - it 'provides generic pod data in json' do + before do AppConfig.privacy.statistics.user_counts = false AppConfig.privacy.statistics.post_counts = false AppConfig.privacy.statistics.comment_counts = false + end + + after do + AppConfig.privacy = nil + end + + it 'provides generic pod data in json' do expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, "version" => AppConfig.version_string, @@ -28,20 +34,25 @@ describe StatisticsPresenter do "wordpress" => false, }) end - + context 'when services are enabled' do before do AppConfig.privacy.statistics.user_counts = true AppConfig.privacy.statistics.post_counts = true AppConfig.privacy.statistics.comment_counts = true AppConfig.services = { - "facebook" => {"enable" => true}, - "twitter" => {"enable" => true}, + "facebook" => {"enable" => true}, + "twitter" => {"enable" => true}, "wordpress" => {"enable" => false}, "tumblr" => {"enable" => false} } end + after do + AppConfig.services = nil + AppConfig.privacy = nil + end + it 'provides generic pod data and counts in json' do expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, From eac3f042a483851e7324f9f5721e54232d0804e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonne=20Ha=C3=9F?= Date: Fri, 3 Oct 2014 16:51:46 +0200 Subject: [PATCH 210/785] Reset dynamic configuration after each example in the testsuite --- Gemfile | 3 ++- Gemfile.lock | 14 ++++++++++++-- config/initializers/setup_simple_captcha.rb | 1 - spec/controllers/invitations_controller_spec.rb | 2 -- spec/controllers/registrations_controller_spec.rb | 8 ++------ spec/helpers/application_helper_spec.rb | 13 ++----------- spec/lib/rake_helper_spec.rb | 7 +------ spec/models/invitation_code_spec.rb | 12 ++---------- spec/models/user_spec.rb | 14 ++------------ spec/presenters/statistics_presenter_spec.rb | 11 ----------- spec/spec_helper.rb | 5 +++++ 11 files changed, 28 insertions(+), 62 deletions(-) diff --git a/Gemfile b/Gemfile index 77f0c9448..257fbd2d9 100644 --- a/Gemfile +++ b/Gemfile @@ -38,7 +38,7 @@ gem 'uglifier', '2.5.3' # Configuration -gem 'configurate', '0.1.0' +gem 'configurate', '0.2.0' # Cross-origin resource sharing @@ -193,6 +193,7 @@ group :development do # Debugging gem 'pry' gem 'pry-debundle' + gem 'pry-byebug' end group :test do diff --git a/Gemfile.lock b/Gemfile.lock index f6f3e1d09..cdfcbb3fd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -63,6 +63,10 @@ GEM bootstrap-sass (2.3.2.2) sass (~> 3.2) builder (3.2.2) + byebug (3.5.1) + columnize (~> 0.8) + debugger-linecache (~> 1.2) + slop (~> 3.6) capybara (2.4.1) mime-types (>= 1.16) nokogiri (>= 1.3.3) @@ -87,13 +91,14 @@ GEM coffee-script-source execjs coffee-script-source (1.8.0) + columnize (0.8.9) compass (0.12.7) chunky_png (~> 1.2) fssm (>= 0.2.7) sass (~> 3.2.19) compass-rails (2.0.0) compass (>= 0.12.2) - configurate (0.1.0) + configurate (0.2.0) connection_pool (2.0.0) crack (0.4.2) safe_yaml (~> 1.0.0) @@ -110,6 +115,7 @@ GEM nokogiri (~> 1.5) rails (>= 3, < 5) database_cleaner (1.3.0) + debugger-linecache (1.2.0) devise (3.3.0) bcrypt (~> 3.0) orm_adapter (~> 0.1) @@ -317,6 +323,9 @@ GEM coderay (~> 1.1.0) method_source (~> 0.8.1) slop (~> 3.4) + pry-byebug (2.0.0) + byebug (~> 3.4) + pry (~> 0.10) pry-debundle (0.8) pry rack (1.5.2) @@ -514,7 +523,7 @@ DEPENDENCIES capybara (= 2.4.1) carrierwave (= 0.10.0) compass-rails (= 2.0.0) - configurate (= 0.1.0) + configurate (= 0.2.0) cucumber-rails (= 1.4.1) database_cleaner (= 1.3.0) devise (= 3.3.0) @@ -555,6 +564,7 @@ DEPENDENCIES omniauth-wordpress (= 0.2.1) opengraph_parser (= 0.2.3) pry + pry-byebug pry-debundle rack-cors (= 0.2.9) rack-google-analytics (= 1.2.0) diff --git a/config/initializers/setup_simple_captcha.rb b/config/initializers/setup_simple_captcha.rb index 366a5a9f8..cdcb6c2a0 100644 --- a/config/initializers/setup_simple_captcha.rb +++ b/config/initializers/setup_simple_captcha.rb @@ -3,5 +3,4 @@ SimpleCaptcha.setup do |sc| sc.length = [1, [AppConfig.settings.captcha_length.to_i, 12].min].max sc.image_style = AppConfig.settings.captcha.image_style sc.distortion = AppConfig.settings.captcha.distortion - p AppConfig.settings.captcha end diff --git a/spec/controllers/invitations_controller_spec.rb b/spec/controllers/invitations_controller_spec.rb index ee1d05009..c0a0bee68 100644 --- a/spec/controllers/invitations_controller_spec.rb +++ b/spec/controllers/invitations_controller_spec.rb @@ -119,12 +119,10 @@ describe InvitationsController, :type => :controller do end it 'redirects if invitations are closed' do - open_bit = AppConfig.settings.invitations.open? AppConfig.settings.invitations.open = false post :create, @invite expect(response).to be_redirect - AppConfig.settings.invitations.open = open_bit end end diff --git a/spec/controllers/registrations_controller_spec.rb b/spec/controllers/registrations_controller_spec.rb index f70fad126..32ee54b4f 100644 --- a/spec/controllers/registrations_controller_spec.rb +++ b/spec/controllers/registrations_controller_spec.rb @@ -24,10 +24,6 @@ describe RegistrationsController, :type => :controller do AppConfig.settings.enable_registrations = false end - after do - AppConfig.settings.enable_registrations = true - end - it 'redirects #new to the login page' do get :new expect(flash[:error]).to eq(I18n.t('registrations.closed')) @@ -54,7 +50,7 @@ describe RegistrationsController, :type => :controller do describe "#create" do render_views - + context "with valid parameters" do before do AppConfig.settings.enable_registrations = true @@ -113,7 +109,7 @@ describe RegistrationsController, :type => :controller do get :create, @invalid_params expect(response).to render_template("registrations/new") end - + it "keeps invalid params in form" do get :create, @invalid_params expect(response.body).to match /jdoe@example.com/m diff --git a/spec/helpers/application_helper_spec.rb b/spec/helpers/application_helper_spec.rb index b75db9533..8ce0ea39c 100644 --- a/spec/helpers/application_helper_spec.rb +++ b/spec/helpers/application_helper_spec.rb @@ -30,7 +30,6 @@ describe ApplicationHelper, :type => :helper do describe "#all_services_connected?" do before do - @old_configured_services = AppConfig.configured_services AppConfig.configured_services = [1, 2, 3] def current_user @@ -40,7 +39,7 @@ describe ApplicationHelper, :type => :helper do end after do - AppConfig.configured_services = @old_configured_services + AppConfig.configured_services = nil end it 'returns true if all networks are connected' do @@ -91,17 +90,13 @@ describe ApplicationHelper, :type => :helper do describe '#changelog_url' do it 'defaults to master branch changleog' do - old_revision = AppConfig.git_revision AppConfig.git_revision = nil expect(changelog_url).to eq('https://github.com/diaspora/diaspora/blob/master/Changelog.md') - AppConfig.git_revision = old_revision end it 'displays the changelog for the current git revision if set' do - old_revision = AppConfig.git_revision AppConfig.git_revision = '123' expect(changelog_url).to eq('https://github.com/diaspora/diaspora/blob/123/Changelog.md') - AppConfig.git_revision = old_revision end end @@ -112,20 +107,16 @@ describe ApplicationHelper, :type => :helper do end it 'displays the supplied pod_name if it is set' do - old_name = AppConfig.settings.pod_name.get AppConfig.settings.pod_name = "Catspora" + # require 'pry'; binding.pry expect(pod_name).to match "Catspora" - AppConfig.settings.pod_name = old_name end end describe '#pod_version' do - it 'displays the supplied pod_version if it is set' do - old_version = AppConfig.version.number.get AppConfig.version.number = "0.0.1.0" expect(pod_version).to match "0.0.1.0" - AppConfig.version.number = old_version end end end diff --git a/spec/lib/rake_helper_spec.rb b/spec/lib/rake_helper_spec.rb index 1bc16079a..c0db62701 100644 --- a/spec/lib/rake_helper_spec.rb +++ b/spec/lib/rake_helper_spec.rb @@ -10,19 +10,14 @@ describe RakeHelpers do before do @csv = Rails.root.join('spec', 'fixtures', 'test.csv') end + describe '#process_emails' do before do Devise.mailer.deliveries = [] - @old_admin = AppConfig.admins.account.get AppConfig.admins.account = FactoryGirl.create(:user).username end - after do - AppConfig.admins.account = @old_admin - end - it 'should send emails to each email' do - expect(EmailInviter).to receive(:new).exactly(3).times.and_return(double.as_null_object) process_emails(@csv, 100, 1, false) end diff --git a/spec/models/invitation_code_spec.rb b/spec/models/invitation_code_spec.rb index 9e3e95185..61d90583e 100644 --- a/spec/models/invitation_code_spec.rb +++ b/spec/models/invitation_code_spec.rb @@ -7,7 +7,7 @@ describe InvitationCode, :type => :model do it 'sets the count to a default value' do code = FactoryGirl.create(:invitation_code) - expect(code.count).to be > 0 + expect(code.count).to be > 0 end describe '#use!' do @@ -21,16 +21,8 @@ describe InvitationCode, :type => :model do end describe '.default_inviter_or' do - before do - @old_account = AppConfig.admins.account.get - AppConfig.admins.account = 'bob' - end - - after do - AppConfig.admins.account = @old_account - end - it 'grabs the set admin account for the pod...' do + AppConfig.admins.account = 'bob' expect(InvitationCode.default_inviter_or(alice).username).to eq('bob') end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 1f52e78b7..b6bcbf802 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -896,16 +896,6 @@ describe User, :type => :model do FactoryGirl.create(:user) } - before(:each) do - @old_autofollow_value = AppConfig.settings.autofollow_on_join? - @old_autofollow_user = AppConfig.settings.autofollow_on_join_user - end - - after(:each) do - AppConfig.settings.autofollow_on_join = @old_followhq_value - AppConfig.settings.autofollow_on_join_user = @old_autofollow_user - end - context "with autofollow sharing enabled" do it "should start sharing with autofollow account" do AppConfig.settings.autofollow_on_join = true @@ -1005,7 +995,7 @@ describe User, :type => :model do end end end - + describe "sign up" do before do params = {:username => "ohai", @@ -1013,7 +1003,7 @@ describe User, :type => :model do :password => "password", :password_confirmation => "password", :captcha => "12345", - + :person => {:profile => {:first_name => "O", diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index 99877d5b0..a020463b1 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -19,10 +19,6 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.comment_counts = false end - after do - AppConfig.privacy = nil - end - it 'provides generic pod data in json' do expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, @@ -48,11 +44,6 @@ describe StatisticsPresenter do } end - after do - AppConfig.services = nil - AppConfig.privacy = nil - end - it 'provides generic pod data and counts in json' do expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, @@ -70,7 +61,5 @@ describe StatisticsPresenter do }) end end - end - end diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index e4c762b41..d8cb8a519 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -94,6 +94,11 @@ prefork = proc do config.after(:all) do `rm -rf #{Rails.root}/tmp/uploads/*` end + + # Reset overridden settings + config.after(:each) do + AppConfig.reset_dynamic! + end end end From 65e9e1c744410ce56e4e76512af4209bd7b62b0e Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Sat, 4 Oct 2014 14:08:24 +0200 Subject: [PATCH 211/785] Hidden overflow for long names on tag pages --- Changelog.md | 2 +- app/assets/stylesheets/tag.css.scss | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/Changelog.md b/Changelog.md index d1454b9e1..8c947ad07 100644 --- a/Changelog.md +++ b/Changelog.md @@ -42,7 +42,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Display new conversation form on conversations/index [#5178](https://github.com/diaspora/diaspora/pull/5178) * Port profile page to Backbone [#5180](https://github.com/diaspora/diaspora/pull/5180) * Pull punycode.js from rails-assets.org [#5263](https://github.com/diaspora/diaspora/pull/5263) - +* Hidden overflow for long names on tag pages [#5279](https://github.com/diaspora/diaspora/pull/5279) ## Bug fixes * orca cannot see 'Add Contact' button [#5158](https://github.com/diaspora/diaspora/pull/5158) diff --git a/app/assets/stylesheets/tag.css.scss b/app/assets/stylesheets/tag.css.scss index 1ee8427bb..f13a6fc7d 100644 --- a/app/assets/stylesheets/tag.css.scss +++ b/app/assets/stylesheets/tag.css.scss @@ -22,5 +22,15 @@ h1.tag { } #tags_show { - .span3 { border-right: 1px solid $border-grey; } + .span3 { + border-right: 1px solid $border-grey; + .side_stream #people_stream { + .name { display: block; } + .name, .diaspora_handle, .tags { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } } From 03f3c74ceefdfc1077203c831643180c51e032cf Mon Sep 17 00:00:00 2001 From: Alex Nordlund Date: Sun, 5 Oct 2014 01:07:30 +0200 Subject: [PATCH 212/785] Moved services to a JSON list. Added AppConfig.privacy.statistics.deprecated_format to toggle showing the old style format. --- app/presenters/statistics_presenter.rb | 10 +++++++--- config/defaults.yml | 1 + config/diaspora.yml.example | 3 +++ spec/presenters/statistics_presenter_spec.rb | 8 ++++---- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/app/presenters/statistics_presenter.rb b/app/presenters/statistics_presenter.rb index a3bcb8b32..199d64b67 100644 --- a/app/presenters/statistics_presenter.rb +++ b/app/presenters/statistics_presenter.rb @@ -4,7 +4,8 @@ class StatisticsPresenter result = { 'name' => AppConfig.settings.pod_name, 'version' => AppConfig.version_string, - 'registrations_open' => AppConfig.settings.enable_registrations + 'registrations_open' => AppConfig.settings.enable_registrations, + 'services' => [] } if AppConfig.privacy.statistics.user_counts? result['total_users'] = User.count @@ -17,8 +18,11 @@ class StatisticsPresenter if AppConfig.privacy.statistics.comment_counts? result['local_comments'] = self.local_comments end - Configuration::KNOWN_SERVICES.each do |service, options| - result[service.to_s] = AppConfig["services.#{service}.enable"] + result["services"] = Configuration::KNOWN_SERVICES.select {|service| AppConfig["services.#{service}.enable"]}.map(&:to_s) + if AppConfig.privacy.statistics.deprecated_format? + Configuration::KNOWN_SERVICES.each do |service, options| + result[service.to_s] = AppConfig["services.#{service}.enable"] + end end result diff --git a/config/defaults.yml b/config/defaults.yml index 01e2599be..d30c2e009 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -53,6 +53,7 @@ defaults: user_counts: false post_counts: false comment_counts: false + deprecated_format: true settings: pod_name: 'diaspora*' enable_registrations: true diff --git a/config/diaspora.yml.example b/config/diaspora.yml.example index 0555ee9bc..4438d5e6a 100644 --- a/config/diaspora.yml.example +++ b/config/diaspora.yml.example @@ -209,6 +209,9 @@ configuration: ## Section ## Local post total count #post_counts: true #comment_counts: true + + ## Also show old services block (enabled by default) + #deprecated_format: false ## General settings settings: ## Section diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index a020463b1..3debcb598 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -17,6 +17,7 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.user_counts = false AppConfig.privacy.statistics.post_counts = false AppConfig.privacy.statistics.comment_counts = false + AppConfig.privacy.statistics.deprecated_format = false end it 'provides generic pod data in json' do @@ -24,10 +25,7 @@ describe StatisticsPresenter do "name" => AppConfig.settings.pod_name, "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, - "facebook" => true, - "twitter" => false, - "tumblr" => false, - "wordpress" => false, + "services"=> ["facebook",] }) end @@ -36,6 +34,7 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.user_counts = true AppConfig.privacy.statistics.post_counts = true AppConfig.privacy.statistics.comment_counts = true + AppConfig.privacy.statistics.deprecated_format = true AppConfig.services = { "facebook" => {"enable" => true}, "twitter" => {"enable" => true}, @@ -54,6 +53,7 @@ describe StatisticsPresenter do "active_users_monthly" => User.monthly_actives.count, "local_posts" => @presenter.local_posts, "local_comments" => @presenter.local_comments, + "services" => ["twitter","facebook"], "facebook" => true, "twitter" => true, "tumblr" => false, From acc7377e5f3b2b0df39d3d09ca8525ec38911d7e Mon Sep 17 00:00:00 2001 From: Alex Nordlund Date: Sun, 5 Oct 2014 01:45:48 +0200 Subject: [PATCH 213/785] Removed setting for statistics, showing both instead. --- app/presenters/statistics_presenter.rb | 6 ++---- config/defaults.yml | 1 - config/diaspora.yml.example | 3 --- spec/presenters/statistics_presenter_spec.rb | 8 +++++--- 4 files changed, 7 insertions(+), 11 deletions(-) diff --git a/app/presenters/statistics_presenter.rb b/app/presenters/statistics_presenter.rb index 199d64b67..f723fc639 100644 --- a/app/presenters/statistics_presenter.rb +++ b/app/presenters/statistics_presenter.rb @@ -19,10 +19,8 @@ class StatisticsPresenter result['local_comments'] = self.local_comments end result["services"] = Configuration::KNOWN_SERVICES.select {|service| AppConfig["services.#{service}.enable"]}.map(&:to_s) - if AppConfig.privacy.statistics.deprecated_format? - Configuration::KNOWN_SERVICES.each do |service, options| - result[service.to_s] = AppConfig["services.#{service}.enable"] - end + Configuration::KNOWN_SERVICES.each do |service, options| + result[service.to_s] = AppConfig["services.#{service}.enable"] end result diff --git a/config/defaults.yml b/config/defaults.yml index d30c2e009..01e2599be 100644 --- a/config/defaults.yml +++ b/config/defaults.yml @@ -53,7 +53,6 @@ defaults: user_counts: false post_counts: false comment_counts: false - deprecated_format: true settings: pod_name: 'diaspora*' enable_registrations: true diff --git a/config/diaspora.yml.example b/config/diaspora.yml.example index 4438d5e6a..d0f26efbb 100644 --- a/config/diaspora.yml.example +++ b/config/diaspora.yml.example @@ -210,9 +210,6 @@ configuration: ## Section #post_counts: true #comment_counts: true - ## Also show old services block (enabled by default) - #deprecated_format: false - ## General settings settings: ## Section diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index 3debcb598..ebd6e2ff7 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -17,7 +17,6 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.user_counts = false AppConfig.privacy.statistics.post_counts = false AppConfig.privacy.statistics.comment_counts = false - AppConfig.privacy.statistics.deprecated_format = false end it 'provides generic pod data in json' do @@ -25,7 +24,11 @@ describe StatisticsPresenter do "name" => AppConfig.settings.pod_name, "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, - "services"=> ["facebook",] + "services"=> ["facebook",], + "facebook" => true, + "tumblr" => false, + "twitter" => false, + "wordpress" => false, }) end @@ -34,7 +37,6 @@ describe StatisticsPresenter do AppConfig.privacy.statistics.user_counts = true AppConfig.privacy.statistics.post_counts = true AppConfig.privacy.statistics.comment_counts = true - AppConfig.privacy.statistics.deprecated_format = true AppConfig.services = { "facebook" => {"enable" => true}, "twitter" => {"enable" => true}, From 1df8f0cf20b96022e7b28e2a61c5201e209962eb Mon Sep 17 00:00:00 2001 From: Roy McKenzie Date: Sat, 4 Oct 2014 17:58:39 -0700 Subject: [PATCH 214/785] Added classes to the body for easier page specific styling. --- app/views/layouts/application.html.haml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/views/layouts/application.html.haml b/app/views/layouts/application.html.haml index 7f6a6d9fb..1924d2956 100644 --- a/app/views/layouts/application.html.haml +++ b/app/views/layouts/application.html.haml @@ -52,7 +52,7 @@ = include_gon(:camel_case => true) - %body + %body{ :class => "page-#{controller_name} action-#{action_name}" } = flash_messages = yield :before_content From 82a8673a36bfc54d37dcf3fb5536c42ff0365876 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Mon, 6 Oct 2014 20:00:07 +0200 Subject: [PATCH 215/785] Add margin to reshare --- app/assets/stylesheets/stream_element.css.scss | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/stream_element.css.scss b/app/assets/stylesheets/stream_element.css.scss index 16c29e736..afeda4c1b 100644 --- a/app/assets/stylesheets/stream_element.css.scss +++ b/app/assets/stylesheets/stream_element.css.scss @@ -75,9 +75,11 @@ } } - .reshare > .media { + .reshare { border-left: 2px solid $border-grey; - .avatar { + margin-top: 3px; + + & > .media .avatar { height: 30px; width: 30px; } From bd24d6bebe6805b412a11df9f8bfcf67cf7af7cb Mon Sep 17 00:00:00 2001 From: jaideng123 Date: Mon, 6 Oct 2014 13:55:46 -0500 Subject: [PATCH 216/785] Added cucumber test for notifications dropdown --- .../widgets/notifications-badge.js | 5 ++++- features/desktop/notifications.feature | 21 +++++++++++++++++++ features/step_definitions/custom_web_steps.rb | 21 +++++++++++++++++++ features/step_definitions/mention_steps.rb | 9 ++++++++ 4 files changed, 55 insertions(+), 1 deletion(-) diff --git a/app/assets/javascripts/widgets/notifications-badge.js b/app/assets/javascripts/widgets/notifications-badge.js index fc2c1d3c4..6c775b9be 100644 --- a/app/assets/javascripts/widgets/notifications-badge.js +++ b/app/assets/javascripts/widgets/notifications-badge.js @@ -46,6 +46,7 @@ self.ajaxLoader.show(); self.badge.addClass("active"); self.dropdown.css("display", "block"); + $('.notifications').addClass("loading"); self.getNotifications(); }; @@ -92,12 +93,14 @@ $('.notifications').perfectScrollbar(); self.ajaxLoader.hide(); isLoading = false; + $('.notifications').removeClass("loading"); //Infinite Scrolling $('.notifications').scroll(function(e) { var bottom = $('.notifications').prop('scrollHeight') - $('.notifications').height(); var currentPosition = $('.notifications').scrollTop(); + isLoading = ($('.loading').length == 1); if (currentPosition + 50 >= bottom && notificationsLoaded <= self.notifications.length && !isLoading) { - isLoading = true; + $('.notifications').addClass("loading"); ++currentPage; self.getMoreNotifications(); } diff --git a/features/desktop/notifications.feature b/features/desktop/notifications.feature index eeafce68c..a94b23df7 100644 --- a/features/desktop/notifications.feature +++ b/features/desktop/notifications.feature @@ -97,3 +97,24 @@ Feature: Notifications And I active the first hovercard after loading the notifications page When I press the aspect dropdown Then the aspect dropdown should be visible + + Scenario: scrollbar shows up when >5 notifications + Given a user with email "bob@bob.bob" is connected with "alice@alice.alice" + And Alice has 6 posts mentioning Bob + When I sign in as "bob@bob.bob" + And I follow "Notifications" in the header + Then the notification dropdown should be visible + Then the notification dropdown scrollbar should be visible + + Scenario: dropdown will load more elements when bottom is reached + Given a user with email "bob@bob.bob" is connected with "alice@alice.alice" + And Alice has 20 posts mentioning Bob + When I sign in as "bob@bob.bob" + And I follow "Notifications" in the header + Then the notification dropdown should be visible + Then the notification dropdown scrollbar should be visible + Then there should be 10 notifications loaded + When I scroll down on the notifications dropdown + Then I should have scrolled down on the notification dropdown + And I wait for notifications to load + Then there should be 15 notifications loaded \ No newline at end of file diff --git a/features/step_definitions/custom_web_steps.rb b/features/step_definitions/custom_web_steps.rb index e74f7168f..e5f6b1d3b 100644 --- a/features/step_definitions/custom_web_steps.rb +++ b/features/step_definitions/custom_web_steps.rb @@ -184,15 +184,36 @@ end And /^I scroll down$/ do page.execute_script("window.scrollBy(0,3000000)") end +And /^I scroll down on the notifications dropdown$/ do + page.execute_script("$('.notifications').scrollTop(350)") +end Then /^I should have scrolled down$/ do page.evaluate_script("window.pageYOffset").should > 0 end +Then /^I should have scrolled down on the notification dropdown$/ do + page.evaluate_script("$('.notifications').scrollTop()").should > 0 +end + + Then /^the notification dropdown should be visible$/ do find(:css, "#notification_dropdown").should be_visible end +Then /^the notification dropdown scrollbar should be visible$/ do + find(:css, ".ps-active-y").should be_visible +end + +Then /^there should be (\d+) notifications loaded$/ do |n| + result = page.evaluate_script("$('.notification_element').length") + result.should == n.to_i +end + +And "I wait for notifications to load" do + page.should_not have_selector(".loading") +end + When /^I resize my window to 800x600$/ do page.execute_script <<-JS window.resizeTo(800,600); diff --git a/features/step_definitions/mention_steps.rb b/features/step_definitions/mention_steps.rb index e270ea875..f7939afbe 100644 --- a/features/step_definitions/mention_steps.rb +++ b/features/step_definitions/mention_steps.rb @@ -5,6 +5,15 @@ And /^Alice has a post mentioning Bob$/ do alice.post(:status_message, :text => "@{Bob Jones; #{bob.person.diaspora_handle}}", :to => aspect) end +And /^Alice has (\d+) posts mentioning Bob$/ do |n| + n.to_i.times do + alice = User.find_by_email 'alice@alice.alice' + bob = User.find_by_email 'bob@bob.bob' + aspect = alice.aspects.where(:name => "Besties").first + alice.post(:status_message, :text => "@{Bob Jones; #{bob.person.diaspora_handle}}", :to => aspect) + end +end + And /^I mention Alice in the publisher$/ do alice = User.find_by_email 'alice@alice.alice' write_in_publisher("@{Alice Smith ; #{alice.person.diaspora_handle}}") From d7e8e2ce2c367ee39eea276e659788b7d59c3a6a Mon Sep 17 00:00:00 2001 From: Sandip Trivedi Date: Mon, 6 Oct 2014 18:54:50 -0400 Subject: [PATCH 217/785] Replaced jquery.textchange.js vendored asset with a bower package #5194 --- Gemfile | 1 + Gemfile.lock | 3 + .../javascripts/app/views/publisher_view.js | 2 +- config/application.rb | 2 +- .../assets/javascripts/jquery.textchange.js | 76 ------------------- 5 files changed, 6 insertions(+), 78 deletions(-) delete mode 100644 vendor/assets/javascripts/jquery.textchange.js diff --git a/Gemfile b/Gemfile index 257fbd2d9..5a0fdd46c 100644 --- a/Gemfile +++ b/Gemfile @@ -86,6 +86,7 @@ gem 'rails-assets-punycode', '1.3.1' # jQuery plugins +gem 'rails-assets-jquery-textchange', '0.2.3' gem 'rails-assets-perfect-scrollbar', '0.4.11' # Localization diff --git a/Gemfile.lock b/Gemfile.lock index cdfcbb3fd..b26e349bd 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -357,6 +357,8 @@ GEM railties (= 4.1.6) sprockets-rails (~> 2.0) rails-assets-jquery (1.11.1) + rails-assets-jquery-textchange (0.2.3) + rails-assets-jquery rails-assets-perfect-scrollbar (0.4.11) rails-assets-jquery (>= 1.10) rails-assets-punycode (1.3.1) @@ -574,6 +576,7 @@ DEPENDENCIES rack-ssl (= 1.4.1) rails (= 4.1.6) rails-assets-jquery (= 1.11.1) + rails-assets-jquery-textchange (= 0.2.3) rails-assets-perfect-scrollbar (= 0.4.11) rails-assets-punycode (= 1.3.1) rails-i18n (= 4.0.3) diff --git a/app/assets/javascripts/app/views/publisher_view.js b/app/assets/javascripts/app/views/publisher_view.js index 876ad8339..2f20a3b44 100644 --- a/app/assets/javascripts/app/views/publisher_view.js +++ b/app/assets/javascripts/app/views/publisher_view.js @@ -8,7 +8,7 @@ //= require ./publisher/aspect_selector_blueprint_view //= require ./publisher/getting_started_view //= require ./publisher/uploader_view -//= require jquery.textchange +//= require jquery-textchange app.views.Publisher = Backbone.View.extend({ diff --git a/config/application.rb b/config/application.rb index a54bdeb32..f9c14f113 100644 --- a/config/application.rb +++ b/config/application.rb @@ -57,7 +57,7 @@ module Diaspora inbox.js jquery.js jquery_ujs.js - jquery.textchange.js + jquery-textchange.js mailchimp.js main.js mobile.js diff --git a/vendor/assets/javascripts/jquery.textchange.js b/vendor/assets/javascripts/jquery.textchange.js deleted file mode 100644 index 3affea18e..000000000 --- a/vendor/assets/javascripts/jquery.textchange.js +++ /dev/null @@ -1,76 +0,0 @@ -/*! - * jQuery TextChange Plugin - * http://www.zurb.com/playground/jquery-text-change-custom-event - * - * Copyright 2010, ZURB - * Released under the MIT License - */ -(function ($) { - - $.event.special.textchange = { - - setup: function (data, namespaces) { - $(this).data('lastValue', this.contentEditable === 'true' ? $(this).html() : $(this).val()); - $(this).bind('keyup.textchange', $.event.special.textchange.handler); - $(this).bind('cut.textchange paste.textchange input.textchange', $.event.special.textchange.delayedHandler); - }, - - teardown: function (namespaces) { - $(this).unbind('.textchange'); - }, - - handler: function (event) { - $.event.special.textchange.triggerIfChanged($(this)); - }, - - delayedHandler: function (event) { - var element = $(this); - setTimeout(function () { - $.event.special.textchange.triggerIfChanged(element); - }, 25); - }, - - triggerIfChanged: function (element) { - var current = element[0].contentEditable === 'true' ? element.html() : element.val(); - if (current !== element.data('lastValue')) { - element.trigger('textchange', [element.data('lastValue')]); - element.data('lastValue', current); - } - } - }; - - $.event.special.hastext = { - - setup: function (data, namespaces) { - $(this).bind('textchange', $.event.special.hastext.handler); - }, - - teardown: function (namespaces) { - $(this).unbind('textchange', $.event.special.hastext.handler); - }, - - handler: function (event, lastValue) { - if ((lastValue === '') && lastValue !== $(this).val()) { - $(this).trigger('hastext'); - } - } - }; - - $.event.special.notext = { - - setup: function (data, namespaces) { - $(this).bind('textchange', $.event.special.notext.handler); - }, - - teardown: function (namespaces) { - $(this).unbind('textchange', $.event.special.notext.handler); - }, - - handler: function (event, lastValue) { - if ($(this).val() === '' && $(this).val() !== lastValue) { - $(this).trigger('notext'); - } - } - }; - -})(jQuery); \ No newline at end of file From 2af32220a56f14e281bed0a9a7d29dd1548f70ad Mon Sep 17 00:00:00 2001 From: Sandip Trivedi Date: Tue, 7 Oct 2014 00:46:24 -0400 Subject: [PATCH 218/785] Replaced jquery.placeholder.js vendored asset with a bower package #5194 --- Gemfile | 5 +- Gemfile.lock | 2 + app/assets/javascripts/main.js | 2 +- .../assets/javascripts/jquery.placeholder.js | 104 ------------------ 4 files changed, 6 insertions(+), 107 deletions(-) delete mode 100644 vendor/assets/javascripts/jquery.placeholder.js diff --git a/Gemfile b/Gemfile index 5a0fdd46c..ab1ebcc79 100644 --- a/Gemfile +++ b/Gemfile @@ -86,8 +86,9 @@ gem 'rails-assets-punycode', '1.3.1' # jQuery plugins -gem 'rails-assets-jquery-textchange', '0.2.3' -gem 'rails-assets-perfect-scrollbar', '0.4.11' +gem 'rails-assets-jquery-placeholder', '1.8.7' +gem 'rails-assets-jquery-textchange', '0.2.3' +gem 'rails-assets-perfect-scrollbar', '0.4.11' # Localization diff --git a/Gemfile.lock b/Gemfile.lock index b26e349bd..7dd5e88e2 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -357,6 +357,7 @@ GEM railties (= 4.1.6) sprockets-rails (~> 2.0) rails-assets-jquery (1.11.1) + rails-assets-jquery-placeholder (1.8.7) rails-assets-jquery-textchange (0.2.3) rails-assets-jquery rails-assets-perfect-scrollbar (0.4.11) @@ -576,6 +577,7 @@ DEPENDENCIES rack-ssl (= 1.4.1) rails (= 4.1.6) rails-assets-jquery (= 1.11.1) + rails-assets-jquery-placeholder (= 1.8.7) rails-assets-jquery-textchange (= 0.2.3) rails-assets-perfect-scrollbar (= 0.4.11) rails-assets-punycode (= 1.3.1) diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index a0d61d8bd..b0ae002b8 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -10,7 +10,7 @@ //= require jquery.remotipart //= require jquery.autoresize //= require jquery.charcount -//= require jquery.placeholder +//= require jquery-placeholder //= require rails-timeago //= require facebox //= require browser_detection diff --git a/vendor/assets/javascripts/jquery.placeholder.js b/vendor/assets/javascripts/jquery.placeholder.js deleted file mode 100644 index b4bbc7cbe..000000000 --- a/vendor/assets/javascripts/jquery.placeholder.js +++ /dev/null @@ -1,104 +0,0 @@ -/*! http://mths.be/placeholder v1.8.7 by @mathias */ -;(function(window, document, $) { - - var isInputSupported = 'placeholder' in document.createElement('input'), - isTextareaSupported = 'placeholder' in document.createElement('textarea'), - prototype = $.fn, - placeholder; - - if (isInputSupported && isTextareaSupported) { - - placeholder = prototype.placeholder = function() { - return this; - }; - - placeholder.input = placeholder.textarea = true; - - } else { - - placeholder = prototype.placeholder = function() { - return this - .filter((isInputSupported ? 'textarea' : ':input') + '[placeholder]') - .not('.placeholder') - .bind('focus.placeholder', clearPlaceholder) - .bind('blur.placeholder', setPlaceholder) - .trigger('blur.placeholder').end(); - }; - - placeholder.input = isInputSupported; - placeholder.textarea = isTextareaSupported; - - $(function() { - // Look for forms - $(document).delegate('form', 'submit.placeholder', function() { - // Clear the placeholder values so they don’t get submitted - var $inputs = $('.placeholder', this).each(clearPlaceholder); - setTimeout(function() { - $inputs.each(setPlaceholder); - }, 10); - }); - }); - - // Clear placeholder values upon page reload - $(window).bind('unload.placeholder', function() { - $('.placeholder').val(''); - }); - - } - - function args(elem) { - // Return an object of element attributes - var newAttrs = {}, - rinlinejQuery = /^jQuery\d+$/; - $.each(elem.attributes, function(i, attr) { - if (attr.specified && !rinlinejQuery.test(attr.name)) { - newAttrs[attr.name] = attr.value; - } - }); - return newAttrs; - } - - function clearPlaceholder() { - var $input = $(this); - if ($input.val() === $input.attr('placeholder') && $input.hasClass('placeholder')) { - if ($input.data('placeholder-password')) { - $input.hide().next().show().focus().attr('id', $input.removeAttr('id').data('placeholder-id')); - } else { - $input.val('').removeClass('placeholder'); - } - } - } - - function setPlaceholder() { - var $replacement, - $input = $(this), - $origInput = $input, - id = this.id; - if ($input.val() === '') { - if ($input.is(':password')) { - if (!$input.data('placeholder-textinput')) { - try { - $replacement = $input.clone().attr({ 'type': 'text' }); - } catch(e) { - $replacement = $('').attr($.extend(args(this), { 'type': 'text' })); - } - $replacement - .removeAttr('name') - // We could just use the `.data(obj)` syntax here, but that wouldn’t work in pre-1.4.3 jQueries - .data('placeholder-password', true) - .data('placeholder-id', id) - .bind('focus.placeholder', clearPlaceholder); - $input - .data('placeholder-textinput', $replacement) - .data('placeholder-id', id) - .before($replacement); - } - $input = $input.removeAttr('id').hide().prev().attr('id', id).show(); - } - $input.addClass('placeholder').val($input.attr('placeholder')); - } else { - $input.removeClass('placeholder'); - } - } - -}(this, document, jQuery)); \ No newline at end of file From eb916f2690c266b8b0669acc1b1e769678612ae8 Mon Sep 17 00:00:00 2001 From: Sandip Trivedi Date: Tue, 7 Oct 2014 00:56:37 -0400 Subject: [PATCH 219/785] Update jquery.placeholder.js from 1.8.7 to 2.0.8 #5194 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index ab1ebcc79..6e4b9a367 100644 --- a/Gemfile +++ b/Gemfile @@ -86,7 +86,7 @@ gem 'rails-assets-punycode', '1.3.1' # jQuery plugins -gem 'rails-assets-jquery-placeholder', '1.8.7' +gem 'rails-assets-jquery-placeholder', '2.0.8' gem 'rails-assets-jquery-textchange', '0.2.3' gem 'rails-assets-perfect-scrollbar', '0.4.11' diff --git a/Gemfile.lock b/Gemfile.lock index 7dd5e88e2..6d93daccf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -357,7 +357,7 @@ GEM railties (= 4.1.6) sprockets-rails (~> 2.0) rails-assets-jquery (1.11.1) - rails-assets-jquery-placeholder (1.8.7) + rails-assets-jquery-placeholder (2.0.8) rails-assets-jquery-textchange (0.2.3) rails-assets-jquery rails-assets-perfect-scrollbar (0.4.11) @@ -577,7 +577,7 @@ DEPENDENCIES rack-ssl (= 1.4.1) rails (= 4.1.6) rails-assets-jquery (= 1.11.1) - rails-assets-jquery-placeholder (= 1.8.7) + rails-assets-jquery-placeholder (= 2.0.8) rails-assets-jquery-textchange (= 0.2.3) rails-assets-perfect-scrollbar (= 0.4.11) rails-assets-punycode (= 1.3.1) From d04cf7046b93d03e8d232b69afebcd0bec0e1d58 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Tue, 7 Oct 2014 10:55:58 +0200 Subject: [PATCH 220/785] Fix pagination for people/guid/contacts --- app/assets/stylesheets/profile.css.scss | 2 ++ app/controllers/people_controller.rb | 2 +- app/views/people/contacts.haml | 2 +- 3 files changed, 4 insertions(+), 2 deletions(-) diff --git a/app/assets/stylesheets/profile.css.scss b/app/assets/stylesheets/profile.css.scss index aabcb0e2e..00d566a87 100644 --- a/app/assets/stylesheets/profile.css.scss +++ b/app/assets/stylesheets/profile.css.scss @@ -119,4 +119,6 @@ } } + + .stream_container > .pagination { text-align: center; } } diff --git a/app/controllers/people_controller.rb b/app/controllers/people_controller.rb index ff2783c6a..030e2cd8c 100644 --- a/app/controllers/people_controller.rb +++ b/app/controllers/people_controller.rb @@ -149,7 +149,6 @@ class PeopleController < ApplicationController if @person @contact = current_user.contact_for(@person) @contacts_of_contact = Contact.contact_contacts_for(current_user, @person) - @hashes = hashes_for_people @contacts_of_contact, @aspects gon.preloads[:person] = PersonPresenter.new(@person, current_user).full_hash_with_profile gon.preloads[:photos] = { count: photos_from(@person).count(:all), @@ -158,6 +157,7 @@ class PeopleController < ApplicationController count: @contacts_of_contact.count(:all), } @contacts_of_contact = @contacts_of_contact.paginate(:page => params[:page], :per_page => (params[:limit] || 15)) + @hashes = hashes_for_people @contacts_of_contact, @aspects respond_with @person else flash[:error] = I18n.t 'people.show.does_not_exist' diff --git a/app/views/people/contacts.haml b/app/views/people/contacts.haml index 90d89e6eb..4046fdb47 100644 --- a/app/views/people/contacts.haml +++ b/app/views/people/contacts.haml @@ -21,7 +21,7 @@ #people_stream.stream - @hashes.each do |hash| = render :partial => 'people/person', :locals => hash - = will_paginate @contacts_of_contact + = will_paginate @contacts_of_contact, :renderer => WillPaginate::ActionView::BootstrapLinkRenderer %a{:id=>"back-to-top", :title=>"#{t('layouts.application.back_to_top')}", :href=>"#"} ⇧ From adc839d6202046fbea32bb91507378a74daf6c00 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Wed, 8 Oct 2014 01:02:57 +0200 Subject: [PATCH 221/785] Add network key to statistics.json, close #5042 --- Changelog.md | 1 + app/presenters/statistics_presenter.rb | 1 + spec/presenters/statistics_presenter_spec.rb | 2 ++ 3 files changed, 4 insertions(+) diff --git a/Changelog.md b/Changelog.md index fa44e79ee..bc03dc818 100644 --- a/Changelog.md +++ b/Changelog.md @@ -61,6 +61,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Increased the number of notifications shown in drop down bar to 15 [#5129](https://github.com/diaspora/diaspora/pull/5129) * Increase possible captcha length [#5169](https://github.com/diaspora/diaspora/pull/5169) * Display visibility icon in publisher aspects dropdown [#4982](https://github.com/diaspora/diaspora/pull/4982) +* Add the "network" key to statistics.json and set it to "Diaspora" [#5308](https://github.com/diaspora/diaspora/pull/5308) # 0.4.1.1 diff --git a/app/presenters/statistics_presenter.rb b/app/presenters/statistics_presenter.rb index a3bcb8b32..c21217ac2 100644 --- a/app/presenters/statistics_presenter.rb +++ b/app/presenters/statistics_presenter.rb @@ -3,6 +3,7 @@ class StatisticsPresenter def as_json(options={}) result = { 'name' => AppConfig.settings.pod_name, + 'network' => "Diaspora", 'version' => AppConfig.version_string, 'registrations_open' => AppConfig.settings.enable_registrations } diff --git a/spec/presenters/statistics_presenter_spec.rb b/spec/presenters/statistics_presenter_spec.rb index a020463b1..bceb463f4 100644 --- a/spec/presenters/statistics_presenter_spec.rb +++ b/spec/presenters/statistics_presenter_spec.rb @@ -22,6 +22,7 @@ describe StatisticsPresenter do it 'provides generic pod data in json' do expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, + "network" => "Diaspora", "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, "facebook" => true, @@ -47,6 +48,7 @@ describe StatisticsPresenter do it 'provides generic pod data and counts in json' do expect(@presenter.as_json).to eq({ "name" => AppConfig.settings.pod_name, + "network" => "Diaspora", "version" => AppConfig.version_string, "registrations_open" => AppConfig.settings.enable_registrations, "total_users" => User.count, From 215fc1c96b804bd6a31aeb4a90720c7ee6b2b615 Mon Sep 17 00:00:00 2001 From: Sandip Trivedi Date: Wed, 8 Oct 2014 00:00:14 -0400 Subject: [PATCH 222/785] Replaced jquery.idle-timer.js vendored asset with a bower package #5194 --- Gemfile | 1 + Gemfile.lock | 2 + app/assets/javascripts/main.js | 2 +- .../assets/javascripts/jquery.idle-timer.js | 246 ------------------ 4 files changed, 4 insertions(+), 247 deletions(-) delete mode 100644 vendor/assets/javascripts/jquery.idle-timer.js diff --git a/Gemfile b/Gemfile index 6e4b9a367..aff8b7649 100644 --- a/Gemfile +++ b/Gemfile @@ -86,6 +86,7 @@ gem 'rails-assets-punycode', '1.3.1' # jQuery plugins +gem 'rails-assets-jquery-idletimer', '0.9.3' gem 'rails-assets-jquery-placeholder', '2.0.8' gem 'rails-assets-jquery-textchange', '0.2.3' gem 'rails-assets-perfect-scrollbar', '0.4.11' diff --git a/Gemfile.lock b/Gemfile.lock index 6d93daccf..e3b669b1f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -357,6 +357,7 @@ GEM railties (= 4.1.6) sprockets-rails (~> 2.0) rails-assets-jquery (1.11.1) + rails-assets-jquery-idletimer (0.9.3) rails-assets-jquery-placeholder (2.0.8) rails-assets-jquery-textchange (0.2.3) rails-assets-jquery @@ -577,6 +578,7 @@ DEPENDENCIES rack-ssl (= 1.4.1) rails (= 4.1.6) rails-assets-jquery (= 1.11.1) + rails-assets-jquery-idletimer (= 0.9.3) rails-assets-jquery-placeholder (= 2.0.8) rails-assets-jquery-textchange (= 0.2.3) rails-assets-perfect-scrollbar (= 0.4.11) diff --git a/app/assets/javascripts/main.js b/app/assets/javascripts/main.js index b0ae002b8..d683db631 100644 --- a/app/assets/javascripts/main.js +++ b/app/assets/javascripts/main.js @@ -17,7 +17,7 @@ //= require jquery.events.input //= require jquery.elastic //= require jquery.mentionsInput -//= require jquery.idle-timer +//= require jquery-idletimer/dist/idle-timer //= require jquery.infinitescroll-custom //= require jquery.autocomplete-custom //= require keycodes diff --git a/vendor/assets/javascripts/jquery.idle-timer.js b/vendor/assets/javascripts/jquery.idle-timer.js deleted file mode 100644 index 8df88d61e..000000000 --- a/vendor/assets/javascripts/jquery.idle-timer.js +++ /dev/null @@ -1,246 +0,0 @@ -/*! - * jQuery idleTimer plugin - * version 0.9.100511 - * by Paul Irish. - * http://github.com/paulirish/yui-misc/tree/ - * MIT license - - * adapted from YUI idle timer by nzakas: - * http://github.com/nzakas/yui-misc/ -*/ -/* - * Copyright (c) 2009 Nicholas C. Zakas - * - * Permission is hereby granted, free of charge, to any person obtaining a copy - * of this software and associated documentation files (the "Software"), to deal - * in the Software without restriction, including without limitation the rights - * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell - * copies of the Software, and to permit persons to whom the Software is - * furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included in - * all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR - * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE - * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, - * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN - * THE SOFTWARE. - */ - -/* updated to fix Chrome setTimeout issue by Zaid Zawaideh */ - - // API available in <= v0.8 - /******************************* - - // idleTimer() takes an optional argument that defines the idle timeout - // timeout is in milliseconds; defaults to 30000 - $.idleTimer(10000); - - - $(document).bind("idle.idleTimer", function(){ - // function you want to fire when the user goes idle - }); - - - $(document).bind("active.idleTimer", function(){ - // function you want to fire when the user becomes active again - }); - - // pass the string 'destroy' to stop the timer - $.idleTimer('destroy'); - - // you can query if the user is idle or not with data() - $.data(document,'idleTimer'); // 'idle' or 'active' - - // you can get time elapsed since user when idle/active - $.idleTimer('getElapsedTime'); // time since state change in ms - - ********/ - - - - // API available in >= v0.9 - /************************* - - // bind to specific elements, allows for multiple timer instances - $(elem).idleTimer(timeout|'destroy'|'getElapsedTime'); - $.data(elem,'idleTimer'); // 'idle' or 'active' - - // if you're using the old $.idleTimer api, you should not do $(document).idleTimer(...) - - // element bound timers will only watch for events inside of them. - // you may just want page-level activity, in which case you may set up - // your timers on document, document.documentElement, and document.body - - - ********/ - -(function($){ - -$.idleTimer = function(newTimeout, elem){ - - // defaults that are to be stored as instance props on the elem - - var idle = false, //indicates if the user is idle - enabled = true, //indicates if the idle timer is enabled - timeout = 30000, //the amount of time (ms) before the user is considered idle - events = 'mousemove keydown DOMMouseScroll mousewheel mousedown touchstart touchmove'; // activity is one of these events - - - elem = elem || document; - - - - /* (intentionally not documented) - * Toggles the idle state and fires an appropriate event. - * @return {void} - */ - var toggleIdleState = function(myelem){ - - // curse you, mozilla setTimeout lateness bug! - if (typeof myelem === 'number'){ - myelem = undefined; - } - - var obj = $.data(myelem || elem,'idleTimerObj'); - - //toggle the state - obj.idle = !obj.idle; - - // reset timeout - var elapsed = (+new Date()) - obj.olddate; - obj.olddate = +new Date(); - - // handle Chrome always triggering idle after js alert or comfirm popup - if (obj.idle && (elapsed < timeout)) { - obj.idle = false; - clearTimeout($.idleTimer.tId); - if (enabled) - $.idleTimer.tId = setTimeout(toggleIdleState, timeout); - return; - } - - //fire appropriate event - - // create a custom event, but first, store the new state on the element - // and then append that string to a namespace - var event = jQuery.Event( $.data(elem,'idleTimer', obj.idle ? "idle" : "active" ) + '.idleTimer' ); - - // we do want this to bubble, at least as a temporary fix for jQuery 1.7 - // event.stopPropagation(); - $(elem).trigger(event); - }, - - /** - * Stops the idle timer. This removes appropriate event handlers - * and cancels any pending timeouts. - * @return {void} - * @method stop - * @static - */ - stop = function(elem){ - - var obj = $.data(elem,'idleTimerObj') || {}; - - //set to disabled - obj.enabled = false; - - //clear any pending timeouts - clearTimeout(obj.tId); - - //detach the event handlers - $(elem).off('.idleTimer'); - }, - - - /* (intentionally not documented) - * Handles a user event indicating that the user isn't idle. - * @param {Event} event A DOM2-normalized event object. - * @return {void} - */ - handleUserEvent = function(){ - - var obj = $.data(this,'idleTimerObj'); - - //clear any existing timeout - clearTimeout(obj.tId); - - - - //if the idle timer is enabled - if (obj.enabled){ - - - //if it's idle, that means the user is no longer idle - if (obj.idle){ - toggleIdleState(this); - } - - //set a new timeout - obj.tId = setTimeout(toggleIdleState, obj.timeout); - - } - }; - - - /** - * Starts the idle timer. This adds appropriate event handlers - * and starts the first timeout. - * @param {int} newTimeout (Optional) A new value for the timeout period in ms. - * @return {void} - * @method $.idleTimer - * @static - */ - - - var obj = $.data(elem,'idleTimerObj') || {}; - - obj.olddate = obj.olddate || +new Date(); - - //assign a new timeout if necessary - if (typeof newTimeout === "number"){ - timeout = newTimeout; - } else if (newTimeout === 'destroy') { - stop(elem); - return this; - } else if (newTimeout === 'getElapsedTime'){ - return (+new Date()) - obj.olddate; - } - - //assign appropriate event handlers - $(elem).on($.trim((events+' ').split(' ').join('.idleTimer ')),handleUserEvent); - - - obj.idle = idle; - obj.enabled = enabled; - obj.timeout = timeout; - - - //set a timeout to toggle state - obj.tId = setTimeout(toggleIdleState, obj.timeout); - - // assume the user is active for the first x seconds. - $.data(elem,'idleTimer',"active"); - - // store our instance on the object - $.data(elem,'idleTimerObj',obj); - - - -}; // end of $.idleTimer() - - -// v0.9 API for defining multiple timers. -$.fn.idleTimer = function(newTimeout){ - if(this[0]){ - $.idleTimer(newTimeout,this[0]); - } - - return this; -}; - - -})(jQuery); From fce957443e2d6454b00a8440dab61064f7969023 Mon Sep 17 00:00:00 2001 From: Sandip Trivedi Date: Wed, 8 Oct 2014 00:10:42 -0400 Subject: [PATCH 223/785] Update jquery.idle-timer.js from 0.9.3 to 1.0.1 #5194 --- Gemfile | 2 +- Gemfile.lock | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Gemfile b/Gemfile index aff8b7649..678a5d214 100644 --- a/Gemfile +++ b/Gemfile @@ -86,7 +86,7 @@ gem 'rails-assets-punycode', '1.3.1' # jQuery plugins -gem 'rails-assets-jquery-idletimer', '0.9.3' +gem 'rails-assets-jquery-idletimer', '1.0.1' gem 'rails-assets-jquery-placeholder', '2.0.8' gem 'rails-assets-jquery-textchange', '0.2.3' gem 'rails-assets-perfect-scrollbar', '0.4.11' diff --git a/Gemfile.lock b/Gemfile.lock index e3b669b1f..3b2e098f0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -357,7 +357,7 @@ GEM railties (= 4.1.6) sprockets-rails (~> 2.0) rails-assets-jquery (1.11.1) - rails-assets-jquery-idletimer (0.9.3) + rails-assets-jquery-idletimer (1.0.1) rails-assets-jquery-placeholder (2.0.8) rails-assets-jquery-textchange (0.2.3) rails-assets-jquery @@ -578,7 +578,7 @@ DEPENDENCIES rack-ssl (= 1.4.1) rails (= 4.1.6) rails-assets-jquery (= 1.11.1) - rails-assets-jquery-idletimer (= 0.9.3) + rails-assets-jquery-idletimer (= 1.0.1) rails-assets-jquery-placeholder (= 2.0.8) rails-assets-jquery-textchange (= 0.2.3) rails-assets-perfect-scrollbar (= 0.4.11) From 476f694bca92712d8606cb5ebd88a7b4bc17d513 Mon Sep 17 00:00:00 2001 From: flaburgan Date: Tue, 7 Oct 2014 08:56:11 +0200 Subject: [PATCH 224/785] Remove one border-bottom on the photo page --- app/assets/stylesheets/stream_element.css.scss | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/stream_element.css.scss b/app/assets/stylesheets/stream_element.css.scss index afeda4c1b..e8d9b4d87 100644 --- a/app/assets/stylesheets/stream_element.css.scss +++ b/app/assets/stylesheets/stream_element.css.scss @@ -1,9 +1,15 @@ -#main_stream .stream_element, #main_stream .photo { - padding: 10px; +#main_stream .stream_element, +#main_stream > div > .photo { border-bottom: 1px solid $border-grey; + padding: 10px; & > .media { - margin: 0; + margin: 0px; + } +} + +#main_stream .stream_element { + & > .media { & > .img > .avatar.small { height: 50px; width: 50px; From 2d44107b5d54e99d57360fee024b99c873211e65 Mon Sep 17 00:00:00 2001 From: James Kiesel Date: Thu, 9 Oct 2014 23:08:33 +1300 Subject: [PATCH 225/785] Allow nil HTTP user agent --- app/controllers/application_controller.rb | 2 +- spec/controllers/application_controller_spec.rb | 7 +++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index f95636f60..327b6068c 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -36,7 +36,7 @@ class ApplicationController < ActionController::Base def after_sign_out_path_for(resource_or_scope) # mobile_fu's is_mobile_device? wasn't working here for some reason... # it may have been just because of the test env. - if request.env['HTTP_USER_AGENT'].match(/mobile/i) + if request.env['HTTP_USER_AGENT'].try(:match, /mobile/i) root_path else new_user_session_path diff --git a/spec/controllers/application_controller_spec.rb b/spec/controllers/application_controller_spec.rb index 1b2e44ff3..3910e9461 100644 --- a/spec/controllers/application_controller_spec.rb +++ b/spec/controllers/application_controller_spec.rb @@ -91,4 +91,11 @@ describe ApplicationController, :type => :controller do end end end + + describe "#after_sign_out_path_for" do + it "can handle a nil HTTP_USER_AGENT" do + @request.headers["HTTP_USER_AGENT"] = nil + expect(@controller.send(:after_sign_out_path_for, alice)).to eq(new_user_session_path) + end + end end From 206ec99f8f8df0e2f8244b8539fe81f2b69384b4 Mon Sep 17 00:00:00 2001 From: James Kiesel Date: Thu, 9 Oct 2014 23:28:30 +1300 Subject: [PATCH 226/785] Strip search query of leading & trailing whitespace --- app/controllers/search_controller.rb | 2 +- spec/controllers/search_controller_spec.rb | 11 +++++++++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/app/controllers/search_controller.rb b/app/controllers/search_controller.rb index 6c2f43474..f3a320615 100644 --- a/app/controllers/search_controller.rb +++ b/app/controllers/search_controller.rb @@ -20,7 +20,7 @@ class SearchController < ApplicationController private def search_query - @search_query ||= params[:q] || params[:term] || '' + @search_query ||= (params[:q] || params[:term] || '').strip end end diff --git a/spec/controllers/search_controller_spec.rb b/spec/controllers/search_controller_spec.rb index 5ec4baf6d..bc07db4ae 100644 --- a/spec/controllers/search_controller_spec.rb +++ b/spec/controllers/search_controller_spec.rb @@ -35,5 +35,16 @@ describe SearchController, :type => :controller do end end + describe '#search_query' do + it 'strips the term parameter' do + @controller.params[:term] = ' IN SPACE! ' + expect(@controller.send(:search_query)).to eq 'IN SPACE!' + end + + it 'strips the q parameter' do + @controller.params[:q] = ' IN SPACE! ' + expect(@controller.send(:search_query)).to eq 'IN SPACE!' + end + end end From 8ca5ca7c92bc3960bce80c17b1fb33aa724bfdff Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Sat, 4 Oct 2014 01:14:42 +0200 Subject: [PATCH 227/785] Reshare the absolute root of a post --- Changelog.md | 1 + app/controllers/reshares_controller.rb | 8 +++++++- spec/controllers/reshares_controller_spec.rb | 13 +++++++++++++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/Changelog.md b/Changelog.md index fa44e79ee..36a68d14f 100644 --- a/Changelog.md +++ b/Changelog.md @@ -44,6 +44,7 @@ The default for including jQuery from a CDN has changed. If you want to continue * Pull punycode.js from rails-assets.org [#5263](https://github.com/diaspora/diaspora/pull/5263) * Redesign profile page and port to Bootstrap [#4657](https://github.com/diaspora/diaspora/pull/4657) * Unify stream selection links in the left sidebar [#5271](https://github.com/diaspora/diaspora/pull/5271) +* Always reshare absolute root of a post [#5276](https://github.com/diaspora/diaspora/pull/5276) ## Bug fixes * orca cannot see 'Add Contact' button [#5158](https://github.com/diaspora/diaspora/pull/5158) diff --git a/app/controllers/reshares_controller.rb b/app/controllers/reshares_controller.rb index 7fc4e815f..1e49a5aa0 100644 --- a/app/controllers/reshares_controller.rb +++ b/app/controllers/reshares_controller.rb @@ -3,7 +3,13 @@ class ResharesController < ApplicationController respond_to :json def create - @reshare = current_user.build_post(:reshare, :root_guid => params[:root_guid]) + post = Post.where(:guid => params[:root_guid]).first + if post.is_a? Reshare + @reshare = current_user.build_post(:reshare, :root_guid => post.absolute_root.guid) + else + @reshare = current_user.build_post(:reshare, :root_guid => params[:root_guid]) + end + if @reshare.save current_user.add_to_streams(@reshare, current_user.aspects) current_user.dispatch_post(@reshare, :url => post_url(@reshare), :additional_subscribers => @reshare.root_author) diff --git a/spec/controllers/reshares_controller_spec.rb b/spec/controllers/reshares_controller_spec.rb index aa21badae..8f9090784 100644 --- a/spec/controllers/reshares_controller_spec.rb +++ b/spec/controllers/reshares_controller_spec.rb @@ -54,6 +54,19 @@ describe ResharesController, :type => :controller do expect(response.body.strip).to be_empty end end + + context 'resharing another user\'s reshare' do + before do + @root = @post + @post = FactoryGirl.create(:reshare, :root => @root, :author => alice.person) + end + + it 'reshares the absolute root' do + post_request! + expect(@post.reshares.count).to eq(0) + expect(@root.reshares.count).to eq(2) + end + end end end end From 823316d7f78e4ef22cc1cfd3880d58c39adac754 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 6 Oct 2014 01:09:00 +0200 Subject: [PATCH 228/785] Convert tag cukes to rspec tests --- features/desktop/tags.feature | 13 ----------- features/desktop/tags_and_comments.feature | 21 ----------------- spec/controllers/tags_controller_spec.rb | 26 +++++++++++++++++++++- 3 files changed, 25 insertions(+), 35 deletions(-) delete mode 100644 features/desktop/tags.feature delete mode 100644 features/desktop/tags_and_comments.feature diff --git a/features/desktop/tags.feature b/features/desktop/tags.feature deleted file mode 100644 index cf438d97b..000000000 --- a/features/desktop/tags.feature +++ /dev/null @@ -1,13 +0,0 @@ -@javascript -Feature: Interacting with tags - - Background: - Given there is a user "Samuel Beckett" who's tagged "#rockstar" - And I am signed in - And I am on the homepage - - Scenario: Searching for a tag - When I search for "#rockstar" - Then I should be on the tag page for "rockstar" - And I should see "Samuel Beckett" - diff --git a/features/desktop/tags_and_comments.feature b/features/desktop/tags_and_comments.feature deleted file mode 100644 index 35111cc22..000000000 --- a/features/desktop/tags_and_comments.feature +++ /dev/null @@ -1,21 +0,0 @@ -@javascript -Feature: Issue #3382 The comments under postings are missing when using the #tags -view - - Background: - Given a user named "Bob Jones" with email "bob@bob.bob" - And I sign in as "bob@bob.bob" - When I post a status with the text "This is a post with a #tag" - And I am on the homepage - - Scenario: - When I search for "#tag" - Then I should be on the tag page for "tag" - And I should see "This is a post with a #tag" - - Scenario: - When I comment "this is a comment on my post" on "This is a post with a #tag" - And I search for "#tag" - Then I should be on the tag page for "tag" - And I should see "this is a comment on my post" - - diff --git a/spec/controllers/tags_controller_spec.rb b/spec/controllers/tags_controller_spec.rb index f2eef5b72..06ccdf6ea 100644 --- a/spec/controllers/tags_controller_spec.rb +++ b/spec/controllers/tags_controller_spec.rb @@ -47,9 +47,22 @@ describe TagsController, :type => :controller do end end + context 'with a tagged user' do + before do + bob.profile.tag_string = "#cats #diaspora #rad" + bob.profile.build_tags + bob.profile.save! + end + + it 'includes the tagged user' do + get :show, :name => 'cats' + expect(response.body).to include(bob.diaspora_handle) + end + end + context 'with a tagged post' do before do - eve.post(:status_message, text: "#what #yes #hellyes #foo", public: true, to: 'all') + @post = eve.post(:status_message, text: "#what #yes #hellyes #foo tagged post", public: true, to: 'all') end context 'signed in' do @@ -66,6 +79,17 @@ describe TagsController, :type => :controller do get :show, :name => 'hellyes' expect(response.status).to eq(200) end + + it 'includes the tagged post' do + get :show, :name => 'foo' + expect(assigns[:stream].posts.first.text).to include("tagged post") + end + + it 'includes comments of the tagged post' do + alice.comment!(@post, "comment on a tagged post") + get :show, :name => 'foo', :format => 'json' + expect(response.body).to include("comment on a tagged post") + end end context "not signed in" do From 2b72fd0f35fe5202d91fecd1efd57411a9a74dc6 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 6 Oct 2014 01:09:55 +0200 Subject: [PATCH 229/785] Remove tests for removed beta code --- features/desktop/edits_profile.feature | 7 ------- features/mobile/edits_profile.feature | 3 --- features/support/paths.rb | 4 ---- 3 files changed, 14 deletions(-) diff --git a/features/desktop/edits_profile.feature b/features/desktop/edits_profile.feature index 627a37f3f..3db0978e9 100644 --- a/features/desktop/edits_profile.feature +++ b/features/desktop/edits_profile.feature @@ -43,10 +43,3 @@ Feature: editing your profile And I confirm the alert And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" Then I should see a "img" within "#profile_photo_upload" - - When I go to my new profile page -# #commented out until we bring back the profile info on new profile -# Then I should see "Gender: Fearless" - And I should see "Boba Fett" -# And I should see "Bio: This is a bio" -# And I should see "Birthday: 1986-11-30" diff --git a/features/mobile/edits_profile.feature b/features/mobile/edits_profile.feature index a89d5e2e4..9c7f88bd2 100644 --- a/features/mobile/edits_profile.feature +++ b/features/mobile/edits_profile.feature @@ -44,6 +44,3 @@ Feature: editing the profile in the mobile view And I confirm the alert And I attach the file "spec/fixtures/button.png" to hidden "file" within "#file-upload" Then I should see a "img" within "#profile_photo_upload" - - When I go to my new profile page - And I should see "Boba Fett" diff --git a/features/support/paths.rb b/features/support/paths.rb index 0f5bf7ba2..8ccf11987 100644 --- a/features/support/paths.rb +++ b/features/support/paths.rb @@ -36,10 +36,6 @@ module NavigationHelpers person_photos_path p when /^my account settings page$/ edit_user_path - when /^my new profile page$/ - person_path(@me.person, :ex => true) - when /^the new stream$/ - stream_path(:ex => true) when /^forgot password page$/ new_user_password_path when /^"(\/.*)"/ From 226f1bbfc3f0847afd86e12047f27b221060b8e9 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Mon, 6 Oct 2014 02:39:53 +0200 Subject: [PATCH 230/785] Convert activity stream cuke --- features/desktop/activity_stream.feature | 23 ----------------------- spec/lib/stream/activity_spec.rb | 11 ++++++++++- 2 files changed, 10 insertions(+), 24 deletions(-) delete mode 100644 features/desktop/activity_stream.feature diff --git a/features/desktop/activity_stream.feature b/features/desktop/activity_stream.feature deleted file mode 100644 index d7ba1a2ae..000000000 --- a/features/desktop/activity_stream.feature +++ /dev/null @@ -1,23 +0,0 @@ -@javascript -Feature: The activity stream - Scenario: Sorting - Given a user with username "bob" - When I sign in as "bob@bob.bob" - - And I click the publisher and post "A- I like turtles" - And I click the publisher and post "B- barack obama is your new bicycle" - And I click the publisher and post "C- barack obama is a square" - - When I go to the activity stream page - Then "C- barack obama is a square" should be post 1 - And "B- barack obama is your new bicycle" should be post 2 - And "A- I like turtles" should be post 3 - - When I like the post "A- I like turtles" - And I comment "Sassy sawfish" on "C- barack obama is a square" - And I like the post "B- barack obama is your new bicycle" - - When I go to the activity stream page - Then "B- barack obama is your new bicycle" should be post 1 - And "C- barack obama is a square" should be post 2 - And "A- I like turtles" should be post 3 diff --git a/spec/lib/stream/activity_spec.rb b/spec/lib/stream/activity_spec.rb index fc77feeca..bb066a3f8 100644 --- a/spec/lib/stream/activity_spec.rb +++ b/spec/lib/stream/activity_spec.rb @@ -3,10 +3,19 @@ require Rails.root.join('spec', 'shared_behaviors', 'stream') describe Stream::Activity do before do - @stream = Stream::Activity.new(alice, :max_time => Time.now, :order => 'updated_at') + @stream = Stream::Activity.new(alice) end describe 'shared behaviors' do it_should_behave_like 'it is a stream' end + + describe "#posts" do + it "calls EvilQuery::Participation with correct parameters" do + expect(::EvilQuery::Participation).to receive(:new) + .with(alice) + .and_return(double.tap { |m| allow(m).to receive(:posts)}) + @stream.posts + end + end end From a12ca511c38adef26f0944e5c5af7c38e570092c Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Fri, 10 Oct 2014 01:59:16 +0200 Subject: [PATCH 231/785] Convert close mentioned account cuke --- features/desktop/closes_account.feature | 19 ------------------- spec/controllers/posts_controller_spec.rb | 11 +++++++++++ 2 files changed, 11 insertions(+), 19 deletions(-) diff --git a/features/desktop/closes_account.feature b/features/desktop/closes_account.feature index 524714b0b..0388943dd 100644 --- a/features/desktop/closes_account.feature +++ b/features/desktop/closes_account.feature @@ -16,22 +16,3 @@ Feature: Close account When I try to sign in manually Then I should be on the new user session page And I should see a flash message with a warning - - Scenario: post display should not throw error when mention is removed for the user whose account is closed - Given following users exist: - | username | email | - | Bob Jones | bob@bob.bob | - | Alice Smith | alice@alice.alice | - And a user with email "bob@bob.bob" is connected with "alice@alice.alice" - And Alice has a post mentioning Bob - - Then I sign in as "bob@bob.bob" - When I go to the users edit page - And I follow "close_account" - And I put in my password in "close_account_password" in the modal window - And I press "close_account_confirm" in the modal window - And I confirm the alert - Then I should be on the new user session page - When I sign in as "alice@alice.alice" - And I am on the home page - Then I should see "Bob Jones" diff --git a/spec/controllers/posts_controller_spec.rb b/spec/controllers/posts_controller_spec.rb index e3f7a6071..246238484 100644 --- a/spec/controllers/posts_controller_spec.rb +++ b/spec/controllers/posts_controller_spec.rb @@ -30,6 +30,17 @@ describe PostsController, :type => :controller do expect(response).to be_success end + it 'succeeds after removing a mention when closing the mentioned user\'s account' do + user = FactoryGirl.create(:user, :username => "user") + alice.share_with(user.person, alice.aspects.first) + msg = alice.build_post :status_message, text: "Mention @{User ; #{user.diaspora_handle}}", :public => true, :to => 'all' + msg.save! + expect(msg.mentioned_people.count).to eq(1) + user.destroy + get :show, "id" => msg.id + expect(response).to be_success + end + it 'renders the application layout on mobile' do get :show, :id => @message.id, :format => :mobile expect(response).to render_template('layouts/application') From 140022875765351b67e9cbcf927bc173252f9e55 Mon Sep 17 00:00:00 2001 From: James Kiesel Date: Fri, 10 Oct 2014 00:22:26 +1300 Subject: [PATCH 232/785] Fix missing password translations --- app/views/passwords/edit.mobile.haml | 8 ++++---- app/views/passwords/new.mobile.haml | 8 ++++---- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/app/views/passwords/edit.mobile.haml b/app/views/passwords/edit.mobile.haml index db592f77c..18c97e636 100644 --- a/app/views/passwords/edit.mobile.haml +++ b/app/views/passwords/edit.mobile.haml @@ -10,20 +10,20 @@ = f.hidden_field :reset_password_token %fieldset %legend - =t('.change_password') + =t('devise.passwords.edit.change_password') .control-group - = f.label :password, t('password'), :class => "control-label" + = f.label :password, t('devise.passwords.edit.new_password'), :class => "control-label" .controls = f.password_field :password .control-group - = f.label :password_confirmation, t('password_confirmation'), :class => "control-label" + = f.label :password_confirmation, t('devise.passwords.edit.confirm_password'), :class => "control-label" .controls = f.password_field :password_confirmation .controls - = f.submit t('.change_password'), :class => 'btn primary' + = f.submit t('devise.passwords.edit.change_password'), :class => 'btn primary' %footer = link_to t('layouts.application.toggle'), toggle_mobile_path diff --git a/app/views/passwords/new.mobile.haml b/app/views/passwords/new.mobile.haml index ea60939b3..dee951b4e 100644 --- a/app/views/passwords/new.mobile.haml +++ b/app/views/passwords/new.mobile.haml @@ -8,17 +8,17 @@ = form_for(resource, :as => resource_name, :url => password_path(resource_name)) do |f| %fieldset %legend - =t('.forgot_password') + =t('devise.passwords.new.forgot_password') - unless devise_error_messages!.empty? - %i= t('.no_account') + %i= t('devise.passwords.new.no_account') .control-group - = f.label :email, t('email'), :class => "control-label" + = f.label :email, t('devise.passwords.new.email'), :class => "control-label" .controls = f.text_field :email .controls - = f.submit t('.send_password_instructions'), :class => 'btn' + = f.submit t('devise.passwords.new.send_password_instructions'), :class => 'btn' %footer - if display_registration_link? From 715f451ed4526f4d22f41a37c4c113f7e9dd05d6 Mon Sep 17 00:00:00 2001 From: Steffen van Bergerem Date: Fri, 10 Oct 2014 20:05:28 +0200 Subject: [PATCH 233/785] only collapse empty comment box --- app/assets/stylesheets/comments.css.scss | 2 +- app/assets/stylesheets/new_styles/_forms.scss | 7 ++++++- app/assets/templates/comment-stream_tpl.jst.hbs | 2 +- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/app/assets/stylesheets/comments.css.scss b/app/assets/stylesheets/comments.css.scss index 5d4e45361..d9d13eb98 100644 --- a/app/assets/stylesheets/comments.css.scss +++ b/app/assets/stylesheets/comments.css.scss @@ -38,5 +38,5 @@ width: 95%; } .comment_box { width: 95%; } - .comment_box:focus { min-height: 100px; } + .comment_box:focus, .comment_box:valid { min-height: 100px; } } diff --git a/app/assets/stylesheets/new_styles/_forms.scss b/app/assets/stylesheets/new_styles/_forms.scss index a6ecf1569..15aeddeac 100644 --- a/app/assets/stylesheets/new_styles/_forms.scss +++ b/app/assets/stylesheets/new_styles/_forms.scss @@ -87,11 +87,16 @@ form.block-form { } textarea, input[type=text], input[type=password], input[type=search] { - &:focus, &:invalid:focus { + &:focus, + &:invalid, + &:invalid:focus, + &:invalid:required, + &:invalid:required:focus { border: 1px solid $border-dark-grey; outline: none; -webkit-box-shadow: none; box-shadow: none; + color : $text-dark-grey; } } diff --git a/app/assets/templates/comment-stream_tpl.jst.hbs b/app/assets/templates/comment-stream_tpl.jst.hbs index abcc20324..2525f1c5b 100644 --- a/app/assets/templates/comment-stream_tpl.jst.hbs +++ b/app/assets/templates/comment-stream_tpl.jst.hbs @@ -20,7 +20,7 @@
    -