Skip to content

Commit

Permalink
Merge pull request #6 from aulasoftwarelibre/remove-neverthrow
Browse files Browse the repository at this point in the history
Remove neverthrow
  • Loading branch information
sgomez authored May 9, 2024
2 parents de1ad63 + 69ecb60 commit 3e107ed
Show file tree
Hide file tree
Showing 72 changed files with 576 additions and 984 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
"amazon-buddy": "^2.2.45",
"date-fns": "^3.6.0",
"framer-motion": "^11.1.7",
"neverthrow": "^6.2.1",
"next": "14.2.3",
"next-auth": "5.0.0-beta.9",
"next-themes": "^0.3.0",
Expand Down
7 changes: 0 additions & 7 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

29 changes: 9 additions & 20 deletions src/core/book/application/__tests__/create-book.use-case.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { describe, expect, it } from 'vitest'
import { ApplicationError } from '@/core/common/domain/errors/application-error'
import { container } from '@/lib/container'
import { prisma } from '@/lib/prisma/prisma'
import { unexpected } from '@/lib/utils/unexpected'
import { bookRequestExamples } from '@/tests/examples/books-request.examples'
import { createAvailableBook } from '@/tests/examples/factories'

Expand All @@ -13,21 +12,16 @@ describe('CreateBookUseCase', () => {
const command = bookRequestExamples.create()

// Act
const result = await container.createBook.with(command)
await container.createBook.with(command)

// Assert
result.match(
async () => {
const savedBook = await prisma.book.findFirst({
where: {
id: command.id,
},
})
expect(savedBook?.version).toEqual(0)
expect(savedBook?.state).toEqual('AVAILABLE')
const savedBook = await prisma.book.findFirst({
where: {
id: command.id,
},
(error) => unexpected.error(error),
)
})
expect(savedBook?.version).toEqual(0)
expect(savedBook?.state).toEqual('AVAILABLE')
})

it('should rejects to create a book with the same id', async () => {
Expand All @@ -39,14 +33,9 @@ describe('CreateBookUseCase', () => {
}

// Act
const result = await container.createBook.with(command)
const result = async () => await container.createBook.with(command)

// Assert
result.match(
(success) => unexpected.success(success),
(error) => {
expect(error).toBeInstanceOf(ApplicationError)
},
)
expect(result).rejects.toThrowError(ApplicationError)
})
})
30 changes: 9 additions & 21 deletions src/core/book/application/__tests__/edit-book.use-case.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { describe, expect, it } from 'vitest'

import { EditBookRequest } from '@/core/book/dto/requests/edit-book.request'
import { NotFoundError } from '@/core/common/domain/errors/application/not-found-error'
import { container } from '@/lib/container'
import { prisma } from '@/lib/prisma/prisma'
import { unexpected } from '@/lib/utils/unexpected'
import { BooksExamples } from '@/tests/examples/books.examples'
import { createAvailableBook } from '@/tests/examples/factories'

Expand All @@ -20,21 +18,16 @@ describe('EditBookUseCase', () => {
})

// Act
const result = await container.editBook.with(command)
await container.editBook.with(command)

// Assert
result.match(
async () => {
const savedBook = await prisma.book.findFirst({
where: {
id: command.id,
},
})
expect(savedBook?.version).toEqual(1)
expect(savedBook?.title).toEqual(command.title)
const savedBook = await prisma.book.findFirst({
where: {
id: command.id,
},
(error) => unexpected.error(error),
)
})
expect(savedBook?.version).toEqual(1)
expect(savedBook?.title).toEqual(command.title)
})

it('should returns an error if book does not exists', async () => {
Expand All @@ -48,14 +41,9 @@ describe('EditBookUseCase', () => {
})

// Act
const result = await container.editBook.with(command)
const result = async () => await container.editBook.with(command)

// Assert
result.match(
(_ok) => unexpected.success(_ok),
(error) => {
expect(error).toBeInstanceOf(NotFoundError)
},
)
expect(result).rejects.toThrowError()
})
})
20 changes: 4 additions & 16 deletions src/core/book/application/__tests__/loan-book.use-case.spec.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import { describe, expect, it } from 'vitest'

