1- # Mock response helper function
2- create_mock_response <- function (status_code = 200 , items = list (), total_pages = 1 ) {
1+ # Mock response helper function for NDJSON
2+ create_mock_ndjson_response <- function (status_code = 200 , ndjson_content = " " ) {
33 response <- list ()
44 class(response ) <- " response"
5-
6- # Mock the status code
75 attr(response , " status_code" ) <- status_code
8-
9- # Mock the content
10- content_data <- list (
11- items = items ,
12- totalPages = total_pages
13- )
14-
15- return (list (response = response , content = content_data ))
6+ return (list (response = response , content = ndjson_content ))
167}
178
18- test_that(" util_importwqwa validates endpoint argument" , {
19- expect_error(
20- util_importwqwa(" invalid_endpoint" ),
21- " 'arg' should be one of"
9+ test_that(" read_importwqwa processes basic NDJSON response" , {
10+ # Mock NDJSON content
11+ ndjson_content <- ' {"id": 1, "value": 10.5, "activityStartDate": "2023-01-01"}
12+ {"id": 2, "value": 12.3, "activityStartDate": "2023-01-02"}'
13+
14+ mock_data <- create_mock_ndjson_response(200 , ndjson_content )
15+
16+ # Create a proper data frame with the activityStartDate column
17+ mock_df <- data.frame (
18+ id = c(1 , 2 ),
19+ value = c(10.5 , 12.3 ),
20+ activityStartDate = c(" 2023-01-01" , " 2023-01-02" ),
21+ stringsAsFactors = FALSE
2222 )
23- })
24-
25- test_that(" util_importwqwa handles single page response" , {
26- # Mock data
27- mock_items <- list (
28- list (id = 1 , name = " Item 1" ),
29- list (id = 2 , name = " Item 2" )
30- )
31-
32- mock_data <- create_mock_response(200 , mock_items , 1 )
3323
34- # Mock httr functions
24+ # Mock functions
3525 mock_get <- mock(mock_data $ response )
3626 mock_stop_for_status <- mock()
37- mock_content <- mock(mock_data $ content )
38-
39- # Mock dplyr::bind_rows to return a simple data frame
40- mock_bind_rows <- mock(data.frame (id = c(1 , 2 ), name = c(" Item 1" , " Item 2" )))
27+ mock_content <- mock(ndjson_content )
28+ mock_fromJSON <- mock(
29+ list (id = 1 , value = 10.5 , activityStartDate = " 2023-01-01" ),
30+ list (id = 2 , value = 12.3 , activityStartDate = " 2023-01-02" )
31+ )
32+ mock_bind_rows <- mock(mock_df )
4133
4234 # Apply stubs
43- stub(util_importwqwa , " httr::GET" , mock_get )
44- stub(util_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
45- stub(util_importwqwa , " httr::content" , mock_content )
46- stub(util_importwqwa , " dplyr::bind_rows" , mock_bind_rows )
35+ stub(read_importwqwa , " httr::GET" , mock_get )
36+ stub(read_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
37+ stub(read_importwqwa , " httr::content" , mock_content )
38+ stub(read_importwqwa , " jsonlite::fromJSON" , mock_fromJSON )
39+ stub(read_importwqwa , " dplyr::bind_rows" , mock_bind_rows )
4740
48- result <- util_importwqwa(" parameters" )
41+ # Suppress trace output for testing
42+ result <- suppressMessages(read_importwqwa(" WIN_21FLHILL" , " Chla_ugl" , trace = FALSE ))
4943
5044 # Verify the result
5145 expect_equal(nrow(result ), 2 )
5246 expect_equal(result $ id , c(1 , 2 ))
47+ expect_true(" activityStartDate" %in% names(result ))
5348
54- # Verify mocks were called correctly
49+ # Verify mocks were called
5550 expect_called(mock_get , 1 )
5651 expect_called(mock_stop_for_status , 1 )
5752 expect_called(mock_content , 1 )
53+ expect_called(mock_fromJSON , 2 ) # Once for each JSON line
5854})
5955
60- test_that(" util_importwqwa handles multiple pages" , {
61- # Mock data for first page
62- mock_items_page1 <- list (list (id = 1 , name = " Item 1" ))
63- mock_items_page2 <- list (list (id = 2 , name = " Item 2" ))
56+ test_that(" read_importwqwa includes optional date parameters" , {
57+ mock_data <- create_mock_ndjson_response(200 , ' {"id": 1, "activityStartDate": "2023-01-01"}' )
6458
65- mock_data_page1 <- create_mock_response( 200 , mock_items_page1 , 2 )
66- mock_data_page2 <- create_mock_response( 200 , mock_items_page2 , 2 )
59+ # Create proper data frame with activityStartDate column
60+ mock_df <- data.frame ( id = 1 , activityStartDate = " 2023-01-01 " , stringsAsFactors = FALSE )
6761
68- # Mock httr functions
69- mock_get <- mock(mock_data_page1 $ response , mock_data_page2 $ response )
70- mock_stop_for_status <- mock()
71- mock_content <- mock(mock_data_page1 $ content , mock_data_page2 $ content )
62+ # Capture the query parameters
63+ mock_get <- mock(mock_data $ response , side_effect = function (url , query ) {
64+ captured_query <<- query
65+ return (mock_data $ response )
66+ })
7267
73- # Mock dplyr::bind_rows
74- mock_bind_rows <- mock(
75- data.frame (id = 1 , name = " Item 1" ), # First call for page 1
76- data.frame (id = 2 , name = " Item 2" ), # Second call for page 2
77- data.frame (id = c(1 , 2 ), name = c(" Item 1" , " Item 2" )) # Final bind
78- )
68+ mock_stop_for_status <- mock()
69+ mock_content <- mock(' {"id": 1, "activityStartDate": "2023-01-01"}' )
70+ mock_fromJSON <- mock(list (id = 1 , activityStartDate = " 2023-01-01" ))
71+ mock_bind_rows <- mock(mock_df )
7972
8073 # Apply stubs
81- stub(util_importwqwa , " httr::GET" , mock_get )
82- stub(util_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
83- stub(util_importwqwa , " httr::content" , mock_content )
84- stub(util_importwqwa , " dplyr::bind_rows " , mock_bind_rows )
85-
86- result <- util_importwqwa( " waterbodies " )
87-
88- # Verify the result
89- expect_equal(nrow( result ), 2 )
74+ stub(read_importwqwa , " httr::GET" , mock_get )
75+ stub(read_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
76+ stub(read_importwqwa , " httr::content" , mock_content )
77+ stub(read_importwqwa , " jsonlite::fromJSON " , mock_fromJSON )
78+ stub( read_importwqwa , " dplyr::bind_rows " , mock_bind_rows )
79+
80+ result <- suppressMessages(
81+ read_importwqwa( " WIN_21FLHILL " , " Chla_ugl " , " 2023-01-01 " , " 2023-02-01 " , trace = FALSE )
82+ )
9083
91- # Verify GET was called twice (once for each page)
92- expect_called(mock_get , 2 )
93- expect_called(mock_stop_for_status , 2 )
94- expect_called(mock_content , 2 )
84+ # Verify parameters were included
85+ expect_equal(result $ activityStartDate , as.Date(" 2023-01-01" ))
9586})
9687
97- test_that(" util_importwqwa handles HTTP errors gracefully" , {
98- # Mock a failed response
88+ test_that(" read_importwqwa handles HTTP errors" , {
9989 mock_response <- list ()
10090 class(mock_response ) <- " response"
101- attr(mock_response , " status_code" ) <- 500
91+ attr(mock_response , " status_code" ) <- 404
10292
10393 mock_get <- mock(mock_response )
104- mock_stop_for_status <- mock(stop(" HTTP 500 Internal Server Error" ))
94+ mock_stop_for_status <- mock(stop(" HTTP 404 Not Found" ))
95+
96+ # Apply stubs
97+ stub(read_importwqwa , " httr::GET" , mock_get )
98+ stub(read_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
99+
100+ expect_error(
101+ suppressMessages(read_importwqwa(" INVALID" , " INVALID" , trace = FALSE )),
102+ " HTTP 404 Not Found"
103+ )
104+ })
105+
106+ test_that(" read_importwqwa handles malformed JSON gracefully" , {
107+ # Mix of valid and invalid JSON
108+ ndjson_content <- ' {"id": 1, "value": 10.5}
109+ {invalid json}
110+ {"id": 2, "value": 12.3}'
111+
112+ mock_data <- create_mock_ndjson_response(200 , ndjson_content )
113+
114+ # Create data frame without activityStartDate since it's not in the test data
115+ mock_df <- data.frame (id = c(1 , 2 ), value = c(10.5 , 12.3 ), stringsAsFactors = FALSE )
116+
117+ mock_get <- mock(mock_data $ response )
118+ mock_stop_for_status <- mock()
119+ mock_content <- mock(ndjson_content )
120+
121+ # Mock fromJSON to succeed twice and fail once
122+ mock_fromJSON <- mock(
123+ list (id = 1 , value = 10.5 ),
124+ stop(" Invalid JSON" ),
125+ list (id = 2 , value = 12.3 )
126+ )
127+
128+ mock_bind_rows <- mock(mock_df )
105129
106130 # Apply stubs
107- stub(util_importwqwa , " httr::GET" , mock_get )
108- stub(util_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
131+ stub(read_importwqwa , " httr::GET" , mock_get )
132+ stub(read_importwqwa , " httr::stop_for_status" , mock_stop_for_status )
133+ stub(read_importwqwa , " httr::content" , mock_content )
134+ stub(read_importwqwa , " jsonlite::fromJSON" , mock_fromJSON )
135+ stub(read_importwqwa , " dplyr::bind_rows" , mock_bind_rows )
109136
110137 expect_error(
111- util_importwqwa( " parameters " ),
112- " HTTP 500 Internal Server Error "
138+ suppressMessages(read_importwqwa( " WIN_21FLHILL " , " Chla_ugl " , trace = FALSE ) ),
139+ " Error parsing JSON line: Invalid JSON "
113140 )
114141})
0 commit comments