From f3db1fbb82ec3cfcd3b0d0f119ba7cd6801be862 Mon Sep 17 00:00:00 2001 From: Justin Date: Wed, 2 Oct 2024 09:15:49 -0700 Subject: [PATCH] feat(graph-api): split off graph api and add users class --- src/lib/graph-api/users/users.spec.ts | 42 +++++++++++++++++++-- src/lib/graph-api/users/users.ts | 53 +++++++++++++++++++++++---- 2 files changed, 84 insertions(+), 11 deletions(-) diff --git a/src/lib/graph-api/users/users.spec.ts b/src/lib/graph-api/users/users.spec.ts index f69cdfb..1c21868 100644 --- a/src/lib/graph-api/users/users.spec.ts +++ b/src/lib/graph-api/users/users.spec.ts @@ -20,29 +20,41 @@ describe('Users', () => { }) }) + describe('getManager', () => { + it(`gets a user's manager by user's userPrincipalName`, async () => { + const user = { id: 'id', userPrincipalName: 'userPrincipalName' } + const manager = { id: 'id', userPrincipalName: 'managerPrincipalName' } + jest.spyOn(mockAxios, 'get').mockResolvedValue({ data: manager }) + await expect(users.getManager(user.userPrincipalName)).resolves.toEqual(manager) + expect(mockAxios.get).toHaveBeenCalledWith(`users/${user.userPrincipalName}/manager`) + }) + }) + describe('assignManager', () => { it('throws an error given user is not found', async () => { - jest.spyOn(mockAxios, 'get').mockResolvedValue({ data: null }) + const err = new Error('resource not found') + jest.spyOn(mockAxios, 'get').mockRejectedValue(err) try { await users.assignManager('user', 'manager') expect(true).toBe(false) } catch (error: any) { expect(error.message).toEqual( - `Attempted to assign user's manager, but no user was found with userPrincipalName "user"`, + `${err.message}: Attempted to assign user's manager, but no user was found with userPrincipalName "user"`, ) } }) it('throws an error given manager is not found', async () => { + const err = new Error('resource not found') jest.spyOn(mockAxios, 'get') .mockResolvedValueOnce({ data: { id: 'userId' } }) - .mockResolvedValueOnce({ data: null }) + .mockRejectedValueOnce(err) try { await users.assignManager('user', 'manager') expect(true).toBe(false) } catch (error: any) { expect(error.message).toEqual( - `Attempted to assign manager as user's manager, but no user was found with userPrincipalName "manager"`, + `${err.message}: Attempted to assign manager as user's manager, but no user was found with userPrincipalName "manager"`, ) } }) @@ -58,4 +70,26 @@ describe('Users', () => { }) }) }) + + describe('removeManager', () => { + it('throws an error given user is not found', async () => { + const err = new Error('resource not found') + jest.spyOn(mockAxios, 'get').mockRejectedValue(err) + try { + await users.removeManager('user') + expect(true).toBe(false) + } catch (error: any) { + expect(error.message).toEqual( + `${err.message}: Attempted to remove user's manager, but no user was found with userPrincipalName "user"`, + ) + } + }) + + it('removes a manager', async () => { + jest.spyOn(mockAxios, 'get').mockResolvedValue({ data: { id: 'userId' } }) + jest.spyOn(mockAxios, 'delete').mockResolvedValue({ status: 204 }) + await users.removeManager('user') + expect(mockAxios.delete).toHaveBeenCalledWith('users/userId/manager/$ref') + }) + }) }) diff --git a/src/lib/graph-api/users/users.ts b/src/lib/graph-api/users/users.ts index c1d1848..71150fa 100644 --- a/src/lib/graph-api/users/users.ts +++ b/src/lib/graph-api/users/users.ts @@ -5,7 +5,7 @@ export class Users { constructor(private readonly http: AxiosInstance) {} /** - * Gets a user by id or userPrincipalNames + * Gets a user by id or userPrincipalName * https://learn.microsoft.com/en-us/graph/api/user-get * @param id {id | userPrincipalName} */ @@ -14,6 +14,16 @@ export class Users { return user } + /** + * Gets a user's by user's id or userPrincipalName + * https://learn.microsoft.com/en-us/graph/api/user-list-manager + * @param userPrincipalName + */ + async getManager(userPrincipalName: string): Promise { + const { data: user } = await this.http.get(`users/${userPrincipalName}/manager`) + return user + } + /** * Assigns a user's manager * https://learn.microsoft.com/en-us/graph/api/user-post-manager @@ -24,22 +34,51 @@ export class Users { userPrincipalName: string, managerPrincipalName: string, ): Promise> { - const user = await this.get(userPrincipalName) - if (!user) + let user: GraphUser + let manager: GraphUser + + try { + user = await this.get(userPrincipalName) + } catch (e: any) { throw new Error( - `Attempted to assign ${userPrincipalName}'s manager, but no user was found with ` + + `${e.message}: Attempted to assign ${userPrincipalName}'s manager, but no user was found with ` + `userPrincipalName "${userPrincipalName}"`, ) + } - const manager = await this.get(managerPrincipalName) - if (!manager) + try { + manager = await this.get(managerPrincipalName) + } catch (e: any) { throw new Error( - `Attempted to assign ${managerPrincipalName} as ${userPrincipalName}'s manager, ` + + `${e.message}: Attempted to assign ${managerPrincipalName} as ${userPrincipalName}'s manager, ` + `but no user was found with userPrincipalName "${managerPrincipalName}"`, ) + } return this.http.put(`users/${user.id}/manager/$ref`, { '@odata.id': `https://graph.microsoft.com/v1.0/users/${manager.id}`, }) } + + /** + * Removes a user's manager + * https://learn.microsoft.com/en-us/graph/api/user-delete-manager + * @param userPrincipalName + */ + async removeManager( + userPrincipalName: string, + ): Promise> { + let user: GraphUser + + try { + user = await this.get(userPrincipalName) + } catch (e: any) { + throw new Error( + `${e.message}: Attempted to remove ${userPrincipalName}'s manager, but no user was found with ` + + `userPrincipalName "${userPrincipalName}"`, + ) + } + + return this.http.delete(`users/${user.id}/manager/$ref`) + } }