diff --git a/app/models/comment.rb b/app/models/comment.rb
index 45b2d38c3..c86b86c6b 100644
--- a/app/models/comment.rb
+++ b/app/models/comment.rb
@@ -1,2 +1,4 @@
class Comment < ActiveRecord::Base
+ validates_presence_of :author
+ validates_presence_of :text
end
diff --git a/spec/features/add_new_comment_spec.rb b/spec/features/add_new_comment_spec.rb
new file mode 100644
index 000000000..4d22873d6
--- /dev/null
+++ b/spec/features/add_new_comment_spec.rb
@@ -0,0 +1,34 @@
+require "rails_helper"
+require "features/shared/examples"
+require "features/shared/contexts"
+
+feature "Add new comment" do
+ context "from main page", page: :main, js: true do
+ context "via Horizontal Form", form: :horizontal do
+ include_examples "New Comment Submission"
+ end
+ context "via Inline Form", form: :inline do
+ include_examples "New Comment Submission"
+ end
+ context "via Stacked Form", form: :stacked do
+ include_examples "New Comment Submission"
+ end
+ end
+
+ context "from simple page", page: :simple, js: true do
+ context "via Horizontal Form", form: :horizontal do
+ include_examples "New Comment Submission"
+ end
+ context "via Inline Form", form: :inline do
+ include_examples "New Comment Submission"
+ end
+ context "via the Stacked Form", form: :stacked do
+ include_examples "New Comment Submission"
+ end
+ end
+
+ context "from classic page", page: :classic do
+ background { click_link "New Comment" }
+ include_examples "New Comment Submission"
+ end
+end
diff --git a/spec/features/comments_spec.rb b/spec/features/comments_spec.rb
deleted file mode 100644
index c506dd553..000000000
--- a/spec/features/comments_spec.rb
+++ /dev/null
@@ -1,131 +0,0 @@
-require "rails_helper"
-
-shared_context "Form Submitted" do |name: "Spicoli", text: "dude!"|
- let(:hint_name) { "Your Name" }
- let(:hint_text) { "Say something using markdown..." }
- let(:name) { name }
- let(:text) { text }
-
- background do
- fill_in hint_name, with: name
- fill_in hint_text, with: text
-
- click_button "Post"
- end
-end
-
-shared_examples "Comments Form" do
- include_context "Form Submitted"
-
- scenario "submits form", js: true do
- expect(page).to have_css(".comment", text: name)
- expect(page).to have_css(".comment", text: text)
- end
-end
-
-shared_context "Horizontal Form" do
- background do
- click_link "Horizontal Form"
- end
-
- it_behaves_like "Comments Form"
-
- context "iframe text" do
- let(:iframe_text) { "" }
-
- include_context "Form Submitted", text: :iframe_text
-
- scenario "doesn't add an iframe", js: true do
- expect(page).not_to have_css("iframe")
- end
- end
-
- context "blank fields" do
- before { @comments_count = all(".comment").size }
- include_context "Form Submitted", name: "", text: ""
-
- scenario "doesn't add a blank comment", js: true do
- expect(page).to have_selector(".comment", count: @comments_count)
- end
- end
-end
-
-shared_context "Inline Form" do
- background do
- click_link "Inline Form"
- end
-
- it_behaves_like "Comments Form"
-end
-
-shared_context "Stacked Form" do
- background do
- click_link "Stacked Form"
- end
-
- it_behaves_like "Comments Form"
-end
-
-feature "Add new comment" do
- context "from the main page" do
- background do
- visit root_path
- end
-
- include_context "Horizontal Form"
- include_context "Inline Form"
- include_context "Stacked Form"
- end
-
- context "from the simple page" do
- background do
- visit simple_path
- end
-
- include_context "Horizontal Form"
- include_context "Inline Form"
- include_context "Stacked Form"
- end
-
- context "from the classic page" do
- background do
- visit comments_path
- click_link "New Comment"
- end
-
- it_behaves_like "Comments Form"
- end
-end
-
-feature "Edit a comment" do
- context "from the classic page" do
- let(:edited_name) { "Edited Name" }
-
- background do
- visit comments_path
- click_link "Edit", match: :first
- end
-
- include_context "Form Submitted", name: :edited_name
-
- scenario "submits form" do
- expect(page).to have_css(".comment", text: :edited_name)
- end
- end
-end
-
-feature "Destroy a comment" do
- context "from the classic page" do
- let(:comment) { Comment.first }
-
- background do
- visit comments_path
- click_link "Destroy", href: comment_path(comment)
- end
-
- scenario "destroys comment" do
- expect(page).to_not have_css(".comment", text: comment.author)
- expect(page).to_not have_css(".comment", text: comment.text)
- end
- end
-end
diff --git a/spec/features/destroy_comment_spec.rb b/spec/features/destroy_comment_spec.rb
new file mode 100644
index 000000000..684454201
--- /dev/null
+++ b/spec/features/destroy_comment_spec.rb
@@ -0,0 +1,14 @@
+require "rails_helper"
+require "features/shared/contexts"
+
+feature "Destroy a comment", existing_comment: true do
+ context "from classic page", page: :classic do
+ let(:comment) { Comment.first }
+
+ scenario "clicking destroy link destroys comment" do
+ click_link "Destroy", href: comment_path(comment)
+ expect(page).to_not have_css(".comment", text: comment.author)
+ expect(page).to_not have_css(".comment", text: comment.text)
+ end
+ end
+end
diff --git a/spec/features/edit_comment_spec.rb b/spec/features/edit_comment_spec.rb
new file mode 100644
index 000000000..9637e70f5
--- /dev/null
+++ b/spec/features/edit_comment_spec.rb
@@ -0,0 +1,39 @@
+require "rails_helper"
+require "features/shared/examples"
+require "features/shared/contexts"
+
+feature "Edit a comment", existing_comment: true do
+ let(:comment) { Comment.first }
+
+ context "from classic page", page: :classic do
+ background { click_link "Edit", match: :first }
+
+ context "when edit is submitted" do
+ let(:edited_name) { "Abraham Lincoln" }
+ include_context "Form Submitted", name: :edited_name
+
+ scenario "comment is updated" do
+ expect(page).to have_css(".comment", text: :edited_name)
+ expect(page).to have_success_message
+ end
+ end
+
+ context "when edit is submitted with blank fields", blank_form_submitted: true do
+ scenario "comment is not updated" do
+ expect(page).not_to have_success_message
+ expect(page).to have_failure_message
+ expect(page).not_to have_css(".comment", text: "")
+ end
+ end
+ end
+end
+
+private
+
+def have_success_message # rubocop:disable Style/PredicateName
+ have_css("#notice", "Comment was successfully created.")
+end
+
+def have_failure_message # rubocop:disable Style/PredicateName
+ have_css("#error_explanation")
+end
diff --git a/spec/features/shared/contexts.rb b/spec/features/shared/contexts.rb
new file mode 100644
index 000000000..3e0442bb9
--- /dev/null
+++ b/spec/features/shared/contexts.rb
@@ -0,0 +1,46 @@
+require "rails_helper"
+
+# Pages
+shared_context "Main Page", page: :main do
+ background { visit root_path }
+end
+shared_context "Simple Page", page: :simple do
+ background { visit simple_path }
+end
+shared_context "Classic Page", page: :classic do
+ background { visit comments_path }
+end
+
+# Forms
+shared_context "Horizontal Form", form: :horizontal do
+ background { click_link "Horizontal Form" }
+end
+shared_context "Inline Form", form: :inline do
+ background { click_link "Inline Form" }
+end
+shared_context "Stacked Form", form: :stacked do
+ background { click_link "Stacked Form" }
+end
+
+# Form Submission
+shared_context "Form Submitted", form_submitted: true do |name: "Spicoli", text: "dude!"|
+ let(:hint_name) { "Your Name" }
+ let(:hint_text) { "Say something using markdown..." }
+ let(:name) { name }
+ let(:text) { text }
+
+ background do
+ fill_in hint_name, with: name
+ fill_in hint_text, with: text
+ click_button "Post"
+ end
+end
+
+shared_context "Form Submitted with Blank Fields", blank_form_submitted: true do
+ include_context "Form Submitted", name: "", text: ""
+end
+
+# Fixtures
+shared_context "Existing Comment", existing_comment: true do
+ before { Comment.create(author: "John Doe", text: "Hello there!") }
+end
diff --git a/spec/features/shared/examples.rb b/spec/features/shared/examples.rb
new file mode 100644
index 000000000..73438a6be
--- /dev/null
+++ b/spec/features/shared/examples.rb
@@ -0,0 +1,32 @@
+require "rails_helper"
+require "features/shared/contexts"
+
+shared_examples "New Comment Submission" do
+ context "when the new comment is submitted" do
+ let(:name) { "John Smith" }
+ let(:text) { "Hello there!" }
+ include_context "Form Submitted", name: :name, text: :text
+
+ scenario "comment is added" do
+ expect(page).to have_css(".comment", text: name)
+ expect(page).to have_css(".comment", text: text)
+ end
+ end
+
+ context "when the new comment is submmited with blank fields", blank_form_submitted: true do
+ let!(:comments_count) { all(".comment").size }
+
+ scenario "comment is not added" do
+ expect(page).to have_selector(".comment", count: comments_count)
+ end
+ end
+
+ context "with iframe text" do
+ let(:iframe_text) { "" }
+ include_context "Form Submitted", text: :iframe_text
+
+ scenario "doesn't add an iframe" do
+ expect(page).not_to have_css("iframe")
+ end
+ end
+end