|
49 | 49 | import org.eclipse.edc.spi.types.domain.message.RemoteMessage; |
50 | 50 | import org.eclipse.edc.transaction.spi.NoopTransactionContext; |
51 | 51 | import org.eclipse.edc.transaction.spi.TransactionContext; |
| 52 | +import org.jspecify.annotations.NonNull; |
52 | 53 | import org.junit.jupiter.api.BeforeEach; |
53 | 54 | import org.junit.jupiter.api.Nested; |
54 | 55 | import org.junit.jupiter.api.Test; |
|
57 | 58 | import org.junit.jupiter.params.provider.Arguments; |
58 | 59 | import org.junit.jupiter.params.provider.ArgumentsProvider; |
59 | 60 | import org.junit.jupiter.params.provider.ArgumentsSource; |
| 61 | +import org.junit.jupiter.params.support.ParameterDeclarations; |
60 | 62 | import org.mockito.ArgumentCaptor; |
61 | 63 |
|
62 | 64 | import java.time.Instant; |
63 | | -import java.util.Collections; |
| 65 | +import java.util.Map; |
64 | 66 | import java.util.UUID; |
65 | 67 | import java.util.stream.Stream; |
66 | 68 |
|
| 69 | +import static java.util.Collections.emptyMap; |
67 | 70 | import static org.assertj.core.api.Assertions.assertThat; |
| 71 | +import static org.assertj.core.api.Assertions.entry; |
68 | 72 | import static org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation.Type.CONSUMER; |
69 | 73 | import static org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiation.Type.PROVIDER; |
70 | 74 | import static org.eclipse.edc.connector.controlplane.contract.spi.types.negotiation.ContractNegotiationStates.ACCEPTED; |
@@ -150,44 +154,55 @@ void notifyAccepted_shouldTransitionToAccepted() { |
150 | 154 | verify(transactionContext, atLeastOnce()).execute(any(TransactionContext.ResultTransactionBlock.class)); |
151 | 155 | } |
152 | 156 |
|
153 | | - @Test |
154 | | - void notifyAgreed_shouldTransitionToAgreed() { |
155 | | - var negotiationConsumerRequested = createContractNegotiationRequested(); |
156 | | - var participantAgent = participantAgent(); |
157 | | - var tokenRepresentation = tokenRepresentation(); |
| 157 | + @Nested |
| 158 | + class NotifyAgreed { |
158 | 159 |
|
159 | | - var contractAgreement = ContractAgreement.Builder.newInstance() |
160 | | - .providerId("providerId") |
161 | | - .consumerId("consumerId") |
162 | | - .assetId("assetId") |
163 | | - .policy(Policy.Builder.newInstance().build()) |
164 | | - .participantContextId("participantContextId") |
165 | | - .build(); |
166 | | - var message = ContractAgreementMessage.Builder.newInstance() |
167 | | - .protocol("protocol") |
168 | | - .counterPartyAddress("http://any") |
169 | | - .processId("processId") |
170 | | - .consumerPid("consumerPid") |
171 | | - .providerPid("providerPid") |
172 | | - .contractAgreement(contractAgreement) |
173 | | - .build(); |
| 160 | + @Test |
| 161 | + void shouldTransitionToAgreed() { |
| 162 | + var negotiationConsumerRequested = createContractNegotiationRequested(); |
| 163 | + var participantAgent = new ParticipantAgent("counterPartyId", Map.of("claim", "value"), emptyMap()); |
| 164 | + var tokenRepresentation = tokenRepresentation(); |
174 | 165 |
|
175 | | - when(protocolTokenValidator.verify(eq(participantContext), eq(tokenRepresentation), any(), any(), eq(message))).thenReturn(ServiceResult.success(participantAgent)); |
176 | | - when(store.findById(any())).thenReturn(negotiationConsumerRequested); |
177 | | - when(store.findByIdAndLease(any())).thenReturn(StoreResult.success(negotiationConsumerRequested)); |
178 | | - when(validationService.validateConfirmed(eq(participantAgent), eq(contractAgreement), any(ContractOffer.class))).thenReturn(Result.success()); |
| 166 | + var contractAgreement = ContractAgreement.Builder.newInstance() |
| 167 | + .providerId("providerId") |
| 168 | + .consumerId("consumerId") |
| 169 | + .assetId("assetId") |
| 170 | + .policy(Policy.Builder.newInstance().build()) |
| 171 | + .participantContextId("participantContextId") |
| 172 | + .build(); |
| 173 | + var message = ContractAgreementMessage.Builder.newInstance() |
| 174 | + .protocol("protocol") |
| 175 | + .counterPartyAddress("http://any") |
| 176 | + .processId("processId") |
| 177 | + .consumerPid("consumerPid") |
| 178 | + .providerPid("providerPid") |
| 179 | + .contractAgreement(contractAgreement) |
| 180 | + .build(); |
179 | 181 |
|
180 | | - var result = service.notifyAgreed(participantContext, message, tokenRepresentation); |
| 182 | + when(protocolTokenValidator.verify(eq(participantContext), eq(tokenRepresentation), any(), any(), eq(message))).thenReturn(ServiceResult.success(participantAgent)); |
| 183 | + when(store.findById(any())).thenReturn(negotiationConsumerRequested); |
| 184 | + when(store.findByIdAndLease(any())).thenReturn(StoreResult.success(negotiationConsumerRequested)); |
| 185 | + when(validationService.validateConfirmed(eq(participantAgent), eq(contractAgreement), any(ContractOffer.class))).thenReturn(Result.success()); |
| 186 | + |
| 187 | + var result = service.notifyAgreed(participantContext, message, tokenRepresentation); |
| 188 | + |
| 189 | + assertThat(result).isSucceeded(); |
| 190 | + verify(store).findById("processId"); |
| 191 | + verify(store).findByIdAndLease("processId"); |
| 192 | + ArgumentCaptor<ContractNegotiation> negotiationCaptor = ArgumentCaptor.forClass(ContractNegotiation.class); |
| 193 | + verify(store).save(negotiationCaptor.capture()); |
| 194 | + ContractNegotiation storedNegotiation = negotiationCaptor.getValue(); |
| 195 | + assertThat(storedNegotiation.stateAsString()).isEqualTo(AGREED.name()); |
| 196 | + assertThat(storedNegotiation.getContractAgreement()).satisfies(storedAgreement -> { |
| 197 | + assertThat(storedAgreement.getProviderId()).isEqualTo("providerId"); |
| 198 | + assertThat(storedAgreement.getConsumerId()).isEqualTo("consumerId"); |
| 199 | + assertThat(storedAgreement.getClaims()).hasSize(1).containsExactly(entry("claim", "value")); |
| 200 | + }); |
| 201 | + verify(validationService).validateConfirmed(eq(participantAgent), eq(contractAgreement), any(ContractOffer.class)); |
| 202 | + verify(listener).agreed(any()); |
| 203 | + verify(transactionContext, atLeastOnce()).execute(any(TransactionContext.ResultTransactionBlock.class)); |
| 204 | + } |
181 | 205 |
|
182 | | - assertThat(result).isSucceeded(); |
183 | | - verify(store).findById("processId"); |
184 | | - verify(store).findByIdAndLease("processId"); |
185 | | - verify(store).save(argThat(negotiation -> |
186 | | - negotiation.getState() == AGREED.code() && negotiation.getContractAgreement().equals(contractAgreement) |
187 | | - )); |
188 | | - verify(validationService).validateConfirmed(eq(participantAgent), eq(contractAgreement), any(ContractOffer.class)); |
189 | | - verify(listener).agreed(any()); |
190 | | - verify(transactionContext, atLeastOnce()).execute(any(TransactionContext.ResultTransactionBlock.class)); |
191 | 206 | } |
192 | 207 |
|
193 | 208 | @Test |
@@ -433,7 +448,7 @@ <M extends RemoteMessage> void notify_shouldReturnNotFound_whenParticipantContex |
433 | 448 |
|
434 | 449 |
|
435 | 450 | private ParticipantAgent participantAgent() { |
436 | | - return new ParticipantAgent("counterPartyId", Collections.emptyMap(), Collections.emptyMap()); |
| 451 | + return new ParticipantAgent("counterPartyId", emptyMap(), emptyMap()); |
437 | 452 | } |
438 | 453 |
|
439 | 454 | private ContractNegotiation createContractNegotiationRequested() { |
@@ -501,7 +516,7 @@ static ContractDefinition createContractDefinition() { |
501 | 516 | private static class NotifyArguments implements ArgumentsProvider { |
502 | 517 |
|
503 | 518 | @Override |
504 | | - public Stream<? extends Arguments> provideArguments(ExtensionContext extensionContext) { |
| 519 | + public @NonNull Stream<? extends Arguments> provideArguments(@NonNull ParameterDeclarations parameters, @NonNull ExtensionContext context) { |
505 | 520 | MethodCall<ContractRequestMessage> requested = ContractNegotiationProtocolService::notifyRequested; |
506 | 521 | MethodCall<ContractOfferMessage> offered = ContractNegotiationProtocolService::notifyOffered; |
507 | 522 | MethodCall<ContractAgreementMessage> agreed = ContractNegotiationProtocolService::notifyAgreed; |
|
0 commit comments