Skip to content

Commit 9ce9756

Browse files
Adding tests for recent singleton changes proposed
1 parent ae4fd06 commit 9ce9756

2 files changed

Lines changed: 306 additions & 0 deletions

File tree

src/swagger-generation/tests/metadataWriter.test.ts

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,4 +285,126 @@ describe("writeMetadata", () => {
285285
}
286286
});
287287
});
288+
289+
describe("singleton support", () => {
290+
it("should include singleton properties in metadata when IsSingleton is true", () => {
291+
const definitionMap: DefinitionMap = new DefinitionMap();
292+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
293+
294+
definitionMap.EntityMap.set(
295+
"microsoft.graph.admin",
296+
new EntityType("admin", undefined, false, undefined, false, false, [], [])
297+
);
298+
299+
entityTypes.set("microsoft.graph.admin", {
300+
Name: "microsoft.graph.admin",
301+
Upsertable: true,
302+
RootUri: "/admin",
303+
IsSingleton: true,
304+
PathSegmentName: "admin",
305+
EntitySetPath: "admin",
306+
NavigationProperty: [],
307+
} as EntityTypeConfig);
308+
309+
const config = {
310+
EntityTypes: entityTypes,
311+
MetadataFilePath: "https://example.com",
312+
APIVersion: "beta",
313+
} as Config;
314+
315+
const metadata = writeMetadata(definitionMap, config);
316+
317+
expect(metadata["admin"]).toBeDefined();
318+
expect(metadata["admin"]["beta"].isSingleton).toBe(true);
319+
expect(metadata["admin"]["beta"].pathSegmentName).toBe("admin");
320+
expect(metadata["admin"]["beta"].entitySetPath).toBe("admin");
321+
});
322+
323+
it("should not include singleton properties when IsSingleton is false", () => {
324+
const definitionMap: DefinitionMap = new DefinitionMap();
325+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
326+
327+
definitionMap.EntityMap.set(
328+
"microsoft.graph.user",
329+
new EntityType("user", undefined, false, undefined, false, false, [], [])
330+
);
331+
332+
entityTypes.set("microsoft.graph.user", {
333+
Name: "microsoft.graph.user",
334+
Upsertable: true,
335+
RootUri: "/users",
336+
IsSingleton: false,
337+
NavigationProperty: [],
338+
} as EntityTypeConfig);
339+
340+
const config = {
341+
EntityTypes: entityTypes,
342+
MetadataFilePath: "https://example.com",
343+
APIVersion: "beta",
344+
} as Config;
345+
346+
const metadata = writeMetadata(definitionMap, config);
347+
348+
expect(metadata["users"]).toBeDefined();
349+
expect(metadata["users"]["beta"].isSingleton).toBe(false);
350+
expect(metadata["users"]["beta"].pathSegmentName).toBeUndefined();
351+
});
352+
353+
it("should skip internal entities when IsInternal is true", () => {
354+
const definitionMap: DefinitionMap = new DefinitionMap();
355+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
356+
357+
definitionMap.EntityMap.set(
358+
"microsoft.graph.internalEntity",
359+
new EntityType("internalEntity", undefined, false, undefined, false, false, [], [])
360+
);
361+
362+
entityTypes.set("microsoft.graph.internalEntity", {
363+
Name: "microsoft.graph.internalEntity",
364+
Upsertable: true,
365+
RootUri: "/internalEntities",
366+
IsInternal: true,
367+
NavigationProperty: [],
368+
} as EntityTypeConfig);
369+
370+
const config = {
371+
EntityTypes: entityTypes,
372+
MetadataFilePath: "https://example.com",
373+
APIVersion: "beta",
374+
} as Config;
375+
376+
const metadata = writeMetadata(definitionMap, config);
377+
378+
expect(metadata["internalEntities"]).toBeUndefined();
379+
});
380+
381+
it("should include internal entity in metadata when IsInternal is false", () => {
382+
const definitionMap: DefinitionMap = new DefinitionMap();
383+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
384+
385+
definitionMap.EntityMap.set(
386+
"microsoft.graph.publicEntity",
387+
new EntityType("publicEntity", undefined, false, undefined, false, false, [], [])
388+
);
389+
390+
entityTypes.set("microsoft.graph.publicEntity", {
391+
Name: "microsoft.graph.publicEntity",
392+
Upsertable: true,
393+
RootUri: "/publicEntities",
394+
IsInternal: false,
395+
NavigationProperty: [],
396+
} as EntityTypeConfig);
397+
398+
const config = {
399+
EntityTypes: entityTypes,
400+
MetadataFilePath: "https://example.com",
401+
APIVersion: "beta",
402+
} as Config;
403+
404+
const metadata = writeMetadata(definitionMap, config);
405+
406+
expect(metadata["publicEntities"]).toBeDefined();
407+
expect(metadata["publicEntities"]["beta"]).toBeDefined();
408+
});
409+
});
288410
});

