From 09bc6f1bfde35edfdc67a0ce372fdd2b88532bed Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Fri, 10 Dec 2021 23:44:45 -0500 Subject: [PATCH 01/12] Add models in private namespace. --- app/models/private/conversation.rb | 3 +++ app/models/private/message.rb | 3 +++ db/migrate/20211211044212_create_private_conversations.rb | 8 ++++++++ db/migrate/20211211044226_create_private_messages.rb | 8 ++++++++ spec/factories/private_conversations.rb | 5 +++++ spec/factories/private_messages.rb | 5 +++++ spec/models/private/conversation_spec.rb | 5 +++++ spec/models/private/message_spec.rb | 5 +++++ 8 files changed, 42 insertions(+) create mode 100644 app/models/private/conversation.rb create mode 100644 app/models/private/message.rb create mode 100644 db/migrate/20211211044212_create_private_conversations.rb create mode 100644 db/migrate/20211211044226_create_private_messages.rb create mode 100644 spec/factories/private_conversations.rb create mode 100644 spec/factories/private_messages.rb create mode 100644 spec/models/private/conversation_spec.rb create mode 100644 spec/models/private/message_spec.rb diff --git a/app/models/private/conversation.rb b/app/models/private/conversation.rb new file mode 100644 index 0000000..a464b7b --- /dev/null +++ b/app/models/private/conversation.rb @@ -0,0 +1,3 @@ +class Private::Conversation < ApplicationRecord + self.table_name = 'private_conversations' +end diff --git a/app/models/private/message.rb b/app/models/private/message.rb new file mode 100644 index 0000000..565a957 --- /dev/null +++ b/app/models/private/message.rb @@ -0,0 +1,3 @@ +class Private::Message < ApplicationRecord + self.table_name = 'private_messages' +end diff --git a/db/migrate/20211211044212_create_private_conversations.rb b/db/migrate/20211211044212_create_private_conversations.rb new file mode 100644 index 0000000..9d37370 --- /dev/null +++ b/db/migrate/20211211044212_create_private_conversations.rb @@ -0,0 +1,8 @@ +class CreatePrivateConversations < ActiveRecord::Migration[5.1] + def change + create_table :private_conversations do |t| + + t.timestamps + end + end +end diff --git a/db/migrate/20211211044226_create_private_messages.rb b/db/migrate/20211211044226_create_private_messages.rb new file mode 100644 index 0000000..5cd14a5 --- /dev/null +++ b/db/migrate/20211211044226_create_private_messages.rb @@ -0,0 +1,8 @@ +class CreatePrivateMessages < ActiveRecord::Migration[5.1] + def change + create_table :private_messages do |t| + + t.timestamps + end + end +end diff --git a/spec/factories/private_conversations.rb b/spec/factories/private_conversations.rb new file mode 100644 index 0000000..612538a --- /dev/null +++ b/spec/factories/private_conversations.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :private_conversation, class: 'Private::Conversation' do + + end +end diff --git a/spec/factories/private_messages.rb b/spec/factories/private_messages.rb new file mode 100644 index 0000000..18cd6a2 --- /dev/null +++ b/spec/factories/private_messages.rb @@ -0,0 +1,5 @@ +FactoryGirl.define do + factory :private_message, class: 'Private::Message' do + + end +end diff --git a/spec/models/private/conversation_spec.rb b/spec/models/private/conversation_spec.rb new file mode 100644 index 0000000..62d892e --- /dev/null +++ b/spec/models/private/conversation_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Private::Conversation, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end diff --git a/spec/models/private/message_spec.rb b/spec/models/private/message_spec.rb new file mode 100644 index 0000000..fb899c9 --- /dev/null +++ b/spec/models/private/message_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Private::Message, type: :model do + pending "add some examples to (or delete) #{__FILE__}" +end From d2a14c440110a0febcf6425e12e3f897a2abb95f Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Fri, 10 Dec 2021 23:49:33 -0500 Subject: [PATCH 02/12] Add model associations for convos. --- app/models/private/conversation.rb | 6 ++++++ app/models/private/message.rb | 5 +++++ app/models/user.rb | 4 ++++ 3 files changed, 15 insertions(+) diff --git a/app/models/private/conversation.rb b/app/models/private/conversation.rb index a464b7b..89c618f 100644 --- a/app/models/private/conversation.rb +++ b/app/models/private/conversation.rb @@ -1,3 +1,9 @@ class Private::Conversation < ApplicationRecord self.table_name = 'private_conversations' + + has_many :messages, + class_name: "Private::Message", + foreign_key: :conversation_id + belongs_to :sender, foreign_key: :sender_id, class_name: 'User' + belongs_to :recipient, foreign_key: :recipient_id, class_name 'User' end diff --git a/app/models/private/message.rb b/app/models/private/message.rb index 565a957..c9edcf5 100644 --- a/app/models/private/message.rb +++ b/app/models/private/message.rb @@ -1,3 +1,8 @@ class Private::Message < ApplicationRecord self.table_name = 'private_messages' + + belongs_to :user + belongs_to :conversation, + class_name: "Private::Conversation", + foreign_key: :conversation_id end diff --git a/app/models/user.rb b/app/models/user.rb index 38100ee..8a0f07c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -5,4 +5,8 @@ class User < ApplicationRecord :recoverable, :rememberable, :validatable has_many :posts, dependent: :destroy + has_many :private_messages, class_name: "Private::Message" + has_many :private_conversations, + foreign_key: :sender_id, + class_name: "Private::Conversation" end From 5454f6b86b1f07713fd8d76d0fb9de1436982727 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sat, 11 Dec 2021 15:35:25 -0500 Subject: [PATCH 03/12] Add tables for models and migrate. --- ...1211044212_create_private_conversations.rb | 6 +++++ .../20211211044226_create_private_messages.rb | 4 ++++ db/schema.rb | 24 ++++++++++++++++++- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/db/migrate/20211211044212_create_private_conversations.rb b/db/migrate/20211211044212_create_private_conversations.rb index 9d37370..0afed89 100644 --- a/db/migrate/20211211044212_create_private_conversations.rb +++ b/db/migrate/20211211044212_create_private_conversations.rb @@ -1,8 +1,14 @@ class CreatePrivateConversations < ActiveRecord::Migration[5.1] def change create_table :private_conversations do |t| + t.integer :recipient_id + t.integer :sender_id t.timestamps end + + add_index :private_conversations, :recipient_id + add_index :private_conversations, :sender_id + add_index :private_conversations, [:recipient_id, :sender_id], unique: true end end diff --git a/db/migrate/20211211044226_create_private_messages.rb b/db/migrate/20211211044226_create_private_messages.rb index 5cd14a5..8125e44 100644 --- a/db/migrate/20211211044226_create_private_messages.rb +++ b/db/migrate/20211211044226_create_private_messages.rb @@ -1,6 +1,10 @@ class CreatePrivateMessages < ActiveRecord::Migration[5.1] def change create_table :private_messages do |t| + t.text :body + t.references :user, foreign_key: true + t.belongs_to :conversation, index: true + t.boolean :seen, default: false t.timestamps end diff --git a/db/schema.rb b/db/schema.rb index 35fa3af..2b7d1c9 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20211111154915) do +ActiveRecord::Schema.define(version: 20211211044226) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -31,6 +31,27 @@ t.index ["user_id"], name: "index_posts_on_user_id" end + create_table "private_conversations", force: :cascade do |t| + t.integer "recipient_id" + t.integer "sender_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["recipient_id", "sender_id"], name: "index_private_conversations_on_recipient_id_and_sender_id", unique: true + t.index ["recipient_id"], name: "index_private_conversations_on_recipient_id" + t.index ["sender_id"], name: "index_private_conversations_on_sender_id" + end + + create_table "private_messages", force: :cascade do |t| + t.text "body" + t.bigint "user_id" + t.bigint "conversation_id" + t.boolean "seen", default: false + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["conversation_id"], name: "index_private_messages_on_conversation_id" + t.index ["user_id"], name: "index_private_messages_on_user_id" + end + create_table "users", force: :cascade do |t| t.string "name", default: "", null: false t.string "email", default: "", null: false @@ -44,4 +65,5 @@ t.index ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true end + add_foreign_key "private_messages", "users" end From 9742c7d493c7a8b339e234bf1cce9f22928cfe6b Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sat, 11 Dec 2021 15:37:48 -0500 Subject: [PATCH 04/12] Conversations controller in private namespace. --- .../javascripts/private/conversations.coffee | 3 +++ app/assets/stylesheets/private/conversations.scss | 3 +++ .../private/conversations_controller.rb | 2 ++ app/helpers/private/conversations_helper.rb | 2 ++ .../private/conversations_controller_spec.rb | 5 +++++ spec/helpers/private/conversations_helper_spec.rb | 15 +++++++++++++++ 6 files changed, 30 insertions(+) create mode 100644 app/assets/javascripts/private/conversations.coffee create mode 100644 app/assets/stylesheets/private/conversations.scss create mode 100644 app/controllers/private/conversations_controller.rb create mode 100644 app/helpers/private/conversations_helper.rb create mode 100644 spec/controllers/private/conversations_controller_spec.rb create mode 100644 spec/helpers/private/conversations_helper_spec.rb diff --git a/app/assets/javascripts/private/conversations.coffee b/app/assets/javascripts/private/conversations.coffee new file mode 100644 index 0000000..24f83d1 --- /dev/null +++ b/app/assets/javascripts/private/conversations.coffee @@ -0,0 +1,3 @@ +# Place all the behaviors and hooks related to the matching controller here. +# All this logic will automatically be available in application.js. +# You can use CoffeeScript in this file: http://coffeescript.org/ diff --git a/app/assets/stylesheets/private/conversations.scss b/app/assets/stylesheets/private/conversations.scss new file mode 100644 index 0000000..aa55a82 --- /dev/null +++ b/app/assets/stylesheets/private/conversations.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the private/conversations controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: http://sass-lang.com/ diff --git a/app/controllers/private/conversations_controller.rb b/app/controllers/private/conversations_controller.rb new file mode 100644 index 0000000..9fd8078 --- /dev/null +++ b/app/controllers/private/conversations_controller.rb @@ -0,0 +1,2 @@ +class Private::ConversationsController < ApplicationController +end diff --git a/app/helpers/private/conversations_helper.rb b/app/helpers/private/conversations_helper.rb new file mode 100644 index 0000000..38df4b1 --- /dev/null +++ b/app/helpers/private/conversations_helper.rb @@ -0,0 +1,2 @@ +module Private::ConversationsHelper +end diff --git a/spec/controllers/private/conversations_controller_spec.rb b/spec/controllers/private/conversations_controller_spec.rb new file mode 100644 index 0000000..70d5654 --- /dev/null +++ b/spec/controllers/private/conversations_controller_spec.rb @@ -0,0 +1,5 @@ +require 'rails_helper' + +RSpec.describe Private::ConversationsController, type: :controller do + +end diff --git a/spec/helpers/private/conversations_helper_spec.rb b/spec/helpers/private/conversations_helper_spec.rb new file mode 100644 index 0000000..abd7688 --- /dev/null +++ b/spec/helpers/private/conversations_helper_spec.rb @@ -0,0 +1,15 @@ +require 'rails_helper' + +# Specs in this file have access to a helper object that includes +# the Private::ConversationsHelper. For example: +# +# describe Private::ConversationsHelper do +# describe "string concat" do +# it "concats two strings with spaces" do +# expect(helper.concat_strings("this","that")).to eq("this that") +# end +# end +# end +RSpec.describe Private::ConversationsHelper, type: :helper do + pending "add some examples to (or delete) #{__FILE__}" +end From 1383a48f5948ea504a4ad4a2a9ba41746b16ef8a Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sat, 11 Dec 2021 15:51:19 -0500 Subject: [PATCH 05/12] Add helper method for contact_user_partial_path --- app/helpers/posts_helper.rb | 8 ++++++++ app/views/posts/show.html.erb | 1 + spec/helpers/posts_helper_spec.rb | 26 ++++++++++++++++++++++++++ 3 files changed, 35 insertions(+) diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index 947b9d6..c00a16e 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -38,4 +38,12 @@ def update_pagination_partial_path 'posts/posts_pagination_page/remove_pagination' end end + + def contact_user_partial_path + if user_signed_in? + @post.user.id != current_user.id ? 'posts/show/contact_user' : 'shared/empty_partial' + else + 'posts/show/login_required' + end + end end diff --git a/app/views/posts/show.html.erb b/app/views/posts/show.html.erb index bbfccfa..08030dc 100644 --- a/app/views/posts/show.html.erb +++ b/app/views/posts/show.html.erb @@ -4,6 +4,7 @@
Posted by <%= @post.user.name %>

