Skip to content

Commit

Permalink
Merge pull request #50 from cat-in-136/redmine6-rails7
Browse files Browse the repository at this point in the history
Support for Redmine6/rails7
  • Loading branch information
cat-in-136 authored Dec 1, 2024
2 parents 914aa81 + 6cbd468 commit 6a5119a
Show file tree
Hide file tree
Showing 20 changed files with 239 additions and 90 deletions.
66 changes: 31 additions & 35 deletions .github/workflows/redmine_plugin.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,21 +11,22 @@ jobs:
fail-fast: false
matrix:
mat_env:
- '3.3 redmica/[email protected]'
- '3.3 redmica/[email protected]'
- '3.2 redmica/[email protected]'
- '3.2 redmica/[email protected]'
- '3.1 redmica/[email protected]'
- '3.0 redmica/[email protected]'
- '2.7 redmica/[email protected]'
- '3.2 redmine/[email protected]'
- '3.1 redmine/[email protected]'
- '3.0 redmine/[email protected]'
- '3.3 redmine/[email protected]'
- '3.2 redmine/[email protected]'
- '3.1 redmine/[email protected]'
- '3.0 redmine/[email protected]'
- '2.7 redmine/[email protected]'
- '2.6 redmine/[email protected]'
- '2.6 redmine/[email protected]'
- '2.6 redmine/[email protected]'
- '2.5 redmine/[email protected]'
experimental: [false]
include:
- mat_env: '3.2 redmica/redmica@master'
- mat_env: '3.3 redmica/redmica@master'
experimental: true
steps:
- run: |
Expand All @@ -43,11 +44,11 @@ jobs:
ruby-version: ${{ env.RUBY_VERSION }}

- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
path: ./${{ env.PLUGIN_NAME }}
- name: Set up Redmine
uses: actions/checkout@v3
uses: actions/checkout@v4
with:
repository: ${{ env.REDMINE_REPOSITORY }}
ref: ${{ env.REDMINE_REF }}
Expand All @@ -56,32 +57,31 @@ jobs:
- name: Copy the plugin files to plugin directory
run: cp -pr ./${{ env.PLUGIN_NAME }} ./redmine/plugins/${{ env.PLUGIN_NAME }}
- name: Create redmine/config/database.yml
uses: DamianReeves/write-file-action@v1.2
uses: DamianReeves/write-file-action@v1.3
with:
path: ./redmine/config/database.yml
contents: |
test:
adapter: sqlite3
database: db/redmine_test.db
- uses: actions/cache@v3
- uses: actions/cache@v4
with:
path: ./redmine/vendor/bundle
key: ${{ runner.os }}-gems-${{ hashFiles('./redmine/**/Gemfile.lock') }}
restore-keys: |
${{ runner.os }}-gems-
- name: uninitialized constant Nokogiri::HTML4 Issue HACK ref. https://qiita.com/Mattani/items/c4bcc95a72b69d1c0489
uses: DamianReeves/write-file-action@v1.2
- name: "'LoadError: cannot load such file -- blankslate' Issue HACK ref. https://www.redmine.org/issues/40802#note-11"
uses: DamianReeves/write-file-action@v1.3
with:
path: ./redmine/Gemfile.local
contents: |
gem 'loofah', '~> 2.20.0'
if: contains(fromJSON('["2.6 redmine/[email protected]", "2.6 redmine/[email protected]", "2.5 redmine/[email protected]"]'), matrix.mat_env)
gem 'builder', '~> 3.2.4'
if: contains(fromJSON('["3.2 redmica/[email protected]", "3.2 redmica/[email protected]", "3.1 redmica/[email protected]", "3.0 redmica/[email protected]", "2.7 redmica/[email protected]", "2.6 redmine/[email protected]", "2.6 redmine/[email protected]", "2.5 redmine/[email protected]", "2.6 redmine/[email protected]", "2.7 redmine/[email protected]"]'), matrix.mat_env)

