Repository: jfqd/redmine_helpdesk Branch: master Commit: 08468822690e Files: 94 Total size: 130.0 KB Directory structure: gitextract_lz5v3in0/ ├── .gitignore ├── .travis.yml ├── CHANGELOG.md ├── CONTRIBUTING.md ├── Gemfile ├── LICENSE ├── README.md ├── Rakefile ├── app/ │ └── views/ │ ├── _issue_edit.erb │ └── _issue_history.erb ├── config/ │ └── locales/ │ ├── de.yml │ ├── en.yml │ ├── es.yml │ ├── it.yml │ ├── ja.yml │ ├── pl.yml │ ├── ru.yml │ ├── tr.yml │ └── zh.yml ├── db/ │ └── migrate/ │ ├── 001_create_custom_owner_email_field.rb │ ├── 002_create_custom_fields_for_reply.rb │ ├── 003_create_custom_field_for_sender_email.rb │ ├── 004_create_custom_field_for_send_to_owner_default.rb │ ├── 005_add_treat_as_supportclient_to_anonymous.rb │ ├── 006_append_footer_to_first_reply.rb │ ├── 007_create_custom_copy_to_field.rb │ ├── 008_create_custom_field_cc_handling.rb │ ├── 009_create_custom_field_for_reopen_closed_issues_by_email.rb │ └── 010_create_custom_field_for_reply_separator.rb ├── init.rb ├── lib/ │ ├── helpdesk_hooks.rb │ ├── helpdesk_mailer.rb │ ├── macro_expander.rb │ ├── redmine_helpdesk/ │ │ ├── journal_patch.rb │ │ ├── mail_handler_patch.rb │ │ └── mailer_patch.rb │ └── tasks/ │ ├── local-db.rake │ ├── plugin_ci.rake │ └── redmine.rake └── test/ ├── confs/ │ ├── database_mysql.yml │ ├── database_postgres.yml │ ├── database_postgres_ext.yml │ └── database_sqlite.yml ├── fixtures/ │ ├── 2.6/ │ │ ├── attachments.yml │ │ ├── custom_fields.yml │ │ ├── custom_fields_projects.yml │ │ ├── custom_fields_trackers.yml │ │ ├── custom_values.yml │ │ ├── enabled_modules.yml │ │ ├── enumerations.yml │ │ ├── issue_statuses.yml │ │ ├── issues.yml │ │ ├── journal_details.yml │ │ ├── journals.yml │ │ ├── member_roles.yml │ │ ├── members.yml │ │ ├── projects.yml │ │ ├── projects_trackers.yml │ │ ├── roles.yml │ │ ├── trackers.yml │ │ └── users.yml │ ├── 3.0/ │ │ ├── attachments.yml │ │ ├── custom_fields.yml │ │ ├── custom_fields_projects.yml │ │ ├── custom_fields_trackers.yml │ │ ├── custom_values.yml │ │ ├── email_addresses.yml │ │ ├── enabled_modules.yml │ │ ├── enumerations.yml │ │ ├── issue_statuses.yml │ │ ├── issues.yml │ │ ├── journal_details.yml │ │ ├── journals.yml │ │ ├── member_roles.yml │ │ ├── members.yml │ │ ├── projects.yml │ │ ├── projects_trackers.yml │ │ ├── roles.yml │ │ ├── trackers.yml │ │ └── users.yml │ ├── files/ │ │ └── 2006/ │ │ └── 07/ │ │ └── 060719210727_source.rb │ └── mail_handler/ │ ├── ticket_by_unknown_user.eml │ ├── ticket_by_unknown_user_with_cc.eml │ ├── ticket_by_user_1.eml │ ├── ticket_by_user_2.eml │ ├── ticket_reply.eml │ ├── ticket_with_attachment.eml │ └── ticket_with_attributes.eml ├── functional/ │ └── issues_controller_with_helpdesk_test.rb ├── test_helper.rb └── unit/ ├── helpdesk_mailer_test.rb ├── journal_patch_test.rb ├── macro_expander_test.rb └── mail_handler_patch_test.rb ================================================ FILE CONTENTS ================================================ ================================================ FILE: .gitignore ================================================ .DS_Store *~ test/app/* ================================================ FILE: .travis.yml ================================================ language: ruby rvm: - 2.5 - 2.6 - jruby services: - mysql - postgresql env: global: - REDMINE_LANG=en - MYSQL_DATABASE=redmine - MYSQL_HOST=127.0.0.1 - MYSQL_PORT=3306 - MYSQL_USER=root - MYSQL_PASSWORD= - POSTGRES_DATABASE=redmine - POSTGRES_USER=postgres matrix: - REDMINE_VERSION=4.0.5 DATABASE_ADAPTER=mysql - REDMINE_VERSION=4.0.5 DATABASE_ADAPTER=postgresql matrix: allow_failures: # Incomplete ActiveRecord 4.2 support in jruby - rvm: 2.6 env: REDMINE_VERSION=4.0.5 DATABASE_ADAPTER=mysql - rvm: 2.6 env: REDMINE_VERSION=4.0.5 DATABASE_ADAPTER=postgresql - rvm: jruby env: REDMINE_VERSION=4.0.5 DATABASE_ADAPTER=mysql - rvm: jruby env: REDMINE_VERSION=4.0.5 DATABASE_ADAPTER=postgresql addons: code_climate: repo_token: secure: "SAyz/KNRQQC1T2oGNUxbDceBcoaL/IxvEmeKEIR3iivj3RMJi2Nm8v5B2Su9MhQBegi2mH70ypgkTPmGh69tSONf1sqkkCAxsZnIqihl1Ai+dwM2KlBLGw/k+IG9/xD1+hgQiO06OKZMPO+Kj9X28mMqJ75YVKGE4alr1mfo2NM=" before_install: - rake helpdesk:redmine:install - cd test/app - export BUNDLE_GEMFILE=Gemfile before_script: - echo $(pwd) - sudo service mysql start - echo $(ps -Af | grep mysqld) - export RAILS_ENV=test - mysql -e 'create database redmine;' - psql -c 'create database redmine;' -U postgres - bundle exec rake generate_secret_token - export RAILS_ENV=test - bundle exec rake db:migrate script: - bundle exec rake helpdesk:ci ================================================ FILE: CHANGELOG.md ================================================ 0.0.20 --- * Make plugin compatibility with Redmine 5.0.x 0.0.19 --- * Italian translation * Fix logger and use new setting * Do not send on private-notes * Fix reopening closed issue error * Improve de locale * Fix typo in email_was_send_to_supportclient * Sets To header optional * Remove Gemfile.lock * Find and process value of custom field directly * Add X-Redmine-Issue-Tracker header to mailerpatch 0.0.18 --- * Remove batches as nobody has the time to fix the tests * Remove untrue stuff from readme * Update mail_handler_patch.rb * Fix migration * Incorrect issue and project ids usage * Add space after the pre 0.0.17 --- * Fix issue by sending redmine journals with redmine_helpdesk * Store email-details before each note by martincizek from orchitech * Make option to reopen closed issues by email work * Added support for reply separator by sandratatarevicova from orchitech 0.0.16 --- * Make plugin compatibility with Redmine 4.0.x * Add option to reopen closed issues by email 0.0.15 --- * Added support for tracking email details by martincizek from orchitech 0.0.14 --- * Make plugin compatibility with Redmine 3.0.1 by Vilppu Vuorinen 0.0.13 --- * Unit and functional tests with travis and code climate support by Vilppu Vuorinen * Add customizable email footers by martincizek * Test compatibility with Redmine 2.6.2 0.0.12 --- * Add support for non-anonymous supportclients by martincizek * Add issue matching based on standard MIME header references by martincizek * Test compatibility with Redmine 2.5.3 0.0.11 --- * Make sure that the notes length is always calculated 0.0.10 --- * Fixed bug trying to send an email with empty notes 0.0.9 --- * Fixed non-working helpdesk-send-to-owner-default checkbox 0.0.8 --- * Add setting for handling send to owner default value by davidef 0.0.7 --- * Added reply-to header by barbazul 0.0.6 --- * Update code for redmine 2.4.x by Craig Gowing * Minor compatibility issues fixed 0.0.5 --- * Fix skip validation issue 0.0.4 --- * Update code for redmine 2.3.x * Send any journal attachments with the email notification to the supportclient 0.0.3 --- * The sender email-address is now adjustable on a per project basis 0.0.2 --- * A standard first reply message can be send to the supportclient on ticket creation (optional, per project) * The email-footer for the email notification to the supportclient can be adjusted (optional, per project) 0.0.1 --- * First release ================================================ FILE: CONTRIBUTING.md ================================================ # Issues Please note that I cannot provide user support for this open source project. All issues related to user support will be closed without a further comment. Open source does not mean that I have unlimited time to solve problems of others for free! If you need professional help please [contact me](http://www.qutic.com/support "hire a consultant") directly - I am for hire. If you find a bug please create an issue in the tracker, write a patch and send me a pull request :-) ================================================ FILE: Gemfile ================================================ gem "codeclimate-test-reporter", group: :test, require: nil unless (Gem::Specification::find_all_by_name('rake').any?) gem "rake", group: :test, require: nil end ================================================ FILE: LICENSE ================================================ Copyright (c) 2012-2021 qutic development GmbH Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. ================================================ FILE: README.md ================================================ # Redmine Helpdesk Lightweight helpdesk plugin for redmine. Adds the email sender-address of an anonymous supportclient to the custom field 'owner-email' of a ticket which was created by a support email. Answers can be send to the supportclient by checking the support checkbox on a journal. ## Support You want to support the development of this plugin? [We provide Redmine hosting including the Helpdesk plugin](https://qutic.com/de/loesungen/redmine-hosting/). ## Features * No need to create any user accounts for anonymous user * Support for sending an email notification to the (anonymous user) supportclient on ticket creation * A standard first reply message can be send to the supportclient on ticket creation (optional, per project) * The email-footer for the email notification to the supportclient can be adjusted (optional, per project) * The email-footer can be customized by using the following placeholders: - Issue parameters - ##issue-id## - ##issue-subject## - ##issue-tracker## - ##issue-status## - Project parameters - ##project-name## - User parameters - ##user-name## - ##user-firstname## - ##user-lastname## - ##user-mail## - ##user-login## - all user custom fields: ##user-cf-[user's custom field name]##, e.g. ##user-cf-position## - Base parameters - ##time-now## * The sender email-address can be adjusted (optional, per project) * Internal communication is not send to the supportclient * The supportclient will get an email notification if the support checkbox on the journal is checked (default value is optional) * Journal attachments will be delivered too * Cc header is handled if the cc-handling checkbox is checked. (optional, per project) * Reopening a closed issue is handled if the reopen-closed-issues-by-email checkbox is checked. (optional, per project) ## Screenshot  ## Getting the plugin A copy of the plugin can be downloaded from [GitHub](https://github.com/jfqd/redmine_helpdesk) ## Installation To install the plugin clone the repo from github and migrate the database: ``` cd /path/to/redmine/ git clone git://github.com/jfqd/redmine_helpdesk.git plugins/redmine_helpdesk bundle install --without development test rmagick bundle exec rake redmine:plugins:migrate RAILS_ENV=production ``` To uninstall the plugin migrate the database back and remove the plugin: ``` cd /path/to/redmine/ rake redmine:plugins:migrate NAME=redmine_helpdesk VERSION=0 RAILS_ENV=production rm -rf plugins/redmine_helpdesk ``` Further information about plugin installation can be found at: https://www.redmine.org/wiki/redmine/Plugins ## Usage To use the helpdesk functionality you need to * add the custom field 'owner-email' to a project in the project configuration * add a standard first reply message into the custom_field 'helpdesk-first-reply' in the project configuration (optional) * add an email-footer into the custom_field 'helpdesk-email-footer' in the project configuration * add a sender email address into the custom_field 'helpdesk-sender-email' in the project configuration (optional) * make sure 'Issue added' and 'Issue updated' in the general redmine settings for email notifications are checked * add the permission 'Treat as supportclient' to all roles you want to be treated as supportclient (the permission is automatically added to the 'Anonymous' role) * disable standard notifications for non-anonymous supportclients to prevent their spamming (optional) * add a cronjob for creating issues from support emails  ## Cronjob Creating tickets from support emails through an IMAP-account is done by a cronjob. If you are not familiar with cron you first should read about the concept. The following syntax is for ubuntu or debian linux: ``` */5 * * * * redmineuser /path/to/your/rake -f /path/to/redmine/Rakefile --silent redmine:email:receive_imap RAILS_ENV="production" host=mail.example.com port=993 username=username password=password ssl=true project=project_identifier folder=INBOX move_on_success=processed move_on_failure=failed no_permission_check=1 unknown_user=accept 1 > /dev/null ``` Further information about receiving emails with redmine can be found at: [https://www.redmine.org/projects/redmine/wiki/RedmineReceivingEmails](https://www.redmine.org/projects/redmine/wiki/RedmineReceivingEmails#Fetching-emails-from-an-IMAP-server) Please note that forwarding emails with **rdm-mailhandler.rb** is currently **not supported** by the plugin. ## Compatibility The latest version of this plugin is only compatible with Redmine 5.0, 5.1. * A version for Redmine 4.2.x is tagged with [v4.2](https://github.com/jfqd/redmine_helpdesk/releases/tag/v4.2 "plugin version for Redmine 4.2.x") and available for [download on github](https://github.com/jfqd/redmine_helpdesk/archive/v4.2.zip "download plugin for Redmine 4.2.x"). * A version for Redmine 4.0.x is tagged with [v4.0](https://github.com/jfqd/redmine_helpdesk/releases/tag/v4.0 "plugin version for Redmine 4.0.x") and available for [download on github](https://github.com/jfqd/redmine_helpdesk/archive/v4.0.zip "download plugin for Redmine 4.0.x"). * A version for Redmine 3.0.x and 3.1.x is tagged with [v3.1](https://github.com/jfqd/redmine_helpdesk/releases/tag/v3.1 "plugin version for Redmine 3.0.x and 3.1.x") and available for [download on github](https://github.com/jfqd/redmine_helpdesk/archive/v3.1.zip "download plugin for Redmine 3.0.x and 3.1.x"). * A version for Redmine 2.4.x and 2.5.x is tagged with [v2.5](https://github.com/jfqd/redmine_helpdesk/releases/tag/v2.5 "plugin version for Redmine 2.4.x and 2.5.x") and available for [download on github](https://github.com/jfqd/redmine_helpdesk/archive/v2.5.zip "download plugin for Redmine 2.4.x and 2.5.x"). * A version for Redmine 2.3.x is tagged with [v2.3](https://github.com/jfqd/redmine_helpdesk/tree/v2.3 "plugin version for Redmine 2.3.x") and available for [download on github](https://github.com/jfqd/redmine_helpdesk/archive/v2.3.zip "download plugin for Redmine 2.3.x"). * A version for Redmine 1.2.x. up to 1.4.7. is tagged with [v1.4](https://github.com/jfqd/redmine_helpdesk/tree/v1.4 "plugin version for Redmine 1.2.x up to 1.4.7") and available for [download on github](https://github.com/jfqd/redmine_helpdesk/archive/v1.4.zip "download plugin for Redmine 1.2.x up to 1.4.7"). If you prefer to run Redmine with JRuby make sure to use Redmine versions prior to 3.0.x! ## Development ### Testing Rake tasks for testing against Redmine are provided. Redmine is installed under `test/app` and tests are run against the local instance. ```bash REDMINE_VERSION=3.2 DATABASE_ADAPTER=mysql rake helpdesk:redmine:install ``` Docker is used to provide local MySQL (`DATABASE_ADAPTER=mysql`) and PostgreSQL (`DATABASE_ADAPTER=postgresql_ext`) instances. ```bash export DATABASE_ADAPTER=mysql rake helpdesk:prepare_local rake helpdesk:migrate ``` Test suite can be executed with: ```bash DATABASE_ADAPTER=mysql rake helpdesk:ext_ci ``` The local database instance has to be stopped with a rake task: ```bash rake helpdesk:localdb:stop ``` ## Contributions * [MatthiasPetermann](https://github.com/MatthiasPetermann) - Update for compatibility with Redmine 5.x / Rails 6.x * [rrsach](https://github.com/rrsach) - Redmine 5 Compatibility * [gianpaol0](https://github.com/gianpaol0) - italian translation * [mgeerdsen](https://github.com/mgeerdsen) - Fix reopening closed issue error * [mgeerdsen](https://github.com/mgeerdsen) - Improve de locale * [lmorillas](https://github.com/lmorillas) - Fix Error when message hasn't "To:" header * [promasu](https://github.com/promasu) - Add X-Redmine-Issue-Tracker header to mailerpatch * [ANemcov](https://github.com/ANemcov) - incorrect issue and project ids usage * [ismaelgc](https://github.com/ismaelgc) - Spanish translation * [monaka](https://github.com/monaka) - Japanese translation * [avoidik](https://github.com/avoidik) - Add missed Russian translation into roles and access manager * [WhereIsPedro](https://github.com/WhereIsPedro) - Polish translation * [vilppuvuorinen](https://github.com/vilppuvuorinen) - 3.0.x compatibility * [vilppuvuorinen](https://github.com/vilppuvuorinen) - Unit and functional tests with travis and code climate support * [ssidelnikov](https://github.com/ssidelnikov) - Make sure that the notes length is always calculated * [nifuki](https://github.com/nifuki) - Fixed bug trying to send an email with empty notes * [nifuki](https://github.com/nifuki) - Fixed non-working helpdesk-send-to-owner-default checkbox * [box789](https://github.com/box789) - Russian translation * [seqizz](https://github.com/seqizz) - Turkish translation * [benstwa](https://github.com/benstwa) - 'send' should be 'sent' * [davidef](https://github.com/davidef) - Add setting for handling sent to owner default value * [Craig Gowing](https://github.com/craiggowing) - Redmine 2.4 compatibility * [Barbazul](https://github.com/barbazul) - Added reply-to header * [Orchitech Solutions](https://github.com/orchitech) - Added issue matching based on standard MIME header references * [Orchitech Solutions](https://github.com/orchitech) - Added support for non-anonymous supportclients (sponsored by ISIC Global Office) * [Orchitech Solutions](https://github.com/orchitech) - Added support for customizable email footers (sponsored by ISIC Global Office) * [Orchitech Solutions](https://github.com/orchitech) - Added support for tracking email details (sponsored by ISIC Global Office) * [shackijj](https://github.com/shackijj) - Added Cc header handling * [archonwang](https://github.com/archonwang) - Add Simplified Chinese * [Niremizov](https://github.com/Niremizov) - Set owner email only if it wasn't set before * [ghost](https://github.com/ghost) - Fix attachements truncated in email sent to supportclient * [Orchitech Solutions](https://github.com/orchitech) - Added support for reply separator (sponsored by ISIC Global Office) ## License This plugin is licensed under the MIT license. See LICENSE-file for details. ## Copyright Copyright (c) 2012-2022 qutic development GmbH ================================================ FILE: Rakefile ================================================ Dir.glob('lib/tasks/*.rake').each { |r| load r} ================================================ FILE: app/views/_issue_edit.erb ================================================ <%= check_box_tag('send_to_owner', "true", (send_to_owner_default == "1")) %> <%=h t('label_support_checkbox') %> (<%=h email %>) ================================================ FILE: app/views/_issue_history.erb ================================================ <%=h t('email_was_send_to_supportclient') %> ================================================ FILE: config/locales/de.yml ================================================ de: label_support_checkbox: "E-Mail an Support-Anfragenden senden" email_was_send_to_supportclient: "Diese Antwort wurde an den Support-Anfragenden gesendet." permission_treat_user_as_supportclient: "Nutzer als Support-Anfragenden behandeln" ================================================ FILE: config/locales/en.yml ================================================ en: label_support_checkbox: "Send mail to supportclient" email_was_send_to_supportclient: "This answer was sent to the supportclient." ================================================ FILE: config/locales/es.yml ================================================ es: label_support_checkbox: "Enviar correo al usuario de soporte" email_was_send_to_supportclient: "Esta respuesta ha sido enviada al usuario de soporte." ================================================ FILE: config/locales/it.yml ================================================ it: label_support_checkbox: "Invia email al cliente" email_was_send_to_supportclient: "Questa risposta è stata inviata al cliente." ================================================ FILE: config/locales/ja.yml ================================================ ja: label_support_checkbox: "サポート顧客へメールを送信" email_was_send_to_supportclient: "この回答はサポート顧客へ送信されました。" ================================================ FILE: config/locales/pl.yml ================================================ pl: label_support_checkbox: "Wyślij wiadomość do klienta" email_was_send_to_supportclient: "Wiadomość została wysłana do klienta." ================================================ FILE: config/locales/ru.yml ================================================ ru: label_support_checkbox: "Отправить e-mail клиенту поддержки" email_was_send_to_supportclient: "Этот ответ был отправлен клиенту поддержки" permission_treat_user_as_supportclient: "Определять пользователя как клиента техподдержки" ================================================ FILE: config/locales/tr.yml ================================================ tr: label_support_checkbox: "Bu yanıtı destek isteyen müşteriye e-posta ile gönder" email_was_send_to_supportclient: "Bu yanıt destek talebi isteyen müşteriye de gönderildi." ================================================ FILE: config/locales/zh.yml ================================================ zh: label_support_checkbox: "发送反馈Email至客户" email_was_send_to_supportclient: "反馈邮件已发送至客户。" permission_treat_user_as_supportclient: "将用户作为客户" ================================================ FILE: db/migrate/001_create_custom_owner_email_field.rb ================================================ class CreateCustomOwnerEmailField < ActiveRecord::Migration[5.2] def self.up # fix PG:DuplicateColumn errors # https://github.com/jfqd/redmine_helpdesk/issues/66 unless column_exists? :journals, :send_to_owner add_column :journals, :send_to_owner, :boolean, :default => false c = CustomField.new( :name => 'owner-email', :editable => true, :field_format => 'string') c.type = 'IssueCustomField' # cannot be set by mass assignement! c.save Tracker.all.each do |t| execute "INSERT INTO custom_fields_trackers (custom_field_id,tracker_id) VALUES (#{c.id},#{t.id})" end end end def self.down c = CustomField.find_by_name('owner-email') execute "DELETE FROM custom_fields_trackers WHERE custom_field_id=#{c.id}" c.delete remove_column :journals, :send_to_owner end end ================================================ FILE: db/migrate/002_create_custom_fields_for_reply.rb ================================================ class CreateCustomFieldsForReply < ActiveRecord::Migration[5.2] def self.up c = CustomField.new( :name => 'helpdesk-first-reply', :editable => true, :visible => false, # do not show it on the project summary page :field_format => 'text') c.type = 'ProjectCustomField' # cannot be set by mass assignement! c.save d = CustomField.new( :name => 'helpdesk-email-footer', :editable => true, :visible => false, # do not show it on the project summary page :field_format => 'text') d.type = 'ProjectCustomField' # cannot be set by mass assignement! d.save end def self.down CustomField.find_by_name('helpdesk-first-reply').delete CustomField.find_by_name('helpdesk-email-footer').delete end end ================================================ FILE: db/migrate/003_create_custom_field_for_sender_email.rb ================================================ class CreateCustomFieldForSenderEmail < ActiveRecord::Migration[5.2] def self.up c = CustomField.new( :name => 'helpdesk-sender-email', :editable => true, :visible => true, :field_format => 'string') c.type = 'ProjectCustomField' # cannot be set by mass assignement! c.save end def self.down CustomField.find_by_name('helpdesk-sender-email').delete end end ================================================ FILE: db/migrate/004_create_custom_field_for_send_to_owner_default.rb ================================================ class CreateCustomFieldForSendToOwnerDefault < ActiveRecord::Migration[5.2] def self.up c = CustomField.new( :name => 'helpdesk-send-to-owner-default', :editable => true, :visible => false, # do not show it on the project summary page :field_format => 'bool') c.type = 'ProjectCustomField' # cannot be set by mass assignement! c.save end def self.down CustomField.find_by_name('helpdesk-send-to-owner-default').delete end end ================================================ FILE: db/migrate/005_add_treat_as_supportclient_to_anonymous.rb ================================================ class AddTreatAsSupportclientToAnonymous < ActiveRecord::Migration[5.2] def self.up anon_id = User.where(type: 'AnonymousUser').first.try(:id) || User.where('lastname LIKE ?', 'Anonymous').first.try(:id) || 4 role = Role.where(builtin: anon_id).first role.add_permission!(:treat_user_as_supportclient) unless role.nil? end def self.down Role.all.each do |r| r.remove_permission!(:treat_user_as_supportclient) end end end ================================================ FILE: db/migrate/006_append_footer_to_first_reply.rb ================================================ class AppendFooterToFirstReply < ActiveRecord::Migration[5.2] # Appends helpdesk-email-footer to helpdesk-first-reply to ensure backward # compatibility for updaters. See https://github.com/jfqd/redmine_helpdesk/issues/52 def self.up first_reply_cf_id = CustomField.find_by_name('helpdesk-first-reply').id footer_cf_id = CustomField.find_by_name('helpdesk-email-footer').id CustomValue.where(:custom_field_id => first_reply_cf_id).each do |first_reply_cv| if !first_reply_cv.value.nil? first_reply_with_footer = first_reply_cv.value first_reply_with_footer << "\n\n" first_reply_with_footer << CustomValue.where("custom_field_id=? and customized_id=?", footer_cf_id, first_reply_cv.customized_id).first.value CustomValue.update(first_reply_cv.id, :value => first_reply_with_footer) end end end end ================================================ FILE: db/migrate/007_create_custom_copy_to_field.rb ================================================ class CreateCustomCopyToField < ActiveRecord::Migration[5.2] def self.up c = CustomField.new( :name => 'copy-to', :editable => true, :field_format => 'string') c.type = 'IssueCustomField' # cannot be set by mass assignement! c.save Tracker.all.each do |t| execute "INSERT INTO custom_fields_trackers (custom_field_id,tracker_id) VALUES (#{c.id},#{t.id})" end end def self.down c = CustomField.find_by_name('copy-to') execute "DELETE FROM custom_fields_trackers WHERE custom_field_id=#{c.id}" c.delete end end ================================================ FILE: db/migrate/008_create_custom_field_cc_handling.rb ================================================ class CreateCustomFieldCcHandling < ActiveRecord::Migration[5.2] def self.up c = CustomField.new( :name => 'cc-handling', :editable => true, :visible => true, :field_format => 'bool') c.type = 'ProjectCustomField' # cannot be set by mass assignement! c.save end def self.down CustomField.find_by_name('cc-handling').delete end end ================================================ FILE: db/migrate/009_create_custom_field_for_reopen_closed_issues_by_email.rb ================================================ class CreateCustomFieldForReopenClosedIssuesByEmail < ActiveRecord::Migration[5.2] def self.up c = CustomField.new( :name => 'reopen-issues-with', :editable => true, :visible => true, :field_format => 'string') c.type = 'ProjectCustomField' # cannot be set by mass assignement! c.save end def self.down CustomField.find_by_name('reopen-issues-with').delete end end ================================================ FILE: db/migrate/010_create_custom_field_for_reply_separator.rb ================================================ class CreateCustomFieldForReplySeparator < ActiveRecord::Migration[5.2] def self.up begin c = CustomField.new( :name => 'helpdesk-reply-separator', :editable => true, :visible => false, # do not show it on the project summary page :field_format => 'string', :default_value => '-- Reply above this line --') c.type = 'ProjectCustomField' c.save rescue # rescue a possible migration error caused by renumbering the file end end def self.down CustomField.find_by_name('helpdesk-reply-separator').delete end end ================================================ FILE: init.rb ================================================ require 'redmine' $LOAD_PATH.unshift "#{File.dirname(__FILE__)}/lib" require 'helpdesk_hooks' require 'helpdesk_mailer' require 'redmine_helpdesk/journal_patch' require 'redmine_helpdesk/mail_handler_patch' require 'redmine_helpdesk/mailer_patch' Redmine::Plugin.register :redmine_helpdesk do name 'Redmine helpdesk plugin' author 'Stefan Husch' description 'Redmine helpdesk plugin' version '0.0.20' requires_redmine :version_or_higher => '5.0.0' project_module :issue_tracking do permission :treat_user_as_supportclient, {} end end ================================================ FILE: lib/helpdesk_hooks.rb ================================================ class HelpdeskHooks < Redmine::Hook::Listener # render partial for 'Send mail to supportclient' def view_issues_edit_notes_bottom(context={}) i = Issue.find(context[:issue].id) c = CustomField.find_by_name('owner-email') owner_email = i.custom_value_for(c).try(:value) return if owner_email.blank? p = i.project s = CustomField.find_by_name('helpdesk-send-to-owner-default') send_to_owner_default = p.custom_value_for(s).try(:value) if p.present? && s.present? lookup = ActionView::LookupContext.new(File.dirname(__FILE__) + '/../app/views/') context = ActionView::Base.with_empty_template_cache.new(lookup, {}, nil) renderer = ActionView::Renderer.new(lookup) renderer.render( context, partial: "issue_edit", locals: { email: owner_email, send_to_owner_default: (send_to_owner_default.present? && send_to_owner_default || false) } ) end # fetch 'send_to_owner' param and set the value into journal.send_to_owner def controller_issues_edit_before_save(context={}) send_to_owner = (context[:params]['send_to_owner'] == "true") context[:journal].send_to_owner = send_to_owner end # add a history note on the journal def view_issues_history_journal_bottom(context={}) return if (context[:journal].nil? || context[:journal].notes.nil? || context[:journal].notes.length == 0) return unless context[:journal].send_to_owner == true i = Issue.find(context[:journal].journalized_id) c = CustomField.find_by_name('owner-email') owner_email = i.custom_value_for(c).try(:value) return if owner_email.blank? lookup = ActionView::LookupContext.new(File.dirname(__FILE__) + '/../app/views/') context = ActionView::Base.with_empty_template_cache.new(lookup, {}, nil) renderer = ActionView::Renderer.new(lookup) renderer.render( context, partial: "issue_history", locals: { email: owner_email } ) end end ================================================ FILE: lib/helpdesk_mailer.rb ================================================ # # With Rails 3 mail is send with the mail method. Sadly redmine # uses this method-name too in their mailer. This is the reason # why we need our own Mailer class. # class HelpdeskMailer < ActionMailer::Base helper :application include Redmine::I18n include MacroExpander # set the hostname for url_for helper def self.default_url_options { :host => Setting.host_name, :protocol => Setting.protocol } end # Sending email notifications to the supportclient def email_to_supportclient(issue, params) # issue, recipient, journal=nil, text='', copy_to=nil recipient = params[:recipient] journal = params[:journal] text = params[:text] carbon_copy = params[:carbon_copy] redmine_headers 'Project' => issue.project.identifier, 'Issue-Id' => issue.id, 'Issue-Author' => issue.author.login redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to message_id issue references issue subject = "[#{issue.project.name} - ##{issue.id}] #{issue.subject}" # Set 'from' email-address to 'helpdesk-sender-email' if available. # Falls back to regular redmine behaviour if 'sender' is empty. p = issue.project s = CustomField.find_by_name('helpdesk-sender-email') sender = p.custom_value_for(s).try(:value) if p.present? && s.present? # If a custom field with text for the first reply is # available then use this one instead of the regular r = CustomField.find_by_name('helpdesk-first-reply') f = CustomField.find_by_name('helpdesk-email-footer') reply = p.nil? || r.nil? ? '' : p.custom_value_for(r).try(:value) footer = p.nil? || f.nil? ? '' : p.custom_value_for(f).try(:value) # add carbon copy ct = CustomField.find_by_name('copy-to') if carbon_copy.nil? carbon_copy = issue.custom_value_for(ct).try(:value) end # add any attachements if journal.present? && text.present? journal.details.each do |d| if d.property == 'attachment' a = Attachment.find(d.prop_key) begin attachments[a.filename] = File.binread(a.diskfile) rescue # ignore rescue end end end end if @message_id_object headers[:message_id] = "<#{self.class.message_id_for(@message_id_object)}>" end if @references_objects headers[:references] = @references_objects.collect {|o| "<#{self.class.references_for(o)}>"}.join(' ') end # create mail object to deliver mail = if text.present? || reply.present? # sending out the journal note to the support client # or the first reply message t = text.present? ? "#{text}\n\n#{footer}" : reply body = expand_macros(t, issue, journal) # precess reply-separator f = CustomField.find_by_name('helpdesk-reply-separator') reply_separator = issue.project.custom_value_for(f).try(:value) if !reply_separator.blank? body = reply_separator + "\n\n" + body end mail( :from => sender.present? && sender || Setting.mail_from, :reply_to => sender.present? && sender || Setting.mail_from, :to => recipient, :subject => subject, :body => body, :date => Time.zone.now, :cc => carbon_copy ) else # fallback to a regular notifications email with redmine view @issue = issue @journal = journal @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue) mail( :from => sender.present? && sender || Setting.mail_from, :reply_to => sender.present? && sender || Setting.mail_from, :to => recipient, :subject => subject, :date => Time.zone.now, :template_path => 'mailer', :template_name => 'issue_edit', :cc => carbon_copy ) end # return mail object to deliver it return mail end private # Appends a Redmine header field (name is prepended with 'X-Redmine-') def redmine_headers(h) h.each { |k,v| headers["X-Redmine-#{k}"] = v.to_s } end def self.token_for(object, rand=true) timestamp = object.send(object.respond_to?(:created_on) ? :created_on : :updated_on) hash = [ "redmine", "#{object.class.name.demodulize.underscore}-#{object.id}", timestamp.strftime("%Y%m%d%H%M%S") ] if rand hash << Redmine::Utils.random_hex(8) end host = Setting.mail_from.to_s.strip.gsub(%r{^.*@|>}, '') host = "#{::Socket.gethostname}.redmine" if host.empty? "#{hash.join('.')}@#{host}" end # Returns a Message-Id for the given object def self.message_id_for(object) token_for(object, true) end # Returns a uniq token for a given object referenced by all notifications # related to this object def self.references_for(object) token_for(object, false) end def message_id(object) @message_id_object = object end def references(object) @references_objects ||= [] @references_objects << object end end ================================================ FILE: lib/macro_expander.rb ================================================ module MacroExpander def expand_macros(string, issue, journal) e = Expander.new(string, issue, journal) e.expand end class Expander include Redmine::I18n def initialize(string, issue, journal) @string = string @issue = issue @journal = journal end def expand unless @issue.nil? expand_issue expand_project end expand_user unless @journal.nil? expand_base @string end private def expand_issue @string.gsub!("##issue-id##", @issue.id.to_s) @string.gsub!("##issue-subject##", @issue.subject) @string.gsub!("##issue-tracker##", @issue.tracker.name) @string.gsub!("##issue-status##", @issue.status.name) end def expand_project p = @issue.project @string.gsub!("##project-name##", p.name) end def expand_user u = @journal.user @string.gsub!("##user-name##", u.name) @string.gsub!("##user-firstname##", u.firstname) @string.gsub!("##user-lastname##", u.lastname) @string.gsub!("##user-mail##", u.mail) @string.gsub!("##user-login##", u.login) expand_user_cf(u) end def expand_user_cf(user) CustomField.where( "type = 'UserCustomField'").each do |user_cf| cf_name = user_cf.name.downcase.gsub(' ', '-') user_cf_cv = user.custom_value_for(user_cf).try(:value) @string.gsub!("##user-cf-#{cf_name}##", user_cf_cv) unless user_cf_cv.nil? end end def expand_base @string.gsub!("##time-now##", I18n.l(Time.zone.now)) end end end ================================================ FILE: lib/redmine_helpdesk/journal_patch.rb ================================================ module RedmineHelpdesk module JournalPatch def self.included(base) # :nodoc: base.send(:include, InstanceMethods) base.class_eval do alias_method :send_notification_without_helpdesk, :send_notification alias_method :send_notification, :send_notification_with_helpdesk end end module InstanceMethods # Overrides the send_notification method which # is only called on journal updates def send_notification_with_helpdesk if notify? && (Setting.notified_events.include?('issue_updated') || (Setting.notified_events.include?('issue_note_added') && notes.present?) || (Setting.notified_events.include?('issue_status_updated') && new_status.present?) || (Setting.notified_events.include?('issue_assigned_to_updated') && detail_for_attribute('assigned_to_id').present?) || (Setting.notified_events.include?('issue_priority_updated') && new_value_for('priority_id').present?) ) Mailer.deliver_issue_edit(self) end # do not send on private-notes if private_notes == true && send_to_owner == true self.send_to_owner = false self.save( validate: false ) end # sending email notifications to the supportclient # only if the send_to_owner checkbox was checked if send_to_owner == true && notes.length != 0 issue = self.journalized.reload owner_email = issue.custom_value_for( CustomField.find_by_name('owner-email') ).value HelpdeskMailer.email_to_supportclient( issue, { recipient: owner_email, journal: self, text: notes } ).deliver unless owner_email.blank? end end end # module InstanceMethods end # module JournalPatch end # module RedmineHelpdesk # Add module to Journal class Journal.send(:include, ::RedmineHelpdesk::JournalPatch) ================================================ FILE: lib/redmine_helpdesk/mail_handler_patch.rb ================================================ module RedmineHelpdesk module MailHandlerPatch def self.included(base) # :nodoc: base.send(:include, InstanceMethods) base.class_eval do alias_method :dispatch_to_default_without_helpdesk, :dispatch_to_default alias_method :dispatch_to_default, :dispatch_to_default_with_helpdesk # needed for reopening a closed issue alias_method :receive_issue_reply_without_helpdesk, :receive_issue_reply alias_method :receive_issue_reply, :receive_issue_reply_with_helpdesk end end module InstanceMethods private # Overrides the dispatch_to_default method to # set the owner-email of a new issue created by # an email request def dispatch_to_default_with_helpdesk issue = receive_issue issue.reload # prevent ActiveRecord::StaleObjectError roles = if issue.author.class == AnonymousUser Role.where(builtin: issue.author.id) else issue.author.roles_for_project(issue.project) end # add owner-email only if the author has assigned some role with # permission treat_user_as_supportclient enabled if issue.author.type.eql?("AnonymousUser") || roles.any? {|role| role.allowed_to?(:treat_user_as_supportclient) } sender_email = @email.from.first # any cc handling needed? custom_value = custom_field_value(issue.project,'cc-handling') if (!@email.cc.nil?) && (custom_value.value == '1') carbon_copy = @email[:cc].formatted.join(', ') custom_value = custom_field_value(issue,'copy-to') custom_value.value = carbon_copy custom_value.save( validate: false ) # skip validation! else carbon_copy = nil end issue.description = email_details + issue.description issue.save( validate: false ) # skip validation! custom_value = custom_field_value(issue,'owner-email') if custom_value.value.to_s.strip.empty? custom_value.value = sender_email custom_value.save( validate: false ) # skip validation! else # Email owner field was already set by some preprocess hooks. # So now we need to send message to another recepient. sender_email = custom_value.value.to_s.strip end # regular email sending to known users is done # on the first issue.save. So we need to send # the notification email to the supportclient # on our own. HelpdeskMailer.email_to_supportclient( issue, { recipient: sender_email, carbon_copy: carbon_copy } ).deliver end after_dispatch_to_default_hook issue return issue end # let other plugins the chance to override this # method to hook into dispatch_to_default def after_dispatch_to_default_hook(issue) end # Fix an issue with email.has_attachments? def add_attachments(obj) if !email.attachments.nil? && email.attachments.size > 0 email.attachments.each do |attachment| obj.attachments << Attachment.create( container: obj, file: attachment.decoded, filename: attachment.filename, author: user, content_type: attachment.mime_type ) end end end # Overrides the receive_issue_reply method def receive_issue_reply_with_helpdesk(issue_id, from_journal=nil) issue = Issue.find_by_id(issue_id) return unless issue # reopening a closed issues by email custom_value = custom_field_value(issue.project,'reopen-issues-with') if issue.closed? && custom_value.present? && custom_value.value.present? status_id = IssueStatus.where("name = ?", custom_value.value).try(:first).try(:id) unless status_id.nil? issue.status_id = status_id issue.save end end # call original method receive_issue_reply_without_helpdesk(issue_id, from_journal) # store email-details before each note last_journal = Journal.find(issue.last_journal_id) last_journal.notes = email_details + last_journal.notes last_journal.save return last_journal end def custom_field_value(issue,name) custom_field = CustomField.find_by_name(name) CustomValue.where( "customized_id = ? AND custom_field_id = ?", issue.id, custom_field.id ).first end def email_details details = "From: " + @email[:from].formatted.first + "\n" details << "To: " + @email[:to].formatted.join(', ') + "\n" if !@email.to.nil? details << "Cc: " + @email[:cc].formatted.join(', ') + "\n" if !@email.cc.nil? details << "Date: " + @email[:date].to_s + "\n" "
\n" + Mail::Encodings.unquote_and_convert_to(details, 'utf-8') + "\n\n" end end # module InstanceMethods end # module MailHandlerPatch end # module RedmineHelpdesk # Add module to MailHandler class MailHandler.send(:include, ::RedmineHelpdesk::MailHandlerPatch) ================================================ FILE: lib/redmine_helpdesk/mailer_patch.rb ================================================ module RedmineHelpdesk module MailerPatch def self.included(base) # :nodoc: base.send(:include, InstanceMethods) base.class_eval do alias_method :issue_edit_without_helpdesk, :issue_edit alias_method :issue_edit, :issue_edit_with_helpdesk end end module InstanceMethods # Overrides the issue_edit method which is only # be called on existing tickets. We will add the # owner-email to the recipients only if no email- # footer text is available. def issue_edit_with_helpdesk(user, journal) issue = journal.journalized redmine_headers 'Project' => issue.project.identifier, 'Issue-Id' => issue.id, 'Issue-Author' => issue.author.login, 'Issue-Tracker' => issue.tracker redmine_headers 'Issue-Assignee' => issue.assigned_to.login if issue.assigned_to message_id journal references issue @author = journal.user # process reply-separator f = CustomField.find_by_name('helpdesk-reply-separator') reply_separator = issue.project.custom_value_for(f).try(:value) if !reply_separator.blank? and !journal.notes.nil? journal.notes = journal.notes.gsub(/#{reply_separator}.*/m, '') journal.save(:validate => false) end # add owner-email to the recipients alternative_user = nil begin if journal.send_to_owner == true f = CustomField.find_by_name('helpdesk-email-footer') p = issue.project owner_email = issue.custom_value_for( CustomField.find_by_name('owner-email') ).value if !owner_email.blank? && !f.nil? && !p.nil? && p.custom_value_for(f).try(:value).blank? alternative_user = owner_email end end rescue Exception => e Rails.logger.error "Error while adding owner-email to recipients of email notification: \"#{e.message}\"." end # any cc handling needed? cc_users = nil begin # any cc handling needed? if alternative_user.present? custom_field = CustomField.find_by_name('cc-handling') custom_value = CustomValue.where( "customized_id = ? AND custom_field_id = ?", issue.project.id, custom_field.id ).first cc_users = custom_value.value.split(',').map(&:strip) if custom_value.value.present? end rescue Exception => e Rails.logger.error "Error while adding cc-users to recipients of email notification: \"#{e.message}\"." end s = "[#{issue.project.name} - #{issue.tracker.name} ##{issue.id}] " s += "(#{issue.status.name}) " if journal.new_value_for('status_id') && Setting.show_status_changes_in_mail_subject? s += issue.subject u = (alternative_user.present? ? alternative_user : user) @issue = issue @user = u @journal = journal @journal_details = journal.visible_details @issue_url = url_for(:controller => 'issues', :action => 'show', :id => issue, :anchor => "change-#{journal.id}") mail( :to => u, :cc => cc_users, :subject => s ) end end # module InstanceMethods end # module MailerPatch end # module RedmineHelpdesk # Add module to Mailer class Mailer.send(:include, ::RedmineHelpdesk::MailerPatch) ================================================ FILE: lib/tasks/local-db.rake ================================================ namespace :helpdesk do namespace :localdb do db_label = 'helpdesk-db' def get_env () db_name = 'redmine' db_host = 'localhost' db_user = 'root' db_adapter = ENV['DATABASE_ADAPTER'] case db_adapter when "mysql" env = "-e MYSQL_DATABASE=#{db_name} "\ "-e MYSQL_ALLOW_EMPTY_PASSWORD=yes " when "postgresql" env = "-e POSTGRES_DB=#{db_name} "\ "-e POSTGRES_USER=#{db_user} "\ when "postgresql_ext" env = "-e POSTGRES_DB=#{db_name} "\ "-e POSTGRES_USER=#{db_user}" else raise StandardError.new "Cannot start local db" end env end def get_port () db_adapter = ENV['DATABASE_ADAPTER'] case db_adapter when "mysql" port = 3306 when "postgresql" port = 5432 when "postgresql_ext" port = 5432 else raise StandardError.new "Cannot start local db" end port end def get_image () db_adapter = ENV['DATABASE_ADAPTER'] case db_adapter when "mysql" image = "mysql" when "postgresql" image = "postgres" when "postgresql_ext" image = "postgres" else raise StandardError.new "Cannot start local db" end image end task :start => :stop do env = get_env() port = get_port() image = get_image() cmd = "docker run -d --name #{db_label} "\ "--net=host "\ "#{env} "\ "#{image}" puts cmd system(cmd) end task :stop do system("docker stop #{db_label}") system("docker rm #{db_label}") end end end ================================================ FILE: lib/tasks/plugin_ci.rake ================================================ namespace :helpdesk do plugin_root = File.expand_path('../../../', __FILE__) coverage_dir = "#{plugin_root}/coverage" desc 'Runs :ci target from plugin scope in test/app' task :ext_ci do cd('test/app') do sh('bundle exec rake helpdesk:ci') end end desc 'Prepared and configures DB in Docker container' task :prepare_local => ['helpdesk:localdb:start', 'helpdesk:redmine:configure_db'] do Rake::Task['helpdesk:install'].invoke() end desc 'Runs bundle install from plugin scop in test/app' task :install do cd('test/app') do sh('bundle install --without production development rmagick') end end desc 'Runs migrate from plugin scope in test/app' task :migrate do cd('test/app') do sh('bundle exec rake generate_secret_token') sh('bundle exec rake db:migrate') end end desc 'Prepares and runs the test suite.' task :ci => ['redmine:plugins:migrate', 'helpdesk:test'] desc 'Runs Redmine plugin tests with single CodeClimate TestReporter invocation.' task :test => [ 'helpdesk:test:clear_coverage_data', 'helpdesk:test:run' ] namespace :test do task :run do Rake::Task['redmine:plugins:test:units'].invoke Rake::Task['redmine:plugins:test:functionals'].invoke # require "simplecov" # require "codeclimate-test-reporter" # SimpleCov.coverage_dir "plugins/coverage" # CodeClimate::TestReporter.configure do |config| # config.git_dir = "plugins/#{ENV['GITHUB_PROJECT']}" # end # CodeClimate::TestReporter::Formatter.new.format(SimpleCov.result) end task :clear_coverage_data do rm_rf coverage_dir end end end ================================================ FILE: lib/tasks/redmine.rake ================================================ require 'fileutils' namespace :helpdesk do namespace :redmine do plugin_root = File.expand_path('../../../', __FILE__) redmine_path = "#{plugin_root}/test/app" tmp_dir = "#{plugin_root}/tmp" redmine_source_url = "http://www.redmine.org/releases" redmine_version = ENV['REDMINE_VERSION'] || "3.2.0" redmine_name = "redmine-#{redmine_version}" redmine_package = "#{redmine_name}.tar.gz" redmine_url = "#{redmine_source_url}/#{redmine_package}" version = redmine_version.split(".") major = version[0] minor = version[1] patch = version[2] task :install => [ :remove, :print_env, :download_tarball, :extract_tarball, :configure_db, :link_plugin, :print_result ] task :print_env do if ENV['DATABASE_ADAPTER'].nil? raise StandardError.new "Database adapter not defined" end puts "" puts "######################" puts "REDMINE INSTALLATION SCRIPT" puts "" puts "REDMINE_VERSION : #{redmine_version}" puts "REDMINE_URL : #{redmine_url}" puts "DATABASE ADAPTER : #{ENV['DATABASE_ADAPTER']}" puts "" end task :remove do rm_rf redmine_path end task :download_tarball do mkdir_p tmp_dir Dir.chdir(tmp_dir) do puts "Downloading tarball" if !system("wget #{redmine_url}") raise StandardError.new "download failed" end end end task :extract_tarball do Dir.chdir(tmp_dir) do puts "Extracting tarball" if !system("tar xf #{redmine_package}") raise StandardError.new "download failed" end mv "#{redmine_name}", "#{redmine_path}", :force => true rm_rf tmp_dir end end task :configure_db do puts "Configuring database" db_adapter = ENV['DATABASE_ADAPTER'] case db_adapter when "mysql" a = "mysql" when "postgresql" a = "postgres" when "postgresql_ext" a = "postgres_ext" when "sqlite" a = "sqlite" else raise StandardError.new "Error copying config files" end cp "#{plugin_root}/test/confs/database_#{a}.yml", "#{redmine_path}/config/database.yml", :verbose => true end task :print_result do puts "Dummy Redmine dir listing" Dir["#{redmine_path}/*"].each do |f| puts f.sub("#{redmine_path}", "") end puts "" puts "Dummy Redmine plugin dir listing" Dir["#{redmine_path}/plugins/*"].each do |f| puts f.sub("#{redmine_path}/plugins", "") end puts "" end task :link_plugin do plugin_dir = "#{redmine_path}/plugins/redmine_helpdesk" ln_sf plugin_root, plugin_dir end end end ================================================ FILE: test/confs/database_mysql.yml ================================================ ## MySQL configuration example ## Data come from environment variables so the test suite can be run ## on Travis or Jenkins (see https://github.com/codevise/jenkins-mysql-job-databases-plugin) production: adapter: mysql2 database: <%= ENV['MYSQL_DATABASE'] || 'redmine' %> host: <%= ENV['MYSQL_HOST'] || '127.0.0.1' %> port: <%= ENV['MYSQL_PORT'] || '3306' %> username: <%= ENV['MYSQL_USER'] || 'root' %> password: <%= ENV['MYSQL_PASSWORD'] %> encoding: utf8 development: adapter: mysql2 database: <%= ENV['MYSQL_DATABASE'] || 'redmine' %> host: <%= ENV['MYSQL_HOST'] || '127.0.0.1' %> port: <%= ENV['MYSQL_PORT'] || '3306' %> username: <%= ENV['MYSQL_USER'] || 'root' %> password: <%= ENV['MYSQL_PASSWORD'] %> encoding: utf8 test: adapter: mysql2 database: <%= ENV['MYSQL_DATABASE'] || 'redmine' %> host: <%= ENV['MYSQL_HOST'] || '127.0.0.1' %> port: <%= ENV['MYSQL_PORT'] || '3306' %> username: <%= ENV['MYSQL_USER'] || 'root' %> password: <%= ENV['MYSQL_PASSWORD'] %> encoding: utf8 ================================================ FILE: test/confs/database_postgres.yml ================================================ ## PostgreSQL configuration example ## Data come from environment variables so the test suite can be run ## on Travis or Jenkins (see https://github.com/lmlima/jenkins-postgresql-job-databases-plugin) production: adapter: postgresql database: <%= ENV['POSTGRES_DATABASE'] || 'redmine' %> username: <%= ENV['POSTGRES_USER'] || 'root' %> encoding: utf8 development: adapter: postgresql database: <%= ENV['POSTGRES_DATABASE'] || 'redmine' %> username: <%= ENV['POSTGRES_USER'] || 'root' %> encoding: utf8 test: adapter: postgresql database: <%= ENV['POSTGRES_DATABASE'] || 'redmine' %> username: <%= ENV['POSTGRES_USER'] || 'root' %> encoding: utf8 ================================================ FILE: test/confs/database_postgres_ext.yml ================================================ ## PostgreSQL configuration example ## Data come from environment variables so the test suite can be run ## on Travis or Jenkins (see https://github.com/lmlima/jenkins-postgresql-job-databases-plugin) production: adapter: postgresql database: <%= ENV['POSTGRES_DATABASE'] || 'redmine' %> host: <%= ENV['POSTGRES_HOST'] || 'localhost' %> username: <%= ENV['POSTGRES_USER'] || 'root' %> encoding: utf8 development: adapter: postgresql database: <%= ENV['POSTGRES_DATABASE'] || 'redmine' %> host: <%= ENV['POSTGRES_HOST'] || 'localhost' %> username: <%= ENV['POSTGRES_USER'] || 'root' %> encoding: utf8 test: adapter: postgresql database: <%= ENV['POSTGRES_DATABASE'] || 'redmine' %> host: <%= ENV['POSTGRES_HOST'] || 'localhost' %> username: <%= ENV['POSTGRES_USER'] || 'root' %> encoding: utf8 ================================================ FILE: test/confs/database_sqlite.yml ================================================ ## SQLite3 configuration example production: adapter: sqlite3 database: db/redmine.sqlite3 development: adapter: sqlite3 database: db/redmine.dev.sqlite3 test: adapter: sqlite3 database: db/redmine.test.sqlite3 ================================================ FILE: test/fixtures/2.6/attachments.yml ================================================ --- attachments_001: created_on: 2006-07-19 21:07:27 +02:00 container_type: Issue container_id: 1 downloads: 0 disk_filename: 060719210727_source.rb disk_directory: "2006/07" digest: b91e08d0cf966d5c6ff411bd8c4cc3a2 id: 1 filesize: 153 filename: source.rb author_id: 1 description: This is a Ruby source file content_type: application/x-ruby ================================================ FILE: test/fixtures/2.6/custom_fields.yml ================================================ --- custom_fields_001: name: owner-email regexp: "" type: IssueCustomField possible_values: "" id: 1 is_required: false field_format: string default_value: "" editable: true visible: true position: 1 custom_fields_002: name: helpdesk-first-reply min_length: 1 regexp: "" visible: false type: ProjectCustomField max_length: 100 possible_values: "" id: 2 is_required: false field_format: text default_value: "" editable: true position: 1 custom_fields_003: name: helpdesk-email-footer min_length: 1 regexp: "" visible: false type: ProjectCustomField max_length: 100 possible_values: "" id: 3 is_required: false field_format: text default_value: "" editable: true position: 1 custom_fields_004: name: helpdesk-sender-email regexp: "" type: ProjectCustomField possible_values: "" id: 4 is_required: false field_format: string default_value: false editable: true visible: true position: 1 custom_fields_005: name: helpdesk-send-to-owner-default regexp: "" type: ProjectCustomField possible_values: "" id: 5 is_required: false field_format: bool default_value: false editable: true visible: false position: 1 custom_fields_006: name: helpdesk-subject min_length: 1 regexp: "" visible: false type: ProjectCustomField max_length: 100 possible_values: "" id: 6 is_required: false field_format: text default_value: "" editable: true position: 1 custom_fields_007: name: helpdesk-send-first-reply visible: false type: ProjectCustomField id: 7 is_required: false field_format: boolean default_value: true editable: true position: 1 custom_fields_008: name: title regexp: "" is_for_all: false type: UserCustomField possible_values: "" id: 8 is_required: false field_format: string default_value: "" editable: true position: 1 custom_fields_009: name: motto regexp: "" is_for_all: false type: UserCustomField possible_values: "" id: 9 is_required: false field_format: string default_value: "" editable: true position: 2 custom_fields_010: name: copy-to regexp: "" type: IssueCustomField possible_values: "" id: 10 is_required: false field_format: string default_value: "" editable: true visible: true position: 1 custom_fields_011: name: cc-handling visible: false type: ProjectCustomField id: 11 is_required: false field_format: bool default_value: false editable: true position: 1 ================================================ FILE: test/fixtures/2.6/custom_fields_projects.yml ================================================ --- custom_fields_projects_001: custom_field_id: 1 project_id: 1 custom_fields_projects_002: custom_field_id: 1 project_id: 2 custom_fields_projects_003: custom_field_id: 10 project_id: 1 custom_fields_projects_004: custom_field_id: 10 project_id: 2 custom_fields_projects_005: custom_field_id: 1 project_id: 4 custom_fields_projects_006: custom_field_id: 10 project_id: 4 ================================================ FILE: test/fixtures/2.6/custom_fields_trackers.yml ================================================ --- custom_fields_trackers_001: custom_field_id: 1 tracker_id: 1 custom_fields_trackers_002: custom_field_id: 1 tracker_id: 2 custom_fields_trackers_003: custom_field_id: 1 tracker_id: 3 custom_fields_trackers_004: custom_field_id: 1 tracker_id: 4 custom_fields_trackers_005: custom_field_id: 10 tracker_id: 1 custom_fields_trackers_006: custom_field_id: 10 tracker_id: 2 custom_fields_trackers_007: custom_field_id: 10 tracker_id: 3 custom_fields_trackers_008: custom_field_id: 10 tracker_id: 4 ================================================ FILE: test/fixtures/2.6/custom_values.yml ================================================ --- custom_values_001: customized_type: Project custom_field_id: 2 customized_id: 1 id: 1 value: "first reply" custom_values_002: customized_type: Project custom_field_id: 3 customized_id: 1 id: 2 value: "email footer" custom_values_003: customized_type: Project custom_field_id: 4 customized_id: 1 id: 3 value: reply@example.com custom_values_004: customized_type: Project custom_field_id: 5 customized_id: 1 id: 4 value: 0 custom_values_005: customized_type: Project custom_field_id: 11 customized_id: 1 id: 5 value: 1 custom_values_006: customized_type: Project custom_field_id: 2 customized_id: 2 id: 6 value: first reply custom_values_007: customized_type: Project custom_field_id: 3 customized_id: 2 id: 7 value: email footer custom_values_008: customized_type: Project custom_field_id: 4 customized_id: 2 id: 8 value: reply@example.com custom_values_009: customized_type: Project custom_field_id: 5 customized_id: 2 id: 9 value: 0 custom_values_010: customized_type: Project custom_field_id: 11 customized_id: 2 id: 10 value: 1 custom_values_011: customized_type: Issue custom_field_id: 1 customized_id: 1 id: 11 value: owner@example.com custom_values_012: customized_type: Project custom_field_id: 2 customized_id: 4 id: 12 value: first reply custom_values_013: customized_type: Project custom_field_id: 3 customized_id: 4 id: 13 value: email footer custom_values_014: customized_type: Project custom_field_id: 4 customized_id: 4 id: 14 value: reply@example.com custom_values_015: customized_type: Project custom_field_id: 5 customized_id: 4 id: 15 value: 0 custom_values_016: customized_type: Project custom_field_id: 11 customized_id: 4 id: 16 value: 0 ================================================ FILE: test/fixtures/2.6/enabled_modules.yml ================================================ --- enabled_modules_001: name: issue_tracking project_id: 1 id: 1 enabled_modules_002: name: time_tracking project_id: 1 id: 2 enabled_modules_003: name: files project_id: 1 id: 3 enabled_modules_004: name: issue_tracking project_id: 2 id: 4 enabled_modules_005: name: time_tracking project_id: 2 id: 5 enabled_modules_006: name: files project_id: 2 id: 6 enabled_modules_007: name: issue_tracking project_id: 4 id: 7 enabled_modules_008: name: time_tracking project_id: 4 id: 8 enabled_modules_009: name: files project_id: 4 id: 9 ================================================ FILE: test/fixtures/2.6/enumerations.yml ================================================ --- enumerations_001: name: Low id: 1 type: IssuePriority active: true position: 1 position_name: lowest enumerations_002: name: Normal id: 2 type: IssuePriority is_default: true active: true position: 2 position_name: default enumerations_003: name: High id: 3 type: IssuePriority active: true position: 3 position_name: high3 enumerations_004: name: Urgent id: 4 type: IssuePriority active: true position: 4 position_name: high2 enumerations_005: name: Immediate id: 5 type: IssuePriority active: true position: 5 position_name: highest ================================================ FILE: test/fixtures/2.6/issue_statuses.yml ================================================ --- issue_statuses_001: id: 1 name: New is_default: true is_closed: false position: 1 issue_statuses_002: id: 2 name: Assigned is_default: false is_closed: false position: 2 issue_statuses_003: id: 3 name: Resolved is_default: false is_closed: false position: 3 issue_statuses_004: name: Feedback id: 4 is_default: false is_closed: false position: 4 issue_statuses_005: id: 5 name: Closed is_default: false is_closed: true position: 5 issue_statuses_006: id: 6 name: Rejected is_default: false is_closed: true position: 6 ================================================ FILE: test/fixtures/2.6/issues.yml ================================================ --- issues_001: created_on: 2015-03-05 21:41:21 +02:00 project_id: 1 updated_on: 2015-03-05 22:05:50 +02:00 priority_id: 2 subject: Can't print recipes id: 1 fixed_version_id: category_id: 1 description: Unable to print recipes tracker_id: 1 assigned_to_id: 1 author_id: 1 status_id: 1 start_date: due_date: root_id: 1 lft: 1 rgt: 2 lock_version: 3 issues_002: created_on: 2006-07-19 21:04:21 +02:00 project_id: 2 updated_on: 2006-07-19 21:09:50 +02:00 priority_id: 2 subject: Add ingredients categories id: 2 fixed_version_id: category_id: description: Ingredients of the recipe should be classified by categories tracker_id: 2 assigned_to_id: author_id: 1 status_id: 2 start_date: due_date: root_id: 2 lft: 1 rgt: 2 lock_version: 3 ================================================ FILE: test/fixtures/2.6/journal_details.yml ================================================ --- journal_details_001: old_value: property: attachment id: 1 value: 060719210727_source.rb prop_key: 1 journal_id: 3 ================================================ FILE: test/fixtures/2.6/journals.yml ================================================ --- journals_001: created_on: <%= 2.days.ago.to_date.to_s(:db) %> notes: "Journal notes" id: 1 journalized_type: Issue user_id: 1 journalized_id: 1 journals_002: created_on: <%= 1.days.ago.to_date.to_s(:db) %> notes: "Some notes." id: 2 journalized_type: Issue user_id: 1 journalized_id: 1 journals_003: created_on: <%= 1.days.ago.to_date.to_s(:db) %> notes: "Some notes with an attachment." id: 3 journalized_type: Issue user_id: 1 journalized_id: 1 journals_004: id: 4 created_on: <%= 1.days.ago.to_date.to_s(:db) %> notes: "A comment on an issue." user_id: 1 journalized_type: Issue journalized_id: 2 ================================================ FILE: test/fixtures/2.6/member_roles.yml ================================================ --- member_roles_001: id: 1 role_id: 1 member_id: 1 member_roles_002: id: 2 role_id: 1 member_id: 2 member_roles_003: id: 3 role_id: 1 member_id: 3 member_roles_004: id: 4 role_id: 6 member_id: 4 ================================================ FILE: test/fixtures/2.6/members.yml ================================================ --- members_001: created_on: 2006-07-19 19:35:33 +02:00 project_id: 1 id: 1 user_id: 1 mail_notification: true members_002: created_on: 2006-07-19 19:35:36 +02:00 project_id: 2 id: 2 user_id: 1 mail_notification: true members_003: created_on: 2006-07-19 19:35:36 +02:00 project_id: 3 id: 3 user_id: 1 mail_notification: true members_004: created_on: 2006-07-19 19:35:36 +02:00 project_id: 2 id: 4 user_id: 2 mail_notification: false members_005: created_on: 2006-07-19 19:35:36 +02:00 project_id: 4 id: 5 user_id: 1 mail_notification: true ================================================ FILE: test/fixtures/2.6/projects.yml ================================================ --- projects_001: created_on: 2015-03-05 19:13:59 +02:00 name: Helpdesk Project 1 updated_on: 2015-03-05 22:53:01 +02:00 id: 1 description: First helpdesk project homepage: "" is_public: true identifier: helpdesk_project_1 parent_id: lft: 1 rgt: 2 projects_002: created_on: 2015-03-05 19:14:19 +02:00 name: Helpdesk Project 2 updated_on: 2015-03-05 19:14:19 +02:00 id: 2 description: Second helpdesk project homepage: "" is_public: false identifier: helpdesk_project_2 parent_id: lft: 3 rgt: 4 projects_003: created_on: 2015-03-05 19:15:21 +02:00 name: Irrelevant Project updated_on: 2015-03-05 19:18:12 +02:00 id: 3 description: Project that has no helpdesk features homepage: "" is_public: true identifier: irrelevant_project parent_id: lft: 5 rgt: 6 projects_004: created_on: 2015-03-05 19:14:19 +02:00 name: Helpdesk Project 4 updated_on: 2015-03-05 19:14:19 +02:00 id: 4 description: Disabled copy-to helpdesk project homepage: "" is_public: true identifier: helpdesk_project_4 parent_id: lft: 6 rgt: 7 ================================================ FILE: test/fixtures/2.6/projects_trackers.yml ================================================ --- projects_trackers_001: project_id: 1 tracker_id: 1 projects_trackers_002: project_id: 1 tracker_id: 2 projects_trackers_003: project_id: 1 tracker_id: 3 projects_trackers_004: project_id: 2 tracker_id: 1 projects_trackers_005: project_id: 2 tracker_id: 2 projects_trackers_006: project_id: 2 tracker_id: 3 projects_trackers_007: project_id: 3 tracker_id: 1 projects_trackers_008: project_id: 3 tracker_id: 2 projects_trackers_009: project_id: 3 tracker_id: 3 projects_trackers_010: project_id: 4 tracker_id: 1 projects_trackers_011: project_id: 4 tracker_id: 2 projects_trackers_012: project_id: 4 tracker_id: 3 ================================================ FILE: test/fixtures/2.6/roles.yml ================================================ --- roles_001: name: Manager id: 1 builtin: 0 issues_visibility: all permissions: | --- - :add_project - :edit_project - :close_project - :select_project_modules - :manage_members - :manage_versions - :manage_categories - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :manage_subtasks - :add_issue_notes - :move_issues - :delete_issues - :view_issue_watchers - :add_issue_watchers - :set_issues_private - :set_notes_private - :view_private_notes - :delete_issue_watchers - :manage_public_queries - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :edit_time_entries - :delete_time_entries - :manage_news - :comment_news - :view_documents - :add_documents - :edit_documents - :delete_documents - :view_wiki_pages - :export_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :delete_wiki_pages_attachments - :protect_wiki_pages - :delete_wiki_pages - :rename_wiki_pages - :add_messages - :edit_messages - :delete_messages - :manage_boards - :view_files - :manage_files - :browse_repository - :manage_repository - :view_changesets - :manage_related_issues - :manage_project_activities position: 1 roles_002: name: Developer id: 2 builtin: 0 issues_visibility: default permissions: | --- - :edit_project - :manage_members - :manage_versions - :manage_categories - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :manage_subtasks - :add_issue_notes - :move_issues - :delete_issues - :view_issue_watchers - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :edit_own_time_entries - :manage_news - :comment_news - :view_documents - :add_documents - :edit_documents - :delete_documents - :view_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :protect_wiki_pages - :delete_wiki_pages - :add_messages - :edit_own_messages - :delete_own_messages - :manage_boards - :view_files - :manage_files - :browse_repository - :view_changesets position: 2 roles_003: name: Reporter id: 3 builtin: 0 issues_visibility: default permissions: | --- - :edit_project - :manage_members - :manage_versions - :manage_categories - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :add_issue_notes - :move_issues - :view_issue_watchers - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :manage_news - :comment_news - :view_documents - :add_documents - :edit_documents - :delete_documents - :view_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :delete_wiki_pages - :add_messages - :manage_boards - :view_files - :manage_files - :browse_repository - :view_changesets position: 3 roles_004: name: Non member id: 4 builtin: 1 issues_visibility: default permissions: | --- - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :add_issue_notes - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :comment_news - :view_documents - :view_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :add_messages - :view_files - :manage_files - :browse_repository - :view_changesets position: 4 roles_005: name: Anonymous id: 5 builtin: 2 issues_visibility: default permissions: | --- - :treat_user_as_supportclient - :view_issues - :add_issue_notes - :view_gantt - :view_calendar - :view_time_entries - :view_documents - :view_wiki_pages - :view_wiki_edits - :view_files - :browse_repository - :view_changesets position: 5 roles_006: name: SupportClient id: 6 builtin: 0 issues_visibility: default permissions: | --- - :treat_user_as_supportclient - :add_issues - :add_issue_notes position: 6 ================================================ FILE: test/fixtures/2.6/trackers.yml ================================================ --- trackers_001: name: Bug id: 1 is_in_chlog: true position: 1 trackers_002: name: Feature request id: 2 is_in_chlog: true position: 2 trackers_003: name: Support request id: 3 is_in_chlog: false position: 3 ================================================ FILE: test/fixtures/2.6/users.yml ================================================ --- users_001: created_on: 2015-03-05 19:34:07 +02:00 status: 1 last_login_on: language: en # password = foo salt: 3126f764c3c5ac61cbfc103f25f934cf hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b updated_on: 2015-03-05 19:34:07 +02:00 admin: true mail: rhill@somenet.foo lastname: Hill firstname: Robert id: 1 auth_source_id: mail_notification: all login: normaluser type: User users_002: created_on: 2015-03-05 19:33:19 +02:00 status: 1 last_login_on: language: en # password = foo salt: 7599f9963ec07b5a3b55b354407120c0 hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed updated_on: 2015-03-05 19:33:19 +02:00 admin: false mail: dlopper@somenet.foo lastname: Lopper firstname: Dave id: 2 auth_source_id: mail_notification: all login: supportclient type: User users_003: id: 3 created_on: 2006-07-19 19:33:19 +02:00 status: 0 last_login_on: language: '' hashed_password: 1 updated_on: 2006-07-19 19:33:19 +02:00 admin: false lastname: Anonymous firstname: '' auth_source_id: mail_notification: only_my_events login: '' type: AnonymousUser ================================================ FILE: test/fixtures/3.0/attachments.yml ================================================ --- attachments_001: created_on: 2006-07-19 21:07:27 +02:00 container_type: Issue container_id: 1 downloads: 0 disk_filename: 060719210727_source.rb disk_directory: "2006/07" digest: b91e08d0cf966d5c6ff411bd8c4cc3a2 id: 1 filesize: 153 filename: source.rb author_id: 1 description: This is a Ruby source file content_type: application/x-ruby ================================================ FILE: test/fixtures/3.0/custom_fields.yml ================================================ --- custom_fields_001: name: owner-email regexp: "" type: IssueCustomField possible_values: "" id: 1 is_required: false field_format: string default_value: "" editable: true visible: true position: 1 custom_fields_002: name: helpdesk-first-reply min_length: 1 regexp: "" visible: false type: ProjectCustomField max_length: 100 possible_values: "" id: 2 is_required: false field_format: text default_value: "" editable: true position: 1 custom_fields_003: name: helpdesk-email-footer min_length: 1 regexp: "" visible: false type: ProjectCustomField max_length: 100 possible_values: "" id: 3 is_required: false field_format: text default_value: "" editable: true position: 1 custom_fields_004: name: helpdesk-sender-email regexp: "" type: ProjectCustomField possible_values: "" id: 4 is_required: false field_format: string default_value: false editable: true visible: true position: 1 custom_fields_005: name: helpdesk-send-to-owner-default regexp: "" type: ProjectCustomField possible_values: "" id: 5 is_required: false field_format: bool default_value: false editable: true visible: false position: 1 custom_fields_006: name: helpdesk-subject min_length: 1 regexp: "" visible: false type: ProjectCustomField max_length: 100 possible_values: "" id: 6 is_required: false field_format: text default_value: "" editable: true position: 1 custom_fields_007: name: helpdesk-send-first-reply visible: false type: ProjectCustomField id: 7 is_required: false field_format: boolean default_value: true editable: true position: 1 custom_fields_008: name: title regexp: "" is_for_all: false type: UserCustomField possible_values: "" id: 8 is_required: false field_format: string default_value: "" editable: true position: 1 custom_fields_009: name: motto regexp: "" is_for_all: false type: UserCustomField possible_values: "" id: 9 is_required: false field_format: string default_value: "" editable: true position: 2 custom_fields_010: name: copy-to regexp: "" type: IssueCustomField possible_values: "" id: 10 is_required: false field_format: string default_value: "" editable: true visible: true position: 1 custom_fields_011: name: cc-handling visible: false type: ProjectCustomField id: 11 is_required: false field_format: bool default_value: false editable: true position: 1 ================================================ FILE: test/fixtures/3.0/custom_fields_projects.yml ================================================ --- custom_fields_projects_001: custom_field_id: 1 project_id: 1 custom_fields_projects_002: custom_field_id: 1 project_id: 2 custom_fields_projects_003: custom_field_id: 10 project_id: 1 custom_fields_projects_004: custom_field_id: 10 project_id: 2 custom_fields_projects_005: custom_field_id: 1 project_id: 4 custom_fields_projects_006: custom_field_id: 10 project_id: 4 ================================================ FILE: test/fixtures/3.0/custom_fields_trackers.yml ================================================ --- custom_fields_trackers_001: custom_field_id: 1 tracker_id: 1 custom_fields_trackers_002: custom_field_id: 1 tracker_id: 2 custom_fields_trackers_003: custom_field_id: 1 tracker_id: 3 custom_fields_trackers_004: custom_field_id: 1 tracker_id: 4 custom_fields_trackers_005: custom_field_id: 10 tracker_id: 1 custom_fields_trackers_006: custom_field_id: 10 tracker_id: 2 custom_fields_trackers_007: custom_field_id: 10 tracker_id: 3 custom_fields_trackers_008: custom_field_id: 10 tracker_id: 4 ================================================ FILE: test/fixtures/3.0/custom_values.yml ================================================ --- custom_values_001: customized_type: Project custom_field_id: 2 customized_id: 1 id: 1 value: "first reply" custom_values_002: customized_type: Project custom_field_id: 3 customized_id: 1 id: 2 value: "email footer" custom_values_003: customized_type: Project custom_field_id: 4 customized_id: 1 id: 3 value: reply@example.com custom_values_004: customized_type: Project custom_field_id: 5 customized_id: 1 id: 4 value: 0 custom_values_005: customized_type: Project custom_field_id: 11 customized_id: 1 id: 5 value: 1 custom_values_006: customized_type: Project custom_field_id: 2 customized_id: 2 id: 6 value: first reply custom_values_007: customized_type: Project custom_field_id: 3 customized_id: 2 id: 7 value: email footer custom_values_008: customized_type: Project custom_field_id: 4 customized_id: 2 id: 8 value: reply@example.com custom_values_009: customized_type: Project custom_field_id: 5 customized_id: 2 id: 9 value: 0 custom_values_010: customized_type: Project custom_field_id: 11 customized_id: 2 id: 10 value: 1 custom_values_011: customized_type: Issue custom_field_id: 1 customized_id: 1 id: 11 value: owner@example.com custom_values_012: customized_type: Project custom_field_id: 2 customized_id: 4 id: 12 value: first reply custom_values_013: customized_type: Project custom_field_id: 3 customized_id: 4 id: 13 value: email footer custom_values_014: customized_type: Project custom_field_id: 4 customized_id: 4 id: 14 value: reply@example.com custom_values_015: customized_type: Project custom_field_id: 5 customized_id: 4 id: 15 value: 0 custom_values_016: customized_type: Project custom_field_id: 11 customized_id: 4 id: 16 value: 0 ================================================ FILE: test/fixtures/3.0/email_addresses.yml ================================================ --- email_address_001: id: 1 user_id: 1 address: rhill@somenet.foo is_default: true created_on: 2006-07-19 19:34:07 +02:00 updated_on: 2006-07-19 19:34:07 +02:00 email_address_002: id: 2 user_id: 2 address: dlopper@somenet.foo is_default: true created_on: 2006-07-19 19:34:07 +02:00 updated_on: 2006-07-19 19:34:07 +02:00 ================================================ FILE: test/fixtures/3.0/enabled_modules.yml ================================================ --- enabled_modules_001: name: issue_tracking project_id: 1 id: 1 enabled_modules_002: name: time_tracking project_id: 1 id: 2 enabled_modules_003: name: files project_id: 1 id: 3 enabled_modules_004: name: issue_tracking project_id: 2 id: 4 enabled_modules_005: name: time_tracking project_id: 2 id: 5 enabled_modules_006: name: files project_id: 2 id: 6 enabled_modules_007: name: issue_tracking project_id: 4 id: 7 enabled_modules_008: name: time_tracking project_id: 4 id: 8 enabled_modules_009: name: files project_id: 4 id: 9 ================================================ FILE: test/fixtures/3.0/enumerations.yml ================================================ --- enumerations_001: name: Low id: 1 type: IssuePriority active: true position: 1 position_name: lowest enumerations_002: name: Normal id: 2 type: IssuePriority is_default: true active: true position: 2 position_name: default enumerations_003: name: High id: 3 type: IssuePriority active: true position: 3 position_name: high3 enumerations_004: name: Urgent id: 4 type: IssuePriority active: true position: 4 position_name: high2 enumerations_005: name: Immediate id: 5 type: IssuePriority active: true position: 5 position_name: highest ================================================ FILE: test/fixtures/3.0/issue_statuses.yml ================================================ --- issue_statuses_001: id: 1 name: New is_closed: false position: 1 issue_statuses_002: id: 2 name: Assigned is_closed: false position: 2 issue_statuses_003: id: 3 name: Resolved is_closed: false position: 3 issue_statuses_004: name: Feedback id: 4 is_closed: false position: 4 issue_statuses_005: id: 5 name: Closed is_closed: true position: 5 issue_statuses_006: id: 6 name: Rejected is_closed: true position: 6 ================================================ FILE: test/fixtures/3.0/issues.yml ================================================ --- issues_001: created_on: 2015-03-05 21:41:21 +02:00 project_id: 1 updated_on: 2015-03-05 22:05:50 +02:00 priority_id: 2 subject: Can't print recipes id: 1 fixed_version_id: category_id: 1 description: Unable to print recipes tracker_id: 1 assigned_to_id: 1 author_id: 1 status_id: 1 start_date: due_date: root_id: 1 lft: 1 rgt: 2 lock_version: 3 issues_002: created_on: 2006-07-19 21:04:21 +02:00 project_id: 2 updated_on: 2006-07-19 21:09:50 +02:00 priority_id: 2 subject: Add ingredients categories id: 2 fixed_version_id: category_id: description: Ingredients of the recipe should be classified by categories tracker_id: 2 assigned_to_id: author_id: 1 status_id: 2 start_date: due_date: root_id: 2 lft: 1 rgt: 2 lock_version: 3 ================================================ FILE: test/fixtures/3.0/journal_details.yml ================================================ --- journal_details_001: old_value: property: attachment id: 1 value: 060719210727_source.rb prop_key: 1 journal_id: 3 ================================================ FILE: test/fixtures/3.0/journals.yml ================================================ --- journals_001: created_on: <%= 2.days.ago.to_date.to_s(:db) %> notes: "Journal notes" id: 1 journalized_type: Issue user_id: 1 journalized_id: 1 journals_002: created_on: <%= 1.days.ago.to_date.to_s(:db) %> notes: "Some notes." id: 2 journalized_type: Issue user_id: 1 journalized_id: 1 journals_003: created_on: <%= 1.days.ago.to_date.to_s(:db) %> notes: "Some notes with an attachment." id: 3 journalized_type: Issue user_id: 1 journalized_id: 1 journals_004: id: 4 created_on: <%= 1.days.ago.to_date.to_s(:db) %> notes: "A comment on an issue." user_id: 1 journalized_type: Issue journalized_id: 2 ================================================ FILE: test/fixtures/3.0/member_roles.yml ================================================ --- member_roles_001: id: 1 role_id: 1 member_id: 1 member_roles_002: id: 2 role_id: 1 member_id: 2 member_roles_003: id: 3 role_id: 1 member_id: 3 member_roles_004: id: 4 role_id: 6 member_id: 4 ================================================ FILE: test/fixtures/3.0/members.yml ================================================ --- members_001: created_on: 2006-07-19 19:35:33 +02:00 project_id: 1 id: 1 user_id: 1 mail_notification: true members_002: created_on: 2006-07-19 19:35:36 +02:00 project_id: 2 id: 2 user_id: 1 mail_notification: true members_003: created_on: 2006-07-19 19:35:36 +02:00 project_id: 3 id: 3 user_id: 1 mail_notification: true members_004: created_on: 2006-07-19 19:35:36 +02:00 project_id: 2 id: 4 user_id: 2 mail_notification: false members_005: created_on: 2006-07-19 19:35:36 +02:00 project_id: 4 id: 5 user_id: 1 mail_notification: true ================================================ FILE: test/fixtures/3.0/projects.yml ================================================ --- projects_001: created_on: 2015-03-05 19:13:59 +02:00 name: Helpdesk Project 1 updated_on: 2015-03-05 22:53:01 +02:00 id: 1 description: First helpdesk project homepage: "" is_public: true identifier: helpdesk_project_1 parent_id: lft: 1 rgt: 2 projects_002: created_on: 2015-03-05 19:14:19 +02:00 name: Helpdesk Project 2 updated_on: 2015-03-05 19:14:19 +02:00 id: 2 description: Second helpdesk project homepage: "" is_public: false identifier: helpdesk_project_2 parent_id: lft: 3 rgt: 4 projects_003: created_on: 2015-03-05 19:15:21 +02:00 name: Irrelevant Project updated_on: 2015-03-05 19:18:12 +02:00 id: 3 description: Project that has no helpdesk features homepage: "" is_public: true identifier: irrelevant_project parent_id: lft: 5 rgt: 6 projects_004: created_on: 2015-03-05 19:14:19 +02:00 name: Helpdesk Project 4 updated_on: 2015-03-05 19:14:19 +02:00 id: 4 description: Disabled copy-to helpdesk project homepage: "" is_public: true identifier: helpdesk_project_4 parent_id: lft: 6 rgt: 7 ================================================ FILE: test/fixtures/3.0/projects_trackers.yml ================================================ --- projects_trackers_001: project_id: 1 tracker_id: 1 projects_trackers_002: project_id: 1 tracker_id: 2 projects_trackers_003: project_id: 1 tracker_id: 3 projects_trackers_004: project_id: 2 tracker_id: 1 projects_trackers_005: project_id: 2 tracker_id: 2 projects_trackers_006: project_id: 2 tracker_id: 3 projects_trackers_007: project_id: 3 tracker_id: 1 projects_trackers_008: project_id: 3 tracker_id: 2 projects_trackers_009: project_id: 3 tracker_id: 3 projects_trackers_010: project_id: 4 tracker_id: 1 projects_trackers_011: project_id: 4 tracker_id: 2 projects_trackers_012: project_id: 4 tracker_id: 3 ================================================ FILE: test/fixtures/3.0/roles.yml ================================================ --- roles_001: name: Manager id: 1 builtin: 0 issues_visibility: all permissions: | --- - :add_project - :edit_project - :close_project - :select_project_modules - :manage_members - :manage_versions - :manage_categories - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :manage_subtasks - :add_issue_notes - :move_issues - :delete_issues - :view_issue_watchers - :add_issue_watchers - :set_issues_private - :set_notes_private - :view_private_notes - :delete_issue_watchers - :manage_public_queries - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :edit_time_entries - :delete_time_entries - :manage_news - :comment_news - :view_documents - :add_documents - :edit_documents - :delete_documents - :view_wiki_pages - :export_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :delete_wiki_pages_attachments - :protect_wiki_pages - :delete_wiki_pages - :rename_wiki_pages - :add_messages - :edit_messages - :delete_messages - :manage_boards - :view_files - :manage_files - :browse_repository - :manage_repository - :view_changesets - :manage_related_issues - :manage_project_activities position: 1 roles_002: name: Developer id: 2 builtin: 0 issues_visibility: default permissions: | --- - :edit_project - :manage_members - :manage_versions - :manage_categories - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :manage_subtasks - :add_issue_notes - :move_issues - :delete_issues - :view_issue_watchers - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :edit_own_time_entries - :manage_news - :comment_news - :view_documents - :add_documents - :edit_documents - :delete_documents - :view_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :protect_wiki_pages - :delete_wiki_pages - :add_messages - :edit_own_messages - :delete_own_messages - :manage_boards - :view_files - :manage_files - :browse_repository - :view_changesets position: 2 roles_003: name: Reporter id: 3 builtin: 0 issues_visibility: default permissions: | --- - :edit_project - :manage_members - :manage_versions - :manage_categories - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :add_issue_notes - :move_issues - :view_issue_watchers - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :manage_news - :comment_news - :view_documents - :add_documents - :edit_documents - :delete_documents - :view_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :delete_wiki_pages - :add_messages - :manage_boards - :view_files - :manage_files - :browse_repository - :view_changesets position: 3 roles_004: name: Non member id: 4 builtin: 1 issues_visibility: default permissions: | --- - :view_issues - :add_issues - :edit_issues - :manage_issue_relations - :add_issue_notes - :save_queries - :view_gantt - :view_calendar - :log_time - :view_time_entries - :comment_news - :view_documents - :view_wiki_pages - :view_wiki_edits - :edit_wiki_pages - :add_messages - :view_files - :manage_files - :browse_repository - :view_changesets position: 4 roles_005: name: Anonymous id: 5 builtin: 2 issues_visibility: default permissions: | --- - :treat_user_as_supportclient - :view_issues - :add_issue_notes - :view_gantt - :view_calendar - :view_time_entries - :view_documents - :view_wiki_pages - :view_wiki_edits - :view_files - :browse_repository - :view_changesets position: 5 roles_006: name: SupportClient id: 6 builtin: 0 issues_visibility: default permissions: | --- - :treat_user_as_supportclient - :add_issues - :add_issue_notes position: 6 ================================================ FILE: test/fixtures/3.0/trackers.yml ================================================ --- trackers_001: name: Bug id: 1 is_in_chlog: true position: 1 default_status_id: 1 trackers_002: name: Feature request id: 2 is_in_chlog: true position: 2 default_status_id: 1 trackers_003: name: Support request id: 3 is_in_chlog: false position: 3 default_status_id: 1 ================================================ FILE: test/fixtures/3.0/users.yml ================================================ --- users_001: created_on: 2015-03-05 19:34:07 +02:00 status: 1 last_login_on: language: en # password = foo salt: 3126f764c3c5ac61cbfc103f25f934cf hashed_password: 9e4dd7eeb172c12a0691a6d9d3a269f7e9fe671b updated_on: 2015-03-05 19:34:07 +02:00 admin: true lastname: Hill firstname: Robert id: 1 auth_source_id: mail_notification: all login: normaluser type: User users_002: created_on: 2015-03-05 19:33:19 +02:00 status: 1 last_login_on: language: en # password = foo salt: 7599f9963ec07b5a3b55b354407120c0 hashed_password: 8f659c8d7c072f189374edacfa90d6abbc26d8ed updated_on: 2015-03-05 19:33:19 +02:00 admin: false lastname: Lopper firstname: Dave id: 2 auth_source_id: mail_notification: all login: supportclient type: User users_003: id: 3 created_on: 2006-07-19 19:33:19 +02:00 status: 0 last_login_on: language: '' hashed_password: 1 updated_on: 2006-07-19 19:33:19 +02:00 admin: false lastname: Anonymous firstname: '' auth_source_id: mail_notification: only_my_events login: '' type: AnonymousUser ================================================ FILE: test/fixtures/files/2006/07/060719210727_source.rb ================================================ # The Greeter class class Greeter def initialize(name) @name = name.capitalize end def salute puts "Hello #{@name}!" end end ================================================ FILE: test/fixtures/mail_handler/ticket_by_unknown_user.eml ================================================ Return-Path: