1
1
package com .conveyal .gtfs .loader ;
2
2
3
3
import com .conveyal .gtfs .TestUtils ;
4
+ import com .conveyal .gtfs .util .FareDTO ;
5
+ import com .conveyal .gtfs .util .FareRuleDTO ;
4
6
import com .conveyal .gtfs .util .FeedInfoDTO ;
5
7
import com .conveyal .gtfs .util .InvalidNamespaceException ;
8
+ import com .conveyal .gtfs .util .RouteDTO ;
6
9
import com .fasterxml .jackson .databind .ObjectMapper ;
7
10
import org .junit .AfterClass ;
8
11
import org .junit .BeforeClass ;
@@ -28,14 +31,19 @@ public class JDBCTableWriterTest {
28
31
private static String testDBName ;
29
32
private static DataSource testDataSource ;
30
33
private static String testNamespace ;
34
+ private static final ObjectMapper mapper = new ObjectMapper ();
35
+
36
+ private static JdbcTableWriter createTestTableWriter (Table table ) throws InvalidNamespaceException {
37
+ return new JdbcTableWriter (table , testDataSource , testNamespace );
38
+ }
31
39
32
40
@ BeforeClass
33
41
public static void setUpClass () throws SQLException {
34
42
// create a new database
35
43
testDBName = TestUtils .generateNewDB ();
36
44
String dbConnectionUrl = String .format ("jdbc:postgresql://localhost/%s" , testDBName );
37
45
testDataSource = createDataSource (dbConnectionUrl , null , null );
38
- LOG .info ("creating feeds table because it isn't automtically generated unless you import a feed" );
46
+ LOG .info ("creating feeds table because it isn't automatically generated unless you import a feed" );
39
47
Connection connection = testDataSource .getConnection ();
40
48
connection .createStatement ()
41
49
.execute ("create table if not exists feeds (namespace varchar primary key, md5 varchar, " +
@@ -50,8 +58,10 @@ public static void setUpClass() throws SQLException {
50
58
}
51
59
52
60
@ Test
53
- public void canCreateUpdateAndDeleteFeedinfoEntities () throws IOException , SQLException , InvalidNamespaceException {
54
- ObjectMapper mapper = new ObjectMapper ();
61
+ public void canCreateUpdateAndDeleteFeedInfoEntities () throws IOException , SQLException , InvalidNamespaceException {
62
+ // Store Table and Class values for use in test.
63
+ final Table feedInfoTable = Table .FEED_INFO ;
64
+ final Class <FeedInfoDTO > feedInfoDTOClass = FeedInfoDTO .class ;
55
65
56
66
// create new object to be saved
57
67
FeedInfoDTO feedInfoInput = new FeedInfoDTO ();
@@ -63,13 +73,13 @@ public void canCreateUpdateAndDeleteFeedinfoEntities () throws IOException, SQLE
63
73
feedInfoInput .default_route_type = "3" ;
64
74
65
75
// convert object to json and save it
66
- JdbcTableWriter createTableWriter = new JdbcTableWriter ( Table . FEED_INFO , testDataSource , testNamespace );
76
+ JdbcTableWriter createTableWriter = createTestTableWriter ( feedInfoTable );
67
77
String createOutput = createTableWriter .create (mapper .writeValueAsString (feedInfoInput ), true );
68
- LOG .info ("create output:" );
78
+ LOG .info ("create {} output:" , feedInfoTable . name );
69
79
LOG .info (createOutput );
70
80
71
81
// parse output
72
- FeedInfoDTO createdFeedInfo = mapper .readValue (createOutput , FeedInfoDTO . class );
82
+ FeedInfoDTO createdFeedInfo = mapper .readValue (createOutput , feedInfoDTOClass );
73
83
74
84
// make sure saved data matches expected data
75
85
assertThat (createdFeedInfo .feed_publisher_name , equalTo (publisherName ));
@@ -79,45 +89,39 @@ public void canCreateUpdateAndDeleteFeedinfoEntities () throws IOException, SQLE
79
89
createdFeedInfo .feed_publisher_name = updatedPublisherName ;
80
90
81
91
// covert object to json and save it
82
- JdbcTableWriter updateTableWriter = new JdbcTableWriter ( Table . FEED_INFO , testDataSource , testNamespace );
92
+ JdbcTableWriter updateTableWriter = createTestTableWriter ( feedInfoTable );
83
93
String updateOutput = updateTableWriter .update (
84
94
createdFeedInfo .id ,
85
95
mapper .writeValueAsString (createdFeedInfo ),
86
96
true
87
97
);
88
- LOG .info ("update output:" );
98
+ LOG .info ("update {} output:" , feedInfoTable . name );
89
99
LOG .info (updateOutput );
90
100
91
- FeedInfoDTO updatedFeedInfoDTO = mapper .readValue (updateOutput , FeedInfoDTO . class );
101
+ FeedInfoDTO updatedFeedInfoDTO = mapper .readValue (updateOutput , feedInfoDTOClass );
92
102
93
103
// make sure saved data matches expected data
94
104
assertThat (updatedFeedInfoDTO .feed_publisher_name , equalTo (updatedPublisherName ));
95
105
96
106
// try to delete record
97
- JdbcTableWriter deleteTableWriter = new JdbcTableWriter ( Table . FEED_INFO , testDataSource , testNamespace );
107
+ JdbcTableWriter deleteTableWriter = createTestTableWriter ( feedInfoTable );
98
108
int deleteOutput = deleteTableWriter .delete (
99
109
createdFeedInfo .id ,
100
110
true
101
111
);
102
- LOG .info ("delete output:" );
103
- LOG .info (updateOutput );
112
+ LOG .info ("deleted {} records from {}" , deleteOutput , feedInfoTable .name );
104
113
105
114
// make sure record does not exist in DB
106
- String sql = String .format (
115
+ assertThatSqlQueryYieldsZeroRows ( String .format (
107
116
"select * from %s.%s where id=%d" ,
108
117
testNamespace ,
109
- Table . FEED_INFO .name ,
118
+ feedInfoTable .name ,
110
119
createdFeedInfo .id
111
- );
112
- LOG .info (sql );
113
- ResultSet rs = testDataSource .getConnection ().prepareStatement (sql ).executeQuery ();
114
- assertThat (rs .getFetchSize (), equalTo (0 ));
120
+ ));
115
121
}
116
122
117
123
@ Test
118
124
public void canPreventSQLInjection () throws IOException , SQLException , InvalidNamespaceException {
119
- ObjectMapper mapper = new ObjectMapper ();
120
-
121
125
// create new object to be saved
122
126
FeedInfoDTO feedInfoInput = new FeedInfoDTO ();
123
127
String publisherName = "' OR 1 = 1; SELECT '1" ;
@@ -128,7 +132,7 @@ public void canPreventSQLInjection() throws IOException, SQLException, InvalidNa
128
132
feedInfoInput .default_route_type = "3" ;
129
133
130
134
// convert object to json and save it
131
- JdbcTableWriter createTableWriter = new JdbcTableWriter (Table .FEED_INFO , testDataSource , testNamespace );
135
+ JdbcTableWriter createTableWriter = createTestTableWriter (Table .FEED_INFO );
132
136
String createOutput = createTableWriter .create (mapper .writeValueAsString (feedInfoInput ), true );
133
137
LOG .info ("create output:" );
134
138
LOG .info (createOutput );
@@ -140,6 +144,169 @@ public void canPreventSQLInjection() throws IOException, SQLException, InvalidNa
140
144
assertThat (createdFeedInfo .feed_publisher_name , equalTo (publisherName ));
141
145
}
142
146
147
+ @ Test
148
+ public void canCreateUpdateAndDeleteFares () throws IOException , SQLException , InvalidNamespaceException {
149
+ // Store Table and Class values for use in test.
150
+ final Table fareTable = Table .FARE_ATTRIBUTES ;
151
+ final Class <FareDTO > fareDTOClass = FareDTO .class ;
152
+
153
+ // create new object to be saved
154
+ FareDTO fareInput = new FareDTO ();
155
+ String fareId = "2A" ;
156
+ fareInput .fare_id = fareId ;
157
+ fareInput .currency_type = "USD" ;
158
+ fareInput .price = 2.50 ;
159
+ fareInput .agency_id = "RTA" ;
160
+ fareInput .payment_method = 0 ;
161
+ // Empty value should be permitted for transfers and transfer_duration
162
+ fareInput .transfers = null ;
163
+ fareInput .transfer_duration = null ;
164
+ FareRuleDTO fareRuleInput = new FareRuleDTO ();
165
+ // Fare ID should be assigned to "child entity" by editor automatically.
166
+ fareRuleInput .fare_id = null ;
167
+ fareRuleInput .route_id = null ;
168
+ // FIXME There is currently no check for valid zone_id values in contains_id, origin_id, and destination_id.
169
+ fareRuleInput .contains_id = "any" ;
170
+ fareRuleInput .origin_id = "value" ;
171
+ fareRuleInput .destination_id = "permitted" ;
172
+ fareInput .fare_rules = new FareRuleDTO []{fareRuleInput };
173
+
174
+ // convert object to json and save it
175
+ JdbcTableWriter createTableWriter = createTestTableWriter (fareTable );
176
+ String createOutput = createTableWriter .create (mapper .writeValueAsString (fareInput ), true );
177
+ LOG .info ("create {} output:" , fareTable .name );
178
+ LOG .info (createOutput );
179
+
180
+ // parse output
181
+ FareDTO createdFare = mapper .readValue (createOutput , fareDTOClass );
182
+
183
+ // make sure saved data matches expected data
184
+ assertThat (createdFare .fare_id , equalTo (fareId ));
185
+ assertThat (createdFare .fare_rules [0 ].fare_id , equalTo (fareId ));
186
+
187
+ // try to update record
188
+ String updatedFareId = "3B" ;
189
+ createdFare .fare_id = updatedFareId ;
190
+
191
+ // covert object to json and save it
192
+ JdbcTableWriter updateTableWriter = createTestTableWriter (fareTable );
193
+ String updateOutput = updateTableWriter .update (
194
+ createdFare .id ,
195
+ mapper .writeValueAsString (createdFare ),
196
+ true
197
+ );
198
+ LOG .info ("update {} output:" , fareTable .name );
199
+ LOG .info (updateOutput );
200
+
201
+ FareDTO updatedFareDTO = mapper .readValue (updateOutput , fareDTOClass );
202
+
203
+ // make sure saved data matches expected data
204
+ assertThat (updatedFareDTO .fare_id , equalTo (updatedFareId ));
205
+ assertThat (updatedFareDTO .fare_rules [0 ].fare_id , equalTo (updatedFareId ));
206
+
207
+ // try to delete record
208
+ JdbcTableWriter deleteTableWriter = createTestTableWriter (fareTable );
209
+ int deleteOutput = deleteTableWriter .delete (
210
+ createdFare .id ,
211
+ true
212
+ );
213
+ LOG .info ("deleted {} records from {}" , deleteOutput , fareTable .name );
214
+
215
+ // make sure fare_attributes record does not exist in DB
216
+ assertThatSqlQueryYieldsZeroRows (String .format (
217
+ "select * from %s.%s where id=%d" ,
218
+ testNamespace ,
219
+ fareTable .name ,
220
+ createdFare .id
221
+ ));
222
+
223
+ // make sure fare_rules record does not exist in DB
224
+ assertThatSqlQueryYieldsZeroRows (String .format (
225
+ "select * from %s.%s where id=%d" ,
226
+ testNamespace ,
227
+ Table .FARE_RULES .name ,
228
+ createdFare .fare_rules [0 ].id
229
+ ));
230
+ }
231
+
232
+ private void assertThatSqlQueryYieldsZeroRows (String sql ) throws SQLException {
233
+ assertThatSqlQueryYieldsRowCount (sql , 0 );
234
+ }
235
+
236
+ private void assertThatSqlQueryYieldsRowCount (String sql , int expectedRowCount ) throws SQLException {
237
+ LOG .info (sql );
238
+ ResultSet resultSet = testDataSource .getConnection ().prepareStatement (sql ).executeQuery ();
239
+ assertThat (resultSet .getFetchSize (), equalTo (expectedRowCount ));
240
+ }
241
+
242
+ @ Test
243
+ public void canCreateUpdateAndDeleteRoutes () throws IOException , SQLException , InvalidNamespaceException {
244
+ // Store Table and Class values for use in test.
245
+ final Table routeTable = Table .ROUTES ;
246
+ final Class <RouteDTO > routeDTOClass = RouteDTO .class ;
247
+
248
+ // create new object to be saved
249
+ RouteDTO routeInput = new RouteDTO ();
250
+ String routeId = "500" ;
251
+ routeInput .route_id = routeId ;
252
+ routeInput .agency_id = "RTA" ;
253
+ // Empty value should be permitted for transfers and transfer_duration
254
+ routeInput .route_short_name = "500" ;
255
+ routeInput .route_long_name = "Hollingsworth" ;
256
+ routeInput .route_type = 3 ;
257
+
258
+ // convert object to json and save it
259
+ JdbcTableWriter createTableWriter = createTestTableWriter (routeTable );
260
+ String createOutput = createTableWriter .create (mapper .writeValueAsString (routeInput ), true );
261
+ LOG .info ("create {} output:" , routeTable .name );
262
+ LOG .info (createOutput );
263
+
264
+ // parse output
265
+ RouteDTO createdRoute = mapper .readValue (createOutput , routeDTOClass );
266
+
267
+ // make sure saved data matches expected data
268
+ assertThat (createdRoute .route_id , equalTo (routeId ));
269
+ // TODO: Verify with a SQL query that the database now contains the created data (we may need to use the same
270
+ // db connection to do this successfully?)
271
+
272
+ // try to update record
273
+ String updatedRouteId = "600" ;
274
+ createdRoute .route_id = updatedRouteId ;
275
+
276
+ // covert object to json and save it
277
+ JdbcTableWriter updateTableWriter = createTestTableWriter (routeTable );
278
+ String updateOutput = updateTableWriter .update (
279
+ createdRoute .id ,
280
+ mapper .writeValueAsString (createdRoute ),
281
+ true
282
+ );
283
+ LOG .info ("update {} output:" , routeTable .name );
284
+ LOG .info (updateOutput );
285
+
286
+ RouteDTO updatedRouteDTO = mapper .readValue (updateOutput , routeDTOClass );
287
+
288
+ // make sure saved data matches expected data
289
+ assertThat (updatedRouteDTO .route_id , equalTo (updatedRouteId ));
290
+ // TODO: Verify with a SQL query that the database now contains the updated data (we may need to use the same
291
+ // db connection to do this successfully?)
292
+
293
+ // try to delete record
294
+ JdbcTableWriter deleteTableWriter = createTestTableWriter (routeTable );
295
+ int deleteOutput = deleteTableWriter .delete (
296
+ createdRoute .id ,
297
+ true
298
+ );
299
+ LOG .info ("deleted {} records from {}" , deleteOutput , routeTable .name );
300
+
301
+ // make sure route record does not exist in DB
302
+ assertThatSqlQueryYieldsZeroRows (String .format (
303
+ "select * from %s.%s where id=%d" ,
304
+ testNamespace ,
305
+ routeTable .name ,
306
+ createdRoute .id
307
+ ));
308
+ }
309
+
143
310
@ AfterClass
144
311
public static void tearDownClass () {
145
312
TestUtils .dropDB (testDBName );
0 commit comments