diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 4e9f94c24..8851f3c8e 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -57,11 +57,15 @@ module ApplicationHelper
end
def person_image_tag(person)
+ image_tag image_or_default(person), :class => "avatar", :alt => person.real_name, :title => person.real_name, "data-person_id" => person.id
+ end
+
+ def image_or_default(person)
image_location = person.profile.image_url
image_location ||= "/images/user/default.png"
-
- image_tag image_location, :class => "avatar", :alt => person.real_name, :title => person.real_name, "data-person_id" => person.id
+ image_location
end
+
def person_image_link(person)
link_to person_image_tag(person), object_path(person)
diff --git a/app/mailers/notifier.rb b/app/mailers/notifier.rb
new file mode 100644
index 000000000..95cdff86f
--- /dev/null
+++ b/app/mailers/notifier.rb
@@ -0,0 +1,22 @@
+class Notifier < ActionMailer::Base
+ default :from => "no-reply@joindiaspora.com"
+ ATTACHMENT = File.read("#{Rails.root}/public/images/diaspora_caps.png")
+
+ def new_request(recipient, sender)
+ @receiver = recipient
+ @sender = sender
+ attachments["diaspora_white.png"] = ATTACHMENT
+
+ mail(:to => "#{recipient.real_name} <#{recipient.email}>",
+ :subject => "new Diaspora* friend request from #{@sender.real_name}", :host => APP_CONFIG[:terse_pod_url])
+ end
+
+ def request_accepted(recipient, sender, aspect)
+ @receiver = recipient
+ @sender = sender
+ @aspect = aspect
+ attachments["diaspora_white.png"] = ATTACHMENT
+ mail(:to => "#{recipient.real_name} <#{recipient.email}>",
+ :subject => "#{@sender.real_name} has accepted your friend request on Diaspora*", :host => APP_CONFIG[:terse_pod_url])
+ end
+end
diff --git a/app/models/person.rb b/app/models/person.rb
index 1e063a743..5a1486653 100644
--- a/app/models/person.rb
+++ b/app/models/person.rb
@@ -97,9 +97,9 @@ class Person
# Raise an error if identifier is not a valid email (generous regexp)
raise "Identifier is invalid" if !(identifier =~ /\A.*\@.*\..*\Z/)
- query = /#{Regexp.escape(identifier.gsub('acct:', '').to_s)}/i
+ query = /\A^#{Regexp.escape(identifier.gsub('acct:', '').to_s)}\z/i
local_person = Person.first(:diaspora_handle => query)
-
+
if local_person
Rails.logger.info("Do not need to webfinger, found a local person #{local_person.real_name}")
local_person
diff --git a/app/models/status_message.rb b/app/models/status_message.rb
index 1c167706e..093316659 100644
--- a/app/models/status_message.rb
+++ b/app/models/status_message.rb
@@ -3,7 +3,8 @@
# the COPYRIGHT file.
class StatusMessage < Post
-
+
+ validates_length_of :message, :maximum => 1000, :message => "please make your status messages less than 1000 characters"
xml_name :status_message
xml_accessor :message
diff --git a/app/models/user.rb b/app/models/user.rb
index 273cc209b..343cc2d76 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -43,8 +43,7 @@ class User
before_validation :strip_username, :on => :create
validates_presence_of :username
validates_uniqueness_of :username, :case_sensitive => false
- validates_format_of :username, :without => /\s/
-
+ validates_format_of :username, :with => /\A[A-Za-z0-9_.]+\z/
validates_with InvitedUserValidator
one :person, :class_name => 'Person', :foreign_key => :owner_id
diff --git a/app/views/albums/_new_album.haml b/app/views/albums/_new_album.haml
index d7bd2d997..e8cd3e778 100644
--- a/app/views/albums/_new_album.haml
+++ b/app/views/albums/_new_album.haml
@@ -2,14 +2,11 @@
-# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file.
-.span-12.last
- .modal_title_bar
- %h4= t('.add_a_new_album')
- = form_for Album.new do |f|
- = f.error_messages
- %p
- = f.label :name
- = f.text_field :name
- = f.hidden_field :to, :value => aspect
- = f.submit t('.create'), :class => 'button'
+= form_for Album.new do |album|
+ = album.error_messages
+ %p
+ = album.label :name
+ = album.hidden_field :to, :value => aspect
+ = album.text_field :name
+ = album.submit t('.create'), :class => 'button'
diff --git a/app/views/albums/index.html.haml b/app/views/albums/index.html.haml
index b9e62113f..ea046d7aa 100644
--- a/app/views/albums/index.html.haml
+++ b/app/views/albums/index.html.haml
@@ -8,22 +8,11 @@
$("#add_album_button").fancybox();
});
-%h2
- = @aspect
- .friend_pictures.horizontal
- = owner_image_link
- - for friend in @friends
- = person_image_link(friend)
+.span-4.append-1.last
+ = render "shared/aspect_friends"
-.span-24.last
- %h3
- = @aspect
- Albums
- = link_to t('.new_album'), '#new_album_pane', {:class => "button", :id => "add_album_button"}
-
- .fancybox_content
- #new_album_pane
- = render "albums/new_album", :aspect => params[:aspect]
+.span-15.last
+ = render "shared/publisher", :type => :album, :aspect => @aspect.id
%div
- for album in @albums
diff --git a/app/views/albums/show.html.haml b/app/views/albums/show.html.haml
index d6f834c82..4941a2bee 100644
--- a/app/views/albums/show.html.haml
+++ b/app/views/albums/show.html.haml
@@ -9,15 +9,12 @@
});
});
-%h2
- = @aspect
- .friend_pictures.horizontal
- = owner_image_link
- - for friend in @friends
- = person_image_link(friend)
-%h3
- = link_to "#{@aspect} Albums", albums_path(:aspect => @aspect)
+= render 'shared/author_info', :post => @album
+
+%ul#breadcrumb
+ %li= link_to "#{@album.person.profile.first_name}'s Photos", '#'
+ %li= @album.name
.span-19.appends-1.last
diff --git a/app/views/aspects/index.html.haml b/app/views/aspects/index.html.haml
index 8ffe1a519..dbc8ec95e 100644
--- a/app/views/aspects/index.html.haml
+++ b/app/views/aspects/index.html.haml
@@ -7,7 +7,7 @@
.span-15.last
= render 'aspects/no_friends_message'
- = render 'shared/publisher'
+ = render 'shared/publisher', :type => :status_message, :aspect => @aspect
= render 'aspects/no_posts_message'
%ul#stream
- for post in @posts
diff --git a/app/views/aspects/manage.html.haml b/app/views/aspects/manage.html.haml
index 3fdedbad9..8ac04b893 100644
--- a/app/views/aspects/manage.html.haml
+++ b/app/views/aspects/manage.html.haml
@@ -10,7 +10,7 @@
%h2
Manage aspects
.right
- = link_to(t('.add_a_new_aspect'), "#add_aspect_pane", :class => "new_aspect add_aspect_button button", :title => t('.add_a_new_aspect'))
+ = link_to("+ #{t('.add_a_new_aspect')}", "#add_aspect_pane", :class => "new_aspect add_aspect_button button", :title => t('.add_a_new_aspect'))
.span-4.append-1.last
%h3=t('.requests')
@@ -18,54 +18,50 @@
.requests
%ul.dropzone
- if @remote_requests.size < 1
- %li.grey No new requests
+ %li No new requests
- else
- for request in @remote_requests
- %li.requested_person{:id => request.person.id, :request_id => request.id}
+ %li.person.request{:data=>{:guid=>request.id, :person_id=>request.person.id}}
= person_image_tag(request.person)
- .name
- = request.person.real_name
%h3 Remove from Aspect
.aspect_remove
%ul.dropzone
- %li.grey Drag to remove person from aspect
-
- %h3=t('.ignore_remove')
- .remove
- %ul.dropzone
- %li.grey Drag to ignore/remove
+ .draggable_info
+ Drag to remove person from aspect
= render 'shared/invitations', :invites => @invites
.span-19.last
%ul#aspect_list
- for aspect in @aspects
- %li.aspect
+ %li.aspect{:data=>{:guid=>aspect.id}}
.aspect_name
%span.edit_name_field
- %h3{:contenteditable => true}= aspect.name
+ %h3{:contenteditable=>true}
+ = aspect.name
%span.tip click to edit
%ul.tools
%li= link_to t('.add_a_new_friend'), "#add_request_pane_#{aspect.id}", :class => 'add_request_button'
%li!= remove_link(aspect)
- %ul.dropzone{:id => aspect.id}
+ %ul.dropzone{:data=>{:aspect_id=>aspect.id}}
+ -for person in aspect.people
+ %li.person{:data=>{:guid=>person.id, :aspect_id=>aspect.id}}
+ .delete
+ .x
+ X
+ .circle
+ = person_image_tag(person)
+ .draggable_info
+ Drag to add people
- -if aspect.people.size < 1
- %li.grey Drag to add people
- -else
- -for person in aspect.people
-
- %li.person{:id => person.id, :class => person.id, :from_aspect_id => aspect.id}
- = person_image_tag(person)
- .name
- = link_to person.real_name, person
.fancybox_content
%div{:id => "add_request_pane_#{aspect.id}"}
= render "requests/new_request", :aspect => aspect
+
diff --git a/app/views/aspects/show.html.haml b/app/views/aspects/show.html.haml
index 8ffe1a519..dbc8ec95e 100644
--- a/app/views/aspects/show.html.haml
+++ b/app/views/aspects/show.html.haml
@@ -7,7 +7,7 @@
.span-15.last
= render 'aspects/no_friends_message'
- = render 'shared/publisher'
+ = render 'shared/publisher', :type => :status_message, :aspect => @aspect
= render 'aspects/no_posts_message'
%ul#stream
- for post in @posts
diff --git a/app/views/notifier/new_request.html.haml b/app/views/notifier/new_request.html.haml
new file mode 100644
index 000000000..66bb56f1a
--- /dev/null
+++ b/app/views/notifier/new_request.html.haml
@@ -0,0 +1,59 @@
+!!!
+%html
+ %head
+ %meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}/
+ :css
+ body{
+ width:600px;
+ font-family:'Arial','Helvetica',sans-serif;
+ font-size:14px;
+ color:#333;
+ }
+ #container{
+ margin-bottom:25px
+ min-height:400px;
+ padding-left:15px;
+ }
+ header{
+ background-color:#333;
+ padding: 15px;
+ margin-bottom: 25px;
+ }
+ p{
+ padding:5px;
+ }
+ p.small{
+ font-size:smaller;
+ color:#999;
+ font-style:italic;
+ }
+ a{
+ color:#107FC9;
+ font-weight:bold;
+ }
+ a:hover{
+ color: #22AAE0;
+ }
+ a:active{
+ color: #005D9C;
+ }
+ .large_text{
+ font-size:21px;
+ font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;
+ }
+ %body
+ %header
+ = image_tag 'diaspora_white.png'
+ #container
+ %p
+ Hello #{@receiver.profile.first_name}!
+ %p
+ = "#{@sender.real_name} (#{@sender.diaspora_handle})"
+ just sent you a friend request on Diaspora*
+ You should really think about checking it out.
+ %br
+ = link_to "sign in here", new_user_session_url
+ %br
+ love,
+ %br
+ the diaspora email robot
diff --git a/app/views/notifier/new_request.text.haml b/app/views/notifier/new_request.text.haml
new file mode 100644
index 000000000..8ab5bc570
--- /dev/null
+++ b/app/views/notifier/new_request.text.haml
@@ -0,0 +1,9 @@
+= "hey #{@receiver.profile.first_name},"
+= "#{@sender.real_name} (#{@sender.diaspora_handle})"
+just sent you a friend request on Diaspora*
+You should really think about checking it out.
+
+= "sign in here: #{new_user_session_url}"
+
+love,
+the diaspora email robot
diff --git a/app/views/notifier/request_accepted.html.haml b/app/views/notifier/request_accepted.html.haml
new file mode 100644
index 000000000..191f8f42c
--- /dev/null
+++ b/app/views/notifier/request_accepted.html.haml
@@ -0,0 +1,59 @@
+!!!
+%html
+ %head
+ %meta{"http-equiv"=>"Content-Type", :content=>"text/html; charset=utf-8"}/
+ :css
+ body{
+ width:600px;
+ font-family:'Arial','Helvetica',sans-serif;
+ font-size:14px;
+ color:#333;
+ }
+ #container{
+ margin-bottom:25px
+ min-height:400px;
+ padding-left:15px;
+ }
+ header{
+ background-color:#333;
+ padding: 15px;
+ margin-bottom: 25px;
+ }
+ p{
+ padding:5px;
+ }
+ p.small{
+ font-size:smaller;
+ color:#999;
+ font-style:italic;
+ }
+ a{
+ color:#107FC9;
+ font-weight:bold;
+ }
+ a:hover{
+ color: #22AAE0;
+ }
+ a:active{
+ color: #005D9C;
+ }
+ .large_text{
+ font-size:21px;
+ font-family:"Helvetica Neue",Arial,Helvetica,sans-serif;
+ }
+ %body
+ %header
+ = image_tag 'diaspora_white.png'
+ #container
+ %p
+ Hello #{@receiver.profile.first_name}!
+ %p
+ = "#{@sender.real_name} (#{@sender.diaspora_handle})"
+ has accepted your friend request. They are now in your
+ = link_to @aspect.name, aspect_url(@aspect)
+ aspect.
+
+ %br
+ love,
+ %br
+ the diaspora email robot
diff --git a/app/views/notifier/request_accepted.text.haml b/app/views/notifier/request_accepted.text.haml
new file mode 100644
index 000000000..e10623f16
--- /dev/null
+++ b/app/views/notifier/request_accepted.text.haml
@@ -0,0 +1,9 @@
+= "hey #{@receiver.profile.first_name},"
+= "#{@sender.real_name} (#{@sender.diaspora_handle})"
+has accepted your friend request. They are now in your
+= "#{@aspect.name} asepct.\n"
+= "#{aspect_url(@aspect)}"
+
+
+love, \n
+the diaspora email robot
diff --git a/app/views/photos/show.html.haml b/app/views/photos/show.html.haml
index e4ae23170..9b48538e5 100644
--- a/app/views/photos/show.html.haml
+++ b/app/views/photos/show.html.haml
@@ -55,15 +55,12 @@
});//end document ready
-%h2
- = @aspect
- .friend_pictures.horizontal
- = owner_image_link
- - for friend in @friends
- = person_image_link(friend)
+= render 'shared/author_info', :post => @photo
-%h3
- = link_to @photo.album.name, @photo.album
+%ul#breadcrumb
+ %li= link_to "#{@album.person.profile.first_name}'s Photos", '#'
+ %li= link_to @album.name, album_path(@album)
+ %li= @photo.caption
= link_to "<< #{t('.prev')}", url_to_prev(@photo, @album), :rel => 'prefetch'
|
diff --git a/app/views/publics/hcard.erb b/app/views/publics/hcard.erb
index 6b8ab3209..5102897a5 100644
--- a/app/views/publics/hcard.erb
+++ b/app/views/publics/hcard.erb
@@ -36,13 +36,9 @@
- Photo
-
-
+
-
- - Note
- - Diaspora is awesome! vi is better than emacs!
-
diff --git a/app/views/shared/_author_info.html.haml b/app/views/shared/_author_info.html.haml
new file mode 100644
index 000000000..6a619c44b
--- /dev/null
+++ b/app/views/shared/_author_info.html.haml
@@ -0,0 +1,15 @@
+#author_info
+ = owner_image_link
+ .from
+ %h2
+ = post.person.real_name
+ .aspect
+ ➔
+ %ul
+ - if post.public?
+ the world
+ - else
+ - for aspect in current_user.aspects_with_post( post.id )
+ %li= link_to aspect.name, aspect
+
+ = link_to "view profile", person_path(post.person)
diff --git a/app/views/shared/_publisher.haml b/app/views/shared/_publisher.haml
index 3a5a9f468..832c07916 100644
--- a/app/views/shared/_publisher.haml
+++ b/app/views/shared/_publisher.haml
@@ -9,7 +9,7 @@
};
});
- $("#publisher textarea").live("focus", function(evt){
+ $("#publisher textarea, #publisher input").live("focus", function(evt){
$("#publisher .options_and_submit").fadeIn(50);
});
@@ -20,28 +20,41 @@
#publisher
= owner_image_tag
- = form_for StatusMessage.new, :remote => true do |status|
- = status.error_messages
- %p
- = status.label :message, "Post a message to #{@aspect}"
- = status.text_area :message, :rows => 2, :value => params[:prefill]
+ - if( !defined?(type) || type == :status_message )
+ = form_for StatusMessage.new, :remote => true do |status|
+ = status.error_messages
+ %p
+ = status.label :message, "Post a message to #{aspect}"
+ = status.text_area :message, :rows => 2, :value => params[:prefill]
- = status.hidden_field :to, :value => (@aspect == :all ? @aspect : @aspect.id)
+ = status.hidden_field :to, :value => (aspect == :all ? aspect : aspect.id)
- .options_and_submit
-
- - if @aspect == :all
- .public_toggle
- = status.check_box( :public, :value => false )
- make public
- = link_to '(?)', "#question_mark_pane", :class => 'question_mark'
+ .options_and_submit
+
+ - if aspect == :all
+ .public_toggle
+ = status.check_box( :public, :value => false )
+ make public
+ = link_to '(?)', "#question_mark_pane", :class => 'question_mark'
- .fancybox_content
- #question_mark_pane
- = render 'shared/public_explain'
+ .fancybox_content
+ #question_mark_pane
+ = render 'shared/public_explain'
- - if @aspect == :all
- = status.submit t('.share'), :title => "Share with all aspects"
- - else
- = status.submit t('.share'), :title => "Share with #{@aspect}"
+ - if aspect == :all
+ = status.submit t('.share'), :title => "Share with all aspects"
+ - else
+ = status.submit t('.share'), :title => "Share with #{aspect}"
+
+ - else
+ = form_for Album.new do |album|
+ = album.error_messages
+ %p
+ = album.label :name
+ = album.text_field :name
+
+ = album.hidden_field :to, :value => aspect
+
+ .options_and_submit
+ = album.submit "Create", :class => 'button'
diff --git a/app/views/shared/_sub_header.haml b/app/views/shared/_sub_header.haml
deleted file mode 100644
index 6f4032c1e..000000000
--- a/app/views/shared/_sub_header.haml
+++ /dev/null
@@ -1,20 +0,0 @@
-#aspect_header
- .container
- .span-4.last
- - if @person
- %h2
- = @person.real_name
- - else
- %h2
- - if @aspect == :all
- = link_to "Everyone", root_path
- - elsif @aspect == :manage
- = link_to t('.manage_aspects'), root_path
- - else
- = link_to @aspect.name, @aspect
-
- .page_title
- = yield :page_title
-
- .span-15.last{ :style => "position:relative;" }
- = yield :publish
diff --git a/app/views/status_messages/show.html.haml b/app/views/status_messages/show.html.haml
index 398b3a536..1e0f15438 100644
--- a/app/views/status_messages/show.html.haml
+++ b/app/views/status_messages/show.html.haml
@@ -3,17 +3,11 @@
-# the COPYRIGHT file.
-%h2
- = @aspect
- .friend_pictures.horizontal
- - for friend in @friends
- = person_image_link(friend)
+= render 'shared/author_info', :post => @status_message
.span-14.append-1.last
#stream
%h1.show_text
- = person_image_link(@status_message.person)
- = link_to @status_message.person.real_name, @status_message.person
= make_links(@status_message.message)
= "Posted #{how_long_ago(@status_message)} to"
diff --git a/config/initializers/mailer_config.rb b/config/initializers/mailer_config.rb
index 73928f740..cbc5f7330 100644
--- a/config/initializers/mailer_config.rb
+++ b/config/initializers/mailer_config.rb
@@ -3,15 +3,17 @@
# the COPYRIGHT file.
Diaspora::Application.configure do
- config.action_mailer.delivery_method = :smtp
config.action_mailer.default_url_options = {:host => APP_CONFIG[:terse_pod_url]}
- config.action_mailer.smtp_settings = {
- :address => APP_CONFIG[:smtp_address],
- :port => APP_CONFIG[:smtp_port],
- :domain => APP_CONFIG[:smtp_domain],
- :authentication => APP_CONFIG[:smtp_authentication],
- :user_name => APP_CONFIG[:smtp_username],
- :password => APP_CONFIG[:smtp_password],
- :enable_starttls_auto => true
- }
+ unless Rails.env == 'test'
+ config.action_mailer.delivery_method = :smtp
+ config.action_mailer.smtp_settings = {
+ :address => APP_CONFIG[:smtp_address],
+ :port => APP_CONFIG[:smtp_port],
+ :domain => APP_CONFIG[:smtp_domain],
+ :authentication => APP_CONFIG[:smtp_authentication],
+ :user_name => APP_CONFIG[:smtp_username],
+ :password => APP_CONFIG[:smtp_password],
+ :enable_starttls_auto => true
+ }
+ end
end
diff --git a/config/initializers/setup_mail.rb b/config/initializers/setup_mail.rb
new file mode 100644
index 000000000..0d3f958a7
--- /dev/null
+++ b/config/initializers/setup_mail.rb
@@ -0,0 +1,2 @@
+# if you wish to intercept emails to go to a particuar email address
+#ActionMailer::Base.register_interceptor(DevelopmentMailInterceptor) if Rails.env.development?
diff --git a/db/seeds/backer.rb b/db/seeds/backer.rb
index 877ffc13f..269772f51 100644
--- a/db/seeds/backer.rb
+++ b/db/seeds/backer.rb
@@ -13,7 +13,8 @@ def create
#set pod url
username = backer_info[backer_number]['username'].gsub(/ /,'').downcase
- set_app_config username
+ set_app_config username unless File.exists?(Rails.root.join('config', 'app_config.yml'))
+
require File.join(File.dirname(__FILE__), "..", "..", "config", "initializers", "_load_app_config.rb")
# Create seed user
diff --git a/db/seeds/dev.rb b/db/seeds/dev.rb
index 33f773613..324cf47bd 100644
--- a/db/seeds/dev.rb
+++ b/db/seeds/dev.rb
@@ -15,7 +15,9 @@ def set_app_config username
end
username = "tom"
-set_app_config username
+set_app_config username unless File.exists?(Rails.root.join('config', 'app_config.yml'))
+
+require Rails.root.join('config', "initializers", "_load_app_config.rb")
# Create seed user
user = User.build( :email => "tom@tom.joindiaspora.com",
diff --git a/db/seeds/tom.rb b/db/seeds/tom.rb
index f4c453d81..fe45e2dd0 100644
--- a/db/seeds/tom.rb
+++ b/db/seeds/tom.rb
@@ -14,7 +14,8 @@ def set_app_config username
file.close
end
-set_app_config "tom"
+set_app_config "tom" unless File.exists?(Rails.root.join('config', 'app_config.yml'))
+
require 'config/initializers/_load_app_config.rb'
# Create seed user
diff --git a/lib/development_mail_interceptor.rb b/lib/development_mail_interceptor.rb
new file mode 100644
index 000000000..efc89596f
--- /dev/null
+++ b/lib/development_mail_interceptor.rb
@@ -0,0 +1,7 @@
+class DevelopmentMailInterceptor
+ def self.delivering_email(message)
+ message.subject = "[#{message.to}] #{message.subject}"
+ message.to = "email@joindiaspora.com"
+ end
+end
+
diff --git a/lib/diaspora/user/friending.rb b/lib/diaspora/user/friending.rb
index 6946910f2..4a19ffd68 100644
--- a/lib/diaspora/user/friending.rb
+++ b/lib/diaspora/user/friending.rb
@@ -63,19 +63,23 @@ module Diaspora
def receive_friend_request(friend_request)
Rails.logger.info("receiving friend request #{friend_request.to_json}")
+
+ #response from a friend request you sent
if request_from_me?(friend_request) && self.aspect_by_id(friend_request.aspect_id)
aspect = self.aspect_by_id(friend_request.aspect_id)
activate_friend(friend_request.person, aspect)
Rails.logger.info("#{self.real_name}'s friend request has been accepted")
-
friend_request.destroy
+ Notifier.request_accepted(self, friend_request.person, aspect).deliver
+ #this is a new friend request
else
self.pending_requests << friend_request
self.save
Rails.logger.info("#{self.real_name} has received a friend request")
friend_request.save
+ Notifier.new_request(self, friend_request.person).deliver
end
end
diff --git a/public/images/user/default.jpg b/public/images/user/default.jpg
deleted file mode 100644
index b242c1e1c..000000000
Binary files a/public/images/user/default.jpg and /dev/null differ
diff --git a/public/javascripts/aspect-edit.js b/public/javascripts/aspect-edit.js
index 825433e0e..9e565e4b2 100644
--- a/public/javascripts/aspect-edit.js
+++ b/public/javascripts/aspect-edit.js
@@ -4,9 +4,9 @@
*/
function decrementRequestsCounter() {
- var $new_requests = $(".new_requests"),
- request_html = $new_requests.html(),
- old_request_count = request_html.match(/\d+/);
+ var $new_requests = $(".new_requests");
+ var request_html = $new_requests.html();
+ var old_request_count = request_html.match(/\d+/);
if( old_request_count == 1 ) {
$new_requests.html(
@@ -19,133 +19,142 @@ function decrementRequestsCounter() {
}
}
+// Dragging person between aspects
$(function() {
- // Multiple classes here won't work
$("ul .person").draggable({
- revert: true
+ revert: true,
+ start: function(event,ui){
+ $(this).children("img").animate({'height':80, 'width':80, 'opacity':0.8},200);
+ $(".draggable_info").fadeIn(100);
+ },
+ stop: function(event,ui){
+ $(this).children("img").animate({'height':70, 'width':70, 'opacity':1},200);
+ $(".draggable_info").fadeOut(100);
+ }
});
- $("ul .requested_person").draggable({
- revert: true
- });
-
- $(".aspect ul").droppable({
+ $(".aspect ul.dropzone").droppable({
hoverClass: 'active',
drop: function(event, ui) {
- if ($(ui.draggable[0]).hasClass('requested_person')){
+ var dropzone = $(this);
+ var person = ui.draggable;
+
+ if( person.hasClass('request') ){
$.ajax({
type: "DELETE",
- url: "/requests/" + ui.draggable[0].getAttribute('request_id') ,
- data: {"accept" : true , "aspect_id" : $(this)[0].id },
+ url: "/requests/" + person.attr('data-guid'),
+ data: {"accept" : true, "aspect_id" : dropzone.attr('data-aspect_id') },
success: function(data){
decrementRequestsCounter();
}
});
-
};
- var dropzone = $(this)[0];
- if ($(this)[0].id == ui.draggable[0].getAttribute('from_aspect_id')){
- ui.draggable.css('background-color','#333');
- } else {
- ui.draggable.css('background-color','orange');
- $.ajax({
- url: "/aspects/move_friend/",
- data: {"friend_id" : ui.draggable[0].id,
- "from" : ui.draggable[0].getAttribute('from_aspect_id'),
- "to" : { "to" : dropzone.id }},
- success: function(data){
- ui.draggable.attr('from_aspect_id', dropzone.id);
- ui.draggable.css('background-color','#333');
- }});
+ if( dropzone.attr('data-aspect_id') != person.attr('data-aspect_id' )){
+ $.ajax({
+ url: "/aspects/move_friend/",
+ data: {"friend_id" : person.attr('data-guid'),
+ "from" : person.attr('data-aspect_id'),
+ "to" : { "to" : dropzone.attr('data-aspect_id') }},
+ success: function(data){
+ person.attr('data-aspect_id', dropzone.attr('data-aspect_id'));
+ }});
}
- $(this).closest("ul").append(ui.draggable);
+
+ $(this).closest("ul").append(person);
}
});
- $(".remove ul").droppable({
- hoverClass: 'active',
- drop: function(event, ui) {
-
- if ($(ui.draggable[0]).hasClass('requested_person')){
- $.ajax({
- type: "DELETE",
- url: "/requests/" + ui.draggable.attr('request_id'),
- success: function () {
- decrementRequestsCounter();
- }
- });
-
- } else {
- $.ajax({
- type: "DELETE",
- url: "/people/" + ui.draggable.attr('id'),
- success: function () {
- alert("Removed Friend, proably want an undo countdown.")
- }
- });
-
- }
-
- $(ui.draggable[0]).fadeOut('slow');
- $(ui.draggable[0]).remove();
- }
- });
$(".aspect_remove ul").droppable({
hoverClass: 'active',
drop: function(event, ui) {
- if ($( "." + ui.draggable[0].id).length == 1) {
+
+ var person = ui.draggable;
+
+ if ( person.attr('data-guid').length == 1 ) {
alert("You can not remove the person from the last aspect");
+
} else {
- if (!$(ui.draggable[0]).hasClass('requested_person')){
- var aspect = ui.draggable[0].getAttribute('from_aspect_id')
- var person_id = ui.draggable[0].id
+ if( !person.hasClass('request') ){
+
$.ajax({
type: "POST",
url: "/aspects/remove_from_aspect",
data:{
- 'friend_id' : person_id,
- 'aspect_id' : aspect
- }
+ 'friend_id' : person.attr('data-guid'),
+ 'aspect_id' : person.attr('data-aspect_id') }
});
}
- $(ui.draggable[0]).fadeOut('slow');
- $(ui.draggable[0]).remove();
-
-
+ person.fadeOut('slow', $(this).remove());
}
-
-
}
});
- $(".aspect h3").live( 'focus', function() {
+});
- var $this = $(this),
- id = $this.closest("li").children("ul").attr("id"),
- link = "/aspects/"+ id;
- $this.keypress(function(e) {
- if (e.which == 13) {
- e.preventDefault();
- $this.blur();
+// Person deletion
+$(".delete").live("click", function() {
- //save changes
- $.ajax({
- type: "PUT",
- url: link,
- data: {"aspect" : {"name" : $this.text() }}
- });
- }
- //update all other aspect links
- $this.keyup(function(e) {
- $("#aspect_nav a[href='"+link+"']").text($this.text());
+ var person = $(this).closest("li.person");
+
+ if (person.hasClass('request')){
+
+ if( confirm("Ignore request?") ){
+ var request_id = person.attr("data-guid");
+
+ $.ajax({
+ type: "DELETE",
+ url: "/requests/" + request_id,
+ success: function () {
+ decrementRequestsCounter();
+ }
});
+ }
+
+ } else {
+
+ if( confirm("Remove this person from all aspects?") ){
+ var person_id = $(this).closest("li.person").attr('data-guid');
+
+ $.ajax({
+ type: "DELETE",
+ url: "/people/" + person_id,
+ success: function() {
+ person.fadeOut(200);
+ }
+ });
+ }
+ }
+});
+
+
+// Editing aspect name
+$(".aspect h3").live('focus', function() {
+
+ var $this = $(this);
+ var id = $this.closest("li.aspect").attr("data-guid");
+ var link = "/aspects/"+ id;
+
+ $this.keypress(function(e) {
+ if (e.which == 13) {
+ e.preventDefault();
+ $this.blur();
+
+ //save changes
+ $.ajax({
+ type: "PUT",
+ url: link,
+ data: {"aspect" : {"name" : $this.text() }}
+ });
+ }
+ //update all other aspect links
+ $this.keyup(function(e) {
+ $("#aspect_nav a[href='"+link+"']").text($this.text());
});
});
-
});
diff --git a/public/javascripts/view.js b/public/javascripts/view.js
index 7e809f978..71fefc347 100644
--- a/public/javascripts/view.js
+++ b/public/javascripts/view.js
@@ -30,6 +30,7 @@ $(document).ready(function(){
$("#add_request_button").fancybox({ 'titleShow': false , 'hideOnOverlayClick' : false });
$(".invite_user_button").fancybox({ 'titleShow': false , 'hideOnOverlayClick' : false });
$(".add_request_button").fancybox({ 'titleShow': false , 'hideOnOverlayClick' : false });
+ $(".remove_person_button").fancybox({ 'titleShow': false , 'hideOnOverlayClick' : false });
$(".question_mark").fancybox({ 'titleShow': false , 'hideOnOverlayClick' : false });
$("input[type='submit']").addClass("button");
diff --git a/public/stylesheets/sass/application.sass b/public/stylesheets/sass/application.sass
index bffe9e526..db0b32edc 100644
--- a/public/stylesheets/sass/application.sass
+++ b/public/stylesheets/sass/application.sass
@@ -202,6 +202,71 @@ header
.avatar
:border-radius 5px
+
+.from
+ :font
+ :family 'Helvetica neue', Arial, Helvetica, sans-serif
+ :text
+ :shadow 0 1px #fff
+
+ .aspect
+ :cursor default
+ :display inline
+ :color #bbb
+ :font
+ :size 85%
+ a
+ :font
+ :weight normal
+ :color #bbb
+
+ &:hover
+ :text
+ :decoration underline
+ &:active
+ :color #999
+ ul
+ :display inline
+ :margin 0
+ :padding 0
+ :list
+ :style none
+ li
+ :display inline
+ &:after
+ :content ","
+ &:last-child:after
+ :content ""
+
+ a
+ :font
+ :weight bold
+
+#author_info
+ :position relative
+ :padding
+ :left 65px
+ :height 70px
+
+ img
+ :position absolute
+ :top 8px
+ :left 0
+
+ h2
+ :margin
+ :bottom -2px
+ a
+ :font
+ :weight normal
+
+ .from
+ :font
+ :size 14px
+
+ .avatar
+ :border-radius 5px
+
li.message
:position relative
:line-height 19px
@@ -220,44 +285,6 @@ li.message
:padding
:left 65px
- .from
- :font
- :family 'Helvetica neue', Arial, Helvetica, sans-serif
- :text
- :shadow 0 1px #fff
-
- .aspect
- :cursor default
- :display inline
- :color #bbb
- :font
- :size 12px
- a
- :font
- :weight normal
- :color #bbb
-
- &:hover
- :text
- :decoration underline
- &:active
- :color #999
- ul
- :display inline
- :margin 0
- :padding 0
- :list
- :style none
- li
- :display inline
- &:after
- :content ","
- &:last-child:after
- :content ""
-
- a
- :font
- :weight bold
:color #444
:font
@@ -639,8 +666,11 @@ label
:position relative
textarea
- :width 515px
:height 42px
+
+ input[type='text'],
+ textarea
+ :width 515px
:margin 0
.options_and_submit
@@ -873,13 +903,7 @@ h1.big_text
:padding 2px
-.aspect,
-.requests,
-.remove,
-.aspect_remove
- :list
- :style none
-
+.aspect
h3
:display inline-block
@@ -914,63 +938,115 @@ h1.big_text
&:last-child
:margin
:right 0
-
- .grey
- :color #999
- :cursor default
- :text-shadow 0 1px #fff
+.aspect,
+.requests,
+.aspect_remove
+ :list
+ :style none
+ :color #999
+ :cursor default
+ :text-shadow 0 1px #fff
ul.dropzone
+ :position relative
:min-height 20px
:margin 0
:bottom 25px
- :background
- :color #efefef
- :border 1px solid #ccc
+
+ :-webkit-border-radius 10px
+ :-moz-border-radius 10px
+ :border-radius 10px
+
:list
:style none
:padding 15px
+ :border 2px dashed #ccc
&.active
:background
- :color #fafafa
+ :color rgba(255,252,127,0.2)
- .person,
- .requested_person
+ .draggable_info
+ :position absolute
+ :display none
+ :right 15px
+ :bottom 10px
+ :font
+ :style italic
+ :size 14px
+ :color #aaa
+
+ .person
:display inline-block
- :padding 5px
:cursor move
- :margin 5px
:z-index 10
+ :position relative
+ :padding 0
+ :margin 5px
- :width 110px
-
- :background
- :color #333
-
- :border-radius 5px
- :color #ccc
-
- a
- :color #ccc
+ :color #eee
img
- :height 40px
- :width 40px
- :display inline
+ :height 70px
+ :width 70px
+ :border-radius 5px
+ :-webkit-box-shadow 0 1px 2px #999
- .name
- :display inline
- :top 0
- :margin
- :left 5px
+ &:hover
+ .delete
+ :display inline
&:active
:z-index 20
- :color #666
- :-webkit-box-shadow 0 1px 3px #000
- :-moz-box-shadow 0 2px 4px #000
- :opacity 0.9
+ img
+ :-webkit-box-shadow 0 1px 3px #000
+ :-moz-box-shadow 0 2px 4px #000
+
+ .delete
+ :display none
+
+ .delete
+ :display none
+
+ :position absolute
+ :top -8px
+ :left -8px
+
+ .circle
+ :z-index 1
+ :position absolute
+ :background
+ :color #333
+
+ :width 20px
+ :max-width 20px
+ :height 20px
+ :max-height 20px
+
+ :border 1px solid #fff
+
+ :-webkit-border-radius 20px
+ :-moz-border-radius 20px
+ :border-radius 20px
+
+ :-webkit-box-shadow 0 1px 3px #000
+
+ .x
+ :z-index 2
+ :position absolute
+ :top 2px
+ :left 7px
+
+ &:hover
+ :cursor default
+ .circle
+ :background
+ :color rgba(208,49,43,1)
+
+
+.requests
+ ul.dropzone
+ :border 2px solid #ccc
ul#settings_nav
:display inline
@@ -1090,6 +1166,10 @@ header
h2
:display inline
+
+ .right
+ :margin
+ :top 10px
.modal_title_bar
:width 100%
@@ -1136,3 +1216,27 @@ header
.controls
:display inline
+ul#breadcrumb
+ :list
+ :style none
+ :margin 0
+ :padding 0
+ :font
+ :size 14px
+ :weight bold
+ :line
+ :height 3em
+
+ a
+ :font
+ :weight bold
+
+ > li
+ :display inline
+
+ &:after
+ :content ' ››'
+
+ &:last-child
+ &:after
+ :content ''
diff --git a/spec/controllers/publics_controller_spec.rb b/spec/controllers/publics_controller_spec.rb
index cf1a71d88..11a35da95 100644
--- a/spec/controllers/publics_controller_spec.rb
+++ b/spec/controllers/publics_controller_spec.rb
@@ -6,10 +6,10 @@ require 'spec_helper'
describe PublicsController do
render_views
- let(:user) {Factory.create :user}
- let(:user2){Factory.create :user}
- let(:aspect1){user.aspect(:name => "foo")}
- let(:aspect2){user2.aspect(:name => "far")}
+ let(:user) { Factory.create :user }
+ let(:user2) { Factory.create :user }
+ let(:aspect1) { user.aspect(:name => "foo") }
+ let(:aspect2) { user2.aspect(:name => "far") }
before do
sign_in :user, user
end
@@ -23,7 +23,7 @@ describe PublicsController do
it 'should accept a post from another node and save the information' do
message = user2.build_post(:status_message, :message => "hi")
friend_users(user, aspect1, user2, aspect2)
-
+
user.reload
user.visible_post_ids.include?(message.id).should be false
@@ -77,10 +77,13 @@ describe PublicsController do
end
describe 'friend requests' do
- let(:aspect2) {user2.aspect(:name => 'disciples')}
- let!(:req) {user2.send_friend_request_to(user.person, aspect2)}
- let!(:xml) {user2.salmon(req).xml_for(user.person)}
+ let(:aspect2) { user2.aspect(:name => 'disciples') }
+ let!(:req) { user2.send_friend_request_to(user.person, aspect2) }
+ let!(:xml) { user2.salmon(req).xml_for(user.person) }
before do
+ deliverable = Object.new
+ deliverable.stub!(:deliver)
+ Notifier.stub!(:new_request).and_return(deliverable)
req.delete
user2.reload
user2.pending_requests.count.should be 1
diff --git a/spec/factories.rb b/spec/factories.rb
index c66fa4f86..8d0b76aee 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -8,14 +8,15 @@
#This inclsion, because gpg-agent(not needed) is never run and hence never sets any env. variables on a MAC
Factory.define :profile do |p|
- p.first_name "Robert"
- p.last_name "Grimm"
+ p.sequence(:first_name){|n| "Robert#{n}"}
+ p.sequence(:last_name){|n| "Grimm#{n}"}
end
+
Factory.define :person do |p|
p.sequence(:diaspora_handle) {|n| "bob-person-#{n}@aol.com"}
p.sequence(:url) {|n| "http://google-#{n}.com/"}
- p.profile Factory.create(:profile)
+ p.profile Factory.create(:profile, :first_name => "eugene", :last_name => "weinstien")
p.serialized_public_key OpenSSL::PKey::RSA.generate(1024).public_key.export
end
@@ -32,7 +33,7 @@ Factory.define :user do |u|
u.password_confirmation "bluepin7"
u.serialized_private_key OpenSSL::PKey::RSA.generate(1024).export
u.after_build do |user|
- user.person = Factory.build(:person, :owner_id => user._id,
+ user.person = Factory.build(:person, :profile => Factory.create(:profile), :owner_id => user._id,
:serialized_public_key => user.encryption_key.public_key.export,
:diaspora_handle => "#{user.username}@#{APP_CONFIG[:pod_url].gsub(/(https?:|www\.)\/\//, '').chop!}")
end
diff --git a/spec/lib/exporter_spec.rb b/spec/lib/diaspora/exporter_spec.rb
similarity index 100%
rename from spec/lib/exporter_spec.rb
rename to spec/lib/diaspora/exporter_spec.rb
diff --git a/spec/lib/importer_spec.rb b/spec/lib/diaspora/importer_spec.rb
similarity index 100%
rename from spec/lib/importer_spec.rb
rename to spec/lib/diaspora/importer_spec.rb
diff --git a/spec/lib/ostatus_builder_spec.rb b/spec/lib/diaspora/ostatus_builder.rb
similarity index 100%
rename from spec/lib/ostatus_builder_spec.rb
rename to spec/lib/diaspora/ostatus_builder.rb
diff --git a/spec/lib/diaspora_parser_spec.rb b/spec/lib/diaspora/parser_spec.rb
similarity index 60%
rename from spec/lib/diaspora_parser_spec.rb
rename to spec/lib/diaspora/parser_spec.rb
index 72b3d96e0..f97a514c3 100644
--- a/spec/lib/diaspora_parser_spec.rb
+++ b/spec/lib/diaspora/parser_spec.rb
@@ -5,15 +5,15 @@
require 'spec_helper'
describe Diaspora::Parser do
- let(:user) {Factory.create(:user)}
- let(:aspect) {user.aspect(:name => 'spies')}
- let(:user2) {Factory.create(:user)}
- let(:aspect2){user2.aspect(:name => "pandas")}
- let(:user3) {Factory.create :user}
- let(:person) {user3.person}
+ let(:user) { Factory.create(:user) }
+ let(:aspect) { user.aspect(:name => 'spies') }
+ let(:user2) { Factory.create(:user) }
+ let(:aspect2) { user2.aspect(:name => "pandas") }
+ let(:user3) { Factory.create :user }
+ let(:person) { user3.person }
describe "parsing compliant XML object" do
- it 'should be able to correctly handle comments with person in db' do
+ it 'should be able to correctly handle comments with person in db' do
post = user.post :status_message, :message => "hello", :to => aspect.id
comment = Factory.build(:comment, :post => post, :person => @person, :text => "Freedom!")
xml = comment.to_diaspora_xml
@@ -25,7 +25,7 @@ describe Diaspora::Parser do
end
it 'should be able to correctly handle person on a comment with person not in db' do
- friend_users(user, aspect, user2, aspect2)
+ friend_users(user, aspect, user2, aspect2)
post = user.post :status_message, :message => "hello", :to => aspect.id
comment = user2.comment "Fool!", :on => post
@@ -40,42 +40,50 @@ describe Diaspora::Parser do
end
it 'should accept retractions' do
- friend_users(user, aspect, user2, aspect2)
+ friend_users(user, aspect, user2, aspect2)
message = Factory.create(:status_message, :person => user2.person)
retraction = Retraction.for(message)
xml = retraction.to_diaspora_xml
- proc {user.receive xml, user2.person}.should change(StatusMessage, :count).by(-1)
+ proc { user.receive xml, user2.person }.should change(StatusMessage, :count).by(-1)
end
- it "should create a new person upon getting a person request" do
- request = Request.instantiate(:to =>"http://www.google.com/", :from => person)
+ context "friending" do
+ before do
+ deliverable = Object.new
+ deliverable.stub!(:deliver)
+ Notifier.stub!(:new_request).and_return(deliverable)
+ end
- xml = request.to_diaspora_xml
+ it "should create a new person upon getting a person request" do
+ request = Request.instantiate(:to =>"http://www.google.com/", :from => person)
- user3.destroy
- person.destroy
- user
- lambda {user.receive xml, person}.should change(Person, :count).by(1)
- end
+ xml = request.to_diaspora_xml
- it "should not create a new person if the person is already here" do
- request = Request.instantiate(:to =>"http://www.google.com/", :from => user2.person)
- original_person_id = user2.person.id
- xml = request.to_diaspora_xml
- user
- lambda {user.receive xml, user2.person}.should_not change(Person, :count)
+ user3.destroy
+ person.destroy
+ user
+ lambda { user.receive xml, person }.should change(Person, :count).by(1)
+ end
- user2.reload
- user2.person.reload
- user2.serialized_private_key.include?("PRIVATE").should be true
+ it "should not create a new person if the person is already here" do
+ request = Request.instantiate(:to =>"http://www.google.com/", :from => user2.person)
+ original_person_id = user2.person.id
+ xml = request.to_diaspora_xml
+ user
+ lambda { user.receive xml, user2.person }.should_not change(Person, :count)
- url = "http://" + request.callback_url.split("/")[2] + "/"
- Person.where(:url => url).first.id.should == original_person_id
+ user2.reload
+ user2.person.reload
+ user2.serialized_private_key.include?("PRIVATE").should be true
+
+ url = "http://" + request.callback_url.split("/")[2] + "/"
+ Person.where(:url => url).first.id.should == original_person_id
+ end
end
it "should activate the Person if I initiated a request to that url" do
- request = user.send_friend_request_to( user3.person, aspect)
+ request = user.send_friend_request_to(user3.person, aspect)
user.reload
request.reverse_for user3
@@ -95,16 +103,16 @@ describe Diaspora::Parser do
end
it 'should process retraction for a person' do
- friend_users(user, aspect, user2, aspect2)
+ friend_users(user, aspect, user2, aspect2)
retraction = Retraction.for(user2)
retraction_xml = retraction.to_diaspora_xml
- lambda {user.receive retraction_xml, user2.person}.should change{
- aspect.reload.people.size}.by(-1)
+ lambda { user.receive retraction_xml, user2.person }.should change {
+ aspect.reload.people.size }.by(-1)
end
it 'should marshal a profile for a person' do
- friend_users(user, aspect, user2, aspect2)
+ friend_users(user, aspect, user2, aspect2)
#Create person
person = user2.person
id = person.id
@@ -132,9 +140,9 @@ describe Diaspora::Parser do
person = Person.first(:id => person.id)
person.profile.should_not be nil
person.profile.first_name.should == old_profile.first_name
- person.profile.last_name.should == old_profile.last_name
- person.profile.image_url.should == old_profile.image_url
- end
+ person.profile.last_name.should == old_profile.last_name
+ person.profile.image_url.should == old_profile.image_url
+ end
end
end
diff --git a/spec/lib/encryptor_spec.rb b/spec/lib/encryptor_spec.rb
new file mode 100644
index 000000000..e993dac45
--- /dev/null
+++ b/spec/lib/encryptor_spec.rb
@@ -0,0 +1,54 @@
+# Copyright (c) 2010, Diaspora Inc. This file is
+# licensed under the Affero General Public License version 3 or later. See
+# the COPYRIGHT file.
+
+require 'spec_helper'
+
+describe 'user encryption' do
+ before do
+ @user = Factory.create(:user)
+ @aspect = @user.aspect(:name => 'dudes')
+ end
+
+ describe 'key exchange on friending' do
+
+ it 'should receive and marshal a public key from a request' do
+ remote_user = Factory.build(:user)
+ remote_user.encryption_key.nil?.should== false
+
+ deliverable = Object.new
+ deliverable.stub!(:deliver)
+ Notifier.stub!(:new_request).and_return(deliverable)
+ Person.should_receive(:by_webfinger).and_return(remote_user.person)
+ #should move this to friend request, but i found it here
+ id = remote_user.person.id
+ original_key = remote_user.exported_key
+
+ request = remote_user.send_friend_request_to(
+ @user.person, remote_user.aspect(:name => "temp"))
+
+ xml = remote_user.salmon(request).xml_for(@user)
+
+ remote_user.person.delete
+ remote_user.delete
+
+ person_count = Person.all.count
+ @user.receive_salmon xml
+
+ Person.all.count.should == person_count + 1
+ new_person = Person.first(:id => id)
+ new_person.exported_key.should == original_key
+ end
+ end
+
+ describe 'encryption' do
+ before do
+ @string = File.open(File.dirname(__FILE__) + '/../fixtures/fb_status').read
+ end
+ it 'should encrypt a string' do
+ ciphertext = @user.encrypt @string
+ ciphertext.include?(@string).should be false
+ @user.decrypt(ciphertext).should == @string
+ end
+ end
+end
diff --git a/spec/mailers/notifier_spec.rb b/spec/mailers/notifier_spec.rb
new file mode 100644
index 000000000..88550680f
--- /dev/null
+++ b/spec/mailers/notifier_spec.rb
@@ -0,0 +1,46 @@
+
+require 'spec_helper'
+
+describe Notifier do
+
+ let!(:user) {Factory.create :user}
+ let!(:aspect) {user.aspect(:name => "science")}
+ let!(:person) {Factory.create :person}
+ let!(:request_mail) {Notifier.new_request(user, person)}
+ let!(:request_accepted_mail) {Notifier.request_accepted(user, person, aspect)}
+
+
+ describe "#new_request" do
+ it 'goes to the right person' do
+ request_mail.to.should == [user.email]
+ end
+
+ it 'has the receivers name in the body' do
+ request_mail.body.encoded.include?(user.person.profile.first_name).should be true
+ end
+
+
+ it 'has the name of person sending the request' do
+ request_mail.body.encoded.include?(person.real_name).should be true
+ end
+ end
+
+ describe "#request_accpeted" do
+ it 'goes to the right person' do
+ request_accepted_mail.to.should == [user.email]
+ end
+
+ it 'has the receivers name in the body' do
+ request_accepted_mail.body.encoded.include?(user.person.profile.first_name).should be true
+ end
+
+
+ it 'has the name of person sending the request' do
+ request_accepted_mail.body.encoded.include?(person.real_name).should be true
+ end
+
+ it 'has the name of the aspect in the body' do
+ request_accepted_mail.body.encoded.include?(aspect.name).should be true
+ end
+ end
+end
diff --git a/spec/models/comment_spec.rb b/spec/models/comment_spec.rb
index 1cd8e9b9d..66056789d 100644
--- a/spec/models/comment_spec.rb
+++ b/spec/models/comment_spec.rb
@@ -97,6 +97,10 @@ describe Comment do
user.receive comment.to_diaspora_xml, user2.person
end
+ context 'posts from a remote person' do
+ before(:all) do
+ stub_comment_signature_verification
+ end
it 'should not send a comment a person made on his own post to anyone' do
User::QUEUE.should_not_receive(:add_post_request)
comment = Comment.new(:person_id => @person.id, :text => "balls", :post => @person_status)
@@ -108,6 +112,10 @@ describe Comment do
comment = Comment.new(:person_id => @person2.id, :text => "balls", :post => @person_status)
user.receive comment.to_diaspora_xml, @person
end
+ after(:all) do
+ unstub_mocha_stubs
+ end
+ end
it 'should not clear the aspect post array on receiving a comment' do
aspect.post_ids.include?(@user_status.id).should be true
@@ -130,4 +138,50 @@ describe Comment do
comment.to_diaspora_xml.include?(commenter.person.id.to_s).should be true
end
end
+
+ describe 'comments' do
+ before do
+ friend_users(user, aspect, user2, aspect2)
+ @remote_message = user2.post :status_message, :message => "hello", :to => aspect2.id
+
+
+ @message = user.post :status_message, :message => "hi", :to => aspect.id
+ end
+ it 'should attach the creator signature if the user is commenting' do
+ user.comment "Yeah, it was great", :on => @remote_message
+ @remote_message.comments.first.signature_valid?.should be true
+ end
+
+ it 'should sign the comment if the user is the post creator' do
+ message = user.post :status_message, :message => "hi", :to => aspect.id
+ user.comment "Yeah, it was great", :on => message
+ message.comments.first.signature_valid?.should be true
+ message.comments.first.verify_post_creator_signature.should be true
+ end
+
+ it 'should verify a comment made on a remote post by a different friend' do
+ comment = Comment.new(:person => user2.person, :text => "cats", :post => @remote_message)
+ comment.creator_signature = comment.send(:sign_with_key,user2.encryption_key)
+ comment.signature_valid?.should be true
+ comment.verify_post_creator_signature.should be false
+ comment.post_creator_signature = comment.send(:sign_with_key,user.encryption_key)
+ comment.verify_post_creator_signature.should be true
+ end
+
+ it 'should reject comments on a remote post with only a creator sig' do
+ comment = Comment.new(:person => user2.person, :text => "cats", :post => @remote_message)
+ comment.creator_signature = comment.send(:sign_with_key,user2.encryption_key)
+ comment.signature_valid?.should be true
+ comment.verify_post_creator_signature.should be false
+ end
+
+ it 'should receive remote comments on a user post with a creator sig' do
+ comment = Comment.new(:person => user2.person, :text => "cats", :post => @message)
+ comment.creator_signature = comment.send(:sign_with_key,user2.encryption_key)
+ comment.signature_valid?.should be true
+ comment.verify_post_creator_signature.should be false
+ end
+
+ end
+
end
diff --git a/spec/models/person_spec.rb b/spec/models/person_spec.rb
index 4aae4daad..fa89610af 100644
--- a/spec/models/person_spec.rb
+++ b/spec/models/person_spec.rb
@@ -187,6 +187,25 @@ describe Person do
end
end
+
+ it 'should only find people who are exact matches' do
+ user = Factory(:user, :username => "SaMaNtHa")
+ person = Factory(:person, :diaspora_handle => "tomtom@tom.joindiaspora.com")
+ user.person.diaspora_handle = "tom@tom.joindiaspora.com"
+ user.person.save
+ Person.by_webfinger("tom@tom.joindiaspora.com").diaspora_handle.should == "tom@tom.joindiaspora.com"
+ end
+
+ it 'should return nil if there is not an exact match' do
+ Redfinger.stub!(:finger).and_return(nil)
+
+ person = Factory(:person, :diaspora_handle => "tomtom@tom.joindiaspora.com")
+ person1 = Factory(:person, :diaspora_handle => "tom@tom.joindiaspora.comm")
+ #Person.by_webfinger("tom@tom.joindiaspora.com").should_be false
+ proc{ Person.by_webfinger("tom@tom.joindiaspora.com")}.should raise_error
+ end
+
+
it 'identifier should be a valid email' do
stub_success("joe.valid+email@my-address.com")
Proc.new {
diff --git a/spec/models/request_spec.rb b/spec/models/request_spec.rb
index a7d242ee7..6483c45fa 100644
--- a/spec/models/request_spec.rb
+++ b/spec/models/request_spec.rb
@@ -28,6 +28,7 @@ describe Request do
xml.should include user.person.url
xml.should include user.profile.first_name
xml.should include user.profile.last_name
+ xml.should include user.exported_key
end
it 'should allow me to see only friend requests sent to me' do
@@ -56,6 +57,10 @@ describe Request do
end
it 'recognized when a request is not from me' do
+ deliverable = Object.new
+ deliverable.stub!(:deliver)
+ Notifier.stub!(:new_request).and_return(deliverable)
+
user2.receive_salmon(user.salmon(request).xml_for(user2.person))
user2.reload
user2.request_from_me?(request).should == false
@@ -64,6 +69,10 @@ describe Request do
context 'quering request through user' do
it 'finds requests for that user' do
+ deliverable = Object.new
+ deliverable.stub!(:deliver)
+ Notifier.stub!(:new_request).and_return(deliverable)
+
user2.receive_salmon(user.salmon(request).xml_for(user2.person))
user2.reload
user2.requests_for_me.include?(request).should == true
diff --git a/spec/models/status_message_spec.rb b/spec/models/status_message_spec.rb
index 8449b964c..086d66e80 100644
--- a/spec/models/status_message_spec.rb
+++ b/spec/models/status_message_spec.rb
@@ -21,6 +21,15 @@ describe StatusMessage do
status = @user.post(:status_message, :message => "Users do things", :to => @aspect.id)
end
+ it 'should require status messages to be less than 1000 characters' do
+ message = ''
+ 1001.times do message = message +'1';end
+ status = Factory.build(:status_message, :message => message)
+
+ status.should_not be_valid
+
+ end
+
describe "XML" do
it 'should serialize to XML' do
message = Factory.create(:status_message, :message => "I hate WALRUSES!", :person => @user.person)
diff --git a/spec/models/user/attack_vectors_spec.rb b/spec/models/user/attack_vectors_spec.rb
index 67235f447..36a586647 100644
--- a/spec/models/user/attack_vectors_spec.rb
+++ b/spec/models/user/attack_vectors_spec.rb
@@ -4,7 +4,7 @@
require 'spec_helper'
-describe User do
+describe "attack vectors" do
let(:user) { Factory(:user) }
let(:aspect) { user.aspect(:name => 'heroes') }
@@ -73,10 +73,11 @@ describe User do
profile.first_name = "Not BOB"
user2.reload
- user2.profile.first_name.should == "Robert"
+
+ first_name = user2.profile.first_name
proc{user.receive_salmon(user3.salmon(profile).xml_for(user.person))}.should raise_error /Malicious Post/
user2.reload
- user2.profile.first_name.should == "Robert"
+ user2.profile.first_name.should == first_name
end
it 'should not overwrite another persons profile through comment' do
diff --git a/spec/models/user/receive_spec.rb b/spec/models/user/receive_spec.rb
index 07b481b17..ab83b8c5d 100644
--- a/spec/models/user/receive_spec.rb
+++ b/spec/models/user/receive_spec.rb
@@ -115,6 +115,7 @@ describe User do
comment_id = comment.id
comment.delete
+ comment.post_creator_signature = comment.sign_with_key(user.encryption_key)
user3.receive comment.to_diaspora_xml, user.person
user3.reload
diff --git a/spec/models/user/user_friending_spec.rb b/spec/models/user/user_friending_spec.rb
index 2fde487b3..63a472031 100644
--- a/spec/models/user/user_friending_spec.rb
+++ b/spec/models/user/user_friending_spec.rb
@@ -1,20 +1,28 @@
+
# Copyright (c) 2010, Diaspora Inc. This file is
# licensed under the Affero General Public License version 3 or later. See
# the COPYRIGHT file.
require 'spec_helper'
-describe User do
- let(:user) {Factory.create :user}
- let(:aspect) {user.aspect(:name => 'heroes')}
- let(:aspect1) {user.aspect(:name => 'other')}
+describe Diaspora::UserModules::Friending do
+ let(:user) { Factory.create :user }
+ let(:aspect) { user.aspect(:name => 'heroes') }
+ let(:aspect1) { user.aspect(:name => 'other') }
let(:friend) { Factory.create(:person) }
- let(:person_one) {Factory.create :person}
- let(:person_two) {Factory.create :person}
-
- let(:user2) { Factory.create :user}
- let(:aspect2) { user2.aspect(:name => "aspect two")}
+ let(:person_one) { Factory.create :person }
+ let(:person_two) { Factory.create :person }
+
+ let(:user2) { Factory.create :user }
+ let(:aspect2) { user2.aspect(:name => "aspect two") }
+
+ before do
+ deliverable = Object.new
+ deliverable.stub!(:deliver)
+ Notifier.stub!(:new_request).and_return(deliverable)
+ Notifier.stub!(:request_accepted).and_return(deliverable)
+ end
context 'friend requesting' do
it "should assign a request to a aspect" do
@@ -29,9 +37,9 @@ describe User do
it "should be able to accept a pending friend request" do
r = Request.instantiate(:to => user.receive_url, :from => friend)
r.save
-
- proc {user.accept_friend_request(r.id, aspect.id)}.should change{
- Request.for_user(user).all.count}.by(-1)
+
+ proc { user.accept_friend_request(r.id, aspect.id) }.should change {
+ Request.for_user(user).all.count }.by(-1)
end
it 'should be able to ignore a pending friend request' do
@@ -39,8 +47,8 @@ describe User do
r = Request.instantiate(:to => user.receive_url, :from => friend)
r.save
- proc{user.ignore_friend_request(r.id)}.should change{
- Request.for_user(user).count}.by(-1)
+ proc { user.ignore_friend_request(r.id) }.should change {
+ Request.for_user(user).count }.by(-1)
end
it 'should not be able to friend request an existing friend' do
@@ -54,6 +62,13 @@ describe User do
proc { user.send_friend_request_to(nil, aspect) }.should raise_error(RuntimeError, /befriend yourself/)
end
+ it 'should send an email on acceptance if a friend request' do
+ Notifier.should_receive(:request_accepted)
+ request = user.send_friend_request_to(user2.person, aspect)
+ request.reverse_for(user2)
+ user.receive_friend_request(request)
+ end
+
describe 'multiple users accepting/rejecting the same person' do
@@ -81,40 +96,52 @@ describe User do
user2.receive @req_three_xml, user.person
end
it 'should befriend the user other user on the same pod' do
- proc{
+ proc {
user2.accept_friend_request @request_three.id, aspect2.id
}.should_not change(Person, :count)
user2.friends.include?(user.person).should be true
end
it 'should not delete the ignored user on the same pod' do
- proc{
+ proc {
user2.ignore_friend_request @request_three.id
}.should_not change(Person, :count)
user2.friends.include?(user.person).should be false
end
+
+ it 'sends an email to the receiving user' do
+ mail_obj = mock("mailer")
+ mail_obj.should_receive(:deliver)
+ Notifier.should_receive(:new_request).and_return(mail_obj)
+ user.receive @req_xml, person_one
+ end
+
+
end
context 'Two users receiving requests from one person' do
before do
user.receive @req_xml, person_one
-
user2.receive @req_two_xml, person_one
end
- it 'should both users should befriend the same person' do
- user.accept_friend_request @request.id, aspect.id
- user.friends.include?(person_one).should be true
- user2.accept_friend_request @request_two.id, aspect2.id
- user2.friends.include?(person_one).should be true
+ describe '#accept_friend_request' do
+ it 'should both users should befriend the same person' do
+ user.accept_friend_request @request.id, aspect.id
+ user.friends.include?(person_one).should be true
+
+ user2.accept_friend_request @request_two.id, aspect2.id
+ user2.friends.include?(person_one).should be true
+ end
+
+ it 'should keep the person around if one of the users rejects him' do
+ user.accept_friend_request @request.id, aspect.id
+ user.friends.include?(person_one).should be true
+
+ user2.ignore_friend_request @request_two.id
+ user2.friends.include?(person_one).should be false
+ end
end
- it 'should keep the person around if one of the users rejects him' do
- user.accept_friend_request @request.id, aspect.id
- user.friends.include?(person_one).should be true
-
- user2.ignore_friend_request @request_two.id
- user2.friends.include?(person_one).should be false
- end
it 'should keep the person around if the users ignores them' do
user.ignore_friend_request user.pending_requests.first.id
@@ -124,6 +151,8 @@ describe User do
user2.friends.include?(person_one).should be false
end
end
+
+
end
describe 'a user accepting rejecting multiple people' do
@@ -160,25 +189,25 @@ describe User do
describe 'unfriending' do
before do
- friend_users(user,aspect, user2, aspect2)
+ friend_users(user, aspect, user2, aspect2)
end
it 'should unfriend the other user on the same seed' do
- lambda {user2.unfriend user.person}.should change{
- user2.friends.count}.by(-1)
+ lambda { user2.unfriend user.person }.should change {
+ user2.friends.count }.by(-1)
aspect2.reload.people.count.should == 0
end
it 'is unfriended by another user' do
- lambda {user.unfriended_by user2.person}.should change{
- user.friends.count}.by(-1)
+ lambda { user.unfriended_by user2.person }.should change {
+ user.friends.count }.by(-1)
aspect.reload.people.count.should == 0
end
it 'should remove the friend from all aspects they are in' do
user.add_person_to_aspect(user2.person.id, aspect1.id)
- lambda {user.unfriended_by user2.person}.should change{
- user.friends.count}.by(-1)
+ lambda { user.unfriended_by user2.person }.should change {
+ user.friends.count }.by(-1)
aspect.reload.people.count.should == 0
aspect1.reload.people.count.should == 0
end
@@ -186,9 +215,9 @@ describe User do
context 'with a post' do
before do
@message = user.post(:status_message, :message => "hi", :to => aspect.id)
- user2.receive @message.to_diaspora_xml.to_s, user.person
- user2.unfriend user.person
- user.unfriended_by user2.person
+ user2.receive @message.to_diaspora_xml.to_s, user.person
+ user2.unfriend user.person
+ user.unfriended_by user2.person
end
it "deletes the unfriended user's posts from visible_posts" do
user.reload.raw_visible_posts.include?(@message.id).should be_false
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 4b2a4d02d..351d5347c 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -10,6 +10,10 @@ describe User do
let(:user2) { Factory(:user) }
let(:aspect2) { user2.aspect(:name => 'stuff') }
+ it 'should have a key' do
+ user.encryption_key.should_not be nil
+ end
+
describe "validation" do
describe "of associated person" do
it "fails if person is not valid" do
@@ -69,6 +73,11 @@ describe User do
user = Factory.build(:user, :username => "bobby tables")
user.should_not be_valid
end
+
+ it 'can not contain non url safe characters' do
+ user = Factory.build(:user, :username => "kittens;")
+ user.should_not be_valid
+ end
end
describe "of email" do
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
index 218def68b..29d731b29 100644
--- a/spec/spec_helper.rb
+++ b/spec/spec_helper.rb
@@ -25,10 +25,6 @@ RSpec.configure do |config|
DatabaseCleaner.strategy = :truncation
DatabaseCleaner.orm = "mongo_mapper"
- config.before(:suite) do
- stub_signature_verification
- end
-
config.before(:each) do
stub_sockets
DatabaseCleaner.clean
@@ -49,10 +45,8 @@ ImageUploader.enable_processing = false
Diaspora::WebSocket.unstub!(:unsubscribe)
end
- def stub_signature_verification
- (get_models.map{|model| model.camelize.constantize} - [User]).each do |model|
- model.any_instance.stubs(:verify_signature).returns(true)
- end
+ def stub_comment_signature_verification
+ Comment.any_instance.stubs(:verify_signature).returns(true)
end
def unstub_mocha_stubs
@@ -82,11 +76,11 @@ ImageUploader.enable_processing = false
aspect2.reload
end
- def stub_success(address = 'abc@example.com')
+ def stub_success(address = 'abc@example.com', opts = {})
host = address.split('@')[1]
stub_request(:get, "https://#{host}/.well-known/host-meta").to_return(:status => 200, :body => host_xrd)
stub_request(:get, "http://#{host}/.well-known/host-meta").to_return(:status => 200, :body => host_xrd)
- if host.include?("joindiaspora.com")
+ if opts[:diaspora] || host.include?("diaspora")
stub_request(:get, /webfinger\/\?q=#{address}/).to_return(:status => 200, :body => finger_xrd)
stub_request(:get, "http://#{host}/hcard/users/4c8eccce34b7da59ff000002").to_return(:status => 200, :body => hcard_response)
else
diff --git a/spec/user_encryption_spec.rb b/spec/user_encryption_spec.rb
deleted file mode 100644
index 645563b9a..000000000
--- a/spec/user_encryption_spec.rb
+++ /dev/null
@@ -1,113 +0,0 @@
-# Copyright (c) 2010, Diaspora Inc. This file is
-# licensed under the Affero General Public License version 3 or later. See
-# the COPYRIGHT file.
-
-require 'spec_helper'
-
-describe 'user encryption' do
- before do
- unstub_mocha_stubs
- @user = Factory.create(:user)
- @aspect = @user.aspect(:name => 'dudes')
-
- @user2 = Factory.create(:user)
- @aspect2 = @user2.aspect(:name => 'dudes')
- end
-
- after do
- stub_signature_verification
- #gpgdir = File.expand_path("../../db/gpg-#{Rails.env}", __FILE__)
- #ctx = GPGME::Ctx.new
- #keys = ctx.keys
- #keys.each{|k| ctx.delete_key(k, true)}
- end
- it 'should have a key' do
- @user.encryption_key.should_not be nil
- end
- describe 'key exchange on friending' do
- it 'should send over a public key' do
- message_queue.stub!(:add_post_request)
- request = @user.send_friend_request_to(Factory.create(:person), @aspect)
- request.to_diaspora_xml.include?( @user.exported_key).should be true
- end
-
- it 'should receive and marshal a public key from a request' do
- remote_user = Factory.build(:user)
- remote_user.encryption_key.nil?.should== false
- #should move this to friend request, but i found it here
- id = remote_user.person.id
- original_key = remote_user.exported_key
-
- request = remote_user.send_friend_request_to(
- @user.person, remote_user.aspect(:name => "temp"))
-
- xml = request.to_diaspora_xml
-
- remote_user.person.delete
- remote_user.delete
-
- person_count = Person.all.count
- @user.receive xml, remote_user.person
-
- Person.all.count.should == person_count + 1
- new_person = Person.first(:id => id)
- new_person.exported_key.should == original_key
- end
- end
-
- describe 'encryption' do
- before do
- @message = @user.post :status_message, :message => "hi", :to => @aspect.id
- end
- it 'should encrypt large messages' do
- ciphertext = @user.encrypt @message.to_diaspora_xml
- ciphertext.include?(@message.to_diaspora_xml).should be false
- @user.decrypt(ciphertext).include?(@message.to_diaspora_xml).should be true
- end
- end
-
- describe 'comments' do
- before do
- friend_users(@user, @aspect, @user2, @aspect2)
- @remote_message = @user2.post :status_message, :message => "hello", :to => @aspect2.id
-
-
- @message = @user.post :status_message, :message => "hi", :to => @aspect.id
- end
- it 'should attach the creator signature if the user is commenting' do
- @user.comment "Yeah, it was great", :on => @remote_message
- @remote_message.comments.first.signature_valid?.should be true
- end
-
- it 'should sign the comment if the user is the post creator' do
- message = @user.post :status_message, :message => "hi", :to => @aspect.id
- @user.comment "Yeah, it was great", :on => message
- message.comments.first.signature_valid?.should be true
- message.comments.first.verify_post_creator_signature.should be true
- end
-
- it 'should verify a comment made on a remote post by a different friend' do
- comment = Comment.new(:person => @user2.person, :text => "cats", :post => @remote_message)
- comment.creator_signature = comment.send(:sign_with_key,@user2.encryption_key)
- comment.signature_valid?.should be true
- comment.verify_post_creator_signature.should be false
- comment.post_creator_signature = comment.send(:sign_with_key,@user.encryption_key)
- comment.verify_post_creator_signature.should be true
- end
-
- it 'should reject comments on a remote post with only a creator sig' do
- comment = Comment.new(:person => @user2.person, :text => "cats", :post => @remote_message)
- comment.creator_signature = comment.send(:sign_with_key,@user2.encryption_key)
- comment.signature_valid?.should be true
- comment.verify_post_creator_signature.should be false
- end
-
- it 'should receive remote comments on a user post with a creator sig' do
- comment = Comment.new(:person => @user2.person, :text => "cats", :post => @message)
- comment.creator_signature = comment.send(:sign_with_key,@user2.encryption_key)
- comment.signature_valid?.should be true
- comment.verify_post_creator_signature.should be false
- end
-
- end
-end