import { LoanBookRequest } from '@/core/book/dto/requests/loan-book.request'
import { ApplicationError } from '@/core/common/domain/errors/application-error'
import { container } from '@/lib/container'
import { prisma } from '@/lib/prisma/prisma'
import { unexpected } from '@/lib/utils/unexpected'
import {
createAvailableBook,
createLoan,
Expand All @@ -23,15 +21,10 @@ describe('Loan book', () => {
})

// Act
const result = container.loanBook.with(request)
await container.loanBook.with(request)

// Assert
await result.match(
async () => {
expect(await prisma.loan.count()).toBe(1)
},
(error) => unexpected.error(error),
)
expect(await prisma.loan.count()).toBe(1)
})

it('should not loan an unavailable book to a user', async () => {
Expand All @@ -45,14 +38,9 @@ describe('Loan book', () => {
})

// Act
const result = container.loanBook.with(request)
const result = async () => container.loanBook.with(request)

// Assert
await result.match(
(_ok) => unexpected.success(_ok),
(_error) => {
expect(_error).instanceof(ApplicationError)
},
)
expect(result).rejects.toThrowError()
})
})
10 changes: 2 additions & 8 deletions src/core/book/application/__tests__/return-book.use-case.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { describe, expect, it } from 'vitest'
import { ReturnBookRequest } from '@/core/book/dto/requests/return-book.request'
import { container } from '@/lib/container'
import { prisma } from '@/lib/prisma/prisma'
import { unexpected } from '@/lib/utils/unexpected'
import {
createLoan,
createLoanedBook,
Expand All @@ -21,14 +20,9 @@ describe('Return book', () => {
})

// Act
const result = container.returnBook.with(request)
await container.returnBook.with(request)

// Assert
await result.match(
async () => {
expect(await prisma.loan.count()).toBe(0)
},
(error) => unexpected.error(error),
)
expect(await prisma.loan.count()).toBe(0)
})
})
6 changes: 3 additions & 3 deletions src/core/book/application/create-book.use-case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ export class CreateBookUseCase {
constructor(private readonly books: Books) {}

async with(command: CreateBookRequest) {
return BookFactory.create(command).asyncAndThen((book) =>
this.books.save(book),
)
const book = BookFactory.create(command)

return this.books.save(book)
}
}
48 changes: 21 additions & 27 deletions src/core/book/application/edit-book.use-case.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { okAsync, Result, ResultAsync } from 'neverthrow'

