api/src/db/factories.ts
import { dateType } from 'aws-sdk/clients/sts'; // tslint:disable-line
import * as faker from 'faker';
import * as Random from 'meteor-random';
import * as momentTz from 'moment-timezone';
import { FIELDS_GROUPS_CONTENT_TYPES } from '../data/constants';
import { fetchElk } from '../elasticsearch';
import {
Boards,
Branches,
Brands,
CalendarBoards,
CalendarGroups,
Calendars,
Channels,
ChecklistItems,
Checklists,
ClientPortals,
Companies,
Configs,
Conformities,
ConversationMessages,
Conversations,
Customers,
DashboardItems,
Dashboards,
Deals,
Departments,
EmailDeliveries,
EmailTemplates,
EngageMessages,
Fields,
FieldsGroups,
Forms,
FormSubmissions,
GrowthHacks,
ImportHistory,
Integrations,
InternalNotes,
KnowledgeBaseArticles,
KnowledgeBaseCategories,
KnowledgeBaseTopics,
MessengerApps,
NotificationConfigurations,
Notifications,
OnboardingHistories,
Permissions,
PipelineLabels,
Pipelines,
ProductCategories,
Products,
ProductTemplates,
ResponseTemplates,
Scripts,
Segments,
Skills,
SkillTypes,
Stages,
Structures,
Tags,
Tasks,
Tickets,
Units,
Users,
UsersGroups,
Webhooks
} from './models';
import { ICustomField } from './models/definitions/common';
import {
ACTIVITY_CONTENT_TYPES,
BOARD_STATUSES,
BOARD_TYPES,
CONVERSATION_OPERATOR_STATUS,
CONVERSATION_STATUSES,
FORM_TYPES,
MESSAGE_TYPES,
NOTIFICATION_TYPES,
PROBABILITY,
PRODUCT_TYPES,
WEBHOOK_ACTIONS
} from './models/definitions/constants';
import { ICustomerDocument } from './models/definitions/customers';
import {
IEmail,
IMessenger,
IScheduleDate
} from './models/definitions/engages';
import { IMessengerAppCrendentials } from './models/definitions/messengerApps';
import { ICondition } from './models/definitions/segments';
import { IUserDocument } from './models/definitions/users';
import PipelineTemplates from './models/PipelineTemplates';
export const getUniqueValue = async (
collection: any,
fieldName: string = 'code',
defaultValue?: string
) => {
const getRandomValue = (type: string) =>
type === 'email' ? faker.internet.email().toLowerCase() : Random.id();
let uniqueValue = defaultValue || getRandomValue(fieldName);
let duplicated = await collection.findOne({ [fieldName]: uniqueValue });
while (duplicated) {
uniqueValue = getRandomValue(fieldName);
duplicated = await collection.findOne({ [fieldName]: uniqueValue });
}
return uniqueValue;
};
interface IActivityLogFactoryInput {
contentType?: string;
contentId?: string;
action?: string;
content?: any;
createdBy?: string;
}
export const activityLogFactory = async (
params: IActivityLogFactoryInput = {}
) => ({
contentType: params.contentType || 'customer',
action: params.action || 'create',
contentId: params.contentId || faker.random.uuid(),
content: params.content || 'content',
createdBy: params.createdBy || faker.random.uuid()
});
interface IDashboardFactoryInput {
relatedIds?: string[];
name?: string;
parentId?: string;
description?: string;
}
export const dashboardFactory = async (params: IDashboardFactoryInput) => {
const dashboard = new Dashboards({
name: params.name || faker.random.word(),
parentId: params.parentId,
description: params.description || faker.random.word(),
relatedIds: params.relatedIds || []
});
return dashboard.save();
};
interface IDashboardFactoryInput {
dashboardId?: string;
layout?: string;
vizState?: string;
name?: string;
type?: string;
}
export const dashboardItemsFactory = async (params: IDashboardFactoryInput) => {
const dashboardItem = new DashboardItems({
name: params.name || 'name',
dashboardId: params.dashboardId || 'dashboardId',
layout: params.layout || 'layout',
vizState: params.vizState || 'vizState',
type: params.type || 'type'
});
return dashboardItem.save();
};
interface IUserFactoryInput {
code?: string;
username?: string;
fullName?: string;
avatar?: string;
position?: string;
twitter?: string;
facebook?: string;
linkedIn?: string;
youtube?: string;
github?: string;
website?: string;
email?: string;
password?: string;
isOwner?: boolean;
isActive?: boolean;
groupIds?: string[];
brandIds?: string[];
deviceTokens?: string[];
registrationToken?: string;
registrationTokenExpires?: Date;
isSubscribed?: string;
isShowNotification?: boolean;
validatedTokens?: string;
}
export const userFactory = async (
params: IUserFactoryInput = {},
syncToEs = false
) => {
const userDoc = {
username: params.username || faker.internet.userName(),
details: {
fullName: params.fullName || faker.random.word(),
avatar: params.avatar || faker.image.imageUrl(),
position: params.position || 'admin'
},
registrationToken: params.registrationToken,
registrationTokenExpires: params.registrationTokenExpires,
links: {
twitter: params.twitter || faker.random.word(),
facebook: params.facebook || faker.random.word(),
linkedIn: params.linkedIn || faker.random.word(),
youtube: params.youtube || faker.random.word(),
github: params.github || faker.random.word(),
website: params.website || faker.random.word()
},
email: await getUniqueValue(Users, 'email', params.email),
password:
params.password ||
'$2a$10$qfBFBmWmUjeRcR.nBBfgDO/BEbxgoai5qQhyjsrDUMiZC6dG7sg1q',
isOwner: typeof params.isOwner !== 'undefined' ? params.isOwner : true,
isActive: typeof params.isActive !== 'undefined' ? params.isActive : true,
groupIds: params.groupIds || [],
brandIds: params.brandIds,
deviceTokens: params.deviceTokens,
isSubscribed: params.isSubscribed,
isShowNotification: params.isShowNotification,
validatedTokens: params.validatedTokens,
...(params.code ? { code: params.code } : {})
};
const user = new Users(userDoc);
await user.save();
return syncToEs
? await fetchElk({
action: 'create',
index: 'users',
body: userDoc,
_id: user._id
})
: user;
};
interface ITagFactoryInput {
colorCode?: string;
type?: string;
parentId?: string;
relatedIds?: string[];
}
export const tagsFactory = (params: ITagFactoryInput = {}) => {
const tag = new Tags({
name: faker.random.word(),
type: params.type || 'engageMessage',
colorCode: params.colorCode || Random.id(),
userId: Random.id(),
parentId: params.parentId,
relatedIds: params.relatedIds || []
});
return tag.save();
};
interface IEngageMessageFactoryInput {
kind?: string;
userId?: string;
segmentIds?: string[];
brandIds?: string[];
tagIds?: string[] | string;
isLive?: boolean;
isDraft?: boolean;
customerIds?: string[];
method?: string;
messenger?: IMessenger;
title?: string;
email?: IEmail;
smsContent?: string;
fromUserId?: string;
fromIntegrationId?: string;
scheduleDate?: IScheduleDate;
createdBy?: string;
createdAt?: Date;
customerTagIds?: string[];
}
export const engageMessageFactory = (
params: IEngageMessageFactoryInput = {}
) => {
const engageMessage = new EngageMessages({
kind: params.kind || 'manual',
customerIds: params.customerIds || [],
method: params.method || 'messenger',
title: params.title || faker.random.word(),
fromUserId: params.userId || faker.random.uuid(),
createdBy: params.createdBy || faker.random.uuid(),
segmentIds: params.segmentIds || [],
brandIds: params.brandIds || [],
tagIds: params.tagIds || [],
customerTagIds: params.customerTagIds || [],
isLive: params.isLive || false,
isDraft: params.isDraft || false,
messenger: params.messenger,
email: params.email,
smsContent: {
content: params.smsContent || 'Sms content',
fromIntegrationId: params.fromIntegrationId
},
scheduleDate: params.scheduleDate || {
type: 'day'
},
createdAt: params.createdAt || new Date()
});
return engageMessage.save();
};
interface IBrandFactoryInput {
code?: string;
name?: string;
description?: string;
}
export const brandFactory = async (params: IBrandFactoryInput = {}) => {
const brand = new Brands({
name: params.name || faker.random.word(),
code: await getUniqueValue(Brands, 'code', params.code),
userId: Random.id(),
description: params.description || faker.random.word(),
createdAt: new Date(),
emailConfig: {
type: 'simple',
template: faker.random.word()
}
});
return brand.save();
};
interface ITemplateInput {
stages?: any[];
}
export const pipelineTemplateFactory = (params: ITemplateInput = {}) => {
const pipelineTemplate = new PipelineTemplates({
name: faker.random.word(),
description: faker.random.word(),
type: BOARD_TYPES.GROWTH_HACK,
stages: params.stages || [
{ name: faker.random.word(), formId: faker.random.word() },
{ name: faker.random.word(), formId: faker.random.word() }
]
});
return pipelineTemplate.save();
};
interface IProductTemplateInput {
title?: string;
discount?: number;
totalAmount?: number;
description?: string;
templateItems?: any[];
tagIds?: string[];
status?: string;
parentId?: string;
relatedIds?: string[];
}
export const productTemplateFactory = async (
params: IProductTemplateInput = {}
) => {
const prouctTemplate = new ProductTemplates({
type: 'productService',
title: await getUniqueValue(
ProductTemplates,
'title',
params.title || faker.random.word()
),
discount: params.discount || faker.random.number(),
totalAmount: params.totalAmount || faker.random.number(),
description: params.description || faker.random.word(),
templateItems: params.templateItems || [
{
_id: Math.random().toString(),
categoryId: Math.random().toString(),
itemId: Math.random().toString(),
unitPrice: faker.random.number(),
quantity: 1,
discount: 0
}
],
tagIds: params.tagIds || [faker.random.uuid()],
status: params.status || 'active',
parentId: params.parentId,
relatedIds: params.relatedIds || []
});
return prouctTemplate.save();
};
interface ILabelInput {
name?: string;
colorCode?: string;
pipelineId?: string;
type?: string;
createdBy?: string;
}
export const pipelineLabelFactory = (params: ILabelInput = {}) => {
const pipelineLabel = new PipelineLabels({
name: params.name || faker.random.word(),
colorCode: params.colorCode || faker.random.word(),
pipelineId: params.pipelineId || faker.random.word(),
type: params.type || BOARD_TYPES.DEAL,
createdBy: params.createdBy || faker.random.uuid().toString()
});
return pipelineLabel.save();
};
interface IEmailTemplateFactoryInput {
content?: string;
customerId?: string;
}
export const emailTemplateFactory = (
params: IEmailTemplateFactoryInput = {}
) => {
const emailTemplate = new EmailTemplates({
name: faker.random.word(),
customerId: params.customerId || Random.id(),
content: params.content || faker.random.word()
});
return emailTemplate.save();
};
interface IResponseTemplateFactoryInput {
name?: string;
content?: string;
brandId?: string;
}
export const responseTemplateFactory = (
params: IResponseTemplateFactoryInput = {}
) => {
const responseTemplate = new ResponseTemplates({
name: params.name || faker.random.word(),
content: params.content || faker.random.word(),
brandId: params.brandId || Random.id(),
files: [faker.random.image()]
});
return responseTemplate.save();
};
interface ISegmentFactoryInput {
contentType?: string;
description?: string;
subOf?: string;
color?: string;
conditions?: ICondition[];
conditionsConjunction?: 'and' | 'or';
boardId?: string;
pipelineId?: string;
}
export const segmentFactory = (params: ISegmentFactoryInput = {}) => {
const defaultConditions = [
{
field: 'messengerData.sessionCount',
operator: 'e',
value: '10',
type: 'string'
}
];
const segment = new Segments({
contentType: params.contentType || ACTIVITY_CONTENT_TYPES.CUSTOMER,
name: faker.random.word(),
description: params.description || faker.random.word(),
subOf: params.subOf,
color: params.color || '#809b87',
conditions: params.conditions || defaultConditions,
conditionsConjunction: params.conditionsConjunction,
boardId: params.boardId,
pipelineId: params.pipelineId
});
return segment.save();
};
interface IInternalNoteFactoryInput {
contentType?: string;
contentTypeId?: string;
content?: string;
mentionedUserIds?: string[];
}
export const internalNoteFactory = (params: IInternalNoteFactoryInput) => {
const internalNote = new InternalNotes({
contentType: params.contentType || ACTIVITY_CONTENT_TYPES.CUSTOMER,
contentTypeId: params.contentTypeId || faker.random.uuid().toString(),
content: params.content || faker.random.word()
});
return internalNote.save();
};
interface IChecklistFactoryInput {
contentType?: string;
contentTypeId?: string;
title?: string;
createdUserId?: string;
}
export const checklistFactory = (params: IChecklistFactoryInput) => {
const checklist = new Checklists({
contentType: params.contentType || ACTIVITY_CONTENT_TYPES.DEAL,
contentTypeId: params.contentTypeId || faker.random.uuid().toString(),
title: params.title || faker.random.uuid().toString(),
createdUserId: params.createdUserId || faker.random.uuid().toString()
});
return checklist.save();
};
interface IChecklistItemFactoryInput {
checklistId?: string;
content?: string;
isChecked?: boolean;
createdUserId?: string;
order?: number;
}
export const checklistItemFactory = (params: IChecklistItemFactoryInput) => {
const checklistItem = new ChecklistItems({
checklistId: params.checklistId || faker.random.uuid().toString,
content: params.content || faker.random.uuid().toString,
isChecked: params.isChecked || false,
createdUserId: params.createdUserId || faker.random.uuid().toString(),
order: params.order || 0
});
return checklistItem.save();
};
interface ICompanyFactoryInput {
primaryName?: string;
names?: string[];
size?: number;
industry?: string;
website?: string;
tagIds?: string[];
scopeBrandIds?: string[];
plan?: string;
status?: string;
createdAt?: Date;
modifiedAt?: Date;
phones?: string[];
emails?: string[];
primaryPhone?: string;
primaryEmail?: string;
parentCompanyId?: string;
ownerId?: string;
mergedIds?: string[];
code?: string;
}
export const companyFactory = async (
params: ICompanyFactoryInput = {},
syncToEs = false
) => {
const companyDoc = {
primaryName: params.primaryName || faker.random.word(),
names: params.names || [],
size: params.size || faker.random.number(),
industry: params.industry || 'Airlines',
website: params.website || faker.internet.domainName(),
tagIds: params.tagIds || [],
plan: params.plan || faker.random.word(),
status: params.status || 'Active',
phones: params.phones || [],
emails: params.emails || [],
scopeBrandIds: params.scopeBrandIds || [],
primaryPhone: params.primaryPhone || '',
primaryEmail: params.primaryEmail || '',
parentCompanyId: params.parentCompanyId || faker.random.uuid().toString(),
ownerId: params.ownerId || faker.random.uuid().toString(),
mergedIds: params.mergedIds || [],
code: params.code || ''
};
const searchText = Companies.fillSearchText({ ...companyDoc });
Object.assign(companyDoc, {
createdAt: params.createdAt || new Date(),
modifiedAt: params.modifiedAt || new Date(),
searchText
});
const company = new Companies(companyDoc);
await company.save();
return syncToEs
? await fetchElk({
action: 'create',
index: 'companies',
body: companyDoc,
_id: company._id
})
: company;
};
interface ICustomerFactoryInput {
integrationId?: string;
firstName?: string;
lastName?: string;
middleName?: string;
sex?: number;
birthDate?: Date;
primaryEmail?: string;
primaryPhone?: string;
emails?: string[];
phones?: string[];
isSubscribed?: string;
leadStatus?: string;
status?: string;
customFieldsData?: any;
trackedData?: any;
tagIds?: string[];
ownerId?: string;
profileScore?: number;
code?: string;
isOnline?: boolean;
lastSeenAt?: number;
sessionCount?: number;
visitorContactInfo?: any;
deviceTokens?: string[];
emailValidationStatus?: string;
phoneValidationStatus?: string;
mergedIds?: string[];
relatedIntegrationIds?: string[];
state?: 'visitor' | 'lead' | 'customer';
}
export const customerFactory = async (
params: ICustomerFactoryInput = {},
useModelMethod = false,
syncToEs = false
): Promise<ICustomerDocument> => {
const createdAt = faker.date.past();
const doc = {
createdAt,
integrationId: params.integrationId,
firstName: params.firstName,
lastName: params.lastName,
middleName: params.middleName,
sex: params.sex,
birthDate: params.birthDate,
primaryEmail: params.primaryEmail,
primaryPhone: params.primaryPhone,
emails: params.emails || [],
phones: params.phones || [],
leadStatus: params.leadStatus || 'new',
status: params.status || 'Active',
lastSeenAt: faker.date.between(createdAt, new Date()),
isOnline: params.isOnline || false,
sessionCount: faker.random.number(),
customFieldsData: params.customFieldsData || [],
trackedData: params.trackedData || [],
tagIds: params.tagIds || [Random.id()],
ownerId: params.ownerId || Random.id(),
emailValidationStatus: params.emailValidationStatus || 'unknown',
phoneValidationStatus: params.phoneValidationStatus || 'unknown',
profileScore: params.profileScore || 0,
code: await getUniqueValue(Customers, 'code', params.code),
visitorContactInfo: params.visitorContactInfo,
deviceTokens: params.deviceTokens || [],
mergedIds: params.mergedIds || [],
relatedIntegrationIds: params.relatedIntegrationIds || [],
state: params.state
};
if (useModelMethod) {
const customer = await Customers.createCustomer(doc);
return syncToEs
? await fetchElk({
action: 'create',
index: 'customers',
body: doc,
_id: customer._id
})
: customer;
}
const customerObject = new Customers(doc);
const savedCustomer = await customerObject.save();
return syncToEs
? await fetchElk({
action: 'create',
index: 'customers',
body: doc,
_id: savedCustomer._id
})
: savedCustomer;
};
interface IFieldFactoryInput {
contentType?: string;
contentTypeId?: string;
type?: string;
validation?: string;
text?: string;
description?: string;
isRequired?: boolean;
order?: number;
visible?: boolean;
groupId?: string;
isDefinedByErxes?: boolean;
isVisible?: boolean;
isVisibleInDetail?: boolean;
canHide?: boolean;
options?: string[];
associatedFieldId?: string;
showInCard?: boolean;
productCategoryId?: string;
}
export const fieldFactory = async (params: IFieldFactoryInput) => {
const groupObj = await fieldGroupFactory({});
if (!groupObj) {
throw new Error('Failed to create fieldGroup');
}
return Fields.create({
contentType: params.contentType || 'form',
contentTypeId: params.contentTypeId || faker.random.uuid(),
type: params.type || 'input',
validation: params.validation || '',
text: params.text || faker.random.word(),
description: params.description || faker.random.word(),
isRequired: params.isRequired || false,
order: params.order || 0,
isVisible:
params.visible === undefined || params.visible === null
? true
: params.visible,
isVisibleInDetail:
params.isVisibleInDetail === undefined ||
params.isVisibleInDetail === null
? true
: params.isVisibleInDetail,
canHide:
params.canHide === undefined || params.canHide === null
? true
: params.canHide,
groupId: params.groupId || (groupObj ? groupObj._id : ''),
associatedFieldId: params.associatedFieldId,
isDefinedByErxes:
params.isDefinedByErxes === undefined || params.isDefinedByErxes === null
? false
: params.isDefinedByErxes,
showInCard: params.showInCard || false,
productCategoryId: params.productCategoryId || ''
});
};
interface IConversationFactoryInput {
customerId?: string;
assignedUserId?: string;
integrationId?: string;
operatorStatus?: string;
userId?: string;
content?: string;
participatedUserIds?: string[];
status?: string;
closedAt?: dateType;
closedUserId?: string;
readUserIds?: string[];
tagIds?: string[];
messageCount?: number;
userRelevance?: string;
number?: number;
firstRespondedUserId?: string;
firstRespondedDate?: dateType;
isCustomerRespondedLast?: boolean;
}
export const conversationFactory = (params: IConversationFactoryInput = {}) => {
const doc = {
content: params.content || faker.random.word(),
customerId: params.customerId || Random.id(),
integrationId: params.integrationId || Random.id(),
status: params.status || CONVERSATION_STATUSES.NEW,
operatorStatus:
params.operatorStatus || CONVERSATION_OPERATOR_STATUS.OPERATOR,
...(params.userRelevance ? { userRelevance: params.userRelevance } : {})
};
return Conversations.createConversation({
...doc,
...params
});
};
interface IConversationMessageFactoryInput {
conversationId?: string;
content?: string;
mentionedUserIds?: string[];
internal?: boolean;
customerId?: string;
userId?: any;
isCustomerRead?: boolean;
engageData?: any;
formWidgetData?: any;
kind?: string;
contentType?: string;
}
export const conversationMessageFactory = async (
params: IConversationMessageFactoryInput
) => {
let conversationId = params.conversationId;
if (!conversationId) {
const conversation = await conversationFactory({});
conversationId = conversation._id;
}
let userId = params.userId;
if (params.userId === undefined) {
userId = Random.id();
}
return ConversationMessages.createMessage({
content: params.content,
attachments: [],
mentionedUserIds: params.mentionedUserIds || [Random.id()],
conversationId,
internal:
params.internal === undefined || params.internal === null
? true
: params.internal,
customerId: params.customerId || Random.id(),
userId,
isCustomerRead: params.isCustomerRead,
engageData: params.engageData || {},
formWidgetData: params.formWidgetData || {},
contentType: params.contentType || MESSAGE_TYPES.TEXT
});
};
interface IIntegrationFactoryInput {
name?: string;
kind?: string;
brandId?: string;
formId?: string;
leadData?: any;
tagIds?: string[];
isActive?: boolean;
messengerData?: any;
languageCode?: string;
bookingData?: any;
visibility?: string;
departmentIds?: string[];
}
export const integrationFactory = async (
params: IIntegrationFactoryInput = {}
) => {
const kind = params.kind || 'messenger';
const doc = {
name: params.name || faker.random.word(),
kind,
languageCode: params.languageCode,
brandId: params.brandId || faker.random.uuid().toString(),
formId: params.formId,
messengerData: params.messengerData,
leadData: params.leadData
? params.leadData
: { thankTitle: 'thankTitle', thankContent: 'thankContent' },
tagIds: params.tagIds,
isActive:
params.isActive === undefined || params.isActive === null
? true
: params.isActive,
bookingData: params.bookingData
? params.bookingData
: {
name: 'Booking Data',
description: 'Booking description'
},
visibility: params.visibility || 'public',
departmentIds: params.departmentIds || []
};
if (params.messengerData && !params.messengerData.timezone) {
doc.messengerData.timezone = momentTz.tz.guess(true);
}
const user = await userFactory({});
return Integrations.create({ createdUserId: user._id, ...doc });
};
interface IFormFactoryInput {
title?: string;
code?: string;
type?: string;
description?: string;
createdUserId?: string;
}
export const formFactory = async (params: IFormFactoryInput = {}) => {
const { title, description, code, type, createdUserId } = params;
return Forms.create({
title: title || faker.random.word(),
description: description || faker.random.word(),
code: await getUniqueValue(Forms, 'code', code),
type: type || FORM_TYPES.GROWTH_HACK,
createdUserId: createdUserId || (await userFactory({}))
});
};
interface IFormSubmissionFactoryInput {
customerId?: string;
formId?: string;
contentType?: string;
contentTypeId?: string;
formFieldId?: string;
value?: string;
}
export const formSubmissionFactory = async (
params: IFormSubmissionFactoryInput = {},
syncToEs = false
) => {
const doc = {
submittedAt: new Date(),
customerId: params.customerId || faker.random.word(),
contentType: params.contentType,
contentTypeId: params.contentTypeId,
formId: params.formId || faker.random.word(),
formFieldId: params.formFieldId,
value: params.value
};
const submission = await FormSubmissions.create(doc);
return syncToEs
? await fetchElk({
action: 'create',
index: 'form_submissions',
body: doc,
_id: submission._id
})
: submission;
};
interface INotificationConfigurationFactoryInput {
isAllowed?: boolean;
notifType?: string;
user?: IUserDocument;
}
export const notificationConfigurationFactory = (
params: INotificationConfigurationFactoryInput
) => {
let { isAllowed } = params;
if (isAllowed == null) {
isAllowed = true;
}
return NotificationConfigurations.create({
notifType: params.notifType || NOTIFICATION_TYPES.CHANNEL_MEMBERS_CHANGE,
// which module's type it is. For example: indocuments
isAllowed,
user: params.user || userFactory({})
});
};
interface INotificationFactoryInput {
receiver?: any;
notifType?: string;
title?: string;
content?: string;
link?: string;
createdUser?: any;
isRead?: boolean;
contentTypeId?: string;
contentType?: string;
}
export const notificationFactory = async (
params: INotificationFactoryInput
) => {
let receiver = params.receiver;
if (!receiver) {
receiver = await userFactory({});
}
return Notifications.create({
notifType: params.notifType || NOTIFICATION_TYPES.CHANNEL_MEMBERS_CHANGE,
title: params.title || 'new Notification title',
content: params.content || 'new Notification content',
link: params.link || 'new Notification link',
receiver: receiver._id || faker.random.word(),
createdUser: params.createdUser || faker.random.word(),
isRead: params.isRead || false,
contentTypeId: params.contentTypeId,
contentType: params.contentType
});
};
interface IChannelFactoryInput {
integrationIds?: string[];
userId?: string;
memberIds?: string[];
}
export const channelFactory = async (params: IChannelFactoryInput = {}) => {
const user = await userFactory({});
const obj = {
name: faker.random.word(),
description: faker.lorem.sentence,
integrationIds: params.integrationIds,
memberIds: params.userId || [user._id],
userId: user._id,
conversationCount: 0,
openConversationCount: 0,
createdAt: new Date(),
...params
};
return Channels.create(obj);
};
interface IKnowledgeBaseTopicFactoryInput {
userId?: string;
color?: string;
brandId?: string;
}
export const knowledgeBaseTopicFactory = async (
params: IKnowledgeBaseTopicFactoryInput = {}
) => {
const doc = {
title: faker.random.word(),
description: faker.lorem.sentence,
brandId: params.brandId || faker.random.word(),
color: params.color
};
return KnowledgeBaseTopics.createDoc(
{
...doc,
...params
},
params.userId || faker.random.word()
);
};
interface IKnowledgeBaseCategoryFactoryInput {
userId?: string;
topicId?: string;
parentCategoryId?: string;
}
export const knowledgeBaseCategoryFactory = async (
params: IKnowledgeBaseCategoryFactoryInput = {}
) => {
const doc = {
title: faker.random.word(),
description: faker.lorem.sentence,
icon: faker.random.word(),
topicId: params.topicId,
parentCategoryId: params.parentCategoryId
};
return KnowledgeBaseCategories.createDoc(
{ ...doc, ...params },
params.userId || faker.random.word()
);
};
interface IKnowledgeBaseArticleCategoryInput {
userId?: string;
reactionChoices?: string[];
status?: string;
modifiedBy?: string;
topicId?: string;
categoryId?: string;
title?: string;
}
export const knowledgeBaseArticleFactory = async (
params: IKnowledgeBaseArticleCategoryInput = {}
) => {
const doc = {
title: params.title || faker.random.word(),
summary: faker.lorem.sentence,
content: faker.lorem.sentence,
icon: faker.random.word(),
reactionChoices: params.reactionChoices || ['wow'],
status: params.status || 'draft',
modifiedBy: params.modifiedBy,
topicId: params.topicId,
categoryId: params.categoryId
};
return KnowledgeBaseArticles.createDoc(
{ ...doc, ...params },
params.userId || faker.random.word()
);
};
interface IBoardFactoryInput {
name?: string;
type?: string;
}
export const boardFactory = (params: IBoardFactoryInput = {}) => {
const board = new Boards({
name: params.name || faker.random.word(),
userId: Random.id(),
type: params.type || BOARD_TYPES.DEAL
});
return board.save();
};
interface IPipelineFactoryInput {
boardId?: string;
type?: string;
bgColor?: string;
hackScoringType?: string;
visibility?: string;
memberIds?: string[];
watchedUserIds?: string[];
startDate?: Date;
endDate?: Date;
templateId?: string;
numberConfig?: string;
numberSize?: string;
}
export const pipelineFactory = async (params: IPipelineFactoryInput = {}) => {
const type = params.type || BOARD_TYPES.DEAL;
let boardId = params.boardId;
if (!boardId) {
const board = await boardFactory({ type });
boardId = board._id;
}
return Pipelines.create({
name: faker.random.word(),
boardId,
type,
visibility: params.visibility || 'public',
bgColor: params.bgColor || 'fff',
hackScoringType: params.hackScoringType,
memberIds: params.memberIds,
watchedUserIds: params.watchedUserIds,
startDate: params.startDate,
endDate: params.endDate,
templateId: params.templateId,
numberConfig: params.numberConfig || '{year}_',
numberSize: params.numberSize || '1'
});
};
interface IStageFactoryInput {
pipelineId?: string;
type?: string;
probability?: string;
formId?: string;
status?: string;
order?: number;
name?: string;
}
export const stageFactory = async (params: IStageFactoryInput = {}) => {
const type = params.type || BOARD_TYPES.DEAL;
const board = await boardFactory({ type });
const pipeline = await pipelineFactory({ type, boardId: board._id });
const stage = new Stages({
name: params.name || faker.random.word(),
pipelineId: params.pipelineId || pipeline._id,
type: params.type || BOARD_TYPES.DEAL,
probability: params.probability || PROBABILITY.TEN,
formId: params.formId,
order: params.order,
status: params.status || BOARD_STATUSES.ACTIVE
});
return stage.save();
};
interface IDealFactoryInput {
name?: string;
stageId?: string;
productsData?: any;
closeDate?: Date;
noCloseDate?: boolean;
assignedUserIds?: string[];
watchedUserIds?: string[];
labelIds?: string[];
modifiedBy?: string;
order?: number;
probability?: string;
searchText?: string;
userId?: string;
initialStageId?: string;
sourceConversationIds?: string[];
companyIds?: string[];
customerIds?: string[];
priority?: string;
startDate?: Date;
customFieldsData?: any;
}
const createConformities = async (mainType, object, params) => {
for (const companyId of params.companyIds || []) {
const conform = await Conformities.addConformity({
mainType,
mainTypeId: object._id,
relType: 'company',
relTypeId: companyId
});
await fetchElk({
action: 'create',
index: 'conformities',
body: {
mainType,
mainTypeId: object._id,
relType: 'company',
relTypeId: companyId
},
_id: conform._id
});
}
for (const customerId of params.customerIds || []) {
const conform = await Conformities.addConformity({
mainType,
mainTypeId: object._id,
relType: 'customer',
relTypeId: customerId
});
await fetchElk({
action: 'create',
index: 'conformities',
body: {
mainType,
mainTypeId: object._id,
relType: 'customer',
relTypeId: customerId
},
_id: conform._id
});
}
};
export const dealFactory = async (
params: IDealFactoryInput = {},
syncToEs = false
) => {
const board = await boardFactory({ type: BOARD_TYPES.DEAL });
const pipeline = await pipelineFactory({ boardId: board._id });
const stage = await stageFactory({ pipelineId: pipeline._id });
const stageId = params.stageId || stage._id;
const dealDoc = {
...params,
initialStageId: stageId,
name: params.name || faker.random.word(),
stageId,
amount: faker.random.objectElement(),
...(!params.noCloseDate
? { closeDate: params.closeDate || new Date() }
: {}),
description: faker.random.word(),
startDate: params.startDate,
productsData: params.productsData,
assignedUserIds: params.assignedUserIds || [faker.random.word()],
userId: params.userId || faker.random.word(),
watchedUserIds: params.watchedUserIds,
labelIds: params.labelIds || [],
order: params.order,
probability: params.probability,
searchText: params.searchText,
sourceConversationIds: params.sourceConversationIds,
priority: params.priority,
createdAt: new Date(),
customFieldsData: params.customFieldsData
};
const deal = new Deals(dealDoc);
const savedDeal = await deal.save();
if (syncToEs) {
await fetchElk({
action: 'create',
index: 'deals',
body: dealDoc,
_id: savedDeal._id
});
await createConformities('deal', savedDeal, params);
}
return savedDeal;
};
interface ITaskFactoryInput {
name?: string;
stageId?: string;
closeDate?: Date;
noCloseDate?: boolean;
assignedUserIds?: string[];
priority?: string;
watchedUserIds?: string[];
labelIds?: string[];
sourceConversationIds?: string[];
initialStageId?: string;
companyIds?: string[];
customerIds?: string[];
customFieldsData?: any;
}
export const attachmentFactory = () => ({
name: faker.random.word(),
url: faker.image.imageUrl(),
type: faker.system.mimeType(),
size: faker.random.number()
});
export const taskFactory = async (
params: ITaskFactoryInput = {},
syncToEs = false
) => {
const board = await boardFactory({ type: BOARD_TYPES.TASK });
const pipeline = await pipelineFactory({
boardId: board._id,
type: BOARD_TYPES.TASK
});
const stage = await stageFactory({
pipelineId: pipeline._id,
type: BOARD_TYPES.TASK
});
const taskDoc = {
...params,
name: params.name || faker.random.word(),
stageId: params.stageId || stage._id,
...(!params.noCloseDate
? { closeDate: params.closeDate || new Date() }
: {}),
description: faker.random.word(),
assignedUserIds: params.assignedUserIds,
priority: params.priority,
watchedUserIds: params.watchedUserIds,
labelIds: params.labelIds || [],
sourceConversationIds: params.sourceConversationIds,
attachments: [attachmentFactory(), attachmentFactory()],
customFieldsData: params.customFieldsData
};
const task = new Tasks(taskDoc);
const savedTask = await task.save();
if (syncToEs) {
await fetchElk({
action: 'create',
index: 'tasks',
body: taskDoc,
_id: savedTask._id
});
await createConformities('task', savedTask, params);
}
return savedTask;
};
interface ITicketFactoryInput {
name?: string;
stageId?: string;
userId?: string;
closeDate?: Date;
noCloseDate?: boolean;
assignedUserIds?: string[];
priority?: string;
source?: string;
watchedUserIds?: string[];
labelIds?: string[];
sourceConversationIds?: string[];
companyIds?: string[];
customerIds?: string[];
customFieldsData?: any;
}
export const ticketFactory = async (
params: ITicketFactoryInput = {},
syncToEs = false
) => {
const board = await boardFactory({ type: BOARD_TYPES.TICKET });
const pipeline = await pipelineFactory({
boardId: board._id,
type: BOARD_TYPES.TICKET
});
const stage = await stageFactory({
pipelineId: pipeline._id,
type: BOARD_TYPES.TICKET
});
const ticketDoc = {
...params,
name: params.name || faker.random.word(),
userId: params.userId,
stageId: params.stageId || stage._id,
...(!params.noCloseDate
? { closeDate: params.closeDate || new Date() }
: {}),
description: faker.random.word(),
assignedUserIds: params.assignedUserIds,
priority: params.priority,
source: params.source,
watchedUserIds: params.watchedUserIds,
labelIds: params.labelIds || [],
sourceConversationIds: params.sourceConversationIds,
customFieldsData: params.customFieldsData
};
const ticket = new Tickets(ticketDoc);
const savedTicket = await ticket.save();
if (syncToEs) {
await fetchElk({
action: 'create',
index: 'tickets',
body: ticketDoc,
_id: savedTicket._id
});
await createConformities('ticket', savedTicket, params);
}
return savedTicket;
};
interface IGrowthHackFactoryInput {
name?: string;
stageId?: string;
closeDate?: Date;
customerIds?: string[];
companyIds?: string[];
noCloseDate?: boolean;
assignedUserIds?: string[];
watchedUserIds?: string[];
hackStages?: string[];
priority?: string;
ease?: number;
impact?: number;
votedUserIds?: string[];
labelIds?: string[];
initialStageId?: string;
order?: number;
}
export const growthHackFactory = async (
params: IGrowthHackFactoryInput = {}
) => {
const board = await boardFactory({ type: BOARD_TYPES.GROWTH_HACK });
const pipeline = await pipelineFactory({ boardId: board._id });
const stage = await stageFactory({ pipelineId: pipeline._id });
const growthHack = new GrowthHacks({
...params,
name: params.name || faker.random.word(),
stageId: params.stageId || stage._id,
companyIds: params.companyIds || [faker.random.word()],
customerIds: params.customerIds || [faker.random.word()],
...(!params.noCloseDate
? { closeDate: params.closeDate || new Date() }
: {}),
description: faker.random.word(),
assignedUserIds: params.assignedUserIds || [faker.random.word()],
hackStages: params.hackStages || [faker.random.word()],
votedUserIds: params.votedUserIds || [faker.random.uuid().toString()],
watchedUserIds: params.watchedUserIds,
ease: params.ease || 0,
impact: params.impact || 0,
priority: params.priority,
labelIds: params.labelIds || [],
order: params.order || Math.random()
});
return growthHack.save();
};
interface IProductFactoryInput {
name?: string;
type?: string;
description?: string;
tagIds?: string[];
categoryId?: string;
vendorId?: string;
customFieldsData?: ICustomField[];
attachmentMore?: any[];
unitPrice?: number;
productCount?: number;
supply?: string;
}
export const productFactory = async (params: IProductFactoryInput = {}) => {
const product = new Products({
name: params.name || faker.random.word(),
categoryId: params.categoryId || faker.random.word(),
type: params.type || PRODUCT_TYPES.PRODUCT,
customFieldsData: params.customFieldsData,
attachmentMore: params.attachmentMore,
description: params.description || faker.random.word(),
sku: faker.random.word(),
code: await getUniqueValue(Products, 'code'),
vendorId: params.vendorId,
createdAt: new Date(),
tagIds: params.tagIds || [],
unitPrice: params.unitPrice || 10,
productCount: params.productCount || 0,
supply: params.supply || 'unique'
});
return product.save();
};
interface IProductCategoryFactoryInput {
name?: string;
description?: string;
parentId?: string;
status?: string;
code?: string;
order?: string;
}
export const productCategoryFactory = async (
params: IProductCategoryFactoryInput = {}
) => {
const productCategory = new ProductCategories({
name: params.name || faker.random.word(),
description: params.description || faker.random.word(),
parentId: params.parentId,
status: params.status,
code: await getUniqueValue(ProductCategories, 'code', params.code),
order: params.order || faker.random.word(),
createdAt: new Date()
});
return productCategory.save();
};
interface IConfigFactoryInput {
code?: string;
value?: string[];
}
export const configFactory = async (params: IConfigFactoryInput = {}) => {
const config = new Configs({
...params,
code: await getUniqueValue(Configs, 'code', params.code),
value: [faker.random.word()]
});
return config.save();
};
interface IFieldGroupFactoryInput {
contentType?: string;
isDefinedByErxes?: boolean;
isVisible?: boolean;
order?: number;
boardIds?: [string];
pipelineIds?: [string];
}
export const fieldGroupFactory = async (params: IFieldGroupFactoryInput) => {
const doc = {
name: faker.random.word(),
contentType: params.contentType || FIELDS_GROUPS_CONTENT_TYPES.CUSTOMER,
description: faker.random.word(),
isDefinedByErxes: params.isDefinedByErxes || false,
isVisible: true,
order: params.order || 0,
boardIds: params.boardIds || [],
pipelineIds: params.pipelineIds || []
};
const groupObj = await FieldsGroups.create(doc);
FieldsGroups.updateOne({ _id: groupObj._id }, { $set: { ...params } });
return FieldsGroups.findOne({ _id: groupObj._id });
};
interface IImportHistoryFactoryInput {
contentTypes?: string[];
failed?: number;
total?: number;
success?: string;
errorMsgs?: string[];
ids?: string[];
}
export const importHistoryFactory = async (
params: IImportHistoryFactoryInput
) => {
const user = await userFactory({});
const doc = {
failed: params.failed || faker.random.number(),
total: params.total || faker.random.number(),
success: params.success || faker.random.number(),
ids: params.ids,
contentTypes: params.contentTypes || ['customer'],
errorMsgs: params.errorMsgs
};
return ImportHistory.create({ ...doc, ...params, userId: user._id });
};
interface IMessengerApp {
name?: string;
kind?: string;
credentials?: IMessengerAppCrendentials;
}
export function messengerAppFactory(params: IMessengerApp) {
return MessengerApps.create({
name: params.name || faker.random.word(),
kind: params.kind,
credentials: params.credentials
});
}
interface IScript {
name?: string;
messengerId?: string;
messengerBrandCode?: string;
leadIds?: string[];
leadMaps?: Array<{ formCode: string; brandCode: string }>;
kbTopicId?: string;
}
export function scriptFactory(params: IScript) {
return Scripts.create({
name: params.name || faker.random.word(),
messengerId: params.messengerId,
messengerBrandCode: params.messengerBrandCode,
leadIds: params.leadIds,
leadMaps: params.leadMaps,
kbTopicId: params.kbTopicId
});
}
interface IPermissionParams {
module?: string;
action?: string;
allowed?: boolean;
userId?: string;
requiredActions?: string[];
groupId?: string;
}
export const permissionFactory = async (params: IPermissionParams = {}) => {
const permission = new Permissions({
module: params.module || faker.random.word(),
action: params.action || faker.random.word(),
allowed: typeof params.allowed === 'undefined' ? true : params.allowed,
userId: params.userId,
requiredActions: params.requiredActions || [],
groupId: params.groupId
});
return permission.save();
};
interface IUserGroupParams {
isVisible?: boolean;
}
export const usersGroupFactory = async (params: IUserGroupParams = {}) => {
const usersGroup = new UsersGroups({
name: await getUniqueValue(UsersGroups, 'name'),
description: faker.random.word(),
isVisible:
params.isVisible === undefined || params.isVisible === null
? true
: params.isVisible
});
return usersGroup.save();
};
interface IConformityFactoryInput {
mainType: string;
mainTypeId: string;
relType: string;
relTypeId: string;
}
export const conformityFactory = (params: IConformityFactoryInput) => {
return Conformities.addConformity(params);
};
interface IEmailDeliveryFactoryInput {
attachments?: string[];
subject?: string;
status?: string;
body?: string;
to?: string[];
cc?: string[];
bcc?: string[];
from?: string;
kind?: string;
userId?: string;
customerId?: string;
}
export const emailDeliveryFactory = async (
params: IEmailDeliveryFactoryInput = {}
) => {
const emailDelviry = new EmailDeliveries({
attachments: params.attachments || [],
subject: params.subject || 'subject',
status: params.status || 'pending',
body: params.body || 'body',
to: params.to || ['to'],
cc: params.cc || ['cc'],
bcc: params.bcc || ['bcc'],
from: params.from || 'from',
kind: params.kind || 'kind',
userId: params.userId || faker.random.uuid(),
customerId: params.customerId || faker.random.uuid()
});
return emailDelviry.save();
};
interface IMessageEngageDataParams {
messageId?: string;
brandId?: string;
content?: string;
fromUserId?: string;
kind?: string;
sentAs?: string;
}
export function engageDataFactory(params: IMessageEngageDataParams) {
return {
messageId: params.messageId || Random.id(),
brandId: params.brandId || Random.id(),
content: params.content || faker.lorem.sentence(),
fromUserId: params.fromUserId || Random.id(),
kind: params.kind || 'popup',
sentAs: params.sentAs || 'post'
};
}
interface IWebhookActionInput {
label?: string;
type?: string;
action?: any;
}
interface IWebhookParams {
url?: string;
actions?: IWebhookActionInput[];
token?: string;
}
export function webhookFactory(params: IWebhookParams) {
const webhook = new Webhooks({
url: params.url || `https://${faker.random.uuid()}.com`,
actions: params.actions || WEBHOOK_ACTIONS,
token: params.token || faker.random.uuid()
});
return webhook.save();
}
interface IOnboardHistoryParams {
userId: string;
isCompleted?: boolean;
completedSteps?: string[];
}
export const onboardHistoryFactory = async (params: IOnboardHistoryParams) => {
const onboard = new OnboardingHistories(params);
return onboard.save();
};
interface ICalendarFactoryInput {
name?: string;
color?: string;
userId?: string;
groupId: string;
createdAt?: Date;
accountId?: string;
}
export const calendarFactory = async (params: ICalendarFactoryInput) => {
const calendar = new Calendars({
name: params.name || faker.random.word(),
categoryId: params.color || faker.random.word(),
userId: params.userId || PRODUCT_TYPES.PRODUCT,
groupId: params.groupId,
accountId: params.accountId || 'erxesApiId'
});
return calendar.save();
};
interface ICalendarBoardFactoryInput {
name?: string;
}
export const calendarBoardFactory = async (
params: ICalendarBoardFactoryInput = {}
) => {
const calendarBoard = new CalendarBoards({
name: params.name || faker.random.word()
});
return calendarBoard.save();
};
interface ICalendarGroupFactoryInput {
name?: string;
isPrivate?: boolean;
userId?: string;
memberIds?: string[];
boardId?: string;
}
export const calendarGroupFactory = async (
params: ICalendarGroupFactoryInput = {}
) => {
const calendarGroup = new CalendarGroups({
name: params.name || faker.random.word(),
isPrivate: params.isPrivate || false,
userId: params.userId || faker.random.word(),
memberIds: params.memberIds || [faker.random.word()],
boardId: params.boardId || (await calendarBoardFactory())._id
});
return calendarGroup.save();
};
export const skillTypeFactor = async (params: { name?: string }) => {
const skillType = new SkillTypes({
name: params.name || faker.random.word()
});
return skillType.save();
};
export const skillFactor = async (params: {
name?: string;
typeId?: string;
memberIds?: string[];
}) => {
const skill = new Skills({
name: params.name || faker.random.word(),
typeId: params.typeId || faker.random.word(),
memberIds: params.memberIds || [faker.random.word()]
});
return skill.save();
};
export const structureFactory = async (params: {
title?: string;
description?: string;
supervisorId?: string;
}) => {
const structure = new Structures({
title: params.title || faker.random.word(),
description: params.description || faker.random.word(),
supervisorId: params.supervisorId
});
return structure.save();
};
export const departmentFactory = async (params: {
title?: string;
parentId?: string;
description?: string;
userIds?: string[];
supervisorId?: string;
}) => {
const department = new Departments({
title: params.title || faker.random.word(),
description: params.description || faker.random.word(),
parentId: params.parentId,
userIds: params.userIds || [],
supervisorId: params.supervisorId
});
return department.save();
};
export const unitFactory = async (params: {
title?: string;
departmentId?: string;
description?: string;
userIds?: string[];
}) => {
const unit = new Units({
title: params.title || faker.random.word(),
description: params.description || faker.random.word(),
departmentId: params.departmentId,
userIds: params.userIds || [faker.random.word()]
});
return unit.save();
};
export const branchFactory = async (params: {
title?: string;
parentId?: string;
address?: string;
userIds?: string[];
}) => {
const unit = new Branches({
title: params.title || faker.random.word(),
parentId: params.parentId,
address: params.address || faker.random.word(),
userIds: params.userIds || [faker.random.word()]
});
return unit.save();
};
export const clientPortalFactory = async (params: { name?: string }) => {
const portal = new ClientPortals({
name: params.name || faker.random.word()
});
return portal.save();
};