From 129a4ffdf88ba1f06fabbe8a244d9c3ae23cedf2 Mon Sep 17 00:00:00 2001 From: khatibtamal Date: Thu, 3 Oct 2024 18:11:49 +0600 Subject: [PATCH] partition id validations in coral and legacy Signed-off-by: khatibtamal --- .../details/messages/TopicMessages.test.tsx | 16 +++- .../topics/details/messages/TopicMessages.tsx | 5 +- .../messages/useMessagesFilters.test.tsx | 77 ++++++++++++++++--- .../details/messages/useMessagesFilters.tsx | 12 ++- .../main/resources/static/js/browseAcls.js | 21 ++++- 5 files changed, 109 insertions(+), 22 deletions(-) diff --git a/coral/src/app/features/topics/details/messages/TopicMessages.test.tsx b/coral/src/app/features/topics/details/messages/TopicMessages.test.tsx index fce8502cf..527948360 100644 --- a/coral/src/app/features/topics/details/messages/TopicMessages.test.tsx +++ b/coral/src/app/features/topics/details/messages/TopicMessages.test.tsx @@ -12,6 +12,12 @@ const mockGetTopicMessages = getTopicMessages as jest.MockedFunction< typeof getTopicMessages >; +const mockTopicOverview = { + topicInfo: { + noOfPartitions: 5, + }, +}; + const mockGetTopicMessagesResponse = { 0: "HELLO", 1: "WORLD", @@ -24,7 +30,15 @@ const mockGetTopicMessagesNoContentResponse = { const selectModeOptions = ["Default", "Custom", "Range"]; function DummyParent() { - return ; + return ( + + ); } describe("TopicMessages", () => { diff --git a/coral/src/app/features/topics/details/messages/TopicMessages.tsx b/coral/src/app/features/topics/details/messages/TopicMessages.tsx index b8adcf5bf..2df149ed3 100644 --- a/coral/src/app/features/topics/details/messages/TopicMessages.tsx +++ b/coral/src/app/features/topics/details/messages/TopicMessages.tsx @@ -32,7 +32,8 @@ function isNoContentResult( } function TopicMessages() { - const { topicName, environmentId } = useTopicDetails(); + const { topicName, environmentId, topicOverview } = useTopicDetails(); + const numberOfPartitions = topicOverview.topicInfo.noOfPartitions; const { validateFilters, @@ -76,7 +77,7 @@ function TopicMessages() { const isConsuming = isInitialLoading || isRefetching; function handleUpdateResultClick(): void { - const isValid = validateFilters(); + const isValid = validateFilters(numberOfPartitions); if (isValid) { updateResults(); diff --git a/coral/src/app/features/topics/details/messages/useMessagesFilters.test.tsx b/coral/src/app/features/topics/details/messages/useMessagesFilters.test.tsx index f76ba2d92..722eeb56c 100644 --- a/coral/src/app/features/topics/details/messages/useMessagesFilters.test.tsx +++ b/coral/src/app/features/topics/details/messages/useMessagesFilters.test.tsx @@ -189,7 +189,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(true); @@ -214,7 +214,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); @@ -226,12 +226,67 @@ describe("useMessagesFilters.tsx", () => { rangeOffsetEndFilters: null, }); }); + it("validateFilters returns false (negative partitionId)", () => { + const { result } = renderHook(() => useMessagesFilters(), { + wrapper: ({ children }) => ( + + {children} + + ), + }); + + let isValid; + + act(() => { + isValid = result.current.validateFilters(5); + }); + + expect(isValid).toBe(false); + + expect(result.current.filterErrors).toStrictEqual({ + customOffsetFilters: null, + partitionIdFilters: "Partition ID cannot be negative", + rangeOffsetStartFilters: null, + rangeOffsetEndFilters: null, + }); + }); + it("validateFilters returns false (invalid partitionId)", () => { + const { result } = renderHook(() => useMessagesFilters(), { + wrapper: ({ children }) => ( + + {children} + + ), + }); + + let isValid; + act(() => { + isValid = result.current.validateFilters(5); + }); + + expect(isValid).toBe(false); + + expect(result.current.filterErrors).toStrictEqual({ + customOffsetFilters: null, + partitionIdFilters: "Invalid partition ID", + rangeOffsetStartFilters: null, + rangeOffsetEndFilters: null, + }); + }); it("validateFilters returns false (missing customOffset)", () => { const { result } = renderHook(() => useMessagesFilters(), { wrapper: ({ children }) => ( {children} @@ -241,7 +296,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); @@ -259,7 +314,7 @@ describe("useMessagesFilters.tsx", () => { wrapper: ({ children }) => ( {children} @@ -270,7 +325,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); @@ -433,7 +488,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(true); @@ -460,7 +515,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); @@ -486,7 +541,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); @@ -514,7 +569,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); @@ -542,7 +597,7 @@ describe("useMessagesFilters.tsx", () => { let isValid; act(() => { - isValid = result.current.validateFilters(); + isValid = result.current.validateFilters(5); }); expect(isValid).toBe(false); diff --git a/coral/src/app/features/topics/details/messages/useMessagesFilters.tsx b/coral/src/app/features/topics/details/messages/useMessagesFilters.tsx index a16291062..003a89609 100644 --- a/coral/src/app/features/topics/details/messages/useMessagesFilters.tsx +++ b/coral/src/app/features/topics/details/messages/useMessagesFilters.tsx @@ -24,7 +24,7 @@ const NAMES = { const initialDefaultOffset: (typeof defaultOffsets)[0] = "5"; interface OffsetFilters { - validateFilters: () => boolean; + validateFilters: (totalNumberOfPartitions: number) => boolean; filterErrors: FilterErrors; getFetchingMode: () => TopicMessagesFetchModeTypes; defaultOffsetFilters: { @@ -70,7 +70,7 @@ function useMessagesFilters(): OffsetFilters { rangeOffsetEndFilters: null, }); - function validateFilters() { + function validateFilters(totalNumberOfPartitions: number) { if (getFetchingMode() === "default") { return true; } @@ -78,7 +78,11 @@ function useMessagesFilters(): OffsetFilters { const partitionIdFiltersError = getPartitionId() === "" || getPartitionId() === null ? "Please enter a partition ID" - : null; + : Number(getPartitionId()) < 0 + ? "Partition ID cannot be negative" + : Number(getPartitionId()) >= totalNumberOfPartitions + ? "Invalid partition ID" + : null; let customOffsetFiltersError = null; let rangeOffsetStartFiltersError = null; @@ -269,7 +273,7 @@ function useMessagesFilters(): OffsetFilters { } function setPartitionId(partitionId: string): void { - if (getDefaultOffset() !== "custom") { + if (getDefaultOffset() !== "custom" && getDefaultOffset() !== "range") { setDefaultOffset("custom"); } if (partitionId.length === 0) { diff --git a/core/src/main/resources/static/js/browseAcls.js b/core/src/main/resources/static/js/browseAcls.js index b8ae343a3..73c5a0ecd 100644 --- a/core/src/main/resources/static/js/browseAcls.js +++ b/core/src/main/resources/static/js/browseAcls.js @@ -898,6 +898,13 @@ app.controller("browseAclsCtrl", function($scope, $http, $location, $window) { return; } + if($scope.selectedPartitionId >= $scope.topicOverview[0].noOfPartitions) + { + $scope.alert = "Please fill in a valid partition id."; + $scope.showAlertToast(); + return; + } + if(!$scope.selectedNumberOfOffsets || $scope.selectedNumberOfOffsets === ""){ $scope.alert = "Please fill how many events/offsets to be displayed"; $scope.showAlertToast(); @@ -928,16 +935,22 @@ app.controller("browseAclsCtrl", function($scope, $http, $location, $window) { return; } - if(!$scope.selectedOffsetRangeStart || $scope.selectedOffsetRangeStart === "" || - !$scope.selectedOffsetRangeEnd || $scope.selectedOffsetRangeEnd === "" + if($scope.selectedPartitionId >= $scope.topicOverview[0].noOfPartitions) + { + $scope.alert = "Please fill in a valid partition id."; + $scope.showAlertToast(); + return; + } + + if($scope.selectedOffsetRangeStart === "" || $scope.selectedOffsetRangeEnd === "" ){ $scope.alert = "Please fill how many offsets range start and end."; $scope.showAlertToast(); return; } - if($scope.selectedOffsetRangeStart <= 0 || isNaN($scope.selectedOffsetRangeStart) || - $scope.selectedOffsetRangeEnd <= 0 || isNaN($scope.selectedOffsetRangeEnd)) + if($scope.selectedOffsetRangeStart < 0 || isNaN($scope.selectedOffsetRangeStart) || + $scope.selectedOffsetRangeEnd < 0 || isNaN($scope.selectedOffsetRangeEnd)) { $scope.alert = "Please fill in a valid number topic offsets start and end."; $scope.showAlertToast();