Skip to content

Commit

Permalink
Add support for fields with optional values, when value is provided (#17
Browse files Browse the repository at this point in the history
)
  • Loading branch information
austek authored Apr 6, 2023
1 parent 248410b commit c909906
Show file tree
Hide file tree
Showing 20 changed files with 535 additions and 245 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ jobs:
run: docker-compose -f docker-compose.yml up -d

- name: Build project
run: sbt ++${{ matrix.scala }} compile scalafmtCheckAll plugin/test
run: sbt ++${{ matrix.scala }} compile scalafmtCheckAll javafmtCheckAll plugin/test

- name: Test Consumer
run: sbt ++${{ matrix.scala }} consumer/test
Expand Down
2 changes: 1 addition & 1 deletion .scalafmt.conf
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# **Note** that config order in this file is important since what comes afterwards takes precedence
version = 3.7.1
version = 3.7.3
project.git = true
runner.dialect = scala213
align = true
Expand Down
2 changes: 1 addition & 1 deletion docs/modules/ROOT/pages/getting_started.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ mkdir -p ~/.pact/plugins/avro-{version}
+
[source,shell,subs=attributes]
----
wget -c https://github.com/austek/pact-avro-plugin/releases/download/v-{version}/pact-avro-plugin-{version}.tgz -O ~/.pact/plugins/avro-{version}/pact-avro-plugin.tgz
wget -c https://github.com/austek/pact-avro-plugin/releases/download/v{version}/pact-avro-plugin-{version}.tgz -O ~/.pact/plugins/avro-{version}/pact-avro-plugin.tgz
----

. Unpack the plugin executable:
Expand Down
2 changes: 1 addition & 1 deletion github-actions.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ ThisBuild / githubWorkflowBuild := Seq(
),
WorkflowStep.Sbt(
name = Some("Build project"),
commands = List("compile", "scalafmtCheckAll", "plugin/test")
commands = List("compile", "scalafmtCheckAll", "javafmtCheckAll", "plugin/test")
),
WorkflowStep.Sbt(
name = Some("Test Consumer"),
Expand Down
79 changes: 79 additions & 0 deletions modules/examples/consumer/src/main/resources/avro/order-v1.avsc
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
[
{
"type": "record",
"name": "OrderNewEvent",
"namespace": "com.collibra.event.client.examples.showcase.schema",
"fields": [
{
"name": "createdOn",
"type": [
"null",
{
"type": "long",
"logicalType": "timestamp-micros"
}
]
},
{
"name": "items",
"type": [
"null",
{
"type": "array",
"items": {
"type": "record",
"name": "OrderItem",
"namespace": "com.collibra.event.client.examples.showcase.domain",
"fields": [
{
"name": "itemId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
},
{
"name": "quantity",
"type": "int"
}
]
}
}
]
},
{
"name": "orderId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
},
{
"name": "userId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
},
{
"name": "walletId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
}
]
}
]
10 changes: 10 additions & 0 deletions modules/examples/consumer/src/main/resources/avro/orders.avsc
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,16 @@
"type": "array",
"items": "com.github.austek.example.Item"
}
},
{
"name": "userId",
"type": [
"null",
{
"type": "string",
"logicalType": "uuid"
}
]
}
]
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
package com.github.austek.example.pulsar.avro;

import static com.github.austek.example.pulsar.avro.PactPulsarConsumerTest.arrayByteToAvroRecord;
import static org.assertj.core.api.Assertions.assertThat;

import au.com.dius.pact.consumer.dsl.PactBuilder;
import au.com.dius.pact.consumer.junit5.PactConsumerTestExt;
import au.com.dius.pact.consumer.junit5.PactTestFor;
import au.com.dius.pact.consumer.junit5.ProviderType;
import au.com.dius.pact.core.model.ContentTypeHint;
import au.com.dius.pact.core.model.PactSpecVersion;
import au.com.dius.pact.core.model.V4Interaction;
import au.com.dius.pact.core.model.V4Pact;
import au.com.dius.pact.core.model.annotations.Pact;
import au.com.dius.pact.core.model.matchingrules.MatchingRule;
import au.com.dius.pact.core.model.matchingrules.MatchingRuleCategory;
import au.com.dius.pact.core.model.matchingrules.MatchingRuleGroup;
import au.com.dius.pact.core.model.matchingrules.MatchingRulesImpl;
import au.com.dius.pact.core.model.v4.MessageContents;
import com.collibra.event.client.examples.showcase.domain.OrderItem;
import com.collibra.event.client.examples.showcase.schema.OrderNewEvent;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;