<%= @post.title %>

<%= @post.content %>

+ <%= render contact_user_partial_path %> diff --git a/spec/helpers/posts_helper_spec.rb b/spec/helpers/posts_helper_spec.rb index 915d8e9..463d427 100644 --- a/spec/helpers/posts_helper_spec.rb +++ b/spec/helpers/posts_helper_spec.rb @@ -81,4 +81,30 @@ ) end end + context "#contact_user_partial_path" do + before(:each) do + @current_user = create(:user, id: 1) + helper.stub(:current_user).and_return(@current_user) + end + it "returns a contact user's partial path" do + helper.stub(:user_signed_in?).and_return(true) + assign(:post, create(:post, user_id: create(:user, id: 2).id)) + expect(helper.contact_user_partial_path).to( + eq 'posts/show/contact_user' + ) + end + it "returns an empty partial's path when post is from current user" do + helper.stub(:user_signed_in?).and_return(true) + assign(:post, create(:post, user_id: @current_user.id)) + expect(helper.contact_user_partial_path).to( + eq 'shared/empty_partial' + ) + end + it "returns login required path when no current user logged in" do + helper.stub(:user_signed_in?).and_return(false) + expect(helper.contact_user_partial_path).to( + eq 'posts/show/login_required' + ) + end + end end From 96977e5e308d160aa7cc365cc081bb00e5786898 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sun, 12 Dec 2021 00:28:35 -0500 Subject: [PATCH 06/12] Templates and specs for contact user. --- app/helpers/posts_helper.rb | 8 ++++++++ app/views/posts/show/_contact_user.html.erb | 3 +++ app/views/posts/show/_login_required.html.erb | 3 +++ spec/helpers/posts_helper_spec.rb | 14 ++++++++++++++ 4 files changed, 28 insertions(+) create mode 100644 app/views/posts/show/_contact_user.html.erb create mode 100644 app/views/posts/show/_login_required.html.erb diff --git a/app/helpers/posts_helper.rb b/app/helpers/posts_helper.rb index c00a16e..620f78c 100644 --- a/app/helpers/posts_helper.rb +++ b/app/helpers/posts_helper.rb @@ -46,4 +46,12 @@ def contact_user_partial_path 'posts/show/login_required' end end + + def leave_message_partial_path + if @message_has_been_sent + 'posts/show/contact_user/already_in_touch' + else + 'posts/show/contact_user/message_form' + end + end end diff --git a/app/views/posts/show/_contact_user.html.erb b/app/views/posts/show/_contact_user.html.erb new file mode 100644 index 0000000..deb3669 --- /dev/null +++ b/app/views/posts/show/_contact_user.html.erb @@ -0,0 +1,3 @@ +
+ <%= render leave_message_partial_path %> +
\ No newline at end of file diff --git a/app/views/posts/show/_login_required.html.erb b/app/views/posts/show/_login_required.html.erb new file mode 100644 index 0000000..001efe4 --- /dev/null +++ b/app/views/posts/show/_login_required.html.erb @@ -0,0 +1,3 @@ +
+ To contact the user you have to <%= link_to 'Login', login_path %> +
\ No newline at end of file diff --git a/spec/helpers/posts_helper_spec.rb b/spec/helpers/posts_helper_spec.rb index 463d427..4e74122 100644 --- a/spec/helpers/posts_helper_spec.rb +++ b/spec/helpers/posts_helper_spec.rb @@ -107,4 +107,18 @@ ) end end + context "#leave_message_partial_path" do + it "returns an already in touch partial path" do + assign('message_has_been_sent', true) + expect(helper.leave_message_partial_path).to( + eq 'posts/show/contact_user/already_in_touch' + ) + end + it "returns a message form partial path" do + assign('message_has_been_sent', false) + expect(helper.leave_message_partial_path).to( + eq 'posts/show/contact_user/message_form' + ) + end + end end From f68b75a558adbc7594d6907fa668536213dbb29d Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sun, 12 Dec 2021 00:41:51 -0500 Subject: [PATCH 07/12] WIP conversation. --- app/controllers/posts_controller.rb | 9 ++++++++- app/models/private/conversation.rb | 6 ++++++ .../show/contact_user/_already_in_touch.html.erb | 3 +++ .../posts/show/contact_user/_message_form.html.erb | 12 ++++++++++++ 4 files changed, 29 insertions(+), 1 deletion(-) create mode 100644 app/views/posts/show/contact_user/_already_in_touch.html.erb create mode 100644 app/views/posts/show/contact_user/_message_form.html.erb diff --git a/app/controllers/posts_controller.rb b/app/controllers/posts_controller.rb index 146c44c..dbc1f22 100644 --- a/app/controllers/posts_controller.rb +++ b/app/controllers/posts_controller.rb @@ -17,7 +17,10 @@ def create end def show - @post = Post.find(params[:id]) + @post = Post.find(params[:id]) + if user_signed_in? + @message_has_been_sent = conversation_exist? + end end def study @@ -56,4 +59,8 @@ def get_posts }).call end + + def conversation_exist? + Private::Conversation.between_users(current_user.id, @post.user.id).present? + end end diff --git a/app/models/private/conversation.rb b/app/models/private/conversation.rb index 89c618f..19c338e 100644 --- a/app/models/private/conversation.rb +++ b/app/models/private/conversation.rb @@ -6,4 +6,10 @@ class Private::Conversation < ApplicationRecord foreign_key: :conversation_id belongs_to :sender, foreign_key: :sender_id, class_name: 'User' belongs_to :recipient, foreign_key: :recipient_id, class_name 'User' + + scope :between_users, -> (user1_id, user2_id) do + where(sender_id: user1_id, recipient_id: user2_id).or( + where(sender_id: user2_id, recipient_id: user1_id) + ) + end end diff --git a/app/views/posts/show/contact_user/_already_in_touch.html.erb b/app/views/posts/show/contact_user/_already_in_touch.html.erb new file mode 100644 index 0000000..2350ff7 --- /dev/null +++ b/app/views/posts/show/contact_user/_already_in_touch.html.erb @@ -0,0 +1,3 @@ +
+ You are already in touch with this user +
\ No newline at end of file diff --git a/app/views/posts/show/contact_user/_message_form.html.erb b/app/views/posts/show/contact_user/_message_form.html.erb new file mode 100644 index 0000000..ee1b51a --- /dev/null +++ b/app/views/posts/show/contact_user/_message_form.html.erb @@ -0,0 +1,12 @@ +<%= form_tag({controller: "private/conversations", action: "create"}, + method: "post", + remote: true) do %> + <%= hidden_field_tag(:post_id, @post.id) %> + <%= text_area_tag(:message_body, + nil, + rows: 3, + class: 'form-control', + placeholder: 'Send a message to the user') %> + <%= submit_tag('Send a message', class: 'btn send-message-to-user') %> +<% end %> + From e451a6f4340c0dd8908dfc18a066cc68526a3952 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sun, 12 Dec 2021 20:36:23 -0500 Subject: [PATCH 08/12] Factories for private convo and msg. --- spec/factories/private_conversations.rb | 14 +++++++++++++- spec/factories/private_messages.rb | 4 +++- 2 files changed, 16 insertions(+), 2 deletions(-) diff --git a/spec/factories/private_conversations.rb b/spec/factories/private_conversations.rb index 612538a..1196e98 100644 --- a/spec/factories/private_conversations.rb +++ b/spec/factories/private_conversations.rb @@ -1,5 +1,17 @@ FactoryGirl.define do factory :private_conversation, class: 'Private::Conversation' do - + association :recipient, factory: :user + association :sender, factory: :user + + factory :private_conversation_with_messages do + transient do + messages_count 1 + end + + after(:create) do |private_conversation, evaluator| + create_list(:private_message, evaluator.messages_count, + conversation: private_conversation) + end + end end end diff --git a/spec/factories/private_messages.rb b/spec/factories/private_messages.rb index 18cd6a2..a1433e7 100644 --- a/spec/factories/private_messages.rb +++ b/spec/factories/private_messages.rb @@ -1,5 +1,7 @@ FactoryGirl.define do factory :private_message, class: 'Private::Message' do - + body 'a'*20 + association :conversation, factory: :private_conversation + user end end From 100225ecdbec64c5d07ad320f86aa0f6721ced48 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sun, 12 Dec 2021 20:42:56 -0500 Subject: [PATCH 09/12] Passing scope test on convo between users. --- app/models/private/conversation.rb | 2 +- spec/models/private/conversation_spec.rb | 10 +++++++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/app/models/private/conversation.rb b/app/models/private/conversation.rb index 19c338e..a1968bf 100644 --- a/app/models/private/conversation.rb +++ b/app/models/private/conversation.rb @@ -5,7 +5,7 @@ class Private::Conversation < ApplicationRecord class_name: "Private::Message", foreign_key: :conversation_id belongs_to :sender, foreign_key: :sender_id, class_name: 'User' - belongs_to :recipient, foreign_key: :recipient_id, class_name 'User' + belongs_to :recipient, foreign_key: :recipient_id, class_name: 'User' scope :between_users, -> (user1_id, user2_id) do where(sender_id: user1_id, recipient_id: user2_id).or( diff --git a/spec/models/private/conversation_spec.rb b/spec/models/private/conversation_spec.rb index 62d892e..b0af10d 100644 --- a/spec/models/private/conversation_spec.rb +++ b/spec/models/private/conversation_spec.rb @@ -1,5 +1,13 @@ require 'rails_helper' RSpec.describe Private::Conversation, type: :model do - pending "add some examples to (or delete) #{__FILE__}" + context "Scopes" do + it "gets a conversation between users" do + user1 = create(:user) + user2 = create(:user) + create(:private_conversation, recipient_id: user1.id, sender_id: user2.id) + conversation = Private::Conversation.between_users(user1.id, user2.id) + expect(conversation.count).to eq 1 + end + end end From 41f20fcf352744540be4c77f51bda7ba1b193060 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Sun, 12 Dec 2021 21:06:41 -0500 Subject: [PATCH 10/12] Add ctrler action, js partials, feature spec. --- .../private/conversations_controller.rb | 18 ++++++++ .../show/contact_user/message_form/_fail.js | 1 + .../contact_user/message_form/_success.js.erb | 4 ++ config/routes.rb | 9 ++++ spec/features/posts/contact_user_spec.rb | 42 +++++++++++++++++++ 5 files changed, 74 insertions(+) create mode 100644 app/views/posts/show/contact_user/message_form/_fail.js create mode 100644 app/views/posts/show/contact_user/message_form/_success.js.erb create mode 100644 spec/features/posts/contact_user_spec.rb diff --git a/app/controllers/private/conversations_controller.rb b/app/controllers/private/conversations_controller.rb index 9fd8078..dce14d2 100644 --- a/app/controllers/private/conversations_controller.rb +++ b/app/controllers/private/conversations_controller.rb @@ -1,2 +1,20 @@ class Private::ConversationsController < ApplicationController + def create + recipient_id = Post.find(params[:post_id]).user.id + conversation = Private::Conversation.new(sender_id: current_user.id, + recipient_id: recipient_id) + if conversation.save + Private::Message.create(user_id: recipient_id, + conversation_id: conversation.id, + body: params[:message_body]) + + respond_to do |format| + format.js {render partial: 'posts/show/contact_user/message_form/success'} + end + else + respond_to do |format| + format.js {render partial: 'posts/show/contact_user/message_form/fail'} + end + end + end end diff --git a/app/views/posts/show/contact_user/message_form/_fail.js b/app/views/posts/show/contact_user/message_form/_fail.js new file mode 100644 index 0000000..25a1df2 --- /dev/null +++ b/app/views/posts/show/contact_user/message_form/_fail.js @@ -0,0 +1 @@ +$('.contact-user').replaceWith('
Message has not been sent
'); \ No newline at end of file diff --git a/app/views/posts/show/contact_user/message_form/_success.js.erb b/app/views/posts/show/contact_user/message_form/_success.js.erb new file mode 100644 index 0000000..d4e007b --- /dev/null +++ b/app/views/posts/show/contact_user/message_form/_success.js.erb @@ -0,0 +1,4 @@ +$('.contact-user').replaceWith('\ +
\ +
Message has been sent
\ +
'); diff --git a/config/routes.rb b/config/routes.rb index fb13bc9..8965c43 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -15,4 +15,13 @@ get 'team' end end + + namespace :private do + resources :conversations, only: [:create] do + member do + post :close + end + end + resources :messages, only: [:index, :create] + end end diff --git a/spec/features/posts/contact_user_spec.rb b/spec/features/posts/contact_user_spec.rb new file mode 100644 index 0000000..a053414 --- /dev/null +++ b/spec/features/posts/contact_user_spec.rb @@ -0,0 +1,42 @@ +require "rails_helper" + +RSpec.feature "Contact user", :type => :feature do + let(:user) { create(:user) } + let(:category) { create(:category, name: 'Arts', branch: 'hobby') } + let(:post) { create(:post, category_id: category.id) } + + context 'logged in user' do + before(:each) do + sign_in user + end + + scenario "successfully sends a message to a post's author", js: true do + visit post_path(post) + expect(page).to have_selector('.contact-user form') + + fill_in('message_body', with: 'a'*20) + find('form .send-message-to-user').trigger('click') + + expect(page).not_to have_selector('.contact-user form') + expect(page).to have_selector('.contacted-user', + text: 'Message has been sent') + end + + scenario "sees an already contacted mesage", js: true do + create(:private_conversation_with_messages, + recipient_id: post.user.id, + sender_id: user.id) + + visit post_path(post) + expect(page).to have_selector('.contact-user .contacted-user', + text: 'You are already in touch with this user') + end + end + + context "user is not logged in" do + scenario "sees a login is required to contact user" do + visit post_path(post) + expect(page).to have_selector('div', text: 'To contact the user you have to Login') + end + end +end \ No newline at end of file From 4c96aff7efd67ed2f5fcc09df4113d676ec84987 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Fri, 24 Dec 2021 21:25:06 -0500 Subject: [PATCH 11/12] Add styles to contact user form. --- .../partials/posts/branch_page.scss | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/app/assets/stylesheets/partials/posts/branch_page.scss b/app/assets/stylesheets/partials/posts/branch_page.scss index 76f6bc7..4317f0b 100644 --- a/app/assets/stylesheets/partials/posts/branch_page.scss +++ b/app/assets/stylesheets/partials/posts/branch_page.scss @@ -95,6 +95,30 @@ .infinite-scroll { display: none; } + + .send-message-to-user { + background-color: $navbarColor; + padding: 10px; + color: white; + border-radius: 10px; + margin-top: 10px; + &:hover { + background-color: black; + color: white; + } + } + + .contact-user { + text-align: center; + } + + .contacted-user { + display: inline-block; + border-radius: 10px; + padding: 10px; + background-color: $navbarColor; + color: white; + } #branch-main-content { background: white; From 312c907db56cfa43d79786a81b2266bd080e2093 Mon Sep 17 00:00:00 2001 From: Devan Kestel Date: Fri, 24 Dec 2021 23:44:41 -0500 Subject: [PATCH 12/12] Add infra for private messages window and specs. --- .../private/conversations_controller.rb | 19 +++++++++++++++--- app/helpers/private/conversations_helper.rb | 11 ++++++++++ app/models/private/conversation.rb | 4 ++++ .../conversations/_conversation.html.erb | 20 +++++++++++++++++++ .../conversation/_heading.html.erb | 11 ++++++++++ .../conversation/_messages_list.html.erb | 9 +++++++++ .../_link_to_previous_messages.html.erb | 6 ++++++ .../private/conversations_helper_spec.rb | 16 ++++++++++++++- spec/models/private/conversation_spec.rb | 11 ++++++++++ 9 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 app/views/private/conversations/_conversation.html.erb create mode 100644 app/views/private/conversations/conversation/_heading.html.erb create mode 100644 app/views/private/conversations/conversation/_messages_list.html.erb create mode 100644 app/views/private/conversations/conversation/messages_list/_link_to_previous_messages.html.erb diff --git a/app/controllers/private/conversations_controller.rb b/app/controllers/private/conversations_controller.rb index dce14d2..920570c 100644 --- a/app/controllers/private/conversations_controller.rb +++ b/app/controllers/private/conversations_controller.rb @@ -1,13 +1,15 @@ class Private::ConversationsController < ApplicationController def create recipient_id = Post.find(params[:post_id]).user.id - conversation = Private::Conversation.new(sender_id: current_user.id, + @conversation = Private::Conversation.new(sender_id: current_user.id, recipient_id: recipient_id) - if conversation.save + if @conversation.save Private::Message.create(user_id: recipient_id, - conversation_id: conversation.id, + conversation_id: @conversation.id, body: params[:message_body]) + add_to_conversations unless already_added? + respond_to do |format| format.js {render partial: 'posts/show/contact_user/message_form/success'} end @@ -17,4 +19,15 @@ def create end end end + + private + + def add_to_conversations + session[:private_conversations] ||= [] + session[:private_conversations] << @conversation.id + end + + def already_added? + session[:private_conversations].include?(@conversation.id) + end end diff --git a/app/helpers/private/conversations_helper.rb b/app/helpers/private/conversations_helper.rb index 38df4b1..88e6f5f 100644 --- a/app/helpers/private/conversations_helper.rb +++ b/app/helpers/private/conversations_helper.rb @@ -1,2 +1,13 @@ module Private::ConversationsHelper + def private_conv_recipient(conversation) + conversation.opposed_user(current_user) + end + + def load_private_messages(conversation) + if conversation.messages.count > 0 + 'private/conversations/conversation/messages_list/link_to_previous_messages' + else + 'shared/empty_partial' + end + end end diff --git a/app/models/private/conversation.rb b/app/models/private/conversation.rb index a1968bf..e3122e1 100644 --- a/app/models/private/conversation.rb +++ b/app/models/private/conversation.rb @@ -12,4 +12,8 @@ class Private::Conversation < ApplicationRecord where(sender_id: user2_id, recipient_id: user1_id) ) end + + def opposed_user(user) + user == recipient ? sender : recipient + end end diff --git a/app/views/private/conversations/_conversation.html.erb b/app/views/private/conversations/_conversation.html.erb new file mode 100644 index 0000000..5436324 --- /dev/null +++ b/app/views/private/conversations/_conversation.html.erb @@ -0,0 +1,20 @@ +<% @recipient = private_conv_recipient(conversation) %> +<% @is_messenger = false %> +
  • +
    + <%= render 'private/conversations/conversation/heading', + conversation: conversation %> + + +
    + <%= render 'private/conversations/conversation/messages_list', + conversation: conversation %> + <%= render 'private/conversations/conversation/new_message_form', + conversation: conversation, + user: user %> +
    +
    +
  • \ No newline at end of file diff --git a/app/views/private/conversations/conversation/_heading.html.erb b/app/views/private/conversations/conversation/_heading.html.erb new file mode 100644 index 0000000..6499303 --- /dev/null +++ b/app/views/private/conversations/conversation/_heading.html.erb @@ -0,0 +1,11 @@ +
    + <%= @recipient.name %> +
    + + +<%= link_to "X", + close_private_conversation_path(conversation), + class: 'close-conversation', + title: 'Close', + remote: true, + method: :post %> \ No newline at end of file diff --git a/app/views/private/conversations/conversation/_messages_list.html.erb b/app/views/private/conversations/conversation/_messages_list.html.erb new file mode 100644 index 0000000..3cc3c4e --- /dev/null +++ b/app/views/private/conversations/conversation/_messages_list.html.erb @@ -0,0 +1,9 @@ +
    + <%= render load_private_messages(conversation), conversation: conversation %> +
    + +
    + +
      +
    +
    \ No newline at end of file diff --git a/app/views/private/conversations/conversation/messages_list/_link_to_previous_messages.html.erb b/app/views/private/conversations/conversation/messages_list/_link_to_previous_messages.html.erb new file mode 100644 index 0000000..22d7af5 --- /dev/null +++ b/app/views/private/conversations/conversation/messages_list/_link_to_previous_messages.html.erb @@ -0,0 +1,6 @@ +<%= link_to "Load messages", + private_messages_path(:conversation_id => conversation.id, + :messages_to_display_offset => @messages_to_display_offset, + :is_messenger => @is_messenger), + class: 'load-more-messages', + remote: true %> \ No newline at end of file diff --git a/spec/helpers/private/conversations_helper_spec.rb b/spec/helpers/private/conversations_helper_spec.rb index abd7688..5cb5e04 100644 --- a/spec/helpers/private/conversations_helper_spec.rb +++ b/spec/helpers/private/conversations_helper_spec.rb @@ -11,5 +11,19 @@ # end # end RSpec.describe Private::ConversationsHelper, type: :helper do - pending "add some examples to (or delete) #{__FILE__}" + context "#load_private_messages" do + let(:conversation) { create(:private_conversation) } + + it "returns load_messages partial path" do + create(:private_message, conversation_id: conversation.id) + expect(helper.load_private_messages(conversation)).to eq( + 'private/conversations/conversation/messages_list/link_to_previous_messages' + ) + end + it "returns empty partial when there are no private messages" do + expect(helper.load_private_messages(conversation)).to eq( + 'shared/empty_partial' + ) + end + end end diff --git a/spec/models/private/conversation_spec.rb b/spec/models/private/conversation_spec.rb index b0af10d..db0657f 100644 --- a/spec/models/private/conversation_spec.rb +++ b/spec/models/private/conversation_spec.rb @@ -10,4 +10,15 @@ expect(conversation.count).to eq 1 end end + context "Methods" do + it "gets an opposed user of the conversation" do + user1 = create(:user) + user2 = create(:user) + conversation = create(:private_conversation, + recipient_id: user1.id, + sender_id: user2.id) + opposed_user = conversation.opposed_user(user1) + expect(opposed_user).to eq user2 + end + end end