test.js 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. /* globals describe, it, before, after */
  2. /* eslint no-loop-func:0 guard-for-in:0 */
  3. // no spam
  4. var logging = require("../lib/logging");
  5. if (process.env.VERBOSE_TEST !== "true" && process.env.TRAVIS !== "true") {
  6. logging.log = logging.debug = logging.warn = logging.error = function() {};
  7. }
  8. var networking = require("../lib/networking");
  9. var helpers = require("../lib/helpers");
  10. var cleaner = require("../lib/cleaner");
  11. var request = require("request");
  12. var config = require("../config");
  13. var server = require("../lib/server");
  14. var assert = require("assert");
  15. var skins = require("../lib/skins");
  16. var cache = require("../lib/cache");
  17. var crc = require("crc").crc32;
  18. var fs = require("fs");
  19. // we don't want tests to fail because of slow internet
  20. config.server.http_timeout *= 3;
  21. var uuids = fs.readFileSync("test/uuids.txt").toString().split(/\r?\n/);
  22. // Get a random UUIDto prevent rate limiting
  23. var uuid = uuids[Math.round(Math.random() * (uuids.length - 1))];
  24. // Let's hope these will never be assigned
  25. var steve_ids = [
  26. "fffffff0" + "fffffff0" + "fffffff0" + "fffffff0",
  27. "fffffff0" + "fffffff0" + "fffffff1" + "fffffff1",
  28. "fffffff0" + "fffffff1" + "fffffff0" + "fffffff1",
  29. "fffffff0" + "fffffff1" + "fffffff1" + "fffffff0",
  30. "fffffff1" + "fffffff0" + "fffffff0" + "fffffff1",
  31. "fffffff1" + "fffffff0" + "fffffff1" + "fffffff0",
  32. "fffffff1" + "fffffff1" + "fffffff0" + "fffffff0",
  33. "fffffff1" + "fffffff1" + "fffffff1" + "fffffff1",
  34. ];
  35. // Let's hope these will never be assigned
  36. var alex_ids = [
  37. "fffffff0" + "fffffff0" + "fffffff0" + "fffffff1",
  38. "fffffff0" + "fffffff0" + "fffffff1" + "fffffff0",
  39. "fffffff0" + "fffffff1" + "fffffff0" + "fffffff0",
  40. "fffffff0" + "fffffff1" + "fffffff1" + "fffffff1",
  41. "fffffff1" + "fffffff0" + "fffffff0" + "fffffff0",
  42. "fffffff1" + "fffffff0" + "fffffff1" + "fffffff1",
  43. "fffffff1" + "fffffff1" + "fffffff0" + "fffffff1",
  44. "fffffff1" + "fffffff1" + "fffffff1" + "fffffff0",
  45. ];
  46. // generates a 12 character random string
  47. function rid() {
  48. return Math.random().toString(36).substring(2, 14);
  49. }
  50. function getRandomInt(min, max) {
  51. return Math.floor(Math.random() * (max - min + 1)) + min;
  52. }
  53. describe("Crafatar", function() {
  54. // we might have to make 2 HTTP requests
  55. this.timeout(config.server.http_timeout * 2 + 50);
  56. before(function(done) {
  57. console.log("Flushing and waiting for redis ...");
  58. cache.get_redis().flushall(function() {
  59. console.log("Redis flushed!");
  60. // cause I don't know how big hard drives are these days
  61. config.cleaner.disk_limit = Infinity;
  62. config.cleaner.redis_limit = Infinity;
  63. cleaner.run();
  64. done();
  65. });
  66. });
  67. describe("UUID/username", function() {
  68. it("non-hex uuid is invalid", function(done) {
  69. assert.strictEqual(helpers.id_valid("g098cb60fa8e427cb299793cbd302c9a"), false);
  70. done();
  71. });
  72. it("empty id is invalid", function(done) {
  73. assert.strictEqual(helpers.id_valid(""), false);
  74. done();
  75. });
  76. it("lowercase uuid is valid", function(done) {
  77. assert.strictEqual(helpers.id_valid("0098cb60fa8e427cb299793cbd302c9a"), true);
  78. done();
  79. });
  80. it("uppercase uuid is valid", function(done) {
  81. assert.strictEqual(helpers.id_valid("1DCEF164FF0A47F2B9A691385C774EE7"), true);
  82. done();
  83. });
  84. it("dashed uuid is valid", function(done) {
  85. assert.strictEqual(helpers.id_valid("0098cb60-fa8e-427c-b299-793cbd302c9a"), true);
  86. done();
  87. });
  88. it("username is invalid", function(done) {
  89. assert.strictEqual(helpers.id_valid("__niceUs3rname__"), false);
  90. done();
  91. });
  92. it("username alex is invalid", function(done) {
  93. assert.strictEqual(helpers.id_valid("alex"), false);
  94. done();
  95. });
  96. it("username mhf_alex is invalid", function(done) {
  97. assert.strictEqual(helpers.id_valid("mhf_alex"), false);
  98. done();
  99. });
  100. it("username steve is invalid", function(done) {
  101. assert.strictEqual(helpers.id_valid("steve"), false);
  102. done();
  103. });
  104. it("username mhf_steve is invalid", function(done) {
  105. assert.strictEqual(helpers.id_valid("mhf_steve"), false);
  106. done();
  107. });
  108. it(">16 length username is invalid", function(done) {
  109. assert.strictEqual(helpers.id_valid("ThisNameIsTooLong"), false);
  110. done();
  111. });
  112. it("should not exist (uuid)", function(done) {
  113. var number = getRandomInt(0, 9).toString();
  114. networking.get_profile(rid(), Array(33).join(number), function(err, profile) {
  115. assert.ifError(err);
  116. assert.strictEqual(profile, null);
  117. done();
  118. });
  119. });
  120. });
  121. describe("Avatar", function() {
  122. for (var a in alex_ids) {
  123. var alexid = alex_ids[a];
  124. (function(alex_id) {
  125. it("UUID " + alex_id + " should default to MHF_Alex", function(done) {
  126. assert.strictEqual(skins.default_skin(alex_id), "mhf_alex");
  127. done();
  128. });
  129. }(alexid));
  130. }
  131. for (var s in steve_ids) {
  132. var steveid = steve_ids[s];
  133. (function(steve_id) {
  134. it("UUID " + steve_id + " should default to MHF_Steve", function(done) {
  135. assert.strictEqual(skins.default_skin(steve_id), "mhf_steve");
  136. done();
  137. });
  138. }(steveid));
  139. }
  140. });
  141. describe("Errors", function() {
  142. it("should time out on uuid info download", function(done) {
  143. var original_timeout = config.server.http_timeout;
  144. config.server.http_timeout = 1;
  145. networking.get_profile(rid(), "069a79f444e94726a5befca90e38aaf5", function(err, profile) {
  146. assert.notStrictEqual(["ETIMEDOUT", "ESOCKETTIMEDOUT"].indexOf(err.code), -1);
  147. config.server.http_timeout = original_timeout;
  148. done();
  149. });
  150. });
  151. it("should time out on skin download", function(done) {
  152. var original_timeout = config.http_timeout;
  153. config.server.http_timeout = 1;
  154. networking.get_from(rid(), "http://textures.minecraft.net/texture/477be35554684c28bdeee4cf11c591d3c88afb77e0b98da893fd7bc318c65184", function(body, res, error) {
  155. assert.notStrictEqual(["ETIMEDOUT", "ESOCKETTIMEDOUT"].indexOf(error.code), -1);
  156. config.server.http_timeout = original_timeout;
  157. done();
  158. });
  159. });
  160. it("should not find the skin", function(done) {
  161. assert.doesNotThrow(function() {
  162. networking.get_from(rid(), "http://textures.minecraft.net/texture/this-does-not-exist", function(img, response, err) {
  163. assert.strictEqual(err, null); // no error here, but it shouldn't throw exceptions
  164. done();
  165. });
  166. });
  167. });
  168. it("should not find the file", function(done) {
  169. skins.open_skin(rid(), "non/existent/path", function(err, img) {
  170. assert(err);
  171. done();
  172. });
  173. });
  174. });
  175. describe("Server", function() {
  176. // throws Exception when default headers are not in res.headers
  177. function assert_headers(res) {
  178. assert(res.headers["content-type"]);
  179. assert("" + res.headers["response-time"]);
  180. assert(res.headers["x-request-id"]);
  181. assert.equal(res.headers["access-control-allow-origin"], "*");
  182. assert.equal(res.headers["cache-control"], "max-age=" + config.caching.browser);
  183. }
  184. // throws Exception when +url+ is requested with +etag+
  185. // and it does not return 304 without a body
  186. function assert_cache(url, etag, callback) {
  187. request.get(url, {
  188. headers: {
  189. "If-None-Match": etag,
  190. },
  191. }, function(error, res, body) {
  192. assert.ifError(error);
  193. assert.strictEqual(body, '');
  194. assert.equal(res.statusCode, 304);
  195. assert_headers(res);
  196. callback();
  197. });
  198. }
  199. before(function(done) {
  200. server.boot(function() {
  201. done();
  202. });
  203. });
  204. it("should return 405 Method Not Allowed for POST", function(done) {
  205. request.post("http://localhost:3000", function(error, res, body) {
  206. assert.ifError(error);
  207. assert.strictEqual(res.statusCode, 405);
  208. done();
  209. });
  210. });
  211. it("should return correct HTTP response for home page", function(done) {
  212. var url = "http://localhost:3000";
  213. request.get(url, function(error, res, body) {
  214. assert.ifError(error);
  215. assert.strictEqual(res.statusCode, 200);
  216. assert_headers(res);
  217. assert(res.headers.etag);
  218. assert.strictEqual(res.headers["content-type"], "text/html; charset=utf-8");
  219. assert.strictEqual(res.headers.etag, '"' + crc(body) + '"');
  220. assert(body);
  221. assert_cache(url, res.headers.etag, function() {
  222. done();
  223. });
  224. });
  225. });
  226. it("should return correct HTTP response for assets", function(done) {
  227. var url = "http://localhost:3000/stylesheets/style.css";
  228. request.get(url, function(error, res, body) {
  229. assert.ifError(error);
  230. assert.strictEqual(res.statusCode, 200);
  231. assert_headers(res);
  232. assert(res.headers.etag);
  233. assert.strictEqual(res.headers["content-type"], "text/css");
  234. assert.strictEqual(res.headers.etag, '"' + crc(body) + '"');
  235. assert(body);
  236. assert_cache(url, res.headers.etag, function() {
  237. done();
  238. });
  239. });
  240. });
  241. it("should return correct HTTP response for URL encoded URLs", function(done) {
  242. var url = "http://localhost:3000/%61%76%61%74%61%72%73/%61%65%37%39%35%61%61%38%36%33%32%37%34%30%38%65%39%32%61%62%32%35%63%38%61%35%39%66%33%62%61%31"; // avatars/ae795aa86327408e92ab25c8a59f3ba1
  243. request.get(url, function(error, res, body) {
  244. assert.ifError(error);
  245. assert.strictEqual(res.statusCode, 201);
  246. assert_headers(res);
  247. assert(res.headers.etag);
  248. assert.strictEqual(res.headers["content-type"], "image/png");
  249. assert(body);
  250. done();
  251. });
  252. });
  253. it("should not fail on simultaneous requests", function(done) {
  254. var url = "http://localhost:3000/avatars/696a82ce41f44b51aa31b8709b8686f0";
  255. // 10 requests at once
  256. var requests = 10;
  257. var finished = 0;
  258. function partDone() {
  259. finished++;
  260. if (requests === finished) {
  261. done();
  262. }
  263. }
  264. function req() {
  265. request.get(url, function(error, res, body) {
  266. assert.ifError(error);
  267. assert.strictEqual(res.statusCode === 201 || res.statusCode === 200, true);
  268. assert_headers(res);
  269. assert(res.headers.etag);
  270. assert.strictEqual(res.headers["content-type"], "image/png");
  271. assert(body);
  272. partDone();
  273. });
  274. }
  275. // make simultanous requests
  276. for (var k = 0; k < requests; k++) {
  277. req(k);
  278. }
  279. });
  280. var server_tests = {
  281. "avatar with existing uuid": {
  282. url: "http://localhost:3000/avatars/853c80ef3c3749fdaa49938b674adae6?size=16",
  283. crc32: [3337292777],
  284. },
  285. "avatar with non-existent uuid": {
  286. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16",
  287. crc32: [2416827277, 1243826040],
  288. },
  289. "avatar with non-existent uuid defaulting to mhf_alex": {
  290. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&default=mhf_alex",
  291. crc32: [862751081, 809395677],
  292. },
  293. "avatar with non-existent uuid defaulting to uuid": {
  294. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&default=853c80ef3c3749fdaa49938b674adae6",
  295. crc32: [0],
  296. redirect: "/avatars/853c80ef3c3749fdaa49938b674adae6?size=16",
  297. },
  298. "avatar with non-existent uuid defaulting to url": {
  299. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  300. crc32: [0],
  301. redirect: "http://example.com/CaseSensitive",
  302. },
  303. "overlay avatar with existing uuid": {
  304. url: "http://localhost:3000/avatars/853c80ef3c3749fdaa49938b674adae6?size=16&overlay",
  305. crc32: [1710265722],
  306. },
  307. "overlay avatar with non-existent uuid": {
  308. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&overlay",
  309. crc32: [2416827277, 1243826040],
  310. },
  311. "overlay avatar with non-existent uuid defaulting to mhf_alex": {
  312. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&overlay&default=mhf_alex",
  313. crc32: [862751081, 809395677],
  314. },
  315. "overlay avatar with non-existent uuid defaulting to uuid": {
  316. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&default=853c80ef3c3749fdaa49938b674adae6",
  317. crc32: [0],
  318. redirect: "/avatars/853c80ef3c3749fdaa49938b674adae6?size=16",
  319. },
  320. "overlay avatar with non-existent uuid defaulting to url": {
  321. url: "http://localhost:3000/avatars/00000000000000000000000000000000?size=16&overlay&default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  322. crc32: [0],
  323. redirect: "http://example.com/CaseSensitive",
  324. },
  325. "cape with existing uuid": {
  326. url: "http://localhost:3000/capes/853c80ef3c3749fdaa49938b674adae6",
  327. crc32: [2556702429],
  328. },
  329. "cape with non-existent uuid": {
  330. url: "http://localhost:3000/capes/00000000000000000000000000000000",
  331. crc32: [0],
  332. },
  333. "cape with non-existent uuid defaulting to url": {
  334. url: "http://localhost:3000/capes/00000000000000000000000000000000?default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  335. crc32: [0],
  336. redirect: "http://example.com/CaseSensitive",
  337. },
  338. "skin with existing uuid": {
  339. url: "http://localhost:3000/skins/853c80ef3c3749fdaa49938b674adae6",
  340. crc32: [26500336],
  341. },
  342. "skin with non-existent uuid": {
  343. url: "http://localhost:3000/skins/00000000000000000000000000000000",
  344. crc32: [981937087],
  345. },
  346. "skin with non-existent uuid defaulting to mhf_alex": {
  347. url: "http://localhost:3000/skins/00000000000000000000000000000000?default=mhf_alex",
  348. crc32: [2298915739],
  349. },
  350. "skin with non-existent uuid defaulting to uuid": {
  351. url: "http://localhost:3000/skins/00000000000000000000000000000000?size=16&default=853c80ef3c3749fdaa49938b674adae6",
  352. crc32: [0],
  353. redirect: "/skins/853c80ef3c3749fdaa49938b674adae6?size=16",
  354. },
  355. "skin with non-existent uuid defaulting to url": {
  356. url: "http://localhost:3000/skins/00000000000000000000000000000000?default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  357. crc32: [0],
  358. redirect: "http://example.com/CaseSensitive",
  359. },
  360. "head render with existing uuid": {
  361. url: "http://localhost:3000/renders/head/853c80ef3c3749fdaa49938b674adae6?scale=2",
  362. crc32: [1168786201],
  363. },
  364. "head render with non-existent uuid": {
  365. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2",
  366. crc32: [3800926063],
  367. },
  368. "head render with non-existent uuid defaulting to mhf_alex": {
  369. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&default=mhf_alex",
  370. crc32: [4027858557],
  371. },
  372. "head render with non-existent uuid defaulting to uuid": {
  373. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&default=853c80ef3c3749fdaa49938b674adae6",
  374. crc32: [0],
  375. redirect: "/renders/head/853c80ef3c3749fdaa49938b674adae6?scale=2",
  376. },
  377. "head render with non-existent uuid defaulting to url": {
  378. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  379. crc32: [0],
  380. redirect: "http://example.com/CaseSensitive",
  381. },
  382. "overlay head render with existing uuid": {
  383. url: "http://localhost:3000/renders/head/853c80ef3c3749fdaa49938b674adae6?scale=2&overlay",
  384. crc32: [2880579826],
  385. },
  386. "overlay head render with non-existent uuid": {
  387. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&overlay",
  388. crc32: [3800926063],
  389. },
  390. "overlay head render with non-existent uuid defaulting to mhf_alex": {
  391. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&overlay&default=mhf_alex",
  392. crc32: [4027858557],
  393. },
  394. "overlay head with non-existent uuid defaulting to uuid": {
  395. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&overlay&default=853c80ef3c3749fdaa49938b674adae6",
  396. crc32: [0],
  397. redirect: "/renders/head/853c80ef3c3749fdaa49938b674adae6?scale=2&overlay=",
  398. },
  399. "overlay head render with non-existent uuid defaulting to url": {
  400. url: "http://localhost:3000/renders/head/00000000000000000000000000000000?scale=2&overlay&default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  401. crc32: [0],
  402. redirect: "http://example.com/CaseSensitive",
  403. },
  404. "body render with existing uuid": {
  405. url: "http://localhost:3000/renders/body/853c80ef3c3749fdaa49938b674adae6?scale=2",
  406. crc32: [2745192436],
  407. },
  408. "body render with non-existent uuid": {
  409. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2",
  410. crc32: [996962526],
  411. },
  412. "body render with non-existent uuid defaulting to mhf_alex": {
  413. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2&default=mhf_alex",
  414. crc32: [1255106465],
  415. },
  416. "body render with non-existent uuid defaulting to uuid": {
  417. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2&default=853c80ef3c3749fdaa49938b674adae6",
  418. crc32: [0],
  419. redirect: "/renders/body/853c80ef3c3749fdaa49938b674adae6?scale=2",
  420. },
  421. "body render with non-existent uuid defaulting to url": {
  422. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2&default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  423. crc32: [0],
  424. redirect: "http://example.com/CaseSensitive",
  425. },
  426. "overlay body render with existing uuid": {
  427. url: "http://localhost:3000/renders/body/853c80ef3c3749fdaa49938b674adae6?scale=2&overlay",
  428. crc32: [2441671793],
  429. },
  430. "overlay body render with non-existent uuid": {
  431. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2&overlay",
  432. crc32: [996962526],
  433. },
  434. "overlay body render with non-existent uuid defaulting to mhf_alex": {
  435. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2&overlay&default=mhf_alex",
  436. crc32: [1255106465],
  437. },
  438. "overlay body render with non-existent uuid defaulting to url": {
  439. url: "http://localhost:3000/renders/body/00000000000000000000000000000000?scale=2&overlay&default=http%3A%2F%2Fexample.com%2FCaseSensitive",
  440. crc32: [0],
  441. redirect: "http://example.com/CaseSensitive",
  442. },
  443. };
  444. for (var description in server_tests) {
  445. var loc = server_tests[description];
  446. (function(location) {
  447. it("should return correct HTTP response for " + description, function(done) {
  448. request.get(location.url, {followRedirect: false, encoding: null}, function(error, res, body) {
  449. assert.ifError(error);
  450. assert_headers(res);
  451. assert(res.headers["x-storage-type"]);
  452. var hash = crc(body);
  453. var matches = false;
  454. for (var c = 0; c < location.crc32.length; c++) {
  455. if (location.crc32[c] === hash) {
  456. matches = true;
  457. break;
  458. }
  459. }
  460. try {
  461. assert(matches);
  462. } catch(e) {
  463. throw new Error(hash + " != " + location.crc32 + " | " + body.toString("base64"));
  464. }
  465. assert.strictEqual(res.headers.location, location.redirect);
  466. if (location.crc32[0] === 0) {
  467. assert.strictEqual(res.statusCode, location.redirect ? 307 : 404);
  468. assert.ifError(res.headers.etag); // etag must not be present on non-200
  469. assert.strictEqual(res.headers["content-type"], "text/plain");
  470. done();
  471. } else {
  472. assert.strictEqual(res.headers["content-type"], "image/png");
  473. assert.strictEqual(res.statusCode, res.headers["x-storage-type"] === "downloaded" ? 201 : 200);
  474. assert(res.headers.etag);
  475. assert.strictEqual(res.headers.etag, '"' + hash + '"');
  476. assert_cache(location.url, res.headers.etag, function() {
  477. done();
  478. });
  479. }
  480. });
  481. });
  482. }(loc));
  483. }
  484. it("should return 304 on server error", function(done) {
  485. var original_debug = config.server.debug_enabled;
  486. var original_timeout = config.server.http_timeout;
  487. config.server.debug_enabled = false;
  488. config.server.http_timeout = 1;
  489. request.get({url: "http://localhost:3000/avatars/0000000000000000000000000000000f", headers: {"If-None-Match": '"some-etag"'}}, function(error, res, body) {
  490. assert.ifError(error);
  491. assert.strictEqual(body, '');
  492. assert.strictEqual(res.statusCode, 304);
  493. config.server.debug_enabled = original_debug;
  494. config.server.http_timeout = original_timeout;
  495. done();
  496. });
  497. });
  498. it("should return a 422 (invalid size)", function(done) {
  499. var size = config.avatars.max_size + 1;
  500. request.get("http://localhost:3000/avatars/2d5aa9cdaeb049189930461fc9b91cc5?size=" + size, function(error, res, body) {
  501. assert.ifError(error);
  502. assert.strictEqual(res.statusCode, 422);
  503. done();
  504. });
  505. });
  506. it("should return a 422 (invalid scale)", function(done) {
  507. var scale = config.renders.max_scale + 1;
  508. request.get("http://localhost:3000/renders/head/2d5aa9cdaeb049189930461fc9b91cc5?scale=" + scale, function(error, res, body) {
  509. assert.ifError(error);
  510. assert.strictEqual(res.statusCode, 422);
  511. done();
  512. });
  513. });
  514. it("should return a 422 (invalid render type)", function(done) {
  515. request.get("http://localhost:3000/renders/invalid/Jake_0", function(error, res, body) {
  516. assert.ifError(error);
  517. assert.strictEqual(res.statusCode, 422);
  518. done();
  519. });
  520. });
  521. // testing all paths for Invalid UUID
  522. var locations = ["avatars", "skins", "capes", "renders/body", "renders/head"];
  523. for (var l in locations) {
  524. loc = locations[l];
  525. (function(location) {
  526. it("should return a 422 (invalid uuid " + location + ")", function(done) {
  527. request.get("http://localhost:3000/" + location + "/thisisaninvaliduuid", function(error, res, body) {
  528. assert.ifError(error);
  529. assert.strictEqual(res.statusCode, 422);
  530. done();
  531. });
  532. });
  533. it("should return a 404 (invalid path " + location + ")", function(done) {
  534. request.get("http://localhost:3000/" + location + "/853c80ef3c3749fdaa49938b674adae6/invalid", function(error, res, body) {
  535. assert.ifError(error);
  536. assert.strictEqual(res.statusCode, 404);
  537. done();
  538. });
  539. });
  540. }(loc));
  541. }
  542. });
  543. // we have to make sure that we test both a 32x64 and 64x64 skin
  544. describe("Networking: Render", function() {
  545. it("should not fail (uuid, 32x64 skin)", function(done) {
  546. helpers.get_render(rid(), "af74a02d19cb445bb07f6866a861f783", 6, true, true, function(err, hash, img) {
  547. assert.strictEqual(err, null);
  548. done();
  549. });
  550. });
  551. it("should not fail (uuid, 64x64 skin)", function(done) {
  552. helpers.get_render(rid(), "2d5aa9cdaeb049189930461fc9b91cc5", 6, true, true, function(err, hash, img) {
  553. assert.strictEqual(err, null);
  554. done();
  555. });
  556. });
  557. });
  558. describe("Networking: Cape", function() {
  559. it("should not fail (guaranteed cape)", function(done) {
  560. helpers.get_cape(rid(), "Dinnerbone", function(err, hash, status, img) {
  561. assert.strictEqual(err, null);
  562. done();
  563. });
  564. });
  565. it("should already exist", function(done) {
  566. before(function() {
  567. cache.get_redis().flushall();
  568. });
  569. helpers.get_cape(rid(), "Dinnerbone", function(err, hash, status, img) {
  570. assert.strictEqual(err, null);
  571. done();
  572. });
  573. });
  574. it("should not be found", function(done) {
  575. helpers.get_cape(rid(), "Jake_0", function(err, hash, status, img) {
  576. assert.ifError(err);
  577. assert.strictEqual(img, null);
  578. done();
  579. });
  580. });
  581. });
  582. describe("Networking: Skin", function() {
  583. it("should not fail", function(done) {
  584. helpers.get_cape(rid(), "Jake_0", function(err, hash, status, img) {
  585. assert.strictEqual(err, null);
  586. done();
  587. });
  588. });
  589. it("should already exist", function(done) {
  590. before(function() {
  591. cache.get_redis().flushall();
  592. });
  593. helpers.get_cape(rid(), "Jake_0", function(err, hash, status, img) {
  594. assert.strictEqual(err, null);
  595. done();
  596. });
  597. });
  598. });
  599. describe("Networking: Avatar", function() {
  600. before(function() {
  601. cache.get_redis().flushall();
  602. });
  603. it("should be downloaded", function(done) {
  604. helpers.get_avatar(rid(), uuid, false, 160, function(err, status, image) {
  605. assert.ifError(err);
  606. assert.strictEqual(status, 2);
  607. done();
  608. });
  609. });
  610. it("should be cached", function(done) {
  611. helpers.get_avatar(rid(), uuid, false, 160, function(err, status, image) {
  612. assert.ifError(err);
  613. assert.strictEqual(status === 0 || status === 1, true);
  614. done();
  615. });
  616. });
  617. });
  618. describe("Networking: Skin", function() {
  619. it("should not fail (uuid)", function(done) {
  620. helpers.get_skin(rid(), uuid, function(err, hash, status, img) {
  621. assert.strictEqual(err, null);
  622. done();
  623. });
  624. });
  625. });
  626. describe("Networking: Render", function() {
  627. it("should not fail (full body)", function(done) {
  628. helpers.get_render(rid(), uuid, 6, true, true, function(err, hash, img) {
  629. assert.ifError(err);
  630. done();
  631. });
  632. });
  633. it("should not fail (only head)", function(done) {
  634. helpers.get_render(rid(), uuid, 6, true, false, function(err, hash, img) {
  635. assert.ifError(err);
  636. done();
  637. });
  638. });
  639. });
  640. describe("Networking: Cape", function() {
  641. it("should not fail (possible cape)", function(done) {
  642. helpers.get_cape(rid(), uuid, function(err, hash, status, img) {
  643. assert.ifError(err);
  644. done();
  645. });
  646. });
  647. });
  648. describe("Errors", function() {
  649. before(function() {
  650. cache.get_redis().flushall();
  651. });
  652. it("uuid SHOULD be rate limited", function(done) {
  653. networking.get_profile(rid(), uuid, function() {
  654. networking.get_profile(rid(), uuid, function(err, profile) {
  655. assert.strictEqual(err.toString(), "HTTP: 429");
  656. assert.strictEqual(profile, null);
  657. done();
  658. });
  659. });
  660. });
  661. });
  662. after(function(done) {
  663. server.close(function() {
  664. cache.get_redis().quit();
  665. done();
  666. });
  667. });
  668. });