Erez Rokah 174d86f0a0
Feat: entry sorting (#3494)
* refactor: typescript search actions, add tests avoid duplicate search

* refactor: switch from promise chain to async/await in loadEntries

* feat: add sorting, initial commit

* fix: set isFetching to true on entries request

* fix: ui improvments and bug fixes

* test: fix tests

* feat(backend-gitlab): cache local tree)

* fix: fix prop type warning

* refactor: code cleanup

* feat(backend-bitbucket): add local tree caching support

* feat: swtich to orderBy and support multiple sort keys

* fix: backoff function

* fix: improve backoff

* feat: infer sortable fields

* feat: fetch file commit metadata - initial commit

* feat: extract file author and date, finalize GitLab & Bitbucket

* refactor: code cleanup

* feat: handle github rate limit errors

* refactor: code cleanup

* fix(github): add missing author and date when traversing cursor

* fix: add missing author and date when traversing cursor

* refactor: code cleanup

* refactor: code cleanup

* refactor: code cleanup

* test: fix tests

* fix: rebuild local tree when head doesn't exist in remote branch

* fix: allow sortable fields to be an empty array

* fix: allow translation of built in sort fields

* build: fix proxy server build

* fix: hide commit author and date fields by default on non git backends

* fix(algolia): add listAllEntries method for alogolia integration

* fix: handle sort fields overflow

* test(bitbucket): re-record some bitbucket e2e tests

* test(bitbucket): fix media library test

* refactor(gitgateway-gitlab): share request code and handle 404 errors

* fix: always show commit date by default

* docs: add sortableFields

* refactor: code cleanup

* improvement: drop multi-sort, rework sort UI

* chore: force main package bumps

Co-authored-by: Shawn Erquhart <shawn@erquh.art>
2020-03-31 23:13:27 -04:00

188 lines
6.4 KiB
JavaScript

import API, { getMaxAccess } from '../API';
global.fetch = jest.fn().mockRejectedValue(new Error('should not call fetch inside tests'));
jest.spyOn(console, 'log').mockImplementation(() => undefined);
describe('GitLab API', () => {
beforeEach(() => {
jest.resetAllMocks();
});
describe('hasWriteAccess', () => {
test('should return true on project access_level >= 30', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest
.fn()
.mockResolvedValueOnce({ permissions: { project_access: { access_level: 30 } } });
await expect(api.hasWriteAccess()).resolves.toBe(true);
});
test('should return false on project access_level < 30', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest
.fn()
.mockResolvedValueOnce({ permissions: { project_access: { access_level: 10 } } });
await expect(api.hasWriteAccess()).resolves.toBe(false);
});
test('should return true on group access_level >= 30', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest
.fn()
.mockResolvedValueOnce({ permissions: { group_access: { access_level: 30 } } });
await expect(api.hasWriteAccess()).resolves.toBe(true);
});
test('should return false on group access_level < 30', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest
.fn()
.mockResolvedValueOnce({ permissions: { group_access: { access_level: 10 } } });
await expect(api.hasWriteAccess()).resolves.toBe(false);
});
test('should return true on shared group access_level >= 40', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest.fn().mockResolvedValueOnce({
permissions: { project_access: null, group_access: null },
shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 40 }],
});
await expect(api.hasWriteAccess()).resolves.toBe(true);
expect(api.requestJSON).toHaveBeenCalledTimes(1);
});
test('should return true on shared group access_level >= 30, developers can merge and push', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest.fn();
api.requestJSON.mockResolvedValueOnce({
permissions: { project_access: null, group_access: null },
shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }],
});
api.requestJSON.mockResolvedValueOnce({
developers_can_merge: true,
developers_can_push: true,
});
await expect(api.hasWriteAccess()).resolves.toBe(true);
});
test('should return false on shared group access_level < 30,', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest.fn();
api.requestJSON.mockResolvedValueOnce({
permissions: { project_access: null, group_access: null },
shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 20 }],
});
api.requestJSON.mockResolvedValueOnce({
developers_can_merge: true,
developers_can_push: true,
});
await expect(api.hasWriteAccess()).resolves.toBe(false);
});
test("should return false on shared group access_level >= 30, developers can't merge", async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest.fn();
api.requestJSON.mockResolvedValueOnce({
permissions: { project_access: null, group_access: null },
shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }],
});
api.requestJSON.mockResolvedValueOnce({
developers_can_merge: false,
developers_can_push: true,
});
await expect(api.hasWriteAccess()).resolves.toBe(false);
});
test("should return false on shared group access_level >= 30, developers can't push", async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest.fn();
api.requestJSON.mockResolvedValueOnce({
permissions: { project_access: null, group_access: null },
shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }],
});
api.requestJSON.mockResolvedValueOnce({
developers_can_merge: true,
developers_can_push: false,
});
await expect(api.hasWriteAccess()).resolves.toBe(false);
});
test('should return false on shared group access_level >= 30, error getting branch', async () => {
const api = new API({ repo: 'repo' });
api.requestJSON = jest.fn();
api.requestJSON.mockResolvedValueOnce({
permissions: { project_access: null, group_access: null },
shared_with_groups: [{ group_access_level: 10 }, { group_access_level: 30 }],
});
const error = new Error('Not Found');
api.requestJSON.mockRejectedValue(error);
await expect(api.hasWriteAccess()).resolves.toBe(false);
expect(console.log).toHaveBeenCalledTimes(1);
expect(console.log).toHaveBeenCalledWith('Failed getting default branch', error);
});
});
describe('getStatuses', () => {
test('should get preview statuses', async () => {
const api = new API({ repo: 'repo' });
const mr = { sha: 'sha' };
const statuses = [
{ name: 'deploy', status: 'success', target_url: 'deploy-url' },
{ name: 'build', status: 'pending' },
];
api.getBranchMergeRequest = jest.fn(() => Promise.resolve(mr));
api.getMergeRequestStatues = jest.fn(() => Promise.resolve(statuses));
const collectionName = 'posts';
const slug = 'title';
await expect(api.getStatuses(collectionName, slug)).resolves.toEqual([
{ context: 'deploy', state: 'success', target_url: 'deploy-url' },
{ context: 'build', state: 'other' },
]);
expect(api.getBranchMergeRequest).toHaveBeenCalledTimes(1);
expect(api.getBranchMergeRequest).toHaveBeenCalledWith('cms/posts/title');
expect(api.getMergeRequestStatues).toHaveBeenCalledTimes(1);
expect(api.getMergeRequestStatues).toHaveBeenCalledWith(mr, 'cms/posts/title');
});
});
describe('getMaxAccess', () => {
it('should return group with max access level', () => {
const groups = [
{ group_access_level: 10 },
{ group_access_level: 5 },
{ group_access_level: 100 },
{ group_access_level: 1 },
];
expect(getMaxAccess(groups)).toBe(groups[2]);
});
});
});