set up example scaffold with rspec + factorybot tests

main
Nelson Jovel 2 years ago
parent 533c921a6d
commit d1e6fb1e39

@ -0,0 +1,60 @@
module Dashboard
class ExamplesController < ApplicationController
before_action :set_example, only: %i[ show edit update destroy ]
# GET /examples
def index
@examples = Example.all
end
# GET /examples/1
def show
end
# GET /examples/new
def new
@example = Example.new
end
# GET /examples/1/edit
def edit
end
# POST /examples
def create
@example = Example.new(example_params)
if @example.save
redirect_to @example, notice: "Example was successfully created."
else
render :new, status: :unprocessable_entity
end
end
# PATCH/PUT /examples/1
def update
if @example.update(example_params)
redirect_to @example, notice: "Example was successfully updated.", status: :see_other
else
render :edit, status: :unprocessable_entity
end
end
# DELETE /examples/1
def destroy
@example.destroy!
redirect_to examples_url, notice: "Example was successfully destroyed.", status: :see_other
end
private
# Use callbacks to share common setup or constraints between actions.
def set_example
@example = Example.find(params[:id])
end
# Only allow a list of trusted parameters through.
def example_params
params.require(:example).permit(:text, :body)
end
end
end

@ -0,0 +1,4 @@
module Dashboard
module ExamplesHelper
end
end

@ -0,0 +1,4 @@
module Dashboard
class Example < ApplicationRecord
end
end

@ -0,0 +1,12 @@
<div id="<%= dom_id example %>">
<p>
<strong>Text:</strong>
<%= example.text %>
</p>
<p>
<strong>Body:</strong>
<%= example.body %>
</p>
</div>

@ -0,0 +1,27 @@
<%= form_with(model: example) do |form| %>
<% if example.errors.any? %>
<div style="color: red">
<h2><%= pluralize(example.errors.count, "error") %> prohibited this example from being saved:</h2>
<ul>
<% example.errors.each do |error| %>
<li><%= error.full_message %></li>
<% end %>
</ul>
</div>
<% end %>
<div>
<%= form.label :text, style: "display: block" %>
<%= form.text_field :text %>
</div>
<div>
<%= form.label :body, style: "display: block" %>
<%= form.text_area :body %>
</div>
<div>
<%= form.submit %>
</div>
<% end %>

@ -0,0 +1,10 @@
<h1>Editing example</h1>
<%= render "form", example: @example %>
<br>
<div>
<%= link_to "Show this example", @example %> |
<%= link_to "Back to examples", examples_path %>
</div>

@ -0,0 +1,14 @@
<p style="color: green"><%= notice %></p>
<h1>Examples</h1>
<div id="examples">
<% @examples.each do |example| %>
<%= render example %>
<p>
<%= link_to "Show this example", example %>
</p>
<% end %>
</div>
<%= link_to "New example", new_example_path %>

@ -0,0 +1,9 @@
<h1>New example</h1>
<%= render "form", example: @example %>
<br>
<div>
<%= link_to "Back to examples", examples_path %>
</div>

@ -0,0 +1,10 @@
<p style="color: green"><%= notice %></p>
<%= render @example %>
<div>
<%= link_to "Edit this example", edit_example_path(@example) %> |
<%= link_to "Back to examples", examples_path %>
<%= button_to "Destroy this example", @example, method: :delete %>
</div>

@ -1,2 +1,3 @@
Dashboard::Engine.routes.draw do
resources :examples
end

@ -0,0 +1,10 @@
class CreateDashboardExamples < ActiveRecord::Migration[7.1]
def change
create_table :dashboard_examples do |t|
t.string :text
t.text :body
t.timestamps
end
end
end

@ -1,5 +1,11 @@
module Dashboard
class Engine < ::Rails::Engine
isolate_namespace Dashboard
config.generators do |g|
g.test_framework :rspec
g.fixture_replacement :factory_bot
g.factory_bot dir: "spec/factories"
end
end
end

@ -0,0 +1,24 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# This file is the source Rails uses to define your schema when running `bin/rails
# db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to
# be faster and is potentially less error prone than running all of your
# migrations from scratch. Old migrations may fail to apply correctly if those
# migrations use external dependencies or application code.
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema[7.1].define(version: 2023_12_23_040511) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
create_table "dashboard_examples", force: :cascade do |t|
t.string "text"
t.text "body"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end
end

