@@ -10,6 +10,7 @@ import {
1010 confirmReschedule ,
1111 fillStripeTestCheckout ,
1212 selectFirstAvailableTimeSlotNextMonth ,
13+ submitAndWaitForResponse ,
1314 testName ,
1415} from "./lib/testUtils" ;
1516
@@ -301,3 +302,108 @@ test.describe("Teams - NonOrg", () => {
301302 } ) ;
302303 todo ( "Reschedule a Round Robin EventType booking" ) ;
303304} ) ;
305+
306+ test . describe ( "Team Slug Validation" , ( ) => {
307+ test . afterEach ( ( { users, orgs } ) => {
308+ users . deleteAll ( ) ;
309+ orgs . deleteAll ( ) ;
310+ } ) ;
311+
312+ test ( "Teams in different organizations can have the same slug" , async ( { page, users, orgs } ) => {
313+ const org1 = await orgs . create ( { name : "Organization 1" } ) ;
314+ const org2 = await orgs . create ( { name : "Organization 2" } ) ;
315+
316+ const owner1 = await users . create (
317+ {
318+ organizationId : org1 . id ,
319+ roleInOrganization : "OWNER" ,
320+ } ,
321+ {
322+ hasTeam : true ,
323+ teamSlug : "cal" ,
324+ teamRole : "OWNER" ,
325+ }
326+ ) ;
327+
328+ const owner2 = await users . create (
329+ {
330+ organizationId : org2 . id ,
331+ roleInOrganization : "OWNER" ,
332+ } ,
333+ {
334+ hasTeam : true ,
335+ teamSlug : "calCom" ,
336+ teamRole : "OWNER" ,
337+ }
338+ ) ;
339+ const { team : team1 } = await owner1 . getFirstTeamMembership ( ) ;
340+
341+ await owner1 . apiLogin ( ) ;
342+ await page . goto ( `/settings/teams/${ team1 . id } /profile` ) ;
343+ await page . locator ( 'input[name="slug"]' ) . fill ( "calCom" ) ;
344+ await submitAndWaitForResponse ( page , "/api/trpc/teams/update?batch=1" , {
345+ action : ( ) => page . locator ( "[data-testid=update-team-profile]" ) . click ( ) ,
346+ } ) ;
347+ } ) ;
348+
349+ test ( "Teams within same organization cannot have duplicate slugs" , async ( { page, users, orgs } ) => {
350+ const org = await orgs . create ( { name : "Organization 1" } ) ;
351+
352+ const owner = await users . create (
353+ {
354+ organizationId : org . id ,
355+ roleInOrganization : "OWNER" ,
356+ } ,
357+ {
358+ hasTeam : true ,
359+ numberOfTeams : 2 ,
360+ teamRole : "OWNER" ,
361+ }
362+ ) ;
363+
364+ const teams = await owner . getAllTeamMembership ( ) ;
365+ await owner . apiLogin ( ) ;
366+ await page . goto ( `/settings/teams/${ teams [ 0 ] . team . id } /profile` ) ;
367+ if ( ! teams [ 1 ] . team . slug ) throw new Error ( "Slug not found for team 2" ) ;
368+ await page . locator ( 'input[name="slug"]' ) . fill ( teams [ 1 ] . team . slug ) ;
369+ await submitAndWaitForResponse ( page , "/api/trpc/teams/update?batch=1" , {
370+ action : ( ) => page . locator ( "[data-testid=update-team-profile]" ) . click ( ) ,
371+ expectedStatusCode : 409 ,
372+ } ) ;
373+ } ) ;
374+
375+ test ( "Teams without organization can have same slug as teams in organizations" , async ( {
376+ page,
377+ users,
378+ orgs,
379+ } ) => {
380+ const org = await orgs . create ( { name : "Organization 1" } ) ;
381+
382+ const orgOwner = await users . create (
383+ {
384+ organizationId : org . id ,
385+ roleInOrganization : "OWNER" ,
386+ } ,
387+ {
388+ hasTeam : true ,
389+ teamSlug : "calCom" ,
390+ teamRole : "OWNER" ,
391+ }
392+ ) ;
393+
394+ const teamOwner = await users . create (
395+ { username : "pro-user" , name : "pro-user" } ,
396+ {
397+ hasTeam : true ,
398+ }
399+ ) ;
400+
401+ const { team } = await teamOwner . getFirstTeamMembership ( ) ;
402+ await teamOwner . apiLogin ( ) ;
403+ await page . goto ( `/settings/teams/${ team . id } /profile` ) ;
404+ await page . locator ( 'input[name="slug"]' ) . fill ( "calCom" ) ;
405+ await submitAndWaitForResponse ( page , "/api/trpc/teams/update?batch=1" , {
406+ action : ( ) => page . locator ( "[data-testid=update-team-profile]" ) . click ( ) ,
407+ } ) ;
408+ } ) ;
409+ } ) ;
0 commit comments