diff --git a/.vscode/.ltici_apitoken.yml b/.vscode/.ltici_apitoken.yml new file mode 100644 index 0000000..774c54f --- /dev/null +++ b/.vscode/.ltici_apitoken.yml @@ -0,0 +1,3 @@ +--- +submission_url: https://grades.firstdraft.com +personal_access_token: 9ALV8qxZ8FFR4VKRcrNkN4ba diff --git a/Gemfile b/Gemfile index 3d7ed82..c5d999c 100644 --- a/Gemfile +++ b/Gemfile @@ -3,6 +3,8 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" } ruby '3.0.3' +gem "draft_generators", :github => "firstdraft/draft_generators" + gem "grade_runner", github: "firstdraft/grade_runner" # Bundle edge Rails instead: gem 'rails', github: 'rails/rails', branch: 'main' @@ -82,4 +84,5 @@ group :development do gem 'rubocop-rspec', require: false gem 'skylight' gem 'web_git', github: 'firstdraft/web_git' + gem "rails_db", "~> 2.4" end diff --git a/Gemfile.lock b/Gemfile.lock index fe0ec3b..483db17 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,3 +1,11 @@ +GIT + remote: https://github.com/firstdraft/draft_generators.git + revision: 23069b562615e42e04c3343e330846594ce51fdb + specs: + draft_generators (0.0.3) + devise + indefinite_article + GIT remote: https://github.com/firstdraft/grade_runner.git revision: e19ab1764a5a4e0a89731fcab76e352d60240ddf @@ -90,6 +98,7 @@ GEM ast (2.4.2) awesome_print (1.9.2) backport (1.2.0) + bcrypt (3.1.18) benchmark (0.2.0) better_errors (2.9.1) coderay (>= 1.0.0) @@ -130,6 +139,12 @@ GEM rexml crass (1.0.6) debug_inspector (1.1.0) + devise (4.9.2) + bcrypt (~> 3.0) + orm_adapter (~> 0.1) + railties (>= 4.1.0) + responders + warden (~> 1.2.3) diff-lcs (1.5.0) diffy (3.4.2) e2mmap (0.1.0) @@ -157,10 +172,24 @@ GEM image_processing (1.12.2) mini_magick (>= 4.9.5, < 5) ruby-vips (>= 2.0.17, < 3) + indefinite_article (0.2.5) + activesupport jaro_winkler (1.5.4) jbuilder (2.11.5) actionview (>= 5.0.0) activesupport (>= 5.0.0) + kaminari (1.2.2) + activesupport (>= 4.1.0) + kaminari-actionview (= 1.2.2) + kaminari-activerecord (= 1.2.2) + kaminari-core (= 1.2.2) + kaminari-actionview (1.2.2) + actionview + kaminari-core (= 1.2.2) + kaminari-activerecord (1.2.2) + activerecord + kaminari-core (= 1.2.2) + kaminari-core (1.2.2) kramdown (2.4.0) rexml kramdown-parser-gfm (1.1.0) @@ -193,6 +222,7 @@ GEM faraday (>= 1, < 3) sawyer (~> 0.9) oj (3.10.18) + orm_adapter (0.5.0) parallel (1.22.1) parser (3.1.1.0) ast (~> 2.4.1) @@ -243,6 +273,13 @@ GEM ruby-graphviz (~> 1.2) rails-html-sanitizer (1.4.3) loofah (~> 2.3) + rails_db (2.4.2) + activerecord + kaminari + rails (>= 5.0.0) + ransack (>= 2.3.2) + simple_form (>= 5.0.1) + terminal-table railties (6.1.5) actionpack (= 6.1.5) activesupport (= 6.1.5) @@ -251,11 +288,18 @@ GEM thor (~> 1.0) rainbow (3.1.1) rake (13.0.6) + ransack (4.0.0) + activerecord (>= 6.1.5) + activesupport (>= 6.1.5) + i18n rb-fsevent (0.11.1) rb-inotify (0.10.1) ffi (~> 1.0) rchardet (1.8.0) regexp_parser (2.2.1) + responders (3.1.0) + actionpack (>= 5.2) + railties (>= 5.2) reverse_markdown (2.1.1) nokogiri rexml (3.2.5) @@ -330,6 +374,9 @@ GEM rexml (~> 3.2, >= 3.2.5) rubyzip (>= 1.2.2) semantic_range (3.0.0) + simple_form (5.2.0) + actionpack (>= 5.2) + activemodel (>= 5.2) sinatra (3.0.4) mustermann (~> 3.0) rack (~> 2.2, >= 2.2.4) @@ -364,6 +411,8 @@ GEM standard (1.9.1) rubocop (= 1.26.1) rubocop-performance (= 1.13.3) + terminal-table (3.0.2) + unicode-display_width (>= 1.1.1, < 3) thor (1.2.1) tilt (2.0.11) turbolinks (5.2.1) @@ -375,6 +424,8 @@ GEM tzinfo (>= 1.0.0) unicode-display_width (2.1.0) uniform_notifier (1.16.0) + warden (1.2.9) + rack (>= 2.0.9) web-console (4.2.0) actionview (>= 6.0.0) activemodel (>= 6.0.0) @@ -417,6 +468,7 @@ DEPENDENCIES byebug capybara (>= 3.26) carrierwave + draft_generators! factory_bot_rails grade_runner! htmlbeautifier @@ -429,6 +481,7 @@ DEPENDENCIES rack-mini-profiler (~> 2.0) rails (~> 6.1.3, >= 6.1.3.1) rails-erd + rails_db (~> 2.4) rollbar rspec-html-matchers rspec-rails diff --git a/app/assets/stylesheets/books.scss b/app/assets/stylesheets/books.scss new file mode 100644 index 0000000..e0f44b0 --- /dev/null +++ b/app/assets/stylesheets/books.scss @@ -0,0 +1,3 @@ +// Place all the styles related to the books controller here. +// They will automatically be included in application.css. +// You can use Sass (SCSS) here: https://sass-lang.com/ diff --git a/app/assets/stylesheets/scaffolds.scss b/app/assets/stylesheets/scaffolds.scss new file mode 100644 index 0000000..bb2597f --- /dev/null +++ b/app/assets/stylesheets/scaffolds.scss @@ -0,0 +1,65 @@ +body { + background-color: #fff; + color: #333; + margin: 33px; } + +body, p, ol, ul, td { + font-family: verdana, arial, helvetica, sans-serif; + font-size: 13px; + line-height: 18px; } + +pre { + background-color: #eee; + padding: 10px; + font-size: 11px; } + +a { + color: #000; } + +a:visited { + color: #666; } + +a:hover { + color: #fff; + background-color: #000; } + +th { + padding-bottom: 5px; } + +td { + padding: 0 5px 7px; } + +div.field, +div.actions { + margin-bottom: 10px; } + +#notice { + color: green; } + +.field_with_errors { + padding: 2px; + background-color: red; + display: table; } + +#error_explanation { + width: 450px; + border: 2px solid red; + padding: 7px 7px 0; + margin-bottom: 20px; + background-color: #f0f0f0; } + +#error_explanation h2 { + text-align: left; + font-weight: bold; + padding: 5px 5px 5px 15px; + font-size: 12px; + margin: -7px -7px 0; + background-color: #c00; + color: #fff; } + +#error_explanation ul li { + font-size: 12px; + list-style: square; } + +label { + display: block; } diff --git a/app/controllers/books_controller.rb b/app/controllers/books_controller.rb new file mode 100644 index 0000000..5b0ba65 --- /dev/null +++ b/app/controllers/books_controller.rb @@ -0,0 +1,70 @@ +class BooksController < ApplicationController + before_action :set_book, only: %i[ show edit update destroy ] + + # GET /books or /books.json + def index + @books = Book.all + end + + # GET /books/1 or /books/1.json + def show + end + + # GET /books/new + def new + @book = Book.new + end + + # GET /books/1/edit + def edit + end + + # POST /books or /books.json + def create + @book = Book.new(book_params) + + respond_to do |format| + if @book.save + format.html { redirect_to book_url(@book), notice: "Book was successfully created." } + format.json { render :show, status: :created, location: @book } + else + format.html { render :new, status: :unprocessable_entity } + format.json { render json: @book.errors, status: :unprocessable_entity } + end + end + end + + # PATCH/PUT /books/1 or /books/1.json + def update + respond_to do |format| + if @book.update(book_params) + format.html { redirect_to book_url(@book), notice: "Book was successfully updated." } + format.json { render :show, status: :ok, location: @book } + else + format.html { render :edit, status: :unprocessable_entity } + format.json { render json: @book.errors, status: :unprocessable_entity } + end + end + end + + # DELETE /books/1 or /books/1.json + def destroy + @book.destroy + + respond_to do |format| + format.html { redirect_to books_url, notice: "Book was successfully destroyed." } + format.json { head :no_content } + end + end + + private + # Use callbacks to share common setup or constraints between actions. + def set_book + @book = Book.find(params[:id]) + end + + # Only allow a list of trusted parameters through. + def book_params + params.require(:book).permit(:title, :description, :released) + end +end diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb new file mode 100644 index 0000000..7898008 --- /dev/null +++ b/app/controllers/movies_controller.rb @@ -0,0 +1,71 @@ +class MoviesController < ApplicationController + def new + @the_movie = Movie.new + + render template: "movies/new" + end + + def edit + @the_movie = Movie.where(id: params.fetch(:id)).first + + render template: "movies/edit.html.erb" + end + + def index + matching_movies = Movie.all + + @list_of_movies = matching_movies.order({ :created_at => :desc }) + + render({ :template => "movies/index.html.erb" }) + end + + def show + the_id = params.fetch("id") + + matching_movies = Movie.where({ :id => the_id }) + + @the_movie = matching_movies.first + + render({ :template => "movies/show.html.erb" }) + end + + def create + @the_movie = Movie.new + @the_movie.title = params.fetch("query_title") + @the_movie.description = params.fetch("query_description") + @the_movie.released = params.fetch("query_released", false) + + if @the_movie.valid? + @the_movie.save + redirect_to("/movies", { :notice => "Movie created successfully." }) + else + + render template: "movies/new" + end + end + + def update + the_id = params.fetch("id") + the_movie = Movie.where({ :id => the_id }).first + + the_movie.title = params.fetch("query_title") + the_movie.description = params.fetch("query_description") + the_movie.released = params.fetch("query_released", false) + + if the_movie.valid? + the_movie.save + redirect_to("/movies/#{the_movie.id}", { :notice => "Movie updated successfully."} ) + else + redirect_to("/movies/#{the_movie.id}", { :alert => the_movie.errors.full_messages.to_sentence }) + end + end + + def destroy + the_id = params.fetch("id") + the_movie = Movie.where({ :id => the_id }).first + + the_movie.destroy + + redirect_to("/movies", { :notice => "Movie deleted successfully."} ) + end +end diff --git a/app/helpers/books_helper.rb b/app/helpers/books_helper.rb new file mode 100644 index 0000000..4b9311e --- /dev/null +++ b/app/helpers/books_helper.rb @@ -0,0 +1,2 @@ +module BooksHelper +end diff --git a/app/models/book.rb b/app/models/book.rb new file mode 100644 index 0000000..f6c5d67 --- /dev/null +++ b/app/models/book.rb @@ -0,0 +1,5 @@ +class Book < ApplicationRecord + validates :title, presence: true + validates :description, presence: true + +end diff --git a/app/models/movie.rb b/app/models/movie.rb new file mode 100644 index 0000000..6374a9c --- /dev/null +++ b/app/models/movie.rb @@ -0,0 +1,6 @@ +class Movie < ApplicationRecord + + validates :title, presence: true + validates :description, presence: true + +end diff --git a/app/views/books/_book.json.jbuilder b/app/views/books/_book.json.jbuilder new file mode 100644 index 0000000..996e96f --- /dev/null +++ b/app/views/books/_book.json.jbuilder @@ -0,0 +1,2 @@ +json.extract! book, :id, :title, :description, :released, :created_at, :updated_at +json.url book_url(book, format: :json) diff --git a/app/views/books/_form.html.erb b/app/views/books/_form.html.erb new file mode 100644 index 0000000..42c97c0 --- /dev/null +++ b/app/views/books/_form.html.erb @@ -0,0 +1,32 @@ +<%= form_with(model: book) do |form| %> + <% if book.errors.any? %> +
+

