-
Notifications
You must be signed in to change notification settings - Fork 9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can mock APIs for HTTP but not HTTPS #52
Comments
This seems pretty similar to kiegroup/mock-github#72 |
Is this an issue of documentation? Is it a known issue and we need to be more clear what's said here?:
|
Hi @walkerab, yes this is a known issue. I am not able to mock HTTPS requests yet because under the hood I use a proxy which decides whether or not to mock a request. Now even if I set the HTTPS_PROXY env var to a "http://" location some clients will issue a CONNECT request first. This request is used to tell a proxy to set up TCP tunnel to the destination which is then secured by TLS. Since the tunnel is encrypted the proxy is not able to read the actual requests and is not able to mock it. So for example:
So, as for your questions:
It is common for clients to honor these variables. I know that curl does but sometimes clients such as Octokit don't and have to be configured manually
It is usually in their documentation
They do but that is not the issue here as I explained above. I do try to "fool" these clients by setting HTTPS_PROXY to a http location but it doesn't work for all clients, for example it doesn't work for curl but it works for axios Now as for the workarounds for this, I would suggest if possible store the base url of your APIs as env variables in your workflow. Then while testing you should be able to change the env variables and set your base url to be http (for example all workflows have $GITHUB_API_URL available, you can easily override that while testing). I do have a plan of trying to handle HTTPS directly by implementing some sort of a MITM proxy but haven't been able to get to it yet. I am open to more ideas, if you have any, on how to handle this :) Sorry for the unclear documentation, I will fix it. |
Thanks for the response, @shubhbapna. What you are saying makes enough sense to me. For now I have worked around this by using the mockttp library instead like so: Workflowname: Mock API Test
on:
pull_request:
jobs:
metrics:
name: Metrics
runs-on: ubuntu-latest
steps:
- name: CA Cert File
run: |
echo "$CA_CERT" > /tmp/ca-cert.pem
- name: HTTP api call
run: |
result=$(curl -s http://google.com)
echo "$result"
- name: HTTPS api call
run: |
result=$(curl --cacert /tmp/ca-cert.pem -s https://google.com)
echo "$result"
- run: |
result=$(\
curl --cacert /tmp/ca-cert.pem -s -L \
-H "Accept: application/vnd.github+json" \
-H "Authorization: Bearer ${{ github.token }}" \
-H "X-GitHub-Api-Version: 2022-11-28" \
http://api.github.com/rate_limit \
)
echo "$result" Jest Test Codeconst { MockGithub } = require("@kie/mock-github")
const { Act } = require("@kie/act-js")
const mockttp = require('mockttp');
const path = require("path")
jest.setTimeout(60000)
let mockGithub
beforeEach(async () => {
mockGithub = new MockGithub({
repo: {
testCompositeAction: {
files: [
{
src: path.join(__dirname, "../.actrc"),
dest: "/.actrc",
},
{
src: path.join(__dirname, "mock-api.test.yml"),
dest: ".github/workflows/mock-api.test.yml",
},
],
},
},
})
await mockGithub.setup()
})
afterEach(async () => {
await mockGithub.teardown()
})
test("it mocks a github api call", async () => {
const https = await mockttp.generateCACertificate()
const server = mockttp.getLocal({ https })
await server.start()
await server.forGet("http://google.com").thenReply(200, "mock response")
await server.forGet("https://google.com").thenReply(200, "mock response")
await server.forGet("http://api.github.com/rate_limit").thenReply(200, "mock response")
const server_url = `http://host.docker.internal:${ server.port }`
const act = new Act(mockGithub.repo.getPath("testCompositeAction"))
.setEnv("HTTP_PROXY", server_url)
.setEnv("http_proxy", server_url)
.setEnv("HTTPS_PROXY", server_url)
.setEnv("https_proxy", server_url)
.setEnv("CA_CERT", https.cert)
.setGithubToken("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") // fake token
const result = await act.runEvent("pull_request", {
logFile: path.join(__dirname, "../logs/metrics.log"),
})
console.log(result)
await server.stop()
}) |
Oh nice this library looks promising. Thank you! Although it looks like it has the same issue I was worried about in a MITM proxy - manually having to pass the cacerts but I think it is a good starting point! |
updated the docs feel free to open it again if it is unclear: opened an issue to hopefully implement complete mocking of HTTPS request: #53 |
Describe the bug
We are able to mock HTTP API requests but when we attempt to mock HTTPS API requests, they instead pass through to the original, un-mocked endpoints.
To Reproduce
Here I've set up three mocks.
I added the moctokit one so I could be sure I wasn't doing the mock setup incorrectly.
Workflow
Jest Test Code
Test Output
Expected behavior
All three mocks should intercept the api calls and respond with 'mock response'.
Instead only the HTTP API request is being mocked. The other two are hitting the actual APIs.
Logs
Logs
Additional context
I've tried this on a macbook (Ventura 13.5) as well as an AWS EC2 instance (Amazon Linux 2023) with the same results.
The text was updated successfully, but these errors were encountered: