MINOR: added a DELETE method for failedRowsSample (#15878)

* added a DELETE method for failedRowsSample

* fixed tests

* changed required permission to EDIT_SAMPLE_DATA

* changed required permission to DELETE_SAMPLE_DATA

* changed required permission to DELETE_TEST_CASE_FAILED_ROWS_SAMPLE

* changed required permissions

addFailedRowsSample -> EDIT_TEST_CASE_FAILED_ROWS_SAMPLE
getFailedRowsSample -> VIEW_TEST_CASE_FAILED_ROWS_SAMPLE

* removed op EditTestCaseFailedRowsSample

* fixed tests

* format
This commit is contained in:
Imri Paran 2024-04-16 17:45:59 +02:00 committed by GitHub
parent fb263158d5
commit 6349adb0ec
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 100 additions and 18 deletions

View File

@ -666,7 +666,9 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
return new RestUtil.DeleteResponse<>(testCase, ENTITY_DELETED); 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 @Transaction
private void removeTestCaseFromTestSuiteResultSummary(UUID testSuiteId, String testCaseFqn) { private void removeTestCaseFromTestSuiteResultSummary(UUID testSuiteId, String testCaseFqn) {
TestSuite testSuite = Entity.getEntity(TEST_SUITE, testSuiteId, "*", Include.ALL, false); TestSuite testSuite = Entity.getEntity(TEST_SUITE, testSuiteId, "*", Include.ALL, false);
@ -723,8 +725,10 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
return testCase.withFailedRowsSample(tableData); return testCase.withFailedRowsSample(tableData);
} }
public void deleteTestCaseFailedRowsSample(UUID id) { @Transaction
public RestUtil.DeleteResponse<TableData> deleteTestCaseFailedRowsSample(UUID id) {
daoCollection.entityExtensionDAO().delete(id, FAILED_ROWS_SAMPLE_EXTENSION); daoCollection.entityExtensionDAO().delete(id, FAILED_ROWS_SAMPLE_EXTENSION);
return new RestUtil.DeleteResponse<>(null, ENTITY_DELETED);
} }
public static class TestCaseFailureResolutionTaskWorkflow extends FeedRepository.TaskWorkflow { public static class TestCaseFailureResolutionTaskWorkflow extends FeedRepository.TaskWorkflow {
@ -740,7 +744,9 @@ public class TestCaseRepository extends EntityRepository<TestCase> {
this.dataQualityDataTimeSeriesDao = Entity.getCollectionDAO().dataQualityDataTimeSeriesDao(); 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 @Override
@Transaction @Transaction
public TestCase performTask(String userName, ResolveTask resolveTask) { public TestCase performTask(String userName, ResolveTask resolveTask) {

View File

@ -961,7 +961,7 @@ public class TestCaseResource extends EntityResource<TestCase, TestCaseRepositor
UUID id, UUID id,
@Valid TableData tableData) { @Valid TableData tableData) {
OperationContext operationContext = OperationContext operationContext =
new OperationContext(entityType, MetadataOperation.EDIT_SAMPLE_DATA); new OperationContext(entityType, MetadataOperation.EDIT_TESTS);
authorizer.authorize(securityContext, operationContext, getResourceContextById(id)); authorizer.authorize(securityContext, operationContext, getResourceContextById(id));
TestCase testCase = repository.find(id, Include.NON_DELETED); TestCase testCase = repository.find(id, Include.NON_DELETED);
if (testCase.getTestCaseResult() == null if (testCase.getTestCaseResult() == null
@ -992,7 +992,7 @@ public class TestCaseResource extends EntityResource<TestCase, TestCaseRepositor
@Parameter(description = "Id of the table", schema = @Schema(type = "UUID")) @PathParam("id") @Parameter(description = "Id of the table", schema = @Schema(type = "UUID")) @PathParam("id")
UUID id) { UUID id) {
OperationContext operationContext = OperationContext operationContext =
new OperationContext(entityType, MetadataOperation.VIEW_SAMPLE_DATA); new OperationContext(entityType, MetadataOperation.VIEW_TEST_CASE_FAILED_ROWS_SAMPLE);
ResourceContext<?> resourceContext = getResourceContextById(id); ResourceContext<?> resourceContext = getResourceContextById(id);
TestCase testCase = repository.find(id, Include.NON_DELETED); TestCase testCase = repository.find(id, Include.NON_DELETED);
authorizer.authorize(securityContext, operationContext, resourceContext); authorizer.authorize(securityContext, operationContext, resourceContext);
@ -1000,6 +1000,31 @@ public class TestCaseResource extends EntityResource<TestCase, TestCaseRepositor
return repository.getSampleData(testCase, authorizePII); return repository.getSampleData(testCase, authorizePII);
} }
@DELETE
@Path("/{id}/failedRowsSample")
@Operation(
operationId = "deleteFailedRowsSample",
summary = "Delete failed rows sample data",
description = "Delete a sample of failed rows for this test case.",
responses = {
@ApiResponse(responseCode = "200", description = "OK"),
@ApiResponse(
responseCode = "404",
description = "Failed rows sample data for test case {id} is not found.")
})
public Response deleteFailedRowsData(
@Context UriInfo uriInfo,
@Context SecurityContext securityContext,
@Parameter(description = "Id of the table", schema = @Schema(type = "UUID")) @PathParam("id")
UUID id) {
OperationContext operationContext =
new OperationContext(entityType, MetadataOperation.DELETE_TEST_CASE_FAILED_ROWS_SAMPLE);
ResourceContext<?> resourceContext = getResourceContextById(id);
authorizer.authorize(securityContext, operationContext, resourceContext);
RestUtil.DeleteResponse<TableData> response = repository.deleteTestCaseFailedRowsSample(id);
return response.toResponse();
}
@PUT @PUT
@Path("/logicalTestCases") @Path("/logicalTestCases")
@Operation( @Operation(

View File

@ -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.assertResponse;
import static org.openmetadata.service.util.TestUtils.assertResponseContains; import static org.openmetadata.service.util.TestUtils.assertResponseContains;
import static org.openmetadata.service.util.TestUtils.dateToTimestamp; import static org.openmetadata.service.util.TestUtils.dateToTimestamp;
import static org.openmetadata.service.util.TestUtils.patch;
import java.io.IOException; import java.io.IOException;
import java.text.ParseException; 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.ChangeDescription;
import org.openmetadata.schema.type.Column; import org.openmetadata.schema.type.Column;
import org.openmetadata.schema.type.ColumnDataType; import org.openmetadata.schema.type.ColumnDataType;
import org.openmetadata.schema.type.MetadataOperation;
import org.openmetadata.schema.type.TableData; import org.openmetadata.schema.type.TableData;
import org.openmetadata.schema.type.TagLabel; import org.openmetadata.schema.type.TagLabel;
import org.openmetadata.schema.type.TaskStatus; import org.openmetadata.schema.type.TaskStatus;
@ -819,6 +817,12 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
TestUtils.put(target, data, CREATED, authHeaders); TestUtils.put(target, data, CREATED, authHeaders);
} }
public void deleteTestCaseResult(String fqn, Map<String, String> authHeaders)
throws HttpResponseException {
WebTarget target = getCollection().path("/" + fqn + "/testCaseResult");
TestUtils.delete(target, authHeaders);
}
@Test @Test
@Override @Override
public void post_entity_as_non_admin_401(TestInfo test) { public void post_entity_as_non_admin_401(TestInfo test) {
@ -2104,7 +2108,7 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
} }
@Test @Test
void put_failedRowSample_200(TestInfo test) throws IOException, ParseException { void put_and_delete_failedRowSample_200(TestInfo test) throws IOException, ParseException {
CreateTestCase create = CreateTestCase create =
createRequest(test) createRequest(test)
.withEntityLink(TABLE_LINK) .withEntityLink(TABLE_LINK)
@ -2125,7 +2129,7 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
// Cannot set failed sample for a non-failing test case // Cannot set failed sample for a non-failing test case
assertResponse( assertResponse(
() -> putSampleData(testCase, columns, rows, ADMIN_AUTH_HEADERS), () -> putFailedRowsSample(testCase, columns, rows, ADMIN_AUTH_HEADERS),
BAD_REQUEST, BAD_REQUEST,
"Failed rows can only be added to a failed test case."); "Failed rows can only be added to a failed test case.");
@ -2138,17 +2142,55 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
.withTimestamp(TestUtils.dateToTimestamp("2024-01-01")), .withTimestamp(TestUtils.dateToTimestamp("2024-01-01")),
ADMIN_AUTH_HEADERS); ADMIN_AUTH_HEADERS);
// Sample data can be put as an ADMIN // Sample data can be put as an ADMIN
putSampleData(testCase, columns, rows, ADMIN_AUTH_HEADERS); putFailedRowsSample(testCase, columns, rows, ADMIN_AUTH_HEADERS);
// Sample data can be put as owner // Sample data can be put as owner
rows.get(0).set(1, 2); // Change value 1 to 2 rows.get(0).set(1, 2); // Change value 1 to 2
putSampleData(testCase, columns, rows, authHeaders(USER1.getName())); putFailedRowsSample(testCase, columns, rows, authHeaders(USER1.getName()));
// Sample data can't be put as non-owner, non-admin // Sample data can't be put as non-owner, non-admin
assertResponse( assertResponse(
() -> putSampleData(testCase, columns, rows, authHeaders(USER2.getName())), () -> putFailedRowsSample(testCase, columns, rows, authHeaders(USER2.getName())),
FORBIDDEN, 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<String> columns = Arrays.asList(C1, C2, C3);
// Add 3 rows of sample data for 3 columns
List<List<Object>> 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 // resolving test case deletes the sample data
TestCaseResult testCaseResult = TestCaseResult testCaseResult =
@ -2192,7 +2234,7 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
List<List<Object>> rows = List<List<Object>> rows =
Arrays.asList(List.of("c1Value1"), List.of("c1Value2"), List.of("c1Value3")); Arrays.asList(List.of("c1Value1"), List.of("c1Value2"), List.of("c1Value3"));
// add sample data // 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 // assert values are not masked for the table owner
TableData data = getSampleData(testCase.getId(), authHeaders(USER1.getName())); TableData data = getSampleData(testCase.getId(), authHeaders(USER1.getName()));
assertFalse( assertFalse(
@ -2213,21 +2255,28 @@ public class TestCaseResourceTest extends EntityResourceTest<TestCase, CreateTes
.count()); .count());
} }
private void putSampleData( private void putFailedRowsSample(
TestCase testCase, TestCase testCase,
List<String> columns, List<String> columns,
List<List<Object>> rows, List<List<Object>> rows,
Map<String, String> authHeaders) Map<String, String> authHeaders)
throws IOException { throws IOException {
TableData tableData = new TableData().withColumns(columns).withRows(rows); 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()); assertEquals(tableData, putResponse.getFailedRowsSample());
TableData data = getSampleData(testCase.getId(), ADMIN_AUTH_HEADERS); TableData data = getSampleData(testCase.getId(), ADMIN_AUTH_HEADERS);
assertEquals(tableData, data); assertEquals(tableData, data);
} }
public TestCase putSampleData(UUID testCaseId, TableData data, Map<String, String> authHeaders) private TestCase deleteFailedRowsSample(TestCase testCase, Map<String, String> 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<String, String> authHeaders)
throws HttpResponseException { throws HttpResponseException {
WebTarget target = getResource(testCaseId).path("/failedRowsSample"); WebTarget target = getResource(testCaseId).path("/failedRowsSample");
return TestUtils.put(target, data, TestCase.class, OK, authHeaders); return TestUtils.put(target, data, TestCase.class, OK, authHeaders);

View File

@ -21,6 +21,7 @@
"ViewQueries", "ViewQueries",
"ViewDataProfile", "ViewDataProfile",
"ViewSampleData", "ViewSampleData",
"ViewTestCaseFailedRowsSample",
"EditAll", "EditAll",
"EditCustomFields", "EditCustomFields",
"EditDataProfile", "EditDataProfile",
@ -42,7 +43,8 @@
"EditUsers", "EditUsers",
"EditLifeCycle", "EditLifeCycle",
"EditKnowledgePanel", "EditKnowledgePanel",
"EditPage" "EditPage",
"DeleteTestCaseFailedRowsSample"
] ]
} }
}, },