Skip to content

Commit

Permalink
Avoid copying Cargo.lock
Browse files Browse the repository at this point in the history
  • Loading branch information
alexliesenfeld committed Aug 31, 2024
1 parent ecbd26f commit b9f8e6d
Show file tree
Hide file tree
Showing 10 changed files with 51 additions and 23 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ docs:
cd tools && cargo run --bin extract_groups
cd tools && cargo run --bin extract_example_tests
rm -rf docs/website/generated && cp -r tools/target/generated docs/website/generated
cd docs/website && npm run generate-docs
cd docs/website && npm install && npm run generate-docs


.PHONY: fmt
Expand Down
6 changes: 3 additions & 3 deletions docs/website/generated/example_tests.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"record-forwarding-github": "#[cfg(all(feature = \"proxy\", feature = \"record\"))]\n#[test]\nfn record_github_api_with_forwarding_test() {\n // Let's create our mock server for the test\n let server = MockServer::start();\n\n // We configure our server to forward the request to the target\n // host instead of answering with a mocked response. The 'when'\n // variable lets you configure rules under which forwarding\n // should take place.\n server.forward_to(\"https://api.github.com\", |rule| {\n rule.filter(|when| {\n when.any_request(); // Ensure all requests are forwarded.\n });\n });\n\n let recording = server.record(|rule| {\n rule\n // Specify which headers to record.\n // Only the headers listed here will be captured and stored\n // as part of the recorded mock. This selective recording is\n // necessary because some headers may vary between requests\n // and could cause issues when replaying the mock later.\n // For instance, headers like 'Authorization' or 'Date' may\n // change with each request.\n .record_request_header(\"User-Agent\")\n .filter(|when| {\n when.any_request(); // Ensure all requests are recorded.\n });\n });\n\n // Now let's send an HTTP request to the mock server. The request\n // will be forwarded to the GitHub API, as we configured before.\n let client = Client::new();\n\n let response = client\n .get(server.url(\"/repos/torvalds/linux\"))\n // GitHub requires us to send a user agent header\n .header(\"User-Agent\", \"httpmock-test\")\n .send()\n .unwrap();\n\n // Since the request was forwarded, we should see a GitHub API response.\n assert_eq!(response.status().as_u16(), 200);\n assert_eq!(true, response.text().unwrap().contains(\"\\\"private\\\":false\"));\n\n // Save the recording to\n // \"target/httpmock/recordings/github-torvalds-scenario_<timestamp>.yaml\".\n recording\n .save(\"github-torvalds-scenario\")\n .expect(\"cannot store scenario on disk\");\n}",
"playback-forwarding-github": "#[cfg(all(feature = \"proxy\", feature = \"record\"))]\n#[test]\nfn playback_github_api() {\n // Start a mock server for the test\n let server = MockServer::start();\n\n // Configure the mock server to forward requests to the target\n // host (GitHub API) instead of responding with a mock. The 'rule'\n // parameter allows you to define conditions under which forwarding\n // should occur.\n server.forward_to(\"https://api.github.com\", |rule| {\n rule.filter(|when| {\n when.any_request(); // Forward all requests.\n });\n });\n\n // Set up recording to capture all forwarded requests and responses\n let recording = server.record(|rule| {\n rule.filter(|when| {\n when.any_request(); // Record all requests and responses.\n });\n });\n\n // Send an HTTP request to the mock server, which will be forwarded\n // to the GitHub API\n let client = Client::new();\n let response = client\n .get(server.url(\"/repos/torvalds/linux\"))\n // GitHub requires a User-Agent header\n .header(\"User-Agent\", \"httpmock-test\")\n .send()\n .unwrap();\n\n // Assert that the response from the forwarded request is as expected\n assert_eq!(response.status().as_u16(), 200);\n assert!(response.text().unwrap().contains(\"\\\"private\\\":false\"));\n\n // Save the recorded interactions to a file\n let target_path = recording\n .save(\"github-torvalds-scenario\")\n .expect(\"Failed to save the recording to disk\");\n\n // Start a new mock server instance for playback\n let playback_server = MockServer::start();\n\n // Load the recorded interactions into the new mock server\n playback_server.playback(target_path);\n\n // Send a request to the playback server and verify the response\n // matches the recorded data\n let response = client\n .get(playback_server.url(\"/repos/torvalds/linux\"))\n .send()\n .unwrap();\n assert_eq!(response.status().as_u16(), 200);\n assert!(response.text().unwrap().contains(\"\\\"private\\\":false\"));\n}",
"record-proxy-github": "#[cfg(all(feature = \"proxy\", feature = \"record\"))]\n#[test]\nfn record_with_proxy_test() {\n // Start a mock server to act as a proxy for the HTTP client\n let server = MockServer::start();\n\n // Configure the mock server to proxy all incoming requests\n server.proxy(|rule| {\n rule.filter(|when| {\n when.any_request(); // Intercept all requests\n });\n });\n\n // Set up recording on the mock server to capture all proxied\n // requests and responses\n let recording = server.record(|rule| {\n rule.filter(|when| {\n when.any_request(); // Record all requests\n });\n });\n\n // Create an HTTP client configured to route requests\n // through the mock proxy server\n let github_client = Client::builder()\n // Set the proxy URL to the mock server's URL\n .proxy(reqwest::Proxy::all(server.base_url()).unwrap())\n .build()\n .unwrap();\n\n // Send a GET request using the client, which will be proxied by the mock server\n let response = github_client.get(server.base_url()).send().unwrap();\n\n // Verify that the response matches the expected mock response\n assert_eq!(response.text().unwrap(), \"This is a mock response\");\n\n // Save the recorded HTTP interactions to a file for future reference or testing\n recording\n .save(\"my_scenario_name\")\n .expect(\"could not save the recording\");\n}",
"record-proxy-github": "#[cfg(all(feature = \"proxy\", feature = \"record\", feature = \"experimental\"))]\n#[test]\nfn record_with_proxy_test() {\n // Start a mock server to act as a proxy for the HTTP client\n let server = MockServer::start();\n\n // Configure the mock server to proxy all incoming requests\n server.proxy(|rule| {\n rule.filter(|when| {\n when.any_request(); // Intercept all requests\n });\n });\n\n // Set up recording on the mock server to capture all proxied\n // requests and responses\n let recording = server.record(|rule| {\n rule.filter(|when| {\n when.any_request(); // Record all requests\n });\n });\n\n // Create an HTTP client configured to route requests\n // through the mock proxy server\n let github_client = Client::builder()\n // Set the proxy URL to the mock server's URL\n .proxy(reqwest::Proxy::all(server.base_url()).unwrap())\n .build()\n .unwrap();\n\n // Send a GET request using the client, which will be proxied by the mock server\n let response = github_client.get(server.base_url()).send().unwrap();\n\n // Verify that the response matches the expected mock response\n assert_eq!(response.text().unwrap(), \"This is a mock response\");\n\n // Save the recorded HTTP interactions to a file for future reference or testing\n recording\n .save(\"my_scenario_name\")\n .expect(\"could not save the recording\");\n}",
"forwarding-github": "#[cfg(feature = \"proxy\")]\n#[test]\nfn forward_to_github_test() {\n // Let's create our mock server for the test\n let server = MockServer::start();\n\n // We configure our server to forward the request to the target\n // host instead of answering with a mocked response. The 'when'\n // variable lets you configure rules under which forwarding\n // should take place.\n server.forward_to(\"https://api.github.com\", |rule| {\n rule.filter(|when| {\n when.any_request(); // Ensure all requests are forwarded.\n });\n });\n\n // Now let's send an HTTP request to the mock server. The request\n // will be forwarded to the GitHub API, as we configured before.\n let client = Client::new();\n\n let response = client\n .get(server.url(\"/repos/torvalds/linux\"))\n // GitHub requires us to send a user agent header\n .header(\"User-Agent\", \"httpmock-test\")\n .send()\n .unwrap();\n\n // Since the request was forwarded, we should see a GitHub API response.\n assert_eq!(response.status().as_u16(), 200);\n assert_eq!(true, response.text().unwrap().contains(\"\\\"private\\\":false\"));\n}",
"forwarding": "#[cfg(feature = \"proxy\")]\n#[test]\nfn forwarding_test() {\n // We will create this mock server to simulate a real service (e.g., GitHub, AWS, etc.).\n let target_server = MockServer::start();\n target_server.mock(|when, then| {\n when.any_request();\n then.status(200).body(\"Hi from fake GitHub!\");\n });\n\n // Let's create our mock server for the test\n let server = MockServer::start();\n\n // We configure our server to forward the request to the target host instead of\n // answering with a mocked response. The 'when' variable lets you configure\n // rules under which forwarding should take place.\n server.forward_to(target_server.base_url(), |rule| {\n rule.filter(|when| {\n when.any_request(); // We want all requests to be forwarded.\n });\n });\n\n // Now let's send an HTTP request to the mock server. The request will be forwarded\n // to the target host, as we configured before.\n let client = Client::new();\n\n // Since the request was forwarded, we should see the target host's response.\n let response = client.get(server.url(\"/get\")).send().unwrap();\n assert_eq!(response.status().as_u16(), 200);\n assert_eq!(response.text().unwrap(), \"Hi from fake GitHub!\");\n}"
"forwarding": "#[cfg(feature = \"proxy\")]\n#[test]\nfn forwarding_test() {\n // We will create this mock server to simulate a real service (e.g., GitHub, AWS, etc.).\n let target_server = MockServer::start();\n target_server.mock(|when, then| {\n when.any_request();\n then.status(200).body(\"Hi from fake GitHub!\");\n });\n\n // Let's create our mock server for the test\n let server = MockServer::start();\n\n // We configure our server to forward the request to the target host instead of\n // answering with a mocked response. The 'when' variable lets you configure\n // rules under which forwarding should take place.\n server.forward_to(target_server.base_url(), |rule| {\n rule.filter(|when| {\n when.any_request(); // We want all requests to be forwarded.\n });\n });\n\n // Now let's send an HTTP request to the mock server. The request will be forwarded\n // to the target host, as we configured before.\n let client = Client::new();\n\n // Since the request was forwarded, we should see the target host's response.\n let response = client.get(server.url(\"/get\")).send().unwrap();\n assert_eq!(response.status().as_u16(), 200);\n assert_eq!(response.text().unwrap(), \"Hi from fake GitHub!\");\n}",
"playback-forwarding-github": "#[cfg(all(feature = \"proxy\", feature = \"record\"))]\n#[test]\nfn playback_github_api() {\n // Start a mock server for the test\n let server = MockServer::start();\n\n // Configure the mock server to forward requests to the target\n // host (GitHub API) instead of responding with a mock. The 'rule'\n // parameter allows you to define conditions under which forwarding\n // should occur.\n server.forward_to(\"https://api.github.com\", |rule| {\n rule.filter(|when| {\n when.any_request(); // Forward all requests.\n });\n });\n\n // Set up recording to capture all forwarded requests and responses\n let recording = server.record(|rule| {\n rule.filter(|when| {\n when.any_request(); // Record all requests and responses.\n });\n });\n\n // Send an HTTP request to the mock server, which will be forwarded\n // to the GitHub API\n let client = Client::new();\n let response = client\n .get(server.url(\"/repos/torvalds/linux\"))\n // GitHub requires a User-Agent header\n .header(\"User-Agent\", \"httpmock-test\")\n .send()\n .unwrap();\n\n // Assert that the response from the forwarded request is as expected\n assert_eq!(response.status().as_u16(), 200);\n assert!(response.text().unwrap().contains(\"\\\"private\\\":false\"));\n\n // Save the recorded interactions to a file\n let target_path = recording\n .save(\"github-torvalds-scenario\")\n .expect(\"Failed to save the recording to disk\");\n\n // Start a new mock server instance for playback\n let playback_server = MockServer::start();\n\n // Load the recorded interactions into the new mock server\n playback_server.playback(target_path);\n\n // Send a request to the playback server and verify the response\n // matches the recorded data\n let response = client\n .get(playback_server.url(\"/repos/torvalds/linux\"))\n .send()\n .unwrap();\n assert_eq!(response.status().as_u16(), 200);\n assert!(response.text().unwrap().contains(\"\\\"private\\\":false\"));\n}"
}
19 changes: 13 additions & 6 deletions docs/website/src/content/docs/record-and-playback/recording.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ description: Explains how requests can be recorded.

