├── .coveralls.yml ├── .devcontainer ├── Dockerfile ├── create-db-user.sql ├── devcontainer.json ├── docker-compose.yml ├── plugin_generator.sh ├── post-create.sh └── redmine.code-workspace ├── .github └── workflows │ ├── build.yml │ └── release.yml ├── .gitignore ├── .gitpod.yml ├── .gitpod ├── database.yml ├── gitpod.code-workspace ├── ignore ├── launch.json ├── setup.sh └── start.sh ├── .hgeol ├── .hgignore ├── GPL.txt ├── Gemfile_for_test ├── README.md ├── app ├── controllers │ ├── wiki_extensions_controller.rb │ └── wiki_extensions_settings_controller.rb ├── models │ ├── wiki_extensions_comment.rb │ ├── wiki_extensions_comments_mailer.rb │ ├── wiki_extensions_count.rb │ ├── wiki_extensions_menu.rb │ ├── wiki_extensions_setting.rb │ ├── wiki_extensions_tag.rb │ ├── wiki_extensions_tag_relation.rb │ └── wiki_extensions_vote.rb └── views │ ├── wiki_extensions │ ├── _body_bottom.html.erb │ ├── _comment_form.html.erb │ ├── _comment_form.mobile.erb │ ├── _comment_form.pdf.erb │ ├── _html_header.html.erb │ ├── _new_page_macro.html.erb │ ├── _tags_form.html.erb │ └── tag.html.erb │ ├── wiki_extensions_comments_mailer │ ├── wiki_commented.html.erb │ └── wiki_commented.text.erb │ └── wiki_extensions_settings │ ├── _menu.html.erb │ └── _show.html.erb ├── assets ├── images │ ├── add.png │ ├── biggrin.png │ ├── check.png │ ├── empty.gif │ ├── main_smile.png │ ├── minus.gif │ ├── plus.gif │ ├── sad.png │ ├── smile.png │ ├── tongue.png │ ├── warning.png │ ├── wink.png │ └── x_mark.png ├── javascripts │ ├── jquery.tablesorter.js │ ├── wiki_extensions.js │ └── wiki_smiles.js └── stylesheets │ ├── wiki_extensions.css │ ├── wiki_extensions_print.css │ └── wiki_smiles.css ├── build-scripts ├── build.sh ├── cleanup.sh ├── database.yml ├── env.sh └── install.sh ├── config ├── emoticons.yml ├── locales │ ├── de.yml │ ├── en.yml │ ├── es.yml │ ├── fr.yml │ ├── it.yml │ ├── ja.yml │ ├── ko.yml │ ├── no.yml │ ├── pl.yml │ ├── pt-BR.yml │ ├── pt.yml │ ├── ru.yml │ ├── sv.yml │ └── zh.yml └── routes.rb ├── db └── migrate │ ├── 0001_create_wiki_extensions_comments.rb │ ├── 0002_create_wiki_extensions_tags.rb │ ├── 0003_create_wiki_extensions_tag_relations.rb │ ├── 0004_create_wiki_extensions_project_settings.rb │ ├── 0005_create_wiki_extensions_project_menus.rb │ ├── 0006_rename_wiki_extensions_tables.rb │ ├── 0007_create_wiki_extensions_counts.rb │ ├── 0008_add_auto_preview.rb │ ├── 0009_add_parent_id.rb │ ├── 0010_add_disable_sidebar.rb │ ├── 0011_remove_disable_sidebar.rb │ ├── 0012_create_wiki_extensions_votes.rb │ └── 0013_add_disable_tags.rb ├── init.rb ├── lib ├── wiki_extensions_application_hooks.rb ├── wiki_extensions_comments.rb ├── wiki_extensions_count_macro.rb ├── wiki_extensions_div_macro.rb ├── wiki_extensions_emoticons.rb ├── wiki_extensions_footnote.rb ├── wiki_extensions_formatter_patch.rb ├── wiki_extensions_helper.rb ├── wiki_extensions_helper_patch.rb ├── wiki_extensions_iframe_macro.rb ├── wiki_extensions_lastupdated_at_macro.rb ├── wiki_extensions_lastupdated_by_macro.rb ├── wiki_extensions_new_macro.rb ├── wiki_extensions_new_page_macro.rb ├── wiki_extensions_notifiable_patch.rb ├── wiki_extensions_page_break_macro.rb ├── wiki_extensions_project_macro.rb ├── wiki_extensions_projects_helper_patch.rb ├── wiki_extensions_recent_macro.rb ├── wiki_extensions_taggedpages_macro.rb ├── wiki_extensions_tags_macro.rb ├── wiki_extensions_twitter_macro.rb ├── wiki_extensions_util.rb ├── wiki_extensions_vote_macro.rb ├── wiki_extensions_wiki_controller_patch.rb ├── wiki_extensions_wiki_macro.rb └── wiki_extensions_wiki_page_patch.rb └── test ├── fixtures ├── wiki_extensions_comments.yml ├── wiki_extensions_counts.yml ├── wiki_extensions_menus.yml ├── wiki_extensions_settings.yml ├── wiki_extensions_tag_relations.yml ├── wiki_extensions_tags.yml └── wiki_extensions_votes.yml ├── functional ├── wiki_controller_test.rb ├── wiki_extensions_controller_test.rb └── wiki_extensions_settings_controller_test.rb ├── test_helper.rb ├── test_runner.rb └── unit ├── emoticons_test.rb ├── wiki_extensions_comment_test.rb ├── wiki_extensions_count_test.rb ├── wiki_extensions_menu_test.rb ├── wiki_extensions_setting_test.rb ├── wiki_extensions_tag_relation_test.rb ├── wiki_extensions_tag_test.rb └── wiki_extensions_vote_test.rb /.coveralls.yml: -------------------------------------------------------------------------------- 1 | service_name: travis-ci -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | ARG RUBY_VERSION=3.2 2 | ARG REDMINE_VERSION=master 3 | FROM haru/redmine_devcontainer:${REDMINE_VERSION}-ruby${RUBY_VERSION} 4 | COPY .devcontainer/post-create.sh /post-create.sh 5 | 6 | 7 | -------------------------------------------------------------------------------- /.devcontainer/create-db-user.sql: -------------------------------------------------------------------------------- 1 | CREATE USER vscode CREATEDB; 2 | CREATE DATABASE vscode WITH OWNER vscode; 3 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // Redmine plugin boilerplate 2 | // version: 1.0.0 3 | { 4 | "name": "Redmine plugin", 5 | "dockerComposeFile": "docker-compose.yml", 6 | "service": "app", 7 | 8 | "mounts": [ 9 | "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind" 10 | ], 11 | "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", 12 | 13 | // Set *default* container specific settings.json values on container create. 14 | "settings": { 15 | "sqltools.connections": [ 16 | { 17 | "name": "Rails Development Database", 18 | "driver": "PostgreSQL", 19 | "previewLimit": 50, 20 | "server": "localhost", 21 | "port": 5432, 22 | 23 | // update this to match config/database.yml 24 | "database": "app_development", 25 | "username": "vscode" 26 | }, 27 | { 28 | "name": "Rails Test Database", 29 | "driver": "PostgreSQL", 30 | "previewLimit": 50, 31 | "server": "localhost", 32 | "port": 5432, 33 | 34 | // update this to match config/database.yml 35 | "database": "app_test", 36 | "username": "vscode" 37 | } 38 | ] 39 | }, 40 | 41 | // Add the IDs of extensions you want installed when the container is created. 42 | "extensions": [ 43 | "mtxr.sqltools", 44 | "mtxr.sqltools-driver-pg", 45 | "craigmaslowski.erb", 46 | "hridoy.rails-snippets", 47 | "misogi.ruby-rubocop", 48 | "jnbt.vscode-rufo", 49 | "donjayamanne.git-extension-pack", 50 | "ms-azuretools.vscode-docker", 51 | "KoichiSasada.vscode-rdbg", 52 | "Serhioromano.vscode-gitflow", 53 | "github.vscode-github-actions", 54 | "Shopify.ruby-extensions-pack", 55 | "ritwickdey.LiveServer" 56 | ], 57 | 58 | // Use 'forwardPorts' to make a list of ports inside the container available locally. 59 | // "forwardPorts": [3000, 5432], 60 | 61 | // Use 'postCreateCommand' to run commands after the container is created. 62 | "postCreateCommand": "sh -x /post-create.sh", 63 | 64 | // Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 65 | "remoteUser": "vscode", 66 | "features": { 67 | // "git": "latest" 68 | }, 69 | 70 | "containerEnv": { 71 | "PLUGIN_NAME": "${localWorkspaceFolderBasename}" 72 | }, 73 | 74 | "forwardPorts": [3000] 75 | } -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '3' 2 | 3 | services: 4 | app: 5 | build: 6 | context: .. 7 | dockerfile: .devcontainer/Dockerfile 8 | args: 9 | # Update 'VARIANT' to pick a version of Ruby: 3, 3.0, 2, 2.7, 2.6 10 | # Append -bullseye or -buster to pin to an OS version. 11 | # Use -bullseye variants on local arm64/Apple Silicon. 12 | RUBY_VERSION: "3.2" 13 | # Optional Node.js version to install 14 | NODE_VERSION: "lts/*" 15 | REDMINE_VERSION: "6.0-stable" 16 | 17 | # Overrides default command so things don't shut down after the process ends. 18 | command: sleep infinity 19 | 20 | # Runs app on the same network as the database container, allows "forwardPorts" in devcontainer.json function. 21 | # network_mode: service:postgres 22 | # Uncomment the next line to use a non-root user for all processes. 23 | # user: vscode 24 | 25 | # Use "forwardPorts" in **devcontainer.json** to forward an app port locally. 26 | # (Adding the "ports" property to this file will not forward from a Codespace.) 27 | 28 | postgres: 29 | image: postgres:latest 30 | restart: unless-stopped 31 | volumes: 32 | - postgres-data:/var/lib/postgresql/data 33 | - ./create-db-user.sql:/docker-entrypoint-initdb.d/create-db-user.sql 34 | environment: 35 | POSTGRES_USER: postgres 36 | POSTGRES_DB: redmine 37 | POSTGRES_PASSWORD: postgres 38 | # Add "forwardPorts": ["5432"] to **devcontainer.json** to forward PostgreSQL locally. 39 | # (Adding the "ports" property to this file will not forward from a Codespace.) 40 | 41 | mysql: 42 | image: mysql:latest 43 | restart: unless-stopped 44 | volumes: 45 | - mysql-data:/var/lib/mysql 46 | # network_mode: service:postgres 47 | command: mysqld --character-set-server=utf8mb4 --collation-server=utf8mb4_unicode_ci 48 | environment: 49 | MYSQL_ROOT_PASSWORD: root 50 | MYSQL_USER: redmine 51 | MYSQL_DB: redmine 52 | MYSQL_PASSWORD: remine 53 | volumes: 54 | postgres-data: null 55 | mysql-data: null 56 | -------------------------------------------------------------------------------- /.devcontainer/plugin_generator.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | cd `dirname $0` 5 | cd .. 6 | BASEDIR=`pwd` 7 | PLUGIN_NAME=`basename $BASEDIR` 8 | echo $PLUGIN_NAME 9 | 10 | cd $REDMINE_ROOT 11 | 12 | export RAILS_ENV="production" 13 | 14 | bundle exec rails generate redmine_plugin $PLUGIN_NAME -------------------------------------------------------------------------------- /.devcontainer/post-create.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd $REDMINE_ROOT 3 | 4 | if [ -d .git.sv ] 5 | then 6 | mv -s .git.sv .git 7 | git pull 8 | rm .git 9 | fi 10 | 11 | ln -s /workspaces/${PLUGIN_NAME} plugins/${PLUGIN_NAME} 12 | if [ -f plugins/${PLUGIN_NAME}/Gemfile_for_test ] 13 | then 14 | cp plugins/${PLUGIN_NAME}/Gemfile_for_test plugins/${PLUGIN_NAME}/Gemfile 15 | fi 16 | 17 | 18 | bundle install 19 | 20 | initdb() { 21 | bundle exec rake db:create 22 | bundle exec rake db:migrate 23 | bundle exec rake redmine:plugins:migrate 24 | 25 | bundle exec rake db:drop RAILS_ENV=test 26 | bundle exec rake db:create RAILS_ENV=test 27 | bundle exec rake db:migrate RAILS_ENV=test 28 | bundle exec rake redmine:plugins:migrate RAILS_ENV=test 29 | } 30 | 31 | initdb 32 | 33 | export DB=mysql2 34 | export DB_NAME=redmine 35 | export DB_USERNAME=root 36 | export DB_PASSWORD=root 37 | export DB_HOST=mysql 38 | export DB_PORT=3306 39 | 40 | initdb 41 | 42 | export DB=postgresql 43 | export DB_NAME=redmine 44 | export DB_USERNAME=postgres 45 | export DB_PASSWORD=postgres 46 | export DB_HOST=postgres 47 | export DB_PORT=5432 48 | 49 | initdb -------------------------------------------------------------------------------- /.devcontainer/redmine.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": ".." 5 | }, 6 | { 7 | "path": "../../../usr/local/redmine" 8 | } 9 | ], 10 | "settings": {} 11 | } -------------------------------------------------------------------------------- /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | push: 4 | pull_request: 5 | env: 6 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} 7 | jobs: 8 | build: 9 | runs-on: ubuntu-latest 10 | strategy: 11 | matrix: 12 | db: [sqlite3, mysql, postgres] 13 | ruby_version: ["3.1", "3.2", "3.3"] 14 | redmine_version: [6.0-stable, master] 15 | services: 16 | mysql: 17 | image: mysql:5.7 18 | options: --health-cmd "mysqladmin ping -h localhost" --health-interval 20s --health-timeout 10s --health-retries 10 19 | env: 20 | MYSQL_ROOT_PASSWORD: dbpassword 21 | postgres: 22 | image: postgres 23 | env: 24 | POSTGRES_USER: root 25 | POSTGRES_PASSWORD: dbpassword 26 | options: >- 27 | --health-cmd pg_isready 28 | --health-interval 10s 29 | --health-timeout 5s 30 | --health-retries 5 31 | container: 32 | image: ruby:${{ matrix.ruby_version }} 33 | env: 34 | DB: ${{ matrix.db }} 35 | DB_USERNAME: root 36 | DB_PASSWORD: dbpassword 37 | DB_HOST: ${{ matrix.db }} 38 | REDMINE_VER: ${{ matrix.redmine_version }} 39 | steps: 40 | - uses: actions/checkout@v4 41 | - name: Install 42 | run: bash -x ./build-scripts/install.sh 43 | - name: Build 44 | run: bash -x ./build-scripts/build.sh 45 | - name: Clean 46 | run: bash -x ./build-scripts/cleanup.sh 47 | - uses: codecov/codecov-action@v5 48 | with: 49 | token: ${{ secrets.CODECOV_TOKEN }} 50 | fail_ci_if_error: true 51 | - name: Slack Notification on Failure 52 | uses: rtCamp/action-slack-notify@v2.0.2 53 | if: failure() 54 | env: 55 | SLACK_CHANNEL: plugin-wiki_ext 56 | SLACK_TITLE: Test Failure 57 | SLACK_COLOR: danger 58 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: build_archive 2 | on: 3 | push: 4 | branches-ignore: 5 | - '**' 6 | tags: 7 | - '**' 8 | permissions: 9 | contents: write 10 | env: 11 | SLACK_WEBHOOK: ${{ secrets.SLACK_WEBHOOK_URL }} 12 | jobs: 13 | archive: 14 | runs-on: ubuntu-latest 15 | steps: 16 | - name: Set version 17 | id: version 18 | run: | 19 | REPOSITORY=$(echo ${{ github.repository }} | sed -e "s#.*/##") 20 | VERSION=$(echo ${{ github.ref }} | sed -e "s#refs/tags/##g") 21 | echo "version=$VERSION" >> $GITHUB_ENV 22 | echo "filename=$REPOSITORY-$VERSION" >> $GITHUB_ENV 23 | echo "plugin=$REPOSITORY" >> $GITHUB_ENV 24 | - uses: actions/checkout@v4 25 | - name: Archive 26 | run: | 27 | cd ..; zip -r ${{ env.filename }}.zip ${{ env.plugin }}/ -x "*.git*"; mv ${{ env.filename }}.zip ${{ env.plugin }}/ 28 | - name: Release 29 | uses: softprops/action-gh-release@v1 30 | with: 31 | draft: true 32 | files: ${{ env.filename }}.zip -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | coverage 2 | Gemfile 3 | Gemfile.lock 4 | -------------------------------------------------------------------------------- /.gitpod.yml: -------------------------------------------------------------------------------- 1 | --- 2 | # List the start up tasks. Learn more https://www.gitpod.io/docs/config-start-tasks/ 3 | tasks: 4 | - init: sh -x ./.gitpod/setup.sh 5 | command: pwd; sh -x /workspace/*/.gitpod/start.sh 6 | env: 7 | REDMINE_VERSION: '5.0-stable' 8 | 9 | # List the ports to expose. Learn more https://www.gitpod.io/docs/config-ports/ 10 | ports: 11 | - port: 3000 12 | onOpen: open-browser 13 | 14 | workspaceLocation: "./redmine" 15 | 16 | vscode: 17 | extensions: 18 | - bung87.rails 19 | - rebornix.ruby 20 | - aliariff.vscode-erb-beautify 21 | - mbessey.vscode-rufo 22 | -------------------------------------------------------------------------------- /.gitpod/database.yml: -------------------------------------------------------------------------------- 1 | # Default setup is given for MySQL 5.7.7 or later. 2 | # Examples for PostgreSQL, SQLite3 and SQL Server can be found at the end. 3 | # Line indentation must be 2 spaces (no tabs). 4 | 5 | production: 6 | adapter: sqlite3 7 | database: db/redmine.sqlite3 8 | 9 | development: 10 | adapter: sqlite3 11 | database: db/redmine_dev.sqlite3 12 | 13 | # Warning: The database defined as "test" will be erased and 14 | # re-generated from your development database when you run "rake". 15 | # Do not set this db to the same as development or production. 16 | test: 17 | adapter: sqlite3 18 | database: db/redmine_test.sqlite3 19 | 20 | -------------------------------------------------------------------------------- /.gitpod/gitpod.code-workspace: -------------------------------------------------------------------------------- 1 | { 2 | "folders": [ 3 | { 4 | "path": "." 5 | }, 6 | { 7 | "path": "../__PLUGIN__NAME" 8 | } 9 | ], 10 | "settings": {} 11 | } -------------------------------------------------------------------------------- /.gitpod/ignore: -------------------------------------------------------------------------------- 1 | .vscode/launch.json 2 | /gitpod.code-workspace 3 | -------------------------------------------------------------------------------- /.gitpod/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | 8 | 9 | { 10 | "name": "Rails server", 11 | "type": "Ruby", 12 | "request": "launch", 13 | "program": "${workspaceRoot}/bin/rails", 14 | "args": [ 15 | "server" 16 | ], 17 | "useBundler": true 18 | }, 19 | { 20 | "name": "Plugin test", 21 | "type": "Ruby", 22 | "request": "launch", 23 | "program": "${workspaceRoot}/bin/rake", 24 | "args": [ 25 | "redmine:plugins:test" 26 | ], 27 | "env": { 28 | "RAILS_ENV": "test" 29 | }, 30 | "useBundler": true 31 | } 32 | ] 33 | } -------------------------------------------------------------------------------- /.gitpod/setup.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | cd $(dirname "$0") || exit 3 | GITPODDIR=$(pwd) 4 | IGNOREDIR="$HOME"/.config/git 5 | mkdir -p "$IGNOREDIR" 6 | cp "$GITPODDIR"/ignore "$IGNOREDIR" 7 | cd .. 8 | BASEDIR=$(pwd) 9 | 10 | if [ -f Gemfile_for_test ]; then 11 | cp Gemfile_for_test Gemfile 12 | fi 13 | cd .. 14 | REDMINEDIR=$(pwd)/redmine 15 | if [ ! -d redmine ]; then 16 | git clone https://github.com/redmine/redmine.git -b "$REDMINE_VERSION" 17 | cd redmine || exit 18 | mv .git .git.org 19 | cd "$REDMINEDIR"/plugins || exit 20 | ln -s "$BASEDIR" . 21 | cp "$GITPODDIR"/database.yml "$REDMINEDIR"/config/ 22 | mkdir "$REDMINEDIR"/.vscode 23 | cd "$REDMINEDIR"/.vscode || exit 24 | ln -s "$GITPODDIR"/launch.json . 25 | echo "gem 'ruby-debug-ide'" >> "$REDMINEDIR"/Gemfile 26 | echo "gem 'debase'" >> "$REDMINEDIR"/Gemfile 27 | sed -i 's/^end$/ config.hosts.clear\nend/' "$REDMINEDIR"/config/environments/development.rb 28 | fi 29 | 30 | 31 | -------------------------------------------------------------------------------- /.gitpod/start.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | REDMINEDIR=/workspace/redmine 4 | cd $(dirname "$0") || exit 5 | GITPODDIR=$(pwd) 6 | cd .. 7 | BASEDIR=$(pwd) 8 | PLUGIN_NAME=$(basename "$BASEDIR") 9 | 10 | cd "$REDMINEDIR" || exit 11 | sed "s/__PLUGIN__NAME/$PLUGIN_NAME/" "$GITPODDIR"/gitpod.code-workspace > "$REDMINEDIR"/gitpod.code-workspace 12 | gem install ruby-debug-ide 13 | bundle install --path vendor/bundle 14 | bundle exec rake db:migrate 15 | bundle exec rake redmine:plugins:migrate 16 | bundle exec rake db:migrate RAILS_ENV=test 17 | bundle exec rake redmine:plugins:migrate RAILS_ENV=test -------------------------------------------------------------------------------- /.hgeol: -------------------------------------------------------------------------------- 1 | [patterns] 2 | **.* = NATIVE 3 | -------------------------------------------------------------------------------- /.hgignore: -------------------------------------------------------------------------------- 1 | ^coverage/ 2 | ^rails/ 3 | ^VERSION$ 4 | ^pkg/ 5 | ^Gemfile.lock$ 6 | syntax: glob 7 | test/coverage 8 | *.orig 9 | Gemfile -------------------------------------------------------------------------------- /Gemfile_for_test: -------------------------------------------------------------------------------- 1 | 2 | group :test do 3 | # gem 'factory_girl_rails' 4 | #gem 'shoulda-matchers' 5 | gem 'shoulda' 6 | gem 'simplecov-lcov', :require => false 7 | end 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [](https://github.com/haru/redmine_wiki_extensions/actions/workflows/build.yml) 2 | [](https://codeclimate.com/github/haru/redmine_wiki_extensions/maintainability) 3 | [](https://codecov.io/gh/haru/redmine_wiki_extensions) 4 | 5 | # Redmine Wiki Extensions Plugin 6 | 7 | Wiki Extensions is a plugin which adds several useful wiki macros to Redmine. 8 | 9 | https://www.r-labs.org/projects/r-labs/wiki/Wiki_Extensions_en 10 | 11 | ## Plugin installation 12 | 13 | 1. Copy the plugin directory into the plugins directory 14 | 15 | 2. Migrate plugin: 16 | rake redmine:plugins:migrate RAILS_ENV=production 17 | 18 | 3. Start Redmine 19 | 20 | 4. Add wiki extensions module into your project. 21 | 22 | ## Note 23 | 24 | This plugin works only on production mode. 25 | 26 | ## Language contributors 27 | 28 | * ru.yml - Dim A 29 | * fr.yml - Pascal Menut 30 | * de.yml - Albrecht Backhaus 31 | * it.yml - earcar 32 | * sv.yml - Henrik Jönsson 33 | * es.yml - Francisco Benítez León 34 | * no.yml - Thomas Nygreen 35 | * pt.yml - Marcelo Fernandes 36 | * pt-BR.yml - Marcelo Fernandes 37 | * pl.yml - Łukasz Rymarczyk 38 | * zh.yml - Tim lin, Steven Wong 39 | -------------------------------------------------------------------------------- /app/controllers/wiki_extensions_controller.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | class WikiExtensionsController < ApplicationController 19 | menu_item :wiki 20 | before_action :find_project, :find_user 21 | before_action :authorize, except: [:stylesheet, :emoticon] 22 | 23 | def add_comment 24 | comment = WikiExtensionsComment.new 25 | comment.wiki_page_id = params[:wiki_page_id].to_i 26 | comment.user_id = @user.id 27 | comment.comment = params[:comment] 28 | comment.save 29 | page = WikiPage.find(comment.wiki_page_id) 30 | # Send email-notification to watchers of wiki page 31 | WikiExtensionsCommentsMailer.deliver_wiki_commented(comment, page) if Setting.notified_events.include? "wiki_comment_added" 32 | redirect_to :controller => "wiki", :action => "show", :project_id => @project, :id => page.title 33 | end 34 | 35 | def reply_comment 36 | comment = WikiExtensionsComment.new 37 | comment.parent_id = params[:comment_id].to_i 38 | comment.wiki_page_id = params[:wiki_page_id].to_i 39 | comment.user_id = @user.id 40 | comment.comment = params[:reply] 41 | comment.save 42 | page = WikiPage.find(comment.wiki_page_id) 43 | # Send email-notification to watchers of wiki page 44 | WikiExtensionsCommentsMailer.deliver_wiki_commented(comment, page) if Setting.notified_events.include? "wiki_comment_added" 45 | redirect_to :controller => "wiki", :action => "show", :project_id => @project, :id => page.title 46 | end 47 | 48 | def tag 49 | tag_id = params[:tag_id].to_i 50 | @tag = WikiExtensionsTag.find(tag_id) 51 | end 52 | 53 | def forward_wiki_page 54 | menu_id = params[:menu_id].to_i 55 | menu = WikiExtensionsMenu.find_or_create(@project.id, menu_id) 56 | redirect_to :controller => "wiki", :action => "show", :project_id => @project, :id => menu.page_name 57 | end 58 | 59 | def destroy_comment 60 | comment_id = params[:comment_id].to_i 61 | comment = WikiExtensionsComment.find(comment_id) 62 | unless User.current.admin or User.current.id == comment.user.id 63 | render_403 64 | return false 65 | end 66 | 67 | page = WikiPage.find(comment.wiki_page_id) 68 | comment.destroy 69 | redirect_to :controller => "wiki", :action => "show", :project_id => @project, :id => page.title 70 | end 71 | 72 | def update_comment 73 | comment_id = params[:comment_id].to_i 74 | comment = WikiExtensionsComment.find(comment_id) 75 | unless User.current.admin or User.current.id == comment.user.id 76 | render_403 77 | return false 78 | end 79 | 80 | page = WikiPage.find(comment.wiki_page_id) 81 | comment.comment = params[:comment] 82 | comment.save 83 | redirect_to :controller => "wiki", :action => "show", :project_id => @project, :id => page.title 84 | end 85 | 86 | def vote 87 | target_class_name = params[:target_class_name] 88 | target_id = params[:target_id].to_i 89 | key = params[:key] 90 | vote = WikiExtensionsVote.find_or_create(target_class_name, target_id, key) 91 | session[:wiki_extension_voted] = Hash.new unless session[:wiki_extension_voted] 92 | unless session[:wiki_extension_voted][vote.id] 93 | vote.countup 94 | vote.save! 95 | session[:wiki_extension_voted][vote.id] = 1 96 | end 97 | 98 | render :inline => " #{vote.count}" 99 | end 100 | 101 | def stylesheet 102 | stylesheet = WikiPage.find_by(wiki_id: @project.wiki.id, title: "StyleSheet") 103 | unless stylesheet 104 | render_404 105 | return 106 | end 107 | 108 | unless stylesheet.visible? 109 | render_403 110 | return 111 | end 112 | render plain: stylesheet.content.text, content_type: "text/css" 113 | end 114 | 115 | def emoticon 116 | icon_name = params[:icon_name] 117 | icon_name += ".#{params[:format]}" if params[:format].present? 118 | directory = File.expand_path(File.dirname(__FILE__) + "/../../assets/images/") 119 | icon_path = File.join(directory, icon_name) 120 | # icon_pathが示すPNGファイルのバイナリデータをクライアントに返す 121 | if File.exist?(icon_path) 122 | send_file icon_path, type: "image/png", disposition: "inline" 123 | else 124 | render_404 125 | end 126 | end 127 | 128 | private 129 | 130 | def find_project 131 | # @project variable must be set before calling the authorize filter 132 | @project = Project.find(params[:id]) unless params[:id].blank? 133 | end 134 | 135 | def find_user 136 | @user = User.current 137 | end 138 | end 139 | -------------------------------------------------------------------------------- /app/controllers/wiki_extensions_settings_controller.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | class WikiExtensionsSettingsController < ApplicationController 19 | layout 'base' 20 | 21 | before_action :find_project, :authorize, :find_user 22 | 23 | def update 24 | menus = params[:menus] 25 | 26 | setting = WikiExtensionsSetting.find_or_create @project.id 27 | begin 28 | setting.transaction do 29 | menus.each_pair {|menu_no, menu| 30 | menu_setting = WikiExtensionsMenu.find_or_create(@project.id, menu[:menu_no].to_i) 31 | menu_setting.enabled = false 32 | menu_setting.attributes = menu.permit(:enabled, :menu_no, :title, :page_name) 33 | menu_setting.save! 34 | } 35 | end 36 | flash[:notice] = l(:notice_successful_update) 37 | rescue => e 38 | flash[:error] = "Updating failed." + e.message 39 | throw e 40 | end 41 | 42 | redirect_to :controller => 'projects', :action => "settings", :id => @project, :tab => 'wiki_extensions' 43 | end 44 | 45 | private 46 | def find_project 47 | # @project variable must be set before calling the authorize filter 48 | @project = Project.find(params[:id]) 49 | end 50 | 51 | def find_user 52 | @user = User.current 53 | end 54 | end 55 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_comment.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | class WikiExtensionsComment < ApplicationRecord 18 | belongs_to :user 19 | belongs_to :wiki_page 20 | validates_presence_of :comment, :wiki_page_id, :user_id 21 | 22 | def children(comments) 23 | comments.select { |comment| comment.parent_id == id } 24 | end 25 | 26 | def project 27 | wiki_page.wiki.project 28 | end 29 | 30 | acts_as_event :title => Proc.new { |o| "Wiki comment: #{o.wiki_page.title}" }, 31 | :author => :user, 32 | :description => :comment, 33 | :datetime => :updated_at, 34 | :url => Proc.new { |o| {:controller => 'wiki', :action => 'show', :id => o.wiki_page.title, :project_id => o.project} } 35 | 36 | acts_as_activity_provider :type => 'wiki_comment', 37 | :permission => :view_wiki_edits, 38 | :timestamp => "updated_at", 39 | :author_key => "user_id", 40 | :scope => select("#{WikiExtensionsComment.table_name}.updated_at, #{WikiExtensionsComment.table_name}.comment, #{WikiExtensionsComment.table_name}.user_id, #{WikiExtensionsComment.table_name}.wiki_page_id") 41 | .joins("LEFT JOIN #{WikiPage.table_name} ON #{WikiPage.table_name}.id = #{WikiExtensionsComment.table_name}.wiki_page_id " + 42 | "LEFT JOIN #{Wiki.table_name} ON #{Wiki.table_name}.id = #{WikiPage.table_name}.wiki_id " + 43 | "LEFT JOIN #{Project.table_name} ON #{Project.table_name}.id = #{Wiki.table_name}.project_id") 44 | 45 | #:find_options => {:include => {:wiki_page => {:wiki => :project}}} 46 | 47 | end 48 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_comments_mailer.rb: -------------------------------------------------------------------------------- 1 | require 'mailer' 2 | 3 | class WikiExtensionsCommentsMailer < Mailer 4 | def self.deliver_wiki_commented(comment, wiki_page) 5 | # Send notification to watchers and author of wiki page 6 | users = wiki_page.watchers.collect { |watcher|watcher.user} | wiki_page.content.notified_users 7 | users.each do |user| 8 | wiki_commented(user, comment, wiki_page).deliver_now 9 | end 10 | end 11 | 12 | def wiki_commented(user, comment, wiki_page) 13 | project = wiki_page.project 14 | author = comment.user 15 | text = comment.comment 16 | redmine_headers 'Project' => project, 17 | 'Wiki-Page-Id' => wiki_page.id, 18 | 'Author' => author 19 | message_id wiki_page 20 | 21 | subject = "[#{project.name} - Wiki - #{wiki_page.title}] commented" 22 | 23 | @project = project 24 | @author = author 25 | @text = text 26 | @wiki_page_title = wiki_page.title 27 | @wiki_page_url = url_for(:controller => 'wiki', :action => 'show', :project_id => project, :id => wiki_page.title) 28 | 29 | mail :to => user, 30 | :subject => subject 31 | 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_count.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | class WikiExtensionsCount < ApplicationRecord 18 | belongs_to :project 19 | belongs_to :page, :foreign_key => :page_id, :class_name => 'WikiPage' 20 | validates_presence_of :project 21 | validates_presence_of :page 22 | validates_presence_of :date 23 | validates_presence_of :count 24 | validates_uniqueness_of :page_id, :scope => :date 25 | 26 | def self.countup(wiki_page_id, date = nil) 27 | date = Date.today unless date 28 | count = WikiExtensionsCount.where(:date => date).where(:page_id => wiki_page_id).first 29 | unless count 30 | page = WikiPage.find(wiki_page_id) 31 | count = WikiExtensionsCount.new 32 | count.project = page.wiki.project 33 | count.page = page 34 | count.date = date 35 | count.count = 0 36 | end 37 | count.count = count.count + 1 38 | count.save! 39 | end 40 | 41 | def self.access_count(wiki_page_id, date = nil) 42 | conditions = ['page_id = ?', wiki_page_id] unless date 43 | conditions = ['date >= ? and page_id = ?', date, wiki_page_id] if date 44 | #total = WikiExtensionsCount.sum(:count, :conditions => conditions) 45 | WikiExtensionsCount.where(conditions).sum(:count) 46 | end 47 | 48 | def self.popularity(project_id, term = 0) 49 | conditions = ['project_id = ?', project_id] if term == 0 50 | conditions = ['project_id = ? and date > ?', project_id, Date.today - term.to_i] if term > 0 51 | WikiExtensionsCount.where(conditions).group(:page_id).sum(:count).to_a.sort_by{|x|0 - x[1]}.map{|x| [x[0], x[1].to_i]} 52 | end 53 | end 54 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_menu.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | class WikiExtensionsMenu < ApplicationRecord 18 | include Redmine::SafeAttributes 19 | belongs_to :project 20 | validates_presence_of :project_id 21 | validates_presence_of :menu_no 22 | 23 | #attr_accessible 'enabled', 'menu_no', 'title', 'page_name' 24 | 25 | def self.find_or_create(pj_id, no) 26 | menu = WikiExtensionsMenu.where(:project_id => pj_id).where(:menu_no => no).first 27 | unless menu 28 | menu = WikiExtensionsMenu.new 29 | menu.project_id = pj_id 30 | menu.menu_no = no 31 | menu.enabled = false 32 | menu.save! 33 | end 34 | return menu 35 | end 36 | 37 | def self.enabled?(pj_id, no) 38 | begin 39 | menu = find_or_create(pj_id, no) 40 | return false if menu.page_name.blank? 41 | menu.enabled 42 | rescue 43 | return false 44 | end 45 | end 46 | 47 | def self.title(pj_id, no) 48 | begin 49 | menu = find_or_create(pj_id, no) 50 | return menu.title unless menu.title.blank? 51 | return menu.page_name unless menu.page_name.blank? 52 | return nil 53 | rescue 54 | return nil 55 | end 56 | end 57 | 58 | def validate 59 | return true unless enabled 60 | #errors.add("title", "is empty") unless attribute_present?("title") 61 | #errors.add("page_name", "is empty") unless attribute_present?("page_name") 62 | 63 | end 64 | end 65 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_setting.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2011-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | class WikiExtensionsSetting < ApplicationRecord 18 | belongs_to :project 19 | #attr_accessible :auto_preview_enabled, :tag_disabled 20 | 21 | def self.find_or_create(pj_id) 22 | setting = WikiExtensionsSetting.find_by(project_id: pj_id) 23 | unless setting 24 | setting = WikiExtensionsSetting.new 25 | setting.project_id = pj_id 26 | setting.save! 27 | end 28 | 5.times do |i| 29 | WikiExtensionsMenu.find_or_create(pj_id, i + 1) 30 | end 31 | return setting 32 | end 33 | 34 | def auto_preview_enabled 35 | false 36 | end 37 | 38 | def menus 39 | WikiExtensionsMenu.where(:project_id => project_id).order("menu_no") 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_tag.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | class WikiExtensionsTag < ApplicationRecord 18 | #attr_accessible :name, :project_id 19 | validates_presence_of :name, :project_id 20 | validates_uniqueness_of :name, :scope => :project_id 21 | 22 | def WikiExtensionsTag.find_or_create(project_id, name) 23 | obj = WikiExtensionsTag.find_or_create_by(name: name, project_id: project_id) 24 | end 25 | 26 | def ==(obj) 27 | return false unless self.project_id == obj.project_id 28 | return self.name == obj.name 29 | end 30 | 31 | def pages 32 | return @pages if @pages 33 | relations = WikiExtensionsTagRelation.where(:tag_id => id).all 34 | @pages = [] 35 | relations.each{|relation| 36 | @pages << relation.wiki_page 37 | } 38 | return @pages 39 | end 40 | 41 | def page_count 42 | pages.length 43 | end 44 | 45 | def <=> obj 46 | self.name <=> obj.name 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_tag_relation.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | class WikiExtensionsTagRelation < ApplicationRecord 18 | belongs_to :wiki_page 19 | belongs_to :tag, :class_name => 'WikiExtensionsTag', :foreign_key => :tag_id 20 | validates_presence_of :wiki_page_id, :tag_id 21 | validates_uniqueness_of :tag_id, :scope => :wiki_page_id 22 | 23 | def destroy 24 | ret = super 25 | target_tag = WikiExtensionsTag.find(tag_id) if tag_id 26 | target_tag.destroy if target_tag.page_count.zero? 27 | ret 28 | end 29 | 30 | end 31 | -------------------------------------------------------------------------------- /app/models/wiki_extensions_vote.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | class WikiExtensionsVote < ApplicationRecord 19 | validates_presence_of :target_class_name, :target_id, :keystr, :count 20 | validates_uniqueness_of :keystr, :scope => [:target_class_name, :target_id] 21 | 22 | def target 23 | return nil unless self.target_class_name 24 | return nil unless self.target_id 25 | targetclass = eval self.target_class_name 26 | targetclass.find(self.target_id) 27 | end 28 | 29 | def target=(obj) 30 | self.target_class_name = obj.class.name 31 | self.target_id = obj.id 32 | end 33 | 34 | def countup 35 | self.count = 0 unless self.count 36 | self.count = self.count + 1 37 | end 38 | 39 | def self.find_or_create(class_name, obj_id, key_str) 40 | vote = WikiExtensionsVote.where(:target_class_name => class_name).where(:target_id => obj_id).where(:keystr => key_str).first 41 | unless vote 42 | vote = WikiExtensionsVote.new 43 | vote.count = 0 44 | vote.target_class_name = class_name 45 | vote.target_id = obj_id 46 | vote.keystr = key_str 47 | end 48 | return vote 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /app/views/wiki_extensions/_body_bottom.html.erb: -------------------------------------------------------------------------------- 1 | <% # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2012-2019 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | -%> 18 | 19 | <% 20 | 21 | return unless WikiExtensionsUtil.is_enabled?(project) 22 | 23 | context = {:project => project, :controller => controller, :request => request} 24 | 25 | return unless controller.class.name == 'WikiController' 26 | action_name = controller.action_name 27 | 28 | params = request.parameters if request 29 | page_name = params[:id] if params 30 | wiki = project.wiki 31 | return unless wiki 32 | page = wiki.find_page(page_name) if page_name 33 | 34 | context = {:project => project, :controller => controller, :request => request} 35 | %> 36 | 37 | <% if action_name == 'edit' or (action_name == 'show' and page_name and page == nil) %> 38 | <%= render :partial => 'wiki_extensions/tags_form', :locals => context %> 39 | 40 | 41 | <% else %> 42 | 43 | 47 | <%= raw javascript_tag('wiki_extension_create_table_header();') %> 48 | 49 | <% end %> -------------------------------------------------------------------------------- /app/views/wiki_extensions/_comment_form.html.erb: -------------------------------------------------------------------------------- 1 | <% # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2012-2013 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | -%> 18 | <% 19 | 20 | url = url_for(:controller => 'wiki_extensions', :action => 'add_comment', :id => @project) 21 | -%> 22 | 23 |
29 |
30 |
31 |
32 |
33 |
34 | <%
35 | i = 0
36 | maxline = 5
37 | %>
38 | <%
39 | maxline.times { |line|
40 | style = ''
41 | style = 'style="display:none;"' if line != 0 and line > (tags.length - 1) / 4
42 | %>
43 | id="<%= "tag_line_#{line.to_s}" %>">
44 | <%
45 | 4.times {
46 | value = ''
47 | value = 'value="' + tags[i].name + '"' if tags[i]
48 | %>
49 |
50 | class="wikiext_tag_inputs"/>
52 |
53 | <%
54 | i = i + 1
55 | }
56 |
57 | nextline = line + 1
58 | %>
59 |
60 | <% if (line < maxline - 1) %>
61 |
62 | <%= image_tag(img, :onclick => raw("$('#tag_line_#{nextline.to_s}').show()")) %>
63 |
64 | <% end %>
65 |
66 |
67 | <%
68 | }
69 | %>
70 |
71 |
72 |
73 |
28 | 29 | <%= text_field_tag "menus[#{i}][title]", menu.title, :size => 70, :required => true, :disabled => !menu.enabled %> 30 |
31 |32 | 33 | <%= text_field_tag "menus[#{i}][page_name]", menu.page_name, :size => 70, :required => true, :disabled => !menu.enabled %> 34 |
35 |47 | 48 | 49 | 50 |
' + "\n\n" + 21 | " !{{div_start_tag(id_name)}}" + "'\n" + 22 | " !{{div_start_tag(id_name, class_name)}}" 23 | macro :div_start_tag do |obj, args| 24 | o = '' if args.length == 0 25 | o = '' if args.length == 1 26 | o = ''.html_safe 38 | end 39 | end 40 | end 41 | 42 | -------------------------------------------------------------------------------- /lib/wiki_extensions_emoticons.rb: -------------------------------------------------------------------------------- 1 | # To change this template, choose Tools | Templates 2 | # and open the template in the editor. 3 | require "yaml" 4 | 5 | module WikiExtensionsEmoticons 6 | YAML_FILE = File.join(File.dirname(__FILE__), '../config/emoticons.yml') 7 | class Emoticons 8 | def emoticons 9 | @@emoticons ||= YAML.load_file(YAML_FILE) 10 | end 11 | end 12 | end 13 | -------------------------------------------------------------------------------- /lib/wiki_extensions_footnote.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsFootnote 20 | 21 | def WikiExtensionsFootnote.preview_page 22 | @@preview_page ||= WikiPage.new 23 | end 24 | 25 | Redmine::WikiFormatting::Macros.register do 26 | desc "Create a footnote.\n\n" + 27 | " \{{fn(word, description)}}" 28 | macro :fn do |obj, args| 29 | return nil if args.length < 2 30 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 31 | word = args.shift 32 | description = args.join(",").strip 33 | page = obj.page if obj 34 | page = WikiExtensionsFootnote.preview_page unless page 35 | data = page.wiki_extension_data 36 | data[:footnotes] ||= [] 37 | data[:footnotes] << {'word' => word, 'description' => description} 38 | 39 | 40 | o = "" 41 | o << word 42 | o << '' 43 | o << "*#{data[:footnotes].length}" 44 | o << '' 45 | return o.html_safe 46 | end 47 | end 48 | 49 | Redmine::WikiFormatting::Macros.register do 50 | desc "Displays footnotes of the page." 51 | macro :fnlist do |obj, args| 52 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 53 | page = obj.page if obj 54 | page = WikiExtensionsFootnote.preview_page unless page 55 | data = page.wiki_extension_data 56 | return '' if data[:footnotes].blank? or data[:footnotes].empty? 57 | o = '' if args.length == 2 27 | o.html_safe 28 | end 29 | end 30 | end 31 | 32 | module WikiExtensionsDivMacro 33 | Redmine::WikiFormatting::Macros.register do 34 | desc "Displays a\n\n" + 35 | " !{{div_end_tag}}" 36 | macro :div_end_tag do |obj, args| 37 | return '' 58 | o << "' 67 | WikiExtensionsFootnote.preview_page.wiki_extension_data[:footnotes] = [] 68 | return o.html_safe 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /lib/wiki_extensions_formatter_patch.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2011-2017 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require_dependency "redmine/wiki_formatting/textile/formatter" 19 | 20 | module WikiExtensionsFormatterPatch 21 | Redmine::WikiFormatting::Textile::Formatter::RULES << :inline_smiles 22 | 23 | private 24 | 25 | def inline_smiles(text) 26 | emoticon_path = WikiExtentionEmoticonPath.new 27 | 28 | @emoticons = WikiExtensionsEmoticons::Emoticons.new 29 | @emoticons.emoticons.each { |emoticon| 30 | src = emoticon_path.get_emoticon_path(emoticon["image"]) 31 | text.gsub!(Regexp.new("#{Regexp.escape(emoticon["emoticon"])}(\\s|
\n" 59 | o << '' 60 | cnt = 0 61 | data[:footnotes].each {|fn| 62 | cnt += 1 63 | o << '
' 66 | o << '- '+ "*#{cnt} " +'#{fn['word']}:#{fn['description']}
" 64 | } 65 | o << '
|)"), 32 | "\\1") 33 | } 34 | end 35 | 36 | class WikiExtentionEmoticonPath 37 | include Rails.application.routes.url_helpers 38 | 39 | def get_emoticon_path(emoticon) 40 | wiki_extensions_emoticon_path(emoticon) 41 | end 42 | end 43 | end 44 | 45 | Redmine::WikiFormatting::Textile::Formatter.prepend(WikiExtensionsFormatterPatch) 46 | -------------------------------------------------------------------------------- /lib/wiki_extensions_helper.rb: -------------------------------------------------------------------------------- 1 | #Author: Dmitry Manayev 2 | 3 | require 'redmine' 4 | module WikiExtensionsHelper 5 | #This needed to define WikiExtensionsHelper for WikiExtensionsController. 6 | end 7 | module ActionView 8 | module Helpers 9 | module WikiExtensionsHelper 10 | 11 | 12 | ## Method for displaying tree of comments\n 13 | #comments_tree - is orderly array of comments; 14 | #parent_id - is id of parent comment; 15 | #k - is number of tree nodes;\n 16 | #page - is wiki_page object; 17 | #data - is wiki_extensions_data on this page 18 | def display_comments_tree(comments_tree, parent_id,page,data,k = 0) 19 | ret = ' ' 20 | 21 | if k != 0 22 | ret << '
' 23 | else 24 | ret << '
' 25 | end 26 | k += 1 27 | if k < 26 #maximum number of tree nodes is 25 28 | comments_tree.each do |comment| 29 | if comment.parent_id == parent_id 30 | 31 | check = comment.children(comments_tree).empty? 32 | div_comment_id = "wikiextensions_comment_#{comment.id}" 33 | li_comment_id = "wikiextensions_comment_li_#{comment.id}" 34 | form_reply_id = "wikiextensions_reply_form_#{comment.id}" 35 | form_div_id = "wikiextensions_comment_form_#{comment.id}" 36 | text_div_id = "wikiextensions_comment_text_#{comment.id}" 37 | 38 | unless check 39 | ret << '
" 141 | return ret 142 | end 143 | end 144 | end 145 | end 146 | -------------------------------------------------------------------------------- /lib/wiki_extensions_helper_patch.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2011-2017 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require_dependency "redmine/wiki_formatting/textile/helper" 19 | 20 | module WikiExtensionsHelperPatch 21 | def heads_for_wiki_formatter 22 | super 23 | return if ie6_or_ie7? 24 | unless @heads_for_wiki_smiles_included 25 | 26 | content_for :header_tags do 27 | # o = stylesheet_link_tag("wiki_smiles.css", :plugin => "redmine_wiki_extensions") 28 | # o << javascript_include_tag("wiki_smiles.js", :plugin => "redmine_wiki_extensions") 29 | # emoticons = WikiExtensions::Emoticons.new 30 | # o << javascript_tag do 31 | # oo = "" 32 | # oo << raw("redmine_base_url = '#{baseurl}';\n") 33 | # oo << "var buttons = [];" 34 | # emoticons.emoticons.each { |emoticon| 35 | # oo << "buttons.push(['#{emoticon["emoticon"].gsub("'", "\\'")}', '#{emoticon["image"]}', '#{emoticon["title"]}']);\n" 36 | # } 37 | # oo << "setEmoticonButtons(buttons, '#{imageurl}');\n" 38 | # oo.html_safe 39 | # end 40 | # o.html_safe 41 | end 42 | @heads_for_wiki_smiles_included = true 43 | end 44 | end 45 | 46 | private 47 | 48 | def ie6_or_ie7? 49 | useragent = request.env['HTTP_USER_AGENT'].to_s 50 | return useragent.match(/IE[ ]+[67]./) != nil 51 | end 52 | end 53 | 54 | Redmine::WikiFormatting::Textile::Helper.prepend(WikiExtensionsHelperPatch) 55 | -------------------------------------------------------------------------------- /lib/wiki_extensions_iframe_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | module WikiExtensionsIframeMacro 19 | Redmine::WikiFormatting::Macros.register do 20 | desc "Insert an iframe tag" + "\n\n" + 21 | " !{{iframe(url, width, height)}}" + "\n\n" 22 | " !{{iframe(url, width, height, scroll)}}" 23 | macro :iframe do |obj, args| 24 | width = '100%' 25 | width = args[1].strip if args[1] 26 | height = '400pt' 27 | height = args[2].strip if args[2] 28 | 29 | scrolling = 'auto' 30 | scrolling = args[3].strip if args.length > 3 31 | url = /([a-zA-Z0-9]+:\/\/[-a-zA-Z0-9\.\?\&=\+@:_~\#\%\/\;]+)/.match(args[0]).to_a[1] 32 | url = url.gsub(/\&/,"&") 33 | o = '' 34 | o << '' 36 | 37 | return o.html_safe 38 | end 39 | end 40 | end 41 | 42 | -------------------------------------------------------------------------------- /lib/wiki_extensions_lastupdated_at_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | module WikiExtensionsLastupdatedAtMacro 19 | Redmine::WikiFormatting::Macros.register do 20 | desc "Displays a date that updated the page.\n\n" + 21 | " !{{lastupdated_at}}\n" 22 | " !{{lastupdated_at(project_name, wiki_page)}}\n" 23 | " !{{lastupdated_at(project_identifier, wiki_page)}}\n" 24 | macro :lastupdated_at do |obj, args| 25 | return nil unless WikiExtensionsUtil.is_enabled?(@project) if @project 26 | if args.length == 0 27 | page = obj 28 | else 29 | return nil if args.length < 2 30 | project_name = args[0].strip 31 | page_name = args[1].strip 32 | project = Project.find_by_name(project_name) 33 | project = Project.find_by_identifier(project_name) unless project 34 | return nil unless project 35 | wiki = Wiki.find_by_project_id(project.id) 36 | return nil unless wiki 37 | page = wiki.find_page(page_name) 38 | end 39 | 40 | return nil unless page 41 | 42 | o = '' 43 | o << l(:label_updated_time, time_tag(page.updated_on)) 44 | o << '' 45 | o.html_safe 46 | end 47 | end 48 | end 49 | -------------------------------------------------------------------------------- /lib/wiki_extensions_lastupdated_by_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | module WikiExtensionsLastupdatedByMacro 19 | Redmine::WikiFormatting::Macros.register do 20 | desc "Displays a user who updated the page.\n\n" + 21 | " !{{lastupdated_by}}" 22 | macro :lastupdated_by do |obj, args| 23 | o = '' 24 | o << "#{avatar(obj.author, :size => "14")}" 25 | o << link_to_user(obj.author) 26 | o << '' 27 | o.html_safe 28 | end 29 | end 30 | end 31 | -------------------------------------------------------------------------------- /lib/wiki_extensions_new_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsNewMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Displays a string 'new'.\n\n" + 22 | " !{{new(yyyy-mm-dd)}}\n" + 23 | " !{{new(yyyy-mm-dd, expire)}}\n\n" + 24 | "Default of expire is 5." 25 | macro :new do |obj, args| 26 | return nil if args.length < 1 27 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 28 | date_string = args[0].strip 29 | expire = args[1].strip.to_i if args[1] 30 | expire = 5 unless expire 31 | date = Date.parse(date_string) 32 | today = Date.today 33 | 34 | o = '' 35 | o << '[' + format_date(date) + ']' 36 | if (today - date < expire) 37 | o << '' + l(:label_wikiextensions_new) 38 | case today - date 39 | when -100 .. 0 40 | o << '!!!' 41 | when 1 42 | o << '!!' 43 | when 2 44 | o << '!' 45 | end 46 | o << '' 47 | end 48 | o << '' 49 | return o.html_safe 50 | end 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /lib/wiki_extensions_new_page_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2011-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsNewPageMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Create new page.\n\n" 22 | macro :new_page do |obj, args| 23 | @_controller.send(:render_to_string, {:partial => "wiki_extensions/new_page_macro"}).html_safe 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/wiki_extensions_notifiable_patch.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2017 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | module WikiExtensionsNotifiablePatch 19 | def self.prepended(base) 20 | class << base 21 | self.prepend(ClassMethods) 22 | end 23 | end 24 | 25 | module ClassMethods 26 | def all 27 | notifications = super 28 | notifications << Redmine::Notifiable.new('wiki_comment_added') 29 | notifications 30 | end 31 | end 32 | end 33 | 34 | Redmine::Notifiable.prepend(WikiExtensionsNotifiablePatch) 35 | -------------------------------------------------------------------------------- /lib/wiki_extensions_page_break_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2013 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsPageBreakMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc 'Page break here.' 22 | macro :page_break do |obj, args| 23 | content_tag(:div, nil, :class => 'wikiext-page-break') 24 | end 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /lib/wiki_extensions_project_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsProjectMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Creates link to other project.\n\n" + 22 | " \{{project(project_name)}}\n" + 23 | " \{{project(project_identifire}}\n" + 24 | " \{{project(project_name, alias)}}\n" + 25 | " \{{project(project_identifire, alias}}\n" 26 | macro :project do |obj, args| 27 | 28 | return nil if args.length < 1 29 | project_name = args[0].strip 30 | project = Project.find_by_name(project_name) 31 | project = Project.find_by_identifier(project_name) unless project 32 | return nil unless project 33 | return nil unless WikiExtensionsUtil.is_enabled?(@project) if @project 34 | if (args[1]) 35 | alias_name = args[1].strip 36 | else 37 | alias_name = project.name 38 | end 39 | 40 | o = link_to(alias_name, :controller => 'projects', :action => 'show', :id => project) 41 | return o.html_safe 42 | end 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /lib/wiki_extensions_projects_helper_patch.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009- Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require_dependency 'projects_helper' 19 | 20 | module WikiExtensionsProjectsHelperPatch 21 | 22 | def project_settings_tabs 23 | tabs = super 24 | action = {:name => 'wiki_extensions', 25 | :controller => 'wiki_extensions_settings', 26 | :action => :show, 27 | :partial => 'wiki_extensions_settings/show', 28 | :label => :wiki_extensions} 29 | 30 | tabs << action if User.current.allowed_to?(action, @project) 31 | 32 | tabs 33 | end 34 | end 35 | 36 | ProjectsHelper.prepend(WikiExtensionsProjectsHelperPatch) 37 | -------------------------------------------------------------------------------- /lib/wiki_extensions_recent_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | module WikiExtensionsRecentMacro 19 | Redmine::WikiFormatting::Macros.register do 20 | desc "Displays a list of pages that were changed recently. " + "'\n\n" + 21 | " !{{recent}}" + "'\n" + 22 | " !{{recent(number_of_days)}}" 23 | macro :recent do |obj, args| 24 | page = obj.page 25 | return nil unless page 26 | project = page.project 27 | return nil unless project 28 | days = 5 29 | days = args[0].strip.to_i if args.length > 0 30 | 31 | return nil if days < 1 32 | 33 | pages = WikiPage.includes(:content).where([" #{WikiPage.table_name}.wiki_id = ? and #{WikiContent.table_name}.updated_on > ?", page.wiki_id, Date.today - days]) 34 | .order("#{WikiContent.table_name}.updated_on desc") 35 | o = '- ' 40 | ret << '' if formats.include?(:html) 41 | else 42 | ret << '
- ' 43 | end 44 | 45 | if formats.include?(:html) 46 | ret << '
" 137 | end 138 | end 139 | end 140 | ret << "' 47 | 48 | if k != 25 && User.current.allowed_to?({controller: 'wiki_extensions', action: 'reply_comment'}, @project) 49 | reply_link = link_to_function(l(:button_reply), "$('##{form_reply_id}').show();", :class => 'icon icon-comment') 50 | ret << reply_link 51 | end 52 | 53 | edit_link = link_to_function(l(:button_edit), "$('##{text_div_id}').hide();$('##{form_div_id}').show();$('##{form_reply_id}').hide();",:class => 'icon icon-edit wiki_font_size') 54 | ret << edit_link if User.current.allowed_to?({:controller => 'wiki_extensions', :action => 'update_comment'}, @project) or User.current.id == comment.user.id or User.current.admin 55 | if User.current.allowed_to?({:controller => 'wiki_extensions', :action => 'destroy_comment'}, @project) or User.current.admin 56 | del_link = link_to_if_authorized(l(:button_delete), {:controller => 'wiki_extensions', 57 | :action => 'destroy_comment', :id => @project, :comment_id => comment.id}, 58 | :class => "icon icon-del", :confirm => l(:text_are_you_sure)) 59 | ret << (del_link || '') 60 | end 61 | 62 | ret << "\n" 63 | ret << "\n" 64 | end 65 | 66 | ret << '' 67 | ret << "#{avatar(comment.user, :size => "20")}" 68 | ret << "\n" 69 | 70 | if l(:this_is_gloc_lib) == 'this_is_gloc_lib' 71 | ret << l(:label_added_time_by, comment.user, distance_of_time_in_words(Time.now,comment.updated_at)) 72 | else 73 | ret << l(:label_added_time_by, :author => comment.user, :age => distance_of_time_in_words(Time.now, comment.updated_at)) 74 | end 75 | ret << "
\n" 76 | ret << '' + "\n" 77 | ret << '" 134 | 135 | ret << display_comments_tree(comments_tree, comment.id,page,data,k) unless check 136 | ret << "' 78 | ret << textilizable(comment, :comment) 79 | ret << '' 80 | 81 | if formats.include?(:html) 82 | ret << "\n" 83 | ret << ' ' 108 | 109 | ret << ' ' 131 | end 132 | 133 | ret << "' 36 | date = nil 37 | pages.each {|page| 38 | content = page.content 39 | updated_on = Date.new(content.updated_on.year, content.updated_on.month, content.updated_on.day) 40 | if date != updated_on 41 | date = updated_on 42 | o << "" + format_date(date) + "' 48 | return o.html_safe 49 | end 50 | end 51 | end 52 | 53 | -------------------------------------------------------------------------------- /lib/wiki_extensions_taggedpages_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2010-2013 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsTaggedpagesMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Displays pages that have specified tag.\n\n"+ 22 | " !{{taggedpages(tagname)}}\n" + 23 | " !{{taggedpages(tagname, project)}}\n" 24 | macro :taggedpages do |obj, args| 25 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 26 | return nil unless WikiExtensionsUtil.tag_enabled?(@project) 27 | 28 | return nil if args.length < 1 29 | tag_names = [] 30 | if (args.length == 1) 31 | tag_names << args[0].strip 32 | project = @project 33 | else 34 | project = Project.find_by_name(args.pop.strip) 35 | args.each{|arg| 36 | tag_names << arg.strip 37 | } 38 | end 39 | 40 | tagged_pages = [] 41 | and_op = false 42 | if (tag_names.length > 1 and tag_names[0] == 'and') 43 | and_op = true 44 | tag_names.delete_at 0 45 | end 46 | first_time = true 47 | tag_names.each {|tag_name| 48 | tag = WikiExtensionsTag.where(:project_id => project.id).where(:name => tag_name).first 49 | if and_op 50 | if tag 51 | if first_time 52 | tagged_pages = tag.pages 53 | first_time = false 54 | else 55 | tagged_pages = tagged_pages & tag.pages 56 | end 57 | else 58 | tagged_pages = [] 59 | end 60 | else 61 | tagged_pages = tagged_pages | tag.pages if tag 62 | end 63 | } 64 | 65 | o = '
" 43 | end 44 | o << link_to(content.page.pretty_title, :controller => 'wiki', :action => 'show', :project_id => content.page.project, :id => content.page.title) 45 | o << '
' 46 | } 47 | o << '' 66 | tagged_pages.uniq.sort{|a, b| a.pretty_title <=> b.pretty_title}.each{|page| 67 | o << '
' 70 | return o.html_safe 71 | end 72 | end 73 | end 74 | 75 | -------------------------------------------------------------------------------- /lib/wiki_extensions_tags_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2014 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsTagsMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Displays tags.\n\n"+ 22 | " !{{tags}}\n" 23 | macro :tags do |obj, args| 24 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 25 | return nil unless WikiExtensionsUtil.tag_enabled?(@project) 26 | page = obj.page 27 | return unless page 28 | project = page.project 29 | 30 | return '' if page.wiki_ext_tags.empty? 31 | 32 | o = ' ' 38 | return o.html_safe 39 | end 40 | end 41 | 42 | Redmine::WikiFormatting::Macros.register do 43 | desc "Displays tagcloud.\n\n"+ 44 | " !{{tagcloud}}\n" 45 | macro :tagcloud do |obj, args| 46 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 47 | return nil unless WikiExtensionsUtil.tag_enabled?(@project) 48 | classes = %w(tag_level1 tag_level2 tag_level3 tag_level4 tag_level5) 49 | page = obj.page 50 | return unless page 51 | project = page.project 52 | o = '- ' + link_to(page.pretty_title, :controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title) + '
' 68 | } 69 | o << '' + l(:label_wikiextensions_tags) + '
' 53 | tags = WikiExtensionsTag.where(:project_id => project.id).all 54 | return '' if tags.empty? 55 | max_count = tags.sort{|a, b| a.page_count <=> b.page_count}.last.page_count.to_f 56 | tags.sort.each{|tag| 57 | index = ((tag.page_count / max_count) * (classes.size - 1)).round 58 | o << link_to("#{tag.name}(#{tag.page_count})", {:controller => 'wiki_extensions', 59 | :action => 'tag', :id => project, :tag_id => tag.id}, :class => classes[index]) 60 | o << ' ' 61 | } 62 | return o.html_safe 63 | end 64 | end 65 | end 66 | -------------------------------------------------------------------------------- /lib/wiki_extensions_twitter_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsTwitterMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Creates link to twitter account page.\n\n" + 22 | " !{{twitter(user_name)}}\n" 23 | macro :twitter do |obj, args| 24 | 25 | return nil if args.length < 1 26 | user_name = args[0].strip 27 | o = "" 28 | o << link_to(h("@#{user_name}"), "http://www.twitter.com/#{user_name}") 29 | return o.html_safe 30 | end 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /lib/wiki_extensions_util.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2014 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | class WikiExtensionsUtil 19 | def WikiExtensionsUtil.is_enabled?(project) 20 | return false unless project 21 | project.module_enabled? 'wiki_extensions' 22 | end 23 | 24 | def WikiExtensionsUtil.tag_enabled?(project) 25 | return false unless project 26 | setting = WikiExtensionsSetting.find_or_create(project.id) 27 | !setting.tag_disabled 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/wiki_extensions_vote_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2010-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsVoteMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Vote macro.\n\n"+ 22 | " !{{vote(key)}}\n" + 23 | " !{{vote(key, label)}}\n" 24 | macro :vote do |obj, args| 25 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 26 | 27 | return nil if args.length < 1 28 | key = args[0].strip 29 | label = l(:wiki_extensions_vote) 30 | label = args[1].strip if args.length > 1 31 | voteid = "wikiext-vote-#{rand(9999999)}" 32 | vote = WikiExtensionsVote.find_or_create(obj.class.name, obj.id, key) 33 | 34 | o = '' 35 | url = url_for({:controller => 'wiki_extensions', :action => 'vote', 36 | :id => @project, :target_class_name => obj.class.name, :target_id => obj.id, 37 | :key => key, :url => @_request.url}) 38 | o << link_to_function(label, "$('##{voteid}').load('#{url}')") 39 | o << ' ' 40 | o << " #{vote.count}" 41 | o << '' 42 | o << '' 43 | return o.html_safe 44 | end 45 | end 46 | 47 | Redmine::WikiFormatting::Macros.register do 48 | desc "Display result of vote macro.\n\n"+ 49 | " !{{show_vote(key)}}\n" 50 | macro :show_vote do |obj, args| 51 | return nil unless WikiExtensionsUtil.is_enabled?(@project) 52 | 53 | return nil if args.length < 1 54 | key = args[0].strip 55 | vote = WikiExtensionsVote.find_or_create(obj.class.name, obj.id, key) 56 | 57 | o = '' 58 | o << "#{vote.count}" 59 | o << '' 60 | return o.html_safe 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /lib/wiki_extensions_wiki_controller_patch.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2013 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require_dependency 'wiki_controller' 19 | 20 | class WikiController 21 | after_action :wiki_extensions_save_tags, :only => [:edit, :update] 22 | end 23 | 24 | module WikiExtensionsWikiControllerPatch 25 | def render(args = nil) 26 | if args and @project and WikiExtensionsUtil.is_enabled?(@project) and @content 27 | if (args.class == Hash and args[:partial] == 'common/preview') 28 | WikiExtensionsFootnote.preview_page.wiki_extension_data[:footnotes] = [] 29 | end 30 | end 31 | super(args) 32 | end 33 | 34 | def respond_to(&block) 35 | if @project and WikiExtensionsUtil.is_enabled?(@project) and @content 36 | if (@_action_name == 'show') 37 | wiki_extensions_include_header 38 | wiki_extensions_add_fnlist 39 | wiki_extensions_include_footer 40 | end 41 | end 42 | super(&block) 43 | end 44 | 45 | def wiki_extensions_get_current_page 46 | @page 47 | end 48 | 49 | private 50 | 51 | def wiki_extensions_save_tags 52 | return true if request.get? 53 | 54 | extension = params[:extension] 55 | return true unless extension 56 | 57 | tags = extension[:tags] 58 | 59 | @page.set_tags(tags) 60 | end 61 | 62 | def wiki_extensions_add_fnlist 63 | text = @content.text 64 | text << "\n\n{{fnlist}}\n" 65 | end 66 | 67 | def wiki_extensions_include_header 68 | return if @page.title == 'Header' || @page.title == 'Footer' 69 | header = @wiki.find_page('Header') 70 | return unless header 71 | text = "\n" 72 | text << '' 73 | text << "\n\n" 74 | text << header.content.text 75 | text << "\n\n" 76 | text << "\n\n" 77 | text << @content.text 78 | @content.text = text 79 | 80 | end 81 | 82 | def wiki_extensions_include_footer 83 | return if @page.title == 'Footer' || @page.title == 'Header' 84 | footer = @wiki.find_page('Footer') 85 | return unless footer 86 | text = @content.text 87 | text << "\n" 88 | text << ' " 92 | 93 | end 94 | end 95 | 96 | WikiController.prepend(WikiExtensionsWikiControllerPatch) 97 | 98 | 99 | -------------------------------------------------------------------------------- /lib/wiki_extensions_wiki_macro.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require 'redmine' 18 | 19 | module WikiExtensionsWikiMacro 20 | Redmine::WikiFormatting::Macros.register do 21 | desc "Link to wiki page of other project.\n\n"+ 22 | " !{{wiki(project_name, wiki_page)}}\n" + 23 | " !{{wiki(project_name, wiki_page, alias)}}\n" + 24 | " !{{wiki(project_identifier, wiki_page)}}\n" + 25 | " !{{wiki(project_identifier, wiki_page, alias)}}\n" 26 | macro :wiki do |obj, args| 27 | return nil unless WikiExtensionsUtil.is_enabled?(@project) if @project 28 | return nil if args.length < 2 29 | project_name = args[0].strip 30 | page_name = args[1].strip 31 | if (args[2]) 32 | alias_name = args[2].strip 33 | else 34 | alias_name = page_name 35 | end 36 | project = Project.find_by_name(project_name) 37 | project = Project.find_by_identifier(project_name) unless project 38 | return nil unless project 39 | wiki = Wiki.find_by_project_id(project.id) 40 | return nil unless wiki 41 | page = wiki.find_page(page_name) 42 | return nil unless page 43 | 44 | o = "" 45 | o << link_to(alias_name, :controller => 'wiki', :action => 'show', :project_id => project, :id => page_name) 46 | return o.html_safe 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /lib/wiki_extensions_wiki_page_patch.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2024 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require_dependency 'wiki_page' 18 | 19 | class WikiPage 20 | has_many :wiki_extensions_tag_relations, :dependent => :destroy 21 | has_many :wiki_ext_tags, :class_name => 'WikiExtensionsTag', :through => :wiki_extensions_tag_relations, :source => :tag 22 | has_one :wiki_extensions_count, :foreign_key => :page_id, :dependent => :destroy 23 | end 24 | 25 | module WikiExtensionsWikiPagePatch 26 | def wiki_extension_data 27 | @wiki_extension_data ||= {} 28 | end 29 | 30 | def set_tags(tag_list = {}) 31 | tag_array = [] 32 | tag_list.each_pair{|num, name| 33 | next if name.blank? 34 | tag_array << name.strip 35 | } 36 | 37 | tag_array = tag_array.uniq 38 | 39 | wiki_extensions_tag_relations.each {|relation| 40 | relation.destroy 41 | } 42 | 43 | tag_array.each{|name| 44 | tag = WikiExtensionsTag.find_or_create(self.project.id, name) 45 | relation = WikiExtensionsTagRelation.new 46 | relation.tag = tag 47 | relation.wiki_page_id = self.id 48 | relation.save 49 | } 50 | end 51 | 52 | end 53 | 54 | WikiPage.prepend(WikiExtensionsWikiPagePatch) 55 | 56 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_comments.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | wiki_page_id: 1 6 | 7 | user_id: 1 8 | 9 | comment: MyText 10 | 11 | created_at: 2009-06-04 23:33:48 12 | 13 | updated_at: 2009-06-04 23:33:48 14 | 15 | two: 16 | id: 2 17 | 18 | wiki_page_id: 1 19 | 20 | user_id: 1 21 | 22 | comment: MyText 23 | 24 | created_at: 2009-06-04 23:33:48 25 | 26 | updated_at: 2009-06-04 23:33:48 27 | 28 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_counts.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | project_id: 1 6 | 7 | page_id: 1 8 | 9 | date: 2009-10-26 10 | 11 | count: 1 12 | 13 | two: 14 | id: 2 15 | 16 | project_id: 1 17 | 18 | page_id: 1 19 | 20 | date: 2009-10-26 21 | 22 | count: 1 23 | 24 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_menus.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | project_id: 1 6 | 7 | page_name: MyString 8 | 9 | enabled: true 10 | menu_no: 1 11 | title: hoge 12 | 13 | two: 14 | id: 2 15 | 16 | project_id: 1 17 | 18 | page_name: MyString1 19 | 20 | enabled: false 21 | menu_no: 2 22 | title: bar 23 | 24 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_settings.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | project_id: 1 6 | 7 | created_at: 2009-09-04 13:49:17 8 | 9 | updated_at: 2009-09-04 13:49:17 10 | 11 | lock_version: 1 12 | 13 | two: 14 | id: 2 15 | 16 | project_id: 1 17 | 18 | created_at: 2009-09-04 13:49:17 19 | 20 | updated_at: 2009-09-04 13:49:17 21 | 22 | lock_version: 1 23 | 24 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_tag_relations.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | tag_id: 1 6 | 7 | wiki_page_id: 1 8 | 9 | created_at: 2009-06-13 10:08:53 10 | 11 | two: 12 | id: 2 13 | 14 | tag_id: 1 15 | 16 | wiki_page_id: 1 17 | 18 | created_at: 2009-06-13 10:08:53 19 | 20 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_tags.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | name: MyString 6 | 7 | created_at: 2009-06-13 10:07:48 8 | 9 | project_id: 1 10 | 11 | two: 12 | id: 2 13 | 14 | name: MyString2 15 | 16 | created_at: 2009-06-13 10:07:48 17 | 18 | project_id: 1 19 | 20 | three: 21 | id: 3 22 | 23 | name: MyString2 24 | 25 | created_at: 2009-06-13 10:07:48 26 | 27 | project_id: 2 28 | 29 | -------------------------------------------------------------------------------- /test/fixtures/wiki_extensions_votes.yml: -------------------------------------------------------------------------------- 1 | # Read about fixtures at http://ar.rubyonrails.org/classes/Fixtures.html 2 | one: 3 | id: 1 4 | 5 | keystr: MyString 6 | 7 | target_class_name: MyString 8 | 9 | target_id: 1 10 | 11 | count: 1 12 | 13 | two: 14 | id: 2 15 | 16 | keystr: MyString 17 | 18 | target_class_name: MyString 19 | 20 | target_id: 1 21 | 22 | count: 1 23 | 24 | -------------------------------------------------------------------------------- /test/functional/wiki_controller_test.rb: -------------------------------------------------------------------------------- 1 | # Code Review plugin for Redmine 2 | # Copyright (C) 2009-2017 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require File.dirname(__FILE__) + '/../test_helper' 18 | 19 | class WikiControllerTest < ActionController::TestCase 20 | fixtures :projects, :users, :roles, :members, :enabled_modules, :wikis, 21 | :wiki_pages, :wiki_contents, :wiki_content_versions, :attachments, 22 | :wiki_extensions_comments, :wiki_extensions_tags 23 | 24 | def setup 25 | @controller = WikiController.new 26 | @request = ActionController::TestRequest.create(self.class.controller_class) 27 | #@response = ActionController::TestResponse.new 28 | @request.env['HTTP_REFERER'] = '/' 29 | @project = Project.find(1) 30 | @wiki = @project.wiki 31 | @page_name = 'macro_test' 32 | @page = @wiki.find_or_new_page(@page_name) 33 | @page.content = WikiContent.new 34 | @page.content.text = 'test' 35 | @page.save! 36 | side_bar = @wiki.find_or_new_page('SideBar') 37 | side_bar.content = WikiContent.new 38 | side_bar.content.text = 'test' 39 | side_bar.save! 40 | header = @wiki.find_or_new_page('Header') 41 | header.content = WikiContent.new 42 | header.content.text = 'test' 43 | header.save! 44 | footer = @wiki.find_or_new_page('Footer') 45 | footer.content = WikiContent.new 46 | footer.content.text = 'test' 47 | footer.save! 48 | style_sheet = @wiki.find_or_new_page('StyleSheet') 49 | style_sheet.content = WikiContent.new 50 | style_sheet.content.text = 'test' 51 | style_sheet.save! 52 | enabled_module = EnabledModule.new 53 | enabled_module.project_id = 1 54 | enabled_module.name = 'wiki_extensions' 55 | enabled_module.save 56 | end 57 | 58 | def test_comment_form 59 | text = '{{comment_form}}' 60 | text << "\n" 61 | text << '{{comments}}' 62 | setContent(text) 63 | @request.session[:user_id] = 1 64 | get :show, :params => { :project_id => 1, :id => @page_name } 65 | assert_response :success 66 | end 67 | 68 | def test_comments 69 | text = '{{comments}}' 70 | setContent(text) 71 | comment = WikiExtensionsComment.new 72 | comment.wiki_page_id = @page.id 73 | comment.user_id = 1 74 | comment.comment = 'aaa' 75 | comment.save! 76 | @request.session[:user_id] = 1 77 | get :show, :params => { :project_id => 1, :id => @page_name } 78 | assert_response :success 79 | end 80 | 81 | def test_div 82 | @request.session[:user_id] = 1 83 | text = "{{div_start_tag(foo)}}\n" 84 | text << "{{div_end_tag}}\n" 85 | text << "{{div_start_tag(var, hoge)}}\n" 86 | text << "{{div_end_tag}}\n" 87 | setContent(text) 88 | @request.session[:user_id] = 1 89 | get :show, :params => { :project_id => 1, :id => @page_name } 90 | assert_response :success 91 | end 92 | 93 | def test_footnote 94 | text = "{{fn(aaa,bbb)}}\n" 95 | text << "{{fn(ccc,ddd)}}\n" 96 | text << "{{fnlist}}\n" 97 | setContent(text) 98 | @request.session[:user_id] = 1 99 | get :show, :params => { :project_id => 1, :id => @page_name } 100 | assert_response :success 101 | end 102 | 103 | def test_new 104 | text = "{{new(#{Date.today.to_s})}}\n" 105 | text << "{{new(#{(Date.today - 1).to_s})}}\n" 106 | text << "{{new(#{(Date.today - 2).to_s})}}\n" 107 | text << "{{new(2009-03-01, 4)}}\n" 108 | setContent(text) 109 | @request.session[:user_id] = 1 110 | get :show, :params => { :project_id => 1, :id => @page_name } 111 | assert_response :success 112 | end 113 | 114 | def test_project 115 | text = "{{project(#{@project.name})}}\n" 116 | text << "{{project(#{@project.id})}}\n" 117 | text << "{{project(#{@project.name}, hoge)}}\n" 118 | text << "{{project(#{@project.id}), bar}}\n" 119 | setContent(text) 120 | @request.session[:user_id] = 1 121 | get :show, :params => { :project_id => 1, :id => @page_name } 122 | assert_response :success 123 | end 124 | 125 | def test_tags 126 | page = @wiki.find_or_new_page(@page_name) 127 | page.wiki_ext_tags << WikiExtensionsTag.find(1) 128 | page.save! 129 | text = "{{tags}}\n" 130 | text << "{{tagcloud}}\n" 131 | setContent(text) 132 | @request.session[:user_id] = 1 133 | get :show, :params => { :project_id => 1, :id => @page_name } 134 | assert_response :success 135 | end 136 | 137 | def test_wiki 138 | text = '' 139 | text << "{{wiki(#{@project.name}, #{@page_name})}}\n" 140 | text << "{{wiki(#{@project.name}, #{@page_name}, foo)}}\n" 141 | text << "{{wiki(#{@project.id}, #{@page_name})}}\n" 142 | text << "{{wiki(#{@project.id}, #{@page_name}, bar)}}\n" 143 | setContent(text) 144 | @request.session[:user_id] = 1 145 | get :show, :params => { :project_id => 1, :id => @page_name } 146 | assert_response :success 147 | end 148 | 149 | def test_edit 150 | @request.session[:user_id] = 1 151 | get :edit, :params => { :project_id => 1, :id => @page_name } 152 | assert_response :success 153 | 154 | post :edit, :params => { :project_id => 1, :id => @page_name, :content => { :text => 'aaa' }, 155 | :extension => { :tags => { '0' => 'aaa', '1' => 'bbb' } } } 156 | assert_response :success 157 | end 158 | 159 | def test_recent 160 | text = '' 161 | text << "{{recent}}\n" 162 | text << "{{recent(10)}}\n" 163 | 164 | setContent(text) 165 | @request.session[:user_id] = 1 166 | get :show, :params => { :project_id => 1, :id => @page_name } 167 | assert_response :success 168 | end 169 | 170 | def test_lastupdated_by 171 | text = '' 172 | text << "{{lastupdated_by}}\n" 173 | 174 | setContent(text) 175 | @request.session[:user_id] = 1 176 | get :show, :params => { :project_id => 1, :id => @page_name } 177 | assert_response :success 178 | end 179 | 180 | def test_lastupdated_at 181 | text = '' 182 | text << "{{lastupdated_at}}\n" 183 | 184 | setContent(text) 185 | @request.session[:user_id] = 1 186 | get :show, :params => { :project_id => 1, :id => @page_name } 187 | assert_response :success 188 | end 189 | 190 | def test_iframe 191 | text = '' 192 | text << "{{iframe(http://google.com, 200, 400)}}\n" 193 | text << "{{iframe(http://google.com, 200, 400, no)}}\n" 194 | 195 | setContent(text) 196 | @request.session[:user_id] = 1 197 | get :show, :params => { :project_id => 1, :id => @page_name } 198 | assert_response :success 199 | end 200 | 201 | context 'count' do 202 | should 'success' do 203 | @request.session[:user_id] = 1 204 | text = '' 205 | text << "{{count}}\n" 206 | 207 | setContent(text) 208 | @request.session[:user_id] = 1 209 | get :show, :params => { :project_id => 1, :id => @page_name } 210 | assert_response :success 211 | end 212 | end 213 | 214 | context 'show_count' do 215 | should 'success' do 216 | text = '' 217 | text << "{{show_count}}\n" 218 | 219 | setContent(text) 220 | @request.session[:user_id] = 1 221 | get :show, :params => { :project_id => 1, :id => @page_name } 222 | assert_response :success 223 | end 224 | end 225 | 226 | context 'popularity' do 227 | should 'success if there is no count data' do 228 | text = '' 229 | text << "{{popularity}}\n" 230 | 231 | setContent(text) 232 | @request.session[:user_id] = 1 233 | get :show, :params => { :project_id => 1, :id => @page_name } 234 | assert_response :success 235 | end 236 | 237 | should 'success if there is count data' do 238 | text = '' 239 | text << "{{count}}\n" 240 | text << "{{popularity}}\n" 241 | 242 | setContent(text) 243 | @request.session[:user_id] = 1 244 | get :show, :params => { :project_id => 1, :id => @page_name } 245 | assert_response :success 246 | end 247 | end 248 | 249 | context 'vote' do 250 | should 'success' do 251 | text = '' 252 | text << "{{vote(aaa)}}\n" 253 | 254 | setContent(text) 255 | @request.session[:user_id] = 1 256 | get :show, :params => { :project_id => 1, :id => @page_name } 257 | assert_response :success 258 | end 259 | end 260 | 261 | context 'show_vote' do 262 | should 'success' do 263 | text = '' 264 | text << "{{show_vote(aaa)}}\n" 265 | 266 | setContent(text) 267 | @request.session[:user_id] = 1 268 | get :show, :params => { :project_id => 1, :id => @page_name } 269 | assert_response :success 270 | end 271 | end 272 | 273 | context 'twitter' do 274 | should 'success' do 275 | text = '' 276 | text << "{{twitter(haru_iida)}}\n" 277 | 278 | setContent(text) 279 | @request.session[:user_id] = 1 280 | get :show, :params => { :project_id => 1, :id => @page_name } 281 | assert_response :success 282 | end 283 | end 284 | 285 | context 'taggedpages' do 286 | should 'success' do 287 | text = '' 288 | text << "{{taggedpages(aaa)}}\n" 289 | 290 | setContent(text) 291 | @request.session[:user_id] = 1 292 | get :show, :params => { :project_id => 1, :id => @page_name } 293 | assert_response :success 294 | end 295 | end 296 | 297 | context 'page_break' do 298 | setup do 299 | setContent("{{page_break}}\n") 300 | 301 | @request.session[:user_id] = 1 302 | get :show, :params => { :project_id => 1, :id => @page_name } 303 | end 304 | 305 | should 'success' do 306 | assert_response :success 307 | end 308 | 309 | should 'be rendered correctly' do 310 | assert response.body.include?('') 311 | end 312 | end 313 | 314 | private 315 | 316 | def setContent(text) 317 | page = @wiki.find_or_new_page(@page_name) 318 | page.content.text = text 319 | page.content.author_id = 1 320 | page.save! 321 | page.content.save! 322 | end 323 | end 324 | -------------------------------------------------------------------------------- /test/functional/wiki_extensions_controller_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2019 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require File.dirname(__FILE__) + '/../test_helper' 18 | 19 | class WikiExtensionsControllerTest < ActionController::TestCase 20 | fixtures :projects, :users, :roles, :members, :enabled_modules, :wikis, 21 | :wiki_pages, :wiki_contents, :wiki_content_versions, :attachments, 22 | :wiki_extensions_comments, :wiki_extensions_tags, :wiki_extensions_menus, 23 | :wiki_extensions_votes 24 | 25 | def setup 26 | @controller = WikiExtensionsController.new 27 | @request = ActionController::TestRequest.create(self.class.controller_class) 28 | #@response = ActionController::TestResponse.new 29 | @request.env['HTTP_REFERER'] = '/' 30 | @project = Project.find(1) 31 | @wiki = @project.wiki 32 | @page_name = 'macro_test' 33 | @page = @wiki.find_or_new_page(@page_name) 34 | @page.content = WikiContent.new 35 | @page.content.text = '{{comments}}' 36 | @page.save! 37 | side_bar = @wiki.find_or_new_page('SideBar') 38 | side_bar.content = WikiContent.new 39 | side_bar.content.text = 'test' 40 | side_bar.save! 41 | style_sheet = @wiki.find_or_new_page('StyleSheet') 42 | style_sheet.content = WikiContent.new 43 | style_sheet.content.text = 'test' 44 | style_sheet.save! 45 | enabled_module = EnabledModule.new 46 | enabled_module.project_id = 1 47 | enabled_module.name = 'wiki_extensions' 48 | enabled_module.save 49 | end 50 | 51 | def test_add_comment 52 | @request.session[:user_id] = 1 53 | post :add_comment, :params => { :id => 1, :wiki_page_id => @page.id, :comment => 'aaa' } 54 | assert_response :redirect 55 | end 56 | 57 | def test_tag 58 | @request.session[:user_id] = 1 59 | get :tag, :params => { :id => 1, :tag_id => 1 } 60 | #assert assigns[:tag] 61 | end 62 | 63 | def test_destroy_comment 64 | comment = WikiExtensionsComment.new 65 | comment.wiki_page_id = @page.id 66 | comment.user_id = 1 67 | comment.comment = 'aaa' 68 | comment.save! 69 | @request.session[:user_id] = 1 70 | post :destroy_comment, :params => { :id => 1, :comment_id => comment.id } 71 | assert_response :redirect 72 | comment = WikiExtensionsComment.where(:id => comment.id).first 73 | assert_nil(comment) 74 | end 75 | 76 | def test_update_comment 77 | comment = WikiExtensionsComment.new 78 | comment.wiki_page_id = @page.id 79 | comment.user_id = 1 80 | comment.comment = 'aaa' 81 | comment.save! 82 | message = 'newcomment' 83 | @request.session[:user_id] = 1 84 | post :update_comment, :params => { :id => 1, :comment_id => comment.id, :comment => message } 85 | assert_response :redirect 86 | comment = WikiExtensionsComment.find(comment.id) 87 | assert_equal(message, comment.comment) 88 | end 89 | 90 | def test_forwad_wiki_page 91 | @request.session[:user_id] = 1 92 | get :forward_wiki_page, :params => { :id => 1, :menu_id => 1 } 93 | assert_response :redirect 94 | end 95 | 96 | def test_stylesheet 97 | @project.is_public = false 98 | @project.save! 99 | get :stylesheet, :params => { :id => 1 } 100 | assert_response 403 101 | 102 | @request.session[:user_id] = 1 103 | get :stylesheet, :params => { :id => 1 } 104 | assert_response :success 105 | 106 | get :stylesheet, :params => { :id => 2 } 107 | assert_response 404 108 | end 109 | 110 | context 'vote' do 111 | should 'success if new vote.' do 112 | @request.session[:user_id] = 1 113 | count = WikiExtensionsVote.all.length 114 | post :vote, :params => { :id => 1, :target_class_name => 'Project', :target_id => 1, 115 | :key => 'aaa', :url => 'http://localhost:3000' } 116 | assert_equal(count + 1, WikiExtensionsVote.all.length) 117 | assert_response :success 118 | end 119 | end 120 | end 121 | -------------------------------------------------------------------------------- /test/functional/wiki_extensions_settings_controller_test.rb: -------------------------------------------------------------------------------- 1 | # Code Review plugin for Redmine 2 | # Copyright (C) 2009-2017 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require File.dirname(__FILE__) + '/../test_helper' 18 | 19 | class WikiExtensionsSettingsControllerTest < ActionController::TestCase 20 | fixtures :projects, :users, :roles, :members, :enabled_modules, :wikis, 21 | :wiki_pages, :wiki_contents, :wiki_content_versions, :attachments, 22 | :wiki_extensions_comments, :wiki_extensions_tags, :wiki_extensions_menus, 23 | :wiki_extensions_votes, :wiki_extensions_settings 24 | 25 | def setup 26 | @controller = WikiExtensionsSettingsController.new 27 | @request = ActionController::TestRequest.create(self.class.controller_class) 28 | #@response = ActionController::TestResponse.new 29 | @request.env["HTTP_REFERER"] = '/' 30 | @request.session[:user_id] = 1 31 | @project = Project.find(1) 32 | 33 | enabled_module = EnabledModule.new 34 | enabled_module.project_id = 1 35 | enabled_module.name = 'wiki_extensions' 36 | enabled_module.save 37 | end 38 | 39 | context "update" do 40 | should "save settings." do 41 | menus = {} 42 | menus[0] = {:enabled => 'true',:menu_no => 1, :title => 'my_title', :page_name => 'my_page_name'} 43 | menus[1] = {:enabled => 'true',:menu_no => 2, :title => 'my_title2', :page_name => 'my_page_name2'} 44 | post :update, :params => { 45 | :menus => menus, :id => @project} 46 | assert_response :redirect 47 | setting = WikiExtensionsSetting.find_or_create @project.id 48 | assert_equal(false, setting.auto_preview_enabled) 49 | menus = setting.menus 50 | assert_equal(5, menus.length) 51 | assert(menus[0].enabled) 52 | assert_equal('my_title', menus[0].title) 53 | assert_equal('my_page_name', menus[0].page_name) 54 | assert(menus[1].enabled) 55 | assert_equal('my_title2', menus[1].title) 56 | assert_equal('my_page_name2', menus[1].page_name) 57 | 58 | menus = {} 59 | menus[0] = {:enabled => 'true',:menu_no => 1, :title => 'my_title', :page_name => 'my_page_name'} 60 | menus[1] = {:menu_no => 2} 61 | post :update, :params => { 62 | :menus => menus, :id => @project} 63 | assert_response :redirect 64 | setting = WikiExtensionsSetting.find_or_create @project.id 65 | menus = setting.menus 66 | assert(menus[0].enabled) 67 | assert(!menus[1].enabled) 68 | 69 | end 70 | end 71 | 72 | end 73 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | require 'rails' 2 | require 'simplecov' 3 | require 'shoulda' 4 | require 'simplecov-lcov' 5 | 6 | 7 | SimpleCov::Formatter::LcovFormatter.config do |config| 8 | config.report_with_single_file = true 9 | config.single_report_path = File.expand_path(File.dirname(__FILE__) + '/../coverage/lcov.info') 10 | end 11 | 12 | SimpleCov.formatter = SimpleCov::Formatter::MultiFormatter[ 13 | SimpleCov::Formatter::LcovFormatter, 14 | SimpleCov::Formatter::HTMLFormatter 15 | ] 16 | 17 | SimpleCov.start do 18 | root File.expand_path(File.dirname(__FILE__) + '/..') 19 | add_filter "/test/" 20 | end 21 | 22 | # Load the normal Rails helper 23 | require File.expand_path(File.dirname(__FILE__) + '/../../../test/test_helper') 24 | 25 | fixtures = [] 26 | Dir.chdir(File.dirname(__FILE__) + '/fixtures/') do 27 | fixtures = Dir.glob('*.yml').map{|s| s.gsub(/.yml$/, '')} 28 | end 29 | ActiveRecord::FixtureSet.create_fixtures(File.dirname(__FILE__) + '/fixtures/', fixtures) 30 | 31 | # Ensure that we are using the temporary fixture path 32 | #Engines::Testing.set_fixture_path 33 | -------------------------------------------------------------------------------- /test/test_runner.rb: -------------------------------------------------------------------------------- 1 | # Code Review plugin for Redmine 2 | # Copyright (C) 2012 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | 19 | require 'simplecov' 20 | require 'simplecov-rcov' 21 | SimpleCov.formatter = SimpleCov::Formatter::RcovFormatter 22 | SimpleCov.start 23 | 24 | require 'fileutils' 25 | testdir = File.dirname(File.expand_path(__FILE__)) 26 | 27 | Dir::chdir("#{testdir}/..") 28 | 29 | require "#{testdir}/test_helper" 30 | 31 | Dir::glob("#{testdir}/fixtures/*.yml").each {|f| 32 | FileUtils.copy(f, "#{testdir}/../../../test/fixtures/") 33 | } 34 | 35 | Dir::glob("#{testdir}/**/*test.rb").each {|f| 36 | require f 37 | } -------------------------------------------------------------------------------- /test/unit/emoticons_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | require "wiki_extensions_emoticons" 20 | 21 | class EmoticonsTest < ActiveSupport::TestCase 22 | fixtures :wiki_extensions_comments 23 | 24 | context "emoticons" do 25 | setup do 26 | @emoticons = WikiExtensionsEmoticons::Emoticons.new 27 | end 28 | 29 | should "not returns nil." do 30 | assert_not_nil(@emoticons.emoticons) 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_comment_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | 20 | class WikiExtensionsCommentTest < ActiveSupport::TestCase 21 | fixtures :wiki_extensions_comments 22 | 23 | # Replace this with your real tests. 24 | def test_truth 25 | assert true 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_count_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | require File.dirname(__FILE__) + '/../test_helper' 18 | 19 | class WikiExtensionsCountTest < ActiveSupport::TestCase 20 | fixtures :wiki_extensions_counts, :projects, :wikis, :wiki_pages 21 | 22 | def test_countup 23 | page_id = 2 24 | assert_equal(0, WikiExtensionsCount.access_count(page_id)) 25 | WikiExtensionsCount.countup(page_id) 26 | assert_equal(1, WikiExtensionsCount.access_count(page_id)) 27 | WikiExtensionsCount.countup(page_id) 28 | assert_equal(2, WikiExtensionsCount.access_count(page_id)) 29 | WikiExtensionsCount.countup(page_id, Date.today - 2) 30 | WikiExtensionsCount.countup(page_id, Date.today - 2) 31 | WikiExtensionsCount.countup(page_id, Date.today - 2) 32 | 33 | assert_equal(5, WikiExtensionsCount.access_count(page_id)) 34 | assert_equal(2, WikiExtensionsCount.access_count(page_id, Date.today)) 35 | end 36 | 37 | def test_popular 38 | WikiExtensionsCount.countup(2) 39 | WikiExtensionsCount.countup(2, Date.today - 1) 40 | WikiExtensionsCount.countup(2, Date.today - 2) 41 | WikiExtensionsCount.countup(2, Date.today - 3) 42 | list = WikiExtensionsCount.popularity(1) 43 | assert_equal(2, list.length) 44 | assert_equal(4, list.to_a[0][1]) 45 | assert_equal(2, list.to_a[1][1]) 46 | list = WikiExtensionsCount.popularity(1, 2) 47 | assert_equal(1, list.length) 48 | assert_equal(2, list.to_a[0][1]) 49 | 50 | end 51 | end 52 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_menu_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | 20 | class WikiExtensionsMenuTest < ActiveSupport::TestCase 21 | fixtures :wiki_extensions_menus, :wiki_extensions_settings 22 | 23 | # Replace this with your real tests. 24 | def test_find_or_create 25 | menu = WikiExtensionsMenu.find_or_create(9, 3) 26 | assert_equal(9, menu.project_id) 27 | assert_equal(3, menu.menu_no) 28 | menu = WikiExtensionsMenu.find_or_create(9, 3) 29 | assert_equal(9, menu.project_id) 30 | end 31 | 32 | def test_title 33 | menu = WikiExtensionsMenu.find_or_create(10, 5) 34 | assert(!WikiExtensionsMenu.title(10, 5)) 35 | menu.page_name = "aaa" 36 | menu.save! 37 | assert_equal("aaa", WikiExtensionsMenu.title(10, 5)) 38 | menu.title = "bbb" 39 | menu.save! 40 | assert_equal("bbb", WikiExtensionsMenu.title(10, 5)) 41 | assert(!WikiExtensionsMenu.title(100, 5)) 42 | end 43 | 44 | def test_enabled? 45 | menu = WikiExtensionsMenu.find_or_create(11, 5) 46 | assert(!WikiExtensionsMenu.enabled?(11, 5)) 47 | menu.enabled = true 48 | menu.save! 49 | assert(!WikiExtensionsMenu.enabled?(11, 5)) 50 | menu.page_name = "aaa" 51 | menu.save! 52 | assert(WikiExtensionsMenu.enabled?(11, 5)) 53 | menu.enabled = false 54 | menu.save! 55 | assert(!WikiExtensionsMenu.enabled?(11, 5)) 56 | assert(!WikiExtensionsMenu.enabled?(111, 5)) 57 | end 58 | end 59 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_setting_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | 20 | class WikiExtensionsSettingTest < ActiveSupport::TestCase 21 | fixtures :wiki_extensions_settings, :wiki_extensions_menus 22 | 23 | def test_find_or_create 24 | assert(!WikiExtensionsSetting.find_by_project_id(5)) 25 | setting = WikiExtensionsSetting.find_or_create(5) 26 | assert_equal(5, setting.project_id) 27 | assert(WikiExtensionsSetting.find_by_project_id(5)) 28 | setting = WikiExtensionsSetting.find_or_create(5) 29 | assert_equal(5, setting.project_id) 30 | end 31 | 32 | def test_menus 33 | setting = WikiExtensionsSetting.find_or_create(6) 34 | assert_equal(5, setting.menus.length) 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_tag_relation_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | 20 | class WikiExtensionsTagRelationTest < ActiveSupport::TestCase 21 | fixtures :wiki_extensions_tag_relations, :wiki_extensions_tags, 22 | :projects, :users, :email_addresses, :roles, :members, :member_roles, 23 | :enabled_modules, :wikis, :wiki_pages, :wiki_contents, 24 | :wiki_content_versions, :attachments, 25 | :issues, :issue_statuses, :trackers 26 | 27 | # Replace this with your real tests. 28 | def test_create 29 | relation = WikiExtensionsTagRelation.new 30 | assert !relation.save 31 | 32 | 33 | tag = WikiExtensionsTag.find_or_create(1, 'bbb') 34 | relation.tag = tag 35 | relation.wiki_page_id = 1 36 | assert relation.save! 37 | 38 | relation.destroy 39 | end 40 | 41 | def test_destroy 42 | tag_name = 'adfafdfadfafdaf' 43 | tag = WikiExtensionsTag.find_or_create(1, tag_name) 44 | relation = WikiExtensionsTagRelation.new 45 | relation.tag = tag 46 | relation.wiki_page_id = 1 47 | assert relation.save! 48 | relation_id = relation.id 49 | tag_id = tag.id 50 | assert_not_nil(WikiExtensionsTag.where(:name => tag_name).first) 51 | assert_not_nil(WikiExtensionsTagRelation.where(:id => relation_id).first) 52 | relation.destroy 53 | assert_nil(WikiExtensionsTagRelation.where(:id => relation_id).first) 54 | assert_nil(WikiExtensionsTag.where(:name => tag_name).first) 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_tag_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2009-2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | 20 | class WikiExtensionsTagTest < ActiveSupport::TestCase 21 | fixtures :wiki_extensions_tags 22 | 23 | # Replace this with your real tests. 24 | def test_equal 25 | tag1 = WikiExtensionsTag.find(1) 26 | tag2 = WikiExtensionsTag.find(2) 27 | tag3 = WikiExtensionsTag.find(3) 28 | assert(!(tag1 == tag2)) 29 | assert(!(tag2 == tag3)) 30 | assert(tag1 == WikiExtensionsTag.find(1)) 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /test/unit/wiki_extensions_vote_test.rb: -------------------------------------------------------------------------------- 1 | # Wiki Extensions plugin for Redmine 2 | # Copyright (C) 2010 Haruyuki Iida 3 | # 4 | # This program is free software; you can redistribute it and/or 5 | # modify it under the terms of the GNU General Public License 6 | # as published by the Free Software Foundation; either version 2 7 | # of the License, or (at your option) any later version. 8 | # 9 | # This program is distributed in the hope that it will be useful, 10 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | # GNU General Public License for more details. 13 | # 14 | # You should have received a copy of the GNU General Public License 15 | # along with this program; if not, write to the Free Software 16 | # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 17 | 18 | require File.dirname(__FILE__) + '/../test_helper' 19 | 20 | class WikiExtensionsVoteTest < ActiveSupport::TestCase 21 | fixtures :wiki_extensions_votes, :projects 22 | 23 | context "target" do 24 | setup do 25 | @vote = WikiExtensionsVote.new 26 | end 27 | 28 | should "return nil when instance initialized." do 29 | assert_nil(@vote.target) 30 | end 31 | 32 | should "return nil if target_class_name is nil" do 33 | @vote.target_id = 1 34 | assert_nil(@vote.target) 35 | end 36 | 37 | should "return nil if target_id is nil" do 38 | @vote.target_class_name = 'Issue' 39 | assert_nil(@vote.target) 40 | end 41 | 42 | should "return object if target_class_name and target_id were setted." do 43 | project = Project.find(1) 44 | @vote.target_class_name = project.class.name 45 | @vote.target_id = project.id 46 | project2 = @vote.target 47 | assert_equal(project.class.name, project2.class.name) 48 | assert_equal(project.id, project2.id) 49 | end 50 | end 51 | 52 | context "target=" do 53 | setup do 54 | @vote = WikiExtensionsVote.new 55 | @project = Project.find(1) 56 | end 57 | 58 | should "set target_class_name" do 59 | @vote.target = @project 60 | assert_equal(@project.class.name, @vote.target_class_name) 61 | end 62 | 63 | should "set target_id" do 64 | @vote.target = @project 65 | assert_equal(@project.id, @vote.target_id) 66 | end 67 | end 68 | 69 | context "save" do 70 | setup do 71 | @vote = WikiExtensionsVote.new 72 | @project = Project.find(1) 73 | end 74 | 75 | should "save" do 76 | @vote.target = @project 77 | @vote.count = 1 78 | @vote.keystr = "aaa" 79 | @vote.save! 80 | vote2 = WikiExtensionsVote.find(@vote.id) 81 | assert_equal(@vote.id, vote2.id) 82 | assert_equal(@project, vote2.target) 83 | end 84 | end 85 | 86 | context "countup" do 87 | setup do 88 | @vote = WikiExtensionsVote.new 89 | end 90 | 91 | should "return 1 if count is nil." do 92 | @vote.count = nil 93 | assert_equal(1, @vote.countup) 94 | assert_equal(1, @vote.count) 95 | end 96 | 97 | should "return 100 if count is 99." do 98 | @vote.count = 99 99 | assert_equal(100, @vote.countup) 100 | assert_equal(100, @vote.count) 101 | end 102 | end 103 | 104 | context "find_or_create" do 105 | setup do 106 | @project = Project.find(1) 107 | @vote = WikiExtensionsVote.new 108 | @vote.target = @project 109 | @vote.count = 1 110 | @vote.keystr = 'aaa' 111 | @vote.save! 112 | end 113 | 114 | should "return new instance which count is 0 if target not found." do 115 | vote = WikiExtensionsVote.find_or_create('Hoge', 3, 'keystr') 116 | assert_not_nil(vote) 117 | assert_equal('Hoge', vote.target_class_name) 118 | assert_equal(3, vote.target_id) 119 | assert_equal('keystr', vote.keystr) 120 | assert_equal(0, vote.count) 121 | end 122 | 123 | should "find instance what has specified values." do 124 | vote = WikiExtensionsVote.find_or_create(@vote.target_class_name, @vote.target_id, @vote.keystr) 125 | assert_not_nil(vote) 126 | assert_equal(@vote.id, vote.id) 127 | end 128 | end 129 | end 130 | --------------------------------------------------------------------------------