@elisra-devops/docgen-data-provider 1.69.14 → 1.69.16
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/bin/modules/PipelinesDataProvider.d.ts +2 -1
- package/bin/modules/PipelinesDataProvider.js +73 -35
- package/bin/modules/PipelinesDataProvider.js.map +1 -1
- package/bin/modules/TicketsDataProvider.js +3 -2
- package/bin/modules/TicketsDataProvider.js.map +1 -1
- package/bin/tests/modules/pipelineDataProvider.test.js +101 -186
- package/bin/tests/modules/pipelineDataProvider.test.js.map +1 -1
- package/bin/tests/modules/ticketsDataProvider.test.js +11 -2
- package/bin/tests/modules/ticketsDataProvider.test.js.map +1 -1
- package/package.json +1 -1
- package/src/modules/PipelinesDataProvider.ts +117 -32
- package/src/modules/TicketsDataProvider.ts +3 -2
- package/src/tests/modules/pipelineDataProvider.test.ts +135 -206
- package/src/tests/modules/ticketsDataProvider.test.ts +20 -3
|
@@ -681,7 +681,7 @@ describe('PipelinesDataProvider', () => {
|
|
|
681
681
|
});
|
|
682
682
|
|
|
683
683
|
describe('getPipelineResourcePipelinesFromObject', () => {
|
|
684
|
-
it('should return empty
|
|
684
|
+
it('should return empty array when no pipeline resources exist', async () => {
|
|
685
685
|
// Arrange
|
|
686
686
|
const inPipeline = {
|
|
687
687
|
resources: {},
|
|
@@ -691,7 +691,7 @@ describe('PipelinesDataProvider', () => {
|
|
|
691
691
|
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
692
692
|
|
|
693
693
|
// Assert
|
|
694
|
-
expect(result).toEqual(
|
|
694
|
+
expect(result).toEqual([]);
|
|
695
695
|
});
|
|
696
696
|
|
|
697
697
|
it('should extract pipeline resources from pipeline object', async () => {
|
|
@@ -714,11 +714,11 @@ describe('PipelinesDataProvider', () => {
|
|
|
714
714
|
id: 789,
|
|
715
715
|
definition: { id: 123, type: 'build' },
|
|
716
716
|
buildNumber: '20231201.1',
|
|
717
|
-
project: { name: '
|
|
717
|
+
project: { name: 'project' },
|
|
718
718
|
repository: { type: 'TfsGit' },
|
|
719
719
|
};
|
|
720
720
|
|
|
721
|
-
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockBuildResponse);
|
|
721
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockBuildResponse); // fixed-url attempt
|
|
722
722
|
|
|
723
723
|
// Act
|
|
724
724
|
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
@@ -730,7 +730,7 @@ describe('PipelinesDataProvider', () => {
|
|
|
730
730
|
buildId: 789,
|
|
731
731
|
definitionId: 123,
|
|
732
732
|
buildNumber: '20231201.1',
|
|
733
|
-
teamProject: '
|
|
733
|
+
teamProject: 'project',
|
|
734
734
|
provider: 'TfsGit',
|
|
735
735
|
});
|
|
736
736
|
});
|
|
@@ -760,226 +760,35 @@ describe('PipelinesDataProvider', () => {
|
|
|
760
760
|
expect(result).toEqual([]);
|
|
761
761
|
});
|
|
762
762
|
|
|
763
|
-
it('should
|
|
764
|
-
// Arrange
|
|
765
|
-
const inPipeline = {
|
|
766
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/10/runs/200',
|
|
767
|
-
resources: {
|
|
768
|
-
pipelines: {
|
|
769
|
-
SOME_PACKAGE: {
|
|
770
|
-
pipeline: {
|
|
771
|
-
id: 123,
|
|
772
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/123?revision=1',
|
|
773
|
-
},
|
|
774
|
-
project: { name: 'project1' },
|
|
775
|
-
source: 'project1-system-package',
|
|
776
|
-
version: '1.0.56',
|
|
777
|
-
branch: 'main',
|
|
778
|
-
},
|
|
779
|
-
},
|
|
780
|
-
},
|
|
781
|
-
} as unknown as PipelineRun;
|
|
782
|
-
|
|
783
|
-
const mockListBuildsResponse = {
|
|
784
|
-
value: [
|
|
785
|
-
{
|
|
786
|
-
id: 789,
|
|
787
|
-
},
|
|
788
|
-
],
|
|
789
|
-
};
|
|
790
|
-
const mockBuildResponse = {
|
|
791
|
-
id: 789,
|
|
792
|
-
definition: { id: 123, type: 'build' },
|
|
793
|
-
buildNumber: '1.0.56',
|
|
794
|
-
project: { name: 'project1' },
|
|
795
|
-
repository: { type: 'TfsGit' },
|
|
796
|
-
};
|
|
797
|
-
|
|
798
|
-
(TFSServices.getItemContent as jest.Mock)
|
|
799
|
-
.mockResolvedValueOnce(mockListBuildsResponse) // findBuildByDefinitionAndBuildNumber
|
|
800
|
-
.mockResolvedValueOnce(mockBuildResponse); // getPipelineBuildByBuildId
|
|
801
|
-
|
|
802
|
-
// Act
|
|
803
|
-
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
804
|
-
|
|
805
|
-
// Assert
|
|
806
|
-
expect(result).toHaveLength(1);
|
|
807
|
-
expect((result as any[])[0]).toEqual({
|
|
808
|
-
name: 'SOME_PACKAGE',
|
|
809
|
-
buildId: 789,
|
|
810
|
-
definitionId: 123,
|
|
811
|
-
buildNumber: '1.0.56',
|
|
812
|
-
teamProject: 'project1',
|
|
813
|
-
provider: 'TfsGit',
|
|
814
|
-
});
|
|
815
|
-
|
|
816
|
-
// Ensure branch normalization was applied in the build search URL
|
|
817
|
-
expect((TFSServices.getItemContent as jest.Mock).mock.calls[0][0]).toContain('branchName=refs%2Fheads%2Fmain');
|
|
818
|
-
expect((TFSServices.getItemContent as jest.Mock).mock.calls[0][0]).toContain('buildNumber=1.0.56');
|
|
819
|
-
expect((TFSServices.getItemContent as jest.Mock).mock.calls[0][0]).toContain('definitions=123');
|
|
820
|
-
});
|
|
821
|
-
|
|
822
|
-
it('should fall back to pipeline run history when buildNumber lookup returns no builds', async () => {
|
|
823
|
-
// Arrange
|
|
824
|
-
const inPipeline = {
|
|
825
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/10/runs/200',
|
|
826
|
-
resources: {
|
|
827
|
-
pipelines: {
|
|
828
|
-
SOME_PACKAGE: {
|
|
829
|
-
pipeline: {
|
|
830
|
-
id: 123,
|
|
831
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/123?revision=1',
|
|
832
|
-
},
|
|
833
|
-
project: { name: 'project1' },
|
|
834
|
-
source: 'project1-system-package',
|
|
835
|
-
version: '20251109.1',
|
|
836
|
-
branch: 'main',
|
|
837
|
-
},
|
|
838
|
-
},
|
|
839
|
-
},
|
|
840
|
-
} as unknown as PipelineRun;
|
|
841
|
-
|
|
842
|
-
const mockListBuildsResponseEmpty = { value: [] };
|
|
843
|
-
const mockRunHistoryResponse = {
|
|
844
|
-
value: [{ id: 789, name: '20251109.1', result: 'succeeded' }],
|
|
845
|
-
};
|
|
846
|
-
const mockBuildResponse = {
|
|
847
|
-
id: 789,
|
|
848
|
-
definition: { id: 123, type: 'build' },
|
|
849
|
-
buildNumber: '20251109.1',
|
|
850
|
-
project: { name: 'project1' },
|
|
851
|
-
repository: { type: 'TfsGit' },
|
|
852
|
-
};
|
|
853
|
-
|
|
854
|
-
(TFSServices.getItemContent as jest.Mock)
|
|
855
|
-
.mockResolvedValueOnce(mockListBuildsResponseEmpty) // findBuildByDefinitionAndBuildNumber
|
|
856
|
-
.mockResolvedValueOnce(mockListBuildsResponseEmpty) // findBuildByBuildNumber (no definition)
|
|
857
|
-
.mockResolvedValueOnce(mockRunHistoryResponse) // GetPipelineRunHistory
|
|
858
|
-
.mockResolvedValueOnce(mockBuildResponse); // getPipelineBuildByBuildId
|
|
859
|
-
|
|
860
|
-
// Act
|
|
861
|
-
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
862
|
-
|
|
863
|
-
// Assert
|
|
864
|
-
expect(result).toHaveLength(1);
|
|
865
|
-
expect((result as any[])[0]).toEqual({
|
|
866
|
-
name: 'SOME_PACKAGE',
|
|
867
|
-
buildId: 789,
|
|
868
|
-
definitionId: 123,
|
|
869
|
-
buildNumber: '20251109.1',
|
|
870
|
-
teamProject: 'project1',
|
|
871
|
-
provider: 'TfsGit',
|
|
872
|
-
});
|
|
873
|
-
});
|
|
874
|
-
|
|
875
|
-
it('should fall back to buildNumber-only lookup when definition-based lookup returns no builds', async () => {
|
|
876
|
-
const inPipeline = {
|
|
877
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/10/runs/200',
|
|
878
|
-
resources: {
|
|
879
|
-
pipelines: {
|
|
880
|
-
SOME_PACKAGE: {
|
|
881
|
-
pipeline: {
|
|
882
|
-
id: 770,
|
|
883
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/770?revision=1',
|
|
884
|
-
},
|
|
885
|
-
project: { name: 'project1' },
|
|
886
|
-
source: 'project1-system-package',
|
|
887
|
-
version: '20251109.1',
|
|
888
|
-
branch: 'main',
|
|
889
|
-
},
|
|
890
|
-
},
|
|
891
|
-
},
|
|
892
|
-
} as unknown as PipelineRun;
|
|
893
|
-
|
|
894
|
-
const mockListBuildsResponseEmpty = { value: [] };
|
|
895
|
-
const mockListBuildsByNumber = {
|
|
896
|
-
value: [
|
|
897
|
-
{
|
|
898
|
-
id: 789,
|
|
899
|
-
definition: { id: 123, name: 'project1-system-package' },
|
|
900
|
-
},
|
|
901
|
-
],
|
|
902
|
-
};
|
|
903
|
-
const mockBuildResponse = {
|
|
904
|
-
id: 789,
|
|
905
|
-
definition: { id: 123, type: 'build' },
|
|
906
|
-
buildNumber: '20251109.1',
|
|
907
|
-
project: { name: 'project1' },
|
|
908
|
-
repository: { type: 'TfsGit' },
|
|
909
|
-
};
|
|
910
|
-
|
|
911
|
-
(TFSServices.getItemContent as jest.Mock)
|
|
912
|
-
.mockResolvedValueOnce(mockListBuildsResponseEmpty) // findBuildByDefinitionAndBuildNumber
|
|
913
|
-
.mockResolvedValueOnce(mockListBuildsByNumber) // findBuildByBuildNumber (no definition)
|
|
914
|
-
.mockResolvedValueOnce(mockBuildResponse); // getPipelineBuildByBuildId
|
|
915
|
-
|
|
916
|
-
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
917
|
-
|
|
918
|
-
expect(result).toHaveLength(1);
|
|
919
|
-
expect((result as any[])[0]).toEqual({
|
|
920
|
-
name: 'SOME_PACKAGE',
|
|
921
|
-
buildId: 789,
|
|
922
|
-
definitionId: 123,
|
|
923
|
-
buildNumber: '20251109.1',
|
|
924
|
-
teamProject: 'project1',
|
|
925
|
-
provider: 'TfsGit',
|
|
926
|
-
});
|
|
927
|
-
|
|
928
|
-
// Ensure the second call is the buildNumber-only lookup (no definitions= filter)
|
|
929
|
-
expect((TFSServices.getItemContent as jest.Mock).mock.calls[1][0]).toContain('buildNumber=20251109.1');
|
|
930
|
-
expect((TFSServices.getItemContent as jest.Mock).mock.calls[1][0]).not.toContain('definitions=');
|
|
931
|
-
});
|
|
932
|
-
|
|
933
|
-
it('should resolve project name when pipeline resource provides project id (GUID)', async () => {
|
|
763
|
+
it('should skip resource when fixed-url returns a build from a different project/pipeline', async () => {
|
|
934
764
|
const inPipeline = {
|
|
935
|
-
url: 'https://dev.azure.com/org/project1/_apis/pipelines/10/runs/200',
|
|
936
765
|
resources: {
|
|
937
766
|
pipelines: {
|
|
938
|
-
|
|
767
|
+
myPipeline: {
|
|
939
768
|
pipeline: {
|
|
940
769
|
id: 123,
|
|
941
|
-
|
|
770
|
+
name: 'ExpectedPipeline',
|
|
771
|
+
url: 'https://dev.azure.com/org/project/_apis/pipelines/123?revision=1',
|
|
942
772
|
},
|
|
943
|
-
project: { name: '1488cb19-7369-4afc-92bf-251d368b85be' },
|
|
944
|
-
source: 'project1-system-package',
|
|
945
|
-
version: '20251109.1',
|
|
946
|
-
branch: 'main',
|
|
947
773
|
},
|
|
948
774
|
},
|
|
949
775
|
},
|
|
950
776
|
} as unknown as PipelineRun;
|
|
951
777
|
|
|
952
|
-
const mockProjectResponse = { id: '1488cb19-7369-4afc-92bf-251d368b85be', name: 'Test CMMI' };
|
|
953
|
-
const mockListBuildsResponse = { value: [{ id: 789 }] };
|
|
954
778
|
const mockBuildResponse = {
|
|
955
779
|
id: 789,
|
|
956
|
-
definition: { id:
|
|
957
|
-
buildNumber: '
|
|
958
|
-
project: { name: '
|
|
780
|
+
definition: { id: 999, name: 'DifferentPipeline', type: 'build' },
|
|
781
|
+
buildNumber: '20231201.1',
|
|
782
|
+
project: { name: 'DifferentProject' },
|
|
959
783
|
repository: { type: 'TfsGit' },
|
|
960
784
|
};
|
|
961
785
|
|
|
962
|
-
(TFSServices.getItemContent as jest.Mock)
|
|
963
|
-
.mockResolvedValueOnce(mockProjectResponse) // normalizeProjectName
|
|
964
|
-
.mockResolvedValueOnce(mockListBuildsResponse) // findBuildByDefinitionAndBuildNumber
|
|
965
|
-
.mockResolvedValueOnce(mockBuildResponse); // getPipelineBuildByBuildId
|
|
786
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce(mockBuildResponse);
|
|
966
787
|
|
|
967
788
|
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
968
789
|
|
|
969
|
-
expect(result).
|
|
970
|
-
expect(
|
|
971
|
-
name: 'SOME_PACKAGE',
|
|
972
|
-
buildId: 789,
|
|
973
|
-
definitionId: 123,
|
|
974
|
-
buildNumber: '20251109.1',
|
|
975
|
-
teamProject: 'Test CMMI',
|
|
976
|
-
provider: 'TfsGit',
|
|
977
|
-
});
|
|
978
|
-
|
|
979
|
-
// Ensure project-id normalization API was called
|
|
980
|
-
expect((TFSServices.getItemContent as jest.Mock).mock.calls[0][0]).toContain(
|
|
981
|
-
`${mockOrgUrl}_apis/projects/1488cb19-7369-4afc-92bf-251d368b85be`
|
|
982
|
-
);
|
|
790
|
+
expect(result).toEqual([]);
|
|
791
|
+
expect(TFSServices.getItemContent).toHaveBeenCalledTimes(1);
|
|
983
792
|
});
|
|
984
793
|
});
|
|
985
794
|
|
|
@@ -1227,6 +1036,126 @@ describe('PipelinesDataProvider', () => {
|
|
|
1227
1036
|
});
|
|
1228
1037
|
});
|
|
1229
1038
|
|
|
1039
|
+
describe('private helper methods', () => {
|
|
1040
|
+
it('tryGetTeamProjectFromAzureDevOpsUrl should extract project segment before _apis', () => {
|
|
1041
|
+
const fn = (pipelinesDataProvider as any).tryGetTeamProjectFromAzureDevOpsUrl.bind(
|
|
1042
|
+
pipelinesDataProvider
|
|
1043
|
+
);
|
|
1044
|
+
expect(fn('https://dev.azure.com/org/Test/_apis/pipelines/123?revision=1')).toBe('Test');
|
|
1045
|
+
expect(fn('https://dev.azure.com/_apis/pipelines/123?revision=1')).toBeUndefined();
|
|
1046
|
+
expect(fn('https://dev.azure.com/org/_apis/pipelines/123?revision=1')).toBe('org');
|
|
1047
|
+
expect(fn('not-a-url')).toBeUndefined();
|
|
1048
|
+
});
|
|
1049
|
+
|
|
1050
|
+
it('tryBuildBuildApiUrlFromPipelinesApiUrl should rewrite pipelines url to builds url and drop query', () => {
|
|
1051
|
+
const fn = (pipelinesDataProvider as any).tryBuildBuildApiUrlFromPipelinesApiUrl.bind(
|
|
1052
|
+
pipelinesDataProvider
|
|
1053
|
+
);
|
|
1054
|
+
expect(fn('https://dev.azure.com/org/Test/_apis/pipelines/123?revision=1')).toBe(
|
|
1055
|
+
'https://dev.azure.com/org/Test/_apis/build/builds/123'
|
|
1056
|
+
);
|
|
1057
|
+
expect(fn('https://dev.azure.com/org/Test/_apis/build/builds/123')).toBeUndefined();
|
|
1058
|
+
expect(fn('not-a-url')).toBeUndefined();
|
|
1059
|
+
});
|
|
1060
|
+
|
|
1061
|
+
it('tryParseRunIdFromUrl should parse run id from pipelines runs URL and build id from builds URL', () => {
|
|
1062
|
+
const fn = (pipelinesDataProvider as any).tryParseRunIdFromUrl.bind(pipelinesDataProvider);
|
|
1063
|
+
expect(fn('https://dev.azure.com/org/Test/_apis/pipelines/10/runs/555')).toBe(555);
|
|
1064
|
+
expect(fn('https://dev.azure.com/org/Test/_apis/build/builds/777')).toBe(777);
|
|
1065
|
+
expect(fn('https://dev.azure.com/org/Test/_apis/pipelines/10/runs/not-a-number')).toBeUndefined();
|
|
1066
|
+
expect(fn('not-a-url')).toBeUndefined();
|
|
1067
|
+
});
|
|
1068
|
+
|
|
1069
|
+
it('normalizeBranchName should normalize branch to refs/heads form', () => {
|
|
1070
|
+
const fn = (pipelinesDataProvider as any).normalizeBranchName.bind(pipelinesDataProvider);
|
|
1071
|
+
expect(fn('main')).toBe('refs/heads/main');
|
|
1072
|
+
expect(fn('heads/main')).toBe('refs/heads/main');
|
|
1073
|
+
expect(fn('refs/heads/main')).toBe('refs/heads/main');
|
|
1074
|
+
expect(fn('')).toBeUndefined();
|
|
1075
|
+
expect(fn(undefined)).toBeUndefined();
|
|
1076
|
+
});
|
|
1077
|
+
|
|
1078
|
+
it('normalizeProjectName should resolve GUID project id to name and cache it', async () => {
|
|
1079
|
+
const guid = '009c6fae-b000-47fe-994e-be3354b78fbc';
|
|
1080
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({ name: 'ResolvedProjectName' });
|
|
1081
|
+
|
|
1082
|
+
const fn = (pipelinesDataProvider as any).normalizeProjectName.bind(pipelinesDataProvider);
|
|
1083
|
+
const first = await fn(guid);
|
|
1084
|
+
const second = await fn(guid);
|
|
1085
|
+
|
|
1086
|
+
expect(first).toBe('ResolvedProjectName');
|
|
1087
|
+
expect(second).toBe('ResolvedProjectName');
|
|
1088
|
+
expect(TFSServices.getItemContent).toHaveBeenCalledTimes(1);
|
|
1089
|
+
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
1090
|
+
`${mockOrgUrl}_apis/projects/${encodeURIComponent(guid)}?api-version=6.0`,
|
|
1091
|
+
mockToken,
|
|
1092
|
+
'get',
|
|
1093
|
+
null,
|
|
1094
|
+
null,
|
|
1095
|
+
false
|
|
1096
|
+
);
|
|
1097
|
+
});
|
|
1098
|
+
|
|
1099
|
+
it('normalizeProjectName should return raw GUID when project resolution fails', async () => {
|
|
1100
|
+
const guid = '009c6fae-b000-47fe-994e-be3354b78fbc';
|
|
1101
|
+
(TFSServices.getItemContent as jest.Mock).mockRejectedValueOnce(new Error('boom'));
|
|
1102
|
+
const fn = (pipelinesDataProvider as any).normalizeProjectName.bind(pipelinesDataProvider);
|
|
1103
|
+
const result = await fn(guid);
|
|
1104
|
+
expect(result).toBe(guid);
|
|
1105
|
+
});
|
|
1106
|
+
|
|
1107
|
+
it('findBuildByBuildNumber should prefer matching definition name when provided', async () => {
|
|
1108
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({
|
|
1109
|
+
value: [
|
|
1110
|
+
{ id: 1, definition: { name: 'Other' } },
|
|
1111
|
+
{ id: 2, definition: { name: 'Expected' } },
|
|
1112
|
+
],
|
|
1113
|
+
});
|
|
1114
|
+
|
|
1115
|
+
const fn = (pipelinesDataProvider as any).findBuildByBuildNumber.bind(pipelinesDataProvider);
|
|
1116
|
+
const result = await fn('project1', '20251225.2', 'main', 'Expected');
|
|
1117
|
+
expect(result?.id).toBe(2);
|
|
1118
|
+
});
|
|
1119
|
+
|
|
1120
|
+
it('tryGetBuildByIdWithFallback should fall back to non-project-scoped URL when project-scoped lookup fails', async () => {
|
|
1121
|
+
jest
|
|
1122
|
+
.spyOn(pipelinesDataProvider as any, 'getPipelineBuildByBuildId')
|
|
1123
|
+
.mockRejectedValueOnce(new Error('not found'));
|
|
1124
|
+
(TFSServices.getItemContent as jest.Mock).mockResolvedValueOnce({ id: 123 });
|
|
1125
|
+
|
|
1126
|
+
const fn = (pipelinesDataProvider as any).tryGetBuildByIdWithFallback.bind(pipelinesDataProvider);
|
|
1127
|
+
const result = await fn('project1', 123);
|
|
1128
|
+
|
|
1129
|
+
expect(result).toEqual({ id: 123 });
|
|
1130
|
+
expect(TFSServices.getItemContent).toHaveBeenCalledWith(
|
|
1131
|
+
`${mockOrgUrl}_apis/build/builds/123`,
|
|
1132
|
+
mockToken,
|
|
1133
|
+
'get',
|
|
1134
|
+
null,
|
|
1135
|
+
null
|
|
1136
|
+
);
|
|
1137
|
+
});
|
|
1138
|
+
|
|
1139
|
+
it('getPipelineResourcePipelinesFromObject should skip resource when pipelines url cannot be converted to builds url', async () => {
|
|
1140
|
+
const inPipeline = {
|
|
1141
|
+
resources: {
|
|
1142
|
+
pipelines: {
|
|
1143
|
+
myPipeline: {
|
|
1144
|
+
pipeline: {
|
|
1145
|
+
id: 123,
|
|
1146
|
+
url: 'https://dev.azure.com/org/project/_apis/build/builds/123',
|
|
1147
|
+
},
|
|
1148
|
+
},
|
|
1149
|
+
},
|
|
1150
|
+
},
|
|
1151
|
+
} as unknown as PipelineRun;
|
|
1152
|
+
|
|
1153
|
+
const result = await pipelinesDataProvider.getPipelineResourcePipelinesFromObject(inPipeline);
|
|
1154
|
+
expect(result).toEqual([]);
|
|
1155
|
+
expect(TFSServices.getItemContent).not.toHaveBeenCalled();
|
|
1156
|
+
});
|
|
1157
|
+
});
|
|
1158
|
+
|
|
1230
1159
|
describe('isInvalidPipelineRun', () => {
|
|
1231
1160
|
const invokeIsInvalidPipelineRun = (
|
|
1232
1161
|
pipelineRun: any,
|
|
@@ -20,8 +20,8 @@ describe('TicketsDataProvider', () => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
describe('isLinkSideAllowedByTypeOrId', () => {
|
|
23
|
-
it('should
|
|
24
|
-
const wiql = "SELECT * FROM WorkItemLinks WHERE Source.[System.WorkItemType]
|
|
23
|
+
it('should return true when source types include allowed types', async () => {
|
|
24
|
+
const wiql = "SELECT * FROM WorkItemLinks WHERE Source.[System.WorkItemType] IN ('Bug')";
|
|
25
25
|
const result = await (ticketsDataProvider as any).isLinkSideAllowedByTypeOrId(
|
|
26
26
|
{},
|
|
27
27
|
wiql,
|
|
@@ -81,6 +81,18 @@ describe('TicketsDataProvider', () => {
|
|
|
81
81
|
});
|
|
82
82
|
});
|
|
83
83
|
|
|
84
|
+
describe('fetchSystemRequirementQueries', () => {
|
|
85
|
+
it('should include Task in allowed types', async () => {
|
|
86
|
+
const structureSpy = jest
|
|
87
|
+
.spyOn(ticketsDataProvider as any, 'structureFetchedQueries')
|
|
88
|
+
.mockResolvedValue({ tree1: { id: 't1' }, tree2: null });
|
|
89
|
+
|
|
90
|
+
await (ticketsDataProvider as any).fetchSystemRequirementQueries({ hasChildren: false }, []);
|
|
91
|
+
|
|
92
|
+
expect(structureSpy.mock.calls[0][3]).toEqual(['epic', 'feature', 'requirement', 'task']);
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
84
96
|
describe('findChildFolderByPossibleNames', () => {
|
|
85
97
|
it('should return null when parent is missing or possibleNames is empty', async () => {
|
|
86
98
|
await expect(
|
|
@@ -641,7 +653,12 @@ describe('TicketsDataProvider', () => {
|
|
|
641
653
|
|
|
642
654
|
it('should reject when WIQL contains a type outside allowedTypes', async () => {
|
|
643
655
|
const wiql = "SELECT * FROM WorkItems WHERE [System.WorkItemType] IN ('Bug','Task')";
|
|
644
|
-
const res = await (ticketsDataProvider as any).isFlatQueryAllowedByTypeOrId(
|
|
656
|
+
const res = await (ticketsDataProvider as any).isFlatQueryAllowedByTypeOrId(
|
|
657
|
+
{},
|
|
658
|
+
wiql,
|
|
659
|
+
['Bug'],
|
|
660
|
+
new Map()
|
|
661
|
+
);
|
|
645
662
|
expect(res).toBe(false);
|
|
646
663
|
});
|
|
647
664
|
});
|