From 3bea0f2128d384c8b1bc498e0c128ab89bce1028 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Mon, 11 Jun 2012 14:51:28 -0400 Subject: [PATCH 01/19] changed the views to show discussion instead of message --- app/views/inbox/index.html.erb | 2 +- app/views/messages/_message_list.html.erb | 2 +- app/views/messages/_message_list_row.html.erb | 2 +- app/views/messages/show.html.erb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/views/inbox/index.html.erb b/app/views/inbox/index.html.erb index e67a407..82b7fa4 100644 --- a/app/views/inbox/index.html.erb +++ b/app/views/inbox/index.html.erb @@ -45,7 +45,7 @@
- Messages <%= link_to_help "messages" %> + Discussions <%= link_to_help "messages" %>
<%= render :partial => 'messages/message_list' %> diff --git a/app/views/messages/_message_list.html.erb b/app/views/messages/_message_list.html.erb index 05a93d6..fb24946 100644 --- a/app/views/messages/_message_list.html.erb +++ b/app/views/messages/_message_list.html.erb @@ -19,4 +19,4 @@
-<%= link_to "New Message", new_message_path %> +<%= link_to "New Discussion", new_message_path %> diff --git a/app/views/messages/_message_list_row.html.erb b/app/views/messages/_message_list_row.html.erb index 851d180..3282826 100644 --- a/app/views/messages/_message_list_row.html.erb +++ b/app/views/messages/_message_list_row.html.erb @@ -11,6 +11,6 @@ <% else %> <%= link_to message.subject, message %> <% end %> - <%= link_to "Leave this message", message_leave_path(message), :remote => true %> + <%= link_to "Leave this discussion", message_leave_path(message), :remote => true %> <%= message.recipients.collect { |r| r.full_name }.to_sentence %> diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb index 68e5d45..134d447 100644 --- a/app/views/messages/show.html.erb +++ b/app/views/messages/show.html.erb @@ -1,7 +1,7 @@ <%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public License version 3 or later. See the COPYRIGHT file for details. %> -<%= pageHeading("Viewing message") %> +<%= pageHeading("Viewing discussion") %> From 4af62ac3a3330a262cdf64c7a7c25a9a2f7a00ff Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Tue, 12 Jun 2012 14:16:19 -0400 Subject: [PATCH 02/19] bleh --- Gemfile.lock | 2 +- app/models/discussion.rb | 66 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 1 deletion(-) create mode 100644 app/models/discussion.rb diff --git a/Gemfile.lock b/Gemfile.lock index 6e33bc1..15ffacf 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -165,7 +165,7 @@ GEM tilt (~> 1.1, != 1.3.0) sqlite3 (1.3.6) sqlite3 (1.3.6-x86-mingw32) - squeel (1.0.2) + squeel (1.0.5) activerecord (~> 3.0) activesupport (~> 3.0) polyamorous (~> 0.5.0) diff --git a/app/models/discussion.rb b/app/models/discussion.rb new file mode 100644 index 0000000..eb618b9 --- /dev/null +++ b/app/models/discussion.rb @@ -0,0 +1,66 @@ +# Copyright 2011-2012 Rice University. Licensed under the Affero General Public +# License version 3 or later. See the COPYRIGHT file for details. + +class Discussion < ActiveRecord::Base + + has_one :comment_thread, :as => :commentable, :dependent => :destroy + before_validation :build_comment_thread, :on => :create + validates_presence_of :comment_thread + validate :subject_not_changed + + attr_accessor :body + + attr_accessible #none + + def self.messages_for(user) + CommentThreadSubscription.message_subscriptions_for(user).collect { |cts| cts.comment_thread.commentable } + end + + def subject + s = read_attribute(:subject) + s.blank? ? "[No Subject]" : s + end + + def recipients + comment_thread.comment_thread_subscriptions.collect { |cts| cts.user } + end + + def has_recipient?(user) + recipients.any?{|r| r == user} + end + + def unsubscribe_callback + destroy if comment_thread.reload.comment_thread_subscriptions.blank? + true + end + + ############################################################################# + # Access control methods + ############################################################################# + + def can_be_read_by?(user) + !user.is_anonymous? && (comment_thread.comment_thread_subscriptions.detect { |cts| cts.user == user } || user.is_administrator?) + end + + def can_be_created_by?(user) + !user.is_anonymous? + end + + def can_be_updated_by?(user) + !user.is_anonymous? && (comment_thread.comment_thread_subscriptions.detect { |cts| cts.user == user } || user.is_administrator?) + end + + def can_be_joined_by?(user) + !user.is_anonymous? && + !comment_thread.comment_thread_subscriptions.detect { |cts| cts.user == user } + end + +protected + + def subject_not_changed + return if !subject_changed? || comment_thread.comments.blank? + errors.add(:base, "You can't change a discussion's subject after it is sent.") + false + end + +end From 3ac99a523ce83f012f302b7c37ce0ec6b5b207e9 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Tue, 12 Jun 2012 14:30:38 -0400 Subject: [PATCH 03/19] bleh --- app/controllers/discussions_controller.rb | 129 ++++++++++++++++++++++ app/views/inbox/index.html.erb | 2 +- 2 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 app/controllers/discussions_controller.rb diff --git a/app/controllers/discussions_controller.rb b/app/controllers/discussions_controller.rb new file mode 100644 index 0000000..926d579 --- /dev/null +++ b/app/controllers/discussions_controller.rb @@ -0,0 +1,129 @@ +# Copyright 2011-2012 Rice University. Licensed under the Affero General Public +# License version 3 or later. See the COPYRIGHT file for details. + +class MessagesController < ApplicationController + + before_filter :include_jquery + + before_filter :get_message, :only => [:add_recipient, :search_recipients, :leave] + + # GET /messages/1 + def show + @message = Message.find(params[:id]) + + raise SecurityTransgression unless present_user.can_read?(@message) + + @message.comment_thread.mark_as_read_for(present_user) + present_user.reload + + respond_to do |format| + format.html # show.html.erb + end + end + + # GET /messages/new + def new + @message = Message.new + + raise SecurityTransgression unless present_user.can_create?(@message) + + respond_to do |format| + if @message.save + @message.comment_thread.subscribe!(present_user) + format.html { redirect_to @message } + else + format.html { redirect_to inbox_path } + end + end + end + + # PUT /messages/1 + def update + @message = Message.find(params[:id]) + + raise SecurityTransgression unless present_user.can_create?(@message) + + @message.subject = params[:message][:subject] + + @comment = Comment.new + @comment.message = params[:message][:body] + @comment.comment_thread = @message.comment_thread + @comment.creator = present_user + + raise SecurityTransgression unless present_user.can_create?(@comment) + + respond_to do |format| + if @message.save && @comment.save + @message.comment_thread.add_unread_except_for(present_user) + flash[:notice] = 'Message was sent successfully.' + format.html { redirect_to @message } + else + format.html { redirect_to @message } + end + end + end + + def leave + @message.comment_thread.unsubscribe!(present_user) + end + + def new_recipient + @action_dialog_title = "Add a recipient" + @action_search_path = message_search_recipients_path(params[:message_id]) + + respond_to do |format| + format.js { render :template => 'users/action_new' } + end + end + + def search_recipients + @selected_type = params[:selected_type] + @text_query = params[:text_query] + @users = User.search(@selected_type, @text_query) + + @users.reject! do |user| + @message.has_recipient?(user) + end + + @action_partial = 'messages/create_recipient_form' + + respond_to do |format| + format.js { render :template => 'users/action_search' } + end + end + + # POST /messages/1/add_recipient + def add_recipient + raise SecurityTransgression unless present_user.can_update?(@message) + + @recipient = User.find_by_username(params[:username]) + + if @recipient.nil? + flash[:alert] = 'User ' + params[:username] + ' not found!' + respond_to do |format| + format.html { redirect_to @message } + format.js { render :template => 'shared/display_flash' } + end + return + end + + respond_to do |format| + if @message.comment_thread.subscribe!(@recipient) + @message.comment_thread.mark_as_unread_for(@recipient) + format.html { redirect_to @message } + format.js + else + flash[:alert] = @message.comment_thread.errors.values.to_sentence + format.html { redirect_to @message } + format.js { render :template => 'shared/display_flash' } + end + end + end + +protected + + def get_message + @message = Message.find(params[:message_id]) + end + +end diff --git a/app/views/inbox/index.html.erb b/app/views/inbox/index.html.erb index e67a407..82b7fa4 100644 --- a/app/views/inbox/index.html.erb +++ b/app/views/inbox/index.html.erb @@ -45,7 +45,7 @@
- Messages <%= link_to_help "messages" %> + Discussions <%= link_to_help "messages" %>
<%= render :partial => 'messages/message_list' %> From 59d52ab93ef74262c543cb41cfb56800fa2e047e Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Tue, 12 Jun 2012 15:15:16 -0400 Subject: [PATCH 04/19] blah v3 --- app/controllers/discussions_controller.rb | 62 +++++++++---------- config/routes.rb | 2 +- test/factories.rb | 2 +- .../functional/discussions_controller_test.rb | 59 ++++++++++++++++++ test/unit/discussion_test.rb | 11 ++++ 5 files changed, 103 insertions(+), 33 deletions(-) create mode 100644 test/functional/discussions_controller_test.rb create mode 100644 test/unit/discussion_test.rb diff --git a/app/controllers/discussions_controller.rb b/app/controllers/discussions_controller.rb index 926d579..cd047c3 100644 --- a/app/controllers/discussions_controller.rb +++ b/app/controllers/discussions_controller.rb @@ -1,19 +1,19 @@ # Copyright 2011-2012 Rice University. Licensed under the Affero General Public # License version 3 or later. See the COPYRIGHT file for details. -class MessagesController < ApplicationController +class DiscussionsController < ApplicationController before_filter :include_jquery - before_filter :get_message, :only => [:add_recipient, :search_recipients, :leave] + before_filter :get_discussion, :only => [:add_recipient, :search_recipients, :leave] - # GET /messages/1 + # GET /discussions/1 def show - @message = Message.find(params[:id]) + @discussion = Discussion.find(params[:id]) - raise SecurityTransgression unless present_user.can_read?(@message) + raise SecurityTransgression unless present_user.can_read?(@discussion) - @message.comment_thread.mark_as_read_for(present_user) + @discussion.comment_thread.mark_as_read_for(present_user) present_user.reload respond_to do |format| @@ -21,50 +21,50 @@ def show end end - # GET /messages/new + # GET /discussions/new def new - @message = Message.new + @discussion = Discussion.new - raise SecurityTransgression unless present_user.can_create?(@message) + raise SecurityTransgression unless present_user.can_create?(@discussion) respond_to do |format| - if @message.save - @message.comment_thread.subscribe!(present_user) - format.html { redirect_to @message } + if @discussion.save + @discussion.comment_thread.subscribe!(present_user) + format.html { redirect_to @discussion } else format.html { redirect_to inbox_path } end end end - # PUT /messages/1 + # PUT /discussions/1 def update - @message = Message.find(params[:id]) + @discussion = Discussion.find(params[:id]) - raise SecurityTransgression unless present_user.can_create?(@message) + raise SecurityTransgression unless present_user.can_create?(@discussion) - @message.subject = params[:message][:subject] + @discussion.subject = params[:message][:subject] @comment = Comment.new @comment.message = params[:message][:body] - @comment.comment_thread = @message.comment_thread + @comment.comment_thread = @discussion.comment_thread @comment.creator = present_user raise SecurityTransgression unless present_user.can_create?(@comment) respond_to do |format| - if @message.save && @comment.save - @message.comment_thread.add_unread_except_for(present_user) + if @discussion.save && @comment.save + @discussion.comment_thread.add_unread_except_for(present_user) flash[:notice] = 'Message was sent successfully.' - format.html { redirect_to @message } + format.html { redirect_to @discussion } else - format.html { redirect_to @message } + format.html { redirect_to @discussion } end end end def leave - @message.comment_thread.unsubscribe!(present_user) + @discussion.comment_thread.unsubscribe!(present_user) end def new_recipient @@ -82,7 +82,7 @@ def search_recipients @users = User.search(@selected_type, @text_query) @users.reject! do |user| - @message.has_recipient?(user) + @discussion.has_recipient?(user) end @action_partial = 'messages/create_recipient_form' @@ -94,27 +94,27 @@ def search_recipients # POST /messages/1/add_recipient def add_recipient - raise SecurityTransgression unless present_user.can_update?(@message) + raise SecurityTransgression unless present_user.can_update?(@discussion) @recipient = User.find_by_username(params[:username]) if @recipient.nil? flash[:alert] = 'User ' + params[:username] + ' not found!' respond_to do |format| - format.html { redirect_to @message } + format.html { redirect_to @discussion } format.js { render :template => 'shared/display_flash' } end return end respond_to do |format| - if @message.comment_thread.subscribe!(@recipient) - @message.comment_thread.mark_as_unread_for(@recipient) - format.html { redirect_to @message } + if @discussion.comment_thread.subscribe!(@recipient) + @discussion.comment_thread.mark_as_unread_for(@recipient) + format.html { redirect_to @discussion } format.js else - flash[:alert] = @message.comment_thread.errors.values.to_sentence - format.html { redirect_to @message } + flash[:alert] = @discussion.comment_thread.errors.values.to_sentence + format.html { redirect_to @discussion } format.js { render :template => 'shared/display_flash' } end end @@ -123,7 +123,7 @@ def add_recipient protected def get_message - @message = Message.find(params[:message_id]) + @discussion = Discussion.find(params[:message_id]) end end diff --git a/config/routes.rb b/config/routes.rb index a4e0518..5c6d253 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -212,7 +212,7 @@ def votable votable end - resources :messages, :only => [:new, :show, :update] do + resources :discussions, :only => [:new, :show, :update] do get 'new_recipient' post 'search_recipients' post 'add_recipient' diff --git a/test/factories.rb b/test/factories.rb index 35291f5..bcceb32 100644 --- a/test/factories.rb +++ b/test/factories.rb @@ -267,7 +267,7 @@ def make_project(options = {}) f.association :user end -Factory.define :message do |f| +Factory.define :discussion do |f| f.subject {Factory.next :content} end diff --git a/test/functional/discussions_controller_test.rb b/test/functional/discussions_controller_test.rb new file mode 100644 index 0000000..bc9aff4 --- /dev/null +++ b/test/functional/discussions_controller_test.rb @@ -0,0 +1,59 @@ +# Copyright 2011-2012 Rice University. Licensed under the Affero General Public +# License version 3 or later. See the COPYRIGHT file for details. + +require 'test_helper' + +class DiscussionsControllerTest < ActionController::TestCase + + setup do + @user = Factory.create(:user) + @discussion = Factory.create(:discussion) + @discussion.comment_thread.subscribe!(@user) + end + + test "should not get new not logged in" do + get :new + assert_redirected_to login_path + end + + test "should get new" do + user_login + get :new + assert_redirected_to message_path(assigns[:message]) + end + + test "should not show message not logged in" do + get :show, :id => @message.to_param + assert_redirected_to login_path + end + + test "should not show message not authorized" do + user_login + get :show, :id => @message.to_param + assert_response(403) + end + + test "should show message" do + sign_in @user + get :show, :id => @message.to_param + assert_response :success + end + + test "should not update message not logged in" do + put :update, :id => @message.to_param, :message => @message.attributes + assert_redirected_to login_path + end + + test "should not update message not authorized" do + user_login + put :update, :id => @message.to_param, :message => @message.attributes + assert_response(403) + end + + test "should update message" do + sign_in @user + put :update, :id => @message.to_param, :message => @message.attributes + assert_redirected_to message_path(assigns(:message)) + end + +end diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb new file mode 100644 index 0000000..41bf043 --- /dev/null +++ b/test/unit/discussion_test.rb @@ -0,0 +1,11 @@ +# Copyright 2011-2012 Rice University. Licensed under the Affero General Public +# License version 3 or later. See the COPYRIGHT file for details. + +require 'test_helper' + +class DiscussionTest < ActiveSupport::TestCase + # Replace this with your real tests. + test "the truth" do + assert true + end +end From 255ac831e7da36da0ef7264c9b2a81a9bbba56d2 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Tue, 12 Jun 2012 16:27:33 -0400 Subject: [PATCH 05/19] ugh...so many changes.... --- app/controllers/discussions_controller.rb | 10 ++--- app/models/comment_thread_subscription.rb | 13 +++--- app/models/discussion.rb | 4 +- .../_create_recipient_form.html.erb | 11 +++++ .../discussions/_discussion_list.html.erb | 22 ++++++++++ .../discussions/_discussion_list_row.html.erb | 16 ++++++++ app/views/discussions/_form.html.erb | 20 ++++++++++ app/views/discussions/_recipient.html.erb | 4 ++ app/views/discussions/_show.html.erb | 8 ++++ app/views/discussions/add_recipient.js.erb | 10 +++++ app/views/discussions/leave.js.erb | 10 +++++ app/views/discussions/show.html.erb | 40 +++++++++++++++++++ 12 files changed, 154 insertions(+), 14 deletions(-) create mode 100644 app/views/discussions/_create_recipient_form.html.erb create mode 100644 app/views/discussions/_discussion_list.html.erb create mode 100644 app/views/discussions/_discussion_list_row.html.erb create mode 100644 app/views/discussions/_form.html.erb create mode 100644 app/views/discussions/_recipient.html.erb create mode 100644 app/views/discussions/_show.html.erb create mode 100644 app/views/discussions/add_recipient.js.erb create mode 100644 app/views/discussions/leave.js.erb create mode 100644 app/views/discussions/show.html.erb diff --git a/app/controllers/discussions_controller.rb b/app/controllers/discussions_controller.rb index cd047c3..a03e01b 100644 --- a/app/controllers/discussions_controller.rb +++ b/app/controllers/discussions_controller.rb @@ -69,7 +69,7 @@ def leave def new_recipient @action_dialog_title = "Add a recipient" - @action_search_path = message_search_recipients_path(params[:message_id]) + @action_search_path = discussion_search_recipients_path(params[:discussion_id]) respond_to do |format| format.js { render :template => 'users/action_new' } @@ -85,14 +85,14 @@ def search_recipients @discussion.has_recipient?(user) end - @action_partial = 'messages/create_recipient_form' + @action_partial = 'discussions/create_recipient_form' respond_to do |format| format.js { render :template => 'users/action_search' } end end - # POST /messages/1/add_recipient + # POST /discussions/1/add_recipient def add_recipient raise SecurityTransgression unless present_user.can_update?(@discussion) @@ -122,8 +122,8 @@ def add_recipient protected - def get_message - @discussion = Discussion.find(params[:message_id]) + def get_discussion + @discussion = Discussion.find(params[:discussion_id]) end end diff --git a/app/models/comment_thread_subscription.rb b/app/models/comment_thread_subscription.rb index 05e9c22..59ab102 100644 --- a/app/models/comment_thread_subscription.rb +++ b/app/models/comment_thread_subscription.rb @@ -10,10 +10,10 @@ class CommentThreadSubscription < ActiveRecord::Base validates_uniqueness_of :user_id, :scope => :comment_thread_id - scope :message_subscriptions, joins{comment_thread}.where{comment_thread.commentable_type == "Message"} + scope :discussion_subscriptions, joins{comment_thread}.where{comment_thread.commentable_type == "Message"} - def self.message_subscriptions_for(user) - where{user_id == user.id}.message_subscriptions + def self.discussion_subscriptions_for(user) + where{user_id == user.id}.discussion_subscriptions end def mark_all_as_read! @@ -33,11 +33,10 @@ def add_unread! protected - def update_message_cache + def update_discussion_cache return unless comment_thread.commentable_type == 'Message' user.update_attribute(:unread_message_count, - Array.new(CommentThreadSubscription.message_subscriptions_for(user)).sum { |ms| - ms.unread_count }) + Array.new(CommentThreadSubscription.discussion_subscriptions_for(user)).sum { |ms| + ms.unread_count }) end - end diff --git a/app/models/discussion.rb b/app/models/discussion.rb index eb618b9..89766e4 100644 --- a/app/models/discussion.rb +++ b/app/models/discussion.rb @@ -12,8 +12,8 @@ class Discussion < ActiveRecord::Base attr_accessible #none - def self.messages_for(user) - CommentThreadSubscription.message_subscriptions_for(user).collect { |cts| cts.comment_thread.commentable } + def self.discussions_for(user) + CommentThreadSubscription.discussion_subscriptions_for(user).collect { |cts| cts.comment_thread.commentable } end def subject diff --git a/app/views/discussions/_create_recipient_form.html.erb b/app/views/discussions/_create_recipient_form.html.erb new file mode 100644 index 0000000..81aed08 --- /dev/null +++ b/app/views/discussions/_create_recipient_form.html.erb @@ -0,0 +1,11 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<%# Callers must supply a 'user' local variable %> + +<%= form_tag(discussion_add_recipient_path(@discussion), + :method => :post, + :remote => true) do %> + <%= hidden_field_tag :username, user.username %> + <%= submit_tag "Add", :class => submit_classes, :onclick => please_wait_js %> +<% end %> diff --git a/app/views/discussions/_discussion_list.html.erb b/app/views/discussions/_discussion_list.html.erb new file mode 100644 index 0000000..f7432ee --- /dev/null +++ b/app/views/discussions/_discussion_list.html.erb @@ -0,0 +1,22 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<% discussions = Discussion.discussions_for(current_user) %> + +
+ + + + + + style="display:none"<% end %>> + + + <% discussions.each do |discussion| %> + <%= render :partial => 'discussions/discussion_list_row', :locals => {:discussion => discussion} %> + <% end %> +
SubjectRecipients
None
+ +
+ +<%= link_to "New discussion", new_discussion_path %> diff --git a/app/views/discussions/_discussion_list_row.html.erb b/app/views/discussions/_discussion_list_row.html.erb new file mode 100644 index 0000000..92e043a --- /dev/null +++ b/app/views/discussions/_discussion_list_row.html.erb @@ -0,0 +1,16 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<% # Clients of this partial must supply the following variable: + # discussion +%> +<% unread_count = discussion.comment_thread.subscription_for(current_user).unread_count %> + + <% if unread_count > 0 %> + <%= link_to discussion.subject + " (" + unread_count.to_s + ")", discussion %> + <% else %> + <%= link_to discussion.subject, discussion %> + <% end %> + <%= link_to "Leave this discussion", discussion_leave_path(discussion), :remote => true %> + <%= discussion.recipients.collect { |r| r.full_name }.to_sentence %> + diff --git a/app/views/discussions/_form.html.erb b/app/views/discussions/_form.html.erb new file mode 100644 index 0000000..15e576c --- /dev/null +++ b/app/views/discussions/_form.html.erb @@ -0,0 +1,20 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<%= form_for(@discussion) do |f| %> +
+
+ <%= f.label :subject, "Subject:" %> + <%= f.text_field :subject %> +
+
+
+ <%= f.label :body, "Body:" %>
+ <%= f.text_area :body %> +
+
+
+ <%= f.submit :class => "#{submit_classes}", + :value => "Send" %> +
+<% end %> diff --git a/app/views/discussions/_recipient.html.erb b/app/views/discussions/_recipient.html.erb new file mode 100644 index 0000000..974e0f9 --- /dev/null +++ b/app/views/discussions/_recipient.html.erb @@ -0,0 +1,4 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +[<%= full_name_link(recipient) %>] diff --git a/app/views/discussions/_show.html.erb b/app/views/discussions/_show.html.erb new file mode 100644 index 0000000..309e439 --- /dev/null +++ b/app/views/discussions/_show.html.erb @@ -0,0 +1,8 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +
+Subject: <%= discussion.subject %> +
+ + diff --git a/app/views/discussions/add_recipient.js.erb b/app/views/discussions/add_recipient.js.erb new file mode 100644 index 0000000..5c013b7 --- /dev/null +++ b/app/views/discussions/add_recipient.js.erb @@ -0,0 +1,10 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<%= display_flash %> + +$("<%= "input[name='username'][type='hidden'][value='" + escape_javascript(params[:username]) + "']" %>").parent().html("<%= escape_javascript(label_tag 'Added') %>") + +$("#recipient_list").append("<%= ej( + render :partial => 'recipient', + :locals => {:recipient => @recipient}) %>"); diff --git a/app/views/discussions/leave.js.erb b/app/views/discussions/leave.js.erb new file mode 100644 index 0000000..859b2f9 --- /dev/null +++ b/app/views/discussions/leave.js.erb @@ -0,0 +1,10 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +$("#discussion_<%= @discussion.id %>").remove(); + +<% flash[:notice] = "You just left the discussion with subject '#{@discussion.subject}'" %> + +<%= display_flash %> + +show_none_row_if_needed("discussion_table"); diff --git a/app/views/discussions/show.html.erb b/app/views/discussions/show.html.erb new file mode 100644 index 0000000..5e06212 --- /dev/null +++ b/app/views/discussions/show.html.erb @@ -0,0 +1,40 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<%= pageHeading("Viewing Discussion") %> + + + + + + + +
To: + <% @discussion.recipients.each do |recipient| %> + <%= render :partial => 'recipient', :locals => {:recipient => recipient} %> + <% end %> + + <%= link_to "Add recipients ...", + discussion_new_recipient_path(@discussion), + :remote => true %> +
+ +<% if @discussion.comment_thread.comments.blank? %> +<%= render 'form' %> +<% else %> +<%= render :partial => 'show', :locals => {:discussion => @discussion} %> +<% end %> + +
+ +<% if !@discussion.comment_thread.comments.blank? %> +<%= render :partial => 'comments/index', :locals => {:commentable => @discussion, + :hide_header => true, + :hide_link => true, + :hide_votes => true, + :comment_name => 'Reply'} %> +<% end %> + +

