diff --git a/.rake_tasks~ b/.rake_tasks~ new file mode 100644 index 0000000..a3efe23 --- /dev/null +++ b/.rake_tasks~ @@ -0,0 +1,40 @@ +about +app:template +app:update +assets:clean[keep] +assets:clobber +assets:environment +assets:precompile +cache_digests:dependencies +cache_digests:nested_dependencies +db:create +db:drop +db:environment:set +db:fixtures:load +db:migrate +db:migrate:status +db:rollback +db:schema:cache:clear +db:schema:cache:dump +db:schema:dump +db:schema:load +db:seed +db:setup +db:structure:dump +db:structure:load +db:version +dev:cache +initializers +log:clear +middleware +notes +notes:custom +restart +routes +secret +stats +test +test:db +time:zones[country_or_offset] +tmp:clear +tmp:create diff --git a/Gemfile b/Gemfile index c715376..57ee8bb 100644 --- a/Gemfile +++ b/Gemfile @@ -16,6 +16,7 @@ gem 'bootstrap-sass', '~> 3.3.6' gem 'bcrypt', '~> 3.1.7' gem 'will_paginate', '~> 3.0.7' gem 'bootstrap-will_paginate', '~> 0.0.10' +gem 'rails-controller-testing' gem 'sass-rails', '~> 5.0' # Use Uglifier as compressor for JavaScript assets gem 'uglifier', '>= 1.3.0' diff --git a/Gemfile.lock b/Gemfile.lock index f3e00f1..3a32d56 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -105,6 +105,10 @@ GEM bundler (>= 1.3.0, < 2.0) railties (= 5.0.1) sprockets-rails (>= 2.0.0) + rails-controller-testing (1.0.1) + actionpack (~> 5.x) + actionview (~> 5.x) + activesupport (~> 5.x) rails-dom-testing (2.0.2) activesupport (>= 4.2.0, < 6.0) nokogiri (~> 1.6) @@ -180,6 +184,7 @@ DEPENDENCIES pg puma (~> 3.0) rails (~> 5.0.1) + rails-controller-testing rails_12factor sass-rails (~> 5.0) spring diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb new file mode 100644 index 0000000..da6c1fa --- /dev/null +++ b/app/controllers/categories_controller.rb @@ -0,0 +1,27 @@ +class CategoriesController < ApplicationController + def index + @categories = Category.paginate(page: params[:page], per_page: 5) + end + + def new + @category = Category.new + end + + def create + @category = Category.new(category_params) + if @category.save + flash[:success] = "Category created successfully." + redirect_to categories_path + else + render 'new' + end + end + + def show + end + + private + def category_params + params.require(:category).permit(:name) + end +end diff --git a/app/models/category.rb b/app/models/category.rb new file mode 100644 index 0000000..67fb1b8 --- /dev/null +++ b/app/models/category.rb @@ -0,0 +1,4 @@ +class Category < ActiveRecord::Base + validates :name, presence: true, length: { minimum: 3, maximum: 25 } + validates_uniqueness_of :name +end diff --git a/app/views/categories/_form.html.erb b/app/views/categories/_form.html.erb new file mode 100644 index 0000000..ad86efb --- /dev/null +++ b/app/views/categories/_form.html.erb @@ -0,0 +1,18 @@ +<%= render 'shared/errors', obj: @category %> + +<%= form_for(@category, :html => {class: "form-horizontal", role: 'form'}) do |f| %> +
+
+ <%= f.label :category %> +
+
+ <%= f.text_field :name, class: "form-control", placeholder: "Enter category name", autofocus: true %> +
+
+
+
+ <%= f.submit "Create", class: 'btn btn-primary home-btn' %> + <%= link_to "Back to Articles List", articles_path, class: 'btn btn-secondary cancel-btn' %> +
+
+<% end %> diff --git a/app/views/categories/index.html.erb b/app/views/categories/index.html.erb new file mode 100644 index 0000000..9cb13b3 --- /dev/null +++ b/app/views/categories/index.html.erb @@ -0,0 +1,16 @@ +

Listing all categories

+ +
+ <% @categories.each do |category| %> + + <% end %> + <%= will_paginate %> +
diff --git a/app/views/categories/new.html.erb b/app/views/categories/new.html.erb new file mode 100644 index 0000000..a94f0b4 --- /dev/null +++ b/app/views/categories/new.html.erb @@ -0,0 +1,3 @@ +

Create Category

