Skip to content

Commit

Permalink
fix: Add getBuilds method for pipeline model [1] (#619)
Browse files Browse the repository at this point in the history
  • Loading branch information
tkyi authored Mar 28, 2024
1 parent b261dab commit 8a2f1af
Show file tree
Hide file tree
Showing 3 changed files with 190 additions and 3 deletions.
4 changes: 2 additions & 2 deletions lib/event.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ class EventModel extends BaseModel {
/* eslint-disable global-require */
const BuildFactory = require('./buildFactory');
/* eslint-enable global-require */
const factory = BuildFactory.getInstance();
const buildFactory = BuildFactory.getInstance();

return factory.list(listConfig);
return buildFactory.list(listConfig);
}

/**
Expand Down
70 changes: 70 additions & 0 deletions lib/pipeline.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ const MAX_EVENT_DELETE_COUNT = 100;
// The default page for fetching not by aggregatedInteval
// And the start page for fetching by aggregatedInteval
const DEFAULT_PAGE = 1;
const DEFAULT_COUNT = 10;
const SCM_NO_ACCESS_STATUSES = [401, 404];

const { getAllRecords, getBuildClusterName, getFullStageJobName } = require('./helper');
Expand Down Expand Up @@ -1658,6 +1659,75 @@ class PipelineModel extends BaseModel {
return factory.list(listConfig);
}

/**
* Fetch builds belonging to a pipeline or events
* @param {Object} [config]
* @param {Number} [config.sort] Sort rangekey by ascending or descending
* @param {Number} [config.sortBy] Sortby field
* @param {Object} [config.paginate] Pagination parameters
* @param {Number} [config.paginate.count] Number of items per page
* @param {Number} [config.paginate.page] Specific page of the set to return
* @param {Number} [config.groupEventId] Group event ID
* @param {Boolean} [config.latest] If we want to return latest in groupEventId, default false
* @return {Promise} Resolves to an array of builds
*/
async getBuilds(config = {}) {
const { sort } = config;
const latest = hoek.reach(config, 'params.latest');
const groupEventId = hoek.reach(config, 'params.groupEventId');

// Fetch all builds for each event with same groupEventId
if (groupEventId && !latest) {
// Lazy load factory dependency to prevent circular dependency issues
// https://nodejs.org/api/modules.html#modules_cycles
/* eslint-disable global-require */
const EventFactory = require('./eventFactory');
/* eslint-enable global-require */
const eventFactory = EventFactory.getInstance();
const events = await eventFactory.list({
params: { groupEventId }
});
const processed = [];

events.forEach(e => processed.push(e.getBuilds()));

return Promise.all(processed).then(builds => {
// flatten array of arrays
return builds.flat(1);
});
}
// Lazy load factory dependency to prevent circular dependency issues
// https://nodejs.org/api/modules.html#modules_cycles
/* eslint-disable global-require */
const BuildFactory = require('./buildFactory');
/* eslint-enable global-require */
const buildFactory = BuildFactory.getInstance();

// Fetch only latest builds with same groupEventId
if (latest && groupEventId) {
return buildFactory.getLatestBuilds({
groupEventId: config.params.groupEventId
});
}

// Latest should not be passed to list config
if (latest !== undefined) {
delete config.params.latest;
}

// Fetch builds for this pipeline with default count and page (implicitly set to 1)
const defaultConfig = {
params: { pipelineId: this.id },
paginate: {
count: DEFAULT_COUNT
},
sort: sort ? sort.toLowerCase() : 'descending' // Sort by primary sort key
};
const listConfig = config ? hoek.applyToDefaults(defaultConfig, config) : defaultConfig;

return buildFactory.list(listConfig);
}

/**
* Update the repository and branch
* @method update
Expand Down
119 changes: 118 additions & 1 deletion test/lib/pipeline.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -265,7 +265,8 @@ describe('Pipeline Model', () => {
list: sinon.stub()
};
buildFactoryMock = {
list: sinon.stub()
list: sinon.stub(),
getLatestBuilds: sinon.stub()
};
userFactoryMock = {
get: sinon.stub(),
Expand Down Expand Up @@ -2593,6 +2594,122 @@ describe('Pipeline Model', () => {
});
});

describe('get builds', () => {
const builds = [
{
id: '777'
},
{
id: '778'
},
{
id: '779'
}
];
const events = [
{
id: '12345f642bbfd1886623964b4cff12db59869e5d',
getBuilds: sinon.stub().resolves(builds)
},
{
id: '12855123cc7f1b808aac07feff24d7d5362cc215',
getBuilds: sinon.stub().resolves(builds)
}
];
const groupEventId = 999;

it('gets a list of builds by groupEventId', () => {
const expected = {
params: { groupEventId }
};

eventFactoryMock.list.resolves(events);

return pipeline.getBuilds({ params: { groupEventId } }).then(result => {
assert.calledWith(eventFactoryMock.list, expected);
assert.deepEqual(result, builds.concat(builds));
});
});

it('returns empty array when no events found for groupEventId', () => {
const expected = {
params: { groupEventId }
};

eventFactoryMock.list.resolves([]);

return pipeline.getBuilds({ params: { groupEventId } }).then(result => {
assert.calledWith(eventFactoryMock.list, expected);
assert.deepEqual(result, []);
});
});

it('gets latest builds', () => {
const expected = {
groupEventId
};

buildFactoryMock.getLatestBuilds.resolves(builds);

return pipeline
.getBuilds({
params: {
groupEventId,
latest: true
}
})
.then(result => {
assert.calledWith(buildFactoryMock.getLatestBuilds, expected);
assert.notCalled(buildFactoryMock.list);
assert.deepEqual(result, builds);
});
});

it('gets a list of builds with default pagination', () => {
const expected = {
params: { pipelineId: 123 },
paginate: { count: 10 },
sort: 'descending'
};

buildFactoryMock.list.resolves(builds);

return pipeline.getBuilds({}).then(result => {
assert.calledWith(buildFactoryMock.list, expected);
assert.deepEqual(result, builds);
});
});

it('gets a list of builds and does not pass through latest when groupEventId not set', () => {
const expected = {
params: { pipelineId: 123 },
paginate: { count: 300, page: 2 },
sort: 'descending'
};

buildFactoryMock.list.resolves(builds);

return pipeline.getBuilds({ params: { latest: true }, paginate: { count: 300, page: 2 } }).then(result => {
assert.calledWith(buildFactoryMock.list, expected);
assert.deepEqual(result, builds);
});
});

it('rejects with errors', () => {
buildFactoryMock.list.rejects(new Error('cannotgetit'));

return pipeline
.getBuilds()
.then(() => {
assert.fail('Should not get here');
})
.catch(err => {
assert.instanceOf(err, Error);
assert.equal(err.message, 'cannotgetit');
});
});
});

describe('getConfiguration', () => {
let parserConfig;
let getFileConfig;
Expand Down

0 comments on commit 8a2f1af

Please sign in to comment.