// Path: src/main/java/com/edwise/completespring/entities/SequenceId.java
// @Document(collection = "sequences")
// @Setter @Getter
// @Accessors(chain = true)
// @ToString(doNotUseGetters = true)
// public class SequenceId {
//     @Id
//     private String id;
// 
//     private long seq;
// 
// }
// 
// Path: src/main/java/com/edwise/completespring/exceptions/SequenceException.java
// public class SequenceException extends RuntimeException {
// 
//     public SequenceException(String msg) {
//         super(msg);
//     }
// }
// 
// Path: src/main/java/com/edwise/completespring/services/impl/BookServiceImpl.java
// @Service
// public class BookServiceImpl implements BookService {
//     public static final String BOOK_COLLECTION = "books";
//     private static final String BOOK_NOT_FOUND_MSG = "Book not found";
// 
//     @Autowired
//     private BookRepository bookRepository;
// 
//     @Autowired
//     private SequenceIdRepository sequenceIdRepository;
// 
//     @Override
//     public List<Book> findAll() {
//         return bookRepository.findAll();
//     }
// 
//     @Override
//     public Book save(Book book) {
//         return bookRepository.save(book);
//     }
// 
//     @Override
//     public Book findOne(Long id) {
//         Optional<Book> result = bookRepository.findById(id);
//         if (!result.isPresent()) {
//             throw new NotFoundException(BOOK_NOT_FOUND_MSG);
//         }
//         return result.get();
//     }
// 
//     @Override
//     public void delete(Long id) {
//         bookRepository.deleteById(id);
//     }
// 
//     @Override
//     public Book create(Book book) {
//         Long id = sequenceIdRepository.getNextSequenceId(BOOK_COLLECTION);
//         book.setId(id);
// 
//         return bookRepository.save(book);
//     }
// 
//     @Override
//     public List<Book> findByTitle(String title) {
//         return bookRepository.findByTitle(title);
//     }
// 
//     @Override
//     public List<Book> findByReleaseDate(LocalDate releaseDate) {
//         return bookRepository.findByReleaseDate(releaseDate);
//     }
// }


import com.edwise.completespring.entities.SequenceId;
import com.edwise.completespring.exceptions.SequenceException;
import com.edwise.completespring.services.impl.BookServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.Mockito.*;
package com.edwise.completespring.repositories.impl;



@RunWith(MockitoJUnitRunner.class)
public class SequenceIdRepositoryImplTest {

    private static final long TEST_SEQUENCE_ID = 7L;
    private static final int ONE_TIME = 1;

    @Mock
    private MongoOperations mongoOperation;

    @InjectMocks
    private SequenceIdRepositoryImpl repository = new SequenceIdRepositoryImpl();

    @Test
    public void testGetNextSequenceId() {
        when(mongoOperation.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class),
                eq(SequenceId.class))).thenReturn(new SequenceId().setId(BookServiceImpl.BOOK_COLLECTION).setSeq(6L));

        long seqId = repository.getNextSequenceId(BookServiceImpl.BOOK_COLLECTION);

        assertThat(seqId).as("Should return a valid sequence").isGreaterThan(0);
        verify(mongoOperation, times(ONE_TIME)).findAndModify(any(Query.class), any(Update.class),
                any(FindAndModifyOptions.class), eq(SequenceId.class));
    }

    @Test
    public void testGetNextSequenceIdWhenNotExistsSequence() {
        when(mongoOperation.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class),
                eq(SequenceId.class))).thenReturn(null);

        Throwable thrown = catchThrowable(() -> repository.getNextSequenceId(BookServiceImpl.BOOK_COLLECTION));

        assertThat(thrown)
// Path: src/main/java/com/edwise/completespring/entities/SequenceId.java
// @Document(collection = "sequences")
// @Setter @Getter
// @Accessors(chain = true)
// @ToString(doNotUseGetters = true)
// public class SequenceId {
//     @Id
//     private String id;
// 
//     private long seq;
// 
// }
// 
// Path: src/main/java/com/edwise/completespring/exceptions/SequenceException.java
// public class SequenceException extends RuntimeException {
// 
//     public SequenceException(String msg) {
//         super(msg);
//     }
// }
// 
// Path: src/main/java/com/edwise/completespring/services/impl/BookServiceImpl.java
// @Service
// public class BookServiceImpl implements BookService {
//     public static final String BOOK_COLLECTION = "books";
//     private static final String BOOK_NOT_FOUND_MSG = "Book not found";
// 
//     @Autowired
//     private BookRepository bookRepository;
// 
//     @Autowired
//     private SequenceIdRepository sequenceIdRepository;
// 
//     @Override
//     public List<Book> findAll() {
//         return bookRepository.findAll();
//     }
// 
//     @Override
//     public Book save(Book book) {
//         return bookRepository.save(book);
//     }
// 
//     @Override
//     public Book findOne(Long id) {
//         Optional<Book> result = bookRepository.findById(id);
//         if (!result.isPresent()) {
//             throw new NotFoundException(BOOK_NOT_FOUND_MSG);
//         }
//         return result.get();
//     }
// 
//     @Override
//     public void delete(Long id) {
//         bookRepository.deleteById(id);
//     }
// 
//     @Override
//     public Book create(Book book) {
//         Long id = sequenceIdRepository.getNextSequenceId(BOOK_COLLECTION);
//         book.setId(id);
// 
//         return bookRepository.save(book);
//     }
// 
//     @Override
//     public List<Book> findByTitle(String title) {
//         return bookRepository.findByTitle(title);
//     }
// 
//     @Override
//     public List<Book> findByReleaseDate(LocalDate releaseDate) {
//         return bookRepository.findByReleaseDate(releaseDate);
//     }
// }


// Path: src/test/java/com/edwise/completespring/repositories/impl/SequenceIdRepositoryImplTest.java
import com.edwise.completespring.entities.SequenceId;
import com.edwise.completespring.exceptions.SequenceException;
import com.edwise.completespring.services.impl.BookServiceImpl;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import org.springframework.data.mongodb.core.FindAndModifyOptions;
import org.springframework.data.mongodb.core.MongoOperations;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.catchThrowable;
import static org.mockito.Mockito.*;

package com.edwise.completespring.repositories.impl;



@RunWith(MockitoJUnitRunner.class)
public class SequenceIdRepositoryImplTest {

    private static final long TEST_SEQUENCE_ID = 7L;
    private static final int ONE_TIME = 1;

    @Mock
    private MongoOperations mongoOperation;

    @InjectMocks
    private SequenceIdRepositoryImpl repository = new SequenceIdRepositoryImpl();

    @Test
    public void testGetNextSequenceId() {
        when(mongoOperation.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class),
                eq(SequenceId.class))).thenReturn(new SequenceId().setId(BookServiceImpl.BOOK_COLLECTION).setSeq(6L));

        long seqId = repository.getNextSequenceId(BookServiceImpl.BOOK_COLLECTION);

        assertThat(seqId).as("Should return a valid sequence").isGreaterThan(0);
        verify(mongoOperation, times(ONE_TIME)).findAndModify(any(Query.class), any(Update.class),
                any(FindAndModifyOptions.class), eq(SequenceId.class));
    }

    @Test
    public void testGetNextSequenceIdWhenNotExistsSequence() {
        when(mongoOperation.findAndModify(any(Query.class), any(Update.class), any(FindAndModifyOptions.class),
                eq(SequenceId.class))).thenReturn(null);

        Throwable thrown = catchThrowable(() -> repository.getNextSequenceId(BookServiceImpl.BOOK_COLLECTION));

        assertThat(thrown)
                .isInstanceOf(SequenceException.class)