tag tests

v1.18.x
barisusakli 8 years ago
parent 33ff5e09bb
commit 7d47f4b067

@ -1,5 +1,6 @@
'use strict';
var async = require('async');
var topics = require('../../topics');
var utils = require('../../../public/src/utils');
@ -13,9 +14,6 @@ module.exports = function (SocketTopics) {
};
SocketTopics.searchAndLoadTags = function (socket, data, callback) {
if (!data) {
return callback(new Error('[[error:invalid-data]]'));
}
topics.searchAndLoadTags(data, callback);
};
@ -26,13 +24,14 @@ module.exports = function (SocketTopics) {
var start = parseInt(data.after, 10);
var stop = start + 99;
topics.getTags(start, stop, function (err, tags) {
if (err) {
return callback(err);
async.waterfall([
function (next) {
topics.getTags(start, stop, next);
},
function (tags, next) {
tags = tags.filter(Boolean);
next(null, {tags: tags, nextStart: stop + 1});
}
tags = tags.filter(Boolean);
callback(null, {tags: tags, nextStart: stop + 1});
});
], callback);
};
};

@ -178,30 +178,30 @@ module.exports = function (Topics) {
var sets = tids.map(function (tid) {
return 'topic:' + tid + ':tags';
});
var uniqueTopicTags;
var topicTags;
async.waterfall([
function (next) {
db.getSetsMembers(sets, next);
},
function (_topicTags, next) {
topicTags = _topicTags;
uniqueTopicTags = _.uniq(_.flatten(topicTags));
db.getSetsMembers(sets, function (err, topicTags) {
if (err) {
return callback(err);
}
var uniqueTopicTags = _.uniq(_.flatten(topicTags));
var tags = uniqueTopicTags.map(function (tag) {
return {value: tag};
});
async.parallel({
tagData: function (next) {
Topics.getTagData(tags, next);
},
counts: function (next) {
db.sortedSetScores('tags:topic:count', uniqueTopicTags, next);
}
}, function (err, results) {
if (err) {
return callback(err);
}
var tags = uniqueTopicTags.map(function (tag) {
return {value: tag};
});
async.parallel({
tagData: function (next) {
Topics.getTagData(tags, next);
},
counts: function (next) {
db.sortedSetScores('tags:topic:count', uniqueTopicTags, next);
}
}, next);
},
function (results, next) {
results.tagData.forEach(function (tag, index) {
tag.score = results.counts[index] ? results.counts[index] : 0;
});
@ -214,9 +214,9 @@ module.exports = function (Topics) {
}
});
callback(null, topicTags);
});
});
next(null, topicTags);
}
], callback);
};
Topics.updateTags = function (tid, tags, callback) {
@ -235,60 +235,54 @@ module.exports = function (Topics) {
};
Topics.deleteTopicTags = function (tid, callback) {
Topics.getTopicTags(tid, function (err, tags) {
if (err) {
return callback(err);
async.waterfall([
function (next) {
Topics.getTopicTags(tid, next);
},
function (tags, next) {
async.series([
function (next) {
db.delete('topic:' + tid + ':tags', next);
},
function (next) {
var sets = tags.map(function (tag) {
return 'tag:' + tag + ':topics';
});
db.sortedSetsRemove(sets, tid, next);
},
function (next) {
async.each(tags, function (tag, next) {
updateTagCount(tag, next);
}, next);
}
], next);
}
async.series([
function (next) {
db.delete('topic:' + tid + ':tags', next);
},
function (next) {
var sets = tags.map(function (tag) {
return 'tag:' + tag + ':topics';
});
db.sortedSetsRemove(sets, tid, next);
},
function (next) {
async.each(tags, function (tag, next) {
updateTagCount(tag, next);
}, next);
}
], function (err) {
callback(err);
});
], function (err) {
callback(err);
});
};
Topics.searchTags = function (data, callback) {
function done(matches) {
plugins.fireHook('filter:tags.search', {data: data, matches: matches}, function (err, data) {
callback(err, data ? data.matches : []);
});
}
if (!data || !data.query) {
return callback(null, []);
}
if (plugins.hasListeners('filter:topics.searchTags')) {
return plugins.fireHook('filter:topics.searchTags', {data: data}, function (err, data) {
if (err) {
return callback(err);
async.waterfall([
function (next) {
if (plugins.hasListeners('filter:topics.searchTags')) {
plugins.fireHook('filter:topics.searchTags', {data: data}, next);
} else {
findMatches(data.query, next);
}
done(data.matches);
});
}
findMatches(data.query, function (err, matches) {
if (err) {
return callback(err);
},
function (result, next) {
plugins.fireHook('filter:tags.search', {data: data, matches: result.matches}, next);
},
function (result, next) {
next(null, result.matches);
}
done(matches);
});
], callback);
};
Topics.autocompleteTags = function (data, callback) {
@ -296,41 +290,44 @@ module.exports = function (Topics) {
return callback(null, []);
}
if (plugins.hasListeners('filter:topics.autocompleteTags')) {
return plugins.fireHook('filter:topics.autocompleteTags', {data: data}, function (err, data) {
if (err) {
return callback(err);
async.waterfall([
function (next) {
if (plugins.hasListeners('filter:topics.autocompleteTags')) {
plugins.fireHook('filter:topics.autocompleteTags', {data: data}, next);
} else {
findMatches(data.query, next);
}
callback(null, data.matches);
});
}
findMatches(data.query, callback);
},
function (result, next) {
next(null, result.matches);
}
], callback);
};
function findMatches(query, callback) {
db.getSortedSetRevRange('tags:topic:count', 0, -1, function (err, tags) {
if (err) {
return callback(err);
}
query = query.toLowerCase();
var matches = [];
for(var i = 0; i < tags.length; ++i) {
if (tags[i].toLowerCase().startsWith(query)) {
matches.push(tags[i]);
if (matches.length > 19) {
break;
async.waterfall([
function (next) {
db.getSortedSetRevRange('tags:topic:count', 0, -1, next);
},
function (tags, next) {
query = query.toLowerCase();
var matches = [];
for(var i = 0; i < tags.length; ++i) {
if (tags[i].toLowerCase().startsWith(query)) {
matches.push(tags[i]);
if (matches.length > 19) {
break;
}
}
}
}
matches = matches.sort(function (a, b) {
return a > b;
});
callback(null, matches);
});
matches = matches.sort(function (a, b) {
return a > b;
});
next(null, {matches: matches});
}
], callback);
}
Topics.searchAndLoadTags = function (data, callback) {
@ -340,28 +337,28 @@ module.exports = function (Topics) {
pageCount: 1
};
if (!data.query || !data.query.length) {
if (!data || !data.query || !data.query.length) {
return callback(null, searchResult);
}
Topics.searchTags(data, function (err, tags) {
if (err) {
return callback(err);
}
async.parallel({
counts: function (next) {
db.sortedSetScores('tags:topic:count', tags, next);
},
tagData: function (next) {
tags = tags.map(function (tag) {
return {value: tag};
});
Topics.getTagData(tags, next);
}
}, function (err, results) {
if (err) {
return callback(err);
}
async.waterfall([
function (next) {
Topics.searchTags(data, next);
},
function (tags, next) {
async.parallel({
counts: function (next) {
db.sortedSetScores('tags:topic:count', tags, next);
},
tagData: function (next) {
tags = tags.map(function (tag) {
return {value: tag};
});
Topics.getTagData(tags, next);
}
}, next);
},
function (results, next) {
results.tagData.forEach(function (tag, index) {
tag.score = results.counts[index];
});
@ -371,9 +368,9 @@ module.exports = function (Topics) {
searchResult.tags = results.tagData;
searchResult.matchCount = results.tagData.length;
searchResult.pageCount = 1;
callback(null, searchResult);
});
});
next(null, searchResult);
}
], callback);
};
Topics.getRelatedTopics = function (topicData, uid, callback) {

@ -872,10 +872,101 @@ describe('Topic\'s', function () {
});
});
});
});
describe('tags', function () {
var socketTopics = require('../src/socket.io/topics');
before(function (done) {
async.parallel({
topic1: function (next) {
topics.post({uid: adminUid, tags: ['php', 'nosql', 'psql', 'nodebb'], title: 'topic title 1', content: 'topic 1 content', cid: topic.categoryId}, next);
},
topic2: function (next) {
topics.post({uid: adminUid, tags: ['javascript', 'mysql', 'python', 'nodejs'], title: 'topic title 2', content: 'topic 2 content', cid: topic.categoryId}, next);
}
}, function (err, results) {
assert.ifError(err);
done();
});
});
it('should return empty array if query is falsy', function (done) {
socketTopics.autocompleteTags({uid: adminUid}, {query: ''}, function (err, data) {
assert.ifError(err);
assert.deepEqual([], data);
done();
});
});
it('should autocomplete tags', function (done) {
socketTopics.autocompleteTags({uid: adminUid}, {query: 'p'}, function (err, data) {
assert.ifError(err);
['php', 'psql', 'python'].forEach(function (tag) {
assert.notEqual(data.indexOf(tag), -1);
});
done();
});
});
it('should return empty array if query is falsy', function (done) {
socketTopics.searchTags({uid: adminUid}, {query: ''}, function (err, data) {
assert.ifError(err);
assert.deepEqual([], data);
done();
});
});
it('should search tags', function (done) {
socketTopics.searchTags({uid: adminUid}, {query: 'no'}, function (err, data) {
assert.ifError(err);
['nodebb', 'nodejs', 'nosql'].forEach(function (tag) {
assert.notEqual(data.indexOf(tag), -1);
});
done();
});
});
it('should return empty array if query is falsy', function (done) {
socketTopics.searchAndLoadTags({uid: adminUid}, {query: ''}, function (err, data) {
assert.ifError(err);
assert.equal(data.matchCount, 0);
assert.equal(data.pageCount, 1);
assert.deepEqual(data.tags, []);
done();
});
});
it('should search and load tags', function (done) {
socketTopics.searchAndLoadTags({uid: adminUid}, {query: 'no'}, function (err, data) {
assert.ifError(err);
assert.equal(data.matchCount, 3);
assert.equal(data.pageCount, 1);
var tagData = [
{ value: 'nodebb', color: '', bgColor: '', score: 3 },
{ value: 'nodejs', color: '', bgColor: '', score: 1 },
{ value: 'nosql', color: '', bgColor: '', score: 1 }
];
assert.deepEqual(data.tags, tagData);
done();
});
});
it('shold return error if data is invalid', function (done) {
socketTopics.loadMoreTags({uid: adminUid}, {after: 'asd'}, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
it('should load more tags', function (done) {
socketTopics.loadMoreTags({uid: adminUid}, {after: 0}, function (err, data) {
assert.ifError(err);
assert(Array.isArray(data.tags));
assert.equal(data.nextStart, 100);
done();
});
});
});

Loading…
Cancel
Save