Compare commits
24 Commits
Author | SHA1 | Date |
---|---|---|
Jean-Philippe Lang | 5f8aa55324 | |
Jean-Philippe Lang | 91a161fadb | |
Jean-Philippe Lang | c75e07f8d3 | |
Jean-Philippe Lang | dbe03f5443 | |
Jean-Philippe Lang | 5b1799f245 | |
Jean-Philippe Lang | 8b1a61d856 | |
Jean-Philippe Lang | 9cb17f598d | |
Toshi MARUYAMA | 0d5dd6fc19 | |
Toshi MARUYAMA | fcc1f198e7 | |
Toshi MARUYAMA | 41667cd5de | |
Toshi MARUYAMA | 51175ede2c | |
Toshi MARUYAMA | 9abdbd423d | |
Jean-Philippe Lang | 63212e5c16 | |
Jean-Philippe Lang | 88b3872179 | |
Jean-Philippe Lang | 066e9b7f94 | |
Jean-Philippe Lang | 805debddd0 | |
Jean-Philippe Lang | 01aa2db0af | |
Toshi MARUYAMA | 645749eea8 | |
Jean-Philippe Lang | 8b9a2ff871 | |
Jean-Philippe Lang | 97434b5aaa | |
Jean-Philippe Lang | 4308dd7d4c | |
Jean-Philippe Lang | 449a92640b | |
Jean-Philippe Lang | 448c0a72ee | |
Jean-Philippe Lang | 20180db41e |
2
Gemfile
2
Gemfile
|
@ -1,6 +1,6 @@
|
|||
source 'https://rubygems.org'
|
||||
|
||||
gem "rails", "3.2.16"
|
||||
gem "rails", "3.2.17"
|
||||
gem "jquery-rails", "~> 2.0.2"
|
||||
gem "coderay", "~> 1.1.0"
|
||||
gem "fastercsv", "~> 1.5.0", :platforms => [:mri_18, :mingw_18, :jruby]
|
||||
|
|
|
@ -119,7 +119,7 @@ class ApplicationController < ActionController::Base
|
|||
if (key = api_key_from_request)
|
||||
# Use API key
|
||||
user = User.find_by_api_key(key)
|
||||
else
|
||||
elsif request.authorization.to_s =~ /\ABasic /i
|
||||
# HTTP Basic, either username/password or API key/random
|
||||
authenticate_with_http_basic do |username, password|
|
||||
user = User.try_to_login(username, password) || User.find_by_api_key(username)
|
||||
|
|
|
@ -62,10 +62,14 @@ class IssuesController < ApplicationController
|
|||
case params[:format]
|
||||
when 'csv', 'pdf'
|
||||
@limit = Setting.issues_export_limit.to_i
|
||||
if params[:columns] == 'all'
|
||||
@query.column_names = @query.available_inline_columns.map(&:name)
|
||||
end
|
||||
when 'atom'
|
||||
@limit = Setting.feeds_limit.to_i
|
||||
when 'xml', 'json'
|
||||
@offset, @limit = api_offset_and_limit
|
||||
@query.column_names = %w(author)
|
||||
else
|
||||
@limit = per_page_option
|
||||
end
|
||||
|
|
|
@ -129,6 +129,10 @@ module QueriesHelper
|
|||
when 'IssueRelation'
|
||||
other = value.other_issue(issue)
|
||||
l(value.label_for(issue)) + " ##{other.id}"
|
||||
when 'TrueClass'
|
||||
l(:general_text_Yes)
|
||||
when 'FalseClass'
|
||||
l(:general_text_No)
|
||||
else
|
||||
value.to_s
|
||||
end
|
||||
|
|
|
@ -241,9 +241,7 @@ class CustomField < ActiveRecord::Base
|
|||
errs << ::I18n.t('activerecord.errors.messages.blank')
|
||||
end
|
||||
end
|
||||
if custom_value.value.present?
|
||||
errs += format.validate_custom_value(custom_value)
|
||||
end
|
||||
errs += format.validate_custom_value(custom_value)
|
||||
errs
|
||||
end
|
||||
|
||||
|
|
|
@ -200,7 +200,7 @@ class Issue < ActiveRecord::Base
|
|||
|
||||
# Overrides Redmine::Acts::Customizable::InstanceMethods#available_custom_fields
|
||||
def available_custom_fields
|
||||
(project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields.all) : []
|
||||
(project && tracker) ? (project.all_issue_custom_fields & tracker.custom_fields) : []
|
||||
end
|
||||
|
||||
def visible_custom_field_values(user=nil)
|
||||
|
|
|
@ -333,8 +333,9 @@ class IssueQuery < Query
|
|||
limit(options[:limit]).
|
||||
offset(options[:offset])
|
||||
|
||||
if has_custom_field_column?
|
||||
scope = scope.preload(:custom_values)
|
||||
scope = scope.preload(:custom_values)
|
||||
if has_column?(:author)
|
||||
scope = scope.preload(:author)
|
||||
end
|
||||
|
||||
issues = scope.all
|
||||
|
|
|
@ -51,7 +51,7 @@ class News < ActiveRecord::Base
|
|||
end
|
||||
|
||||
def recipients
|
||||
project.users.select {|user| user.notify_about?(self)}.map(&:mail)
|
||||
project.users.select {|user| user.notify_about?(self) && user.allowed_to?(:view_news, project)}.map(&:mail)
|
||||
end
|
||||
|
||||
# Returns the email addresses that should be cc'd when a new news is added
|
||||
|
|
|
@ -384,8 +384,8 @@ class User < Principal
|
|||
# Find a user account by matching the exact login and then a case-insensitive
|
||||
# version. Exact matches will be given priority.
|
||||
def self.find_by_login(login)
|
||||
login = Redmine::CodesetUtil.replace_invalid_utf8(login.to_s)
|
||||
if login.present?
|
||||
login = login.to_s
|
||||
# First look for an exact match
|
||||
user = where(:login => login).detect {|u| u.login == login}
|
||||
unless user
|
||||
|
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
<div class="splitcontentleft">
|
||||
<div class="box tabular">
|
||||
<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
|
||||
<p><%= f.text_field :name, :required => true %></p>
|
||||
<p><%= f.text_area :description, :rows => 7 %></p>
|
||||
<p><%= f.select :field_format, custom_field_formats_for_select(@custom_field), {}, :disabled => !@custom_field.new_record? %></p>
|
||||
|
||||
<% if @custom_field.format.multiple_supported %>
|
||||
<p>
|
||||
|
|
|
@ -8,7 +8,7 @@
|
|||
<tbody>
|
||||
<% @group.users.sort.each do |user| %>
|
||||
<tr id="user-<%= user.id %>" class="<%= cycle 'odd', 'even' %>">
|
||||
<td class="user"><%= link_to_user user %></td>
|
||||
<td class="name"><%= link_to_user user %></td>
|
||||
<td class="buttons">
|
||||
<%= delete_link group_user_path(@group, :user_id => user), :remote => true %>
|
||||
</td>
|
||||
|
|
|
@ -43,3 +43,5 @@
|
|||
|
||||
<%= call_hook(:view_issues_form_details_bottom, { :issue => @issue, :form => f }) %>
|
||||
<% end %>
|
||||
|
||||
<% heads_for_wiki_formatter %>
|
||||
|
|
|
@ -100,7 +100,7 @@ fr:
|
|||
units:
|
||||
byte:
|
||||
one: "octet"
|
||||
other: "octet"
|
||||
other: "octets"
|
||||
kb: "ko"
|
||||
mb: "Mo"
|
||||
gb: "Go"
|
||||
|
@ -146,7 +146,7 @@ fr:
|
|||
not_same_project: "n'appartient pas au même projet"
|
||||
circular_dependency: "Cette relation créerait une dépendance circulaire"
|
||||
cant_link_an_issue_with_a_descendant: "Une demande ne peut pas être liée à l'une de ses sous-tâches"
|
||||
earlier_than_minimum_start_date: "ne peut pas être antérieure au %{date} à cause des demandes qui précédent"
|
||||
earlier_than_minimum_start_date: "ne peut pas être antérieure au %{date} à cause des demandes qui précèdent"
|
||||
|
||||
actionview_instancetag_blank_option: Choisir
|
||||
|
||||
|
@ -235,13 +235,13 @@ fr:
|
|||
field_is_required: Obligatoire
|
||||
field_firstname: Prénom
|
||||
field_lastname: Nom
|
||||
field_mail: "Email "
|
||||
field_mail: Email
|
||||
field_filename: Fichier
|
||||
field_filesize: Taille
|
||||
field_downloads: Téléchargements
|
||||
field_author: Auteur
|
||||
field_created_on: "Créé "
|
||||
field_updated_on: "Mis-à-jour "
|
||||
field_created_on: Créé
|
||||
field_updated_on: Mis-à-jour
|
||||
field_closed_on: Fermé
|
||||
field_field_format: Format
|
||||
field_is_for_all: Pour tous les projets
|
||||
|
@ -266,14 +266,14 @@ fr:
|
|||
field_fixed_version: Version cible
|
||||
field_user: Utilisateur
|
||||
field_role: Rôle
|
||||
field_homepage: "Site web "
|
||||
field_homepage: Site web
|
||||
field_is_public: Public
|
||||
field_parent: Sous-projet de
|
||||
field_is_in_roadmap: Demandes affichées dans la roadmap
|
||||
field_login: "Identifiant "
|
||||
field_login: Identifiant
|
||||
field_mail_notification: Notifications par mail
|
||||
field_admin: Administrateur
|
||||
field_last_login_on: "Dernière connexion "
|
||||
field_last_login_on: Dernière connexion
|
||||
field_language: Langue
|
||||
field_effective_date: Date
|
||||
field_password: Mot de passe
|
||||
|
@ -547,10 +547,10 @@ fr:
|
|||
label_login: Connexion
|
||||
label_logout: Déconnexion
|
||||
label_help: Aide
|
||||
label_reported_issues: "Demandes soumises "
|
||||
label_reported_issues: Demandes soumises
|
||||
label_assigned_to_me_issues: Demandes qui me sont assignées
|
||||
label_last_login: "Dernière connexion "
|
||||
label_registered_on: "Inscrit le "
|
||||
label_last_login: Dernière connexion
|
||||
label_registered_on: Inscrit le
|
||||
label_activity: Activité
|
||||
label_overall_activity: Activité globale
|
||||
label_user_activity: "Activité de %{value}"
|
||||
|
@ -655,7 +655,7 @@ fr:
|
|||
label_query_plural: Rapports personnalisés
|
||||
label_query_new: Nouveau rapport
|
||||
label_my_queries: Mes rapports personnalisés
|
||||
label_filter_add: "Ajouter le filtre "
|
||||
label_filter_add: Ajouter le filtre
|
||||
label_filter_plural: Filtres
|
||||
label_equals: égal
|
||||
label_not_equals: différent
|
||||
|
@ -688,7 +688,7 @@ fr:
|
|||
label_repository_new: Nouveau dépôt
|
||||
label_repository_plural: Dépôts
|
||||
label_browse: Parcourir
|
||||
label_revision: "Révision "
|
||||
label_revision: Révision
|
||||
label_revision_plural: Révisions
|
||||
label_associated_revisions: Révisions associées
|
||||
label_added: ajouté
|
||||
|
@ -708,7 +708,7 @@ fr:
|
|||
label_roadmap_due_in: "Échéance dans %{value}"
|
||||
label_roadmap_overdue: "En retard de %{value}"
|
||||
label_roadmap_no_issues: Aucune demande pour cette version
|
||||
label_search: "Recherche "
|
||||
label_search: Recherche
|
||||
label_result_plural: Résultats
|
||||
label_all_words: Tous les mots
|
||||
label_wiki: Wiki
|
||||
|
@ -879,7 +879,7 @@ fr:
|
|||
label_cross_project_system: Avec tous les projets
|
||||
label_gantt_progress_line: Ligne de progression
|
||||
label_visibility_private: par moi uniquement
|
||||
label_visibility_roles: par ces roles uniquement
|
||||
label_visibility_roles: par ces rôles uniquement
|
||||
label_visibility_public: par tout le monde
|
||||
label_link: Lien
|
||||
label_only: seulement
|
||||
|
@ -1014,9 +1014,9 @@ fr:
|
|||
text_project_closed: Ce projet est fermé et accessible en lecture seule.
|
||||
text_turning_multiple_off: "Si vous désactivez les valeurs multiples, les valeurs multiples seront supprimées pour n'en conserver qu'une par objet."
|
||||
|
||||
default_role_manager: "Manager "
|
||||
default_role_developer: "Développeur "
|
||||
default_role_reporter: "Rapporteur "
|
||||
default_role_manager: Manager
|
||||
default_role_developer: Développeur
|
||||
default_role_reporter: Rapporteur
|
||||
default_tracker_bug: Anomalie
|
||||
default_tracker_feature: Evolution
|
||||
default_tracker_support: Assistance
|
||||
|
|
|
@ -0,0 +1,12 @@
|
|||
class ChangeChangesetsCommentsLimit < ActiveRecord::Migration
|
||||
def up
|
||||
if ActiveRecord::Base.connection.adapter_name =~ /mysql/i
|
||||
max_size = 16.megabytes
|
||||
change_column :changesets, :comments, :text, :limit => max_size
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
# no-op
|
||||
end
|
||||
end
|
|
@ -4,6 +4,62 @@ Redmine - project management software
|
|||
Copyright (C) 2006-2014 Jean-Philippe Lang
|
||||
http://www.redmine.org/
|
||||
|
||||
== 2014-03-02 v2.5.0
|
||||
|
||||
* Defect #3163: Large inline images overflow
|
||||
* Defect #13385: Searchable checkbox displayed on edit form for not-searchable custom field formats.
|
||||
* Defect #13396: Updating an issue with user or list format custom field, currently having value that is locked or removed, clears that field
|
||||
* Defect #14361: Mercurial commit ids are short (12 digits) on database
|
||||
* Defect #15377: bundle install --without development test fails
|
||||
* Defect #15381: Error pages improvement
|
||||
* Defect #15485: HTML 5 validation multiple ids
|
||||
* Defect #15551: Validating a Setting with invalid name triggers an error
|
||||
* Defect #15552: Preferences are not preserved after adding user with validation error
|
||||
* Defect #15704: Journal for relation should store relation type instead of i18n key
|
||||
* Defect #15709: TimeEntry custom_values are not deleted from the database when destroying the associated project
|
||||
* Defect #15831: Successful update notice for workflows
|
||||
* Defect #15848: REST API: Cannot retrieve memberships of closed projects
|
||||
* Defect #15929: REST API: Integer custom field validation fails when using non-string values
|
||||
* Defect #15947: Deadlock when delete issues in same time on multiple sessions
|
||||
* Defect #15983: Project.activities returns different types depending on context
|
||||
* Defect #16077: Table of contents macro conflicts with collapse macro
|
||||
* Defect #16091: Export CSV with many custom field runs many queries
|
||||
* Defect #16107: ApplicationController mishandles non-Basic authentication information, causing an internal error
|
||||
* Defect #16143: Can't insert too long comment field from repository (MySQL)
|
||||
* Feature #1179: Optionally allow Text and Long Text custom fields support wiki formatting
|
||||
* Feature #1358: Link_to for Custom Field
|
||||
* Feature #2083: CustomField of type "external-link-to" with configurable URL prefix
|
||||
* Feature #2549: Enable the watching of news
|
||||
* Feature #2691: Option to disable automated language-guessing based on HTTP_ACCEPT_LANGUAGE HTTP-header
|
||||
* Feature #8152: Render Version and User custom fields as links
|
||||
* Feature #8562: Watchers list too big in new issue form
|
||||
* Feature #8572: Configuration of which versions (by version-status) are shown in version-format custom fields
|
||||
* Feature #8842: REST API: Filter issues created/updated before or after specific timestamp
|
||||
* Feature #13134: Focus first text field automatically
|
||||
* Feature #14309: Add favicon to Atom feeds
|
||||
* Feature #15275: Improve usage of label "button_update"
|
||||
* Feature #15362: Wrap filters, options and buttons with extra div on the issue list
|
||||
* Feature #15520: Markdown formatting
|
||||
* Feature #15699: Description for custom fields
|
||||
* Feature #15701: Add project identifier substitution option to the URL-pattern property of link format custom fields
|
||||
* Feature #15790: Use the mime-types gem to get mime type for unknown extension
|
||||
* Feature #15815: REST API : Add project status in API response
|
||||
* Feature #15926: Redirect to back_url or referer when clicking "Sign in" while already logged-in
|
||||
* Patch #12753: Update config.i18n.load_path for plugin-supplied locales
|
||||
* Patch #13774: Show warning if CSV-Export exceeds limit
|
||||
* Patch #14766: Better block detection on my page
|
||||
* Patch #15403: Czech "message" and "changeset" translation change
|
||||
* Patch #15420: Don't create duplicate wikis in tests
|
||||
* Patch #15689: Make favicon themeable
|
||||
* Patch #15785: Support more character encodings in incoming emails
|
||||
|
||||
== 2014-03-02 v2.4.4
|
||||
|
||||
* Defect #16081: Export CSV - Custom field true/false not using translation
|
||||
* Defect #16161: Parent task search and datepicker not available after changing status
|
||||
* Defect #16169: Wrong validation when updating integer custom field with spaces
|
||||
* Defect #16177: Mercurial 2.9 compatibility
|
||||
|
||||
== 2014-02-08 v2.4.3
|
||||
|
||||
* Defect #13544: Commit reference: autogenerated issue note has wrong commit link syntax in multi-repo or cross-project context
|
||||
|
|
|
@ -131,7 +131,8 @@ module Redmine
|
|||
# Returns the validation error messages for custom_value
|
||||
# Should return an empty array if custom_value is valid
|
||||
def validate_custom_value(custom_value)
|
||||
errors = Array.wrap(custom_value.value).reject(&:blank?).map do |value|
|
||||
values = Array.wrap(custom_value.value).reject {|value| value.to_s == ''}
|
||||
errors = values.map do |value|
|
||||
validate_single_value(custom_value.custom_field, value, custom_value.customized)
|
||||
end
|
||||
errors.flatten.uniq
|
||||
|
@ -252,16 +253,15 @@ module Redmine
|
|||
class Unbounded < Base
|
||||
def validate_single_value(custom_field, value, customized=nil)
|
||||
errs = super
|
||||
if value.present?
|
||||
unless custom_field.regexp.blank? or value =~ Regexp.new(custom_field.regexp)
|
||||
errs << ::I18n.t('activerecord.errors.messages.invalid')
|
||||
end
|
||||
if custom_field.min_length && value.length < custom_field.min_length
|
||||
errs << ::I18n.t('activerecord.errors.messages.too_short', :count => custom_field.min_length)
|
||||
end
|
||||
if custom_field.max_length && custom_field.max_length > 0 && value.length > custom_field.max_length
|
||||
errs << ::I18n.t('activerecord.errors.messages.too_long', :count => custom_field.max_length)
|
||||
end
|
||||
value = value.to_s
|
||||
unless custom_field.regexp.blank? or value =~ Regexp.new(custom_field.regexp)
|
||||
errs << ::I18n.t('activerecord.errors.messages.invalid')
|
||||
end
|
||||
if custom_field.min_length && value.length < custom_field.min_length
|
||||
errs << ::I18n.t('activerecord.errors.messages.too_short', :count => custom_field.min_length)
|
||||
end
|
||||
if custom_field.max_length && custom_field.max_length > 0 && value.length > custom_field.max_length
|
||||
errs << ::I18n.t('activerecord.errors.messages.too_long', :count => custom_field.max_length)
|
||||
end
|
||||
errs
|
||||
end
|
||||
|
@ -528,8 +528,9 @@ module Redmine
|
|||
end
|
||||
|
||||
def validate_custom_value(custom_value)
|
||||
invalid_values = Array.wrap(custom_value.value) - Array.wrap(custom_value.value_was) - custom_value.custom_field.possible_values
|
||||
if invalid_values.select(&:present?).any?
|
||||
values = Array.wrap(custom_value.value).reject {|value| value.to_s == ''}
|
||||
invalid_values = values - Array.wrap(custom_value.value_was) - custom_value.custom_field.possible_values
|
||||
if invalid_values.any?
|
||||
[::I18n.t('activerecord.errors.messages.inclusion')]
|
||||
else
|
||||
[]
|
||||
|
|
|
@ -79,8 +79,13 @@ def _tags(ui, repo):
|
|||
def _branches(ui, repo):
|
||||
# see mercurial/commands.py:branches
|
||||
def iterbranches():
|
||||
for t, n in repo.branchtags().iteritems():
|
||||
yield t, n, repo.changelog.rev(n)
|
||||
if getattr(repo, 'branchtags', None) is not None:
|
||||
# Mercurial < 2.9
|
||||
for t, n in repo.branchtags().iteritems():
|
||||
yield t, n, repo.changelog.rev(n)
|
||||
else:
|
||||
for tag, heads, tip, isclosed in repo.branchmap().iterbranches():
|
||||
yield tag, tip, repo.changelog.rev(tip)
|
||||
def branchheads(branch):
|
||||
try:
|
||||
return repo.branchheads(branch, closed=False)
|
||||
|
|
|
@ -3,14 +3,14 @@ require 'rexml/document'
|
|||
module Redmine
|
||||
module VERSION #:nodoc:
|
||||
MAJOR = 2
|
||||
MINOR = 4
|
||||
TINY = 3
|
||||
MINOR = 5
|
||||
TINY = 0
|
||||
|
||||
# Branch values:
|
||||
# * official release: nil
|
||||
# * stable branch: stable
|
||||
# * trunk: devel
|
||||
BRANCH = 'devel'
|
||||
BRANCH = 'stable'
|
||||
|
||||
# Retrieves the revision from the working copy
|
||||
def self.revision
|
||||
|
|
|
@ -221,7 +221,7 @@ module Redmine
|
|||
out = ''.html_safe
|
||||
out << link_to_function(show_label, js, :id => "#{html_id}-show", :class => 'collapsible collapsed')
|
||||
out << link_to_function(hide_label, js, :id => "#{html_id}-hide", :class => 'collapsible', :style => 'display:none;')
|
||||
out << content_tag('div', textilizable(text, :object => obj), :id => html_id, :class => 'collapsed-text', :style => 'display:none;')
|
||||
out << content_tag('div', textilizable(text, :object => obj, :headings => false), :id => html_id, :class => 'collapsed-text', :style => 'display:none;')
|
||||
out
|
||||
end
|
||||
|
||||
|
|
|
@ -125,7 +125,7 @@ table.list { border: 1px solid #e4e4e4; border-collapse: collapse; width: 100%;
|
|||
table.list th { background-color:#EEEEEE; padding: 4px; white-space:nowrap; }
|
||||
table.list td {text-align:center; vertical-align:top; padding-right:10px;}
|
||||
table.list td.id { width: 2%; text-align: center;}
|
||||
table.list td.name, table.list td.description, table.list td.subject, table.list td.comments {text-align: left;}
|
||||
table.list td.name, table.list td.description, table.list td.subject, table.list td.comments, table.list td.roles {text-align: left;}
|
||||
table.list td.tick {width:15%}
|
||||
table.list td.checkbox { width: 15px; padding: 2px 0 0 0; }
|
||||
table.list td.checkbox input {padding:0px;}
|
||||
|
|
Binary file not shown.
|
@ -26,7 +26,7 @@ class RepositoriesMercurialControllerTest < ActionController::TestCase
|
|||
REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
|
||||
CHAR_1_HEX = "\xc3\x9c"
|
||||
PRJ_ID = 3
|
||||
NUM_REV = 32
|
||||
NUM_REV = 34
|
||||
|
||||
ruby19_non_utf8_pass =
|
||||
(RUBY_VERSION >= '1.9' && Encoding.default_external.to_s != 'UTF-8')
|
||||
|
|
|
@ -28,6 +28,29 @@ class Redmine::ApiTest::AuthenticationTest < Redmine::ApiTest::Base
|
|||
Setting.rest_api_enabled = '0'
|
||||
end
|
||||
|
||||
def test_api_should_trigger_basic_http_auth_with_basic_authorization_header
|
||||
ApplicationController.any_instance.expects(:authenticate_with_http_basic).once
|
||||
get '/users/current.xml', {}, credentials('jsmith')
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
def test_api_should_not_trigger_basic_http_auth_with_non_basic_authorization_header
|
||||
ApplicationController.any_instance.expects(:authenticate_with_http_basic).never
|
||||
get '/users/current.xml', {}, 'HTTP_AUTHORIZATION' => 'Digest foo bar'
|
||||
assert_response 401
|
||||
end
|
||||
|
||||
def test_invalid_utf8_credentials_should_not_trigger_an_error
|
||||
invalid_utf8 = "\x82"
|
||||
if invalid_utf8.respond_to?(:force_encoding)
|
||||
invalid_utf8.force_encoding('UTF-8')
|
||||
assert !invalid_utf8.valid_encoding?
|
||||
end
|
||||
assert_nothing_raised do
|
||||
get '/users/current.xml', {}, credentials(invalid_utf8, "foo")
|
||||
end
|
||||
end
|
||||
|
||||
def test_api_request_should_not_use_user_session
|
||||
log_user('jsmith', 'jsmith')
|
||||
|
||||
|
|
|
@ -119,6 +119,14 @@ class ActiveSupport::TestCase
|
|||
User.current = saved_user
|
||||
end
|
||||
|
||||
def with_locale(locale, &block)
|
||||
saved_localed = ::I18n.locale
|
||||
::I18n.locale = locale
|
||||
yield
|
||||
ensure
|
||||
::I18n.locale = saved_localed
|
||||
end
|
||||
|
||||
def change_user_password(login, new_password)
|
||||
user = User.where(:login => login).first
|
||||
user.password, user.password_confirmation = new_password, new_password
|
||||
|
|
|
@ -113,9 +113,8 @@ class Redmine::UiTest::IssuesTest < Redmine::UiTest::Base
|
|||
assert page.has_no_content?('Some Watcher')
|
||||
click_link 'Search for watchers to add'
|
||||
within('form#new-watcher-form') do
|
||||
assert page.has_content?('Some One')
|
||||
fill_in 'user_search', :with => 'watch'
|
||||
assert page.has_no_content?('Some One')
|
||||
assert page.has_content?('Some Watcher')
|
||||
check 'Some Watcher'
|
||||
click_button 'Add'
|
||||
end
|
||||
|
|
|
@ -536,6 +536,17 @@ class ChangesetTest < ActiveSupport::TestCase
|
|||
end
|
||||
end
|
||||
|
||||
def test_comments_should_accept_more_than_64k
|
||||
c = Changeset.new(:repository => Repository.first,
|
||||
:committed_on => Time.now,
|
||||
:revision => '123',
|
||||
:scmid => '12345',
|
||||
:comments => "a" * 500.kilobyte)
|
||||
assert c.save
|
||||
c.reload
|
||||
assert_equal 500.kilobyte, c.comments.size
|
||||
end
|
||||
|
||||
def test_identifier
|
||||
c = Changeset.find_by_revision('1')
|
||||
assert_equal c.revision, c.identifier
|
||||
|
|
|
@ -146,6 +146,7 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?('a' * 2)
|
||||
assert !f.valid_field_value?('a')
|
||||
assert !f.valid_field_value?('a' * 6)
|
||||
|
@ -156,6 +157,7 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?('ABC')
|
||||
assert !f.valid_field_value?('abc')
|
||||
end
|
||||
|
@ -165,6 +167,7 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?('1975-07-14')
|
||||
assert !f.valid_field_value?('1975-07-33')
|
||||
assert !f.valid_field_value?('abc')
|
||||
|
@ -175,6 +178,7 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?('value2')
|
||||
assert !f.valid_field_value?('abc')
|
||||
end
|
||||
|
@ -184,6 +188,7 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?('123')
|
||||
assert f.valid_field_value?('+123')
|
||||
assert f.valid_field_value?('-123')
|
||||
|
@ -195,6 +200,7 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?('11.2')
|
||||
assert f.valid_field_value?('-6.250')
|
||||
assert f.valid_field_value?('5')
|
||||
|
@ -206,9 +212,11 @@ class CustomFieldTest < ActiveSupport::TestCase
|
|||
|
||||
assert f.valid_field_value?(nil)
|
||||
assert f.valid_field_value?('')
|
||||
assert !f.valid_field_value?(' ')
|
||||
assert f.valid_field_value?([])
|
||||
assert f.valid_field_value?([nil])
|
||||
assert f.valid_field_value?([''])
|
||||
assert !f.valid_field_value?([' '])
|
||||
|
||||
assert f.valid_field_value?('value2')
|
||||
assert !f.valid_field_value?('abc')
|
||||
|
|
|
@ -36,4 +36,18 @@ class QueriesHelperTest < ActionView::TestCase
|
|||
assert_equal filter_count + 1, fo.size
|
||||
assert_equal [], fo[0]
|
||||
end
|
||||
|
||||
def test_query_to_csv_should_translate_boolean_custom_field_values
|
||||
f = IssueCustomField.generate!(:field_format => 'bool', :name => 'Boolean', :is_for_all => true, :trackers => Tracker.all)
|
||||
issues = [
|
||||
Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {f.id.to_s => '0'}),
|
||||
Issue.generate!(:project_id => 1, :tracker_id => 1, :custom_field_values => {f.id.to_s => '1'})
|
||||
]
|
||||
|
||||
with_locale 'fr' do
|
||||
csv = query_to_csv(issues, IssueQuery.new, :columns => 'all')
|
||||
assert_include "Oui", csv
|
||||
assert_include "Non", csv
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -89,8 +89,8 @@ begin
|
|||
adp = Redmine::Scm::Adapters::MercurialAdapter.new(repo)
|
||||
repo_path = adp.info.root_url.gsub(/\\/, "/")
|
||||
assert_equal REPOSITORY_PATH, repo_path
|
||||
assert_equal '31', adp.info.lastrev.revision
|
||||
assert_equal '31eeee7395c8c78e66dd54c50addd078d10b2355',adp.info.lastrev.scmid
|
||||
assert_equal '33', adp.info.lastrev.revision
|
||||
assert_equal '2e6d546429230f377d7d19c2078abd2dd909f235',adp.info.lastrev.scmid
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -235,6 +235,22 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
|
|||
assert_select_in result, 'a.collapsible', :text => 'Hide example'
|
||||
end
|
||||
|
||||
def test_macro_collapse_should_not_break_toc
|
||||
text = <<-RAW
|
||||
{{toc}}
|
||||
|
||||
h1. Title
|
||||
|
||||
{{collapse(Show example, Hide example)
|
||||
h2. Heading
|
||||
}}"
|
||||
RAW
|
||||
|
||||
expected_toc = '<ul class="toc"><li><a href="#Title">Title</a><ul><li><a href="#Heading">Heading</a></li></ul></li></ul>'
|
||||
|
||||
assert_include expected_toc, textilizable(text).gsub(/[\r\n]/, '')
|
||||
end
|
||||
|
||||
def test_macro_child_pages
|
||||
expected = "<p><ul class=\"pages-hierarchy\">\n" +
|
||||
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
|
||||
|
|
|
@ -23,7 +23,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
|
|||
include Redmine::I18n
|
||||
|
||||
REPOSITORY_PATH = Rails.root.join('tmp/test/mercurial_repository').to_s
|
||||
NUM_REV = 32
|
||||
NUM_REV = 34
|
||||
CHAR_1_HEX = "\xc3\x9c"
|
||||
|
||||
def setup
|
||||
|
@ -263,7 +263,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
|
|||
|
||||
# with_limit
|
||||
changesets = @repository.latest_changesets('', nil, 2)
|
||||
assert_equal %w|31 30|, changesets.collect(&:revision)
|
||||
assert_equal ["#{NUM_REV - 1}", "#{NUM_REV - 2}"], changesets.collect(&:revision)
|
||||
|
||||
# with_filepath
|
||||
changesets = @repository.latest_changesets(
|
||||
|
@ -600,7 +600,7 @@ class RepositoryMercurialTest < ActiveSupport::TestCase
|
|||
@repository.fetch_changesets
|
||||
@project.reload
|
||||
assert_equal NUM_REV, @repository.changesets.count
|
||||
%w|31 31eeee7395c8 31eee|.each do |r1|
|
||||
["#{NUM_REV - 1}", "2e6d54642923", "2e6d5"].each do |r1|
|
||||
changeset = @repository.find_changeset_by_name(r1)
|
||||
assert_nil changeset.next
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue