Skip to content

Commit

Permalink
Merge code changes for EDGEDCB-34 (#40)
Browse files Browse the repository at this point in the history
* Merge code changes for EDGEDCB-34

* Merge code changes for EDGEDCB-34

---------

Co-authored-by: Antony Hruschev <[email protected]>
  • Loading branch information
gurleenkaurbp and AntonAntonich authored Jan 27, 2025
1 parent 2fac2fd commit 6371f7a
Show file tree
Hide file tree
Showing 9 changed files with 142 additions and 3 deletions.
3 changes: 3 additions & 0 deletions src/main/java/org/folio/ed/client/DcbClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,7 @@ TransactionStatusResponse createCirculationRequest(@PathVariable("dcbTransaction
@PutMapping(value = "/{dcbTransactionId}/status")
TransactionStatusResponse updateTransactionStatus(@PathVariable("dcbTransactionId") String dcbTransactionId,
@RequestBody TransactionStatus transactionStatus);

@PutMapping(value = "/{dcbTransactionId}")
void updateTransactionDetails(@PathVariable("dcbTransactionId") String dcbTransactionId, @RequestBody org.folio.ed.domain.dto.DcbUpdateTransaction dcbUpdateTransaction);
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,4 +36,10 @@ public ResponseEntity<TransactionStatusResponse> updateDCBTransactionStatus(Stri
return ResponseEntity.status(HttpStatus.OK)
.body(dcbTransactionService.updateDCBTransactionStatus(dcbTransactionId, transactionStatus));
}

@Override
public ResponseEntity<Void> updateTransactionDetails(String dcbTransactionId, org.folio.ed.domain.dto.DcbUpdateTransaction dcbUpdateTransaction) {
dcbTransactionService.updateTransactionDetails(dcbTransactionId, dcbUpdateTransaction);
return ResponseEntity.status(HttpStatus.NO_CONTENT).build();
}
}
6 changes: 6 additions & 0 deletions src/main/java/org/folio/ed/service/DcbTransactionService.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,10 @@ public TransactionStatusResponse updateDCBTransactionStatus(String dcbTransactio
log.info("updateDCBTransactionStatus:: Updating status transaction for id: {} to {}", dcbTransactionId, transactionStatus.getStatus());
return dcbClient.updateTransactionStatus(dcbTransactionId, transactionStatus);
}

public void updateTransactionDetails(String dcbTransactionId, org.folio.ed.domain.dto.DcbUpdateTransaction dcbUpdateTransaction) {
log.info("updateTransactionDetails:: Updating transaction item details for id: {} to {}", dcbTransactionId, dcbUpdateTransaction.getItem());
dcbClient.updateTransactionDetails(dcbTransactionId, dcbUpdateTransaction);
}

}
23 changes: 23 additions & 0 deletions src/main/resources/swagger.api/edge-dcb.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,22 @@ paths:
$ref: '#/components/responses/Conflict'
'500':
$ref: '#/components/responses/InternalServerError'
put:
description: Update the details of a transaction
operationId: updateTransactionDetails
tags:
- circulation
parameters:
- $ref: '#/components/parameters/dcbTransactionId'
requestBody:
$ref: "#/components/requestBodies/DcbUpdateTransaction"
responses:
'204':
description: 'Transaction updated successfully'
'404':
$ref: '#/components/responses/NotFound'
'500':
$ref: '#/components/responses/InternalServerError'
/transactions/{dcbTransactionId}/status:
parameters:
- $ref: '#/components/parameters/dcbTransactionId'
Expand Down Expand Up @@ -73,6 +89,13 @@ components:
application/json:
schema:
$ref: "schemas/dcbTransaction.yaml#/DcbTransaction"
DcbUpdateTransaction:
description: DCB transaction update object
required: true
content:
application/json:
schema:
$ref: "schemas/dcbUpdateTransaction.yaml#/DcbUpdateTransaction"
responses:
TransactionStatus:
description: Transaction Status object
Expand Down
18 changes: 18 additions & 0 deletions src/main/resources/swagger.api/schemas/dcbUpdateItem.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
DcbUpdateItem:
description: Item metadata required for updating the existing transaction
type: object
properties:
barcode:
description: The barcode of the item as specified in the lending library
type: string
materialType:
description: The “hub-normalized” form of the item item type, used in the circulation rules for determining the correct loan policy.
type: string
lendingLibraryCode:
description: The code which identifies the lending library
type: string
additionalProperties: false
required:
- barcode
- materialType
- lendingLibraryCode
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
DcbUpdateTransaction:
type: object
properties:
item:
$ref: 'dcbUpdateItem.yaml#/DcbUpdateItem'

Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
package org.folio.ed.controller;

import static org.assertj.core.api.Assertions.assertThat;
import static org.folio.ed.utils.EntityUtils.createDcbTransaction;
import static org.folio.ed.utils.EntityUtils.createTransactionStatus;
import static org.folio.ed.utils.EntityUtils.*;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
Expand Down Expand Up @@ -260,4 +259,54 @@ private void setUpMockAuthnClient(String token) {
public static String asJsonString(Object value) {
return OBJECT_MAPPER.writeValueAsString(value);
}

@Test
void shouldConvertApiKeyToHeadersForPutTransactionDetails() throws Exception {
// Given
var apiKey = ApiKeyUtils.generateApiKey(10, TENANT, USERNAME);
setUpMockAuthnClient(TOKEN);
// When we make a valid request to mod-dcb with the API key set
mockDcbServer.enqueue(new MockResponse()
.setResponseCode(204)
.setHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON));
var putResponse = mockMvc.perform(put("/dcbService/transactions/{transactionId}?apiKey={apiKey}", TRANSACTION_ID, apiKey)
.content(asJsonString(createDcbUpdateTransaction()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse();

// Then the outgoing response from the edge API should contain the Okapi auth headers and the response body should
// match mod-dcb response
var headers = mockDcbServer.takeRequest().getHeaders();
assertThat(headers.get(XOkapiHeaders.TENANT)).isEqualTo(TENANT);
assertThat(headers.get(XOkapiHeaders.TOKEN)).isEqualTo(TOKEN);
assertThat(headers.get(XOkapiHeaders.USER_ID)).isNull();
assertThat(putResponse.getContentAsString()).isEmpty();
assertThat(putResponse.getStatus()).isEqualTo(204);
}

@Test
void shouldReturnClientErrorsWhenPutTransactionDetails() throws Exception {
// Given
var apiKey = ApiKeyUtils.generateApiKey(10, TENANT, USERNAME);
var dcbResponseCode = HttpStatus.I_AM_A_TEAPOT.value(); // Arbitrary HTTP error status code
var dcbResponseBody = "I'm a teapot!";
setUpMockAuthnClient(TOKEN);

// When mod-dcb responds with an error
mockDcbServer.enqueue(new MockResponse()
.setResponseCode(dcbResponseCode)
.setBody(dcbResponseBody));
var putResponse = mockMvc.perform(put("/dcbService/transactions/{transactionId}?apiKey={apiKey}", TRANSACTION_ID, apiKey)
.content(asJsonString(createDcbUpdateTransaction()))
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON))
.andReturn()
.getResponse();

// If mod-dcb doesn't return the error of type errors, then we edge-dcb will throw INTERNAL_SERVER_ERROR
assertThat(putResponse.getStatus()).isEqualTo(HttpStatus.INTERNAL_SERVER_ERROR.value());
assertThat(putResponse.getContentAsString()).contains(dcbResponseBody);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,13 @@
import org.mockito.junit.jupiter.MockitoExtension;

import static org.folio.ed.utils.EntityUtils.*;
import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import org.folio.ed.domain.dto.DcbUpdateTransaction;

@ExtendWith(MockitoExtension.class)
class DcbTransactionServiceTest {
Expand Down Expand Up @@ -46,4 +48,18 @@ void updateDcbTransactionStatusTest() {
dcbTransactionService.updateDCBTransactionStatus("123", createTransactionStatus(TransactionStatus.StatusEnum.OPEN));
Mockito.verify(dcbClient).updateTransactionStatus(anyString(), any(TransactionStatus.class));
}

@Test
void updateDcbTransactionDetails() {
dcbTransactionService.updateTransactionDetails("123", createDcbUpdateTransaction());
verify(dcbClient).updateTransactionDetails(anyString(), any(DcbUpdateTransaction.class));
}

@Test
void updateDcbTransactionDetailsShouldThrowAnErrorIfClientReturnsError() {
org.folio.ed.domain.dto.DcbUpdateTransaction dcbUpdateTransaction = createDcbUpdateTransaction();
doThrow(IllegalStateException.class).when(dcbClient).updateTransactionDetails(anyString(), any(DcbUpdateTransaction.class));
assertThrows(IllegalStateException.class,
() -> dcbTransactionService.updateTransactionDetails("123", dcbUpdateTransaction));
}
}
12 changes: 12 additions & 0 deletions src/test/java/org/folio/ed/utils/EntityUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import org.folio.ed.domain.dto.DcbTransaction;
import org.folio.ed.domain.dto.TransactionStatus;
import org.folio.ed.domain.dto.TransactionStatusResponse;
import org.folio.ed.domain.dto.DcbUpdateTransaction;
import org.folio.ed.domain.dto.DcbUpdateItem;

public class EntityUtils {

Expand Down Expand Up @@ -45,4 +47,14 @@ public static DcbPatron createDcbPatron() {
public static TransactionStatusResponse createTransactionStatusResponse(TransactionStatusResponse.StatusEnum statusEnum){
return TransactionStatusResponse.builder().status(statusEnum).build();
}

public static org.folio.ed.domain.dto.DcbUpdateTransaction createDcbUpdateTransaction() {
return DcbUpdateTransaction.builder()
.item(DcbUpdateItem.builder()
.barcode(ITEM_ID)
.materialType("book")
.lendingLibraryCode("KU")
.build())
.build();
}
}

0 comments on commit 6371f7a

Please sign in to comment.