-
Notifications
You must be signed in to change notification settings - Fork 155
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #271 from trescube/added-tests-for-various-helper-…
…functions added unit tests for various helper functions
- Loading branch information
Showing
7 changed files
with
464 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import { describe, it, expect } from 'vitest' | ||
|
||
import { beautify } from '../../../src/helpers/beautify' | ||
|
||
describe.concurrent('helpers/elasticsearchAdapter.ts', () => { | ||
describe.concurrent('beautify.ts beautify', () => { | ||
it('should return empty string when supplied with empty string', () => { | ||
expect(beautify('')).toBe('') | ||
}) | ||
|
||
it('should return undefined when supplied with undefined', () => { | ||
expect(beautify(undefined as unknown as string)).toBe(undefined) | ||
}) | ||
|
||
it('should return null when supplied with null', () => { | ||
expect(beautify(null as unknown as string)).toBe(null) | ||
}) | ||
|
||
it('should return false when supplied with false', () => { | ||
expect(beautify(false as unknown as string)).toBe(false) | ||
}) | ||
|
||
it('should return 0 when supplied with 0', () => { | ||
expect(beautify(0 as unknown as string)).toBe(0) | ||
}) | ||
|
||
it('should return empty string when supplied with empty string', () => { | ||
const text = '{"a":123456789012345678901234567890}' | ||
|
||
const normalJSONStrinigified = JSON.stringify(JSON.parse(text)) | ||
|
||
expect(normalJSONStrinigified).toBe('{"a":1.2345678901234568e+29}') | ||
|
||
expect(beautify(text)).toBe('{\n "a": 1.2345678901234567890123456789e+29\n}') | ||
}) | ||
|
||
it('should return the input string if not parseable as JSON', () => { | ||
const text = 'this { is not } json' | ||
|
||
expect(beautify(text)).toBe(text) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import { describe, it, expect } from 'vitest' | ||
|
||
import { buildFetchAuthHeader, addTrailingSlash, uriWithCredentials } from '../../../src/helpers/elasticsearchAdapter' | ||
|
||
describe.concurrent('helpers/elasticsearchAdapter.ts', () => { | ||
describe.concurrent('elasticsearchAdapter.ts buildFetchAuthHeader', () => { | ||
it('should base64-encode username and password when both are non-zero length', () => { | ||
const result = buildFetchAuthHeader('username', 'password') | ||
|
||
const [schema, encoded] = result.split(' ') | ||
|
||
expect(schema).toBe('Basic') | ||
expect(decodeURIComponent(escape(atob(encoded))).split(':')).toEqual(['username', 'password']) | ||
}) | ||
|
||
it('should base64-encode only username when non-zero length and password is zero-length', () => { | ||
const result = buildFetchAuthHeader('username', '') | ||
|
||
const [schema, encoded] = result.split(' ') | ||
|
||
expect(schema).toBe('Basic') | ||
expect(decodeURIComponent(escape(atob(encoded)))).toEqual('username') | ||
}) | ||
|
||
it('should return ApiKey schema and plaintext password when username is zero-length and password is non-zero length', () => { | ||
const result = buildFetchAuthHeader('', 'password') | ||
|
||
const [schema, apiKey] = result.split(' ') | ||
|
||
expect(schema).toBe('ApiKey') | ||
expect(apiKey).toBe('password') | ||
}) | ||
|
||
it('should return empty string when both username and password are zero-length', () => { | ||
const result = buildFetchAuthHeader('', '') | ||
|
||
expect(result).toBe('') | ||
}) | ||
}) | ||
|
||
describe.concurrent('elasticsearchAdapter.ts addTrailingSlash', () => { | ||
it('should not append a / if uri already ends with a /', () => { | ||
const uri = 'http://localhost:9200/' | ||
const result = addTrailingSlash(uri) | ||
expect(result).toBe(uri) | ||
}) | ||
|
||
it('should append a / if uri does not end with a /', () => { | ||
const uri = 'http://localhost:9200' | ||
const result = addTrailingSlash(uri) | ||
expect(result).toBe(uri + '/') | ||
}) | ||
}) | ||
|
||
describe.concurrent('elasticsearchAdapter.ts uriWithCredentials', () => { | ||
it('should stringify URI with username and password when username is non-zero length', () => { | ||
const uri = 'http://localhost:9200/' | ||
const result = uriWithCredentials(uri, 'username', 'password') | ||
expect(result).toBe('http://username:password@localhost:9200/') | ||
}) | ||
|
||
it('should not stringify URI with username and password when username is zero length', () => { | ||
const uri = 'http://localhost:9200/' | ||
const result = uriWithCredentials(uri, '', 'password') | ||
expect(result).toBe(uri) | ||
}) | ||
|
||
it('should replace embedded username and password when new username is non-zero length', () => { | ||
const uri = 'http://original_username:original_password@localhost:9200/' | ||
const result = uriWithCredentials(uri, 'username', 'password') | ||
expect(result).toBe('http://username:password@localhost:9200/') | ||
}) | ||
|
||
it('should replace username and retain password when new username is zero length', () => { | ||
const uri = 'http://original_username:original_password@localhost:9200/' | ||
const result = uriWithCredentials(uri, '', 'password') | ||
expect(result).toBe('http://:original_password@localhost:9200/') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import { describe, it, expect } from 'vitest' | ||
|
||
import { flattenObj } from '../../../src/helpers/flatten' | ||
|
||
describe.concurrent('helpers/flatten.ts', () => { | ||
describe.concurrent('flatten.ts flattenObj', () => { | ||
it('should flatten all root objects to dot notation', () => { | ||
const obj = { | ||
a: 1, | ||
b: { | ||
c: { | ||
d: 2, | ||
} | ||
}, | ||
e: [3, 4, { f: { g: 5 } }], | ||
h: { | ||
i: 6 | ||
} | ||
} | ||
|
||
expect(flattenObj(obj)).toStrictEqual({ | ||
a: 1, | ||
'b.c.d': 2, | ||
e: [3, 4, { f: { g: 5 } }], | ||
'h.i': 6 | ||
}) | ||
}) | ||
|
||
it('should throw a RangeError when input object contains a circular reference', () => { | ||
const obj = { | ||
a: 1 | ||
} | ||
|
||
obj['b'] = obj | ||
|
||
expect(() => flattenObj(obj)).toThrowError(RangeError) | ||
}) | ||
|
||
it('should flatten null to an empty object', () => { | ||
expect(flattenObj(null)).toStrictEqual({}) | ||
}) | ||
|
||
it('should flatten undefined to an empty object', () => { | ||
expect(flattenObj(undefined)).toStrictEqual({}) | ||
}) | ||
|
||
it('should flatten number to an empty object', () => { | ||
expect(flattenObj(17)).toStrictEqual({}) | ||
}) | ||
|
||
it('should flatten boolean to an empty object', () => { | ||
expect(flattenObj(true)).toStrictEqual({}) | ||
}) | ||
|
||
it('should flatten array to an index+character object', () => { | ||
expect(flattenObj(['a', 'b'])).toStrictEqual({ | ||
0: 'a', | ||
1: 'b' | ||
}) | ||
}) | ||
|
||
it('should flatten string to index+character object', () => { | ||
expect(flattenObj('asdf')).toStrictEqual({ | ||
0: 'a', | ||
1: 's', | ||
2: 'd', | ||
3: 'f' | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { describe, it, expect } from 'vitest' | ||
|
||
import { newElasticsearchCluster } from '../../../src/helpers/newCluster' | ||
import { DEFAULT_CLUSTER_NAME, DEFAULT_CLUSTER_URI } from '../../../src/consts.ts' | ||
|
||
describe.concurrent('helpers/newCluster.ts', () => { | ||
describe.concurrent('newCluster.ts newElasticsearchCluster', () => { | ||
it('should return empty string when supplied with empty string', () => { | ||
expect(newElasticsearchCluster()).toEqual({ | ||
name: DEFAULT_CLUSTER_NAME, | ||
distribution: '', | ||
username: '', | ||
password: '', | ||
uri: DEFAULT_CLUSTER_URI, | ||
clusterName: '', | ||
version: '', | ||
majorVersion: '', | ||
uuid: '', | ||
status: '' | ||
}) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
import { describe, it, expect } from 'vitest' | ||
|
||
import { nodeRoleTitle } from '../../../src/helpers/nodes' | ||
|
||
const NEWLINE = '\r\n' | ||
|
||
describe.concurrent('helpers/nodes.ts', () => { | ||
describe.concurrent('nodes.ts nodeRoleTitle', () => { | ||
it('should return empty string when supplied with empty string', () => { | ||
expect(nodeRoleTitle('')).toBe('') | ||
}) | ||
|
||
it('should return all role titles when input string contains them all', () => { | ||
// include all lowercase latin alphabet characters and hyphen character for future proofing | ||
const nodes = new Set(nodeRoleTitle('abcdefghijklmnopqrstuvwxyz-').trimEnd().split(NEWLINE)) | ||
|
||
expect(nodes.size).toBe(13) | ||
|
||
expect(nodes).toContain('c - cold node') | ||
expect(nodes).toContain('d - data node') | ||
expect(nodes).toContain('f - frozen node') | ||
expect(nodes).toContain('h - hot node') | ||
expect(nodes).toContain('i - ingest node') | ||
expect(nodes).toContain('l - machine learning node') | ||
expect(nodes).toContain('m - master-eligible node') | ||
expect(nodes).toContain('r - remote cluster client node') | ||
expect(nodes).toContain('s - content node') | ||
expect(nodes).toContain('t - transform node') | ||
expect(nodes).toContain('v - voting-only node') | ||
expect(nodes).toContain('w - warm node') | ||
expect(nodes).toContain('coordinating nodes') | ||
}) | ||
|
||
it('should only include a single role title when input is a single role character', () => { | ||
const supportedRoles = new Map([ | ||
['c','c - cold node'], | ||
['d','d - data node'], | ||
['f','f - frozen node'], | ||
['h','h - hot node'], | ||
['i','i - ingest node'], | ||
['l','l - machine learning node'], | ||
['m','m - master-eligible node'], | ||
['r','r - remote cluster client node'], | ||
['s','s - content node'], | ||
['t','t - transform node'], | ||
['v','v - voting-only node'], | ||
['w','w - warm node'], | ||
['-','coordinating nodes'] | ||
]) | ||
|
||
for (const [role, title] of supportedRoles) { | ||
expect(nodeRoleTitle(role).trimEnd()).toBe(title) | ||
} | ||
}) | ||
|
||
it('should return an empty string for all unsupported latin-1 lowercase letters', () => { | ||
const unsupportedRoleTypes = ['a', 'b', 'e', 'g', 'j', 'k', 'n', 'o', 'p', 'q', 'u', 'x', 'y', 'z'] | ||
|
||
for (const role of unsupportedRoleTypes) { | ||
expect(nodeRoleTitle(role)).toBe('') | ||
} | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
import { describe, it, expect } from 'vitest' | ||
|
||
import { sortableField } from '../../../src/helpers/search' | ||
import { DEFAULT_SORTABLE_COLUMNS } from '../../../src/consts' | ||
|
||
describe.concurrent('helpers/search.ts', () => { | ||
describe.concurrent('search.ts sortableField', () => { | ||
it('should return column name for all default sortable columns', () => { | ||
for (const column of DEFAULT_SORTABLE_COLUMNS) { | ||
expect(sortableField(column, null)).toBe(column) | ||
} | ||
}) | ||
|
||
it('should return null when fieldName is not a default sortable column name and property is falsy', () => { | ||
for (const falsyProperty of [null, undefined, 0, '', false, NaN]) { | ||
expect(sortableField('non-default sortable column', falsyProperty)).toBe(null) | ||
} | ||
}) | ||
|
||
it('should return fieldName when property.type is a sortable type', () => { | ||
for (const type of ['long', 'integer', 'double', 'float', 'date', 'boolean', 'keyword']) { | ||
const property = { | ||
type: 'keyword' | ||
} | ||
|
||
expect(sortableField('random fieldName', property)).toBe('random fieldName') | ||
} | ||
}) | ||
|
||
it('should return fieldName with \'.keyword\' appended when property.fields.keyword is truthy', () => { | ||
const property = { | ||
fields: { | ||
keyword: 'some value' | ||
} | ||
} | ||
|
||
expect(sortableField('random fieldName', property)).toBe('random fieldName.keyword') | ||
}) | ||
|
||
it('should return fieldName with \'.keyword\' appended when property.fields.keyword is truthy', () => { | ||
const property = { | ||
fields: { | ||
keyword: 'some value' | ||
} | ||
} | ||
|
||
expect(sortableField('random fieldName', property)).toBe('random fieldName.keyword') | ||
}) | ||
|
||
it('should return fieldName appended with subfield type when subfield type is sortable', () => { | ||
for (const type of ['long', 'integer', 'double', 'float', 'date', 'boolean', 'keyword']) { | ||
const property = { | ||
fields: { | ||
a: { | ||
type | ||
}, | ||
b: 2 | ||
} | ||
} | ||
|
||
expect(sortableField('random fieldName', property)).toBe('random fieldName.a') | ||
} | ||
}) | ||
|
||
it('should return null when subfield type is non-sortable', () => { | ||
const property = { | ||
fields: { | ||
a: { | ||
type: 'non-sortable type' | ||
} | ||
} | ||
} | ||
|
||
expect(sortableField('random fieldName', property)).toBe(null) | ||
}) | ||
|
||
it('should return property has fields but none of them have a type', () => { | ||
const property = { | ||
fields: { | ||
a: {}, | ||
b: {} | ||
} | ||
} | ||
|
||
expect(sortableField('random fieldName', property)).toBe(null) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.