+ +<%= link_to 'Back to Inbox', inbox_path %> From 32e14c8ded319592534e351d78df5eeb2bfde415 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Wed, 13 Jun 2012 00:43:41 -0400 Subject: [PATCH 06/19] run 1 of replacements --- ...comment_thread_subscriptions_controller.rb | 2 +- app/controllers/comments_controller.rb | 8 +++--- app/helpers/application_helper.rb | 4 +-- app/mailers/subscription_notifier.rb | 2 +- app/models/comment.rb | 6 ++-- app/models/comment_thread_subscription.rb | 12 ++++---- app/models/user.rb | 4 +-- .../_subscription_link.html.erb | 4 +-- .../destroy.js.erb | 2 +- app/views/comments/create.js.erb | 2 +- app/views/inbox/index.html.erb | 4 +-- config/routes.rb | 2 +- .../functional/discussions_controller_test.rb | 28 +++++++++---------- test/functional/help_controller_test.rb | 2 +- 14 files changed, 41 insertions(+), 41 deletions(-) diff --git a/app/controllers/comment_thread_subscriptions_controller.rb b/app/controllers/comment_thread_subscriptions_controller.rb index 1bd38b6..b6dc1c5 100644 --- a/app/controllers/comment_thread_subscriptions_controller.rb +++ b/app/controllers/comment_thread_subscriptions_controller.rb @@ -40,7 +40,7 @@ def destroy respond_to do |format| format.html do - if @comment_thread.commentable_type == 'Message' + if @comment_thread.commentable_type == 'Discussion' redirect_to inbox_path else redirect_to(polymorphic_path([@commentable, :comments])) diff --git a/app/controllers/comments_controller.rb b/app/controllers/comments_controller.rb index 3689bc3..b5e41e6 100644 --- a/app/controllers/comments_controller.rb +++ b/app/controllers/comments_controller.rb @@ -30,7 +30,7 @@ def new @comment = Comment.new @comment.comment_thread = @comment_thread @comment.creator = present_user - if @comment_thread.commentable_type == 'Message' + if @comment_thread.commentable_type == 'Discussion' @create_verb = 'Send' @comment_name = 'Reply' else @@ -55,7 +55,7 @@ def create @comment.comment_thread = @comment_thread @comment.creator = present_user - if @comment_thread.commentable_type == 'Message' + if @comment_thread.commentable_type == 'Discussion' @comment_notice = 'Reply sent.' @hide_votes = true else @@ -94,7 +94,7 @@ def show def edit raise SecurityTransgression unless present_user.can_update?(@comment) - if @comment_thread.commentable_type == 'Message' + if @comment_thread.commentable_type == 'Discussion' @comment_name = 'Reply' else @comment_name = 'Comment' @@ -110,7 +110,7 @@ def edit def update raise SecurityTransgression unless present_user.can_update?(@comment) - if @comment_thread.commentable_type == 'Message' + if @comment_thread.commentable_type == 'Discussion' @comment_notice = 'Reply updated.' else @comment_notice = 'Comment updated.' diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index fc1947e..b6808fe 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -143,8 +143,8 @@ def commentable_name(comment_thread) question_id_text(comment_thread.commentable.question) when 'Project' comment_thread.commentable.name - when 'Message' - "message: " + comment_thread.commentable.subject + when 'Discussion' + "discussion: " + comment_thread.commentable.subject end end diff --git a/app/mailers/subscription_notifier.rb b/app/mailers/subscription_notifier.rb index dd1072b..d14b9ea 100644 --- a/app/mailers/subscription_notifier.rb +++ b/app/mailers/subscription_notifier.rb @@ -23,7 +23,7 @@ def setup_variables(comment) @commentable = @comment_thread.commentable.becomes( Kernel.const_get(@comment_thread.commentable_type)) @active_subscribers = User.subscribers_for(@comment_thread).active_users - @is_message = @comment_thread.commentable_type == 'Message' + @is_message = @comment_thread.commentable_type == 'Discussion' end end diff --git a/app/models/comment.rb b/app/models/comment.rb index ecaf1c8..c5e2e16 100644 --- a/app/models/comment.rb +++ b/app/models/comment.rb @@ -29,16 +29,16 @@ def can_be_created_by?(user) end def can_be_updated_by?(user) - !user.is_anonymous? && user == creator && (comment_thread.commentable_type != 'Message' || comment_thread.comments.last == self) + !user.is_anonymous? && user == creator && (comment_thread.commentable_type != 'Discussion' || comment_thread.comments.last == self) end def can_be_destroyed_by?(user) !user.is_anonymous? && (user == creator || user.is_administrator?) && - (comment_thread.commentable_type != 'Message' || comment_thread.comments.last == self) + (comment_thread.commentable_type != 'Discussion' || comment_thread.comments.last == self) end def can_be_voted_on_by?(user) - can_be_read_by?(user) && user != creator && comment_thread.commentable_type != 'Message' + can_be_read_by?(user) && user != creator && comment_thread.commentable_type != 'Discussion' end end diff --git a/app/models/comment_thread_subscription.rb b/app/models/comment_thread_subscription.rb index 59ab102..5111bcf 100644 --- a/app/models/comment_thread_subscription.rb +++ b/app/models/comment_thread_subscription.rb @@ -10,7 +10,7 @@ class CommentThreadSubscription < ActiveRecord::Base validates_uniqueness_of :user_id, :scope => :comment_thread_id - scope :discussion_subscriptions, joins{comment_thread}.where{comment_thread.commentable_type == "Message"} + scope :discussion_subscriptions, joins{comment_thread}.where{comment_thread.commentable_type == "Discussion"} def self.discussion_subscriptions_for(user) where{user_id == user.id}.discussion_subscriptions @@ -18,24 +18,24 @@ def self.discussion_subscriptions_for(user) def mark_all_as_read! update_attribute(:unread_count, 0) - update_message_cache + update_discussion_cache end def mark_all_as_unread! update_attribute(:unread_count, comment_thread.comments.count) - update_message_cache + update_discussion_cache end def add_unread! update_attribute(:unread_count, unread_count + 1) - update_message_cache + update_discussion_cache end protected def update_discussion_cache - return unless comment_thread.commentable_type == 'Message' - user.update_attribute(:unread_message_count, + return unless comment_thread.commentable_type == 'Discussion' + user.update_attribute(:unread_discussion_count, Array.new(CommentThreadSubscription.discussion_subscriptions_for(user)).sum { |ms| ms.unread_count }) end diff --git a/app/models/user.rb b/app/models/user.rb index 9f93087..7968d8d 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -128,8 +128,8 @@ def can_join?(container_type, container_id) return Question.find(container_id).can_be_joined_by?(self) when 'project' return Project.find(container_id).can_be_joined_by?(self) - when 'message' - return Message.find(container_id).can_be_joined_by?(self) + when 'discussion' + return Discussion.find(container_id).can_be_joined_by?(self) end end diff --git a/app/views/comment_thread_subscriptions/_subscription_link.html.erb b/app/views/comment_thread_subscriptions/_subscription_link.html.erb index b47640f..dd8d2c7 100644 --- a/app/views/comment_thread_subscriptions/_subscription_link.html.erb +++ b/app/views/comment_thread_subscriptions/_subscription_link.html.erb @@ -7,10 +7,10 @@ subscription ||= false %> <% sub_string = subscription ? "Unsubscribe" : "Subscribe" %> -<% show_confirm = (subscription && commentable.comment_thread.commentable_type == 'Message') %> +<% show_confirm = (subscription && commentable.comment_thread.commentable_type == 'Discussion') %> <%= link_to sub_string, polymorphic_path([sub_string.downcase, commentable, :comments]), :confirm => (show_confirm ? "Are you sure?\n" + - "Once you unsubscribe from this message, " + + "Once you unsubscribe from this discussion, " + "you will not be able to see it anymore." : nil), :remote => true %> diff --git a/app/views/comment_thread_subscriptions/destroy.js.erb b/app/views/comment_thread_subscriptions/destroy.js.erb index 8795f71..edbf544 100644 --- a/app/views/comment_thread_subscriptions/destroy.js.erb +++ b/app/views/comment_thread_subscriptions/destroy.js.erb @@ -1,7 +1,7 @@ <%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public License version 3 or later. See the COPYRIGHT file for details. %> -<% if @comment_thread.commentable_type == 'Message' %> +<% if @comment_thread.commentable_type == 'Discussion' %> window.location.replace("<%= escape_javascript(inbox_path) %>") <% else %> <%= display_flash %> diff --git a/app/views/comments/create.js.erb b/app/views/comments/create.js.erb index 1950837..9117f3c 100644 --- a/app/views/comments/create.js.erb +++ b/app/views/comments/create.js.erb @@ -3,7 +3,7 @@ <%= display_flash(false) %> -<% if @comment_thread.commentable_type == 'Message' %> +<% if @comment_thread.commentable_type == 'Discussion' %> $(".edit_link").hide(); $(".delete_link").hide(); <% end %> diff --git a/app/views/inbox/index.html.erb b/app/views/inbox/index.html.erb index 82b7fa4..fe8ed13 100644 --- a/app/views/inbox/index.html.erb +++ b/app/views/inbox/index.html.erb @@ -45,10 +45,10 @@
- Discussions <%= link_to_help "messages" %> + Discussions <%= link_to_help "discussions" %>
- <%= render :partial => 'messages/message_list' %> + <%= render :partial => 'discussions/discussion_list' %>
diff --git a/config/routes.rb b/config/routes.rb index 5c6d253..f48957c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -94,7 +94,7 @@ def votable get 'help/images', :to => 'help#image_help', :as => 'images' get 'help/dialog', :to => 'help#dialog', :as => 'dialog' get 'help/comments', :to => 'help#comments', :as => 'comments' - get 'help/messages', :to => 'help#message_help', :as => "messages" + get 'help/discussions', :to => 'help#discussion_help', :as => "discussions" get 'help/roles', :to => 'help#roles_help', :as => 'roles' get 'help/topic/:topic_name', :to => 'help#topic', :as => 'topic_help' diff --git a/test/functional/discussions_controller_test.rb b/test/functional/discussions_controller_test.rb index bc9aff4..89b7da6 100644 --- a/test/functional/discussions_controller_test.rb +++ b/test/functional/discussions_controller_test.rb @@ -19,41 +19,41 @@ class DiscussionsControllerTest < ActionController::TestCase test "should get new" do user_login get :new - assert_redirected_to message_path(assigns[:message]) + assert_redirected_to discussion_path(assigns[:discussion]) end - test "should not show message not logged in" do - get :show, :id => @message.to_param + test "should not show discussion not logged in" do + get :show, :id => @discussion.to_param assert_redirected_to login_path end - test "should not show message not authorized" do + test "should not show discussion not authorized" do user_login - get :show, :id => @message.to_param + get :show, :id => @discussion.to_param assert_response(403) end - test "should show message" do + test "should show discussion" do sign_in @user - get :show, :id => @message.to_param + get :show, :id => @discussion.to_param assert_response :success end - test "should not update message not logged in" do - put :update, :id => @message.to_param, :message => @message.attributes + test "should not update discussion not logged in" do + put :update, :id => @discussion.to_param, :discussion => @discussion.attributes assert_redirected_to login_path end - test "should not update message not authorized" do + test "should not update discussion not authorized" do user_login - put :update, :id => @message.to_param, :message => @message.attributes + put :update, :id => @discussion.to_param, :discussion => @discussion.attributes assert_response(403) end - test "should update message" do + test "should update discussion" do sign_in @user - put :update, :id => @message.to_param, :message => @message.attributes - assert_redirected_to message_path(assigns(:message)) + put :update, :id => @discussion.to_param, :discussion => @discussion.attributes + assert_redirected_to discussion_path(assigns(:discussion)) end end diff --git a/test/functional/help_controller_test.rb b/test/functional/help_controller_test.rb index 55ef272..098e817 100644 --- a/test/functional/help_controller_test.rb +++ b/test/functional/help_controller_test.rb @@ -41,7 +41,7 @@ class HelpControllerTest < ActionController::TestCase end test "should get topic" do - get :topic, :topic_name => "messages" + get :topic, :topic_name => "discussions" assert_response :success end From 7b2b484adc032cf73f68411e608e0364ce515997 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Thu, 14 Jun 2012 11:53:48 -0400 Subject: [PATCH 07/19] more changes --- app/assets/images/discussion_settings.png | Bin 0 -> 24898 bytes app/views/help/discussion_help.html.erb | 17 +++++++++++++++++ .../20120613211916_create_discussions.rb | 8 ++++++++ test/factories/discussions.rb | 6 ++++++ 4 files changed, 31 insertions(+) create mode 100644 app/assets/images/discussion_settings.png create mode 100644 app/views/help/discussion_help.html.erb create mode 100644 db/migrate/20120613211916_create_discussions.rb create mode 100644 test/factories/discussions.rb diff --git a/app/assets/images/discussion_settings.png b/app/assets/images/discussion_settings.png new file mode 100644 index 0000000000000000000000000000000000000000..2d7a1df878dfba31de04c0a722f25a9fe0d0c43a GIT binary patch literal 24898 zcmcF~Q;=n0vt?D6ZM)01ZQHipUAAr8wr$(CyKHl+`@b`BC+1}yW*$z(J`ou!b7k)H zVP#gRoQx<8Bqk&P004}*n2-Vh0N~yC^CI|<@4pjQQT_k`XiDaSf^y=5g7|X3Y)#Cq zi~#^#02kFwl~Bg(E>kmE&!wl#<9|=Fo5qmIkFwW~@&f}Ck%5!_%pofYDZ!UWAc72Y zftQ!-<%5UFGvJex+sYaKeWiJ|>3ubQ)>!l>{q*!StrS+78NjZ>MN~Mj_Z}cXbU@)k z8itIf$_9A@xd#v$fDgE5tBYR#wW&#EWZs)hmlU93{$9*Ybje%qRn`cU_X}MY0ADkp zcbImF6}xvC&;q zAP5J5tFoDu86F@GUZ8m34fN+PF%bYg48nImLIAyA{54UwG0k`Y*oWZJN-i!3uw9XQ z^x59=NYAz_>+65;Qn$8zzjn5-{O*N7SsLSCKS9(WS z{eR>cSmS&Z6%&JDTnf-p3-F%e8NQ27oxt0Mxt;CJ>oQ^CuBhbk8IeO1;l_-0ZhV&e)ebM6FvpU zhpF%(pnGjk0tM{BG7lA9GvFh0@!zp45G9%;MeI%Jeu4f18$3|$<}29tP8I{~0=M1Z zHT=Yl^ow{AHKDr}yvA!|Wf+oKk8+~V>P`K^yn`E#>d;*qVIH9#wf>lep!QSYqs)hy zSu?|F;K<2QpUvRItPD^QJj-{SO%qG!paZN%81?mb*oej3!iLwyO)c0(4rsXSXrInj z*|`tre9r#!l?w=tt8T9Ok`D+_`x!dI0nkIoKoN?GjgBliE2>h}jXcQJrz#Sbhfhk| zJ^%hybbhYho%mt(Wl8I&hW8$h8rl)@I)(dtN0+Jk37{bme>~wvmnoJ7;20SIo#PTq zH1dlYuJd<4z|R~(6Ed(J5I;WXmnld-5VIfLdeBrpFm}LIJwU0v{3F-}e!wx141BO; z0HQtga)4$0)GYus{w6b^Z9UR-;6c4)=wOO^m=pfZdMF+s>F~h2_=p3*_Iw^ObVLy3 zd=@dVM$qc~k1>=7ARqz=a@YxwI6ja$h$TNbfEEQ+b77B3n1HzhviKQi5bq&gVe|Dg zQZSBuh4s|cV3vZZ^+jE1vB5?AN9|Cxz?1u#uZdewx**{C_ph1WQFR0XkzvA62BYId zN^_y*S;$zG0K&o~1P}Aaj-}h#L#V^i${PCVek7v3=rx4qBBmpOF^9gFu`VwehC{iP_NBX zQ?9^RLc#Kr?#1oP8elPatAVTiy~2zQJM0@jV7_lju z;R4bDu?2(YJ3WxROS|WOZTJlGPU4$|FExX|0{;#!9`LhIU4V2KP(Q0i+z3Amu`x7i z0Nwz!Hp3;5jn6~oT}n`pkS|}xP!vfjUPe)7Ug&qSNzf4%HDM)iCBX&m8rzz{8pj&X znrTC}I8hw9c=Ult7%@uRsd%#(tvHquNgecR#<}R0Y!y*+-0;ZN3AjU_!>a?X!>EI? z!}2liOyvyHvG6g>N$1J@G35#8arR6#JstfB;|g5>Bep@y2;D%lDUt07RET$nAH?^pH`1Ys%wC2VqmOr=wK*uY++nsx^WuH zAVr_W6y}h|z}f^y?`vjcuypohHg)s`sCDbEhielJnC54Y5cYGkhobQ0``EXIl1>Dv*!QD4ws;9o^P zB|SF2QobU-XnsQc%)J1;`FB9Lc$rsuwf0M zRAF`DY2hT{EFnB-grO&4!r_Y{+^EB0<)Oi0*~oZ_KEw&cenb?+xMF>A6mh+Aq{Mg< z`UMMxKMO1hvc%>k&LoE=S;eMDYR1$?jm8>AJCaf29OJ2zItkwtWz=b;E-N+?xbiy! zJ&HVv-$_9rKy(8o0*Awhgpme6!Y;z_5{VMu6J^M`l}!|yRCr1@s^0~Ll>^Iu2^)(m zi!DkvN<4&O)~8jj5j3`+qB{aTe4J{ZZZjz{88D|Y^O#9k23hDVXe}Tv-Y#>LGZ$0m zTvU3BxN8LG?HB&mFx5!bUDj+CaaNI)o0h%m*z)UY@e27Q{&)iY1*+ta>hCBB)9)GN zDMCi5nD3E~U?{S`IfODqD-A65LmE>`MLJPhQR;1i&LqiX&_s5^b;5J;n1Fm`{zrgqc5{Vnr2tCH=w?k4ZhF99DXKJgxd949^V9fcShIrSNd8htzA>tXo% znA4aCx%8Q~nG3oJx)|NDI|+8wu>|x#Z@l7!6m;eU>cnqbksZQpCA=xTEksTy zcs@K$=W>{`8$Lh$-s&Hxi_?pANAOJoOx_d8lhxy14t?%?r>L?j?kifY=Ffw$f59^U z8Reh!Uu-?z*x88X8tg!F<-Pm3y+Rp5NkFl}x#f1as(IhN?OzWB3?vk$5H60=ix$F8 zC0nBIlIxR;(_&Dy&|Y&(_{H>foNSmi95j|NRu+vEJ&co0(@bH@OW?3K5?UFS6Lurv zKQ=^hS=LeZ5bs4gEOV0CrZB0fE%))^aD7s2DmC4(6ta-8XkfW-xt-z2;r=IMt@ZUT z;}6u-S4ntDdY7K}u2ZLl=ZElRxG;>JpjQ7}A$PI}Eta-T_fOA5DMCv_ek8LnOO38m zN5{O?y4J6>wMNS2z-rY-y2gWMflBepa%+C;`HQLxI8G{#S59V5O`DO8lC!<5vU8IY znp1*DqX(-elBcQ%;fKl%=nnSft5sgd@x!J4b*E-gP%5xX*fi*^wtVm6r>e)zDuT$| zD0hpewIJmn%`3`n+ZV}~>Li53*d?$sxHZv5QBFJy?sJTJoc5QI=>_F}}HVocY_QX%@JFYK~kMO$W4O&Z`&~A$imDI~D`m|QwGdfP@ zKb%jGjuU5tj16tP!Hjd;o6cUlKJD8<9D|CTQ*e(9fmHd4?5=`4{&aHm(^_* zQ{Dw$8=nrxjKhE0XeD%Cm#vm{ykNfCTC=))YwdT_*P1!EGrMW6NUV07#=Jwmj^E8+ z?p~apADt3d7vGX;eFQAn@Bw^e9mSw`!vE{&T?lWMJ5qb8w_q0xQ?*%aD5*+f}e?PO+W zC8+XIbC)vCxU6dP`!d{p>q7h9<&u4G@oe+>_t;a7Zk;!uk9Lkpj2s>Nv*k$nOmEHW zbw7f9EUbLlY{snSLNdK)ZKM6_4Iso(Xq@;!!QsIhxpe8_TiqPuqiC@rV;tihT*m0> zl$T>nOnD+&qOK;LeTrI%GP2i!(v8??biTsy#`tY?bCRs;j1q;aYt{tkq87I!s5YVY znS;|;E7TvnCF=!68V%+G9gD8_TKW9al7|3T+pSGedLE?3vryKk%BgHdd}F|IZ2Yfp5>QpV?J`J~aDLzEFH3csGLb0Nz)BxwEG|Ms=WGEm~>XdmCy$FJ7LyCetb_@IHAXn?RbH5#9^|N%wF_`~U~? z>;0nms`Z2io?atvg{1Ly=AopJlOnA9U-sE=;sYoQ@FM{$Sw>^Ag_32w({@Sr5gDPv z5iAik3E#kEFlZ>8(P&|^kq&=;HRW{41=&@PB&C$Ogbav}>X*tgP}PO~GP%8k^bMPp z5FdL}ic=O`*jTJ&YG6KW0B%rsxaQb)+&-B+j>g(xJg09n(K1!ANwZAS!!_EqFgGbQ zp>7Kw1hu{!bXvO1^~@HG-!I*4m7$-)r8%k!v*Ef_dwLp?*}jlJOT9ulxj4>0kUZl& zTi(@0hKDaf8Gyehc@`0~FY!(hVbgxr64ErXNw91nVxSc{63h9M=M59Feivv;7qu@Z{ zWM-Dt_}c#RS0a)V%5EZva~&BDv{QUGQ!tcVlK8Hbu_%dku%J3+bu8!9h+* z#&Iml1LwXgN8Xm|B5&-EiswRyi@Uaup@*yU^i@qPUL>zoJQ#Ez;1!TLe!RV9OTJn; zEa?8FYjYQ*L*KUGC4pvx1-cJ4&2wxTkmg4H!hvmJSX+b$?MK@)f?O7KIA+6di*i= zbbLpW9wi>f5^CBlvcS#*@gs93+OyBc=?e$wgDHtCzwL2vtZv{CVM$I&Y>1eN!HVS+ zvI=oG|D+7XvUGQIf0&6VnDqE^t5>aFvVVf@|Ej+myPZaBz{TX^(qYrRFGN@FQ=+g_ zx=ayC-L((@)s9q!!jl-Q{3e@})uzPl@hTW;XFaz%dza^Ejz&Tw!D^(P*7kEdW&OTR z{ZOO#LA5f>8f-n=nPO|?D(zzSl=|vz?aHOxn9t$*T>B)~cXy^cKtx64Dni>+i+A?^ z{^%eaZ6|R8@(Qa)Q-<^T7iV+BZxTIa05(=IpLq;`^9{g~cwoL3 zMDcX|7g$Y1fT&Xd7P22R^+*5=oww63{6F%<67T?Ef5z^^yFkSfxSFvhKxYQD<&c{} zgDHm~13m}yjryWH-faRcXgLFgm z1pVL;BtooyX6Q1w)z{F2HT@im>yr!F zMZ~7%TQh7njyD@Z#;TT(_Tpy6rsq?^Irq_QK!)L!$4FP0SJmemkOdH!-;tkp07KAC zu%yt4kc4QcD3qMKAvpcEVe%e3QUy|doLjti5#|-8w0pWurv1K;f{JL=OK)q3KgfG< z74j*HG#XlR8}>Ypjn~iIUpvUl=D%RH-YzzZ+nydMVJMS%nX0ru>~Xfo7HQVa7Y^5u zHqf@Soj5)1wl|;M^`AOLAVt=PlZIci&plPRAC3y&9fr=II}QXc=la4<-oo)tc#A7K z*TJ8=t_e?G4I7dIFJ|U?==m+rU;nT;n z$r|#{i&KhgN*fU1{4^X*b?~9_#}&>V=QClOBI{WhDHvv&!k+RoF4bQ&%`_g@Pd3Tk z8QDqL&p4tuWZCDxyT8NTVa%OTAbGX~HUO3ma0z4yAQf5@k`2c}qfH`9ph}>Kt%_l% zUH|E<`dQf5h8SKK6jp7KtI_-lCaq5`dm)iY&aLCg>o3wTZD<((V_yGvL||EAv~twL zi#Dq@iM8s*ENn#-V*5jeR;Hm=m{xU5WQ+I4_-XD1#*Xs&=KkH5?94WC4w)U@v1o{b zncYh1b#Sa*fxftZH7xWbl z*zXM<7k8xkwPv{-d-X#tTit~3Hy7bJ$_cZ%c)ismb&J>8ZZe(gU%~!N=jlG00=?ox zj$(5ItcP3xpG*8VC85UR;vK9P_&5e)`whuiast1A! zJ;b%dO-JD*d?OlWm!U}JVMTh<%;Mjw_h3(u^AZL04K4%4Bs@d9@CT6ET&3mbRQ6q}Hg2sK{Ou zTAf{EWp5)qYg}jE(l(zC63t%L$AjZd1X$}a?M2Bw(w9UKkJX&5U3gJjZ?S}c4qYf1 zCdVu_oilqREuuAQ!*0p8j+sv_PgvH-@iZ%$X*{;J*C6koO=DQy$02o~a4T<+X;Lwi z(adC5xjU^GXbrdnLQ^{hqH)sssr%SIw>a>Nxy<#s4IS~N!?O9zti5+VasH!gx%JAV z`=HXWxfx9Gk_&gPec3Mip*khjJzopXe~5-#0~amB&MWTazOUXr{!USo_E`6}GcH3V zYc^#ub>6*_wfauPkl#_>OWZ(xhx+AWPGYz{;A!kil_x{f@k8u=<$-*M@#D`Ut@~1s z#-yr$b^X~JYYQt!*TrYk>&HydvB_7`@X}E9Ty`CAaMOp=IUZ6@$N@p@k6BFoli}p` z^=#pooIGG3yutPLbmsMSUW-^gpck+?w8uB^L0CrA(N)P-w0tiwS~(mC_-~mV z!cI*6Hvj+>(%%mtKw1Vm002IKxDdaR3*bd3oQvXc>M=Jw#yT)iPz=)ywTw@|0Vsct zy21}}5F@NK(pcNijRySY+|@CrlO=;Inu_;L6Wc+a-T1dcex~+BbF5l-gb%{B@D;gM zb1PdZ#0dphV(qsFQ8gMem{!=K*;?-U#-Q%2PEN5SI5(WkU%~zU z65|s@Am)f;0p%q{62c`>MAKq<6TxuP(E_WmJGG71QM0#On5f!QrR4pzwSCE}S$n?@ zxBa|?GLCrvh3^Edid+NXLM#@Juv3XsI`U{(6e;+`19qww-7h$ z0JHUc)xMe%?P0lN98a)HyZe0q*l~4f1~bOv%1eOb2yKXuBUX#6rS0}28~$yx}KWBiRvr_xuRw?nkNo)g~Zwy4@$ zSpH_?G|r0GKUR27!j8Lt%E^&`Cm=tZ&neT>ZMD%jtqwAc;t%ijy$LtLg{QrM!6vn) zg-TSuxxV$s)Md&{&t=ijX&_g-iL)r)^yE17)rMN9y(!pRqqnT5wDiZNm(yIQt>lA< zTLz>v(*ooxtIal=Ol>xjwx)%J^X0l?_b)AJLh39?ygieO3hQT2Q8&9dTM`pWc}B@XM4tg3_(T@b&p*gBGZ zh`%N0^95*M&5?xXXqWA{2?67VUkM$JmwJtCh}pXQ#c56AX67(Bf8x>u5zG-kdEu0{ zavMmQqBIu44ufxY0(5S3Awy{17jIkinAk{`K8U?9UH1!|ZIHMN?bdI4N0HbpApT|?4 zfNmqOu~^SDZ(@@X%x>h4lbP$Wz6A!7!JOPJ>v?$7W*Xu6fHy4lnL00$XUK$YDM{%c zHgp}}7j&^PdSX;|BG?i=p7Py#i31?o?o3^SAPWcI!Qe8h!nGD(NkT!O9;RTQIP|h#M8mAnD_ss(z5aq|}B6?oB ztq4Ydb3qU;6u=`b1#J$ITtyD^%f2jgGypW z#cGS^pV~&);k6f(u+;kQTX=#l|KYw~)<;BtkfVwzK~e+Xew#c`v(a-#JY0V{?`^By z-S{$1G`}@QG(Ch6A&62hsbSn{@dt-jPLs0|{7T zsy*qKg$+AW6p>TT6SaXY^2Qvzf;0+RkB$Wl*4#Q0JKb8ojv#zLDEjk=D@`hRQKPcQ_3Udv zLcplPTWGua?vj~a(fa$++PRwGTOHMV;G5Ym%}Vxqw%8HH2}Y1;L4tu2snmfgHXs#99F4`z7+Q z0T=t(u8=NC!dG>5A(*+_b;%7AT^S6xU#U)0;# zRaHxgeYvr0_jII^ME#cHj8|g7;OPnGl-8@1|2d@zH9w7VNYgvA0Cy!6iAA360#xzl z(6NXzrBwtOWVafLtrIVY`JGF7A)m_bdQ(FyD@i(2Zk|(Sh_})jR->#SnnepF*^HDX zbUi`Ey~EC`#Gr4RHJ>y@nWLj$GZOON8&?4A^4-~M11Pt{0c4OgcZ|9bwtvFuY+3JNA&LjG=@BZPFYzZiPuE;tb`*)ucP zUS2U0Yvypyu1HZ5QLH98Hi>%AEoT+xx2;k zy009V*zMOUFgjj6AYACUmhi#`CC7>8aUHV|vk$*alYSsxe~ei6Y8 z)P0v0ncP?4r+aK#lnKG#ojS(nr!T?MD$2MX$$xfnWXA8Ud+;2m0p@!tA+jR}rmNG1 zWTx`}8#kHBk5z51875p4kC*uNjK2-0@| z`J&ho)Mn3j=-j$ ze|bR?_{4Vpzjo(y?tL@(HP8re^dA~zzkWOio&9u%|I6_ET*3mV6^X&ZK=qy0?_~Y@ zjy!yW-wgL(cq`wG;jl1J{~eW(*}pjoU*a>t{Y^5R)wgAEBsA1N{$Uy4to}P@#Cg9+ z5Xd(o-w$CK07CazPVh;=e_K}ix1~N||KDeP-=C!4j7M++j{em(NcuZdHL?2tYRngl z)H9-U04s3!52c^PC)RUiq~pP<{JvHB!c>j&w+z9TO*;=bHq4akT8LaI!eB=Hn6D`W+M)TE7&W?d}B#iWC=uf7s z^n}x^wdUeNTIB}NJbg&uuyM=KtfI}xb!R+@f>$_ZX2(ELQ&WjR&ByaIXtY7ONJnPo z%QGdrcYJm8tUa&rC`ofi4r*Qowe)6_!;Vi-^KCYS0H^d|k!*zB>!-5$+h=>rbw`{`> zt$UpMzfd$$TsrrZ+{2hEA)4qUz?uq7OihGDfnHDzqo7CC#WFFU%p>L1zlh}RGt#CP zbn^dEK7o#PqU7sx6QhL)9tNhiD{0t?V?uS!^+C!oz+1{8??NSazhE@i7y;s*i8L&&<*xx_7W4@jp2i#)rrCX?5ld#sS80s5yYy7(#@~z%BIWDmMMzr_ z#0*)pPEIFz%tJsn{#$#dXpE14?=SUPM)iwk z4IG=Wj6Sm#jwGV(Y<>%4We3CSnW&vAP&RdJ*fYKkEK$OA*&37@Vx5p5{I<5ixmZta z71;2z7@K~v_R))aHEsbIfDVY}sttXJ@H4j7bD}+Qp9t+`_{t$ET@! z9>SFF(%A!+Z_|oORF(vNU9-^4Y?W{87^b(Jg86qK5c0bxZCF;*_D`_)<0o0-d##+; zT$hoGvNqZur%T?5xo2cUdrk61`T!Wi_a$3_$bj@ce9KVUQdP=}H@AP> znL4dX7AJC01mFZlCCG^4xaBoA{b93;QN&yow058|S8crtaa+|EKS~+{JA=@`x@fVl zo{1&+*+U^QW!{#&oseoR6P!5t6-k4Bp@pSX%&2j$l7c5dmK0Q#>(Wr<%!(#@d?={7S3KWVh7p9ma@7V+BL{J{(*b9wr#MI+Z=>+G)H6T@ zjMbBB;RQ#IGzG!dL>`s~g@%+`BxII0$U2BP^RlsKN1#C@eRGJ$oudh|Kt+X`ch4wt zKHb_0iqmi16tl5Dl$ss_Rp1SS)t?qKcSs<=f-+y2FmklzppbBy`vnGJV0kA}ZW)7rbz&}Nn802zyUs5xm~ioRqjct| z$fcUvrq3WvptjS_Spvcz9dRw2j-5(5;j;2a99ObX?x(gRK4Um`>*!DAF|Xll%zAi~ zIsh!*qyU;VX-r!6%-n!*ix=ioJYXCZz(>we$@auW z2O_y4&OrJS|x#9;9EB)7f#2nlryl*fF&Q^p=TvPx1E<&}_tL(dc zX8JgPR5L=u62Do8fZECz<1TMMC9{uwcBq7Bn}CxxStWQ4)$R_%$27aTmd~T6=sy~6 z7Z_g0oFRp>kukA2a=epeQ>?E87pq-aq2XoAh~sIXJ%OX)MVeU(acWVFMoj7m(~Nxy zDcGS`Zznk*dtv7Z$?Q*_B*oJ|GDOjCOyH&&WTwJRYdK|A+t8~eZW)eRB3kuby}m(C zxMVwm;#tw8fc6!s?Wm@CT!CP|4bwRbYwNzmXzj|ADv0cAwUq?`2M%dF%`??0qht=| z<#L5Y)_VNv8+J&`v@#9xe3VW*t;ul@hJqf(OQZc@il_#DSvo=1B&=!AT$Giei+c{U zBTiYblw?H1%f1!UxeqmL(j|G6H|RUW%=$Zc zQu{T%V9Xs2o)ZoM4?JS1?Uwc{^F>z4z0(n4aE?!fA+JbZ9XBu{TA2jML z@l$^qLs{i+ceHuGC82HK;BM~PfZP_&q?q4b0?>OZhfe90={z)kU(GTkr1OLb;-$Pp zVywZU1B<(AlhLV;R_ebmXI-p^HR)#Q$rC*LY@le%ZzhU7F=aN|;Mt}$KDk136H2nf zu;7BPAlO=m{vuGTAVmj7LQm;4UT10FB6(b#0vj1|Zc&gUFbRz*%Q?5xspf$yXGoRj zM;vSO+)G~b#Wp5vJfH&RR}F-~CR))rHUj4ji_(4>tJ1GX#Ui9%Z)jtRwx6dUg>}TX zT_q`BC*`~zsBPmqk6ln5Y&=|G zr#19LhqD(4qCX4ZxodNjDmCuLmF@TsuRe0}Fh0 zp3cWP({$gIKgO>bn$OKZkRoNL{doG^9_pWDESXcXW_a&sqMxc3V}zE^vHhq$H_?0)pJ)d!laAzFcmEM@hsV8b1k%xfsh;1R4BqrfCy1G_{X z;vC0(_vd+FyC`~rcho&Qj}IM!_4K?wI9%_nlXB~GZ%xTWj9&4z)991=9`*4+4i%Eg zqFPq3L=AuBAds7zp%T|pi;MkT((RQd7o#K25=@UUER60HfJ%z`#EXRX?tbq?XoD?AiK#< zIJ>zj;h;$5X~k!Q)XeL3t}ReBPYEeI8clHj=Q_9hzRMGxrbV|^5IogbS%aG(H_Cgv z!@s5LYsQhD;U%NleqSZi`fM(2X7__9k8wlhCn=!zLH;c}oEnwvG!jHjnqROce#r*E zKV-otp}S_N{S6FeV;zEVCQ{T@p#8(Zt(3FA;CRh5Xc5z!yh@{%sD^ByJ1qODM(F0v zCPt{?t>3|BGZ$T@u7a}t-i)T+3bmhp=f!%!<;t0-KZIDwEhOTwS9|zzmPTf0n%UUc z7!$~8Y`L;!mk0=&ZwLg?bCu@K7_sCP-qv)RZ_MhtJ-i9j_#b8LH62Fl%gt!p6)f89 zyUOAd>y%x}W`X#zqvc1pO_liF^D1jBTwUh!f+ot`IQEb;Nu|=UG>mZs#Yc@M^V6xZ zCiPh;qGETW&Wa(%+4a`&m_sNsSrWq*LzUDC7lQ2;7nTc%P(3u@4`#`-65`UW{`Q<^ zs=a!mwElV1*$)?>)>yhOSmv7>;ROyKh8X0F^;go%u?DiEz_XN-s#*ina z(W8w}l*}g%Glnelld@IPRD%O6x55cD{>K+x8CcN#JoTL@7Ww61cFR}A<-{7hkF1$S z%@hk|KI;|@kgUr!&EkO-7h$P#vB}jreS_>VM$wIOGHy+`{m_ih4CU+ZpUKrjV(Fty zMyjBz7D0U$5y^Ak^KwNySyPrd%KXMrMjSGcrlj{yvOD-y62e-j_0+#vlYRS9+aFR% z)%Nadf40?>t2l+cL*MB{C!LKd#lJ+gOJ9da*4wxpLWO#Sf}(=PcTUz2kX=IDabB{1NfN|wPQmTE5toHcV)t3D7L{^H z?m-CCzMoLr73FbTy|7fj^^z4+W^{aoYb)7wY@k`iCROVe$9KXX)StN^?pJv|oh7rz z1d(ubDRBTqn6`F!a0&1yJwry!qR3$thv9@iVyu+vjT`Lk(W$aMlWLm=9~4gu@gXy{ zt#$C=Sq0UP6&@>SsK5@A9#aGF#7 zdPQM09}l=tZ{kf2ZGwGFfpi91K?)Jd)sgVI+8CqN(*k1TJor5?9VInwvSiBRQNvCU zX=#P;OSaAySyw0`H_h5b$U>KfzR|TMH)CnIqgRffAL>c^LFY5@T}Q9a4cw8EMCDQ0 zxlR~xjfBeS$rTFQg12YJ8X+i7;)Newo|S=qv0~N9ybFDgEYCqTz58&lTr6ejX69aT zprVJFo?XU5*2jUQL}aFzeo*uAW9RLuMTHmk#7>en{Kc3YG(lIGxm=FU!DU}%#nm%BPdhUgPVls_}5Pm+2 zi_5X<5KB4N9tZ~9>3}7i^(7QMdR;h`5sxOtf{zhzE5|K-;w^0sjM`5h$9OPtFv3x_yQR{su!DdC`d{UfeJtzvsf`E<8St*gHpB80L5ki5%A3HoYbCf8*vsaG}9$MH4$@G~T6XGFA z;AY}<03XwscaSirniZM6MvDt`veZx5>2+B320mqpl9duSjx1W_=iauEj}<;V_~V#C zoA3q5kt|g@y_C(WpWXM3i5M>e4%lDai9!3F zXetYO498KNOpM@;Qm09cX#om1*`4C8d=J6y^5P;=$T*OOA5OVyPHNDt)I}%RaQbd0 zkZtYI?XWrKgzX|Q^%GiK=DeyR|G<%b&HWeSBGvATh0<>clpSXEc}V&4<3It(qZOxC zS>E)^;yK7g*ce*8TjuullQPk`Ah^e!jIGp*JqjG=YQoy?6XrgJKi6?wb#T?^i!mm# z+G?Tgm=D^e9LI{$M;pTs)k?<6vbG(YhYj^_1g}E-e}3LLLO-%1Wrsha{w5T4e!8m@ zhHoFnx^AYVEl2IivVK04DT5?Srg_UdI^&~L`ydISMUF{fqHB_ z@J8oS3zh%E+5}!2|AKU0Xf|(P(Q|O_HtUJkE}X~YW^XqRWFv-ryKvM0T@LRWI>E+< zx&(Fu^;gjH0j8n!75W(~6&DuP@yC+GFZMry>zD-pGZx0a_4o@a=;Tgn z=P2D)r_N~fPbxqY4nzdZkJS;_3)h2K(IJuY8kA&_zw&0X3cTdE;3lU8eEdb@1Mwdx zLx_LdpQGt3sDEJrh<##l-T?opfE9m5$|bI_3;w^Nou1J!&p)jY-SV#<${cOr{!gI$ z?xVu}i}ru-qXLLHodf+->1sv3)jhR4vL>*94!`05X?c48ckp#zgJ@q!s^{?ku;}>! zwo92nGeV^QNs}YsI~EbpU|Ik15Ac^rPv{EpUm`vc-w|NIa{Y@v0`Ob39QHw~h4_mC zi1BU6fbH`A?=aswD9~RvfTRXU|JX2m8yd4+1OE+`4)j~<#RHNVAo+)H^ldn9xAU)? zs0R)Iotys_hn`XLZV%F5$35uy--;zP8$$ZOY{h&hk*435^nZp=_=axxlLhcEK0cvO ztacEP>_5kbKHvH%{f>~;kH5L+`_5VW|4(9O2iAYv+-GlUajFUocaqK%+1lizn5(-l zPnuic9_BBdzex|3xEUG=si-xSQQ5E8vTe28zPHM8qpT9wIFiNf&Zp+LX%(uE$9~o> zW&v=-MnWsM-NE|DYHbacz+n&4|1}FxtL8k97d5Hb=r(oO$L8V~`1Pu8N4e1^85{A? z(DCx=w@7KCRRrr!&Z4!+Q2JT5&HCh7=yrH$Ri_b+!yhbu@7Q%)_H+)A+G#d;TKIe6 z{rBVf>Snt$n163L8tst}Hm{e5vhw0uqh+ydcGlheOtHCo*jfXmu!D)S7KzgdX|2CX z$&M%(VRF?TWWt073TKNC{2BP9B&aoL=OPY(WPRGae0x;wBIhd&j9=XvrH`Px@zQ5W z9UlwpX(PX4<;CEkagFR=R7GR{E7@rvV4*eM9C3bI?63W5q4-6&b7JQdvGz<+1zfpC zl12E}y>MC@djn5dvvyZm~a z^4BkCKP-;EX>nbz*Oaf7ZK^g8RzO0g5R_?+!c+jX;W-FGB~0tpLmNmP0BZHgf{ui| zhoUDQ*L`9EIVDa3MJU>=#%_ZV0pb}I24jPl7(Z2YzP+e&tvi(RDkDgOdC97jR|BPq zG>=ryWQpj`1=#tgJbR#7b^p=(S%+_F^4@yBI}cevv2rs!_a0!js%L7 z;gO&?$>O|%ruKS^sk0|DdP|MTcve*v(8JU23hoQi#nsd0B#rIT#O%kmdib9uL zp<9}TWm5yTg+Us>=0~p7xZ-Y9kVft<7JH16Y`>ufD?z2>+AFs<#v~r|e;+9L1Fz;7 zc8naMq#_BUQsb+j)Y#fy8jF~xW#Qy}Z=7P%orp|Q@c2hh!RklJ+4VVmsN+3Um5SL~ z&Ju%RS?|i}+66Ur``MZEqn)&bCjbRbha-kF5$J9_;B0q$S5Z?g`TUB~_~Y8?EBB0U z!gCBTfUf#_0!HWNTa%rB-0_-%V*Bsytk=YS3rtRiv0cs%q_%gNtoiQZuA-u>2XC_< z3C4!}wLcvL^#sR<(oWN;-+GQbVD)x~)~MgooR;aXRBf#$&?S*Ge~?hPs|0qeH2e_F z+Y_U0pkiNdvut09shT)eSxA+o!h>by=^hTlF@bl3TvM2Z^Bj1-&#ym0j4&DX)b*|2 z=L!f*Spk%qCn)MC!ZvXBk|2q%5d!*wPeQBOlj>oD=XeY;yGs1zB;O2D7lKvAbD~4p z-blBe0bA~S%F=dBA-ymzw61ki=7@4HFDsGAIMBZIW5ZkkgZN6+Gj&axC3q5=8Bs>6 z*8FrS%%cJptX~wRHWBQQhtBAX;WDJ;Ce}yHZDMBgL5Bx@Pv=zW_uWp9b!ygr{Yl7@ zNIL>8xN#!~lxEJj5`y!bjO|I_ofwv8$$aDN539xToiIwypQ;3cm3Mw{{>)Drt6DUiXG0t&xnYVz&w&wVQu)WtBThB3C5U*Ca5 zckJ}c#N4f#`i8fNFK%aPnlj>8gNe*4Vi^#k=GC z8li$jk0m;{T(yMRzK1x#1&<>d>I+v`PGjY;v^|`k_brsgB9-EIKUr2fmDo;-^F?e; zKV{r|6f!em7_(!|G93UjNYKD*r>Hdwu~$tfVUD=9fPB5@?dP308{KYTLm-u;(DD zr`jHevm z#}@gd4-uP%q)lNP`1g%o)UxA{WM}2E*r30i7kXv~iLM&SBm2a3TCX=Dk;?R>K@T{G z>>K#acXjbRLjcnd)KS{3Sg2OH?+gK|+2XdiZyi)}ZWMgz;i=n~{Q;u8`9BoeF~;GX zFW!cf>MoVf9xT=(rmN3#QF)gap^>7}U!(pc3e7LZS4Ajr*c*))Oz(^Db&A!Lsy96o z5;~APixVxu<~m(gxQPoB8ijB=&D>P-xuoOZTV5q5hZP#- zQ-~9sBG09yoF~I7EqIJbgRwef-aaaGb@l;#Ekn%gRq8yow8V+Z7*XNI>*YpJhk!znN}s0)95Th^B#WTe9ekJ?DVoSbXhK4Yt5(7JZ+n zjum@^r$9Z%H{p6q=l!rd><7~gqOn+_E@3;Aw{Lq@aQ-KDzsMp@evS#!jk3E?aXmzK z4(QPjXF1|>+;ox$Zwjq<7(HSHO9;<2{z7R}rS^T`HF(#j7G;(W6|9JFa^DoByUR20 z^*?JgTIORYWFh?jmN?n7_=R@g`iCNs>hvRWK>(FU?N!5n=#zt@8dY^Z zYS7nT0~Io_iaadJQ*(2f_VP!ROt#xu#rYp z*(>r_=xX%pz0vUJl--|CYdhzsm2-VI92%23A_qxx)YMvlB-V5t_s+(`#T@VV^hLMr zt>w?_vS739w%TUfc_so~Xj+xtVc)j^u zQd)~kyJ}6hDzIp&mg8Zv3`5rj8>9?O9baA{mv;}t`cQyLex^2D&vuifFMsrJ;}*sz zfc>erN>oVw>Hj~PIm@W1zPR5j3L?@i2uP=Zgp_nBF?31H2m+FdbPp(vN`o{=3>`Cc zw}iBGcXx~f!^|`A|KDdl&${=%xOd$b_q;x9?=$Ip#p+J3jW&LdHtu4{W2Bmo7Uojo z%BO1&p2OQdFp-y^Or#Z&gkxl@x8S{`-9tBeiKK0BX5T(vJ&Wo$T;L$94#E4vra6`!+vF8_xJ=$MFx& zMoCeknrLHsk)&p;d>X4_Kb4lcgHN@tE>hC)>NOgu-@VkW{UQB!1)~yoPLA>FI`mNZ zf^fqJV|O_0Du(anT=v@fp_cR9$0z%s#<&aA(ekzCA(=w<3c2M_;deXiBAg-Zi%cOY ze4_>5zw=Y()#}7otq)>iRWl>{z>xduUw=@7Si*O>?EAYGAhQzV~w7EnS(nnKGfff@b5n1v+)XMW0!|qFAkqsDm zV0vAdla(t|wblM$9VK1_3+X#qk8}k&W zzy22S-cCr*{js6dx$o(caS0Qv@YweLC9-OOvi9KwdQHZIn9$W7otZ0vKY!i;mwL3T zO2kvD=^Spp$zx%{{pLpsWTVYQ?EI8K)i$~Q(o6i}&s@{vbT&UnS;YYH2LZ7<#(v-) zh)8~Q;Lz#M^~3?kw#O`OFF5TJ+O_dPegT?<4=2o)$OYb2Q1d{Ev`x<0{XX^hK^>yHs(DQL zlw9?b*|CmRuw9;noY2Svd>0=PiWd=kUdsU)`I9U!?zpu*v*&m-1JmznB2xXmD%>Xw zxpvuA_9*kji&2Y7>tl@E9(qprPZqQ3ydR`v<~f&zxP}(@(4n{m9L>*NJry7L;8N zU&DJN-}%7f?IB%^7_rWg07H+s*JfMn!hmnt3OPUHA}p#v4LB+wW*i@#{}U1g^?7d$ zA)__7@4wGvIlI@0@r0Uss?ihHzm7SoMm!<$ zDVZNufQA%;rDjcYb5-W)>UMiG*|j7jo0W_mBrSiDxLRNc=Ah)`%y^LvLz!#f#R`&%lMJs$1PSl(FG`cwLH|>nnA21%|aEkIV>FQ4P4Q*&PkUlgs?P#mFdm2B4D8;X-J)Y-_fp0mz& z-)NRPv%E^ia{A&YnNIjU0kNlcsO`+NV0ujio+sh&fygIfSm=hVY?cu|k7Yhx3MT0XFP@67_d=*(% zWY+LUkl#KP?Td`6O1kT1y+Yl#@BMLI=3^h7c(oFh;Zp|A>szvpA?K7Htt6CYPNMD1 zf`ab{Q^j3(96Q9fINz!y>CmP#1r#Y}njd>b?sq2FyVf}5>d_RZXMjq|3CFuM=zuk5 zf+I=3d0Gq;Sz<>>Y(`k{+yo@^`8r9h)7ev7jg%K9(3lT)o9xY5$r;iXgoD!|3V~P| zVgb5LBpPh}+)7Z}izE>&0vRlWXbgTT!lf;`^~+5tusV$6Te#TFSZ{$D3qKQvi@gdY zdc=IgCBvg`tUnjL=(x^utahyP#iB+a~y0+mYV}LBD*f)2@3D-*J88N+grl&__X{#cokr=Bz^q%LZfWf z4xMizj_jNLb!)J!_!c*L?e!=Xj9fP^fSPeCe-fw4cs8PFlY9o*&%wTpV{62`@3z6! z{t7m+_Pq%6A-@MKfl;f?8P}H@VARr_H)QaE+-78m)B&OI6I@?pnfJxwc|3(`i_x{( z^&xLt_nhlRuSna~SaF+&0DTa7WH8b#yV|t~wSK?|M0R_RMrFh{BhQ|rD_Y*TAUj{cXuVg%B;cD$$BCf1f2^8Dlsfb<6 z8U;D_q@YvznRFJb&XO=J10J`J!^Lt56#DQ~oV(Fy$2z%rySD~_?z5z6;Sx5#U?uez zNu&2U{GEuJO_XB*dvPVaqyVIU^>q@zP(C`VOZ01gx1@7YQr{x&welpCpyu;jk9xmG zhCqp$j{e<(V)Je!R^TgzMtr77Emd76Yt!>a1g3;9=bHDwifd3WXP zuu`GWYECkX2Dn2(=_0d>T702%8tWm>9To%sm2ZAq%-s+M%R`58p1MQsDEHJzkZ8NE z+I`Zn&Vsv6Y!|(yiGCNSRA8s6D>pFGoW<`LeSiS`wYS*59$yF5Zm+T5?+kXR@=4D? zuQcb+$}OgB=Y7oBtAaL2zy`Lu*|o5+llB56c?vB8UaFd za4iC>NLva4?s(x>O>VXRC=Kd(xUHDr3 z;F?QV!>ymscH;3fH*W4+cTI;mdk;iK|0?u(7tVX3$4<$f`(ED8{MmJ710V9ND{+dl zpYh0q=1`1aB80`1_*Pp^_Wp?pR@Q4%Pl!a@@I0`KXZJ0dnRrn^t>|)Sd+i^;=@Lor zUY0Euqcm*F%(#eq+$6=&tIo^q08&a6lgfw2j&7iIe^X|tYMOuk+>RrEqQ8o-gy~zZ z*7DTuLW;0cc(iQ^Av<`Sx9qb-SHiZbl!s^aM0b6%(>UHB-kGv@;^#YXD{T+iPvVaQ z6MN(j;lMt;W_u8Ac zsn3OJJxdSUvpwkN3UuQ-&o7Sz))8E|@ooo|zn<#P)N?E#S?Z%}PZ?%*o6yQUr8K8@ zA*!{G_@>8A`gSbg_v^57xc*q8rgJPbn(hT}r5kRYt(S*iIt)55qbOrBt;#r3!I@GJ zD!tnFUj2^T1?XknW<%*J?ffC1Z@bGX*w}4RXNb3;H0X=#5c*2VJ#u7R5?+wVhv7d5 zNp}BR{ap0Lb}p+K-6`(TmpF30nUxLRdn82Bj-^dn11QC;k~PO{!9PDmG>VD(@q(WoH&#wyFbt^ zDdQS>tTtZMTs^VeJt4uw8Gs11 zJGf$~YT4c1k($F#s#$PdOqFO(ZS?rG#6(ehUt7ftQ1fXwkG%_?T!va{*Bip{nAy&E zC)0w_kxLZOfpNRV`t$x5^$PH1{h!`U4MlkY!wP?QDNh5174Y4Y#TLtVsvS`B2G>0Q zLYXL7F*aT<%QIS&QyGCS%XKr{Ze~E(!Th@OWLrR+wGrakWS?i`q^u(^PgruD$3tZo z*U{jJ%%}ELdCGC(WuYHLmDuVZR51=&VKg@ffy%dus|Ma_#=C9~MPF2Pj4=eTH66l8 zZq<3xB6g7#QB==YB#;*x1R^~(77{J>K@1n@3tWfUJ0xXe;rEA^XJ{ubZ?@*j?PYpU~-=c|ecN1mf*N z*6i^qRbWVxck&Lc_r^f|al4b`^paRYzNuP2i<^F8S(zgpu$03@mL=L{IU5YX7)T*4 zk~?fO8xJ-GAL*(nmoRe)kPZlZ>Qz1(-Yx(0hf=Kmv%0yq1YE_B_QGr$YvxGgbHNPu zS96vpSag$Z9kliw8ocZG+=!cEe*~Mjyqd_TF35Dlr9Ig_SeP6hK40$!3`y2)i%qS2 zZ(KH{J&=x4aB~f6)I-o%ihUucTGyRpN2zm>R|JY!vgW+%INvUw_JW>&ThQJ2*{S*? z@v)lBiA+Z{$86LVQDGkan2K_@_q)jFuo-N7@}R|2%fifD71h71lGh(S=PWL1@?L9c z1VLexBYs`piBK6f=+M8MLx)$N%#WNlAZd&ZDB`(N*-OSA_cg^6eGR#{;Q6T8XAA(7 z0^~|7=c)=Hx72>uC=7XDI|_U5L;(9>icg!*prl1Q2!jFOt_MX0Mle^q zNG17=c>@Bh-Cdf7%S*yNp)z+eOk_=wt6h8E()l2S)ec^&Z$9;V67Z)mDuGKuiHlE? zH|fs%|A~B<;jzU(IiYU19~ZFx%iAINZT`BV`MYGW-cWm?WYYt_o6sBiP3Vo@{FO1u zJc}@M{GY;^%s+R^#XOsxe{JXy0Mf22Q0c4l#N(BqRHk^k1UVa7zn2!ra&wSS#pCbf zMnXIp0%fxN^XHv{-_j)K0kf04HL_E=1|@R%{WfJr(R>S4q=my1`+M7mhjThDw%jFH z+8Fd<2wxa3&xVyfC|tNRA2~2He#Rkznf-Ct9+oW2r;XMKOF-Y1E67bcbQyiwrEOw})QwwC-fthIzJ}4z zEdl@#UpL9rVI{>Twu-w){B@pCl&wNA|?Fs zo{)T9?fv4PSJukPeZOMHm@>AoDNMvpw9Bwlf~4!2j3fh%w)~M{F{&Un-$@Hh-W~Qv&(uDIWx2u7Q++p?$CY_;gf) zW-;p%yWk%_505Fqpxj_Tu{&ti~O$RS(Qr0X{e90%TKMCT$&x z(LGDLi4j7jTQ#~a--klauC~`pGLy8e+miV=L)NDPb#NlN^A;_ z94S=#+mDC49yw-^CZu|G>gbvL4D^WF+VwcsU?}@5&eM|{sx(&NyB-75e-(+6F|6Wf z<=2XL%+$XBG|;>^JW0^oeR8gvcjMc^I??0K%MQmx(Gn-64~v>3*;_m|BAVnq!lXkH zF|Az@R2Xgm^@bljqUxl3os@<7!^fn-ZU3iYM0X^Em#?Cc)8A-QBbvzQR%>SB-6<(g z<+Q;)Wa5l>d&xI=>0%+Qy2{?@)B4QFv|-7-%uKd-;z}|+KKrGuu)JeP2+h^yrPTG= zSgMkV^MLUGiV}>d{WnT5z;7ri-4bI)SICj1?rzOaSeKRNtD2r)^Bgs!4mEthEO{V*E;( z(&Sh%UF|TtGhUR)2LjqxXGz|Y5_9ILG%R@wzQJ|0djEvhLFt9sI`5$`Y`0&0(G#%TXC+7qj z1U@*7c!;PtnwCaS{yKhHfc$E)7?udcdvef^UXO9+&GIz7wV#f}Son1r{$2Q=Nh(z-!V5e(YlK^y2^#L>Xx2bYjk! zji7PU^U6DgFHm{=8jeq_-G>)U%dm&sEYDmu+ciMj0MKP%ue*cyq;1CBc#%V!>~xFH zN3@is?~xto%DoKwJSt+fe}_!@esD4jmUQ9~lO`ws>}-vOK&@AKsVS*tuIRcK)UkZU z=Mi)4zTk)7e)+QyJS%ubiPC%-Ut)NAYPpbIpIx?C8ye*c{@OVfn^2NNG2~%=&>|^V zaCYr(V+i&+9?6aX*IuqPqt8*F)`NUF0{)fpf?1xXz~spXpS3#ij{g1ax6%R|(|E|~ zd5KPG$O+HUPlyF|YGg#Z)A=WPY>&|vRXX?XFCvyQK&sDskCS1)Q1D0%^i_%)BFRF) z^rUO{tvEx5>lIa{UhV+KR0*tC$FO4;ii`so>0eA1`Ucx|Fk)V|hPGvI z&4RL@!K0tO&MsPt*>%CcJe$7~I(u-%(G&ANvUf;hi7l_kB0F_CkvzPo(e?i2i^Cc| z5VB*@9Ub#E#Bs=v)xzIY(2&kzx{)EN5BEu8oZq(5vYgzx`7I878n8@4Z7ZDTLYnrH z0Wlx;yWVdv&x(*uGZE7U24?Y|za~E!u zqx9RnfKWmpd@cKEtZFN?mHs}d6rKIk63=@KtSS(7(nmnGRE<2L+}OU( zC!&APke&iIqr&Csrz41C$JRLiHHdL8e}zy-eU&pg+WdO)dIaL?m~Un;fTUaC9LJc)#kU zs^Gd&wURvezVa}q%4hrrqNv0;+qQR@Wd`%%aQOT4K&hT)kR-WWnWB#wsDzRQ4|gCav;kG=?uY&8{-BsUAl!)j4l+adW@Q!TN_NOEKJsMqgtT zR@5p38uxA`E-j({^?`ef_fo)v@ZlFix6?z@{ytP9|ERjLy1F_qFAs%6nZrn}c8Mnr zo8UknV_-!c&W);?iTlt3gP>_b{=v*qt*pd7rQIfSW<0mT=l?52&3sd@6#ka;->iF> zJ~6>`IY{R1iW@+3W6m=97*gMsxxkwen58q!ax-SFp*N+IM2hF@?fA)Iie>w ALI3~& literal 0 HcmV?d00001 diff --git a/app/views/help/discussion_help.html.erb b/app/views/help/discussion_help.html.erb new file mode 100644 index 0000000..d87a522 --- /dev/null +++ b/app/views/help/discussion_help.html.erb @@ -0,0 +1,17 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +<%=pageHeading("Discussions")%> +
Discussions
+
+
+

