Skip to content
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

refactor/node api design changes #459

Merged
merged 45 commits into from
Aug 30, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
5b064c0
refactor(node): first pass at changing API design away from express m…
domharrington May 25, 2022
8365fd3
refactor(node): add support for nested express urls via req.originalUrl
domharrington May 25, 2022
ec1c08a
refactor(node): remove unneeded test to do with grouping function
domharrington May 25, 2022
15b026a
refactor(node): fix up bufferLength tests
domharrington May 26, 2022
3a7b181
refactor(node): move get-project-base-url tests elsewhere
domharrington May 26, 2022
9b097bd
refactor(node): get `res._body` tests working
domharrington May 26, 2022
edd32b5
refactor(node): get `req.body` tests working
domharrington May 26, 2022
e9a318d
refactor(node): tidy up tests
domharrington May 26, 2022
425b94f
refactor(node): add some tests for the validation errors
domharrington May 26, 2022
ad8b7d8
refactor(node): tidy up
domharrington May 26, 2022
da6d627
refactor(node): fix up other tests
domharrington May 26, 2022
da9db38
refactor(node): rename default export to readmeio.log()
domharrington May 26, 2022
4003342
refactor(node): tidy up
domharrington May 26, 2022
cc37208
refactor(node): switch from using default export
domharrington May 26, 2022
150d913
refactor(integration): updating express app to use new method signature
domharrington May 26, 2022
f34aa1c
refactor(node): add test showing usage of calling getProjectBaseUrl()…
domharrington May 26, 2022
7098501
refactor(integration): remove unused lint rule
domharrington May 26, 2022
17edfc0
refactor(integration): update hapi code sample to use new api
domharrington May 27, 2022
0f3477d
chore: lint
domharrington May 27, 2022
14a2c4c
test: add test for har `pageref`
domharrington Jun 1, 2022
ed15cb8
Merge branch 'main' into refactor/node-api-design-changes
domharrington Jul 15, 2022
607d540
chore: lint
domharrington Jul 15, 2022
cbe84cd
feat: return with the logId from readme.log() function
domharrington Jul 15, 2022
5c0eca6
Merge branch 'main' into refactor/node-api-design-changes
domharrington Aug 22, 2022
a8eee90
chore: lint after `main` branch merge
domharrington Aug 22, 2022
79523b8
chore: fix some tests due to missing dependency
domharrington Aug 22, 2022
c8fe441
refactor: remove `getProjectBaseUrl()` function
domharrington Aug 22, 2022
e0576f4
refactor: removing express type dependency from logging functions
domharrington Aug 22, 2022
a06d21c
refactor: remove seemingly unused code
domharrington Aug 22, 2022
19245a8
Merge branch 'main' into refactor/node-api-design-changes
domharrington Aug 23, 2022
0567582
feat(integration): add POST method test
domharrington Aug 23, 2022
552961a
fix(integration): update hapi test with new api design
domharrington Aug 23, 2022
d4e0ade
fix(integration): get fastify demo working with new api design
domharrington Aug 24, 2022
edc168a
chore: code comment about raw.setHeaders piece
domharrington Aug 24, 2022
2ac995e
fix(integration): forgot to re-export verifyWebhook after refactor
domharrington Aug 24, 2022
5444d7a
Merge branch 'main' into refactor/node-api-design-changes
domharrington Aug 24, 2022
b7f8011
feat(integration): add support for POST methods to php and c#
domharrington Aug 24, 2022
04cde20
feat(integration): add support for POST methods to python/flask
domharrington Aug 24, 2022
1936d0b
Merge branch 'main' into refactor/node-api-design-changes
domharrington Aug 24, 2022
e0e2651
chore(python): lint
domharrington Aug 24, 2022
97592bf
chore: temp fix php integration test
domharrington Aug 25, 2022
c6cd973
refactor(node): switch to using spread operator instead of arr.slice()
domharrington Aug 29, 2022
7ab4e87
Update .github/MAINTAINERS.md
domharrington Aug 30, 2022
633be34
Merge branch 'main' into refactor/node-api-design-changes
domharrington Aug 30, 2022
c311e01
chore: updated comment to be clearer
domharrington Aug 30, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/MAINTAINERS.md
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ To build a Metrics integration test server, you must write an HTTP server that d
- Looks for an `README_API_KEY` environment variable, and exits with an exit code of 1 if it does not exist.
- Spawns an HTTP server that listens on the `PORT` environment variable, or 4000 if no environment variable exists.
- The HTTP server should have a listener on `GET /` that responds with a 200 status code, and a JSON response body of `{ "message": "hello world" }`
- The HTTP server should have a listener on `POST /` that will be provided with a JSON body of `{ "user": { "email": "[email protected]" } }` which should be included in the Metrics payload. This should respond with a 200 status code and an empty body.
- The HTTP server should have a Metrics SDK installed, that responds with the following identification object for the user making the request:

