Pārlūkot izejas kodu

support remove/re-add plan using same payment

tags/v0.1.6
Jonathan Cobb pirms 5 gadiem
vecāks
revīzija
ee13162d26
12 mainītis faili ar 191 papildinājumiem un 94 dzēšanām
  1. +5
    -4
      bubble-server/src/main/java/bubble/cloud/payment/PaymentDriverBase.java
  2. +23
    -0
      bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java
  3. +9
    -12
      bubble-server/src/main/java/bubble/dao/bill/AccountPlanPaymentDAO.java
  4. +13
    -14
      bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java
  5. +1
    -4
      bubble-server/src/main/java/bubble/model/bill/AccountPaymentMethod.java
  6. +8
    -2
      bubble-server/src/main/java/bubble/model/bill/AccountPlan.java
  7. +1
    -1
      bubble-server/src/main/java/bubble/model/bill/Bill.java
  8. +36
    -2
      bubble-server/src/main/java/bubble/resources/bill/AccountPaymentsResource.java
  9. +3
    -2
      bubble-server/src/main/java/bubble/resources/bill/AccountPlanPaymentsResource.java
  10. +37
    -29
      bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java
  11. +1
    -1
      bubble-server/src/main/resources/message_templates/server/en_US/post_auth/ResourceMessages.properties
  12. +54
    -23
      bubble-server/src/test/resources/models/tests/payment/pay_credit_multi_start_stop.json

+ 5
- 4
bubble-server/src/main/java/bubble/cloud/payment/PaymentDriverBase.java Parādīt failu

@@ -85,7 +85,7 @@ public abstract class PaymentDriverBase<T> extends CloudServiceDriverBase<T> imp

