From de90679a5c455a26a01d629c4be754f9d231fa65 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marius=20B=C4=82LTEANU?= Date: Fri, 5 Dec 2025 00:36:37 +0200 Subject: [PATCH] Adds webooks for time entries (#29664). diff --git a/app/models/time_entry.rb b/app/models/time_entry.rb index f20958894..ed46137ea 100644 --- a/app/models/time_entry.rb +++ b/app/models/time_entry.rb @@ -58,6 +58,10 @@ class TimeEntry < ApplicationRecord before_validation :set_author_if_nil validate :validate_time_entry + after_create_commit ->{ Webhook.trigger('time_entry.created', self) } + after_update_commit ->{ Webhook.trigger('time_entry.updated', self) } + after_destroy_commit ->{ Webhook.trigger('time_entry.deleted', self) } + scope :visible, (lambda do |*args| joins(:project). where(TimeEntry.visible_condition(args.shift || User.current, *args)) diff --git a/app/models/webhook_payload.rb b/app/models/webhook_payload.rb index dfc2e845c..e54a17bb6 100644 --- a/app/models/webhook_payload.rb +++ b/app/models/webhook_payload.rb @@ -29,7 +29,8 @@ class WebhookPayload EVENTS = { issue: %w[created updated deleted], - wiki_page: %w[created updated deleted] + wiki_page: %w[created updated deleted], + time_entry: %w[created updated deleted], } def to_h @@ -110,6 +111,25 @@ class WebhookPayload } end + def time_entry_payload(action) + time_entry = object + ts = case action + when 'created' + time_entry.created_on + when 'deleted' + Time.now + else + time_entry.updated_on + end + { + type: event, + timestamp: ts.iso8601, + data: { + time_entry: ApiRenderer.new("app/views/timelog/show.api.rsb", user).to_h(time_entry: time_entry) + } + } + end + # given a path to an API template (relative to RAILS_ROOT), renders it and returns the resulting hash class ApiRenderer include ApplicationHelper diff --git a/config/locales/en.yml b/config/locales/en.yml index e5d8a4388..de42a2a2d 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -1193,8 +1193,12 @@ en: webhook_events_wiki_page_created: Wiki page created webhook_events_wiki_page_updated: Wiki page updated webhook_events_wiki_page_deleted: Wiki page deleted + webhook_events_time_entry: Time entries + webhook_events_time_entry_created: Time entry created + webhook_events_time_entry_updated: Time entry updated + webhook_events_time_entry_deleted: Time entry deleted webhook_url_info: Redmine will send a POST request to this URL whenever one of the selected events occurs in one of the selected projects. - webhook_secret_info_html: If provided, Redmine will use this to create a hash signature that is sent with each delivery as the value of the X-Redmine-Signature-256 header. + webhook_secret_info_html: If provided, Redmine will use this to create a hash signature that is sent with each delivery as the value of the X-Redmine-Signature-256 header. button_login: Login button_submit: Submit diff --git a/test/unit/webhook_payload_test.rb b/test/unit/webhook_payload_test.rb index 9ab94694d..329d485a0 100644 --- a/test/unit/webhook_payload_test.rb +++ b/test/unit/webhook_payload_test.rb @@ -94,4 +94,35 @@ class WebhookPayloadTest < ActiveSupport::TestCase assert_equal 'wiki_page.deleted', h[:type] assert_equal 'Test_Page', h.dig(:data, :wiki_page, :title) end + + test "time entry created payload should contain time entry details" do + time_entry = TimeEntry.generate! + + p = WebhookPayload.new('time_entry.created', time_entry, @dlopper) + assert h = p.to_h + assert_equal 'time_entry.created', h[:type] + assert_equal time_entry.hours, h.dig(:data, :time_entry, :hours) + end + + test "time entry updated payload should contain updated timestamp" do + time_entry = TimeEntry.first + + time_entry.hours = 2.5 + time_entry.save! + + p = WebhookPayload.new('time_entry.updated', time_entry, @dlopper) + h = p.to_h + assert_equal 'time_entry.updated', h[:type] + assert_equal 2.5, h.dig(:data, :time_entry, :hours) + end + + test "time entry deleted payload should contain basic info" do + time_entry = TimeEntry.first + time_entry.destroy + + p = WebhookPayload.new('time_entry.deleted', time_entry, @dlopper) + h = p.to_h + assert_equal 'time_entry.deleted', h[:type] + assert_equal 4.25, h.dig(:data, :time_entry, :hours) + end end -- 2.50.1 (Apple Git-155)