Discussions in Quadbase are different than what one would think, you can't specifically send a discussion to someone as you would in an email. Instead discussions are automatically generated when question attributes are altered from the default settings.

+

The alterable attributes include toggling role requests and adding a collaborator to a workspace. Settings regarding when discussions are sent to a user are personable, and can be edited under the account tab on the upper-right hand corner of every Quadbase page. Click on this tab, and you will see discussion settings towards the bottom.

+
+ <%=image_tag("account_tab.png", {:border => 1})%> +
+

These discussion settings are in the form of check boxes. Click on the boxes next to the setting you want to alter, and then click the update button near the bottom left of the screen. Here is an example configuration for discussion settings.

+
+ <%=image_tag("discussion_settings.png", {:border => 1})%> +
+

Play around with the discussion settings to see when you would prefer to be notified of new entries in a discussion

diff --git a/db/migrate/20120613211916_create_discussions.rb b/db/migrate/20120613211916_create_discussions.rb new file mode 100644 index 0000000..dfe3f0c --- /dev/null +++ b/db/migrate/20120613211916_create_discussions.rb @@ -0,0 +1,8 @@ +class CreateDiscussions < ActiveRecord::Migration + def change + create_table :discussions do |t| + + t.timestamps + end + end +end diff --git a/test/factories/discussions.rb b/test/factories/discussions.rb new file mode 100644 index 0000000..0d1f85f --- /dev/null +++ b/test/factories/discussions.rb @@ -0,0 +1,6 @@ +# Read about factories at https://github.com/thoughtbot/factory_girl + +FactoryGirl.define do + factory :discussion do + end +end From c18143b4fd77f685f17a76451371011b072c0bfc Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Thu, 14 Jun 2012 15:58:41 -0400 Subject: [PATCH 08/19] ugh --- test/factories/discussions.rb | 6 ------ 1 file changed, 6 deletions(-) delete mode 100644 test/factories/discussions.rb diff --git a/test/factories/discussions.rb b/test/factories/discussions.rb deleted file mode 100644 index 0d1f85f..0000000 --- a/test/factories/discussions.rb +++ /dev/null @@ -1,6 +0,0 @@ -# Read about factories at https://github.com/thoughtbot/factory_girl - -FactoryGirl.define do - factory :discussion do - end -end From 8ad3aaece1f96e981aa69f01dc7d345eacc86817 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Thu, 14 Jun 2012 17:33:41 -0400 Subject: [PATCH 09/19] finally deleted messages, believe all connection to message is severed --- app/controllers/discussions_controller.rb | 2 +- app/helpers/discussions_helper.rb | 5 ++++ app/views/discussions/_form.html.erb | 2 +- app/views/help/roles_help.html.erb | 2 +- app/views/help/topics/_discussions.html.erb | 4 +++ .../20120613211916_create_discussions.rb | 8 ------ ...14200100_rename_messages_to_discussions.rb | 11 ++++++++ db/schema.rb | 25 ++++++++----------- 8 files changed, 33 insertions(+), 26 deletions(-) create mode 100644 app/helpers/discussions_helper.rb create mode 100644 app/views/help/topics/_discussions.html.erb delete mode 100644 db/migrate/20120613211916_create_discussions.rb create mode 100644 db/migrate/20120614200100_rename_messages_to_discussions.rb diff --git a/app/controllers/discussions_controller.rb b/app/controllers/discussions_controller.rb index a03e01b..4a8e277 100644 --- a/app/controllers/discussions_controller.rb +++ b/app/controllers/discussions_controller.rb @@ -43,7 +43,7 @@ def update raise SecurityTransgression unless present_user.can_create?(@discussion) - @discussion.subject = params[:message][:subject] + @discussion.subject = params[:discussion][:subject] @comment = Comment.new @comment.message = params[:message][:body] diff --git a/app/helpers/discussions_helper.rb b/app/helpers/discussions_helper.rb new file mode 100644 index 0000000..fac42c6 --- /dev/null +++ b/app/helpers/discussions_helper.rb @@ -0,0 +1,5 @@ +# Copyright 2011-2012 Rice University. Licensed under the Affero General Public +# License version 3 or later. See the COPYRIGHT file for details. + +module DiscussionsHelper +end diff --git a/app/views/discussions/_form.html.erb b/app/views/discussions/_form.html.erb index 15e576c..2a72891 100644 --- a/app/views/discussions/_form.html.erb +++ b/app/views/discussions/_form.html.erb @@ -15,6 +15,6 @@
<%= f.submit :class => "#{submit_classes}", - :value => "Send" %> + :value => "Create New Discussion" %>
<% end %> diff --git a/app/views/help/roles_help.html.erb b/app/views/help/roles_help.html.erb index 2a98fa9..e7112e0 100644 --- a/app/views/help/roles_help.html.erb +++ b/app/views/help/roles_help.html.erb @@ -42,4 +42,4 @@
<%=image_tag("message_roles.png", {:border => 1})%>
-

