Permalink
Browse files

Merge branch 'master' of git://github.com/wlodars/jobberrails into wl…

…oards/master
  • Loading branch information...
2 parents 8df1d94 + 66cab3a commit 04221122097871b454bb0a423f6d57b114316389 Ivan Acosta-Rubio committed Jul 11, 2008
Showing with 991 additions and 49 deletions.
  1. +78 −0 app/controllers/admin/categories_controller.rb
  2. +39 −0 app/controllers/admin/jobs_controller.rb
  3. +12 −0 app/controllers/application.rb
  4. +27 −0 app/controllers/sessions_controller.rb
  5. +41 −0 app/helpers/admin/categories_helper.rb
  6. +33 −0 app/helpers/admin/jobs_helper.rb
  7. +3 −0 app/helpers/application_helper.rb
  8. +2 −2 app/helpers/categories_helper.rb
  9. +1 −1 app/helpers/jobs_helper.rb
  10. +11 −0 app/helpers/sessions_helper.rb
  11. +20 −0 app/models/admin.rb
  12. +4 −1 app/models/category.rb
  13. +14 −0 app/views/admin/categories/_category.html.haml
  14. +4 −0 app/views/admin/categories/_list.html.haml
  15. +6 −0 app/views/admin/categories/create.js.rjs
  16. +10 −0 app/views/admin/categories/destroy.js.rjs
  17. +11 −0 app/views/admin/categories/index.html.haml
  18. +2 −0 app/views/admin/categories/saveorder.js.rjs
  19. +3 −0 app/views/admin/categories/show.html.haml
  20. +5 −0 app/views/admin/categories/update.js.rjs
  21. +25 −0 app/views/admin/jobs/_jobs_table.html.haml
  22. +2 −0 app/views/admin/jobs/destroy.js.rjs
  23. +2 −0 app/views/admin/jobs/index.html.haml
  24. +51 −0 app/views/admin/jobs/show.html.haml
  25. +2 −0 app/views/admin/jobs/update.js.rjs
  26. +4 −0 app/views/layouts/_admin_flash_boxes.html.haml
  27. +14 −0 app/views/layouts/_admin_header.html.haml
  28. +23 −0 app/views/layouts/admin.html.haml
  29. +1 −1 app/views/layouts/application.html.haml
  30. 0 app/views/session/_login_status.html.haml
  31. +6 −0 app/views/sessions/_login_status.html.haml
  32. +12 −0 app/views/sessions/new.html.haml
  33. +11 −4 config/routes.rb
  34. +4 −0 db/fixtures/admins.rb
  35. +15 −0 db/migrate/20080703181307_create_admins.rb
  36. +8 −1 db/schema.rb
  37. BIN public/images/icon-delete.png
  38. 0 public/images/icon_accept.gif
  39. BIN public/images/icon_activate.gif
  40. +159 −0 public/stylesheets/styles.css
  41. +11 −0 test/fixtures/admins.yml
  42. +13 −6 test/fixtures/categories.yml
  43. +6 −6 test/fixtures/job_types.yml
  44. +22 −18 test/fixtures/jobs.yml
  45. +4 −6 test/fixtures/locations.yml
  46. +70 −0 test/functional/admin/categories_controller_test.rb
  47. +43 −0 test/functional/admin/jobs_controller_test.rb
  48. +5 −3 test/functional/jobs_controller_test.rb
  49. +30 −0 test/functional/sessions_controller_test.rb
  50. +99 −0 test/integration/administrative_panel_test.rb
  51. +3 −0 test/test_helper.rb
  52. +20 −0 test/unit/admin_test.rb
