diff --git a/app/assets/stylesheets/content/work_packages/_table_content.sass b/app/assets/stylesheets/content/work_packages/_table_content.sass index a434d9e841..c3b3a7405b 100644 --- a/app/assets/stylesheets/content/work_packages/_table_content.sass +++ b/app/assets/stylesheets/content/work_packages/_table_content.sass @@ -66,8 +66,10 @@ color: $nm-color-error-icon // Remove padding from grouping rows (exceeds allowed width of 41px) -.wp-table--group-header td - padding: 0 !important +.wp-table--group-header + height: $table-timeline--row-height + td + padding: 0 !important // Shrink column of details / inline-create icons .wp-table--configuration-modal--trigger diff --git a/app/controllers/work_packages/bulk_controller.rb b/app/controllers/work_packages/bulk_controller.rb index e01bc6de4f..53d4db4476 100644 --- a/app/controllers/work_packages/bulk_controller.rb +++ b/app/controllers/work_packages/bulk_controller.rb @@ -38,39 +38,22 @@ class WorkPackages::BulkController < ApplicationController include IssuesHelper def edit - @available_statuses = @projects.map { |p| Workflow.available_statuses(p) }.inject { |memo, w| memo & w } - @custom_fields = @projects.map(&:all_work_package_custom_fields).inject { |memo, c| memo & c } - @assignables = @projects.map(&:possible_assignees).inject { |memo, a| memo & a } - @responsibles = @projects.map(&:possible_responsibles).inject { |memo, a| memo & a } - @types = @projects.map(&:types).inject { |memo, t| memo & t } + setup_edit end def update - unsaved_work_package_ids = [] - saved_work_packages = [] - - @work_packages.each do |work_package| - work_package.reload - work_package.add_journal(User.current, params[:notes]) - - # filter parameters by whitelist and add defaults - attributes = parse_params_for_bulk_work_package_attributes params, work_package.project + @call = ::WorkPackages::Bulk::UpdateService + .new(user: current_user, work_packages: @work_packages) + .call(params: params) - call_hook(:controller_work_packages_bulk_edit_before_save, params: params, work_package: work_package) - - service_call = WorkPackages::UpdateService - .new(user: user, work_package: work_package) - .call(attributes: attributes, send_notifications: params[:send_notification] == '1') - - if service_call.success? - saved_work_packages << service_call.result - else - unsaved_work_package_ids << work_package.id - end + if @call.success? + flash[:notice] = t(:notice_successful_update) + redirect_back_or_default(controller: '/work_packages', action: :index, project_id: @project) + else + @bulk_errors = @call.errors + setup_edit + render action: :edit end - - set_flash_from_bulk_save(@work_packages, unsaved_work_package_ids) - redirect_back_or_default(controller: '/work_packages', action: :index, project_id: @project) end def destroy @@ -103,6 +86,14 @@ class WorkPackages::BulkController < ApplicationController private + def setup_edit + @available_statuses = @projects.map { |p| Workflow.available_statuses(p) }.inject { |memo, w| memo & w } + @custom_fields = @projects.map(&:all_work_package_custom_fields).inject { |memo, c| memo & c } + @assignables = @projects.map(&:possible_assignees).inject { |memo, a| memo & a } + @responsibles = @projects.map(&:possible_responsibles).inject { |memo, a| memo & a } + @types = @projects.map(&:types).inject { |memo, t| memo & t } + end + def destroy_work_packages(work_packages) work_packages.each do |work_package| begin @@ -116,34 +107,6 @@ class WorkPackages::BulkController < ApplicationController end end - def parse_params_for_bulk_work_package_attributes(params, project) - return {} unless params.has_key? :work_package - - safe_params = permitted_params.update_work_package project: project - attributes = safe_params.reject { |_k, v| v.blank? } - attributes.keys.each do |k| - attributes[k] = '' if attributes[k] == 'none' - end - attributes[:custom_field_values].reject! { |_k, v| v.blank? } if attributes[:custom_field_values] - attributes.delete :custom_field_values if not attributes.has_key?(:custom_field_values) or attributes[:custom_field_values].empty? - attributes - end - - # Sets the `flash` notice or error based the number of work packages that did not save - # - # @param [Array, WorkPackage] work_packages all of the saved and unsaved WorkPackages - # @param [Array, Integer] unsaved_work_package_ids the WorkPackage ids that were not saved - def set_flash_from_bulk_save(work_packages, unsaved_work_package_ids) - if unsaved_work_package_ids.empty? - flash[:notice] = l(:notice_successful_update) unless work_packages.empty? - else - flash[:error] = l(:notice_failed_to_save_work_packages, - count: unsaved_work_package_ids.size, - total: work_packages.size, - ids: '#' + unsaved_work_package_ids.join(', #')) - end - end - def user current_user end diff --git a/app/models/repository/subversion.rb b/app/models/repository/subversion.rb index 46968cc526..9fb4ee6b81 100644 --- a/app/models/repository/subversion.rb +++ b/app/models/repository/subversion.rb @@ -94,13 +94,16 @@ class Repository::Subversion < Repository def fetch_changesets scm_info = scm.info if scm_info - # latest revision found in database - db_revision = latest_changeset ? latest_changeset.revision.to_i : 0 + # latest revision found in database, may be nil + db_revision = latest_changeset&.revision&.to_i + + # first revision to fetch + identifier_from = db_revision ? db_revision + 1 : scm.start_revision + # latest revision in the repository scm_revision = scm_info.lastrev.identifier.to_i - if db_revision < scm_revision - logger.debug "Fetching changesets for repository #{url}" if logger && logger.debug? - identifier_from = db_revision + 1 + if db_revision.nil? || db_revision < scm_revision + Rails.logger.debug { "Fetching changesets for repository #{url}" } while (identifier_from <= scm_revision) # loads changesets by batches of 200 identifier_to = [identifier_from + 199, scm_revision].min diff --git a/app/services/service_result.rb b/app/services/service_result.rb index 4504df55fe..ebcd33c345 100644 --- a/app/services/service_result.rb +++ b/app/services/service_result.rb @@ -38,6 +38,7 @@ class ServiceResult def initialize(success: false, errors: nil, context: {}, + dependent_results: [], result: nil) self.success = success self.result = result @@ -50,7 +51,7 @@ class ServiceResult ActiveModel::Errors.new(self) end - self.dependent_results = [] + self.dependent_results = dependent_results end alias success? :success @@ -65,7 +66,9 @@ class ServiceResult end def all_results - [result] + dependent_results.map(&:result) + dependent_results.map(&:result).tap do |results| + results.unshift result unless result.nil? + end end def all_errors diff --git a/app/services/work_packages/bulk/update_service.rb b/app/services/work_packages/bulk/update_service.rb new file mode 100644 index 0000000000..e6315ea8b7 --- /dev/null +++ b/app/services/work_packages/bulk/update_service.rb @@ -0,0 +1,93 @@ +#-- encoding: UTF-8 + +#-- copyright +# OpenProject is a project management system. +# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License version 3. +# +# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: +# Copyright (C) 2006-2017 Jean-Philippe Lang +# Copyright (C) 2010-2013 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# 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 General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# See docs/COPYRIGHT.rdoc for more details. +#++ + +module WorkPackages + module Bulk + class UpdateService + include ::Shared::ServiceContext + include ::HookHelper + + attr_accessor :user, :work_packages, :permitted_params + + def initialize(user:, work_packages:) + self.user = user + self.work_packages = work_packages + end + + def call(params:) + self.permitted_params = PermittedParams.new(params, user) + in_context(true) do + bulk_update(params) + end + end + + private + + def bulk_update(params) + saved = [] + errors = {} + + work_packages.each do |work_package| + work_package.add_journal(user, params[:notes]) + + # filter parameters by whitelist and add defaults + attributes = parse_params_for_bulk_work_package_attributes params, work_package.project + + call_hook(:controller_work_packages_bulk_edit_before_save, params: params, work_package: work_package) + + service_call = WorkPackages::UpdateService + .new(user: user, work_package: work_package) + .call(attributes: attributes, send_notifications: params[:send_notification] == '1') + + if service_call.success? + saved << work_package.id + else + errors[work_package.id] = service_call.errors.full_messages + end + end + + ServiceResult.new success: errors.empty?, result: saved, errors: errors + end + + def parse_params_for_bulk_work_package_attributes(params, project) + return {} unless params.has_key? :work_package + + safe_params = permitted_params.update_work_package project: project + attributes = safe_params.reject { |_k, v| v.blank? } + attributes.keys.each do |k| + attributes[k] = '' if attributes[k] == 'none' + end + attributes[:custom_field_values].reject! { |_k, v| v.blank? } if attributes[:custom_field_values] + attributes.delete :custom_field_values if not attributes.has_key?(:custom_field_values) or attributes[:custom_field_values].empty? + attributes + end + end + end +end diff --git a/app/views/work_packages/bulk/edit.html.erb b/app/views/work_packages/bulk/edit.html.erb index 6bdf9110b6..677c7e43f0 100644 --- a/app/views/work_packages/bulk/edit.html.erb +++ b/app/views/work_packages/bulk/edit.html.erb @@ -28,8 +28,35 @@ See docs/COPYRIGHT.rdoc for more details. ++#%> <% html_title l(:label_bulk_edit_selected_work_packages) %> + +<% if @bulk_errors.present? %> +
+ +
+

