@oneuptime/common 7.0.4428 → 7.0.4518
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Models/DatabaseModels/Alert.ts +1 -1
- package/Models/DatabaseModels/AlertCustomField.ts +1 -1
- package/Models/DatabaseModels/BillingPaymentMethod.ts +1 -1
- package/Models/DatabaseModels/DatabaseBaseModel/FileModel.ts +1 -1
- package/Models/DatabaseModels/IncidentCustomField.ts +1 -1
- package/Models/DatabaseModels/Index.ts +2 -0
- package/Models/DatabaseModels/MonitorCustomField.ts +1 -1
- package/Models/DatabaseModels/OnCallDutyPolicyCustomField.ts +1 -1
- package/Models/DatabaseModels/ScheduledMaintenanceCustomField.ts +1 -1
- package/Models/DatabaseModels/ScheduledMaintenanceTemplate.ts +1 -1
- package/Models/DatabaseModels/StatusPageAnnouncement.ts +1 -1
- package/Models/DatabaseModels/StatusPageAnnouncementTemplate.ts +473 -0
- package/Models/DatabaseModels/StatusPageCustomField.ts +1 -1
- package/Server/API/FileAPI.ts +2 -2
- package/Server/API/StatusPageAPI.ts +4 -4
- package/Server/Infrastructure/Postgres/SchemaMigrations/1749813704371-MigrationName.ts +67 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/1750250435756-MigrationName.ts +59 -0
- package/Server/Infrastructure/Postgres/SchemaMigrations/Index.ts +4 -0
- package/Server/Middleware/ProjectAuthorization.ts +2 -4
- package/Server/Services/BillingPaymentMethodService.ts +1 -1
- package/Server/Services/Index.ts +2 -0
- package/Server/Services/StatusPageAnnouncementTemplateService.ts +10 -0
- package/Server/Utils/OpenAPI.ts +12 -10
- package/Server/Utils/Response.ts +1 -1
- package/Server/Utils/Workspace/Slack/Slack.ts +62 -10
- package/Tests/Server/Middleware/ProjectAuthorization.test.ts +3 -1
- package/Tests/UI/Components/FilePicker.test.tsx +2 -2
- package/Tests/UI/Components/Input.test.tsx +22 -0
- package/Tests/UI/Components/MarkdownEditor.test.tsx +61 -0
- package/Tests/UI/Components/TextArea.test.tsx +22 -0
- package/Types/Permission.ts +80 -8
- package/UI/Components/Checkbox/Checkbox.tsx +1 -1
- package/UI/Components/CodeEditor/CodeEditor.tsx +36 -2
- package/UI/Components/CustomFields/CustomFieldsDetail.tsx +3 -3
- package/UI/Components/Detail/Detail.tsx +3 -2
- package/UI/Components/Detail/Field.ts +1 -1
- package/UI/Components/Detail/FieldLabel.tsx +1 -1
- package/UI/Components/FilePicker/FilePicker.tsx +2 -2
- package/UI/Components/Forms/Fields/FormField.tsx +4 -1
- package/UI/Components/Forms/ModelForm.tsx +1 -1
- package/UI/Components/Forms/Types/Field.ts +4 -1
- package/UI/Components/Image/Image.tsx +2 -2
- package/UI/Components/Input/Input.tsx +2 -0
- package/UI/Components/Markdown.tsx/MarkdownEditor.tsx +2 -0
- package/UI/Components/ModelDetail/ModelDetail.tsx +1 -1
- package/UI/Components/ModelTable/BaseModelTable.tsx +1 -1
- package/UI/Components/TextArea/TextArea.tsx +2 -0
- package/UI/Utils/Markdown.tsx +22 -0
- package/Utils/Schema/AnalyticsModelSchema.ts +0 -5
- package/Utils/Schema/ModelSchema.ts +0 -26
- package/build/dist/Models/DatabaseModels/Alert.js +1 -1
- package/build/dist/Models/DatabaseModels/Alert.js.map +1 -1
- package/build/dist/Models/DatabaseModels/AlertCustomField.js +2 -2
- package/build/dist/Models/DatabaseModels/AlertCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js +2 -2
- package/build/dist/Models/DatabaseModels/BillingPaymentMethod.js.map +1 -1
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js +2 -2
- package/build/dist/Models/DatabaseModels/DatabaseBaseModel/FileModel.js.map +1 -1
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js +2 -2
- package/build/dist/Models/DatabaseModels/IncidentCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/Index.js +2 -0
- package/build/dist/Models/DatabaseModels/Index.js.map +1 -1
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js +2 -2
- package/build/dist/Models/DatabaseModels/MonitorCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js +2 -2
- package/build/dist/Models/DatabaseModels/OnCallDutyPolicyCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js +2 -2
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceCustomField.js.map +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js +1 -1
- package/build/dist/Models/DatabaseModels/ScheduledMaintenanceTemplate.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncement.js.map +1 -1
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js +488 -0
- package/build/dist/Models/DatabaseModels/StatusPageAnnouncementTemplate.js.map +1 -0
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js +2 -2
- package/build/dist/Models/DatabaseModels/StatusPageCustomField.js.map +1 -1
- package/build/dist/Server/API/FileAPI.js +2 -2
- package/build/dist/Server/API/FileAPI.js.map +1 -1
- package/build/dist/Server/API/StatusPageAPI.js +4 -4
- package/build/dist/Server/API/StatusPageAPI.js.map +1 -1
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1749813704371-MigrationName.js +30 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1749813704371-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1750250435756-MigrationName.js +26 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/1750250435756-MigrationName.js.map +1 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js +4 -0
- package/build/dist/Server/Infrastructure/Postgres/SchemaMigrations/Index.js.map +1 -1
- package/build/dist/Server/Middleware/ProjectAuthorization.js +2 -2
- package/build/dist/Server/Middleware/ProjectAuthorization.js.map +1 -1
- package/build/dist/Server/Services/BillingPaymentMethodService.js +1 -1
- package/build/dist/Server/Services/BillingPaymentMethodService.js.map +1 -1
- package/build/dist/Server/Services/Index.js +2 -0
- package/build/dist/Server/Services/Index.js.map +1 -1
- package/build/dist/Server/Services/StatusPageAnnouncementTemplateService.js +9 -0
- package/build/dist/Server/Services/StatusPageAnnouncementTemplateService.js.map +1 -0
- package/build/dist/Server/Utils/OpenAPI.js +12 -10
- package/build/dist/Server/Utils/OpenAPI.js.map +1 -1
- package/build/dist/Server/Utils/Response.js +1 -1
- package/build/dist/Server/Utils/Response.js.map +1 -1
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js +36 -0
- package/build/dist/Server/Utils/Workspace/Slack/Slack.js.map +1 -1
- package/build/dist/Tests/Server/Middleware/ProjectAuthorization.test.js +1 -1
- package/build/dist/Tests/Server/Middleware/ProjectAuthorization.test.js.map +1 -1
- package/build/dist/Tests/UI/Components/FilePicker.test.js +1 -1
- package/build/dist/Tests/UI/Components/FilePicker.test.js.map +1 -1
- package/build/dist/Tests/UI/Components/Input.test.js +16 -0
- package/build/dist/Tests/UI/Components/Input.test.js.map +1 -1
- package/build/dist/Tests/UI/Components/MarkdownEditor.test.js +25 -0
- package/build/dist/Tests/UI/Components/MarkdownEditor.test.js.map +1 -0
- package/build/dist/Tests/UI/Components/TextArea.test.js +16 -1
- package/build/dist/Tests/UI/Components/TextArea.test.js.map +1 -1
- package/build/dist/Types/Permission.js +69 -8
- package/build/dist/Types/Permission.js.map +1 -1
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js +29 -2
- package/build/dist/UI/Components/CodeEditor/CodeEditor.js.map +1 -1
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js +3 -3
- package/build/dist/UI/Components/CustomFields/CustomFieldsDetail.js.map +1 -1
- package/build/dist/UI/Components/Detail/Detail.js +3 -2
- package/build/dist/UI/Components/Detail/Detail.js.map +1 -1
- package/build/dist/UI/Components/FilePicker/FilePicker.js +2 -2
- package/build/dist/UI/Components/FilePicker/FilePicker.js.map +1 -1
- package/build/dist/UI/Components/Forms/Fields/FormField.js +2 -2
- package/build/dist/UI/Components/Forms/Fields/FormField.js.map +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js +1 -1
- package/build/dist/UI/Components/Forms/ModelForm.js.map +1 -1
- package/build/dist/UI/Components/Image/Image.js +2 -2
- package/build/dist/UI/Components/Image/Image.js.map +1 -1
- package/build/dist/UI/Components/Input/Input.js +1 -1
- package/build/dist/UI/Components/Input/Input.js.map +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js +1 -1
- package/build/dist/UI/Components/Markdown.tsx/MarkdownEditor.js.map +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js +1 -1
- package/build/dist/UI/Components/ModelDetail/ModelDetail.js.map +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js +1 -1
- package/build/dist/UI/Components/ModelTable/BaseModelTable.js.map +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js +1 -1
- package/build/dist/UI/Components/TextArea/TextArea.js.map +1 -1
- package/build/dist/UI/Utils/Markdown.js +15 -0
- package/build/dist/UI/Utils/Markdown.js.map +1 -0
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js +0 -2
- package/build/dist/Utils/Schema/AnalyticsModelSchema.js.map +1 -1
- package/build/dist/Utils/Schema/ModelSchema.js +2 -10
- package/build/dist/Utils/Schema/ModelSchema.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1749813704371 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1749813704371";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`CREATE TABLE "StatusPageAnnouncementTemplate" ("_id" uuid NOT NULL DEFAULT uuid_generate_v4(), "createdAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "updatedAt" TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT now(), "deletedAt" TIMESTAMP WITH TIME ZONE, "version" integer NOT NULL, "projectId" uuid NOT NULL, "templateName" character varying(100) NOT NULL, "templateDescription" character varying(500), "title" character varying(100) NOT NULL, "description" text NOT NULL, "shouldStatusPageSubscribersBeNotified" boolean NOT NULL DEFAULT true, "createdByUserId" uuid, "deletedByUserId" uuid, CONSTRAINT "PK_42d7cd04fe3d2c2e25288483072" PRIMARY KEY ("_id"))`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`CREATE INDEX "IDX_19d05157cdb68a582d2489bc9e" ON "StatusPageAnnouncementTemplate" ("projectId") `,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`CREATE TABLE "AnnouncementTemplateStatusPage" ("announcementTemplateId" uuid NOT NULL, "statusPageId" uuid NOT NULL, CONSTRAINT "PK_8434706f7e047041ee73a3e8b76" PRIMARY KEY ("announcementTemplateId", "statusPageId"))`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`CREATE INDEX "IDX_182e3a7c2c910755382971e473" ON "AnnouncementTemplateStatusPage" ("announcementTemplateId") `,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`CREATE INDEX "IDX_d64c5bcc98bd6a09fee1f5b247" ON "AnnouncementTemplateStatusPage" ("statusPageId") `,
|
|
21
|
+
);
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "StatusPageAnnouncementTemplate" ADD CONSTRAINT "FK_19d05157cdb68a582d2489bc9e1" FOREIGN KEY ("projectId") REFERENCES "Project"("_id") ON DELETE CASCADE ON UPDATE NO ACTION`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "StatusPageAnnouncementTemplate" ADD CONSTRAINT "FK_9f1b244a75d53bd2d208934551a" FOREIGN KEY ("createdByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "StatusPageAnnouncementTemplate" ADD CONSTRAINT "FK_ced5ce354456a65d71e39cd8e7d" FOREIGN KEY ("deletedByUserId") REFERENCES "User"("_id") ON DELETE SET NULL ON UPDATE NO ACTION`,
|
|
30
|
+
);
|
|
31
|
+
await queryRunner.query(
|
|
32
|
+
`ALTER TABLE "AnnouncementTemplateStatusPage" ADD CONSTRAINT "FK_182e3a7c2c910755382971e4739" FOREIGN KEY ("announcementTemplateId") REFERENCES "StatusPageAnnouncementTemplate"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
|
33
|
+
);
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "AnnouncementTemplateStatusPage" ADD CONSTRAINT "FK_d64c5bcc98bd6a09fee1f5b2473" FOREIGN KEY ("statusPageId") REFERENCES "StatusPage"("_id") ON DELETE CASCADE ON UPDATE CASCADE`,
|
|
36
|
+
);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
40
|
+
await queryRunner.query(
|
|
41
|
+
`ALTER TABLE "AnnouncementTemplateStatusPage" DROP CONSTRAINT "FK_d64c5bcc98bd6a09fee1f5b2473"`,
|
|
42
|
+
);
|
|
43
|
+
await queryRunner.query(
|
|
44
|
+
`ALTER TABLE "AnnouncementTemplateStatusPage" DROP CONSTRAINT "FK_182e3a7c2c910755382971e4739"`,
|
|
45
|
+
);
|
|
46
|
+
await queryRunner.query(
|
|
47
|
+
`ALTER TABLE "StatusPageAnnouncementTemplate" DROP CONSTRAINT "FK_ced5ce354456a65d71e39cd8e7d"`,
|
|
48
|
+
);
|
|
49
|
+
await queryRunner.query(
|
|
50
|
+
`ALTER TABLE "StatusPageAnnouncementTemplate" DROP CONSTRAINT "FK_9f1b244a75d53bd2d208934551a"`,
|
|
51
|
+
);
|
|
52
|
+
await queryRunner.query(
|
|
53
|
+
`ALTER TABLE "StatusPageAnnouncementTemplate" DROP CONSTRAINT "FK_19d05157cdb68a582d2489bc9e1"`,
|
|
54
|
+
);
|
|
55
|
+
await queryRunner.query(
|
|
56
|
+
`DROP INDEX "public"."IDX_d64c5bcc98bd6a09fee1f5b247"`,
|
|
57
|
+
);
|
|
58
|
+
await queryRunner.query(
|
|
59
|
+
`DROP INDEX "public"."IDX_182e3a7c2c910755382971e473"`,
|
|
60
|
+
);
|
|
61
|
+
await queryRunner.query(`DROP TABLE "AnnouncementTemplateStatusPage"`);
|
|
62
|
+
await queryRunner.query(
|
|
63
|
+
`DROP INDEX "public"."IDX_19d05157cdb68a582d2489bc9e"`,
|
|
64
|
+
);
|
|
65
|
+
await queryRunner.query(`DROP TABLE "StatusPageAnnouncementTemplate"`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
2
|
+
|
|
3
|
+
export class MigrationName1750250435756 implements MigrationInterface {
|
|
4
|
+
public name = "MigrationName1750250435756";
|
|
5
|
+
|
|
6
|
+
public async up(queryRunner: QueryRunner): Promise<void> {
|
|
7
|
+
await queryRunner.query(
|
|
8
|
+
`ALTER TABLE "File" RENAME COLUMN "type" TO "fileType"`,
|
|
9
|
+
);
|
|
10
|
+
await queryRunner.query(
|
|
11
|
+
`ALTER TABLE "BillingPaymentMethod" RENAME COLUMN "type" TO "paymentMethodType"`,
|
|
12
|
+
);
|
|
13
|
+
await queryRunner.query(
|
|
14
|
+
`ALTER TABLE "IncidentCustomField" RENAME COLUMN "type" TO "customFieldType"`,
|
|
15
|
+
);
|
|
16
|
+
await queryRunner.query(
|
|
17
|
+
`ALTER TABLE "MonitorCustomField" RENAME COLUMN "type" TO "customFieldType"`,
|
|
18
|
+
);
|
|
19
|
+
await queryRunner.query(
|
|
20
|
+
`ALTER TABLE "OnCallDutyPolicyCustomField" RENAME COLUMN "type" TO "customFieldType"`,
|
|
21
|
+
);
|
|
22
|
+
await queryRunner.query(
|
|
23
|
+
`ALTER TABLE "ScheduledMaintenanceCustomField" RENAME COLUMN "type" TO "customFieldType"`,
|
|
24
|
+
);
|
|
25
|
+
await queryRunner.query(
|
|
26
|
+
`ALTER TABLE "StatusPageCustomField" RENAME COLUMN "type" TO "customFieldType"`,
|
|
27
|
+
);
|
|
28
|
+
await queryRunner.query(
|
|
29
|
+
`ALTER TABLE "AlertCustomField" RENAME COLUMN "type" TO "customFieldType"`,
|
|
30
|
+
);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
public async down(queryRunner: QueryRunner): Promise<void> {
|
|
34
|
+
await queryRunner.query(
|
|
35
|
+
`ALTER TABLE "AlertCustomField" RENAME COLUMN "customFieldType" TO "type"`,
|
|
36
|
+
);
|
|
37
|
+
await queryRunner.query(
|
|
38
|
+
`ALTER TABLE "StatusPageCustomField" RENAME COLUMN "customFieldType" TO "type"`,
|
|
39
|
+
);
|
|
40
|
+
await queryRunner.query(
|
|
41
|
+
`ALTER TABLE "ScheduledMaintenanceCustomField" RENAME COLUMN "customFieldType" TO "type"`,
|
|
42
|
+
);
|
|
43
|
+
await queryRunner.query(
|
|
44
|
+
`ALTER TABLE "OnCallDutyPolicyCustomField" RENAME COLUMN "customFieldType" TO "type"`,
|
|
45
|
+
);
|
|
46
|
+
await queryRunner.query(
|
|
47
|
+
`ALTER TABLE "MonitorCustomField" RENAME COLUMN "customFieldType" TO "type"`,
|
|
48
|
+
);
|
|
49
|
+
await queryRunner.query(
|
|
50
|
+
`ALTER TABLE "IncidentCustomField" RENAME COLUMN "customFieldType" TO "type"`,
|
|
51
|
+
);
|
|
52
|
+
await queryRunner.query(
|
|
53
|
+
`ALTER TABLE "BillingPaymentMethod" RENAME COLUMN "paymentMethodType" TO "type"`,
|
|
54
|
+
);
|
|
55
|
+
await queryRunner.query(
|
|
56
|
+
`ALTER TABLE "File" RENAME COLUMN "fileType" TO "type"`,
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
@@ -136,6 +136,8 @@ import { MigrationName1747674762672 } from "./1747674762672-MigrationName";
|
|
|
136
136
|
import { MigrationName1748456937826 } from "./1748456937826-MigrationName";
|
|
137
137
|
import { MigrationName1749065784320 } from "./1749065784320-MigrationName";
|
|
138
138
|
import { MigrationName1749133333893 } from "./1749133333893-MigrationName";
|
|
139
|
+
import { MigrationName1749813704371 } from "./1749813704371-MigrationName";
|
|
140
|
+
import { MigrationName1750250435756 } from "./1750250435756-MigrationName";
|
|
139
141
|
|
|
140
142
|
export default [
|
|
141
143
|
InitialMigration,
|
|
@@ -276,4 +278,6 @@ export default [
|
|
|
276
278
|
MigrationName1748456937826,
|
|
277
279
|
MigrationName1749065784320,
|
|
278
280
|
MigrationName1749133333893,
|
|
281
|
+
MigrationName1749813704371,
|
|
282
|
+
MigrationName1750250435756,
|
|
279
283
|
];
|
|
@@ -77,7 +77,7 @@ export default class ProjectMiddleware {
|
|
|
77
77
|
|
|
78
78
|
if (!apiKey) {
|
|
79
79
|
throw new BadDataException(
|
|
80
|
-
"
|
|
80
|
+
"API Key not found in the request header. Please provide a valid API Key in the request header.",
|
|
81
81
|
);
|
|
82
82
|
}
|
|
83
83
|
|
|
@@ -99,9 +99,7 @@ export default class ProjectMiddleware {
|
|
|
99
99
|
tenantId = apiKeyModel?.projectId || null;
|
|
100
100
|
|
|
101
101
|
if (!tenantId) {
|
|
102
|
-
throw new BadDataException(
|
|
103
|
-
"Project ID not found for the provided API Key.",
|
|
104
|
-
);
|
|
102
|
+
throw new BadDataException("Invalid API Key");
|
|
105
103
|
}
|
|
106
104
|
|
|
107
105
|
(req as OneUptimeRequest).tenantId = tenantId;
|
|
@@ -64,7 +64,7 @@ export class Service extends DatabaseService<Model> {
|
|
|
64
64
|
|
|
65
65
|
billingPaymentMethod.projectId = project.id!;
|
|
66
66
|
|
|
67
|
-
billingPaymentMethod.
|
|
67
|
+
billingPaymentMethod.paymentMethodType = paymentMethod.type;
|
|
68
68
|
billingPaymentMethod.last4Digits = paymentMethod.last4Digits;
|
|
69
69
|
billingPaymentMethod.isDefault = paymentMethod.isDefault;
|
|
70
70
|
billingPaymentMethod.paymentProviderPaymentMethodId = paymentMethod.id;
|
package/Server/Services/Index.ts
CHANGED
|
@@ -94,6 +94,7 @@ import SmsLogService from "./SmsLogService";
|
|
|
94
94
|
import SmsService from "./SmsService";
|
|
95
95
|
import SpanService from "./SpanService";
|
|
96
96
|
import StatusPageAnnouncementService from "./StatusPageAnnouncementService";
|
|
97
|
+
import StatusPageAnnouncementTemplateService from "./StatusPageAnnouncementTemplateService";
|
|
97
98
|
import StatusPageCustomFieldService from "./StatusPageCustomFieldService";
|
|
98
99
|
import StatusPageDomainService from "./StatusPageDomainService";
|
|
99
100
|
import StatusPageFooterLinkService from "./StatusPageFooterLinkService";
|
|
@@ -249,6 +250,7 @@ const services: Array<BaseService> = [
|
|
|
249
250
|
SmsService,
|
|
250
251
|
|
|
251
252
|
StatusPageAnnouncementService,
|
|
253
|
+
StatusPageAnnouncementTemplateService,
|
|
252
254
|
StatusPageCustomFieldService,
|
|
253
255
|
StatusPageDomainService,
|
|
254
256
|
StatusPageFooterLinkService,
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import DatabaseService from "./DatabaseService";
|
|
2
|
+
import Model from "../../Models/DatabaseModels/StatusPageAnnouncementTemplate";
|
|
3
|
+
|
|
4
|
+
export class Service extends DatabaseService<Model> {
|
|
5
|
+
public constructor() {
|
|
6
|
+
super(Model);
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export default new Service();
|
package/Server/Utils/OpenAPI.ts
CHANGED
|
@@ -242,6 +242,7 @@ export default class OpenAPIUtil {
|
|
|
242
242
|
data.registry.registerPath({
|
|
243
243
|
method: "post",
|
|
244
244
|
path: `${model.crudApiPath}/get-list`,
|
|
245
|
+
operationId: `list${tableName}`,
|
|
245
246
|
summary: `List ${singularModelName}`,
|
|
246
247
|
description: `Endpoint to list all ${singularModelName} items`,
|
|
247
248
|
tags: [singularModelName],
|
|
@@ -301,6 +302,7 @@ export default class OpenAPIUtil {
|
|
|
301
302
|
data.registry.registerPath({
|
|
302
303
|
method: "post",
|
|
303
304
|
path: `${model.crudApiPath}/count`,
|
|
305
|
+
operationId: `count${tableName}`,
|
|
304
306
|
summary: `Count ${singularModelName}`,
|
|
305
307
|
description: `Endpoint to count ${singularModelName} items`,
|
|
306
308
|
tags: [singularModelName],
|
|
@@ -359,6 +361,7 @@ export default class OpenAPIUtil {
|
|
|
359
361
|
data.registry.registerPath({
|
|
360
362
|
method: "post",
|
|
361
363
|
path: `${model.crudApiPath}`,
|
|
364
|
+
operationId: `create${tableName}`,
|
|
362
365
|
summary: `Create ${singularModelName}`,
|
|
363
366
|
description: `Endpoint to create a new ${singularModelName}`,
|
|
364
367
|
tags: [singularModelName],
|
|
@@ -372,11 +375,6 @@ export default class OpenAPIUtil {
|
|
|
372
375
|
data: {
|
|
373
376
|
$ref: `#/components/schemas/${createSchemaName}`,
|
|
374
377
|
},
|
|
375
|
-
miscDataProps: {
|
|
376
|
-
type: "object",
|
|
377
|
-
description: "Additional data properties for creation",
|
|
378
|
-
additionalProperties: true,
|
|
379
|
-
},
|
|
380
378
|
select: { $ref: `#/components/schemas/${selectSchemaName}` },
|
|
381
379
|
},
|
|
382
380
|
required: ["data"],
|
|
@@ -466,6 +464,7 @@ export default class OpenAPIUtil {
|
|
|
466
464
|
data.registry.registerPath({
|
|
467
465
|
method: "post",
|
|
468
466
|
path: `${model.crudApiPath}/{id}`,
|
|
467
|
+
operationId: `get${tableName}`,
|
|
469
468
|
summary: `Get ${singularModelName}`,
|
|
470
469
|
description: `Endpoint to retrieve a single ${singularModelName} by ID`,
|
|
471
470
|
tags: [singularModelName],
|
|
@@ -544,6 +543,7 @@ export default class OpenAPIUtil {
|
|
|
544
543
|
data.registry.registerPath({
|
|
545
544
|
method: "put",
|
|
546
545
|
path: `${model.crudApiPath}/{id}`,
|
|
546
|
+
operationId: `update${tableName}`,
|
|
547
547
|
summary: `Update ${singularModelName}`,
|
|
548
548
|
description: `Endpoint to update an existing ${singularModelName}`,
|
|
549
549
|
tags: [singularModelName],
|
|
@@ -615,6 +615,7 @@ export default class OpenAPIUtil {
|
|
|
615
615
|
data.registry.registerPath({
|
|
616
616
|
method: "delete",
|
|
617
617
|
path: `${model.crudApiPath}/{id}`,
|
|
618
|
+
operationId: `delete${tableName}`,
|
|
618
619
|
summary: `Delete ${singularModelName}`,
|
|
619
620
|
description: `Endpoint to delete a ${singularModelName}`,
|
|
620
621
|
tags: [singularModelName],
|
|
@@ -859,6 +860,7 @@ export default class OpenAPIUtil {
|
|
|
859
860
|
data.registry.registerPath({
|
|
860
861
|
method: "post",
|
|
861
862
|
path: `${model.crudApiPath}/get-list`,
|
|
863
|
+
operationId: `list${tableName}`,
|
|
862
864
|
summary: `List ${singularModelName}`,
|
|
863
865
|
description: `Endpoint to list all ${singularModelName} items`,
|
|
864
866
|
tags: [singularModelName],
|
|
@@ -919,6 +921,7 @@ export default class OpenAPIUtil {
|
|
|
919
921
|
data.registry.registerPath({
|
|
920
922
|
method: "post",
|
|
921
923
|
path: `${model.crudApiPath}/count`,
|
|
924
|
+
operationId: `count${tableName}`,
|
|
922
925
|
summary: `Count ${singularModelName}`,
|
|
923
926
|
description: `Endpoint to count ${singularModelName} items`,
|
|
924
927
|
tags: [singularModelName],
|
|
@@ -977,6 +980,7 @@ export default class OpenAPIUtil {
|
|
|
977
980
|
data.registry.registerPath({
|
|
978
981
|
method: "post",
|
|
979
982
|
path: `${model.crudApiPath}`,
|
|
983
|
+
operationId: `create${tableName}`,
|
|
980
984
|
summary: `Create ${singularModelName}`,
|
|
981
985
|
description: `Endpoint to create a new ${singularModelName}`,
|
|
982
986
|
tags: [singularModelName],
|
|
@@ -990,11 +994,6 @@ export default class OpenAPIUtil {
|
|
|
990
994
|
data: {
|
|
991
995
|
$ref: `#/components/schemas/${createSchemaName}`,
|
|
992
996
|
},
|
|
993
|
-
miscDataProps: {
|
|
994
|
-
type: "object",
|
|
995
|
-
description: "Additional data properties for creation",
|
|
996
|
-
additionalProperties: true,
|
|
997
|
-
},
|
|
998
997
|
select: { $ref: `#/components/schemas/${selectSchemaName}` },
|
|
999
998
|
},
|
|
1000
999
|
required: ["data"],
|
|
@@ -1043,6 +1042,7 @@ export default class OpenAPIUtil {
|
|
|
1043
1042
|
data.registry.registerPath({
|
|
1044
1043
|
method: "post",
|
|
1045
1044
|
path: `${model.crudApiPath}/{id}`,
|
|
1045
|
+
operationId: `get${tableName}`,
|
|
1046
1046
|
summary: `Get ${singularModelName}`,
|
|
1047
1047
|
description: `Endpoint to retrieve a single ${singularModelName} by ID`,
|
|
1048
1048
|
tags: [singularModelName],
|
|
@@ -1115,6 +1115,7 @@ export default class OpenAPIUtil {
|
|
|
1115
1115
|
data.registry.registerPath({
|
|
1116
1116
|
method: "put",
|
|
1117
1117
|
path: `${model.crudApiPath}/{id}`,
|
|
1118
|
+
operationId: `update${tableName}`,
|
|
1118
1119
|
summary: `Update ${singularModelName}`,
|
|
1119
1120
|
description: `Endpoint to update an existing ${singularModelName}`,
|
|
1120
1121
|
tags: [singularModelName],
|
|
@@ -1186,6 +1187,7 @@ export default class OpenAPIUtil {
|
|
|
1186
1187
|
data.registry.registerPath({
|
|
1187
1188
|
method: "delete",
|
|
1188
1189
|
path: `${model.crudApiPath}/{id}`,
|
|
1190
|
+
operationId: `delete${tableName}`,
|
|
1189
1191
|
summary: `Delete ${singularModelName}`,
|
|
1190
1192
|
description: `Endpoint to delete a ${singularModelName}`,
|
|
1191
1193
|
tags: [singularModelName],
|
package/Server/Utils/Response.ts
CHANGED
|
@@ -75,7 +75,7 @@ export default class Response {
|
|
|
75
75
|
const oneUptimeResponse: OneUptimeResponse = res as OneUptimeResponse;
|
|
76
76
|
|
|
77
77
|
/** Set the proper content type */
|
|
78
|
-
oneUptimeResponse.set("Content-Type", file.
|
|
78
|
+
oneUptimeResponse.set("Content-Type", file.fileType);
|
|
79
79
|
oneUptimeResponse.status(200);
|
|
80
80
|
/** Return response */
|
|
81
81
|
// readstream.pipe(res);
|
|
@@ -60,6 +60,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
60
60
|
Authorization: `Bearer ${data.authToken}`,
|
|
61
61
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
62
62
|
},
|
|
63
|
+
{
|
|
64
|
+
retries: 3,
|
|
65
|
+
exponentialBackoff: true,
|
|
66
|
+
},
|
|
63
67
|
);
|
|
64
68
|
|
|
65
69
|
logger.debug("Response from Slack API for getting user info:");
|
|
@@ -122,6 +126,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
122
126
|
Authorization: `Bearer ${data.authToken}`,
|
|
123
127
|
["Content-Type"]: "application/json",
|
|
124
128
|
},
|
|
129
|
+
{
|
|
130
|
+
retries: 3,
|
|
131
|
+
exponentialBackoff: true,
|
|
132
|
+
},
|
|
125
133
|
);
|
|
126
134
|
|
|
127
135
|
if (result instanceof HTTPErrorResponse) {
|
|
@@ -202,6 +210,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
202
210
|
Authorization: `Bearer ${data.authToken}`,
|
|
203
211
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
204
212
|
},
|
|
213
|
+
{
|
|
214
|
+
retries: 3,
|
|
215
|
+
exponentialBackoff: true,
|
|
216
|
+
},
|
|
205
217
|
);
|
|
206
218
|
|
|
207
219
|
logger.debug("Response from Slack API for archiving channel:");
|
|
@@ -245,6 +257,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
245
257
|
Authorization: `Bearer ${data.authToken}`,
|
|
246
258
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
247
259
|
},
|
|
260
|
+
{
|
|
261
|
+
retries: 3,
|
|
262
|
+
exponentialBackoff: true,
|
|
263
|
+
},
|
|
248
264
|
);
|
|
249
265
|
|
|
250
266
|
logger.debug("Response from Slack API for joining channel:");
|
|
@@ -301,6 +317,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
301
317
|
Authorization: `Bearer ${data.authToken}`,
|
|
302
318
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
303
319
|
},
|
|
320
|
+
{
|
|
321
|
+
retries: 3,
|
|
322
|
+
exponentialBackoff: true,
|
|
323
|
+
},
|
|
304
324
|
);
|
|
305
325
|
|
|
306
326
|
logger.debug("Response from Slack API for inviting user:");
|
|
@@ -449,6 +469,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
449
469
|
Authorization: `Bearer ${data.authToken}`,
|
|
450
470
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
451
471
|
},
|
|
472
|
+
{
|
|
473
|
+
retries: 3,
|
|
474
|
+
exponentialBackoff: true,
|
|
475
|
+
},
|
|
452
476
|
);
|
|
453
477
|
|
|
454
478
|
logger.debug("Response from Slack API for getting channel info:");
|
|
@@ -519,6 +543,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
519
543
|
Authorization: `Bearer ${data.authToken}`,
|
|
520
544
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
521
545
|
},
|
|
546
|
+
{
|
|
547
|
+
retries: 3,
|
|
548
|
+
exponentialBackoff: true,
|
|
549
|
+
},
|
|
522
550
|
);
|
|
523
551
|
|
|
524
552
|
logger.debug("Response from Slack API for getting all channels:");
|
|
@@ -779,6 +807,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
779
807
|
Authorization: `Bearer ${data.authToken}`,
|
|
780
808
|
["Content-Type"]: "application/json",
|
|
781
809
|
},
|
|
810
|
+
{
|
|
811
|
+
retries: 3,
|
|
812
|
+
exponentialBackoff: true,
|
|
813
|
+
},
|
|
782
814
|
);
|
|
783
815
|
|
|
784
816
|
logger.debug("Response from Slack API for sending message:");
|
|
@@ -853,6 +885,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
853
885
|
Authorization: `Bearer ${data.authToken}`,
|
|
854
886
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
855
887
|
},
|
|
888
|
+
{
|
|
889
|
+
retries: 3,
|
|
890
|
+
exponentialBackoff: true,
|
|
891
|
+
},
|
|
856
892
|
);
|
|
857
893
|
|
|
858
894
|
logger.debug("Response from Slack API for creating channel:");
|
|
@@ -1233,6 +1269,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
1233
1269
|
Authorization: `Bearer ${data.authToken}`,
|
|
1234
1270
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
1235
1271
|
},
|
|
1272
|
+
{
|
|
1273
|
+
retries: 3,
|
|
1274
|
+
exponentialBackoff: true,
|
|
1275
|
+
},
|
|
1236
1276
|
);
|
|
1237
1277
|
|
|
1238
1278
|
if (response instanceof HTTPErrorResponse) {
|
|
@@ -1297,6 +1337,10 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
1297
1337
|
Authorization: `Bearer ${data.authToken}`,
|
|
1298
1338
|
["Content-Type"]: "application/x-www-form-urlencoded",
|
|
1299
1339
|
},
|
|
1340
|
+
{
|
|
1341
|
+
retries: 3,
|
|
1342
|
+
exponentialBackoff: true,
|
|
1343
|
+
},
|
|
1300
1344
|
);
|
|
1301
1345
|
|
|
1302
1346
|
logger.debug("Response from Slack API for getting channel members:");
|
|
@@ -1373,17 +1417,25 @@ export default class SlackUtil extends WorkspaceBase {
|
|
|
1373
1417
|
logger.debug(data);
|
|
1374
1418
|
|
|
1375
1419
|
const apiResult: HTTPResponse<JSONObject> | HTTPErrorResponse | null =
|
|
1376
|
-
await API.post(
|
|
1377
|
-
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
type: "
|
|
1382
|
-
text:
|
|
1420
|
+
await API.post(
|
|
1421
|
+
data.url,
|
|
1422
|
+
{
|
|
1423
|
+
blocks: [
|
|
1424
|
+
{
|
|
1425
|
+
type: "section",
|
|
1426
|
+
text: {
|
|
1427
|
+
type: "mrkdwn",
|
|
1428
|
+
text: `${data.text}`,
|
|
1429
|
+
},
|
|
1383
1430
|
},
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1431
|
+
],
|
|
1432
|
+
},
|
|
1433
|
+
undefined,
|
|
1434
|
+
{
|
|
1435
|
+
retries: 3,
|
|
1436
|
+
exponentialBackoff: true,
|
|
1437
|
+
},
|
|
1438
|
+
);
|
|
1387
1439
|
|
|
1388
1440
|
logger.debug("Response from Slack API for sending message via webhook:");
|
|
1389
1441
|
logger.debug(apiResult);
|
|
@@ -214,7 +214,9 @@ describe("ProjectMiddleware", () => {
|
|
|
214
214
|
);
|
|
215
215
|
|
|
216
216
|
expect(next).toHaveBeenCalledWith(
|
|
217
|
-
new BadDataException(
|
|
217
|
+
new BadDataException(
|
|
218
|
+
"API Key not found in the request header. Please provide a valid API Key in the request header.",
|
|
219
|
+
),
|
|
218
220
|
);
|
|
219
221
|
});
|
|
220
222
|
|
|
@@ -60,7 +60,7 @@ const mockCreateResponse: MockCreateResponseFunction = async (
|
|
|
60
60
|
{
|
|
61
61
|
file: (await file.arrayBuffer()) as Buffer,
|
|
62
62
|
name: file.name,
|
|
63
|
-
type: file.type,
|
|
63
|
+
type: file.type as MimeType,
|
|
64
64
|
slug: file.name,
|
|
65
65
|
isPublic: true,
|
|
66
66
|
},
|
|
@@ -75,7 +75,7 @@ const mockFileModel: MockFileModelFunction = async (
|
|
|
75
75
|
): Promise<FileModel> => {
|
|
76
76
|
const fileModel: FileModel = new FileModel(new ObjectID("123"));
|
|
77
77
|
fileModel.name = file.name;
|
|
78
|
-
fileModel.
|
|
78
|
+
fileModel.fileType = file.type as MimeType;
|
|
79
79
|
fileModel.slug = file.name;
|
|
80
80
|
fileModel.isPublic = true;
|
|
81
81
|
fileModel.file = (await file.arrayBuffer()) as Buffer;
|
|
@@ -39,6 +39,7 @@ describe("Input", () => {
|
|
|
39
39
|
error: "error",
|
|
40
40
|
outerDivClassName: "outerDivClassName",
|
|
41
41
|
autoFocus: true,
|
|
42
|
+
disableSpellCheck: false,
|
|
42
43
|
};
|
|
43
44
|
|
|
44
45
|
const { getByRole } = render(<Input {...props} />);
|
|
@@ -283,4 +284,25 @@ describe("Input", () => {
|
|
|
283
284
|
|
|
284
285
|
expect(getByRole("textbox")).toHaveFocus();
|
|
285
286
|
});
|
|
287
|
+
|
|
288
|
+
test("enables spellcheck by default", () => {
|
|
289
|
+
const { getByRole } = render(<Input />);
|
|
290
|
+
const input: HTMLElement = getByRole("textbox");
|
|
291
|
+
|
|
292
|
+
expect(input).toHaveAttribute("spellcheck", "true");
|
|
293
|
+
});
|
|
294
|
+
|
|
295
|
+
test("disables spellcheck when disableSpellCheck is true", () => {
|
|
296
|
+
const { getByRole } = render(<Input disableSpellCheck={true} />);
|
|
297
|
+
const input: HTMLElement = getByRole("textbox");
|
|
298
|
+
|
|
299
|
+
expect(input).toHaveAttribute("spellcheck", "false");
|
|
300
|
+
});
|
|
301
|
+
|
|
302
|
+
test("enables spellcheck when disableSpellCheck is false", () => {
|
|
303
|
+
const { getByRole } = render(<Input disableSpellCheck={false} />);
|
|
304
|
+
const input: HTMLElement = getByRole("textbox");
|
|
305
|
+
|
|
306
|
+
expect(input).toHaveAttribute("spellcheck", "true");
|
|
307
|
+
});
|
|
286
308
|
});
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import MarkdownEditor from "../../../UI/Components/Markdown.tsx/MarkdownEditor";
|
|
3
|
+
import { render, screen } from "@testing-library/react";
|
|
4
|
+
import { describe, expect, test } from "@jest/globals";
|
|
5
|
+
|
|
6
|
+
describe("MarkdownEditor with SpellCheck", () => {
|
|
7
|
+
test("should enable spell check by default", () => {
|
|
8
|
+
render(
|
|
9
|
+
<MarkdownEditor
|
|
10
|
+
initialValue="This is a test with speling errors"
|
|
11
|
+
placeholder="Enter markdown here..."
|
|
12
|
+
/>,
|
|
13
|
+
);
|
|
14
|
+
|
|
15
|
+
const textarea: HTMLTextAreaElement = screen.getByRole(
|
|
16
|
+
"textbox",
|
|
17
|
+
) as HTMLTextAreaElement;
|
|
18
|
+
expect(textarea.spellcheck).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test("should disable spell check when disableSpellCheck is true", () => {
|
|
22
|
+
render(
|
|
23
|
+
<MarkdownEditor
|
|
24
|
+
initialValue="This is a test with speling errors"
|
|
25
|
+
placeholder="Enter markdown here..."
|
|
26
|
+
disableSpellCheck={true}
|
|
27
|
+
/>,
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
const textarea: HTMLTextAreaElement = screen.getByRole(
|
|
31
|
+
"textbox",
|
|
32
|
+
) as HTMLTextAreaElement;
|
|
33
|
+
expect(textarea.spellcheck).toBe(false);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
test("should handle spell check prop changes", () => {
|
|
37
|
+
const { rerender } = render(
|
|
38
|
+
<MarkdownEditor
|
|
39
|
+
initialValue="This is a test with speling errors"
|
|
40
|
+
placeholder="Enter markdown here..."
|
|
41
|
+
disableSpellCheck={false}
|
|
42
|
+
/>,
|
|
43
|
+
);
|
|
44
|
+
|
|
45
|
+
let textarea: HTMLTextAreaElement = screen.getByRole(
|
|
46
|
+
"textbox",
|
|
47
|
+
) as HTMLTextAreaElement;
|
|
48
|
+
expect(textarea.spellcheck).toBe(true);
|
|
49
|
+
|
|
50
|
+
rerender(
|
|
51
|
+
<MarkdownEditor
|
|
52
|
+
initialValue="This is a test with speling errors"
|
|
53
|
+
placeholder="Enter markdown here..."
|
|
54
|
+
disableSpellCheck={true}
|
|
55
|
+
/>,
|
|
56
|
+
);
|
|
57
|
+
|
|
58
|
+
textarea = screen.getByRole("textbox") as HTMLTextAreaElement;
|
|
59
|
+
expect(textarea.spellcheck).toBe(false);
|
|
60
|
+
});
|
|
61
|
+
});
|
|
@@ -25,6 +25,7 @@ describe("TextArea", () => {
|
|
|
25
25
|
tabIndex={1}
|
|
26
26
|
error="error"
|
|
27
27
|
autoFocus={true}
|
|
28
|
+
disableSpellCheck={false}
|
|
28
29
|
/>,
|
|
29
30
|
);
|
|
30
31
|
const textarea: HTMLElement = getByRole("textbox");
|
|
@@ -150,4 +151,25 @@ describe("TextArea", () => {
|
|
|
150
151
|
expect(getByDisplayValue("")).toBeInTheDocument();
|
|
151
152
|
expect(queryByDisplayValue("\n")).not.toBeInTheDocument();
|
|
152
153
|
});
|
|
154
|
+
|
|
155
|
+
test("enables spellcheck by default", () => {
|
|
156
|
+
const { getByRole } = render(<TextArea />);
|
|
157
|
+
const textarea: HTMLElement = getByRole("textbox");
|
|
158
|
+
|
|
159
|
+
expect(textarea).toHaveAttribute("spellcheck", "true");
|
|
160
|
+
});
|
|
161
|
+
|
|
162
|
+
test("disables spellcheck when disableSpellCheck is true", () => {
|
|
163
|
+
const { getByRole } = render(<TextArea disableSpellCheck={true} />);
|
|
164
|
+
const textarea: HTMLElement = getByRole("textbox");
|
|
165
|
+
|
|
166
|
+
expect(textarea).toHaveAttribute("spellcheck", "false");
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test("enables spellcheck when disableSpellCheck is false", () => {
|
|
170
|
+
const { getByRole } = render(<TextArea disableSpellCheck={false} />);
|
|
171
|
+
const textarea: HTMLElement = getByRole("textbox");
|
|
172
|
+
|
|
173
|
+
expect(textarea).toHaveAttribute("spellcheck", "true");
|
|
174
|
+
});
|
|
153
175
|
});
|