Skip to content

Commit

Permalink
Add account details feature
Browse files Browse the repository at this point in the history
  • Loading branch information
mapu77 committed Jul 17, 2018
1 parent bdd11ae commit fc6ecab
Show file tree
Hide file tree
Showing 17 changed files with 306 additions and 6 deletions.
15 changes: 13 additions & 2 deletions src/main/java/com/twu/biblioteca/App.java
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
package com.twu.biblioteca;

import com.twu.biblioteca.accounts.application.AccountInteractor;
import com.twu.biblioteca.accounts.infrastructure.AccountPresenter;
import com.twu.biblioteca.accounts.infrastructure.persistence.InMemoryAccountRepository;
import com.twu.biblioteca.authentication.application.Authenticator;
import com.twu.biblioteca.authentication.infrastructure.AuthenticatorInputController;
import com.twu.biblioteca.authentication.infrastructure.AuthenticatorPresenter;
import com.twu.biblioteca.authentication.infrastructure.InvalidLibraryNumber;
import com.twu.biblioteca.authentication.infrastructure.persistance.InMemoryAccessRepository;
import com.twu.biblioteca.authentication.infrastructure.persistence.InMemoryAccessRepository;
import com.twu.biblioteca.books.application.BookRepository;
import com.twu.biblioteca.books.application.BookShelvesInteractor;
import com.twu.biblioteca.books.infrastructure.AbstractBookPresenter;
import com.twu.biblioteca.books.infrastructure.BookInputController;
import com.twu.biblioteca.books.infrastructure.BookPresenter;
import com.twu.biblioteca.books.infrastructure.persistance.InMemoryBookRepository;
import com.twu.biblioteca.books.infrastructure.persistence.InMemoryBookRepository;
import com.twu.biblioteca.movies.application.MovieShelvesInteractor;
import com.twu.biblioteca.movies.infrastructure.MovieInputController;
import com.twu.biblioteca.movies.infrastructure.MoviePresenter;
Expand All @@ -31,6 +34,8 @@ public class App {
private static BookRepository bookRepository = new InMemoryBookRepository(Arrays.asList(
new String[]{"Harry Potter and the Philosopher's Stone", "J.K. Rowling", "1997"},
new String[]{"Game of Thrones: A Game of Thrones", "George R. Martin", "1996"}));
private static InMemoryAccountRepository accountRepository = new InMemoryAccountRepository(Arrays.asList(
new String[][]{new String[]{"Eduard Maura", "emaura@thoughtworks.com", "Fake Street 123", "+1 123 456 789", "123-1234"}}));

public static void main(String[] args) {
AppPresenter appPresenter = new AppPresenter(System.out);
Expand All @@ -49,6 +54,9 @@ public static void main(String[] args) {
AuthenticatorInputController authenticatorInputController = new AuthenticatorInputController(System.in);
Authenticator authenticator = new Authenticator(accessRepository);
AuthenticatorPresenter authenticatorPresenter = new AuthenticatorPresenter(authenticator, System.out);

AccountInteractor accountInteractor = new AccountInteractor(accountRepository);
AccountPresenter accountPresenter = new AccountPresenter(accountInteractor, System.out);
while (account == null) {
try {
appPresenter.askForLibraryNumber();
Expand Down Expand Up @@ -84,6 +92,9 @@ public static void main(String[] args) {
String movieName = movieInputController.readMovieName();
moviePresenter.checkOutMovie(movieName);
break;
case 6:
accountPresenter.showInfoOf(account);
break;
default:
appPresenter.sayInvalidOption();
}
Expand Down
1 change: 1 addition & 0 deletions src/main/java/com/twu/biblioteca/AppPresenter.java
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ void showMenu() {
output.println("\t3. Return a book");
output.println("\t4. List movies");
output.println("\t5. Checkout a movie");
output.println("\t6. Show account details");
output.println("\t0. Exit");
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
package com.twu.biblioteca.accounts.application;

import com.twu.biblioteca.accounts.core.Account;

import java.util.Optional;

public class AccountInteractor {
private final AccountRepository accountRepository;

public AccountInteractor(AccountRepository accountRepository) {
this.accountRepository = accountRepository;
}

public Account find(String libraryNumber) {
Optional<Account> account = this.accountRepository.find(libraryNumber);
if (account.isPresent()) return account.get();
else throw new AccountNotFound();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package com.twu.biblioteca.accounts.application;

class AccountNotFound extends RuntimeException {
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package com.twu.biblioteca.accounts.application;

import com.twu.biblioteca.accounts.core.Account;

import java.util.Optional;

public interface AccountRepository {
Optional<Account> find(String aLibraryNumber);
}
40 changes: 40 additions & 0 deletions src/main/java/com/twu/biblioteca/accounts/core/Account.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.twu.biblioteca.accounts.core;

public class Account {
private String phoneNumber;
private String address;
private String email;
private String name;

void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}

public String getPhoneNumber() {
return phoneNumber;
}

void setAddress(String address) {
this.address = address;
}

public String getAddress() {
return address;
}

void setEmail(String email) {
this.email = email;
}

public String getEmail() {
return email;
}

public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}
}
37 changes: 37 additions & 0 deletions src/main/java/com/twu/biblioteca/accounts/core/AccountBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package com.twu.biblioteca.accounts.core;

public class AccountBuilder {
private String phoneNumber;
private String address;
private String email;
private String name;

public Account build() {
Account account = new Account();
account.setName(name);
account.setEmail(email);
account.setAddress(address);
account.setPhoneNumber(phoneNumber);
return account;
}

public AccountBuilder withPhoneNumber(String aPhoneNumber) {
this.phoneNumber = aPhoneNumber;
return this;
}

public AccountBuilder withAddress(String anAddress) {
this.address = anAddress;
return this;
}

public AccountBuilder withEmail(String anEmail) {
this.email = anEmail;
return this;
}

public AccountBuilder withName(String aName) {
this.name = aName;
return this;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package com.twu.biblioteca.accounts.infrastructure;

import com.twu.biblioteca.accounts.application.AccountInteractor;
import com.twu.biblioteca.accounts.core.Account;

import java.io.PrintStream;

public class AccountPresenter {
private final AccountInteractor accountInteractor;
private final PrintStream out;

public AccountPresenter(AccountInteractor accountInteractor, PrintStream out) {
this.accountInteractor = accountInteractor;
this.out = out;
}

public void showInfoOf(String accountNumber) {
Account account = accountInteractor.find(accountNumber);
out.println("Name: " + account.getName());
out.println("Email: " + account.getEmail());
out.println("Address: " + account.getAddress());
out.println("Phone: " + account.getPhoneNumber());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.twu.biblioteca.accounts.infrastructure.persistence;

import com.twu.biblioteca.accounts.application.AccountRepository;
import com.twu.biblioteca.accounts.core.Account;
import com.twu.biblioteca.accounts.core.AccountBuilder;

import java.util.Collection;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

public class InMemoryAccountRepository implements AccountRepository {
private Map<String, Account> accounts;

public InMemoryAccountRepository(Collection<String[]> accounts) {
this.accounts = accounts.stream().collect(Collectors.toMap(mapKey(), mapAccount()));
}

private Function<String[], Account> mapAccount() {
return values -> new AccountBuilder().withName(values[0]).withEmail(values[1]).withAddress(values[2]).withPhoneNumber(values[3]).build();
}

private Function<String[], String> mapKey() {
return values -> values[4];
}

@Override
public Optional<Account> find(String aLibraryNumber) {
return this.accounts.containsKey(aLibraryNumber) ? Optional.of(this.accounts.get(aLibraryNumber)) : Optional.empty();
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.twu.biblioteca.authentication.infrastructure.persistance;
package com.twu.biblioteca.authentication.infrastructure.persistence;

import com.twu.biblioteca.authentication.application.AccessRepository;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.twu.biblioteca.books.infrastructure.persistance;
package com.twu.biblioteca.books.infrastructure.persistence;

import com.twu.biblioteca.books.application.BookRepository;
import com.twu.biblioteca.books.core.BookInfo;
Expand Down
1 change: 1 addition & 0 deletions src/test/java/com/twu/biblioteca/AppPresenterShould.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public void showMenuOptions() {
inOrder.verify(outMock).println("\t3. Return a book");
inOrder.verify(outMock).println("\t4. List movies");
inOrder.verify(outMock).println("\t5. Checkout a movie");
inOrder.verify(outMock).println("\t6. Show account details");
inOrder.verify(outMock).println("\t0. Exit");
verifyNoMoreInteractions(outMock);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.twu.biblioteca.accounts.application;

import com.twu.biblioteca.accounts.core.Account;
import org.junit.Before;
import org.junit.Test;

import java.util.Optional;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

public class AccountInteractorShould {

private AccountRepository accountRepoMock;
private AccountInteractor accountInteractor;

@Before
public void setUp() {
accountRepoMock = mock(AccountRepository.class);
accountInteractor = new AccountInteractor(accountRepoMock);
}

@Test (expected = AccountNotFound.class)
public void throwAccountNotFoundWhenAccountIsNotInRepo() {
when(accountRepoMock.find("aLibraryNumber")).thenReturn(Optional.empty());
accountInteractor.find("aLibraryNumber");
}

@Test
public void returnAnAccountWhenItIsInTheRepo() {
Account value = new Account();
when(accountRepoMock.find("aLibraryNumber")).thenReturn(Optional.of(value));
Account expectedAccount = accountInteractor.find("aLibraryNumber");
assertThat(expectedAccount, is(value));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.twu.biblioteca.accounts.infrastructure;

import com.twu.biblioteca.accounts.application.AccountInteractor;
import com.twu.biblioteca.accounts.core.AccountBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.PrintStream;

import static org.mockito.Mockito.*;

public class AccountPresenterShould {
private AccountInteractor accountInteractorMock;
private PrintStream outMock;
private AccountPresenter accountPresenter;

@Before
public void setUp() {
accountInteractorMock = mock(AccountInteractor.class);
outMock = mock(PrintStream.class);
accountPresenter = new AccountPresenter(accountInteractorMock, outMock);
}

@Test
public void printAccountNameWhenAskingForAccountDetails() {
when(accountInteractorMock.find("Some account")).thenReturn(new AccountBuilder().withName("A name").build());
accountPresenter.showInfoOf("Some account");
verify(outMock).println("Name: A name");
}

@Test
public void printAccountEmailWhenAskingForAccountDetails() {
when(accountInteractorMock.find("Some account")).thenReturn(new AccountBuilder().withEmail("An email").build());
accountPresenter.showInfoOf("Some account");
verify(outMock).println("Email: An email");
}

@Test
public void printAccountAddressWhenAskingForAccountDetails() {
when(accountInteractorMock.find("Some account")).thenReturn(new AccountBuilder().withAddress("An address").build());
accountPresenter.showInfoOf("Some account");
verify(outMock).println("Address: An address");
}

@Test
public void printAccountPhoneNumberWhenAskingForAccountDetails() {
when(accountInteractorMock.find("Some account")).thenReturn(new AccountBuilder().withPhoneNumber("A phone number").build());
accountPresenter.showInfoOf("Some account");
verify(outMock).println("Phone: A phone number");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
package com.twu.biblioteca.accounts.infrastructure.persistence;

import com.twu.biblioteca.accounts.application.AccountRepository;
import org.junit.Test;

import java.util.Arrays;
import java.util.Collections;
import java.util.Optional;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;


public class InMemoryAccountRepositoryShould {

@Test
public void returnAnEmptyAccountWhenNotFindingOne() {
AccountRepository accountRepository = new InMemoryAccountRepository(Collections.emptyList());
assertThat(accountRepository.find("some account number"), is(Optional.empty()));
}

@Test
public void returnAnAccountWhenFindingIt() {
AccountRepository accountRepository = new InMemoryAccountRepository(Arrays.asList(new String[][] {
new String[] {"Some name", "Some email", "Some address", "Some phone number", "some account number"}
}));
assertThat(accountRepository.find("some account number").isPresent(), is(true));
assertThat(accountRepository.find("some account number").get().getName(), is("Some name"));
assertThat(accountRepository.find("some account number").get().getEmail(), is("Some email"));
assertThat(accountRepository.find("some account number").get().getAddress(), is("Some address"));
assertThat(accountRepository.find("some account number").get().getPhoneNumber(), is("Some phone number"));
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.twu.biblioteca.authentication.infrastructure.persistance;
package com.twu.biblioteca.authentication.infrastructure.persistence;

import org.junit.Test;

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package com.twu.biblioteca.books.infrastructure.persistance;
package com.twu.biblioteca.books.infrastructure.persistence;

import org.junit.Test;

Expand Down

0 comments on commit fc6ecab

Please sign in to comment.