require File.expand_path('../../spec_helper', __FILE__)

describe ProjectsController, :logged => :admin do
  describe 'INDEX' do

    let!(:project) {FactoryGirl.create(:project, :enabled_module_names => ['issue_tracking'])}

    context 'projects tree' do
      let!(:child) { FactoryGirl.create(:project, parent: project, name: 'Child project') }

      it 'render parent project of filtered project with nonfilter set' do
        get :index, set_filter: 1, name: '~child'
        expect(assigns(:projects).size).to eq(1) # only roots on first request
        expect(assigns(:projects).first.id).to eq(project.id)
        expect(assigns(:projects).first.nofilter).not_to be_blank
      end

      it 'return right children set with root_id set' do
        get :index, set_filter: 1, name: '~child', root_id: project.id
        expect(assigns(:projects).size).to eq(1)
        expect(assigns(:projects).first.id).to eq(child.id)
        expect(assigns(:projects).first.nofilter).to be_blank
      end

      it 'return empty set if all projects are filtered' do
        get :index, set_filter: 1, name: '~deploy'
        expect(assigns(:projects).size).to eq(0)
      end

    end

    context 'outputs' do
      render_views

      ['list', 'tiles', 'calendar', 'chart', 'report'].each do |output|
        it output do
          get :index, set_filter: 1, outputs: [output]
          expect( response ).to be_success
        end
      end
    end

    context 'EXPORTS' do
      render_views

      it 'exports to pdf' do
        get :index, :format => 'pdf', set_filter: '0', easy_query: {columns_to_export: 'all'}
        expect( response ).to be_success
        expect( response.content_type ).to eq( 'application/pdf' )
      end

      it 'exports to xlsx' do
        get :index, :format => 'xlsx', set_filter: '0', easy_query: {columns_to_export: 'all'}
        expect( response ).to be_success
        expect( response.content_type ).to eq( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' )
      end

      it 'exports to xlsx aggr' do
        get :index, :format => 'xlsx', set_filter: '1', aggregated_hours: '1'
        expect( response ).to be_success
        expect( response.content_type ).to eq( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' )
      end

      it 'exports to csv' do
        get :index, :format => 'csv', set_filter: '0', easy_query: {columns_to_export: 'all'}
        expect( response ).to be_success
        expect( response.content_type ).to include( 'text/csv' )
      end
    end

    context 'API' do
      render_views

      it 'renders projects to JSON' do
        count = Project.count
        get :index, :format => 'json'
        expect( response ).to be_success
        expect(json).to have_key(:projects)
        expect( json[:total_count] ).to eq( count )
        expect( json[:projects].count ).to eq( count )
      end
    end

    context 'SETTINGS' do
      render_views

      context 'EXPORTS' do
        context 'milestones in project settings' do
          it 'exports to pdf' do
            get :settings, :id => project.id, :tab => 'versions', :format => 'pdf', set_filter: '0', easy_query: {columns_to_export: 'all'}
            expect( response ).to be_success
            expect( response.content_type ).to eq( 'application/pdf' )
          end

          it 'exports to xlsx' do
            get :settings, :id => project.id, :tab => 'versions', :format => 'xlsx', set_filter: '0', easy_query: {columns_to_export: 'all'}
            expect( response ).to be_success
            expect( response.content_type ).to eq( 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' )
          end

          it 'exports to csv' do
            get :settings, :id => project.id, :tab => 'versions', :format => 'csv', set_filter: '0', easy_query: {columns_to_export: 'all'}
            expect( response ).to be_success
            expect( response.content_type ).to include( 'text/csv' )
          end
        end
      end

      context 'per module', :logged => true do
        let!(:member) do
          m = Member.new(:user_id => User.current.id, :project_id => FactoryGirl.create(:project).id)
          m.role_ids = [Role.create(:name => 'edit_own_projects', :permissions => ['edit_own_projects']).id]
          m.save!
        end

        it 'get projects settings without permissions' do
          Redmine::AccessControl.available_project_modules.each do |project_module|
            project.enabled_module_names = [project_module]
            project.save
            User.current.reload
            get :settings, :id => project
            raise "response: #{response.status} #{project_module}" if response.status != 200
          end
        end
      end

      it 'add a comment' do
        expect{put :update_history, :id => project, :notes => 'test'}.to change(project.journals, :count).by(1)
      end

    end

  end

  describe '#search' do
    let(:project) { FactoryGirl.create(:project, name: 'Vyhledavany projekt') }

    it 'find project matching query' do
      get :index, easy_query_q: 'Vyhledavany'
      expect(response).to be_success
    end
  end

  describe '#copy' do
    context 'project with subprojects and subproject template' do
      let!(:parent_project) { FactoryGirl.create(:project, :with_subprojects, :number_of_subprojects => 2) }
      let!(:template) { FactoryGirl.create(:project, :easy_is_easy_template => true, :parent => parent_project) }
      let(:invalid_query) { FactoryGirl.build(:easy_issue_query,
          :project => parent_project,
          :filters => {'tracker_id' => {:values => [(Tracker.last.id + 1).to_s], :operator => '='}})
      }
      let(:copy_params) {
        {
          "project" => {
            "name" => parent_project.name,
            "parent_id" => nil,
            "description" => parent_project.description,
            "homepage" => parent_project.homepage,
            "author_id" => User.current.id,
            "is_public" => parent_project.is_public,
            "is_planned" => parent_project.is_planned,
            "inherit_members" => parent_project.inherit_members,
            "easy_is_easy_template" => parent_project.easy_is_easy_template,
            "inherit_easy_invoicing_settings" => Redmine::Plugin.installed?(:easy_invoicing) ? parent_project.inherit_easy_invoicing_settings : false,
            "inherit_time_entry_activities" => parent_project.inherit_time_entry_activities,
            "inherit_easy_money_settings" => Redmine::Plugin.installed?(:easy_money) ? parent_project.inherit_easy_money_settings : false,
            "project_custom_field_ids" => parent_project.project_custom_fields.pluck(:id),
            "enabled_module_names" => parent_project.enabled_module_names,
            "tracker_ids" => parent_project.trackers.pluck(:id),
            "issue_custom_field_ids" => parent_project.issue_custom_fields.pluck(:id)
          },
          "only"=>["easy_page_modules", "subprojects", "members", "versions", "issues", "issue_categories", "easy_queries", "documents", "activity", "news", "easy_contacts", "easy_knowledge", "easy_money", ""],
          "id"=>parent_project.id
        }
      }

      it 'should copy only non-template projects' do
        parent_project.reload

        non_templates_before_copy = 3
        templates_before_copy = 1

        expect(Project.non_templates.count).to eq(non_templates_before_copy)
        expect(Project.all.count).to eq(non_templates_before_copy + templates_before_copy)

        post :copy, copy_params

        expect(Project.all.count).to eq(templates_before_copy + 2*non_templates_before_copy)
      end

      it 'should copy with invalid query' do
        allow(invalid_query).to receive(:valid?).and_return(false)

        invalid_query.save(:validate => false)
        expect(invalid_query.valid?).to be false
        parent_project.reload
        expect{post :copy, copy_params}.to change(Project, :count).by(3)
      end
    end
  end

  context 'load allowed parents', :logged => :admin do
    let!(:project) {FactoryGirl.create(:project)}
    let!(:project2) {FactoryGirl.create(:project)}
    let!(:template) {FactoryGirl.create(:project, :easy_is_easy_template => true)}

    render_views

    it 'force templates' do
      get :load_allowed_parents, :id => project.id, :format => :json, :force => 'templates'
      expect(response).to be_success
      expect(response.body).to include(template.name)
      expect(response.body).not_to include(project.name)
      expect(response.body).not_to include(project2.name)
    end

    it 'force projects' do
      get :load_allowed_parents, :id => project.id, :format => :json, :force => 'projects'
      expect(response).to be_success
      expect(response.body).not_to include(template.name)
      expect(response.body).not_to include(project.name)
      expect(response.body).to include(project2.name)
    end
  end

  context 'bulk update', :logged => :admin do
    let!(:project) {FactoryGirl.create(:project)}
    let!(:project2) {FactoryGirl.create(:project)}

    render_views

    it 'destroy' do
      expect { delete :bulk_destroy, :data => {:ids => [project.id, project2.id]} }.to change(Project, :count).by(-2)
    end

    it 'archive / unarchive' do
      post :bulk_archive, :data => {:ids => [project.id, project2.id]}
      [project, project2].each(&:reload)
      expect(project.archived? && project2.archived?).to eq(true)

      post :bulk_unarchive, :data => {:ids => [project.id, project2.id]}
      [project, project2].each(&:reload)
      expect(project.archived? || project2.archived?).to eq(false)
    end

    it 'close / reopen' do
      post :bulk_close, :data => {:ids => [project.id, project2.id]}
      [project, project2].each(&:reload)
      expect(project.closed? && project2.closed?).to eq(true)

      post :bulk_reopen, :data => {:ids => [project.id, project2.id]}
      [project, project2].each(&:reload)
      expect(project.closed? || project2.closed?).to eq(false)
    end
  end
end
