---
title: "Getting Started"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Getting Started}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

Load webmockr

```{r}
library(webmockr)
```

Enable webmockr

```{r}
webmockr::enable()
```


## Inside a test framework

```{r}
library(crul)
library(testthat)

# make a stub
stub_request("get", "https://httpbin.org/get") %>%
  to_return(body = "success!", status = 200)

# check that it's in the stub registry
stub_registry()

# make the request
z <- crul::HttpClient$new(url = "https://httpbin.org")$get("get")

# run tests (nothing returned means it passed)
expect_is(z, "HttpResponse")
expect_equal(z$status_code, 200)
expect_equal(z$parse("UTF-8"), "success!")
```

```{r echo=FALSE}
stub_registry_clear()
```


## Outside a test framework

```{r}
library(crul)
```

### Stubbed request based on uri only and with the default response

```{r}
stub_request("get", "https://httpbin.org/get")
```

```{r}
x <- HttpClient$new(url = "https://httpbin.org")
x$get('get')
```

set return objects

```{r}
stub_request("get", "https://httpbin.org/get") %>%
  wi_th(
    query = list(hello = "world")
  ) %>%
  to_return(status = 418)
```

```{r}
x$get('get', query = list(hello = "world"))
```

### Stubbing requests based on method, uri and query params

```{r}
stub_request("get", "https://httpbin.org/get") %>%
  wi_th(
    query = list(hello = "world"),
    headers = list(
      'User-Agent' = 'libcurl/7.51.0 r-curl/2.6 crul/0.3.6',
      'Accept-Encoding' = "gzip, deflate"
    )
  )
```

```{r}
stub_registry()
```

```{r}
x <- HttpClient$new(url = "https://httpbin.org")
x$get('get', query = list(hello = "world"))
```

### Stubbing requests and set expectation of a timeout

```{r error=TRUE}
stub_request("post", "https://httpbin.org/post") %>% to_timeout()
x <- HttpClient$new(url = "https://httpbin.org")
x$post('post')
```

### Stubbing requests and set HTTP error expectation

```{r error=TRUE}
library(fauxpas)
stub_request("get", "https://httpbin.org/get?a=b") %>% to_raise(HTTPBadRequest)
x <- HttpClient$new(url = "https://httpbin.org")
x$get('get', query = list(a = "b"))
```

## httr integration

```{r}
library(webmockr)
library(httr)

# turn on httr mocking
httr_mock()
```

```{r eval=FALSE}
# no stub found
GET("https://httpbin.org/get")
#> Error: Real HTTP connections are disabled.
#> Unregistered request:
#>   GET https://httpbin.org/get   with headers {Accept: application/json, text/xml, application/xml, */*}
#>
#> You can stub this request with the following snippet:
#>
#>    stub_request('get', uri = 'https://httpbin.org/get') %>%
#>      wi_th(
#>        headers = list('Accept' = 'application/json, text/xml, application/xml, */*')
#>      )
#> ============================================================
```

make a stub

```{r}
stub_request('get', uri = 'https://httpbin.org/get') %>%
  wi_th(
    headers = list(
      'Accept' = 'application/json, text/xml, application/xml, */*'
    )
  ) %>%
  to_return(
    status = 418,
    body = "I'm a teapot!!!",
    headers = list(im_a = "teapot")
  )
```

now returns mocked response


```{r eval=FALSE} 
(res <- GET("https://httpbin.org/get"))
res$status_code
#> [1] 418
res$headers
#> $im_a
#> [1] "teapot"
```

## httr2 integration

```{r message=FALSE}
library(webmockr)
library(httr2)

# turn on httr2 mocking
enable()
```

```{r eval=FALSE}
# no stub found
req <- request("https://hb.opencpu.org/get")
req_perform(req)
#> Error: Real HTTP connections are disabled.
#> Unregistered request:
#>   GET https://hb.opencpu.org/get
#>
#> You can stub this request with the following snippet:
#>
#>    stub_request('get', uri = 'https://hb.opencpu.org/get')
#> ============================================================
```

make a stub

```{r}
stub_request('get', uri = 'https://hb.opencpu.org/get') %>%
  to_return(
    status = 418,
    body = "I'm a teapot!!!",
    headers = list(im_a = "teapot")
  )
```

now returns mocked response


```{r eval=FALSE} 
req <- request("https://hb.opencpu.org/get")
res <- req_perform(req)
res
res$status_code
#> [1] 418
res$headers
#> <httr2_headers/list>
#> im_a: teapot
```

## Writing to disk

Write to a file before mocked request

```{r echo=FALSE}
stub_registry_clear()
request_registry_clear()
```

```{r}
## make a temp file
f <- tempfile(fileext = ".json")
## write something to the file
cat("{\"hello\":\"world\"}\n", file = f)
readLines(f)
## make the stub
invisible(
  stub_request("get", "https://httpbin.org/get") %>%
    to_return(body = file(f))
)
## make a request
out <- HttpClient$new("https://httpbin.org/get")$get(disk = f)
readLines(file(f))
```

OR - you can use `mock_file()` to have `webmockr` handle file and contents

```{r}
g <- tempfile(fileext = ".json")
## make the stub
invisible(
  stub_request("get", "https://httpbin.org/get") %>%
    to_return(body = mock_file(g, "{\"hello\":\"mars\"}\n"))
)
## make a request
out <- crul::HttpClient$new("https://httpbin.org/get")$get(disk = g)
readLines(out$content)
```

Writing to disk is supported in `crul`, `httr`, and `httr2`

## Many requests in a row

e.g., many redirects, then a final successful request

```{r eval=FALSE}
webmockr::enable()
library(crul)
library(fauxpas)

z <- stub_request("get", "https://httpbin.org/get")
to_return(z, status = 200, body = "foobar", headers = list(a = 5))
to_return(z, status = 200, body = "bears", headers = list(b = 6))
to_raise(z, HTTPBadRequest)
z

con <- crul::HttpClient$new(url = "https://httpbin.org")
# the first to_return()
first <- con$get("get")
first
first$parse("UTF-8")
# the second to_return()
second <- con$get("get")
second
second$parse("UTF-8")
# the third to_return() - fails as specified
third <- con$get("get")
```

Note that subsequent requests past the number of responses given with `to_return()`/etc.
simply gives the last response you specified. Although if you set a `to_timeout` or 
`to_raise` this feature won't happen since you fail out.