Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
121 changes: 67 additions & 54 deletions src/api-keys/api-keys.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { enableFetchMocks } from 'jest-fetch-mock';
import type { ErrorResponse } from '../interfaces';
import { Resend } from '../resend';
import {
mockErrorResponse,
mockSuccessResponse,
} from '../test-utils/mock-fetch';
import type {
CreateApiKeyOptions,
CreateApiKeyResponseSuccess,
Expand All @@ -23,12 +27,8 @@ describe('API Keys', () => {
id: '430eed87-632a-4ea6-90db-0aace67ec228',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 201,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockSuccessResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -42,6 +42,11 @@ describe('API Keys', () => {
"token": "re_PKr4RCko_Lhm9ost2YjNCctnPjbLw8Nqk",
},
"error": null,
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -55,12 +60,8 @@ describe('API Keys', () => {
name: 'validation_error',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 422,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockErrorResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -74,6 +75,11 @@ describe('API Keys', () => {
"message": "String must contain at least 1 character(s)",
"name": "validation_error",
},
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -90,12 +96,8 @@ describe('API Keys', () => {
id: '430eed87-632a-4ea6-90db-0aace67ec228',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 201,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockSuccessResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -109,6 +111,11 @@ describe('API Keys', () => {
"token": "re_PKr4RCko_Lhm9ost2YjNCctnPjbLw8Nqk",
},
"error": null,
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -123,12 +130,8 @@ describe('API Keys', () => {
id: '430eed87-632a-4ea6-90db-0aace67ec228',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 201,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockSuccessResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -142,6 +145,11 @@ describe('API Keys', () => {
"token": "re_PKr4RCko_Lhm9ost2YjNCctnPjbLw8Nqk",
},
"error": null,
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -152,12 +160,8 @@ describe('API Keys', () => {
message: 'Access must be "full_access" | "sending_access"',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 422,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockErrorResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -176,6 +180,11 @@ describe('API Keys', () => {
"message": "Access must be "full_access" | "sending_access"",
"name": "invalid_access",
},
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand Down Expand Up @@ -271,12 +280,8 @@ describe('API Keys', () => {
created_at: '2023-04-06T23:09:49.093947+00:00',
},
];
fetchMock.mockOnce(JSON.stringify(response), {
status: 200,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockSuccessResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -296,6 +301,11 @@ describe('API Keys', () => {
},
],
"error": null,
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -306,12 +316,8 @@ describe('API Keys', () => {
const response: RemoveApiKeyResponseSuccess = {};

it('removes an api key', async () => {
fetchMock.mockOnce(JSON.stringify(response), {
status: 200,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockSuccessResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -320,6 +326,11 @@ describe('API Keys', () => {
{
"data": {},
"error": null,
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -330,12 +341,8 @@ describe('API Keys', () => {
message: 'Something went wrong',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 500,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockErrorResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -349,6 +356,11 @@ describe('API Keys', () => {
"message": "Something went wrong",
"name": "application_error",
},
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand All @@ -359,12 +371,8 @@ describe('API Keys', () => {
message: 'API key not found',
};

fetchMock.mockOnce(JSON.stringify(response), {
status: 404,
headers: {
'content-type': 'application/json',
Authorization: 'Bearer re_924b3rjh2387fbewf823',
},
mockErrorResponse(response, {
headers: { Authorization: 'Bearer re_924b3rjh2387fbewf823' },
});

const resend = new Resend('re_zKa4RCko_Lhm9ost2YjNCctnPjbLw8Nop');
Expand All @@ -380,6 +388,11 @@ describe('API Keys', () => {
"message": "API key not found",
"name": "not_found",
},
"rateLimiting": {
"limit": 2,
"remainingRequests": 2,
"shouldResetAfter": 1,
},
}
`);
});
Expand Down
12 changes: 2 additions & 10 deletions src/api-keys/interfaces/create-api-key-options.interface.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { PostOptions } from '../../common/interfaces';
import type { ErrorResponse } from '../../interfaces';
import type { Response } from '../../interfaces';

export interface CreateApiKeyOptions {
name: string;
Expand All @@ -14,12 +14,4 @@ export interface CreateApiKeyResponseSuccess {
id: string;
}

export type CreateApiKeyResponse =
| {
data: CreateApiKeyResponseSuccess;
error: null;
}
| {
data: null;
error: ErrorResponse;
};
export type CreateApiKeyResponse = Response<CreateApiKeyResponseSuccess>;
12 changes: 2 additions & 10 deletions src/api-keys/interfaces/list-api-keys.interface.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,9 @@
import type { ErrorResponse } from '../../interfaces';
import type { Response } from '../../interfaces';
import type { ApiKey } from './api-key';

export type ListApiKeysResponseSuccess = Pick<
ApiKey,
'name' | 'id' | 'created_at'
>[];

export type ListApiKeysResponse =
| {
data: ListApiKeysResponseSuccess;
error: null;
}
| {
data: null;
error: ErrorResponse;
};
export type ListApiKeysResponse = Response<ListApiKeysResponseSuccess>;
12 changes: 2 additions & 10 deletions src/api-keys/interfaces/remove-api-keys.interface.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,6 @@
import type { ErrorResponse } from '../../interfaces';
import type { Response } from '../../interfaces';

// biome-ignore lint/complexity/noBannedTypes: <explanation>
export type RemoveApiKeyResponseSuccess = {};

export type RemoveApiKeyResponse =
| {
data: RemoveApiKeyResponseSuccess;
error: null;
}
| {
data: null;
error: ErrorResponse;
};
export type RemoveApiKeyResponse = Response<RemoveApiKeyResponseSuccess>;
Loading