Commit a0a098e7 authored by Robert Knight's avatar Robert Knight

Rewrite used parts of stream-filter.coffee in JS

Port stream-filter.coffee to JS and add tests, but only for the
functionality that we actually still use in the app. Following the
removal of support for real-time updates in the stream, the websocket is
only configured to filter by URI, annotation ID or reply IDs
("references") in the sidebar and standalone annotation viewer.
parent 59cd2eb6
module.exports = class StreamFilter
strategies: ['include_any', 'include_all', 'exclude_any', 'exclude_all']
filter:
match_policy : 'include_any'
clauses : []
actions :
create: true
update: true
delete: true
constructor: ->
getFilter: -> return @filter
getMatchPolicy: -> return @filter.match_policy
getClauses: -> return @filter.clauses
getActions: -> return @filter.actions
getActionCreate: -> return @filter.actions.create
getActionUpdate: -> return @filter.actions.update
getActionDelete: -> return @filter.actions.delete
setMatchPolicy: (policy) ->
@filter.match_policy = policy
this
setMatchPolicyIncludeAny: ->
@filter.match_policy = 'include_any'
this
setMatchPolicyIncludeAll: ->
@filter.match_policy = 'include_all'
this
setMatchPolicyExcludeAny: ->
@filter.match_policy = 'exclude_any'
this
setMatchPolicyExcludeAll: ->
@filter.match_policy = 'exclude_all'
this
setActions: (actions) ->
@filter.actions = actions
this
setActionCreate: (action) ->
@filter.actions.create = action
this
setActionUpdate: (action) ->
@filter.actions.update = action
this
setActionDelete: (action) ->
@filter.actions.delete = action
this
noClauses: ->
@filter.clauses = []
this
addClause: (field, operator, value, case_sensitive = false, options = {}) ->
@filter.clauses.push
field: field
operator: operator
value: value
case_sensitive: case_sensitive
options: options
this
resetFilter: ->
@setMatchPolicyIncludeAny()
@setActionCreate(true)
@setActionUpdate(true)
@setActionDelete(true)
@noClauses()
this
'use strict';
/**
* StreamFilter generates JSON-serializable configuration objects that
* control which real-time updates are received from the annotation service.
*
* See https://github.com/hypothesis/h/blob/master/h/streamer/filter.py
* for the schema.
*/
class StreamFilter {
constructor() {
this.resetFilter();
}
/**
* Add a matching clause to the configuration.
*
* @param field - Field to filter by
* @param operator - How to filter
* @param value - Value to match
* @param caseSensitive - Whether matching should be case sensitive
*/
addClause(field, operator, value, caseSensitive = false) {
this.filter.clauses.push({
field,
operator,
value,
case_sensitive: caseSensitive,
});
return this;
}
/** Return the JSON-serializable filtering configuration. */
getFilter() {
return this.filter;
}
/** Reset the configuration to return all updates. */
resetFilter() {
this.filter = {
match_policy: 'include_any',
clauses: [],
actions: {
create: true,
update: true,
delete: true,
},
};
return this;
}
}
module.exports = StreamFilter;
'use strict';
const StreamFilter = require('../stream-filter');
describe('sidebar/services/stream-filter', () => {
describe('#addClause', () => {
[{
field: '/uri',
operator: 'one_of',
value: ['https://example.com', 'doi:1234'],
},{
field: '/id',
operator: 'exactly',
value: '1234',
},{
field: '/references',
operator: 'one_of',
value: ['1234', '5678'],
}].forEach(({ field, operator, value }) => {
it('generates filter configurations', () => {
const filter = new StreamFilter();
filter.addClause(field, operator, value);
const config = filter.getFilter();
assert.deepEqual(config, {
match_policy: 'include_any',
clauses: [{
field,
operator,
value,
case_sensitive: false,
}],
actions: {
create: true,
update: true,
delete: true,
},
});
});
});
it('is chainable', () => {
const filter = new StreamFilter();
assert.equal(filter.addClause('/id', 'exactly', '123'), filter);
});
});
describe('#resetFilter', () => {
it('resets the configuration', () => {
const filter = new StreamFilter();
filter.addClause('/uri', 'one_of', ['https://example.com']);
filter.resetFilter();
const config = filter.getFilter();
assert.deepEqual(config, {
match_policy: 'include_any',
clauses: [],
actions: {
create: true,
update: true,
delete: true,
},
});
});
it('is chainable', () => {
const filter = new StreamFilter();
assert.equal(filter.resetFilter(), filter);
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment