Merge pull request #827 from coralproject/correctly-resolve-isClosed

Correctly determine the status of the asset
This commit is contained in:
Kim Gardner
2017-08-04 06:54:20 -04:00
committed by GitHub
7 changed files with 93 additions and 6 deletions
@@ -16,7 +16,7 @@ class ConfigureStreamContainer extends Component {
this.state = {
changed: false,
dirtySettings: props.asset.settings,
closedAt: (props.asset.closedAt === null ? 'open' : 'closed')
closedAt: !props.asset.isClosed ? 'open' : 'closed'
};
this.toggleStatus = this.toggleStatus.bind(this);
@@ -19,6 +19,7 @@ import cn from 'classnames';
import {getTopLevelParent, attachCommentToParent} from '../graphql/utils';
import AllCommentsPane from './AllCommentsPane';
import AutomaticAssetClosure from '../containers/AutomaticAssetClosure';
import styles from './Stream.css';
@@ -101,7 +102,7 @@ class Stream extends React.Component {
editName
} = this.props;
const {keepCommentBox} = this.state;
const open = asset.closedAt === null;
const open = !asset.isClosed;
// even though the permalinked comment is the highlighted one, we're displaying its parent + replies
let highlightedComment = comment && getTopLevelParent(comment);
@@ -141,6 +142,7 @@ class Stream extends React.Component {
return (
<div id="stream" className={styles.root}>
<AutomaticAssetClosure assetId={asset.id} closedAt={asset.closedAt}/>
{comment &&
<Button
cStyle="darkGrey"
@@ -0,0 +1,81 @@
import React from 'react';
import PropTypes from 'prop-types';
import {gql} from 'react-apollo';
const FRAGMENT = gql`
fragment CoralEmbedStream_AutomaticAssetClosure_Fragment on Asset {
id
isClosed
}
`;
function getFragmentId(assetId) {
return `Asset_${assetId}`;
}
/**
* AutomaticAssetClosure updates the graphql state of the provide asset
* to `isClosed=true` when passed `closedAt`.
*/
class AutomaticAssetClosure extends React.Component {
static contextTypes = {
client: PropTypes.object.isRequired,
};
timer = null;
componentWillMount() {
this.setupTimer(this.props.assetId, this.props.closedAt);
}
componentWillReceiveProps(next) {
if (
this.props.assetId !== next.assetId ||
this.props.closedAt !== next.closedAt
) {
this.setupTimer(next.assetId, next.closedAt);
}
}
closeAsset(assetId) {
this.context.client.writeFragment({
fragment: FRAGMENT,
id: getFragmentId(assetId),
data: {
isClosed: true,
},
});
}
setupTimer(assetId, closedAt) {
clearTimeout(this.timer);
this.timer = null;
if (assetId && closedAt) {
const asset = this.context.client.readFragment({
fragment: FRAGMENT,
id: getFragmentId(assetId),
});
if (!asset.isClosed && closedAt) {
const diff = (new Date(closedAt) - new Date());
if (diff >= 0) {
this.timer = setTimeout(() => this.closeAsset(assetId), diff);
} else {
this.closeAsset(assetId);
}
}
}
}
render() {
return null;
}
}
AutomaticAssetClosure.PropTypes = {
assetId: PropTypes.string,
closedAt: PropTypes.string,
};
export default AutomaticAssetClosure;
@@ -251,6 +251,7 @@ const fragments = {
title
url
closedAt
isClosed
created_at
settings {
moderation
+3
View File
@@ -596,6 +596,9 @@ type Asset {
# The date that the asset was closed at.
closedAt: Date
# True if asset is closed.
isClosed: Boolean!
# Summary of all Actions against all entities associated with the Asset.
# (likes, flags, etc.). Requires the `ADMIN` role.
action_summaries: [AssetActionSummary!]
+2 -2
View File
@@ -61,7 +61,7 @@ const AssetSchema = new Schema({
timestamps: {
createdAt: 'created_at',
updatedAt: 'updated_at'
}
},
});
AssetSchema.index({
@@ -79,7 +79,7 @@ AssetSchema.index({
* Returns true if the asset is closed, false else.
*/
AssetSchema.virtual('isClosed').get(function() {
return this.closedAt && this.closedAt.getTime() <= new Date().getTime();
return Boolean(this.closedAt && this.closedAt.getTime() <= new Date().getTime());
});
const Asset = mongoose.model('Asset', AssetSchema);
+2 -2
View File
@@ -43,7 +43,7 @@ describe('/api/v1/assets', () => {
.set(passport.inject({roles: ['ADMIN']}))
.then((res) => {
const body = res.body;
expect(body).to.have.property('count', 2);
expect(body).to.have.property('result');
@@ -129,7 +129,7 @@ describe('/api/v1/assets', () => {
return AssetsService.findOrCreateByUrl('http://test.com')
.then((asset) => {
expect(asset).to.have.property('isClosed', null);
expect(asset).to.have.property('isClosed', false);
expect(asset).to.have.property('closedAt', null);
return chai.request(app)