diff --git a/karma.conf.js b/karma.conf.js index 16722e083..8499f4542 100644 --- a/karma.conf.js +++ b/karma.conf.js @@ -45,6 +45,7 @@ var testFixture = require('./test/_globals.js'), { name: 'ServerWorkerRequests', path: './seeds/EmptyProject.webgmex', + tags: ['v1'], branches: ['b1', 'b2', 'updateProjectFromFile'] } ]; @@ -80,12 +81,13 @@ var testFixture = require('./test/_globals.js'), logger: logger }) .then(function (importResult) { - var i, - createBranches = []; + let i; + const createBranchesAndTags = []; + if (Object.hasOwn(projectInfo, 'branches') && projectInfo.branches.length > 1) { // First one is already added thus i = 1. for (i = 1; i < projectInfo.branches.length; i += 1) { - createBranches.push(storage.createBranch( + createBranchesAndTags.push(storage.createBranch( { projectId: testFixture.projectName2Id(projectInfo.name), branchName: projectInfo.branches[i], @@ -94,7 +96,18 @@ var testFixture = require('./test/_globals.js'), ); } } - return Q.allDone(createBranches); + + (projectInfo.tags || []).forEach((tag) => { + createBranchesAndTags.push(storage.createTag( + { + projectId: testFixture.projectName2Id(projectInfo.name), + tagName: tag, + hash: importResult.commitHash + }) + ); + }); + + return Q.allDone(createBranchesAndTags); }) .then(function () { var nextProject = PROJECTS_TO_IMPORT.shift(); diff --git a/src/server/storage/safestorage.js b/src/server/storage/safestorage.js index eadcc724e..a79f2c478 100644 --- a/src/server/storage/safestorage.js +++ b/src/server/storage/safestorage.js @@ -15,7 +15,6 @@ var Q = require('q'), REGEXP = requireJS('common/regexp'), Storage = require('./storage'), - filterArray = require('./storagehelpers').filterArray, UserProject = require('./userproject'); function check(cond, deferred, msg) { @@ -58,6 +57,7 @@ SafeStorage.prototype.constructor = SafeStorage; * @param {boolean} [data.info] - include the info field from the _projects collection. * @param {boolean} [data.rights] - include users' authorization information for each project. * @param {boolean} [data.branches] - include a dictionary with all branches and their hash. + * @param {boolean} [data.tags] - include a dictionary with all tags and their hash. * @param {boolean} [data.hooks] - include the dictionary with all hooks. * @param {string} [data.projectId] - if given will return only single matching project. * @param {string} [data.username=gmeConfig.authentication.guestAccount] @@ -120,35 +120,35 @@ SafeStorage.prototype.getProjects = function (data, callback) { return Q.all(allProjects.map(getAuthorizedProjects)); }) - .then(function (projects) { - function getBranches(project) { - var branchesDeferred = Q.defer(); - Storage.prototype.getBranches.call(self, {projectId: project._id}) - .then(function (branches) { - project.branches = branches; - branchesDeferred.resolve(project); - }) - .catch(function (err) { - if (err.message.indexOf('Project does not exist') > -1) { - self.logger.error('Inconsistency: project exists in user "' + data.username + - '" and in _projects, but not as a collection on its own: ', project._id); - branchesDeferred.resolve(); - } else { - branchesDeferred.reject(err); - } - }); + .then(async function (projects) { + const result = []; + for (const project of projects) { + try { + if (!project) { + continue; + } - return branchesDeferred.promise; - } + if (data.branches === true) { + project.branches = await Storage.prototype.getBranches.call(self, {projectId: project._id}); + } - if (data.branches === true) { - return Q.all(filterArray(projects).map(getBranches)); - } else { - deferred.resolve(filterArray(projects)); + if (data.tags === true) { + project.tags = await Storage.prototype.getTags.call(self, {projectId: project._id}); + } + + result.push(project); + } catch (err) { + if (err.message.indexOf('Project does not exist') > -1) { + self.logger.error('Inconsistency: project exists in user "' + data.username + + '" and in _projects, but not as a collection on its own: ', project._id); + // Proceed with other projects.. + } else { + deferred.reject(err); + } + } } - }) - .then(function (projectsAndBranches) { - deferred.resolve(filterArray(projectsAndBranches)); + + deferred.resolve(result); }) .catch(function (err) { deferred.reject(err); @@ -1168,6 +1168,10 @@ SafeStorage.prototype.createTag = function (data, callback) { }, rejected = false; + if (!Object.hasOwn(data, 'commitHash') && Object.hasOwn(data, 'hash')) { + data.commitHash = data.hash; + } + rejected = check(data !== null && typeof data === 'object', deferred, 'data is not an object.') || check(typeof data.projectId === 'string', deferred, 'data.projectId is not a string.') || @@ -1176,9 +1180,9 @@ SafeStorage.prototype.createTag = function (data, callback) { check(typeof data.tagName === 'string', deferred, 'data.tagName is not a string.') || check(REGEXP.TAG.test(data.tagName), deferred, 'data.tagName failed regexp: ' + data.tagName) || - check(typeof data.commitHash === 'string', deferred, 'data.hash is not a string.') || + check(typeof data.commitHash === 'string', deferred, 'data.commitHash is not a string.') || check(data.commitHash === '' || REGEXP.HASH.test(data.commitHash), deferred, - 'data.hash is not a valid hash: ' + data.commitHash); + 'data.commitHash is not a valid hash: ' + data.commitHash); if (Object.hasOwn(data, 'username')) { rejected = rejected || check(typeof data.username === 'string', deferred, 'data.username is not a string.'); diff --git a/test-karma/client/js/client.spec.js b/test-karma/client/js/client.spec.js index 16d6da2d5..ea0008265 100644 --- a/test-karma/client/js/client.spec.js +++ b/test-karma/client/js/client.spec.js @@ -618,6 +618,27 @@ describe('GME client', function () { }); }); + it('getProjects asObject=true, branches=true, tags=true, rights=true, info=true', function (done) { + client.getProjects({ + asObject: true, + rights: true, + branches: true, + info: true, + tags: true + }, function (err, res) { + try { + expect(err).to.equal(null); + //console.log(JSON.stringify(allProjects, null, 2)); + expect(res['guest+ServerWorkerRequests']) + .to.include.keys('name', 'rights', '_id', 'owner', 'info', 'branches', 'tags'); + expect(res['guest+ServerWorkerRequests'].tags.v1[0]).to.equal('#'); + done(); + } catch (err) { + done(err); + } + }); + }); + it('getProjectsAndBranches-true should return an object with branches and rights', function (done) { client.getProjectsAndBranches(true, function (err, projects) { var key; diff --git a/test/server/storage/safestorage.spec.js b/test/server/storage/safestorage.spec.js index 080032950..351bbb82b 100644 --- a/test/server/storage/safestorage.spec.js +++ b/test/server/storage/safestorage.spec.js @@ -37,7 +37,7 @@ describe('SafeStorage', function () { .nodeify(done); }); - describe('Projects', function () { + describe.only('Projects', function () { var safeStorage, importResult, commitHash; @@ -57,7 +57,10 @@ describe('SafeStorage', function () { expect(result.projectId).to.equal(projectId); commitHash = result.commitHash; importResult = result; - return result.project.createBranch('setFail', commitHash); + return Q.all([ + result.project.createBranch('setFail', commitHash), + result.project.createTag('v1', commitHash) + ]); }) .nodeify(done); }); @@ -165,6 +168,41 @@ describe('SafeStorage', function () { .nodeify(done); }); + it('should getProjects (rights=true, info=true, branches=true, tags=true)', function (done) { + var data = { + rights: true, + info: true, + branches: true, + tags: true + }; + + safeStorage.getProjects(data) + .then(function (projects) { + expect(projects).to.have.property('length'); + expect(projects.length).to.equal(1); + expect(typeof projects[0].info).to.equal('object'); + expect(typeof projects[0].branches).to.equal('object'); + expect(typeof projects[0].tags).to.equal('object'); + expect(projects[0].branches).to.include.keys('master'); + expect(projects[0].tags.v1).to.equal(projects[0].branches.master); + delete projects[0].info; + delete projects[0].branches; + delete projects[0].tags; + expect(projects[0]).to.deep.equal({ + _id: 'guest+newProject', + //fullName: 'guest/newProject', + name: 'newProject', + owner: 'guest', + rights: { + delete: true, + read: true, + write: true + } + }); + }) + .nodeify(done); + }); + it('should getProjects (rights=true, info=true, branches=true, projectId=%projectId%)', function (done) { var data = { rights: true,