diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java index daa0cca1326..10093727d9a 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/jdbi3/TestCaseRepository.java @@ -666,7 +666,9 @@ public class TestCaseRepository extends EntityRepository { return new RestUtil.DeleteResponse<>(testCase, ENTITY_DELETED); } - /** Remove test case from test suite summary and update test suite */ + /** + * Remove test case from test suite summary and update test suite + */ @Transaction private void removeTestCaseFromTestSuiteResultSummary(UUID testSuiteId, String testCaseFqn) { TestSuite testSuite = Entity.getEntity(TEST_SUITE, testSuiteId, "*", Include.ALL, false); @@ -723,8 +725,10 @@ public class TestCaseRepository extends EntityRepository { return testCase.withFailedRowsSample(tableData); } - public void deleteTestCaseFailedRowsSample(UUID id) { + @Transaction + public RestUtil.DeleteResponse deleteTestCaseFailedRowsSample(UUID id) { daoCollection.entityExtensionDAO().delete(id, FAILED_ROWS_SAMPLE_EXTENSION); + return new RestUtil.DeleteResponse<>(null, ENTITY_DELETED); } public static class TestCaseFailureResolutionTaskWorkflow extends FeedRepository.TaskWorkflow { @@ -740,7 +744,9 @@ public class TestCaseRepository extends EntityRepository { this.dataQualityDataTimeSeriesDao = Entity.getCollectionDAO().dataQualityDataTimeSeriesDao(); } - /** If the task is resolved, we'll resolve the Incident with the given reason */ + /** + * If the task is resolved, we'll resolve the Incident with the given reason + */ @Override @Transaction public TestCase performTask(String userName, ResolveTask resolveTask) { diff --git a/openmetadata-service/src/main/java/org/openmetadata/service/resources/dqtests/TestCaseResource.java b/openmetadata-service/src/main/java/org/openmetadata/service/resources/dqtests/TestCaseResource.java index 42326e11d86..20646712891 100644 --- a/openmetadata-service/src/main/java/org/openmetadata/service/resources/dqtests/TestCaseResource.java +++ b/openmetadata-service/src/main/java/org/openmetadata/service/resources/dqtests/TestCaseResource.java @@ -961,7 +961,7 @@ public class TestCaseResource extends EntityResource resourceContext = getResourceContextById(id); TestCase testCase = repository.find(id, Include.NON_DELETED); authorizer.authorize(securityContext, operationContext, resourceContext); @@ -1000,6 +1000,31 @@ public class TestCaseResource extends EntityResource resourceContext = getResourceContextById(id); + authorizer.authorize(securityContext, operationContext, resourceContext); + RestUtil.DeleteResponse response = repository.deleteTestCaseFailedRowsSample(id); + return response.toResponse(); + } + @PUT @Path("/logicalTestCases") @Operation( diff --git a/openmetadata-service/src/test/java/org/openmetadata/service/resources/dqtests/TestCaseResourceTest.java b/openmetadata-service/src/test/java/org/openmetadata/service/resources/dqtests/TestCaseResourceTest.java index d3fb75f5dd2..37b55dcdeef 100644 --- a/openmetadata-service/src/test/java/org/openmetadata/service/resources/dqtests/TestCaseResourceTest.java +++ b/openmetadata-service/src/test/java/org/openmetadata/service/resources/dqtests/TestCaseResourceTest.java @@ -33,7 +33,6 @@ import static org.openmetadata.service.util.TestUtils.assertListNull; import static org.openmetadata.service.util.TestUtils.assertResponse; import static org.openmetadata.service.util.TestUtils.assertResponseContains; import static org.openmetadata.service.util.TestUtils.dateToTimestamp; -import static org.openmetadata.service.util.TestUtils.patch; import java.io.IOException; import java.text.ParseException; @@ -73,7 +72,6 @@ import org.openmetadata.schema.tests.type.TestSummary; import org.openmetadata.schema.type.ChangeDescription; import org.openmetadata.schema.type.Column; import org.openmetadata.schema.type.ColumnDataType; -import org.openmetadata.schema.type.MetadataOperation; import org.openmetadata.schema.type.TableData; import org.openmetadata.schema.type.TagLabel; import org.openmetadata.schema.type.TaskStatus; @@ -819,6 +817,12 @@ public class TestCaseResourceTest extends EntityResourceTest authHeaders) + throws HttpResponseException { + WebTarget target = getCollection().path("/" + fqn + "/testCaseResult"); + TestUtils.delete(target, authHeaders); + } + @Test @Override public void post_entity_as_non_admin_401(TestInfo test) { @@ -2104,7 +2108,7 @@ public class TestCaseResourceTest extends EntityResourceTest putSampleData(testCase, columns, rows, ADMIN_AUTH_HEADERS), + () -> putFailedRowsSample(testCase, columns, rows, ADMIN_AUTH_HEADERS), BAD_REQUEST, "Failed rows can only be added to a failed test case."); @@ -2138,17 +2142,55 @@ public class TestCaseResourceTest extends EntityResourceTest putSampleData(testCase, columns, rows, authHeaders(USER2.getName())), + () -> putFailedRowsSample(testCase, columns, rows, authHeaders(USER2.getName())), FORBIDDEN, - permissionNotAllowed(USER2.getName(), List.of(MetadataOperation.EDIT_SAMPLE_DATA))); + permissionNotAllowed(USER2.getName(), List.of(EDIT_TESTS))); + + deleteFailedRowsSample(testCase, ADMIN_AUTH_HEADERS); + + assertResponse( + () -> getSampleData(testCase.getId(), ADMIN_AUTH_HEADERS), + NOT_FOUND, + FAILED_ROWS_SAMPLE_EXTENSION + " instance for " + testCase.getId() + " not found"); + } + + @Test + void resolved_test_case_deletes_sample_data(TestInfo test) throws IOException, ParseException { + CreateTestCase create = + createRequest(test) + .withEntityLink(TABLE_LINK) + .withTestSuite(TEST_SUITE1.getFullyQualifiedName()) + .withTestDefinition(TEST_DEFINITION3.getFullyQualifiedName()) + .withParameterValues( + List.of( + new TestCaseParameterValue().withValue("100").withName("missingCountValue"))); + TestCase testCase = createAndCheckEntity(create, ADMIN_AUTH_HEADERS); + List columns = Arrays.asList(C1, C2, C3); + + // Add 3 rows of sample data for 3 columns + List> rows = + Arrays.asList( + Arrays.asList("c1Value1", 1, true), + Arrays.asList("c1Value2", null, false), + Arrays.asList("c1Value3", 3, true)); + + putTestCaseResult( + testCase.getFullyQualifiedName(), + new TestCaseResult() + .withResult("result") + .withTestCaseStatus(TestCaseStatus.Failed) + .withTimestamp(TestUtils.dateToTimestamp("2024-01-01")), + ADMIN_AUTH_HEADERS); + + putFailedRowsSample(testCase, columns, rows, ADMIN_AUTH_HEADERS); // resolving test case deletes the sample data TestCaseResult testCaseResult = @@ -2192,7 +2234,7 @@ public class TestCaseResourceTest extends EntityResourceTest> rows = Arrays.asList(List.of("c1Value1"), List.of("c1Value2"), List.of("c1Value3")); // add sample data - putSampleData(testCase, columns, rows, ADMIN_AUTH_HEADERS); + putFailedRowsSample(testCase, columns, rows, ADMIN_AUTH_HEADERS); // assert values are not masked for the table owner TableData data = getSampleData(testCase.getId(), authHeaders(USER1.getName())); assertFalse( @@ -2213,21 +2255,28 @@ public class TestCaseResourceTest extends EntityResourceTest columns, List> rows, Map authHeaders) throws IOException { TableData tableData = new TableData().withColumns(columns).withRows(rows); - TestCase putResponse = putSampleData(testCase.getId(), tableData, authHeaders); + TestCase putResponse = putFailedRowsSample(testCase.getId(), tableData, authHeaders); assertEquals(tableData, putResponse.getFailedRowsSample()); TableData data = getSampleData(testCase.getId(), ADMIN_AUTH_HEADERS); assertEquals(tableData, data); } - public TestCase putSampleData(UUID testCaseId, TableData data, Map authHeaders) + private TestCase deleteFailedRowsSample(TestCase testCase, Map authHeaders) + throws IOException { + WebTarget target = getResource(testCase.getId()).path("/failedRowsSample"); + return TestUtils.delete(target, TestCase.class, authHeaders); + } + + public TestCase putFailedRowsSample( + UUID testCaseId, TableData data, Map authHeaders) throws HttpResponseException { WebTarget target = getResource(testCaseId).path("/failedRowsSample"); return TestUtils.put(target, data, TestCase.class, OK, authHeaders); diff --git a/openmetadata-spec/src/main/resources/json/schema/entity/policies/accessControl/resourceDescriptor.json b/openmetadata-spec/src/main/resources/json/schema/entity/policies/accessControl/resourceDescriptor.json index 8d961ed8c18..a5fc6160a4c 100644 --- a/openmetadata-spec/src/main/resources/json/schema/entity/policies/accessControl/resourceDescriptor.json +++ b/openmetadata-spec/src/main/resources/json/schema/entity/policies/accessControl/resourceDescriptor.json @@ -21,6 +21,7 @@ "ViewQueries", "ViewDataProfile", "ViewSampleData", + "ViewTestCaseFailedRowsSample", "EditAll", "EditCustomFields", "EditDataProfile", @@ -42,7 +43,8 @@ "EditUsers", "EditLifeCycle", "EditKnowledgePanel", - "EditPage" + "EditPage", + "DeleteTestCaseFailedRowsSample" ] } },