summaryrefslogtreecommitdiff
path: root/spec/frontend/lib/utils
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/lib/utils')
-rw-r--r--spec/frontend/lib/utils/apollo_startup_js_link_spec.js375
-rw-r--r--spec/frontend/lib/utils/common_utils_spec.js19
-rw-r--r--spec/frontend/lib/utils/datetime_utility_spec.js9
-rw-r--r--spec/frontend/lib/utils/dom_utils_spec.js33
-rw-r--r--spec/frontend/lib/utils/number_utility_spec.js11
-rw-r--r--spec/frontend/lib/utils/text_utility_spec.js15
6 files changed, 446 insertions, 16 deletions
diff --git a/spec/frontend/lib/utils/apollo_startup_js_link_spec.js b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js
new file mode 100644
index 00000000000..faead3ff8fe
--- /dev/null
+++ b/spec/frontend/lib/utils/apollo_startup_js_link_spec.js
@@ -0,0 +1,375 @@
+import { ApolloLink, Observable } from 'apollo-link';
+import { StartupJSLink } from '~/lib/utils/apollo_startup_js_link';
+
+describe('StartupJSLink', () => {
+ const FORWARDED_RESPONSE = { data: 'FORWARDED_RESPONSE' };
+
+ const STARTUP_JS_RESPONSE = { data: 'STARTUP_JS_RESPONSE' };
+ const OPERATION_NAME = 'startupJSQuery';
+ const STARTUP_JS_QUERY = `query ${OPERATION_NAME}($id: Int = 3){
+ name
+ id
+ }`;
+
+ const STARTUP_JS_RESPONSE_TWO = { data: 'STARTUP_JS_RESPONSE_TWO' };
+ const OPERATION_NAME_TWO = 'startupJSQueryTwo';
+ const STARTUP_JS_QUERY_TWO = `query ${OPERATION_NAME_TWO}($id: Int = 3){
+ id
+ name
+ }`;
+
+ const ERROR_RESPONSE = {
+ data: {
+ user: null,
+ },
+ errors: [
+ {
+ path: ['user'],
+ locations: [{ line: 2, column: 3 }],
+ extensions: {
+ message: 'Object not found',
+ type: 2,
+ },
+ },
+ ],
+ };
+
+ let startupLink;
+ let link;
+
+ function mockFetchCall(status = 200, response = STARTUP_JS_RESPONSE) {
+ const p = {
+ ok: status >= 200 && status < 300,
+ status,
+ headers: new Headers({ 'Content-Type': 'application/json' }),
+ statusText: `MOCK-FETCH ${status}`,
+ clone: () => p,
+ json: () => Promise.resolve(response),
+ };
+ return Promise.resolve(p);
+ }
+
+ function mockOperation({ operationName = OPERATION_NAME, variables = { id: 3 } } = {}) {
+ return { operationName, variables, setContext: () => {} };
+ }
+
+ const setupLink = () => {
+ startupLink = new StartupJSLink();
+ link = ApolloLink.from([startupLink, new ApolloLink(() => Observable.of(FORWARDED_RESPONSE))]);
+ };
+
+ it('forwards requests if no calls are set up', done => {
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls).toBe(null);
+ expect(startupLink.request).toEqual(StartupJSLink.noopRequest);
+ done();
+ });
+ });
+
+ it('forwards requests if the operation is not pre-loaded', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ operationName: 'notLoaded' })).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(1);
+ done();
+ });
+ });
+
+ describe('variable match errors: ', () => {
+ it('forwards requests if the variables are not matching', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 'NOT_MATCHING' },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('forwards requests if more variables are set in the operation', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('forwards requests if less variables are set in the operation', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3, name: 'tanuki' },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ variables: { id: 3 } })).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('forwards requests if different variables are set', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { name: 'tanuki' },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ variables: { id: 3 } })).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('forwards requests if array variables have a different order', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: [3, 4] },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ variables: { id: [4, 3] } })).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+ });
+
+ describe('error handling', () => {
+ it('forwards the call if the fetchCall is failing with a HTTP Error', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(404),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('forwards the call if it errors (e.g. failing JSON)', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: Promise.reject(new Error('Parsing failed')),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('forwards the call if the response contains an error', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(200, ERROR_RESPONSE),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it("forwards the call if the response doesn't contain a data object", done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(200, { 'no-data': 'yay' }),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(FORWARDED_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+ });
+
+ it('resolves the request if the operation is matching', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(STARTUP_JS_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('resolves the request exactly once', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation()).subscribe(result => {
+ expect(result).toEqual(STARTUP_JS_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ link.request(mockOperation()).subscribe(result2 => {
+ expect(result2).toEqual(FORWARDED_RESPONSE);
+ done();
+ });
+ });
+ });
+
+ it('resolves the request if the variables have a different order', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3, name: 'foo' },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ variables: { name: 'foo', id: 3 } })).subscribe(result => {
+ expect(result).toEqual(STARTUP_JS_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('resolves the request if the variables have undefined values', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { name: 'foo' },
+ },
+ ],
+ };
+ setupLink();
+ link
+ .request(mockOperation({ variables: { name: 'foo', undef: undefined } }))
+ .subscribe(result => {
+ expect(result).toEqual(STARTUP_JS_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('resolves the request if the variables are of an array format', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: [3, 4] },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ variables: { id: [3, 4] } })).subscribe(result => {
+ expect(result).toEqual(STARTUP_JS_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+
+ it('resolves multiple requests correctly', done => {
+ window.gl = {
+ startup_graphql_calls: [
+ {
+ fetchCall: mockFetchCall(),
+ query: STARTUP_JS_QUERY,
+ variables: { id: 3 },
+ },
+ {
+ fetchCall: mockFetchCall(200, STARTUP_JS_RESPONSE_TWO),
+ query: STARTUP_JS_QUERY_TWO,
+ variables: { id: 3 },
+ },
+ ],
+ };
+ setupLink();
+ link.request(mockOperation({ operationName: OPERATION_NAME_TWO })).subscribe(result => {
+ expect(result).toEqual(STARTUP_JS_RESPONSE_TWO);
+ expect(startupLink.startupCalls.size).toBe(1);
+ link.request(mockOperation({ operationName: OPERATION_NAME })).subscribe(result2 => {
+ expect(result2).toEqual(STARTUP_JS_RESPONSE);
+ expect(startupLink.startupCalls.size).toBe(0);
+ done();
+ });
+ });
+ });
+});
diff --git a/spec/frontend/lib/utils/common_utils_spec.js b/spec/frontend/lib/utils/common_utils_spec.js
index effc446d846..09eb362c77e 100644
--- a/spec/frontend/lib/utils/common_utils_spec.js
+++ b/spec/frontend/lib/utils/common_utils_spec.js
@@ -959,6 +959,25 @@ describe('common_utils', () => {
});
});
+ describe('roundDownFloat', () => {
+ it('Rounds down decimal places of a float number with provided precision', () => {
+ expect(commonUtils.roundDownFloat(3.141592, 3)).toBe(3.141);
+ });
+
+ it('Rounds down a float number to a whole number when provided precision is zero', () => {
+ expect(commonUtils.roundDownFloat(3.141592, 0)).toBe(3);
+ expect(commonUtils.roundDownFloat(3.9, 0)).toBe(3);
+ });
+
+ it('Rounds down float number to nearest 0, 10, 100, 1000 and so on when provided precision is below 0', () => {
+ expect(commonUtils.roundDownFloat(34567.14159, -1)).toBeCloseTo(34560);
+ expect(commonUtils.roundDownFloat(34567.14159, -2)).toBeCloseTo(34500);
+ expect(commonUtils.roundDownFloat(34567.14159, -3)).toBeCloseTo(34000);
+ expect(commonUtils.roundDownFloat(34567.14159, -4)).toBeCloseTo(30000);
+ expect(commonUtils.roundDownFloat(34567.14159, -5)).toBeCloseTo(0);
+ });
+ });
+
describe('searchBy', () => {
const searchSpace = {
iid: 1,
diff --git a/spec/frontend/lib/utils/datetime_utility_spec.js b/spec/frontend/lib/utils/datetime_utility_spec.js
index b0b0b028761..6092b44720f 100644
--- a/spec/frontend/lib/utils/datetime_utility_spec.js
+++ b/spec/frontend/lib/utils/datetime_utility_spec.js
@@ -643,16 +643,15 @@ describe('localTimeAgo', () => {
});
it.each`
- timeagoArg | title | dataOriginalTitle
- ${false} | ${'some time'} | ${null}
- ${true} | ${''} | ${'Feb 18, 2020 10:22pm GMT+0000'}
- `('converts $seconds seconds to $approximation', ({ timeagoArg, title, dataOriginalTitle }) => {
+ timeagoArg | title
+ ${false} | ${'some time'}
+ ${true} | ${'Feb 18, 2020 10:22pm GMT+0000'}
+ `('converts $seconds seconds to $approximation', ({ timeagoArg, title }) => {
const element = document.querySelector('time');
datetimeUtility.localTimeAgo($(element), timeagoArg);
jest.runAllTimers();
- expect(element.getAttribute('data-original-title')).toBe(dataOriginalTitle);
expect(element.getAttribute('title')).toBe(title);
});
});
diff --git a/spec/frontend/lib/utils/dom_utils_spec.js b/spec/frontend/lib/utils/dom_utils_spec.js
index d918016a5f4..f5c2a797df5 100644
--- a/spec/frontend/lib/utils/dom_utils_spec.js
+++ b/spec/frontend/lib/utils/dom_utils_spec.js
@@ -3,6 +3,8 @@ import {
canScrollUp,
canScrollDown,
parseBooleanDataAttributes,
+ isElementVisible,
+ isElementHidden,
} from '~/lib/utils/dom_utils';
const TEST_MARGIN = 5;
@@ -160,4 +162,35 @@ describe('DOM Utils', () => {
});
});
});
+
+ describe.each`
+ offsetWidth | offsetHeight | clientRectsLength | visible
+ ${0} | ${0} | ${0} | ${false}
+ ${1} | ${0} | ${0} | ${true}
+ ${0} | ${1} | ${0} | ${true}
+ ${0} | ${0} | ${1} | ${true}
+ `(
+ 'isElementVisible and isElementHidden',
+ ({ offsetWidth, offsetHeight, clientRectsLength, visible }) => {
+ const element = {
+ offsetWidth,
+ offsetHeight,
+ getClientRects: () => new Array(clientRectsLength),
+ };
+
+ const paramDescription = `offsetWidth=${offsetWidth}, offsetHeight=${offsetHeight}, and getClientRects().length=${clientRectsLength}`;
+
+ describe('isElementVisible', () => {
+ it(`returns ${visible} when ${paramDescription}`, () => {
+ expect(isElementVisible(element)).toBe(visible);
+ });
+ });
+
+ describe('isElementHidden', () => {
+ it(`returns ${!visible} when ${paramDescription}`, () => {
+ expect(isElementHidden(element)).toBe(!visible);
+ });
+ });
+ },
+ );
});
diff --git a/spec/frontend/lib/utils/number_utility_spec.js b/spec/frontend/lib/utils/number_utility_spec.js
index f600f2bcd55..2f8f1092612 100644
--- a/spec/frontend/lib/utils/number_utility_spec.js
+++ b/spec/frontend/lib/utils/number_utility_spec.js
@@ -1,6 +1,5 @@
import {
formatRelevantDigits,
- bytesToKB,
bytesToKiB,
bytesToMiB,
bytesToGiB,
@@ -55,16 +54,6 @@ describe('Number Utils', () => {
});
});
- describe('bytesToKB', () => {
- it.each`
- input | output
- ${1000} | ${1}
- ${1024} | ${1.024}
- `('returns $output KB for $input bytes', ({ input, output }) => {
- expect(bytesToKB(input)).toBe(output);
- });
- });
-
describe('bytesToKiB', () => {
it('calculates KiB for the given bytes', () => {
expect(bytesToKiB(1024)).toEqual(1);
diff --git a/spec/frontend/lib/utils/text_utility_spec.js b/spec/frontend/lib/utils/text_utility_spec.js
index 6fef5f6b63c..d7cedb939d2 100644
--- a/spec/frontend/lib/utils/text_utility_spec.js
+++ b/spec/frontend/lib/utils/text_utility_spec.js
@@ -325,4 +325,19 @@ describe('text_utility', () => {
expect(textUtils.hasContent(txt)).toEqual(result);
});
});
+
+ describe('isValidSha1Hash', () => {
+ const validSha1Hash = '92d10c15';
+ const stringOver40 = new Array(42).join('a');
+
+ it.each`
+ hash | valid
+ ${validSha1Hash} | ${true}
+ ${'__characters'} | ${false}
+ ${'abc'} | ${false}
+ ${stringOver40} | ${false}
+ `(`returns $valid for $hash`, ({ hash, valid }) => {
+ expect(textUtils.isValidSha1Hash(hash)).toBe(valid);
+ });
+ });
});