Merged trunk r1773.
git-svn-id: http://redmine.rubyforge.org/svn/branches/work@1774 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Vendored
+49
@@ -36,4 +36,53 @@ attachments_003:
|
||||
filename: logo.gif
|
||||
description: This is a logo
|
||||
author_id: 2
|
||||
attachments_004:
|
||||
created_on: 2006-07-19 21:07:27 +02:00
|
||||
container_type: Issue
|
||||
container_id: 3
|
||||
downloads: 0
|
||||
disk_filename: 060719210727_source.rb
|
||||
digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
|
||||
id: 4
|
||||
filesize: 153
|
||||
filename: source.rb
|
||||
author_id: 2
|
||||
description: This is a Ruby source file
|
||||
content_type: application/x-ruby
|
||||
attachments_005:
|
||||
created_on: 2006-07-19 21:07:27 +02:00
|
||||
container_type: Issue
|
||||
container_id: 3
|
||||
downloads: 0
|
||||
disk_filename: 060719210727_changeset.diff
|
||||
digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
|
||||
id: 5
|
||||
filesize: 687
|
||||
filename: changeset.diff
|
||||
author_id: 2
|
||||
content_type: text/x-diff
|
||||
attachments_006:
|
||||
created_on: 2006-07-19 21:07:27 +02:00
|
||||
container_type: Issue
|
||||
container_id: 3
|
||||
downloads: 0
|
||||
disk_filename: 060719210727_archive.zip
|
||||
digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
|
||||
id: 6
|
||||
filesize: 157
|
||||
filename: archive.zip
|
||||
author_id: 2
|
||||
content_type: application/octet-stream
|
||||
attachments_007:
|
||||
created_on: 2006-07-19 21:07:27 +02:00
|
||||
container_type: Issue
|
||||
container_id: 4
|
||||
downloads: 0
|
||||
disk_filename: 060719210727_archive.zip
|
||||
digest: b91e08d0cf966d5c6ff411bd8c4cc3a2
|
||||
id: 7
|
||||
filesize: 157
|
||||
filename: archive.zip
|
||||
author_id: 1
|
||||
content_type: application/octet-stream
|
||||
|
||||
Vendored
+7
@@ -13,4 +13,11 @@ changes_002:
|
||||
path: /test/some/path/elsewhere/in/the/repo
|
||||
from_path:
|
||||
from_revision:
|
||||
changes_003:
|
||||
id: 3
|
||||
changeset_id: 101
|
||||
action: M
|
||||
path: /test/some/path/in/the/repo
|
||||
from_path:
|
||||
from_revision:
|
||||
|
||||
+11
-2
@@ -4,9 +4,13 @@ custom_fields_001:
|
||||
min_length: 0
|
||||
regexp: ""
|
||||
is_for_all: true
|
||||
is_filter: true
|
||||
type: IssueCustomField
|
||||
max_length: 0
|
||||
possible_values: MySQL|PostgreSQL|Oracle
|
||||
possible_values:
|
||||
- MySQL
|
||||
- PostgreSQL
|
||||
- Oracle
|
||||
id: 1
|
||||
is_required: false
|
||||
field_format: list
|
||||
@@ -29,9 +33,14 @@ custom_fields_003:
|
||||
min_length: 0
|
||||
regexp: ""
|
||||
is_for_all: false
|
||||
is_filter: true
|
||||
type: ProjectCustomField
|
||||
max_length: 0
|
||||
possible_values: Stable|Beta|Alpha|Planning
|
||||
possible_values:
|
||||
- Stable
|
||||
- Beta
|
||||
- Alpha
|
||||
- Planning
|
||||
id: 3
|
||||
is_required: true
|
||||
field_format: list
|
||||
|
||||
+4
@@ -39,4 +39,8 @@ enabled_modules_010:
|
||||
name: wiki
|
||||
project_id: 3
|
||||
id: 10
|
||||
enabled_modules_011:
|
||||
name: issue_tracking
|
||||
project_id: 2
|
||||
id: 11
|
||||
|
||||
+6
@@ -19,6 +19,7 @@ enumerations_005:
|
||||
name: Normal
|
||||
id: 5
|
||||
opt: IPRI
|
||||
is_default: true
|
||||
enumerations_006:
|
||||
name: High
|
||||
id: 6
|
||||
@@ -39,4 +40,9 @@ enumerations_010:
|
||||
name: Development
|
||||
id: 10
|
||||
opt: ACTI
|
||||
is_default: true
|
||||
enumerations_011:
|
||||
name: QA
|
||||
id: 11
|
||||
opt: ACTI
|
||||
|
||||
Binary file not shown.
@@ -0,0 +1,13 @@
|
||||
Index: trunk/app/controllers/issues_controller.rb
|
||||
===================================================================
|
||||
--- trunk/app/controllers/issues_controller.rb (r‚vision 1483)
|
||||
+++ trunk/app/controllers/issues_controller.rb (r‚vision 1484)
|
||||
@@ -149,7 +149,7 @@
|
||||
attach_files(@issue, params[:attachments])
|
||||
flash[:notice] = l(:notice_successful_create)
|
||||
Mailer.deliver_issue_add(@issue) if Setting.notified_events.include?('issue_added')
|
||||
- redirect_to :controller => 'issues', :action => 'show', :id => @issue, :project_id => @project
|
||||
+ redirect_to :controller => 'issues', :action => 'show', :id => @issue
|
||||
return
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,10 @@
|
||||
# The Greeter class
|
||||
class Greeter
|
||||
def initialize(name)
|
||||
@name = name.capitalize
|
||||
end
|
||||
|
||||
def salute
|
||||
puts "Hello #{@name}!"
|
||||
end
|
||||
end
|
||||
+11
@@ -9,3 +9,14 @@ issue_categories_002:
|
||||
project_id: 1
|
||||
assigned_to_id:
|
||||
id: 2
|
||||
issue_categories_003:
|
||||
name: Stock management
|
||||
project_id: 2
|
||||
assigned_to_id:
|
||||
id: 3
|
||||
issue_categories_004:
|
||||
name: Printing
|
||||
project_id: 2
|
||||
assigned_to_id:
|
||||
id: 4
|
||||
|
||||
Vendored
+23
-3
@@ -13,6 +13,8 @@ issues_001:
|
||||
assigned_to_id:
|
||||
author_id: 2
|
||||
status_id: 1
|
||||
start_date: <%= 1.day.ago.to_date.to_s(:db) %>
|
||||
due_date: <%= 10.day.from_now.to_date.to_s(:db) %>
|
||||
issues_002:
|
||||
created_on: 2006-07-19 21:04:21 +02:00
|
||||
project_id: 1
|
||||
@@ -20,13 +22,15 @@ issues_002:
|
||||
priority_id: 5
|
||||
subject: Add ingredients categories
|
||||
id: 2
|
||||
fixed_version_id:
|
||||
fixed_version_id: 2
|
||||
category_id:
|
||||
description: Ingredients of the recipe should be classified by categories
|
||||
tracker_id: 2
|
||||
assigned_to_id: 3
|
||||
author_id: 2
|
||||
status_id: 2
|
||||
start_date: <%= 2.day.ago.to_date.to_s(:db) %>
|
||||
due_date:
|
||||
issues_003:
|
||||
created_on: 2006-07-19 21:07:27 +02:00
|
||||
project_id: 1
|
||||
@@ -38,7 +42,7 @@ issues_003:
|
||||
category_id:
|
||||
description: Error 281 is encountered when saving a recipe
|
||||
tracker_id: 1
|
||||
assigned_to_id:
|
||||
assigned_to_id: 3
|
||||
author_id: 2
|
||||
status_id: 1
|
||||
start_date: <%= 1.day.from_now.to_date.to_s(:db) %>
|
||||
@@ -71,4 +75,20 @@ issues_005:
|
||||
assigned_to_id:
|
||||
author_id: 2
|
||||
status_id: 1
|
||||
|
||||
issues_006:
|
||||
created_on: <%= 1.minute.ago.to_date.to_s(:db) %>
|
||||
project_id: 5
|
||||
updated_on: <%= 1.minute.ago.to_date.to_s(:db) %>
|
||||
priority_id: 4
|
||||
subject: Issue of a private subproject
|
||||
id: 6
|
||||
fixed_version_id:
|
||||
category_id:
|
||||
description: This is an issue of a private subproject of cookbook
|
||||
tracker_id: 1
|
||||
assigned_to_id:
|
||||
author_id: 2
|
||||
status_id: 1
|
||||
start_date: <%= Date.today.to_s(:db) %>
|
||||
due_date: <%= 1.days.from_now.to_date.to_s(:db) %>
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
x-sender: <jsmith@somenet.foo>
|
||||
x-receiver: <redmine@somenet.foo>
|
||||
Received: from somenet.foo ([127.0.0.1]) by somenet.foo;
|
||||
Sun, 25 Feb 2007 09:57:56 GMT
|
||||
Date: Sun, 25 Feb 2007 10:57:56 +0100
|
||||
From: jsmith@somenet.foo
|
||||
To: redmine@somenet.foo
|
||||
Message-Id: <45e15df440c00_b90238570a27b@osiris.tmail>
|
||||
In-Reply-To: <45e15df440c29_b90238570a27b@osiris.tmail>
|
||||
Subject: [Cookbook - Feature #2]
|
||||
Mime-Version: 1.0
|
||||
Content-Type: text/plain; charset=utf-8
|
||||
|
||||
Note added by mail
|
||||
@@ -0,0 +1,42 @@
|
||||
Return-Path: <jsmith@somenet.foo>
|
||||
Received: from osiris ([127.0.0.1])
|
||||
by OSIRIS
|
||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||
From: "John Smith" <jsmith@somenet.foo>
|
||||
To: <redmine@somenet.foo>
|
||||
Subject: New ticket on a given project
|
||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain;
|
||||
format=flowed;
|
||||
charset="iso-8859-1";
|
||||
reply-type=original
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Priority: 3
|
||||
X-MSMail-Priority: Normal
|
||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
|
||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||
platea dictumst.
|
||||
|
||||
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
||||
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
||||
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
||||
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
||||
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
||||
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
||||
|
||||
Project: onlinestore
|
||||
Status: Resolved
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
Return-Path: <jsmith@somenet.foo>
|
||||
Received: from osiris ([127.0.0.1])
|
||||
by OSIRIS
|
||||
with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200
|
||||
Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris>
|
||||
From: "John Smith" <jsmith@somenet.foo>
|
||||
To: <redmine@somenet.foo>
|
||||
References: <485d0ad366c88_d7014663a025f@osiris.tmail>
|
||||
Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories
|
||||
Date: Sat, 21 Jun 2008 18:41:39 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0"
|
||||
X-Priority: 3
|
||||
X-MSMail-Priority: Normal
|
||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
|
||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
||||
Content-Type: text/plain;
|
||||
charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
This is reply
|
||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
||||
Content-Type: text/html;
|
||||
charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML><HEAD>
|
||||
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
|
||||
<STYLE>BODY {
|
||||
FONT-SIZE: 0.8em; COLOR: #484848; FONT-FAMILY: Verdana, sans-serif
|
||||
}
|
||||
BODY H1 {
|
||||
FONT-SIZE: 1.2em; MARGIN: 0px; FONT-FAMILY: "Trebuchet MS", Verdana, =
|
||||
sans-serif
|
||||
}
|
||||
A {
|
||||
COLOR: #2a5685
|
||||
}
|
||||
A:link {
|
||||
COLOR: #2a5685
|
||||
}
|
||||
A:visited {
|
||||
COLOR: #2a5685
|
||||
}
|
||||
A:hover {
|
||||
COLOR: #c61a1a
|
||||
}
|
||||
A:active {
|
||||
COLOR: #c61a1a
|
||||
}
|
||||
HR {
|
||||
BORDER-RIGHT: 0px; BORDER-TOP: 0px; BACKGROUND: #ccc; BORDER-LEFT: 0px; =
|
||||
WIDTH: 100%; BORDER-BOTTOM: 0px; HEIGHT: 1px
|
||||
}
|
||||
.footer {
|
||||
FONT-SIZE: 0.8em; FONT-STYLE: italic
|
||||
}
|
||||
</STYLE>
|
||||
|
||||
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR></HEAD>
|
||||
<BODY bgColor=3D#ffffff>
|
||||
<DIV><SPAN class=3Dfooter><FONT face=3DArial color=3D#000000 =
|
||||
size=3D2>This is=20
|
||||
reply</FONT></DIV></SPAN></BODY></HTML>
|
||||
|
||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0--
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
Return-Path: <jsmith@somenet.foo>
|
||||
Received: from osiris ([127.0.0.1])
|
||||
by OSIRIS
|
||||
with hMailServer ; Sat, 21 Jun 2008 18:41:39 +0200
|
||||
Message-ID: <006a01c8d3bd$ad9baec0$0a00a8c0@osiris>
|
||||
From: "John Smith" <jsmith@somenet.foo>
|
||||
To: <redmine@somenet.foo>
|
||||
References: <485d0ad366c88_d7014663a025f@osiris.tmail>
|
||||
Subject: Re: [Cookbook - Feature #2] (New) Add ingredients categories
|
||||
Date: Sat, 21 Jun 2008 18:41:39 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="----=_NextPart_000_0067_01C8D3CE.711F9CC0"
|
||||
X-Priority: 3
|
||||
X-MSMail-Priority: Normal
|
||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
|
||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
||||
Content-Type: text/plain;
|
||||
charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
This is reply
|
||||
|
||||
Status: Resolved
|
||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0
|
||||
Content-Type: text/html;
|
||||
charset="utf-8"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
=EF=BB=BF<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML><HEAD>
|
||||
<META http-equiv=3DContent-Type content=3D"text/html; charset=3Dutf-8">
|
||||
<STYLE>BODY {
|
||||
FONT-SIZE: 0.8em; COLOR: #484848; FONT-FAMILY: Verdana, sans-serif
|
||||
}
|
||||
BODY H1 {
|
||||
FONT-SIZE: 1.2em; MARGIN: 0px; FONT-FAMILY: "Trebuchet MS", Verdana, =
|
||||
sans-serif
|
||||
}
|
||||
A {
|
||||
COLOR: #2a5685
|
||||
}
|
||||
A:link {
|
||||
COLOR: #2a5685
|
||||
}
|
||||
A:visited {
|
||||
COLOR: #2a5685
|
||||
}
|
||||
A:hover {
|
||||
COLOR: #c61a1a
|
||||
}
|
||||
A:active {
|
||||
COLOR: #c61a1a
|
||||
}
|
||||
HR {
|
||||
BORDER-RIGHT: 0px; BORDER-TOP: 0px; BACKGROUND: #ccc; BORDER-LEFT: 0px; =
|
||||
WIDTH: 100%; BORDER-BOTTOM: 0px; HEIGHT: 1px
|
||||
}
|
||||
.footer {
|
||||
FONT-SIZE: 0.8em; FONT-STYLE: italic
|
||||
}
|
||||
</STYLE>
|
||||
|
||||
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR></HEAD>
|
||||
<BODY bgColor=3D#ffffff>
|
||||
<DIV><SPAN class=3Dfooter><FONT face=3DArial color=3D#000000 =
|
||||
size=3D2>This is=20
|
||||
reply Status: Resolved</FONT></DIV></SPAN></BODY></HTML>
|
||||
|
||||
------=_NextPart_000_0067_01C8D3CE.711F9CC0--
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
Return-Path: <jsmith@somenet.foo>
|
||||
Received: from osiris ([127.0.0.1])
|
||||
by OSIRIS
|
||||
with hMailServer ; Sat, 21 Jun 2008 15:53:25 +0200
|
||||
Message-ID: <002301c8d3a6$2cdf6950$0a00a8c0@osiris>
|
||||
From: "John Smith" <jsmith@somenet.foo>
|
||||
To: <redmine@somenet.foo>
|
||||
Subject: Ticket created by email with attachment
|
||||
Date: Sat, 21 Jun 2008 15:53:25 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: multipart/mixed;
|
||||
boundary="----=_NextPart_000_001F_01C8D3B6.F05C5270"
|
||||
X-Priority: 3
|
||||
X-MSMail-Priority: Normal
|
||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||
|
||||
This is a multi-part message in MIME format.
|
||||
|
||||
------=_NextPart_000_001F_01C8D3B6.F05C5270
|
||||
Content-Type: multipart/alternative;
|
||||
boundary="----=_NextPart_001_0020_01C8D3B6.F05C5270"
|
||||
|
||||
|
||||
------=_NextPart_001_0020_01C8D3B6.F05C5270
|
||||
Content-Type: text/plain;
|
||||
charset="iso-8859-1"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
This is a new ticket with attachments
|
||||
------=_NextPart_001_0020_01C8D3B6.F05C5270
|
||||
Content-Type: text/html;
|
||||
charset="iso-8859-1"
|
||||
Content-Transfer-Encoding: quoted-printable
|
||||
|
||||
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
|
||||
<HTML><HEAD>
|
||||
<META http-equiv=3DContent-Type content=3D"text/html; =
|
||||
charset=3Diso-8859-1">
|
||||
<META content=3D"MSHTML 6.00.2900.2883" name=3DGENERATOR>
|
||||
<STYLE></STYLE>
|
||||
</HEAD>
|
||||
<BODY bgColor=3D#ffffff>
|
||||
<DIV><FONT face=3DArial size=3D2>This is a new ticket with=20
|
||||
attachments</FONT></DIV></BODY></HTML>
|
||||
|
||||
------=_NextPart_001_0020_01C8D3B6.F05C5270--
|
||||
|
||||
------=_NextPart_000_001F_01C8D3B6.F05C5270
|
||||
Content-Type: image/jpeg;
|
||||
name="Paella.jpg"
|
||||
Content-Transfer-Encoding: base64
|
||||
Content-Disposition: attachment;
|
||||
filename="Paella.jpg"
|
||||
|
||||
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
|
||||
cbis+/WpUqUcMZKdF44n/9k=
|
||||
|
||||
------=_NextPart_000_001F_01C8D3B6.F05C5270--
|
||||
|
||||
@@ -0,0 +1,43 @@
|
||||
Return-Path: <jsmith@somenet.foo>
|
||||
Received: from osiris ([127.0.0.1])
|
||||
by OSIRIS
|
||||
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
|
||||
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
|
||||
From: "John Smith" <jsmith@somenet.foo>
|
||||
To: <redmine@somenet.foo>
|
||||
Subject: New ticket on a given project
|
||||
Date: Sun, 22 Jun 2008 12:28:07 +0200
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain;
|
||||
format=flowed;
|
||||
charset="iso-8859-1";
|
||||
reply-type=original
|
||||
Content-Transfer-Encoding: 7bit
|
||||
X-Priority: 3
|
||||
X-MSMail-Priority: Normal
|
||||
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
|
||||
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas imperdiet
|
||||
turpis et odio. Integer eget pede vel dolor euismod varius. Phasellus
|
||||
blandit eleifend augue. Nulla facilisi. Duis id diam. Class aptent taciti
|
||||
sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. In
|
||||
in urna sed tellus aliquet lobortis. Morbi scelerisque tortor in dolor. Cras
|
||||
sagittis odio eu lacus. Aliquam sem tortor, consequat sit amet, vestibulum
|
||||
id, iaculis at, lectus. Fusce tortor libero, congue ut, euismod nec, luctus
|
||||
eget, eros. Pellentesque tortor enim, feugiat in, dignissim eget, tristique
|
||||
sed, mauris. Pellentesque habitant morbi tristique senectus et netus et
|
||||
malesuada fames ac turpis egestas. Quisque sit amet libero. In hac habitasse
|
||||
platea dictumst.
|
||||
|
||||
Nulla et nunc. Duis pede. Donec et ipsum. Nam ut dui tincidunt neque
|
||||
sollicitudin iaculis. Duis vitae dolor. Vestibulum eget massa. Sed lorem.
|
||||
Nullam volutpat cursus erat. Cras felis dolor, lacinia quis, rutrum et,
|
||||
dictum et, ligula. Sed erat nibh, gravida in, accumsan non, placerat sed,
|
||||
massa. Sed sodales, ante fermentum ultricies sollicitudin, massa leo
|
||||
pulvinar dui, a gravida orci mi eget odio. Nunc a lacus.
|
||||
|
||||
Project: onlinestore
|
||||
Tracker: Feature request
|
||||
category: Stock management
|
||||
priority: Urgent
|
||||
Vendored
+9
-1
@@ -34,7 +34,7 @@ members_005:
|
||||
project_id: 1
|
||||
role_id: 3
|
||||
principal_type: Group
|
||||
principal_id: 2 # Clients
|
||||
principal_id: 2
|
||||
members_006:
|
||||
id: 6
|
||||
created_on: 2008-01-19 19:35:36 +02:00
|
||||
@@ -43,4 +43,12 @@ members_006:
|
||||
principal_type: User
|
||||
principal_id: 7
|
||||
inherited_from: 5
|
||||
members_007:
|
||||
id: 7
|
||||
created_on: 2006-07-19 19:35:33 +02:00
|
||||
project_id: 5
|
||||
role_id: 1
|
||||
principal_type: User
|
||||
principal_id: 2
|
||||
inherited_from:
|
||||
|
||||
Vendored
+13
-1
@@ -3,7 +3,7 @@ projects_001:
|
||||
created_on: 2006-07-19 19:13:59 +02:00
|
||||
name: eCookbook
|
||||
updated_on: 2006-07-19 22:53:01 +02:00
|
||||
projects_count: 2
|
||||
projects_count: 3
|
||||
id: 1
|
||||
description: Recipes management application
|
||||
homepage: http://ecookbook.somenet.foo/
|
||||
@@ -43,3 +43,15 @@ projects_004:
|
||||
is_public: true
|
||||
identifier: subproject2
|
||||
parent_id: 1
|
||||
projects_005:
|
||||
created_on: 2006-07-19 19:15:51 +02:00
|
||||
name: Private child of eCookbook
|
||||
updated_on: 2006-07-19 19:17:07 +02:00
|
||||
projects_count: 0
|
||||
id: 5
|
||||
description: This is a private subproject of a public project
|
||||
homepage: ""
|
||||
is_public: false
|
||||
identifier: private_child
|
||||
parent_id: 1
|
||||
|
||||
+4
@@ -38,3 +38,7 @@ projects_trackers_010:
|
||||
projects_trackers_011:
|
||||
project_id: 4
|
||||
tracker_id: 2
|
||||
projects_trackers_012:
|
||||
project_id: 1
|
||||
tracker_id: 3
|
||||
|
||||
Binary file not shown.
Vendored
+6
@@ -15,6 +15,8 @@ manager:
|
||||
- :add_issue_notes
|
||||
- :move_issues
|
||||
- :delete_issues
|
||||
- :view_issue_watchers
|
||||
- :add_issue_watchers
|
||||
- :manage_public_queries
|
||||
- :save_queries
|
||||
- :view_gantt
|
||||
@@ -29,6 +31,7 @@ manager:
|
||||
- :manage_documents
|
||||
- :view_wiki_pages
|
||||
- :edit_wiki_pages
|
||||
- :protect_wiki_pages
|
||||
- :delete_wiki_pages
|
||||
- :rename_wiki_pages
|
||||
- :add_messages
|
||||
@@ -57,6 +60,7 @@ developer:
|
||||
- :add_issue_notes
|
||||
- :move_issues
|
||||
- :delete_issues
|
||||
- :view_issue_watchers
|
||||
- :save_queries
|
||||
- :view_gantt
|
||||
- :view_calendar
|
||||
@@ -69,6 +73,7 @@ developer:
|
||||
- :manage_documents
|
||||
- :view_wiki_pages
|
||||
- :edit_wiki_pages
|
||||
- :protect_wiki_pages
|
||||
- :delete_wiki_pages
|
||||
- :add_messages
|
||||
- :manage_boards
|
||||
@@ -93,6 +98,7 @@ reporter:
|
||||
- :manage_issue_relations
|
||||
- :add_issue_notes
|
||||
- :move_issues
|
||||
- :view_issue_watchers
|
||||
- :save_queries
|
||||
- :view_gantt
|
||||
- :view_calendar
|
||||
|
||||
Vendored
+1
-1
@@ -14,7 +14,7 @@ versions_002:
|
||||
updated_on: 2006-07-19 21:00:33 +02:00
|
||||
id: 2
|
||||
description: Stable release
|
||||
effective_date: 2006-07-19
|
||||
effective_date: <%= 20.day.from_now.to_date.to_s(:db) %>
|
||||
versions_003:
|
||||
created_on: 2006-07-19 21:00:33 +02:00
|
||||
name: "2.0"
|
||||
|
||||
Vendored
+6
@@ -0,0 +1,6 @@
|
||||
---
|
||||
watchers_001:
|
||||
watchable_type: Issue
|
||||
watchable_id: 2
|
||||
user_id: 3
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@
|
||||
wiki_contents_001:
|
||||
text: |-
|
||||
h1. CookBook documentation␍
|
||||
␍
|
||||
{{child_pages}}␍
|
||||
Some updated [[documentation]] here with gzipped history
|
||||
updated_on: 2007-03-07 00:10:51 +01:00
|
||||
page_id: 1
|
||||
|
||||
Vendored
+8
@@ -4,19 +4,27 @@ wiki_pages_001:
|
||||
title: CookBook_documentation
|
||||
id: 1
|
||||
wiki_id: 1
|
||||
protected: true
|
||||
parent_id:
|
||||
wiki_pages_002:
|
||||
created_on: 2007-03-08 00:18:07 +01:00
|
||||
title: Another_page
|
||||
id: 2
|
||||
wiki_id: 1
|
||||
protected: false
|
||||
parent_id:
|
||||
wiki_pages_003:
|
||||
created_on: 2007-03-08 00:18:07 +01:00
|
||||
title: Start_page
|
||||
id: 3
|
||||
wiki_id: 2
|
||||
protected: false
|
||||
parent_id:
|
||||
wiki_pages_004:
|
||||
created_on: 2007-03-08 00:18:07 +01:00
|
||||
title: Page_with_an_inline_image
|
||||
id: 4
|
||||
wiki_id: 1
|
||||
protected: false
|
||||
parent_id: 1
|
||||
|
||||
@@ -44,6 +44,17 @@ class AccountControllerTest < Test::Unit::TestCase
|
||||
assert_nil assigns(:user)
|
||||
end
|
||||
|
||||
def test_login_should_redirect_to_back_url_param
|
||||
# request.uri is "test.host" in test environment
|
||||
post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.host/issues/show/1'
|
||||
assert_redirected_to '/issues/show/1'
|
||||
end
|
||||
|
||||
def test_login_should_not_redirect_to_another_host
|
||||
post :login, :username => 'jsmith', :password => 'jsmith', :back_url => 'http://test.foo/fake'
|
||||
assert_redirected_to '/my/page'
|
||||
end
|
||||
|
||||
def test_login_with_wrong_password
|
||||
post :login, :username => 'admin', :password => 'bad'
|
||||
assert_response :success
|
||||
|
||||
@@ -0,0 +1,79 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'attachments_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class AttachmentsController; def rescue_action(e) raise e end; end
|
||||
|
||||
|
||||
class AttachmentsControllerTest < Test::Unit::TestCase
|
||||
fixtures :users, :projects, :issues, :attachments
|
||||
|
||||
def setup
|
||||
@controller = AttachmentsController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
Attachment.storage_path = "#{RAILS_ROOT}/test/fixtures/files"
|
||||
User.current = nil
|
||||
end
|
||||
|
||||
def test_routing
|
||||
assert_routing('/attachments/1', :controller => 'attachments', :action => 'show', :id => '1')
|
||||
assert_routing('/attachments/1/filename.ext', :controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext')
|
||||
assert_routing('/attachments/download/1', :controller => 'attachments', :action => 'download', :id => '1')
|
||||
assert_routing('/attachments/download/1/filename.ext', :controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext')
|
||||
end
|
||||
|
||||
def test_recognizes
|
||||
assert_recognizes({:controller => 'attachments', :action => 'show', :id => '1'}, '/attachments/1')
|
||||
assert_recognizes({:controller => 'attachments', :action => 'show', :id => '1'}, '/attachments/show/1')
|
||||
assert_recognizes({:controller => 'attachments', :action => 'show', :id => '1', :filename => 'filename.ext'}, '/attachments/1/filename.ext')
|
||||
assert_recognizes({:controller => 'attachments', :action => 'download', :id => '1'}, '/attachments/download/1')
|
||||
assert_recognizes({:controller => 'attachments', :action => 'download', :id => '1', :filename => 'filename.ext'},'/attachments/download/1/filename.ext')
|
||||
end
|
||||
|
||||
def test_show_diff
|
||||
get :show, :id => 5
|
||||
assert_response :success
|
||||
assert_template 'diff'
|
||||
end
|
||||
|
||||
def test_show_text_file
|
||||
get :show, :id => 4
|
||||
assert_response :success
|
||||
assert_template 'file'
|
||||
end
|
||||
|
||||
def test_show_other
|
||||
get :show, :id => 6
|
||||
assert_response :success
|
||||
assert_equal 'application/octet-stream', @response.content_type
|
||||
end
|
||||
|
||||
def test_download_text_file
|
||||
get :download, :id => 4
|
||||
assert_response :success
|
||||
assert_equal 'application/x-ruby', @response.content_type
|
||||
end
|
||||
|
||||
def test_anonymous_on_private_private
|
||||
get :download, :id => 7
|
||||
assert_redirected_to 'account/login'
|
||||
end
|
||||
end
|
||||
@@ -40,6 +40,8 @@ class DocumentsControllerTest < Test::Unit::TestCase
|
||||
|
||||
def test_new_with_one_attachment
|
||||
@request.session[:user_id] = 2
|
||||
set_tmp_attachments_directory
|
||||
|
||||
post :new, :project_id => 'ecookbook',
|
||||
:document => { :title => 'DocumentsControllerTest#test_post_new',
|
||||
:description => 'This is a new document',
|
||||
|
||||
@@ -0,0 +1,61 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'enumerations_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class EnumerationsController; def rescue_action(e) raise e end; end
|
||||
|
||||
class EnumerationsControllerTest < Test::Unit::TestCase
|
||||
fixtures :enumerations, :issues, :users
|
||||
|
||||
def setup
|
||||
@controller = EnumerationsController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@request.session[:user_id] = 1 # admin
|
||||
end
|
||||
|
||||
def test_index
|
||||
get :index
|
||||
assert_response :success
|
||||
assert_template 'list'
|
||||
end
|
||||
|
||||
def test_destroy_enumeration_not_in_use
|
||||
post :destroy, :id => 7
|
||||
assert_redirected_to :controller => 'enumerations', :action => 'index'
|
||||
assert_nil Enumeration.find_by_id(7)
|
||||
end
|
||||
|
||||
def test_destroy_enumeration_in_use
|
||||
post :destroy, :id => 4
|
||||
assert_response :success
|
||||
assert_template 'destroy'
|
||||
assert_not_nil Enumeration.find_by_id(4)
|
||||
end
|
||||
|
||||
def test_destroy_enumeration_in_use_with_reassignment
|
||||
issue = Issue.find(:first, :conditions => {:priority_id => 4})
|
||||
post :destroy, :id => 4, :reassign_to_id => 6
|
||||
assert_redirected_to :controller => 'enumerations', :action => 'index'
|
||||
assert_nil Enumeration.find_by_id(4)
|
||||
# check that the issue was reassign
|
||||
assert_equal 6, issue.reload.priority_id
|
||||
end
|
||||
end
|
||||
@@ -38,7 +38,9 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
:custom_fields,
|
||||
:custom_values,
|
||||
:custom_fields_trackers,
|
||||
:time_entries
|
||||
:time_entries,
|
||||
:journals,
|
||||
:journal_details
|
||||
|
||||
def setup
|
||||
@controller = IssuesController.new
|
||||
@@ -53,13 +55,44 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
assert_template 'index.rhtml'
|
||||
assert_not_nil assigns(:issues)
|
||||
assert_nil assigns(:project)
|
||||
assert_tag :tag => 'a', :content => /Can't print recipes/
|
||||
assert_tag :tag => 'a', :content => /Subproject issue/
|
||||
# private projects hidden
|
||||
assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
|
||||
assert_no_tag :tag => 'a', :content => /Issue on project 2/
|
||||
end
|
||||
|
||||
def test_index_with_project
|
||||
Setting.display_subprojects_issues = 0
|
||||
get :index, :project_id => 1
|
||||
assert_response :success
|
||||
assert_template 'index.rhtml'
|
||||
assert_not_nil assigns(:issues)
|
||||
assert_tag :tag => 'a', :content => /Can't print recipes/
|
||||
assert_no_tag :tag => 'a', :content => /Subproject issue/
|
||||
end
|
||||
|
||||
def test_index_with_project_and_subprojects
|
||||
Setting.display_subprojects_issues = 1
|
||||
get :index, :project_id => 1
|
||||
assert_response :success
|
||||
assert_template 'index.rhtml'
|
||||
assert_not_nil assigns(:issues)
|
||||
assert_tag :tag => 'a', :content => /Can't print recipes/
|
||||
assert_tag :tag => 'a', :content => /Subproject issue/
|
||||
assert_no_tag :tag => 'a', :content => /Issue of a private subproject/
|
||||
end
|
||||
|
||||
def test_index_with_project_and_subprojects_should_show_private_subprojects
|
||||
@request.session[:user_id] = 2
|
||||
Setting.display_subprojects_issues = 1
|
||||
get :index, :project_id => 1
|
||||
assert_response :success
|
||||
assert_template 'index.rhtml'
|
||||
assert_not_nil assigns(:issues)
|
||||
assert_tag :tag => 'a', :content => /Can't print recipes/
|
||||
assert_tag :tag => 'a', :content => /Subproject issue/
|
||||
assert_tag :tag => 'a', :content => /Issue of a private subproject/
|
||||
end
|
||||
|
||||
def test_index_with_project_and_filter
|
||||
@@ -137,7 +170,7 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
assert_response :success
|
||||
assert_template 'new'
|
||||
|
||||
assert_tag :tag => 'input', :attributes => { :name => 'custom_fields[2]',
|
||||
assert_tag :tag => 'input', :attributes => { :name => 'issue[custom_field_values][2]',
|
||||
:value => 'Default string' }
|
||||
end
|
||||
|
||||
@@ -166,17 +199,20 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
def test_post_new
|
||||
@request.session[:user_id] = 2
|
||||
post :new, :project_id => 1,
|
||||
:issue => {:tracker_id => 1,
|
||||
:issue => {:tracker_id => 3,
|
||||
:subject => 'This is the test_new issue',
|
||||
:description => 'This is the description',
|
||||
:priority_id => 5},
|
||||
:custom_fields => {'2' => 'Value for field 2'}
|
||||
:priority_id => 5,
|
||||
:estimated_hours => '',
|
||||
:custom_field_values => {'2' => 'Value for field 2'}}
|
||||
assert_redirected_to 'issues/show'
|
||||
|
||||
issue = Issue.find_by_subject('This is the test_new issue')
|
||||
assert_not_nil issue
|
||||
assert_equal 2, issue.author_id
|
||||
v = issue.custom_values.find_by_custom_field_id(2)
|
||||
assert_equal 3, issue.tracker_id
|
||||
assert_nil issue.estimated_hours
|
||||
v = issue.custom_values.find(:first, :conditions => {:custom_field_id => 2})
|
||||
assert_not_nil v
|
||||
assert_equal 'Value for field 2', v.value
|
||||
end
|
||||
@@ -191,6 +227,50 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
assert_redirected_to 'issues/show'
|
||||
end
|
||||
|
||||
def test_post_new_with_required_custom_field_and_without_custom_fields_param
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
field.update_attribute(:is_required, true)
|
||||
|
||||
@request.session[:user_id] = 2
|
||||
post :new, :project_id => 1,
|
||||
:issue => {:tracker_id => 1,
|
||||
:subject => 'This is the test_new issue',
|
||||
:description => 'This is the description',
|
||||
:priority_id => 5}
|
||||
assert_response :success
|
||||
assert_template 'new'
|
||||
issue = assigns(:issue)
|
||||
assert_not_nil issue
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
end
|
||||
|
||||
def test_post_should_preserve_fields_values_on_validation_failure
|
||||
@request.session[:user_id] = 2
|
||||
post :new, :project_id => 1,
|
||||
:issue => {:tracker_id => 1,
|
||||
:subject => 'This is the test_new issue',
|
||||
# empty description
|
||||
:description => '',
|
||||
:priority_id => 6,
|
||||
:custom_field_values => {'1' => 'Oracle', '2' => 'Value for field 2'}}
|
||||
assert_response :success
|
||||
assert_template 'new'
|
||||
|
||||
assert_tag :input, :attributes => { :name => 'issue[subject]',
|
||||
:value => 'This is the test_new issue' }
|
||||
assert_tag :select, :attributes => { :name => 'issue[priority_id]' },
|
||||
:child => { :tag => 'option', :attributes => { :selected => 'selected',
|
||||
:value => '6' },
|
||||
:content => 'High' }
|
||||
# Custom fields
|
||||
assert_tag :select, :attributes => { :name => 'issue[custom_field_values][1]' },
|
||||
:child => { :tag => 'option', :attributes => { :selected => 'selected',
|
||||
:value => 'Oracle' },
|
||||
:content => 'Oracle' }
|
||||
assert_tag :input, :attributes => { :name => 'issue[custom_field_values][2]',
|
||||
:value => 'Value for field 2'}
|
||||
end
|
||||
|
||||
def test_copy_issue
|
||||
@request.session[:user_id] = 2
|
||||
get :new, :project_id => 1, :copy_from => 1
|
||||
@@ -230,19 +310,43 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
:content => 'Urgent',
|
||||
:attributes => { :selected => 'selected' } }
|
||||
end
|
||||
|
||||
def test_reply_to_issue
|
||||
@request.session[:user_id] = 2
|
||||
get :reply, :id => 1
|
||||
assert_response :success
|
||||
assert_select_rjs :show, "update"
|
||||
end
|
||||
|
||||
def test_post_edit
|
||||
def test_reply_to_note
|
||||
@request.session[:user_id] = 2
|
||||
get :reply, :id => 1, :journal_id => 2
|
||||
assert_response :success
|
||||
assert_select_rjs :show, "update"
|
||||
end
|
||||
|
||||
def test_post_edit_without_custom_fields_param
|
||||
@request.session[:user_id] = 2
|
||||
ActionMailer::Base.deliveries.clear
|
||||
|
||||
issue = Issue.find(1)
|
||||
assert_equal '125', issue.custom_value_for(2).value
|
||||
old_subject = issue.subject
|
||||
new_subject = 'Subject modified by IssuesControllerTest#test_post_edit'
|
||||
|
||||
post :edit, :id => 1, :issue => {:subject => new_subject}
|
||||
assert_difference('Journal.count') do
|
||||
assert_difference('JournalDetail.count', 2) do
|
||||
post :edit, :id => 1, :issue => {:subject => new_subject,
|
||||
:priority_id => '6',
|
||||
:category_id => '1' # no change
|
||||
}
|
||||
end
|
||||
end
|
||||
assert_redirected_to 'issues/show/1'
|
||||
issue.reload
|
||||
assert_equal new_subject, issue.subject
|
||||
# Make sure custom fields were not cleared
|
||||
assert_equal '125', issue.custom_value_for(2).value
|
||||
|
||||
mail = ActionMailer::Base.deliveries.last
|
||||
assert_kind_of TMail::Mail, mail
|
||||
@@ -250,14 +354,40 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
assert mail.body.include?("Subject changed from #{old_subject} to #{new_subject}")
|
||||
end
|
||||
|
||||
def test_post_edit_with_custom_field_change
|
||||
@request.session[:user_id] = 2
|
||||
issue = Issue.find(1)
|
||||
assert_equal '125', issue.custom_value_for(2).value
|
||||
|
||||
assert_difference('Journal.count') do
|
||||
assert_difference('JournalDetail.count', 3) do
|
||||
post :edit, :id => 1, :issue => {:subject => 'Custom field change',
|
||||
:priority_id => '6',
|
||||
:category_id => '1', # no change
|
||||
:custom_field_values => { '2' => 'New custom value' }
|
||||
}
|
||||
end
|
||||
end
|
||||
assert_redirected_to 'issues/show/1'
|
||||
issue.reload
|
||||
assert_equal 'New custom value', issue.custom_value_for(2).value
|
||||
|
||||
mail = ActionMailer::Base.deliveries.last
|
||||
assert_kind_of TMail::Mail, mail
|
||||
assert mail.body.include?("Searchable field changed from 125 to New custom value")
|
||||
end
|
||||
|
||||
def test_post_edit_with_status_and_assignee_change
|
||||
issue = Issue.find(1)
|
||||
assert_equal 1, issue.status_id
|
||||
@request.session[:user_id] = 2
|
||||
post :edit,
|
||||
:id => 1,
|
||||
:issue => { :status_id => 2, :assigned_to_id => 3 },
|
||||
:notes => 'Assigned to dlopper'
|
||||
assert_difference('TimeEntry.count', 0) do
|
||||
post :edit,
|
||||
:id => 1,
|
||||
:issue => { :status_id => 2, :assigned_to_id => 3 },
|
||||
:notes => 'Assigned to dlopper',
|
||||
:time_entry => { :hours => '', :comments => '', :activity_id => Enumeration.get_values('ACTI').first }
|
||||
end
|
||||
assert_redirected_to 'issues/show/1'
|
||||
issue.reload
|
||||
assert_equal 2, issue.status_id
|
||||
@@ -288,10 +418,12 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
def test_post_edit_with_note_and_spent_time
|
||||
@request.session[:user_id] = 2
|
||||
spent_hours_before = Issue.find(1).spent_hours
|
||||
post :edit,
|
||||
:id => 1,
|
||||
:notes => '2.5 hours added',
|
||||
:time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.get_values('ACTI').first }
|
||||
assert_difference('TimeEntry.count') do
|
||||
post :edit,
|
||||
:id => 1,
|
||||
:notes => '2.5 hours added',
|
||||
:time_entry => { :hours => '2.5', :comments => '', :activity_id => Enumeration.get_values('ACTI').first }
|
||||
end
|
||||
assert_redirected_to 'issues/show/1'
|
||||
|
||||
issue = Issue.find(1)
|
||||
@@ -307,6 +439,8 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_post_edit_with_attachment_only
|
||||
set_tmp_attachments_directory
|
||||
|
||||
# anonymous user
|
||||
post :edit,
|
||||
:id => 1,
|
||||
@@ -398,10 +532,10 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
:attributes => { :href => '/issues/edit/1?issue%5Bstatus_id%5D=5',
|
||||
:class => '' }
|
||||
assert_tag :tag => 'a', :content => 'Immediate',
|
||||
:attributes => { :href => '/issues/edit/1?issue%5Bpriority_id%5D=8',
|
||||
:attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&priority_id=8',
|
||||
:class => '' }
|
||||
assert_tag :tag => 'a', :content => 'Dave Lopper',
|
||||
:attributes => { :href => '/issues/edit/1?issue%5Bassigned_to_id%5D=3',
|
||||
:attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&ids%5B%5D=1',
|
||||
:class => '' }
|
||||
assert_tag :tag => 'a', :content => 'Copy',
|
||||
:attributes => { :href => '/projects/ecookbook/issues/new?copy_from=1',
|
||||
@@ -431,6 +565,12 @@ class IssuesControllerTest < Test::Unit::TestCase
|
||||
assert_tag :tag => 'a', :content => 'Edit',
|
||||
:attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&ids%5B%5D=2',
|
||||
:class => 'icon-edit' }
|
||||
assert_tag :tag => 'a', :content => 'Immediate',
|
||||
:attributes => { :href => '/issues/bulk_edit?ids%5B%5D=1&ids%5B%5D=2&priority_id=8',
|
||||
:class => '' }
|
||||
assert_tag :tag => 'a', :content => 'Dave Lopper',
|
||||
:attributes => { :href => '/issues/bulk_edit?assigned_to_id=3&ids%5B%5D=1&ids%5B%5D=2',
|
||||
:class => '' }
|
||||
assert_tag :tag => 'a', :content => 'Move',
|
||||
:attributes => { :href => '/issues/move?ids%5B%5D=1&ids%5B%5D=2',
|
||||
:class => 'icon-move' }
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'mail_handler_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class MailHandlerController; def rescue_action(e) raise e end; end
|
||||
|
||||
class MailHandlerControllerTest < Test::Unit::TestCase
|
||||
fixtures :users, :projects, :enabled_modules, :roles, :members, :issues, :issue_statuses, :trackers, :enumerations
|
||||
|
||||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
|
||||
|
||||
def setup
|
||||
@controller = MailHandlerController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
User.current = nil
|
||||
end
|
||||
|
||||
def test_should_create_issue
|
||||
# Enable API and set a key
|
||||
Setting.mail_handler_api_enabled = 1
|
||||
Setting.mail_handler_api_key = 'secret'
|
||||
|
||||
post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
|
||||
assert_response 201
|
||||
end
|
||||
|
||||
def test_should_not_allow
|
||||
# Disable API
|
||||
Setting.mail_handler_api_enabled = 0
|
||||
Setting.mail_handler_api_key = 'secret'
|
||||
|
||||
post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml'))
|
||||
assert_response 403
|
||||
end
|
||||
end
|
||||
@@ -40,6 +40,15 @@ class MessagesControllerTest < Test::Unit::TestCase
|
||||
assert_not_nil assigns(:topic)
|
||||
end
|
||||
|
||||
def test_show_with_reply_permission
|
||||
@request.session[:user_id] = 2
|
||||
get :show, :board_id => 1, :id => 1
|
||||
assert_response :success
|
||||
assert_template 'show'
|
||||
assert_tag :div, :attributes => { :id => 'reply' },
|
||||
:descendant => { :tag => 'textarea', :attributes => { :id => 'message_content' } }
|
||||
end
|
||||
|
||||
def test_show_message_not_found
|
||||
get :show, :board_id => 1, :id => 99999
|
||||
assert_response 404
|
||||
@@ -108,4 +117,11 @@ class MessagesControllerTest < Test::Unit::TestCase
|
||||
assert_redirected_to 'boards/show'
|
||||
assert_nil Message.find_by_id(1)
|
||||
end
|
||||
|
||||
def test_quote
|
||||
@request.session[:user_id] = 2
|
||||
xhr :get, :quote, :board_id => 1, :id => 3
|
||||
assert_response :success
|
||||
assert_select_rjs :show, 'reply'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -29,24 +29,27 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
@controller = ProjectsController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
@request.session[:user_id] = nil
|
||||
end
|
||||
|
||||
def test_index
|
||||
get :index
|
||||
assert_response :success
|
||||
assert_template 'list'
|
||||
end
|
||||
|
||||
def test_list
|
||||
get :list
|
||||
assert_response :success
|
||||
assert_template 'list'
|
||||
assert_template 'index'
|
||||
assert_not_nil assigns(:project_tree)
|
||||
# Root project as hash key
|
||||
assert assigns(:project_tree).has_key?(Project.find(1))
|
||||
assert assigns(:project_tree).keys.include?(Project.find(1))
|
||||
# Subproject in corresponding value
|
||||
assert assigns(:project_tree)[Project.find(1)].include?(Project.find(3))
|
||||
end
|
||||
|
||||
def test_index_atom
|
||||
get :index, :format => 'atom'
|
||||
assert_response :success
|
||||
assert_template 'common/feed.atom.rxml'
|
||||
assert_select 'feed>title', :text => 'Redmine: Latest projects'
|
||||
assert_select 'feed>entry', :count => Project.count(:conditions => Project.visible_by(User.current))
|
||||
end
|
||||
|
||||
def test_show_by_id
|
||||
get :show, :id => 1
|
||||
@@ -63,6 +66,21 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
assert_equal Project.find_by_identifier('ecookbook'), assigns(:project)
|
||||
end
|
||||
|
||||
def test_private_subprojects_hidden
|
||||
get :show, :id => 'ecookbook'
|
||||
assert_response :success
|
||||
assert_template 'show'
|
||||
assert_no_tag :tag => 'a', :content => /Private child/
|
||||
end
|
||||
|
||||
def test_private_subprojects_visible
|
||||
@request.session[:user_id] = 2 # manager who is a member of the private subproject
|
||||
get :show, :id => 'ecookbook'
|
||||
assert_response :success
|
||||
assert_template 'show'
|
||||
assert_tag :tag => 'a', :content => /Private child/
|
||||
end
|
||||
|
||||
def test_settings
|
||||
@request.session[:user_id] = 2 # manager
|
||||
get :settings, :id => 1
|
||||
@@ -73,7 +91,7 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
def test_edit
|
||||
@request.session[:user_id] = 2 # manager
|
||||
post :edit, :id => 1, :project => {:name => 'Test changed name',
|
||||
:custom_field_ids => ['']}
|
||||
:issue_custom_field_ids => ['']}
|
||||
assert_redirected_to 'projects/settings/ecookbook'
|
||||
project = Project.find(1)
|
||||
assert_equal 'Test changed name', project.name
|
||||
@@ -135,22 +153,20 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
assert_response :success
|
||||
assert_template 'activity'
|
||||
assert_not_nil assigns(:events_by_day)
|
||||
assert_not_nil assigns(:events)
|
||||
|
||||
# subproject issue not included by default
|
||||
assert !assigns(:events).include?(Issue.find(5))
|
||||
|
||||
assert_tag :tag => "h3",
|
||||
:content => /#{2.days.ago.to_date.day}/,
|
||||
:sibling => { :tag => "dl",
|
||||
:child => { :tag => "dt",
|
||||
:attributes => { :class => 'issue-edit' },
|
||||
:attributes => { :class => /issue-edit/ },
|
||||
:child => { :tag => "a",
|
||||
:content => /(#{IssueStatus.find(2).name})/,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
end
|
||||
|
||||
def test_previous_project_activity
|
||||
get :activity, :id => 1, :from => 3.days.ago.to_date
|
||||
assert_response :success
|
||||
assert_template 'activity'
|
||||
@@ -160,7 +176,7 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
:content => /#{3.day.ago.to_date.day}/,
|
||||
:sibling => { :tag => "dl",
|
||||
:child => { :tag => "dt",
|
||||
:attributes => { :class => 'issue' },
|
||||
:attributes => { :class => /issue/ },
|
||||
:child => { :tag => "a",
|
||||
:content => /#{Issue.find(1).subject}/,
|
||||
}
|
||||
@@ -168,53 +184,30 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
}
|
||||
end
|
||||
|
||||
def test_activity_with_subprojects
|
||||
get :activity, :id => 1, :with_subprojects => 1
|
||||
assert_response :success
|
||||
assert_template 'activity'
|
||||
assert_not_nil assigns(:events)
|
||||
|
||||
assert assigns(:events).include?(Issue.find(1))
|
||||
assert !assigns(:events).include?(Issue.find(4))
|
||||
# subproject issue
|
||||
assert assigns(:events).include?(Issue.find(5))
|
||||
end
|
||||
|
||||
def test_global_activity_anonymous
|
||||
def test_global_activity
|
||||
get :activity
|
||||
assert_response :success
|
||||
assert_template 'activity'
|
||||
assert_not_nil assigns(:events)
|
||||
assert_not_nil assigns(:events_by_day)
|
||||
|
||||
assert assigns(:events).include?(Issue.find(1))
|
||||
# Issue of a private project
|
||||
assert !assigns(:events).include?(Issue.find(4))
|
||||
assert_tag :tag => "h3",
|
||||
:content => /#{5.day.ago.to_date.day}/,
|
||||
:sibling => { :tag => "dl",
|
||||
:child => { :tag => "dt",
|
||||
:attributes => { :class => /issue/ },
|
||||
:child => { :tag => "a",
|
||||
:content => /#{Issue.find(5).subject}/,
|
||||
}
|
||||
}
|
||||
}
|
||||
end
|
||||
|
||||
def test_global_activity_logged_user
|
||||
@request.session[:user_id] = 2 # manager
|
||||
get :activity
|
||||
def test_activity_atom_feed
|
||||
get :activity, :format => 'atom'
|
||||
assert_response :success
|
||||
assert_template 'activity'
|
||||
assert_not_nil assigns(:events)
|
||||
|
||||
assert assigns(:events).include?(Issue.find(1))
|
||||
# Issue of a private project the user belongs to
|
||||
assert assigns(:events).include?(Issue.find(4))
|
||||
assert_template 'common/feed.atom.rxml'
|
||||
end
|
||||
|
||||
|
||||
def test_global_activity_with_all_types
|
||||
get :activity, :show_issues => 1, :show_news => 1, :show_files => 1, :show_documents => 1, :show_changesets => 1, :show_wiki_pages => 1, :show_messages => 1
|
||||
assert_response :success
|
||||
assert_template 'activity'
|
||||
assert_not_nil assigns(:events)
|
||||
|
||||
assert assigns(:events).include?(Issue.find(1))
|
||||
assert !assigns(:events).include?(Issue.find(4))
|
||||
assert assigns(:events).include?(Message.find(5))
|
||||
end
|
||||
|
||||
def test_calendar
|
||||
get :calendar, :id => 1
|
||||
assert_response :success
|
||||
@@ -222,27 +215,56 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
assert_not_nil assigns(:calendar)
|
||||
end
|
||||
|
||||
def test_calendar_with_subprojects
|
||||
def test_calendar_with_subprojects_should_not_show_private_subprojects
|
||||
get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
|
||||
assert_response :success
|
||||
assert_template 'calendar'
|
||||
assert_not_nil assigns(:calendar)
|
||||
assert_no_tag :tag => 'a', :content => /#6/
|
||||
end
|
||||
|
||||
def test_calendar_with_subprojects_should_show_private_subprojects
|
||||
@request.session[:user_id] = 2
|
||||
get :calendar, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
|
||||
assert_response :success
|
||||
assert_template 'calendar'
|
||||
assert_not_nil assigns(:calendar)
|
||||
assert_tag :tag => 'a', :content => /#6/
|
||||
end
|
||||
|
||||
def test_gantt
|
||||
get :gantt, :id => 1
|
||||
assert_response :success
|
||||
assert_template 'gantt.rhtml'
|
||||
assert_not_nil assigns(:events)
|
||||
events = assigns(:events)
|
||||
assert_not_nil events
|
||||
# Issue with start and due dates
|
||||
i = Issue.find(1)
|
||||
assert_not_nil i.due_date
|
||||
assert events.include?(Issue.find(1))
|
||||
# Issue with without due date but targeted to a version with date
|
||||
i = Issue.find(2)
|
||||
assert_nil i.due_date
|
||||
assert events.include?(i)
|
||||
end
|
||||
|
||||
def test_gantt_with_subprojects
|
||||
def test_gantt_with_subprojects_should_not_show_private_subprojects
|
||||
get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
|
||||
assert_response :success
|
||||
assert_template 'gantt.rhtml'
|
||||
assert_not_nil assigns(:events)
|
||||
assert_no_tag :tag => 'a', :content => /#6/
|
||||
end
|
||||
|
||||
def test_gantt_with_subprojects_should_show_private_subprojects
|
||||
@request.session[:user_id] = 2
|
||||
get :gantt, :id => 1, :with_subprojects => 1, :tracker_ids => [1, 2]
|
||||
assert_response :success
|
||||
assert_template 'gantt.rhtml'
|
||||
assert_not_nil assigns(:events)
|
||||
assert_tag :tag => 'a', :content => /#6/
|
||||
end
|
||||
|
||||
def test_gantt_export_to_pdf
|
||||
get :gantt, :id => 1, :format => 'pdf'
|
||||
assert_response :success
|
||||
@@ -265,4 +287,33 @@ class ProjectsControllerTest < Test::Unit::TestCase
|
||||
assert_redirected_to 'admin/projects'
|
||||
assert Project.find(1).active?
|
||||
end
|
||||
|
||||
def test_project_menu
|
||||
assert_no_difference 'Redmine::MenuManager.items(:project_menu).size' do
|
||||
Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.push :foo, { :controller => 'projects', :action => 'show' }, :cation => 'Foo'
|
||||
menu.push :bar, { :controller => 'projects', :action => 'show' }, :before => :activity
|
||||
menu.push :hello, { :controller => 'projects', :action => 'show' }, :caption => Proc.new {|p| p.name.upcase }, :after => :bar
|
||||
end
|
||||
|
||||
get :show, :id => 1
|
||||
assert_tag :div, :attributes => { :id => 'main-menu' },
|
||||
:descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Foo' } }
|
||||
|
||||
assert_tag :div, :attributes => { :id => 'main-menu' },
|
||||
:descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'Bar' },
|
||||
:before => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' } } }
|
||||
|
||||
assert_tag :div, :attributes => { :id => 'main-menu' },
|
||||
:descendant => { :tag => 'li', :child => { :tag => 'a', :content => 'ECOOKBOOK' },
|
||||
:before => { :tag => 'li', :child => { :tag => 'a', :content => 'Activity' } } }
|
||||
|
||||
# Remove the menu items
|
||||
Redmine::MenuManager.map :project_menu do |menu|
|
||||
menu.delete :foo
|
||||
menu.delete :bar
|
||||
menu.delete :hello
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -43,10 +43,10 @@ class RepositoriesControllerTest < Test::Unit::TestCase
|
||||
assert_response :success
|
||||
assert_template 'revision'
|
||||
assert_no_tag :tag => "div", :attributes => { :class => "contextual" },
|
||||
:child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook?rev=0'}
|
||||
:child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook/0'}
|
||||
}
|
||||
assert_tag :tag => "div", :attributes => { :class => "contextual" },
|
||||
:child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook?rev=2'}
|
||||
:child => { :tag => "a", :attributes => { :href => '/repositories/revision/ecookbook/2'}
|
||||
}
|
||||
end
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class RepositoriesCvsControllerTest < Test::Unit::TestCase
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if RUBY_PLATFORM =~ /mswin/
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
# CVS module
|
||||
MODULE_NAME = 'test'
|
||||
|
||||
@@ -89,6 +89,19 @@ class RepositoriesCvsControllerTest < Test::Unit::TestCase
|
||||
get :entry, :id => 1, :path => ['sources', 'watchers_controller.rb']
|
||||
assert_response :success
|
||||
assert_template 'entry'
|
||||
assert_no_tag :tag => 'td', :attributes => { :class => /line-code/},
|
||||
:content => /before_filter/
|
||||
end
|
||||
|
||||
def test_entry_at_given_revision
|
||||
# changesets must be loaded
|
||||
Project.find(1).repository.fetch_changesets
|
||||
get :entry, :id => 1, :path => ['sources', 'watchers_controller.rb'], :rev => 2
|
||||
assert_response :success
|
||||
assert_template 'entry'
|
||||
# this line was removed in r3
|
||||
assert_tag :tag => 'td', :attributes => { :class => /line-code/},
|
||||
:content => /before_filter/
|
||||
end
|
||||
|
||||
def test_entry_not_found
|
||||
|
||||
@@ -26,7 +26,7 @@ class RepositoriesGitControllerTest < Test::Unit::TestCase
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if RUBY_PLATFORM =~ /mswin/
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
|
||||
def setup
|
||||
@controller = RepositoriesController.new
|
||||
|
||||
@@ -71,6 +71,19 @@ class RepositoriesSubversionControllerTest < Test::Unit::TestCase
|
||||
assert_not_nil assigns(:entries)
|
||||
assert_equal ['folder', '.project', 'helloworld.c', 'helloworld.rb', 'textfile.txt'], assigns(:entries).collect(&:name)
|
||||
end
|
||||
|
||||
def test_changes
|
||||
get :changes, :id => 1, :path => ['subversion_test', 'folder', 'helloworld.rb' ]
|
||||
assert_response :success
|
||||
assert_template 'changes'
|
||||
# svn properties
|
||||
assert_not_nil assigns(:properties)
|
||||
assert_equal 'native', assigns(:properties)['svn:eol-style']
|
||||
assert_tag :ul,
|
||||
:child => { :tag => 'li',
|
||||
:child => { :tag => 'b', :content => 'svn:eol-style' },
|
||||
:child => { :tag => 'span', :content => 'native' } }
|
||||
end
|
||||
|
||||
def test_entry
|
||||
get :entry, :id => 1, :path => ['subversion_test', 'helloworld.c']
|
||||
@@ -78,6 +91,15 @@ class RepositoriesSubversionControllerTest < Test::Unit::TestCase
|
||||
assert_template 'entry'
|
||||
end
|
||||
|
||||
def test_entry_at_given_revision
|
||||
get :entry, :id => 1, :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_tag :tag => 'td', :attributes => { :class => /line-code/},
|
||||
:content => /Here's the code/
|
||||
end
|
||||
|
||||
def test_entry_not_found
|
||||
get :entry, :id => 1, :path => ['subversion_test', 'zzz.c']
|
||||
assert_tag :tag => 'div', :attributes => { :class => /error/ },
|
||||
@@ -97,6 +119,37 @@ class RepositoriesSubversionControllerTest < Test::Unit::TestCase
|
||||
assert_equal 'folder', assigns(:entry).name
|
||||
end
|
||||
|
||||
def test_revision
|
||||
get :revision, :id => 1, :rev => 2
|
||||
assert_response :success
|
||||
assert_template 'revision'
|
||||
assert_tag :tag => 'tr',
|
||||
:child => { :tag => 'td',
|
||||
# link to the entry at rev 2
|
||||
:child => { :tag => 'a', :attributes => {:href => 'repositories/entry/ecookbook/test/some/path/in/the/repo?rev=2'},
|
||||
:content => %r{/test/some/path/in/the/repo} }
|
||||
},
|
||||
:child => { :tag => 'td',
|
||||
# link to partial diff
|
||||
:child => { :tag => 'a', :attributes => { :href => '/repositories/diff/ecookbook/test/some/path/in/the/repo?rev=2' } }
|
||||
}
|
||||
end
|
||||
|
||||
def test_revision_with_repository_pointing_to_a_subdirectory
|
||||
r = Project.find(1).repository
|
||||
# Changes repository url to a subdirectory
|
||||
r.update_attribute :url, (r.url + '/test/some')
|
||||
|
||||
get :revision, :id => 1, :rev => 2
|
||||
assert_response :success
|
||||
assert_template 'revision'
|
||||
assert_tag :tag => 'tr',
|
||||
:child => { :tag => 'td', :content => %r{/test/some/path/in/the/repo} },
|
||||
:child => { :tag => 'td',
|
||||
:child => { :tag => 'a', :attributes => { :href => '/repositories/diff/ecookbook/path/in/the/repo?rev=2' } }
|
||||
}
|
||||
end
|
||||
|
||||
def test_diff
|
||||
get :diff, :id => 1, :rev => 3
|
||||
assert_response :success
|
||||
|
||||
@@ -5,7 +5,10 @@ require 'search_controller'
|
||||
class SearchController; def rescue_action(e) raise e end; end
|
||||
|
||||
class SearchControllerTest < Test::Unit::TestCase
|
||||
fixtures :projects, :enabled_modules, :issues, :custom_fields, :custom_values
|
||||
fixtures :projects, :enabled_modules, :roles, :users,
|
||||
:issues, :trackers, :issue_statuses,
|
||||
:custom_fields, :custom_values,
|
||||
:repositories, :changesets
|
||||
|
||||
def setup
|
||||
@controller = SearchController.new
|
||||
@@ -25,6 +28,31 @@ class SearchControllerTest < Test::Unit::TestCase
|
||||
assert assigns(:results).include?(Project.find(1))
|
||||
end
|
||||
|
||||
def test_search_all_projects
|
||||
get :index, :q => 'recipe subproject commit', :submit => 'Search'
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
|
||||
assert assigns(:results).include?(Issue.find(2))
|
||||
assert assigns(:results).include?(Issue.find(5))
|
||||
assert assigns(:results).include?(Changeset.find(101))
|
||||
assert_tag :dt, :attributes => { :class => /issue/ },
|
||||
:child => { :tag => 'a', :content => /Add ingredients categories/ },
|
||||
:sibling => { :tag => 'dd', :content => /should be classified by categories/ }
|
||||
|
||||
assert assigns(:results_by_type).is_a?(Hash)
|
||||
assert_equal 4, assigns(:results_by_type)['changesets']
|
||||
assert_tag :a, :content => 'Changesets (4)'
|
||||
end
|
||||
|
||||
def test_search_project_and_subprojects
|
||||
get :index, :id => 1, :q => 'recipe subproject', :scope => 'subprojects', :submit => 'Search'
|
||||
assert_response :success
|
||||
assert_template 'index'
|
||||
assert assigns(:results).include?(Issue.find(1))
|
||||
assert assigns(:results).include?(Issue.find(5))
|
||||
end
|
||||
|
||||
def test_search_without_searchable_custom_fields
|
||||
CustomField.update_all "searchable = #{ActiveRecord::Base.connection.quoted_false}"
|
||||
|
||||
|
||||
@@ -30,11 +30,22 @@ class TimelogControllerTest < Test::Unit::TestCase
|
||||
@response = ActionController::TestResponse.new
|
||||
end
|
||||
|
||||
def test_create
|
||||
def test_get_edit
|
||||
@request.session[:user_id] = 3
|
||||
get :edit, :project_id => 1
|
||||
assert_response :success
|
||||
assert_template 'edit'
|
||||
# Default activity selected
|
||||
assert_tag :tag => 'option', :attributes => { :selected => 'selected' },
|
||||
:content => 'Development'
|
||||
end
|
||||
|
||||
def test_post_edit
|
||||
@request.session[:user_id] = 3
|
||||
post :edit, :project_id => 1,
|
||||
:time_entry => {:comments => 'Some work on TimelogControllerTest',
|
||||
:activity_id => '10',
|
||||
# Not the default activity
|
||||
:activity_id => '11',
|
||||
:spent_on => '2008-03-14',
|
||||
:issue_id => '1',
|
||||
:hours => '7.3'}
|
||||
@@ -43,6 +54,7 @@ class TimelogControllerTest < Test::Unit::TestCase
|
||||
i = Issue.find(1)
|
||||
t = TimeEntry.find_by_comments('Some work on TimelogControllerTest')
|
||||
assert_not_nil t
|
||||
assert_equal 11, t.activity_id
|
||||
assert_equal 7.3, t.hours
|
||||
assert_equal 3, t.user_id
|
||||
assert_equal i, t.issue
|
||||
@@ -198,6 +210,14 @@ class TimelogControllerTest < Test::Unit::TestCase
|
||||
assert_equal '2007-04-22'.to_date, assigns(:to)
|
||||
end
|
||||
|
||||
def test_details_atom_feed
|
||||
get :details, :project_id => 1, :format => 'atom'
|
||||
assert_response :success
|
||||
assert_equal 'application/atom+xml', @response.content_type
|
||||
assert_not_nil assigns(:items)
|
||||
assert assigns(:items).first.is_a?(TimeEntry)
|
||||
end
|
||||
|
||||
def test_details_csv_export
|
||||
get :details, :project_id => 1, :format => 'csv'
|
||||
assert_response :success
|
||||
|
||||
@@ -22,7 +22,7 @@ require 'versions_controller'
|
||||
class VersionsController; def rescue_action(e) raise e end; end
|
||||
|
||||
class VersionsControllerTest < Test::Unit::TestCase
|
||||
fixtures :projects, :versions, :users, :roles, :members, :enabled_modules
|
||||
fixtures :projects, :versions, :issues, :users, :roles, :members, :enabled_modules
|
||||
|
||||
def setup
|
||||
@controller = VersionsController.new
|
||||
@@ -60,9 +60,9 @@ class VersionsControllerTest < Test::Unit::TestCase
|
||||
|
||||
def test_destroy
|
||||
@request.session[:user_id] = 2
|
||||
post :destroy, :id => 2
|
||||
post :destroy, :id => 3
|
||||
assert_redirected_to 'projects/settings/ecookbook'
|
||||
assert_nil Version.find_by_id(2)
|
||||
assert_nil Version.find_by_id(3)
|
||||
end
|
||||
|
||||
def test_issue_status_by
|
||||
|
||||
@@ -0,0 +1,70 @@
|
||||
# Redmine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
require 'watchers_controller'
|
||||
|
||||
# Re-raise errors caught by the controller.
|
||||
class WatchersController; def rescue_action(e) raise e end; end
|
||||
|
||||
class WatchersControllerTest < Test::Unit::TestCase
|
||||
fixtures :projects, :users, :roles, :members, :enabled_modules,
|
||||
:issues, :trackers, :projects_trackers, :issue_statuses, :enumerations, :watchers
|
||||
|
||||
def setup
|
||||
@controller = WatchersController.new
|
||||
@request = ActionController::TestRequest.new
|
||||
@response = ActionController::TestResponse.new
|
||||
User.current = nil
|
||||
end
|
||||
|
||||
def test_get_watch_should_be_invalid
|
||||
@request.session[:user_id] = 3
|
||||
get :watch, :object_type => 'issue', :object_id => '1'
|
||||
assert_response 405
|
||||
end
|
||||
|
||||
def test_watch
|
||||
@request.session[:user_id] = 3
|
||||
assert_difference('Watcher.count') do
|
||||
xhr :post, :watch, :object_type => 'issue', :object_id => '1'
|
||||
assert_response :success
|
||||
assert_select_rjs :replace_html, 'watcher'
|
||||
end
|
||||
assert Issue.find(1).watched_by?(User.find(3))
|
||||
end
|
||||
|
||||
def test_unwatch
|
||||
@request.session[:user_id] = 3
|
||||
assert_difference('Watcher.count', -1) do
|
||||
xhr :post, :unwatch, :object_type => 'issue', :object_id => '2'
|
||||
assert_response :success
|
||||
assert_select_rjs :replace_html, 'watcher'
|
||||
end
|
||||
assert !Issue.find(1).watched_by?(User.find(3))
|
||||
end
|
||||
|
||||
def test_new_watcher
|
||||
@request.session[:user_id] = 2
|
||||
assert_difference('Watcher.count') do
|
||||
xhr :post, :new, :object_type => 'issue', :object_id => '2', :watcher => {:user_id => '4'}
|
||||
assert_response :success
|
||||
assert_select_rjs :replace_html, 'watchers'
|
||||
end
|
||||
assert Issue.find(2).watched_by?(User.find(4))
|
||||
end
|
||||
end
|
||||
@@ -46,4 +46,18 @@ class WelcomeControllerTest < Test::Unit::TestCase
|
||||
get :index
|
||||
assert_equal :fr, @controller.current_language
|
||||
end
|
||||
|
||||
def test_browser_language_alternate
|
||||
Setting.default_language = 'en'
|
||||
@request.env['HTTP_ACCEPT_LANGUAGE'] = 'zh-TW'
|
||||
get :index
|
||||
assert_equal :"zh-tw", @controller.current_language
|
||||
end
|
||||
|
||||
def test_browser_language_alternate_not_valid
|
||||
Setting.default_language = 'en'
|
||||
@request.env['HTTP_ACCEPT_LANGUAGE'] = 'fr-CA'
|
||||
get :index
|
||||
assert_equal :fr, @controller.current_language
|
||||
end
|
||||
end
|
||||
|
||||
@@ -32,10 +32,16 @@ class WikiControllerTest < Test::Unit::TestCase
|
||||
end
|
||||
|
||||
def test_show_start_page
|
||||
get :index, :id => 1
|
||||
get :index, :id => 'ecookbook'
|
||||
assert_response :success
|
||||
assert_template 'show'
|
||||
assert_tag :tag => 'h1', :content => /CookBook documentation/
|
||||
|
||||
# child_pages macro
|
||||
assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
|
||||
:child => { :tag => 'li',
|
||||
:child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Page_with_an_inline_image' },
|
||||
:content => 'Page with an inline image' } }
|
||||
end
|
||||
|
||||
def test_show_page_with_name
|
||||
@@ -86,14 +92,35 @@ class WikiControllerTest < Test::Unit::TestCase
|
||||
assert_tag :tag => 'strong', :content => /previewed text/
|
||||
end
|
||||
|
||||
def test_preview_new_page
|
||||
@request.session[:user_id] = 2
|
||||
xhr :post, :preview, :id => 1, :page => 'New page',
|
||||
:content => { :text => 'h1. New page',
|
||||
:comments => '',
|
||||
:version => 0 }
|
||||
assert_response :success
|
||||
assert_template 'common/_preview'
|
||||
assert_tag :tag => 'h1', :content => /New page/
|
||||
end
|
||||
|
||||
def test_history
|
||||
get :history, :id => 1, :page => 'CookBook_documentation'
|
||||
assert_response :success
|
||||
assert_template 'history'
|
||||
assert_not_nil assigns(:versions)
|
||||
assert_equal 3, assigns(:versions).size
|
||||
assert_select "input[type=submit][name=commit]"
|
||||
end
|
||||
|
||||
|
||||
def test_history_with_one_version
|
||||
get :history, :id => 1, :page => 'Another_page'
|
||||
assert_response :success
|
||||
assert_template 'history'
|
||||
assert_not_nil assigns(:versions)
|
||||
assert_equal 1, assigns(:versions).size
|
||||
assert_select "input[type=submit][name=commit]", false
|
||||
end
|
||||
|
||||
def test_diff
|
||||
get :diff, :id => 1, :page => 'CookBook_documentation', :version => 2, :version_from => 1
|
||||
assert_response :success
|
||||
@@ -152,12 +179,76 @@ class WikiControllerTest < Test::Unit::TestCase
|
||||
pages = assigns(:pages)
|
||||
assert_not_nil pages
|
||||
assert_equal Project.find(1).wiki.pages.size, pages.size
|
||||
assert_tag :tag => 'a', :attributes => { :href => '/wiki/ecookbook/CookBook_documentation' },
|
||||
:content => /CookBook documentation/
|
||||
|
||||
assert_tag :ul, :attributes => { :class => 'pages-hierarchy' },
|
||||
:child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/CookBook_documentation' },
|
||||
:content => 'CookBook documentation' },
|
||||
:child => { :tag => 'ul',
|
||||
:child => { :tag => 'li',
|
||||
:child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Page_with_an_inline_image' },
|
||||
:content => 'Page with an inline image' } } } },
|
||||
:child => { :tag => 'li', :child => { :tag => 'a', :attributes => { :href => '/wiki/ecookbook/Another_page' },
|
||||
:content => 'Another page' } }
|
||||
end
|
||||
|
||||
def test_not_found
|
||||
get :index, :id => 999
|
||||
assert_response 404
|
||||
end
|
||||
|
||||
def test_protect_page
|
||||
page = WikiPage.find_by_wiki_id_and_title(1, 'Another_page')
|
||||
assert !page.protected?
|
||||
@request.session[:user_id] = 2
|
||||
post :protect, :id => 1, :page => page.title, :protected => '1'
|
||||
assert_redirected_to 'wiki/ecookbook/Another_page'
|
||||
assert page.reload.protected?
|
||||
end
|
||||
|
||||
def test_unprotect_page
|
||||
page = WikiPage.find_by_wiki_id_and_title(1, 'CookBook_documentation')
|
||||
assert page.protected?
|
||||
@request.session[:user_id] = 2
|
||||
post :protect, :id => 1, :page => page.title, :protected => '0'
|
||||
assert_redirected_to 'wiki/ecookbook'
|
||||
assert !page.reload.protected?
|
||||
end
|
||||
|
||||
def test_show_page_with_edit_link
|
||||
@request.session[:user_id] = 2
|
||||
get :index, :id => 1
|
||||
assert_response :success
|
||||
assert_template 'show'
|
||||
assert_tag :tag => 'a', :attributes => { :href => '/wiki/1/CookBook_documentation/edit' }
|
||||
end
|
||||
|
||||
def test_show_page_without_edit_link
|
||||
@request.session[:user_id] = 4
|
||||
get :index, :id => 1
|
||||
assert_response :success
|
||||
assert_template 'show'
|
||||
assert_no_tag :tag => 'a', :attributes => { :href => '/wiki/1/CookBook_documentation/edit' }
|
||||
end
|
||||
|
||||
def test_edit_unprotected_page
|
||||
# Non members can edit unprotected wiki pages
|
||||
@request.session[:user_id] = 4
|
||||
get :edit, :id => 1, :page => 'Another_page'
|
||||
assert_response :success
|
||||
assert_template 'edit'
|
||||
end
|
||||
|
||||
def test_edit_protected_page_by_nonmember
|
||||
# Non members can't edit protected wiki pages
|
||||
@request.session[:user_id] = 4
|
||||
get :edit, :id => 1, :page => 'CookBook_documentation'
|
||||
assert_response 403
|
||||
end
|
||||
|
||||
def test_edit_protected_page_by_member
|
||||
@request.session[:user_id] = 2
|
||||
get :edit, :id => 1, :page => 'CookBook_documentation'
|
||||
assert_response :success
|
||||
assert_template 'edit'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
|
||||
require "#{File.dirname(__FILE__)}/../test_helper"
|
||||
|
||||
begin
|
||||
require 'mocha'
|
||||
rescue
|
||||
# Won't run some tests
|
||||
end
|
||||
|
||||
class AccountTest < ActionController::IntegrationTest
|
||||
fixtures :users
|
||||
|
||||
@@ -67,8 +73,12 @@ class AccountTest < ActionController::IntegrationTest
|
||||
|
||||
post 'account/register', :user => {:login => "newuser", :language => "en", :firstname => "New", :lastname => "User", :mail => "newuser@foo.bar"},
|
||||
:password => "newpass", :password_confirmation => "newpass"
|
||||
assert_redirected_to 'account/login'
|
||||
log_user('newuser', 'newpass')
|
||||
assert_redirected_to 'my/account'
|
||||
follow_redirect!
|
||||
assert_response :success
|
||||
assert_template 'my/account'
|
||||
|
||||
assert User.find_by_login('newuser').active?
|
||||
end
|
||||
|
||||
def test_register_with_manual_activation
|
||||
@@ -98,4 +108,46 @@ class AccountTest < ActionController::IntegrationTest
|
||||
assert_redirected_to 'account/login'
|
||||
log_user('newuser', 'newpass')
|
||||
end
|
||||
|
||||
if Object.const_defined?(:Mocha)
|
||||
|
||||
def test_onthefly_registration
|
||||
# disable registration
|
||||
Setting.self_registration = '0'
|
||||
AuthSource.expects(:authenticate).returns([:login => 'foo', :firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com', :auth_source_id => 66])
|
||||
|
||||
post 'account/login', :username => 'foo', :password => 'bar'
|
||||
assert_redirected_to 'my/page'
|
||||
|
||||
user = User.find_by_login('foo')
|
||||
assert user.is_a?(User)
|
||||
assert_equal 66, user.auth_source_id
|
||||
assert user.hashed_password.blank?
|
||||
end
|
||||
|
||||
def test_onthefly_registration_with_invalid_attributes
|
||||
# disable registration
|
||||
Setting.self_registration = '0'
|
||||
AuthSource.expects(:authenticate).returns([:login => 'foo', :lastname => 'Smith', :auth_source_id => 66])
|
||||
|
||||
post 'account/login', :username => 'foo', :password => 'bar'
|
||||
assert_response :success
|
||||
assert_template 'account/register'
|
||||
assert_tag :input, :attributes => { :name => 'user[firstname]', :value => '' }
|
||||
assert_tag :input, :attributes => { :name => 'user[lastname]', :value => 'Smith' }
|
||||
assert_no_tag :input, :attributes => { :name => 'user[login]' }
|
||||
assert_no_tag :input, :attributes => { :name => 'user[password]' }
|
||||
|
||||
post 'account/register', :user => {:firstname => 'Foo', :lastname => 'Smith', :mail => 'foo@bar.com'}
|
||||
assert_redirected_to 'my/account'
|
||||
|
||||
user = User.find_by_login('foo')
|
||||
assert user.is_a?(User)
|
||||
assert_equal 66, user.auth_source_id
|
||||
assert user.hashed_password.blank?
|
||||
end
|
||||
|
||||
else
|
||||
puts 'Mocha is missing. Skipping tests.'
|
||||
end
|
||||
end
|
||||
|
||||
@@ -48,8 +48,9 @@ class AdminTest < ActionController::IntegrationTest
|
||||
post "projects/add", :project => { :name => "blog",
|
||||
:description => "weblog",
|
||||
:identifier => "blog",
|
||||
:is_public => 1 },
|
||||
'custom_fields[3]' => 'Beta'
|
||||
:is_public => 1,
|
||||
:custom_field_values => { '3' => 'Beta' }
|
||||
}
|
||||
assert_redirected_to "admin/projects"
|
||||
assert_equal 'Successful creation.', flash[:notice]
|
||||
|
||||
|
||||
@@ -1,10 +1,30 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require "#{File.dirname(__FILE__)}/../test_helper"
|
||||
|
||||
class IssuesTest < ActionController::IntegrationTest
|
||||
fixtures :projects,
|
||||
:users,
|
||||
:roles,
|
||||
:members,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:enabled_modules,
|
||||
:issue_statuses,
|
||||
:issues,
|
||||
:enumerations,
|
||||
@@ -47,6 +67,7 @@ class IssuesTest < ActionController::IntegrationTest
|
||||
# add then remove 2 attachments to an issue
|
||||
def test_issue_attachements
|
||||
log_user('jsmith', 'jsmith')
|
||||
set_tmp_attachments_directory
|
||||
|
||||
post 'issues/edit/1',
|
||||
:notes => 'Some notes',
|
||||
|
||||
@@ -57,21 +57,11 @@ class Test::Unit::TestCase
|
||||
def test_uploaded_file(name, mime)
|
||||
ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + "/files/#{name}", mime)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# ActionController::TestUploadedFile bug
|
||||
# see http://dev.rubyonrails.org/ticket/4635
|
||||
class String
|
||||
def original_filename
|
||||
"testfile.txt"
|
||||
end
|
||||
|
||||
def content_type
|
||||
"text/plain"
|
||||
end
|
||||
|
||||
def read
|
||||
self.to_s
|
||||
# Use a temporary directory for attachment related tests
|
||||
def set_tmp_attachments_directory
|
||||
Dir.mkdir "#{RAILS_ROOT}/tmp/test" unless File.directory?("#{RAILS_ROOT}/tmp/test")
|
||||
Dir.mkdir "#{RAILS_ROOT}/tmp/test/attachments" unless File.directory?("#{RAILS_ROOT}/tmp/test/attachments")
|
||||
Attachment.storage_path = "#{RAILS_ROOT}/tmp/test/attachments"
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class ActivityTest < Test::Unit::TestCase
|
||||
fixtures :projects, :versions, :users, :roles, :members, :issues, :journals, :journal_details,
|
||||
:trackers, :projects_trackers, :issue_statuses, :enabled_modules, :enumerations, :boards, :messages
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
end
|
||||
|
||||
def test_activity_without_subprojects
|
||||
events = find_events(User.anonymous, :project => @project)
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
assert !events.include?(Issue.find(4))
|
||||
# subproject issue
|
||||
assert !events.include?(Issue.find(5))
|
||||
end
|
||||
|
||||
def test_activity_with_subprojects
|
||||
events = find_events(User.anonymous, :project => @project, :with_subprojects => 1)
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
# subproject issue
|
||||
assert events.include?(Issue.find(5))
|
||||
end
|
||||
|
||||
def test_global_activity_anonymous
|
||||
events = find_events(User.anonymous)
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
assert events.include?(Message.find(5))
|
||||
# Issue of a private project
|
||||
assert !events.include?(Issue.find(4))
|
||||
end
|
||||
|
||||
def test_global_activity_logged_user
|
||||
events = find_events(User.find(2)) # manager
|
||||
assert_not_nil events
|
||||
|
||||
assert events.include?(Issue.find(1))
|
||||
# Issue of a private project the user belongs to
|
||||
assert events.include?(Issue.find(4))
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def find_events(user, options={})
|
||||
Redmine::Activity::Fetcher.new(user, options).events(Date.today - 30, Date.today + 1)
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,32 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class AttachmentTest < Test::Unit::TestCase
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
def test_diskfilename
|
||||
assert Attachment.disk_filename("test_file.txt") =~ /^\d{12}_test_file.txt$/
|
||||
assert_equal 'test_file.txt', Attachment.disk_filename("test_file.txt")[13..-1]
|
||||
assert_equal '770c509475505f37c2b8fb6030434d6b.txt', Attachment.disk_filename("test_accentué.txt")[13..-1]
|
||||
assert_equal 'f8139524ebb8f32e51976982cd20a85d', Attachment.disk_filename("test_accentué")[13..-1]
|
||||
assert_equal 'cbb5b0f30978ba03731d61f9f6d10011', Attachment.disk_filename("test_accentué.ça")[13..-1]
|
||||
end
|
||||
end
|
||||
@@ -39,6 +39,17 @@ class ChangesetTest < Test::Unit::TestCase
|
||||
assert fixed.closed?
|
||||
assert_equal 90, fixed.done_ratio
|
||||
end
|
||||
|
||||
def test_ref_keywords_any_line_start
|
||||
Setting.commit_ref_keywords = '*'
|
||||
|
||||
c = Changeset.new(:repository => Project.find(1).repository,
|
||||
:committed_on => Time.now,
|
||||
:comments => '#1 is the reason of this commit')
|
||||
c.scan_comment_for_issue_ids
|
||||
|
||||
assert_equal [1], c.issue_ids.sort
|
||||
end
|
||||
|
||||
def test_previous
|
||||
changeset = Changeset.find_by_revision('3')
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class DefaultDataTest < Test::Unit::TestCase
|
||||
fixtures :roles
|
||||
|
||||
def test_no_data
|
||||
assert !Redmine::DefaultData::Loader::no_data?
|
||||
Role.delete_all("builtin = 0")
|
||||
Tracker.delete_all
|
||||
IssueStatus.delete_all
|
||||
Enumeration.delete_all
|
||||
assert Redmine::DefaultData::Loader::no_data?
|
||||
end
|
||||
|
||||
def test_load
|
||||
GLoc.valid_languages.each do |lang|
|
||||
begin
|
||||
Role.delete_all("builtin = 0")
|
||||
Tracker.delete_all
|
||||
IssueStatus.delete_all
|
||||
Enumeration.delete_all
|
||||
assert Redmine::DefaultData::Loader::load(lang)
|
||||
rescue ActiveRecord::RecordInvalid => e
|
||||
assert false, ":#{lang} default data is invalid (#{e.message})."
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,45 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class EnumerationTest < Test::Unit::TestCase
|
||||
fixtures :enumerations, :issues
|
||||
|
||||
def setup
|
||||
end
|
||||
|
||||
def test_objects_count
|
||||
# low priority
|
||||
assert_equal 5, Enumeration.find(4).objects_count
|
||||
# urgent
|
||||
assert_equal 0, Enumeration.find(7).objects_count
|
||||
end
|
||||
|
||||
def test_in_use
|
||||
# low priority
|
||||
assert Enumeration.find(4).in_use?
|
||||
# urgent
|
||||
assert !Enumeration.find(7).in_use?
|
||||
end
|
||||
|
||||
def test_destroy_with_reassign
|
||||
Enumeration.find(4).destroy(Enumeration.find(6))
|
||||
assert_nil Issue.find(:first, :conditions => {:priority_id => 4})
|
||||
assert_equal 5, Enumeration.find(6).objects_count
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,42 @@
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
|
||||
class FilesystemAdapterTest < Test::Unit::TestCase
|
||||
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def setup
|
||||
@adapter = Redmine::Scm::Adapters::FilesystemAdapter.new(REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 2, @adapter.entries.size
|
||||
assert_equal ["dir", "test"], @adapter.entries.collect(&:name)
|
||||
assert_equal ["dir", "test"], @adapter.entries(nil).collect(&:name)
|
||||
assert_equal ["dir", "test"], @adapter.entries("/").collect(&:name)
|
||||
["dir", "/dir", "/dir/", "dir/"].each do |path|
|
||||
assert_equal ["subdir", "dirfile"], @adapter.entries(path).collect(&:name)
|
||||
end
|
||||
# If y try to use "..", the path is ignored
|
||||
["/../","dir/../", "..", "../", "/..", "dir/.."].each do |path|
|
||||
assert_equal ["dir", "test"], @adapter.entries(path).collect(&:name), ".. must be ignored in path argument"
|
||||
end
|
||||
end
|
||||
|
||||
def test_cat
|
||||
assert_equal "TEST CAT\n", @adapter.cat("test")
|
||||
assert_equal "TEST CAT\n", @adapter.cat("/test")
|
||||
# Revision number is ignored
|
||||
assert_equal "TEST CAT\n", @adapter.cat("/test", 1)
|
||||
end
|
||||
|
||||
else
|
||||
puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
|
||||
def test_fake; assert true end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
@@ -20,7 +20,11 @@ require File.dirname(__FILE__) + '/../../test_helper'
|
||||
class ApplicationHelperTest < HelperTestCase
|
||||
include ApplicationHelper
|
||||
include ActionView::Helpers::TextHelper
|
||||
fixtures :projects, :repositories, :changesets, :trackers, :issue_statuses, :issues, :documents, :versions, :wikis, :wiki_pages, :wiki_contents, :roles, :enabled_modules
|
||||
fixtures :projects, :roles, :enabled_modules,
|
||||
:repositories, :changesets,
|
||||
:trackers, :issue_statuses, :issues, :versions, :documents,
|
||||
:wikis, :wiki_pages, :wiki_contents,
|
||||
:boards, :messages
|
||||
|
||||
def setup
|
||||
super
|
||||
@@ -31,10 +35,14 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'http://foo.bar' => '<a class="external" href="http://foo.bar">http://foo.bar</a>',
|
||||
'http://foo.bar/~user' => '<a class="external" href="http://foo.bar/~user">http://foo.bar/~user</a>',
|
||||
'http://foo.bar.' => '<a class="external" href="http://foo.bar">http://foo.bar</a>.',
|
||||
'This is a link: http://foo.bar.' => 'This is a link: <a class="external" href="http://foo.bar">http://foo.bar</a>.',
|
||||
'A link (eg. http://foo.bar).' => 'A link (eg. <a class="external" href="http://foo.bar">http://foo.bar</a>).',
|
||||
'http://foo.bar/foo.bar#foo.bar.' => '<a class="external" href="http://foo.bar/foo.bar#foo.bar">http://foo.bar/foo.bar#foo.bar</a>.',
|
||||
'www.foo.bar' => '<a class="external" href="http://www.foo.bar">www.foo.bar</a>',
|
||||
'http://foo.bar/page?p=1&t=z&s=' => '<a class="external" href="http://foo.bar/page?p=1&t=z&s=">http://foo.bar/page?p=1&t=z&s=</a>',
|
||||
'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>'
|
||||
'http://foo.bar/page#125' => '<a class="external" href="http://foo.bar/page#125">http://foo.bar/page#125</a>',
|
||||
'http://foo@www.bar.com' => '<a class="external" href="http://foo@www.bar.com">http://foo@www.bar.com</a>',
|
||||
'ftp://foo.bar' => '<a class="external" href="ftp://foo.bar">ftp://foo.bar</a>',
|
||||
}
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
end
|
||||
@@ -58,7 +66,10 @@ class ApplicationHelperTest < HelperTestCase
|
||||
to_test = {
|
||||
'This is a "link":http://foo.bar' => 'This is a <a href="http://foo.bar" class="external">link</a>',
|
||||
'This is an intern "link":/foo/bar' => 'This is an intern <a href="/foo/bar">link</a>',
|
||||
'"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>'
|
||||
'"link (Link title)":http://foo.bar' => '<a href="http://foo.bar" title="Link title" class="external">link</a>',
|
||||
"This is not a \"Link\":\n\nAnother paragraph" => "This is not a \"Link\":</p>\n\n\n\t<p>Another paragraph",
|
||||
# no multiline link text
|
||||
"This is a double quote \"on the first line\nand another on a second line\":test" => "This is a double quote \"on the first line<br />\nand another on a second line\":test"
|
||||
}
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
end
|
||||
@@ -76,7 +87,10 @@ class ApplicationHelperTest < HelperTestCase
|
||||
version_link = link_to('1.0', {:controller => 'versions', :action => 'show', :id => 2},
|
||||
:class => 'version')
|
||||
|
||||
source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => 'some/file'}
|
||||
message_url = {:controller => 'messages', :action => 'show', :board_id => 1, :id => 4}
|
||||
|
||||
source_url = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file']}
|
||||
source_url_with_ext = {:controller => 'repositories', :action => 'entry', :id => 'ecookbook', :path => ['some', 'file.ext']}
|
||||
|
||||
to_test = {
|
||||
# tickets
|
||||
@@ -92,10 +106,20 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'version:"1.0"' => version_link,
|
||||
# source
|
||||
'source:/some/file' => link_to('source:/some/file', source_url, :class => 'source'),
|
||||
'source:/some/file.' => link_to('source:/some/file', source_url, :class => 'source') + ".",
|
||||
'source:/some/file.ext.' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
|
||||
'source:/some/file. ' => link_to('source:/some/file', source_url, :class => 'source') + ".",
|
||||
'source:/some/file.ext. ' => link_to('source:/some/file.ext', source_url_with_ext, :class => 'source') + ".",
|
||||
'source:/some/file, ' => link_to('source:/some/file', source_url, :class => 'source') + ",",
|
||||
'source:/some/file@52' => link_to('source:/some/file@52', source_url.merge(:rev => 52), :class => 'source'),
|
||||
'source:/some/file.ext@52' => link_to('source:/some/file.ext@52', source_url_with_ext.merge(:rev => 52), :class => 'source'),
|
||||
'source:/some/file#L110' => link_to('source:/some/file#L110', source_url.merge(:anchor => 'L110'), :class => 'source'),
|
||||
'source:/some/file.ext#L110' => link_to('source:/some/file.ext#L110', source_url_with_ext.merge(:anchor => 'L110'), :class => 'source'),
|
||||
'source:/some/file@52#L110' => link_to('source:/some/file@52#L110', source_url.merge(:rev => 52, :anchor => 'L110'), :class => 'source'),
|
||||
'export:/some/file' => link_to('export:/some/file', source_url.merge(:format => 'raw'), :class => 'source download'),
|
||||
# message
|
||||
'message#4' => link_to('Post 2', message_url, :class => 'message'),
|
||||
'message#5' => link_to('RE: post 2', message_url.merge(:anchor => 'message-5'), :class => 'message'),
|
||||
# escaping
|
||||
'!#3.' => '#3.',
|
||||
'!r1' => 'r1',
|
||||
@@ -106,7 +130,9 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'!version:"1.0"' => 'version:"1.0"',
|
||||
'!source:/some/file' => 'source:/some/file',
|
||||
# invalid expressions
|
||||
'source:' => 'source:'
|
||||
'source:' => 'source:',
|
||||
# url hash
|
||||
"http://foo.bar/FAQ#3" => '<a class="external" href="http://foo.bar/FAQ#3">http://foo.bar/FAQ#3</a>',
|
||||
}
|
||||
@project = Project.find(1)
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
@@ -116,6 +142,9 @@ class ApplicationHelperTest < HelperTestCase
|
||||
to_test = {
|
||||
'[[CookBook documentation]]' => '<a href="/wiki/ecookbook/CookBook_documentation" class="wiki-page">CookBook documentation</a>',
|
||||
'[[Another page|Page]]' => '<a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a>',
|
||||
# link with anchor
|
||||
'[[CookBook documentation#One-section]]' => '<a href="/wiki/ecookbook/CookBook_documentation#One-section" class="wiki-page">CookBook documentation</a>',
|
||||
'[[Another page#anchor|Page]]' => '<a href="/wiki/ecookbook/Another_page#anchor" class="wiki-page">Page</a>',
|
||||
# page that doesn't exist
|
||||
'[[Unknown page]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">Unknown page</a>',
|
||||
'[[Unknown page|404]]' => '<a href="/wiki/ecookbook/Unknown_page" class="wiki-page new">404</a>',
|
||||
@@ -125,6 +154,8 @@ class ApplicationHelperTest < HelperTestCase
|
||||
'[[onlinestore:Start page]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Start page</a>',
|
||||
'[[onlinestore:Start page|Text]]' => '<a href="/wiki/onlinestore/Start_page" class="wiki-page">Text</a>',
|
||||
'[[onlinestore:Unknown page]]' => '<a href="/wiki/onlinestore/Unknown_page" class="wiki-page new">Unknown page</a>',
|
||||
# striked through link
|
||||
'-[[Another page|Page]]-' => '<del><a href="/wiki/ecookbook/Another_page" class="wiki-page">Page</a></del>',
|
||||
# escaping
|
||||
'![[Another page|Page]]' => '[[Another page|Page]]',
|
||||
}
|
||||
@@ -141,17 +172,22 @@ class ApplicationHelperTest < HelperTestCase
|
||||
"<pre>\nline 1\nline2</pre>" => "<pre>\nline 1\nline2</pre>",
|
||||
"<pre><code>\nline 1\nline2</code></pre>" => "<pre><code>\nline 1\nline2</code></pre>",
|
||||
"<pre><div>content</div></pre>" => "<pre><div>content</div></pre>",
|
||||
"HTML comment: <!-- no comments -->" => "<p>HTML comment: <!-- no comments --></p>",
|
||||
"<!-- opening comment" => "<p><!-- opening comment</p>"
|
||||
}
|
||||
to_test.each { |text, result| assert_equal result, textilizable(text) }
|
||||
end
|
||||
|
||||
def test_allowed_html_tags
|
||||
to_test = {
|
||||
"<pre>preformatted text</pre>" => "<pre>preformatted text</pre>",
|
||||
"<notextile>no *textile* formatting</notextile>" => "no *textile* formatting",
|
||||
}
|
||||
to_test.each { |text, result| assert_equal result, textilizable(text) }
|
||||
end
|
||||
|
||||
def test_wiki_links_in_tables
|
||||
to_test = {"|Cell 11|Cell 12|Cell 13|\n|Cell 21|Cell 22||\n|Cell 31||Cell 33|" =>
|
||||
'<tr><td>Cell 11</td><td>Cell 12</td><td>Cell 13</td></tr>' +
|
||||
'<tr><td>Cell 21</td><td>Cell 22</td></tr>' +
|
||||
'<tr><td>Cell 31</td><td>Cell 33</td></tr>',
|
||||
|
||||
"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
|
||||
to_test = {"|[[Page|Link title]]|[[Other Page|Other title]]|\n|Cell 21|[[Last page]]|" =>
|
||||
'<tr><td><a href="/wiki/ecookbook/Page" class="wiki-page new">Link title</a></td>' +
|
||||
'<td><a href="/wiki/ecookbook/Other_Page" class="wiki-page new">Other title</a></td>' +
|
||||
'</tr><tr><td>Cell 21</td><td><a href="/wiki/ecookbook/Last_page" class="wiki-page new">Last page</a></td></tr>'
|
||||
@@ -160,6 +196,108 @@ class ApplicationHelperTest < HelperTestCase
|
||||
to_test.each { |text, result| assert_equal "<table>#{result}</table>", textilizable(text).gsub(/[\t\n]/, '') }
|
||||
end
|
||||
|
||||
def test_text_formatting
|
||||
to_test = {'*_+bold, italic and underline+_*' => '<strong><em><ins>bold, italic and underline</ins></em></strong>',
|
||||
'(_text within parentheses_)' => '(<em>text within parentheses</em>)'
|
||||
}
|
||||
to_test.each { |text, result| assert_equal "<p>#{result}</p>", textilizable(text) }
|
||||
end
|
||||
|
||||
def test_wiki_horizontal_rule
|
||||
assert_equal '<hr />', textilizable('---')
|
||||
assert_equal '<p>Dashes: ---</p>', textilizable('Dashes: ---')
|
||||
end
|
||||
|
||||
def test_table_of_content
|
||||
raw = <<-RAW
|
||||
{{toc}}
|
||||
|
||||
h1. Title
|
||||
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
|
||||
h2. Subtitle
|
||||
|
||||
Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
|
||||
|
||||
h2. Subtitle with %{color:red}red text%
|
||||
|
||||
h1. Another title
|
||||
|
||||
RAW
|
||||
|
||||
expected = '<ul class="toc">' +
|
||||
'<li class="heading1"><a href="#Title">Title</a></li>' +
|
||||
'<li class="heading2"><a href="#Subtitle">Subtitle</a></li>' +
|
||||
'<li class="heading2"><a href="#Subtitle-with-red-text">Subtitle with red text</a></li>' +
|
||||
'<li class="heading1"><a href="#Another-title">Another title</a></li>' +
|
||||
'</ul>'
|
||||
|
||||
assert textilizable(raw).gsub("\n", "").include?(expected)
|
||||
end
|
||||
|
||||
def test_blockquote
|
||||
# orig raw text
|
||||
raw = <<-RAW
|
||||
John said:
|
||||
> Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
> Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
|
||||
> * Donec odio lorem,
|
||||
> * sagittis ac,
|
||||
> * malesuada in,
|
||||
> * adipiscing eu, dolor.
|
||||
>
|
||||
> >Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.
|
||||
> Proin a tellus. Nam vel neque.
|
||||
|
||||
He's right.
|
||||
RAW
|
||||
|
||||
# expected html
|
||||
expected = <<-EXPECTED
|
||||
<p>John said:</p>
|
||||
<blockquote>
|
||||
Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas sed libero.
|
||||
Nullam commodo metus accumsan nulla. Curabitur lobortis dui id dolor.
|
||||
<ul>
|
||||
<li>Donec odio lorem,</li>
|
||||
<li>sagittis ac,</li>
|
||||
<li>malesuada in,</li>
|
||||
<li>adipiscing eu, dolor.</li>
|
||||
</ul>
|
||||
<blockquote>
|
||||
<p>Nulla varius pulvinar diam. Proin id arcu id lorem scelerisque condimentum. Proin vehicula turpis vitae lacus.</p>
|
||||
</blockquote>
|
||||
<p>Proin a tellus. Nam vel neque.</p>
|
||||
</blockquote>
|
||||
<p>He's right.</p>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_table
|
||||
raw = <<-RAW
|
||||
This is a table with empty cells:
|
||||
|
||||
|cell11|cell12||
|
||||
|cell21||cell23|
|
||||
|cell31|cell32|cell33|
|
||||
RAW
|
||||
|
||||
expected = <<-EXPECTED
|
||||
<p>This is a table with empty cells:</p>
|
||||
|
||||
<table>
|
||||
<tr><td>cell11</td><td>cell12</td><td></td></tr>
|
||||
<tr><td>cell21</td><td></td><td>cell23</td></tr>
|
||||
<tr><td>cell31</td><td>cell32</td><td>cell33</td></tr>
|
||||
</table>
|
||||
EXPECTED
|
||||
|
||||
assert_equal expected.gsub(%r{\s+}, ''), textilizable(raw).gsub(%r{\s+}, '')
|
||||
end
|
||||
|
||||
def test_macro_hello_world
|
||||
text = "{{hello_world}}"
|
||||
assert textilizable(text).match(/Hello world!/)
|
||||
|
||||
@@ -18,7 +18,13 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class IssueTest < Test::Unit::TestCase
|
||||
fixtures :projects, :users, :members, :trackers, :projects_trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :time_entries
|
||||
fixtures :projects, :users, :members,
|
||||
:trackers, :projects_trackers,
|
||||
:issue_statuses, :issue_categories,
|
||||
:enumerations,
|
||||
:issues,
|
||||
:custom_fields, :custom_fields_projects, :custom_fields_trackers, :custom_values,
|
||||
:time_entries
|
||||
|
||||
def test_create
|
||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'test_create', :description => 'IssueTest#test_create', :estimated_hours => '1:30')
|
||||
@@ -27,6 +33,76 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert_equal 1.5, issue.estimated_hours
|
||||
end
|
||||
|
||||
def test_create_with_required_custom_field
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
field.update_attribute(:is_required, true)
|
||||
|
||||
issue = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :subject => 'test_create', :description => 'IssueTest#test_create_with_required_custom_field')
|
||||
assert issue.available_custom_fields.include?(field)
|
||||
# No value for the custom field
|
||||
assert !issue.save
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
# Blank value
|
||||
issue.custom_field_values = { field.id => '' }
|
||||
assert !issue.save
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
# Invalid value
|
||||
issue.custom_field_values = { field.id => 'SQLServer' }
|
||||
assert !issue.save
|
||||
assert_equal 'activerecord_error_invalid', issue.errors.on(:custom_values)
|
||||
# Valid value
|
||||
issue.custom_field_values = { field.id => 'PostgreSQL' }
|
||||
assert issue.save
|
||||
issue.reload
|
||||
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
|
||||
end
|
||||
|
||||
def test_update_issue_with_required_custom_field
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
field.update_attribute(:is_required, true)
|
||||
|
||||
issue = Issue.find(1)
|
||||
assert_nil issue.custom_value_for(field)
|
||||
assert issue.available_custom_fields.include?(field)
|
||||
# No change to custom values, issue can be saved
|
||||
assert issue.save
|
||||
# Blank value
|
||||
issue.custom_field_values = { field.id => '' }
|
||||
assert !issue.save
|
||||
# Valid value
|
||||
issue.custom_field_values = { field.id => 'PostgreSQL' }
|
||||
assert issue.save
|
||||
issue.reload
|
||||
assert_equal 'PostgreSQL', issue.custom_value_for(field).value
|
||||
end
|
||||
|
||||
def test_should_not_update_attributes_if_custom_fields_validation_fails
|
||||
issue = Issue.find(1)
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
assert issue.available_custom_fields.include?(field)
|
||||
|
||||
issue.custom_field_values = { field.id => 'Invalid' }
|
||||
issue.subject = 'Should be not be saved'
|
||||
assert !issue.save
|
||||
|
||||
issue.reload
|
||||
assert_equal "Can't print recipes", issue.subject
|
||||
end
|
||||
|
||||
def test_should_not_recreate_custom_values_objects_on_update
|
||||
field = IssueCustomField.find_by_name('Database')
|
||||
|
||||
issue = Issue.find(1)
|
||||
issue.custom_field_values = { field.id => 'PostgreSQL' }
|
||||
assert issue.save
|
||||
custom_value = issue.custom_value_for(field)
|
||||
issue.reload
|
||||
issue.custom_field_values = { field.id => 'MySQL' }
|
||||
assert issue.save
|
||||
issue.reload
|
||||
assert_equal custom_value.id, issue.custom_value_for(field).id
|
||||
end
|
||||
|
||||
def test_category_based_assignment
|
||||
issue = Issue.create(:project_id => 1, :tracker_id => 1, :author_id => 3, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Assignment test', :description => 'Assignment test', :category_id => 1)
|
||||
assert_equal IssueCategory.find(1).assigned_to, issue.assigned_to
|
||||
@@ -42,7 +118,7 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert_equal orig.custom_values.first.value, issue.custom_values.first.value
|
||||
end
|
||||
|
||||
def test_close_duplicates
|
||||
def test_should_close_duplicates
|
||||
# Create 3 issues
|
||||
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
||||
assert issue1.save
|
||||
@@ -52,12 +128,12 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert issue3.save
|
||||
|
||||
# 2 is a dupe of 1
|
||||
IssueRelation.create(:issue_from => issue1, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
# And 3 is a dupe of 2
|
||||
IssueRelation.create(:issue_from => issue2, :issue_to => issue3, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
IssueRelation.create(:issue_from => issue3, :issue_to => issue2, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
# And 3 is a dupe of 1 (circular duplicates)
|
||||
IssueRelation.create(:issue_from => issue1, :issue_to => issue3, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
|
||||
IssueRelation.create(:issue_from => issue3, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
|
||||
assert issue1.reload.duplicates.include?(issue2)
|
||||
|
||||
# Closing issue 1
|
||||
@@ -69,17 +145,46 @@ class IssueTest < Test::Unit::TestCase
|
||||
assert issue3.reload.closed?
|
||||
end
|
||||
|
||||
def test_move_to_another_project
|
||||
def test_should_not_close_duplicated_issue
|
||||
# Create 3 issues
|
||||
issue1 = Issue.new(:project_id => 1, :tracker_id => 1, :author_id => 1, :status_id => 1, :priority => Enumeration.get_values('IPRI').first, :subject => 'Duplicates test', :description => 'Duplicates test')
|
||||
assert issue1.save
|
||||
issue2 = issue1.clone
|
||||
assert issue2.save
|
||||
|
||||
# 2 is a dupe of 1
|
||||
IssueRelation.create(:issue_from => issue2, :issue_to => issue1, :relation_type => IssueRelation::TYPE_DUPLICATES)
|
||||
# 2 is a dup of 1 but 1 is not a duplicate of 2
|
||||
assert !issue2.reload.duplicates.include?(issue1)
|
||||
|
||||
# Closing issue 2
|
||||
issue2.init_journal(User.find(:first), "Closing issue2")
|
||||
issue2.status = IssueStatus.find :first, :conditions => {:is_closed => true}
|
||||
assert issue2.save
|
||||
# 1 should not be also closed
|
||||
assert !issue1.reload.closed?
|
||||
end
|
||||
|
||||
def test_move_to_another_project_with_same_category
|
||||
issue = Issue.find(1)
|
||||
assert issue.move_to(Project.find(2))
|
||||
issue.reload
|
||||
assert_equal 2, issue.project_id
|
||||
# Category removed
|
||||
assert_nil issue.category
|
||||
# Category changes
|
||||
assert_equal 4, issue.category_id
|
||||
# Make sure time entries were move to the target project
|
||||
assert_equal 2, issue.time_entries.first.project_id
|
||||
end
|
||||
|
||||
def test_move_to_another_project_without_same_category
|
||||
issue = Issue.find(2)
|
||||
assert issue.move_to(Project.find(2))
|
||||
issue.reload
|
||||
assert_equal 2, issue.project_id
|
||||
# Category cleared
|
||||
assert_nil issue.category_id
|
||||
end
|
||||
|
||||
def test_issue_destroy
|
||||
Issue.find(1).destroy
|
||||
assert_nil Issue.find_by_id(1)
|
||||
|
||||
@@ -18,40 +18,111 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class MailHandlerTest < Test::Unit::TestCase
|
||||
fixtures :users, :projects, :enabled_modules, :roles, :members, :issues, :trackers, :enumerations
|
||||
fixtures :users, :projects,
|
||||
:enabled_modules,
|
||||
:roles,
|
||||
:members,
|
||||
:issues,
|
||||
:trackers,
|
||||
:projects_trackers,
|
||||
:enumerations,
|
||||
:issue_categories
|
||||
|
||||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler'
|
||||
|
||||
FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures'
|
||||
CHARSET = "utf-8"
|
||||
|
||||
include ActionMailer::Quoting
|
||||
|
||||
def setup
|
||||
ActionMailer::Base.delivery_method = :test
|
||||
ActionMailer::Base.perform_deliveries = true
|
||||
ActionMailer::Base.deliveries = []
|
||||
|
||||
@expected = TMail::Mail.new
|
||||
@expected.set_content_type "text", "plain", { "charset" => CHARSET }
|
||||
@expected.mime_version = '1.0'
|
||||
ActionMailer::Base.deliveries.clear
|
||||
end
|
||||
|
||||
def test_add_note_to_issue
|
||||
raw = read_fixture("add_note_to_issue.txt").join
|
||||
MailHandler.receive(raw)
|
||||
def test_add_issue
|
||||
# This email contains: 'Project: onlinestore'
|
||||
issue = submit_email('ticket_on_given_project.eml')
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'New ticket on a given project', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
||||
end
|
||||
|
||||
issue = Issue.find(2)
|
||||
journal = issue.journals.find(:first, :order => "created_on DESC")
|
||||
assert journal
|
||||
assert_equal User.find_by_mail("jsmith@somenet.foo"), journal.user
|
||||
assert_equal "Note added by mail", journal.notes
|
||||
def test_add_issue_with_status
|
||||
# This email contains: 'Project: onlinestore' and 'Status: Resolved'
|
||||
issue = submit_email('ticket_on_given_project.eml')
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal IssueStatus.find_by_name("Resolved"), issue.status
|
||||
end
|
||||
|
||||
def test_add_issue_with_attributes_override
|
||||
issue = submit_email('ticket_with_attributes.eml', :allow_override => 'tracker,category,priority')
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'New ticket on a given project', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal 'Feature request', issue.tracker.to_s
|
||||
assert_equal 'Stock management', issue.category.to_s
|
||||
assert_equal 'Urgent', issue.priority.to_s
|
||||
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
||||
end
|
||||
|
||||
def test_add_issue_with_partial_attributes_override
|
||||
issue = submit_email('ticket_with_attributes.eml', :issue => {:priority => 'High'}, :allow_override => ['tracker'])
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'New ticket on a given project', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal 'Feature request', issue.tracker.to_s
|
||||
assert_nil issue.category
|
||||
assert_equal 'High', issue.priority.to_s
|
||||
assert issue.description.include?('Lorem ipsum dolor sit amet, consectetuer adipiscing elit.')
|
||||
end
|
||||
|
||||
def test_add_issue_with_attachment_to_specific_project
|
||||
issue = submit_email('ticket_with_attachment.eml', :issue => {:project => 'onlinestore'})
|
||||
assert issue.is_a?(Issue)
|
||||
assert !issue.new_record?
|
||||
issue.reload
|
||||
assert_equal 'Ticket created by email with attachment', issue.subject
|
||||
assert_equal User.find_by_login('jsmith'), issue.author
|
||||
assert_equal Project.find(2), issue.project
|
||||
assert_equal 'This is a new ticket with attachments', issue.description
|
||||
# Attachment properties
|
||||
assert_equal 1, issue.attachments.size
|
||||
assert_equal 'Paella.jpg', issue.attachments.first.filename
|
||||
assert_equal 'image/jpeg', issue.attachments.first.content_type
|
||||
assert_equal 10790, issue.attachments.first.filesize
|
||||
end
|
||||
|
||||
def test_add_issue_note
|
||||
journal = submit_email('ticket_reply.eml')
|
||||
assert journal.is_a?(Journal)
|
||||
assert_equal User.find_by_login('jsmith'), journal.user
|
||||
assert_equal Issue.find(2), journal.journalized
|
||||
assert_match /This is reply/, journal.notes
|
||||
end
|
||||
|
||||
def test_add_issue_note_with_status_change
|
||||
# This email contains: 'Status: Resolved'
|
||||
journal = submit_email('ticket_reply_with_status.eml')
|
||||
assert journal.is_a?(Journal)
|
||||
issue = Issue.find(journal.issue.id)
|
||||
assert_equal User.find_by_login('jsmith'), journal.user
|
||||
assert_equal Issue.find(2), journal.journalized
|
||||
assert_match /This is reply/, journal.notes
|
||||
assert_equal IssueStatus.find_by_name("Resolved"), issue.status
|
||||
end
|
||||
|
||||
private
|
||||
def read_fixture(action)
|
||||
IO.readlines("#{FIXTURES_PATH}/mail_handler/#{action}")
|
||||
end
|
||||
|
||||
def encode(subject)
|
||||
quoted_printable(subject, CHARSET)
|
||||
end
|
||||
|
||||
def submit_email(filename, options={})
|
||||
raw = IO.read(File.join(FIXTURES_PATH, filename))
|
||||
MailHandler.receive(raw, options)
|
||||
end
|
||||
end
|
||||
|
||||
@@ -36,7 +36,7 @@ class MailerTest < Test::Unit::TestCase
|
||||
# link to a referenced ticket
|
||||
assert mail.body.include?('<a href="https://mydomain.foo/issues/show/2" class="issue" title="Add ingredients categories (Assigned)">#2</a>')
|
||||
# link to a changeset
|
||||
assert mail.body.include?('<a href="https://mydomain.foo/repositories/revision/ecookbook?rev=2" class="changeset" title="This commit fixes #1, #2 and references #1 & #3">r2</a>')
|
||||
assert mail.body.include?('<a href="https://mydomain.foo/repositories/revision/ecookbook/2" class="changeset" title="This commit fixes #1, #2 and references #1 & #3">r2</a>')
|
||||
end
|
||||
|
||||
# test mailer methods for each language
|
||||
@@ -116,4 +116,13 @@ class MailerTest < Test::Unit::TestCase
|
||||
assert Mailer.deliver_register(token)
|
||||
end
|
||||
end
|
||||
|
||||
def test_reminders
|
||||
ActionMailer::Base.deliveries.clear
|
||||
Mailer.reminders(:days => 42)
|
||||
assert_equal 1, ActionMailer::Base.deliveries.size
|
||||
mail = ActionMailer::Base.deliveries.last
|
||||
assert mail.bcc.include?('dlopper@somenet.foo')
|
||||
assert mail.body.include?('Bug #3: Error 281 when updating a recipe')
|
||||
end
|
||||
end
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
begin
|
||||
require 'mocha'
|
||||
|
||||
class MercurialAdapterTest < Test::Unit::TestCase
|
||||
|
||||
TEMPLATES_DIR = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATES_DIR
|
||||
TEMPLATE_NAME = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_NAME
|
||||
TEMPLATE_EXTENSION = Redmine::Scm::Adapters::MercurialAdapter::TEMPLATE_EXTENSION
|
||||
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/mercurial_repository'
|
||||
|
||||
def test_hgversion
|
||||
to_test = { "0.9.5" => [0,9,5],
|
||||
"1.0" => [1,0],
|
||||
"1e4ddc9ac9f7+20080325" => nil,
|
||||
"1.0.1+20080525" => [1,0,1],
|
||||
"1916e629a29d" => nil}
|
||||
|
||||
to_test.each do |s, v|
|
||||
test_hgversion_for(s, v)
|
||||
end
|
||||
end
|
||||
|
||||
def test_template_path
|
||||
to_test = { [0,9,5] => "0.9.5",
|
||||
[1,0] => "1.0",
|
||||
[] => "1.0",
|
||||
[1,0,1] => "1.0"}
|
||||
|
||||
to_test.each do |v, template|
|
||||
test_template_path_for(v, template)
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def test_hgversion_for(hgversion, version)
|
||||
Redmine::Scm::Adapters::MercurialAdapter.expects(:hgversion_from_command_line).returns(hgversion)
|
||||
adapter = Redmine::Scm::Adapters::MercurialAdapter
|
||||
assert_equal version, adapter.hgversion
|
||||
end
|
||||
|
||||
def test_template_path_for(version, template)
|
||||
adapter = Redmine::Scm::Adapters::MercurialAdapter
|
||||
assert_equal "#{TEMPLATES_DIR}/#{TEMPLATE_NAME}-#{template}.#{TEMPLATE_EXTENSION}", adapter.template_path_for(version)
|
||||
assert File.exist?(adapter.template_path_for(version))
|
||||
end
|
||||
end
|
||||
|
||||
rescue LoadError
|
||||
def test_fake; assert(false, "Requires mocha to run those tests") end
|
||||
end
|
||||
@@ -101,7 +101,7 @@ class ProjectTest < Test::Unit::TestCase
|
||||
assert sub.save
|
||||
assert_equal @ecookbook.id, sub.parent.id
|
||||
@ecookbook.reload
|
||||
assert_equal 3, @ecookbook.children.size
|
||||
assert_equal 4, @ecookbook.children.size
|
||||
end
|
||||
|
||||
def test_subproject_invalid
|
||||
@@ -118,6 +118,7 @@ class ProjectTest < Test::Unit::TestCase
|
||||
|
||||
def test_rolled_up_trackers
|
||||
parent = Project.find(1)
|
||||
parent.trackers = Tracker.find([1,2])
|
||||
child = parent.children.find(3)
|
||||
|
||||
assert_equal [1, 2], parent.tracker_ids
|
||||
|
||||
@@ -20,15 +20,109 @@ require File.dirname(__FILE__) + '/../test_helper'
|
||||
class QueryTest < Test::Unit::TestCase
|
||||
fixtures :projects, :users, :members, :roles, :trackers, :issue_statuses, :issue_categories, :enumerations, :issues, :custom_fields, :custom_values, :queries
|
||||
|
||||
def test_custom_fields_for_all_projects_should_be_available_in_global_queries
|
||||
query = Query.new(:project => nil, :name => '_')
|
||||
assert query.available_filters.has_key?('cf_1')
|
||||
assert !query.available_filters.has_key?('cf_3')
|
||||
end
|
||||
|
||||
def find_issues_with_query(query)
|
||||
Issue.find :all,
|
||||
:include => [ :assigned_to, :status, :tracker, :project, :priority ],
|
||||
:conditions => query.statement
|
||||
end
|
||||
|
||||
def test_query_with_multiple_custom_fields
|
||||
query = Query.find(1)
|
||||
assert query.valid?
|
||||
assert query.statement.include?("#{CustomValue.table_name}.value IN ('MySQL')")
|
||||
issues = Issue.find :all,:include => [ :assigned_to, :status, :tracker, :project, :priority ], :conditions => query.statement
|
||||
issues = find_issues_with_query(query)
|
||||
assert_equal 1, issues.length
|
||||
assert_equal Issue.find(3), issues.first
|
||||
end
|
||||
|
||||
def test_operator_none
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('fixed_version_id', '!*', [''])
|
||||
query.add_filter('cf_1', '!*', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NULL")
|
||||
assert query.statement.include?("#{CustomValue.table_name}.value IS NULL OR #{CustomValue.table_name}.value = ''")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_none_for_integer
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('estimated_hours', '!*', [''])
|
||||
issues = find_issues_with_query(query)
|
||||
assert !issues.empty?
|
||||
assert issues.all? {|i| !i.estimated_hours}
|
||||
end
|
||||
|
||||
def test_operator_all
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('fixed_version_id', '*', [''])
|
||||
query.add_filter('cf_1', '*', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.fixed_version_id IS NOT NULL")
|
||||
assert query.statement.include?("#{CustomValue.table_name}.value IS NOT NULL AND #{CustomValue.table_name}.value <> ''")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_greater_than
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('done_ratio', '>=', ['40'])
|
||||
assert query.statement.include?("#{Issue.table_name}.done_ratio >= 40")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_in_more_than
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', '>t+', ['15'])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date >=")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_in_less_than
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', '<t+', ['15'])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_today
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 't', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_this_week_on_date
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('due_date', 'w', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.due_date BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_this_week_on_datetime
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('created_on', 'w', [''])
|
||||
assert query.statement.include?("#{Issue.table_name}.created_on BETWEEN")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_contains
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('subject', '~', ['string'])
|
||||
assert query.statement.include?("#{Issue.table_name}.subject LIKE '%string%'")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_operator_does_not_contains
|
||||
query = Query.new(:project => Project.find(1), :name => '_')
|
||||
query.add_filter('subject', '!~', ['string'])
|
||||
assert query.statement.include?("#{Issue.table_name}.subject NOT LIKE '%string%'")
|
||||
find_issues_with_query(query)
|
||||
end
|
||||
|
||||
def test_default_columns
|
||||
q = Query.new
|
||||
assert !q.columns.empty?
|
||||
@@ -42,6 +136,11 @@ class QueryTest < Test::Unit::TestCase
|
||||
assert q.has_column?(c)
|
||||
end
|
||||
|
||||
def test_label_for
|
||||
q = Query.new
|
||||
assert_equal 'assigned_to', q.label_for('assigned_to_id')
|
||||
end
|
||||
|
||||
def test_editable_by
|
||||
admin = User.find(1)
|
||||
manager = User.find(2)
|
||||
|
||||
@@ -22,7 +22,7 @@ class RepositoryCvsTest < Test::Unit::TestCase
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/cvs_repository'
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if RUBY_PLATFORM =~ /mswin/
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
# CVS module
|
||||
MODULE_NAME = 'test'
|
||||
|
||||
|
||||
@@ -48,6 +48,13 @@ class RepositoryDarcsTest < Test::Unit::TestCase
|
||||
@repository.fetch_changesets
|
||||
assert_equal 6, @repository.changesets.count
|
||||
end
|
||||
|
||||
def test_cat
|
||||
@repository.fetch_changesets
|
||||
cat = @repository.cat("sources/welcome_controller.rb", 2)
|
||||
assert_not_nil cat
|
||||
assert cat.include?('class WelcomeController < ApplicationController')
|
||||
end
|
||||
else
|
||||
puts "Darcs test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2007 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class RepositoryFilesystemTest < Test::Unit::TestCase
|
||||
fixtures :projects
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/filesystem_repository'
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
Setting.enabled_scm << 'Filesystem' unless Setting.enabled_scm.include?('Filesystem')
|
||||
assert @repository = Repository::Filesystem.create(:project => @project, :url => REPOSITORY_PATH)
|
||||
end
|
||||
|
||||
if File.directory?(REPOSITORY_PATH)
|
||||
def test_fetch_changesets
|
||||
@repository.fetch_changesets
|
||||
@repository.reload
|
||||
|
||||
assert_equal 0, @repository.changesets.count
|
||||
assert_equal 0, @repository.changes.count
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 2, @repository.entries("", 2).size
|
||||
assert_equal 2, @repository.entries("dir", 3).size
|
||||
end
|
||||
|
||||
def test_cat
|
||||
assert_equal "TEST CAT\n", @repository.scm.cat("test")
|
||||
end
|
||||
|
||||
else
|
||||
puts "Filesystem test repository NOT FOUND. Skipping unit tests !!! See doc/RUNNING_TESTS."
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
||||
@@ -22,7 +22,7 @@ class RepositoryGitTest < Test::Unit::TestCase
|
||||
|
||||
# No '..' in the repository path
|
||||
REPOSITORY_PATH = RAILS_ROOT.gsub(%r{config\/\.\.}, '') + '/tmp/test/git_repository'
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if RUBY_PLATFORM =~ /mswin/
|
||||
REPOSITORY_PATH.gsub!(/\//, "\\") if Redmine::Platform.mswin?
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
|
||||
@@ -48,6 +48,26 @@ class RepositoryMercurialTest < Test::Unit::TestCase
|
||||
@repository.fetch_changesets
|
||||
assert_equal 6, @repository.changesets.count
|
||||
end
|
||||
|
||||
def test_entries
|
||||
assert_equal 2, @repository.entries("sources", 2).size
|
||||
assert_equal 1, @repository.entries("sources", 3).size
|
||||
end
|
||||
|
||||
def test_locate_on_outdated_repository
|
||||
# Change the working dir state
|
||||
%x{hg -R #{REPOSITORY_PATH} up -r 0}
|
||||
assert_equal 1, @repository.entries("images", 0).size
|
||||
assert_equal 2, @repository.entries("images").size
|
||||
assert_equal 2, @repository.entries("images", 2).size
|
||||
end
|
||||
|
||||
|
||||
def test_cat
|
||||
assert @repository.scm.cat("sources/welcome_controller.rb", 2)
|
||||
assert_nil @repository.scm.cat("sources/welcome_controller.rb")
|
||||
end
|
||||
|
||||
else
|
||||
puts "Mercurial test repository NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
|
||||
@@ -45,6 +45,26 @@ class RepositoryTest < Test::Unit::TestCase
|
||||
assert_equal repository, project.repository
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
changesets = Changeset.count(:all, :conditions => "repository_id = 10")
|
||||
changes = Change.count(:all, :conditions => "repository_id = 10", :include => :changeset)
|
||||
assert_difference 'Changeset.count', -changesets do
|
||||
assert_difference 'Change.count', -changes do
|
||||
Repository.find(10).destroy
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def test_should_not_create_with_disabled_scm
|
||||
# disable Subversion
|
||||
Setting.enabled_scm = ['Darcs', 'Git']
|
||||
repository = Repository::Subversion.new(:project => Project.find(3), :url => "svn://localhost")
|
||||
assert !repository.save
|
||||
assert_equal :activerecord_error_invalid, repository.errors.on(:type)
|
||||
# re-enable Subversion for following tests
|
||||
Setting.delete_all
|
||||
end
|
||||
|
||||
def test_scan_changesets_for_issue_ids
|
||||
# choosing a status to apply to fix issues
|
||||
Setting.commit_fix_status_id = IssueStatus.find(:first, :conditions => ["is_closed = ?", true]).id
|
||||
|
||||
@@ -26,7 +26,7 @@ class RoleTest < Test::Unit::TestCase
|
||||
|
||||
target = Role.new(:name => 'Target')
|
||||
assert target.save
|
||||
assert target.workflows.copy(source)
|
||||
target.workflows.copy(source)
|
||||
target.reload
|
||||
assert_equal 90, target.workflows.size
|
||||
end
|
||||
|
||||
@@ -0,0 +1,143 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class SearchTest < Test::Unit::TestCase
|
||||
fixtures :users,
|
||||
:members,
|
||||
:projects,
|
||||
:roles,
|
||||
:enabled_modules,
|
||||
:issues,
|
||||
:trackers,
|
||||
:journals,
|
||||
:journal_details,
|
||||
:repositories,
|
||||
:changesets
|
||||
|
||||
def setup
|
||||
@project = Project.find(1)
|
||||
@issue_keyword = '%unable to print recipes%'
|
||||
@issue = Issue.find(1)
|
||||
@changeset_keyword = '%very first commit%'
|
||||
@changeset = Changeset.find(100)
|
||||
end
|
||||
|
||||
def test_search_by_anonymous
|
||||
User.current = nil
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
|
||||
# Removes the :view_changesets permission from Anonymous role
|
||||
remove_permission Role.anonymous, :view_changesets
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert !r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_by_user
|
||||
User.current = User.find_by_login('rhill')
|
||||
assert User.current.memberships.empty?
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
|
||||
# Removes the :view_changesets permission from Non member role
|
||||
remove_permission Role.non_member, :view_changesets
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert !r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_by_allowed_member
|
||||
User.current = User.find_by_login('jsmith')
|
||||
assert User.current.projects.include?(@project)
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_by_unallowed_member
|
||||
# Removes the :view_changesets permission from user's and non member role
|
||||
remove_permission Role.find(1), :view_changesets
|
||||
remove_permission Role.non_member, :view_changesets
|
||||
|
||||
User.current = User.find_by_login('jsmith')
|
||||
assert User.current.projects.include?(@project)
|
||||
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
|
||||
# Make the project private
|
||||
@project.update_attribute :is_public, false
|
||||
r = Issue.search(@issue_keyword).first
|
||||
assert r.include?(@issue)
|
||||
r = Changeset.search(@changeset_keyword).first
|
||||
assert !r.include?(@changeset)
|
||||
end
|
||||
|
||||
def test_search_issue_with_multiple_hits_in_journals
|
||||
i = Issue.find(1)
|
||||
assert_equal 2, i.journals.count(:all, :conditions => "notes LIKE '%notes%'")
|
||||
|
||||
r = Issue.search('%notes%').first
|
||||
assert_equal 1, r.size
|
||||
assert_equal i, r.first
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def remove_permission(role, permission)
|
||||
role.permissions = role.permissions - [ permission ]
|
||||
role.save
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,33 @@
|
||||
# redMine - project management software
|
||||
# Copyright (C) 2006-2008 Jean-Philippe Lang
|
||||
#
|
||||
# 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.
|
||||
|
||||
require 'mkmf'
|
||||
|
||||
require File.dirname(__FILE__) + '/../test_helper'
|
||||
|
||||
class SubversionAdapterTest < Test::Unit::TestCase
|
||||
|
||||
if find_executable0('svn')
|
||||
def test_client_version
|
||||
v = Redmine::Scm::Adapters::SubversionAdapter.client_version
|
||||
assert v.is_a?(Array)
|
||||
end
|
||||
else
|
||||
puts "Subversion binary NOT FOUND. Skipping unit tests !!!"
|
||||
def test_fake; assert true end
|
||||
end
|
||||
end
|
||||
@@ -26,7 +26,7 @@ class TrackerTest < Test::Unit::TestCase
|
||||
|
||||
target = Tracker.new(:name => 'Target')
|
||||
assert target.save
|
||||
assert target.workflows.copy(source)
|
||||
target.workflows.copy(source)
|
||||
target.reload
|
||||
assert_equal 89, target.workflows.size
|
||||
end
|
||||
|
||||
@@ -57,6 +57,12 @@ class UserTest < Test::Unit::TestCase
|
||||
assert_equal "john", @admin.login
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
User.find(2).destroy
|
||||
assert_nil User.find_by_id(2)
|
||||
assert Member.find_all_by_principal_type_and_principal_id('User', 2).empty?
|
||||
end
|
||||
|
||||
def test_validate
|
||||
@admin.login = ""
|
||||
assert !@admin.save
|
||||
|
||||
@@ -48,6 +48,50 @@ class WikiPageTest < Test::Unit::TestCase
|
||||
assert page.new_record?
|
||||
end
|
||||
|
||||
def test_parent_title
|
||||
page = WikiPage.find_by_title('Another_page')
|
||||
assert_nil page.parent_title
|
||||
|
||||
page = WikiPage.find_by_title('Page_with_an_inline_image')
|
||||
assert_equal 'CookBook documentation', page.parent_title
|
||||
end
|
||||
|
||||
def test_assign_parent
|
||||
page = WikiPage.find_by_title('Another_page')
|
||||
page.parent_title = 'CookBook documentation'
|
||||
assert page.save
|
||||
page.reload
|
||||
assert_equal WikiPage.find_by_title('CookBook_documentation'), page.parent
|
||||
end
|
||||
|
||||
def test_unassign_parent
|
||||
page = WikiPage.find_by_title('Page_with_an_inline_image')
|
||||
page.parent_title = ''
|
||||
assert page.save
|
||||
page.reload
|
||||
assert_nil page.parent
|
||||
end
|
||||
|
||||
def test_parent_validation
|
||||
page = WikiPage.find_by_title('CookBook_documentation')
|
||||
|
||||
# A page that doesn't exist
|
||||
page.parent_title = 'Unknown title'
|
||||
assert !page.save
|
||||
assert_equal :activerecord_error_invalid, page.errors.on(:parent_title)
|
||||
# A child page
|
||||
page.parent_title = 'Page_with_an_inline_image'
|
||||
assert !page.save
|
||||
assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title)
|
||||
# The page itself
|
||||
page.parent_title = 'CookBook_documentation'
|
||||
assert !page.save
|
||||
assert_equal :activerecord_error_circular_dependency, page.errors.on(:parent_title)
|
||||
|
||||
page.parent_title = 'Another_page'
|
||||
assert page.save
|
||||
end
|
||||
|
||||
def test_destroy
|
||||
page = WikiPage.find(1)
|
||||
page.destroy
|
||||
|
||||
Reference in New Issue
Block a user