-
Notifications
You must be signed in to change notification settings - Fork 0
Add get order status via MontonioClient facade #39
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
Open
rammrain
wants to merge
3
commits into
main
Choose a base branch
from
task-16
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,77 @@ | ||
| # Get Order Status — Design | ||
|
|
||
| **Issue:** #16 | ||
| **Date:** 2026-04-10 | ||
|
|
||
| ## Summary | ||
|
|
||
| Add a `GET /orders/{uuid}` operation exposed through a domain-scoped facade: | ||
| `MontonioClient(config).orders().get(uuid)` returning the existing `OrderResponse`. | ||
|
|
||
| ## Public API | ||
|
|
||
| ```java | ||
| MontonioClient client = new MontonioClient(configuration); | ||
| OrderResponse order = client.orders().get("order-uuid"); | ||
| ``` | ||
|
|
||
| ### Classes Introduced | ||
|
|
||
| | Class | Package | Role | | ||
| |-------|---------|------| | ||
| | `MontonioClient` | `ee.bitweb.montonio.sdk` | Top-level facade, owns `MontonioHttpClient`, lazy-creates domain services | | ||
| | `OrderService` | `ee.bitweb.montonio.sdk.order` | Validates input, delegates `GET /orders/{uuid}` to HTTP client | | ||
|
|
||
| No new models — reuses `OrderResponse`, `PaymentIntent`, `PaymentStatus`, and all supporting types from #14. | ||
|
|
||
| ### Dependency Flow | ||
|
|
||
| ```text | ||
| MontonioClient → MontonioHttpClient → HttpClient (java.net) | ||
| ↓ | ||
| OrderService (receives MontonioHttpClient) | ||
| ``` | ||
|
|
||
| ## MontonioClient | ||
|
|
||
| - Constructor takes `MontonioSdkConfiguration`, creates `MontonioHttpClient` internally. | ||
| - Package-private constructor overload accepts `MontonioHttpClient` for testing. | ||
| - `orders()` uses lazy-cached initialization: creates `OrderService` on first call, reuses it after. | ||
| - Not thread-safe on `orders()` — benign race at worst. Matches typical single-threaded SDK usage. | ||
|
|
||
| ## OrderService | ||
|
|
||
| - Package-private constructor receives `MontonioHttpClient` — users go through `MontonioClient`. | ||
| - `get(String uuid)` validates null/blank (throws `MontonioValidationException` with field `"uuid"`), then delegates to `httpClient.get("/orders/" + uuid, OrderResponse.class)`. | ||
| - No additional error handling — `MontonioHttpClient` already maps 4xx/5xx to `MontonioApiException` and network failures to `MontonioNetworkException`. | ||
|
|
||
| ## Testing | ||
|
|
||
| ### OrderServiceTest | ||
|
|
||
| Unit tests with stubbed HTTP client (same pattern as `MontonioHttpClientTest`): | ||
|
|
||
| | Test case | Setup | Assertion | | ||
| |-----------|-------|-----------| | ||
| | Successful retrieval | Stub 200, full JSON | All fields deserialized, including nested paymentIntents | | ||
| | Null UUID | `get(null)` | `MontonioValidationException` with field `"uuid"` | | ||
| | Blank UUID | `get(" ")` | `MontonioValidationException` with field `"uuid"` | | ||
| | Order not found | Stub 404 with error JSON | `MontonioApiException` with status 404 | | ||
| | Multiple payment intents | Stub 200, 2+ intents | List size and individual fields correct | | ||
| | Various payment statuses | Stub 200, PAID/PENDING/VOIDED | `PaymentStatus` enum deserialized correctly | | ||
|
|
||
| ### MontonioClientTest | ||
|
|
||
| | Test case | Assertion | | ||
| |-----------|-----------| | ||
| | `orders()` returns non-null | Basic wiring | | ||
| | `orders()` returns same instance | Lazy-caching works | | ||
| | Constructor rejects null config | Validation error | | ||
|
|
||
| ## Decisions | ||
|
|
||
| - **Domain-scoped facade** (`client.orders().get()`) over flat methods or standalone services — scales as more domains are added. | ||
| - **Lazy-cached domain services** — avoids allocating services never used, avoids re-allocating on every call. | ||
| - **Full `OrderResponse` return** — no slimmer DTO; callers pick fields they need. | ||
| - **Null/blank validation only** — no UUID format regex; let the API decide validity beyond that. | ||
| - **Package-private constructors** — testability without exposing internals to SDK consumers. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| package ee.bitweb.montonio.sdk; | ||
|
|
||
| import ee.bitweb.montonio.sdk.http.MontonioHttpClient; | ||
| import ee.bitweb.montonio.sdk.order.OrderService; | ||
|
|
||
| public class MontonioClient { | ||
|
|
||
| private final MontonioHttpClient httpClient; | ||
| private volatile OrderService orderService; | ||
|
|
||
| public MontonioClient(MontonioSdkConfiguration configuration) { | ||
| if (configuration == null) { | ||
| throw new NullPointerException("configuration must not be null"); | ||
| } | ||
| this.httpClient = new MontonioHttpClient(configuration); | ||
| } | ||
|
|
||
| MontonioClient(MontonioHttpClient httpClient) { | ||
| if (httpClient == null) { | ||
| throw new NullPointerException("httpClient must not be null"); | ||
| } | ||
| this.httpClient = httpClient; | ||
| } | ||
|
|
||
| public OrderService orders() { | ||
| OrderService local = orderService; | ||
| if (local == null) { | ||
| synchronized (this) { | ||
| local = orderService; | ||
| if (local == null) { | ||
| local = new OrderService(httpClient); | ||
| orderService = local; | ||
| } | ||
| } | ||
| } | ||
| return local; | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
src/main/java/ee/bitweb/montonio/sdk/order/OrderService.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| package ee.bitweb.montonio.sdk.order; | ||
|
|
||
| import ee.bitweb.montonio.sdk.exception.MontonioValidationException; | ||
| import ee.bitweb.montonio.sdk.http.MontonioHttpClient; | ||
| import ee.bitweb.montonio.sdk.order.response.OrderResponse; | ||
|
|
||
| public class OrderService { | ||
|
|
||
| private final MontonioHttpClient httpClient; | ||
|
|
||
| public OrderService(MontonioHttpClient httpClient) { | ||
| if (httpClient == null) { | ||
| throw new NullPointerException("httpClient must not be null"); | ||
| } | ||
| this.httpClient = httpClient; | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
|
|
||
| public OrderResponse get(String uuid) { | ||
| if (uuid == null) { | ||
| throw new MontonioValidationException("uuid", "must not be null or blank"); | ||
| } | ||
| String trimmedUuid = uuid.trim(); | ||
| if (trimmedUuid.isEmpty()) { | ||
| throw new MontonioValidationException("uuid", "must not be null or blank"); | ||
| } | ||
| return httpClient.get("/orders/" + trimmedUuid, OrderResponse.class); | ||
| } | ||
|
coderabbitai[bot] marked this conversation as resolved.
|
||
| } | ||
40 changes: 40 additions & 0 deletions
40
src/test/java/ee/bitweb/montonio/sdk/MontonioClientTest.java
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| package ee.bitweb.montonio.sdk; | ||
|
|
||
| import ee.bitweb.montonio.sdk.order.OrderService; | ||
| import org.junit.jupiter.api.Test; | ||
|
|
||
| import static org.junit.jupiter.api.Assertions.*; | ||
|
|
||
| class MontonioClientTest { | ||
|
|
||
| @Test | ||
| void constructorRejectsNullConfiguration() { | ||
| MontonioSdkConfiguration nullConfig = null; | ||
| assertThrows(NullPointerException.class, () -> new MontonioClient(nullConfig)); | ||
| } | ||
|
|
||
| @Test | ||
| void ordersReturnsNonNull() { | ||
| MontonioClient client = createClient(); | ||
|
|
||
| assertNotNull(client.orders()); | ||
| } | ||
|
|
||
| @Test | ||
| void ordersReturnsSameInstanceOnRepeatedCalls() { | ||
| MontonioClient client = createClient(); | ||
|
|
||
| OrderService first = client.orders(); | ||
| OrderService second = client.orders(); | ||
|
|
||
| assertSame(first, second); | ||
| } | ||
|
|
||
| private MontonioClient createClient() { | ||
| MontonioSdkConfiguration configuration = MontonioSdkConfiguration.builder() | ||
| .accessKey("test-access-key") | ||
| .secretKey("test-secret-key-that-is-long-enough") | ||
| .build(); | ||
| return new MontonioClient(configuration); | ||
| } | ||
| } |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.