Merge branch 'develop' into feature/service-worker-caching
This commit is contained in:
@@ -237,10 +237,11 @@ export const MARKDOWN_PATTERNS = [
|
||||
patterns: [{ pattern: /`([^`]+)`/g, replacement: '$1' }],
|
||||
},
|
||||
{
|
||||
type: 'link', // PM: link, eg: [text](url) or <url>
|
||||
type: 'link', // PM: link
|
||||
patterns: [
|
||||
{ pattern: /\[([^\]]+)\]\([^)]+\)/g, replacement: '$1' }, // [text](url) -> text
|
||||
{ pattern: /<(https?:\/\/[^>]+)>/g, replacement: '$1' }, // <url> -> url (autolinks)
|
||||
{ pattern: /<([a-zA-Z][a-zA-Z0-9+.-]*:[^\s>]+)>/g, replacement: '$1' }, // <https://...>, <mailto:...>, <tel:...>, <ftp://...>, etc
|
||||
{ pattern: /<([^\s@]+@[^\s@>]+)>/g, replacement: '$1' }, // <user@example.com> -> user@example.com
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
@@ -901,6 +901,17 @@ describe('stripUnsupportedFormatting', () => {
|
||||
expect(stripUnsupportedFormatting(content, fullSchema)).toBe(content);
|
||||
});
|
||||
|
||||
it('preserves various URI scheme autolinks', () => {
|
||||
const content =
|
||||
'Email <mailto:user@example.com> or call <tel:+1234567890>';
|
||||
expect(stripUnsupportedFormatting(content, fullSchema)).toBe(content);
|
||||
});
|
||||
|
||||
it('preserves email autolinks', () => {
|
||||
const content = 'Contact us at <support@chatwoot.com>';
|
||||
expect(stripUnsupportedFormatting(content, fullSchema)).toBe(content);
|
||||
});
|
||||
|
||||
it('preserves lists when schema supports them', () => {
|
||||
const content = '- item 1\n- item 2\n1. first\n2. second';
|
||||
expect(stripUnsupportedFormatting(content, fullSchema)).toBe(content);
|
||||
@@ -984,6 +995,26 @@ describe('stripUnsupportedFormatting', () => {
|
||||
expect(stripUnsupportedFormatting(content, emptySchema)).toBe(expected);
|
||||
});
|
||||
|
||||
it('converts URI scheme autolinks to plain text', () => {
|
||||
const content =
|
||||
'Email <mailto:support@example.com> or call <tel:+1234567890>';
|
||||
const expected =
|
||||
'Email mailto:support@example.com or call tel:+1234567890';
|
||||
expect(stripUnsupportedFormatting(content, emptySchema)).toBe(expected);
|
||||
});
|
||||
|
||||
it('converts email autolinks to plain text', () => {
|
||||
const content = 'Reach us at <admin@chatwoot.com> for help';
|
||||
const expected = 'Reach us at admin@chatwoot.com for help';
|
||||
expect(stripUnsupportedFormatting(content, emptySchema)).toBe(expected);
|
||||
});
|
||||
|
||||
it('handles mixed autolink types', () => {
|
||||
const content = 'Visit <https://example.com> or email <info@example.com>';
|
||||
const expected = 'Visit https://example.com or email info@example.com';
|
||||
expect(stripUnsupportedFormatting(content, emptySchema)).toBe(expected);
|
||||
});
|
||||
|
||||
it('strips bullet list markers', () => {
|
||||
expect(
|
||||
stripUnsupportedFormatting('- item 1\n- item 2', emptySchema)
|
||||
|
||||
@@ -14,11 +14,19 @@ class ActionCableListener < BaseListener
|
||||
end
|
||||
|
||||
def notification_deleted(event)
|
||||
return if event.data[:notification].user.blank?
|
||||
notification_data = event.data[:notification_data]
|
||||
|
||||
notification, account, unread_count, count = extract_notification_and_account(event)
|
||||
tokens = [event.data[:notification].user.pubsub_token]
|
||||
broadcast(account, tokens, NOTIFICATION_DELETED, { notification: { id: notification.id }, unread_count: unread_count, count: count })
|
||||
user = User.find_by(id: notification_data[:user_id])
|
||||
account = Account.find_by(id: notification_data[:account_id])
|
||||
return if user.blank? || account.blank?
|
||||
|
||||
notification_finder = NotificationFinder.new(user, account)
|
||||
tokens = [user.pubsub_token]
|
||||
broadcast(account, tokens, NOTIFICATION_DELETED, {
|
||||
notification: { id: notification_data[:id] },
|
||||
unread_count: notification_finder.unread_count,
|
||||
count: notification_finder.count
|
||||
})
|
||||
end
|
||||
|
||||
def account_cache_invalidated(event)
|
||||
|
||||
@@ -180,7 +180,17 @@ class Notification < ApplicationRecord
|
||||
end
|
||||
|
||||
def dispatch_destroy_event
|
||||
Rails.configuration.dispatcher.dispatch(NOTIFICATION_DELETED, Time.zone.now, notification: self)
|
||||
# Pass serialized data instead of ActiveRecord object to avoid DeserializationError
|
||||
# when the async EventDispatcherJob runs after the notification has been deleted
|
||||
Rails.configuration.dispatcher.dispatch(
|
||||
NOTIFICATION_DELETED,
|
||||
Time.zone.now,
|
||||
notification_data: {
|
||||
id: id,
|
||||
user_id: user_id,
|
||||
account_id: account_id
|
||||
}
|
||||
)
|
||||
end
|
||||
|
||||
def set_last_activity_at
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@
|
||||
"dependencies": {
|
||||
"@breezystack/lamejs": "^1.2.7",
|
||||
"@chatwoot/ninja-keys": "1.2.3",
|
||||
"@chatwoot/prosemirror-schema": "1.3.4",
|
||||
"@chatwoot/prosemirror-schema": "1.3.5",
|
||||
"@chatwoot/utils": "^0.0.51",
|
||||
"@formkit/core": "^1.6.7",
|
||||
"@formkit/vue": "^1.6.7",
|
||||
|
||||
Generated
+5
-5
@@ -23,8 +23,8 @@ importers:
|
||||
specifier: 1.2.3
|
||||
version: 1.2.3
|
||||
'@chatwoot/prosemirror-schema':
|
||||
specifier: 1.3.4
|
||||
version: 1.3.4
|
||||
specifier: 1.3.5
|
||||
version: 1.3.5
|
||||
'@chatwoot/utils':
|
||||
specifier: ^0.0.51
|
||||
version: 0.0.51
|
||||
@@ -454,8 +454,8 @@ packages:
|
||||
'@chatwoot/ninja-keys@1.2.3':
|
||||
resolution: {integrity: sha512-xM8d9P5ikDMZm2WbaCTk/TW5HFauylrU3cJ75fq5je6ixKwyhl/0kZbVN/vbbZN4+AUX/OaSIn6IJbtCgIF67g==}
|
||||
|
||||
'@chatwoot/prosemirror-schema@1.3.4':
|
||||
resolution: {integrity: sha512-XY1UyG9topVy7fNCt45YgiU/QzlJJRhrcrSWcvAIIcDYKomnEcGOyeAfM3WeFD6GgOuLzRUyIHrW+WQGpHaZvA==}
|
||||
'@chatwoot/prosemirror-schema@1.3.5':
|
||||
resolution: {integrity: sha512-3Koj3jwO1qOxJG84D4FqPOJ6o8k6ehZi1zedO3vKRERATm2Cy1p+ET6FEvVYWUpoBvDwR6hNVScXrcNNVobhsA==}
|
||||
|
||||
'@chatwoot/utils@0.0.51':
|
||||
resolution: {integrity: sha512-WlEmWfOTzR7YZRUWzn5Wpm15/BRudpwqoNckph8TohyDbiim1CP4UZGa+qjajxTbNGLLhtKlm0Xl+X16+5Wceg==}
|
||||
@@ -4970,7 +4970,7 @@ snapshots:
|
||||
hotkeys-js: 3.8.7
|
||||
lit: 2.2.6
|
||||
|
||||
'@chatwoot/prosemirror-schema@1.3.4':
|
||||
'@chatwoot/prosemirror-schema@1.3.5':
|
||||
dependencies:
|
||||
markdown-it-sup: 2.0.0
|
||||
prosemirror-commands: 1.6.0
|
||||
|
||||
@@ -132,7 +132,14 @@ describe ActionCableListener do
|
||||
describe '#notification_deleted' do
|
||||
let(:event_name) { :'notification.deleted' }
|
||||
let!(:notification) { create(:notification, account: account, user: agent) }
|
||||
let!(:event) { Events::Base.new(event_name, Time.zone.now, notification: notification) }
|
||||
let(:notification_data) do
|
||||
{
|
||||
id: notification.id,
|
||||
user_id: agent.id,
|
||||
account_id: account.id
|
||||
}
|
||||
end
|
||||
let!(:event) { Events::Base.new(event_name, Time.zone.now, notification_data: notification_data) }
|
||||
|
||||
it 'sends message to account admins, inbox agents' do
|
||||
expect(ActionCableBroadcastJob).to receive(:perform_later).with(
|
||||
|
||||
Reference in New Issue
Block a user