```json
Expand Down
69 changes: 60 additions & 9 deletions __tests__/integration-metrics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ function isListening(port, attempt = 0) {
});
}

async function getBody(response) {
let responseBody = '';
// eslint-disable-next-line no-restricted-syntax
for await (const chunk of response) {
responseBody += chunk;
}
expect(responseBody).not.toBe('');
return JSON.parse(responseBody);
}

// https://gist.github.com/krnlde/797e5e0a6f12cc9bd563123756fc101f
http.get[promisify.custom] = function getAsync(options) {
return new Promise((resolve, reject) => {
Expand All @@ -49,6 +59,22 @@ http.get[promisify.custom] = function getAsync(options) {
});
};

function post(url, body, options) {
return new Promise((resolve, reject) => {
const request = http
.request(url, { method: 'post', ...options }, response => {
response.end = new Promise(res => {
response.on('end', res);
});
resolve(response);
})
.on('error', reject);

request.write(body);
request.end();
});
}

const get = promisify(http.get);

const randomApiKey = 'a-random-readme-api-key';
Expand Down Expand Up @@ -152,21 +178,14 @@ describe('Metrics SDK Integration Tests', () => {
});
});

// TODO this needs fleshing out more with more assertions and complex
// test cases, along with more servers in different languages too!
it('should make a request to a metrics backend with a har file', async () => {
await get(`http://localhost:${PORT}`);

const [req] = await once(metricsServer, 'request');
expect(req.url).toBe('/v1/request');
expect(req.headers.authorization).toBe('Basic YS1yYW5kb20tcmVhZG1lLWFwaS1rZXk6');

let body = '';
// eslint-disable-next-line no-restricted-syntax
for await (const chunk of req) {
body += chunk;
}
body = JSON.parse(body);
const body = await getBody(req);
const [har] = body;

// Check for a uuid
Expand Down Expand Up @@ -205,11 +224,43 @@ describe('Metrics SDK Integration Tests', () => {
// Flask prints a \n character after the JSON response
// https://github.com/pallets/flask/issues/4635
expect(response.content.text.replace('\n', '')).toBe(JSON.stringify({ message: 'hello world' }));
// The \n character above means we cannot compare to a fixed number
expect(response.content.size).toStrictEqual(response.content.text.length);
expect(response.content.mimeType).toMatch(/application\/json(;\s?charset=utf-8)?/);

const responseHeaders = caseless(arrayToObject(response.headers));
expect(responseHeaders.get('content-type')).toMatch(/application\/json(;\s?charset=utf-8)?/);
});

it('should process the http POST body', async () => {
const postData = JSON.stringify({ user: { email: '[email protected]' } });
await post(`http://localhost:${PORT}/`, postData, {
headers: {
'content-type': 'application/json',
// Explicit content-length is required for Python/Flask
'content-length': Buffer.byteLength(postData),
},
});

const [req] = await once(metricsServer, 'request');

const body = await getBody(req);
const [har] = body;

const { request, response } = har.request.log.entries[0];
expect(request.method).toBe('POST');
expect(response.status).toBe(200);
expect(request.postData).toStrictEqual(
process.env.EXAMPLE_SERVER.startsWith('php')
? {
mimeType: 'application/json',
params: [],
}
: {
mimeType: 'application/json',
text: postData,
}
);
expect(response.content.text).toMatch('');
expect(response.content.size).toBe(0);
});
});
6 changes: 6 additions & 0 deletions packages/dotnet/examples/net6.0/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,4 +34,10 @@
await context.Response.WriteAsJsonAsync(new { message = "hello world" });
});

app.MapPost("/", async context =>
{
context.Response.StatusCode = 200;
await context.Response.CompleteAsync();
});

app.Run($"http://localhost:{port}");
Loading