Merge branch 'master' into styleguide

v1.18.x
Julian Lam 8 years ago
commit e71bd7a27f

@ -39,8 +39,8 @@
"markAsUnreadForAll.success": "すべてのスレッドを未読にしました。",
"mark_unread": "未読としてマーク",
"mark_unread.success": "スレッドは未読にマークされました。",
"watch": "ウッチ",
"unwatch": "ウッチ解除",
"watch": "ウッチ",
"unwatch": "ウッチ解除",
"watch.title": "新しい投稿の通知を受ける",
"unwatch.title": "このスレッドの通知を停止します",
"share_this_post": "投稿を共有",
@ -107,7 +107,7 @@
"more_guests": "ゲストさんが%1人",
"users_and_others": "%1と他は%2",
"sort_by": "並び替え",
"oldest_to_newest": "古い\bものから新しい順",
"oldest_to_newest": "古いものから新しい順",
"newest_to_oldest": "新しいものから古い順",
"most_votes": "最も投票された順",
"most_posts": "最も投稿された順",

@ -51,7 +51,7 @@
"change_password": "パスワードを変更",
"change_password_error": "無効のパスワード!",
"change_password_error_wrong_current": "現在のパスワードは正しくありません!",
"change_password_error_length": "パスワードは短い過ぎです!",
"change_password_error_length": "パスワードが短過ぎです!",
"change_password_error_match": "パスワードは一致しません!",
"change_password_error_privileges": "パスワードを更新する権限はありません。",
"change_password_success": "パスワードを更新しました!",
@ -79,7 +79,7 @@
"digest_monthly": "マンスリー",
"send_chat_notifications": "オンラインではない時に新しいチャットメッセージを受信した場合、通知メールを送信する。",
"send_post_notifications": "購読中のスレッドに返信があった場合、メールで通知する。",
"settings-require-reload": "変化がありましてブラウザを更新する必要があります。ここを押して、ページ更新します。",
"settings-require-reload": "設定を変更するにはページを更新する必要があります。ここを押して、ページ更新します。",
"has_no_follower": "フォロワーはまだいません :(",
"follows_no_one": "フォロー中のユーザーはまだいません :(",
"has_no_posts": "このユーザーはまだ一つも投稿していません",
@ -106,7 +106,7 @@
"delay_image_loading": "画像読み込みを遅延させる",
"image_load_delay_help": "有効の場合、スレッド内の画像はスクロールされるまで読み込みません",
"scroll_to_my_post": "返信を投稿した後、新しい投稿を表示する",
"follow_topics_you_reply_to": "あなたが返信するスレッドをウォッチ",
"follow_topics_you_reply_to": "あなたが返信したスレッドをウォッチする",
"follow_topics_you_create": "あなたが作成したスレッドをウォッチする",
"grouptitle": "グループ題名",
"no-group-title": "グループ名がありません",

@ -3,29 +3,29 @@
"title": "Site Başlığı",
"title.name": "Topluluk İsmi",
"title.show-in-header": "Show Site Title in Header",
"browser-title": "Browser Title",
"browser-title": "Tarayıcı Başlığı",
"browser-title-help": "If no browser title is specified, the site title will be used",
"title-layout": "Title Layout",
"title-layout-help": "Define how the browser title will be structured ie. {pageTitle} | {browserTitle}",
"description.placeholder": "A short description about your community",
"description": "Site Açıklaması",
"keywords": "Site Keywords",
"keywords": "Site Anahtar Kelimeler",
"keywords-placeholder": "Keywords describing your community, comma-separated",
"logo": "Site Logo",
"logo.image": "Image",
"logo.image": "Görsel",
"logo.image-placeholder": "Path to a logo to display on forum header",
"logo.upload": "Yükle",
"logo.url": "URL",
"logo.url-placeholder": "The URL of the site logo",
"logo.url-help": "When the logo is clicked, send users to this address. If left blank, user will be sent to the forum index.",
"logo.alt-text": "Alt Text",
"logo.alt-text": "Alt Yazı",
"log.alt-text-placeholder": "Alternative text for accessibility",
"favicon": "Favicon",
"favicon.upload": "Yükle",
"touch-icon": "Homescreen/Touch Icon",
"touch-icon.upload": "Yükle",
"touch-icon.help": "Recommended size and format: 192x192, PNG format only. If no touch icon is specified, NodeBB will fall back to using the favicon.",
"outgoing-links": "Outgoing Links",
"outgoing-links": "Harici Bağlantılar",
"outgoing-links.warning-page": "Use Outgoing Links Warning Page",
"search-default-sort-by": "Search default sort by"
"search-default-sort-by": "Aramada varsayılan sıralama"
}

@ -77,7 +77,6 @@ app.cacheBuster = null;
require(['taskbar', 'helpers', 'forum/pagination'], function (taskbar, helpers, pagination) {
taskbar.init();
// templates.js helpers
helpers.register();
pagination.init();

@ -1,7 +1,14 @@
'use strict';
(function (exports) {
var helpers = {};
'use strict';
/* globals define, utils, config */
// export the class if we are in a Node-like system.
if (typeof module === 'object' && module.exports === exports) {
exports = module.exports/* = SemVer*/;
}
var helpers = exports;
helpers.displayMenuItem = function (data, index) {
var item = data.navigation[index];

@ -32,17 +32,18 @@ groupsController.getGroupsFromSet = function (uid, sort, start, stop, callback)
set = 'groups:visible:createtime';
}
groups.getGroupsFromSet(set, uid, start, stop, function (err, groups) {
if (err) {
return callback(err);
}
callback(null, {
groups: groups,
async.waterfall([
function (next) {
groups.getGroupsFromSet(set, uid, start, stop, next);
},
function (groupsData, next) {
next(null, {
groups: groupsData,
allowGroupCreation: parseInt(meta.config.allowGroupCreation, 10) === 1,
nextStart: stop + 1,
});
});
},
], callback);
};
groupsController.details = function (req, res, callback) {

@ -298,7 +298,7 @@ topicsController.teaser = function (req, res, next) {
var tid = req.params.topic_id;
if (!utils.isNumber(tid)) {
return next(new Error('[[error:invalid-tid]]'));
return next();
}
async.waterfall([

@ -30,7 +30,7 @@ uploadsController.upload = function (req, res, filesIterator) {
deleteTempFiles(files);
if (err) {
return res.status(500).send(err.message);
return res.status(500).json({ path: req.path, error: err.message });
}
res.status(200).send(images);
@ -136,26 +136,24 @@ uploadsController.uploadThumb = function (req, res, next) {
}
uploadsController.upload(req, res, function (uploadedFile, next) {
file.isFileTypeAllowed(uploadedFile.path, function (err) {
if (err) {
return next(err);
}
async.waterfall([
function (next) {
if (!uploadedFile.type.match(/image./)) {
return next(new Error('[[error:invalid-file]]'));
}
file.isFileTypeAllowed(uploadedFile.path, next);
},
function (next) {
var size = parseInt(meta.config.topicThumbSize, 10) || 120;
image.resizeImage({
path: uploadedFile.path,
extension: path.extname(uploadedFile.name),
width: size,
height: size,
}, function (err) {
if (err) {
return next(err);
}
}, next);
},
function (next) {
if (plugins.hasListeners('filter:uploadImage')) {
return plugins.fireHook('filter:uploadImage', {
image: uploadedFile,
@ -164,8 +162,8 @@ uploadsController.uploadThumb = function (req, res, next) {
}
uploadFile(req.uid, uploadedFile, next);
});
});
},
], next);
}, next);
};
@ -184,12 +182,14 @@ uploadsController.uploadGroupCover = function (uid, uploadedFile, callback) {
}, callback);
}
file.isFileTypeAllowed(uploadedFile.path, function (err) {
if (err) {
return callback(err);
}
saveFileToLocal(uploadedFile, callback);
});
async.waterfall([
function (next) {
file.isFileTypeAllowed(uploadedFile.path, next);
},
function (next) {
saveFileToLocal(uploadedFile, next);
},
], callback);
};
function uploadFile(uid, uploadedFile, callback) {
@ -228,17 +228,18 @@ function saveFileToLocal(uploadedFile, callback) {
filename = Date.now() + '-' + validator.escape(filename.replace(path.extname(uploadedFile.name) || '', '')).substr(0, 255) + extension;
file.saveFileToLocal(filename, 'files', uploadedFile.path, function (err, upload) {
if (err) {
return callback(err);
}
callback(null, {
async.waterfall([
function (next) {
file.saveFileToLocal(filename, 'files', uploadedFile.path, next);
},
function (upload, next) {
next(null, {
url: nconf.get('relative_path') + upload.url,
path: upload.path,
name: uploadedFile.name,
});
});
},
], callback);
}
function deleteTempFiles(files) {

@ -137,7 +137,6 @@ module.exports = function (Groups) {
};
Groups.acceptMembership = function (groupName, uid, callback) {
// Note: For simplicity, this method intentially doesn't check the caller uid for ownership!
async.waterfall([
async.apply(db.setRemove, 'group:' + groupName + ':pending', uid),
async.apply(db.setRemove, 'group:' + groupName + ':invited', uid),
@ -146,7 +145,6 @@ module.exports = function (Groups) {
};
Groups.rejectMembership = function (groupName, uid, callback) {
// Note: For simplicity, this method intentially doesn't check the caller uid for ownership!
async.parallel([
async.apply(db.setRemove, 'group:' + groupName + ':pending', uid),
async.apply(db.setRemove, 'group:' + groupName + ':invited', uid),

@ -62,13 +62,14 @@ module.exports = function (privileges) {
};
privileges.topics.can = function (privilege, tid, uid, callback) {
topics.getTopicField(tid, 'cid', function (err, cid) {
if (err) {
return callback(err);
async.waterfall([
function (next) {
topics.getTopicField(tid, 'cid', next);
},
function (cid, next) {
privileges.categories.can(privilege, cid, uid, next);
}
privileges.categories.can(privilege, cid, uid, callback);
});
], callback);
};
privileges.topics.filterTids = function (privilege, tids, uid, callback) {

@ -77,7 +77,7 @@ function isOwner(next) {
isAdmin: async.apply(user.isAdministrator, socket.uid),
isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName),
}, function (err, results) {
if (err || (!isOwner && !results.isAdmin)) {
if (err || (!results.isOwner && !results.isAdmin)) {
return callback(err || new Error('[[error:no-privileges]]'));
}
next(socket, data, callback);
@ -141,22 +141,25 @@ SocketGroups.issueMassInvite = isOwner(function (socket, data, callback) {
if (!data || !data.usernames || !data.groupName) {
return callback(new Error('[[error:invalid-data]]'));
}
var usernames = data.usernames.split(',');
var usernames = String(data.usernames).split(',');
usernames = usernames.map(function (username) {
return username && username.trim();
});
user.getUidsByUsernames(usernames, function (err, uids) {
if (err) {
return callback(err);
}
async.waterfall([
function (next) {
user.getUidsByUsernames(usernames, next);
},
function (uids, next) {
uids = uids.filter(function (uid) {
return !!uid && parseInt(uid, 10);
});
async.eachSeries(uids, function (uid, next) {
groups.invite(data.groupName, uid, next);
}, callback);
});
}, next);
},
], callback);
});
SocketGroups.rescindInvite = isOwner(function (socket, data, callback) {
@ -181,12 +184,14 @@ SocketGroups.kick = isOwner(function (socket, data, callback) {
return callback(new Error('[[error:cant-kick-self]]'));
}
groups.ownership.isOwner(data.uid, data.groupName, function (err, isOwner) {
if (err) {
return callback(err);
}
groups.kick(data.uid, data.groupName, isOwner, callback);
});
async.waterfall([
function (next) {
groups.ownership.isOwner(data.uid, data.groupName, next);
},
function (isOwner, next) {
groups.kick(data.uid, data.groupName, isOwner, next);
},
], callback);
});
SocketGroups.create = function (socket, data, callback) {
@ -198,32 +203,19 @@ SocketGroups.create = function (socket, data, callback) {
return callback(new Error('[[error:invalid-group-name]]'));
}
data.ownerUid = socket.uid;
groups.create(data, callback);
};
SocketGroups.delete = function (socket, data, callback) {
SocketGroups.delete = isOwner(function (socket, data, callback) {
if (data.groupName === 'administrators' ||
data.groupName === 'registered-users' ||
data.groupName === 'Global Moderators') {
return callback(new Error('[[error:not-allowed]]'));
}
async.parallel({
isOwner: async.apply(groups.ownership.isOwner, socket.uid, data.groupName),
isAdmin: async.apply(user.isAdministrator, socket.uid),
}, function (err, checks) {
if (err) {
return callback(err);
}
if (!checks.isOwner && !checks.isAdmin) {
return callback(new Error('[[error:no-privileges]]'));
}
groups.destroy(data.groupName, callback);
});
};
});
SocketGroups.search = function (socket, data, callback) {
data.options = data.options || {};
@ -241,7 +233,7 @@ SocketGroups.search = function (socket, data, callback) {
SocketGroups.loadMore = function (socket, data, callback) {
if (!data.sort || !utils.isNumber(data.after) || parseInt(data.after, 10) < 0) {
return callback();
return callback(new Error('[[error:invalid-data]]'));
}
var groupsPerPage = 9;
@ -260,13 +252,17 @@ SocketGroups.loadMoreMembers = function (socket, data, callback) {
return callback(new Error('[[error:invalid-data]]'));
}
data.after = parseInt(data.after, 10);
user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, function (err, users) {
if (err) {
return callback(err);
}
callback(null, { users: users, nextStart: data.after + 10 });
async.waterfall([
function (next) {
user.getUsersFromSet('group:' + data.groupName + ':members', socket.uid, data.after, data.after + 9, next);
},
function (users, next) {
next(null, {
users: users,
nextStart: data.after + 10,
});
},
], callback);
};
SocketGroups.cover = {};

@ -432,7 +432,6 @@ describe('Groups', function () {
var socketGroups = require('../src/socket.io/groups');
var meta = require('../src/meta');
it('should error if data is null', function (done) {
socketGroups.before({ uid: 0 }, 'groups.join', null, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
@ -535,7 +534,27 @@ describe('Groups', function () {
});
});
it('should reject membership of user', function (done) {
socketGroups.reject({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: testUid }, function (err) {
assert.ifError(err);
Groups.isInvited(testUid, 'PrivateCanJoin', function (err, invited) {
assert.ifError(err);
assert.equal(invited, false);
done();
});
});
});
it('should error if not owner or admin', function (done) {
socketGroups.accept({ uid: 0 }, { groupName: 'PrivateCanJoin', toUid: testUid }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
done();
});
});
it('should accept membership of user', function (done) {
socketGroups.join({ uid: testUid }, { groupName: 'PrivateCanJoin' }, function (err) {
assert.ifError(err);
socketGroups.accept({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: testUid }, function (err) {
assert.ifError(err);
Groups.isMember(testUid, 'PrivateCanJoin', function (err, isMember) {
@ -545,6 +564,155 @@ describe('Groups', function () {
});
});
});
});
it('should reject/accept all memberships requests', function (done) {
function requestMembership(uids, callback) {
async.series([
function (next) {
socketGroups.join({ uid: uids.uid1 }, { groupName: 'PrivateCanJoin' }, next);
},
function (next) {
socketGroups.join({ uid: uids.uid2 }, { groupName: 'PrivateCanJoin' }, next);
},
], function (err) {
callback(err);
});
}
var uids;
async.waterfall([
function (next) {
async.parallel({
uid1: function (next) {
User.create({ username: 'groupuser1' }, next);
},
uid2: function (next) {
User.create({ username: 'groupuser2' }, next);
},
}, next);
},
function (results, next) {
uids = results;
requestMembership(results, next);
},
function (next) {
socketGroups.rejectAll({ uid: adminUid }, { groupName: 'PrivateCanJoin' }, next);
},
function (next) {
Groups.getPending('PrivateCanJoin', next);
},
function (pending, next) {
assert.equal(pending.length, 0);
requestMembership(uids, next);
},
function (next) {
socketGroups.acceptAll({ uid: adminUid }, { groupName: 'PrivateCanJoin' }, next);
},
function (next) {
Groups.isMembers([uids.uid1, uids.uid2], 'PrivateCanJoin', next);
},
function (isMembers, next) {
assert(isMembers[0]);
assert(isMembers[1]);
next();
},
], function (err) {
done(err);
});
});
it('should issue invite to user', function (done) {
User.create({ username: 'invite1' }, function (err, uid) {
assert.ifError(err);
socketGroups.issueInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: uid }, function (err) {
assert.ifError(err);
Groups.isInvited(uid, 'PrivateCanJoin', function (err, isInvited) {
assert.ifError(err);
assert(isInvited);
done();
});
});
});
});
it('should fail with invalid data', function (done) {
socketGroups.issueMassInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', usernames: null }, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
it('should issue mass invite to users', function (done) {
User.create({ username: 'invite2' }, function (err, uid) {
assert.ifError(err);
socketGroups.issueMassInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', usernames: 'invite1, invite2' }, function (err) {
assert.ifError(err);
Groups.isInvited(uid, 'PrivateCanJoin', function (err, isInvited) {
assert.ifError(err);
assert(isInvited);
done();
});
});
});
});
it('should rescind invite', function (done) {
User.create({ username: 'invite3' }, function (err, uid) {
assert.ifError(err);
socketGroups.issueInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: uid }, function (err) {
assert.ifError(err);
socketGroups.rescindInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: uid }, function (err) {
assert.ifError(err);
Groups.isInvited(uid, 'PrivateCanJoin', function (err, isInvited) {
assert.ifError(err);
assert(!isInvited);
done();
});
});
});
});
});
it('should error if user is not invited', function (done) {
socketGroups.acceptInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin' }, function (err) {
assert.equal(err.message, '[[error:not-invited]]');
done();
});
});
it('should accept invite', function (done) {
User.create({ username: 'invite4' }, function (err, uid) {
assert.ifError(err);
socketGroups.issueInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: uid }, function (err) {
assert.ifError(err);
socketGroups.acceptInvite({ uid: uid }, { groupName: 'PrivateCanJoin' }, function (err) {
assert.ifError(err);
Groups.isMember(uid, 'PrivateCanJoin', function (err, isMember) {
assert.ifError(err);
assert(isMember);
done();
});
});
});
});
});
it('should reject invite', function (done) {
User.create({ username: 'invite5' }, function (err, uid) {
assert.ifError(err);
socketGroups.issueInvite({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: uid }, function (err) {
assert.ifError(err);
socketGroups.rejectInvite({ uid: uid }, { groupName: 'PrivateCanJoin' }, function (err) {
assert.ifError(err);
Groups.isInvited(uid, 'PrivateCanJoin', function (err, isInvited) {
assert.ifError(err);
assert(!isInvited);
done();
});
});
});
});
});
it('should grant ownership to user', function (done) {
socketGroups.grant({ uid: adminUid }, { groupName: 'PrivateCanJoin', toUid: testUid }, function (err) {
@ -568,6 +736,13 @@ describe('Groups', function () {
});
});
it('should fail to kick user with invalid data', function (done) {
socketGroups.kick({ uid: adminUid }, { groupName: 'PrivateCanJoin', uid: adminUid }, function (err) {
assert.equal(err.message, '[[error:cant-kick-self]]');
done();
});
});
it('should kick user from group', function (done) {
socketGroups.kick({ uid: adminUid }, { groupName: 'PrivateCanJoin', uid: testUid }, function (err) {
assert.ifError(err);
@ -578,6 +753,131 @@ describe('Groups', function () {
});
});
});
it('should fail to create group with invalid data', function (done) {
socketGroups.create({ uid: 0 }, {}, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
done();
});
});
it('should fail to create group if group creation is disabled', function (done) {
var oldValue = meta.config.allowGroupCreation;
meta.config.allowGroupCreation = 0;
socketGroups.create({ uid: 1 }, {}, function (err) {
assert.equal(err.message, '[[error:group-creation-disabled]]');
meta.config.allowGroupCreation = oldValue;
done();
});
});
it('should fail to create group if name is privilege group', function (done) {
var oldValue = meta.config.allowGroupCreation;
meta.config.allowGroupCreation = 1;
socketGroups.create({ uid: 1 }, { name: 'cid:1:privileges:groups:find' }, function (err) {
assert.equal(err.message, '[[error:invalid-group-name]]');
meta.config.allowGroupCreation = oldValue;
done();
});
});
it('should create/update group', function (done) {
var oldValue = meta.config.allowGroupCreation;
meta.config.allowGroupCreation = 1;
socketGroups.create({ uid: adminUid }, { name: 'createupdategroup' }, function (err, groupData) {
meta.config.allowGroupCreation = oldValue;
assert.ifError(err);
assert(groupData);
var data = {
groupName: 'createupdategroup',
values: {
name: 'renamedupdategroup',
description: 'cat group',
userTitle: 'cats',
userTitleEnabled: 1,
disableJoinRequests: 1,
hidden: 1,
private: 0,
},
};
socketGroups.update({ uid: adminUid }, data, function (err) {
assert.ifError(err);
Groups.get('renamedupdategroup', {}, function (err, groupData) {
assert.ifError(err);
assert.equal(groupData.name, 'renamedupdategroup');
assert.equal(groupData.userTitle, 'cats');
assert.equal(groupData.description, 'cat group');
assert.equal(groupData.hidden, true);
assert.equal(groupData.disableJoinRequests, true);
assert.equal(groupData.private, false);
done();
});
});
});
});
it('should delete group', function (done) {
socketGroups.delete({ uid: adminUid }, { groupName: 'renamedupdategroup' }, function (err) {
assert.ifError(err);
Groups.exists('renamedupdategroup', function (err, exists) {
assert.ifError(err);
assert(!exists);
done();
});
});
});
it('should fail to delete group if name is special', function (done) {
socketGroups.delete({ uid: adminUid }, { groupName: 'administrators' }, function (err) {
assert.equal(err.message, '[[error:not-allowed]]');
done();
});
});
it('should fail to delete group if name is special', function (done) {
socketGroups.delete({ uid: adminUid }, { groupName: 'registered-users' }, function (err) {
assert.equal(err.message, '[[error:not-allowed]]');
done();
});
});
it('should fail to delete group if name is special', function (done) {
socketGroups.delete({ uid: adminUid }, { groupName: 'Global Moderators' }, function (err) {
assert.equal(err.message, '[[error:not-allowed]]');
done();
});
});
it('should fail to load more groups with invalid data', function (done) {
socketGroups.loadMore({ uid: adminUid }, {}, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
it('should load more groups', function (done) {
socketGroups.loadMore({ uid: adminUid }, { after: 0, sort: 'count' }, function (err, data) {
assert.ifError(err);
assert(Array.isArray(data.groups));
done();
});
});
it('should fail to load more members with invalid data', function (done) {
socketGroups.loadMoreMembers({ uid: adminUid }, {}, function (err) {
assert.equal(err.message, '[[error:invalid-data]]');
done();
});
});
it('should load more members', function (done) {
socketGroups.loadMoreMembers({ uid: adminUid }, { after: 0, groupName: 'PrivateCanJoin' }, function (err, data) {
assert.ifError(err);
assert(Array.isArray(data.users));
done();
});
});
});
describe('admin socket methods', function () {
@ -815,6 +1115,13 @@ describe('Groups', function () {
});
});
it('should fail to remove cover if not logged in', function (done) {
socketGroups.cover.remove({ uid: 0 }, { groupName: 'Test' }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');
done();
});
});
it('should fail to remove cover if not owner', function (done) {
socketGroups.cover.remove({ uid: regularUid }, { groupName: 'Test' }, function (err) {
assert.equal(err.message, '[[error:no-privileges]]');

@ -0,0 +1,55 @@
'use strict';
var async = require('async');
var assert = require('assert');
var db = require('./mocks/databasemock');
var helpers = require('../public/src/modules/helpers');
describe('helpers', function () {
it('should return false if item doesn\'t exist', function (done) {
var flag = helpers.displayMenuItem({navigation: []}, 0);
assert(!flag);
done();
});
it('should return false if route is /users and privateUserInfo is on and user is not logged in', function (done) {
var flag = helpers.displayMenuItem({
navigation: [{route: '/users'}],
privateUserInfo: true,
config: {
loggedIn: false
}
}, 0);
assert(!flag);
done();
});
it('should return false if route is /tags and privateTagListing is on and user is not logged in', function (done) {
var flag = helpers.displayMenuItem({
navigation: [{route: '/tags'}],
privateTagListing: true,
config: {
loggedIn: false
}
}, 0);
assert(!flag);
done();
});
it('should stringify object', function (done) {
var str = helpers.stringify({a: 'herp < derp > and & quote "'});
assert.equal(str, '{&quot;a&quot;:&quot;herp &lt; derp &gt; and &amp; quote \\&quot;&quot;}');
done();
});
it('should escape html', function (done) {
var str = helpers.escape('gdkfhgk < some > and &');
assert.equal(str, 'gdkfhgk &lt; some &gt; and &amp;');
done();
});
});

@ -10,6 +10,7 @@ var topics = require('../src/topics');
var categories = require('../src/categories');
var User = require('../src/user');
var groups = require('../src/groups');
var helpers = require('./helpers');
var socketPosts = require('../src/socket.io/posts');
describe('Topic\'s', function () {
@ -19,7 +20,7 @@ describe('Topic\'s', function () {
before(function (done) {
groups.resetCache();
User.create({ username: 'admin' }, function (err, uid) {
User.create({ username: 'admin', password: '123456' }, function (err, uid) {
if (err) {
return done(err);
}
@ -669,7 +670,11 @@ describe('Topic\'s', function () {
});
});
it('should load topic', function (done) {
describe('controller', function () {
var request = require('request');
var topicData;
before(function (done) {
topics.post({
uid: topic.userId,
title: 'topic for controller test',
@ -679,15 +684,161 @@ describe('Topic\'s', function () {
}, function (err, result) {
assert.ifError(err);
assert.ok(result);
var request = require('request');
request(nconf.get('url') + '/topic/' + result.topicData.slug, function (err, response, body) {
topicData = result.topicData;
done();
});
});
it('should load topic', function (done) {
request(nconf.get('url') + '/topic/' + topicData.slug, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 200);
assert(body);
done();
});
});
it('should 404 if post index is invalid', function (done) {
request(nconf.get('url') + '/topic/' + topicData.slug + '/derp', function (err, response) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
});
});
it('should 404 if topic does not exist', function (done) {
request(nconf.get('url') + '/topic/123123/does-not-exist', function (err, response) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
});
});
it('should 401 if not allowed to read as guest', function (done) {
var privileges = require('../src/privileges');
privileges.categories.rescind(['read'], topicData.cid, 'guests', function (err) {
assert.ifError(err);
request(nconf.get('url') + '/api/topic/' + topicData.slug, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 401);
assert(body);
privileges.categories.give(['read'], topicData.cid, 'guests', done);
});
});
});
it('should redirect to correct topic if slug is missing', function (done) {
request(nconf.get('url') + '/topic/' + topicData.tid + '/herpderp/1?page=2', function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 200);
assert(body);
done();
});
});
it('should redirect if post index is out of range', function (done) {
request(nconf.get('url') + '/api/topic/' + topicData.slug + '/-1', function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 308);
assert.equal(body, '"/topic/13/topic-for-controller-test"');
done();
});
});
it('should 404 if page is out of bounds', function (done) {
var meta = require('../src/meta');
meta.config.usePagination = 1;
request(nconf.get('url') + '/topic/' + topicData.slug + '?page=100', function (err, response) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
});
});
it('should mark topic read', function (done) {
helpers.loginUser('admin', '123456', function (err, jar) {
assert.ifError(err);
request(nconf.get('url') + '/topic/' + topicData.slug, {
jar: jar,
}, function (err, res) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
topics.hasReadTopics([topicData.tid], adminUid, function (err, hasRead) {
assert.ifError(err);
assert.equal(hasRead[0], true);
done();
});
});
});
});
it('should 404 if tid is not a number', function (done) {
request(nconf.get('url') + '/api/topic/teaser/nan', { json: true }, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
});
});
it('should 403 if cant read', function (done) {
request(nconf.get('url') + '/api/topic/teaser/' + 123123, { json: true }, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 403);
assert.equal(body, '[[error:no-privileges]]');
done();
});
});
it('should load topic teaser', function (done) {
request(nconf.get('url') + '/api/topic/teaser/' + topicData.tid, { json: true }, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 200);
assert(body);
assert.equal(body.tid, topicData.tid);
assert.equal(body.content, 'topic content');
assert(body.user);
assert(body.topic);
assert(body.category);
done();
});
});
it('should 404 if tid is not a number', function (done) {
request(nconf.get('url') + '/api/topic/pagination/nan', { json: true }, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
});
});
it('should 404 if tid does not exist', function (done) {
request(nconf.get('url') + '/api/topic/pagination/1231231', { json: true }, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 404);
done();
});
});
it('should load pagination', function (done) {
request(nconf.get('url') + '/api/topic/pagination/' + topicData.tid, { json: true }, function (err, response, body) {
assert.ifError(err);
assert.equal(response.statusCode, 200);
assert(body);
assert.deepEqual(body, {
prev: { page: 1, active: false },
next: { page: 1, active: false },
rel: [],
pages: [],
currentPage: 1,
pageCount: 1,
});
done();
});
});
});
describe('infinitescroll', function () {
var socketTopics = require('../src/socket.io/topics');

@ -87,6 +87,20 @@ describe('Upload Controllers', function () {
});
});
it('should resize and upload an image to a post', function (done) {
var oldValue = meta.config.maximumImageWidth;
meta.config.maximumImageWidth = 10;
helpers.uploadFile(nconf.get('url') + '/api/post/upload', path.join(__dirname, '../test/files/test.png'), { cid: cid }, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
assert(Array.isArray(body));
assert(body[0].path);
assert(body[0].url);
meta.config.maximumImageWidth = oldValue;
done();
});
});
it('should upload a file to a post', function (done) {
meta.config.allowFileUploads = 1;
@ -99,6 +113,37 @@ describe('Upload Controllers', function () {
done();
});
});
it('should fail if topic thumbs are disabled', function (done) {
helpers.uploadFile(nconf.get('url') + '/api/topic/thumb/upload', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 500);
assert.equal(body.error, '[[error:topic-thumbnails-are-disabled]]');
done();
});
});
it('should fail if file is not image', function (done) {
meta.config.allowTopicsThumbnail = 1;
helpers.uploadFile(nconf.get('url') + '/api/topic/thumb/upload', path.join(__dirname, '../test/files/503.html'), {}, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 500);
assert.equal(body.error, '[[error:invalid-file]]');
done();
});
});
it('should upload topic thumb', function (done) {
meta.config.allowTopicsThumbnail = 1;
helpers.uploadFile(nconf.get('url') + '/api/topic/thumb/upload', path.join(__dirname, '../test/files/test.png'), {}, jar, csrf_token, function (err, res, body) {
assert.ifError(err);
assert.equal(res.statusCode, 200);
assert(Array.isArray(body));
assert(body[0].path);
assert(body[0].url);
done();
});
});
});

Loading…
Cancel
Save