Repository: asyncapi/parser-js
Pull request #669 (2022-11-07 11:27:13)

fix: add missed methods to the SecurityScheme model
<!--   Thank you for your contribution. Before you submit the pull request:
1. Follow contributing guidelines and make sure PR title follows Conventional Commits specification -> https://github.com/asyncapi/generator/blob/master/CONTRIBUTING.md
2. Test your changes and attach their results to the pull request.
3. Update the relevant documentation.
-->

**Description**

Add missed methods to the `SecurityScheme` model - `name()`.

I don't know if we should have methods like `hasName`, `hasScheme` for every optional fields. What do you think?

Blocks https://github.com/asyncapi/markdown-template/pull/312

cc @smoya 

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=669)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=669) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=669&metric=duplicated_lines_density&view=list) No Duplication information


sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=669)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=669) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=669&metric=duplicated_lines_density&view=list) No Duplication information


smoya: > I don't know if we should have methods like `hasName`, `hasScheme` for every optional fields. What do you think?

I think we should. Not only because of consistency but making life easier. 👍 

sonarcloud[bot]: Kudos, SonarCloud Quality Gate passed!&nbsp; &nbsp; [![Quality Gate passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/passed-16px.png 'Quality Gate passed')](https://sonarcloud.io/dashboard?id=asyncapi_parser-js&pullRequest=669)

[![Bug](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/bug-16px.png 'Bug')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG) [0 Bugs](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=BUG)  
[![Vulnerability](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/vulnerability-16px.png 'Vulnerability')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY) [0 Vulnerabilities](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=VULNERABILITY)  
[![Security Hotspot](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/security_hotspot-16px.png 'Security Hotspot')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT) [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=SECURITY_HOTSPOT)  
[![Code Smell](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/code_smell-16px.png 'Code Smell')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL) [![A](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/RatingBadge/A-16px.png 'A')](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL) [0 Code Smells](https://sonarcloud.io/project/issues?id=asyncapi_parser-js&pullRequest=669&resolved=false&types=CODE_SMELL)

[![No Coverage information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/CoverageChart/NoCoverageInfo-16px.png 'No Coverage information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=669) No Coverage information  
[![No Duplication information](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/Duplications/NoDuplicationInfo-16px.png 'No Duplication information')](https://sonarcloud.io/component_measures?id=asyncapi_parser-js&pullRequest=669&metric=duplicated_lines_density&view=list) No Duplication information



Patch:
diff --git a/src/models/security-requirement.ts b/src/models/security-requirement.ts
index f24ab62..6dc4d78 100644
--- a/src/models/security-requirement.ts
+++ b/src/models/security-requirement.ts
@@ -2,6 +2,6 @@ import type { BaseModel } from './base';
 import type { SecuritySchemeInterface } from './security-scheme';
 
 export interface SecurityRequirementInterface extends BaseModel {
-  scheme(): SecuritySchemeInterface
+  scheme(): SecuritySchemeInterface;
   scopes(): string[];
 }
diff --git a/src/models/security-scheme.ts b/src/models/security-scheme.ts
index e3c0846..87eea93 100644
--- a/src/models/security-scheme.ts
+++ b/src/models/security-scheme.ts
@@ -3,12 +3,18 @@ import type { OAuthFlowsInterface } from './oauth-flows';
 import type { DescriptionMixinInterface, ExtensionsMixinInterface } from './mixins';
 
 export interface SecuritySchemeInterface extends BaseModel, DescriptionMixinInterface, ExtensionsMixinInterface {
-  id(): string
+  id(): string;
+  type(): string;
+  hasName(): boolean;
+  name(): string | undefined;
+  hasIn(): boolean;
+  in(): string | undefined;
+  hasScheme(): boolean;
+  scheme(): string | undefined;
   hasBearerFormat(): boolean;
   bearerFormat(): string | undefined;
-  openIdConnectUrl(): string | undefined;
-  scheme(): string | undefined;
+  hasFlows(): boolean;
   flows(): OAuthFlowsInterface | undefined;
-  type(): string;
-  in(): string | undefined;
+  hasOpenIdConnectUrl(): boolean;
+  openIdConnectUrl(): string | undefined;
 }
diff --git a/src/models/v2/security-scheme.ts b/src/models/v2/security-scheme.ts
index 2e3b299..2685407 100644
--- a/src/models/v2/security-scheme.ts
+++ b/src/models/v2/security-scheme.ts
@@ -14,6 +14,10 @@ export class SecurityScheme extends BaseModel<v2.SecuritySchemeObject, { id: str
     return this._meta.id;
   }
 
+  type(): v2.SecuritySchemeType {
+    return this._json.type;
+  }
+
   hasDescription(): boolean {
     return hasDescription(this);
   }
@@ -22,33 +26,53 @@ export class SecurityScheme extends BaseModel<v2.SecuritySchemeObject, { id: str
     return description(this);
   }
 
-  hasBearerFormat(): boolean {
-    return !!this._json.bearerFormat;
+  hasName(): boolean {
+    return !!this._json.name;
   }
 
-  bearerFormat(): string | undefined {
-    return this._json.bearerFormat;
+  name(): string | undefined {
+    return this._json.name;
   }
 
-  openIdConnectUrl(): string | undefined {
-    return this._json.openIdConnectUrl;
+  hasIn(): boolean {
+    return !!this._json.in;
+  }
+
+  in(): v2.SecuritySchemaLocation | undefined {
+    return this._json.in;
+  }
+
+  hasScheme(): boolean {
+    return !!this._json.scheme;
   }
 
   scheme(): string | undefined {
     return this._json.scheme;
   }
 
+  hasBearerFormat(): boolean {
+    return !!this._json.bearerFormat;
+  }
+
+  bearerFormat(): string | undefined {
+    return this._json.bearerFormat;
+  }
+
+  hasFlows(): boolean {
+    return !!this._json.flows;
+  }
+
   flows(): OAuthFlowsInterface | undefined {
     if (!this._json.flows) return undefined;
     return new OAuthFlows(this._json.flows);
   }
 
-  type(): v2.SecuritySchemeType {
-    return this._json.type;
+  hasOpenIdConnectUrl(): boolean {
+    return !!this._json.openIdConnectUrl;
   }
 
-  in(): v2.SecuritySchemaLocation | undefined {
-    return this._json.in;
+  openIdConnectUrl(): string | undefined {
+    return this._json.openIdConnectUrl;
   }
 
   extensions(): ExtensionsInterface {


Test patch:
diff --git a/test/models/v2/security-requirement.spec.ts b/test/models/v2/security-requirement.spec.ts
index a3319c9..de57c65 100644
--- a/test/models/v2/security-requirement.spec.ts
+++ b/test/models/v2/security-requirement.spec.ts
@@ -12,6 +12,7 @@ describe('SecurityRequirement model', function() {
       expect(d.scheme()).toEqual(expectedScheme);   
     });
   });
+  
   describe('.scopes()', function() {
     it('should return scopes', function() {
       const scopes = ['scope_one'];
diff --git a/test/models/v2/security-scheme.spec.ts b/test/models/v2/security-scheme.spec.ts
index bcf3935..3e0f02e 100644
--- a/test/models/v2/security-scheme.spec.ts
+++ b/test/models/v2/security-scheme.spec.ts
@@ -1,10 +1,12 @@
 import { SecurityScheme } from '../../../src/models/v2/security-scheme';
 import { OAuthFlows } from '../../../src/models/v2/oauth-flows';
+import { assertDescription, assertExtensions } from './utils';
 
 import type { v2 } from '../../../src/spec-types';
 
 const doc1: v2.SecuritySchemeObject = {
   type: 'http',
+  name: 'api_key',
   in: 'header',
   scheme: 'bearer',
   bearerFormat: 'JWT',
@@ -26,38 +28,103 @@ const emptyItem = new SecurityScheme({ type: 'X509' });
 describe('Security Scheme', function () {
   describe('.id()', function () {
     it('should return name if present', function () {
-      expect(sc1.id()).toMatch('api_key');
+      expect(sc1.id()).toEqual('api_key');
     });
   });
 
   describe('.type()', function () {
     it('should return type when it is present', function () {
-      expect(sc1.type()).toMatch(doc1.type);
+      expect(sc1.type()).toEqual(doc1.type);
     });
   });
 
-  describe('.hasBearerFormat()', function () {
-    it('should return true if bearerFormat is present', function () {
-      expect(sc1.hasBearerFormat()).toBeTruthy();
+  describe('.hasName()', function () {
+    it('should return true if name is present', function () {
+      const data = new SecurityScheme({ type: 'apiKey', name: 'name' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasName()).toEqual(true);
     });
 
-    it('should return false if bearerFormat is not present', function () {
-      expect(emptyItem.hasBearerFormat()).toBeFalsy();
+    it('should return false if name is not present', function () {
+      const data = new SecurityScheme({ type: 'apiKey' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasName()).toEqual(false);
+    });
+  });
+
+  describe('.name()', function () {
+    it('should return name if present', function () {
+      expect(sc1.name()).toEqual(doc1.name);
+    });
+  });
+
+  describe('.hasIn()', function () {
+    it('should return true if in is present', function () {
+      const data = new SecurityScheme({ type: 'apiKey', in: 'header' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasIn()).toEqual(true);
+    });
+
+    it('should return false if in is not present', function () {
+      const data = new SecurityScheme({ type: 'apiKey' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasIn()).toEqual(false);
     });
   });
 
   describe('.in()', function () {
     it('should return in if present', function () {
-      expect(sc1.in()).toMatch(doc1.in as string);
+      expect(sc1.in()).toEqual(doc1.in);
       expect(emptyItem.in()).toBeUndefined();
     });
   });
 
-  describe('.openIdConnectUrl()', function () {
-    it('should return openIdConnectUrl value', function () {
-      expect(sc1.openIdConnectUrl()).toMatch(doc1.openIdConnectUrl as string);
+  describe('.hasBearerFormat()', function () {
+    it('should return true if bearerFormat is present', function () {
+      const data = new SecurityScheme({ type: 'apiKey', bearerFormat: 'bearerFormat' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasBearerFormat()).toEqual(true);
+    });
+
+    it('should return false if bearerFormat is not present', function () {
+      const data = new SecurityScheme({ type: 'apiKey' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasBearerFormat()).toEqual(false);
+    });
+  });
+
+  describe('.bearerFormat()', function () {
+    it('should return bearerFormat if present', function () {
+      expect(sc1.bearerFormat()).toEqual(doc1.bearerFormat);
+      expect(emptyItem.bearerFormat()).toBeUndefined();
+    });
+  });
+
+  describe('.hasScheme()', function () {
+    it('should return true if bearerFormat is present', function () {
+      const data = new SecurityScheme({ type: 'apiKey', scheme: 'scheme' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasScheme()).toEqual(true);
+    });
+
+    it('should return false if bearerFormat is not present', function () {
+      const data = new SecurityScheme({ type: 'apiKey' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasScheme()).toEqual(false);
+    });
+  });
+
+  describe('.scheme()', function () {
+    it('should return scheme if present', function () {
+      expect(sc1.scheme()).toEqual(doc1.scheme);
+      expect(emptyItem.scheme()).toBeUndefined();
     });
   });
+
+  describe('.hasFlows()', function () {
+    it('should return true if flows is present', function () {
+      const data = new SecurityScheme({ type: 'apiKey', flows: {} }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasFlows()).toEqual(true);
+    });
+
+    it('should return false if flows is not present', function () {
+      const data = new SecurityScheme({ type: 'apiKey' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasFlows()).toEqual(false);
+    });
+  });
+
   describe('.flows()', function () {
     it('should return undefined if flow object is not present', function () {
       expect(emptyItem.flows()).toBeUndefined();
@@ -67,4 +134,27 @@ describe('Security Scheme', function () {
       expect(sc1.flows() instanceof OAuthFlows).toBeTruthy();
     });
   });
+
+  describe('.hasOpenIdConnectUrl()', function () {
+    it('should return true if openIdConnectUrl is present', function () {
+      const data = new SecurityScheme({ type: 'apiKey', openIdConnectUrl: 'openIdConnectUrl' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasOpenIdConnectUrl()).toEqual(true);
+    });
+
+    it('should return false if openIdConnectUrl is not present', function () {
+      const data = new SecurityScheme({ type: 'apiKey' }, { asyncapi: {} as any, pointer: '', id: 'security-model' });
+      expect(data.hasOpenIdConnectUrl()).toEqual(false);
+    });
+  });
+
+  describe('.openIdConnectUrl()', function () {
+    it('should return openIdConnectUrl value', function () {
+      expect(sc1.openIdConnectUrl()).toMatch(doc1.openIdConnectUrl as string);
+    });
+  });
+
+  describe('mixins inheritance', function () {
+    assertDescription(SecurityScheme);
+    assertExtensions(SecurityScheme);
+  });
 });
diff --git a/test/models/v2/server-variable.spec.ts b/test/models/v2/server-variable.spec.ts
index f88659b..65110a1 100644
--- a/test/models/v2/server-variable.spec.ts
+++ b/test/models/v2/server-variable.spec.ts
@@ -1,9 +1,11 @@
 import { ServerVariable } from '../../../src/models/v2/server-variable';
+import { assertDescription, assertExtensions } from './utils';
 
 const doc = {
   description: 'Secure connection (TLS) is available through port 8883.',
   default: '1883',
-  enum: ['1883', '8883']
+  enum: ['1883', '8883'],
+  examples: ['1883', '8883'],
 };
 
 const sv = new ServerVariable(doc, { asyncapi: {} as any, pointer: '', id: 'doc' });
@@ -36,4 +38,15 @@ describe('Server Variable ', function() {
       expect(sv.allowedValues()).toEqual(doc.enum);
     });
   });
+
+  describe('.examples()', function() {
+    it('should return array', function() {
+      expect(sv.examples()).toEqual(doc.examples);
+    });
+  });
+
+  describe('mixins inheritance', function () {
+    assertDescription(ServerVariable);
+    assertExtensions(ServerVariable);
+  });
 });