From 151c361a71c0b663c44c6bf5f7d310f1f12a87af Mon Sep 17 00:00:00 2001 From: Petteri Räty Date: Sat, 12 Mar 2011 19:50:20 +0200 Subject: Rename QuestionCategory to Category We have a need for a many to many between questions and categories so start the work by renaming QuestionCategory to just Category. This allows us to add a pivot model with the name QuestionCategory. --- app/controllers/categories_controller.rb | 21 ++++++++++++ app/controllers/question_categories_controller.rb | 21 ------------ app/models/answer.rb | 2 +- app/models/category.rb | 39 ++++++++++++++++++++++ app/models/question.rb | 18 +++++----- app/models/question_category.rb | 39 ---------------------- app/models/question_group.rb | 4 +-- app/models/user.rb | 8 ++--- app/models/user_category.rb | 6 ++-- app/models/user_mailer.rb | 2 +- app/viewhints/user_hints.rb | 2 +- app/views/categories/show.dryml | 6 ++++ app/views/question_categories/show.dryml | 6 ---- app/views/question_groups/category.dryml | 2 +- app/views/taglibs/nav.dryml | 2 +- app/views/taglibs/pages.dryml | 4 +-- db/fixtures/questions-email.yml | 2 +- db/fixtures/questions-multichoice.yml | 2 +- db/fixtures/questions.yml | 22 ++++++------ ...2173240_rename_question_category_to_category.rb | 29 ++++++++++++++++ db/schema.rb | 28 ++++++++-------- db/seeds.rb | 16 ++++----- features/step_definitions/categories_steps.rb | 3 ++ .../step_definitions/question_categories_steps.rb | 6 ---- features/step_definitions/questions_steps.rb | 4 +-- features/step_definitions/users_steps.rb | 10 +++--- spec/factories.rb | 12 +++---- spec/models/answer_spec.rb | 10 +++--- spec/models/category_spec.rb | 31 +++++++++++++++++ spec/models/question_category_spec.rb | 31 ----------------- spec/models/question_group_spec.rb | 8 ++--- spec/models/question_spec.rb | 24 ++++++------- spec/models/user_category_spec.rb | 8 ++--- spec/models/user_mailer_spec.rb | 2 +- spec/models/user_spec.rb | 4 +-- spec/support/factory_orders.rb | 22 ++++++------ 36 files changed, 241 insertions(+), 215 deletions(-) create mode 100644 app/controllers/categories_controller.rb delete mode 100644 app/controllers/question_categories_controller.rb create mode 100644 app/models/category.rb delete mode 100644 app/models/question_category.rb create mode 100644 app/views/categories/show.dryml delete mode 100644 app/views/question_categories/show.dryml create mode 100644 db/migrate/20110312173240_rename_question_category_to_category.rb create mode 100644 features/step_definitions/categories_steps.rb delete mode 100644 features/step_definitions/question_categories_steps.rb create mode 100644 spec/models/category_spec.rb delete mode 100644 spec/models/question_category_spec.rb diff --git a/app/controllers/categories_controller.rb b/app/controllers/categories_controller.rb new file mode 100644 index 0000000..c5749f9 --- /dev/null +++ b/app/controllers/categories_controller.rb @@ -0,0 +1,21 @@ +# Gentoo Recruiters Web App - to help Gentoo recruiters do their job better +# Copyright (C) 2010 Joachim Filip Bartosik +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, version 3 of the License +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +class CategoriesController < ApplicationController + + hobo_model_controller + + auto_actions :all + +end diff --git a/app/controllers/question_categories_controller.rb b/app/controllers/question_categories_controller.rb deleted file mode 100644 index ec63105..0000000 --- a/app/controllers/question_categories_controller.rb +++ /dev/null @@ -1,21 +0,0 @@ -# Gentoo Recruiters Web App - to help Gentoo recruiters do their job better -# Copyright (C) 2010 Joachim Filip Bartosik -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, version 3 of the License -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -class QuestionCategoriesController < ApplicationController - - hobo_model_controller - - auto_actions :all - -end diff --git a/app/models/answer.rb b/app/models/answer.rb index 73e7750..b214ebb 100644 --- a/app/models/answer.rb +++ b/app/models/answer.rb @@ -45,7 +45,7 @@ class Answer < ActiveRecord::Base :joins => :owner, :conditions => { 'users.mentor_id', mentor } } } named_scope :in_category, lambda { |category| { - :joins => :question, :conditions => { 'questions.question_category_id', category} } } + :joins => :question, :conditions => { 'questions.category_id', category} } } named_scope :with_feedback, lambda { |opt| { :conditions => { :feedback => opt } } } diff --git a/app/models/category.rb b/app/models/category.rb new file mode 100644 index 0000000..a52a50d --- /dev/null +++ b/app/models/category.rb @@ -0,0 +1,39 @@ +# Gentoo Recruiters Web App - to help Gentoo recruiters do their job better +# Copyright (C) 2010 Joachim Filip Bartosik +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU Affero General Public License as +# published by the Free Software Foundation, version 3 of the License +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Affero General Public License for more details. +# +# You should have received a copy of the GNU Affero General Public License +# along with this program. If not, see . +# Questions are arranged in categories. Recruit should answer question in some +# categories. +class Category < ActiveRecord::Base + + hobo_model # Don't put anything above this + + fields do + name :string, :null => false + timestamps + end + + validates_presence_of :name + + has_many :questions + has_many :user_categories + has_many :users, :through => :user_categories, :accessible => true + + include Permissions::AnyoneCanViewAdminCanChange + + # Array of arrays [Category name, Category id], includes also + # ['All Categories', nil] array. + def self.as_select_opts + [['All Categories', nil]] + self.all(:select => 'name, id').collect{ |q| [q.name, q.id]} + end +end diff --git a/app/models/question.rb b/app/models/question.rb index b8cfed6..a660de6 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -39,7 +39,7 @@ class Question < ActiveRecord::Base #maybe add a page for not complete questions belongs_to :user, :creator => true - belongs_to :question_category + belongs_to :category belongs_to :question_group has_many :answers has_one :reference_answer, :class_name => "Answer", :conditions => ["answers.reference = ?", true] @@ -58,7 +58,7 @@ class Question < ActiveRecord::Base return true if new_record? # when it's not new record allow changing only some properties - return only_changed?(:title, :content, :documentation, :question_category) + return only_changed?(:title, :content, :documentation, :category) end false @@ -89,7 +89,7 @@ class Question < ActiveRecord::Base end named_scope :unanswered_ungrouped, lambda { |uid|{ - :joins => {:question_category => :user_categories}, + :joins => {:category => :user_categories}, :conditions => [ 'user_categories.user_id = ? AND questions.question_group_id IS NULL ' + 'AND NOT EXISTS (' + 'SELECT * FROM answers WHERE answers.owner_id = ? AND answers.question_id = questions.id)', @@ -109,7 +109,7 @@ class Question < ActiveRecord::Base :conditions => ['questions.id != ?', id]}} named_scope :ungrouped_questions_of_user, lambda { |user_id|{ - :joins => {:question_category => :user_categories}, + :joins => {:category => :user_categories}, :conditions => ['user_categories.user_id = ? AND questions.question_group_id IS NULL', user_id]}} named_scope :grouped_questions_of_user, lambda { |user_id|{ @@ -120,7 +120,7 @@ class Question < ActiveRecord::Base :conditions => { :user_id => user_id, :approved => false }}} named_scope :unanswered, lambda { |uid|{ - :joins => {:question_category => {:user_categories => :user}}, + :joins => {:category => {:user_categories => :user}}, :conditions => [ 'users.id = ? AND NOT EXISTS ( ' + 'SELECT * FROM answers WHERE answers.owner_id = ? AND answers.question_id = questions.id)', uid, uid]}} @@ -183,9 +183,9 @@ class Question < ActiveRecord::Base protected # Sends notification about new question (TODO: check for group). def notify_new_question - # If question category isn't assigned don't try to access it - if question_category && approved - for user in question_category.users + # If category isn't assigned don't try to access it + if category && approved + for user in category.users UserMailer.delay.deliver_new_question(user, self) end end @@ -193,7 +193,7 @@ class Question < ActiveRecord::Base # Sends notification about new question (TODO: check for group). def notify_approved_question - if question_category && !approved_was && approved + if category && !approved_was && approved notify_new_question end end diff --git a/app/models/question_category.rb b/app/models/question_category.rb deleted file mode 100644 index e67810c..0000000 --- a/app/models/question_category.rb +++ /dev/null @@ -1,39 +0,0 @@ -# Gentoo Recruiters Web App - to help Gentoo recruiters do their job better -# Copyright (C) 2010 Joachim Filip Bartosik -# -# This program is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as -# published by the Free Software Foundation, version 3 of the License -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with this program. If not, see . -# Questions are arranged in categories. Recruit should answer question in some -# categories. -class QuestionCategory < ActiveRecord::Base - - hobo_model # Don't put anything above this - - fields do - name :string, :null => false - timestamps - end - - validates_presence_of :name - - has_many :questions - has_many :user_categories - has_many :users, :through => :user_categories, :accessible => true - - include Permissions::AnyoneCanViewAdminCanChange - - # Array of arrays [Category name, Category id], includes also - # ['All Categories', nil] array. - def self.as_select_opts - [['All Categories', nil]] + QuestionCategory.all(:select => 'name, id').collect{ |q| [q.name, q.id]} - end -end diff --git a/app/models/question_group.rb b/app/models/question_group.rb index 81d738b..4ecd037 100644 --- a/app/models/question_group.rb +++ b/app/models/question_group.rb @@ -32,12 +32,12 @@ class QuestionGroup < ActiveRecord::Base include Permissions::AnyoneCanViewAdminCanChange named_scope :in_category, lambda { |cid| { - :joins => :questions, :conditions => ['questions.question_category_id = ?', cid], + :joins => :questions, :conditions => ['questions.category_id = ?', cid], :group => 'question_groups.id, question_groups.name, question_groups.description, question_groups.created_at, question_groups.updated_at'}} named_scope :unassociated_in_category, lambda { |uid, cid| { - :joins => :questions, :conditions => ['questions.question_category_id = ? AND NOT EXISTS + :joins => :questions, :conditions => ['questions.category_id = ? AND NOT EXISTS (SELECT user_question_groups.* FROM user_question_groups INNER JOIN questions ON questions.id = user_question_groups.question_id WHERE (user_question_groups.user_id = ? AND questions.question_group_id = question_groups.id))', cid, uid], diff --git a/app/models/user.rb b/app/models/user.rb index 071c708..ca7af6c 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -37,7 +37,7 @@ class User < ActiveRecord::Base has_many :user_categories has_many :user_question_groups - has_many :question_categories, :through => :user_categories, :accessible => true, :uniq => true + has_many :categories, :through => :user_categories, :accessible => true, :uniq => true has_many :grouped_questions, :through => :user_question_groups has_many :answers, :foreign_key => :owner_id has_many :answered_questions, :through => :answers, :class_name => "Question", :source => :question @@ -49,8 +49,8 @@ class User < ActiveRecord::Base named_scope :mentorless_recruits, :conditions => { :role => 'recruit', :mentor_id => nil} named_scope :recruits_answered_all, :conditions => "role = 'recruit' AND NOT EXISTS (SELECT questions.id FROM questions - INNER JOIN question_categories cat ON questions.question_category_id = cat.id INNER JOIN - user_categories ON user_categories.question_category_id = cat.id WHERE + INNER JOIN categories cat ON questions.category_id = cat.id INNER JOIN + user_categories ON user_categories.category_id = cat.id WHERE user_categories.user_id = users.id AND questions.question_group_id IS NULL AND NOT EXISTS ( SELECT answers.id FROM answers WHERE answers.question_id = questions.id AND answers.owner_id = users.id)) AND NOT EXISTS @@ -224,7 +224,7 @@ class User < ActiveRecord::Base return mentor_picked_up_or_resigned? if mentor_changed? # make sure recruiters change only what they are allowed to - return false unless only_changed?(:question_categories, :role, :nick) + return false unless only_changed?(:categories, :role, :nick) # and make sure change to role wasn't changed or was promotion of recruit # to mentor or demotion of mentor to recruit diff --git a/app/models/user_category.rb b/app/models/user_category.rb index 3f60283..e4b8b51 100644 --- a/app/models/user_category.rb +++ b/app/models/user_category.rb @@ -28,9 +28,9 @@ class UserCategory < ActiveRecord::Base end belongs_to :user, :null => false - belongs_to :question_category, :null => false + belongs_to :category, :null => false - validates_uniqueness_of :user_id, :scope => :question_category_id + validates_uniqueness_of :user_id, :scope => :category_id multi_permission :create, :update, :destroy do return true if acting_user.role.is_recruiter? @@ -48,7 +48,7 @@ class UserCategory < ActiveRecord::Base end def before_create - for group in QuestionGroup.unassociated_in_category(user, question_category).all + for group in QuestionGroup.unassociated_in_category(user, category).all chosen_question = rand(group.questions.count) UserQuestionGroup.create! :user => user, :question => (Question.all :limit => 1, :offset => chosen_question, :conditions => {:question_group_id => group.id})[0] diff --git a/app/models/user_mailer.rb b/app/models/user_mailer.rb index b405c8e..4acaff2 100644 --- a/app/models/user_mailer.rb +++ b/app/models/user_mailer.rb @@ -32,7 +32,7 @@ class UserMailer < ActionMailer::Base def new_question(user, question) common(user, "New question") - @body = { :title=> question.title, :category => question.question_category, + @body = { :title=> question.title, :category => question.category, :id => question.id} end diff --git a/app/viewhints/user_hints.rb b/app/viewhints/user_hints.rb index 91e3516..635f09e 100644 --- a/app/viewhints/user_hints.rb +++ b/app/viewhints/user_hints.rb @@ -13,5 +13,5 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . class UserHints < Hobo::ViewHints - children :answers, :question_categories, :project_acceptances + children :answers, :categories, :project_acceptances end diff --git a/app/views/categories/show.dryml b/app/views/categories/show.dryml new file mode 100644 index 0000000..8744afd --- /dev/null +++ b/app/views/categories/show.dryml @@ -0,0 +1,6 @@ + + +

