kwicherbelliaken / bad-reviews-make-good-movies

0 stars 0 forks source link

[TEST]: add tests for api handlers #40

Closed slackermorris closed 8 months ago

slackermorris commented 9 months ago

Yup. I think a lot will fall out from this. I'm getting the feeling that the backend is a little convoluted.

slackermorris commented 9 months ago

OK. I just added Zod. The lambda typings are a dogs breakfast so I need to figure how I can make sense of it all.

There is also this helpful article for mocking underlying AWS services: https://aws.amazon.com/blogs/developer/mocking-modular-aws-sdk-for-javascript-v3-in-unit-tests/

slackermorris commented 9 months ago

Maybe it is better to declare schemas for the different entities in my DB. Sort of like:

const userSchema = new Schema({
  fullName: {
    type: Schema.Types.String,
    required: true,
    unique: true,
  },
  email: {
    type: Schema.Types.String,
    required: true,
    unique: true,
  },
  password: {
    type: Schema.Types.String,
    required: true,
  },
  birthDate: {
    type: Schema.Types.Date,
    required: true,
  }
}, {
  collection: "users",
  timestamps: true,
});
slackermorris commented 9 months ago

This is a really helpful article on Zod and TypeScript and the difference. Worthwhile read.

slackermorris commented 9 months ago

Middy middleware example: https://socket.dev/npm/package/middy-kneel-before-zod

slackermorris commented 9 months ago

OK I fixed the signature for the handler wrapper types. Now I have the issue of the pathParameters conflicting.

slackermorris commented 9 months ago

This is the issue I am facing:

type UndefinedPathParameters = {

  pathParameters?: undefined;
};

type Boo = UndefinedPathParameters & z.infer<typeof eventSchema>;

const apple: Boo = {
  pathParameters: {
    username: "joe",
  },
};
Screen Shot 2023-12-06 at 8 10 27 AM

Interestingly enough, the expected fix with Omit works:

type Boo = Omit<UndefinedPathParameters, "pathParameters"> &
  z.infer<typeof eventSchema>;

So, why doesn't it work with the AWS types?

slackermorris commented 9 months ago

This is the issue I am now having w/r/t the ApiHandler and the typing of the event: https://github.com/microsoft/TypeScript/issues/50027

slackermorris commented 9 months ago

Not exactly what I am after but it does serve as a good example of at least... something.

slackermorris commented 9 months ago

Well, I just found out why Ed chooses to take this approach:

Screen Shot 2023-12-07 at 7 46 56 AM

https://stackoverflow.com/questions/69769503/how-can-i-use-typescript-partials-to-test-aws-lambda

slackermorris commented 9 months ago

I want to express that the Event is in fact an API Gateway Proxy Event.

slackermorris commented 9 months ago

Sweet. I set up a custom Zod Error mapper. I just need to confirm that I get the message back from the error handler.

slackermorris commented 8 months ago

So, I am using Walters' write up for testing Dynamo to try and test my own endpoints. The issue is that I am unsure what version of the aws-sdk I am using.

slackermorris commented 8 months ago

I should read this to understand the difference between aws-sdk V2 and V3: https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html#welcome_whats_new_v3

slackermorris commented 8 months ago

I feel like I am just going to have to bite the bullet and introduce aws-sdk V3 because the testing utilities depend on it.

slackermorris commented 8 months ago

This is a really helpful resource to understand the difference between @aws-sdk/dynamo client and lib: https://medium.com/@phillip.le/unit-testing-aws-sdk-in-typescript-236df2d73332

slackermorris commented 8 months ago

Here is someone raising a concern about sst not supporting V3: https://forum.serverless.com/t/support-for-nodejs18-x-and-aws-sdk-v3/18399

Another example of someone wondering about this: https://github.com/serverless/serverless/issues/11920

It doesn't seem as though they intend to support V3?

slackermorris commented 8 months ago

It seems as though you can use the V3 sdk without requiring an equivalent migration by sst. I'll need to write this up to understand this.

slackermorris commented 8 months ago

I need to read this about transitive and direct dependencies: https://fossa.com/blog/direct-dependencies-vs-transitive-dependencies/

slackermorris commented 8 months ago

dynamoDbRepository is a good example of migrating to V3.

slackermorris commented 8 months ago

Give a good read of this tomorrow morning: https://aws.amazon.com/blogs/developer/mocking-modular-aws-sdk-for-javascript-v3-in-unit-tests/

slackermorris commented 8 months ago

So, if I want to mock out V2, then I'll need to follow a pattern something like:

const mockDynamoPut = jest.fn();
jest.mock('aws-sdk/clients/dynamodb', () => ({
  DocumentClient: class MockDocumentClient {
    put(...args: Array<unknown>) {
      return {
        promise: () => mockDynamoPut(...args),
      };
    }
  },
}));

    expect(mockDynamoPut).toHaveBeenCalledWith(
      expect.objectContaining({
        Item: expect.objectContaining({
          accountId: mockAccountId,
          data: mockChecklistDefintionOverrides,
          meta: expect.objectContaining({ userId: mockUserId }),
        }),
      })
    );

Which is fine, but when I upgrade to V3 then the whole approach will need to be refactored. I think it is better that I upgrade to V3 now.

slackermorris commented 8 months ago

Cool. I have written the getUser test.

slackermorris commented 8 months ago

I think I will write the createUser test now.

slackermorris commented 8 months ago

Lol I forgot that I did a tonne of refactoring of everything to make this happen.

slackermorris commented 8 months ago

I need an http JSON body parser. I think this means I need to install middy.

slackermorris commented 8 months ago

OK I added middy middleware. I actually think I could have done it myself, but meh. It is handier than doing that me thinks.

slackermorris commented 8 months ago

Endpoints create and get user both work now and are unit tested.