@ -0,0 +1,6 @@
FactoryBot.define do
factory :example, class: "Dashboard::Example" do
text { "MyString" }
body { "MyText" }
end
end

@ -0,0 +1,17 @@
require 'rails_helper'
# Specs in this file have access to a helper object that includes
# the ExamplesHelper. For example:
#
# describe ExamplesHelper 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
module Dashboard
RSpec.describe ExamplesHelper, type: :helper do
pending "add some examples to (or delete) #{__FILE__}"
end
end

@ -0,0 +1,10 @@
require "rails_helper"
module Dashboard
RSpec.describe Example, type: :model do
it "creates an example to test rspec and factorybot" do
create(:example)
expect(Example.count).to eq 1
end
end
end

@ -1,10 +1,11 @@
# This file is copied to spec/ when you run 'rails generate rspec:install'
require 'spec_helper'
ENV['RAILS_ENV'] ||= 'test'
require_relative '../config/environment'
require "spec_helper"
ENV["RAILS_ENV"] ||= "test"
require_relative "../spec/dummy/config/environment"
# Prevent database truncation if the environment is production
abort("The Rails environment is running in production mode!") if Rails.env.production?
require 'rspec/rails'
require "rspec/rails"
# Add additional requires below this line. Rails is not loaded until this point!
# Requires supporting ruby files with custom matchers and macros, etc, in
@ -29,12 +30,19 @@ begin
rescue ActiveRecord::PendingMigrationError => e
abort e.to_s.strip
end
require "factory_bot_rails"
FactoryBot.definition_file_paths << File.join(File.dirname(__FILE__), "factories")
FactoryBot.factories.clear
FactoryBot.find_definitions
RSpec.configure do |config|
# Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
config.fixture_paths = [
Rails.root.join('spec/fixtures')
Rails.root.join("spec/fixtures")
]
config.include FactoryBot::Syntax::Methods
# If you're not using ActiveRecord, or you'd prefer not to run each of your
# examples within a transaction, remove the following line or assign false
# instead of true.
@ -62,4 +70,9 @@ RSpec.configure do |config|
config.filter_rails_from_backtrace!
# arbitrary gems may also be filtered via:
# config.filter_gems_from_backtrace("gem name")
config.before(:example, type: :view) do
view.class_eval do
include Dashboard::Engine.routes.url_helpers
end
end
end

@ -0,0 +1,138 @@
require 'rails_helper'
# This spec was generated by rspec-rails when you ran the scaffold generator.
# It demonstrates how one might use RSpec to test the controller code that
# was generated by Rails when you ran the scaffold generator.
#
# It assumes that the implementation code is generated by the rails scaffold
# generator. If you are using any extension libraries to generate different
# controller code, this generated spec may or may not pass.
#
# It only uses APIs available in rails and/or rspec-rails. There are a number
# of tools you can use to make these specs even more expressive, but we're
# sticking to rails and rspec-rails APIs to keep things simple and stable.
module Dashboard
RSpec.describe "/examples", type: :request do
include Engine.routes.url_helpers
# This should return the minimal set of attributes required to create a valid
# Example. As you add validations to Example, be sure to
# adjust the attributes here as well.
let(:valid_attributes) {
skip("Add a hash of attributes valid for your model")
}
let(:invalid_attributes) {
skip("Add a hash of attributes invalid for your model")
}
describe "GET /index" do
it "renders a successful response" do
Example.create! valid_attributes
get examples_url
expect(response).to be_successful
end
end
describe "GET /show" do
it "renders a successful response" do
example = Example.create! valid_attributes
get example_url(example)
expect(response).to be_successful
end
end
describe "GET /new" do
it "renders a successful response" do
get new_example_url
expect(response).to be_successful
end
end
describe "GET /edit" do
it "renders a successful response" do
example = Example.create! valid_attributes
get edit_example_url(example)
expect(response).to be_successful
end
end
describe "POST /create" do
context "with valid parameters" do
it "creates a new Example" do
expect {
post examples_url, params: { example: valid_attributes }
}.to change(Example, :count).by(1)
end
it "redirects to the created example" do
post examples_url, params: { example: valid_attributes }
expect(response).to redirect_to(example_url(Example.last))
end
end
context "with invalid parameters" do
it "does not create a new Example" do
expect {
post examples_url, params: { example: invalid_attributes }
}.to change(Example, :count).by(0)
end
it "renders a response with 422 status (i.e. to display the 'new' template)" do
post examples_url, params: { example: invalid_attributes }
expect(response).to have_http_status(:unprocessable_entity)
end
end
end
describe "PATCH /update" do
context "with valid parameters" do
let(:new_attributes) {
skip("Add a hash of attributes valid for your model")
}
it "updates the requested example" do
example = Example.create! valid_attributes
patch example_url(example), params: { example: new_attributes }
example.reload
skip("Add assertions for updated state")
end
it "redirects to the example" do
example = Example.create! valid_attributes
patch example_url(example), params: { example: new_attributes }
example.reload
expect(response).to redirect_to(example_url(example))
end
end
context "with invalid parameters" do
it "renders a response with 422 status (i.e. to display the 'edit' template)" do
example = Example.create! valid_attributes
patch example_url(example), params: { example: invalid_attributes }
expect(response).to have_http_status(:unprocessable_entity)
end
end
end
describe "DELETE /destroy" do
it "destroys the requested example" do
example = Example.create! valid_attributes
expect {
delete example_url(example)
}.to change(Example, :count).by(-1)
end
it "redirects to the examples list" do
example = Example.create! valid_attributes
delete example_url(example)
expect(response).to redirect_to(examples_url)
end
end
end
end