View
78 app/controllers/admin/categories_controller.rb
@@ -0,0 +1,78 @@
+class Admin::CategoriesController < ApplicationController
+ before_filter :login_required
+ layout 'admin'
+
+ # GET /admin/categories
+ def index
+ @categories = Category.list
+ end
+
+ # GET /admin/categories/1
+ def show
+ @category = Category.find_by_value(params[:id])
+ @jobs = @category.jobs.find_all_by_is_active(true, :order => "created_at DESC")
+ end
+
+ # POST /admin/categories
+ def create
+ max_position = Category.find_by_sql "SELECT MAX(position) as position FROM categories"
+ max_id = Category.find_by_sql "SELECT MAX(id) as id FROM categories"
+ @category = Category.new(:name => 'New category', :value => "newcategory#{max_id[0].id + 1}", :position => max_position[0].position + 1)
+ @category.save
+ flash_notice("Category has been added")
+
+ respond_to do |format|
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/create.js.rjs
+ end
+ end
+
+ # PUT /admin/categories/1
+ def update
+ @category = Category.find(params[:id])
+ flash_notice("Category has been updated")
+
+ respond_to do |format|
+ if @category.update_attributes(:name => params[:name], :value => params[:url])
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/update.js.rjs
+ else
+ format.html { redirect_to admin_categories_url }
+ format.js {
+ render :update do |page|
+ @category.reload
+ page.alert @category.errors.full_messages.join("\n")
+ page.replace("category_#{@category.id}", :partial => 'admin/categories/category', :category => @category)
+ page.sortable 'categoriesContainer', :tag => 'div', :url => saveorder_admin_categories_path
+ end
+ }
+ end
+ end
+ end
+
+ # PUT /admin/categories/saveorder
+ def saveorder
+ params[:categoriesContainer].each_with_index do |id, position|
+ category = Category.find(id)
+ category.update_attribute('position', position)
+ end
+ flash_notice("Categories order changed. Saving ...")
+
+ respond_to do |format|
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/saveorder.js.rjs
+ end
+ end
+
+ # DELETE /admin/categories/1
+ def destroy
+ @category = Category.find(params[:id])
+ @category.destroy if @category.jobs.empty?
+ flash_notice("Category has been deleted")
+
+ respond_to do |format|
+ format.html { redirect_to admin_categories_url }
+ format.js # admin/categories/destroy.js.rjs
+ end
+ end
+end
View
39 app/controllers/admin/jobs_controller.rb
@@ -0,0 +1,39 @@
+class Admin::JobsController < ApplicationController
+ before_filter :login_required
+ layout 'admin'
+
+ # GET /admin/jobs
+ def index
+ @jobs = Job.find_all_by_is_active(false, :order => 'updated_at DESC')
+ end
+
+ # GET /admin/jobs/1
+ def show
+ @job = Job.find(params[:id])
+ end
+
+ # PUT /admin/jobs/1
+ def update
+ @job = Job.find(params[:id])
+ flash_notice("Job has been activated/deactivated")
+
+ respond_to do |format|
+ if @job.update_attributes(:is_active => @job.is_active ? false : true)
+ format.html { redirect_to admin_jobs_url }
+ format.js # admin/jobs/update.js.rjs
+ end
+ end
+ end
+
+ # DELETE /admin/jobs/1
+ def destroy
+ @job = Job.find(params[:id])
+ @job.destroy
+ flash_notice("Job has been deleted")
+
+ respond_to do |format|
+ format.html { redirect_to admin_jobs_url }
+ format.js # admin/jobs/destroy.js.rjs
+ end
+ end
+end
View
12 app/controllers/application.rb
@@ -13,7 +13,19 @@ class ApplicationController < ActionController::Base
# Uncomment this to filter the contents of submitted sensitive data parameters
# from your application log (in this case, all fields with names like "password").
filter_parameter_logging :password
+
+ def login_required
+ unless session[:admin]
+ flash[:notice] = "Please log in."
+ redirect_to login_url
+ end
+ end
+ def flash_notice(string)
+ flash[:notice] = string
+ flash.discard(:notice)
+ end
+
protected
def production?
ENV["RAILS_ENV"] == "production"
View
27 app/controllers/sessions_controller.rb
@@ -0,0 +1,27 @@
+class SessionsController < ApplicationController
+ layout 'admin'
+
+ def new
+ if session[:admin]
+ redirect_to admin_url
+ end
+ end
+
+ def create
+ admin = Admin.authenticate(params[:login], params[:password])
+ if admin
+ session[:admin] = admin
+ flash[:notice] = "You are logged as #{admin.login}"
+ redirect_to admin_url
+ else
+ flash[:error] = "Invalid login or password!"
+ redirect_to login_url
+ end
+ end
+
+ def destroy
+ reset_session
+ flash[:notice] = "You've been logged out."
+ redirect_to login_url
+ end
+end
View
41 app/helpers/admin/categories_helper.rb
@@ -0,0 +1,41 @@
+module Admin::CategoriesHelper
+ def admin_category_nav_item(category)
+ category_nav_item(category, true)
+ end
+
+ def show_save_category(category_id)
+ "Element.show('saveCategory#{category_id}')"
+ end
+
+ def link_to_delete_category(category_id)
+ link_to_remote(image_tag("icon-delete.png", :alt => 'Delete') + " Delete", {
+ :url => admin_category_url(category_id),
+ :confirm => 'Are you sure you want to delete this category?',
+ :method => :delete },
+ { :class => 'deleteCategory'})
+ end
+
+ def link_to_save_category(category_id)
+ link_to_remote(image_tag("disk.png", :alt => 'Save') + " Save", {
+ :url => admin_category_url(category_id),
+ :method => :put,
+ :with => "'name='+$F('name[#{category_id}]')+'&url='+$F('url[#{category_id}]')" },
+ { :id => "saveCategory#{category_id}",
+ :class => 'saveCategory', :style => 'display:none;' })
+ end
+
+ def sortable_element_categories_container
+ sortable_element "categoriesContainer",
+ :url => saveorder_admin_categories_path,
+ :tag => "div",
+ :complete => visual_effect(:highlight, 'categoriesContainer')
+ end
+
+ def link_to_add_category
+ link_to_remote image_tag("add.png", :alt => 'Add') + " Add new category",
+ :url => admin_categories_path,
+ :method => :post,
+ :loading => "Element.show('overlay')",
+ :complete => "Element.hide('overlay');"
+ end
+end
View
33 app/helpers/admin/jobs_helper.rb
@@ -0,0 +1,33 @@
+module Admin::JobsHelper
+ def activation_image_tag(job)
+ activate = "activate"
+ unless job.is_active
+ activate = "de" + activate
+ end
+ image_tag("icon_#{activate}.gif",
+ :alt => activate.capitalize,
+ :id => "activate_#{job.id}")
+ end
+
+ def link_to_activate_deactivate_job(job)
+ link_to_remote(activation_image_tag(job), {
+ :url => admin_job_url(job.id),
+ :method => :put,
+ :loading => "Element.hide('activ_butt_#{job.id}');Element.show('loading_#{job.id}')",
+ :complete => "Element.hide('loading_#{job.id}');Element.show('activ_butt_#{job.id}')"},
+ { :id => "activ_butt_#{job.id}"} )
+ end
+
+ def link_to_delete_job(job_id)
+ link_to_remote(image_tag("icon-delete.png", :alt => 'Delete'),
+ :url => admin_job_url(job_id),
+ :confirm => 'Are you sure you want to delete this post?',
+ :method => :delete)
+ end
+
+ def saving_job_image_tag(job_id)
+ image_tag("ajax-loader.gif", :alt => "Saving...",
+ :style => 'display:none',
+ :id => "loading_#{job_id}")
+ end
+end
View
3 app/helpers/application_helper.rb
@@ -23,4 +23,7 @@ def error_message_for(record, attribute, error_msg = nil)
end
end
+ def display_notice
+ page.insert_html :after, 'footer', :partial => 'layouts/admin_flash_boxes'
+ end
end
View
4 app/helpers/categories_helper.rb
@@ -1,5 +1,5 @@
module CategoriesHelper
- def category_nav_item(category)
+ def category_nav_item(category, admin = false)
li_options = {}
@@ -8,7 +8,7 @@ def category_nav_item(category)
li_options[:class] = "selected"
end
- link = link_to "<span>#{category.name}</span><span class='cnr'>&nbsp;</span>", category_url(category), :title => category.name
+ link = link_to "<span>#{category.name}</span><span class='cnr'>&nbsp;</span>", (admin ? admin_category_url(category) : category_url(category)), :title => category.name
return content_tag(:li, link, li_options)
end
View
2 app/helpers/jobs_helper.rb
@@ -17,7 +17,7 @@ def job_location_text(job)
puts ", #{job.location}"
elsif !job.location.blank?
haml_tag :span, "in", :class => "la"
- puts " #{job.location}"
+ puts " #{job.location.name}"
end
end
end
View
11 app/helpers/sessions_helper.rb
@@ -0,0 +1,11 @@
+module SessionsHelper
+ # checks if user is logged in
+ def logged_in?
+ session[:admin] ? true : false
+ end
+
+ # returns currently logged admin
+ def current_user
+ session[:admin]
+ end
+end
View
20 app/models/admin.rb
@@ -0,0 +1,20 @@
+require 'digest/sha1'
+
+class Admin < ActiveRecord::Base
+ validates_length_of :login, :within => 3..40
+ validates_length_of :password, :within => 5..40
+ validates_presence_of :login, :password
+ validates_uniqueness_of :login
+
+ attr_protected :id
+
+ def self.authenticate(login, pass)
+ a = find_by_login(login)
+ a && Admin.encrypt(pass) == a.password ? a : nil
+ end
+
+ protected
+ def self.encrypt(pass)
+ Digest::SHA1.hexdigest(pass)
+ end
+end
View
5 app/models/category.rb
@@ -1,6 +1,9 @@
class Category < ActiveRecord::Base
has_many :jobs
-
+
+ validates_presence_of :name, :value
+ validates_uniqueness_of :value
+
def to_param
self.value
end
View
14 app/views/admin/categories/_category.html.haml
@@ -0,0 +1,14 @@
+.categoryItem{:id => "category_#{category.id}"}
+ .categoryHandle
+ .categoryWrapper
+ .categoryManagement{:style => 'float:right;width:10%;'}
+ = link_to_delete_category(category.id)
+ = link_to_save_category(category.id)
+ %label
+ %span Name:
+ = text_field_tag "name[#{category.id}]", category.name, :size => 60
+ = observe_field "name[#{category.id}]", :frequency => 1, :function => show_save_category(category.id)
+ %label
+ %span URL:
+ = text_field_tag "url[#{category.id}]", category.value, :size => 60
+ = observe_field "url[#{category.id}]", :frequency => 1, :function => show_save_category(category.id)
View
4 app/views/admin/categories/_list.html.haml
@@ -0,0 +1,4 @@
+%ul
+ - Category.list.each do |category|
+ = admin_category_nav_item(category)
+= clear
View
6 app/views/admin/categories/create.js.rjs
@@ -0,0 +1,6 @@
+page.insert_html :bottom, 'categoriesContainer', :partial => 'admin/categories/category'
+page.sortable 'categoriesContainer', :tag => 'div', :url => saveorder_admin_categories_path,
+ :complete => visual_effect(:highlight, 'categoriesContainer')
+@category = nil
+page.replace_html "categories", :partial => 'admin/categories/list'
+page.display_notice
View
10 app/views/admin/categories/destroy.js.rjs
@@ -0,0 +1,10 @@
+if @category.jobs.empty?
+ page["category_#{@category.id}"].visual_effect :fade, "category_#{@category.id}"
+ page.delay(1) do
+ page.remove "category_#{@category.id}"
+ end
+ page.replace_html "categories", :partial => 'admin/categories/list'
+ page.display_notice
+else
+ page.alert("You cannot delete this category because there are jobs in this category!")
+end
View
11 app/views/admin/categories/index.html.haml
@@ -0,0 +1,11 @@
+%h2 Categories
+
+#categoriesContainer
+ = partial @categories
+
+= sortable_element_categories_container
+
+#overlay{:style => "display: none; top: 145px; left: 157px;height: 72px;"}
+ = image_tag("ajax-loader.gif", :alt => "Loading...")
+%p
+ = link_to_add_category
View
2 app/views/admin/categories/saveorder.js.rjs
@@ -0,0 +1,2 @@
+page.replace_html "categories", :partial => 'admin/categories/list'
+page.display_notice
View
3 app/views/admin/categories/show.html.haml
@@ -0,0 +1,3 @@
+.job-listings
+ %h2= "Jobs for " + @category.name.pluralize
+ = partial "admin/jobs/jobs_table", :jobs => @jobs
View
5 app/views/admin/categories/update.js.rjs
@@ -0,0 +1,5 @@
+page["category_#{@category.id}"].visual_effect :pulsate, "category_#{@category.id}"
+page.hide "saveCategory#{@category.id}"
+@category = nil
+page.replace_html "categories", :partial => 'admin/categories/list'
+page.display_notice
View
25 app/views/admin/jobs/_jobs_table.html.haml
@@ -0,0 +1,25 @@
+- unless jobs.empty?
+ -# Display Job Posts
+ %table.job-posts{:cellspacing => 0}
+ - jobs.each do |job|
+ %tr.job_item{:id => "job_" + job.id.to_s}
+ %td
+ = job_type_image(job.job_type)
+ = link_to job.title, admin_job_url(job), :title => job.title
+ %span.la at
+ = job_location_text(job)
+
+ -# display time
+ %td.time-posted
+ = image_tag "clock.gif", :class => "vert-middle"
+ = job.created_at.to_s(:job_listing)
+
+ %td{:style => 'text-align:left;width:15%'}
+ -# activate/deactivate link
+ = link_to_activate_deactivate_job(job)
+ = saving_job_image_tag(job.id)
+ -# delete link
+ = link_to_delete_job(job.id)
+
+- else
+ #no-ads No jobs, yet.
View
2 app/views/admin/jobs/destroy.js.rjs
@@ -0,0 +1,2 @@
+page["job_#{@job.id}"].visual_effect :fade, "job_#{@job.id}"
+page.display_notice
View
2 app/views/admin/jobs/index.html.haml
@@ -0,0 +1,2 @@
+%h2 Inactive jobs
+= partial "admin/jobs/jobs_table", :jobs => @jobs
View
51 app/views/admin/jobs/show.html.haml
@@ -0,0 +1,51 @@
+- if @job
+ = br
+ = link_to '« go back', admin_category_url(@job.category)
+ #job_details
+ -# display job outdated warning if applicable
+ - if @job.created_at < 40.days.ago
+ .old-ad
+ This job ad has been posted over 40 days ago...
+
+ -# show applicants count
+ .applied-to-job
+ = @job.job_applicants.size
+ %p
+ - if @job.job_applicants.size != 1
+ applicants
+ - else
+ applicant
+
+ -# show job title
+ %h2
+ = job_type_image(@job.job_type)
+ = @job.title
+
+ -# show job location
+ %p
+ %span.fading at
+ - unless @job.url.blank? or @job.url == "http://"
+ = link_to @job.company, @job.url
+ - else
+ %strong= @job.company
+
+ - if @job.located_at == "Anywhere"
+ %strong= "(" + @job.located_at + ")"
+ - else
+ %span.fading in
+ %strong= @job.located_at
+
+ -# show job description
+ .job-description
+ = @job.description_html
+ = br
+
+ #job_bottom
+ #number_views
+ Published at:
+ %strong= @job.created_at.to_s(:post_listing_date)
+ = br
+ Viewed:
+ %strong= pluralize(@job.view_count, "time")
+ = clear
+
View
2 app/views/admin/jobs/update.js.rjs
@@ -0,0 +1,2 @@
+page.replace "activate_#{@job.id}", activation_image_tag(@job)
+page.display_notice
View
4 app/views/layouts/_admin_flash_boxes.html.haml
@@ -0,0 +1,4 @@
+- flash.each do |key, msg|
+ = content_tag :div, msg, :class => [key], :id => "#{key}_message"
+ - content_tag :script, :type => "text/javascript" do
+ = "setTimeout(\"new Effect.Fade('#{key}_message');\", 2000);"
View
14 app/views/layouts/_admin_header.html.haml
@@ -0,0 +1,14 @@
+#header
+ %h1#logo= link_to AppConfig.site_name, root_path
+ - if logged_in?
+ %ul#top{:style => 'padding-top:40px'}
+ %li= link_to "Pages", "#"
+ = bull
+ %li= link_to "Categories", admin_categories_path
+ = bull
+ %li= link_to "Change your password", "#"
+ = bull
+ %li= link_to "Logout", logout_path
+
+- unless logged_in?
+ #categs-nav
View
23 app/views/layouts/admin.html.haml
@@ -0,0 +1,23 @@
+!!! Strict
+%html{html_attrs}
+ %head
+ %meta{"http-equiv" => "Content-type", "content" => "text/html; charset=utf-8"}
+
+ = title :site => AppConfig.site_name
+ = stylesheets
+ = javascripts
+
+ = feed_links
+
+ %body
+ #container
+ = partial "layouts/admin_header"
+ - if logged_in?
+ #categories
+ = partial "admin/categories/list"
+
+ #content
+ = yield
+
+ #footer
+ = render :partial => 'layouts/admin_flash_boxes'
View
2 app/views/layouts/application.html.haml
@@ -11,7 +11,7 @@
%body
#container
- = partial "session/login_status"
+ = partial "sessions/login_status"
= partial "layouts/header"
= partial "search/searchbox"
= partial "categories/list"
View
0 app/views/session/_login_status.html.haml
No changes.
View
6 app/views/sessions/_login_status.html.haml
@@ -0,0 +1,6 @@
+.login_status
+ - if logged_in?
+ = "You are logged as #{current_user.login} " + link_to('Logout', logout_path)
+ = link_to '/ Admin tools', admin_path
+ - else
+ = link_to 'Login', login_path
View
12 app/views/sessions/new.html.haml
@@ -0,0 +1,12 @@
+- form_tag session_path, :id => 'publish_form' do
+ %fieldset
+ %legend Login
+ %table{:border => 0, :cellspacing => 2, :cellpadding => 2}
+ %tr
+ %td.publish-label Username:
+ %td= text_field_tag :login, params[:login], :size => 40
+ %tr
+ %td.publish-label Password:
+ %td= password_field_tag :password, params[:password], :size => 40
+ %fieldset
+ = submit_tag 'Login', :id => 'submit'
View
15 config/routes.rb
@@ -1,5 +1,9 @@
ActionController::Routing::Routes.draw do |map|
+ map.login '/login', :controller => 'sessions', :action => 'new'
+ map.logout '/logout', :controller => 'sessions', :action => 'destroy'
+ map.resource :session
+
map.resources :jobs, :member => {
:verify => :any,
:apply => :post,
@@ -11,10 +15,13 @@
map.resources :categories
map.resource :search, :controller => "Search"
- # map.namespace :admin do |admin|
- # # Directs /admin/jobs/* to Admin::JobsController (app/controllers/admin/jobs_controller.rb)
- # admin.resources :jobs
- # end
+ map.admin '/admin', :controller => 'admin/jobs', :action => 'index'
+ map.namespace :admin do |admin|
+ # Directs /admin/jobs/* to Admin::JobsController (app/controllers/admin/jobs_controller.rb)
+ admin.resources :jobs
+ # Directs /admin/categories/* to Admin::CategoriesController (app/controllers/admin/categories_controller.rb)
+ admin.resources :categories, :collection => {:saveorder => :put}
+ end
map.root :controller => "jobs"
View
4 db/fixtures/admins.rb
@@ -0,0 +1,4 @@
+Admin.seed(:login, :password) do |s|
+ s.login = 'admin'
+ s.password = 'd033e22ae348aeb5660fc2140aec35850c4da997' # admin
+end
View
15 db/migrate/20080703181307_create_admins.rb
@@ -0,0 +1,15 @@
+class CreateAdmins < ActiveRecord::Migration
+ def self.up
+ create_table :admins do |t|
+ t.string :login
+ t.string :password
+
+ t.timestamps
+ end
+
+ end
+
+ def self.down
+ drop_table :admins
+ end
+end
View
9 db/schema.rb
@@ -9,7 +9,14 @@
#
# It's strongly recommended to check this file into your version control system.
-ActiveRecord::Schema.define(:version => 20080628140740) do
+ActiveRecord::Schema.define(:version => 20080703181307) do
+
+ create_table "admins", :force => true do |t|
+ t.string "login"
+ t.string "password"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
create_table "categories", :force => true do |t|
t.string "name"
View
BIN public/images/icon-delete.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
0 public/images/icon_accept.gif 100755 → 100644
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
BIN public/images/icon_activate.gif
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
View
159 public/stylesheets/styles.css
@@ -889,3 +889,162 @@ label.request-label {
.error a {color:#8a1f11;}
.notice a {color:#514721;}
.success a {color:#264409;}
+
+.login_status {text-align:right; margin-right: 20px;}
+
+#publish_form {}
+#publish_form fieldset, #promo_form fieldset {
+ background-color: #f5f5f5;
+ border: 1px solid #ccc;
+ margin: 0 0 5px 0;
+ padding: 10px;
+}
+#publish_form fieldset legend {
+ font-weight: bold;
+ color: #555;
+ font-size: 12px;
+}
+#publish_form input, #publish_form textarea, #frm-send-to-friend input, #frm-send-edit-link input, #apply-online input, #apply-online textarea, #promo_form input {
+ border: 1px solid #ccc;
+ padding: 5px;
+ font-size: 12px;
+ font-family: Helvetica, Arial, sans-serif;
+}
+#publish_form input:focus, #search input:hover, #publish_form textarea:focus, #search textarea:hover, #frm-send-to-friend input:focus,
+#frm-send-to-friend input:hover, #frm-send-edit-link input:focus, #frm-send-edit-link input:hover, #apply-online input:focus, #apply-online input:hover, #apply-online textarea:focus, #apply-online textarea:hover, #promo_form input:focus, #promo_form input:hover {
+ border: 1px solid #7F635F;
+}
+#publish_form input#submit, #send-to-friend input#submit, #frm-send-edit-link input#submit, #apply-online input#submit, #promo_form input#submit {
+ background-color: #0099CC;
+ color: #fff;
+ border: 1px solid #009988;
+ cursor: pointer;
+ cursor: hand;
+}
+#publish_form input#submit:hover, #send-to-friend input#submit:hover, #apply-online input#submit:hover, #promo_form input#submit:hover {
+ background-color: #00aaee;
+}
+#publish_form label.small {
+ color: #555;
+ font-size: 12px;
+}
+#publish_form input.no-border {
+ border: 0;
+}
+
+td.publish-label {
+ width: 100px;
+}
+
+div#categs-nav {
+ background:#0099CC none repeat scroll 0% 0%;
+ float:left;
+ font-size:11px;
+ margin-top:25px;
+ padding-bottom:6px;
+ width:950px;
+}
+
+#no-ads {
+ color:#555555;
+ margin-top:10px;
+}
+
+#categoriesContainer {
+ position:relative;
+ width:670px;
+ padding-top:10px;
+ padding-bottom:10px;
+}
+
+.categoryItem {
+ background-color:#F5F5F5;
+ border:1px solid #CCCCCC;
+ margin:0pt 0pt 5px;
+ position:relative;
+ width:650px;
+ margin-left:10px;
+}
+
+.categoryHandle {
+ background:#0099CC none repeat scroll 0% 0%;
+ cursor:move;
+ height:10px;
+ margin-bottom:5px;
+ overflow:hidden;
+}
+
+.categoryWrapper {
+ padding:5px;
+}
+
+.categoryItem label {
+ display:block;
+ margin-bottom:5px;
+}
+
+.categoryItem label span {
+ clear:left;
+ display:block;
+ float:left;
+ font-weight:bold;
+ margin-bottom:5px;
+ width:70px;
+}
+
+a.deleteCategory, a.saveCategory {
+ float: right;
+}
+
+div.footer {
+ background:#F2FCFF url(/images/footer-bg.png) no-repeat scroll center top;
+ color:#888888;
+ float:left;
+ font-size:11px;
+ height:14em;
+ margin-top:30px;
+ padding-top:12px;
+ text-align:center;
+ width:100%;
+}
+
+#overlay {
+ vertical-align:middle;
+ background-color:#FFFFFF;
+ opacity:0.7;
+ width:650px;
+}
+
+#overlay img {
+ left:50%;
+ margin-left:-12px;
+ margin-top:-12px;
+ position:relative;
+ top:50%;
+ z-index:3000;
+}
+
+#notice_message {
+ left:50%;
+ margin-left:-150px;
+ position:absolute;
+ top:0pt;
+ width:300px;
+ background-color:#fff;
+ border:8px solid #eeeeee;
+ font-size:9px;
+ padding-top:10px;
+ text-align:center;
+}
+
+#error_message {
+ left:50%;
+ margin-left:-150px;
+ position:absolute;
+ top:0pt;
+ width:300px;
+ background-color:#fff;
+ border:8px solid #ec0f0f;
+ font-size:9px;
+ padding-top:10px;
+}
View
11 test/fixtures/admins.yml
@@ -0,0 +1,11 @@
+bob:
+ login: bob
+ password: a94a8fe5ccb19ba61c4c0873d391e987982fbbd3 # test
+
+mark:
+ login: mark
+ password: bf5a0cb861642b94cb8635dce9d197d375569e1f # longtest
+
+admin:
+ login: admin
+ password: d033e22ae348aeb5660fc2140aec35850c4da997 # admin
View
19 test/fixtures/categories.yml
@@ -1,7 +1,14 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+programmer:
+ name: Programmers
+ value: programmers
+ position: 1
-# one:
-# column: value
-#
-# two:
-# column: value
+designer:
+ name: Designers
+ value: designers
+ position: 2
+
+administrator:
+ name: Administrators
+ value: administrators
+ position: 3
View
12 test/fixtures/job_types.yml
@@ -1,7 +1,7 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+fulltime:
+ name: Full-time
+ value: fulltime
-# one:
-# column: value
-#
-# two:
-# column: value
+parttime:
+ name: Part-time
+ value: parttime
View
40 test/fixtures/jobs.yml
@@ -1,25 +1,29 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
-
one:
- title: MyString
- description: MyText
- company: MyString
- url: MyString
- apply: MyString
+ title: web developer
+ description: temporary description
+ company: Foo Inc
+ url: http://www.xyz.pl
+ apply: null
is_temp: false
- is_active: false
- outside_location: MyString
- poster_email: MyString
+ is_active: true
+ outside_location:
+ poster_email: temp@temp.us
apply_online: false
+ job_type: fulltime
+ category: programmer
+ location: seatle
two:
- title: MyString
- description: MyText
- company: MyString
- url: MyString
- apply: MyString
- is_temp: false
+ title: graphic
+ description: some description
+ company: Some company
+ url: www.xxx.xx
+ apply: null
+ is_temp: true
is_active: false
- outside_location: MyString
- poster_email: MyString
+ outside_location:
+ poster_email: admin@admin.sd
apply_online: false
+ job_type: parttime
+ category: designer
+ location: tampa
View
10 test/fixtures/locations.yml
@@ -1,7 +1,5 @@
-# Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html
+seatle:
+ name: Seattle, WA
-# one:
-# column: value
-#
-# two:
-# column: value
+tampa:
+ name: Tampa, FL
View
70 test/functional/admin/categories_controller_test.rb
@@ -0,0 +1,70 @@
+require 'test_helper'
+
+class Admin::CategoriesControllerTest < ActionController::TestCase
+ def test_should_show_category_and_active_jobs
+ login_as(:mark)
+ get :show, :id => categories(:programmer).name
+ assert_response :success
+ assert_not_nil assigns(:jobs)
+ assigns(:jobs).each do |job|
+ assert_equal categories(:programmer).name, job.category.name
+ assert job.is_active
+ end
+ end
+
+ def test_should_get_categories
+ login_as(:admin)
+ get :index
+ assert_equal Category.count, assigns(:categories).size
+ end
+
+ def test_should_create_category
+ login_as(:mark)
+ assert_difference('Category.count') do
+ xhr :post, :create
+ end
+ assert_select_rjs :insert_html, :bottom, 'categoriesContainer'
+ end
+
+ def test_should_update_category
+ login_as(:admin)
+ get :index
+ xhr :put, :update, {:id => categories(:programmer).id, :name => "New name", :url => 'new_value23'}
+ assert_response :success
+ categories(:programmer).reload
+ assert_equal('New name', categories(:programmer).name)
+ end
+
+ def test_should_not_update_category
+ login_as(:mark)
+ category = categories(:programmer)
+ xhr :put, :update, {:id => categories(:programmer).id, :name => "Programmers", :url => 'new_value23'}
+ categories(:programmer).reload
+ assert_equal category.name, categories(:programmer).name
+ end
+
+ def test_should_delete_category_without_jobs
+ login_as(:bob)
+ assert_difference('Category.count', -1) do
+ xhr :delete, :destroy, :id => categories(:administrator).id
+ end
+ assert_response :success
+ assert_select_rjs :remove, "category_#{categories(:administrator).id}"
+ end
+
+ def test_should_not_delete_category_with_jobs
+ login_as(:bob)
+ count = Category.count
+ xhr :delete, :destroy, :id => categories(:programmer).id
+ assert_equal(count, Category.count)
+ end
+
+ def test_should_change_order
+ login_as(:mark)
+ xhr :put, :saveorder, :categoriesContainer => [categories(:administrator).id, categories(:programmer).id, categories(:designer).id]
+ categories(:administrator).reload
+ assert_equal 0, categories(:administrator).position
+ categories(:designer).reload
+ assert_equal 2, categories(:designer).position
+ end
+end
View
43 test/functional/admin/jobs_controller_test.rb
@@ -0,0 +1,43 @@
+require 'test_helper'
+
+class Admin::JobsControllerTest < ActionController::TestCase
+ def test_should_get_inactive_jobs_index
+ login_as(:admin)
+ get :index
+ assert_response :success
+ end
+
+ def test_should_destroy_inactive_job
+ login_as(:bob)
+ assert_difference('Job.count', -1) do
+ xhr :delete, :destroy, :id => jobs(:one).id
+ end
+ assert_response :success
+ end
+
+ def test_should_activate_inactive_job
+ login_as(:admin)
+ get :index
+ assert_equal 1, assigns(:jobs).size
+ assert_equal false, jobs(:two).is_active
+ xhr :put, :update, :id => jobs(:two).id
+ assert_response :success
+ jobs(:two).reload
+ assert jobs(:two).is_active
+ get :index
+ assert_equal 0, assigns(:jobs).size
+ end
+
+ def test_should_deactivate_active_job
+ login_as(:admin)
+ get :index
+ assert_equal 1, assigns(:jobs).size
+ assert jobs(:one).is_active
+ xhr :put, :update, :id => jobs(:one).id
+ assert_response :success
+ jobs(:one).reload
+ assert_equal false, jobs(:one).is_active
+ get :index
+ assert_equal 2, assigns(:jobs).size
+ end
+end
View
8 test/functional/jobs_controller_test.rb
@@ -14,10 +14,11 @@ def test_should_get_new
def test_should_create_job
assert_difference('Job.count') do
- post :create, :job => { }
+ post :create, :job => {:title => 'developer', :description => 'Excellent payment! ;)',
+ :company => 'Foo', :poster_email => 'fooinc@temp.com'}
end
- assert_redirected_to job_path(assigns(:job))
+ assert_redirected_to verify_job_path(assigns(:job))
end
def test_should_show_job
@@ -31,7 +32,8 @@ def test_should_get_edit
end
def test_should_update_job
- put :update, :id => jobs(:one).id, :job => { }
+ put :update, :id => jobs(:one).id, :job => { :title => 'developer', :description => 'Excellent payment! ;)',
+ :company => 'Foo', :poster_email => 'fooinc@temp.com'}
assert_redirected_to job_path(assigns(:job))
end
View
30 test/functional/sessions_controller_test.rb
@@ -0,0 +1,30 @@
+require 'test_helper'
+
+class SessionsControllerTest < ActionController::TestCase
+
+ def test_should_login_and_redirect
+ post :create, :login => "bob", :password => "test"
+ assert session[:admin]
+ assert_response :redirect
+ assert_redirected_to admin_jobs_url
+ end
+
+ def test_should_fail_login_and_not_redirect
+ post :create, :login => 'quentin', :password => 'bad password'
+ assert_nil session[:admin]
+ assert_response :success
+ end
+
+ def test_should_login_and_logout
+ post :create, :login => "admin", :password => "admin"
+ assert session[:admin]
+ assert_response :redirect
+ assert_redirected_to admin_jobs_url
+
+ get :destroy
+ assert_nil session[:admin]
+ assert_response :redirect
+ assert_redirected_to login_url
+ end
+
+end
View
99 test/integration/administrative_panel_test.rb
@@ -0,0 +1,99 @@
+require 'test_helper'
+
+class AdministrativePanelTest < ActionController::IntegrationTest
+
+ def test_login_logout
+ get '/admin/jobs'
+ assert_response :redirect
+
+ assert_equal 'Please log in.', flash[:notice]
+
+ post '/session', {:login => 'admin', :password => 'admin'}
+ assert_response :redirect
+
+ assert session[:admin]
+
+ post '/logout'
+ assert_response :redirect
+ assert_nil session[:admin]
+ end
+
+ def test_activate_and_deactivate_jobs
+ login_user
+
+ # activate deactive job
+ put "/admin/jobs/#{jobs(:two).id}"
+ jobs(:two).reload
+ assert jobs(:two).is_active
+
+ # deactivate active job
+ get "/admin/categories/#{jobs(:two).category}"
+ put "/admin/jobs/#{jobs(:two).id}"
+ jobs(:two).reload
+ assert_equal(false, jobs(:two).is_active)
+ assert_equal "Job has been activated/deactivated", flash[:notice]
+
+ logout_user
+ end
+
+ def test_delete_job
+ login_user
+
+ # inactive job
+ delete "/admin/jobs/#{jobs(:two).id}"
+ assert_raise(ActiveRecord::RecordNotFound) { jobs(:two).reload }
+
+ # active job
+ delete "/admin/jobs/#{jobs(:one).id}"
+ assert_raise(ActiveRecord::RecordNotFound) { jobs(:one).reload }
+
+ logout_user
+ end
+
+ def test_manage_categories
+ login_user
+
+ get '/admin/categories'
+ assert_response :success
+
+ count = Category.count
+
+ # add category
+ post '/admin/categories'
+ assert_response :redirect
+ assert_not_equal(count, Category.count)
+
+ # update category name
+ put "/admin/categories/#{categories(:designer).id}", :name => 'New name', :url => categories(:designer).value
+ categories(:designer).reload
+ assert_equal 'New name', categories(:designer).name
+
+ # sort categories
+ put '/admin/categories/saveorder', :categoriesContainer => [categories(:designer).id,categories(:administrator).id,categories(:programmer).id]
+ assert_equal [0,1,2], [categories(:designer).reload.position, categories(:administrator).reload.position,categories(:programmer).reload.position]
+
+ count = Category.count
+ # should not delete category with jobs
+ delete "/admin/categories/#{categories(:designer).id}"
+ assert_response :redirect
+ assert_equal count, Category.count
+
+ # should delete category without jobs
+ delete "/admin/categories/#{categories(:administrator).id}"
+ assert_response :redirect
+ assert_equal count - 1, Category.count
+
+ logout_user
+ end
+
+ private
+ def login_user
+ post '/session', {:login => 'admin', :password => 'admin'}
+ assert_response :redirect
+ end
+
+ def logout_user
+ post '/logout'
+ assert_response :redirect
+ end
+end
View
3 test/test_helper.rb
@@ -35,4 +35,7 @@ class Test::Unit::TestCase
fixtures :all
# Add more helper methods to be used by all tests here...
+ def login_as(admin)
+ @request.session[:admin] = admin ? admins(admin) : nil
+ end
end
View
20 test/unit/admin_test.rb
@@ -0,0 +1,20 @@
+require 'test_helper'
+
+class AdminTest < ActiveSupport::TestCase
+
+ def test_authentication
+
+ assert_not_nil Admin.authenticate("admin", "admin")
+
+ assert_equal admins(:mark), Admin.authenticate("mark", "longtest")
+
+ # wrong username
+ assert_nil Admin.authenticate("adminnn", "admin")
+
+ #wrong password
+ assert_nil Admin.authenticate("bob", "wrongpass")
+
+ #wrong login and pass
+ assert_nil Admin.authenticate("nonbob", "wrongpass")
+ end
+end

0 comments on commit 0422112

Please sign in to comment.