package ru.abelov.banking;

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

/**
 * Test class of Bak class.
 * @author Aleksandr Belov.
 * @since 03.05.2017
 */

public class BankTest {

    /**
     * Test of addUser().
     */

    @Test
    public void whenMethodAddsUser() {
        final User user = new User("Ivan", 12345);
        final Bank bank = new Bank();
        assertThat(bank.getUsers().size(), is(0));
        bank.addUser(user);
        assertThat(bank.getUsers().size(), is(1));
        bank.addUser(user);
        assertThat(bank.getUsers().size(), is(1));
    }

    /**
     * Test of deleteUser().
     */

    @Test
    public void whenMethodRemovesUser() {
        final User user = new User("Ivan", 12345);
        final Bank bank = new Bank();
        assertThat(bank.getUsers().size(), is(0));
        bank.addUser(user);
        assertThat(bank.getUsers().size(), is(1));
        bank.deleteUser(user);
        assertThat(bank.getUsers().size(), is(0));
    }

    /**
     * Test of addAccountToUser().
     */

    @Test
    public void whenMethodAddsAccountToUser() {
        final User user = new User("Ivan", 12345);
        final Bank bank = new Bank();
        final Account account = new Account(0.0, 54321);
        bank.addUser(user);
        assertThat(bank.getUserAccounts(user).size(), is(0));
        bank.addAccountToUser(user, account);
        assertThat(bank.getUserAccounts(user).size(), is(1));
    }

    /**
     * Test of deleteAccountFromUser().
     */

    @Test
    public void whenMethodDeletesAccountFromUser() {
        final User user = new User("Ivan", 12345);
        final Bank bank = new Bank();
        final Account account = new Account(5.0, 54321);
        bank.addUser(user);
        bank.addAccountToUser(user, account);
        bank.deleteAccountFromUser(user, account);
        assertThat(bank.getUserAccounts(user).size(), is(0));
    }

    /**
     * Test of deleteAccountFromUser().
     */

    @Test
    public void whenMethodTransfersMoneyFromUserAccountCorrectly() {
        final User user0 = new User("Ivan", 12345);
        final User user1 = new User("Petr", 23456);
        final Bank bank = new Bank();
        final Account account0 = new Account(5.0, 54321);
        final Account account1 = new Account(5.0, 65432);
        final double low = 1;
        final double high = 10;
        bank.addUser(user0);
        bank.addUser(user1);
        boolean result = bank.transferMoney(user0, account0, user1, account1, low);
        assertThat(result, is(false));
        bank.addAccountToUser(user0, account0);
        result = bank.transferMoney(user0, account0, user1, account1, low);
        assertThat(result, is(false));
        bank.addAccountToUser(user1, account1);
        result = bank.transferMoney(user0, account0, user1, account1, low);
        assertThat(result, is(true));
        result = bank.transferMoney(user0, account0, user1, account1, high);
        assertThat(result, is(false));
    }

    /**
     * Test of bankContainsUser().
     */

    @Test(expected = UserNotFoundException.class)
    public void whenRemoveNonexistentUser() {
        final Bank bank = new Bank();
        final User user0 = new User("Ivan", 12345);
        final User user1 = new User("Petr", 23456);
        bank.addUser(user0);
        bank.deleteUser(user1);
    }
}