Skip to content

Commit f167a02

Browse files
Copilotabraham
andcommitted
Add integration test for entity same version nullable fix
Added comprehensive integration test to verify that: - AsyncRefresh attributes are not marked as nullable - Generated OpenAPI schema is correct - Attributes added in different versions still marked as nullable - Admin::Dimension handled correctly - Optional flag preserved for explicitly optional attributes Co-authored-by: abraham <[email protected]>
1 parent 7aee486 commit f167a02

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import { EntityParser } from '../../parsers/EntityParser';
2+
import { OpenAPIGenerator } from '../../generators/OpenAPIGenerator';
3+
4+
describe('Entity Same Version Nullable - Integration Test', () => {
5+
it('should not mark AsyncRefresh attributes as nullable since all were added in 4.4.0', () => {
6+
const parser = new EntityParser();
7+
const entities = parser.parseAllEntities();
8+
9+
const asyncRefreshEntity = entities.find((e) => e.name === 'AsyncRefresh');
10+
11+
expect(asyncRefreshEntity).toBeDefined();
12+
13+
if (asyncRefreshEntity) {
14+
// Check that none of the attributes are marked as nullable
15+
// (except for explicitly optional ones like result_count)
16+
const idAttr = asyncRefreshEntity.attributes.find(
17+
(a) => a.name === 'id'
18+
);
19+
const statusAttr = asyncRefreshEntity.attributes.find(
20+
(a) => a.name === 'status'
21+
);
22+
const resultCountAttr = asyncRefreshEntity.attributes.find(
23+
(a) => a.name === 'result_count'
24+
);
25+
26+
expect(idAttr).toBeDefined();
27+
expect(idAttr?.nullable).toBeUndefined();
28+
expect(idAttr?.versions).toEqual(['4.4.0']);
29+
30+
expect(statusAttr).toBeDefined();
31+
expect(statusAttr?.nullable).toBeUndefined();
32+
expect(statusAttr?.versions).toEqual(['4.4.0']);
33+
34+
expect(resultCountAttr).toBeDefined();
35+
expect(resultCountAttr?.nullable).toBeUndefined();
36+
// result_count is optional but not nullable
37+
expect(resultCountAttr?.optional).toBe(true);
38+
expect(resultCountAttr?.versions).toEqual(['4.4.0']);
39+
}
40+
});
41+
42+
it('should generate correct OpenAPI schema for AsyncRefresh without nullable types', () => {
43+
const parser = new EntityParser();
44+
const entities = parser.parseAllEntities();
45+
const generator = new OpenAPIGenerator();
46+
47+
const spec = generator.generateSchema(entities, []);
48+
49+
const asyncRefreshSchema = spec.components?.schemas?.AsyncRefresh;
50+
51+
expect(asyncRefreshSchema).toBeDefined();
52+
53+
if (asyncRefreshSchema && 'properties' in asyncRefreshSchema) {
54+
// Check id property - should be string, not ["string", "null"]
55+
const idProp = asyncRefreshSchema.properties?.id;
56+
expect(idProp).toBeDefined();
57+
if (idProp && 'type' in idProp) {
58+
expect(idProp.type).toBe('string');
59+
expect(idProp.type).not.toEqual(['string', 'null']);
60+
}
61+
62+
// Check status property - should be string, not ["string", "null"]
63+
const statusProp = asyncRefreshSchema.properties?.status;
64+
expect(statusProp).toBeDefined();
65+
if (statusProp && 'type' in statusProp) {
66+
expect(statusProp.type).toBe('string');
67+
expect(statusProp.type).not.toEqual(['string', 'null']);
68+
}
69+
70+
// Check result_count property - should be integer, not ["integer", "null"]
71+
const resultCountProp = asyncRefreshSchema.properties?.result_count;
72+
expect(resultCountProp).toBeDefined();
73+
if (resultCountProp && 'type' in resultCountProp) {
74+
expect(resultCountProp.type).toBe('integer');
75+
expect(resultCountProp.type).not.toEqual(['integer', 'null']);
76+
}
77+
78+
// Check required array - should include id and status, but not result_count
79+
expect(asyncRefreshSchema.required).toContain('id');
80+
expect(asyncRefreshSchema.required).toContain('status');
81+
expect(asyncRefreshSchema.required).not.toContain('result_count');
82+
}
83+
});
84+
85+
it('should still mark attributes as nullable when added in different versions', () => {
86+
const parser = new EntityParser();
87+
const entities = parser.parseAllEntities();
88+
89+
// Account entity has attributes added in different versions
90+
const accountEntity = entities.find((e) => e.name === 'Account');
91+
92+
expect(accountEntity).toBeDefined();
93+
94+
if (accountEntity) {
95+
// Some newer attributes should still be nullable
96+
const hideCollectionsAttr = accountEntity.attributes.find(
97+
(a) => a.name === 'hide_collections'
98+
);
99+
100+
// This was added in 4.3.0, so it should be nullable for backwards compatibility
101+
if (hideCollectionsAttr) {
102+
expect(hideCollectionsAttr.versions).toContain('4.3.0');
103+
expect(hideCollectionsAttr.nullable).toBe(true);
104+
}
105+
}
106+
});
107+
108+
it('should handle Admin::Dimension correctly (all attributes added in 3.5.0)', () => {
109+
const parser = new EntityParser();
110+
const entities = parser.parseAllEntities();
111+
112+
const dimensionEntity = entities.find((e) => e.name === 'Admin::Dimension');
113+
114+
expect(dimensionEntity).toBeDefined();
115+
116+
if (dimensionEntity) {
117+
// All attributes were added in 3.5.0, so none should be nullable
118+
for (const attr of dimensionEntity.attributes) {
119+
if (attr.versions && attr.versions.includes('3.5.0')) {
120+
expect(attr.nullable).toBeUndefined();
121+
}
122+
}
123+
}
124+
});
125+
126+
it('should preserve optional flag for explicitly optional attributes', () => {
127+
const parser = new EntityParser();
128+
const entities = parser.parseAllEntities();
129+
130+
// Admin::DimensionData has some explicitly optional attributes
131+
const dimensionDataEntity = entities.find(
132+
(e) => e.name === 'Admin::DimensionData'
133+
);
134+
135+
expect(dimensionDataEntity).toBeDefined();
136+
137+
if (dimensionDataEntity) {
138+
const unitAttr = dimensionDataEntity.attributes.find(
139+
(a) => a.name === 'unit'
140+
);
141+
const humanValueAttr = dimensionDataEntity.attributes.find(
142+
(a) => a.name === 'human_value'
143+
);
144+
145+
// These were explicitly marked as optional in the docs
146+
expect(unitAttr?.optional).toBe(true);
147+
expect(unitAttr?.nullable).toBeUndefined();
148+
149+
expect(humanValueAttr?.optional).toBe(true);
150+
expect(humanValueAttr?.nullable).toBeUndefined();
151+
}
152+
});
153+
});

0 commit comments

Comments
 (0)