From 2401de2461bde8cbfe43ff49c6cada509293129b Mon Sep 17 00:00:00 2001 From: MoisesMachado Date: Thu, 19 Jun 2008 18:13:00 +0000 Subject: [PATCH] ActionItem439: finishing enterprise activation (or ... sort of) --- app/controllers/my_profile/profile_editor_controller.rb | 2 +- app/controllers/public/account_controller.rb | 45 ++++++++++++++++++++++++--------------------- app/models/enterprise.rb | 30 +++++++++++++++++------------- app/models/enterprise_activation.rb | 23 +++++++++++++++++++++++ app/models/task.rb | 13 +++++++------ app/views/account/activate_enterprise.rhtml | 2 +- db/schema.rb | 4 ++-- test/functional/account_controller_test.rb | 70 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-------- test/unit/enterprise_activation_test.rb | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ test/unit/enterprise_test.rb | 30 ++++++++++++++++++------------ test/unit/task_test.rb | 9 +++++++++ 11 files changed, 232 insertions(+), 64 deletions(-) create mode 100644 app/models/enterprise_activation.rb create mode 100644 test/unit/enterprise_activation_test.rb diff --git a/app/controllers/my_profile/profile_editor_controller.rb b/app/controllers/my_profile/profile_editor_controller.rb index 0de16dc..04b5530 100644 --- a/app/controllers/my_profile/profile_editor_controller.rb +++ b/app/controllers/my_profile/profile_editor_controller.rb @@ -1,6 +1,6 @@ class ProfileEditorController < MyProfileController - protect 'edit_profile', :profile, :only => [:index, :edit] + protect 'edit_profile', :profile def index @pending_tasks = profile.tasks.pending.select{|i| user.has_permission?(i.permission, profile)} diff --git a/app/controllers/public/account_controller.rb b/app/controllers/public/account_controller.rb index 1f1acb2..8755792 100644 --- a/app/controllers/public/account_controller.rb +++ b/app/controllers/public/account_controller.rb @@ -128,25 +128,27 @@ class AccountController < PublicController protected def activate_enterprise - load_enterprise - unless @enterprise + enterprise = load_enterprise + @enterprise = enterprise + + unless enterprise render :action => 'invalid_enterprise_code' return end - if @enterprise.enabled + if enterprise.enabled render :action => 'already_activated' return end # Reaches here only if answer is not correct if request.post? && !answer_correct - @enterprise.block + enterprise.block end - define_question + @question = enterprise.question - if !@question || @enterprise.blocked? + if !@question || enterprise.blocked? render :action => 'blocked' return end @@ -155,33 +157,34 @@ class AccountController < PublicController end def post_activate_enterprise - if @enterprise - @enterprise.enable(@user.person) + activation = load_enterprise_activation + if activation + activation.requestor = user + activation.finish end end - def load_enterprise - @enterprise ||= Enterprise.return_by_code(params[:enterprise_code]) + def load_enterprise_activation + EnterpriseActivation.find_by_code(params[:enterprise_code]) end - def define_question - return if @question - if !@enterprise.foundation_year.blank? - @question = :foundation_year - elsif !@enterprise.cnpj.blank? - @question = :cnpj + def load_enterprise + activation = load_enterprise_activation + if activation.nil? + nil + else + activation.enterprise end end def answer_correct return true unless params[:enterprise_code] - load_enterprise - define_question - return false unless @question - return false if @enterprise.enabled + enterprise = load_enterprise + return false unless enterprise.question + return false if enterprise.enabled - params[:answer] == @enterprise.send(@question).to_s + params[:answer] == enterprise.send(enterprise.question).to_s end def go_to_user_initial_page diff --git a/app/models/enterprise.rb b/app/models/enterprise.rb index 0eef2d4..cbd3d00 100644 --- a/app/models/enterprise.rb +++ b/app/models/enterprise.rb @@ -24,19 +24,6 @@ class Enterprise < Organization true end - def code - ("%06d" % id) + Digest::MD5.hexdigest(id.to_s)[0..5] - end - - def self.return_by_code(code) - return unless code - id = code[0..5].to_i - md5 = code[6..11] - return unless md5 == Digest::MD5.hexdigest(id.to_s)[0..5] - - Enterprise.find(id) - end - def blocked? data[:blocked] end @@ -53,4 +40,21 @@ class Enterprise < Organization save end + def question + if !self.foundation_year.blank? + :foundation_year + elsif !self.cnpj.blank? + :cnpj + else + nil + end + end + + after_create :create_activation_task + def create_activation_task + if !self.enabled + EnterpriseActivation.create!(:enterprise => self, :code_length => 7) + end + end + end diff --git a/app/models/enterprise_activation.rb b/app/models/enterprise_activation.rb new file mode 100644 index 0000000..ff16568 --- /dev/null +++ b/app/models/enterprise_activation.rb @@ -0,0 +1,23 @@ +class EnterpriseActivation < Task + + class RequestorRequired < Exception; end + + acts_as_having_settings :field => :data + settings_items :enterprise_id, :integer + + validates_presence_of :enterprise_id + + def enterprise + Enterprise.find(enterprise_id) + end + + def enterprise=(ent) + self.enterprise_id = ent.id + end + + def perform + raise EnterpriseActivation::RequestorRequired if requestor.nil? + self.enterprise.enable(requestor) + end + +end diff --git a/app/models/task.rb b/app/models/task.rb index 5b7a9a9..d034882 100644 --- a/app/models/task.rb +++ b/app/models/task.rb @@ -35,11 +35,12 @@ class Task < ActiveRecord::Base self.status ||= Task::Status::ACTIVE end + attr_accessor :code_length before_validation_on_create do |task| if task.code.nil? - task.code = Task.generate_code + task.code = Task.generate_code(task.code_length) while (Task.find_by_code(task.code)) - task.code = Task.generate_code + task.code = Task.generate_code(task.code_length) end end end @@ -162,12 +163,12 @@ class Task < ActiveRecord::Base self.find(:all, :conditions => { :status => [Task::Status::CANCELLED, Task::Status::FINISHED]}) end - # generates a random code string consisting of 36 characters in the ranges - # a-z and 0-9 - def generate_code + # generates a random code string consisting of length characters (or 36 by + # default) in the ranges a-z and 0-9 + def generate_code(length = nil) chars = ('a'..'z').to_a + ('0'..'9').to_a code = "" - chars.size.times do |n| + (length || chars.size).times do |n| code << chars[rand(chars.size)] end code diff --git a/app/views/account/activate_enterprise.rhtml b/app/views/account/activate_enterprise.rhtml index 22975c6..f1253c7 100644 --- a/app/views/account/activate_enterprise.rhtml +++ b/app/views/account/activate_enterprise.rhtml @@ -26,7 +26,7 @@ <%= ApplicationHelper::NoosferoFormBuilder::output_field(@question == :foundation_year ? _('What year your enterprise was founded?') : _('What is the CNPJ of your enterprise?'), text_field_tag(:answer, nil,:help => help=_('We need to be sure that this is your enterprise'))) %> -<%= hidden_field_tag :enterprise_code, @enterprise.code %> +<%= hidden_field_tag :enterprise_code, params[:enterprise_code] %> <% if @terms_of_use %>

