1+ /* eslint-disable @typescript-eslint/no-explicit-any */
12import { describe , it , expect , vi , beforeEach } from "vitest" ;
23
34import { PermissionCheckService } from "@calcom/features/pbac/services/permission-check.service" ;
45import { WatchlistRepository } from "@calcom/lib/server/repository/watchlist.repository" ;
56import { WatchlistType , WatchlistAction , MembershipRole } from "@calcom/prisma/enums" ;
67
8+ import { TRPCError } from "@trpc/server" ;
9+
710import { createWatchlistEntryHandler } from "./createWatchlistEntry.handler" ;
811
912vi . mock ( "@calcom/features/pbac/services/permission-check.service" ) ;
@@ -35,7 +38,7 @@ describe("createWatchlistEntryHandler", () => {
3538 it ( "should throw FORBIDDEN when user is not part of an organization" , async ( ) => {
3639 await expect (
3740 createWatchlistEntryHandler ( {
38- ctx : { user : { ...mockUser , organizationId : undefined , profile : null } } ,
41+ ctx : { user : { ...( mockUser as any ) , organizationId : undefined , profile : null } } ,
3942 input : {
4043 type : WatchlistType . EMAIL ,
4144 value : "spam@example.com" ,
@@ -54,7 +57,7 @@ describe("createWatchlistEntryHandler", () => {
5457
5558 await expect (
5659 createWatchlistEntryHandler ( {
57- ctx : { user : mockUser } ,
60+ ctx : { user : mockUser as any } ,
5861 input : {
5962 type : WatchlistType . EMAIL ,
6063 value : "spam@example.com" ,
@@ -73,7 +76,7 @@ describe("createWatchlistEntryHandler", () => {
7376 mockWatchlistRepo . createEntry . mockResolvedValue ( { id : "watchlist-1" } ) ;
7477
7578 await createWatchlistEntryHandler ( {
76- ctx : { user : mockUser } ,
79+ ctx : { user : mockUser as any } ,
7780 input : {
7881 type : WatchlistType . EMAIL ,
7982 value : "test@example.com" ,
@@ -97,7 +100,7 @@ describe("createWatchlistEntryHandler", () => {
97100 it ( "should throw BAD_REQUEST for invalid email format" , async ( ) => {
98101 await expect (
99102 createWatchlistEntryHandler ( {
100- ctx : { user : mockUser } ,
103+ ctx : { user : mockUser as any } ,
101104 input : {
102105 type : WatchlistType . EMAIL ,
103106 value : "invalid-email" ,
@@ -114,7 +117,7 @@ describe("createWatchlistEntryHandler", () => {
114117 it ( "should throw BAD_REQUEST for email missing @ symbol" , async ( ) => {
115118 await expect (
116119 createWatchlistEntryHandler ( {
117- ctx : { user : mockUser } ,
120+ ctx : { user : mockUser as any } ,
118121 input : {
119122 type : WatchlistType . EMAIL ,
120123 value : "notanemail.com" ,
@@ -126,43 +129,43 @@ describe("createWatchlistEntryHandler", () => {
126129 } ) ;
127130 } ) ;
128131
129- it ( "should throw BAD_REQUEST for invalid domain format without @" , async ( ) => {
130- await expect (
131- createWatchlistEntryHandler ( {
132- ctx : { user : mockUser } ,
133- input : {
134- type : WatchlistType . DOMAIN ,
135- value : "example.com" ,
136- } ,
137- } )
138- ) . rejects . toMatchObject ( {
139- code : "BAD_REQUEST" ,
140- message : "Invalid domain format. Domain must start with @ (e.g., @example.com)" ,
132+ it ( "should accept valid domain format without @" , async ( ) => {
133+ mockWatchlistRepo . createEntry . mockResolvedValue ( { id : "watchlist-1" } ) ;
134+
135+ const result = await createWatchlistEntryHandler ( {
136+ ctx : { user : mockUser as any } ,
137+ input : {
138+ type : WatchlistType . DOMAIN ,
139+ value : "example.com" ,
140+ } ,
141141 } ) ;
142142
143- expect ( mockWatchlistRepo . createEntry ) . not . toHaveBeenCalled ( ) ;
143+ expect ( result . success ) . toBe ( true ) ;
144+ expect ( mockWatchlistRepo . createEntry ) . toHaveBeenCalled ( ) ;
144145 } ) ;
145146
146147 it ( "should throw BAD_REQUEST for domain with invalid format" , async ( ) => {
147148 await expect (
148149 createWatchlistEntryHandler ( {
149- ctx : { user : mockUser } ,
150+ ctx : { user : mockUser as any } ,
150151 input : {
151152 type : WatchlistType . DOMAIN ,
152- value : "not-a- domain" ,
153+ value : "invalid.. domain" ,
153154 } ,
154155 } )
155- ) . rejects . toMatchObject ( {
156- code : "BAD_REQUEST" ,
157- message : "Invalid domain format. Domain must start with @ (e.g., @example.com)" ,
158- } ) ;
156+ ) . rejects . toStrictEqual (
157+ new TRPCError ( {
158+ code : "BAD_REQUEST" ,
159+ message : "Invalid domain format (e.g., example.com)" ,
160+ } )
161+ ) ;
159162 } ) ;
160163
161164 it ( "should accept valid email format" , async ( ) => {
162165 mockWatchlistRepo . createEntry . mockResolvedValue ( { id : "watchlist-1" } ) ;
163166
164167 const result = await createWatchlistEntryHandler ( {
165- ctx : { user : mockUser } ,
168+ ctx : { user : mockUser as any } ,
166169 input : {
167170 type : WatchlistType . EMAIL ,
168171 value : "valid@example.com" ,
@@ -173,19 +176,23 @@ describe("createWatchlistEntryHandler", () => {
173176 expect ( mockWatchlistRepo . createEntry ) . toHaveBeenCalled ( ) ;
174177 } ) ;
175178
176- it ( "should accept valid domain format with @ " , async ( ) => {
179+ it ( "should accept valid domain format and normalize it " , async ( ) => {
177180 mockWatchlistRepo . createEntry . mockResolvedValue ( { id : "watchlist-1" } ) ;
178181
179182 const result = await createWatchlistEntryHandler ( {
180- ctx : { user : mockUser } ,
183+ ctx : { user : mockUser as any } ,
181184 input : {
182185 type : WatchlistType . DOMAIN ,
183- value : "@ example.com" ,
186+ value : "example.com" ,
184187 } ,
185188 } ) ;
186189
187190 expect ( result . success ) . toBe ( true ) ;
188- expect ( mockWatchlistRepo . createEntry ) . toHaveBeenCalled ( ) ;
191+ expect ( mockWatchlistRepo . createEntry ) . toHaveBeenCalledWith (
192+ expect . objectContaining ( {
193+ value : "example.com" ,
194+ } )
195+ ) ;
189196 } ) ;
190197 } ) ;
191198
@@ -205,7 +212,7 @@ describe("createWatchlistEntryHandler", () => {
205212 mockWatchlistRepo . createEntry . mockResolvedValue ( mockEntry ) ;
206213
207214 const result = await createWatchlistEntryHandler ( {
208- ctx : { user : mockUser } ,
215+ ctx : { user : mockUser as any } ,
209216 input : {
210217 type : WatchlistType . EMAIL ,
211218 value : "spam@example.com" ,
@@ -224,29 +231,29 @@ describe("createWatchlistEntryHandler", () => {
224231 } ) ;
225232 } ) ;
226233
227- it ( "should create watchlist entry for DOMAIN type" , async ( ) => {
234+ it ( "should create watchlist entry for DOMAIN type and normalize it " , async ( ) => {
228235 const mockEntry = {
229236 id : "watchlist-2" ,
230237 type : WatchlistType . DOMAIN ,
231- value : "@ spammer.com" ,
238+ value : "spammer.com" ,
232239 organizationId : 100 ,
233240 action : WatchlistAction . BLOCK ,
234241 } ;
235242 mockWatchlistRepo . createEntry . mockResolvedValue ( mockEntry ) ;
236243
237244 const result = await createWatchlistEntryHandler ( {
238- ctx : { user : mockUser } ,
245+ ctx : { user : mockUser as any } ,
239246 input : {
240247 type : WatchlistType . DOMAIN ,
241- value : "@ spammer.com" ,
248+ value : "spammer.com" ,
242249 } ,
243250 } ) ;
244251
245252 expect ( result . success ) . toBe ( true ) ;
246253 expect ( result . entry ) . toEqual ( mockEntry ) ;
247254 expect ( mockWatchlistRepo . createEntry ) . toHaveBeenCalledWith ( {
248255 type : WatchlistType . DOMAIN ,
249- value : "@ spammer.com" ,
256+ value : "spammer.com" ,
250257 organizationId : 100 ,
251258 action : WatchlistAction . BLOCK ,
252259 description : undefined ,
@@ -258,7 +265,7 @@ describe("createWatchlistEntryHandler", () => {
258265 mockWatchlistRepo . createEntry . mockResolvedValue ( { id : "watchlist-4" } ) ;
259266
260267 await createWatchlistEntryHandler ( {
261- ctx : { user : mockUser } ,
268+ ctx : { user : mockUser as any } ,
262269 input : {
263270 type : WatchlistType . EMAIL ,
264271 value : "SPAM@EXAMPLE.COM" ,
@@ -279,7 +286,7 @@ describe("createWatchlistEntryHandler", () => {
279286 mockWatchlistRepo . createEntry . mockResolvedValue ( { id : "watchlist-5" } ) ;
280287
281288 await createWatchlistEntryHandler ( {
282- ctx : { user : mockUser } ,
289+ ctx : { user : mockUser as any } ,
283290 input : {
284291 type : WatchlistType . EMAIL ,
285292 value : "test@example.com" ,
0 commit comments