Files
workavia-calendar-front/__test__/utils/calendarUtils.test.tsx
T
lethemanh cadfa70e60 #708 apply strictier linting rules (#717)
* #708 apply strictier linting rules and fix simple eslint bugs

* #708 fix eslint errors relate to promise

* #708 fix eslint import/no-extraneous-dependencies

* #708 fix eslint errors of react-hook

* #708 enable eslint check for typescript

---------

Co-authored-by: lethemanh <lethemanh@lethemanhs-MacBook-Pro.local>
2026-04-01 17:15:10 +02:00

232 lines
6.7 KiB
TypeScript

import {
eventToFullCalendarFormat,
getCalendarVisibility
} from '@/components/Calendar/utils/calendarUtils'
import { Calendar, DelegationAccess } from '@/features/Calendars/CalendarTypes'
import { AclEntry } from '@/features/Calendars/types/CalendarData'
import { CalendarEvent } from '@/features/Events/EventsTypes'
import { userOrganiser } from '@/features/User/userDataTypes'
describe('getCalendarVisibility', () => {
it("returns 'public' when {DAV:}authenticated has {DAV:}read", () => {
const acl: AclEntry[] = [
{
privilege: '{DAV:}read',
principal: '{DAV:}authenticated',
protected: true
}
]
expect(getCalendarVisibility(acl)).toBe('public')
})
it("returns 'private' when {DAV:}authenticated only has read-free-busy", () => {
const acl: AclEntry[] = [
{
privilege: '{urn:ietf:params:xml:ns:caldav}read-free-busy',
principal: '{DAV:}authenticated',
protected: true
}
]
expect(getCalendarVisibility(acl)).toBe('private')
})
it("returns 'private' when {DAV:}authenticated is not present", () => {
const acl: AclEntry[] = [
{
privilege: '{DAV:}read',
principal: 'principals/users/123',
protected: true
}
]
expect(getCalendarVisibility(acl)).toBe('private')
})
it("ignores non-authenticated principals and still returns 'private'", () => {
const acl: AclEntry[] = [
{
privilege: '{DAV:}read',
principal: 'principals/users/other',
protected: true
},
{
privilege: '{DAV:}write',
principal: 'principals/users/other',
protected: true
}
]
expect(getCalendarVisibility(acl)).toBe('private')
})
it('stops early when it finds a {DAV:}read for {DAV:}authenticated', () => {
const acl: AclEntry[] = [
{
privilege: '{DAV:}read',
principal: '{DAV:}authenticated',
protected: true
},
{
privilege: '{DAV:}write',
principal: '{DAV:}authenticated',
protected: true
}
]
expect(getCalendarVisibility(acl)).toBe('public')
})
})
jest.mock('twake-i18n', () => ({
useI18n: () => ({ t: (key: string) => key })
}))
const baseEvent: CalendarEvent = {
uid: 'event-1',
calId: 'user1/cal1',
title: 'Test Event',
start: '2024-01-15T10:00:00',
end: '2024-01-15T11:00:00',
allday: false,
organizer: { cal_address: 'owner@example.com' } as userOrganiser,
color: { light: '#FF0000' },
class: 'PUBLIC'
} as unknown as CalendarEvent
const makeCalendar = (overrides: Partial<Calendar> = {}): Calendar =>
({
id: 'user1/cal1',
name: 'Test Calendar',
delegated: false,
access: {} as DelegationAccess,
owner: { emails: ['alice@example.com'], firstname: 'Alice' },
color: { light: '#FF0000' },
events: {},
...overrides
}) as Calendar
const callFormat = (
event: CalendarEvent,
calendars: Record<string, Calendar>,
userAddress = 'alice@example.com',
userId = 'user1'
) =>
eventToFullCalendarFormat([event], [], userId, userAddress, false, calendars)
describe('eventToFullCalendarFormat - editable flag', () => {
describe('personal calendar (non-delegated)', () => {
const calendar = makeCalendar({ delegated: false })
it('is editable when user is organizer', () => {
const event = {
...baseEvent,
organizer: { cal_address: 'alice@example.com' }
} as CalendarEvent
const [result] = callFormat(event, { 'user1/cal1': calendar })
expect(result.editable).toBe(true)
})
it('is not editable when user is not organizer', () => {
const event = {
...baseEvent,
organizer: { cal_address: 'other@example.com' }
} as CalendarEvent
const [result] = callFormat(event, { 'user1/cal1': calendar })
expect(result.editable).toBe(false)
})
it('is not editable when pending', () => {
const event = {
...baseEvent,
organizer: { cal_address: 'alice@example.com' }
} as CalendarEvent
const [result] = eventToFullCalendarFormat(
[event],
[],
'user1',
'alice@example.com',
true,
{ 'user1/cal1': calendar }
)
expect(result.editable).toBe(false)
})
})
describe('delegated calendar', () => {
const writeDelegatedCalendar = makeCalendar({
id: 'user2/cal1',
delegated: true,
access: { write: true } as DelegationAccess,
owner: { emails: ['owner@example.com'], firstname: 'Owner' }
})
const readDelegatedCalendar = makeCalendar({
id: 'user2/cal1',
delegated: true,
access: { read: true } as DelegationAccess,
owner: { emails: ['owner@example.com'], firstname: 'Owner' }
})
const event = { ...baseEvent, calId: 'user2/cal1' }
it('is editable when owner is organizer and delegated user has write rights', () => {
const [result] = callFormat(
{
...event,
organizer: { cal_address: 'owner@example.com' }
} as CalendarEvent,
{ 'user2/cal1': writeDelegatedCalendar }
)
expect(result.editable).toBe(true)
})
it('is not editable when owner is organizer but delegated user only has read access', () => {
const [result] = callFormat(
{
...event,
organizer: { cal_address: 'owner@example.com' }
} as CalendarEvent,
{ 'user2/cal1': readDelegatedCalendar }
)
expect(result.editable).toBe(false)
})
it('is not editable when owner is not organizer', () => {
const [result] = callFormat(
{
...event,
organizer: { cal_address: 'someone-else@example.com' }
} as CalendarEvent,
{ 'user2/cal1': writeDelegatedCalendar }
)
expect(result.editable).toBe(false)
})
it('is not editable when pending even if owner is organizer', () => {
const [result] = eventToFullCalendarFormat(
[
{
...event,
organizer: { cal_address: 'owner@example.com' }
} as CalendarEvent
],
[],
'user1',
'alice@example.com',
true,
{ 'user2/cal1': writeDelegatedCalendar }
)
expect(result.editable).toBe(false)
})
it('uses owner email not logged-in user email for organizer check', () => {
// logged-in user is alice, owner is owner@example.com
// organizer matches owner → editable
const [result] = callFormat(
{
...event,
organizer: { cal_address: 'owner@example.com' }
} as CalendarEvent,
{ 'user2/cal1': writeDelegatedCalendar },
'alice@example.com' // logged-in user, should NOT be used for delegated
)
expect(result.editable).toBe(true)
})
})
})