-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add the ability to create article comments
- Loading branch information
Showing
9 changed files
with
428 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -101,5 +101,124 @@ describe Blogging::ArticleDetailHandler do | |
|
||
handler.context["favorited"].should be_false | ||
end | ||
|
||
it "inserts an empty page of comments if the article has no comments" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
|
||
request = Marten::HTTP::Request.new(method: "GET", resource: "/test/xyz") | ||
request.session = Marten::HTTP::Session::Store::Cookie.new("sessionkey") | ||
MartenAuth.sign_in(request, user) | ||
|
||
handler = Blogging::ArticleDetailHandler.new( | ||
request, | ||
Marten::Routing::MatchParameters{"slug" => article.slug!} | ||
) | ||
|
||
handler.context["comments"].empty?.should be_true | ||
end | ||
|
||
it "inserts the first page of comments if the article has comments and no page parameter is set" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
other_user = create_user(username: "test2", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
other_article = Blogging::Article.create!( | ||
title: "My other article", | ||
slug: "my-other-article", | ||
description: "My other-article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
|
||
15.times do |i| | ||
Blogging::Comment.create!( | ||
article: article, | ||
body: "# Hello World #{i}", | ||
author: other_user.profile!, | ||
) | ||
|
||
Blogging::Comment.create!( | ||
article: other_article, | ||
body: "# Hello World", | ||
author: other_user.profile!, | ||
) | ||
end | ||
|
||
request = Marten::HTTP::Request.new(method: "GET", resource: "/test/xyz") | ||
request.session = Marten::HTTP::Session::Store::Cookie.new("sessionkey") | ||
MartenAuth.sign_in(request, user) | ||
|
||
handler = Blogging::ArticleDetailHandler.new( | ||
request, | ||
Marten::Routing::MatchParameters{"slug" => article.slug!} | ||
) | ||
|
||
handler.context["comments"].empty?.should be_false | ||
handler.context["comments"].size.should eq 10 | ||
handler.context["comments"].to_a[0].raw.should be_a Blogging::Comment | ||
handler.context["comments"].to_a.all? { |c| c.raw.as(Blogging::Comment).article == article }.should be_true | ||
end | ||
|
||
it "inserts the right page of comments if the article has comments and no page parameter is set" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
other_user = create_user(username: "test2", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
other_article = Blogging::Article.create!( | ||
title: "My other article", | ||
slug: "my-other-article", | ||
description: "My other-article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
|
||
15.times do |i| | ||
Blogging::Comment.create!( | ||
article: article, | ||
body: "# Hello World #{i}", | ||
author: other_user.profile!, | ||
) | ||
|
||
Blogging::Comment.create!( | ||
article: other_article, | ||
body: "# Hello World", | ||
author: other_user.profile!, | ||
) | ||
end | ||
|
||
request = Marten::HTTP::Request.new(method: "GET", resource: "/test/xyz?comment_page=2") | ||
request.session = Marten::HTTP::Session::Store::Cookie.new("sessionkey") | ||
MartenAuth.sign_in(request, user) | ||
|
||
handler = Blogging::ArticleDetailHandler.new( | ||
request, | ||
Marten::Routing::MatchParameters{"slug" => article.slug!} | ||
) | ||
|
||
handler.context["comments"].empty?.should be_false | ||
handler.context["comments"].size.should eq 5 | ||
handler.context["comments"].to_a[0].raw.should be_a Blogging::Comment | ||
handler.context["comments"].to_a.all? { |c| c.raw.as(Blogging::Comment).article == article }.should be_true | ||
end | ||
end | ||
end |
66 changes: 66 additions & 0 deletions
66
spec/apps/blogging/handlers/comment_create_handler_spec.cr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
require "./spec_helper" | ||
|
||
describe Blogging::CommentCreateHandler do | ||
describe "#post" do | ||
it "redirects to the sign in page if the user is not authenticated" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
|
||
response = Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_create", slug: article.slug!), | ||
data: {"body" => "My super comment"} | ||
) | ||
|
||
response.status.should eq 302 | ||
response.headers["Location"].should eq Marten.routes.reverse("auth:sign_in") | ||
|
||
article.reload.comments.size.should eq 0 | ||
end | ||
|
||
it "creates a new article comment if the user is authenticated" do | ||
user = create_user(username: "test1", email: "[email protected]", password: "insecure") | ||
Marten::Spec.client.sign_in(user) | ||
|
||
other_user = create_user(username: "test2", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: other_user.profile!, | ||
) | ||
|
||
response = Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_create", slug: article.slug!), | ||
data: {"body" => "My super comment"} | ||
) | ||
|
||
response.status.should eq 302 | ||
response.headers["Location"].should eq Marten.routes.reverse("blogging:article_detail", slug: article.slug!) | ||
|
||
article.reload.comments.size.should eq 1 | ||
article.comments.first!.body.should eq "My super comment" | ||
article.comments.first!.author.should eq user.profile! | ||
end | ||
|
||
it "raises a not found error if the article is not found" do | ||
user = create_user(username: "test1", email: "[email protected]", password: "insecure") | ||
Marten::Spec.client.sign_in(user) | ||
|
||
expect_raises(Marten::DB::Errors::RecordNotFound) do | ||
Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_create", slug: "not-found"), | ||
data: {"body" => "My super comment"} | ||
) | ||
end | ||
end | ||
end | ||
end |
118 changes: 118 additions & 0 deletions
118
spec/apps/blogging/handlers/comment_delete_handler_spec.cr
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
require "./spec_helper" | ||
|
||
describe Blogging::CommentDeleteHandler do | ||
describe "#post" do | ||
it "redirects to the sign in page if the user is not authenticated" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
comment = article.comments.create!(article: article, body: "My super comment", author: user.profile!) | ||
|
||
response = Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_delete", slug: article.slug!, comment_id: comment.id!), | ||
) | ||
|
||
response.status.should eq 302 | ||
response.headers["Location"].should eq Marten.routes.reverse("auth:sign_in") | ||
|
||
comment.reload.persisted?.should be_true | ||
end | ||
|
||
it "deletes the targeted comment and redirects to the article page" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
Marten::Spec.client.sign_in(user) | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
comment = article.comments.create!(article: article, body: "My super comment", author: user.profile!) | ||
|
||
response = Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_delete", slug: article.slug!, comment_id: comment.id!), | ||
) | ||
|
||
response.status.should eq 302 | ||
response.headers["Location"].should eq Marten.routes.reverse("blogging:article_detail", slug: article.slug!) | ||
|
||
expect_raises(Marten::DB::Errors::RecordNotFound) do | ||
comment.reload | ||
end | ||
end | ||
|
||
it "raises a not found error if the article is not found" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
comment = Blogging::Comment.create!(article: article, body: "My super comment", author: user.profile!) | ||
|
||
Marten::Spec.client.sign_in(user) | ||
|
||
expect_raises(Marten::DB::Errors::RecordNotFound) do | ||
Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_delete", slug: "not-found", comment_id: comment.id!), | ||
data: {"body" => "My super comment"} | ||
) | ||
end | ||
end | ||
|
||
it "raises a not found error if the comment is not found" do | ||
user = create_user(username: "test", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
|
||
Marten::Spec.client.sign_in(user) | ||
|
||
expect_raises(Marten::DB::Errors::RecordNotFound) do | ||
Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_delete", slug: article.slug!, comment_id: 0), | ||
data: {"body" => "My super comment"} | ||
) | ||
end | ||
end | ||
|
||
it "raises a permission denied error if the comment was created by another user" do | ||
user = create_user(username: "test1", email: "[email protected]", password: "insecure") | ||
other_user = create_user(username: "test2", email: "[email protected]", password: "insecure") | ||
|
||
article = Blogging::Article.create!( | ||
title: "My article", | ||
slug: "my-article", | ||
description: "My article description", | ||
body: "# Hello World", | ||
author: user.profile!, | ||
) | ||
comment = Blogging::Comment.create!(article: article, body: "My super comment", author: other_user.profile!) | ||
|
||
Marten::Spec.client.sign_in(user) | ||
|
||
expect_raises(Marten::HTTP::Errors::PermissionDenied) do | ||
Marten::Spec.client.post( | ||
Marten.routes.reverse("blogging:comment_delete", slug: article.slug!, comment_id: comment.id!), | ||
data: {"body" => "My super comment"} | ||
) | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
module Blogging | ||
class CommentCreateHandler < Marten::Handlers::Schema | ||
include Auth::RequireSignedInUser | ||
|
||
@article : Blogging::Article? | ||
|
||
schema CommentSchema | ||
http_method_names :post | ||
|
||
before_dispatch :retrieve_article | ||
|
||
after_failed_schema_validation :redirect_to_article | ||
after_successful_schema_validation :create_article_comment | ||
|
||
private def article! | ||
@article.not_nil! | ||
end | ||
|
||
private def create_article_comment | ||
Blogging::Comment.create!( | ||
article: article!, | ||
author: request.user!.profile!, | ||
body: schema.body!, | ||
) | ||
|
||
redirect_to_article | ||
end | ||
|
||
private def redirect_to_article | ||
redirect reverse("blogging:article_detail", slug: article!.not_nil!.slug!) | ||
end | ||
|
||
private def retrieve_article | ||
@article = Blogging::Article.get!(slug: params[:slug]?) | ||
end | ||
end | ||
end |
Oops, something went wrong.