- name: Before script
run: |
cd ./redmine
bundle config --local path ${BUNDLE_PATH:-vendor/bundle}
bundle install
Expand All @@ -94,31 +94,27 @@ jobs:
# Execute plugin's migration
bundle exec rake redmine:plugins NAME=${{ env.PLUGIN_NAME }}
working-directory: ./redmine
env:
REDMINE_LANG: en
RAILS_ENV: test

# HACK sometimes fails login error, so retry 10 times
# HACK use shell script file to avoid interruption by error
- name: Prepare test script
uses: DamianReeves/[email protected]
with:
path: ./run_test.sh
contents: |
#!/bin/sh
cd ./redmine
for i in `seq 0 9`; do
# Execute plugin's test
bundle exec rake redmine:plugins:test NAME=${{ env.PLUGIN_NAME }}
retval=$?
if [ "$retval" -eq 0 ]; then
break
fi
echo "${i}-th test failed; Retry test..."
done
exit $retval
- name: Execute test
run: sh ./run_test.sh
run: |
#!/bin/sh
for i in `seq 0 9`; do
# Execute plugin's test
bundle exec rake redmine:plugins:test NAME=${{ env.PLUGIN_NAME }}
retval=$?
if [ "$retval" -eq 0 ]; then
break
fi
echo "${i}-th test failed; Retry test..."
done
exit $retval
shell: bash {0}
working-directory: ./redmine
env:
REDMINE_LANG: en
RAILS_ENV: test
7 changes: 7 additions & 0 deletions README.rdoc
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,10 @@ Follow below steps to migrate from other plugins :
* Restart your redmine

