feat(caprover): allow to trigger an application update
+ added test coverage
This commit is contained in:
43
domain/AppQueries.test.ts
Normal file
43
domain/AppQueries.test.ts
Normal file
@@ -0,0 +1,43 @@
|
||||
import { beforeEach, describe, expect, it } from "bun:test";
|
||||
import { ApplicationUpdateStarted } from "./events/ApplicationUpdateStarted";
|
||||
import { TestApp } from "./testing/TestApp";
|
||||
|
||||
describe("AppQueries", () => {
|
||||
describe("pendingApplicationUpdates", () => {
|
||||
let app: TestApp;
|
||||
beforeEach(() => {
|
||||
app = new TestApp([
|
||||
new ApplicationUpdateStarted(
|
||||
{ id: "mail", newVersion: "1.0.0" },
|
||||
new Date()
|
||||
),
|
||||
new ApplicationUpdateStarted(
|
||||
{ id: "blog", newVersion: "10.0.1" },
|
||||
new Date()
|
||||
),
|
||||
]);
|
||||
});
|
||||
|
||||
it("should return an empty array when there are no pending updates", () => {
|
||||
const app = new TestApp();
|
||||
expect(app.queries.pendingApplicationUpdates()).toEqual([]);
|
||||
});
|
||||
|
||||
it("should return all pending updates when no appName is provided", () => {
|
||||
expect(app.queries.pendingApplicationUpdates()).toEqual([
|
||||
{ id: "mail", newVersion: "1.0.0" },
|
||||
{ id: "blog", newVersion: "10.0.1" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should return all pending updates for the provided application", () => {
|
||||
expect(app.queries.pendingApplicationUpdates("mail")).toEqual([
|
||||
{ id: "mail", newVersion: "1.0.0" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("should return an empty array when there are no pending updates for the provided appName", () => {
|
||||
expect(app.queries.pendingApplicationUpdates("unknown")).toEqual([]);
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -5,7 +5,10 @@ export default class AppQueries {
|
||||
constructor(private readonly projections: AppProjections) {}
|
||||
|
||||
pendingApplicationUpdates(appName?: string): UpdateDefinition[] {
|
||||
// TODO: Implement filtering by appName
|
||||
return this.projections.ApplicationUpdates.getPendingUpdates();
|
||||
const updates = this.projections.ApplicationUpdates.getPendingUpdates();
|
||||
if (!appName) {
|
||||
return updates;
|
||||
}
|
||||
return updates.filter((update) => update.id === appName);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ export default class ApplicationUpdates implements DomainProjection {
|
||||
private readonly pendingUpdates: UpdateDefinition[] = [];
|
||||
handle(event: DomainEvent<any>): void {
|
||||
if (event.type === "ApplicationUpdateStarted") {
|
||||
console.log("ApplicationUpdateStarted", event.payload);
|
||||
this.pendingUpdates.push(event.payload);
|
||||
}
|
||||
}
|
||||
|
||||
44
domain/testing/TestApp.ts
Normal file
44
domain/testing/TestApp.ts
Normal file
@@ -0,0 +1,44 @@
|
||||
import AppProjections from "../AppProjections";
|
||||
import AppQueries from "../AppQueries";
|
||||
import EventStore from "../EventStore";
|
||||
|
||||
export class TestApp {
|
||||
readonly eventStore: InMemoryEventStore = new InMemoryEventStore();
|
||||
readonly projections: AppProjections = new AppProjections();
|
||||
readonly queries: AppQueries = new AppQueries(this.projections);
|
||||
|
||||
constructor(history: DomainEvent<any>[] = []) {
|
||||
this.projections.getAll().forEach((projection) => {
|
||||
this.eventStore.subscribe(projection);
|
||||
});
|
||||
|
||||
for (const event of history) {
|
||||
this.eventStore.append(event);
|
||||
}
|
||||
}
|
||||
}
|
||||
class InMemoryEventStore implements EventStore {
|
||||
private handlers: DomainProjection[] = [];
|
||||
private readonly events: DomainEvent<any>[] = [];
|
||||
|
||||
async append(event: DomainEvent<any>): Promise<void> {
|
||||
this.events.push(event);
|
||||
for (const handler of this.handlers) {
|
||||
handler.handle(event);
|
||||
}
|
||||
}
|
||||
|
||||
subscribe(projection: DomainProjection): void {
|
||||
this.handlers.push(projection);
|
||||
}
|
||||
|
||||
async replay(): Promise<void> {
|
||||
throw new Error(
|
||||
"Replay is not relevant for InMemoryEventStore. Use append instead."
|
||||
);
|
||||
}
|
||||
|
||||
getAllEvents(): DomainEvent<any>[] {
|
||||
return this.events;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user