<%= pluralize(book.errors.count, "error") %> prohibited this book from being saved:

+ + +
+ <% end %> + +
+ <%= form.label :title %> + <%= form.text_field :title %> +
+ +
+ <%= form.label :description %> + <%= form.text_area :description %> +
+ +
+ <%= form.label :released %> + <%= form.check_box :released %> +
+ +
+ <%= form.submit %> +
+<% end %> diff --git a/app/views/books/edit.html.erb b/app/views/books/edit.html.erb new file mode 100644 index 0000000..ff28963 --- /dev/null +++ b/app/views/books/edit.html.erb @@ -0,0 +1,6 @@ +

Editing Book

+ +<%= render 'form', book: @book %> + +<%= link_to 'Show', @book %> | +<%= link_to 'Back', books_path %> diff --git a/app/views/books/index.html.erb b/app/views/books/index.html.erb new file mode 100644 index 0000000..90e09d1 --- /dev/null +++ b/app/views/books/index.html.erb @@ -0,0 +1,31 @@ +

<%= notice %>

+ +

Books

+ + + + + + + + + + + + + <% @books.each do |book| %> + + + + + + + + + <% end %> + +
TitleDescriptionReleased
<%= book.title %><%= book.description %><%= book.released %><%= link_to 'Show', book %><%= link_to 'Edit', edit_book_path(book) %><%= link_to 'Destroy', book, method: :delete, data: { confirm: 'Are you sure?' } %>
+ +
+ +<%= link_to 'New Book', new_book_path %> diff --git a/app/views/books/index.json.jbuilder b/app/views/books/index.json.jbuilder new file mode 100644 index 0000000..cc35e64 --- /dev/null +++ b/app/views/books/index.json.jbuilder @@ -0,0 +1 @@ +json.array! @books, partial: "books/book", as: :book diff --git a/app/views/books/new.html.erb b/app/views/books/new.html.erb new file mode 100644 index 0000000..9607d41 --- /dev/null +++ b/app/views/books/new.html.erb @@ -0,0 +1,5 @@ +

New Book

+ +<%= render 'form', book: @book %> + +<%= link_to 'Back', books_path %> diff --git a/app/views/books/show.html.erb b/app/views/books/show.html.erb new file mode 100644 index 0000000..7b71386 --- /dev/null +++ b/app/views/books/show.html.erb @@ -0,0 +1,19 @@ +

<%= notice %>

+ +

+ Title: + <%= @book.title %> +

+ +

+ Description: + <%= @book.description %> +

+ +

+ Released: + <%= @book.released %> +

+ +<%= link_to 'Edit', edit_book_path(@book) %> | +<%= link_to 'Back', books_path %> diff --git a/app/views/books/show.json.jbuilder b/app/views/books/show.json.jbuilder new file mode 100644 index 0000000..c1e5174 --- /dev/null +++ b/app/views/books/show.json.jbuilder @@ -0,0 +1 @@ +json.partial! "books/book", book: @book diff --git a/app/views/layouts/application.html.erb b/app/views/layouts/application.html.erb index 9917f83..9844173 100644 --- a/app/views/layouts/application.html.erb +++ b/app/views/layouts/application.html.erb @@ -7,10 +7,13 @@ <%= csp_meta_tag %> <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %> - <%= javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> + <% # javascript_pack_tag 'application', 'data-turbolinks-track': 'reload' %> +