src/swagger-generation/tests/swaggerWriter.test.ts

Lines changed: 184 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1385,5 +1385,189 @@ describe('enums', () => {
13851385

13861386
expect(writeSwagger(definitionMap, config)).toEqual(expectedSwagger);
13871387
});
1388+
});
1389+
1390+
describe('singleton resource support', () => {
1391+
it('should generate swagger path without ID parameter for singleton resources', () => {
1392+
const definitionMap: DefinitionMap = new DefinitionMap();
1393+
const entityMap: EntityMap = new Map<string, EntityType>();
1394+
1395+
const adminEntity = new EntityType('admin', undefined, false, undefined, false, false, [], []);
1396+
entityMap.set('microsoft.graph.admin', adminEntity);
1397+
1398+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
1399+
entityTypes.set('microsoft.graph.admin', {
1400+
Name: 'microsoft.graph.admin',
1401+
RootUri: '/admin',
1402+
Upsertable: true,
1403+
IsSingleton: true,
1404+
PathSegmentName: 'admin',
1405+
EntitySetPath: 'admin',
1406+
NavigationProperty: []
1407+
} as EntityTypeConfig);
1408+
1409+
const config = {
1410+
ExtensionVersion: "1.0.0",
1411+
EntityTypes: entityTypes,
1412+
MetadataFilePath: 'https://example.com',
1413+
APIVersion: 'beta'
1414+
} as Config;
1415+
1416+
definitionMap.EntityMap = entityMap;
1417+
definitionMap.EnumMap = new Map();
1418+
1419+
const result = writeSwagger(definitionMap, config);
1420+
1421+
// Check that the singleton path exists without ID parameter
1422+
expect(result.paths['/{rootScope}/providers/Microsoft.Graph/admin']).toBeDefined();
1423+
1424+
// Check that the operation exists
1425+
const adminPath = result.paths['/{rootScope}/providers/Microsoft.Graph/admin'];
1426+
expect(adminPath.put).toBeDefined();
1427+
1428+
// Check that no ID parameter is included for singleton
1429+
if (adminPath.put) {
1430+
const parameters = adminPath.put.parameters;
1431+
const idParameter = parameters.find(p => p.name === 'adminId');
1432+
expect(idParameter).toBeUndefined();
1433+
1434+
// Should still have body parameter
1435+
const bodyParameter = parameters.find(p => p.in === 'body');
1436+
expect(bodyParameter).toBeDefined();
1437+
}
1438+
});
1439+
1440+
it('should generate swagger path with ID parameter for non-singleton resources', () => {
1441+
const definitionMap: DefinitionMap = new DefinitionMap();
1442+
const entityMap: EntityMap = new Map<string, EntityType>();
1443+
1444+
const userEntity = new EntityType('user', undefined, false, undefined, false, false, [], []);
1445+
entityMap.set('microsoft.graph.user', userEntity);
1446+
1447+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
1448+
entityTypes.set('microsoft.graph.user', {
1449+
Name: 'microsoft.graph.user',
1450+
RootUri: '/users',
1451+
Upsertable: true,
1452+
IsSingleton: false,
1453+
NavigationProperty: []
1454+
} as EntityTypeConfig);
1455+
1456+
const config = {
1457+
ExtensionVersion: "1.0.0",
1458+
EntityTypes: entityTypes,
1459+
MetadataFilePath: 'https://example.com',
1460+
APIVersion: 'beta'
1461+
} as Config;
1462+
1463+
definitionMap.EntityMap = entityMap;
1464+
definitionMap.EnumMap = new Map();
1465+
1466+
const result = writeSwagger(definitionMap, config);
1467+
1468+
// Check that the regular path exists with ID parameter
1469+
expect(result.paths['/{rootScope}/providers/Microsoft.Graph/users/{userId}']).toBeDefined();
1470+
1471+
// Check that the operation exists
1472+
const userPath = result.paths['/{rootScope}/providers/Microsoft.Graph/users/{userId}'];
1473+
expect(userPath.put).toBeDefined();
1474+
1475+
// Check that ID parameter is included for non-singleton
1476+
if (userPath.put) {
1477+
const parameters = userPath.put.parameters;
1478+
const idParameter = parameters.find(p => p.name === 'userId');
1479+
expect(idParameter).toBeDefined();
1480+
if (idParameter) {
1481+
expect(idParameter.in).toBe('path');
1482+
expect(idParameter.required).toBe(true);
1483+
}
1484+
}
1485+
});
13881486

1487+
it('should skip internal entities in swagger generation when IsInternal is true', () => {
1488+
const definitionMap: DefinitionMap = new DefinitionMap();
1489+
const entityMap: EntityMap = new Map<string, EntityType>();
1490+
1491+
const internalEntity = new EntityType('internalEntity', undefined, false, undefined, false, false, [], []);
1492+
entityMap.set('microsoft.graph.internalEntity', internalEntity);
1493+
1494+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
1495+
entityTypes.set('microsoft.graph.internalEntity', {
1496+
Name: 'microsoft.graph.internalEntity',
1497+
RootUri: '/internalEntities',
1498+
Upsertable: true,
1499+
IsInternal: true,
1500+
NavigationProperty: []
1501+
} as EntityTypeConfig);
1502+
1503+
const config = {
1504+
ExtensionVersion: "1.0.0",
1505+
EntityTypes: entityTypes,
1506+
MetadataFilePath: 'https://example.com',
1507+
APIVersion: 'beta'
1508+
} as Config;
1509+
1510+
definitionMap.EntityMap = entityMap;
1511+
definitionMap.EnumMap = new Map();
1512+
1513+
const result = writeSwagger(definitionMap, config);
1514+
1515+
// Check that no path is generated for internal entity
1516+
const internalPaths = Object.keys(result.paths).filter(path => path.includes('internalEntities'));
1517+
expect(internalPaths).toHaveLength(0);
1518+
});
1519+
1520+
it('should generate swagger for container singleton resources', () => {
1521+
const definitionMap: DefinitionMap = new DefinitionMap();
1522+
const entityMap: EntityMap = new Map<string, EntityType>();
1523+
1524+
const domainRegEntity = new EntityType('domainRegistration', undefined, false, undefined, false, false, [], []);
1525+
entityMap.set('microsoft.graph.domainRegistration', domainRegEntity);
1526+
1527+
const entityTypes: Map<string, EntityTypeConfig> = new Map<string, EntityTypeConfig>();
1528+
entityTypes.set('microsoft.graph.domainRegistration', {
1529+
Name: 'microsoft.graph.domainRegistration',
1530+
RootUri: '/applications/domainRegistration',
1531+
Upsertable: true,
1532+
IsSingleton: true,
1533+
PathSegmentName: 'domainRegistration',
1534+
EntitySetPath: 'applications/domainRegistration',
1535+
ContainerEntitySet: 'applications',
1536+
NavigationProperty: []
1537+
} as EntityTypeConfig);
1538+
1539+
const config = {
1540+
ExtensionVersion: "1.0.0",
1541+
EntityTypes: entityTypes,
1542+
MetadataFilePath: 'https://example.com',
1543+
APIVersion: 'beta'
1544+
} as Config;
1545+
1546+
definitionMap.EntityMap = entityMap;
1547+
definitionMap.EnumMap = new Map();
1548+
1549+
const result = writeSwagger(definitionMap, config);
1550+
1551+
// Check that the container singleton path exists without ID parameter
1552+
expect(result.paths['/{rootScope}/providers/Microsoft.Graph/applications/{applicationsId}/domainRegistration']).toBeDefined();
1553+
1554+
// Check that the operation exists
1555+
const domainRegPath = result.paths['/{rootScope}/providers/Microsoft.Graph/applications/{applicationsId}/domainRegistration'];
1556+
expect(domainRegPath.put).toBeDefined();
1557+
1558+
// Check that no ID parameter is included for the singleton itself
1559+
if (domainRegPath.put) {
1560+
const parameters = domainRegPath.put.parameters;
1561+
const singletonIdParameter = parameters.find(p => p.name === 'domainRegistrationId');
1562+
expect(singletonIdParameter).toBeUndefined();
1563+
1564+
// Should still have container ID parameter
1565+
const containerIdParameter = parameters.find(p => p.name === 'applicationsId');
1566+
expect(containerIdParameter).toBeDefined();
1567+
1568+
// Should still have body parameter
1569+
const bodyParameter = parameters.find(p => p.in === 'body');
1570+
expect(bodyParameter).toBeDefined();
1571+
}
1572+
});
13891573
});

0 commit comments

Comments
 (0)