Просмотр исходного кода

Feature: Mobile - Improve subscription handling for article updates.

Martin Gruner 2 лет назад
Родитель
Сommit
9495b14c62

+ 2 - 0
app/frontend/shared/graphql/types.ts

@@ -1273,6 +1273,8 @@ export type TicketUpdatesPayload = {
   __typename?: 'TicketUpdatesPayload';
   /** Updated ticket */
   ticket?: Maybe<Ticket>;
+  /** Updated ticket article (optional) */
+  ticketArticle?: Maybe<TicketArticle>;
 };
 
 /** Autogenerated return type of Translations. */

+ 6 - 0
app/graphql/gql/subscriptions/ticket_updates.rb

@@ -8,12 +8,18 @@ module Gql::Subscriptions
     description 'Updates to ticket records'
 
     field :ticket, Gql::Types::TicketType, description: 'Updated ticket'
+    field :ticket_article, Gql::Types::Ticket::ArticleType, description: 'Updated ticket article (optional)'
 
     def authorized?(ticket_id:)
       Gql::ZammadSchema.authorized_object_from_id ticket_id, type: ::Ticket, user: context.current_user
     end
 
+    # This can either be passed a ::Ticket for ticket updates, or a ::Ticket::Article if a specific article was changed.
     def update(ticket_id:)
+      if object.is_a?(::Ticket::Article)
+        return { ticket: object.ticket, ticket_article: object }
+      end
+
       { ticket: object }
     end
   end

+ 1 - 0
app/models/ticket/article.rb

@@ -18,6 +18,7 @@ class Ticket::Article < ApplicationModel
   include Ticket::Article::EnqueueCommunicateTwitterJob
   include Ticket::Article::HasTicketContactAttributesImpact
   include Ticket::Article::ResetsTicketState
+  include Ticket::Article::TriggersSubscriptions
 
   # AddsMetadataGeneral depends on AddsMetadataOriginById, so load that first
   include Ticket::Article::AddsMetadataOriginById

+ 1 - 2
app/models/ticket/article/has_ticket_contact_attributes_impact.rb

@@ -11,8 +11,8 @@ module Ticket::Article::HasTicketContactAttributesImpact
   private
 
   def update_ticket_article_attributes
-
     changed = false
+
     if article_count_update
       changed = true
     end
@@ -29,7 +29,6 @@ module Ticket::Article::HasTicketContactAttributesImpact
       changed = true
     end
 
-    # save ticket
     if !changed
       ticket.touch # rubocop:disable Rails/SkipsModelValidations
       return

+ 17 - 0
app/models/ticket/article/triggers_subscriptions.rb

@@ -0,0 +1,17 @@
+# Copyright (C) 2012-2022 Zammad Foundation, https://zammad-foundation.org/
+
+# Trigger GraphQL subscriptions on ticket article changes.
+module Ticket::Article::TriggersSubscriptions
+  extend ActiveSupport::Concern
+
+  included do
+    after_update :trigger_subscriptions
+  end
+
+  private
+
+  def trigger_subscriptions
+    # Trigger the TicketUpdate subscription, but pass the article to signal that this article changed.
+    Gql::Subscriptions::TicketUpdates.trigger(self, arguments: { ticket_id: Gql::ZammadSchema.id_from_object(ticket) })
+  end
+end

+ 16 - 7
spec/graphql/gql/subscriptions/ticket_updates_spec.rb

@@ -16,6 +16,10 @@ RSpec.describe Gql::Subscriptions::TicketUpdates, type: :graphql do
             internalId
             title
           }
+          ticketArticle {
+            id
+            subject
+          }
         }
       }
     QUERY
@@ -30,7 +34,7 @@ RSpec.describe Gql::Subscriptions::TicketUpdates, type: :graphql do
       let(:agent) { create(:agent, groups: [ticket.group]) }
 
       it 'subscribes' do
-        expect(gql.result.data).to eq({ 'ticket' => nil })
+        expect(gql.result.data).to eq({ 'ticket' => nil, 'ticketArticle' => nil })
       end
 
       it 'receives ticket updates' do
@@ -39,14 +43,19 @@ RSpec.describe Gql::Subscriptions::TicketUpdates, type: :graphql do
         expect(mock_channel.mock_broadcasted_messages.first[:result]['data']['ticketUpdates']['ticket']['title']).to eq(ticket.title)
       end
 
-      context 'when a new article is created' do
+      context 'when a new article is created', :aggregate_failures do
         it 'receives ticket updates' do
-          create(:ticket_article,
-                 ticket:  ticket,
-                 subject: 'subcription test',
-                 from:    'no-reply@zammad.com')
+          article = create(:ticket_article,
+                           ticket:  ticket,
+                           subject: 'subcription test',
+                           from:    'no-reply@zammad.com')
+
+          article.internal = !article.internal
+          article.save!
 
-          expect(mock_channel.mock_broadcasted_messages).not_to be_empty
+          expect(mock_channel.mock_broadcasted_messages.count).to be(2)
+          expect(mock_channel.mock_broadcasted_messages.first[:result]['data']['ticketUpdates']['ticket']['title']).to eq(ticket.title)
+          expect(mock_channel.mock_broadcasted_messages.last[:result]['data']['ticketUpdates']['ticketArticle']['subject']).to eq(article.subject)
         end
       end