diff --git a/db/schema.rb b/db/schema.rb index 4393198..a1bd028 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -68,8 +68,8 @@ ActiveRecord::Schema.define(:version => 41) do t.integer "category_id" end - add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" add_index "articles_categories", ["category_id"], :name => "index_articles_categories_on_category_id" + add_index "articles_categories", ["article_id"], :name => "index_articles_categories_on_article_id" create_table "blocks", :force => true do |t| t.string "title" @@ -217,8 +217,8 @@ ActiveRecord::Schema.define(:version => 41) do t.datetime "created_at" end - add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" add_index "taggings", ["taggable_id", "taggable_type"], :name => "index_taggings_on_taggable_id_and_taggable_type" + add_index "taggings", ["tag_id"], :name => "index_taggings_on_tag_id" create_table "tags", :force => true do |t| t.string "name" diff --git a/test/functional/account_controller_test.rb b/test/functional/account_controller_test.rb index c6a3ff1..c41fe37 100644 --- a/test/functional/account_controller_test.rb +++ b/test/functional/account_controller_test.rb @@ -277,6 +277,8 @@ class AccountControllerTest < Test::Unit::TestCase end should 'report invalid enterprise code on signup' do + EnterpriseActivation.expects(:find_by_code).with('some_invalid_code').returns(nil).at_least_once + get :signup, :enterprise_code => 'some_invalid_code' assert_template 'invalid_enterprise_code' @@ -284,35 +286,60 @@ class AccountControllerTest < Test::Unit::TestCase should 'report enterprise already enabled' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :cnpj => '0'*14, :enabled => true) - get :signup, :enterprise_code => ent.code + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' assert_template 'already_activated' end should 'load enterprise from code on signup' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent') - get :signup, :enterprise_code => ent.code + + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' assert_equal ent, assigns(:enterprise) end should 'block enterprises that do not have foundation_year or cnpj' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :enabled => false) - get :signup, :enterprise_code => ent.code + + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' assert_template 'blocked' end should 'show form to those enterprises that have foundation year' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :foundation_year => 1998, :enabled => false) - get :signup, :enterprise_code => ent.code + + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' assert_template 'activate_enterprise' end should 'show form to those enterprises that have cnpj' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :cnpj => '0'*14, :enabled => false) - get :signup, :enterprise_code => ent.code + + + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' assert_template 'activate_enterprise' end @@ -320,7 +347,13 @@ class AccountControllerTest < Test::Unit::TestCase should 'block those who are blocked' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :foundation_year => '1998', :enabled => false) ent.block - get :signup, :enterprise_code => ent.code + + + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' assert_template 'blocked' end @@ -328,7 +361,11 @@ class AccountControllerTest < Test::Unit::TestCase should 'block those who failed to answer the question' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :foundation_year => 1998, :enabled => false) - create_user({}, :enterprise_code => ent.code, :answer => '1997') + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + create_user({}, :enterprise_code => '0123456789', :answer => '1997') ent.reload assert_nil User.find_by_login('test_user') @@ -338,13 +375,30 @@ class AccountControllerTest < Test::Unit::TestCase should 'activate enterprise for those who answer the question right and make them admin of the enterprise' do ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :foundation_year => 1998, :enabled => false) - create_user({}, :enterprise_code => ent.code, :answer => '1998') + + task = EnterpriseActivation.create!(:enterprise => ent) + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + create_user({}, :enterprise_code => '0123456789', :answer => '1998') ent.reload assert ent.enabled assert_includes ent.members, assigns(:user).person end + should 'put hidden field with enterprise code for answering question' do + ent = Enterprise.create!(:name => 'test enterprise', :identifier => 'test_ent', :foundation_year => 1998, :enabled => false) + + task = mock + task.expects(:enterprise).returns(ent).at_least_once + EnterpriseActivation.expects(:find_by_code).with('0123456789').returns(task).at_least_once + + get :signup, :enterprise_code => '0123456789' + + assert_tag :tag => 'input', :attributes => { :type => 'hidden', :name => 'enterprise_code', :value => '0123456789'} + + end + protected def create_user(options = {}, extra_options ={}) post :signup, { :user => { :login => 'quire', diff --git a/test/unit/enterprise_activation_test.rb b/test/unit/enterprise_activation_test.rb new file mode 100644 index 0000000..d5f9ba4 --- /dev/null +++ b/test/unit/enterprise_activation_test.rb @@ -0,0 +1,68 @@ +require File.dirname(__FILE__) + '/../test_helper' + +class EnterpriseActivationTest < ActiveSupport::TestCase + + fixtures :users, :profiles + + should 'be a Task' do + assert_kind_of Task, EnterpriseActivation.new + end + + should 'keep enterprise_id' do + assert_nil EnterpriseActivation.new.enterprise_id + end + + should 'have an enteprise through enterprise_id' do + ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent') + + assert_equal ent, EnterpriseActivation.new(:enterprise_id => ent.id).enterprise + end + + should 'require an enterprise' do + t = EnterpriseActivation.new + t.valid? + assert t.errors.invalid?(:enterprise_id), "enterprise must be required" + + ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent') + t.enterprise = ent + t.valid? + assert !t.errors.invalid?(:enterprise_id), "must validate after enterprise is set" + end + + should 'activate enterprise when finished' do + ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent', :enabled => false) + t = EnterpriseActivation.create!(:enterprise => ent) + t.requestor = profiles(:ze) + + t.finish + ent.reload + + assert ent.enabled, "finishing task should left enterprise enabled" + end + + should 'require requestor to finish' do + ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent', :enabled => false) + t = EnterpriseActivation.create!(:enterprise => ent) + + assert_raise EnterpriseActivation::RequestorRequired do + t.finish + end + end + + should 'put requestor as enterprise owner when finishing' do + ent = Enterprise.create!(:name => 'my enterprise', :identifier => 'myent', :enabled => false) + t = EnterpriseActivation.create!(:enterprise => ent) + + person = profiles(:ze) + t.requestor = person + + t.stubs(:enterprise).returns(ent) + + # must pass the requestor to the enterprise activation + ent.expects(:enable).with(person) + + t.finish + end + +end + diff --git a/test/unit/enterprise_test.rb b/test/unit/enterprise_test.rb index 304cc6d..4ff88c1 100644 --- a/test/unit/enterprise_test.rb +++ b/test/unit/enterprise_test.rb @@ -125,18 +125,6 @@ class EnterpriseTest < Test::Unit::TestCase assert_not_includes c.members, p end - should 'return coherent code' do - ent = Enterprise.create!(:name => 'my test profile', :identifier => 'mytestprofile') - ent2 = Enterprise.create!(:name => 'my test profile 2', :identifier => 'mytestprofile2') - - assert_equal ent, Enterprise.return_by_code(ent.code) - assert_nil Enterprise.return_by_code(ent.code.next) - end - - should 'return nil when asked for an enterprise with code nil' do - assert_nil Enterprise.return_by_code(nil) - end - should 'have foudation_year' do ent = Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent') @@ -167,4 +155,22 @@ class EnterpriseTest < Test::Unit::TestCase assert_includes ent.members, p end + should 'create EnterpriseActivation task when creating with enabled = false' do + EnterpriseActivation.delete_all + ent = Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent', :enabled => false) + assert_equal [ent], EnterpriseActivation.find(:all).map(&:enterprise) + end + + should 'create EnterpriseActivation with 7-characters codes' do + EnterpriseActivation.delete_all + Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent', :enabled => false) + assert_equal 7, EnterpriseActivation.find(:first).code.size + end + + should 'not create activation task when enabled = true' do + assert_no_difference EnterpriseActivation, :count do + Enterprise.create!(:name => 'test enteprise', :identifier => 'test_ent', :enabled => true) + end + end + end diff --git a/test/unit/task_test.rb b/test/unit/task_test.rb index 99f7e14..601c886 100644 --- a/test/unit/task_test.rb +++ b/test/unit/task_test.rb @@ -135,6 +135,15 @@ class TaskTest < Test::Unit::TestCase assert_not_nil Task.find_by_code(task.code) end + should 'use 36-chars codes by default' do + assert_equal 36, Task.create.code.size + end + + should 'be able to limit the length of the generated code' do + assert_equal 3, Task.create(:code_length => 3).code.size + assert_equal 7, Task.create(:code_length => 7).code.size + end + should 'not send notification to target when target_notification_message is nil (as in Task base class)' do task = Task.new TaskMailer.expects(:deliver_target_notification).never -- libgit2 0.21.2