From 35e28034a11b8d3dd7f5c7958230e7734c259027 Mon Sep 17 00:00:00 2001 From: Robin Beer Date: Wed, 17 May 2023 11:23:25 +0100 Subject: [PATCH 1/6] feat(Allow the deletion of a stop from pattern stops): Updated EditorController to include a new end --- .../controllers/api/EditorController.java | 66 +++++++++++++++++++ .../controllers/api/EditorControllerTest.java | 48 ++++++++++++++ 2 files changed, 114 insertions(+) diff --git a/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java b/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java index 7b6b94270..8629607d7 100644 --- a/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java +++ b/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java @@ -29,8 +29,10 @@ import java.io.IOException; import java.sql.Connection; import java.sql.PreparedStatement; +import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; +import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; @@ -41,6 +43,7 @@ import static com.conveyal.datatools.common.utils.SparkUtils.getObjectNode; import static com.conveyal.datatools.common.utils.SparkUtils.logMessageAndHalt; import static com.conveyal.datatools.manager.controllers.api.UserController.inTestingEnvironment; +import static org.eclipse.jetty.http.HttpStatus.OK_200; import static spark.Spark.delete; import static spark.Spark.options; import static spark.Spark.patch; @@ -129,6 +132,10 @@ private void registerRoutes() { put(ROOT_ROUTE + ID_PARAM + "/stop_times", this::updateStopTimesFromPatternStops, json::write); delete(ROOT_ROUTE + ID_PARAM + "/trips", this::deleteTripsForPattern, json::write); } + + if ("stop".equals(classToLowercase)) { + patch(ROOT_ROUTE + "/deletefrompatternstops", this::deleteStopFromPatternStops, json::write); + } } /** @@ -258,6 +265,65 @@ private String deleteTripsForPattern(Request req, Response res) { } } + /** + * HTTP endpoint to delete a stop from all pattern stops given a string stopId (i.e. not the integer ID field). + * Then normalize the stop times for all updated patterns (i.e. the ones where the stop has been deleted). + */ + private String deleteStopFromPatternStops(Request req, Response res) { + long startTime = System.currentTimeMillis(); + String namespace = getNamespaceAndValidateSession(req); + + // NOTE: This is a string stop ID, not the integer ID that all other HTTP endpoints use. + String stopId = req.queryParams("stopId"); + if (stopId == null) { + logMessageAndHalt(req, 400, "Must provide a valid stopId."); + } + + try ( + Connection connection = datasource.getConnection(); + PreparedStatement statement = connection.prepareStatement( + String.format("select pattern_id, stop_sequence from %s.pattern_stops where stop_id = ?", namespace) + ) + ) { + // Get the patterns to be normalized before the related stop is deleted. + statement.setString(1, stopId); + ResultSet resultSet = statement.executeQuery(); + Map patternsToBeNormalized = new HashMap<>(); + while (resultSet.next()) { + patternsToBeNormalized.put( + resultSet.getInt("pattern_id"), + resultSet.getInt("stop_sequence") + ); + } + + int deletedCount = 0; + // Table writer closes the database connection after use, so a new one is required for each task. + JdbcTableWriter tableWriter; + if (!patternsToBeNormalized.isEmpty()) { + tableWriter = new JdbcTableWriter(Table.PATTERN_STOP, datasource, namespace); + deletedCount = tableWriter.deleteWhere("stop_id", stopId, true); + if (deletedCount > 0) { + for (Map.Entry patternId : patternsToBeNormalized.entrySet()) { + tableWriter = new JdbcTableWriter(Table.PATTERN_STOP, datasource, namespace); + int stopSequence = patternId.getValue(); + // Begin with the stop prior to the one deleted, unless at the beginning. + int beginWithSequence = (stopSequence != 0) ? stopSequence - 1 : stopSequence; + tableWriter.normalizeStopTimesForPattern(patternId.getKey(), beginWithSequence); + } + } + } + return formatJSON(String.format("Deleted %d.", deletedCount), OK_200); + } catch (InvalidNamespaceException e) { + logMessageAndHalt(req, 400, "Invalid namespace.", e); + return null; + } catch (Exception e) { + logMessageAndHalt(req, 500, "Error deleting entity.", e); + return null; + } finally { + LOG.info("Delete stop from pattern stops operation took {} msec.", System.currentTimeMillis() - startTime); + } + } + /** * Currently designed to delete multiple trips in a single transaction. Trip IDs should be comma-separated in a query * parameter. TODO: Implement this for other entity types? diff --git a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java index 8e5cacc19..73a945a79 100644 --- a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java +++ b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java @@ -25,16 +25,20 @@ import spark.utils.IOUtils; import java.io.IOException; +import java.sql.SQLException; import java.util.Date; import java.util.stream.Stream; +import static com.conveyal.datatools.TestUtils.assertThatSqlCountQueryYieldsExpectedCount; import static com.conveyal.datatools.TestUtils.createFeedVersionFromGtfsZip; import static com.conveyal.datatools.manager.auth.Auth0Users.USERS_API_PATH; import static com.conveyal.datatools.manager.controllers.api.UserController.TEST_AUTH0_DOMAIN; import static io.restassured.RestAssured.given; +import static org.eclipse.jetty.http.HttpStatus.OK_200; import static org.hamcrest.MatcherAssert.assertThat; import static org.hamcrest.Matchers.equalTo; import static org.hamcrest.Matchers.is; +import static org.junit.jupiter.api.Assertions.assertEquals; public class EditorControllerTest extends UnitTest { private static final Logger LOG = LoggerFactory.getLogger(EditorControllerTest.class); @@ -143,6 +147,50 @@ public void canPatchStopsConditionally() throws IOException { } } + /** + * Test the removal of a stop from stop patterns. + */ + @Test + void canRemoveStopFromPatternStops() throws IOException, SQLException { + // Get a fresh feed source so that the editor namespace was updated after snapshot. + FeedSource freshFeedSource = Persistence.feedSources.getById(feedVersion.feedSourceId); + String stopId = "WARM"; + // Check for presence of stopId in pattern stops. + assertThatSqlCountQueryYieldsExpectedCount( + String.format( + "SELECT count(*) FROM %s.pattern_stops WHERE stop_id = '%s'", + freshFeedSource.editorNamespace, + stopId + ), + 4 + ); + + String path = String.format( + "/api/editor/secure/stop/deletefrompatternstops?stopId=%s&feedId=%s&sessionId=test", + stopId, + feedVersion.feedSourceId + ); + String response = given() + .port(DataManager.PORT) + .patch(path) + .then() + .extract() + .response() + .asString(); + JsonNode json = mapper.readTree(response); + assertEquals(OK_200, json.get("code").asInt()); + + // Check for removal of stopId in pattern stops. + assertThatSqlCountQueryYieldsExpectedCount( + String.format( + "SELECT count(*) FROM %s.pattern_stops WHERE stop_id = '%s'", + freshFeedSource.editorNamespace, + stopId + ), + 0 + ); + } + /** * Perform patch table request on the feed source ID with the requested query and patch JSON. A null query will * apply the patch JSON to the entire table. From bc6b861fbb68a9cff374fe9579b7e258f510c892 Mon Sep 17 00:00:00 2001 From: "philip.cline" Date: Wed, 17 May 2023 10:48:56 -0400 Subject: [PATCH 2/6] chore(gtfs lib): update gtfs lib --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 632b0d7da..33a52e498 100644 --- a/pom.xml +++ b/pom.xml @@ -268,7 +268,7 @@ com.github.conveyal gtfs-lib - 3d79493 + a3e5707 From 7084e51eec7eab514b20abb79400c30c4f6b2782 Mon Sep 17 00:00:00 2001 From: Robin Beer Date: Wed, 17 May 2023 16:01:38 +0100 Subject: [PATCH 3/6] refactor(Updated scope): Now deleted stop and related stop times --- .../controllers/api/EditorController.java | 48 ++++++++++++------- .../controllers/api/EditorControllerTest.java | 46 +++++++++++------- 2 files changed, 60 insertions(+), 34 deletions(-) diff --git a/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java b/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java index 8629607d7..a253fbb6b 100644 --- a/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java +++ b/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java @@ -134,7 +134,7 @@ private void registerRoutes() { } if ("stop".equals(classToLowercase)) { - patch(ROOT_ROUTE + "/deletefrompatternstops", this::deleteStopFromPatternStops, json::write); + patch(ROOT_ROUTE + "/cascadeDeleteStop", this::cascadeDeleteStop, json::write); } } @@ -266,12 +266,16 @@ private String deleteTripsForPattern(Request req, Response res) { } /** - * HTTP endpoint to delete a stop from all pattern stops given a string stopId (i.e. not the integer ID field). - * Then normalize the stop times for all updated patterns (i.e. the ones where the stop has been deleted). + * HTTP endpoint to delete a stop and all references in stop times and pattern stops given a string stopId (i.e. not + * the integer ID field). Then normalize the stop times for all updated patterns (i.e. the ones where the stop has + * been deleted). */ - private String deleteStopFromPatternStops(Request req, Response res) { + private String cascadeDeleteStop(Request req, Response res) { + // Table writer closes the database connection after use, so a new one is required for each task. + JdbcTableWriter tableWriter; long startTime = System.currentTimeMillis(); String namespace = getNamespaceAndValidateSession(req); + String stopIdColumnName = "stop_id"; // NOTE: This is a string stop ID, not the integer ID that all other HTTP endpoints use. String stopId = req.queryParams("stopId"); @@ -282,7 +286,7 @@ private String deleteStopFromPatternStops(Request req, Response res) { try ( Connection connection = datasource.getConnection(); PreparedStatement statement = connection.prepareStatement( - String.format("select pattern_id, stop_sequence from %s.pattern_stops where stop_id = ?", namespace) + String.format("select id, stop_sequence from %s.pattern_stops where %s = ?", namespace, stopIdColumnName) ) ) { // Get the patterns to be normalized before the related stop is deleted. @@ -291,28 +295,40 @@ private String deleteStopFromPatternStops(Request req, Response res) { Map patternsToBeNormalized = new HashMap<>(); while (resultSet.next()) { patternsToBeNormalized.put( - resultSet.getInt("pattern_id"), + resultSet.getInt("id"), resultSet.getInt("stop_sequence") ); } - int deletedCount = 0; - // Table writer closes the database connection after use, so a new one is required for each task. - JdbcTableWriter tableWriter; + tableWriter = new JdbcTableWriter(Table.STOP_TIMES, datasource, namespace); + int deletedCountStopTimes = tableWriter.deleteWhere(stopIdColumnName, stopId, true); + + int deletedCountPatternStops = 0; if (!patternsToBeNormalized.isEmpty()) { tableWriter = new JdbcTableWriter(Table.PATTERN_STOP, datasource, namespace); - deletedCount = tableWriter.deleteWhere("stop_id", stopId, true); - if (deletedCount > 0) { - for (Map.Entry patternId : patternsToBeNormalized.entrySet()) { + deletedCountPatternStops = tableWriter.deleteWhere(stopIdColumnName, stopId, true); + if (deletedCountPatternStops > 0) { + for (Map.Entry patternStop : patternsToBeNormalized.entrySet()) { tableWriter = new JdbcTableWriter(Table.PATTERN_STOP, datasource, namespace); - int stopSequence = patternId.getValue(); + int stopSequence = patternStop.getValue(); // Begin with the stop prior to the one deleted, unless at the beginning. int beginWithSequence = (stopSequence != 0) ? stopSequence - 1 : stopSequence; - tableWriter.normalizeStopTimesForPattern(patternId.getKey(), beginWithSequence); + tableWriter.normalizeStopTimesForPattern(patternStop.getKey(), beginWithSequence); } } } - return formatJSON(String.format("Deleted %d.", deletedCount), OK_200); + + tableWriter = new JdbcTableWriter(Table.STOPS, datasource, namespace); + int deletedCountStop = tableWriter.deleteWhere(stopIdColumnName, stopId, true); + + return formatJSON( + String.format( + "Deleted %d stop, %d pattern stops and %d stop times.", + deletedCountStop, + deletedCountPatternStops, + deletedCountStopTimes), + OK_200 + ); } catch (InvalidNamespaceException e) { logMessageAndHalt(req, 400, "Invalid namespace.", e); return null; @@ -320,7 +336,7 @@ private String deleteStopFromPatternStops(Request req, Response res) { logMessageAndHalt(req, 500, "Error deleting entity.", e); return null; } finally { - LOG.info("Delete stop from pattern stops operation took {} msec.", System.currentTimeMillis() - startTime); + LOG.info("Cascade delete of stop operation took {} msec.", System.currentTimeMillis() - startTime); } } diff --git a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java index 73a945a79..59c0a2d47 100644 --- a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java +++ b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java @@ -151,22 +151,35 @@ public void canPatchStopsConditionally() throws IOException { * Test the removal of a stop from stop patterns. */ @Test - void canRemoveStopFromPatternStops() throws IOException, SQLException { + void canRemoveStopFromStopTimesAndPatternStops() throws IOException, SQLException { // Get a fresh feed source so that the editor namespace was updated after snapshot. FeedSource freshFeedSource = Persistence.feedSources.getById(feedVersion.feedSourceId); String stopId = "WARM"; - // Check for presence of stopId in pattern stops. - assertThatSqlCountQueryYieldsExpectedCount( - String.format( - "SELECT count(*) FROM %s.pattern_stops WHERE stop_id = '%s'", - freshFeedSource.editorNamespace, - stopId - ), - 4 + String stopCountSql = String.format( + "SELECT count(*) FROM %s.stops WHERE stop_id = '%s'", + freshFeedSource.editorNamespace, + stopId + ); + String stopTimesCountSql = String.format( + "SELECT count(*) FROM %s.stop_times WHERE stop_id = '%s'", + freshFeedSource.editorNamespace, + stopId + ); + String patternStopsCountSql = String.format( + "SELECT count(*) FROM %s.pattern_stops WHERE stop_id = '%s'", + freshFeedSource.editorNamespace, + stopId ); + // Check for presence of stopId in stops. + assertThatSqlCountQueryYieldsExpectedCount(stopCountSql ,1); + // Check for presence of stopId in stop times. + assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql ,522); + // Check for presence of stopId in pattern stops. + assertThatSqlCountQueryYieldsExpectedCount(patternStopsCountSql, 4); + String path = String.format( - "/api/editor/secure/stop/deletefrompatternstops?stopId=%s&feedId=%s&sessionId=test", + "/api/editor/secure/stop/cascadeDeleteStop?stopId=%s&feedId=%s&sessionId=test", stopId, feedVersion.feedSourceId ); @@ -180,15 +193,12 @@ void canRemoveStopFromPatternStops() throws IOException, SQLException { JsonNode json = mapper.readTree(response); assertEquals(OK_200, json.get("code").asInt()); + // Check for removal of stopId in stops. + assertThatSqlCountQueryYieldsExpectedCount(stopCountSql ,0); + // Check for removal of stopId in stop times. + assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql ,0); // Check for removal of stopId in pattern stops. - assertThatSqlCountQueryYieldsExpectedCount( - String.format( - "SELECT count(*) FROM %s.pattern_stops WHERE stop_id = '%s'", - freshFeedSource.editorNamespace, - stopId - ), - 0 - ); + assertThatSqlCountQueryYieldsExpectedCount(patternStopsCountSql, 0); } /** From af5b89c219fb2a09c1792b075444518b1acf5600 Mon Sep 17 00:00:00 2001 From: Robin Beer Date: Fri, 19 May 2023 10:28:27 +0100 Subject: [PATCH 4/6] refactor(Addressed PR feedback): End point type is now delete --- .../controllers/api/EditorController.java | 8 ++-- .../controllers/api/EditorControllerTest.java | 46 +++++++++---------- 2 files changed, 25 insertions(+), 29 deletions(-) diff --git a/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java b/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java index a253fbb6b..bd50dff8f 100644 --- a/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java +++ b/src/main/java/com/conveyal/datatools/editor/controllers/api/EditorController.java @@ -134,7 +134,7 @@ private void registerRoutes() { } if ("stop".equals(classToLowercase)) { - patch(ROOT_ROUTE + "/cascadeDeleteStop", this::cascadeDeleteStop, json::write); + delete(ROOT_ROUTE + ID_PARAM + "/cascadeDeleteStop", this::cascadeDeleteStop, json::write); } } @@ -266,7 +266,7 @@ private String deleteTripsForPattern(Request req, Response res) { } /** - * HTTP endpoint to delete a stop and all references in stop times and pattern stops given a string stopId (i.e. not + * HTTP endpoint to delete a stop and all references in stop times and pattern stops given a string stop_id (i.e. not * the integer ID field). Then normalize the stop times for all updated patterns (i.e. the ones where the stop has * been deleted). */ @@ -277,8 +277,8 @@ private String cascadeDeleteStop(Request req, Response res) { String namespace = getNamespaceAndValidateSession(req); String stopIdColumnName = "stop_id"; - // NOTE: This is a string stop ID, not the integer ID that all other HTTP endpoints use. - String stopId = req.queryParams("stopId"); + // NOTE: This is a string stop ID, not the integer ID that other HTTP endpoints use. + String stopId = req.params("id"); if (stopId == null) { logMessageAndHalt(req, 400, "Must provide a valid stopId."); } diff --git a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java index 59c0a2d47..8f7bf9199 100644 --- a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java +++ b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java @@ -148,44 +148,30 @@ public void canPatchStopsConditionally() throws IOException { } /** - * Test the removal of a stop from stop patterns. + * Test the removal of a stop and all references in stop times and pattern stops. */ @Test - void canRemoveStopFromStopTimesAndPatternStops() throws IOException, SQLException { + void canCascadeDeleteStop() throws IOException, SQLException { // Get a fresh feed source so that the editor namespace was updated after snapshot. FeedSource freshFeedSource = Persistence.feedSources.getById(feedVersion.feedSourceId); String stopId = "WARM"; - String stopCountSql = String.format( - "SELECT count(*) FROM %s.stops WHERE stop_id = '%s'", - freshFeedSource.editorNamespace, - stopId - ); - String stopTimesCountSql = String.format( - "SELECT count(*) FROM %s.stop_times WHERE stop_id = '%s'", - freshFeedSource.editorNamespace, - stopId - ); - String patternStopsCountSql = String.format( - "SELECT count(*) FROM %s.pattern_stops WHERE stop_id = '%s'", - freshFeedSource.editorNamespace, - stopId - ); + String stopCountSql = getCountSql(freshFeedSource.editorNamespace, "stops", stopId); + String stopTimesCountSql = getCountSql(freshFeedSource.editorNamespace, "stop_times", stopId); + String patternStopsCountSql = getCountSql(freshFeedSource.editorNamespace, "pattern_stops", stopId); - // Check for presence of stopId in stops. + // Check for presence of stopId in stops, stop times and pattern stops. assertThatSqlCountQueryYieldsExpectedCount(stopCountSql ,1); - // Check for presence of stopId in stop times. assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql ,522); - // Check for presence of stopId in pattern stops. assertThatSqlCountQueryYieldsExpectedCount(patternStopsCountSql, 4); String path = String.format( - "/api/editor/secure/stop/cascadeDeleteStop?stopId=%s&feedId=%s&sessionId=test", + "/api/editor/secure/stop/%s/cascadeDeleteStop?feedId=%s&sessionId=test", stopId, feedVersion.feedSourceId ); String response = given() .port(DataManager.PORT) - .patch(path) + .delete(path) .then() .extract() .response() @@ -193,11 +179,9 @@ void canRemoveStopFromStopTimesAndPatternStops() throws IOException, SQLExceptio JsonNode json = mapper.readTree(response); assertEquals(OK_200, json.get("code").asInt()); - // Check for removal of stopId in stops. + // Check for removal of stopId in stops, stop times and pattern stops. assertThatSqlCountQueryYieldsExpectedCount(stopCountSql ,0); - // Check for removal of stopId in stop times. assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql ,0); - // Check for removal of stopId in pattern stops. assertThatSqlCountQueryYieldsExpectedCount(patternStopsCountSql, 0); } @@ -240,4 +224,16 @@ private static JsonNode graphqlQuery (String namespace, String graphQLQueryFile) .asString(); return mapper.readTree(graphQLString); } + + /** + * Build a sql statement to provide a count on the number of rows matching the stop id. + */ + private static String getCountSql(String namespace, String tableName, String stopId) { + return String.format( + "SELECT count(*) FROM %s.%s WHERE stop_id = '%s'", + namespace, + tableName, + stopId + ); + } } From 59e1cd80ee161dd6da3d669f4449002dc953a1ab Mon Sep 17 00:00:00 2001 From: Robin Beer Date: Fri, 19 May 2023 10:38:32 +0100 Subject: [PATCH 5/6] refactor(EditorControllerTest.java): Corrected formatting. --- .../editor/controllers/api/EditorControllerTest.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java index 8f7bf9199..8512cf941 100644 --- a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java +++ b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java @@ -160,8 +160,8 @@ void canCascadeDeleteStop() throws IOException, SQLException { String patternStopsCountSql = getCountSql(freshFeedSource.editorNamespace, "pattern_stops", stopId); // Check for presence of stopId in stops, stop times and pattern stops. - assertThatSqlCountQueryYieldsExpectedCount(stopCountSql ,1); - assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql ,522); + assertThatSqlCountQueryYieldsExpectedCount(stopCountSql, 1); + assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql, 522); assertThatSqlCountQueryYieldsExpectedCount(patternStopsCountSql, 4); String path = String.format( @@ -180,8 +180,8 @@ void canCascadeDeleteStop() throws IOException, SQLException { assertEquals(OK_200, json.get("code").asInt()); // Check for removal of stopId in stops, stop times and pattern stops. - assertThatSqlCountQueryYieldsExpectedCount(stopCountSql ,0); - assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql ,0); + assertThatSqlCountQueryYieldsExpectedCount(stopCountSql, 0); + assertThatSqlCountQueryYieldsExpectedCount(stopTimesCountSql, 0); assertThatSqlCountQueryYieldsExpectedCount(patternStopsCountSql, 0); } From 0751bdf37da809e1f9ade79dafbe1042d3e0ee2f Mon Sep 17 00:00:00 2001 From: Robin Beer Date: Fri, 19 May 2023 11:54:47 +0100 Subject: [PATCH 6/6] refactor(EditorControllerTest.java): Created a distinct feed version for the cascade delete stop tes Deleting a stop from the previously shared feed version was causing another test to fail. --- .../controllers/api/EditorControllerTest.java | 36 ++++++++++++++----- 1 file changed, 27 insertions(+), 9 deletions(-) diff --git a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java index 8512cf941..45a658b3f 100644 --- a/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java +++ b/src/test/java/com/conveyal/datatools/editor/controllers/api/EditorControllerTest.java @@ -44,7 +44,9 @@ public class EditorControllerTest extends UnitTest { private static final Logger LOG = LoggerFactory.getLogger(EditorControllerTest.class); private static Project project; private static FeedSource feedSource; + private static FeedSource feedSourceCascadeDelete; private static FeedVersion feedVersion; + private static FeedVersion feedVersionCascadeDelete; private static final ObjectMapper mapper = new ObjectMapper(); /** @@ -59,18 +61,23 @@ public static void setUp() throws Exception { UserController.setBaseUsersUrl("http://" + TEST_AUTH0_DOMAIN + USERS_API_PATH); // Create a project, feed sources, and feed versions to merge. project = new Project(); - project.name = String.format("Test %s", new Date().toString()); + project.name = String.format("Test %s", new Date()); Persistence.projects.create(project); + feedSource = new FeedSource("BART"); feedSource.projectId = project.id; Persistence.feedSources.create(feedSource); + + feedSourceCascadeDelete = new FeedSource("CASCADE_DELETE"); + feedSourceCascadeDelete.projectId = project.id; + Persistence.feedSources.create(feedSourceCascadeDelete); + feedVersion = createFeedVersionFromGtfsZip(feedSource, "bart_old.zip"); - // Create and run snapshot job - Snapshot snapshot = new Snapshot("Snapshot of " + feedVersion.name, feedSource.id, feedVersion.namespace); - CreateSnapshotJob createSnapshotJob = - new CreateSnapshotJob(Auth0UserProfile.createTestAdminUser(), snapshot, true, false, false); - // Run in current thread so tests do not run until this is complete. - createSnapshotJob.run(); + feedVersionCascadeDelete = createFeedVersionFromGtfsZip(feedSourceCascadeDelete, "bart_old.zip"); + + // Create and run snapshot jobs + crateAndRunSnapshotJob(feedVersion.name, feedSource.id, feedVersion.namespace); + crateAndRunSnapshotJob(feedVersionCascadeDelete.name, feedSourceCascadeDelete.id, feedVersionCascadeDelete.namespace); LOG.info("{} setup completed in {} ms", EditorControllerTest.class.getSimpleName(), System.currentTimeMillis() - startTime); } @@ -78,6 +85,17 @@ public static void setUp() throws Exception { public static void tearDown() { project.delete(); feedSource.delete(); + feedSourceCascadeDelete.delete(); + } + + /** + * Create and run a snapshot job in the current thread (so tests do not run until this is complete). + */ + private static void crateAndRunSnapshotJob(String feedVersionName, String feedSourceId, String namespace) { + Snapshot snapshot = new Snapshot("Snapshot of " + feedVersionName, feedSourceId, namespace); + CreateSnapshotJob createSnapshotJob = + new CreateSnapshotJob(Auth0UserProfile.createTestAdminUser(), snapshot, true, false, false); + createSnapshotJob.run(); } private static Stream createPatchTableTests() { @@ -153,7 +171,7 @@ public void canPatchStopsConditionally() throws IOException { @Test void canCascadeDeleteStop() throws IOException, SQLException { // Get a fresh feed source so that the editor namespace was updated after snapshot. - FeedSource freshFeedSource = Persistence.feedSources.getById(feedVersion.feedSourceId); + FeedSource freshFeedSource = Persistence.feedSources.getById(feedVersionCascadeDelete.feedSourceId); String stopId = "WARM"; String stopCountSql = getCountSql(freshFeedSource.editorNamespace, "stops", stopId); String stopTimesCountSql = getCountSql(freshFeedSource.editorNamespace, "stop_times", stopId); @@ -167,7 +185,7 @@ void canCascadeDeleteStop() throws IOException, SQLException { String path = String.format( "/api/editor/secure/stop/%s/cascadeDeleteStop?feedId=%s&sessionId=test", stopId, - feedVersion.feedSourceId + feedVersionCascadeDelete.feedSourceId ); String response = given() .port(DataManager.PORT)