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鈥檒l occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: move unexpectedHttpErrorLogger to testlab #2830

Merged
merged 1 commit into from
May 7, 2019

Conversation

nabdelgadir
Copy link
Contributor

@nabdelgadir nabdelgadir commented May 3, 2019

See #2803 (comment) for motivation.

Moving the unexpectedHttpErrorLogger from @loopback/rest to @loopback/testlab so it can be used for tests in other packages/examples.

Checklist

馃憠 Read and sign the CLA (Contributor License Agreement) 馃憟

  • npm test passes on your machine
  • New tests added or existing tests modified to cover all changes
  • Code conforms with the style guide
  • API Documentation in code was updated
  • Documentation in /docs/site was updated
  • Affected artifact templates in packages/cli were updated
  • Affected example projects in examples/* were updated

馃憠 Check out how to submit a PR 馃憟

@nabdelgadir nabdelgadir self-assigned this May 3, 2019
import {IncomingMessage} from 'http';

export function createUnexpectedHttpErrorLogger(
expectedStatusCode: number = 0,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we use 200 as the default value?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we accept ...expectedStatusCodes: number[] to allow multiple status codes without breaking existing code?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The purpose of this helper is to disable error logs printed by our default error handler for the status code expected by an integration/end-to-end test making HTTP calls to the tested application.

Typically, such test is verifying the response status code against a single value only.

await client.get('/foo/bar').expect(404);

Should we use 200 as the default value?

That does not make much sense to me - no error is logged for 2xx and 3xx status codes. This helper is useful only for tests expecting 4xx or 5xx response.

Can we accept ...expectedStatusCodes: number[] to allow multiple status codes without breaking existing code?

I think so. However, I am not convinced this a good practice to support. Let's defer this enhancement until we have a real-world use case needing it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That does not make much sense to me - no error is logged for 2xx and 3xx status codes. This helper is useful only for tests expecting 4xx or 5xx response.

Then why don't we have the following signature? It leaves the default to undefined instead of 0 to avoid similar confusions as I had.

export function createUnexpectedHttpErrorLogger(
  expectedStatusCode? number,
) {}

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't remember why I picked 0 as the default value. Your proposal to use undefined instead of 0 is fine with me 馃憤

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated to use undefined. 馃憤

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code changes LGTM.

Let's document the new helper please.

packages/testlab/src/http-error-logger.ts Show resolved Hide resolved
@bajtos bajtos added feature Testlab @loopback/testlab labels May 3, 2019
@bajtos bajtos added this to the May 2019 milestone milestone May 3, 2019
@raymondfeng
Copy link
Contributor

@bajtos
Copy link
Member

bajtos commented May 3, 2019

Please also check the test coverage - https://coveralls.io/builds/23172908/source?filename=packages%2Ftestlab%2Fsrc%2Fhttp-error-logger.ts#L14

Good catch!

Screen Shot 2019-05-03 at 17 57 33

I think we should disable code coverage for the console.error branch, because this branch is never executed on successful CI builds.

I think /* istanbul ignore next */ is the tool to use? See https://github.com/gotwarlost/istanbul/blob/master/ignoring-code-for-coverage.md

@nabdelgadir nabdelgadir force-pushed the refactor-unexpected-error-logger branch from b954f93 to 9e4a821 Compare May 3, 2019 22:01
@nabdelgadir nabdelgadir requested a review from bajtos May 3, 2019 22:10
@nabdelgadir nabdelgadir force-pushed the refactor-unexpected-error-logger branch 4 times, most recently from 1af00c8 to 7ca3c14 Compare May 4, 2019 15:14
@nabdelgadir
Copy link
Contributor Author

nabdelgadir commented May 4, 2019

The test I created initially does pass, but it requires @loopback/rest which causes a circular dependency, so I had to remove it.

Since I'm squashing the commits, here's the test mentioned:

import {HttpErrors, RestApplication, SequenceActions} from '@loopback/rest';
import * as sinon from 'sinon';
import {createUnexpectedHttpErrorLogger} from '../..';
import {createRestAppClient} from '../../client';
import {expect} from '../../expect';

describe('createUnexpectedHttpErrorLogger', () => {
  it('does not log an error if the status code is expected', async () => {
    const errorLogger = createUnexpectedHttpErrorLogger(401);
    const app = new RestApplication();
    const spy = sinon.spy(console, 'error');

    function throwUnauthorizedError() {
      throw new HttpErrors.Unauthorized('Unauthorized!');
    }
    app.route('get', '/', {responses: {}}, throwUnauthorizedError);

    app.bind(SequenceActions.LOG_ERROR).to(errorLogger);

    await app.start();
    const client = createRestAppClient(app);

    await client.get('/');
    expect(spy.notCalled).to.be.true();
    spy.restore();
  });
});

Copy link
Member

@bajtos bajtos left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM as far as I am concerned, but see my suggestion below on how to improve the docs.

Please consider addressing Raymond's comment above and getting his approval too.


An error logger that logs the error only when the HTTP status code is not the
expected HTTP status code. This helps surpress the console from printing an
expected error.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This helps surpress the console from printing an expected error.

Let's improve this part. My proposal - feel free to change it as you like:

This is useful when writing tests for error responses:

- We don't want any error message printed to the console when 
  the server responds with the expected error and the test passes.

- When something else goes wrong and the server returns an unexpected 
  error status code, we do want an error message to be printed to the console 
  so that we have enough information to troubleshoot the failing test.

@nabdelgadir nabdelgadir force-pushed the refactor-unexpected-error-logger branch from 7ca3c14 to 7c3b475 Compare May 7, 2019 14:20
@nabdelgadir nabdelgadir merged commit 798c416 into master May 7, 2019
@nabdelgadir nabdelgadir deleted the refactor-unexpected-error-logger branch May 7, 2019 14:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Testlab @loopback/testlab
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants