Skip to content

Commit

Permalink
Remove event (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
mmarchois authored Apr 15, 2021
1 parent d067526 commit 3c52794
Show file tree
Hide file tree
Showing 8 changed files with 161 additions and 4 deletions.
5 changes: 5 additions & 0 deletions api/src/Application/Calendar/Command/RemoveEventCommand.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { ICommand } from 'src/Application/ICommand';

export class RemoveEventCommand implements ICommand {
constructor(public readonly id: string) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { mock, instance, when, verify, anything } from 'ts-mockito';
import { RemoveEventCommandHandler } from './RemoveEventCommandHandler';
import { RemoveEventCommand } from './RemoveEventCommand';
import { EventRepository } from 'src/Infrastructure/Calendar/Repository/EventRepository';
import { Event } from 'src/Domain/Calendar/Event.entity';
import { EventNotFoundException } from 'src/Domain/Calendar/Exception/EventNotFoundException';

describe('RemoveEventCommandHandler', () => {
let eventRepository: EventRepository;
let removedEvent: Event;
let handler: RemoveEventCommandHandler;

const command = new RemoveEventCommand('17efcbee-bd2f-410e-9e99-51684b592bad');

beforeEach(() => {
eventRepository = mock(EventRepository);
removedEvent = mock(Event);

handler = new RemoveEventCommandHandler(
instance(eventRepository)
);
});

it('testEventRemovedSuccessfully', async () => {
when(eventRepository.findOneById('17efcbee-bd2f-410e-9e99-51684b592bad'))
.thenResolve(instance(removedEvent));
when(removedEvent.getId()).thenReturn(
'17efcbee-bd2f-410e-9e99-51684b592bad'
);
when(
eventRepository.save(instance(removedEvent))
).thenResolve(instance(removedEvent));

await handler.execute(command);

verify(
eventRepository.remove(instance(removedEvent))
).once();
verify(eventRepository.findOneById('17efcbee-bd2f-410e-9e99-51684b592bad')).once();
});

it('testEventNotFound', async () => {
when(eventRepository.findOneById('17efcbee-bd2f-410e-9e99-51684b592bad'))
.thenResolve(null);

try {
expect(await handler.execute(command)).toBeUndefined();
} catch (e) {
expect(e).toBeInstanceOf(EventNotFoundException);
expect(e.message).toBe('calendar.errors.event_not_found');
verify(eventRepository.findOneById('17efcbee-bd2f-410e-9e99-51684b592bad')).once();
verify(eventRepository.remove(anything())).never();
}
});
});
23 changes: 23 additions & 0 deletions api/src/Application/Calendar/Command/RemoveEventCommandHandler.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { Inject } from '@nestjs/common';
import { CommandHandler } from '@nestjs/cqrs';
import { EventNotFoundException } from 'src/Domain/Calendar/Exception/EventNotFoundException';
import { IEventRepository } from 'src/Domain/Calendar/Repository/IEventRepository';
import { RemoveEventCommand } from './RemoveEventCommand';

@CommandHandler(RemoveEventCommand)
export class RemoveEventCommandHandler {
constructor(
@Inject('IEventRepository')
private readonly eventRepository: IEventRepository,
) {}

public async execute({ id }: RemoveEventCommand): Promise<void> {
const event = await this.eventRepository.findOneById(id);

if (!event) {
throw new EventNotFoundException();
}

await this.eventRepository.remove(event);
}
}
1 change: 1 addition & 0 deletions api/src/Domain/Calendar/Repository/IEventRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ export interface IEventRepository {
save(event: Event): Promise<Event>;
findByPeriod(fromDate: Date, toDate: Date): Promise<Event[]>;
findOneById(id: string): Promise<Event | undefined>;
remove(event: Event): void;
}
38 changes: 38 additions & 0 deletions api/src/Infrastructure/Calendar/Action/RemoveEventAction.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {
Controller,
Inject,
BadRequestException,
UseGuards,
Param,
Delete
} from '@nestjs/common';
import { AuthGuard } from '@nestjs/passport';
import { ApiTags, ApiOperation, ApiBearerAuth } from '@nestjs/swagger';
import { RemoveEventCommand } from 'src/Application/Calendar/Command/RemoveEventCommand';
import { ICommandBus } from 'src/Application/ICommandBus';
import { UserRole } from 'src/Domain/User/User.entity';
import { IdDTO } from 'src/Infrastructure/Common/DTO/IdDTO';
import { Roles } from 'src/Infrastructure/User/Decorator/Roles';
import { RolesGuard } from 'src/Infrastructure/User/Security/RolesGuard';

@Controller('events')
@ApiTags('Calendar')
@ApiBearerAuth()
@UseGuards(AuthGuard('bearer'), RolesGuard)
export class RemoveEventAction {
constructor(
@Inject('ICommandBus')
private readonly commandBus: ICommandBus
) {}

@Delete(':id')
@Roles(UserRole.PHOTOGRAPHER)
@ApiOperation({ summary: 'Remove event' })
public async index(@Param() { id }: IdDTO) {
try {
await this.commandBus.execute(new RemoveEventCommand(id));
} catch (e) {
throw new BadRequestException(e.message);
}
}
}
4 changes: 4 additions & 0 deletions api/src/Infrastructure/Calendar/Repository/EventRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,10 @@ export class EventRepository implements IEventRepository {
return this.repository.save(event);
}

public remove(event: Event): void {
this.repository.delete(event.getId());
}

public findByPeriod(fromDate: Date, toDate: Date): Promise<Event[]> {
return this.repository
.createQueryBuilder('event')
Expand Down
8 changes: 6 additions & 2 deletions api/src/Infrastructure/Calendar/calendar.module.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { CreateEventCommandHandler } from 'src/Application/Calendar/Command/CreateEventCommandHandler';
import { RemoveEventCommandHandler } from 'src/Application/Calendar/Command/RemoveEventCommandHandler';
import { GetEventByIdQueryHandler } from 'src/Application/Calendar/Query/GetEventByIdQueryHandler';
import { GetEventsByPeriodQueryHandler } from 'src/Application/Calendar/Query/GetEventsByPeriodQueryHandler';
import { Event } from 'src/Domain/Calendar/Event.entity';
Expand All @@ -12,6 +13,7 @@ import { UserRepository } from '../User/Repository/UserRepository';
import { CreateEventAction } from './Action/CreateEventAction';
import { GetEventAction } from './Action/GetEventAction';
import { GetEventsAction } from './Action/GetEventsAction';
import { RemoveEventAction } from './Action/RemoveEventAction';
import { EventRepository } from './Repository/EventRepository';

@Module({
Expand All @@ -26,15 +28,17 @@ import { EventRepository } from './Repository/EventRepository';
controllers: [
GetEventsAction,
CreateEventAction,
GetEventAction
GetEventAction,
RemoveEventAction
],
providers: [
{ provide: 'IEventRepository', useClass: EventRepository },
{ provide: 'ISchoolRepository', useClass: SchoolRepository },
{ provide: 'IUserRepository', useClass: UserRepository },
CreateEventCommandHandler,
GetEventsByPeriodQueryHandler,
GetEventByIdQueryHandler
GetEventByIdQueryHandler,
RemoveEventCommandHandler
]
})
export class CalendarModule {}
31 changes: 29 additions & 2 deletions client/src/routes/admin/calendar/[id]/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@

<script>
import { _ } from 'svelte-i18n';
import { goto } from '@sapper/app';
import { onMount } from 'svelte';
import { get } from 'utils/axios';
import { get, del } from 'utils/axios';
import Breadcrumb from 'components/Breadcrumb.svelte';
import { errorNormalizer } from 'normalizer/errors';
import ServerErrors from 'components/ServerErrors.svelte';
Expand All @@ -18,6 +19,7 @@
export let id;
let event;
let loading = false;
let title = '';
let errors = [];
Expand All @@ -29,6 +31,22 @@
errors = errorNormalizer(e);
}
});
const handleDelete = async () => {
if (!confirm($_('common.confirm.delete'))) {
return;
}
try {
loading = true;
await del(`events/${event.id}`);
goto('/admin/calendar');
} catch (e) {
errors = errorNormalizer(e);
} finally {
loading = false;
}
};
</script>

<svelte:head>
Expand All @@ -45,8 +63,17 @@
{#if event}
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">
{$_('calendar.detail.informations')}
<Link href={`/admin/calendar/${id}/edit`} value={$_('common.form.edit')} />
</h4>
<Detail {event} />
<div class="text-center mt-4">
<Link href={`/admin/calendar/${id}/edit`} value={$_('common.form.edit')} />
<button
disable={loading}
class="ml-2 px-2 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-red-600 border border-transparent rounded-lg active:bg-red-600 hover:bg-red-700 focus:outline-none focus:shadow-outline-purple"
type="button"
on:click={handleDelete}>
{$_('common.form.remove')}
</button>
</div>
{/if}
</div>

0 comments on commit 3c52794

Please sign in to comment.