<%= notice %>

+

<%= alert %>

+ <%= yield %> diff --git a/app/views/movies/edit.html.erb b/app/views/movies/edit.html.erb new file mode 100644 index 0000000..fe8bb98 --- /dev/null +++ b/app/views/movies/edit.html.erb @@ -0,0 +1,37 @@ +

+ Editing Movie +

+ +
+ + + + +
+ + + +
+ +
+ + + +
+ +
+ > + + +
+ + +
diff --git a/app/views/movies/index.html.erb b/app/views/movies/index.html.erb new file mode 100644 index 0000000..1323932 --- /dev/null +++ b/app/views/movies/index.html.erb @@ -0,0 +1,87 @@ +
+
+

+ List of all movies +

+ Add a new movie +
+
+ +
+ +
+
+ +
+
+ +
+
+
+ + + + + + + + + + + + + + + + + + <% @list_of_movies.each do |a_movie| %> + + + + + + + + + + + + + + + <% end %> +
+ ID + + Title + + Description + + Released + + Created at + + Updated at + +
+ <%= a_movie.id %> + + <%= a_movie.title %> + + <%= a_movie.description %> + + <%= a_movie.released %> + + <%= time_ago_in_words(a_movie.created_at) %> ago + + <%= time_ago_in_words(a_movie.updated_at) %> ago + + + Show details + +
+
+
+ +
diff --git a/app/views/movies/new.html.erb b/app/views/movies/new.html.erb new file mode 100644 index 0000000..99aa24c --- /dev/null +++ b/app/views/movies/new.html.erb @@ -0,0 +1,39 @@ +

