This commit is contained in:
einhornimmond 2024-04-23 13:40:21 +02:00
parent 1e3dbbee68
commit 3df3b83274
4 changed files with 159 additions and 33 deletions

View File

@ -0,0 +1,50 @@
import { User } from '@entity/User'
import { UserContact } from '@entity/UserContact'
import { GetUser } from '@/apis/humhub/model/GetUser'
import { PostUser } from '@/apis/humhub/model/PostUser'
import { UsersResponse } from '@/apis/humhub/model/UsersResponse'
/**
* HumHubClient as singleton class
*/
export class HumHubClient {
// eslint-disable-next-line no-use-before-define
private static instance: HumHubClient
// eslint-disable-next-line no-useless-constructor, @typescript-eslint/no-empty-function
private constructor() {}
public static getInstance(): HumHubClient {
if (!HumHubClient.instance) {
HumHubClient.instance = new HumHubClient()
}
return HumHubClient.instance
}
public async users(): Promise<UsersResponse | null> {
return Promise.resolve(new UsersResponse())
}
public async userByEmail(email: string): Promise<GetUser | null> {
const user = new User()
user.emailContact = new UserContact()
user.emailContact.email = email
return Promise.resolve(new GetUser(user, 1))
}
public async createUser(): Promise<void> {
return Promise.resolve()
}
public async updateUser(inputUser: PostUser, humhubUserId: number): Promise<GetUser | null> {
const user = new User()
user.emailContact = new UserContact()
user.emailContact.email = inputUser.account.email
return Promise.resolve(new GetUser(user, humhubUserId))
}
public async deleteUser(): Promise<void> {
return Promise.resolve()
}
}

View File

@ -0,0 +1,44 @@
import { User } from '@entity/User'
import { isHumhubUserIdenticalToDbUser } from '@/apis/humhub/compareHumhubUserDbUser'
import { GetUser } from '@/apis/humhub/model/GetUser'
export enum ExecutedHumhubAction {
UPDATE,
CREATE,
SKIP,
DELETE,
}
/**
* Trigger action according to conditions
* | User exist on humhub | export to humhub allowed | changes in user data | ACTION
* | true | false | ignored | DELETE
* | true | true | true | UPDATE
* | true | true | false | SKIP
* | false | false | ignored | SKIP
* | false | true | ignored | CREATE
* @param user
* @param humHubClient
* @param humhubUsers
* @returns
*/
export async function syncUser(
user: User,
humhubUsers: Map<string, GetUser>,
): Promise<ExecutedHumhubAction> {
const humhubUser = humhubUsers.get(user.emailContact.email.trim())
if (humhubUser) {
if (!user.humhubAllowed) {
return Promise.resolve(ExecutedHumhubAction.DELETE)
}
if (!isHumhubUserIdenticalToDbUser(humhubUser, user)) {
// if humhub allowed
return Promise.resolve(ExecutedHumhubAction.UPDATE)
}
} else {
if (user.humhubAllowed) {
return Promise.resolve(ExecutedHumhubAction.CREATE)
}
}
return Promise.resolve(ExecutedHumhubAction.SKIP)
}

View File

@ -2,47 +2,16 @@
import { User } from '@entity/User'
import { UserContact } from '@entity/UserContact'
import { CONFIG } from '@/config'
import { HumHubClient } from './HumHubClient'
import { GetUser } from './model/GetUser'
import { syncUser, ExecutedHumhubAction } from './syncUser'
jest.mock('@/apis/humhub/HumHubClient')
const defaultUser = new User()
defaultUser.emailContact = new UserContact()
defaultUser.emailContact.email = 'email@gmail.com'
CONFIG.HUMHUB_ACTIVE = true
CONFIG.HUMHUB_API_URL = 'http://localhost'
let humhubClient: HumHubClient | undefined
let humhubClientSpy: {
createUser: jest.SpyInstance
updateUser: jest.SpyInstance
deleteUser: jest.SpyInstance
}
describe('syncUser function', () => {
beforeAll(() => {
humhubClient = HumHubClient.getInstance()
if (!humhubClient) {
throw new Error('error creating humhub client')
}
humhubClientSpy = {
createUser: jest.spyOn(humhubClient, 'createUser'),
updateUser: jest.spyOn(humhubClient, 'updateUser'),
deleteUser: jest.spyOn(humhubClient, 'deleteUser'),
}
humhubClientSpy.createUser.mockImplementation(() => Promise.resolve())
humhubClientSpy.updateUser.mockImplementation(() => Promise.resolve())
humhubClientSpy.deleteUser.mockImplementation(() => Promise.resolve())
})
afterEach(() => {
humhubClientSpy.createUser.mockClear()
humhubClientSpy.updateUser.mockClear()
humhubClientSpy.deleteUser.mockClear()
})
afterAll(() => {
jest.resetAllMocks()
})

View File

@ -0,0 +1,63 @@
import { User } from '@entity/User'
import { UserContact } from '@entity/UserContact'
import { HumHubClient } from '@/apis/humhub/HumHubClient'
import { GetUser } from '@/apis/humhub/model/GetUser'
import { ExecutedHumhubAction } from '@/apis/humhub/syncUser'
import { UpdateUserInfosArgs } from '@/graphql/arg/UpdateUserInfosArgs'
import { PublishNameType } from '@/graphql/enum/PublishNameType'
import { backendLogger as logger } from '@/server/logger'
import { syncHumhub } from './syncHumhub'
jest.mock('@/apis/humhub/HumHubClient')
jest.mock('@/apis/humhub/syncUser')
const mockUser = new User()
mockUser.humhubAllowed = true
mockUser.emailContact = new UserContact()
mockUser.emailContact.email = 'email@gmail.com'
mockUser.humhubPublishName = PublishNameType.PUBLISH_NAME_FULL
const mockUpdateUserInfosArg = new UpdateUserInfosArgs()
const mockHumHubUser = new GetUser(mockUser, 1)
describe('syncHumhub', () => {
beforeAll(() => {
// humhubClientMockbBeforeAll()
})
beforeEach(() => {
jest.spyOn(logger, 'debug').mockImplementation()
jest.spyOn(logger, 'info').mockImplementation()
jest.spyOn(HumHubClient, 'getInstance')
})
afterEach(() => {
// humhubClientMockbAfterEach()
})
afterAll(() => {
jest.resetAllMocks()
})
it('Should not sync if no relevant changes', async () => {
await syncHumhub(mockUpdateUserInfosArg, new User())
expect(HumHubClient.getInstance).not.toBeCalled()
// language logging from some other place
expect(logger.debug).toBeCalledTimes(4)
expect(logger.info).toBeCalledTimes(0)
})
it('Should retrieve user from humhub and sync if relevant changes', async () => {
mockUpdateUserInfosArg.firstName = 'New' // Relevant changes
mockUser.firstName = 'New'
await syncHumhub(mockUpdateUserInfosArg, mockUser)
expect(logger.debug).toHaveBeenCalledTimes(7) // Four language logging calls, two debug calls in function, one for not syncing
expect(logger.info).toHaveBeenLastCalledWith('finished sync user with humhub', {
localId: mockUser.id,
externId: mockHumHubUser.id,
result: ExecutedHumhubAction.UPDATE,
})
})
// Add more test cases as needed...
})