-
-
Notifications
You must be signed in to change notification settings - Fork 293
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’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
MSW: Enum types should be generated "as const" in mocks #960
Comments
@Will-Mann-16 this looks like an easy one to verify and fix for MSW? |
I'll take a look. |
@ClementLevesque looking at this it seems to work correctly, I'm getting a union type passed through correctly and it uses ![]() openapi: 3.0.0
info:
title: ""
description: Generated by astra
contact: {}
license:
name: ""
version: ""
servers:
- url: http://localhost:8000/
paths:
/json:
get:
description: GetJSON is a test function
parameters:
- name: hello
in: header
schema:
type: string
responses:
"200":
description: ""
headers:
x-google-api-key:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/main.ResponseStruct"
"400":
description: ""
headers:
x-google-api-key:
schema:
type: string
content:
application/json:
schema:
$ref: "#/components/schemas/example_route_in.InResponseStruct"
components:
schemas:
database_sql.NullString:
type: object
properties:
String:
type: string
Valid:
type: boolean
description: |-
NullString represents a string that may be null.
NullString implements the Scanner interface so
it can be used as a scan destination:
var s NullString
err := db.QueryRow("SELECT name FROM foo WHERE id=?", id).Scan(&s)
...
if s.Valid {
// use s.String
} else {
// NULL value
}
example_route_in.InResponseStruct:
type: object
properties:
hello:
type: string
description: InResponseStruct is a test struct
main.ResponseStruct:
type: object
properties:
enum-int:
$ref: "#/components/schemas/main.TestEnumInt"
enum-string:
$ref: "#/components/schemas/main.TestEnumString"
map:
type: object
additionalProperties:
type: string
not-required:
type: integer
format: int32
required:
type: string
separate:
type: array
items:
$ref: "#/components/schemas/example_route_in.InResponseStruct"
test:
$ref: "#/components/schemas/database_sql.NullString"
time:
$ref: "#/components/schemas/time.Time"
description: ResponseStruct is a test struct
main.TestEnumInt:
enum:
- 1
- 2
- 3
type: integer
format: int32
main.TestEnumString:
enum:
- a
- b
- c
- x
- "y"
- z
type: string
time.Time:
type: string
format: date-time Notice the EDIT: So upon further investigation this works as expected when we have an enum as an object's property, but not when an enum is the top level return type. I'll see if I can find a fix for this. |
Will close until we hear back from OP |
@melloware @Will-Mann-16 Thank you both for taking time to investigate the issue I'm working on the same project as @ClementLevesque and have created a repository with a minimal reproduction. You can find it there https://github.com/Kcazer/stunning-winner I also tried your schema with our config, but, as expected, it was working fine, but I noticed two main differences :
|
And 6.20.0 just came out just verifying it still happens? |
Still happening with 6.20 But in the meantime, I've managed to track the main cause. It's definitely related to the use of $refs in the source schema. It seems to me than only "global" enums are imported in mock files, not the inline ones. When using the following schema : {
"swagger": "2.0",
"info": { "title": "orval-repro", "version": "1.0" },
"definitions": {
"y": {
"type": "string",
"enum": ["AAA", "BBB", "CCC"]
}
},
"paths": {
"/json": {
"get": {
"operationId": "JsonSample",
"summary": "Used for issue reproduction",
"tags": [],
"parameters": [],
"responses": {
"200": {
"description": "Simple JSON Object",
"schema": {
"type": "object",
"properties": {
"x": {
"type": "string",
"enum": ["AAA", "BBB", "CCC"]
},
"y": {
"$ref": "#/definitions/y"
}
}
}
}
}
}
}
},
"basePath": "/",
"consumes": ["application/json"],
"produces": ["application/json"]
} The generated mock will look like this // Schema
export type JsonSample200X = (typeof JsonSample200X)[keyof typeof JsonSample200X];
export const JsonSample200X = { AAA: "AAA", BBB: "BBB", CCC: "CCC" } as const;
export type Y = (typeof Y)[keyof typeof Y];
export const Y = { AAA: "AAA", BBB: "BBB", CCC: "CCC" } as const;
export type JsonSample200 = { x?: JsonSample200X; y?: Y; };
// Mock
import { faker } from "@faker-js/faker";
import { HttpResponse, delay, http } from "msw";
import { Y } from "./generated.schemas";
export const getJsonSampleMock = () => ({
// Inline schema => inline values, when `Object.values(JsonSample200X)` would work
x: faker.helpers.arrayElement([
faker.helpers.arrayElement(["AAA", "BBB", "CCC"]),
undefined,
]),
// Reference => is imported, everything works fine
y: faker.helpers.arrayElement([
faker.helpers.arrayElement(Object.values(Y)),
undefined,
]),
}); |
I don't think it's related, we're using different names and there is no nesting on my latest code sample |
Yeah but its basically pointing to a |
Our issue is specifically about the case when no $ref are used. When using refs, mocks are generated with the correct typings, but when inlining enums, they become |
Undertsood. PR's are welcome... |
👋 It seems that enum types in mocks are not generated "as const", therefore mocks do not satisfy routes generated types (string vs "string" as const).
What are the steps to reproduce this issue?
"properties":{"type":{"type":"string","enum":["value"]}...
What happens?
The mock generated becomes :
What were you expecting to happen?
Any other comments?
It might be fixed with the following (not tested) :
orval/packages/msw/src/getters/scalar.ts
Line 142 in ed1261a
https://github.com/anymaniax/orval/blob/ed1261af7ff773ca1338302e313ac8f02c3da00c/packages/msw/src/getters/scalar.ts#L197C1-L197C60
What versions are you using?
Operating System: MacOs
Package Version: 6.17.0
Thanks for your help 🙏 ❤️
The text was updated successfully, but these errors were encountered: