Skip to content

Instantly share code, notes, and snippets.

View PCreations's full-sized avatar

Pierre Criulanscy PCreations

View GitHub Profile
@PCreations
PCreations / 64fdd9babe19.diff
Created July 17, 2024 08:22
64fdd9babe19.diff
-1,3 +1,4 @@
export abstract class BookRepository {
abstract save(book: { title: string }): Promise<void>;
+ abstract doesBookExist(title: string): Promise<boolean>;
}
@PCreations
PCreations / 35aed18c289b.diff
Created July 17, 2024 08:22
35aed18c289b.diff
-0,0 +1,5 @@
+export class BookAlreadyExistsError extends Error {
+ constructor(bookTitle: string) {
+ super(`The book ${bookTitle} already exists`);
+ }
+}
@PCreations
PCreations / 4b8eb8ab76bf.diff
Created July 17, 2024 08:22
4b8eb8ab76bf.diff
import { BookRepository } from './book-repository.port';
export class InMemoryBookRepository implements BookRepository {
+ booksByTitle = new Map<string, { title: string }>(); // J'en profite ici pour créer une Map référençant les livres par titre.
+
lastSavedBook: { title: string } | undefined;
async save(book: { title: string }): Promise<void> {
this.lastSavedBook = book;
+ this.booksByTitle.set(book.title, book);
@PCreations
PCreations / ed668e3a14ad.diff
Created July 17, 2024 08:22
ed668e3a14ad.diff
+ test('Example: User cannot add a book that already exists', async () => {
+ const bookRepository = new StubBookRepository();
+ bookRepository.booksByTitle.set('Clean Code', { title: 'Clean Code' });
+ const addBook = new AddBookUseCase(bookRepository);
+
+ const addingBook = addBook.execute({ title: 'Clean Code' });
+
+ await expect(addingBook).rejects.toThrowError(
+ new BookAlreadyExistsError('The book Clean Code already exists'),
+ );
@PCreations
PCreations / c3a4110d4a3f.diff
Created July 17, 2024 08:22
c3a4110d4a3f.diff
+
+ test('Example: User cannot add a book that already exists', async ({
+ page,
+ }) => {
+ await page.goto('http://localhost:3000');
+ await page.getByLabel(/title/i).fill('Clean Code');
+ await page.getByText(/add book/i).click();
+
+ await page.getByLabel(/title/i).fill('Clean Code');
+ await page.getByText(/add book/i).click();
@PCreations
PCreations / 955c48385798.diff
Created July 17, 2024 08:22
955c48385798.diff
-15,6 +15,7 @@ export class AppController {
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script src="https://cdn.tailwindcss.com"></script>
+ <script src="https://unpkg.com/htmx.org@2.0.1"></script>
</head>
<body>
<main class="container mx-auto px-4 py-8">
@PCreations
PCreations / 14e2e73cf3b9.diff
Created July 17, 2024 08:22
14e2e73cf3b9.diff
export class AppController {
<html>
<head>
<title>Crafty Reads</title>
+ <meta charset="UTF-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
+ <script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
- <form>
@PCreations
PCreations / c0a2e3b039d9.diff
Created May 31, 2024 17:00
c0a2e3b039d9.diff
-1,10 +1,18 @@
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
-import { AppService } from './app.service';
+import { AddBookUseCase } from './add-book.usecase';
+import { StubBookRepository } from './stub.book-repository';
+import { BookRepository } from './book-repository.port';
@Module({
imports: [],
@PCreations
PCreations / 7dbd6ee4b353.diff
Created May 31, 2024 17:00
7dbd6ee4b353.diff
-1,5 +1,7 @@
+import { Injectable } from '@nestjs/common';
import { BookRepository } from './book-repository.port';
+@Injectable()
export class AddBookUseCase {
constructor(private readonly bookRepository: BookRepository) {}
@PCreations
PCreations / b91fc4f5db9a.diff
Created May 31, 2024 17:00
b91fc4f5db9a.diff
-1,3 +1,3 @@
-export interface BookRepository {
- save(book: { title: string }): Promise<void>;
+export abstract class BookRepository {
+ abstract save(book: { title: string }): Promise<void>;
}