final AccountPlanPayment priorPayment = findPriorPayment(plan, paymentMethod, bill);
if (priorPayment != null) {
billDAO.update(bill.setStatus(BillStatus.paid));
billDAO.update(bill.setPrice(0L).setStatus(BillStatus.paid));
accountPlanPaymentDAO.create(new AccountPlanPayment()
.setAccount(accountPlan.getAccount())
.setPlan(accountPlan.getPlan())
@@ -129,14 +129,15 @@ public abstract class PaymentDriverBase<T> extends CloudServiceDriverBase<T> imp
// - it is for the current period
// - the corresponding AccountPlan has been deleted
// if so we can re-use that payment and do not need to charge anything now
final List<AccountPlanPayment> priorSimilarPayments = accountPlanPaymentDAO.findByAccountPaymentMethodAndPeriodAndPriceAndCurrency(
final List<AccountPlanPayment> priorSimilarPayments = accountPlanPaymentDAO.findByAccountPaymentMethodAndPeriodAndCurrency(
paymentMethod.getUuid(),
bill.getPeriod(),
plan.getPrice(),
plan.getCurrency());
for (AccountPlanPayment app : priorSimilarPayments) {
final AccountPlan ap = accountPlanDAO.findByUuid(app.getAccountPlan());
if (ap != null && ap.deleted()) return app;
if (ap != null && ap.deleted() && app.getAmount() >= plan.getPrice()) {
return app;
}
}
return null;
}


+ 23
- 0
bubble-server/src/main/java/bubble/dao/bill/AccountPlanDAO.java Parādīt failu

@@ -2,13 +2,18 @@ package bubble.dao.bill;

import bubble.cloud.payment.PaymentServiceDriver;
import bubble.dao.account.AccountOwnedEntityDAO;
import bubble.dao.cloud.BubbleNetworkDAO;
import bubble.dao.cloud.CloudServiceDAO;
import bubble.model.bill.*;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNetworkState;
import bubble.model.cloud.CloudService;
import bubble.server.BubbleConfiguration;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import java.util.List;

import static java.util.concurrent.TimeUnit.SECONDS;
import static org.cobbzilla.util.daemon.ZillaRuntime.background;
import static org.cobbzilla.util.system.Sleep.sleep;
@@ -21,12 +26,17 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO<AccountPlan> {
@Autowired private BubblePlanDAO planDAO;
@Autowired private BillDAO billDAO;
@Autowired private CloudServiceDAO cloudDAO;
@Autowired private BubbleNetworkDAO networkDAO;
@Autowired private BubbleConfiguration configuration;

public AccountPlan findByAccountAndNetwork(String accountUuid, String networkUuid) {
return findByUniqueFields("account", accountUuid, "network", networkUuid);
}

public List<AccountPlan> findByAccountAndNotDeleted(String account) {
return findByFields("account", account, "deleted", false);
}

@Override public Object preCreate(AccountPlan accountPlan) {
if (!accountPlan.hasPaymentMethod()) throw invalidEx("err.paymentMethod.required");

@@ -74,4 +84,17 @@ public class AccountPlanDAO extends AccountOwnedEntityDAO<AccountPlan> {
return super.postCreate(accountPlan, context);
}

@Override public void delete(String uuid) {
final AccountPlan accountPlan = findByUuid(uuid);
if (accountPlan == null) return;

final BubbleNetwork network = networkDAO.findByUuid(accountPlan.getNetwork());
if (network != null && network.getState() != BubbleNetworkState.stopped) {
throw invalidEx("err.accountPlan.stopNetworkBeforeDeleting");
}
update(accountPlan.setDeleted(true).setEnabled(false));
}

@Override public void forceDelete(String uuid) { super.delete(uuid); }

}

+ 9
- 12
bubble-server/src/main/java/bubble/dao/bill/AccountPlanPaymentDAO.java Parādīt failu

@@ -6,8 +6,6 @@ import org.springframework.stereotype.Repository;

import java.util.List;

import static org.hibernate.criterion.Restrictions.*;

@Repository
public class AccountPlanPaymentDAO extends AccountOwnedEntityDAO<AccountPlanPayment> {

@@ -17,16 +15,14 @@ public class AccountPlanPaymentDAO extends AccountOwnedEntityDAO<AccountPlanPaym
return findByUniqueFields("planPaymentMethod", planPaymentMethod, "bill", billUuid);
}

public List<AccountPlanPayment> findByAccountPaymentMethodAndPeriodAndPriceAndCurrency(String paymentMethodUuid,
String billPeriod,
Long price,
String currency) {
return list(criteria().add(and(
eq("paymentMethod", paymentMethodUuid),
eq("period", billPeriod),
eq("currency", currency),
ge("amount", price)
)));
public List<AccountPlanPayment> findByAccountPayment(String accountPayment) {
return findByField("payment", accountPayment);
}

public List<AccountPlanPayment> findByAccountPaymentMethodAndPeriodAndCurrency(String paymentMethodUuid,
String billPeriod,
String currency) {
return findByFields("paymentMethod", paymentMethodUuid, "period", billPeriod, "currency", currency);
}

public List<AccountPlanPayment> findByAccountAndBill(String accountUuid, String billUuid) {
@@ -40,4 +36,5 @@ public class AccountPlanPaymentDAO extends AccountOwnedEntityDAO<AccountPlanPaym
public List<AccountPlanPayment> findByAccountAndAccountPlanAndBill(String accountUuid, String accountPlanUuid, String billUuid) {
return findByFields("account", accountUuid, "accountPlan", accountPlanUuid, "bill", billUuid);
}

}

+ 13
- 14
bubble-server/src/main/java/bubble/dao/cloud/BubbleNetworkDAO.java Parādīt failu

@@ -3,7 +3,10 @@ package bubble.dao.cloud;
import bubble.dao.account.AccountOwnedEntityDAO;
import bubble.dao.bill.AccountPlanDAO;
import bubble.model.bill.AccountPlan;
import bubble.model.cloud.*;
import bubble.model.cloud.BubbleDomain;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.BubbleNode;
import bubble.model.cloud.CloudService;
import bubble.server.BubbleConfiguration;
import bubble.service.boot.SelfNodeService;
import bubble.service.cloud.NetworkService;
@@ -16,8 +19,6 @@ import java.io.IOException;
import java.util.List;
import java.util.stream.Collectors;

import static org.cobbzilla.wizard.resources.ResourceUtil.invalidEx;

@Repository @Slf4j
public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {

@@ -64,12 +65,11 @@ public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {

public void delete(String uuid, boolean force) {
final BubbleNetwork network = findByUuid(uuid);
if (network.getState() != BubbleNetworkState.stopped) {
if (force) {
networkService.stopNetwork(network);
} else {
throw invalidEx("err.network.cannotDelete", "stop network before deleting");
}
if (network == null) return;
try {
networkService.stopNetwork(network);
} catch (Exception e) {
log.warn("delete("+uuid+"): error stopping network: "+e);
}
try {
if (force) {
@@ -104,11 +104,10 @@ public class BubbleNetworkDAO extends AccountOwnedEntityDAO<BubbleNetwork> {
if (accountPlan == null) {
log.warn("delete("+uuid+"): AccountPlan not found");
} else {
if (force) {
accountPlanDAO.delete(accountPlan.getUuid());
} else {
accountPlanDAO.update(accountPlan.setNetwork(null).setDeletedNetwork(network.getUuid()));
}
accountPlanDAO.update(accountPlan
.setEnabled(false)
.setNetwork(null)
.setDeletedNetwork(network.getUuid()));
}

if (force) {


+ 1
- 4
bubble-server/src/main/java/bubble/model/bill/AccountPaymentMethod.java Parādīt failu

@@ -23,10 +23,7 @@ import org.cobbzilla.wizard.model.entityconfig.annotations.ECType;
import org.cobbzilla.wizard.validation.ValidationResult;
import org.hibernate.annotations.Type;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.*;

import static org.cobbzilla.util.daemon.ZillaRuntime.empty;
import static org.cobbzilla.util.reflect.ReflectionUtil.copy;


+ 8
- 2
bubble-server/src/main/java/bubble/model/bill/AccountPlan.java Parādīt failu

@@ -31,7 +31,8 @@ import static org.cobbzilla.util.reflect.ReflectionUtil.copy;
public class AccountPlan extends IdentifiableBase implements HasAccount {

public static final String[] CREATE_FIELDS = {
"name", "description", "locale", "timezone", "domain", "network", "plan", "footprint", "paymentMethod"
"name", "description", "locale", "timezone", "domain", "network", "plan", "footprint",
"paymentMethod", "savedPaymentMethod"
};

@SuppressWarnings("unused")
@@ -62,9 +63,14 @@ public class AccountPlan extends IdentifiableBase implements HasAccount {
@Getter @Setter private Boolean enabled = false;
public boolean enabled() { return enabled != null && enabled; }

@Column(nullable=false)
@Getter @Setter private Boolean deleted = false;
public boolean deleted() { return deleted != null && deleted; }
public boolean notDeleted() { return !deleted(); }

@ECIndex(unique=true) @Column(length=UUID_MAXLEN)
@Getter @Setter private String deletedNetwork;
public boolean deleted() { return deletedNetwork != null; }
public boolean hasDeletedNetwork() { return deletedNetwork != null; }

// Fields below are used when creating a new plan, to also create the network associated with it
@Size(max=10000, message="err.description.length")


+ 1
- 1
bubble-server/src/main/java/bubble/model/bill/Bill.java Parādīt failu

@@ -50,7 +50,7 @@ public class Bill extends IdentifiableBase implements HasAccountNoName {
@Type(type=ENCRYPTED_LONG) @Column(updatable=false, columnDefinition="varchar("+(ENC_LONG)+") NOT NULL")
@Getter @Setter private Long quantity = 0L;

@Type(type=ENCRYPTED_LONG) @Column(updatable=false, columnDefinition="varchar("+(ENC_LONG)+") NOT NULL")
@Type(type=ENCRYPTED_LONG) @Column(columnDefinition="varchar("+(ENC_LONG)+") NOT NULL")
@Getter @Setter private Long price = 0L;

@ECIndex @Column(nullable=false, updatable=false, length=10)


+ 36
- 2
bubble-server/src/main/java/bubble/resources/bill/AccountPaymentsResource.java Parādīt failu

@@ -1,21 +1,55 @@
package bubble.resources.bill;

import bubble.dao.bill.AccountPaymentDAO;
import bubble.dao.bill.AccountPlanPaymentDAO;
import bubble.dao.bill.BillDAO;
import bubble.model.account.Account;
import bubble.model.bill.AccountPayment;
import bubble.model.bill.AccountPlanPayment;
import bubble.model.bill.Bill;
import bubble.resources.account.ReadOnlyAccountOwnedResource;
import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.Consumes;
import javax.ws.rs.Produces;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.Response;
import java.util.ArrayList;
import java.util.List;

import static bubble.ApiConstants.EP_BILLS;
import static org.cobbzilla.util.http.HttpContentTypes.APPLICATION_JSON;
import static org.cobbzilla.wizard.resources.ResourceUtil.notFound;
import static org.cobbzilla.wizard.resources.ResourceUtil.ok;

@Consumes(APPLICATION_JSON)
@Produces(APPLICATION_JSON)
@Slf4j
public class AccountPaymentsResource extends ReadOnlyAccountOwnedResource<AccountPayment, AccountPaymentDAO> {

@Autowired private AccountPlanPaymentDAO planPaymentDAO;
@Autowired private BillDAO billDAO;

public AccountPaymentsResource(Account account) { super(account); }

@GET @Path("/{id}"+EP_BILLS)
public Response getBills(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPayment accountPayment = super.find(ctx, id);
if (accountPayment == null) return notFound(id);

final List<AccountPlanPayment> planPayments = planPaymentDAO.findByAccountPayment(accountPayment.getUuid());
final List<Bill> bills = new ArrayList<>();
for (AccountPlanPayment app : planPayments) {
final Bill bill = billDAO.findByUuid(app.getBill());
if (bill == null) {
log.warn("getBills: bill "+app.getBill()+" not found for AccountPlanPayment="+app.getUuid());
continue;
}
bills.add(bill);
}
return ok(bills);
}

}

+ 3
- 2
bubble-server/src/main/java/bubble/resources/bill/AccountPlanPaymentsResource.java Parādīt failu

@@ -14,6 +14,7 @@ import lombok.extern.slf4j.Slf4j;
import org.glassfish.jersey.server.ContainerRequest;
import org.springframework.beans.factory.annotation.Autowired;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.core.Context;
@@ -75,7 +76,7 @@ public class AccountPlanPaymentsResource extends ReadOnlyAccountOwnedResource<Ac
return planPayment;
}

@Path("/{id}"+EP_PAYMENT)
@GET @Path("/{id}"+EP_PAYMENT)
public Response getPayment(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlanPayment planPayment = super.find(ctx, id);
@@ -84,7 +85,7 @@ public class AccountPlanPaymentsResource extends ReadOnlyAccountOwnedResource<Ac
return payment == null ? notFound(id) : ok(payment);
}

@Path("/{id}"+EP_BILL)
@GET @Path("/{id}"+EP_BILL)
public Response getBill(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlanPayment planPayment = super.find(ctx, id);


+ 37
- 29
bubble-server/src/main/java/bubble/resources/bill/AccountPlansResource.java Parādīt failu

@@ -15,10 +15,7 @@ import bubble.model.bill.AccountPaymentMethod;
import bubble.model.bill.AccountPlan;
import bubble.model.bill.AccountPlanPaymentMethod;
import bubble.model.bill.BubblePlan;
import bubble.model.cloud.BubbleDomain;
import bubble.model.cloud.BubbleFootprint;
import bubble.model.cloud.BubbleNetwork;
import bubble.model.cloud.CloudService;
import bubble.model.cloud.*;
import bubble.resources.account.AccountOwnedResource;
import bubble.server.BubbleConfiguration;
import lombok.extern.slf4j.Slf4j;
@@ -53,33 +50,13 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco

public AccountPlansResource(Account account) { super(account); }

@Path("/{id}"+EP_BILLS)
public BillsResource getBills(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlan plan = find(ctx, id);
if (plan == null) throw notFoundEx(id);
return configuration.subResource(BillsResource.class, account, plan);
@Override protected AccountPlan find(ContainerRequest ctx, String id) {
final AccountPlan accountPlan = super.find(ctx, id);
return accountPlan == null || accountPlan.deleted() ? null : accountPlan;
}

@Path("/{id}"+EP_PAYMENTS)
public AccountPlanPaymentsResource getPayments(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlan plan = find(ctx, id);
if (plan == null) throw notFoundEx(id);
return configuration.subResource(AccountPlanPaymentsResource.class, account, plan);
}

@GET @Path("/{id}"+EP_PAYMENT_METHOD)
public Response getPaymentMethod(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlan plan = find(ctx, id);
if (plan == null) return notFound(id);

final AccountPlanPaymentMethod planPaymentMethod = accountPlanPaymentMethodDAO.findCurrentMethodForPlan(plan.getUuid());
if (planPaymentMethod == null) return notFound();

final AccountPaymentMethod paymentMethod = accountPaymentMethodDAO.findByUuid(planPaymentMethod.getPaymentMethod());
return paymentMethod == null ? notFound() : ok(paymentMethod);
@Override protected List<AccountPlan> list(ContainerRequest ctx) {
return getDao().findByAccountAndNotDeleted(account.getUuid());
}

@Override protected boolean canCreate(Request req, ContainerRequest ctx, Account caller, AccountPlan request) {
@@ -166,6 +143,8 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco
final AccountPaymentMethod paymentMethodToCreate = new AccountPaymentMethod(request.getPaymentMethod()).setAccount(request.getAccount());
final AccountPaymentMethod paymentMethodCreated = accountPaymentMethodDAO.create(paymentMethodToCreate);
request.setPaymentMethod(paymentMethodCreated);
} else {
request.setPaymentMethod(paymentMethod);
}
return request;
}
@@ -191,4 +170,33 @@ public class AccountPlansResource extends AccountOwnedResource<AccountPlan, Acco
}
}

@Path("/{id}"+EP_BILLS)
public BillsResource getBills(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlan plan = find(ctx, id);
if (plan == null) throw notFoundEx(id);
return configuration.subResource(BillsResource.class, account, plan);
}

@Path("/{id}"+EP_PAYMENTS)
public AccountPlanPaymentsResource getPayments(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlan plan = find(ctx, id);
if (plan == null) throw notFoundEx(id);
return configuration.subResource(AccountPlanPaymentsResource.class, account, plan);
}

@GET @Path("/{id}"+EP_PAYMENT_METHOD)
public Response getPaymentMethod(@Context ContainerRequest ctx,
@PathParam("id") String id) {
final AccountPlan plan = find(ctx, id);
if (plan == null) return notFound(id);

final AccountPlanPaymentMethod planPaymentMethod = accountPlanPaymentMethodDAO.findCurrentMethodForPlan(plan.getUuid());
if (planPaymentMethod == null) return notFound();

final AccountPaymentMethod paymentMethod = accountPaymentMethodDAO.findByUuid(planPaymentMethod.getPaymentMethod());
return paymentMethod == null ? notFound() : ok(paymentMethod);
}

}

+ 1
- 1
bubble-server/src/main/resources/message_templates/server/en_US/post_auth/ResourceMessages.properties Parādīt failu

@@ -73,6 +73,7 @@ err.accountContactsJson.length=Account contacts length violation
err.accountPlan.callerCountryDisallowed=Your country is not currently supported by our platform
err.accountPlan.disabled=Account plan is not enabled
err.accountPlan.notFound=Account plan not found
err.accountPlan.stopNetworkBeforeDeleting=You must stop the bubble first, the delete the plan
err.admin.cannotRemoveAdminStatusFromSelf=You cannot remove admin status from your own account
err.allowedCountriesJson.length=Allowed countries list is too long
err.approval.invalid=Approval cannot proceed
@@ -145,7 +146,6 @@ err.name.mismatch=Name mismatch
err.name.reserved=Name is reserved
err.netlocation.invalid=Must specify both cloud and region, or neither
err.network.alreadyStarted=Network is already started
err.network.cannotDelete=CAnnot delete network: stop network before deleting
err.network.exists=A plan already exists for this network
err.networkKeys.noVerifiedContacts=No verified contacts exist
err.networkName.required=Network name is required


+ 54
- 23
bubble-server/src/test/resources/models/tests/payment/pay_credit_multi_start_stop.json Parādīt failu

@@ -98,6 +98,7 @@
},

{
"before": "sleep 15s",
"comment": "verify account payment methods, should be one",
"request": { "uri": "me/paymentMethods" },
"response": {
@@ -114,7 +115,8 @@
"response": {
"check": [
{"condition": "json.length === 1"},
{"condition": "json[0].getName() === accountPlan.getName()"}
{"condition": "json[0].getName() === accountPlan.getName()"},
{"condition": "json[0].enabled()"}
]
}
},
@@ -123,7 +125,7 @@
"comment": "verify account plan payment info",
"request": { "uri": "me/plans/{{accountPlan.uuid}}/paymentMethod" },
"response": {
"store": "savedPaymentMethods",
"store": "savedPaymentMethod",
"check": [
{"condition": "json.getPaymentMethodType().name() === 'credit'"},
{"condition": "json.getMaskedPaymentInfo() === 'XXXX-XXXX-XXXX-4242'"}
@@ -138,7 +140,7 @@
"store": "bills",
"check": [
{"condition": "json.length === 1"},
{"condition": "json[0].getPlan() === '{{accountPlan.uuid}}'"},
{"condition": "json[0].getAccountPlan() === '{{accountPlan.uuid}}'"},
{"condition": "json[0].getQuantity() === 1"},
{"condition": "json[0].getPrice() === {{plans.[0].price}}"},
{"condition": "json[0].getTotal() === {{plans.[0].price}}"},
@@ -154,8 +156,8 @@
"store": "payments",
"check": [
{"condition": "json.length === 1"},
{"condition": "json[0].getPlan() === '{{accountPlan.uuid}}'"},
{"condition": "json[0].getAmount() === '{{plans.[0].price}}'"},
{"condition": "json[0].getAccountPlan() === '{{accountPlan.uuid}}'"},
{"condition": "json[0].getAmount() === {{plans.[0].price}}"},
{"condition": "json[0].getStatus().name() === 'success'"}
]
}
@@ -172,6 +174,26 @@
}
},

{
"comment": "try to delete plan, must stop network first",
"request": {
"method": "delete",
"uri": "me/plans/{{accountPlan.uuid}}"
},
"response": {
"status": 422,
"check": [{"condition": "json.has('err.accountPlan.stopNetworkBeforeDeleting')"}]
}
},

{
"comment": "delete network",
"request": {
"method": "delete",
"uri": "me/networks/{{accountPlan.network}}"
}
},

{
"comment": "delete plan",
"request": {
@@ -201,8 +223,7 @@
"plan": "{{plans.[0].name}}",
"footprint": "US",
"paymentMethod": {
"paymentMethodType": "credit",
"uuid": "{{savedPaymentMethods.[0].uuid}}"
"uuid": "{{savedPaymentMethod.uuid}}"
}
}
},
@@ -212,6 +233,7 @@
},

{
"before": "sleep 15s",
"comment": "verify we still have only one payment method",
"request": { "uri": "me/paymentMethods" },
"response": {
@@ -221,12 +243,12 @@

{
"comment": "verify account plan payment info is same as used before",
"request": { "uri": "me/plans/{{accountPlan.uuid}}/paymentMethod" },
"request": { "uri": "me/plans/{{accountPlan2.uuid}}/paymentMethod" },
"response": {
"check": [
{"condition": "json.getPaymentMethodType().name() === 'credit'"},
{"condition": "json.getMaskedPaymentInfo() === 'XXXX-XXXX-XXXX-4242'"},
{"condition": "json.getUuid() === '{{savedPaymentMethods.[0].uuid}}'"}
{"condition": "json.getUuid() === '{{savedPaymentMethod.uuid}}'"}
]
}
},
@@ -248,7 +270,8 @@
"store": "plan2bills",
"check": [
{"condition": "json.length === 1"},
{"condition": "json[0].getPlan() === '{{accountPlan2.uuid}}'"},
{"condition": "json[0].getPlan() === '{{plans.[0].uuid}}'"},
{"condition": "json[0].getAccountPlan() === '{{accountPlan2.uuid}}'"},
{"condition": "json[0].getQuantity() === 1"},
{"condition": "json[0].getPrice() === 0"},
{"condition": "json[0].getTotal() === 0"}
@@ -257,40 +280,48 @@
},

{
"comment": "verify we have made two successful payments (but one of them will be zero)",
"comment": "verify we have still only made one successful payment",
"request": { "uri": "me/payments" },
"response": {
"check": [
{"condition": "json.length === 2"},
{"condition": "json.length === 1"},
{"condition": "json[0].getStatus().name() === 'success'"},
{"condition": "json[1].getStatus().name() === 'success'"},
{"condition": "_find(json, function (p) { if (p.getAmount() === {{plans.[0].price}}) return p; }) != null"},
{"condition": "_find(json, function (p) { if (p.getAmount() === 0) return p; }) != null"}
{"condition": "json[0].getAmount() === {{plans.[0].price}}"}
]
}
},

{
"comment": "find payments made on second plan",
"comment": "verify payment exists via plan and is successful, and price was zero",
"request": { "uri": "me/plans/{{accountPlan2.uuid}}/payments" },
"response": {
"store": "plan2payments",
"check": [
{"condition": "json.length === 1"}
{"condition": "json.length === 1"},
{"condition": "json[0].getPlan() === '{{plans.[0].uuid}}'"},
{"condition": "json[0].getAccountPlan() === '{{accountPlan2.uuid}}'"},
{"condition": "json[0].getPaymentObject().getAmount() === {{plans.[0].price}}"},
{"condition": "json[0].getPaymentObject().getStatus().name() === 'success'"},
{"condition": "json[0].getBillObject().getPlan() === '{{plans.[0].uuid}}'"},
{"condition": "json[0].getBillObject().getAccountPlan() === '{{accountPlan2.uuid}}'"},
{"condition": "json[0].getBillObject().getQuantity() === 1"},
{"condition": "json[0].getBillObject().getPrice() === 0"},
{"condition": "json[0].getBillObject().getTotal() === 0"},
{"condition": "json[0].getBillObject().getStatus().name() === 'paid'"}
]
}
},

{
"comment": "verify successful payment has paid for the second bill (with zero total)",
"request": { "uri": "me/plans/{{accountPlan2.uuid}}/payments/{{plan2payments.[0].uuid}}/bills" },
"request": { "uri": "me/plans/{{accountPlan2.uuid}}/payments/{{plan2payments.[0].uuid}}/bill" },
"response": {
"check": [
{"condition": "json.length === 1"},
{"condition": "json[0].getPlan() === '{{accountPlan2.uuid}}'"},
{"condition": "json[0].getQuantity() === 1"},
{"condition": "json[0].getPrice() === 0"},
{"condition": "json[0].getTotal() === 0"}
{"condition": "json.getPlan() === '{{plans.[0].uuid}}'"},
{"condition": "json.getAccountPlan() === '{{accountPlan2.uuid}}'"},
{"condition": "json.getQuantity() === 1"},
{"condition": "json.getPrice() === 0"},
{"condition": "json.getTotal() === 0"}
]
}
}


Notiek ielāde…
Atcelt
Saglabāt