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| %>
+
+
+<% 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