processOutputBBReference vs processOutputBBReferences

This commit is contained in:
Adria Navarro 2024-05-03 09:31:24 +02:00
parent 1767650337
commit 2c5e9ff784
2 changed files with 129 additions and 65 deletions

View File

@ -1,7 +1,6 @@
import { cache, db as dbCore } from "@budibase/backend-core" import { cache, db as dbCore } from "@budibase/backend-core"
import { utils } from "@budibase/shared-core" import { utils } from "@budibase/shared-core"
import { import {
FieldType,
BBReferenceFieldSubType, BBReferenceFieldSubType,
DocumentType, DocumentType,
SEPARATOR, SEPARATOR,
@ -104,67 +103,30 @@ interface UserReferenceInfo {
_id: string _id: string
primaryDisplay: string primaryDisplay: string
email: string email: string
firstName: string firstName?: string
lastName: string lastName?: string
} }
export function processOutputBBReferences( export async function processOutputBBReference(
value: string, value: string,
type: FieldType.BB_REFERENCE_SINGLE subtype: BBReferenceFieldSubType.USER
): Promise<UserReferenceInfo | undefined> ): Promise<UserReferenceInfo | undefined> {
export function processOutputBBReferences(
value: string,
type: FieldType.BB_REFERENCE,
subtype: BBReferenceFieldSubType
): Promise<UserReferenceInfo[] | undefined>
export async function processOutputBBReferences(
value: string | string[],
type: FieldType.BB_REFERENCE | FieldType.BB_REFERENCE_SINGLE,
subtype?: BBReferenceFieldSubType
) {
if (value === null || value === undefined) { if (value === null || value === undefined) {
// Already processed or nothing to process // Already processed or nothing to process
return value || undefined return value || undefined
} }
switch (type) { if (!value) {
case FieldType.BB_REFERENCE: { return undefined
const ids = }
typeof value === "string" ? value.split(",").filter(id => !!id) : value
switch (subtype) {
case undefined:
throw "Subtype must be defined"
case BBReferenceFieldSubType.USER:
case BBReferenceFieldSubType.USERS: {
const { users } = await cache.user.getUsers(ids)
if (!users.length) {
return undefined
}
return users.map(u => ({
_id: u._id,
primaryDisplay: u.email,
email: u.email,
firstName: u.firstName,
lastName: u.lastName,
}))
}
default:
throw utils.unreachable(subtype)
}
}
case FieldType.BB_REFERENCE_SINGLE: {
if (!value) {
return undefined
}
switch (subtype) {
case BBReferenceFieldSubType.USER:
let user let user
try { try {
user = await cache.user.getUser(value as string) user = await cache.user.getUser(value as string)
} catch (err: any) { } catch (err: any) {
if (err.code !== 404) { if (err.statusCode !== 404) {
throw err throw err
} }
} }
@ -173,15 +135,46 @@ export async function processOutputBBReferences(
} }
return { return {
_id: user._id, _id: user._id!,
primaryDisplay: user.email, primaryDisplay: user.email,
email: user.email, email: user.email,
firstName: user.firstName, firstName: user.firstName,
lastName: user.lastName, lastName: user.lastName,
} }
}
default: default:
throw utils.unreachable(type) throw utils.unreachable(subtype)
}
}
export async function processOutputBBReferences(
value: string,
subtype: BBReferenceFieldSubType
): Promise<UserReferenceInfo[] | undefined> {
if (value === null || value === undefined) {
// Already processed or nothing to process
return value || undefined
}
const ids =
typeof value === "string" ? value.split(",").filter(id => !!id) : value
switch (subtype) {
case BBReferenceFieldSubType.USER:
case BBReferenceFieldSubType.USERS: {
const { users } = await cache.user.getUsers(ids)
if (!users.length) {
return undefined
}
return users.map(u => ({
_id: u._id!,
primaryDisplay: u.email,
email: u.email,
firstName: u.firstName,
lastName: u.lastName,
}))
}
default:
throw utils.unreachable(subtype)
} }
} }

View File

