From 22bf7c2c6c239d08a541db71c41c71d353351f27 Mon Sep 17 00:00:00 2001
From: Augustin LECONTE <["ext.sopra.aleconte@grandlyon.com"]>
Date: Thu, 20 Jan 2022 17:06:29 +0000
Subject: [PATCH] feat/US43-user-management

---
 src/admin/admin.controller.spec.ts            | 12 ++++++
 src/admin/admin.controller.ts                 | 26 +++++++++++++
 src/structures/services/structures.service.ts | 19 ++++++++++
 src/users/users.service.spec.ts               | 38 +++++++++++++++++++
 src/users/users.service.ts                    | 28 +++++++++++++-
 test/mock/services/structures.mock.service.ts |  4 ++
 test/mock/services/user.mock.service.ts       | 13 +++++++
 7 files changed, 138 insertions(+), 2 deletions(-)

diff --git a/src/admin/admin.controller.spec.ts b/src/admin/admin.controller.spec.ts
index d5af5352c..d594e2dbe 100644
--- a/src/admin/admin.controller.spec.ts
+++ b/src/admin/admin.controller.spec.ts
@@ -197,4 +197,16 @@ describe('AdminController', () => {
     expect((await controller.getAdminStructuresList()).claimed.length).toEqual(0);
     expect((await controller.getAdminStructuresList()).incomplete.length).toEqual(2);
   });
+
+  it('should find attached users', async () => {
+    expect((await controller.findAttachedUsers()).length).toBe(0);
+  });
+
+  it('should find unattached users', async () => {
+    expect((await controller.findUnattachedUsers()).length).toBe(0);
+  });
+
+  it('should find unverified users', async () => {
+    expect((await controller.findUnVerifiedUsers()).length).toBe(0);
+  });
 });
diff --git a/src/admin/admin.controller.ts b/src/admin/admin.controller.ts
index 3fae73b8f..5521d40e8 100644
--- a/src/admin/admin.controller.ts
+++ b/src/admin/admin.controller.ts
@@ -21,6 +21,7 @@ import { UsersService } from '../users/users.service';
 import { PendingStructureDto } from './dto/pending-structure.dto';
 import { validate } from 'class-validator';
 import { Structure } from '../structures/schemas/structure.schema';
+import { IUser } from '../users/interfaces/user.interface';
 
 @Controller('admin')
 export class AdminController {
@@ -162,6 +163,31 @@ export class AdminController {
     else return this.usersService.findAll();
   }
 
+  @UseGuards(JwtAuthGuard, RolesGuard)
+  @Roles('admin')
+  @Get('getUnAttachedUsers')
+  public async findUnattachedUsers() {
+    return this.usersService.findAllUnattached();
+  }
+
+  @UseGuards(JwtAuthGuard, RolesGuard)
+  @Roles('admin')
+  @Get('getAttachedUsers')
+  public async findAttachedUsers() {
+    return this.usersService.findAllAttached().then(async (users: IUser[]) => {
+      return this.structuresService.getAllUserCompletedStructures(users);
+    });
+  }
+
+  @UseGuards(JwtAuthGuard, RolesGuard)
+  @Roles('admin')
+  @Get('getUnVerifiedUsers')
+  public async findUnVerifiedUsers() {
+    return this.usersService.findAllUnVerified().then(async (users: IUser[]) => {
+      return this.structuresService.getAllUserCompletedStructures(users);
+    });
+  }
+
   @UseGuards(JwtAuthGuard, RolesGuard)
   @Roles('admin')
   @Post('searchNewsletterSubscriptions')
diff --git a/src/structures/services/structures.service.ts b/src/structures/services/structures.service.ts
index d1bb442ca..afa5d0542 100644
--- a/src/structures/services/structures.service.ts
+++ b/src/structures/services/structures.service.ts
@@ -616,4 +616,23 @@ export class StructuresService {
   private hasTempMail(structure: Structure): boolean {
     return structure.contactMail === 'unknown@unknown.com';
   }
+
+  public async getAllUserCompletedStructures(users: IUser[]): Promise<any[]> {
+    return Promise.all(
+      users.map(async (user) => {
+        return {
+          id: user._id,
+          surname: user.surname,
+          name: user.name,
+          email: user.email,
+          phone: user.phone,
+          structures: await Promise.all(
+            user.structuresLink.map(async (id) => {
+              return await this.findOne(id.toHexString());
+            })
+          ),
+        };
+      })
+    );
+  }
 }
diff --git a/src/users/users.service.spec.ts b/src/users/users.service.spec.ts
index 3b830315a..be5f9c272 100644
--- a/src/users/users.service.spec.ts
+++ b/src/users/users.service.spec.ts
@@ -9,6 +9,7 @@ import { LoginDto } from '../auth/login-dto';
 import { EmailChangeDto } from './dto/change-email.dto';
 import * as bcrypt from 'bcrypt';
 import { ConfigurationModule } from '../configuration/configuration.module';
+import { IUser } from './interfaces/user.interface';
 
 function hashPassword() {
   return bcrypt.hashSync(process.env.USER_PWD, process.env.SALT);
@@ -289,4 +290,41 @@ describe('UsersService', () => {
       expect(await service.updateStructureLinked('test@mii.com', '6001a37716b08100062e4160')).toBe(result);
     });
   });
