Skip to content

Commit 0da7ca3

Browse files
Merge pull request #908 from sparrowapp-dev/release/2.35.0
Release/2.35.0 to Dev [Test flow test data Implementation]
2 parents e83eab8 + bcc0951 commit 0da7ca3

12 files changed

Lines changed: 2105 additions & 316 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "project-sparrow-api",
3-
"version": "2.34.0",
3+
"version": "2.35.0",
44
"description": "Backend APIs for Project Sparrow.",
55
"author": "techdome",
66
"license": "",

src/modules/common/enum/testflow.enum.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,21 @@ export interface EmailData {
3737
scheduleRunPassedCount: number;
3838
scheduleRunFailedCount: number;
3939
scheduleRunTotalRequest: number;
40-
scheduleRunPassPercentage: string;
40+
scheduleRunPassPercentage: string;
4141
scheduleTotalTime: string | number;
4242
scheduleRunEnvName: string;
4343
isSuccess: boolean;
4444
isFailed: boolean;
4545
isPartial: boolean;
46+
testflowDataSummary?: DatasetSummaryItem[];
47+
}
48+
49+
export interface DatasetSummaryItem {
50+
datasetName: string;
51+
requestCount: number;
52+
passedCount: number;
53+
failedCount: number;
54+
duration: string;
4655
}
4756