@ -4,6 +4,7 @@ import { BBReferenceFieldSubType, FieldType, User } from "@budibase/types"
import { import {
processInputBBReference, processInputBBReference,
processInputBBReferences, processInputBBReferences,
processOutputBBReference,
processOutputBBReferences, processOutputBBReferences,
} from "../bbReferenceProcessor" } from "../bbReferenceProcessor"
import { import {
@ -33,6 +34,12 @@ jest.mock("@budibase/backend-core", (): typeof backendCore => {
const config = new DBTestConfiguration() const config = new DBTestConfiguration()
describe("bbReferenceProcessor", () => { describe("bbReferenceProcessor", () => {
const cacheGetUserSpy = backendCore.cache.user.getUser as jest.MockedFunction<
typeof backendCore.cache.user.getUser
>
const cacheGetUsersSpy = backendCore.cache.user
.getUsers as jest.MockedFunction<typeof backendCore.cache.user.getUsers>
const users: User[] = [] const users: User[] = []
beforeAll(async () => { beforeAll(async () => {
const userCount = 10 const userCount = 10
@ -57,9 +64,6 @@ describe("bbReferenceProcessor", () => {
describe("processInputBBReference", () => { describe("processInputBBReference", () => {
describe("subtype user", () => { describe("subtype user", () => {
const cacheGetUserSpy = backendCore.cache.user
.getUser as jest.MockedFunction<typeof backendCore.cache.user.getUser>
it("validate valid string id", async () => { it("validate valid string id", async () => {
const user = _.sample(users) const user = _.sample(users)
const userId = user!._id! const userId = user!._id!
@ -118,9 +122,6 @@ describe("bbReferenceProcessor", () => {
describe("processInputBBReferences", () => { describe("processInputBBReferences", () => {
describe("subtype user", () => { describe("subtype user", () => {
const cacheGetUsersSpy = backendCore.cache.user
.getUsers as jest.MockedFunction<typeof backendCore.cache.user.getUsers>
it("validate valid string id", async () => { it("validate valid string id", async () => {
const user = _.sample(users) const user = _.sample(users)
const userId = user!._id! const userId = user!._id!
@ -224,6 +225,41 @@ describe("bbReferenceProcessor", () => {
}) })
}) })
describe("processOutputBBReference", () => {
describe("subtype user", () => {
it("fetches user given a valid string id", async () => {
const user = _.sample(users)!
const userId = user._id!
const result = await config.doInTenant(() =>
processOutputBBReference(userId, BBReferenceFieldSubType.USER)
)
expect(result).toEqual({
_id: user._id,
primaryDisplay: user.email,
email: user.email,
firstName: user.firstName,
lastName: user.lastName,
})
expect(cacheGetUserSpy).toHaveBeenCalledTimes(1)
expect(cacheGetUserSpy).toHaveBeenCalledWith(userId)
})
it("returns undefined given an unexisting user", async () => {
const userId = generator.guid()
const result = await config.doInTenant(() =>
processOutputBBReference(userId, BBReferenceFieldSubType.USER)
)
expect(result).toBeUndefined()
expect(cacheGetUserSpy).toHaveBeenCalledTimes(1)
expect(cacheGetUserSpy).toHaveBeenCalledWith(userId)
})
})
})
describe("processOutputBBReferences", () => { describe("processOutputBBReferences", () => {
describe("subtype user", () => { describe("subtype user", () => {
it("fetches user given a valid string id", async () => { it("fetches user given a valid string id", async () => {
@ -231,11 +267,7 @@ describe("bbReferenceProcessor", () => {
const userId = user._id! const userId = user._id!
const result = await config.doInTenant(() => const result = await config.doInTenant(() =>
processOutputBBReferences( processOutputBBReferences(userId, BBReferenceFieldSubType.USER)
userId,
FieldType.BB_REFERENCE,
BBReferenceFieldSubType.USER
)
) )
expect(result).toEqual([ expect(result).toEqual([
@ -259,7 +291,6 @@ describe("bbReferenceProcessor", () => {
const result = await config.doInTenant(() => const result = await config.doInTenant(() =>
processOutputBBReferences( processOutputBBReferences(
[userId1, userId2].join(","), [userId1, userId2].join(","),
FieldType.BB_REFERENCE,
BBReferenceFieldSubType.USER BBReferenceFieldSubType.USER
) )
) )
@ -279,6 +310,46 @@ describe("bbReferenceProcessor", () => {
expect(cacheGetUsersSpy).toHaveBeenCalledTimes(1) expect(cacheGetUsersSpy).toHaveBeenCalledTimes(1)
expect(cacheGetUsersSpy).toHaveBeenCalledWith([userId1, userId2]) expect(cacheGetUsersSpy).toHaveBeenCalledWith([userId1, userId2])
}) })
it("trims unexisting users user given a valid string id csv", async () => {
const [user1, user2] = _.sampleSize(users, 2)
const userId1 = user1._id!
const userId2 = user2._id!
const unexistingUserId1 = generator.guid()
const unexistingUserId2 = generator.guid()
const input = [
unexistingUserId1,
userId1,
unexistingUserId2,
userId2,
].join(",")
const result = await config.doInTenant(() =>
processOutputBBReferences(input, BBReferenceFieldSubType.USER)
)
expect(result).toHaveLength(2)
expect(result).toEqual(
expect.arrayContaining(
[user1, user2].map(u => ({
_id: u._id,
primaryDisplay: u.email,
email: u.email,
firstName: u.firstName,
lastName: u.lastName,
}))
)
)
expect(cacheGetUsersSpy).toHaveBeenCalledTimes(1)
expect(cacheGetUsersSpy).toHaveBeenCalledWith([
unexistingUserId1,
userId1,
unexistingUserId2,
userId2,
])
})
}) })
}) })
}) })