Questions

+ +
+
diff --git a/app/views/question_categories/show.dryml b/app/views/question_categories/show.dryml deleted file mode 100644 index 8744afd..0000000 --- a/app/views/question_categories/show.dryml +++ /dev/null @@ -1,6 +0,0 @@ - - -

Questions

- -
-
diff --git a/app/views/question_groups/category.dryml b/app/views/question_groups/category.dryml index 8ac016b..0242002 100644 --- a/app/views/question_groups/category.dryml +++ b/app/views/question_groups/category.dryml @@ -2,7 +2,7 @@
<%= - select("id", nil, QuestionCategory.as_select_opts, {:include_blank => false, :selected => params['id']._?[0].to_i}) + select("id", nil, Category.as_select_opts, {:include_blank => false, :selected => params['id']._?[0].to_i}) %> diff --git a/app/views/taglibs/nav.dryml b/app/views/taglibs/nav.dryml index 6dad653..1c25680 100644 --- a/app/views/taglibs/nav.dryml +++ b/app/views/taglibs/nav.dryml @@ -1,7 +1,7 @@ Home - Question Categories + Question Categories Question Groups Suggest Questions Approve Questions diff --git a/app/views/taglibs/pages.dryml b/app/views/taglibs/pages.dryml index 06d29ba..79de5b3 100644 --- a/app/views/taglibs/pages.dryml +++ b/app/views/taglibs/pages.dryml @@ -18,7 +18,7 @@
- + You are currently assigned to categories: View questions: @@ -53,7 +53,7 @@ Check answers of recruits you mentor. You also can view answers of the recruits you mentor in categories: - + diff --git a/db/fixtures/questions-email.yml b/db/fixtures/questions-email.yml index 6a4a64b..4d4c800 100644 --- a/db/fixtures/questions-email.yml +++ b/db/fixtures/questions-email.yml @@ -1,7 +1,7 @@ email_q1: title: Gentoo-dev-announce posting documentation: - question_category: ebuild + category: ebuild content: "Email a major eclass change announcement. Replace all @gentoo.org addresses with @localhost addresses. Remember to sign the email. The from field should match email you set in the application. diff --git a/db/fixtures/questions-multichoice.yml b/db/fixtures/questions-multichoice.yml index 58fe2b9..ae1af23 100644 --- a/db/fixtures/questions-multichoice.yml +++ b/db/fixtures/questions-multichoice.yml @@ -1,6 +1,6 @@ multichoice_q1: title: Fake multiple choice documentation: Fake - question_category: ebuild + category: ebuild content: Some question options: Option 1; Option 2; Option 3 diff --git a/db/fixtures/questions.yml b/db/fixtures/questions.yml index d0fc816..7ff29e1 100644 --- a/db/fixtures/questions.yml +++ b/db/fixtures/questions.yml @@ -1,7 +1,7 @@ ebuild_q1: title: Big changes in Gentoo documentation: GLEPs - question_category: ebuild + category: ebuild content: What is the proper method for suggesting a wide-ranging feature or enhancement to Gentoo? Describe the process for getting this feature approved and implemented. @@ -9,21 +9,21 @@ ebuild_q1: ebuild_q2: title: Responsibilities documentation: devrel policy - question_category: ebuild + category: ebuild content: Who should be contacted with complaints about specific developers or projects? ebuild_q3: title: Gentoo mailing lists documentation: gentoo.org - question_category: ebuild + category: ebuild content: "When is it appropriate to post to the following mailing lists: gentoo-core, gentoo-dev, gentoo-dev-announce, gentoo-project?" ebuild_q4: title: src_install documentation: GLEPs - question_category: ebuild + category: ebuild question_group: ebuild_group1 content: "\n src_install () { \n dobin uvconvert/${PN} @@ -35,7 +35,7 @@ ebuild_q4: ebuild_q5: title: src_install documentation: devmanual - question_category: ebuild + category: ebuild question_group: ebuild_group1 content: "\n src_install() { \n dobin utrac @@ -47,7 +47,7 @@ ebuild_q5: ebuild_q6: title: src_install documentation: handbook - question_category: ebuild + category: ebuild question_group: ebuild_group1 content: "\n src_install() { \n dobin tree @@ -58,13 +58,13 @@ ebuild_q6: mentor_q1: title: Scopes in ebuild documentation: handbook - question_category: mentoring + category: mentoring content: "What's the difference between local and global scope in an ebuild?" mentor_q2: title: Optional SSL support in ebuild documentation: devmanual - question_category: mentoring + category: mentoring content: 'You have a patch for foomatic which enables SSL support that is optional at build time. Assuming that foomatic uses an autotools based build system provide most probable changes required in an `EAPI="0"` ebuild. @@ -73,7 +73,7 @@ mentor_q2: mentor_q3: title: Improve maintainability of ebuild documentation: devmanual - question_category: mentoring + category: mentoring content: "You are writing an ebuild for the foomatic package. Upstream calls the current version \"1.3-7b\" (but this is _not_ a beta release). How would the ebuild be named? What's wrong with the ebuild snippet below and how should this @@ -84,12 +84,12 @@ mentor_q3: non_q1: title: Gentoo Foundation documentation: gentoo.org - question_category: non_ebuild + category: non_ebuild content: What is the Gentoo Foundation? How does one apply for membership and who are eligible? non_q2: title: Gentoo Council documentation: GLEPs - question_category: non_ebuild + category: non_ebuild content: What is the purpose of the Gentoo Council? diff --git a/db/migrate/20110312173240_rename_question_category_to_category.rb b/db/migrate/20110312173240_rename_question_category_to_category.rb new file mode 100644 index 0000000..e20fa72 --- /dev/null +++ b/db/migrate/20110312173240_rename_question_category_to_category.rb @@ -0,0 +1,29 @@ +class RenameQuestionCategoryToCategory < ActiveRecord::Migration + def self.up + rename_table :question_categories, :categories + + rename_column :questions, :question_category_id, :category_id + + rename_column :user_categories, :question_category_id, :category_id + + remove_index :questions, :name => :index_questions_on_question_category_id rescue ActiveRecord::StatementInvalid + add_index :questions, [:category_id] + + remove_index :user_categories, :name => :index_user_categories_on_question_category_id rescue ActiveRecord::StatementInvalid + add_index :user_categories, [:category_id] + end + + def self.down + rename_column :questions, :category_id, :question_category_id + + rename_column :user_categories, :category_id, :question_category_id + + rename_table :categories, :question_categories + + remove_index :questions, :name => :index_questions_on_category_id rescue ActiveRecord::StatementInvalid + add_index :questions, [:question_category_id] + + remove_index :user_categories, :name => :index_user_categories_on_category_id rescue ActiveRecord::StatementInvalid + add_index :user_categories, [:question_category_id] + end +end diff --git a/db/schema.rb b/db/schema.rb index 49089a1..cbdde12 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -9,7 +9,7 @@ # # It's strongly recommended to check this file into your version control system. -ActiveRecord::Schema.define(:version => 20101211142354) do +ActiveRecord::Schema.define(:version => 20110312173240) do create_table "answers", :force => true do |t| t.text "content", :default => "", :null => false @@ -28,6 +28,12 @@ ActiveRecord::Schema.define(:version => 20101211142354) do add_index "answers", ["question_id"], :name => "index_answers_on_question_id" add_index "answers", ["type"], :name => "index_answers_on_type" + create_table "categories", :force => true do |t| + t.string "name", :null => false + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "comments", :force => true do |t| t.text "content", :null => false t.datetime "created_at" @@ -72,12 +78,6 @@ ActiveRecord::Schema.define(:version => 20101211142354) do add_index "project_acceptances", ["user_id"], :name => "index_project_acceptances_on_user_id" - create_table "question_categories", :force => true do |t| - t.string "name", :null => false - t.datetime "created_at" - t.datetime "updated_at" - end - create_table "question_content_emails", :force => true do |t| t.text "requirements", :default => "", :null => false t.text "description" @@ -114,28 +114,28 @@ ActiveRecord::Schema.define(:version => 20101211142354) do end create_table "questions", :force => true do |t| - t.string "title", :null => false + t.string "title", :null => false t.string "documentation" - t.boolean "approved", :default => false + t.boolean "approved", :default => false t.datetime "created_at" t.datetime "updated_at" t.integer "user_id" - t.integer "question_category_id" + t.integer "category_id" t.integer "question_group_id" end - add_index "questions", ["question_category_id"], :name => "index_questions_on_question_category_id" + add_index "questions", ["category_id"], :name => "index_questions_on_category_id" add_index "questions", ["question_group_id"], :name => "index_questions_on_question_group_id" add_index "questions", ["user_id"], :name => "index_questions_on_user_id" create_table "user_categories", :force => true do |t| t.datetime "created_at" t.datetime "updated_at" - t.integer "user_id", :null => false - t.integer "question_category_id", :null => false + t.integer "user_id", :null => false + t.integer "category_id", :null => false end - add_index "user_categories", ["question_category_id"], :name => "index_user_categories_on_question_category_id" + add_index "user_categories", ["category_id"], :name => "index_user_categories_on_category_id" add_index "user_categories", ["user_id"], :name => "index_user_categories_on_user_id" create_table "user_question_groups", :force => true do |t| diff --git a/db/seeds.rb b/db/seeds.rb index 4d06bc3..352cc18 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -46,7 +46,7 @@ APP_CONFIG['developer_data']['check'] = false # Remove existing database entries User.destroy_all Answer.destroy_all -QuestionCategory.destroy_all +Category.destroy_all QuestionGroup.destroy_all Question.destroy_all UserCategory.destroy_all @@ -56,21 +56,21 @@ User.destroy_all seeder = SeedHelper.new # Question categories -seeder.objects['ebuild'] = QuestionCategory.create! :name => 'Ebuild quiz' -seeder.objects['mentoring'] = QuestionCategory.create! :name => 'End of mentoring quiz' -seeder.objects['non'] = QuestionCategory.create! :name => 'Non-ebuild staff quiz' +seeder.objects['ebuild'] = Category.create! :name => 'Ebuild quiz' +seeder.objects['mentoring'] = Category.create! :name => 'End of mentoring quiz' +seeder.objects['non'] = Category.create! :name => 'Non-ebuild staff quiz' # Question groups seeder.objects['ebuild_group1'] = QuestionGroup.create! :name => 'ebuild_group1', :description => 'src_install implementations to comment on' # Questions with text content - load from YAML file -seeder.read_yaml('db/fixtures/questions.yml', Question, ['question_category', 'question_group']) do |name, hash, objects, klass| +seeder.read_yaml('db/fixtures/questions.yml', Question, ['category', 'question_group']) do |name, hash, objects, klass| objects[name] = klass.create! (hash - {'content' => nil}) objects["#{name}-content"] = QuestionContentText.create! :question => objects[name], :content => hash['content'] end # Questions with multiple choice content - load from YAML file -seeder.read_yaml('db/fixtures/questions-multichoice.yml', Question, ['question_category', 'question_group']) do |name, hash, objects, klass| +seeder.read_yaml('db/fixtures/questions-multichoice.yml', Question, ['category', 'question_group']) do |name, hash, objects, klass| objects[name] = klass.create!(hash - {'options' => nil, 'content' => nil}) objects["#{name}-content"] = QuestionContentMultipleChoice.create! :question => objects[name], :content => hash['content'] for opt in hash['options'].split(';') @@ -80,7 +80,7 @@ seeder.read_yaml('db/fixtures/questions-multichoice.yml', Question, ['question_c end # Questions with email content - load from YAML file -seeder.read_yaml('db/fixtures/questions-email.yml', Question, ['question_category', 'question_group']) do |name, hash, objects, klass| +seeder.read_yaml('db/fixtures/questions-email.yml', Question, ['category', 'question_group']) do |name, hash, objects, klass| objects[name] = klass.create!(hash - {'content' => nil, 'req_text' => nil}) objects["#{name}-content"] = QuestionContentEmail.create! :question => objects[name], :description=> hash['content'], :req_text => hash['req_text'] end @@ -97,7 +97,7 @@ user_cats = [ ['mentoring', 'mentor']] for uc in user_cats - UserCategory.create! :question_category => seeder.objects[uc[0]], :user => seeder.objects[uc[1]] + UserCategory.create! :category => seeder.objects[uc[0]], :user => seeder.objects[uc[1]] end diff --git a/features/step_definitions/categories_steps.rb b/features/step_definitions/categories_steps.rb new file mode 100644 index 0000000..66eee68 --- /dev/null +++ b/features/step_definitions/categories_steps.rb @@ -0,0 +1,3 @@ +Given /^a category "([^\"]*)"$/ do |name| + @category = Category.find_by_name(name) || Category.create!(:name => name) +end diff --git a/features/step_definitions/question_categories_steps.rb b/features/step_definitions/question_categories_steps.rb deleted file mode 100644 index e5d34e1..0000000 --- a/features/step_definitions/question_categories_steps.rb +++ /dev/null @@ -1,6 +0,0 @@ -Given /^a question category "([^\"]*)"$/ do |name| - @question_category = QuestionCategory.find_by_name(name) - if @question_category.nil? - @question_category = QuestionCategory.create!(:name => name) - end -end diff --git a/features/step_definitions/questions_steps.rb b/features/step_definitions/questions_steps.rb index fce0762..b0cd6fd 100644 --- a/features/step_definitions/questions_steps.rb +++ b/features/step_definitions/questions_steps.rb @@ -11,8 +11,8 @@ end Given /^a question "([^\"]*)" in category "([^\"]*)"$/ do |title, category| Given "a question \"#{title}\"" - Given "a question category \"#{category}\"" - @question.question_category = @question_category + Given "a category \"#{category}\"" + @question.category = @category @question.save! end diff --git a/features/step_definitions/users_steps.rb b/features/step_definitions/users_steps.rb index 932e538..9b66f29 100644 --- a/features/step_definitions/users_steps.rb +++ b/features/step_definitions/users_steps.rb @@ -14,9 +14,9 @@ end Given /^user "([^\"]*)" has category "([^\"]*)"$/ do |user_name, category_name| Given "user \"#{user_name}\"" - Given "a question category \"#{category_name}\"" - unless @user.question_categories.include?(@question_category) - @user.question_categories.push(@question_category) + Given "a category \"#{category_name}\"" + unless @user.categories.include?(@category) + @user.categories.push(@category) end @user.save! end @@ -30,8 +30,8 @@ Given /^"([^\"]*)" answered question "([^\"]*)"$/ do |user, question| end Given /^user "([^\"]*)" answered all questions in "([^\"]*)"$/ do |user_name, category_name| - Given "a question category \"#{category_name}\"" - for q in @question_category.questions + Given "a category \"#{category_name}\"" + for q in @category.questions if q.question_group.nil? Given "\"#{user_name}\" answered question \"#{q.title}\"" end diff --git a/spec/factories.rb b/spec/factories.rb index 0b26477..2c663af 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -43,12 +43,12 @@ u.nick { |u| u.name } end - Factory.sequence :question_category do |n| - "question category-#{n}" + Factory.sequence :category do |n| + "category-#{n}" end - Factory.define :question_category do |q| - q.name { Factory.next(:question_category) } + Factory.define :category do |q| + q.name { Factory.next(:category) } end Factory.sequence :question do |n| @@ -58,7 +58,7 @@ # it'll belong to new category by default Factory.define :question do |q| q.title { Factory.next(:question) } - q.question_category { Factory(:question_category)} + q.category { Factory(:category)} end Factory.sequence :answer do |n| @@ -81,7 +81,7 @@ Factory.define :user_category do |q| q.user { Factory(:recruit) } - q.question_category { Factory(:question_category) } + q.category { Factory(:category) } end Factory.sequence :comment do |n| diff --git a/spec/models/answer_spec.rb b/spec/models/answer_spec.rb index de72393..e300537 100644 --- a/spec/models/answer_spec.rb +++ b/spec/models/answer_spec.rb @@ -269,11 +269,11 @@ describe Answer do it "should properly return wrong answers of recruit" do recruit = Factory(:recruit) - cat = Factory(:question_category) - q1 = Factory(:question, :question_category => cat) - q2 = Factory(:question, :question_category => cat) - q3 = Factory(:question, :question_category => cat) - q4 = Factory(:question, :question_category => cat) + cat = Factory(:category) + q1 = Factory(:question, :category => cat) + q2 = Factory(:question, :category => cat) + q3 = Factory(:question, :category => cat) + q4 = Factory(:question, :category => cat) Factory(:question_content_text, :question => q4) diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb new file mode 100644 index 0000000..8e482c5 --- /dev/null +++ b/spec/models/category_spec.rb @@ -0,0 +1,31 @@ +require 'spec_helper.rb' +describe Category do + + include Permissions::TestPermissions + + it "should allow admin to create, edit, update and remove" do + cud_allowed([Factory(:administrator)], Factory(:category)) + end + + it "should prohibit nonadmins to creating, editing, updating and removing" do + cud_denied([Factory(:recruit), Factory(:mentor), Guest.new, + Factory(:recruiter)], Factory(:category)) + end + + it "should be allowed for everybody to view" do + view_allowed([Factory(:recruit), Factory(:mentor), Factory(:recruiter), + Factory(:administrator), Guest.new], Factory(:category)) + end + + it { should validate_presence_of :name } + + it "should return proper as_select_opts" do + c1 = Factory(:category) + c2 = Factory(:category) + options = [['All Categories', nil], [c1.name, c1.id], [c2.name, c2.id]] + + (options - Category.as_select_opts).should be_empty + (Category.as_select_opts - options).should be_empty + Category.as_select_opts.count.should == Category.as_select_opts.uniq.count + end +end diff --git a/spec/models/question_category_spec.rb b/spec/models/question_category_spec.rb deleted file mode 100644 index 32511a8..0000000 --- a/spec/models/question_category_spec.rb +++ /dev/null @@ -1,31 +0,0 @@ -require 'spec_helper.rb' -describe QuestionCategory do - - include Permissions::TestPermissions - - it "should allow admin to create, edit, update and remove" do - cud_allowed([Factory(:administrator)], Factory(:question_category)) - end - - it "should prohibit nonadmins to creating, editing, updating and removing" do - cud_denied([Factory(:recruit), Factory(:mentor), Guest.new, - Factory(:recruiter)], Factory(:question_category)) - end - - it "should be allowed for everybody to view" do - view_allowed([Factory(:recruit), Factory(:mentor), Factory(:recruiter), - Factory(:administrator), Guest.new], Factory(:question_category)) - end - - it { should validate_presence_of :name } - - it "should return proper as_select_opts" do - c1 = Factory(:question_category) - c2 = Factory(:question_category) - options = [['All Categories', nil], [c1.name, c1.id], [c2.name, c2.id]] - - (options - QuestionCategory.as_select_opts).should be_empty - (QuestionCategory.as_select_opts - options).should be_empty - QuestionCategory.as_select_opts.count.should == QuestionCategory.as_select_opts.uniq.count - end -end diff --git a/spec/models/question_group_spec.rb b/spec/models/question_group_spec.rb index ac8cb06..b490f89 100644 --- a/spec/models/question_group_spec.rb +++ b/spec/models/question_group_spec.rb @@ -18,12 +18,12 @@ describe QuestionGroup do end it "should return proper in_category results" do - category = Factory(:question_category) + category = Factory(:category) groups_in_cat = [] for n in 1..5 groups_in_cat.push Factory(:question_group) for i in 1..n - Factory(:question, :question_category => category, :question_group => groups_in_cat.last) + Factory(:question, :category => category, :question_group => groups_in_cat.last) end end @@ -39,12 +39,12 @@ describe QuestionGroup do it "should return proper unassociated_in_category results" do recruit = Factory(:recruit) - category = Factory(:question_category) + category = Factory(:category) groups_in_cat = [] for n in 1..5 groups_in_cat.push Factory(:question_group) for i in 1..n - Factory(:question, :question_category => category, :question_group => groups_in_cat.last) + Factory(:question, :category => category, :question_group => groups_in_cat.last) end end diff --git a/spec/models/question_spec.rb b/spec/models/question_spec.rb index 0489be4..5dddd70 100644 --- a/spec/models/question_spec.rb +++ b/spec/models/question_spec.rb @@ -66,10 +66,10 @@ describe Question do end it "should send email notifications to watching recruits when created by recruiter" do - category = Factory(:question_category) - recruit = Factory(:recruit, :question_categories => [category]) + category = Factory(:category) + recruit = Factory(:recruit, :categories => [category]) question = Question.new(:title => "new question", - :question_category => category) + :category => category) UserMailer.should_receive_delayed(:deliver_new_question, recruit, question) @@ -77,10 +77,10 @@ describe Question do end it "should send email notifications to watching recruits when approved" do - category = Factory(:question_category) - recruit = Factory(:recruit, :question_categories => [category]) + category = Factory(:category) + recruit = Factory(:recruit, :categories => [category]) question = Factory(:question, :title => "new question", - :question_category => category, :user => Factory(:recruit)) + :category => category, :user => Factory(:recruit)) UserMailer.should_receive_delayed(:deliver_new_question, recruit, question) question.approved = true @@ -88,10 +88,10 @@ describe Question do end it "should not send email notifications to watching recruits when approved is changed" do - category = Factory(:question_category) - recruit = Factory(:recruit, :question_categories => [category]) + category = Factory(:category) + recruit = Factory(:recruit, :categories => [category]) question = Factory(:question, :title => "new question", - :question_category => category, :user => Factory(:recruit), :approved => true) + :category => category, :user => Factory(:recruit), :approved => true) UserMailer.should_not_receive(:deliver_new_question).with(recruit, question) @@ -146,7 +146,7 @@ describe Question do question.should be_editable_by(recruit) question.should be_editable_by(recruit, :title) question.should be_editable_by(recruit, :documentation) - question.should be_editable_by(recruit, :question_category) + question.should be_editable_by(recruit, :category) question.should_not be_editable_by(recruit, :user) question.should_not be_editable_by(recruit, :approved) @@ -159,7 +159,7 @@ describe Question do question.should be_editable_by(recruit) question.should be_editable_by(recruit, :title) question.should be_editable_by(recruit, :documentation) - question.should be_editable_by(recruit, :question_category) + question.should be_editable_by(recruit, :category) question.should_not be_editable_by(recruit, :user) question.should_not be_editable_by(recruit, :approved) @@ -172,7 +172,7 @@ describe Question do question.should be_editable_by(admin) question.should be_editable_by(admin, :title) question.should be_editable_by(admin, :documentation) - question.should be_editable_by(admin, :question_category) + question.should be_editable_by(admin, :category) question.should be_editable_by(admin, :approved) question.should_not be_editable_by(admin, :user) diff --git a/spec/models/user_category_spec.rb b/spec/models/user_category_spec.rb index 3b833d3..99efdea 100644 --- a/spec/models/user_category_spec.rb +++ b/spec/models/user_category_spec.rb @@ -64,13 +64,13 @@ describe UserCategory do end end - it "should associate user with one question from each group from question category on creation" do - category = Factory(:question_category) + it "should associate user with one question from each group from category on creation" do + category = Factory(:category) groups_in_cat = [] for n in 1..5 groups_in_cat.push Factory(:question_group) for i in 1..n - Factory(:question, :question_category => category, :question_group => groups_in_cat.last) + Factory(:question, :category => category, :question_group => groups_in_cat.last) end end @@ -79,7 +79,7 @@ describe UserCategory do end recruit = Factory(:recruit) - Factory(:user_category, :user => recruit, :question_category => category) + Factory(:user_category, :user => recruit, :category => category) for group in groups_in_cat has_question_from_group = group.questions.inject(false) do |result, question| diff --git a/spec/models/user_mailer_spec.rb b/spec/models/user_mailer_spec.rb index 4e7c613..39a45e2 100644 --- a/spec/models/user_mailer_spec.rb +++ b/spec/models/user_mailer_spec.rb @@ -10,7 +10,7 @@ describe UserMailer do notification.should deliver_to(recruit.email_address) notification.should deliver_from("no-reply@localhost") notification.should have_text(/There is a new question "#{question.title}"/) - notification.should have_text(/in category "#{question.question_category.name}" you are assigned to./) + notification.should have_text(/in category "#{question.category.name}" you are assigned to./) notification.should have_text(/http:\/\/localhost:3000\/questions\/#{question.id}/) notification.should have_subject('New question') end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 529c3b9..ee256c4 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -310,7 +310,7 @@ describe User do q1 = Factory(:question) Factory(:question_content_multiple_choice, :question => q1) Factory(:user_category, - :question_category => q1.question_category, + :category => q1.category, :user => recruit) recruit.answered_all_multi_choice_questions?.should be_false @@ -337,7 +337,7 @@ describe User do q1 = Factory(:question) Factory(:user_category, :user => recruit, - :question_category => q1.question_category) + :category => q1.category) recruit.progress.should == "Answered 0 of 1 questions." Factory(:answer, :owner => recruit, :question => q1) diff --git a/spec/support/factory_orders.rb b/spec/support/factory_orders.rb index 76c0d63..d02249a 100644 --- a/spec/support/factory_orders.rb +++ b/spec/support/factory_orders.rb @@ -11,25 +11,25 @@ def recruit_with_answered_and_unanswered_questions(n=5) r.unanswered = [] for i in 1..n # answered and unanswered ungrouped questions - category = Factory(:question_category) - r.answered.push Factory(:question, :question_category => category) - r.unanswered.push Factory(:question, :question_category => category) + category = Factory(:category) + r.answered.push Factory(:question, :category => category) + r.unanswered.push Factory(:question, :category => category) Factory(:answer, :owner => r.recruit, :question => r.answered.last) # and answered and unanswered question in one group group = Factory(:question_group) - r.answered.push Factory(:question, :question_category => category, :question_group => group) + r.answered.push Factory(:question, :category => category, :question_group => group) Factory(:user_question_group, :user => r.recruit, :question => r.answered.last) # This question isn't unanswered! This is question user can't answer - Factory(:question, :question_category => category, :question_group => group) + Factory(:question, :category => category, :question_group => group) # add a unanswered grouped question - r.unanswered.push Factory(:question, :question_category => category, :question_group => Factory(:question_group)) + r.unanswered.push Factory(:question, :category => category, :question_group => Factory(:question_group)) Factory(:user_question_group, :user => r.recruit, :question => r.unanswered.last) Factory(:answer, :owner => r.recruit, :question => r.answered.last) - r.recruit.question_categories.push category + r.recruit.categories.push category end r end @@ -48,17 +48,17 @@ def recruit_with_answers_in_categories(mentor = nil, n_categories = 5, n_ans_in_ r.answers_in_cat = [] r.all_answers = [] for i in 1..n_categories - r.categories.push Factory(:question_category) + r.categories.push Factory(:category) r.answers_in_cat.push [] for i in 1..n_ans_in_cat - question = Factory(:question, :question_category => r.categories.last) + question = Factory(:question, :category => r.categories.last) r.all_answers.push Factory(:answer, :owner => r.recruit, :question => question) r.answers_in_cat.last.push r.all_answers.last # group of two questions, answered group = Factory(:question_group) - question = Factory(:question, :question_category => r.categories.last, :question_group => group) - Factory(:question, :question_category => r.categories.last, :question_group => group) + question = Factory(:question, :category => r.categories.last, :question_group => group) + Factory(:question, :category => r.categories.last, :question_group => group) Factory(:user_question_group, :user => r.recruit, :question => question) r.all_answers.push Factory(:answer, :owner => r.recruit, :question => question) r.answers_in_cat.last.push r.all_answers.last -- cgit v1.2.3-65-gdbad