+ +<%= render 'form' %> diff --git a/app/views/categories/show.html.erb b/app/views/categories/show.html.erb new file mode 100644 index 0000000..e69de29 diff --git a/config/routes.rb b/config/routes.rb index cd8ad8b..7ce9a3f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,10 +2,15 @@ # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html root 'pages#home' get 'about', to: 'pages#about' + + resources :articles + get 'signup', to: 'users#new' + resources :users, except: [:new] + get 'login', to: 'sessions#new' post 'login', to: 'sessions#create' delete 'logout', to: 'sessions#destroy' - resources :users, except: [:new] - resources :articles + + resources :categories, except: [:destroy] end diff --git a/db/migrate/20170228143327_create_category.rb b/db/migrate/20170228143327_create_category.rb new file mode 100644 index 0000000..d2f3e46 --- /dev/null +++ b/db/migrate/20170228143327_create_category.rb @@ -0,0 +1,8 @@ +class CreateCategory < ActiveRecord::Migration[5.0] + def change + create_table :categories do |t| + t.string :name + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index a2f8e5d..bd1e639 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170228021927) do +ActiveRecord::Schema.define(version: 20170228143327) do create_table "articles", force: :cascade do |t| t.string "title" @@ -20,6 +20,12 @@ t.integer "user_id" end + create_table "categories", force: :cascade do |t| + t.string "name" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + create_table "users", force: :cascade do |t| t.string "username" t.string "email" diff --git a/test/controllers/categories_controller_test.rb b/test/controllers/categories_controller_test.rb new file mode 100644 index 0000000..c8fb569 --- /dev/null +++ b/test/controllers/categories_controller_test.rb @@ -0,0 +1,23 @@ +require 'test_helper' + +class CategoriesControllerTest < ActionController::TestCase + + def setup + @category = Category.create(name: "sports") + end + + test 'should get category index' do + get :index + assert_response :success + end + + test 'should get category new' do + get :new + assert_response :success + end + + test 'should get category show' do + get :show, params: { id: @category.id } + assert_response :success + end +end diff --git a/test/integration/create_categories_test.rb b/test/integration/create_categories_test.rb new file mode 100644 index 0000000..690dcf6 --- /dev/null +++ b/test/integration/create_categories_test.rb @@ -0,0 +1,26 @@ +require 'test_helper' + +class CreateCategoriesTest < ActionDispatch::IntegrationTest + test "get new category test and create category" do + get new_category_path + assert_template 'categories/new' + assert_difference 'Category.count', 1 do + #post_via_redirect categories_path, params: { category: { name: "sports" } } + post categories_path, params: { category: { name: "sports" } } + follow_redirect! + end + assert_template 'categories/index' + assert_match "sports", response.body + end + + test "invalid category submission results in failure" do + get new_category_path + assert_template 'categories/new' + assert_no_difference 'Category.count' do + post categories_path, params: { category: { name: "" } } + end + assert_template 'categories/new' + assert_select 'h2.panel-title' + assert_select 'div.panel-body' + end +end diff --git a/test/integration/list_categories_test.rb b/test/integration/list_categories_test.rb new file mode 100644 index 0000000..993b307 --- /dev/null +++ b/test/integration/list_categories_test.rb @@ -0,0 +1,16 @@ +require 'test_helper' + +class ListCategoriesTest < ActionDispatch::IntegrationTest + + def setup + @category = Category.create(name: "sports") + @category2 = Category.create(name: "programming") + end + + test "should show categories listing" do + get categories_path + assert_template 'categories/index' + assert_select 'a[href=?]', category_path(@category), text: @category.name + assert_select 'a[href=?]', category_path(@category2), text: @category2.name + end +end diff --git a/test/models/category_test.rb b/test/models/category_test.rb new file mode 100644 index 0000000..f8ecd82 --- /dev/null +++ b/test/models/category_test.rb @@ -0,0 +1,34 @@ +require 'test_helper' + +class CategoryTest < ActiveSupport::TestCase + + def setup + @category = Category.new(name: "sports") + end + + test "category should be valid" do + assert @category.valid? + end + + test 'category name should be present' do + @category.name = "" + assert_not @category.valid? + end + + test 'category name should be unique' do + @category.save + category2 = Category.new(name: "sports") + + assert_not category2.valid? + end + + test 'category name should be too long' do + @category.name = "a" * 26 + assert_not @category.valid? + end + + test 'category name should be too short' do + @category.name = "aa" + assert_not @category.valid? + end +end