mirror of
https://github.com/Growstuff/growstuff.git
synced 2026-04-04 15:14:09 -04:00
Add comments to photos (#4130)
* Add comments to photos Extend the photo show page to support comments by logged in users. - Make the Comment model polymorphic. - Update the Photo and Post models to have comments. - Update the comments controller to handle the polymorphic association. - Update the photo show page to display comments and a comment form. - Create a reusable comments partial. * Add migration * Fix tests * Fix tests * Slightly fix tests * Fix variables * Add field * Refactor slightly * Refactor slightly * Refactor slightly * Refactor * Photos respond to this as well * Refactor to polymorphic_url * Rename * Wrong relationship * Refactor and fix tests * Fix relationships * Fix rendering * Fix tests * Fix model tests * Fix test * Fix test * Fix test * Fix test * Fix controller spec * Fix view tests --------- Co-authored-by: google-labs-jules[bot] <161369871+google-labs-jules[bot]@users.noreply.github.com> Co-authored-by: Daniel O'Connor <daniel.oconnor@gmail.com>
This commit is contained in:
committed by
GitHub
parent
79a54351e3
commit
8564ec7a7c
@@ -13,43 +13,55 @@ class CommentsController < ApplicationController
|
||||
end
|
||||
|
||||
def new
|
||||
@commentable = find_commentable
|
||||
@comment = Comment.new
|
||||
@post = Post.find_by(id: params[:post_id])
|
||||
|
||||
if @post
|
||||
@comments = @post.comments
|
||||
if @commentable
|
||||
@comments = @commentable.comments
|
||||
respond_with(@comments)
|
||||
else
|
||||
redirect_to(request.referer || root_url,
|
||||
alert: "Can't post a comment on a non-existent post")
|
||||
alert: "Can't post a comment on a non-existent commentable")
|
||||
end
|
||||
end
|
||||
|
||||
def edit
|
||||
@comments = @comment.post.comments
|
||||
# TODO: Why does this need a collection of comments?
|
||||
@comments = @comment.commentable.comments
|
||||
@commentable = @comment.commentable
|
||||
end
|
||||
|
||||
def create
|
||||
@comment = Comment.new(comment_params)
|
||||
@commentable = @comment.commentable
|
||||
@comment.author = current_member
|
||||
@comment.save
|
||||
respond_with @comment, location: @comment.post
|
||||
respond_with @comment, location: @commentable
|
||||
end
|
||||
|
||||
def update
|
||||
@comment.update(body: comment_params['body'])
|
||||
respond_with @comment, location: @comment.post
|
||||
respond_with @comment, location: @comment.commentable
|
||||
end
|
||||
|
||||
def destroy
|
||||
@post = @comment.post
|
||||
@commentable = @comment.commentable
|
||||
@comment.destroy
|
||||
respond_with(@post)
|
||||
respond_with(@commentable)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_commentable
|
||||
return unless params[:comment]
|
||||
|
||||
if params[:comment][:commentable_type] == 'Photo'
|
||||
Photo.find(params[:comment][:commentable_id])
|
||||
elsif params[:comment][:commentable_type] == 'Post'
|
||||
Post.find(params[:comment][:commentable_id])
|
||||
end
|
||||
end
|
||||
|
||||
def comment_params
|
||||
params.require(:comment).permit(:body, :post_id)
|
||||
params.require(:comment).permit(:body, :commentable_id, :commentable_type)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -21,6 +21,7 @@ class PhotosController < ApplicationController
|
||||
|
||||
def show
|
||||
@crops = Crop.distinct.joins(:photo_associations).where(photo_associations: { photo: @photo })
|
||||
@comment = Comment.new(commentable: @photo)
|
||||
respond_with(@photo)
|
||||
end
|
||||
|
||||
|
||||
@@ -2,26 +2,27 @@
|
||||
|
||||
class Comment < ApplicationRecord
|
||||
belongs_to :author, class_name: 'Member', inverse_of: :comments
|
||||
belongs_to :post, counter_cache: true
|
||||
belongs_to :commentable, polymorphic: true, counter_cache: true
|
||||
# validates :body, presence: true
|
||||
|
||||
scope :post_order, -> { order(created_at: :asc) } # for display on post page
|
||||
|
||||
after_create do
|
||||
recipient = post.author.id
|
||||
recipient = commentable.author.id
|
||||
sender = author.id
|
||||
# don't send notifications to yourself
|
||||
if recipient != sender
|
||||
Notification.create(
|
||||
recipient_id: recipient,
|
||||
sender_id: sender,
|
||||
subject: "#{author} commented on #{post.subject}",
|
||||
subject: "#{author} commented on #{commentable.subject}",
|
||||
body:,
|
||||
post_id: post.id
|
||||
notifiable: commentable
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
def to_s
|
||||
"#{author.login_name} commented on #{post.subject}"
|
||||
"#{author.login_name} commented on #{commentable.subject}"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -10,7 +10,8 @@ class Follow < ApplicationRecord
|
||||
recipient_id: followed_id,
|
||||
sender_id: follower_id,
|
||||
subject: "#{follower.login_name} is now following you",
|
||||
body: "#{follower.login_name} just followed you on #{ENV.fetch('GROWSTUFF_SITE_NAME', nil)}. "
|
||||
body: "#{follower.login_name} just followed you on #{ENV.fetch('GROWSTUFF_SITE_NAME', nil)}. ",
|
||||
notifiable: self
|
||||
)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
class Notification < ApplicationRecord
|
||||
belongs_to :sender, class_name: 'Member', inverse_of: :sent_notifications
|
||||
belongs_to :recipient, class_name: 'Member', inverse_of: :notifications
|
||||
belongs_to :post, optional: true
|
||||
belongs_to :notifiable, polymorphic: true
|
||||
|
||||
validates :subject, length: { maximum: 255 }
|
||||
|
||||
|
||||
@@ -8,6 +8,7 @@ class Photo < ApplicationRecord
|
||||
PHOTO_CAPABLE = %w(Garden Planting Harvest Seed Post Crop).freeze
|
||||
|
||||
has_many :photo_associations, dependent: :delete_all, inverse_of: :photo
|
||||
has_many :comments, as: :commentable, dependent: :destroy
|
||||
|
||||
# This doesn't work, ActiveRecord tries to use the polymoriphic photographable
|
||||
# relationship instead.
|
||||
@@ -83,6 +84,14 @@ class Photo < ApplicationRecord
|
||||
"#{title} by #{owner.login_name}"
|
||||
end
|
||||
|
||||
def subject
|
||||
title
|
||||
end
|
||||
|
||||
def author
|
||||
owner
|
||||
end
|
||||
|
||||
def flickr_photo_id
|
||||
source_id if source == 'flickr'
|
||||
end
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
class Post < ApplicationRecord
|
||||
extend FriendlyId
|
||||
include Likeable
|
||||
|
||||
friendly_id :author_date_subject, use: %i(slugged finders)
|
||||
include PhotoCapable
|
||||
|
||||
@@ -10,9 +11,10 @@ class Post < ApplicationRecord
|
||||
# Relationships
|
||||
belongs_to :author, class_name: 'Member', inverse_of: :posts
|
||||
belongs_to :forum, optional: true
|
||||
has_many :comments, dependent: :destroy
|
||||
has_many :comments, as: :commentable, dependent: :destroy
|
||||
has_many :crop_posts, dependent: :delete_all
|
||||
has_many :crops, through: :crop_posts
|
||||
has_many :notifications, as: :notifiable, dependent: :destroy
|
||||
|
||||
after_create :send_notification
|
||||
#
|
||||
@@ -95,6 +97,7 @@ class Post < ApplicationRecord
|
||||
Notification.create(
|
||||
recipient_id:,
|
||||
sender_id: sender,
|
||||
notifiable: self,
|
||||
subject: "#{author} mentioned you in their post #{subject}",
|
||||
body:
|
||||
)
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
%a{ name: "comments" }
|
||||
- if post.comments
|
||||
- if commentable.comments
|
||||
%hr/
|
||||
%h2
|
||||
= comment_icon
|
||||
= localize_plural(post.comments, Comment)
|
||||
- post.comments.post_order.each do |comment|
|
||||
= localize_plural(commentable.comments, Comment)
|
||||
- commentable.comments.post_order.each do |comment|
|
||||
= render "comments/single", comment: comment
|
||||
|
||||
- else
|
||||
%h2 There are no comments yet
|
||||
|
||||
@@ -1 +1 @@
|
||||
#{link_to 'commented', event_model} on #{link_to event_model.post, event_model.post}
|
||||
#{link_to 'commented', event_model} on #{link_to event_model.commentable, event_model.commentable}
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
- @comment ||= Comment.new(commentable: @commentable)
|
||||
.card.col-md-8.col-lg-7.mx-auto.float-none.white.z-depth-1.py-2.px-2
|
||||
.card-body
|
||||
- if content_for? :title
|
||||
@@ -14,13 +15,13 @@
|
||||
%li= msg
|
||||
|
||||
.md-form
|
||||
= f.text_area :body, rows: 6, class: 'form-control md-textarea', autofocus: 'autofocus'
|
||||
= f.text_area :body, rows: 6, class: 'form-control md-textarea', autofocus: 'autofocus', required: true, pattern: '\w+'
|
||||
= f.label :body, "Your comment:"
|
||||
|
||||
%span.help-block
|
||||
= render partial: "shared/markdown_help"
|
||||
.actions.text-right
|
||||
= f.submit 'Post comment', class: 'btn btn-primary'
|
||||
- if defined?(@post)
|
||||
.field
|
||||
= f.hidden_field :post_id, value: @post.id
|
||||
.field
|
||||
= f.hidden_field :commentable_id, value: @commentable.id
|
||||
= f.hidden_field :commentable_type, value: @commentable.class.name
|
||||
|
||||
@@ -2,6 +2,6 @@
|
||||
|
||||
%p
|
||||
Editing comment on
|
||||
= link_to @comment.post.subject, @comment.post
|
||||
= link_to @comment.commentable.subject, @comment.commentable
|
||||
|
||||
= render 'form'
|
||||
= render 'form', locals: { comment: @comment, commentable: @comment.commentable }
|
||||
|
||||
@@ -5,17 +5,18 @@
|
||||
%link= comments_url
|
||||
- @comments.each do |comment|
|
||||
%item
|
||||
%title Comment by #{comment.author.login_name} on #{comment.post.subject}
|
||||
%title Comment by #{comment.author.login_name} on #{comment.commentable.subject}
|
||||
%description
|
||||
:escaped_markdown
|
||||
<p>
|
||||
Comment on
|
||||
#{ link_to comment.post.subject, post_url(comment.post) }
|
||||
#{ link_to comment.commentable.subject, polymorphic_url(comment.commentable) }
|
||||
</p>
|
||||
|
||||
:escaped_markdown
|
||||
#{ strip_tags markdownify(comment.body) }
|
||||
|
||||
%pubdate= comment.created_at.to_fs(:rfc822)
|
||||
%link= post_url(comment.post)
|
||||
%link= polymorphic_url(comment.commentable)
|
||||
%guid= comment_url(comment)
|
||||
|
||||
|
||||
@@ -1,11 +1,17 @@
|
||||
= content_for :title, "New comment"
|
||||
- if @commentable.is_a?(Post)
|
||||
%section.blog-post
|
||||
.card.post{ id: "post-#{@commentable.id}" }
|
||||
.card-header
|
||||
%h2.display-3= @commentable.subject
|
||||
.card-body= render "posts/single", post: @commentable || @comment.commentable, subject: true
|
||||
- elsif @commentable.is_a?(Photo)
|
||||
%section.blog-post
|
||||
.card.photo{ id: "photo-#{@commentable.id}" }
|
||||
.card-header
|
||||
%h2.display-3= @commentable.subject
|
||||
.card-body= render "photos/card", photo: @commentable || @comment.commentable, subject: true
|
||||
|
||||
%section.blog-post
|
||||
.card.post{ id: "post-#{@post.id}" }
|
||||
.card-header
|
||||
%h2.display-3= @post.subject
|
||||
.card-body= render "posts/single", post: @post || @comment.post, subject: true
|
||||
= render partial: "comments/comments", locals: { commentable: @commentable || @comment.commentable }
|
||||
|
||||
= render partial: "posts/comments", locals: { post: @post || @comment.post }
|
||||
|
||||
= render 'form'
|
||||
= render 'form', locals: { comment: @comment, commentable: @commentable || @comment.commentable }
|
||||
|
||||
@@ -46,4 +46,12 @@
|
||||
- else
|
||||
= @photo.license_name
|
||||
|
||||
= render "associations", photo: @photo
|
||||
= render "associations", photo: @photo
|
||||
.row
|
||||
- if can? :create, Comment
|
||||
= link_to new_comment_path(comment: { commentable_type: 'Photo', commentable_id: @photo.id }), class: 'btn' do
|
||||
= icon 'fas', 'comment'
|
||||
Comment
|
||||
.row
|
||||
.col-md-9
|
||||
= render 'comments/comments', commentable: @photo
|
||||
@@ -1,3 +1,4 @@
|
||||
- @post ||= post if defined?(post)
|
||||
%p
|
||||
Posted by
|
||||
- if @post.author
|
||||
@@ -13,7 +14,7 @@
|
||||
and edited at
|
||||
= @post.updated_at.to_fs(:default)
|
||||
|
||||
= link_to "Permalink", post
|
||||
= link_to "Permalink", @post
|
||||
|
||||
:markdown
|
||||
#{ strip_tags markdownify(@post.body) }
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
- content_for :buttonbar do
|
||||
- if @post.comments.count > 10 && can?(:create, Comment)
|
||||
= link_to 'Comment', new_comment_path(post_id: @post.id), class: 'btn'
|
||||
= link_to 'Comment', new_comment_path(comment: { commentable_type: 'Post', commentable_id: @post.id }), class: 'btn'
|
||||
|
||||
- content_for :breadcrumbs do
|
||||
%li.breadcrumb-item= link_to @post.author, @post.author
|
||||
@@ -48,12 +48,12 @@
|
||||
= render 'likes/likes', object: @post
|
||||
.float-right
|
||||
- if can? :create, Comment
|
||||
= link_to new_comment_path(post_id: @post.id), class: 'btn' do
|
||||
= link_to new_comment_path(comment: { commentable_type: 'Post', commentable_id: @post.id }), class: 'btn' do
|
||||
= icon 'fas', 'comment'
|
||||
Comment
|
||||
|
||||
%section.comments
|
||||
= render "comments", post: @post
|
||||
= render "comments/comments", commentable: @post
|
||||
|
||||
.col-md-4.col-12
|
||||
= render @post.author
|
||||
|
||||
14
db/migrate/20250810120000_make_notifications_polymorphic.rb
Normal file
14
db/migrate/20250810120000_make_notifications_polymorphic.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class MakeNotificationsPolymorphic < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
add_column :notifications, :notifiable_type, :string
|
||||
rename_column :notifications, :post_id, :notifiable_id
|
||||
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
ActiveRecord::Base.connection.execute("UPDATE notifications SET notifiable_type = 'Post' WHERE notifiable_type IS NULL")
|
||||
end
|
||||
end
|
||||
|
||||
add_index :notifications, %i(notifiable_type notifiable_id)
|
||||
end
|
||||
end
|
||||
14
db/migrate/20250824081313_change_comments_polymorphic.rb
Normal file
14
db/migrate/20250824081313_change_comments_polymorphic.rb
Normal file
@@ -0,0 +1,14 @@
|
||||
class ChangeCommentsPolymorphic < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
add_column :comments, :commentable_type, :string
|
||||
rename_column :comments, :post_id, :commentable_id
|
||||
|
||||
add_index :comments, %i(commentable_type commentable_id)
|
||||
|
||||
reversible do |dir|
|
||||
dir.up do
|
||||
ActiveRecord::Base.connection.execute("UPDATE comments SET commentable_type = 'Post' WHERE commentable_type IS NULL")
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
24
db/migrate/20250824085224_add_photos_comment_count.rb
Normal file
24
db/migrate/20250824085224_add_photos_comment_count.rb
Normal file
@@ -0,0 +1,24 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class AddPhotosCommentCount < ActiveRecord::Migration[7.2]
|
||||
def change
|
||||
change_table :photos do |t|
|
||||
t.integer :comments_count, default: 0
|
||||
end
|
||||
reversible do |dir|
|
||||
dir.up { set_counter_value }
|
||||
end
|
||||
end
|
||||
|
||||
def set_counter_value
|
||||
execute <<-SQL.squish
|
||||
UPDATE photos
|
||||
SET comments_count = (
|
||||
SELECT count(1)
|
||||
FROM comments
|
||||
WHERE comments.commentable_id = comments.id
|
||||
AND comments.commentable_type = 'Photo'
|
||||
)
|
||||
SQL
|
||||
end
|
||||
end
|
||||
10
db/schema.rb
10
db/schema.rb
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema[7.2].define(version: 2024_09_29_041435) do
|
||||
ActiveRecord::Schema[7.2].define(version: 2025_08_24_085224) do
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "plpgsql"
|
||||
|
||||
@@ -202,11 +202,12 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_29_041435) do
|
||||
end
|
||||
|
||||
create_table "comments", id: :serial, force: :cascade do |t|
|
||||
t.integer "post_id", null: false
|
||||
t.integer "commentable_id", null: false
|
||||
t.integer "author_id", null: false
|
||||
t.text "body", null: false
|
||||
t.datetime "created_at", precision: nil
|
||||
t.datetime "updated_at", precision: nil
|
||||
t.string "commentable_type"
|
||||
end
|
||||
|
||||
create_table "crop_companions", force: :cascade do |t|
|
||||
@@ -470,9 +471,11 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_29_041435) do
|
||||
t.string "subject"
|
||||
t.text "body"
|
||||
t.boolean "read", default: false
|
||||
t.integer "post_id"
|
||||
t.integer "notifiable_id"
|
||||
t.datetime "created_at", precision: nil
|
||||
t.datetime "updated_at", precision: nil
|
||||
t.string "notifiable_type"
|
||||
t.index ["notifiable_type", "notifiable_id"], name: "index_notifications_on_notifiable_type_and_notifiable_id"
|
||||
end
|
||||
|
||||
create_table "orders_products", id: false, force: :cascade do |t|
|
||||
@@ -505,6 +508,7 @@ ActiveRecord::Schema[7.2].define(version: 2024_09_29_041435) do
|
||||
t.datetime "date_taken", precision: nil
|
||||
t.integer "likes_count", default: 0
|
||||
t.string "source"
|
||||
t.integer "comments_count", default: 0
|
||||
t.index ["fullsize_url"], name: "index_photos_on_fullsize_url", unique: true
|
||||
t.index ["thumbnail_url"], name: "index_photos_on_thumbnail_url", unique: true
|
||||
end
|
||||
|
||||
@@ -35,12 +35,16 @@ describe CommentsController do
|
||||
let(:post) { FactoryBot.create(:post) }
|
||||
|
||||
describe "with valid params" do
|
||||
before { get :new, params: { post_id: post.id } }
|
||||
before do
|
||||
get :new, params: {
|
||||
comment: { commentable_id: post.id, commentable_type: "Post" }
|
||||
}
|
||||
end
|
||||
|
||||
let(:old_comment) { FactoryBot.create(:comment, post:) }
|
||||
let(:old_comment) { FactoryBot.create(:comment, commentable: post) }
|
||||
|
||||
it "picks up post from params" do
|
||||
expect(assigns(:post)).to eq(post)
|
||||
expect(assigns(:commentable)).to eq(post)
|
||||
end
|
||||
|
||||
it "assigns the old comments as @comments" do
|
||||
@@ -60,8 +64,8 @@ describe CommentsController do
|
||||
before { get :edit, params: { id: comment.to_param } }
|
||||
|
||||
describe "my comment" do
|
||||
let!(:comment) { FactoryBot.create(:comment, author: member, post:) }
|
||||
let!(:old_comment) { FactoryBot.create(:comment, post:, created_at: Time.zone.yesterday) }
|
||||
let!(:comment) { FactoryBot.create(:comment, author: member, commentable: post) }
|
||||
let!(:old_comment) { FactoryBot.create(:comment, commentable: post, created_at: Time.zone.yesterday) }
|
||||
|
||||
it "assigns previous comments as @comments" do
|
||||
expect(assigns(:comments)).to eq([comment, old_comment])
|
||||
@@ -69,7 +73,7 @@ describe CommentsController do
|
||||
end
|
||||
|
||||
describe "not my comment" do
|
||||
let(:comment) { FactoryBot.create(:comment, post:) }
|
||||
let(:comment) { FactoryBot.create(:comment, commentable: post) }
|
||||
|
||||
it { expect(response).not_to be_successful }
|
||||
end
|
||||
@@ -82,7 +86,7 @@ describe CommentsController do
|
||||
let(:comment) { FactoryBot.create(:comment, author: member) }
|
||||
|
||||
it "redirects to the comment's post" do
|
||||
expect(response).to redirect_to(comment.post)
|
||||
expect(response).to redirect_to(comment.commentable)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -95,12 +99,12 @@ describe CommentsController do
|
||||
describe "attempting to change post_id" do
|
||||
let(:post) { FactoryBot.create(:post, subject: 'our post') }
|
||||
let(:other_post) { FactoryBot.create(:post, subject: 'the other post') }
|
||||
let(:valid_attributes) { { post_id: other_post.id, body: "kōrero" } }
|
||||
let(:comment) { FactoryBot.create(:comment, author: member, post:) }
|
||||
let(:valid_attributes) { { commentable_type: "Post", commentable_id: other_post.id, body: "kōrero" } }
|
||||
let(:comment) { FactoryBot.create(:comment, author: member, commentable: post) }
|
||||
|
||||
it "does not change post_id" do
|
||||
comment.reload
|
||||
expect(comment.post_id).to eq(post.id)
|
||||
expect(comment.commentable_id).to eq(post.id)
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -112,7 +116,7 @@ describe CommentsController do
|
||||
let(:comment) { FactoryBot.create(:comment, author: member) }
|
||||
|
||||
it "redirects to the post the comment was on" do
|
||||
expect(response).to redirect_to(comment.post)
|
||||
expect(response).to redirect_to(comment.commentable)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
FactoryBot.define do
|
||||
factory :comment do
|
||||
post
|
||||
association :commentable, factory: :post
|
||||
author
|
||||
sequence(:body) { |n| "OMG LOL #{n}" }
|
||||
# because our commenters are more polite than YouTube's
|
||||
|
||||
@@ -10,7 +10,7 @@ FactoryBot.define do
|
||||
|
||||
body { "MyText" }
|
||||
read { false }
|
||||
post
|
||||
association :notifiable, factory: :post
|
||||
|
||||
factory :no_email_notification do
|
||||
recipient { FactoryBot.create(:no_email_notifications_member) }
|
||||
|
||||
@@ -7,9 +7,9 @@ describe 'Commenting on a post' do
|
||||
let(:member) { create(:member) }
|
||||
let(:post) { create(:post, author: member) }
|
||||
|
||||
before { visit new_comment_path post_id: post.id }
|
||||
before { visit new_comment_path(comment: { commentable_type: "Post", commentable_id: post.id }) }
|
||||
|
||||
include_examples 'is accessible'
|
||||
it_behaves_like 'is accessible'
|
||||
|
||||
it "creating a comment" do
|
||||
fill_in "comment_body", with: "This is a sample test for comment"
|
||||
@@ -20,13 +20,13 @@ describe 'Commenting on a post' do
|
||||
end
|
||||
|
||||
context "editing a comment" do
|
||||
let(:existing_comment) { create(:comment, post:, author: member) }
|
||||
let(:existing_comment) { create(:comment, commentable: post, author: member) }
|
||||
|
||||
before do
|
||||
visit edit_comment_path existing_comment
|
||||
end
|
||||
|
||||
include_examples 'is accessible'
|
||||
it_behaves_like 'is accessible'
|
||||
|
||||
it "saving edit" do
|
||||
fill_in "comment_body", with: "Testing edit for comment"
|
||||
|
||||
@@ -155,7 +155,7 @@ describe "member profile", :js do
|
||||
|
||||
context 'member has comments' do
|
||||
let(:post) { FactoryBot.create(:post) }
|
||||
let!(:comment) { FactoryBot.create(:comment, post:, author: member) }
|
||||
let!(:comment) { FactoryBot.create(:comment, commentable: post, author: member) }
|
||||
|
||||
before { visit member_path(member) }
|
||||
|
||||
@@ -221,8 +221,8 @@ describe "member profile", :js do
|
||||
end
|
||||
|
||||
context "not signed in" do
|
||||
include_examples 'member details'
|
||||
include_examples 'member activity'
|
||||
it_behaves_like 'member details'
|
||||
it_behaves_like 'member activity'
|
||||
|
||||
it "no bio" do
|
||||
member.update! bio: nil
|
||||
@@ -233,8 +233,8 @@ describe "member profile", :js do
|
||||
|
||||
context "signed in member" do
|
||||
include_context 'signed in member'
|
||||
include_examples 'member details'
|
||||
include_examples 'member activity'
|
||||
it_behaves_like 'member details'
|
||||
it_behaves_like 'member activity'
|
||||
|
||||
context "your own profile page" do
|
||||
before { visit member_path(member) }
|
||||
|
||||
@@ -188,8 +188,8 @@ rest of the garden.
|
||||
|
||||
describe 'posts' do
|
||||
it 'loads posts#show' do
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
visit post_path(post)
|
||||
page.percy_snapshot(page, name: "#{prefix}/posts#show")
|
||||
end
|
||||
@@ -199,7 +199,7 @@ rest of the garden.
|
||||
FactoryBot.create_list(:post, 12, author: member)
|
||||
end
|
||||
Post.all.order(id: :desc).limit(4) do |post|
|
||||
FactoryBot.create_list(:comment, rand(1..5), post:)
|
||||
FactoryBot.create_list(:comment, rand(1..5), commentable: post)
|
||||
end
|
||||
visit posts_path
|
||||
page.percy_snapshot(page, name: "#{prefix}/posts#index")
|
||||
@@ -218,7 +218,7 @@ rest of the garden.
|
||||
context "when signed out" do
|
||||
let(:prefix) { 'signed-out' }
|
||||
|
||||
include_examples 'visit pages'
|
||||
it_behaves_like 'visit pages'
|
||||
|
||||
it 'loads sign in page' do
|
||||
visit crops_path # some random page
|
||||
@@ -247,7 +247,7 @@ rest of the garden.
|
||||
let(:prefix) { 'signed-in' }
|
||||
|
||||
include_context 'signed in member'
|
||||
include_examples 'visit pages'
|
||||
it_behaves_like 'visit pages'
|
||||
|
||||
it 'load my plantings#show' do
|
||||
planting = FactoryBot.create(:planting, crop: tomato, owner: member, garden: member.gardens.first)
|
||||
@@ -329,7 +329,7 @@ rest of the garden.
|
||||
end
|
||||
|
||||
it 'comments#new' do
|
||||
visit new_comment_path(post_id: post.id)
|
||||
visit new_comment_path(comment: { commentable_type: Post, commentable_id: post.id })
|
||||
page.percy_snapshot(page, name: "comments#new")
|
||||
end
|
||||
end
|
||||
|
||||
@@ -41,7 +41,7 @@ describe ApplicationHelper do
|
||||
|
||||
context 'with a populated collection' do
|
||||
context 'with one element' do
|
||||
before { create(:comment, post:) }
|
||||
before { create(:comment, commentable: post) }
|
||||
|
||||
it 'returns a string with the quantity and the plural of the model' do
|
||||
expect(localize_plural(post.comments, Comment)).to eq '1 comment'
|
||||
@@ -49,7 +49,7 @@ describe ApplicationHelper do
|
||||
end
|
||||
|
||||
context 'with more than one element' do
|
||||
before { create_list(:comment, 2, post:) }
|
||||
before { create_list(:comment, 2, commentable: post) }
|
||||
|
||||
it 'returns a string with the quantity and the plural of the model' do
|
||||
expect(localize_plural(post.comments, Comment)).to eq '2 comments'
|
||||
|
||||
@@ -7,7 +7,7 @@ describe Comment do
|
||||
let(:comment) { FactoryBot.create(:comment) }
|
||||
|
||||
it "belongs to a post" do
|
||||
comment.post.should be_an_instance_of Post
|
||||
comment.commentable.should be_an_instance_of Post
|
||||
end
|
||||
|
||||
it "belongs to an author" do
|
||||
@@ -26,17 +26,17 @@ describe Comment do
|
||||
@c = FactoryBot.create(:comment)
|
||||
@n = Notification.first
|
||||
@n.sender.should eq @c.author
|
||||
@n.recipient.should eq @c.post.author
|
||||
@n.recipient.should eq @c.commentable.author
|
||||
@n.subject.should include 'commented on'
|
||||
@n.body.should eq @c.body
|
||||
@n.post.should eq @c.post
|
||||
@n.notifiable.should eq @c.commentable # polymorphic association, this is a Post.
|
||||
end
|
||||
|
||||
it "doesn't send notifications to yourself" do
|
||||
@m = FactoryBot.create(:member)
|
||||
@p = FactoryBot.create(:post, author: @m)
|
||||
expect do
|
||||
FactoryBot.create(:comment, post: @p, author: @m)
|
||||
FactoryBot.create(:comment, commentable: @p, author: @m)
|
||||
end.not_to change(Notification, :count)
|
||||
end
|
||||
end
|
||||
@@ -45,8 +45,8 @@ describe Comment do
|
||||
before do
|
||||
@m = FactoryBot.create(:member)
|
||||
@p = FactoryBot.create(:post, author: @m)
|
||||
@c1 = FactoryBot.create(:comment, post: @p, author: @m)
|
||||
@c2 = FactoryBot.create(:comment, post: @p, author: @m)
|
||||
@c1 = FactoryBot.create(:comment, commentable: @p, author: @m)
|
||||
@c2 = FactoryBot.create(:comment, commentable: @p, author: @m)
|
||||
end
|
||||
|
||||
it 'has a scope for ASC order for displaying on post page' do
|
||||
|
||||
@@ -6,7 +6,7 @@ describe Notification do
|
||||
let(:notification) { FactoryBot.create(:notification) }
|
||||
|
||||
it "belongs to a post" do
|
||||
expect(notification.post).to be_an_instance_of Post
|
||||
expect(notification.notifiable).to be_an_instance_of Post
|
||||
end
|
||||
|
||||
it "belongs to a recipient" do
|
||||
|
||||
@@ -19,22 +19,22 @@ describe Post do
|
||||
|
||||
it "has many comments" do
|
||||
post = FactoryBot.create(:post, author: member)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
post.comments.size.should == 2
|
||||
end
|
||||
|
||||
it "supports counting comments" do
|
||||
post = FactoryBot.create(:post, author: member)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
post.comment_count.should == 2
|
||||
end
|
||||
|
||||
it "destroys comments when deleted" do
|
||||
post = FactoryBot.create(:post, author: member)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, post:)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
FactoryBot.create(:comment, commentable: post)
|
||||
post.comments.size.should eq(2)
|
||||
all = Comment.count
|
||||
post.destroy
|
||||
@@ -73,8 +73,8 @@ describe Post do
|
||||
end
|
||||
|
||||
it "sets recent activity to comment time" do
|
||||
comment = FactoryBot.create(:comment, post:,
|
||||
created_at: 1.hour.ago)
|
||||
comment = FactoryBot.create(:comment, commentable: post,
|
||||
created_at: 1.hour.ago)
|
||||
post.recent_activity.to_i.should eq comment.created_at.to_i
|
||||
end
|
||||
|
||||
@@ -88,7 +88,7 @@ describe Post do
|
||||
it "new comment on old post is recently active" do
|
||||
# now comment on an older post
|
||||
post2 = FactoryBot.create(:post, created_at: 1.minute.ago)
|
||||
FactoryBot.create(:comment, post:, created_at: 1.second.ago)
|
||||
FactoryBot.create(:comment, commentable: post, created_at: 1.second.ago)
|
||||
described_class.recently_active.first.should eq post
|
||||
described_class.recently_active.second.should eq post2
|
||||
end
|
||||
|
||||
@@ -3,9 +3,12 @@
|
||||
require 'rails_helper'
|
||||
|
||||
describe "comments/edit" do
|
||||
let(:comment) { FactoryBot.create(:comment) }
|
||||
|
||||
before do
|
||||
controller.stub(:current_user) { nil }
|
||||
assign(:comment, FactoryBot.create(:comment))
|
||||
assign(:comment, comment)
|
||||
assign(:commentable, comment.commentable)
|
||||
end
|
||||
|
||||
it "renders the edit comment form" do
|
||||
|
||||
@@ -8,8 +8,8 @@ describe 'comments/index.rss.haml' do
|
||||
@author = FactoryBot.create(:member)
|
||||
@post = FactoryBot.create(:post)
|
||||
assign(:comments, [
|
||||
FactoryBot.create(:comment, author: @author, post: @post),
|
||||
FactoryBot.create(:comment, author: @author, post: @post)
|
||||
FactoryBot.create(:comment, author: @author, commentable: @post),
|
||||
FactoryBot.create(:comment, author: @author, commentable: @post)
|
||||
])
|
||||
render
|
||||
end
|
||||
|
||||
@@ -6,9 +6,10 @@ describe "comments/new" do
|
||||
before do
|
||||
controller.stub(:current_user) { nil }
|
||||
@post = FactoryBot.create(:post, body: 'tena koutou ki te ao')
|
||||
@comment = FactoryBot.create(:comment, post: @post)
|
||||
@comment = FactoryBot.create(:comment, commentable: @post)
|
||||
assign(:comment, @comment)
|
||||
assign(:comments, [@comment])
|
||||
assign(:commentable, @post)
|
||||
render
|
||||
end
|
||||
|
||||
|
||||
@@ -24,7 +24,7 @@ describe "forums/index" do
|
||||
|
||||
context "posts" do
|
||||
let!(:post) { FactoryBot.create(:forum_post, forum: forum1) }
|
||||
let!(:comment) { FactoryBot.create(:comment, post:) }
|
||||
let!(:comment) { FactoryBot.create(:comment, commentable: post) }
|
||||
|
||||
before { render }
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ describe "posts/_single" do
|
||||
end
|
||||
|
||||
it "doesn't contain a link to new comment" do
|
||||
assert_select("a", { href: new_comment_path(post_id: @post.id) }, false)
|
||||
assert_select("a", { href: new_comment_path(comment: { commmentable_type: "Post", commentable_id: @post.id }) }, false)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -35,7 +35,7 @@ describe "posts/_single" do
|
||||
end
|
||||
|
||||
it "contains link to new comment" do
|
||||
assert_select("a", { href: new_comment_path(post_id: @post.id) }, "Reply")
|
||||
assert_select("a", { href: new_comment_path(comment: { commmentable_type: "Post", commentable_id: @post.id }) }, "Reply")
|
||||
end
|
||||
|
||||
it "does not contain an edit link" do
|
||||
@@ -78,7 +78,7 @@ describe "posts/_single" do
|
||||
sign_in @member
|
||||
controller.stub(:current_user) { @member }
|
||||
@post = FactoryBot.create(:post, author: @member)
|
||||
@comment = FactoryBot.create(:comment, post: @post)
|
||||
@comment = FactoryBot.create(:comment, commentable: @post)
|
||||
@comment.update(body: "I've been updated")
|
||||
render partial: "comments/single", locals: { comment: @comment }
|
||||
end
|
||||
@@ -113,7 +113,7 @@ describe "posts/_single" do
|
||||
sign_in @member
|
||||
controller.stub(:current_user) { @member }
|
||||
@post = FactoryBot.create(:post, author: @member)
|
||||
@comment = FactoryBot.create(:comment, post: @post)
|
||||
@comment = FactoryBot.create(:comment, commentable: @post)
|
||||
@comment.update(updated_at: @comment.created_at)
|
||||
render partial: "comments/single", locals: { comment: @comment }
|
||||
end
|
||||
|
||||
@@ -61,7 +61,7 @@ describe "posts/show" do
|
||||
|
||||
context "when there is one comment" do
|
||||
let(:post) { FactoryBot.create(:html_post, author:) }
|
||||
let!(:comment) { FactoryBot.create(:comment, post:) }
|
||||
let!(:comment) { FactoryBot.create(:comment, commentable: post) }
|
||||
|
||||
before do
|
||||
@comments = post.comments
|
||||
@@ -85,12 +85,12 @@ describe "posts/show" do
|
||||
let(:post) { FactoryBot.create(:html_post, author:) }
|
||||
|
||||
before do
|
||||
@comment1 = FactoryBot.create(:comment, post:, body: "F1rst!!!",
|
||||
@comment1 = FactoryBot.create(:comment, commentable: post, body: "F1rst!!!",
|
||||
created_at: Date.new(2010, 5, 17))
|
||||
@comment3 = FactoryBot.create(:comment, post:, body: "Th1rd!!!",
|
||||
@comment3 = FactoryBot.create(:comment, commentable: post, body: "Th1rd!!!",
|
||||
created_at: Date.new(2012, 5, 17))
|
||||
@comment4 = FactoryBot.create(:comment, post:, body: "F0urth!!!")
|
||||
@comment2 = FactoryBot.create(:comment, post:, body: "S3c0nd!!1!",
|
||||
@comment4 = FactoryBot.create(:comment, commentable: post, body: "F0urth!!!")
|
||||
@comment2 = FactoryBot.create(:comment, commentable: post, body: "S3c0nd!!1!",
|
||||
created_at: Date.new(2011, 5, 17))
|
||||
@comments = post.comments
|
||||
render
|
||||
@@ -121,7 +121,7 @@ describe "posts/show" do
|
||||
end
|
||||
|
||||
it 'shows a comment button' do
|
||||
expect(subject).to have_link "Comment", href: new_comment_path(post_id: post.id)
|
||||
expect(subject).to have_link "Comment", href: new_comment_path(comment: { commentable_type: "Post", commentable_id: post.id })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -7,8 +7,8 @@ describe 'posts/show.rss.haml' do
|
||||
controller.stub(:current_user) { nil }
|
||||
@author = FactoryBot.create(:member)
|
||||
@post = FactoryBot.create(:post)
|
||||
FactoryBot.create(:comment, author: @author, post: @post)
|
||||
FactoryBot.create(:comment, author: @author, post: @post)
|
||||
FactoryBot.create(:comment, author: @author, commentable: @post)
|
||||
FactoryBot.create(:comment, author: @author, commentable: @post)
|
||||
assign(:post, @post)
|
||||
render
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user