diff --git a/packages/api/src/controllers/user.ts b/packages/api/src/controllers/user.ts index 3173d337a..8e18a0f11 100644 --- a/packages/api/src/controllers/user.ts +++ b/packages/api/src/controllers/user.ts @@ -52,9 +52,7 @@ class UserController { children, avatarMediaId, avatarMediaPath, - trust: { - phone, - }, + phone, }, overwrite, recover diff --git a/packages/core/src/database/migrations/z1652135660-migrateUserPhone.js b/packages/core/src/database/migrations/z1652135660-migrateUserPhone.js new file mode 100644 index 000000000..92f687c71 --- /dev/null +++ b/packages/core/src/database/migrations/z1652135660-migrateUserPhone.js @@ -0,0 +1,27 @@ +'use strict'; + +const AWS = require('aws-sdk'); + +module.exports = { + async up(queryInterface, Sequelize) { + if (process.env.NODE_ENV === 'test') { + return; + } + + const query = ` + UPDATE app_user + SET "phone" = "user".phone + FROM ( + select "userAddress", phone + from app_user_through_trust inner join app_user_trust aut on aut.id = app_user_through_trust."appUserTrustId" + ) "user" + WHERE "app_user"."address" = "user"."userAddress"`; + + await queryInterface.sequelize.query(query, { + raw: true, + type: Sequelize.QueryTypes.UPDATE, + }); + }, + + down(queryInterface, Sequelize) {}, +}; diff --git a/packages/core/src/services/app/user.ts b/packages/core/src/services/app/user.ts index 882ac589a..89d849d72 100644 --- a/packages/core/src/services/app/user.ts +++ b/packages/core/src/services/app/user.ts @@ -27,7 +27,6 @@ export default class UserService { public static appUser = models.appUser; public static beneficiary = models.beneficiary; public static manager = models.manager; - public static appUserTrust = models.appUserTrust; public static appUserThroughTrust = models.appUserThroughTrust; public static appMediaContent = models.appMediaContent; public static appMediaThumbnail = models.appMediaThumbnail; @@ -50,8 +49,8 @@ export default class UserService { if (overwrite) { await this.overwriteUser(user); } else if (!exists) { - const existsPhone = user.trust?.phone - ? await this.existsAccountByPhone(user.trust.phone) + const existsPhone = user.phone + ? await this.existsAccountByPhone(user.phone, user.address) : false; if (existsPhone) @@ -69,19 +68,7 @@ export default class UserService { if (!exists) { // create new user, including their phone number information userFromRegistry = ( - await this.appUser.create( - user, - user.trust?.phone - ? { - include: [ - { - model: models.appUserTrust, - as: 'trust', - }, - ], - } - : {} - ) + await this.appUser.create(user) ).toJSON() as AppUser; } else { if (user.pushNotificationToken) { @@ -179,19 +166,11 @@ export default class UserService { public static async overwriteUser(user: AppUserCreationAttributes) { try { const usersToInactive = await this.appUser.findAll({ - include: [ - { - model: this.appUserTrust, - as: 'trust', - where: { - phone: user.trust?.phone, - }, - }, - ], where: { address: { [Op.not]: user.address, }, + phone: user.phone, }, }); @@ -259,45 +238,11 @@ export default class UserService { phone?: string ): Promise { const user = await this.appUser.findOne({ - include: [ - { - model: this.appUserTrust, - as: 'trust', - }, - ], where: { address }, }); if (user === null) { throw new BaseError('USER_NOT_FOUND', address + ' user not found!'); } - if (phone) { - const uu = user.toJSON() as AppUser; - const userTrustId = - uu.trust && uu.trust.length > 0 ? uu.trust[0].id : undefined; - if (userTrustId === undefined) { - try { - await this.sequelize.transaction(async (t) => { - const userTrust = await this.appUserTrust.create( - { - phone, - }, - { transaction: t } - ); - await this.appUserThroughTrust.create( - { - userAddress: address, - appUserTrustId: userTrust.id, - }, - { transaction: t } - ); - }); - } catch (e) { - Logger.error( - 'creating trust profile to existing account ' + e - ); - } - } - } return UserService.loadUser(user); } @@ -440,23 +385,21 @@ export default class UserService { return exists !== null; } - public static async existsAccountByPhone(phone: string): Promise { - const query = ` - SELECT app_user_trust.phone, address - FROM app_user_trust - LEFT JOIN app_user_through_trust ON "appUserTrustId" = id - LEFT JOIN "app_user" as "user" ON "user".address = "userAddress" - WHERE app_user_trust.phone = :phone - AND "user".active = TRUE`; - - const exists = await sequelize.query(query, { - type: QueryTypes.SELECT, - replacements: { + public static async existsAccountByPhone( + phone: string, + address: string + ): Promise { + const user = await models.appUser.findOne({ + where: { phone, - }, - }); + address: { + [Op.not]: address, + }, + active: true + } + }) - return exists.length > 0; + return !!user; } public static async updateLastLogin(id: number): Promise { diff --git a/packages/core/src/services/ubi/community/list.ts b/packages/core/src/services/ubi/community/list.ts index 7d83e756b..cea1ebae0 100644 --- a/packages/core/src/services/ubi/community/list.ts +++ b/packages/core/src/services/ubi/community/list.ts @@ -100,19 +100,12 @@ export class CommunityListService { const communityProposals = await this._getOpenProposals(); if (query.ambassadorAddress) { const ambassador = (await models.appUser.findOne({ - attributes: [], - include: [ - { - model: models.appUserTrust, - as: 'trust', - attributes: ['phone'], - }, - ], + attributes: ['phone'], where: { address: query.ambassadorAddress, }, })) as any; - const phone = ambassador?.trust[0]?.phone; + const phone = ambassador?.phone; if (phone) { const parsePhone = parsePhoneNumber(phone); extendedWhere = { diff --git a/packages/core/tests/factories/user.ts b/packages/core/tests/factories/user.ts index 98995608a..fb39e952c 100644 --- a/packages/core/tests/factories/user.ts +++ b/packages/core/tests/factories/user.ts @@ -33,9 +33,7 @@ const data = async (props?: ICreateProps) => { gender: props?.gender ? props?.gender : 'u', pushNotificationToken: '', suspect: props?.suspect ? props.suspect : false, - trust: { - phone: props?.phone ? props.phone : faker.phone.phoneNumber(), - }, + phone: props?.phone ? props.phone : faker.phone.phoneNumber(), active: props?.active, year: props?.year, }; @@ -54,15 +52,7 @@ const UserFactory = async ( const result: AppUser[] = []; for (let index = 0; index < options.n; index++) { const newUser = (await AppUserModel.create( - await data(options.props ? options.props[index] : undefined), - { - include: [ - { - model: AppUserTrustModel, - as: 'trust', - }, - ], - } as any + await data(options.props ? options.props[index] : undefined) )) as AppUserModel; // use any :facepalm: result.push(newUser.toJSON() as AppUser); } diff --git a/packages/core/tests/integration/user.test.ts b/packages/core/tests/integration/user.test.ts index 4c1d6daff..c39345680 100644 --- a/packages/core/tests/integration/user.test.ts +++ b/packages/core/tests/integration/user.test.ts @@ -64,20 +64,13 @@ describe('user service', () => { const phone = faker.phone.phoneNumber(); const newUser = await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const findUser = await models.appUser.findOne({ where: { address: newUser.user.address }, }); - const findPhone = await sequelize.models.AppUserTrustModel.findOne({ - where: { phone }, - }); // eslint-disable-next-line no-unused-expressions expect(findUser).to.not.be.null; - // eslint-disable-next-line no-unused-expressions - expect(findPhone).to.not.be.null; }); it('authentication creates new user with all params', async () => { @@ -98,22 +91,17 @@ describe('user service', () => { children: 1, avatarMediaId: 5, pushNotificationToken: 'ckniwoaicoska', - trust: { - phone, - }, + phone, }); const findUser = await models.appUser.findOne({ where: { address: newUser.user.address }, }); - const findPhone = await sequelize.models.AppUserTrustModel.findOne({ - where: { phone }, - }); // eslint-disable-next-line no-unused-expressions expect(findUser).to.not.be.null; // eslint-disable-next-line no-unused-expressions - expect(findPhone).to.not.be.null; expect(newUser.user).to.include({ address, + phone, language: 'pt', currency, suspect: false, @@ -133,28 +121,20 @@ describe('user service', () => { // await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const loadUser = await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const findUser = await models.appUser.findOne({ where: { address: loadUser.user.address }, }); - const findPhone = await sequelize.models.AppUserTrustModel.findOne({ - where: { phone }, - }); // eslint-disable-next-line no-unused-expressions expect(findUser).to.not.be.null; - // eslint-disable-next-line no-unused-expressions - expect(findPhone).to.not.be.null; expect(loadUser.user).to.include({ address, + phone, }); }); @@ -176,9 +156,7 @@ describe('user service', () => { children: 1, avatarMediaId: 5, pushNotificationToken: 'ckniwoaicoska', - trust: { - phone, - }, + phone, }); const loadUser = await UserService.authenticate({ address, @@ -191,22 +169,16 @@ describe('user service', () => { children: 1, avatarMediaId: 5, pushNotificationToken: 'ckniwoaicoska', - trust: { - phone, - }, + phone, }); const findUser = await models.appUser.findOne({ where: { address: loadUser.user.address }, }); - const findPhone = await sequelize.models.AppUserTrustModel.findOne({ - where: { phone }, - }); // eslint-disable-next-line no-unused-expressions expect(findUser).to.not.be.null; - // eslint-disable-next-line no-unused-expressions - expect(findPhone).to.not.be.null; expect(loadUser.user).to.include({ address, + phone, language: 'pt', currency, suspect: false, @@ -228,16 +200,12 @@ describe('user service', () => { await UserService.authenticate({ address: firstAddress, - trust: { - phone, - }, + phone, }); let error: any; await UserService.authenticate({ address: secondAddress, - trust: { - phone, - }, + phone, }).catch((err) => { error = err; }); @@ -256,17 +224,13 @@ describe('user service', () => { await UserService.authenticate({ address: firstAddress, - trust: { - phone, - }, + phone, }); const loadUser = await UserService.authenticate( { address: secondAddress, - trust: { - phone, - }, + phone, }, true ); @@ -296,18 +260,14 @@ describe('user service', () => { // create the first account await UserService.authenticate({ address: firstAddress, - trust: { - phone, - }, + phone, }); // replace by a new account await UserService.authenticate( { address: secondAddress, - trust: { - phone, - }, + phone, }, true ); @@ -317,9 +277,7 @@ describe('user service', () => { // try to login with the first account again await UserService.authenticate({ address: firstAddress, - trust: { - phone, - }, + phone, }).catch((err) => { error = err; }); @@ -333,9 +291,7 @@ describe('user service', () => { const phone = faker.phone.phoneNumber(); const login = await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const oldLastLogin = login.user.lastLogin; @@ -344,9 +300,7 @@ describe('user service', () => { await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const user = await models.appUser.findOne({ @@ -365,9 +319,7 @@ describe('user service', () => { const phone = faker.phone.phoneNumber(); const newUser = await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const logged = await UserService.welcome(newUser.user.address); // eslint-disable-next-line no-unused-expressions @@ -380,9 +332,7 @@ describe('user service', () => { const phone = faker.phone.phoneNumber(); const newUser = await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const logged = await UserService.welcome( newUser.user.address, @@ -485,9 +435,7 @@ describe('user service', () => { const phone = faker.phone.phoneNumber(); await UserService.authenticate({ address, - trust: { - phone, - }, + phone, }); const data = { diff --git a/packages/worker/src/jobs.ts b/packages/worker/src/jobs.ts index 4ea1a84de..9cb2007bf 100644 --- a/packages/worker/src/jobs.ts +++ b/packages/worker/src/jobs.ts @@ -8,16 +8,12 @@ import { calcuateCommunitiesMetrics, internalNotifyLowCommunityFunds, internalNotifyNewCommunities, - verifyCommunitySuspectActivity, } from './jobs/cron/community'; import { calcuateGlobalMetrics } from './jobs/cron/global'; import { cleanupNetworkRewards } from './jobs/cron/network'; import { verifyStoriesLifecycle } from './jobs/cron/stories'; import { updateExchangeRates } from './jobs/cron/updateExchangeRates'; -import { - verifyUserSuspectActivity, - verifyDeletedAccounts, -} from './jobs/cron/user'; +import { verifyDeletedAccounts } from './jobs/cron/user'; const provider = new ethers.providers.JsonRpcProvider(config.jsonRpcUrl); const providerFallback = new ethers.providers.JsonRpcProvider( @@ -456,56 +452,6 @@ function cron() { true ); - // at 5:12 am. - // eslint-disable-next-line no-new - new CronJob( - '12 5 * * *', - () => { - utils.Logger.info('Verify community suspicious activity...'); - verifyCommunitySuspectActivity() - .then(() => { - services.app.CronJobExecutedService.add( - 'verifyCommunitySuspectActivity' - ); - utils.Logger.info( - 'verifyCommunitySuspectActivity successfully executed!' - ); - }) - .catch((e) => { - utils.Logger.error( - 'verifyCommunitySuspectActivity FAILED! ' + e - ); - }); - }, - null, - true - ); - - // at 2:12 am and 2:12 pm. - // eslint-disable-next-line no-new - new CronJob( - '12 2,14 * * *', - () => { - utils.Logger.info('Verify user suspicious activity...'); - verifyUserSuspectActivity() - .then(() => { - services.app.CronJobExecutedService.add( - 'verifyUserSuspectActivity' - ); - utils.Logger.info( - 'verifyUserSuspectActivity successfully executed!' - ); - }) - .catch((e) => { - utils.Logger.error( - 'verifyUserSuspectActivity FAILED! ' + e - ); - }); - }, - null, - true - ); - try { // everyday at 1am // eslint-disable-next-line no-new diff --git a/packages/worker/src/jobs/cron/community.ts b/packages/worker/src/jobs/cron/community.ts index 9697991c8..c13300091 100644 --- a/packages/worker/src/jobs/cron/community.ts +++ b/packages/worker/src/jobs/cron/community.ts @@ -11,35 +11,6 @@ import BigNumber from 'bignumber.js'; import { median, mean } from 'mathjs'; import { col, fn, literal, Op, QueryTypes } from 'sequelize'; -export async function verifyCommunitySuspectActivity(): Promise { - const query = ` - WITH - communities AS ( - SELECT "Community"."id", - count(*) filter ( where suspect is true ) AS "suspect", - count(*) as "total" - FROM "community" AS "Community" - INNER JOIN "beneficiary" AS "beneficiaries" ON "Community"."id" = "beneficiaries"."communityId" AND "beneficiaries"."active" = true - LEFT OUTER JOIN "app_user" AS "app_user" ON "beneficiaries"."address" = "app_user"."address" - WHERE "Community"."status" = 'valid' AND "Community"."visibility" = 'public' - GROUP BY "Community"."id" - having count(*) filter ( where suspect is true ) > 0 - ), - suspect_level AS ( - select ((communities.suspect::float / communities.total::float) * 100) as ps, - (60 * log10(((communities.suspect::float / communities.total::float) * 100) + 1)) as y, - id - from communities - ) - INSERT INTO ubi_community_suspect ("communityId", percentage, suspect) - (select id as "communityId", (ROUND(ps * 100) / 100) as percentage, GREATEST(1, ROUND(LEAST(suspect_level.y, 100) / 10)) as suspect - from suspect_level)`; - - await database.sequelize.query(query, { - type: QueryTypes.INSERT, - }); -} - export async function calcuateCommunitiesMetrics(): Promise { type ICommunityToMetrics = Omit< interfaces.ubi.community.CommunityAttributes, diff --git a/packages/worker/src/jobs/cron/user.ts b/packages/worker/src/jobs/cron/user.ts index a41770382..2f221b927 100644 --- a/packages/worker/src/jobs/cron/user.ts +++ b/packages/worker/src/jobs/cron/user.ts @@ -1,45 +1,6 @@ import { interfaces, database } from '@impactmarket/core'; import { QueryTypes, Op } from 'sequelize'; -export async function verifyUserSuspectActivity(): Promise { - const query = ` - WITH active_users AS ( - SELECT - "user".address, - "trust".phone - FROM - "app_user" as "user" - LEFT OUTER JOIN app_user_through_trust AS "through_trust" ON "user".address = "through_trust"."userAddress" - LEFT OUTER JOIN app_user_trust AS "trust" ON "through_trust"."appUserTrustId" = "trust".id - WHERE - "user".active = true - ), - suspect_phone AS ( - SELECT - phone, - count(phone) n - FROM - active_users - GROUP BY - phone - ) - UPDATE - "app_user" as "user" - SET - suspect = CASE WHEN suspect_phone.n > 1 THEN true ELSE false END - FROM - active_users, - suspect_phone - WHERE - "user".address = active_users.address - AND suspect_phone.phone = active_users.phone - AND suspect = CASE WHEN suspect_phone.n > 1 THEN false ELSE true END;`; - - await database.sequelize.query(query, { - type: QueryTypes.UPDATE, - }); -} - export async function verifyDeletedAccounts(): Promise { const t = await database.sequelize.transaction(); try { diff --git a/packages/worker/tests/integration/cron/verifyCommunitySuspectActivity.test.ts b/packages/worker/tests/integration/cron/verifyCommunitySuspectActivity.test.ts deleted file mode 100644 index 0bff6ec50..000000000 --- a/packages/worker/tests/integration/cron/verifyCommunitySuspectActivity.test.ts +++ /dev/null @@ -1,169 +0,0 @@ -import { database, interfaces, tests } from '@impactmarket/core'; -import { expect } from 'chai'; -import { Sequelize } from 'sequelize'; -import Sinon, { stub } from 'sinon'; - -import { verifyCommunitySuspectActivity } from '../../../src/jobs/cron/community'; - -describe('[jobs - cron] verifyCommunitySuspectActivity', () => { - let sequelize: Sequelize; - let users: interfaces.app.appUser.AppUser[]; - let communities: interfaces.ubi.community.CommunityAttributes[]; - - let ubiCommunitySuspectAddStub: Sinon.SinonStub; - - before(async () => { - sequelize = tests.config.setup.sequelizeSetup(); - await sequelize.sync(); - - ubiCommunitySuspectAddStub = stub( - database.models.ubiCommunitySuspect, - 'bulkCreate' - ); - ubiCommunitySuspectAddStub.returns(Promise.resolve()); - }); - - after(async () => { - await tests.config.setup.truncate(sequelize, 'Beneficiary'); - await tests.config.setup.truncate(sequelize); - }); - - beforeEach(async () => { - await tests.config.setup.truncate(sequelize, 'Beneficiary'); - await tests.config.setup.truncate(sequelize, 'Community'); - ubiCommunitySuspectAddStub.reset(); - }); - - it('with 100% (level 10) suspicious activity', async () => { - users = await tests.factories.UserFactory({ - n: 5, - props: Array(5).fill({ suspect: true }), - }); - communities = await tests.factories.CommunityFactory([ - { - requestByAddress: users[0].address, - hasAddress: true, - }, - ]); - await tests.factories.BeneficiaryFactory(users, communities[0].id); - - await verifyCommunitySuspectActivity(); - const suspectActivity = - await database.models.ubiCommunitySuspect.findAll({ - where: { - communityId: communities[0].id, - }, - }); - - expect(suspectActivity[0]).to.include({ - communityId: communities[0].id, - percentage: 100, - suspect: 10, - }); - }); - - it('with 1% (level 2) suspicious activity', async () => { - users = await tests.factories.UserFactory({ - n: 100, - props: Array(1).fill({ suspect: true }), - }); - communities = await tests.factories.CommunityFactory([ - { - requestByAddress: users[0].address, - hasAddress: true, - }, - ]); - await tests.factories.BeneficiaryFactory(users, communities[0].id); - - await verifyCommunitySuspectActivity(); - const suspectActivity = - await database.models.ubiCommunitySuspect.findAll({ - where: { - communityId: communities[0].id, - }, - }); - - expect(suspectActivity[0]).to.include({ - communityId: communities[0].id, - percentage: 1, - suspect: 2, - }); - }); - - it('with 14.29% (level 7) suspicious activity', async () => { - users = await tests.factories.UserFactory({ - n: 35, - props: Array(5).fill({ suspect: true }), - }); - communities = await tests.factories.CommunityFactory([ - { - requestByAddress: users[0].address, - hasAddress: true, - }, - ]); - await tests.factories.BeneficiaryFactory(users, communities[0].id); - - await verifyCommunitySuspectActivity(); - const suspectActivity = - await database.models.ubiCommunitySuspect.findAll({ - where: { - communityId: communities[0].id, - }, - }); - - expect(suspectActivity[0]).to.include({ - communityId: communities[0].id, - percentage: 14.29, - suspect: 7, - }); - }); - - it('with 50% (level 10) suspicious activity', async () => { - users = await tests.factories.UserFactory({ - n: 10, - props: Array(5).fill({ suspect: true }), - }); - communities = await tests.factories.CommunityFactory([ - { - requestByAddress: users[0].address, - hasAddress: true, - }, - ]); - await tests.factories.BeneficiaryFactory(users, communities[0].id); - - await verifyCommunitySuspectActivity(); - const suspectActivity = - await database.models.ubiCommunitySuspect.findAll({ - where: { - communityId: communities[0].id, - }, - }); - - expect(suspectActivity[0]).to.include({ - communityId: communities[0].id, - percentage: 50, - suspect: 10, - }); - }); - - it('without suspicious activity', async () => { - users = await tests.factories.UserFactory({ n: 10 }); - communities = await tests.factories.CommunityFactory([ - { - requestByAddress: users[0].address, - hasAddress: true, - }, - ]); - await tests.factories.BeneficiaryFactory(users, communities[0].id); - - await verifyCommunitySuspectActivity(); - const suspectActivity = - await database.models.ubiCommunitySuspect.findAll({ - where: { - communityId: communities[0].id, - }, - }); - - expect(suspectActivity.length).to.be.equal(0); - }); -}); diff --git a/packages/worker/tests/integration/cron/verifyDeletedAccounts.test.ts b/packages/worker/tests/integration/cron/verifyDeletedAccounts.test.ts index 334f5608a..562d9b837 100644 --- a/packages/worker/tests/integration/cron/verifyDeletedAccounts.test.ts +++ b/packages/worker/tests/integration/cron/verifyDeletedAccounts.test.ts @@ -187,13 +187,6 @@ describe('[jobs - cron] verifyDeletedAccounts', () => { }, }); - const phone = users[1].trust ? users[1].trust[0].phone : null; - const findPhone = await database.models.appUserTrust.findOne({ - where: { - phone, - }, - }); - const beneficiary = await database.models.beneficiary.findOne({ where: { address: users[1].address, @@ -227,8 +220,6 @@ describe('[jobs - cron] verifyDeletedAccounts', () => { // eslint-disable-next-line no-unused-expressions expect(user).to.be.null; - // eslint-disable-next-line no-unused-expressions - expect(findPhone).to.be.null; expect(beneficiary).to.include({ active: true, }); @@ -276,12 +267,6 @@ describe('[jobs - cron] verifyDeletedAccounts', () => { }, }); - const phone = users[0].trust ? users[0].trust[0].phone : null; - const findPhone = await database.models.appUserTrust.findOne({ - where: { - phone, - }, - }); const findStoryContent = await database.models.storyContent.findOne({ where: { byAddress: users[0].address, @@ -296,8 +281,6 @@ describe('[jobs - cron] verifyDeletedAccounts', () => { // eslint-disable-next-line no-unused-expressions expect(user).to.be.null; - // eslint-disable-next-line no-unused-expressions - expect(findPhone).to.be.null; expect(manager).to.include({ active: true, }); diff --git a/packages/worker/tests/integration/cron/verifyUserSuspectActivity.test.ts b/packages/worker/tests/integration/cron/verifyUserSuspectActivity.test.ts deleted file mode 100644 index a885cab70..000000000 --- a/packages/worker/tests/integration/cron/verifyUserSuspectActivity.test.ts +++ /dev/null @@ -1,129 +0,0 @@ -import { database, interfaces, tests } from '@impactmarket/core'; -import { expect } from 'chai'; -import { Sequelize } from 'sequelize'; -import { replace, restore } from 'sinon'; - -import { verifyUserSuspectActivity } from '../../../src/jobs/cron/user'; - -// in this test there are users being assined with suspicious activity and others being removed -describe('[jobs - cron] verifyUserSuspectActivity', () => { - let sequelize: Sequelize; - before(async () => { - sequelize = tests.config.setup.sequelizeSetup(); - await sequelize.sync(); - - replace(database.sequelize, 'query', sequelize.query); - }); - - afterEach(async () => { - await tests.config.setup.truncate(sequelize, 'AppUserModel'); - await tests.config.setup.truncate(sequelize); - }); - - after(() => { - restore(); - }); - - it('should detect suspicious account', async () => { - await tests.factories.UserFactory({ - n: 3, - props: [ - { - phone: '00351969696966', - }, - { - phone: '00351969696966', - }, - { - phone: '00351969696967', - }, - ], - }); - await verifyUserSuspectActivity(); - const users: interfaces.app.appUser.AppUser[] = - await database.models.appUser.findAll({ - include: [ - { - model: database.models.appUserTrust, - as: 'trust', - }, - ], - }); - - users.forEach((user) => { - if (user.trust![0].phone === '00351969696966') { - expect(user.suspect).to.be.equal(true); - } else { - expect(user.suspect).to.be.equal(false); - } - }); - }); - - it('should remove suspect status from unsuspecting accounts', async () => { - await tests.factories.UserFactory({ - n: 3, - props: [ - { - phone: '00351969696969', - suspect: true, // was suspect before - }, - { - phone: '00351969696970', - }, - { - phone: '00351969696970', - }, - ], - }); - await verifyUserSuspectActivity(); - const users: interfaces.app.appUser.AppUser[] = - await database.models.appUser.findAll({ - include: [ - { - model: database.models.appUserTrust, - as: 'trust', - }, - ], - }); - - users.forEach((user) => { - if (user.trust![0].phone === '00351969696969') { - expect(user.suspect).to.be.equal(false); - } else { - expect(user.suspect).to.be.equal(true); - } - }); - }); - - it('should ignore inactive accounts', async () => { - await tests.factories.UserFactory({ - n: 2, - props: [ - { - phone: '00351969696970', - active: false, - }, - { - phone: '00351969696970', - suspect: true, - }, - ], - }); - await verifyUserSuspectActivity(); - const users: interfaces.app.appUser.AppUser[] = - await database.models.appUser.findAll({ - include: [ - { - model: database.models.appUserTrust, - as: 'trust', - }, - ], - }); - - users.forEach((user) => { - expect(user.suspect).to.be.equal(false); - }); - }); - - // TODO: devide in two tests, one to find suspect, one to remove -});