+ Add a new movie +

+ + <% @the_movie.errors.full_messages.each do |msg| %> +
  • <%= msg %>
  • + <% end %> + + +
    + + +
    + + + +
    + +
    + + + +
    + +
    + + + +
    + + +
    diff --git a/app/views/movies/show.html.erb b/app/views/movies/show.html.erb new file mode 100644 index 0000000..d1f505e --- /dev/null +++ b/app/views/movies/show.html.erb @@ -0,0 +1,105 @@ +
    +
    +

    + Movie #<%= @the_movie.id %> details +

    + +
    +
    + + Go back + +
    + +
    + + Delete Movie + +
    +
    + +
    +
    + Title +
    +
    + <%= @the_movie.title %> +
    + +
    + Description +
    +
    + <%= @the_movie.description %> +
    + +
    + Released +
    +
    + <%= @the_movie.released %> +
    + +
    + Created at +
    +
    + <%= time_ago_in_words(@the_movie.created_at) %> ago +
    + +
    + Updated at +
    +
    + <%= time_ago_in_words(@the_movie.updated_at) %> ago +
    +
    + + + +
    + + +
    +
    +

    + Edit movie +

    + +
    + + + + +
    + + + +
    + +
    + + + +
    + +
    + > + + +
    + + +
    +
    +
    + +
    diff --git a/config/routes.rb b/config/routes.rb index c06383a..1712abe 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,27 @@ Rails.application.routes.draw do + resources :books + # Routes for the Movie resource: + + get("/movies/:id/edit", { :controller => "movies", :action => "edit" }) + + + # CREATE + post("/movies", { :controller => "movies", :action => "create" }) + + # READ + get("/movies", { :controller => "movies", :action => "index" }) + get("/movies/new", { :controller => "movies", :action => "new" }) + + get("/movies/:id", { :controller => "movies", :action => "show" }) + + # UPDATE + + patch("/movies/:id", { :controller => "movies", :action => "update" }) + + # DELETE + delete("/movies/:id", { :controller => "movies", :action => "destroy" }) + + #------------------------------ + # For details on the DSL available within this file, see https://guides.rubyonrails.org/routing.html end diff --git a/db/migrate/20230412172437_create_movies.rb b/db/migrate/20230412172437_create_movies.rb new file mode 100644 index 0000000..65fc80f --- /dev/null +++ b/db/migrate/20230412172437_create_movies.rb @@ -0,0 +1,11 @@ +class CreateMovies < ActiveRecord::Migration[6.1] + def change + create_table :movies do |t| + t.string :title + t.text :description + t.boolean :released + + t.timestamps + end + end +end diff --git a/db/migrate/20230707161607_create_books.rb b/db/migrate/20230707161607_create_books.rb new file mode 100644 index 0000000..e648925 --- /dev/null +++ b/db/migrate/20230707161607_create_books.rb @@ -0,0 +1,11 @@ +class CreateBooks < ActiveRecord::Migration[6.1] + def change + create_table :books do |t| + t.string :title + t.text :description + t.boolean :released + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 4603022..dff5c0e 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,25 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 2023_07_07_161607) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "books", force: :cascade do |t| + t.string "title" + t.text "description" + t.boolean "released" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + + create_table "movies", force: :cascade do |t| + t.string "title" + t.text "description" + t.boolean "released" + t.datetime "created_at", precision: 6, null: false + t.datetime "updated_at", precision: 6, null: false + end + end diff --git a/test/controllers/books_controller_test.rb b/test/controllers/books_controller_test.rb new file mode 100644 index 0000000..bf6ebbc --- /dev/null +++ b/test/controllers/books_controller_test.rb @@ -0,0 +1,48 @@ +require "test_helper" + +class BooksControllerTest < ActionDispatch::IntegrationTest + setup do + @book = books(:one) + end + + test "should get index" do + get books_url + assert_response :success + end + + test "should get new" do + get new_book_url + assert_response :success + end + + test "should create book" do + assert_difference('Book.count') do + post books_url, params: { book: { description: @book.description, released: @book.released, title: @book.title } } + end + + assert_redirected_to book_url(Book.last) + end + + test "should show book" do + get book_url(@book) + assert_response :success + end + + test "should get edit" do + get edit_book_url(@book) + assert_response :success + end + + test "should update book" do + patch book_url(@book), params: { book: { description: @book.description, released: @book.released, title: @book.title } } + assert_redirected_to book_url(@book) + end + + test "should destroy book" do + assert_difference('Book.count', -1) do + delete book_url(@book) + end + + assert_redirected_to books_url + end +end diff --git a/test/fixtures/books.yml b/test/fixtures/books.yml new file mode 100644 index 0000000..5e5594a --- /dev/null +++ b/test/fixtures/books.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + description: MyText + released: false + +two: + title: MyString + description: MyText + released: false diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml new file mode 100644 index 0000000..5e5594a --- /dev/null +++ b/test/fixtures/movies.yml @@ -0,0 +1,11 @@ +# Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + description: MyText + released: false + +two: + title: MyString + description: MyText + released: false diff --git a/test/models/book_test.rb b/test/models/book_test.rb new file mode 100644 index 0000000..69ab9de --- /dev/null +++ b/test/models/book_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class BookTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb new file mode 100644 index 0000000..c81cd39 --- /dev/null +++ b/test/models/movie_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +class MovieTest < ActiveSupport::TestCase + # test "the truth" do + # assert true + # end +end diff --git a/test/system/books_test.rb b/test/system/books_test.rb new file mode 100644 index 0000000..4e73445 --- /dev/null +++ b/test/system/books_test.rb @@ -0,0 +1,47 @@ +require "application_system_test_case" + +class BooksTest < ApplicationSystemTestCase + setup do + @book = books(:one) + end + + test "visiting the index" do + visit books_url + assert_selector "h1", text: "Books" + end + + test "creating a Book" do + visit books_url + click_on "New Book" + + fill_in "Description", with: @book.description + check "Released" if @book.released + fill_in "Title", with: @book.title + click_on "Create Book" + + assert_text "Book was successfully created" + click_on "Back" + end + + test "updating a Book" do + visit books_url + click_on "Edit", match: :first + + fill_in "Description", with: @book.description + check "Released" if @book.released + fill_in "Title", with: @book.title + click_on "Update Book" + + assert_text "Book was successfully updated" + click_on "Back" + end + + test "destroying a Book" do + visit books_url + page.accept_confirm do + click_on "Destroy", match: :first + end + + assert_text "Book was successfully destroyed" + end +end