Skip to content

Commit

Permalink
add more validation
Browse files Browse the repository at this point in the history
  • Loading branch information
krzysztofzuraw committed Oct 24, 2024
1 parent 40344a3 commit a494cb9
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 12 deletions.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@
"tailwindcss": "^3.4.1",
"tslog": "^4.9.3",
"typescript": "^5.5.3",
"vite-tsconfig-paths": "^5.0.1",
"vitest": "^2.1.3"
},
"saleor": {
Expand Down
56 changes: 53 additions & 3 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

34 changes: 34 additions & 0 deletions src/modules/dropin/adyen/price.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,22 @@ describe("SaleorPrice", () => {

expect(adyenPrice.getAmount()).toBe(10011);
});

it("should throw an error when creating SaleorPrice with integer as amount", () => {
expect(() => SaleorPrice.create({ amount: 10011, currency: "USD" }))
.toThrowErrorMatchingInlineSnapshot(`
[ArgsParseError: ZodError: [
{
"code": "custom",
"message": "Expected float, received integer",
"path": [
"amount"
]
}
]
Invalid arguments]
`);
});
});

describe("AdyenPrice", () => {
Expand All @@ -18,4 +34,22 @@ describe("AdyenPrice", () => {

expect(saleorPrice.getAmount()).toBe(100.11);
});

it("should throw an error when creating AdyenPrice with float as amount", () => {
expect(() => AdyenPrice.create({ amount: 10.011, currency: "USD" }))
.toThrowErrorMatchingInlineSnapshot(`
[ArgsParseError: ZodError: [
{
"code": "invalid_type",
"expected": "integer",
"received": "float",
"message": "Expected integer, received float",
"path": [
"amount"
]
}
]
Invalid arguments]
`);
});
});
50 changes: 42 additions & 8 deletions src/modules/dropin/adyen/price.ts
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
import Decimal from "decimal.js-light";
import { z } from "zod";

interface Price {
getAmount(): number;
getCurrency(): string;
}
import { BaseError } from "@/lib/errors";

/**
* Represents a price in the Saleor system (amount is represented as float).
*/
export class SaleorPrice implements Price {
export class SaleorPrice {
static ArgsParseError = BaseError.subclass("ArgsParseError");

private static ArgsSchema = z.object({
amount: z
.number()
.refine((value) => Number.isFinite(value) && value % 1 !== 0, {
message: "Expected float, received integer",
}),
});

private constructor(
private amount: Decimal,
private currency: string,
Expand All @@ -19,6 +27,14 @@ export class SaleorPrice implements Price {
}

static create(args: { amount: number; currency: string }) {
const parsedArgs = SaleorPrice.ArgsSchema.safeParse(args);

if (parsedArgs.success === false) {
throw new SaleorPrice.ArgsParseError("Invalid arguments", {
cause: parsedArgs.error,
});
}

return new SaleorPrice(new Decimal(args.amount), args.currency);
}

Expand All @@ -37,14 +53,32 @@ export class SaleorPrice implements Price {
/**
* Represents a price in the Adyen system (amount is represented as integer).
*/
export class AdyenPrice implements Price {
export class AdyenPrice {
static ArgsParseError = BaseError.subclass("ArgsParseError");

private static ArgsSchema = z.object({
amount: z.number().int(),
currency: z.string(),
});

private constructor(
private amount: Decimal,
private currency: string,
) {}

static create(args: { amount: number; currency: string }) {
return new AdyenPrice(new Decimal(args.amount), args.currency);
static create(args: z.infer<typeof AdyenPrice.ArgsSchema>) {
const parsedArgs = AdyenPrice.ArgsSchema.safeParse(args);

if (parsedArgs.success === false) {
throw new AdyenPrice.ArgsParseError("Invalid arguments", {
cause: parsedArgs.error,
});
}

return new AdyenPrice(
new Decimal(parsedArgs.data.amount),
parsedArgs.data.currency,
);
}

toSaleorPrice(): SaleorPrice {
Expand Down
3 changes: 2 additions & 1 deletion vitest.config.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import react from "@vitejs/plugin-react";
import tsconfigPaths from "vite-tsconfig-paths";
import { defineConfig } from "vitest/config";

export default defineConfig({
plugins: [react()],
plugins: [react(), tsconfigPaths()],
test: {
environment: "jsdom",
watch: false,
Expand Down

0 comments on commit a494cb9

Please sign in to comment.