1- import templates from '../src/templates' ;
21import EventNotifyMock from './__mocks__/event-notify' ;
32import SeveralEventsNotifyMock from './__mocks__/several-events-notify' ;
3+ import AssigneeNotifyMock from './__mocks__/assignee-notify' ;
44import WebhookProvider from '../src/provider' ;
55
66/**
@@ -18,9 +18,6 @@ const deliver = jest.fn();
1818 */
1919jest . mock ( './../src/deliverer.ts' , ( ) => {
2020 return jest . fn ( ) . mockImplementation ( ( ) => {
21- /**
22- * Now we can track calls to 'deliver'
23- */
2421 return {
2522 deliver : deliver ,
2623 } ;
@@ -35,48 +32,92 @@ afterEach(() => {
3532} ) ;
3633
3734describe ( 'WebhookProvider' , ( ) => {
38- /**
39- * Check that the 'send' method works without errors
40- */
41- it ( 'The "send" method should render and deliver message' , async ( ) => {
35+ it ( 'should deliver a message with { type, payload } structure' , async ( ) => {
4236 const provider = new WebhookProvider ( ) ;
4337
4438 await provider . send ( webhookEndpointSample , EventNotifyMock ) ;
4539
4640 expect ( deliver ) . toHaveBeenCalledTimes ( 1 ) ;
47- expect ( deliver ) . toHaveBeenCalledWith ( webhookEndpointSample , expect . anything ( ) ) ;
41+ expect ( deliver ) . toHaveBeenCalledWith ( webhookEndpointSample , expect . objectContaining ( {
42+ type : 'event' ,
43+ payload : expect . any ( Object ) ,
44+ } ) ) ;
4845 } ) ;
4946
50- /**
51- * Logic for select the template depended on events count
52- */
53- describe ( 'Select correct template' , ( ) => {
54- /**
55- * If there is a single event in payload, use the 'event' template
56- */
57- it ( 'Select the event template if there is a single event in notify payload' , async ( ) => {
58- const provider = new WebhookProvider ( ) ;
59- const EventTpl = jest . spyOn ( templates , 'EventTpl' ) ;
60- const SeveralEventsTpl = jest . spyOn ( templates , 'SeveralEventsTpl' ) ;
61-
62- await provider . send ( webhookEndpointSample , EventNotifyMock ) ;
63-
64- expect ( EventTpl ) . toHaveBeenCalledTimes ( 1 ) ;
65- expect ( SeveralEventsTpl ) . toHaveBeenCalledTimes ( 0 ) ;
66- } ) ;
67-
68- /**
69- * If there are several events in payload, use the 'several-events' template
70- */
71- it ( 'Select the several-events template if there are several events in notify payload' , async ( ) => {
72- const provider = new WebhookProvider ( ) ;
73- const EventTpl = jest . spyOn ( templates , 'EventTpl' ) ;
74- const SeveralEventsTpl = jest . spyOn ( templates , 'SeveralEventsTpl' ) ;
75-
76- await provider . send ( webhookEndpointSample , SeveralEventsNotifyMock ) ;
77-
78- expect ( EventTpl ) . toHaveBeenCalledTimes ( 0 ) ;
79- expect ( SeveralEventsTpl ) . toHaveBeenCalledTimes ( 1 ) ;
80- } ) ;
47+ it ( 'should preserve notification type in delivery' , async ( ) => {
48+ const provider = new WebhookProvider ( ) ;
49+
50+ await provider . send ( webhookEndpointSample , EventNotifyMock ) ;
51+ expect ( deliver . mock . calls [ 0 ] [ 1 ] . type ) . toBe ( 'event' ) ;
52+
53+ deliver . mockClear ( ) ;
54+
55+ await provider . send ( webhookEndpointSample , SeveralEventsNotifyMock ) ;
56+ expect ( deliver . mock . calls [ 0 ] [ 1 ] . type ) . toBe ( 'several-events' ) ;
57+
58+ deliver . mockClear ( ) ;
59+
60+ await provider . send ( webhookEndpointSample , AssigneeNotifyMock ) ;
61+ expect ( deliver . mock . calls [ 0 ] [ 1 ] . type ) . toBe ( 'assignee' ) ;
62+ } ) ;
63+
64+ it ( 'should strip internal fields (host, hostOfStatic) from payload' , async ( ) => {
65+ const provider = new WebhookProvider ( ) ;
66+
67+ await provider . send ( webhookEndpointSample , {
68+ type : 'payment-failed' ,
69+ payload : {
70+ host : 'https://garage.hawk.so' ,
71+ hostOfStatic : 'https://api.hawk.so' ,
72+ workspace : { name : 'Workspace' } ,
73+ reason : 'Insufficient funds' ,
74+ } ,
75+ } as any ) ;
76+
77+ const delivery = deliver . mock . calls [ 0 ] [ 1 ] ;
78+
79+ expect ( delivery . payload ) . not . toHaveProperty ( 'host' ) ;
80+ expect ( delivery . payload ) . not . toHaveProperty ( 'hostOfStatic' ) ;
81+ expect ( delivery . payload ) . toHaveProperty ( 'reason' , 'Insufficient funds' ) ;
82+ } ) ;
83+
84+ it ( 'should handle all known notification types without throwing' , async ( ) => {
85+ const provider = new WebhookProvider ( ) ;
86+
87+ const types = [
88+ 'event' ,
89+ 'several-events' ,
90+ 'assignee' ,
91+ 'block-workspace' ,
92+ 'blocked-workspace-reminder' ,
93+ 'payment-failed' ,
94+ 'payment-success' ,
95+ 'days-limit-almost-reached' ,
96+ 'events-limit-almost-reached' ,
97+ 'sign-up' ,
98+ 'password-reset' ,
99+ 'workspace-invite' ,
100+ ] ;
101+
102+ for ( const type of types ) {
103+ await expect (
104+ provider . send ( webhookEndpointSample , {
105+ type,
106+ payload : { host : 'h' , hostOfStatic : 's' } ,
107+ } as any )
108+ ) . resolves . toBeUndefined ( ) ;
109+ }
110+
111+ expect ( deliver ) . toHaveBeenCalledTimes ( types . length ) ;
112+ } ) ;
113+
114+ it ( 'should only have { type, payload } keys at root level' , async ( ) => {
115+ const provider = new WebhookProvider ( ) ;
116+
117+ await provider . send ( webhookEndpointSample , EventNotifyMock ) ;
118+
119+ const delivery = deliver . mock . calls [ 0 ] [ 1 ] ;
120+
121+ expect ( Object . keys ( delivery ) . sort ( ) ) . toEqual ( [ 'payload' , 'type' ] ) ;
81122 } ) ;
82123} ) ;
0 commit comments