Skip to content

Commit 1c48448

Browse files
committed
fixed some cases for broken status history populating
fixed and improved some related unit tests
1 parent 93a1ff2 commit 1c48448

File tree

5 files changed

+61
-65
lines changed

5 files changed

+61
-65
lines changed

src/models/milestone.js

Lines changed: 20 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,35 +9,44 @@ import { STATUS_HISTORY_REFERENCES } from '../constants';
99
* NOTE that this function mutates milestone
1010
*
1111
* @param {Array|Object} milestone one milestone or list of milestones
12+
* @param {Object} options options which has been used to call main method
1213
*
1314
* @returns {Promise} promise
1415
*/
15-
const populateWithStatusHistory = async (milestone) => {
16+
const populateWithStatusHistory = async (milestone, options) => {
17+
// depend on this option `milestone` is a sequlize ORM object or plain JS object
18+
const isRaw = !!_.get(options, 'raw');
19+
const getMilestoneId = m => (
20+
isRaw ? m.id : m.dataValues.id
21+
);
22+
const formatMilestone = statusHistory => (
23+
isRaw ? { statusHistory } : { dataValues: { statusHistory } }
24+
);
1625
if (Array.isArray(milestone)) {
1726
const allStatusHistory = await models.StatusHistory.findAll({
1827
where: {
19-
referenceId: { $in: milestone.map(m => m.dataValues.id) },
28+
referenceId: { $in: milestone.map(getMilestoneId) },
2029
reference: 'milestone',
2130
},
2231
order: [['createdAt', 'desc']],
2332
raw: true,
2433
});
2534

2635
return milestone.map((m, index) => {
27-
const statusHistory = allStatusHistory.filter(s => s.referenceId === m.dataValues.id);
28-
return _.merge(milestone[index], { dataValues: { statusHistory } });
36+
const statusHistory = _.filter(allStatusHistory, { referenceId: getMilestoneId(m) });
37+
return _.merge(milestone[index], formatMilestone(statusHistory));
2938
});
3039
}
3140

3241
const statusHistory = await models.StatusHistory.findAll({
3342
where: {
34-
referenceId: milestone.dataValues.id,
43+
referenceId: getMilestoneId(milestone),
3544
reference: 'milestone',
3645
},
3746
order: [['createdAt', 'desc']],
3847
raw: true,
3948
});
40-
return _.merge(milestone, { dataValues: { statusHistory } });
49+
return _.merge(milestone, formatMilestone(statusHistory));
4150
};
4251

4352
/**
@@ -131,7 +140,7 @@ module.exports = (sequelize, DataTypes) => {
131140
updatedBy: milestone.updatedBy,
132141
}, {
133142
transaction: options.transaction,
134-
}).then(() => populateWithStatusHistory(milestone)),
143+
}).then(() => populateWithStatusHistory(milestone, options)),
135144

136145
afterBulkCreate: (milestones, options) => {
137146
const listStatusHistory = milestones.map(({ dataValues }) => ({
@@ -145,7 +154,7 @@ module.exports = (sequelize, DataTypes) => {
145154

146155
return models.StatusHistory.bulkCreate(listStatusHistory, {
147156
transaction: options.transaction,
148-
}).then(() => populateWithStatusHistory(milestones));
157+
}).then(() => populateWithStatusHistory(milestones, options));
149158
},
150159

151160
afterUpdate: (milestone, options) => {
@@ -161,12 +170,12 @@ module.exports = (sequelize, DataTypes) => {
161170
transaction: options.transaction,
162171
}).then(() => populateWithStatusHistory(milestone));
163172
}
164-
return populateWithStatusHistory(milestone);
173+
return populateWithStatusHistory(milestone, options);
165174
},
166175

167-
afterFind: (milestone) => {
176+
afterFind: (milestone, options) => {
168177
if (!milestone) return Promise.resolve();
169-
return populateWithStatusHistory(milestone);
178+
return populateWithStatusHistory(milestone, options);
170179
},
171180
},
172181
});

src/routes/milestones/list.spec.js

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ const milestones = [
8282
},
8383
];
8484

85-
describe('LIST timelines', () => {
85+
describe('LIST milestones', () => {
8686
before(function beforeHook(done) {
8787
this.timeout(10000);
8888
testUtil.clearDb()
@@ -165,13 +165,12 @@ describe('LIST timelines', () => {
165165
updatedBy: 2,
166166
},
167167
]))
168-
.then(() =>
169-
// Create timelines and milestones
170-
models.Timeline.bulkCreate(timelines)
171-
.then(() => models.Milestone.bulkCreate(milestones)))
172-
.then((mappedMilestones) => {
168+
// Create timelines and milestones
169+
.then(() => models.Timeline.bulkCreate(timelines))
170+
.then(() => models.Milestone.bulkCreate(milestones))
171+
.then((createdMilestones) => {
173172
// Index to ES
174-
timelines[0].milestones = mappedMilestones.map(({ dataValues }) => dataValues);
173+
timelines[0].milestones = _.map(createdMilestones, cm => _.omit(cm.toJSON(), 'deletedAt', 'deletedBy'));
175174
timelines[0].projectId = 1;
176175
return server.services.es.index({
177176
index: ES_TIMELINE_INDEX,

src/routes/milestones/update.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -171,8 +171,8 @@ module.exports = [
171171
}
172172
const statusHistory = await models.StatusHistory.findAll({
173173
where: { referenceId: milestone.id },
174-
order: [['createdAt', 'desc']],
175-
attributes: ['status'],
174+
order: [['createdAt', 'desc'], ['id', 'desc']],
175+
attributes: ['status', 'id'],
176176
limit: 2,
177177
raw: true,
178178
});

src/routes/milestones/update.spec.js

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1178,8 +1178,8 @@ describe('UPDATE Milestone', () => {
11781178
duration: 2,
11791179
startDate: '2018-05-13T00:00:00.000Z',
11801180
endDate: '2018-05-14T00:00:00.000Z',
1181-
completionDate: '2018-05-15T00:00:00.000Z',
1182-
status: 'paused',
1181+
completionDate: '2018-05-16T00:00:00.000Z',
1182+
status: 'active',
11831183
type: 'type1',
11841184
details: {
11851185
detail1: {
@@ -1198,28 +1198,10 @@ describe('UPDATE Milestone', () => {
11981198
createdAt: '2018-05-11T00:00:00.000Z',
11991199
updatedAt: '2018-05-11T00:00:00.000Z',
12001200
},
1201-
]).then(() => models.StatusHistory.bulkCreate([
1202-
{
1203-
reference: 'milestone',
1204-
referenceId: 7,
1205-
status: 'active',
1206-
comment: 'comment',
1207-
createdBy: 1,
1208-
createdAt: '2018-05-15T00:00:00Z',
1209-
updatedBy: 1,
1210-
updatedAt: '2018-05-15T00:00:00Z',
1211-
},
1212-
{
1213-
reference: 'milestone',
1214-
referenceId: 7,
1215-
status: 'paused',
1216-
comment: 'comment',
1217-
createdBy: 1,
1218-
createdAt: '2018-05-16T00:00:00Z',
1219-
updatedBy: 1,
1220-
updatedAt: '2018-05-16T00:00:00Z',
1221-
},
1222-
]).then(() => {
1201+
]).then(() => models.Milestone.findById(7)
1202+
// pause milestone before resume
1203+
.then(milestone => milestone.update(_.assign({}, milestone.toJSON(), { status: 'paused' }))),
1204+
).then(() => {
12231205
request(server)
12241206
.patch('/v4/timelines/1/milestones/7')
12251207
.set({
@@ -1245,11 +1227,11 @@ describe('UPDATE Milestone', () => {
12451227
}).then((statusHistories) => {
12461228
statusHistories.length.should.be.eql(1);
12471229
done();
1248-
});
1249-
});
1230+
}).catch(done);
1231+
}).catch(done);
12501232
}
12511233
});
1252-
}));
1234+
});
12531235
});
12541236

12551237
describe('Bus api', () => {

src/routes/timelines/list.spec.js

Lines changed: 24 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -182,25 +182,31 @@ describe('LIST timelines', () => {
182182
]))
183183
.then(() =>
184184
// Create timelines
185-
Promise.all([
186-
models.Timeline.bulkCreate(timelines, { returning: true }),
187-
models.Milestone.bulkCreate(milestones),
188-
]))
189-
.then(([createdTimelines, mappedMilestones]) =>
185+
models.Timeline.bulkCreate(timelines, { returning: true })
186+
.then(createdTimelines => (
187+
// create milestones after timelines
188+
models.Milestone.bulkCreate(milestones))
189+
.then(createdMilestones => [createdTimelines, createdMilestones]),
190+
),
191+
).then(([createdTimelines, createdMilestones]) =>
190192
// Index to ES
191-
Promise.all(_.map(createdTimelines, (createdTimeline) => {
192-
const timelineJson = _.omit(createdTimeline.toJSON(), 'deletedAt', 'deletedBy');
193-
timelineJson.projectId = createdTimeline.id !== 3 ? 1 : 2;
194-
if (timelineJson.id === 1) {
195-
timelineJson.milestones = mappedMilestones;
196-
}
197-
return server.services.es.index({
198-
index: ES_TIMELINE_INDEX,
199-
type: ES_TIMELINE_TYPE,
200-
id: timelineJson.id,
201-
body: timelineJson,
202-
});
203-
}))
193+
Promise.all(_.map(createdTimelines, (createdTimeline) => {
194+
const timelineJson = _.omit(createdTimeline.toJSON(), 'deletedAt', 'deletedBy');
195+
timelineJson.projectId = createdTimeline.id !== 3 ? 1 : 2;
196+
if (timelineJson.id === 1) {
197+
timelineJson.milestones = _.map(
198+
createdMilestones,
199+
cm => _.omit(cm.toJSON(), 'deletedAt', 'deletedBy'),
200+
);
201+
}
202+
203+
return server.services.es.index({
204+
index: ES_TIMELINE_INDEX,
205+
type: ES_TIMELINE_TYPE,
206+
id: timelineJson.id,
207+
body: timelineJson,
208+
});
209+
}))
204210
.then(() => {
205211
// sleep for some time, let elasticsearch indices be settled
206212
sleep.sleep(5);

0 commit comments

Comments
 (0)