import codeExamples from "../../../../generated/example_tests.json"
import { Code } from '@astrojs/starlight/components';
import { Aside } from '@astrojs/starlight/components';

`httpmock` provides functionality to record both requests to third-party services and their responses.
There are two strategies how you can achieve that: Forwarding and Proxy.
Expand Down Expand Up @@ -34,8 +35,10 @@ server.forward_to("https://github.com", |rule| {
});
```

> Hint: If no forwarding rule matches a request, the mock server reverts to its standard mocking strategy and attempts
to serve a configured mock response.
<Aside type="note" title="Hint">
If no forwarding rule matches a request, the mock server reverts to its standard mocking strategy and attempts
to serve a configured mock response..
</Aside>

You can use the forwarding functionality to record requests sent to the remote service.

Expand All @@ -48,8 +51,10 @@ the responses it returns.

## Proxy Strategy

> Note: This feature is currently **unstable** and is available only under the `experimental` feature
flag. There is **no guarantee** that it will be included in a future stable release.
<Aside type="caution" title="Note">
This feature is currently **unstable** and is available only under the `experimental` feature
flag. There is **no guarantee** that it will be included in a future stable release.
</Aside>

The proxy feature in `httpmock`, while functional on its own, is particularly useful for recording
in scenarios where modifying or injecting the base URL used by the client is not possible.
Expand All @@ -73,8 +78,10 @@ The proxy server then tunnels or forwards the request to the target host, which

When configured as a proxy, `httpmock` can intercept, record, and forward both requests and responses.

> Hint: If no proxy rule matches a request, the mock server reverts to its standard mocking strategy and attempts
to serve a configured mock response.
<Aside type="note" title="Hint">
If no proxy rule matches a request, the mock server reverts to its standard mocking strategy and attempts
to serve a configured mock response.
</Aside>

### Full Example
<Code code={codeExamples['record-proxy-github']} lang="rust" />
Expand Down
11 changes: 8 additions & 3 deletions docs/website/src/content/docs/server/debugging.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title: Debugging
description: Describes what features are available to make debugging easier.
---
import { Aside } from '@astrojs/starlight/components';

## Test Failure Output

Expand Down Expand Up @@ -75,7 +76,11 @@ This output is useful for investigating issues, like figuring out why a request

The debug log level is usually the most helpful, but you can use trace to get even more details.

> **Note**: To see the log output during test execution, add the `--nocapture` argument when running your tests.
<Aside type="note" title="Note">
To see the log output during test execution, add the `--nocapture` argument when running your tests.
</Aside>

> **Hint**: If you're using the `env_logger` backend, set the `RUST_LOG` environment variable to `httpmock=debug`
to see `httpmock` logs.
<Aside type="note" title="Note">
If you're using the `env_logger` backend, set the `RUST_LOG` environment variable to `httpmock=debug`
to see `httpmock` logs.
</Aside>
7 changes: 5 additions & 2 deletions docs/website/src/content/docs/server/https.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@
title: HTTPS
description: Describes how the mock server can be configured to support HTTPS
---
import { Aside } from '@astrojs/starlight/components';

> **Note**: This feature is currently **unstable** and there is no guarantee it will be included in a future stable release.
There is progress on stabilizing it, but at the moment, HTTPS **does not work with the proxy feature**.
<Aside type="caution" title="Note">
This feature is currently **unstable** and there is no guarantee it will be included in a future stable release.
There is progress on stabilizing it, but at the moment, HTTPS **does not work with the proxy feature**.
</Aside>

By default, `httpmock` does not enable HTTPS support for testing. However, you can enable it on demand by using the
Cargo feature `https`. When this feature is enabled, `httpmock` automatically uses HTTPS for all internal communication
Expand Down
16 changes: 10 additions & 6 deletions docs/website/src/content/docs/server/standalone.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
title: Standalone Server
description: Describes how to set up and use a standalone mock server.
---
import { Aside } from '@astrojs/starlight/components';

You can use `httpmock` to run a standalone mock server in a separate process, such as a Docker container.
This setup allows the mock server to be accessible to multiple applications, not just within your Rust tests.
Expand Down Expand Up @@ -82,9 +83,10 @@ This means that test functions may be blocked when connecting to the remote serv
This is in contrast to tests that use a local mock server where parallel test execution is possible, because
each test uses its own mock server.

> **Note**: Sequential execution is only enforced on a per-process basis. This means that if multiple test runs or
applications use the remote server simultaneously, interference may still occur.

<Aside type="caution" title="Note">
Sequential execution is only enforced on a per-process basis. This means that if multiple test runs or
applications use the remote server simultaneously, interference may still occur.
</Aside>

## Usage Without Rust

Expand All @@ -108,9 +110,11 @@ then:
json_body: '{ "status" : "created" }'
```
> **Note**: Defining mocks with YAML files is straightforward because the field names directly match the corresponding
methods in the Rust API, found in the [`When`](https://docs.rs/httpmock/latest/httpmock/struct.When.html) or
[`Then`](https://docs.rs/httpmock/latest/httpmock/struct.Then.html) data structures.
<Aside type="note" title="Note">
Defining mocks with YAML files is straightforward because the field names directly match the corresponding
methods in the Rust API, found in the [`When`](https://docs.rs/httpmock/latest/httpmock/struct.When.html) or
[`Then`](https://docs.rs/httpmock/latest/httpmock/struct.Then.html) data structures.
</Aside>

Please refer to [this example file](https://github.com/alexliesenfeld/httpmock/blob/master/tests/resources/static_yaml_mock.yaml),
which includes many of the usable fields.
Loading

0 comments on commit b9f8e6d

Please sign in to comment.