-
Notifications
You must be signed in to change notification settings - Fork 18
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: fixed XStatePersistence plugin and fixed the tests
- Loading branch information
Showing
22 changed files
with
465 additions
and
464 deletions.
There are no files selected for viewing
72 changes: 36 additions & 36 deletions
72
packages/data-store/src/__tests__/xstatePersistence.entities.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,45 +1,45 @@ | ||
import {DataSource} from 'typeorm' | ||
import {StateEntity, stateEntityFrom} from "../entities/xstatePersistence/StateEntity"; | ||
import { DataSource } from 'typeorm' | ||
import { StateEntity, stateEntityFrom } from '../entities/xstatePersistence/StateEntity' | ||
|
||
import {DataStoreXStateStoreEntities, DataStoreXStateStoreMigrations, NonPersistedXStateStoreEvent} from '../index' | ||
import { DataStoreXStateStoreEntities, DataStoreXStateStoreMigrations, NonPersistedXStateStoreEvent } from '../index' | ||
|
||
describe('Database entities tests', (): void => { | ||
let dbConnection: DataSource | ||
let dbConnection: DataSource | ||
|
||
beforeEach(async (): Promise<void> => { | ||
dbConnection = await new DataSource({ | ||
type: 'sqlite', | ||
database: ':memory:', | ||
//logging: 'all', | ||
migrationsRun: false, | ||
migrations: DataStoreXStateStoreMigrations, | ||
synchronize: false, | ||
entities: [...DataStoreXStateStoreEntities], | ||
}).initialize() | ||
await dbConnection.runMigrations() | ||
expect(await dbConnection.showMigrations()).toBeFalsy() | ||
}) | ||
beforeEach(async (): Promise<void> => { | ||
dbConnection = await new DataSource({ | ||
type: 'sqlite', | ||
database: ':memory:', | ||
//logging: 'all', | ||
migrationsRun: false, | ||
migrations: DataStoreXStateStoreMigrations, | ||
synchronize: false, | ||
entities: [...DataStoreXStateStoreEntities], | ||
}).initialize() | ||
await dbConnection.runMigrations() | ||
expect(await dbConnection.showMigrations()).toBeFalsy() | ||
}) | ||
|
||
afterEach(async (): Promise<void> => { | ||
await dbConnection.destroy() | ||
}) | ||
afterEach(async (): Promise<void> => { | ||
await dbConnection.destroy() | ||
}) | ||
|
||
it('should save xstate event to database', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
it('should save xstate event to database', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
|
||
const xstateEventEntity: StateEntity = stateEntityFrom(xstateEvent) | ||
const fromDb: StateEntity = await dbConnection.getRepository(StateEntity).save(xstateEventEntity) | ||
const xstateEventEntity: StateEntity = stateEntityFrom(xstateEvent) | ||
const fromDb: StateEntity = await dbConnection.getRepository(StateEntity).save(xstateEventEntity) | ||
|
||
expect(fromDb).toBeDefined() | ||
expect(fromDb?.id).not.toBeNull() | ||
expect(fromDb?.type).toEqual(xstateEvent.type) | ||
expect(fromDb?.state).toEqual(xstateEvent.state) | ||
expect(fromDb?.tenantId).toEqual(xstateEvent.tenantId) | ||
expect(fromDb?.completedAt).toEqual(xstateEvent.completedAt) | ||
}) | ||
expect(fromDb).toBeDefined() | ||
expect(fromDb?.id).not.toBeNull() | ||
expect(fromDb?.type).toEqual(xstateEvent.type) | ||
expect(fromDb?.state).toEqual(xstateEvent.state) | ||
expect(fromDb?.tenantId).toEqual(xstateEvent.tenantId) | ||
expect(fromDb?.completedAt).toEqual(xstateEvent.completedAt) | ||
}) | ||
}) |
231 changes: 116 additions & 115 deletions
231
packages/data-store/src/__tests__/xstatePersistence.store.test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,120 +1,121 @@ | ||
import {DataSource} from 'typeorm' | ||
import {DataStoreXStateStoreEntities, GetStateArgs, NonPersistedXStateStoreEvent, State, XStateStore} from '../index' | ||
import {DataStoreXStateStoreMigrations} from '../migrations' | ||
import { DataSource } from 'typeorm' | ||
import { DataStoreXStateStoreEntities, GetStateArgs, NonPersistedXStateStoreEvent, State, XStateStore } from '../index' | ||
import { DataStoreXStateStoreMigrations } from '../migrations' | ||
|
||
describe('Database entities tests', (): void => { | ||
let dbConnection: DataSource | ||
let xstateStore: XStateStore | ||
|
||
beforeEach(async (): Promise<void> => { | ||
dbConnection = await new DataSource({ | ||
type: 'sqlite', | ||
database: ':memory:', | ||
logging: 'all', | ||
migrationsRun: false, | ||
migrations: DataStoreXStateStoreMigrations, | ||
synchronize: false, | ||
entities: DataStoreXStateStoreEntities, | ||
}).initialize() | ||
await dbConnection.runMigrations() | ||
expect(await dbConnection.showMigrations()).toBeFalsy() | ||
xstateStore = new XStateStore(dbConnection) | ||
let dbConnection: DataSource | ||
let xstateStore: XStateStore | ||
|
||
beforeEach(async (): Promise<void> => { | ||
dbConnection = await new DataSource({ | ||
type: 'sqlite', | ||
database: ':memory:', | ||
logging: 'all', | ||
migrationsRun: false, | ||
migrations: DataStoreXStateStoreMigrations, | ||
synchronize: false, | ||
entities: DataStoreXStateStoreEntities, | ||
}).initialize() | ||
await dbConnection.runMigrations() | ||
expect(await dbConnection.showMigrations()).toBeFalsy() | ||
xstateStore = new XStateStore(dbConnection) | ||
}) | ||
|
||
afterEach(async (): Promise<void> => { | ||
await dbConnection.destroy() | ||
}) | ||
|
||
it('should store xstate event', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
createdAt: new Date(), | ||
updatedAt: new Date(), | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
|
||
const savedXStoreEvent: State = await xstateStore.saveState(xstateEvent) | ||
expect(savedXStoreEvent).toBeDefined() | ||
}) | ||
|
||
it('should get all state events', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
|
||
const stateEvent1: NonPersistedXStateStoreEvent = await xstateStore.saveState({ ...xstateEvent }) | ||
expect(stateEvent1).toBeDefined() | ||
|
||
const stateEvent2: NonPersistedXStateStoreEvent = await xstateStore.saveState({ ...xstateEvent }) | ||
expect(stateEvent2).toBeDefined() | ||
|
||
const result: Array<State> = await xstateStore.getStates() | ||
expect(result).toHaveLength(2) | ||
}) | ||
|
||
it('should retrieve an xstate event', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
|
||
const savedXStoreEvent1: State = await xstateStore.saveState(xstateEvent) | ||
expect(savedXStoreEvent1).toBeDefined() | ||
|
||
const result: State = await xstateStore.getState(xstateEvent) | ||
expect(result).toBeDefined() | ||
}) | ||
|
||
it('should return an error if type filter does not match', async (): Promise<void> => { | ||
const args: GetStateArgs = { | ||
type: 'unknown_event', | ||
} | ||
|
||
await expect(xstateStore.getState(args)).rejects.toEqual(Error('No state found for type: unknown_event')) | ||
}) | ||
|
||
it('should delete the expired records', async () => { | ||
const now = new Date() | ||
const newestXstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'test_type_1', | ||
createdAt: now, | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
const middleXstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'test_type_2', | ||
createdAt: new Date(+now - 30000), | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
|
||
const oldestXstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'test_type_3', | ||
createdAt: new Date(+now - 60000), | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id', | ||
} | ||
|
||
await xstateStore.saveState(oldestXstateEvent) | ||
await xstateStore.saveState(middleXstateEvent) | ||
await xstateStore.saveState(newestXstateEvent) | ||
|
||
await xstateStore.deleteState({ | ||
where: `created_at < datetime('now', :ttl)`, | ||
parameters: { ttl: '-30 seconds' }, | ||
}) | ||
|
||
afterEach(async (): Promise<void> => { | ||
await dbConnection.destroy() | ||
}) | ||
|
||
it('should store xstate event', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
createdAt: new Date(), | ||
updatedAt: new Date(), | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
|
||
const savedXStoreEvent: State = await xstateStore.saveState(xstateEvent) | ||
expect(savedXStoreEvent).toBeDefined() | ||
}) | ||
|
||
it('should get all state events', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
|
||
const stateEvent1: NonPersistedXStateStoreEvent = await xstateStore.saveState({...xstateEvent}) | ||
expect(stateEvent1).toBeDefined() | ||
|
||
const stateEvent2: NonPersistedXStateStoreEvent = await xstateStore.saveState({...xstateEvent}) | ||
expect(stateEvent2).toBeDefined() | ||
|
||
const result: Array<State> = await xstateStore.getStates() | ||
expect(result).toHaveLength(2) | ||
}) | ||
|
||
it('should retrieve an xstate event', async (): Promise<void> => { | ||
const xstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'b40b8474-58a2-4b23-9fde-bd6ee1902cdb', | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
|
||
const savedXStoreEvent1: State = await xstateStore.saveState(xstateEvent) | ||
expect(savedXStoreEvent1).toBeDefined() | ||
|
||
const result: State = await xstateStore.getState(xstateEvent) | ||
expect(result).toBeDefined() | ||
}) | ||
|
||
it('should return an error if type filter does not match', async (): Promise<void> => { | ||
const args: GetStateArgs = { | ||
type: 'unknown_event' | ||
} | ||
|
||
await expect(xstateStore.getState(args)).rejects.toEqual(Error('No state found for type: unknown_event')) | ||
}) | ||
|
||
it('should delete the expired records', async () => { | ||
const now = new Date() | ||
const newestXstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'test_type_1', | ||
createdAt: now, | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
const middleXstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'test_type_2', | ||
createdAt: new Date(+now - 30000), | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
|
||
const oldestXstateEvent: NonPersistedXStateStoreEvent = { | ||
state: 'test_state', | ||
type: 'test_type_3', | ||
createdAt: new Date(+now - 60000), | ||
completedAt: new Date(), | ||
tenantId: 'test_tenant_id' | ||
} | ||
|
||
await xstateStore.saveState(oldestXstateEvent) | ||
await xstateStore.saveState(middleXstateEvent) | ||
await xstateStore.saveState(newestXstateEvent) | ||
|
||
await xstateStore.deleteState({ | ||
where: `created_at < datetime('now', :ttl)`, parameters: { ttl: '-30 seconds' } | ||
}) | ||
|
||
await expect(xstateStore.getState({ type: 'test_type_1'})).resolves.toBeDefined() | ||
await expect(xstateStore.getState({ type: 'test_type_2'})).resolves.toBeDefined() | ||
await expect(xstateStore.getState({ type: 'test_type_3'})).rejects.toEqual(Error('No state found for type: test_type_3')) | ||
}) | ||
await expect(xstateStore.getState({ type: 'test_type_1' })).resolves.toBeDefined() | ||
await expect(xstateStore.getState({ type: 'test_type_2' })).resolves.toBeDefined() | ||
await expect(xstateStore.getState({ type: 'test_type_3' })).rejects.toEqual(Error('No state found for type: test_type_3')) | ||
}) | ||
}) |
44 changes: 22 additions & 22 deletions
44
packages/data-store/src/entities/xstatePersistence/StateEntity.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,35 +1,35 @@ | ||
import {BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn} from "typeorm" | ||
import {NonPersistedXStateStoreEvent} from "../../types"; | ||
import { BaseEntity, Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn } from 'typeorm' | ||
import { NonPersistedXStateStoreEvent } from '../../types' | ||
|
||
@Entity('StateEntity') | ||
export class StateEntity extends BaseEntity { | ||
@PrimaryGeneratedColumn('uuid', { name: 'id' }) | ||
id!: string | ||
@PrimaryGeneratedColumn('uuid', { name: 'id' }) | ||
id!: string | ||
|
||
@Column({ name: 'state', nullable: false }) | ||
state!: string | ||
@Column({ name: 'state', nullable: false }) | ||
state!: string | ||
|
||
@Column({ name: 'type', nullable: false }) | ||
type!: string | ||
@Column({ name: 'type', nullable: false }) | ||
type!: string | ||
|
||
@CreateDateColumn({ name: 'created_at', nullable: false }) | ||
createdAt!: Date | ||
@CreateDateColumn({ name: 'created_at', nullable: false }) | ||
createdAt!: Date | ||
|
||
@UpdateDateColumn({ name: 'updated_at', nullable: false }) | ||
updatedAt!: Date | ||
@UpdateDateColumn({ name: 'updated_at', nullable: false }) | ||
updatedAt!: Date | ||
|
||
@Column({ name: 'completed_at', type: 'datetime', nullable: true }) | ||
completedAt?: Date | ||
@Column({ name: 'completed_at', type: 'datetime', nullable: true }) | ||
completedAt?: Date | ||
|
||
@Column({ name: 'tenant_id', type: 'varchar', nullable: true }) | ||
tenantId?: string | ||
@Column({ name: 'tenant_id', type: 'varchar', nullable: true }) | ||
tenantId?: string | ||
} | ||
|
||
export const stateEntityFrom = (args: NonPersistedXStateStoreEvent): StateEntity => { | ||
const stateEntity = new StateEntity() | ||
stateEntity.state = args.state | ||
stateEntity.type = args.type | ||
stateEntity.completedAt = args.completedAt | ||
stateEntity.tenantId = args.tenantId | ||
return stateEntity | ||
const stateEntity = new StateEntity() | ||
stateEntity.state = args.state | ||
stateEntity.type = args.type | ||
stateEntity.completedAt = args.completedAt | ||
stateEntity.tenantId = args.tenantId | ||
return stateEntity | ||
} |
Oops, something went wrong.