Closed DemiusAcademius closed 5 months ago
package md.maib.retail.loyalty.campagin.rest;
import au.com.dius.pact.provider.junit5.HttpTestTarget; import au.com.dius.pact.provider.junit5.PactVerificationContext; import au.com.dius.pact.provider.junitsupport.IgnoreNoPactsToVerify; import au.com.dius.pact.provider.junitsupport.Provider; import au.com.dius.pact.provider.junitsupport.VerificationReports; import au.com.dius.pact.provider.junitsupport.loader.PactFolder; import au.com.dius.pact.provider.spring.junit5.PactVerificationSpringProvider; import md.maib.commons.integration.test.IntegrationTest; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.TestTemplate; import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.web.server.LocalServerPort; import org.springframework.test.context.TestPropertySource;
import javax.annotation.Nullable; import java.util.List;
@IntegrationTest @TestPropertySource("classpath:/integration-tests.properties") @Provider("loyalty-campaign-service") @PactFolder("pacts") @IgnoreNoPactsToVerify @VerificationReports(value = {"console", "json"}, reportDir = "target/pact/reports") class ApplicationVerificationTest {
@BeforeEach
void before(@Nullable PactVerificationContext context, @LocalServerPort int port,
@Autowired(required = false) List<StateHandler> stateHandlers) {
if (context != null && stateHandlers != null) {
context.withStateChangeHandlers(stateHandlers.toArray())
.setTarget(new HttpTestTarget("localhost", port, "/"));
}
}
@TestTemplate
@ExtendWith(PactVerificationSpringProvider.class)
void verification(@Nullable PactVerificationContext context) {
if (context != null) {
context.verifyInteraction();
}
}
}
integration-test.properties
embedded.service.enabled=false
{ "consumer": { "name": "loyalty-campaign-gateway" }, "interactions": [ { "description": "a request with params for applications", "providerStates": [ { "name": "get campaign by id" } ], "request": { "method": "GET", "path": "/api/campaigns/fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91" }, "response": { "body": { "id": "fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91", "name": "Some other campaign", "interval": { "start": "2018-11-30T18:35:24Z", "end": "2023-12-31T18:35:24Z" }, "tags": [ "PARTNER", "PROMO" ], "rules": [ { "id": "587936e3-80da-4ff3-abfe-e5eea796135e", "conditions": [ { "negated": false, "field": "MERCHANT_ID", "operator": "EQ", "value": "Linella" } ], "sponsor": "PARTNER", "rate": 5.00 } ], "isDefault": false, "createdAt": "2018-11-30T18:35:24Z" }, "headers": { "Content-Type": "application/json" }, "status": 200 } }, { "description": "a request with params for applications", "providerStates": [ { "name": "find campaign by name" } ], "request": { "method": "GET", "path": "/api/campaigns", "query": { "name": [ "Some campa" ], "tags": [ "PARTNER, PROMO" ] } }, "response": { "body": [ { "value": "fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91" } ], "headers": { "Content-Type": "application/json" }, "status": 200 } }, { "description": "a request with params for applications", "providerStates": [ { "name": "complete campaign" } ], "request": { "method": "POST", "headers": { "Content-Type": "application/json" }, "path": "/api/campaigns/fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91/completion", "body": { "completedAt": "2025-12-31" } }, "response": { "status": 204 } }, { "description": "a request with params for applications", "providerStates": [ { "name": "register campaign" } ], "request": { "method": "POST", "headers": { "Content-Type": "application/json" }, "path": "/api/campaigns", "body": { "name": "Some campaign", "startInclusive": "2018-01-01", "endExclusive": "2025-12-31", "tags": [ "PROMO" ], "rules": [ { "conditions": [ { "negated": false, "fieldName": "MCC", "operator": "IN", "operatorModifier": null, "value": "123,456" } ], "effect": { "sponsor": "BANK", "rate": 5.0 } } ] } }, "response": { "headers": { "Location": "http://localhost:55555/api/campaigns/fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91" }, "status": 201, "matchingRules": { "header": { "Location": { "combine": "AND", "matchers": [ { "match": "regex", "regex": "http://localhost:\\d+/api/campaigns/fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91" } ] } } } } } ], "metadata": { "pact-jvm": { "version": "4.6.1" }, "pactSpecification": { "version": "3.0.0" } }, "provider": { "name": "loyalty-campaign-service" } }
@State("get campaign by id") void getCampaignById() { var id = fromString("fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91"); var interval = Interval.of(parse("2018-11-30T18:35:24.00Z"), parse("2023-12-31T18:35:24.00Z")); var campaign = new CampaignEntity( new CampaignId(id), new CampaignName("Some other campaign"), interval, List.of( new RuleEntity( new RuleId(fromString("587936e3-80da-4ff3-abfe-e5eea796135e")), List.of( new ConditionEntity( new ConditionId(fromString("de1bef3f-acae-48da-8584-410683553cef")), false, PurchaseField.MERCHANT_ID, ConditionOperator.EQ, null, "Linella") ), new CashbackEffectEntity(new EffectId(fromString("65f14e63-9ad9-4d9e-abdc-c9b153ceb8cb")), CampaignSponsor.PARTNER, new BigDecimal("5.00")) ) ), parse("2018-11-30T18:35:24.00Z") ); when(getCampaignByIdUseCase.getCampaign(any())).thenReturn(Optional.of(campaign)); when(campaignIsDefaultUseCase.isDefault(any())).thenReturn(false); when(listCampaignTagsUseCase.listCampaignTags(any())).thenReturn(List.of(CampaignTag.PARTNER, CampaignTag.PROMO)); }
mvn test -Dgroups=integration
simple state for RegisterCampaign
@State("register campaign")
void registerCampaign() {
var id = fromString("fe5cea5a-71ce-44cd-9b7a-1aba11dc5a91");
when(registrationCampaignUseCase.registerCampaign(any())).thenReturn(Either.right(new CampaignId(id)));
}
the same error
JSON parse error: Cannot invoke "String.length()" because "name" is null]
,can it be because of Controller method?
@PostMapping @Transactional public ResponseEntity
return validated.fold(
violations -> {
throw responseExceptionFromViolations(violations);
},
command -> {
var result = registrationCampaignUseCase.registerCampaign(command);
return result.map(campaignId -> {
var location = ServletUriComponentsBuilder
.fromCurrentRequest()
.path("/{id}")
.buildAndExpand(campaignId.campaignId().toString()).toUri();
return ResponseEntity.created(location).build();
}).getOrElse(() -> ResponseEntity.notFound().build());
}
);
}
package md.maib.commons.integration.test;
import org.junit.jupiter.api.Tag; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.TestPropertySource;
import java.lang.annotation.Documented; import java.lang.annotation.ElementType; import java.lang.annotation.Inherited; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;
import static org.springframework.boot.test.context.SpringBootTest.WebEnvironment.RANDOM_PORT;
@Target(ElementType.TYPE) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited @Tag("integration") @SpringBootTest(webEnvironment = RANDOM_PORT, args = "build.image=false") @TestPropertySource("classpath:integration-tests.properties") public @interface IntegrationTest { }