/* * The MIT License (MIT) * * Copyright (c) 2013-2017 Cinchapi Inc. * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ package com.cinchapi.concourse.example.bank; import java.text.MessageFormat; import java.util.Set; import org.junit.Assert; import org.junit.Test; import com.cinchapi.concourse.Link; import com.cinchapi.concourse.test.ClientServerTest; import com.cinchapi.concourse.test.Variables; import com.google.common.base.Throwables; import com.google.common.collect.Sets; /** * This is a test to show that the Concourse backed implementation for the Bank * application satisfies the necessary constraints. * <p> * This test takes advantage of the <em>concourse-ete-test-core</em> framework, * which allows us to easily define test cases that run application source code * against a real Concourse server instance that is completely managed for us. * </p> * <p> * When using this test framework, we can make assertions about our business * logic (like we would do anyway) and simultaneously make direct assertions * about what data is stored in the database without doing any extra work. * </p> * * @author Jeff Nelson */ public class ConcourseBankTest extends ClientServerTest { @Override protected String getServerVersion() { // This allows us to control the exact version of Concourse against // which the tests will run. This should always match the version of // Concourse that is used when the application is deployed (i.e. 0.4.4, // 0.5.0, etc). The nice thing about this is that whenever the Concourse // version is upgraded for the application, we can simply change the // version number used within our tests and ensure that none of the // application code has broken as a result of the upgrade. return "latest"; } @Override public void beforeEachTest() { // Here we can define tasks that are run before each test case. // Since the application code uses the default connection scheme, we // have to configure the tests to use the connection information that // maps to the test server provided by the framework. server.syncDefaultClientConnectionInfo(); Constants.refreshConnectionInfo(); } @Override public void afterEachTest() { // Here we can define tasks that are run after each test case. The // application has a shutdown hook to close the connection pool, but // that is only run once the JVM terminates. Since all tests are run // within the same JVM, we manually close down the connection pool at // the end of each test. try { Constants.CONCOURSE_CONNECTIONS.close(); } catch (Exception e) { throw Throwables.propagate(e); } } @Test public void testOwnersAreLinks() { // In this test, we register variables that we want to debug in case the // test fails. All registered variables are output the console whenever // a test fails. Customer a = Variables.register("a", new ConcourseCustomer("Jeff", "Nelson")); Customer b = Variables.register("b", new ConcourseCustomer("Ashleah", "Nelson")); Customer c = Variables.register("c", new ConcourseCustomer("John", "Doe")); Account acct = new ConcourseAccount(250.15, a, b, c); Set<Link> links = client.select("owners", acct.getId()); Variables.register("links", links); Assert.assertTrue(links.contains(Link.to(a.getId()))); Assert.assertTrue(links.contains(Link.to(b.getId()))); Assert.assertTrue(links.contains(Link.to(c.getId()))); String ccl = MessageFormat.format("{0} {1} AND {0} {2} AND {0} {3}", "owners lnks2", Long.toString(a.getId()), Long.toString(b.getId()), Long.toString(c.getId())); Assert.assertEquals(Sets.newHashSet(acct.getId()), client.find(ccl)); } @Test public void testDeposit() { Customer cust = new ConcourseCustomer("Jeff", "Nelson"); Account acct = new ConcourseAccount(100.00, cust); Assert.assertEquals(100.00, client.get("balance", acct.getId())); acct.deposit(100); Assert.assertEquals(200.00, client.get("balance", acct.getId())); } @Test public void testWithdrawal() { Customer cust = new ConcourseCustomer("Jeff", "Nelson"); Account acct = new ConcourseAccount(100.00, cust); Assert.assertTrue(acct.withdraw(40.38)); Assert.assertEquals(59.62, client.get("balance", acct.getId())); Assert.assertTrue(client.describe(acct.getId()).contains("charges")); } @Test public void testCannotOverdraft() { Customer cust = new ConcourseCustomer("Jeff", "Nelson"); Account acct = new ConcourseAccount(100.00, cust); Assert.assertFalse(acct.withdraw(200.00)); } @Test public void testOverdraftProtection() { Customer cust1 = new ConcourseCustomer("Jeff", "Nelson"); Customer cust2 = new ConcourseCustomer("Ashleah", "Nelson"); Account checking = new ConcourseAccount(100, cust1, cust2); Account savings1 = new ConcourseAccount(100, cust1); Account savings2 = new ConcourseAccount(100, cust1); Assert.assertTrue(checking.withdraw(230.00)); Assert.assertTrue(checking.getBalance() >= 0); Assert.assertTrue(savings1.getBalance() >= 0); Assert.assertTrue(savings2.getBalance() >= 0); Assert.assertEquals( 70.00, checking.getBalance() + savings1.getBalance() + savings2.getBalance(), 0); } @Test public void testOverdraftProtectionNotPossible() { Customer cust1 = new ConcourseCustomer("Jeff", "Nelson"); Customer cust2 = new ConcourseCustomer("Ashleah", "Nelson"); Account checking = new ConcourseAccount(100, cust1, cust2); Account savings1 = new ConcourseAccount(100, cust1); Account savings2 = new ConcourseAccount(100, cust1); Assert.assertFalse(checking.withdraw(330.00)); Assert.assertEquals(100.00, checking.getBalance(), 0); Assert.assertEquals(100.00, savings1.getBalance(), 0); Assert.assertEquals(100.00, savings2.getBalance(), 0); } }