<%= t('work_packages.bulk.could_not_be_saved') %>

+ + +
+
+<% end %> +

<%= l(:label_bulk_edit_selected_work_packages) %>

- + + <%= styled_form_tag(url_for(controller: '/work_packages/bulk', action: :update), method: :put, class: '-wide-labels') do %> <%= @work_packages.collect {|i| hidden_field_tag('ids[]', i.id)}.join.html_safe %> diff --git a/config/locales/en.yml b/config/locales/en.yml index d6a25fdeaf..9f2ceaa1ee 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -255,6 +255,10 @@ en: one: 'One descendant work package' other: '%{count} work package descendants' + bulk: + could_not_be_saved: "The following work packages could not be saved:" + + move: no_common_statuses_exists: "There is no status available for all selected work packages. Their status cannot be changed." unsupported_for_multiple_projects: 'Bulk move/copy is not supported for work packages from multiple projects' diff --git a/lib/open_project/scm/adapters/subversion.rb b/lib/open_project/scm/adapters/subversion.rb index 04525af2e6..55f8b367d1 100644 --- a/lib/open_project/scm/adapters/subversion.rb +++ b/lib/open_project/scm/adapters/subversion.rb @@ -177,6 +177,25 @@ module OpenProject revisions end + ## + # For repositories that are actually checked-out sub directories of + # other repositories Repository#fetch_changesets will fail trying to + # go through revisions 1:200 because the lowest available revision + # can be greater than 200. + # + # To fix this we find out the earliest available revision here + # and start from there. + def start_revision + cmd = %w(log -r1:HEAD --limit 1) + [target('')] + + rev = capture_svn(cmd).lines.map(&:strip) + .select { |line| line =~ /\Ar\d+ \|/ } + .map { |line| line.split(" ").first.sub(/\Ar/, "") } + .first + + rev ? rev.to_i : 0 + end + def diff(path, identifier_from, identifier_to = nil, _type = 'inline') path ||= '' diff --git a/lib/tasks/testing.rake b/lib/tasks/testing.rake index 71520ed60d..40d768245a 100644 --- a/lib/tasks/testing.rake +++ b/lib/tasks/testing.rake @@ -28,72 +28,6 @@ #++ namespace :test do - desc 'Run unit and functional scm tests' - task :scm do - errors = %w(test:scm:units test:scm:functionals).collect { |task| - begin - Rake::Task[task].invoke - nil - rescue => e - task - end - }.compact - abort "Errors running #{errors.to_sentence(locale: :en)}!" if errors.any? - end - - namespace :scm do - namespace :setup do - desc 'Creates directory for test repositories' - task :create_dir do - FileUtils.mkdir_p Rails.root + '/tmp/test' - end - - supported_scms = [:subversion, :git] - - desc 'Creates a test subversion repository' - supported_scms.each do |scm| - desc "Creates a test #{scm} repository" - task scm => :create_dir do - repo_path = File.join(Rails.root, "tmp/test/#{scm}_repository") - FileUtils.mkdir_p repo_path - # system "gunzip < spec/fixtures/repositories/#{scm}_repository.tar.gz | tar -xv -C tmp/test" - system "tar -xvz -C #{repo_path} -f spec/fixtures/repositories/#{scm}_repository.tar.gz" - end - end - - desc 'Creates all test repositories' - task all: supported_scms - end - - desc 'Updates installed test repositories' - task :update do - require 'fileutils' - Dir.glob('tmp/test/*_repository').each do |dir| - next unless File.basename(dir) =~ %r{\A(.+)_repository\z} && File.directory?(dir) - scm = $1 - next unless fixture = Dir.glob("spec/fixtures/repositories/#{scm}_repository.*").first - next if File.stat(dir).ctime > File.stat(fixture).mtime - - FileUtils.rm_rf dir - Rake::Task["test:scm:setup:#{scm}"].execute - end - end - - Rake::TestTask.new(units: 'db:test:prepare') do |t| - t.libs << 'test' - t.verbose = true - t.test_files = FileList['test/unit/repository*_test.rb'] + FileList['test/unit/lib/redmine/scm/**/*_test.rb'] - end - Rake::Task['test:scm:units'].comment = 'Run the scm unit tests' - - Rake::TestTask.new(functionals: 'db:test:prepare') do |t| - t.libs << 'test' - t.verbose = true - t.test_files = FileList['test/functional/repositories*_test.rb'] - end - Rake::Task['test:scm:functionals'].comment = 'Run the scm functional tests' - end - desc 'runs all tests' namespace :suite do task run: [:cucumber, :spec, 'spec:legacy'] diff --git a/script/ci/setup.sh b/script/ci/setup.sh index 757542238c..178a8f7922 100644 --- a/script/ci/setup.sh +++ b/script/ci/setup.sh @@ -68,8 +68,4 @@ if [ $1 = 'units' ]; then run "sudo apt-get install -qq pandoc" fi -if [ $1 = 'spec_legacy' ]; then - run "bundle exec rake test:scm:setup:all" -fi - run "cp -rp public/assets/frontend_assets.manifest.json config/frontend_assets.manifest.json" diff --git a/spec/controllers/work_packages/bulk_controller_spec.rb b/spec/controllers/work_packages/bulk_controller_spec.rb index 33c50687a6..ce88ff6a49 100644 --- a/spec/controllers/work_packages/bulk_controller_spec.rb +++ b/spec/controllers/work_packages/bulk_controller_spec.rb @@ -399,7 +399,7 @@ describe WorkPackages::BulkController, type: :controller do include_context 'update_request' it 'does not succeed' do - expect(flash[:error]).to include(work_package_ids.join(', #')) + expect(assigns[:bulk_errors].keys).to match_array(work_package_ids) expect(subject).to match_array [user.id] end end diff --git a/spec/features/work_packages/bulk/update_work_package_spec.rb b/spec/features/work_packages/bulk/update_work_package_spec.rb new file mode 100644 index 0000000000..a15b7bfa5f --- /dev/null +++ b/spec/features/work_packages/bulk/update_work_package_spec.rb @@ -0,0 +1,124 @@ +require 'spec_helper' +require 'features/page_objects/notification' + +describe 'Bulk update work packages through Rails view', js: true do + let(:dev_role) do + FactoryBot.create :role, + permissions: %i[view_work_packages] + end + let(:mover_role) do + FactoryBot.create :role, + permissions: %i[view_work_packages copy_work_packages move_work_packages manage_subtasks add_work_packages] + end + let(:dev) do + FactoryBot.create :user, + firstname: 'Dev', + lastname: 'Guy', + member_in_project: project, + member_through_role: dev_role + end + let(:mover) do + FactoryBot.create :admin, + firstname: 'Manager', + lastname: 'Guy', + member_in_project: project, + member_through_role: mover_role + end + + let(:type) { FactoryBot.create :type, name: 'Bug' } + + let!(:project) { FactoryBot.create(:project, name: 'Source', types: [type]) } + + let!(:status) { FactoryBot.create :status } + + let!(:work_package) { + FactoryBot.create(:work_package, + author: dev, + status: status, + project: project, + type: type) + } + let!(:work_package2) { + FactoryBot.create(:work_package, + author: dev, + status: status, + project: project, + type: type) + } + + let!(:status2) { FactoryBot.create :default_status } + let!(:workflow) do + FactoryBot.create :workflow, + type_id: type.id, + old_status: work_package.status, + new_status: status2, + role: mover_role + end + + let(:wp_table) { ::Pages::WorkPackagesTable.new(project) } + let(:context_menu) { Components::WorkPackages::ContextMenu.new } + + before do + login_as current_user + wp_table.visit! + expect_angular_frontend_initialized + wp_table.expect_work_package_listed work_package, work_package2 + + # Select all work packages + find('body').send_keys [:control, 'a'] + end + + describe 'copying work packages' do + context 'with permission' do + let(:current_user) { mover } + + before do + context_menu.open_for work_package + context_menu.choose 'Bulk edit' + + # On work packages edit page + expect(page).to have_selector('#work_package_status_id') + select status2.name, from: 'work_package_status_id' + end + + it 'sets two statuses' do + click_on 'Submit' + + expect_angular_frontend_initialized + wp_table.expect_work_package_count 2 + + # Should update the status + work_package2.reload + work_package.reload + expect(work_package.status_id).to eq(status2.id) + expect(work_package2.status_id).to eq(status2.id) + end + + context 'when making an error in the form' do + it 'does not update the work packages' do + fill_in 'work_package_start_date', with: '123' + click_on 'Submit' + + expect(page).to have_selector('.notification-box', text: I18n.t('work_packages.bulk.could_not_be_saved')) + expect(page).to have_selector('.notification-box', text: work_package.id) + expect(page).to have_selector('.notification-box', text: work_package2.id) + + # Should not update the status + work_package2.reload + work_package.reload + expect(work_package.status_id).to eq(status.id) + expect(work_package2.status_id).to eq(status.id) + end + end + end + + context 'without permission' do + let(:current_user) { dev } + + it 'does not allow to copy' do + context_menu.open_for work_package + context_menu.expect_no_options 'Bulk edit' + end + end + end +end diff --git a/spec_legacy/functional/repositories_controller_spec.rb b/spec_legacy/functional/repositories_controller_spec.rb deleted file mode 100644 index 31ae505fe6..0000000000 --- a/spec_legacy/functional/repositories_controller_spec.rb +++ /dev/null @@ -1,164 +0,0 @@ -#-- encoding: UTF-8 - -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ -require_relative '../legacy_spec_helper' -require 'repositories_controller' - -describe RepositoriesController, type: :controller do - render_views - - # We load legacy fixtures and repository - # but now have to override them with the temporary subversion - # repository, as the filesystem repository has been stripped. - fixtures :all - - before do - unless repository_configured?('subversion') - skip 'Subversion test repository NOT FOUND. Skipping functional tests !!!' - end - end - - let(:project) { Project.find(1) } - - before do - User.current = nil - end - - it 'should revisions' do - get :revisions, params: { project_id: 1 } - assert_response :success - assert_template 'revisions' - refute_nil assigns(:changesets) - end - - it 'should revision' do - get :revision, params: { project_id: 1, rev: 1 } - assert_response :success - refute_nil assigns(:changeset) - assert_equal '1', assigns(:changeset).revision - end - - it 'should revision with before nil and after normal' do - get :revision, params: { project_id: 1, rev: 1 } - assert_response :success - assert_template 'revision' - assert_select('ul', - { - attributes: { class: 'toolbar-items' }, - descendant: { - tag: 'a', - attributes: { - href: @controller.url_for( - only_path: true, - controller: 'repositories', - action: 'revision', - project_id: 'ecookbook', - rev: '0' - ) - } - } - }, false) - assert_select 'ul', - attributes: { class: 'toolbar-items' }, - descendant: { - tag: 'a', - attributes: { - href: @controller.url_for( - only_path: true, - controller: 'repositories', - action: 'revision', - project_id: 'ecookbook', - rev: '2' - ) - } - } - end - - it 'should graph commits per month' do - get :graph, params: { project_id: 1, graph: 'commits_per_month' } - assert_response :success - assert_equal 'image/svg+xml', response.content_type - end - - it 'should committers' do - session[:user_id] = 2 - # add a commit with an unknown user - Changeset.create!( - repository: Project.find(1).repository, - committer: 'foo', - committed_on: Time.now, - revision: 100, - comments: 'Committed by foo.' - ) - - get :committers, params: { project_id: 1 } - assert_response :success - assert_template 'committers' - - assert_select 'td', - content: 'foo', - sibling: { - tag: 'td', - child: { - tag: 'select', - attributes: { name: %r{^committers\[\d+\]\[\]$} } - } - } - assert_select('td', - { - content: 'foo', - sibling: { - tag: 'td', - descendant: { tag: 'option', attributes: { selected: 'selected' } } - } - }, false) - end - - it 'should map committers' do - session[:user_id] = 2 - # add a commit with an unknown user - c = Changeset.create!( - repository: Project.find(1).repository, - committer: 'foo', - committed_on: Time.now, - revision: 100, - comments: 'Committed by foo.' - ) - assert_no_difference "Changeset.where('user_id = 3').count" do - post :committers, - params: { - project_id: 1, - committers: { '0' => ['foo', '2'], - '1' => ['dlopper', '3'] } - } - assert_redirected_to '/projects/ecookbook/repository/committers' - assert_equal User.find(2), c.reload.user - end - end -end diff --git a/spec_legacy/functional/repositories_git_controller_spec.rb b/spec_legacy/functional/repositories_git_controller_spec.rb deleted file mode 100644 index 522f11524a..0000000000 --- a/spec_legacy/functional/repositories_git_controller_spec.rb +++ /dev/null @@ -1,255 +0,0 @@ -#-- encoding: UTF-8 -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ -require_relative '../legacy_spec_helper' -require 'repositories_controller' - -describe RepositoriesController, 'Git', type: :controller do - render_views - - fixtures :all - - # No '..' in the repository path - let(:git_repository_path) { - path = Rails.root.to_s.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository' - path.gsub!(/\//, '\\') if Redmine::Platform.mswin? - path - } - - before do - skip 'Git test repository NOT FOUND. Skipping functional tests !!!' unless File.directory?(git_repository_path) - - User.current = nil - @repository = Repository::Git.create( - project: Project.find(3), - scm_type: 'local', - url: git_repository_path, - path_encoding: 'ISO-8859-1' - ) - - assert @repository - end - - it 'should browse root' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: 3 } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assert_equal 10, assigns(:entries).size - assert assigns(:entries).detect { |e| e.name == 'images' && e.kind == 'dir' } - assert assigns(:entries).detect { |e| e.name == 'this_is_a_really_long_and_verbose_directory_name' && e.kind == 'dir' } - assert assigns(:entries).detect { |e| e.name == 'sources' && e.kind == 'dir' } - assert assigns(:entries).detect { |e| e.name == 'README' && e.kind == 'file' } - assert assigns(:entries).detect { |e| e.name == 'copied_README' && e.kind == 'file' } - assert assigns(:entries).detect { |e| e.name == 'new_file.txt' && e.kind == 'file' } - assert assigns(:entries).detect { |e| e.name == 'renamed_test.txt' && e.kind == 'file' } - assert assigns(:entries).detect { |e| e.name == 'filemane with spaces.txt' && e.kind == 'file' } - assert assigns(:entries).detect { |e| e.name == ' filename with a leading space.txt ' && e.kind == 'file' } - refute_nil assigns(:changesets) - assigns(:changesets).size > 0 - end - - it 'should browse branch' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: 3, rev: 'test_branch' } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assert_equal 4, assigns(:entries).size - assert assigns(:entries).detect { |e| e.name == 'images' && e.kind == 'dir' } - assert assigns(:entries).detect { |e| e.name == 'sources' && e.kind == 'dir' } - assert assigns(:entries).detect { |e| e.name == 'README' && e.kind == 'file' } - assert assigns(:entries).detect { |e| e.name == 'test.txt' && e.kind == 'file' } - refute_nil assigns(:changesets) - assigns(:changesets).size > 0 - end - - it 'should browse tag' do - @repository.fetch_changesets - @repository.reload - [ - 'tag00.lightweight', - 'tag01.annotated', - ].each do |t1| - get :show, params: { project_id: 3, rev: t1 } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assigns(:entries).size > 0 - refute_nil assigns(:changesets) - assigns(:changesets).size > 0 - end - end - - it 'should browse directory' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: 3, repo_path: 'images' } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assert_equal ['edit.png'], assigns(:entries).map(&:name) - entry = assigns(:entries).detect { |e| e.name == 'edit.png' } - refute_nil entry - assert_equal 'file', entry.kind - assert_equal 'images/edit.png', entry.path - refute_nil assigns(:changesets) - assigns(:changesets).size > 0 - end - - it 'should browse at given revision' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: 3, repo_path: 'images', rev: '7234cb2750b63f47bff735edc50a1c0a433c2518' } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assert_equal ['delete.png'], assigns(:entries).map(&:name) - refute_nil assigns(:changesets) - assigns(:changesets).size > 0 - end - - it 'should changes' do - get :changes, params: { project_id: 3, repo_path: 'images/edit.png' } - assert_response :success - assert_template 'changes' - assert_select 'div', - attributes: { class: 'repository-breadcrumbs' }, - content: 'edit.png' - end - - it 'should entry show' do - get :entry, params: { project_id: 3, repo_path: 'sources/watchers_controller.rb' } - assert_response :success - assert_template 'entry' - # Line 19 - assert_select 'th', - content: /11/, - attributes: { class: /line-num/ }, - sibling: { tag: 'td', content: /WITHOUT ANY WARRANTY/ } - end - - it 'should entry download' do - get :entry, params: { project_id: 3, repo_path: 'sources/watchers_controller.rb', format: 'raw' } - assert_response :success - # File content - assert response.body.include?('WITHOUT ANY WARRANTY') - end - - it 'should directory entry' do - get :entry, params: { project_id: 3, repo_path: 'sources' } - assert_response :success - assert_template 'show' - refute_nil assigns(:entry) - assert_equal 'sources', assigns(:entry).name - end - - it 'should diff' do - @repository.fetch_changesets - @repository.reload - - # Full diff of changeset 2f9c0091 - get :diff, params: { project_id: 3, rev: '2f9c0091c754a91af7a9c478e36556b4bde8dcf7' } - assert_response :success - assert_template 'diff' - # Line 22 removed - assert_select 'th', - content: /22/, - sibling: { tag: 'td', - attributes: { class: /diff_out/ }, - content: /def remove/ } - assert_select 'h2', content: /2f9c0091/ - end - - it 'should diff two revs' do - @repository.fetch_changesets - @repository.reload - - get :diff, params: { project_id: 3, rev: '61b685fbe55ab05b5ac68402d5720c1a6ac973d1', - rev_to: '2f9c0091c754a91af7a9c478e36556b4bde8dcf7' } - assert_response :success - assert_template 'diff' - - diff = assigns(:diff) - refute_nil diff - assert_select 'h2', content: /2f9c0091:61b685fb/ - end - - it 'should annotate' do - get :annotate, params: { project_id: 3, repo_path: 'sources/watchers_controller.rb' } - assert_response :success - assert_template 'annotate' - # Line 23, changeset 2f9c0091 - assert_select 'th', content: /24/, - sibling: { tag: 'td', child: { tag: 'a', content: /2f9c0091/ } }, - sibling: { tag: 'td', content: /jsmith/ }, - sibling: { tag: 'td', content: /watcher =/ } - end - - it 'should annotate at given revision' do - @repository.fetch_changesets - @repository.reload - get :annotate, params: { project_id: 3, rev: 'deff7', repo_path: 'sources/watchers_controller.rb' } - assert_response :success - assert_template 'annotate' - assert_select 'div', - attributes: { class: 'repository-breadcrumbs' }, - content: /at deff712f/ - end - - it 'should annotate binary file' do - get :annotate, params: { project_id: 3, repo_path: 'images/edit.png' } - assert_response 200 - - assert_select 'p', attributes: { class: /nodata/ }, - content: I18n.t('repositories.warnings.cannot_annotate') - end - - it 'should revision' do - @repository.fetch_changesets - @repository.reload - ['61b685fbe55ab05b5ac68402d5720c1a6ac973d1', '61b685f'].each do |r| - get :revision, params: { project_id: 3, rev: r } - assert_response :success - assert_template 'revision' - end - end - - it 'should empty revision' do - @repository.fetch_changesets - @repository.reload - ['', ' ', nil].each do |r| - get :revision, params: { project_id: 3, rev: r } - assert_response 404 - assert_error_tag content: /was not found/ - end - end -end diff --git a/spec_legacy/functional/repositories_subversion_controller_spec.rb b/spec_legacy/functional/repositories_subversion_controller_spec.rb deleted file mode 100644 index 15c9558eac..0000000000 --- a/spec_legacy/functional/repositories_subversion_controller_spec.rb +++ /dev/null @@ -1,302 +0,0 @@ -#-- encoding: UTF-8 -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ -require_relative '../legacy_spec_helper' -require 'repositories_controller' - -describe RepositoriesController, 'Subversion', type: :controller do - render_views - - fixtures :all - - PRJ_ID = 3 - - before do - skip 'Subversion test repository NOT FOUND. Skipping functional tests !!!' unless repository_configured?('subversion') - - Setting.default_language = 'en' - User.current = nil - - @project = Project.find(PRJ_ID) - @repository = Repository::Subversion.create(project: @project, - scm_type: 'local', - url: self.class.subversion_repository_url) - - assert @repository - end - - it 'should show' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: PRJ_ID } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - refute_nil assigns(:changesets) - end - - it 'should browse root' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: PRJ_ID } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - entry = assigns(:entries).detect { |e| e.name == 'subversion_test' } - assert_equal 'dir', entry.kind - end - - it 'should browse directory' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: PRJ_ID, repo_path: 'subversion_test' } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assert_equal ['[folder_with_brackets]', 'folder', '.project', 'helloworld.c', 'textfile.txt'], assigns(:entries).map(&:name) - entry = assigns(:entries).detect { |e| e.name == 'helloworld.c' } - assert_equal 'file', entry.kind - assert_equal 'subversion_test/helloworld.c', entry.path - assert_select 'a', content: 'helloworld.c', attributes: { class: /text\-x\-c/ } - end - - it 'should browse at given revision' do - @repository.fetch_changesets - @repository.reload - get :show, params: { project_id: PRJ_ID, repo_path: 'subversion_test', rev: 4 } - assert_response :success - assert_template 'show' - refute_nil assigns(:entries) - assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'], assigns(:entries).map(&:name) - end - - it 'should file changes' do - @repository.fetch_changesets - @repository.reload - get :changes, params: { project_id: PRJ_ID, repo_path: 'subversion_test/folder/helloworld.rb' } - assert_response :success - assert_template 'changes' - - changesets = assigns(:changesets) - refute_nil changesets - assert_equal %w(6 3 2), changesets.map(&:revision) - - # svn properties displayed with svn >= 1.5 only - if @repository.scm.client_version_above?([1, 5, 0]) - refute_nil assigns(:properties) - assert_equal 'native', assigns(:properties)['svn:eol-style'] - assert_select 'ul', - child: { tag: 'li', - child: { tag: 'b', content: 'svn:eol-style' }, - child: { tag: 'span', content: 'native' } } - end - end - - it 'should directory changes' do - @repository.fetch_changesets - @repository.reload - get :changes, params: { project_id: PRJ_ID, repo_path: 'subversion_test/folder' } - assert_response :success - assert_template 'changes' - - changesets = assigns(:changesets) - refute_nil changesets - assert_equal %w(10 9 7 6 5 2), changesets.map(&:revision) - end - - it 'should entry' do - @repository.fetch_changesets - @repository.reload - get :entry, params: { project_id: PRJ_ID, repo_path: 'subversion_test/helloworld.c' } - assert_response :success - assert_template 'entry' - end - - context 'small file upload size', - with_settings: { file_max_size_displayed: 0 } do - - it 'should entry should send if too big' do - @repository.fetch_changesets - @repository.reload - get :entry, params: { project_id: PRJ_ID, repo_path: 'subversion_test/helloworld.c' } - assert_response :success - assert_template nil - assert_equal 'attachment; filename="helloworld.c"', response.headers['Content-Disposition'] - end - end - - it 'should entry at given revision' do - @repository.fetch_changesets - @repository.reload - get :entry, params: { project_id: PRJ_ID, repo_path: 'subversion_test/helloworld.rb', rev: 2 } - assert_response :success - assert_template 'entry' - # this line was removed in r3 and file was moved in r6 - assert_select 'td', attributes: { class: /line-code/ }, - content: /Here's the code/ - end - - it 'should entry not found' do - @repository.fetch_changesets - @repository.reload - get :entry, params: { project_id: PRJ_ID, repo_path: 'subversion_test/zzz.c' } - assert_select 'div', attributes: { id: /errorExplanation/ }, - content: /The entry or revision was not found in the repository/ - end - - it 'should entry download' do - @repository.fetch_changesets - @repository.reload - get :entry, params: { project_id: PRJ_ID, repo_path: 'subversion_test/helloworld.c', format: 'raw' } - assert_response :success - assert_template nil - assert_equal 'attachment; filename="helloworld.c"', response.headers['Content-Disposition'] - end - - it 'should directory entry' do - @repository.fetch_changesets - @repository.reload - get :entry, params: { project_id: PRJ_ID, repo_path: 'subversion_test/folder' } - assert_response :success - assert_template 'show' - refute_nil assigns(:entry) - assert_equal 'folder', assigns(:entry).name - end - - # TODO: this test needs fixtures. - it 'should revision' do - @repository.fetch_changesets - @repository.reload - get :revision, params: { project_id: 1, rev: 2 } - assert_response :success - assert_template 'revision' - assert_select 'ul', - child: { tag: 'li', - # link to the entry at rev 2 - child: { tag: 'a', - attributes: { href: '/projects/ecookbook/repository/revisions/2/entry/test/some/path/in/the/repo' }, - content: 'repo', - # link to partial diff - sibling: { tag: 'a', - attributes: { href: '/projects/ecookbook/repository/revisions/2/diff/test/some/path/in/the/repo' } - } - } - } - end - - it 'should invalid revision' do - @repository.fetch_changesets - @repository.reload - get :revision, params: { project_id: PRJ_ID, rev: 'something_weird' } - assert_response 404 - assert_error_tag content: /was not found/ - end - - it 'should invalid revision diff' do - get :diff, params: { project_id: PRJ_ID, rev: '1', rev_to: 'something_weird' } - assert_response 404 - assert_error_tag content: /was not found/ - end - - it 'should empty revision' do - @repository.fetch_changesets - @repository.reload - ['', ' ', nil].each do |r| - get :revision, params: { project_id: PRJ_ID, rev: r } - assert_response 404 - assert_error_tag content: /was not found/ - end - end - - # TODO: this test needs fixtures. - it 'should revision with repository pointing to a subdirectory' do - r = Project.find(1).repository - # Changes repository url to a subdirectory - r.update_attribute :url, (r.url + '/subversion_test/folder/') - - get :revision, params: { project_id: 1, rev: 2 } - assert_response :success - assert_template 'revision' - assert_select 'ul', - child: { tag: 'li', - # link to the entry at rev 2 - child: { tag: 'a', - attributes: { href: '/projects/ecookbook/repository/revisions/2/entry/test/some/path/in/the/repo' }, - content: 'repo', - # link to partial diff - sibling: { tag: 'a', - attributes: { href: '/projects/ecookbook/repository/revisions/2/diff/test/some/path/in/the/repo' } - } - } - } - end - - it 'should revision diff' do - @repository.fetch_changesets - @repository.reload - get :diff, params: { project_id: PRJ_ID, rev: 3 } - assert_response :success - assert_template 'diff' - - assert_select 'h2', content: /3/ - end - - it 'should directory diff' do - @repository.fetch_changesets - @repository.reload - get :diff, params: { project_id: PRJ_ID, rev: 6, rev_to: 2, repo_path: 'subversion_test/folder' } - assert_response :success - assert_template 'diff' - - diff = assigns(:diff) - refute_nil diff - # 2 files modified - assert_equal 2, Redmine::UnifiedDiff.new(diff).size - - assert_select 'h2', content: /2:6/ - end - - it 'should annotate' do - @repository.fetch_changesets - @repository.reload - get :annotate, params: { project_id: PRJ_ID, repo_path: 'subversion_test/helloworld.c' } - assert_response :success - assert_template 'annotate' - end - - it 'should annotate at given revision' do - @repository.fetch_changesets - @repository.reload - get :annotate, params: { project_id: PRJ_ID, rev: 8, repo_path: 'subversion_test/helloworld.c' } - assert_response :success - assert_template 'annotate' - assert_select 'div', - attributes: { class: 'repository-breadcrumbs' }, - content: /at 8/ - end -end diff --git a/spec_legacy/unit/lib/redmine/scm/adapters/git_adapter_spec.rb b/spec_legacy/unit/lib/redmine/scm/adapters/git_adapter_spec.rb deleted file mode 100644 index ef75e9cf5a..0000000000 --- a/spec_legacy/unit/lib/redmine/scm/adapters/git_adapter_spec.rb +++ /dev/null @@ -1,254 +0,0 @@ -#-- encoding: UTF-8 -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ - -# This file includes UTF-8 "Felix Schäfer". -# We need to consider Ruby 1.9 compatibility. - -require 'legacy_spec_helper' - -describe OpenProject::Scm::Adapters::Git, type: :model do - let(:git_repository_path) { Rails.root.to_s.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository' } - - FELIX_UTF8 = 'Felix Schäfer' - FELIX_HEX = "Felix Sch\xC3\xA4fer" - CHAR_1_HEX = "\xc3\x9c" - - ## Ruby uses ANSI api to fork a process on Windows. - ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem - ## and these are incompatible with ASCII. - # WINDOWS_PASS1 = Redmine::Platform.mswin? - WINDOWS_PASS1 = false - - before do - skip 'Git test repository NOT FOUND. Skipping unit tests !!!' unless File.directory?(git_repository_path) - - @adapter = OpenProject::Scm::Adapters::Git.new( - git_repository_path, - nil, - nil, - nil, - 'ISO-8859-1' - ) - assert @adapter - @char_1 = CHAR_1_HEX.dup - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - end - end - - it 'should scm version' do - to_test = { "git version 1.7.3.4\n" => [1, 7, 3, 4], - "1.6.1\n1.7\n1.8" => [1, 6, 1], - "1.6.2\r\n1.8.1\r\n1.9.1" => [1, 6, 2] } - to_test.each do |s, v| - test_scm_version_for(s, v) - end - end - - it 'should branches' do - assert_equal [ - 'latin-1-path-encoding', - 'master', - 'test-latin-1', - 'test_branch', - ], @adapter.branches - end - - it 'should tags' do - assert_equal [ - 'tag00.lightweight', - 'tag01.annotated', - ], @adapter.tags - end - - it 'should getting all revisions' do - assert_equal 22, @adapter.revisions('', nil, nil, all: true).length - end - - it 'should getting certain revisions' do - assert_equal 1, @adapter.revisions('', '899a15d^', '899a15d').length - end - - it 'should revisions reverse' do - revs1 = @adapter.revisions('', nil, nil, all: true, reverse: true) - assert_equal 22, revs1.length - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', revs1[0].identifier - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs1[20].identifier - - since2 = Time.gm(2010, 9, 30, 0, 0, 0) - revs2 = @adapter.revisions('', nil, nil, all: true, since: since2, reverse: true) - assert_equal 7, revs2.length - assert_equal '67e7792ce20ccae2e4bb73eed09bb397819c8834', revs2[0].identifier - assert_equal '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', revs2[5].identifier - assert_equal '71e5c1d3dca6304805b143b9d0e6695fb3895ea4', revs2[6].identifier - end - - it 'should getting revisions with spaces in filename' do - assert_equal 1, @adapter.revisions('filemane with spaces.txt', - nil, nil, all: true).length - end - - it 'should getting revisions with leading and trailing spaces in filename' do - assert_equal ' filename with a leading space.txt ', - @adapter.revisions(' filename with a leading space.txt ', - nil, nil, all: true)[0].paths[0][:path] - end - - it 'should getting entries with leading and trailing spaces in filename' do - assert_equal ' filename with a leading space.txt ', - @adapter.entries('', - '83ca5fd546063a3c7dc2e568ba3355661a9e2b2c')[3].name - end - - it 'should annotate' do - annotate = @adapter.annotate('sources/watchers_controller.rb') - assert_kind_of OpenProject::Scm::Adapters::Annotate, annotate - assert_equal 41, annotate.lines.size - assert_equal '# This program is free software; you can redistribute it and/or', - annotate.lines[4].strip - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', - annotate.revisions[4].identifier - assert_equal 'jsmith', annotate.revisions[4].author - end - - it 'should annotate moved file' do - annotate = @adapter.annotate('renamed_test.txt') - assert_kind_of OpenProject::Scm::Adapters::Annotate, annotate - assert_equal 2, annotate.lines.size - end - - it 'should last rev' do - last_rev = @adapter.lastrev('README', - '4f26664364207fa8b1af9f8722647ab2d4ac5d43') - assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', last_rev.scmid - assert_equal '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', last_rev.identifier - assert_equal 'Adam Soltys ', last_rev.author - assert_equal '2009-06-24 05:27:38 +0000'.to_time, last_rev.time - end - - it 'should last rev with spaces in filename' do - last_rev = @adapter.lastrev('filemane with spaces.txt', - 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b') - str_felix_utf8 = FELIX_UTF8.dup - str_felix_hex = FELIX_HEX.dup - last_rev_author = last_rev.author - if last_rev_author.respond_to?(:force_encoding) - last_rev_author.force_encoding('UTF-8') - end - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', last_rev.scmid - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', last_rev.identifier - assert_equal "#{str_felix_utf8} ", - last_rev.author - assert_equal "#{str_felix_hex} ", - last_rev.author - assert_equal '2010-09-18 19:59:46 +0000'.to_time, last_rev.time - end - - it 'test latin 1 path' do - if WINDOWS_PASS1 - # - else - p2 = "latin-1-dir/test-#{@char_1}-2.txt" - ['4fc55c43bf3d3dc2efb66145365ddc17639ce81e', '4fc55c43bf3'].each do |r1| - assert @adapter.diff(p2, r1) - assert @adapter.cat(p2, r1) - annotation = @adapter.annotate(p2, r1) - assert annotation.present?, 'No annotation returned' - assert_equal 1, annotation.lines.length - ['64f1f3e89ad1cb57976ff0ad99a107012ba3481d', '64f1f3e89ad1cb5797'].each do |r2| - assert @adapter.diff(p2, r1, r2) - end - end - end - end - - it 'should entries tag' do - entries1 = @adapter.entries(nil, 'tag01.annotated') - assert entries1 - assert_equal 3, entries1.size - assert_equal 'sources', entries1[1].name - assert_equal 'sources', entries1[1].path - assert_equal 'dir', entries1[1].kind - readme = entries1[2] - assert_equal 'README', readme.name - assert_equal 'README', readme.path - assert_equal 'file', readme.kind - assert_equal 27, readme.size - assert_equal '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', readme.lastrev.identifier - assert_equal Time.gm(2007, 12, 14, 9, 24, 1), readme.lastrev.time - end - - it 'should entries branch' do - entries1 = @adapter.entries(nil, 'test_branch') - assert entries1 - assert_equal 4, entries1.size - assert_equal 'sources', entries1[1].name - assert_equal 'sources', entries1[1].path - assert_equal 'dir', entries1[1].kind - readme = entries1[2] - assert_equal 'README', readme.name - assert_equal 'README', readme.path - assert_equal 'file', readme.kind - assert_equal 159, readme.size - assert_equal '713f4944648826f558cf548222f813dabe7cbb04', readme.lastrev.identifier - assert_equal Time.gm(2009, 6, 19, 4, 37, 23), readme.lastrev.time - end - - it 'should entries latin 1 files' do - entries1 = @adapter.entries('latin-1-dir', '64f1f3e8') - assert entries1 - assert_equal 3, entries1.size - f1 = entries1[1] - assert_equal "test-#{@char_1}-2.txt", f1.name - assert_equal "latin-1-dir/test-#{@char_1}-2.txt", f1.path - assert_equal 'file', f1.kind - end - - it 'should entries latin 1 dir' do - if WINDOWS_PASS1 - # - else - entries1 = @adapter.entries("latin-1-dir/test-#{@char_1}-subdir", - '1ca7f5ed') - assert entries1 - assert_equal 3, entries1.size - f1 = entries1[1] - assert_equal "test-#{@char_1}-2.txt", f1.name - assert_equal "latin-1-dir/test-#{@char_1}-subdir/test-#{@char_1}-2.txt", f1.path - assert_equal 'file', f1.kind - end - end - - private - - def test_scm_version_for(scm_command_version, version) - expect(@adapter).to receive(:scm_version_from_command_line).and_return(scm_command_version) - assert_equal version, @adapter.git_binary_version - end -end diff --git a/spec_legacy/unit/lib/redmine/scm/adapters/subversion_adapter_spec.rb b/spec_legacy/unit/lib/redmine/scm/adapters/subversion_adapter_spec.rb deleted file mode 100644 index fa0c4351bc..0000000000 --- a/spec_legacy/unit/lib/redmine/scm/adapters/subversion_adapter_spec.rb +++ /dev/null @@ -1,64 +0,0 @@ -#-- encoding: UTF-8 -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ - -require 'legacy_spec_helper' - -describe OpenProject::Scm::Adapters::Subversion, type: :model do - if repository_configured?('subversion') - before do - @adapter = OpenProject::Scm::Adapters::Subversion.new(self.class.subversion_repository_url) - end - - it 'should client version' do - v = @adapter.client_version - assert v.is_a?(Array) - end - - it 'should scm version' do - to_test = { "svn, version 1.6.13 (r1002816)\n" => [1, 6, 13], - "svn, versione 1.6.13 (r1002816)\n" => [1, 6, 13], - "1.6.1\n1.7\n1.8" => [1, 6, 1], - "1.6.2\r\n1.8.1\r\n1.9.1" => [1, 6, 2] } - to_test.each do |s, v| - test_scm_version_for(s, v) - end - end - - private - - def test_scm_version_for(scm_version, version) - expect(@adapter).to receive(:scm_version_from_command_line).and_return(scm_version) - assert_equal version, @adapter.svn_binary_version - end - - else - puts 'Subversion test repository NOT FOUND. Skipping unit tests !!!' - it 'should fake' do; assert true end - end -end diff --git a/spec_legacy/unit/repository_git_spec.rb b/spec_legacy/unit/repository_git_spec.rb deleted file mode 100644 index 81b821cb35..0000000000 --- a/spec_legacy/unit/repository_git_spec.rb +++ /dev/null @@ -1,338 +0,0 @@ -#-- encoding: UTF-8 -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ -require 'legacy_spec_helper' - -describe Repository::Git, type: :model do - fixtures :all - - # No '..' in the repository path - let(:git_repository_path) { - path = Rails.root.to_s.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository' - path.gsub!(/\//, '\\') if Redmine::Platform.mswin? - path - } - - FELIX_HEX2 = "Felix Sch\xC3\xA4fer" - CHAR_1_HEX2 = "\xc3\x9c" - - ## Ruby uses ANSI api to fork a process on Windows. - ## Japanese Shift_JIS and Traditional Chinese Big5 have 0x5c(backslash) problem - ## and these are incompatible with ASCII. - # WINDOWS_PASS = Redmine::Platform.mswin? - WINDOWS_PASS = false - - before do - skip 'Git test repository NOT FOUND. Skipping unit tests !!!' unless File.directory?(git_repository_path) - - @project = Project.find(3) - @repository = Repository::Git.create( - project: @project, - scm_type: 'local', - url: git_repository_path, - path_encoding: 'ISO-8859-1' - ) - assert @repository - @char_1 = CHAR_1_HEX2.dup - if @char_1.respond_to?(:force_encoding) - @char_1.force_encoding('UTF-8') - end - end - - it 'should fetch changesets from scratch' do - @repository.fetch_changesets - @repository.reload - - assert_equal 22, @repository.changesets.count - file_count = @repository.file_changes.count - assert([33,34].include? file_count) # Mac OS X reports one file less changed - - commit = @repository.changesets.reorder(Arel.sql('committed_on ASC')).first - assert_equal "Initial import.\nThe repository contains 3 files.", commit.comments - assert_equal 'jsmith ', commit.committer - assert_equal User.find_by_login('jsmith'), commit.user - # TODO: add a commit with commit time <> author time to the test repository - assert_equal '2007-12-14 09:22:52 +0000'.to_time, commit.committed_on - assert_equal '2007-12-14'.to_date, commit.commit_date - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', commit.revision - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', commit.scmid - assert_equal 3, commit.file_changes.count - change = commit.file_changes.sort_by(&:path).first - assert_equal 'README', change.path - assert_equal 'A', change.action - end - - it 'should fetch changesets incremental' do - @repository.fetch_changesets - # Remove the 3 latest changesets - @repository.changesets.order(Arel.sql('committed_on DESC')).limit(8).each(&:destroy) - @repository.reload - cs1 = @repository.changesets - assert_equal 14, cs1.count - - rev_a_commit = @repository.changesets.order(Arel.sql('committed_on DESC')).first - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', rev_a_commit.revision - # Mon Jul 5 22:34:26 2010 +0200 - rev_a_committed_on = Time.gm(2010, 9, 18, 19, 59, 46) - assert_equal 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b', rev_a_commit.scmid - assert_equal rev_a_committed_on, rev_a_commit.committed_on - latest_rev = @repository.latest_changeset - assert_equal rev_a_committed_on, latest_rev.committed_on - - @repository.fetch_changesets - assert_equal 22, @repository.changesets.count - end - - it 'should latest changesets' do - @repository.fetch_changesets - @repository.reload - # with limit - changesets = @repository.latest_changesets('', nil, 2) - assert_equal 2, changesets.size - - # with path - changesets = @repository.latest_changesets('images', nil) - assert_equal [ - 'deff712f05a90d96edbd70facc47d944be5897e3', - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', nil) - assert_equal [ - '32ae898b720c2f7eec2723d5bdd558b4cb2d3ddf', - '4a07fe31bffcf2888791f3e6cbc9c4545cefe3e8', - '713f4944648826f558cf548222f813dabe7cbb04', - '61b685fbe55ab05b5ac68402d5720c1a6ac973d1', - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - # with path, revision and limit - changesets = @repository.latest_changesets('images', '899a15dba') - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('images', '899a15dba', 1) - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', '899a15dba') - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', '899a15dba', 1) - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - ], changesets.map(&:revision) - - # with path, tag and limit - changesets = @repository.latest_changesets('images', 'tag01.annotated') - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('images', 'tag01.annotated', 1) - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', 'tag01.annotated') - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', 'tag01.annotated', 1) - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - ], changesets.map(&:revision) - - # with path, branch and limit - changesets = @repository.latest_changesets('images', 'test_branch') - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('images', 'test_branch', 1) - assert_equal [ - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', 'test_branch') - assert_equal [ - '713f4944648826f558cf548222f813dabe7cbb04', - '61b685fbe55ab05b5ac68402d5720c1a6ac973d1', - '899a15dba03a3b350b89c3f537e4bbe02a03cdc9', - '7234cb2750b63f47bff735edc50a1c0a433c2518', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets('README', 'test_branch', 2) - assert_equal [ - '713f4944648826f558cf548222f813dabe7cbb04', - '61b685fbe55ab05b5ac68402d5720c1a6ac973d1', - ], changesets.map(&:revision) - - # latin-1 encoding path - changesets = @repository.latest_changesets( - "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89') - assert_equal [ - '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', - '4fc55c43bf3d3dc2efb66145365ddc17639ce81e', - ], changesets.map(&:revision) - - changesets = @repository.latest_changesets( - "latin-1-dir/test-#{@char_1}-2.txt", '64f1f3e89', 1) - assert_equal [ - '64f1f3e89ad1cb57976ff0ad99a107012ba3481d', - ], changesets.map(&:revision) - end - - it 'should latest changesets latin 1 dir' do - if WINDOWS_PASS - # - else - @repository.fetch_changesets - @repository.reload - changesets = @repository.latest_changesets( - "latin-1-dir/test-#{@char_1}-subdir", '1ca7f5ed') - assert_equal [ - '1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127', - ], changesets.map(&:revision) - end - end - - it 'should find changeset by name' do - @repository.fetch_changesets - @repository.reload - ['7234cb2750b63f47bff735edc50a1c0a433c2518', '7234cb2750b'].each do |r| - assert_equal '7234cb2750b63f47bff735edc50a1c0a433c2518', - @repository.find_changeset_by_name(r).revision - end - end - - it 'should find changeset by empty name' do - @repository.fetch_changesets - @repository.reload - ['', ' ', nil].each do |r| - assert_nil @repository.find_changeset_by_name(r) - end - end - - it 'should identifier' do - @repository.fetch_changesets - @repository.reload - c = @repository.changesets.find_by(revision: '7234cb2750b63f47bff735edc50a1c0a433c2518') - assert_equal c.scmid, c.identifier - end - - it 'should format identifier' do - @repository.fetch_changesets - @repository.reload - c = @repository.changesets.find_by(revision: '7234cb2750b63f47bff735edc50a1c0a433c2518') - assert_equal '7234cb27', c.format_identifier - end - - it 'should activities' do - c = Changeset.create(repository: @repository, - committed_on: Time.now, - revision: 'abc7234cb2750b63f47bff735edc50a1c0a433c2', - scmid: 'abc7234cb2750b63f47bff735edc50a1c0a433c2', - comments: 'test') - - event = find_events(User.find(2)).first # manager - assert event.event_title.include?('abc7234c:') - assert event.event_path =~ /\?rev=abc7234cb2750b63f47bff735edc50a1c0a433c2$/ - end - - it 'should log utf8' do - @repository.fetch_changesets - @repository.reload - str_felix_hex = FELIX_HEX2.dup - if str_felix_hex.respond_to?(:force_encoding) - str_felix_hex.force_encoding('UTF-8') - end - c = @repository.changesets.find_by(revision: 'ed5bb786bbda2dee66a2d50faf51429dbc043a7b') - assert_equal "#{str_felix_hex} ", c.committer - end - - it 'should previous' do - @repository.fetch_changesets - @repository.reload - %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1| - changeset = @repository.find_changeset_by_name(r1) - %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2| - assert_equal @repository.find_changeset_by_name(r2), changeset.previous - end - end - end - - it 'should previous nil' do - @repository.fetch_changesets - @repository.reload - %w|7234cb2750b63f47bff735edc50a1c0a433c2518 7234cb2|.each do |r1| - changeset = @repository.find_changeset_by_name(r1) - assert_nil changeset.previous - end - end - - it 'should next' do - @repository.fetch_changesets - @repository.reload - %w|64f1f3e89ad1cb57976ff0ad99a107012ba3481d 64f1f3e89ad1|.each do |r2| - changeset = @repository.find_changeset_by_name(r2) - %w|1ca7f5ed374f3cb31a93ae5215c2e25cc6ec5127 1ca7f5ed|.each do |r1| - assert_equal @repository.find_changeset_by_name(r1), changeset.next - end - end - end - - it 'should next nil' do - @repository.fetch_changesets - @repository.reload - %w|71e5c1d3dca6304805b143b9d0e6695fb3895ea4 71e5c1d3|.each do |r1| - changeset = @repository.find_changeset_by_name(r1) - assert_nil changeset.next - end - end - - private - - def find_events(user, options = {}) - fetcher = Redmine::Activity::Fetcher.new(user, options) - fetcher.scope = ['changesets'] - fetcher.events(Date.today - 30, Date.today + 1) - end -end diff --git a/spec_legacy/unit/repository_subversion_spec.rb b/spec_legacy/unit/repository_subversion_spec.rb deleted file mode 100644 index 8c17bb85d6..0000000000 --- a/spec_legacy/unit/repository_subversion_spec.rb +++ /dev/null @@ -1,212 +0,0 @@ -#-- encoding: UTF-8 -#-- copyright -# OpenProject is a project management system. -# Copyright (C) 2012-2018 the OpenProject Foundation (OPF) -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License version 3. -# -# OpenProject is a fork of ChiliProject, which is a fork of Redmine. The copyright follows: -# Copyright (C) 2006-2017 Jean-Philippe Lang -# Copyright (C) 2010-2013 the ChiliProject Team -# -# This program is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License -# as published by the Free Software Foundation; either version 2 -# of the License, or (at your option) any later version. -# -# 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 General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program; if not, write to the Free Software -# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. -# -# See docs/COPYRIGHT.rdoc for more details. -#++ -require 'legacy_spec_helper' - -describe Repository::Subversion, type: :model do - fixtures :all - - before do - skip 'Subversion test repository NOT FOUND. Skipping unit tests !!!' unless repository_configured?('subversion') - - @project = Project.find(3) - @repository = Repository::Subversion.create(project: @project, - scm_type: 'existing', - url: self.class.subversion_repository_url) - assert @repository - end - - it 'should fetch changesets from scratch' do - @repository.fetch_changesets - @repository.reload - - assert_equal 14, @repository.changesets.count - assert_equal 34, @repository.file_changes.count - assert_equal 'Initial import.', @repository.changesets.find_by(revision: '1').comments - end - - it 'should fetch changesets incremental' do - @repository.fetch_changesets - # Remove changesets with revision > 5 - @repository.changesets.each do |c| c.destroy if c.revision.to_i > 5 end - @repository.reload - assert_equal 5, @repository.changesets.count - - @repository.fetch_changesets - assert_equal 14, @repository.changesets.count - end - - it 'should latest changesets' do - @repository.fetch_changesets - - # with limit - changesets = @repository.latest_changesets('', nil, 2) - assert_equal 2, changesets.size - assert_equal @repository.latest_changesets('', nil).take(2), changesets - - # with path - changesets = @repository.latest_changesets('subversion_test/folder', nil) - assert_equal ['10', '9', '7', '6', '5', '2'], changesets.map(&:revision) - - # with path and revision - changesets = @repository.latest_changesets('subversion_test/folder', 8) - assert_equal ['7', '6', '5', '2'], changesets.map(&:revision) - end - - it 'should directory listing with square brackets in path' do - @repository.fetch_changesets - @repository.reload - - entries = @repository.entries('subversion_test/[folder_with_brackets]') - refute_nil entries, 'Expect to find entries in folder_with_brackets' - assert_equal 1, entries.size, 'Expect one entry in folder_with_brackets' - assert_equal 'README.txt', entries.first.name - end - - it 'should directory listing with square brackets in base' do - @project = Project.find(3) - @repository = Repository::Subversion.create( - project: @project, - scm_type: 'local', - url: "file:///#{self.class.repository_path('subversion')}/subversion_test/[folder_with_brackets]") - - @repository.fetch_changesets - @repository.reload - - assert_equal 1, @repository.changesets.count, 'Expected to see 1 revision' - assert_equal 2, @repository.file_changes.count, 'Expected to see 2 changes, dir add and file add' - - entries = @repository.entries('') - refute_nil entries, 'Expect to find entries' - assert_equal 1, entries.size, 'Expect a single entry' - assert_equal 'README.txt', entries.first.name - end - - it 'should identifier' do - @repository.fetch_changesets - @repository.reload - c = @repository.changesets.find_by(revision: '1') - assert_equal c.revision, c.identifier - end - - it 'should find changeset by empty name' do - @repository.fetch_changesets - @repository.reload - ['', ' ', nil].each do |r| - assert_nil @repository.find_changeset_by_name(r) - end - end - - it 'should identifier nine digit' do - c = Changeset.new(repository: @repository, committed_on: Time.now, - revision: '123456789', comments: 'test') - assert_equal c.identifier, c.revision - end - - it 'should format identifier' do - @repository.fetch_changesets - @repository.reload - c = @repository.changesets.find_by(revision: '1') - assert_equal c.format_identifier, c.revision - end - - it 'should format identifier nine digit' do - c = Changeset.new(repository: @repository, committed_on: Time.now, - revision: '123456789', comments: 'test') - assert_equal c.format_identifier, c.revision - end - - it 'should activities' do - c = Changeset.create(repository: @repository, committed_on: Time.now, - revision: '1', comments: 'test') - event = find_events(User.find(2)).first # manager - assert event.event_title.include?('1:') - assert event.event_path =~ /\?rev=1$/ - end - - it 'should activities nine digit' do - c = Changeset.create(repository: @repository, committed_on: Time.now, - revision: '123456789', comments: 'test') - event = find_events(User.find(2)).first # manager - assert event.event_title.include?('123456789:') - assert event.event_path =~ /\?rev=123456789$/ - end - - it 'should log encoding ignore setting' do - Setting.commit_logs_encoding = 'windows-1252' - s1 = "\xC2\x80" - s2 = "\xc3\x82\xc2\x80" - if s1.respond_to?(:force_encoding) - s1.force_encoding('ISO-8859-1') - s2.force_encoding('UTF-8') - assert_equal s1.encode('UTF-8'), s2 - end - c = Changeset.new(repository: @repository, - comments: s2, - revision: '123', - committed_on: Time.now) - assert c.save - assert_equal s2, c.comments - end - - it 'should previous' do - @repository.fetch_changesets - @repository.reload - changeset = @repository.find_changeset_by_name('3') - assert_equal @repository.find_changeset_by_name('2'), changeset.previous - end - - it 'should previous nil' do - @repository.fetch_changesets - @repository.reload - changeset = @repository.find_changeset_by_name('1') - assert_nil changeset.previous - end - - it 'should next' do - @repository.fetch_changesets - @repository.reload - changeset = @repository.find_changeset_by_name('2') - assert_equal @repository.find_changeset_by_name('3'), changeset.next - end - - it 'should next nil' do - @repository.fetch_changesets - @repository.reload - changeset = @repository.find_changeset_by_name('14') - assert_nil changeset.next - end - - private - - def find_events(user, options = {}) - fetcher = Redmine::Activity::Fetcher.new(user, options) - fetcher.scope = ['changesets'] - fetcher.events(Date.today - 30, Date.today + 1) - end -end