@ExtendWith(PactConsumerTestExt.class)
@PactTestFor(
pactVersion = PactSpecVersion.V4,
providerType = ProviderType.ASYNCH,
providerName = "OrderTopicV1")
class OrderV1ConsumerTest {
private final String schemasPath =
Objects.requireNonNull(getClass().getResource("/avro/order-v1.avsc")).getPath();

@Pact(consumer = "OrderTopicConsumer")
V4Pact configureRecordWithDependantRecord(PactBuilder builder) {
var messageBody =
Map.of(
"message.contents",
Map.ofEntries(
Map.entry("pact:avro", schemasPath),
Map.entry("pact:record-name", "OrderNewEvent"),
Map.entry("pact:content-type", "avro/binary"),
Map.entry("orderId", "notEmpty('0c7cbb5a-9a9a-4088-9713-c0c88475c903')"),
Map.entry("userId", "notEmpty('20bef962-8cbd-4b8c-8337-97ae385ac45d')"),
Map.entry(
"items",
List.of(
Map.of(
"itemId", "notEmpty('e41c5f30-fa8e-4cfd-989d-95ca5a04037f')",
"quantity", "notEmpty('1')"),
Map.of(
"itemId", "notEmpty('8a62474a-7157-4c67-9126-c6dcecb1df08')",
"quantity", "notEmpty('2')")))));
return builder
.usingPlugin("avro")
.expectsToReceive("Order Created", "core/interaction/message")
.with(messageBody)
.toPact();
}

@Test
@PactTestFor(pactMethod = "configureRecordWithDependantRecord")
void consumerRecordWithDependantRecord(V4Interaction.AsynchronousMessage message)
throws IOException {
MessageContents messageContents = message.getContents();
List<OrderNewEvent> orders =
arrayByteToAvroRecord(OrderNewEvent.class, messageContents.getContents().getValue());
OrderNewEvent order = assertFirstOrder(orders);

assertThat(messageContents.getContents().getContentType())
.hasToString("avro/binary; record=OrderNewEvent");
assertThat(messageContents.getContents().getContentTypeHint())
.isEqualTo(ContentTypeHint.BINARY);

Map<String, MatchingRuleCategory> ruleCategoryMap =
((MatchingRulesImpl) messageContents.getMatchingRules()).getRules();
assertThat(ruleCategoryMap).hasSize(1);
Map<String, MatchingRuleGroup> rules = ruleCategoryMap.get("body").getMatchingRules();
List<MatchingRule> idRules = rules.get("$.userId").getRules();
assertThat(idRules).hasSize(1);
assertThat(idRules.get(0)).extracting("name").isEqualTo("not-empty");
}

private static OrderNewEvent assertFirstOrder(List<OrderNewEvent> orders) {
assertThat(orders).hasSize(1);
OrderNewEvent order = orders.get(0);
assertThat(order.getOrderId()).hasToString("0c7cbb5a-9a9a-4088-9713-c0c88475c903");
assertThat(order.getUserId()).hasToString("20bef962-8cbd-4b8c-8337-97ae385ac45d");
assertThat(order.getItems()).hasSize(2);
OrderItem item1 = order.getItems().get(0);
assertThat(item1.getItemId()).hasToString("e41c5f30-fa8e-4cfd-989d-95ca5a04037f");
assertThat(item1.getQuantity()).isEqualTo(1);
OrderItem item2 = order.getItems().get(1);
assertThat(item2.getItemId()).hasToString("8a62474a-7157-4c67-9126-c6dcecb1df08");
assertThat(item2.getQuantity()).isEqualTo(2L);
return order;
}
}
Loading

0 comments on commit c909906

Please sign in to comment.