gitpod/components/gitpod-db/src/accounting-db.spec.db.ts
2022-03-14 21:48:21 +05:30

151 lines
6.6 KiB
TypeScript

/**
* Copyright (c) 2021 Gitpod GmbH. All rights reserved.
* Licensed under the Gitpod Enterprise Source Code License,
* See License.enterprise.txt in the project root folder.
*/
import { Subscription } from "@gitpod/gitpod-protocol/lib/accounting-protocol";
import * as chai from "chai";
import { suite, test, timeout } from "mocha-typescript";
import { QueryRunner } from "typeorm";
import { AccountingDB } from "./accounting-db";
import { oneMonthLater, rightAfter, rightBefore } from "@gitpod/gitpod-protocol/lib/util/timeutil";
import { DBAccountEntry } from "./typeorm/entity/db-account-entry";
import { TransactionalAccountingDBImpl } from "./typeorm/accounting-db-impl";
import { DBWorkspace } from "./typeorm/entity/db-workspace";
import { DBWorkspaceInstance } from "./typeorm/entity/db-workspace-instance";
import { DBSubscription } from "./typeorm/entity/db-subscription";
import { testContainer } from "./test-container";
import { TypeORM } from "./typeorm/typeorm";
const expect = chai.expect;
@suite
@timeout(5000)
export class AccountingDBSpec {
typeORM = testContainer.get<TypeORM>(TypeORM);
db: AccountingDB;
queryRunner: QueryRunner;
async before() {
const connection = await this.typeORM.getConnection();
const manager = connection.manager;
await manager.clear(DBAccountEntry);
await manager.clear(DBSubscription);
await manager.clear(DBWorkspaceInstance);
await manager.clear(DBWorkspace);
this.queryRunner = connection.createQueryRunner();
await this.queryRunner.connect();
await this.queryRunner.startTransaction();
this.db = new TransactionalAccountingDBImpl(this.queryRunner.manager);
}
async after() {
this.queryRunner.rollbackTransaction();
}
@test public async subscriptionFixedPeriod() {
const now = new Date().toISOString();
const later = oneMonthLater(now, 31);
const inBetween = new Date(0.5 * (new Date(now).getTime() + new Date(later).getTime())).toISOString();
const subscription = <Subscription>{
userId: "Now open",
startDate: now,
endDate: later,
amount: 1.01,
planId: "test",
};
await this.db.newSubscription(subscription);
// date inclusion
expectExactlyOne(await this.db.findActiveSubscriptions(now, now), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(now, inBetween), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(inBetween, later), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(now, later), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(rightBefore(later), rightBefore(later)), subscription);
// date exclusion
expect(await this.db.findActiveSubscriptions(later, later)).to.be.empty;
expect(await this.db.findActiveSubscriptions(rightBefore(now), rightBefore(now))).to.be.empty;
}
@test public async subscriptionOpenEnd() {
const now = new Date().toISOString();
const later = oneMonthLater(now, 31);
const inBetween = new Date(0.5 * (new Date(now).getTime() + new Date(later).getTime())).toISOString();
const subscription = <Subscription>{
userId: "Open ended",
startDate: now,
endDate: undefined, // open ended
amount: 1.01,
planId: "test",
};
await this.db.newSubscription(subscription);
// date inclusion
expectExactlyOne(await this.db.findActiveSubscriptions(now, now), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(later, later), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(now, inBetween), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(inBetween, later), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(now, later), subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(rightAfter(later), rightAfter(later)), subscription);
// date exclusion
expect(await this.db.findActiveSubscriptions(rightBefore(now), rightBefore(now))).to.be.empty;
}
@test public async subscriptionUpdate() {
const now = new Date().toISOString();
const later = oneMonthLater(now, 31);
const subscription = <Subscription>{
userId: "Open ended",
startDate: now,
endDate: undefined, // open ended
amount: 1.01,
planId: "test",
};
const dbSubscription = await this.db.newSubscription(subscription);
expectExactlyOne(await this.db.findActiveSubscriptions(now, rightAfter(later)), subscription);
expect(await this.db.findActiveSubscriptions(rightBefore(now), rightBefore(now))).to.be.empty;
Subscription.cancelSubscription(dbSubscription, later);
await this.db.storeSubscription(dbSubscription);
expect(await this.db.findActiveSubscriptions(rightAfter(later), rightAfter(later))).to.be.empty;
await this.db.storeSubscription(dbSubscription);
expect(await this.db.findActiveSubscriptions(rightAfter(later), rightAfter(later))).to.be.empty;
}
@test public async subscriptionsForUser() {
const now = new Date().toISOString();
const later = oneMonthLater(now, 31);
const subscription = <Subscription>{
userId: "Open ended",
startDate: now,
endDate: undefined, // open ended
amount: 1.01,
planId: "test",
};
let dbSubscription = await this.db.newSubscription(subscription);
expectExactlyOne(await this.db.findActiveSubscriptionsForUser(subscription.userId, now), subscription);
expect(await this.db.findActiveSubscriptionsForUser(subscription.userId, rightBefore(now))).to.be.an("array")
.and.empty;
expectExactlyOne(await this.db.findActiveSubscriptionsForUser(subscription.userId, later), subscription);
Subscription.cancelSubscription(dbSubscription, later);
await this.db.storeSubscription(dbSubscription);
expectExactlyOne(
await this.db.findActiveSubscriptionsForUser(subscription.userId, rightBefore(later)),
dbSubscription,
);
expect(await this.db.findActiveSubscriptionsForUser(subscription.userId, later)).to.be.an("array").and.empty;
}
}
const expectExactlyOne = <T>(result: T[], expectation: T) => {
expect(result.length).to.be.equal(1);
expect(result[0]).to.deep.include(expectation);
};
module.exports = new AccountingDBSpec();