@ -0,0 +1,39 @@
require "rails_helper"
module Dashboard
RSpec.describe ExamplesController, type: :routing do
describe "routing" do
it "routes to #index" do
expect(get: "dashboard/examples").to route_to("dashboard/examples#index")
end
it "routes to #new" do
expect(get: "dashboard/examples/new").to route_to("dashboard/examples#new")
end
it "routes to #show" do
expect(get: "dashboard/examples/1").to route_to("dashboard/examples#show", id: "1")
end
it "routes to #edit" do
expect(get: "/dashboard/examples/1/edit").to route_to("dashboard/examples#edit", id: "1")
end
it "routes to #create" do
expect(post: "/dashboard/examples").to route_to("dashboard/examples#create")
end
it "routes to #update via PUT" do
expect(put: "/dashboard/examples/1").to route_to("dashboard/examples#update", id: "1")
end
it "routes to #update via PATCH" do
expect(patch: "/dashboard/examples/1").to route_to("dashboard/examples#update", id: "1")
end
it "routes to #destroy" do
expect(delete: "/dashboard/examples/1").to route_to("dashboard/examples#destroy", id: "1")
end
end
end
end

@ -0,0 +1,26 @@
require "rails_helper"
module Dashboard
RSpec.xdescribe "dashboard/examples/edit", type: :view do
let(:example) do
Example.create!(
text: "MyString",
body: "MyText"
)
end
before(:each) do
assign(:example, example)
end
it "renders the edit example form" do
render
assert_select "form[action=?][method=?]", example_path(example), "post" do
assert_select "input[name=?]", "example[text]"
assert_select "textarea[name=?]", "example[body]"
end
end
end
end

@ -0,0 +1,26 @@
require "rails_helper"
require "nokogiri"
module Dashboard
RSpec.describe "/dashboard/examples/index", type: :view do
before(:each) do
assign(:examples, [
Example.create!(
text: "Word",
body: "Sentence"
),
Example.create!(
text: "Word",
body: "Sentence"
)
])
end
it "renders a list of examples" do
render
cell_selector = Rails::VERSION::STRING >= "7" ? "div>p" : "tr>td"
assert_select cell_selector, text: Regexp.new("Word".to_s), count: 2
assert_select cell_selector, text: Regexp.new("Sentence".to_s), count: 2
end
end
end

@ -0,0 +1,22 @@
require "rails_helper"
module Dashboard
RSpec.xdescribe "dashboard/examples/new", type: :view do
before(:each) do
assign(:example, Example.new(
text: "MyString",
body: "MyText"
))
end
it "renders new example form" do
render
assert_select "form[action=?][method=?]", examples_path, "post" do
assert_select "input[name=?]", "example[text]"
assert_select "textarea[name=?]", "example[body]"
end
end
end
end

@ -0,0 +1,18 @@
require "rails_helper"
module Dashboard
RSpec.describe "dashboard/examples/show", type: :view do
before(:each) do
assign(:example, Example.create!(
text: "Word",
body: "Sentence"
))
end
it "renders attributes in <p>" do
render
expect(rendered).to match(/Word/)
expect(rendered).to match(/Sentence/)
end
end
end
Loading…
Cancel
Save