+
+  it('should find All Unattacheduser', async () => {
+    const result = [
+      {
+        _id: '123',
+        validationToken:
+          'cf1c74c22cedb6b575945098db42d2f493fb759c9142c6aff7980f252886f36ee086574ee99a06bc99119079257116c959c8ec870949cebdef2b293666dbca42',
+        emailVerified: false,
+        email: 'jacques.dupont@mii.com',
+        password: hashPassword(),
+        role: 0,
+        newEmail: '',
+        changeEmailToken: '',
+        resetPasswordToken: null,
+        structuresLink: [],
+        pendingStructuresLink: [],
+        structureOutdatedMailSent: [],
+        name: 'Jacques',
+        surname: 'Dupont',
+        phone: '06 06 06 06 06',
+      } as IUser,
+    ];
+    jest.spyOn(service, 'findAllUnattached').mockImplementation(async (): Promise<IUser[]> => result);
+    expect(await service.findAllUnattached()).toBe(result);
+  });
+
+  it('should find attached users', async () => {
+    const result = [];
+    jest.spyOn(service, 'findAllAttached').mockImplementation(async (): Promise<IUser[]> => result);
+    expect((await service.findAllAttached()).length).toBe(0);
+  });
+
+  it('should find UnVerified Users', async () => {
+    const result = [];
+    jest.spyOn(service, 'findAllUnVerified').mockImplementation(async (): Promise<IUser[]> => result);
+    expect((await service.findAllUnVerified()).length).toBe(0);
+  });
 });
diff --git a/src/users/users.service.ts b/src/users/users.service.ts
index 993ae82a4..ce0e954d6 100644
--- a/src/users/users.service.ts
+++ b/src/users/users.service.ts
@@ -82,8 +82,32 @@ export class UsersService {
     return this.userModel.findOne({ email: mail }).select('-password').exec();
   }
 
-  public async findAll(): Promise<User[]> {
-    return await this.userModel.find().exec();
+  public findAll(): Promise<User[]> {
+    return this.userModel.find().exec();
+  }
+
+  public findAllUnattached(): Promise<IUser[]> {
+    return this.userModel
+      .find()
+      .where('emailVerified')
+      .equals(true)
+      .where('structuresLink')
+      .size(0)
+      .sort({ surname: 1 })
+      .exec();
+  }
+
+  public findAllAttached(): Promise<IUser[]> {
+    return this.userModel
+      .find({ $where: 'this.structuresLink.length>0' })
+      .where('emailVerified')
+      .equals(true)
+      .sort({ surname: 1 })
+      .exec();
+  }
+
+  public findAllUnVerified(): Promise<IUser[]> {
+    return this.userModel.find().where('emailVerified').equals(false).sort({ surname: 1 }).exec();
   }
 
   public async findById(id: string, passwordQuery?: boolean): Promise<IUser | undefined> {
diff --git a/test/mock/services/structures.mock.service.ts b/test/mock/services/structures.mock.service.ts
index f088613ba..5482c2ffe 100644
--- a/test/mock/services/structures.mock.service.ts
+++ b/test/mock/services/structures.mock.service.ts
@@ -865,4 +865,8 @@ export class StructuresServiceMock {
       __v: 0,
     };
   }
+
+  async getAllUserCompletedStructures(users: any[]): Promise<any[]> {
+    return [];
+  }
 }
diff --git a/test/mock/services/user.mock.service.ts b/test/mock/services/user.mock.service.ts
index cd00bb601..5b3fc7d57 100644
--- a/test/mock/services/user.mock.service.ts
+++ b/test/mock/services/user.mock.service.ts
@@ -1,6 +1,7 @@
 import { HttpException, HttpStatus } from '@nestjs/common';
 import { PendingStructureDto } from '../../../src/admin/dto/pending-structure.dto';
 import { LoginDto } from '../../../src/auth/login-dto';
+import { User } from '../../../src/users/schemas/user.schema';
 
 export class UsersServiceMock {
   findOne(mail: string, passwordQuery?: boolean) {
@@ -187,4 +188,16 @@ export class UsersServiceMock {
       },
     ];
   }
+
+  async findAllAttached(): Promise<User[]> {
+    return await [];
+  }
+
+  async findAllUnattached(): Promise<User[]> {
+    return await [];
+  }
+
+  async findAllUnVerified(): Promise<User[]> {
+    return await [];
+  }
 }
-- 
GitLab