commit
72594b7765
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 |
@ -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 <asoltys@gmail.com>', 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} <felix@fachschaften.org>", |
||||
last_rev.author |
||||
assert_equal "#{str_felix_hex} <felix@fachschaften.org>", |
||||
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 |
@ -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 |
@ -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 <jsmith@foo.bar>', 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} <felix@fachschaften.org>", 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 |
@ -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 |
Loading…
Reference in new issue