Skip to content
Snippets Groups Projects
Commit 18f5e759 authored by Hugo SUBTIL's avatar Hugo SUBTIL
Browse files

Merge branch 'feat/newsletter-subscription' into 'dev'

Feat/newsletter subscription

See merge request web-et-numerique/pamn_plateforme-des-acteurs-de-la-mediation-numerique/pamn_server!56
parents b067483a c507f536
No related branches found
No related tags found
3 merge requests!96release V1.10.0,!62Dev,!56Feat/newsletter subscription
......@@ -3,8 +3,8 @@ import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationModule } from '../configuration/configuration.module';
import { MailerService } from '../mailer/mailer.service';
import { CreateStructureDto } from '../structures/dto/create-structure.dto';
import { structureDto } from '../structures/dto/structure.dto';
import { NewsletterSubscription } from '../newsletter/newsletter-subscription.schema';
import { NewsletterService } from '../newsletter/newsletter.service';
import { Structure } from '../structures/schemas/structure.schema';
import { StructuresService } from '../structures/services/structures.service';
import { User } from '../users/schemas/user.schema';
......@@ -21,11 +21,16 @@ describe('AdminController', () => {
providers: [
UsersService,
StructuresService,
NewsletterService,
MailerService,
{
provide: getModelToken('User'),
useValue: User,
},
{
provide: getModelToken('NewsletterSubscription'),
useValue: NewsletterSubscription,
},
{
provide: getModelToken('Structure'),
useValue: Structure,
......
......@@ -2,6 +2,7 @@ import { Body, Delete, Param } from '@nestjs/common';
import { Controller, Get, Post, UseGuards } from '@nestjs/common';
import { ApiOperation, ApiParam } from '@nestjs/swagger';
import { JwtAuthGuard } from '../auth/guards/jwt-auth.guard';
import { NewsletterService } from '../newsletter/newsletter.service';
import { StructuresService } from '../structures/services/structures.service';
import { Roles } from '../users/decorators/roles.decorator';
import { RolesGuard } from '../users/guards/roles.guard';
......@@ -10,7 +11,11 @@ import { PendingStructureDto } from './dto/pending-structure.dto';
@Controller('admin')
export class AdminController {
constructor(private usersService: UsersService, private structuresService: StructuresService) {}
constructor(
private usersService: UsersService,
private structuresService: StructuresService,
private newsletterService: NewsletterService
) {}
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
......@@ -96,4 +101,21 @@ export class AdminController {
return this.usersService.searchUsers(searchString.searchString);
else return this.usersService.findAll();
}
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Post('searchNewsletterSubscriptions')
public async getNewsletterSubscriptions(@Body() searchString: { searchString: string }) {
if (searchString && searchString.searchString.length > 0)
return this.newsletterService.searchNewsletterSubscription(searchString.searchString);
else return this.newsletterService.findAll();
}
@UseGuards(JwtAuthGuard, RolesGuard)
@Roles('admin')
@Delete('newsletterSubscription/:email')
@ApiParam({ name: 'email', type: String, required: true })
public async unsubscribeUserFromNewsletter(@Param() params) {
return await this.newsletterService.deleteOneEmail(params.email);
}
}
import { Module } from '@nestjs/common';
import { NewsletterModule } from '../newsletter/newsletter.module';
import { StructuresModule } from '../structures/structures.module';
import { UsersModule } from '../users/users.module';
import { AdminController } from './admin.controller';
import { AdminService } from './admin.service';
@Module({
imports: [UsersModule, StructuresModule],
imports: [UsersModule, StructuresModule, NewsletterModule],
controllers: [AdminController],
providers: [AdminService],
})
......
......@@ -12,6 +12,7 @@ import { TclModule } from './tcl/tcl.module';
import { AdminModule } from './admin/admin.module';
import { PostsModule } from './posts/posts.module';
import { TempUserModule } from './temp-user/temp-user.module';
import { NewsletterModule } from './newsletter/newsletter.module';
@Module({
imports: [
ConfigurationModule,
......@@ -28,6 +29,7 @@ import { TempUserModule } from './temp-user/temp-user.module';
AdminModule,
PostsModule,
TempUserModule,
NewsletterModule
],
controllers: [AppController],
})
......
import { Document } from 'mongoose';
export interface INewsletterSubscription extends Document {
email: string;
}
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document } from 'mongoose';
export type NewsletterSubscriptionDocument = NewsletterSubscription & Document;
@Schema({ timestamps: { createdAt: 'createdAt', updatedAt: 'updatedAt' } })
export class NewsletterSubscription {
@Prop({ required: true })
email: string;
}
export const NewsletterSubscriptionSchema = SchemaFactory.createForClass(NewsletterSubscription);
import { HttpModule } from '@nestjs/common';
import { getModelToken } from '@nestjs/mongoose';
import { Test, TestingModule } from '@nestjs/testing';
import { ConfigurationModule } from '../configuration/configuration.module';
import { NewsletterSubscription } from './newsletter-subscription.schema';
import { NewsletterController } from './newsletter.controller';
import { NewsletterService } from './newsletter.service';
describe('NewsletterController', () => {
let controller: NewsletterController;
beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
imports: [ConfigurationModule, HttpModule],
providers: [
NewsletterService,
{
provide: getModelToken('NewsletterSubscription'),
useValue: NewsletterSubscription,
},
],
controllers: [NewsletterController],
}).compile();
controller = module.get<NewsletterController>(NewsletterController);
});
it('should be defined', () => {
expect(controller).toBeDefined();
});
it('should subscribe user', async () => {
const result = { email: 'email@test.com' };
jest.spyOn(controller, 'newsletterSubscribe').mockImplementation(async (): Promise<{ email }> => result);
const email = { email: 'email@test.com' };
expect(await controller.newsletterSubscribe(email)).toBe(result);
});
it('should unsubscribe user', async () => {
const result = { email: 'email@test.com' };
jest.spyOn(controller, 'newsletterUnsubscribe').mockImplementation(async (): Promise<{ email }> => result);
const email = { email: 'email@test.com' };
expect(await controller.newsletterUnsubscribe(email)).toBe(result);
});
});
import { Body, Controller, Post } from '@nestjs/common';
import { NewsletterService } from './newsletter.service';
@Controller('newsletter')
export class NewsletterController {
constructor(private newsletterService: NewsletterService) {}
@Post('subscribe')
public async newsletterSubscribe(@Body() email: { email: string }) {
return this.newsletterService.newsletterSubscribe(email.email);
}
@Post('unsubscribe')
public async newsletterUnsubscribe(@Body() email: { email: string }) {
return this.newsletterService.newsletterUnsubscribe(email.email);
}
}
import { HttpModule, Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { NewsletterService } from './newsletter.service';
import { NewsletterController } from './newsletter.controller';
import { NewsletterSubscription, NewsletterSubscriptionSchema } from './newsletter-subscription.schema';
@Module({
imports: [
MongooseModule.forFeature([{ name: NewsletterSubscription.name, schema: NewsletterSubscriptionSchema }]),
HttpModule,
],
providers: [NewsletterService],
exports: [NewsletterService],
controllers: [NewsletterController],
})
export class NewsletterModule {}
import { HttpException, HttpStatus, Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model, Types } from 'mongoose';
import { INewsletterSubscription } from './interface/newsletter-subscription.interface';
import { NewsletterSubscription } from './newsletter-subscription.schema';
@Injectable()
export class NewsletterService {
constructor(
@InjectModel(NewsletterSubscription.name) private newsletterSubscriptionModel: Model<INewsletterSubscription>
) {}
public async newsletterSubscribe(email: string): Promise<NewsletterSubscription> {
const existingEmail = await this.findOne(email);
if (existingEmail) {
throw new HttpException('Email already exists', HttpStatus.BAD_REQUEST);
}
const createSubscription = new this.newsletterSubscriptionModel({ email: email });
createSubscription.save();
return await this.findOne(email);
}
public async newsletterUnsubscribe(email: string): Promise<NewsletterSubscription> {
const subscription = await this.newsletterSubscriptionModel.findOne({ email: email }).exec();
if (!subscription) {
throw new HttpException('Invalid email', HttpStatus.BAD_REQUEST);
}
return subscription.deleteOne();
}
public async findOne(mail: string): Promise<NewsletterSubscription | undefined> {
return this.newsletterSubscriptionModel.findOne({ email: mail }).exec();
}
public async searchNewsletterSubscription(searchString: string) {
return this.newsletterSubscriptionModel.find({ email: new RegExp(searchString, 'i') }).exec();
}
public async deleteOneEmail(mail: string): Promise<NewsletterSubscription | undefined> {
const subscription = await this.newsletterSubscriptionModel.findOne({ email: mail }).exec();
if (!subscription) {
throw new HttpException('Invalid email', HttpStatus.BAD_REQUEST);
}
return subscription.deleteOne();
}
public async findAll(): Promise<NewsletterSubscription[]> {
return await this.newsletterSubscriptionModel.find().exec();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment