Commit 9e00708f authored by Eric Eastwood's avatar Eric Eastwood
parent f9700381
import {
FETCH_SUCCESS_STATUS,
FETCH_ERROR_STATUS,
} from '../constants';
import { assembleDisplayIssuableReference } from '../../../lib/utils/issuable_reference_utils';
class RelatedIssuesStore {
constructor() {
this.state = {
// Stores issue objects that we can lookup by reference
issueMap: {},
// Stores references to the actual known related issues
relatedIssues: [],
// Stores references to the "staging area" related issues that are planned to be added
pendingRelatedIssues: [],
};
}
getIssueFromReference(reference, namespacePath, projectPath) {
const issue = this.state.issueMap[reference];
let displayReference = reference;
if (issue && issue.fetchStatus === FETCH_SUCCESS_STATUS) {
displayReference = assembleDisplayIssuableReference(
issue,
namespacePath,
projectPath,
);
}
const fetchStatus = issue ? issue.fetchStatus : FETCH_ERROR_STATUS;
return {
reference,
displayReference,
path: issue && issue.path,
title: issue && issue && issue.title,
state: issue && issue.state,
fetchStatus,
canRemove: issue && issue.destroy_relation_path && issue.destroy_relation_path.length > 0,
};
}
getIssuesFromReferences(references, namespacePath, projectPath) {
return references.map(reference =>
this.getIssueFromReference(reference, namespacePath, projectPath));
}
addToIssueMap(reference, issue) {
this.state.issueMap = {
...this.state.issueMap,
[reference]: issue,
};
}
setRelatedIssues(value) {
this.state.relatedIssues = value;
}
setPendingRelatedIssues(issues) {
this.state.pendingRelatedIssues = issues;
}
}
export default RelatedIssuesStore;
......@@ -17,23 +17,15 @@ function getReferencePieces(partialReference, namespacePath, projectPath) {
};
}
function assembleNecessaryIssuableReference(
partialReference,
currentNamespacePath,
currentProjectPath,
) {
const {
namespace,
project,
issue,
} = getReferencePieces(partialReference, currentNamespacePath, currentProjectPath);
let necessaryReference = `#${issue}`;
if (currentProjectPath !== project) {
necessaryReference = project + necessaryReference;
// Transform `foo/bar#123` into `#123` given
// `currentNamespacePath = 'foo'` and `currentProjectPath = 'bar'`
function assembleDisplayIssuableReference(issue, currentNamespacePath, currentProjectPath) {
let necessaryReference = `#${issue.iid}`;
if (issue.project_path && currentProjectPath !== issue.project_path) {
necessaryReference = issue.project_path + necessaryReference;
}
if (currentNamespacePath !== namespace) {
necessaryReference = `${namespace}/${necessaryReference}`;
if (issue.namespace_full_path && currentNamespacePath !== issue.namespace_full_path) {
necessaryReference = `${issue.namespace_full_path}/${necessaryReference}`;
}
return necessaryReference;
......@@ -51,6 +43,6 @@ function assembleFullIssuableReference(partialReference, currentNamespacePath, c
export {
ISSUABLE_REFERENCE_RE,
getReferencePieces,
assembleNecessaryIssuableReference,
assembleDisplayIssuableReference,
assembleFullIssuableReference,
};
import _ from 'underscore';
import {
FETCH_SUCCESS_STATUS,
FETCH_ERROR_STATUS,
} from '~/issuable/related_issues/constants';
import RelatedIssuesStore from '~/issuable/related_issues/stores/related_issues_store';
const issuable1 = {
namespace_full_path: 'foo',
project_path: 'bar',
iid: '123',
title: 'issue1',
path: '/foo/bar/issues/123',
state: 'opened',
fetchStatus: FETCH_SUCCESS_STATUS,
destroy_relation_path: '/foo/bar/issues/123/related_issues/1',
};
const issuable1Reference = `${issuable1.namespace_full_path}/${issuable1.project_path}#${issuable1.iid}`;
const issuable2 = {
namespace_full_path: 'foo',
project_path: 'bar',
iid: '124',
title: 'issue1',
path: '/foo/bar/issues/124',
state: 'opened',
fetchStatus: FETCH_SUCCESS_STATUS,
destroy_relation_path: '/foo/bar/issues/124/related_issues/1',
};
const issuable2Reference = `${issuable2.namespace_full_path}/${issuable2.project_path}#${issuable2.iid}`;
describe('RelatedIssuesStore', () => {
let store;
beforeEach(() => {
store = new RelatedIssuesStore();
});
describe('getIssueFromReference', () => {
it('get issue with issueMap populated', () => {
store.state.issueMap = {
[issuable1Reference]: issuable1,
};
expect(store.getIssueFromReference(issuable1Reference, 'foo', 'bar')).toEqual({
..._.omit(issuable1, 'namespace_full_path', 'project_path', 'iid', 'destroy_relation_path'),
reference: issuable1Reference,
displayReference: '#123',
fetchStatus: FETCH_SUCCESS_STATUS,
canRemove: true,
});
});
it('get issue with issue missing in issueMap', () => {
expect(store.getIssueFromReference(issuable1Reference, 'foo', 'bar')).toEqual({
reference: issuable1Reference,
displayReference: issuable1Reference,
title: undefined,
path: undefined,
state: undefined,
fetchStatus: FETCH_ERROR_STATUS,
canRemove: undefined,
});
});
});
describe('getIssuesFromReferences', () => {
it('get issues with issueMap populated', () => {
store.state.issueMap = {
[issuable1Reference]: issuable1,
[issuable2Reference]: issuable2,
};
expect(store.getIssuesFromReferences([issuable1Reference, issuable2Reference], 'foo', 'bar')).toEqual([{
..._.omit(issuable1, 'namespace_full_path', 'project_path', 'iid', 'destroy_relation_path'),
reference: issuable1Reference,
displayReference: '#123',
fetchStatus: FETCH_SUCCESS_STATUS,
canRemove: true,
}, {
..._.omit(issuable2, 'namespace_full_path', 'project_path', 'iid', 'destroy_relation_path'),
reference: issuable2Reference,
displayReference: '#124',
fetchStatus: FETCH_SUCCESS_STATUS,
canRemove: true,
}]);
});
});
describe('addToIssueMap', () => {
it('defaults to empty object hash', () => {
expect(store.state.issueMap).toEqual({});
});
it('add issue', () => {
store.addToIssueMap(issuable1Reference, issuable1);
expect(store.state.issueMap).toEqual({
[issuable1Reference]: issuable1,
});
});
});
describe('setRelatedIssues', () => {
it('defaults to empty array', () => {
expect(store.state.relatedIssues).toEqual([]);
});
it('add reference', () => {
const relatedIssues = ['#123'];
store.setRelatedIssues(relatedIssues);
expect(store.state.relatedIssues).toEqual(relatedIssues);
});
});
describe('setPendingRelatedIssues', () => {
it('defaults to empty array', () => {
expect(store.state.pendingRelatedIssues).toEqual([]);
});
it('add reference', () => {
const relatedIssues = ['#123'];
store.setPendingRelatedIssues(relatedIssues);
expect(store.state.pendingRelatedIssues).toEqual(relatedIssues);
});
});
});
import {
getReferencePieces,
assembleNecessaryIssuableReference,
assembleDisplayIssuableReference,
assembleFullIssuableReference,
} from '~/lib/utils/issuable_reference_utils';
......@@ -50,24 +50,24 @@ describe('issuable_reference_utils', () => {
});
});
describe('assembleNecessaryIssuableReference', () => {
describe('assembleDisplayIssuableReference', () => {
it('should work with only issue number reference', () => {
expect(assembleNecessaryIssuableReference('#111', 'foo', 'bar')).toEqual('#111');
expect(assembleDisplayIssuableReference({ iid: 111 }, 'foo', 'bar')).toEqual('#111');
});
it('should work with project and issue number reference', () => {
expect(assembleNecessaryIssuableReference('qux#111', 'foo', 'bar')).toEqual('qux#111');
expect(assembleDisplayIssuableReference({ project_path: 'qux', iid: 111 }, 'foo', 'bar')).toEqual('qux#111');
});
it('should work with full reference to current project', () => {
expect(assembleNecessaryIssuableReference('foo/garply#111', 'foo', 'bar')).toEqual('garply#111');
expect(assembleDisplayIssuableReference({ namespace_full_path: 'foo', project_path: 'garply', iid: 111 }, 'foo', 'bar')).toEqual('garply#111');
});
it('should work with sub-groups', () => {
expect(assembleNecessaryIssuableReference('some/with/sub/groups/other#111', 'foo', 'bar')).toEqual('some/with/sub/groups/other#111');
expect(assembleDisplayIssuableReference({ namespace_full_path: 'some/with/sub/groups', project_path: 'other', iid: 111 }, 'foo', 'bar')).toEqual('some/with/sub/groups/other#111');
});
it('does not mangle other group references', () => {
expect(assembleNecessaryIssuableReference('some/other#111', 'foo', 'bar')).toEqual('some/other#111');
expect(assembleDisplayIssuableReference({ namespace_full_path: 'some', project_path: 'other', iid: 111 }, 'foo', 'bar')).toEqual('some/other#111');
});
it('does not mangle other group even with partial match', () => {
expect(assembleNecessaryIssuableReference('bar/baz/fido#111', 'foo/bar/baz', 'garply')).toEqual('bar/baz/fido#111');
expect(assembleDisplayIssuableReference({ namespace_full_path: 'bar/baz', project_path: 'fido', iid: 111 }, 'foo/bar/baz', 'garply')).toEqual('bar/baz/fido#111');
});
});
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment