Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DE-606] Components currency prices fixes and tests #168

Merged
merged 9 commits into from
Nov 19, 2024
10 changes: 6 additions & 4 deletions doc/controllers/component-price-points.md
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,8 @@ Use this endpoint to retrieve details for a specific component price point. You
```java
ComponentPricePointResponse readComponentPricePoint(
final ReadComponentPricePointComponentId componentId,
final ReadComponentPricePointPricePointId pricePointId)
final ReadComponentPricePointPricePointId pricePointId,
final Boolean currencyPrices)
```

## Parameters
Expand All @@ -517,6 +518,7 @@ ComponentPricePointResponse readComponentPricePoint(
| --- | --- | --- | --- |
| `componentId` | [`ReadComponentPricePointComponentId`](../../doc/models/containers/read-component-price-point-component-id.md) | Template, Required | This is a container for one-of cases. |
| `pricePointId` | [`ReadComponentPricePointPricePointId`](../../doc/models/containers/read-component-price-point-price-point-id.md) | Template, Required | This is a container for one-of cases. |
| `currencyPrices` | `Boolean` | Query, Optional | Include an array of currency price data |

## Response Type

Expand All @@ -533,7 +535,7 @@ ReadComponentPricePointPricePointId pricePointId = ReadComponentPricePointPriceP
);