If the user accepts the role request, he or she becomes the author or copyright holder or whatever role was assigned to them. If the user rejects the role request, the roles remain unchanged and as they were before the role change request was made.

\ No newline at end of file +

If the user accepts the role request, he or she becomes the author or copyright holder or whatever role was assigned to them. If the user rejects the role request, the roles remain unchanged and as they were before the role change request was made.

diff --git a/app/views/help/topics/_discussions.html.erb b/app/views/help/topics/_discussions.html.erb new file mode 100644 index 0000000..1141d95 --- /dev/null +++ b/app/views/help/topics/_discussions.html.erb @@ -0,0 +1,4 @@ +<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public + License version 3 or later. See the COPYRIGHT file for details. %> + +Discussions allow you to communicate with other Quadbase users. They work just like e-mail discussions, except that e-mail addresses are never revealed. diff --git a/db/migrate/20120613211916_create_discussions.rb b/db/migrate/20120613211916_create_discussions.rb deleted file mode 100644 index dfe3f0c..0000000 --- a/db/migrate/20120613211916_create_discussions.rb +++ /dev/null @@ -1,8 +0,0 @@ -class CreateDiscussions < ActiveRecord::Migration - def change - create_table :discussions do |t| - - t.timestamps - end - end -end diff --git a/db/migrate/20120614200100_rename_messages_to_discussions.rb b/db/migrate/20120614200100_rename_messages_to_discussions.rb new file mode 100644 index 0000000..0fd11c1 --- /dev/null +++ b/db/migrate/20120614200100_rename_messages_to_discussions.rb @@ -0,0 +1,11 @@ +class RenameMessagesToDiscussions < ActiveRecord::Migration + def up + rename_table :messages, :discussions + rename_column :users, :unread_message_count, :unread_discussion_count + end + + def down + rename_table :discussions, :messages + rename_comlumn :users, :unread_discussion_count, :unread_message_count + end +end diff --git a/db/schema.rb b/db/schema.rb index 25599a3..0357c75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120613211916) do +ActiveRecord::Schema.define(:version => 20120614200100) do create_table "announcements", :force => true do |t| t.integer "user_id" @@ -83,8 +83,9 @@ end create_table "discussions", :force => true do |t| - t.datetime "created_at", :null => false - t.datetime "updated_at", :null => false + t.string "subject" + t.datetime "created_at" + t.datetime "updated_at" end create_table "licenses", :force => true do |t| @@ -128,12 +129,6 @@ t.string "required_logic_library_version_ids" end - create_table "messages", :force => true do |t| - t.string "subject" - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "project_members", :force => true do |t| t.integer "project_id" t.integer "user_id" @@ -265,16 +260,16 @@ end create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false t.string "reset_password_token" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + 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.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" t.string "confirmation_token" @@ -284,10 +279,10 @@ t.datetime "updated_at" t.string "first_name" t.string "last_name" - t.boolean "is_administrator", :default => false + t.boolean "is_administrator", :default => false t.string "username" t.datetime "disabled_at" - t.integer "unread_message_count", :default => 0 + t.integer "unread_discussion_count", :default => 0 end add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true From af0e389158d10df1e70a38a8dbf3dc4f74de15a3 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Thu, 14 Jun 2012 17:48:13 -0400 Subject: [PATCH 10/19] finally working discussion inbox --- app/controllers/discussions_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/discussions_controller.rb b/app/controllers/discussions_controller.rb index 4a8e277..57bced6 100644 --- a/app/controllers/discussions_controller.rb +++ b/app/controllers/discussions_controller.rb @@ -46,7 +46,7 @@ def update @discussion.subject = params[:discussion][:subject] @comment = Comment.new - @comment.message = params[:message][:body] + @comment.message = params[:discussion][:body] @comment.comment_thread = @discussion.comment_thread @comment.creator = present_user From 2d572785256cd657ded91a34f5e67c4186414115 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Fri, 15 Jun 2012 15:47:07 -0400 Subject: [PATCH 11/19] trying to write tesys --- .../discussions/_discussion_list.html.erb | 2 +- test/unit/discussion_test.rb | 21 ++++++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/app/views/discussions/_discussion_list.html.erb b/app/views/discussions/_discussion_list.html.erb index f7432ee..0e0b5ea 100644 --- a/app/views/discussions/_discussion_list.html.erb +++ b/app/views/discussions/_discussion_list.html.erb @@ -10,7 +10,7 @@ Recipients style="display:none"<% end %>> - None + No Discussions <% discussions.each do |discussion| %> <%= render :partial => 'discussions/discussion_list_row', :locals => {:discussion => discussion} %> diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb index 41bf043..dd9647c 100644 --- a/test/unit/discussion_test.rb +++ b/test/unit/discussion_test.rb @@ -4,8 +4,23 @@ require 'test_helper' class DiscussionTest < ActiveSupport::TestCase - # Replace this with your real tests. - test "the truth" do - assert true + + setup do + @user = Factory.create(:user) + @user2 = Factory.create(:user) + + @comment_thread = Factory.create(:comment_thread) + @comment_thread2 = Factory.create(:comment_thread) + @comment_thread.subscribe!(@user) + @comment_thread2.subscribe!(@user) end + + test "gets user's subsciptions'" do + + #discussions = Discussion.discussions_for(@user) + #assert discussions.count == 0 + end + + + end From f3a7130ca8bedc7437f47547361de9e1b8c2cfa5 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Fri, 15 Jun 2012 15:57:23 -0400 Subject: [PATCH 12/19] still trying to write the tests --- app/controllers/messages_controller.rb | 129 ------------------ app/models/message.rb | 66 --------- .../messages/_create_recipient_form.html.erb | 11 -- app/views/messages/_form.html.erb | 20 --- app/views/messages/_message_list.html.erb | 22 --- app/views/messages/_message_list_row.html.erb | 16 --- app/views/messages/_recipient.html.erb | 4 - app/views/messages/_show.html.erb | 8 -- app/views/messages/add_recipient.js.erb | 10 -- app/views/messages/leave.js.erb | 10 -- app/views/messages/show.html.erb | 40 ------ test/functional/messages_controller_test.rb | 59 -------- test/unit/discussion_test.rb | 1 - test/unit/message_test.rb | 11 -- 14 files changed, 407 deletions(-) delete mode 100644 app/controllers/messages_controller.rb delete mode 100644 app/models/message.rb delete mode 100644 app/views/messages/_create_recipient_form.html.erb delete mode 100644 app/views/messages/_form.html.erb delete mode 100644 app/views/messages/_message_list.html.erb delete mode 100644 app/views/messages/_message_list_row.html.erb delete mode 100644 app/views/messages/_recipient.html.erb delete mode 100644 app/views/messages/_show.html.erb delete mode 100644 app/views/messages/add_recipient.js.erb delete mode 100644 app/views/messages/leave.js.erb delete mode 100644 app/views/messages/show.html.erb delete mode 100644 test/functional/messages_controller_test.rb delete mode 100644 test/unit/message_test.rb diff --git a/app/controllers/messages_controller.rb b/app/controllers/messages_controller.rb deleted file mode 100644 index 926d579..0000000 --- a/app/controllers/messages_controller.rb +++ /dev/null @@ -1,129 +0,0 @@ -# Copyright 2011-2012 Rice University. Licensed under the Affero General Public -# License version 3 or later. See the COPYRIGHT file for details. - -class MessagesController < ApplicationController - - before_filter :include_jquery - - before_filter :get_message, :only => [:add_recipient, :search_recipients, :leave] - - # GET /messages/1 - def show - @message = Message.find(params[:id]) - - raise SecurityTransgression unless present_user.can_read?(@message) - - @message.comment_thread.mark_as_read_for(present_user) - present_user.reload - - respond_to do |format| - format.html # show.html.erb - end - end - - # GET /messages/new - def new - @message = Message.new - - raise SecurityTransgression unless present_user.can_create?(@message) - - respond_to do |format| - if @message.save - @message.comment_thread.subscribe!(present_user) - format.html { redirect_to @message } - else - format.html { redirect_to inbox_path } - end - end - end - - # PUT /messages/1 - def update - @message = Message.find(params[:id]) - - raise SecurityTransgression unless present_user.can_create?(@message) - - @message.subject = params[:message][:subject] - - @comment = Comment.new - @comment.message = params[:message][:body] - @comment.comment_thread = @message.comment_thread - @comment.creator = present_user - - raise SecurityTransgression unless present_user.can_create?(@comment) - - respond_to do |format| - if @message.save && @comment.save - @message.comment_thread.add_unread_except_for(present_user) - flash[:notice] = 'Message was sent successfully.' - format.html { redirect_to @message } - else - format.html { redirect_to @message } - end - end - end - - def leave - @message.comment_thread.unsubscribe!(present_user) - end - - def new_recipient - @action_dialog_title = "Add a recipient" - @action_search_path = message_search_recipients_path(params[:message_id]) - - respond_to do |format| - format.js { render :template => 'users/action_new' } - end - end - - def search_recipients - @selected_type = params[:selected_type] - @text_query = params[:text_query] - @users = User.search(@selected_type, @text_query) - - @users.reject! do |user| - @message.has_recipient?(user) - end - - @action_partial = 'messages/create_recipient_form' - - respond_to do |format| - format.js { render :template => 'users/action_search' } - end - end - - # POST /messages/1/add_recipient - def add_recipient - raise SecurityTransgression unless present_user.can_update?(@message) - - @recipient = User.find_by_username(params[:username]) - - if @recipient.nil? - flash[:alert] = 'User ' + params[:username] + ' not found!' - respond_to do |format| - format.html { redirect_to @message } - format.js { render :template => 'shared/display_flash' } - end - return - end - - respond_to do |format| - if @message.comment_thread.subscribe!(@recipient) - @message.comment_thread.mark_as_unread_for(@recipient) - format.html { redirect_to @message } - format.js - else - flash[:alert] = @message.comment_thread.errors.values.to_sentence - format.html { redirect_to @message } - format.js { render :template => 'shared/display_flash' } - end - end - end - -protected - - def get_message - @message = Message.find(params[:message_id]) - end - -end diff --git a/app/models/message.rb b/app/models/message.rb deleted file mode 100644 index 49ba3c6..0000000 --- a/app/models/message.rb +++ /dev/null @@ -1,66 +0,0 @@ -# Copyright 2011-2012 Rice University. Licensed under the Affero General Public -# License version 3 or later. See the COPYRIGHT file for details. - -class Message < ActiveRecord::Base - - has_one :comment_thread, :as => :commentable, :dependent => :destroy - before_validation :build_comment_thread, :on => :create - validates_presence_of :comment_thread - validate :subject_not_changed - - attr_accessor :body - - attr_accessible #none - - def self.messages_for(user) - CommentThreadSubscription.message_subscriptions_for(user).collect { |cts| cts.comment_thread.commentable } - end - - def subject - s = read_attribute(:subject) - s.blank? ? "[No Subject]" : s - end - - def recipients - comment_thread.comment_thread_subscriptions.collect { |cts| cts.user } - end - - def has_recipient?(user) - recipients.any?{|r| r == user} - end - - def unsubscribe_callback - destroy if comment_thread.reload.comment_thread_subscriptions.blank? - true - end - - ############################################################################# - # Access control methods - ############################################################################# - - def can_be_read_by?(user) - !user.is_anonymous? && (comment_thread.comment_thread_subscriptions.detect { |cts| cts.user == user } || user.is_administrator?) - end - - def can_be_created_by?(user) - !user.is_anonymous? - end - - def can_be_updated_by?(user) - !user.is_anonymous? && (comment_thread.comment_thread_subscriptions.detect { |cts| cts.user == user } || user.is_administrator?) - end - - def can_be_joined_by?(user) - !user.is_anonymous? && - !comment_thread.comment_thread_subscriptions.detect { |cts| cts.user == user } - end - -protected - - def subject_not_changed - return if !subject_changed? || comment_thread.comments.blank? - errors.add(:base, "You can't change a message's subject after it is sent.") - false - end - -end diff --git a/app/views/messages/_create_recipient_form.html.erb b/app/views/messages/_create_recipient_form.html.erb deleted file mode 100644 index c1ccc1d..0000000 --- a/app/views/messages/_create_recipient_form.html.erb +++ /dev/null @@ -1,11 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -<%# Callers must supply a 'user' local variable %> - -<%= form_tag(message_add_recipient_path(@message), - :method => :post, - :remote => true) do %> - <%= hidden_field_tag :username, user.username %> - <%= submit_tag "Add", :class => submit_classes, :onclick => please_wait_js %> -<% end %> \ No newline at end of file diff --git a/app/views/messages/_form.html.erb b/app/views/messages/_form.html.erb deleted file mode 100644 index 5614b6d..0000000 --- a/app/views/messages/_form.html.erb +++ /dev/null @@ -1,20 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -<%= form_for(@message) do |f| %> -
-
- <%= f.label :subject, "Subject:" %> - <%= f.text_field :subject %> -
-
-
- <%= f.label :body, "Body:" %>
- <%= f.text_area :body %> -
-
-
- <%= f.submit :class => "#{submit_classes}", - :value => "Send" %> -
-<% end %> diff --git a/app/views/messages/_message_list.html.erb b/app/views/messages/_message_list.html.erb deleted file mode 100644 index fb24946..0000000 --- a/app/views/messages/_message_list.html.erb +++ /dev/null @@ -1,22 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -<% messages = Message.messages_for(current_user) %> - - - - - - - - style="display:none"<% end %>> - - - <% messages.each do |message| %> - <%= render :partial => 'messages/message_list_row', :locals => {:message => message} %> - <% end %> -
SubjectRecipients
None
- -
- -<%= link_to "New Discussion", new_message_path %> diff --git a/app/views/messages/_message_list_row.html.erb b/app/views/messages/_message_list_row.html.erb deleted file mode 100644 index 3282826..0000000 --- a/app/views/messages/_message_list_row.html.erb +++ /dev/null @@ -1,16 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -<% # Clients of this partial must supply the following variable: - # message -%> -<% unread_count = message.comment_thread.subscription_for(current_user).unread_count %> - - <% if unread_count > 0 %> - <%= link_to message.subject + " (" + unread_count.to_s + ")", message %> - <% else %> - <%= link_to message.subject, message %> - <% end %> - <%= link_to "Leave this discussion", message_leave_path(message), :remote => true %> - <%= message.recipients.collect { |r| r.full_name }.to_sentence %> - diff --git a/app/views/messages/_recipient.html.erb b/app/views/messages/_recipient.html.erb deleted file mode 100644 index fbb60dc..0000000 --- a/app/views/messages/_recipient.html.erb +++ /dev/null @@ -1,4 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -[<%= full_name_link(recipient) %>] \ No newline at end of file diff --git a/app/views/messages/_show.html.erb b/app/views/messages/_show.html.erb deleted file mode 100644 index a731e14..0000000 --- a/app/views/messages/_show.html.erb +++ /dev/null @@ -1,8 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -
-Subject: <%= message.subject %> -
- - diff --git a/app/views/messages/add_recipient.js.erb b/app/views/messages/add_recipient.js.erb deleted file mode 100644 index 5c013b7..0000000 --- a/app/views/messages/add_recipient.js.erb +++ /dev/null @@ -1,10 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -<%= display_flash %> - -$("<%= "input[name='username'][type='hidden'][value='" + escape_javascript(params[:username]) + "']" %>").parent().html("<%= escape_javascript(label_tag 'Added') %>") - -$("#recipient_list").append("<%= ej( - render :partial => 'recipient', - :locals => {:recipient => @recipient}) %>"); diff --git a/app/views/messages/leave.js.erb b/app/views/messages/leave.js.erb deleted file mode 100644 index 4cc8032..0000000 --- a/app/views/messages/leave.js.erb +++ /dev/null @@ -1,10 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -$("#message_<%= @message.id %>").remove(); - -<% flash[:notice] = "You just left the message with subject '#{@message.subject}'" %> - -<%= display_flash %> - -show_none_row_if_needed("message_table"); \ No newline at end of file diff --git a/app/views/messages/show.html.erb b/app/views/messages/show.html.erb deleted file mode 100644 index 134d447..0000000 --- a/app/views/messages/show.html.erb +++ /dev/null @@ -1,40 +0,0 @@ -<%# Copyright 2011-2012 Rice University. Licensed under the Affero General Public - License version 3 or later. See the COPYRIGHT file for details. %> - -<%= pageHeading("Viewing discussion") %> - - - - - - - -
To: - <% @message.recipients.each do |recipient| %> - <%= render :partial => 'recipient', :locals => {:recipient => recipient} %> - <% end %> - - <%= link_to "Add recipients ...", - message_new_recipient_path(@message), - :remote => true %> -
- -<% if @message.comment_thread.comments.blank? %> -<%= render 'form' %> -<% else %> -<%= render :partial => 'show', :locals => {:message => @message} %> -<% end %> - -
- -<% if !@message.comment_thread.comments.blank? %> -<%= render :partial => 'comments/index', :locals => {:commentable => @message, - :hide_header => true, - :hide_link => true, - :hide_votes => true, - :comment_name => 'Reply'} %> -<% end %> - -