Ditto {issue_votes}[https://github.com/KohaSuomi/issue_votes]. Run <code>bundle exec rake -T redmine_hearts:migrate_from</code> to check the task name.

== License

* Codes: MIT License.
* Legacy Icons: famfamfam-silk: {CC-By-2.5}[https://creativecommons.org/licenses/by/2.5/] by Mark James http://www.famfamfam.com/lab/icons/silk/
* Vector Icons: {Tabler Icons}[https://tabler.io/]: MIT License

2 changes: 1 addition & 1 deletion app/controllers/hearts_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# along with this program; if not, write to the Free Software

class HeartsController < ApplicationController
unloadable
unloadable if respond_to?(:unloadable)

accept_api_auth :index, :heart, :unheart, :hearted_users

Expand Down
17 changes: 16 additions & 1 deletion app/helpers/hearts_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,11 @@ def heart_link_with_counter_manual(objects, heart_bool, hearted_users_count, use
objects = Array.wrap(objects)

css = heart_bool ? 'icon icon-heart' : 'icon icon-heart-off'
text = content_tag :span, l(:hearts_link_label), :class => 'heart-link-label'
if defined? hearts_icon_with_label # redmine >= 6.0
text = hearts_icon_with_label('heart', l(:hearts_link_label), css_class: 'heart-link-label')
else
text = content_tag :span, l(:hearts_link_label), :class => 'heart-link-label'
end
object_type = objects.first.class.to_s.underscore
object_id = (objects.size == 1) ? objects.first.id : objects.map(&:id).sort

Expand Down Expand Up @@ -127,4 +131,15 @@ def render_api_heartable_include(heartable, api)
end
end
end

if defined? IconsHelper # redmine >= 6.0
include IconsHelper
def hearts_icon_with_label(icon_name, label_text, icon_only: false, size: 18, css_class: nil)
label_classes = ["icon-label"]
label_classes << "hidden" if icon_only
plugin = 'redmine_hearts'
sprite_icon(icon_name, size: size, css_class: css_class, plugin: plugin) + content_tag(:span, label_text, class: label_classes.join(' '))
end
end

end
12 changes: 7 additions & 5 deletions app/models/heart.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,22 +18,24 @@
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

class Heart < ActiveRecord::Base
unloadable
class Heart < (defined?(ApplicationRecord) == 'constant' ? ApplicationRecord : ActiveRecord::Base)
unloadable if respond_to?(:unloadable)

belongs_to :heartable, :polymorphic => true
belongs_to :user

attribute :skip_validate_user, :boolean

validates_presence_of :user
validates_uniqueness_of :user_id, :scope => [:heartable_type, :heartable_id]
validate :validate_user
validate :validate_user, :unless => :skip_validate_user

def self.of_projects(*args)
projects = args.size > 0 ? args.shift : Project.none
user = args.size > 0 ? args.shift : nil
raise ArgumentError if args.size > 0

ActiveRecord::Base.subclasses.select { |klass|
(defined?(ApplicationRecord) == 'constant' ? ApplicationRecord : ActiveRecord::Base).subclasses.select { |klass|
klass.included_modules.include?(Redmine::Acts::Heartable::InstanceMethods)
}.map { |klass|
if user && klass.respond_to?(:visible)
Expand All @@ -57,7 +59,7 @@ def self.of_projects(*args)
def self.notifications_to(user)
raise ArgumentError unless user

ActiveRecord::Base.subclasses.select { |klass|
(defined?(ApplicationRecord) == 'constant' ? ApplicationRecord : ActiveRecord::Base).subclasses.select { |klass|
klass.included_modules.include?(Redmine::Acts::Heartable::InstanceMethods)
}.select { |klass|
klass.column_names.include?("author_id") || klass.column_names.include?("user_id")
Expand Down
8 changes: 8 additions & 0 deletions assets/images/icons.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 11 additions & 2 deletions assets/stylesheets/application.css
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
.icon-heart { background-image: url(../images/heart.png); }
.icon-heart-off { background-image: url(../images/heart_off.png); }

.heart-link-with-count { display: inline-block; }
.heart-count-number { padding-left: 1ex; }
.heart-count-number { padding-left: 0.75ex; }

/* redmine >= 6.0 */
:is(.icon-heart, .icon-heart-off):has(svg.icon-svg) { background-image: none; }
.icon-heart .icon-svg { fill: #fb8098; stroke: none; }
.heart-link-with-count:has(svg.icon-svg) {
display: inline-flex;
align-items: center;
vertical-align: middle;
}


@media screen and (max-width: 899px) {
.heart-link-with-count > *:nth-child(1) {
Expand Down
2 changes: 2 additions & 0 deletions config/icon_source.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- name: heart
svg: heart
4 changes: 3 additions & 1 deletion init.rb
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,12 @@
require File.expand_path('../lib/redmine_hearts/view_hook.rb', __FILE__)

Redmine::Plugin.register :redmine_hearts do
requires_redmine :version_or_higher => '4.2.0'

name 'Redmine Hearts plugin'
author '@cat_in_136'
description 'provide intra-Redmine Like/Fav reactions'
version '3.0.1'
version '4.0.0'
url 'https://github.com/cat-in-136/redmine_hearts'
author_url 'https://github.com/cat-in-136/'

Expand Down
2 changes: 1 addition & 1 deletion lib/redmine/acts/heartable.rb
Original file line number Diff line number Diff line change
Expand Up @@ -98,5 +98,5 @@ module ClassMethods; end
end
end

ActiveRecord::Base.send(:include, Redmine::Acts::Heartable)
(defined?(ApplicationRecord) == 'constant' ? ApplicationRecord : ActiveRecord::Base).send(:include, Redmine::Acts::Heartable)

2 changes: 1 addition & 1 deletion lib/redmine_hearts/heartable_patch.rb
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ def self.included(base) # :nodoc:
end

base.class_eval do
unloadable
unloadable if respond_to?(:unloadable)
acts_as_heartable options
end
end
Expand Down
9 changes: 6 additions & 3 deletions lib/redmine_hearts/view_hook.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,8 @@ def view_layouts_base_html_head(context={})
if subject
controller.send(:render_to_string, {
:partial => "hooks/redmine_hearts/view_layouts_base_html_head",
:locals => context.merge(:@heartable => subject)
:locals => context,
:assigns => { :heartable => subject }
})
end
end
Expand All @@ -36,7 +37,8 @@ def view_layouts_base_content(context={})
if subject
controller.send(:render_to_string, {
:partial => "hooks/redmine_hearts/view_layouts_base_content",
:locals => context.merge(:@heartable => subject)
:locals => context,
:assigns => { :heartable => subject }
})
end
end
Expand All @@ -47,7 +49,8 @@ def view_account_left_bottom(context={})
controller = context[:controller]
controller.send(:render_to_string, {
:partial => "hooks/redmine_hearts/view_account_left_bottom",
:locals => context.merge(:@heart_count => heart_count)
:locals => context,
:assigns => { :heart_count => heart_count }
})
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/tasks/redmine_hearts.rake
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ namespace :redmine_hearts do

num_of_heart_before_processing = Heart.count

VoteOnIssue.where('vote_val > 0').each do |vote|
VoteOnIssue.where('vote_val > 0').where.not(issue: nil, user: nil).each do |vote|
issue = vote.issue
user = vote.user
datetime = vote.created_at || Time.now
Expand All @@ -100,6 +100,7 @@ namespace :redmine_hearts do
:user => user,
:created_at => datetime,
:updated_at => datetime,
:skip_validate_user => true,
)
end
end
Expand Down
20 changes: 10 additions & 10 deletions test/fixtures/hearts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,29 @@ hearts_005:
heartable_type: Wiki
heartable_id: 1
user_id: 3
created_at: <%= 30.days.ago.to_date.to_s(:db) %>
updated_at: <%= 30.days.ago.to_date.to_s(:db) %>
created_at: <%= 30.days.ago %>
updated_at: <%= 30.days.ago %>
hearts_006:
heartable_type: WikiPage
heartable_id: 1
user_id: 3
created_at: <%= 29.days.ago.to_date.to_s(:db) %>
updated_at: <%= 29.days.ago.to_date.to_s(:db) %>
created_at: <%= 29.days.ago %>
updated_at: <%= 29.days.ago %>
hearts_007:
heartable_type: News
heartable_id: 1
user_id: 3
created_at: <%= 2.days.ago.to_date.to_s(:db) %>
updated_at: <%= 2.days.ago.to_date.to_s(:db) %>
created_at: <%= 2.days.ago %>
updated_at: <%= 2.days.ago %>
hearts_008:
heartable_type: Journal
heartable_id: 1
user_id: 3
created_at: <%= 1.day.ago.to_date.to_s(:db) %>
updated_at: <%= 1.day.ago.to_date.to_s(:db) %>
created_at: <%= 1.day.ago %>
updated_at: <%= 1.day.ago %>
hearts_004:
heartable_type: Board
heartable_id: 1
user_id: 3
created_at: <%= 1.minute.ago.to_date.to_s(:db) %>
updated_at: <%= 1.minute.ago.to_date.to_s(:db) %>
created_at: <%= 1.minute.ago %>
updated_at: <%= 1.minute.ago %>
8 changes: 4 additions & 4 deletions test/integration/hearts_hooked_boards_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,16 @@ class HeartsHookedBoardsTest < Redmine::IntegrationTest
def test_index_shall_not_contain_hooks
get '/projects/1/boards/'
assert_response :success
assert_select 'script[src*="transplant_heart_link_with_counter.js"]', :count => 0
assert_select 'link[href*="redmine_hearts/stylesheets/application.css"]', :count => 0
assert_select 'script:match("src", ?)', /\/redmine_hearts\/.*transplant_heart_link_with_counter.*\.js/, :count => 0
assert_select 'link:match("href", ?)', /\/redmine_hearts\/.*application.*\.css/, :count => 0
assert_select '.heart-link-with-count', :count => 0
end

def test_topic_view
get '/boards/1/topics/1'
assert_response :success
assert_select 'script[src*="transplant_heart_link_with_counter.js"]', :count => 1
assert_select 'link[href*="redmine_hearts/stylesheets/application.css"]', :count => 1
assert_select 'script:match("src", ?)', /\/redmine_hearts\/.*transplant_heart_link_with_counter.*\.js/, :count => 1
assert_select 'link:match("href", ?)', /\/redmine_hearts\/.*application.*\.css/, :count => 1

assert_select '#content > .heart-link-with-count.message-1-heart', :count => 1
assert_select '#content > .heart-link-with-count.message-1-heart .heart-count-number', :text => "1"
Expand Down
Loading

0 comments on commit 6a5119a

Please sign in to comment.