From 24bd374baa0c1385d1e4743457f3164063d3a08c Mon Sep 17 00:00:00 2001 From: Simon Larsen Date: Fri, 6 Sep 2024 11:52:15 +0100 Subject: [PATCH] refactor: Update nullable property for endAnnouncementAt column in StatusPageAnnouncement model --- .../DatabaseModels/StatusPageAnnouncement.ts | 4 ++-- Common/Server/API/StatusPageAPI.ts | 2 +- .../1725618842598-MigrationName.ts | 17 +++++++++++++++++ .../Postgres/SchemaMigrations/Index.ts | 2 ++ .../Server/Services/BillingService.test.ts | 6 ++++++ .../Services/BillingServiceHelper.ts | 2 ++ .../Pages/StatusPages/View/Announcements.tsx | 3 ++- StatusPage/src/Pages/Announcement/List.tsx | 19 +++++++++++++------ 8 files changed, 45 insertions(+), 10 deletions(-) create mode 100644 Common/Server/Infrastructure/Postgres/SchemaMigrations/1725618842598-MigrationName.ts diff --git a/Common/Models/DatabaseModels/StatusPageAnnouncement.ts b/Common/Models/DatabaseModels/StatusPageAnnouncement.ts index 94303274f63..e90279e8c37 100644 --- a/Common/Models/DatabaseModels/StatusPageAnnouncement.ts +++ b/Common/Models/DatabaseModels/StatusPageAnnouncement.ts @@ -260,7 +260,7 @@ export default class StatusPageAnnouncement extends BaseModel { @TableColumn({ title: "End At", type: TableColumnType.Date, - required: true, + required: false, description: "When should this announcement hidden?", }) @ColumnAccessControl({ @@ -284,7 +284,7 @@ export default class StatusPageAnnouncement extends BaseModel { ], }) @Column({ - nullable: false, + nullable: true, type: ColumnType.Date, }) public endAnnouncementAt?: Date = undefined; diff --git a/Common/Server/API/StatusPageAPI.ts b/Common/Server/API/StatusPageAPI.ts index 706e38801b4..5e33aeda17f 100644 --- a/Common/Server/API/StatusPageAPI.ts +++ b/Common/Server/API/StatusPageAPI.ts @@ -840,7 +840,7 @@ export default class StatusPageAPI extends BaseAPI< query: { statusPages: objectId as any, showAnnouncementAt: QueryHelper.lessThan(today), - endAnnouncementAt: QueryHelper.greaterThan(today), + endAnnouncementAt: QueryHelper.greaterThanOrNull(today), projectId: statusPage.projectId!, }, select: { diff --git a/Common/Server/Infrastructure/Postgres/SchemaMigrations/1725618842598-MigrationName.ts b/Common/Server/Infrastructure/Postgres/SchemaMigrations/1725618842598-MigrationName.ts new file mode 100644 index 00000000000..603ab051886 --- /dev/null +++ b/Common/Server/Infrastructure/Postgres/SchemaMigrations/1725618842598-MigrationName.ts @@ -0,0 +1,17 @@ +import { MigrationInterface, QueryRunner } from "typeorm"; + +export class MigrationName1725618842598 implements MigrationInterface { + public name = "MigrationName1725618842598"; + + public async up(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "StatusPageAnnouncement" ALTER COLUMN "endAnnouncementAt" DROP NOT NULL`, + ); + } + + public async down(queryRunner: QueryRunner): Promise { + await queryRunner.query( + `ALTER TABLE "StatusPageAnnouncement" ALTER COLUMN "endAnnouncementAt" SET NOT NULL`, + ); + } +} diff --git a/Common/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts b/Common/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts index fd1520eeef7..69b23b1b5fb 100644 --- a/Common/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +++ b/Common/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts @@ -50,6 +50,7 @@ import { MigrationName1725360199561 } from "./1725360199561-MigrationName"; import { MigrationName1725379949648 } from "./1725379949648-MigrationName"; import { MigrationName1725551629492 } from "./1725551629492-MigrationName"; import { MigrationName1725556630384 } from "./1725556630384-MigrationName"; +import { MigrationName1725618842598 } from "./1725618842598-MigrationName"; export default [ InitialMigration, @@ -104,4 +105,5 @@ export default [ MigrationName1725379949648, MigrationName1725551629492, MigrationName1725556630384, + MigrationName1725618842598, ]; diff --git a/Common/Tests/Server/Services/BillingService.test.ts b/Common/Tests/Server/Services/BillingService.test.ts index 8216f029987..fc1674acb1a 100644 --- a/Common/Tests/Server/Services/BillingService.test.ts +++ b/Common/Tests/Server/Services/BillingService.test.ts @@ -1230,13 +1230,17 @@ describe("BillingService", () => { downloadableLink: "", status: "paid", subscriptionId: invoice.subscription, + invoiceNumber: invoice.number, + invoiceDate: new Date(invoice.created * 1000), }; }), ); + expect(mockStripe.invoices.list).toHaveBeenCalledWith({ customer: customerId, limit: 100, }); + }); it("should return an empty array if no invoices are found for the customer", async () => { @@ -1428,6 +1432,8 @@ describe("BillingService", () => { status: mockPaidInvoice.status, downloadableLink: "", subscriptionId: mockPaidInvoice.subscription, + invoiceNumber: mockPaidInvoice.number, + invoiceDate: new Date(mockPaidInvoice.created * 1000), }); expect(mockStripe.invoices.pay).toHaveBeenCalledWith( mockPaidInvoice.id, diff --git a/Common/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts b/Common/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts index 1ea821e85e1..9ebe67520db 100644 --- a/Common/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts +++ b/Common/Tests/Server/TestingUtils/Services/BillingServiceHelper.ts @@ -107,6 +107,8 @@ const getStripeInvoice: GetStripeInvoiceFunction = (): Stripe.Invoice => { currency: "usd", customer: Faker.generateRandomObjectID().toString(), subscription: Faker.generateRandomObjectID().toString(), + created: new Date().getTime() / 1000, + number: Faker.generateRandomString(), status: "paid", }; }; diff --git a/Dashboard/src/Pages/StatusPages/View/Announcements.tsx b/Dashboard/src/Pages/StatusPages/View/Announcements.tsx index 7ce5bef67ec..7602a9d481a 100644 --- a/Dashboard/src/Pages/StatusPages/View/Announcements.tsx +++ b/Dashboard/src/Pages/StatusPages/View/Announcements.tsx @@ -102,7 +102,7 @@ const StatusPageDelete: FunctionComponent = ( stepId: "more", title: "End Showing Announcement At", fieldType: FormFieldSchemaType.DateTime, - required: true, + required: false, placeholder: "Pick Date and Time", }, { @@ -171,6 +171,7 @@ const StatusPageDelete: FunctionComponent = ( }, title: "End Announcement At", type: FieldType.DateTime, + noValueMessage: "-", }, { field: { diff --git a/StatusPage/src/Pages/Announcement/List.tsx b/StatusPage/src/Pages/Announcement/List.tsx index 0c578d0d5db..b42daf6f99b 100644 --- a/StatusPage/src/Pages/Announcement/List.tsx +++ b/StatusPage/src/Pages/Announcement/List.tsx @@ -148,17 +148,24 @@ const Overview: FunctionComponent = ( const activeAnnouncement: Array = announcements.filter((announcement: StatusPageAnnouncement) => { - return OneUptimeDate.isBefore( - OneUptimeDate.getCurrentDate(), - announcement.endAnnouncementAt!, + return ( + !announcement.endAnnouncementAt || + (announcement.endAnnouncementAt && + OneUptimeDate.isBefore( + OneUptimeDate.getCurrentDate(), + announcement.endAnnouncementAt!, + )) ); }); const pastAnnouncement: Array = announcements.filter((announcement: StatusPageAnnouncement) => { - return OneUptimeDate.isAfter( - OneUptimeDate.getCurrentDate(), - announcement.endAnnouncementAt!, + return ( + announcement.endAnnouncementAt && + OneUptimeDate.isAfter( + OneUptimeDate.getCurrentDate(), + announcement.endAnnouncementAt!, + ) ); });