- -<%= link_to 'Back to Inbox', inbox_path %> diff --git a/test/functional/messages_controller_test.rb b/test/functional/messages_controller_test.rb deleted file mode 100644 index 9fe69ec..0000000 --- a/test/functional/messages_controller_test.rb +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2011-2012 Rice University. Licensed under the Affero General Public -# License version 3 or later. See the COPYRIGHT file for details. - -require 'test_helper' - -class MessagesControllerTest < ActionController::TestCase - - setup do - @user = Factory.create(:user) - @message = Factory.create(:message) - @message.comment_thread.subscribe!(@user) - end - - test "should not get new not logged in" do - get :new - assert_redirected_to login_path - end - - test "should get new" do - user_login - get :new - assert_redirected_to message_path(assigns[:message]) - end - - test "should not show message not logged in" do - get :show, :id => @message.to_param - assert_redirected_to login_path - end - - test "should not show message not authorized" do - user_login - get :show, :id => @message.to_param - assert_response(403) - end - - test "should show message" do - sign_in @user - get :show, :id => @message.to_param - assert_response :success - end - - test "should not update message not logged in" do - put :update, :id => @message.to_param, :message => @message.attributes - assert_redirected_to login_path - end - - test "should not update message not authorized" do - user_login - put :update, :id => @message.to_param, :message => @message.attributes - assert_response(403) - end - - test "should update message" do - sign_in @user - put :update, :id => @message.to_param, :message => @message.attributes - assert_redirected_to message_path(assigns(:message)) - end - -end diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb index dd9647c..66ee38f 100644 --- a/test/unit/discussion_test.rb +++ b/test/unit/discussion_test.rb @@ -16,7 +16,6 @@ class DiscussionTest < ActiveSupport::TestCase end test "gets user's subsciptions'" do - #discussions = Discussion.discussions_for(@user) #assert discussions.count == 0 end diff --git a/test/unit/message_test.rb b/test/unit/message_test.rb deleted file mode 100644 index c4ce2dd..0000000 --- a/test/unit/message_test.rb +++ /dev/null @@ -1,11 +0,0 @@ -# Copyright 2011-2012 Rice University. Licensed under the Affero General Public -# License version 3 or later. See the COPYRIGHT file for details. - -require 'test_helper' - -class MessageTest < ActiveSupport::TestCase - # Replace this with your real tests. - test "the truth" do - assert true - end -end From 0eb8cff924134fc057c7c09b215a5b89bd87fdeb Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Fri, 15 Jun 2012 20:55:39 -0400 Subject: [PATCH 13/19] added one test, need to figure out other tests to do.... --- test/unit/discussion_test.rb | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb index 66ee38f..e41bbf7 100644 --- a/test/unit/discussion_test.rb +++ b/test/unit/discussion_test.rb @@ -9,17 +9,20 @@ class DiscussionTest < ActiveSupport::TestCase @user = Factory.create(:user) @user2 = Factory.create(:user) - @comment_thread = Factory.create(:comment_thread) - @comment_thread2 = Factory.create(:comment_thread) + @discussion = Factory.create(:discussion) + @comment_thread = @discussion.comment_thread @comment_thread.subscribe!(@user) - @comment_thread2.subscribe!(@user) + end - test "gets user's subsciptions'" do - #discussions = Discussion.discussions_for(@user) - #assert discussions.count == 0 + test "gets user's subsciptions" do + discussions = Discussion.discussions_for(@user) + assert discussions.count == 1 + assert discussions.last == @discussion end - + test "gets subject" do + assert @discussion.subject != nil + end end From b8c118846ccee0f6664dc54ff1e9b0e5d9fadd7f Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Sat, 16 Jun 2012 00:07:57 -0400 Subject: [PATCH 14/19] finished tests XD --- test/factories.rb | 2 ++ test/unit/discussion_test.rb | 34 ++++++++++++++++++++-------------- 2 files changed, 22 insertions(+), 14 deletions(-) diff --git a/test/factories.rb b/test/factories.rb index bcceb32..19caf19 100644 --- a/test/factories.rb +++ b/test/factories.rb @@ -269,6 +269,8 @@ def make_project(options = {}) Factory.define :discussion do |f| f.subject {Factory.next :content} + f.body {Factory.next :content} + f.association :comment_thread end Factory.define :deputization do |f| diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb index e41bbf7..1077d25 100644 --- a/test/unit/discussion_test.rb +++ b/test/unit/discussion_test.rb @@ -4,25 +4,31 @@ require 'test_helper' class DiscussionTest < ActiveSupport::TestCase - - setup do - @user = Factory.create(:user) - @user2 = Factory.create(:user) - - @discussion = Factory.create(:discussion) - @comment_thread = @discussion.comment_thread - @comment_thread.subscribe!(@user) + test "cannot mass-assign comment_thread, subject, body" do + ct = Factory.create(:comment_thread) + d = Discussion.new(:comment_thread => ct, :subject => 'head', :body => 'bod') + assert d.comment_thread != ct + assert d.subject != 'head' + assert d.body != 'bod' end - test "gets user's subsciptions" do - discussions = Discussion.discussions_for(@user) - assert discussions.count == 1 - assert discussions.last == @discussion + test "should have a recipient when subscribed" do + discussion = Factory.create(:discussion) + user = Factory.create(:user) + discussion.comment_thread.subscribe!(user) + assert discussion.has_recipient?(user) end - test "gets subject" do - assert @discussion.subject != nil + test "should delete discussion when no recipients are left" do + discussion = Factory.create(:discussion) + user = Factory.create(:user) + ct = discussion.comment_thread + ct.subscribe!(user) + assert discussion.has_recipient?(user) + + ct.unsubscribe!(user) + assert_raise(ActiveRecord::RecordNotFound) { Discussion.find(discussion.id) } end end From 541146444053b22b57b2b34cc9f3d61abc8588f5 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Wed, 27 Jun 2012 10:20:49 -0400 Subject: [PATCH 15/19] changed Factory to FactoryGirl in tests --- test/functional/discussions_controller_test.rb | 4 ++-- test/unit/discussion_test.rb | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/test/functional/discussions_controller_test.rb b/test/functional/discussions_controller_test.rb index 89b7da6..40e2465 100644 --- a/test/functional/discussions_controller_test.rb +++ b/test/functional/discussions_controller_test.rb @@ -6,8 +6,8 @@ class DiscussionsControllerTest < ActionController::TestCase setup do - @user = Factory.create(:user) - @discussion = Factory.create(:discussion) + @user = FactoryGirl.create(:user) + @discussion = FactoryGirl.create(:discussion) @discussion.comment_thread.subscribe!(@user) end diff --git a/test/unit/discussion_test.rb b/test/unit/discussion_test.rb index 1077d25..ad9afe7 100644 --- a/test/unit/discussion_test.rb +++ b/test/unit/discussion_test.rb @@ -6,7 +6,7 @@ class DiscussionTest < ActiveSupport::TestCase test "cannot mass-assign comment_thread, subject, body" do - ct = Factory.create(:comment_thread) + ct = FactoryGirl.create(:comment_thread) d = Discussion.new(:comment_thread => ct, :subject => 'head', :body => 'bod') assert d.comment_thread != ct assert d.subject != 'head' @@ -14,15 +14,15 @@ class DiscussionTest < ActiveSupport::TestCase end test "should have a recipient when subscribed" do - discussion = Factory.create(:discussion) - user = Factory.create(:user) + discussion = FactoryGirl.create(:discussion) + user = FactoryGirl.create(:user) discussion.comment_thread.subscribe!(user) assert discussion.has_recipient?(user) end test "should delete discussion when no recipients are left" do - discussion = Factory.create(:discussion) - user = Factory.create(:user) + discussion = FactoryGirl.create(:discussion) + user = FactoryGirl.create(:user) ct = discussion.comment_thread ct.subscribe!(user) assert discussion.has_recipient?(user) From ec737564daf8597b752f3945b0b29599aa863d69 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Fri, 29 Jun 2012 14:00:04 -0400 Subject: [PATCH 16/19] merge issues --- ...14200100_rename_messages_to_discussions.rb | 2 +- db/schema.rb | 26 +++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/db/migrate/20120614200100_rename_messages_to_discussions.rb b/db/migrate/20120614200100_rename_messages_to_discussions.rb index 0fd11c1..6395988 100644 --- a/db/migrate/20120614200100_rename_messages_to_discussions.rb +++ b/db/migrate/20120614200100_rename_messages_to_discussions.rb @@ -6,6 +6,6 @@ def up def down rename_table :discussions, :messages - rename_comlumn :users, :unread_discussion_count, :unread_message_count + rename_column :users, :unread_discussion_count, :unread_message_count end end diff --git a/db/schema.rb b/db/schema.rb index 0357c75..3f91387 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120614200100) do +ActiveRecord::Schema.define(:version => 20120424015013) do create_table "announcements", :force => true do |t| t.integer "user_id" @@ -82,12 +82,6 @@ t.datetime "updated_at" end - create_table "discussions", :force => true do |t| - t.string "subject" - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "licenses", :force => true do |t| t.string "short_name" t.string "long_name" @@ -129,6 +123,12 @@ t.string "required_logic_library_version_ids" end + create_table "messages", :force => true do |t| + t.string "subject" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "project_members", :force => true do |t| t.integer "project_id" t.integer "user_id" @@ -260,16 +260,16 @@ end create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false t.string "reset_password_token" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + 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.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" t.string "confirmation_token" @@ -279,10 +279,10 @@ t.datetime "updated_at" t.string "first_name" t.string "last_name" - t.boolean "is_administrator", :default => false + t.boolean "is_administrator", :default => false t.string "username" t.datetime "disabled_at" - t.integer "unread_discussion_count", :default => 0 + t.integer "unread_message_count", :default => 0 end add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true From 9cd534a07142045653dc6a94381a19303d767c82 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Mon, 9 Jul 2012 16:17:13 -0400 Subject: [PATCH 17/19] few minor changes --- db/schema.rb | 26 +++++++++---------- ...per_test.rb => discussions_helper_test.rb} | 2 +- 2 files changed, 14 insertions(+), 14 deletions(-) rename test/unit/helpers/{messages_helper_test.rb => discussions_helper_test.rb} (77%) diff --git a/db/schema.rb b/db/schema.rb index 3f91387..0357c75 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20120424015013) do +ActiveRecord::Schema.define(:version => 20120614200100) do create_table "announcements", :force => true do |t| t.integer "user_id" @@ -82,6 +82,12 @@ t.datetime "updated_at" end + create_table "discussions", :force => true do |t| + t.string "subject" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "licenses", :force => true do |t| t.string "short_name" t.string "long_name" @@ -123,12 +129,6 @@ t.string "required_logic_library_version_ids" end - create_table "messages", :force => true do |t| - t.string "subject" - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "project_members", :force => true do |t| t.integer "project_id" t.integer "user_id" @@ -260,16 +260,16 @@ end create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :limit => 128, :default => "", :null => false t.string "reset_password_token" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + 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.integer "failed_attempts", :default => 0 + t.integer "failed_attempts", :default => 0 t.string "unlock_token" t.datetime "locked_at" t.string "confirmation_token" @@ -279,10 +279,10 @@ t.datetime "updated_at" t.string "first_name" t.string "last_name" - t.boolean "is_administrator", :default => false + t.boolean "is_administrator", :default => false t.string "username" t.datetime "disabled_at" - t.integer "unread_message_count", :default => 0 + t.integer "unread_discussion_count", :default => 0 end add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true diff --git a/test/unit/helpers/messages_helper_test.rb b/test/unit/helpers/discussions_helper_test.rb similarity index 77% rename from test/unit/helpers/messages_helper_test.rb rename to test/unit/helpers/discussions_helper_test.rb index a365652..461c049 100644 --- a/test/unit/helpers/messages_helper_test.rb +++ b/test/unit/helpers/discussions_helper_test.rb @@ -3,5 +3,5 @@ require 'test_helper' -class MessagesHelperTest < ActionView::TestCase +class DiscussionsHelperTest < ActionView::TestCase end From 5b6f1e13a31878c5d0dfc2fc37a7ec752cc9dbd5 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Thu, 12 Jul 2012 17:25:36 -0400 Subject: [PATCH 18/19] fixed a few typos --- app/mailers/subscription_notifier.rb | 4 ++-- test/factories.rb | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/app/mailers/subscription_notifier.rb b/app/mailers/subscription_notifier.rb index d14b9ea..4c4b774 100644 --- a/app/mailers/subscription_notifier.rb +++ b/app/mailers/subscription_notifier.rb @@ -10,7 +10,7 @@ def comment_created_email(comment) mail(:bcc => @active_subscribers.reject{ |as| as == @creator }.collect { |as| as.email }, :subject => @creator.full_name + - (@is_message ? " sent you a message: " + @commentable.subject : + (@is_discussion ? " sent you a message: " + @commentable.subject : " has commented on a thread to which you subscribe")).deliver end @@ -23,7 +23,7 @@ def setup_variables(comment) @commentable = @comment_thread.commentable.becomes( Kernel.const_get(@comment_thread.commentable_type)) @active_subscribers = User.subscribers_for(@comment_thread).active_users - @is_message = @comment_thread.commentable_type == 'Discussion' + @is_discussion = @comment_thread.commentable_type == 'Discussion' end end diff --git a/test/factories.rb b/test/factories.rb index 2704d4f..1f2f858 100644 --- a/test/factories.rb +++ b/test/factories.rb @@ -273,7 +273,6 @@ def make_project(options = {}) f.association :comment_thread end - factory :deputization do |f| f.association :deputizer, :factory => :user f.association :deputy, :factory => :user From 578b673aff5a8e42b38bd597389be7c1f7d09186 Mon Sep 17 00:00:00 2001 From: Joel Yin Date: Fri, 20 Jul 2012 17:42:07 -0400 Subject: [PATCH 19/19] fixed db --- db/schema.rb | 129 ++++++++++++++++++++++++++------------------------- 1 file changed, 65 insertions(+), 64 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index 0357c75..ac009f4 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -18,16 +18,16 @@ t.text "subject" t.text "body" t.boolean "force" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "answer_choices", :force => true do |t| t.integer "question_id" t.text "content" t.decimal "credit" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "content_html", :limit => 255 end @@ -37,16 +37,16 @@ t.integer "attachment_file_size" t.datetime "attachment_updated_at" t.integer "uploader_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "attachable_assets", :force => true do |t| t.integer "attachable_id" t.integer "asset_id" t.string "local_name" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "description" t.string "attachable_type" end @@ -54,16 +54,16 @@ create_table "comment_thread_subscriptions", :force => true do |t| t.integer "comment_thread_id" t.integer "user_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "unread_count", :default => 0 end create_table "comment_threads", :force => true do |t| t.string "commentable_type" t.integer "commentable_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "comments", :force => true do |t| @@ -71,29 +71,29 @@ t.text "message" t.integer "creator_id" t.boolean "is_log" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "deputizations", :force => true do |t| t.integer "deputizer_id" t.integer "deputy_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "discussions", :force => true do |t| t.string "subject" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "licenses", :force => true do |t| t.string "short_name" t.string "long_name" t.string "url" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "agreement_partial_name" t.boolean "is_default" end @@ -102,8 +102,8 @@ t.string "name" t.integer "number" t.text "summary" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "always_required" end @@ -113,8 +113,8 @@ t.text "code" t.text "minified_code" t.boolean "deprecated" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "logics", :force => true do |t| @@ -122,8 +122,8 @@ t.string "variables" t.string "logicable_type" t.integer "logicable_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "cached_code" t.string "variables_array" t.string "required_logic_library_version_ids" @@ -133,21 +133,21 @@ t.integer "project_id" t.integer "user_id" t.boolean "is_default" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "project_questions", :force => true do |t| t.integer "project_id" t.integer "question_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "projects", :force => true do |t| 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 "question_collaborators", :force => true do |t| @@ -156,8 +156,8 @@ t.integer "position" t.boolean "is_author", :default => false t.boolean "is_copyright_holder", :default => false - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "question_role_requests_count", :default => 0 end @@ -165,24 +165,24 @@ t.integer "independent_question_id" t.integer "dependent_question_id" t.string "kind" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "question_derivations", :force => true do |t| t.integer "derived_question_id" t.integer "source_question_id" t.integer "deriver_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "question_parts", :force => true do |t| t.integer "multipart_question_id" t.integer "child_question_id" t.integer "order" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "question_role_requests", :force => true do |t| @@ -190,16 +190,16 @@ t.boolean "toggle_is_author" t.boolean "toggle_is_copyright_holder" t.integer "requestor_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "is_approved", :default => false t.boolean "is_accepted", :default => false end create_table "question_setups", :force => true do |t| t.text "content" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "content_html", :limit => 255 end @@ -209,8 +209,8 @@ t.string "question_type" t.text "content" t.integer "question_setup_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.integer "license_id" t.text "content_html", :limit => 255 t.integer "locked_by", :default => -1 @@ -225,8 +225,8 @@ t.integer "creator_id" t.text "content" t.integer "question_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.text "content_html" t.text "explanation" t.boolean "is_visible" @@ -253,36 +253,37 @@ t.integer "user_id" t.boolean "project_member_email", :default => true t.boolean "role_request_email", :default => true - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.boolean "announcement_email" t.boolean "auto_author_subscribe", :default => true end create_table "users", :force => true do |t| - t.string "email", :default => "", :null => false - t.string "encrypted_password", :limit => 128, :default => "", :null => false + t.string "email", :default => "", :null => false + t.string "encrypted_password", :default => "", :null => false t.string "reset_password_token" + t.datetime "reset_password_sent_at" t.datetime "remember_created_at" - t.integer "sign_in_count", :default => 0 + 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.integer "failed_attempts", :default => 0 - t.string "unlock_token" - t.datetime "locked_at" t.string "confirmation_token" t.datetime "confirmed_at" t.datetime "confirmation_sent_at" - t.datetime "created_at" - t.datetime "updated_at" + t.integer "failed_attempts", :default => 0 + t.string "unlock_token" + t.datetime "locked_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false t.string "first_name" t.string "last_name" - t.boolean "is_administrator", :default => false + t.boolean "is_administrator", :default => false t.string "username" t.datetime "disabled_at" - t.integer "unread_discussion_count", :default => 0 + t.integer "unread_discussion_count", :default => 0 end add_index "users", ["confirmation_token"], :name => "index_users_on_confirmation_token", :unique => true @@ -295,16 +296,16 @@ t.boolean "thumbs_up" t.string "votable_type" t.integer "votable_id" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end create_table "website_configurations", :force => true do |t| t.string "name" t.string "value" t.string "value_type" - t.datetime "created_at" - t.datetime "updated_at" + t.datetime "created_at", :null => false + t.datetime "updated_at", :null => false end end