Skip to content

Commit

Permalink
Merge branch '__rultor'
Browse files Browse the repository at this point in the history
  • Loading branch information
rultor committed Oct 15, 2020
2 parents c24581d + 9705ed3 commit 9e7510e
Show file tree
Hide file tree
Showing 3 changed files with 376 additions and 2 deletions.
2 changes: 0 additions & 2 deletions self-api/src/main/java/com/selfxdsd/api/PaymentMethods.java
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@
* @author criske
* @version $Id$
* @since 0.0.26
* @todo #608:60min Provide implementation and unit tests for
* PaymentMethods#ofWallet(...).
*/
public interface PaymentMethods extends Iterable<PaymentMethod> {

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* Copyright (c) 2020, Self XDSD Contributors
* All rights reserved.
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"),
* to read the Software only. Permission is hereby NOT GRANTED to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software.
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.selfxdsd.core.projects;

import com.selfxdsd.api.PaymentMethod;
import com.selfxdsd.api.PaymentMethods;
import com.selfxdsd.api.Wallet;
import com.selfxdsd.api.exceptions.PaymentMethodsException;
import com.selfxdsd.api.storage.Storage;

import java.util.Iterator;
import java.util.function.Supplier;
import java.util.stream.Stream;

/**
* PaymentMethods for a Wallet.
* @author criske
* @version $Id$
* @since 0.0.28
*/
public final class WalletPaymentMethods implements PaymentMethods {

/**
* The wallet in question.
*/
private final Wallet wallet;

/**
* Payment methods for this Wallet.
*/
private final Supplier<Stream<PaymentMethod>> paymentMethods;

/**
* Storage.
*/
private final Storage storage;

/**
* Ctor.
* @param wallet The wallet in question.
* @param paymentMethods Payment methods for this Wallet.
* @param storage Storage.
*/
public WalletPaymentMethods(final Wallet wallet,
final
Supplier<Stream<PaymentMethod>> paymentMethods,
final Storage storage) {
this.wallet = wallet;
this.paymentMethods = paymentMethods;
this.storage = storage;
}

@Override
public PaymentMethod register(final Wallet wallet,
final String identifier) {
if(!this.wallet.equals(wallet)){
throw new PaymentMethodsException("Can't register this payment "
+ "method because it will be part of different wallet.");
}
return this.storage.paymentMethods().register(wallet, identifier);
}

@Override
public boolean remove(final PaymentMethod paymentMethod) {
if(!paymentMethod.wallet().equals(this.wallet)){
throw new PaymentMethodsException("Can't remove this payment "
+ "method because it's part of different wallet.");
}
return this.storage.paymentMethods().remove(paymentMethod);
}

@Override
public PaymentMethods ofWallet(final Wallet wallet) {
if(!this.wallet.equals(wallet)){
throw new PaymentMethodsException("These are payment methods for"
+ wallet.toString() + ", can't call ofWallet() "
+ "for other wallet.");
}
return this;
}

@Override
public PaymentMethod active() {
return this.paymentMethods.get()
.filter(PaymentMethod::active)
.findFirst()
.orElse(null);
}

@Override
public PaymentMethod activate(final PaymentMethod paymentMethod) {
if(!paymentMethod.wallet().equals(this.wallet)){
throw new PaymentMethodsException("Can't activate this payment "
+ "method because it's part of different wallet.");
}
return this.storage.paymentMethods().activate(paymentMethod);
}

@Override
public Iterator<PaymentMethod> iterator() {
return this.paymentMethods.get().iterator();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,253 @@
/**
* Copyright (c) 2020, Self XDSD Contributors
* All rights reserved.
* <p>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"),
* to read the Software only. Permission is hereby NOT GRANTED to use, copy,
* modify, merge, publish, distribute, sublicense, and/or sell copies of
* the Software.
* <p>
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
* OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
* OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.selfxdsd.core.projects;

import com.selfxdsd.api.PaymentMethod;
import com.selfxdsd.api.PaymentMethods;
import com.selfxdsd.api.Wallet;
import com.selfxdsd.api.exceptions.PaymentMethodsException;
import com.selfxdsd.api.storage.Storage;
import org.hamcrest.MatcherAssert;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.mockito.Mockito;

import java.util.stream.Stream;

/**
* Unit tests for {@link WalletPaymentMethods}.
* @author criske
* @version $Id$
* @since 0.0.28
*/
public final class WalletPaymentMethodsTestCase {

/**
* WalletPaymentMethods can be iterated.
*/
@Test
public void iterationWorks() {
final Storage storage = Mockito.mock(Storage.class);
final Wallet wallet = Mockito.mock(Wallet.class);
final Iterable<PaymentMethod> pms = () -> new WalletPaymentMethods(
wallet,
() -> Stream.of(
Mockito.mock(PaymentMethod.class),
Mockito.mock(PaymentMethod.class),
Mockito.mock(PaymentMethod.class)
),
storage
).iterator();

MatcherAssert.assertThat(pms, Matchers.iterableWithSize(3));
}

/**
* WalletPaymentMethods can register a PaymentMethod.
*/
@Test
public void canRegisterPaymentMethod() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethods pms = new WalletPaymentMethods(
wallet,
Stream::empty,
storage
);

pms.register(wallet, "pm_1");

Mockito.verify(all).register(wallet, "pm_1");
}

/**
* WalletPaymentMethods.register(...) throws if register PaymentMethod for
* other wallet.
*/
@Test(expected = PaymentMethodsException.class)
public void complainsIfRegisterPaymentMethodForOtherWallet() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethods pms = new WalletPaymentMethods(
wallet,
Stream::empty,
storage
);

pms.register(Mockito.mock(Wallet.class), "pm_1");
}

/**
* WalletPaymentMethods.remove(...) throws if register PaymentMethod is from
* other wallet.
*/
@Test
public void canRemovePaymentMethod() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethod pmeth = Mockito.mock(PaymentMethod.class);
Mockito.when(pmeth.wallet()).thenReturn(wallet);
final PaymentMethods pms = new WalletPaymentMethods(
wallet,
() -> Stream.of(pmeth),
storage
);

pms.remove(pmeth);

Mockito.verify(all).remove(pmeth);
}

/**
* WalletPaymentMethods can remove a PaymentMethod.
*/
@Test(expected = PaymentMethodsException.class)
public void complainsIfRemovePaymentMethodFromOtherWallet() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethod pmeth = Mockito.mock(PaymentMethod.class);
Mockito.when(pmeth.wallet()).thenReturn(wallet);
final PaymentMethods pms = new WalletPaymentMethods(
wallet,
() -> Stream.of(pmeth),
storage
);
final PaymentMethod otherPmeth = Mockito.mock(PaymentMethod.class);
Mockito.when(otherPmeth.wallet())
.thenReturn(Mockito.mock(Wallet.class));

pms.remove(otherPmeth);
}