try {
ComponentPricePointResponse result = componentPricePointsController.readComponentPricePoint(componentId, pricePointId);
ComponentPricePointResponse result = componentPricePointsController.readComponentPricePoint(componentId, pricePointId, null);
System.out.println(result);
} catch (ApiException e) {
e.printStackTrace();
Expand Down Expand Up @@ -807,12 +809,12 @@ UpdateCurrencyPricesRequest body = new UpdateCurrencyPricesRequest.Builder(
Arrays.asList(
new UpdateCurrencyPrice.Builder(
100,
51
51D
)
.build(),
new UpdateCurrencyPrice.Builder(
101,
41
41D
)
.build()
)
Expand Down
4 changes: 2 additions & 2 deletions doc/controllers/product-price-points.md
Original file line number Diff line number Diff line change
Expand Up @@ -802,12 +802,12 @@ UpdateCurrencyPricesRequest body = new UpdateCurrencyPricesRequest.Builder(
Arrays.asList(
new UpdateCurrencyPrice.Builder(
200,
15
15D
)
.build(),
new UpdateCurrencyPrice.Builder(
201,
5
5D
)
.build()
)
Expand Down
4 changes: 2 additions & 2 deletions doc/models/update-currency-price.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@
| Name | Type | Tags | Description | Getter | Setter |
| --- | --- | --- | --- | --- | --- |
| `Id` | `int` | Required | ID of the currency price record being updated | int getId() | setId(int id) |
| `Price` | `int` | Required | New price for the given currency | int getPrice() | setPrice(int price) |
| `Price` | `double` | Required | New price for the given currency | double getPrice() | setPrice(double price) |

## Example (as JSON)

```json
{
"id": 146,
"price": 18
"price": 71.86
}
```

2 changes: 1 addition & 1 deletion doc/models/update-currency-prices-request.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"currency_prices": [
{
"id": 50,
"price": 78
"price": 233.74
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -309,27 +309,33 @@ private ApiCall<ComponentPricePointResponse, ApiException> prepareUpdateComponen
* @param pricePointId Required parameter: The id or handle of the price point. When using the
* handle, it must be prefixed with `handle:`. Example: `123` for an integer ID, or
* `handle:example-price_point-handle` for a string handle.
* @param currencyPrices Optional parameter: Include an array of currency price data
* @return Returns the ComponentPricePointResponse response from the API call
* @throws ApiException Represents error response from the server.
* @throws IOException Signals that an I/O exception of some sort has occurred.
*/
public ComponentPricePointResponse readComponentPricePoint(
final ReadComponentPricePointComponentId componentId,
final ReadComponentPricePointPricePointId pricePointId) throws ApiException, IOException {
return prepareReadComponentPricePointRequest(componentId, pricePointId).execute();
final ReadComponentPricePointPricePointId pricePointId,
final Boolean currencyPrices) throws ApiException, IOException {
return prepareReadComponentPricePointRequest(componentId, pricePointId,
currencyPrices).execute();
}

/**
* Builds the ApiCall object for readComponentPricePoint.
*/
private ApiCall<ComponentPricePointResponse, ApiException> prepareReadComponentPricePointRequest(
final ReadComponentPricePointComponentId componentId,
final ReadComponentPricePointPricePointId pricePointId) throws IOException {
final ReadComponentPricePointPricePointId pricePointId,
final Boolean currencyPrices) throws IOException {
return new ApiCall.Builder<ComponentPricePointResponse, ApiException>()
.globalConfig(getGlobalConfiguration())
.requestBuilder(requestBuilder -> requestBuilder
.server(Server.ENUM_DEFAULT.value())
.path("/components/{component_id}/price_points/{price_point_id}.json")
.queryParam(param -> param.key("currency_prices")
.value(currencyPrices).isRequired(false))
.templateParam(param -> param.key("component_id").value(componentId)
.shouldEncode(true))
.templateParam(param -> param.key("price_point_id").value(pricePointId)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
public class UpdateCurrencyPrice
extends BaseModel {
private int id;
private int price;
private double price;

/**
* Default constructor.
Expand All @@ -27,11 +27,11 @@ public UpdateCurrencyPrice() {
/**
* Initialization constructor.
* @param id int value for id.
* @param price int value for price.
* @param price double value for price.
*/
public UpdateCurrencyPrice(
int id,
int price) {
double price) {
this.id = id;
this.price = price;
}
Expand Down Expand Up @@ -59,20 +59,20 @@ public void setId(int id) {
/**
* Getter for Price.
* New price for the given currency
* @return Returns the int
* @return Returns the double
*/
@JsonGetter("price")
public int getPrice() {
public double getPrice() {
return price;
}

/**
* Setter for Price.
* New price for the given currency
* @param price Value for int
* @param price Value for double
*/
@JsonSetter("price")
public void setPrice(int price) {
public void setPrice(double price) {
this.price = price;
}

Expand Down Expand Up @@ -101,7 +101,7 @@ public Builder toBuilder() {
*/
public static class Builder {
private int id;
private int price;
private double price;

/**
* Initialization constructor.
Expand All @@ -112,9 +112,9 @@ public Builder() {
/**
* Initialization constructor.
* @param id int value for id.
* @param price int value for price.
* @param price double value for price.
*/
public Builder(int id, int price) {
public Builder(int id, double price) {
this.id = id;
this.price = price;
}
Expand All @@ -131,10 +131,10 @@ public Builder id(int id) {

/**
* Setter for price.
* @param price int value for price.
* @param price double value for price.
* @return Builder
*/
public Builder price(int price) {
public Builder price(double price) {
this.price = price;
return this;
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,155 @@
package com.maxio.advancedbilling.controllers.components;

import com.maxio.advancedbilling.TestClient;
import com.maxio.advancedbilling.exceptions.ApiException;
import com.maxio.advancedbilling.exceptions.ErrorArrayMapResponseException;
import com.maxio.advancedbilling.models.Component;
import com.maxio.advancedbilling.models.ComponentCurrencyPrice;
import com.maxio.advancedbilling.models.ComponentPricePoint;
import com.maxio.advancedbilling.models.CreateCurrencyPrice;
import com.maxio.advancedbilling.models.CreateCurrencyPricesRequest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;

import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

import static com.maxio.advancedbilling.utils.assertions.CommonAssertions.assertNotFound;
import static com.maxio.advancedbilling.utils.assertions.CommonAssertions.assertUnauthorized;
import static com.maxio.advancedbilling.utils.assertions.CommonAssertions.assertUnprocessableEntity;
import static org.assertj.core.api.Assertions.assertThat;

public class ComponentsControllerCreateCurrencyPricesTest extends ComponentsControllerTestBase {

private static Component component;

@BeforeAll
static void setupComponent() throws IOException, ApiException {
component = createQuantityBasedComponent();
}

@Test
void shouldCreateComponentPricePointCurrencyPrices() throws IOException, ApiException {
// given
Component component = createQuantityBasedComponent();
ComponentPricePoint componentPricePoint = TEST_SETUP.createComponentPricePoint(component.getId());
int price1Id = componentPricePoint.getPrices().get(0).getId();
int price2Id = componentPricePoint.getPrices().get(1).getId();

CreateCurrencyPricesRequest createCurrencyPricesRequest = new CreateCurrencyPricesRequest(
List.of(
new CreateCurrencyPrice.Builder()
.currency("EUR")
.price(10.2)
.priceId(price1Id)
.build(),
new CreateCurrencyPrice.Builder()
.currency("EUR")
.price(11.0)
.priceId(price2Id)
.build()
)
);

// when
List<ComponentCurrencyPrice> response = COMPONENTS__PRICE_POINT_CONTROLLER
.createCurrencyPrices(componentPricePoint.getId(), createCurrencyPricesRequest)
.getCurrencyPrices();

// then
assertThat(response.size()).isEqualTo(2);

assertThat(response.get(0).getId()).isNotNull();
assertThat(response.get(0).getCurrency()).isEqualTo("EUR");
assertThat(response.get(0).getPriceId()).isEqualTo(price1Id);
assertThat(response.get(0).getPrice()).isEqualTo("10.2");
assertThat(response.get(0).getFormattedPrice()).isEqualTo("€10,20");
assertThat(response.get(0).getPricePointId()).isEqualTo(componentPricePoint.getId());

assertThat(response.get(1).getId()).isNotNull();
assertThat(response.get(1).getCurrency()).isEqualTo("EUR");
assertThat(response.get(1).getPriceId()).isEqualTo(price2Id);
assertThat(response.get(1).getPrice()).isEqualTo("11.0");
assertThat(response.get(1).getFormattedPrice()).isEqualTo("€11,00");
assertThat(response.get(1).getPricePointId()).isEqualTo(componentPricePoint.getId());
}

@ParameterizedTest
@MethodSource("argsForShouldReturn422WhenCreatingCurrencyPricesWithInvalidData")
void shouldReturn422WhenCreatingCurrencyPricesWithInvalidData(CreateCurrencyPricesRequest request,
Map<String, List<String>> expectedErrors) {
// when - then
assertUnprocessableEntity(
ErrorArrayMapResponseException.class,
() -> COMPONENTS__PRICE_POINT_CONTROLLER.createCurrencyPrices(
component.getDefaultPricePointId(),
request
),
e -> assertThat(e.getErrors()).containsExactlyInAnyOrderEntriesOf(expectedErrors)
);
}

private static Stream<Arguments> argsForShouldReturn422WhenCreatingCurrencyPricesWithInvalidData() {
int priceId = component.getPrices().get(0).getId();
return Stream.of(
Arguments.of(
new CreateCurrencyPricesRequest(
List.of(
new CreateCurrencyPrice.Builder()
.currency("abc")
.price(10.2)
.priceId(priceId)
.build())),
Map.of(
"currency_prices[0].currency", List.of("Currency: is not one of the allowed values.",
"Currency must be defined on the site level."))
),
Arguments.of(
new CreateCurrencyPricesRequest(
List.of(
new CreateCurrencyPrice.Builder()
.currency("USD")
.price(-10d)
.priceId(priceId)
.build()
)),
Map.of(
"currency_prices[0].price", List.of("Unit price: must be greater than or equal to $0.00."),
"currency_prices[0].currency", List.of("Pricing already exists for this currency."))
),
Arguments.of(
new CreateCurrencyPricesRequest(
List.of(
new CreateCurrencyPrice.Builder()
.currency("USD")
.price(10d)
.priceId(0)
.build()
)),
Map.of("base", List.of("Missing definition for prices with ids: [%s].".formatted(priceId)))
)
);
}

@Test
void shouldNotCreateCurrencyPriceForNonExistentPricePoint() {
assertNotFound(() -> COMPONENTS__PRICE_POINT_CONTROLLER.createCurrencyPrices(
99999,
new CreateCurrencyPricesRequest(List.of())
));
}

@Test
void shouldNotCreateCurrencyPricesWhenProvidingInvalidCredentials() {
assertUnauthorized(() -> TestClient.createInvalidCredentialsClient()
.getComponentPricePointsController().createCurrencyPrices(productFamilyId,
new CreateCurrencyPricesRequest(List.of()))
);
}

}
Loading
Loading