Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Content API v2 date formatting (#10095)
closes #10065 - Added UTC offset to dates returned by Content API - Added test checking new format is compatible with Admin API - Refactored output serializer mapping logic
- Loading branch information
Showing
14 changed files
with
488 additions
and
132 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
const moment = require('moment-timezone'); | ||
const settingsCache = require('../../../../../../services/settings/cache'); | ||
|
||
const format = (date) => { | ||
return moment(date) | ||
.tz(settingsCache.get('active_timezone')) | ||
.toISOString(true); | ||
}; | ||
|
||
const forPost = (attrs) => { | ||
['created_at', 'updated_at', 'published_at'].forEach((field) => { | ||
if (attrs[field]) { | ||
attrs[field] = format(attrs[field]); | ||
} | ||
}); | ||
|
||
return attrs; | ||
}; | ||
|
||
const forTag = (attrs) => { | ||
['created_at', 'updated_at'].forEach((field) => { | ||
if (attrs[field]) { | ||
attrs[field] = format(attrs[field]); | ||
} | ||
}); | ||
|
||
return attrs; | ||
}; | ||
|
||
module.exports.format = format; | ||
module.exports.forPost = forPost; | ||
module.exports.forTag = forTag; |
61 changes: 61 additions & 0 deletions
61
core/server/api/v2/utils/serializers/output/utils/mapper.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
const utils = require('../../../index'); | ||
const url = require('./url'); | ||
const date = require('./date'); | ||
|
||
const mapPost = (model, frame) => { | ||
const jsonModel = model.toJSON(frame.options); | ||
|
||
url.forPost(model.id, jsonModel, frame.options); | ||
|
||
if (utils.isContentAPI(frame)) { | ||
date.forPost(jsonModel); | ||
} | ||
|
||
if (frame.options && frame.options.withRelated) { | ||
frame.options.withRelated.forEach((relation) => { | ||
// @NOTE: this block also decorates primary_tag/primary_author objects as they | ||
// are being passed by reference in tags/authors. Might be refactored into more explicit call | ||
// in the future, but is good enough for current use-case | ||
if (relation === 'tags' && jsonModel.tags) { | ||
jsonModel.tags = jsonModel.tags.map(tag => url.forTag(tag.id, tag)); | ||
|
||
if (utils.isContentAPI(frame)) { | ||
jsonModel.tags = jsonModel.tags.map(tag => date.forTag(tag)); | ||
} | ||
} | ||
|
||
if (relation === 'author' && jsonModel.author) { | ||
jsonModel.author = url.forUser(jsonModel.author.id, jsonModel.author); | ||
} | ||
|
||
if (relation === 'authors' && jsonModel.authors) { | ||
jsonModel.authors = jsonModel.authors.map(author => url.forUser(author.id, author)); | ||
} | ||
}); | ||
} | ||
|
||
return jsonModel; | ||
}; | ||
|
||
const mapUser = (model, frame) => { | ||
const jsonModel = model.toJSON(frame.options); | ||
|
||
url.forUser(model.id, jsonModel); | ||
|
||
return jsonModel; | ||
}; | ||
|
||
const mapTag = (model, frame) => { | ||
const jsonModel = model.toJSON(frame.options); | ||
url.forTag(model.id, jsonModel); | ||
|
||
if (utils.isContentAPI(frame)) { | ||
date.forTag(jsonModel); | ||
} | ||
|
||
return jsonModel; | ||
}; | ||
|
||
module.exports.mapPost = mapPost; | ||
module.exports.mapUser = mapUser; | ||
module.exports.mapTag = mapTag; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
54 changes: 54 additions & 0 deletions
54
core/test/unit/api/v2/utils/serializers/output/pages_spec.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
const should = require('should'); | ||
const sinon = require('sinon'); | ||
const testUtils = require('../../../../../../utils'); | ||
const mapper = require('../../../../../../../server/api/v2/utils/serializers/output/utils/mapper'); | ||
const serializers = require('../../../../../../../server/api/v2/utils/serializers'); | ||
|
||
const sandbox = sinon.sandbox.create(); | ||
|
||
describe('Unit: v2/utils/serializers/output/pages', () => { | ||
let pageModel; | ||
|
||
beforeEach(() => { | ||
pageModel = (data) => { | ||
return Object.assign(data, {toJSON: sandbox.stub().returns(data)}); | ||
}; | ||
|
||
sandbox.stub(mapper, 'mapPost').returns({}); | ||
}); | ||
|
||
afterEach(() => { | ||
sandbox.restore(); | ||
}); | ||
|
||
it('calls the mapper', () => { | ||
const apiConfig = {}; | ||
const frame = { | ||
options: { | ||
withRelated: ['tags', 'authors'], | ||
context: { | ||
private: false | ||
} | ||
} | ||
}; | ||
|
||
const ctrlResponse = { | ||
data: [ | ||
pageModel(testUtils.DataGenerator.forKnex.createPost({ | ||
id: 'id1', | ||
page: true | ||
})), | ||
pageModel(testUtils.DataGenerator.forKnex.createPost({ | ||
id: 'id2', | ||
page: true | ||
})) | ||
], | ||
meta: {} | ||
}; | ||
|
||
serializers.output.pages.all(ctrlResponse, apiConfig, frame); | ||
|
||
mapper.mapPost.callCount.should.equal(2); | ||
mapper.mapPost.getCall(0).args.should.eql([ctrlResponse.data[0], frame]); | ||
}); | ||
}); |
Oops, something went wrong.