import { Book } from '@/core/book/domain/model/book.entity'
import { Books } from '@/core/book/domain/services/books.repository'
import { EditBookRequest } from '@/core/book/dto/requests/edit-book.request'
import { NotFoundError } from '@/core/common/domain/errors/application/not-found-error'
import { ApplicationError } from '@/core/common/domain/errors/application-error'
import { DomainError } from '@/core/common/domain/errors/domain-error'
import { BookId } from '@/core/common/domain/value-objects/book-id'
import { FullNames } from '@/core/common/domain/value-objects/fullnames'
import { Image } from '@/core/common/domain/value-objects/image'
Expand All @@ -14,34 +9,33 @@ import { Title } from '@/core/common/domain/value-objects/title'
export class EditBookUseCase {
constructor(private readonly books: Books) {}

async with(command: EditBookRequest) {
return BookId.create(command.id)
.asyncAndThen((bookId) => this.findBook(bookId))
.andThen((book) => this.updateBook(book, command))
async with(command: EditBookRequest): Promise<void> {
const bookId = BookId.create(command.id)
const book = await this.findBook(bookId)

return this.updateBook(book, command)
}

private findBook(bookId: BookId): ResultAsync<Book, NotFoundError> {
return (
this.books.findAvailable(bookId) as ResultAsync<Book, NotFoundError>
).orElse(() => this.books.findLoaned(bookId))
private async findBook(bookId: BookId): Promise<Book> {
try {
return this.books.findAvailable(bookId)
} catch {
return this.books.findLoaned(bookId)
}
}

private updateBook(
private async updateBook(
book: Book,
command: EditBookRequest,
): ResultAsync<void, DomainError | ApplicationError> {
return Result.combine([
Title.create(command.title),
FullNames.create(command.authors),
Image.create(command.image),
])
.asyncAndThen(([title, authors, image]) => {
book.title = title
book.image = image
book.authors = authors
): Promise<void> {
const authors = FullNames.create(command.authors)
const image = Image.create(command.image)
const title = Title.create(command.title)

book.authors = authors
book.image = image
book.title = title

return okAsync(book)
})
.andThen((_book) => this.books.save(_book))
return this.books.save(book)
}
}
24 changes: 13 additions & 11 deletions src/core/book/application/loan-book-use.case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,22 @@ export class LoanBookUseCase {
private readonly loanBookService: LoanBookService,
) {}

with(command: LoanBookRequest) {
return this.findAvailableBook(command.bookId) //
.andThen((book) => this.loanBook(book, command.userId))
async with(command: LoanBookRequest) {
const book = await this.findAvailableBook(command.bookId)

return this.loanBook(book, command.userId)
}

private findAvailableBook(bookId: string) {
return BookId.create(bookId).asyncAndThen((_bookId) =>
this.books.findAvailable(_bookId),
)
private async findAvailableBook(bookId: string) {
const _bookId = BookId.create(bookId)

return this.books.findAvailable(_bookId)
}

private loanBook(book: AvailableBook, userId: string) {
return UserId.create(userId)
.asyncAndThen((_email) => book.loanTo(_email, this.loanBookService))
.andThen(() => this.books.save(book))
private async loanBook(book: AvailableBook, userId: string) {
const _userId = UserId.create(userId)
await book.loanTo(_userId, this.loanBookService)

return this.books.save(book)
}
}
26 changes: 11 additions & 15 deletions src/core/book/application/return-book.use-case.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,20 @@ export class ReturnBookUseCase {
private readonly returnBookService: ReturnBookService,
) {}

with(command: ReturnBookRequest) {
return this.findLoanedBook(command.bookId) //
.andThen((book) => this.returnBook(book))
}
async with(command: ReturnBookRequest) {
const book = await this.findLoanedBook(command.bookId) //

private findLoanedBook(bookId: string) {
return BookId.create(bookId).asyncAndThen((_bookId) =>
this.books.findLoaned(_bookId),
)
return this.returnBook(book)
}

private returnBook(book: LoanedBook) {
return book
.doAvailable(this.returnBookService)
.andThen(() => this.books.save(book))
private async findLoanedBook(bookId: string) {
const _bookId = BookId.create(bookId)

return this.books.findLoaned(_bookId)
}
}

export function add(...arguments_: number[]) {
return arguments_.reduce((a, b) => a + b, 0)
private async returnBook(book: LoanedBook) {
await book.doAvailable(this.returnBookService)
return this.books.save(book)
}
}
12 changes: 3 additions & 9 deletions src/core/book/domain/model/available-book.entity.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,14 @@
import { ResultAsync } from 'neverthrow'

import { Book, BookState } from '@/core/book/domain/model/book.entity'
import { ApplicationError } from '@/core/common/domain/errors/application-error'
import { UserId } from '@/core/common/domain/value-objects/user-id'
import { ignore } from '@/core/common/utils/ignore'
import { LoanBookService } from '@/core/loan/domain/services/loan-book.service'

export class AvailableBook extends Book {
loanTo(
async loanTo(
userId: UserId,
loanBookService: LoanBookService,
): ResultAsync<void, ApplicationError> {
): Promise<void> {
this._state = BookState.LOANED

return loanBookService.with(this, userId).andThen(() => {
return ignore()
})
return loanBookService.with(this, userId)
}
}
Loading

0 comments on commit 3e107ed

Please sign in to comment.