/**
* Returns itself when calling ofWallet(...).
*/
@Test
public void returnsItself() {
final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethods pms = new WalletPaymentMethods(
wallet,
Stream::empty,
Mockito.mock(Storage.class)
);
MatcherAssert.assertThat(pms.ofWallet(wallet), Matchers.equalTo(pms));
}

/**
* Throws when calling ofWallet(...) for other Wallet.
*/
@Test(expected = PaymentMethodsException.class)
public void complainsIfFilteringForOtherWallet() {
final PaymentMethods pms = new WalletPaymentMethods(
Mockito.mock(Wallet.class),
Stream::empty,
Mockito.mock(Storage.class)
);
pms.ofWallet(Mockito.mock(Wallet.class));
}

/**
* Returns active PaymentMethod.
*/
@Test
public void returnsActivePaymentMethod() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final PaymentMethod active = Mockito.mock(PaymentMethod.class);
Mockito.when(active.active()).thenReturn(true);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethods pms = new WalletPaymentMethods(
wallet,
() -> Stream.of(
Mockito.mock(PaymentMethod.class),
Mockito.mock(PaymentMethod.class),
Mockito.mock(PaymentMethod.class),
active
),
storage
);

MatcherAssert.assertThat(pms.active(), Matchers.equalTo(active));
}

/**
* Can activate a PaymentMethod.
*/
@Test
public void canActivatePaymentMethod() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethod pmeth = Mockito.mock(PaymentMethod.class);
Mockito.when(pmeth.wallet()).thenReturn(wallet);

final PaymentMethods pms = new WalletPaymentMethods(
wallet,
() -> Stream.of(pmeth),
storage
);

pms.activate(pmeth);

Mockito.verify(all).activate(pmeth);
}

/**
* Complains when activate PaymentMethod if is attached to other Wallet.
*/
@Test(expected = PaymentMethodsException.class)
public void complainsWhenActivatePaymentMethodIfAttachedToOtherWallet() {
final Storage storage = Mockito.mock(Storage.class);
final PaymentMethods all = Mockito.mock(PaymentMethods.class);
Mockito.when(storage.paymentMethods()).thenReturn(all);

final Wallet wallet = Mockito.mock(Wallet.class);
final PaymentMethod pmeth = Mockito.mock(PaymentMethod.class);
Mockito.when(pmeth.wallet()).thenReturn(Mockito.mock(Wallet.class));

final PaymentMethods pms = new WalletPaymentMethods(
wallet,
Stream::empty,
storage
);

pms.activate(pmeth);
}
}

0 comments on commit 9e7510e

Please sign in to comment.