4857
export interface OnceConfig {

src/modules/common/models/testflow.model.ts

Lines changed: 191 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,26 @@ import {
2121
import { Auth, KeyValue } from "./collection.rxdb.model";
2222
import { AuthModeEnum, BodyModeEnum } from "./collection.model";
2323
import { HTTPMethods } from "fastify";
24-
import { DayOfWeek, NotificationReceiveType, RequestDataTypeEnum, RunCycleEnum, } from "../enum/testflow.enum";
24+
import {
25+
DayOfWeek,
26+
NotificationReceiveType,
27+
RequestDataTypeEnum,
28+
RunCycleEnum,
29+
} from "../enum/testflow.enum";
2530

2631
export class SparrowRequestBody {
2732
raw?: string;
2833
urlencoded?: KeyValue[];
2934
formdata?: FormData;
3035
}
3136

32-
3337
export class FormDataKeyValue {
3438
key: string;
3539
value: string | unknown;
3640
checked: boolean;
3741
type: "text" | "file";
3842
}
3943

40-
4144
interface FormData {
4245
text: FormDataKeyValue[];
4346
}
@@ -227,6 +230,78 @@ export class TestflowNodes {
227230
data?: NodeData;
228231
}
229232

233+
// Main TestflowDataSet class
234+
export class TestflowDataSet {
235+
@IsArray()
236+
@IsNotEmpty()
237+
dataSet: Record<string, string | number | boolean | null>[];
238+
}
239+
240+
export enum FormatType {
241+
JSON = "JSON",
242+
CSV = "CSV",
243+
}
244+
245+
export class TestflowDataSetItem {
246+
@IsString()
247+
@ApiProperty({ required: true, example: "uuid" })
248+
id: string;
249+
250+
@IsString()
251+
@ApiProperty({ required: true, example: "testflow-dataset-name" })
252+
@IsNotEmpty()
253+
name: string;
254+
255+
@ValidateNested()
256+
@Type(() => TestflowDataSet)
257+
item: TestflowDataSet;
258+
259+
@IsString()
260+
@IsNotEmpty()
261+
formatType: FormatType;
262+
263+
@IsString()
264+
@IsNotEmpty()
265+
fileSize: string;
266+
267+
@IsDate()
268+
@IsOptional()
269+
createdAt?: Date;
270+
271+
@IsDate()
272+
@IsOptional()
273+
updatedAt?: Date;
274+
275+
@IsString()
276+
@IsOptional()
277+
createdBy?: string;
278+
279+
@IsString()
280+
@IsOptional()
281+
updatedBy?: string;
282+
}
283+
284+
export class TestflowDataSetItemDto {
285+
@IsArray()
286+
@IsNotEmpty()
287+
dataSet: Record<string, string | number | boolean | null>[];
288+
}
289+
290+
export class TestflowDataSetDto {
291+
@ValidateNested()
292+
@Type(() => TestflowDataSetItemDto)
293+
item: TestflowDataSetItemDto;
294+
295+
@IsString()
296+
@IsNotEmpty()
297+
formatType: FormatType;
298+
299+
@IsString()
300+
@IsOptional()
301+
@ApiProperty({ required: true, example: "testflow-dataset-name" })
302+
name: string;
303+
}
304+
230305
/**
231306
* Represents a Testflow, containing nodes and edges.
232307
*/
@@ -257,6 +332,12 @@ export class Testflow {
257332
@IsOptional()
258333
schedules?: TestflowSchedular[];
259334

335+
@IsArray()
336+
@Type(() => TestflowDataSetItem)
337+
@ValidateNested({ each: true })
338+
@IsOptional()
339+
datasets?: TestflowDataSetItem[];
340+
260341
@IsDate()
261342
@IsOptional()
262343
createdAt?: Date;
@@ -363,7 +444,7 @@ export class TestFlowSchedularRunHistory {
363444

364445
@IsArray()
365446
@IsOptional()
366-
responses?:TestflowSchedularHistoryResponse[];
447+
responses?: TestflowSchedularHistoryResponse[];
367448

368449
@IsArray()
369450
@Type(() => TestflowEdges)
@@ -406,6 +487,79 @@ export class TestFlowSchedularRunHistory {
406487
updatedBy?: string;
407488
}
408489

490+
export class TestflowSchedularDataSetHistory {
491+
@IsString()
492+
@ApiProperty({ required: true, example: "uuid" })
493+
id: string;
494+
495+
@IsArray()
496+
@Type(() => TestflowDataSetRunHistoryRequest)
497+
@ValidateNested({ each: true })
498+
@IsOptional()
499+
schedularDataRunHistory?: TestflowDataSetRunHistoryRequest[];
500+
501+
@IsArray()
502+
@Type(() => TestflowEdges)
503+
@ValidateNested({ each: true })
504+
@IsOptional()
505+
edges?: TestflowEdges[];
506+
507+
@IsArray()
508+
@Type(() => TestflowNodes)
509+
@ValidateNested({ each: true })
510+
@IsOptional()
511+
nodes?: TestflowNodes[];
512+
513+
@IsBoolean()
514+
isScheduled: boolean;
515+
516+
@IsString()
517+
@IsNotEmpty()
518+
status: string;
519+
520+
@IsDate()
521+
@IsOptional()
522+
createdAt?: Date;
523+
524+
@IsDate()
525+
@IsOptional()
526+
updatedAt?: Date;
527+
528+
@IsString()
529+
@IsOptional()
530+
createdBy?: string;
531+
532+
@IsString()
533+
@IsOptional()
534+
updatedBy?: string;
535+
}
536+
537+
export class TestflowDataSetRunHistoryRequest {
538+
@IsString()
539+
@IsNotEmpty()
540+
failedRequests: number;
541+
542+
@IsArray()
543+
@IsOptional()
544+
requests?: TestflowSchedularHistoryRequest[];
545+
546+
@IsArray()
547+
@IsOptional()
548+
responses?: TestflowSchedularHistoryResponse[];
549+
550+
@IsString()
551+
@IsNotEmpty()
552+
status: string;
553+
554+
@IsNumber()
555+
@IsNotEmpty()
556+
successRequests: number;
557+
558+
@IsString()
559+
@IsNotEmpty()
560+
totalTime: string;
561+
}
562+
409563
export class NotificationDto {
410564
@ApiProperty({
411565
required: false,
@@ -429,7 +583,7 @@ export class RunConfigurationDto {
429583
required: true,
430584
enum: RunCycleEnum,
431585
example: RunCycleEnum.DAILY,
432-
description: "Type of run cycle"
586+
description: "Type of run cycle",
433587
})
434588
@IsEnum(RunCycleEnum)
435589
runCycle: RunCycleEnum;
@@ -438,7 +592,8 @@ export class RunConfigurationDto {
438592
@ApiProperty({
439593
required: false,
440594
example: "2025-12-25T15:30:00.000Z",
441-
description: "ISO date string for one-time execution (required for ONCE type)"
595+
description:
596+
"ISO date string for one-time execution (required for ONCE type)",
442597
})
443598
@IsISO8601()
444599
@IsOptional()
@@ -450,7 +605,7 @@ export class RunConfigurationDto {
450605
example: 2,
451606
minimum: 1,
452607
maximum: 24,
453-
description: "Interval in hours (required for HOURLY type)"
608+
description: "Interval in hours (required for HOURLY type)",
454609
})
455610
@IsInt()
456611
@Min(1)
@@ -462,8 +617,9 @@ export class RunConfigurationDto {
462617
@ApiProperty({
463618
required: false,
464619
example: [1, 3, 5], // Monday, Wednesday, Friday
465-
description: "Array of days (0=Sunday, 1=Monday, ..., 6=Saturday) - required for WEEKLY type",
466-
type: [Number]
620+
description:
621+
"Array of days (0=Sunday, 1=Monday, ..., 6=Saturday) - required for WEEKLY type",
622+
type: [Number],
467623
})
468624
@IsArray()
469625
@IsInt({ each: true })
@@ -477,12 +633,13 @@ export class RunConfigurationDto {
477633
@ApiProperty({
478634
required: false,
479635
example: "14:30",
480-
description: "Time in HH:mm format - REQUIRED for DAILY (runs daily at this time), REQUIRED for WEEKLY (runs on selected days at this time), OPTIONAL for HOURLY (start time)"
636+
description:
637+
"Time in HH:mm format - REQUIRED for DAILY (runs daily at this time), REQUIRED for WEEKLY (runs on selected days at this time), OPTIONAL for HOURLY (start time)",
481638
})
482639
@IsString()
483640
@IsOptional()
484641
@Transform(({ value }) => {
485-
if (typeof value === 'string' && /^\d{2}:\d{2}$/.test(value)) {
642+
if (typeof value === "string" && /^\d{2}:\d{2}$/.test(value)) {
486643
return value;
487644
}
488645
return value;
@@ -529,7 +686,15 @@ export class TestflowSchedular {
529686
@IsBoolean()
530687
@ApiProperty({ required: true, example: true })
531688
@IsOptional()
532-
isActive:boolean;
689+
isActive: boolean;
690+
691+
@IsString()
692+
@IsOptional()
693+
testflowDataSetId?: string;
694+
695+
@IsString()
696+
@IsOptional()
697+
testflowDataSetName?: string;
533698

534699
@ApiProperty({
535700
required: false,
@@ -560,14 +725,20 @@ export class TestflowSchedular {
560725
@IsString()
561726
@ApiProperty({ required: true, example: "test" })
562727
@IsOptional()
563-
schedularName?:string;
728+
schedularName?: string;
564729

565730
@IsArray()
566731
@Type(() => TestFlowSchedularRunHistory)
567732
@ValidateNested({ each: true })
568733
@IsOptional()
569734
schedularRunHistory?: TestFlowSchedularRunHistory[];
570735

736+
@IsArray()
737+
@Type(() => TestflowSchedularDataSetHistory)
738+
@ValidateNested({ each: true })
739+
@IsOptional()
740+
schedularDataSetHistory?: TestflowSchedularDataSetHistory[];
741+
571742
@IsDate()
572743
@IsOptional()
573744
createdAt?: Date;
@@ -584,3 +755,10 @@ export class TestflowSchedular {
584755
@IsOptional()
585756
updatedBy?: string;
586757
}
758+
759+
export class RunScheduleTestDataSetDto {
760+
@IsString()
761+
@ApiProperty({ required: true, example: "uuid" })
762+
@IsOptional()
763+
testflowDataSetId?: string;
764+
}

0 commit comments

Comments
 (0)