Skip to content
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

Added test reproducing issue with documentExists check #131

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions samples/webApi/expressjs-with-postgresql/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@
},
"homepage": "https://github.com/event-driven-io/emmett#readme",
"dependencies": {
"@event-driven-io/emmett": "0.20.0",
"@event-driven-io/emmett-expressjs": "0.20.0",
"@event-driven-io/emmett-postgresql": "0.20.0"
"@event-driven-io/emmett": "0.21.0",
"@event-driven-io/emmett-expressjs": "0.21.0",
"@event-driven-io/emmett-postgresql": "0.21.0"
},
"devDependencies": {
"@testcontainers/postgresql": "^10.10.3",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ void describe('Shopping Cart Short Details Projection', () => {
}
});

void it.skip('adds product to empty shopping cart', () =>
void it('adds product to empty shopping cart', () =>
given([])
.when([
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ void describe('Postgres Projections', () => {
let eventStore: PostgresEventStore;
let connectionString: string;
let pongo: PongoClient;
const now = new Date();

before(async () => {
postgres = await new PostgreSqlContainer().start();
Expand Down Expand Up @@ -68,7 +69,7 @@ void describe('Postgres Projections', () => {

const result = await handle(eventStore, shoppingCartId, () => ({
type: 'ProductItemAdded',
data: { productItem },
data: { productItem, addedAt: now },
}));

const couponId = uuid();
Expand All @@ -78,7 +79,7 @@ void describe('Postgres Projections', () => {

await handle(eventStore, shoppingCartId, () => ({
type: 'ProductItemAdded',
data: { productItem },
data: { productItem, addedAt: new Date() },
}));

await handle(eventStore, shoppingCartId, () => ({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ void describe('EventStoreDBEventStore', () => {
let eventStore: PostgresEventStore;
let connectionString: string;
let pongo: PongoClient;
const now = new Date();

before(async () => {
postgres = await new PostgreSqlContainer().start();
Expand Down Expand Up @@ -65,10 +66,10 @@ void describe('EventStoreDBEventStore', () => {
handledEventsInCustomProjection = [];

await eventStore.appendToStream<ShoppingCartEvent>(shoppingCartId, [
{ type: 'ProductItemAdded', data: { productItem } },
{ type: 'ProductItemAdded', data: { productItem, addedAt: now } },
]);
await eventStore.appendToStream<ShoppingCartEvent>(shoppingCartId, [
{ type: 'ProductItemAdded', data: { productItem } },
{ type: 'ProductItemAdded', data: { productItem, addedAt: new Date() } },
]);
await eventStore.appendToStream<ShoppingCartEvent>(shoppingCartId, [
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,13 @@ const assertDocumentsEqual = <
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Document ids are not matching! Expected: ${expected._id}, actual: ${actual._id}`,
);
if ('_version' in expected)
assertEqual(
expected._version,
actual._version,
// eslint-disable-next-line @typescript-eslint/restrict-template-expressions
`Document versions are not matching! Expected: ${expected._version}, actual: ${actual._version}`,
);

return assertDeepEqual(
withoutIdAndVersion(actual),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
addedAt: new Date(),
},
metadata: {
streamName: shoppingCartId,
Expand All @@ -83,6 +84,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
addedAt: new Date(),
},
}),
])
Expand All @@ -107,6 +109,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
addedAt: new Date(),
},
},
]),
Expand All @@ -117,6 +120,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 30, productId: 'shoes', quantity: 30 },
addedAt: new Date(),
},
},
]),
Expand All @@ -141,6 +145,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
addedAt: new Date(),
},
},
]),
Expand All @@ -151,6 +156,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
addedAt: new Date(),
},
},
]),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { type ReadEvent } from '@event-driven-io/emmett/src';
import {
PostgreSqlContainer,
StartedPostgreSqlContainer,
Expand All @@ -6,10 +7,6 @@ import { after, before, beforeEach, describe, it } from 'node:test';
import { v4 as uuid } from 'uuid';
import {
documentExists,
eventInStream,
eventsInStream,
expectPongoDocuments,
newEventsInStream,
pongoSingleStreamProjection,
PostgreSQLProjectionSpec,
} from '.';
Expand All @@ -23,6 +20,7 @@ void describe('Postgres Projections', () => {
let connectionString: string;
let given: PostgreSQLProjectionSpec<ProductItemAdded | DiscountApplied>;
let shoppingCartId: string;
const now = new Date();

before(async () => {
postgres = await new PostgreSqlContainer().start();
Expand Down Expand Up @@ -51,6 +49,7 @@ void describe('Postgres Projections', () => {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
addedAt: now,
},
metadata: {
streamName: shoppingCartId,
Expand All @@ -60,6 +59,7 @@ void describe('Postgres Projections', () => {
.then(
documentExists<ShoppingCartShortInfo>(
{
openedAt: now,
productItemsCount: 100,
totalAmount: 10000,
appliedDiscounts: [],
Expand All @@ -71,102 +71,109 @@ void describe('Postgres Projections', () => {
),
));

void it('with empty given and when eventsInStream', () =>
given([])
.when([
eventInStream(shoppingCartId, {
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
},
}),
])
.then(
expectPongoDocuments
.fromCollection<ShoppingCartShortInfo>(
shoppingCartShortInfoCollectionName,
)
.withId(shoppingCartId)
.toBeEqual({
productItemsCount: 100,
totalAmount: 10000,
appliedDiscounts: [],
}),
));

void it('with empty given and when eventsInStream', () => {
const couponId = uuid();

return given(
eventsInStream<ProductItemAdded>(shoppingCartId, [
{
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
},
},
]),
)
.when(
newEventsInStream(shoppingCartId, [
{
type: 'DiscountApplied',
data: { percent: 10, couponId },
},
]),
)
.then(
expectPongoDocuments
.fromCollection<ShoppingCartShortInfo>(
shoppingCartShortInfoCollectionName,
)
.withId(shoppingCartId)
.toBeEqual({
productItemsCount: 100,
totalAmount: 9000,
appliedDiscounts: [couponId],
}),
);
});

void it('with idempotency check', () => {
const couponId = uuid();

return given(
eventsInStream<ProductItemAdded>(shoppingCartId, [
{
type: 'ProductItemAdded',
data: {
productItem: { price: 100, productId: 'shoes', quantity: 100 },
},
},
]),
)
.when(
newEventsInStream(shoppingCartId, [
{
type: 'DiscountApplied',
data: { percent: 10, couponId },
},
]),
{ numberOfTimes: 2 },
)
.then(
expectPongoDocuments
.fromCollection<ShoppingCartShortInfo>(
shoppingCartShortInfoCollectionName,
)
.withId(shoppingCartId)
.toBeEqual({
productItemsCount: 100,
totalAmount: 9000,
appliedDiscounts: [couponId],
}),
);
});
// void it('with empty given and when eventsInStream', () =>
// given([])
// .when([
// eventInStream(shoppingCartId, {
// type: 'ProductItemAdded',
// data: {
// productItem: { price: 100, productId: 'shoes', quantity: 100 },
// addedAt: now,
// },
// }),
// ])
// .then(
// expectPongoDocuments
// .fromCollection<ShoppingCartShortInfo>(
// shoppingCartShortInfoCollectionName,
// )
// .withId(shoppingCartId)
// .toBeEqual({
// openedAt: now,
// productItemsCount: 100,
// totalAmount: 10000,
// appliedDiscounts: [],
// }),
// ));

// void it('with empty given and when eventsInStream', () => {
// const couponId = uuid();

// return given(
// eventsInStream<ProductItemAdded>(shoppingCartId, [
// {
// type: 'ProductItemAdded',
// data: {
// productItem: { price: 100, productId: 'shoes', quantity: 100 },
// addedAt: now,
// },
// },
// ]),
// )
// .when(
// newEventsInStream(shoppingCartId, [
// {
// type: 'DiscountApplied',
// data: { percent: 10, couponId },
// },
// ]),
// )
// .then(
// expectPongoDocuments
// .fromCollection<ShoppingCartShortInfo>(
// shoppingCartShortInfoCollectionName,
// )
// .withId(shoppingCartId)
// .toBeEqual({
// openedAt: now,
// productItemsCount: 100,
// totalAmount: 9000,
// appliedDiscounts: [couponId],
// }),
// );
// });

// void it('with idempotency check', () => {
// const couponId = uuid();

// return given(
// eventsInStream<ProductItemAdded>(shoppingCartId, [
// {
// type: 'ProductItemAdded',
// data: {
// productItem: { price: 100, productId: 'shoes', quantity: 100 },
// addedAt: now,
// },
// },
// ]),
// )
// .when(
// newEventsInStream(shoppingCartId, [
// {
// type: 'DiscountApplied',
// data: { percent: 10, couponId },
// },
// ]),
// { numberOfTimes: 2 },
// )
// .then(
// expectPongoDocuments
// .fromCollection<ShoppingCartShortInfo>(
// shoppingCartShortInfoCollectionName,
// )
// .withId(shoppingCartId)
// .toBeEqual({
// openedAt: now,
// productItemsCount: 100,
// totalAmount: 9000,
// appliedDiscounts: [couponId],
// }),
// );
// });
});

type ShoppingCartShortInfo = {
openedAt: Date;
productItemsCount: number;
totalAmount: number;
appliedDiscounts: string[];
Expand All @@ -176,12 +183,13 @@ const shoppingCartShortInfoCollectionName = 'shoppingCartShortInfo';

const evolve = (
document: ShoppingCartShortInfo,
{ type, data: event }: ProductItemAdded | DiscountApplied,
{ type, data: event }: ReadEvent<ProductItemAdded | DiscountApplied>,
): ShoppingCartShortInfo => {
switch (type) {
case 'ProductItemAdded':
return {
...document,
openedAt: document.openedAt ?? event.addedAt,
totalAmount:
document.totalAmount +
event.productItem.price * event.productItem.quantity,
Expand All @@ -207,6 +215,7 @@ const shoppingCartShortInfoProjection = pongoSingleStreamProjection({
evolve,
canHandle: ['ProductItemAdded', 'DiscountApplied'],
initialState: () => ({
openedAt: undefined!,
productItemsCount: 0,
totalAmount: 0,
appliedDiscounts: [],
Expand Down
Loading
Loading