Skip to content

Commit

Permalink
♻️ (Shopify integration): Refactor Shopify handler methods to improve…
Browse files Browse the repository at this point in the history
… clarity

✨ (Shopify tests): Update tests to reflect new logic for handling empty customer addresses
🔧 (Shopify validators): Simplify GetShopifyCustomerParams schema by removing address field
  • Loading branch information
sebpalluel committed Apr 29, 2024
1 parent 3725e1d commit d547637
Show file tree
Hide file tree
Showing 3 changed files with 31 additions and 45 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -631,9 +631,7 @@ describe('ShopifyWebhookAndApiHandler', () => {
);

handler.extractAndVerifyShopifyRequest = jest.fn().mockResolvedValue({
resultParams: {
address: 'test-address',
},
resultParams: {},
organizerId: 'test-organizer-id',
});

Expand All @@ -652,23 +650,18 @@ describe('ShopifyWebhookAndApiHandler', () => {
expect(JSON.parse(response.body)).toEqual({ address: 'test-address' });
});

it('should throw ForbiddenError if the address does not match', async () => {
it('should return empty address if the customer does not exist', async () => {
(adminSdk.GetShopifyCustomer as jest.Mock).mockResolvedValue({
shopifyCustomer: [{ address: 'different-address' }],
shopifyCustomer: [],
});

const response = await handler.hasShopifyCustomer({
req: mockRequest,
id: 'test-customer-id',
});

expect(response.status).toBe(403);
expect(JSON.parse(response.body)).toEqual(
expect.objectContaining({
error: expect.stringContaining(
'Invalid address. The address must match the address of the customer.',
),
}),
);
expect(response.status).toBe(200);
expect(JSON.parse(response.body)).toEqual({ address: null });
});
});
});
53 changes: 24 additions & 29 deletions libs/integrations/external-api-handlers/src/lib/shopify/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ export class ShopifyWebhookAndApiHandler extends BaseWebhookAndApiHandler {
super();
}

async serializeAndValidateParams<T extends RequestType>(
private async serializeAndValidateParams<T extends RequestType>(
requestType: T,
params: { [key: string]: string | string[] },
): Promise<RequestTypeToValidator[T]> {
Expand All @@ -87,7 +87,7 @@ export class ShopifyWebhookAndApiHandler extends BaseWebhookAndApiHandler {
return validator.parse(deserializedParams) as RequestTypeToValidator[T];
}

async extractAndVerifyShopifyRequest(req: NextRequest) {
private async extractAndVerifyShopifyRequest(req: NextRequest) {
const searchParams = req.nextUrl.searchParams;
const shop = this.getRequiredParam(searchParams, 'shop');
const timestamp = this.getRequiredParam(searchParams, 'timestamp');
Expand Down Expand Up @@ -284,7 +284,7 @@ export class ShopifyWebhookAndApiHandler extends BaseWebhookAndApiHandler {
);
}
});
return new NextResponse(JSON.stringify(res), {
return new NextResponse(JSON.stringify(res || {}), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
Expand Down Expand Up @@ -330,12 +330,11 @@ export class ShopifyWebhookAndApiHandler extends BaseWebhookAndApiHandler {
createShopifyCustomer = handleApiRequest<CreateShopifyCustomerOptions>(
async (options) => {
const { req, id } = options;
const { resultParams, organizerId } =
await this.extractAndVerifyShopifyRequest(req);
const validatedParams = await this.serializeAndValidateParams(
RequestType.CreateShopifyCustomer,
resultParams,
);
const { address, organizerId } =
await this.extractAndValidateShopifyParams(
req,
RequestType.CreateShopifyCustomer,
);
const shopifyCustomer = await this.getShopifyCustomer({
organizerId,
customerId: id,
Expand All @@ -345,13 +344,13 @@ export class ShopifyWebhookAndApiHandler extends BaseWebhookAndApiHandler {
}
// get or create a new account
await handleAccount({
address: validatedParams.address.toLowerCase(),
address: address.toLowerCase(),
});
await adminSdk.InsertShopifyCustomer({
object: {
organizerId,
id,
address: validatedParams.address.toLowerCase(),
address: address.toLowerCase(),
},
});
return new NextResponse(JSON.stringify({}), {
Expand All @@ -365,29 +364,25 @@ export class ShopifyWebhookAndApiHandler extends BaseWebhookAndApiHandler {
hasShopifyCustomer = handleApiRequest<GetShopifyCustomerOptions>(
async (options) => {
const { req, id } = options;
const { resultParams, organizerId } =
await this.extractAndVerifyShopifyRequest(req);
const validatedParams = await this.serializeAndValidateParams(
RequestType.CreateShopifyCustomer,
resultParams,
const { organizerId } = await this.extractAndValidateShopifyParams(
req,
RequestType.GetShopifyCustomer,
);
const shopifyCustomer = await this.getShopifyCustomer({
organizerId,
customerId: id,
});
if (
shopifyCustomer &&
shopifyCustomer.address.toLowerCase() !==
validatedParams.address.toLowerCase()
) {
throw new ForbiddenError(
'Invalid address. The address must match the address of the customer.',
);
}
return new NextResponse(JSON.stringify(shopifyCustomer), {
status: 200,
headers: { 'Content-Type': 'application/json' },
});
return new NextResponse(
JSON.stringify(
shopifyCustomer
? { address: shopifyCustomer.address }
: { address: null },
),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
},
);
},
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@ export const CreateShopifyCustomerParams = z.object({
address: z.string(),
});

export const GetShopifyCustomerParams = z.object({
address: z.string(),
});
export const GetShopifyCustomerParams = z.object({});

export const LineItemSchema = z.object({
key: z.string(),
Expand Down

0 comments on commit d547637

Please sign in to comment.