mirror of
https://github.com/clusterio/clusterio.git
synced 2026-11-12 07:04:52 +09:00
178 lines
7.0 KiB
JavaScript
178 lines
7.0 KiB
JavaScript
const assert = require("assert");
|
|
const child_process = require("child_process");
|
|
const functions = require("./interfacingFunctions");
|
|
const luamin = require("luamin");
|
|
const isFactorioCommand = require("./isFactorioCommand");
|
|
const nock = require("nock");
|
|
|
|
// sinon does weird prototype manipulation and so doen't need to be saved to anything.
|
|
require("mocha-sinon");
|
|
const sinon = require("sinon");
|
|
|
|
describe("inventoryImports/interfacingFunctions.js", function(){
|
|
describe("handleInventory(inventory, config)", function(){
|
|
let config = {
|
|
masterIP:"localhost",
|
|
masterPort:8080,
|
|
}
|
|
it("returns false if given invalid input", function(){
|
|
assert(functions.handleInventory("this is a string") === false, "when given strings it should return false and do nothing");
|
|
});
|
|
it("Sends post requests and outputs factorio commands", function(done){
|
|
let inventory = {
|
|
"players":{
|
|
"Danielv123":{
|
|
"inventory":{
|
|
"stone":12,
|
|
"iron-ore":120,
|
|
"raw-wood":10,
|
|
"iron-plate":8,
|
|
"steel-plate":480
|
|
},
|
|
"requestSlots":{
|
|
"iron-plate":100,
|
|
"steel-plate":480,
|
|
"raw-wood":20,
|
|
"bullshit":0,
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var scope = nock('http://localhost:8080')
|
|
.post('/api/remove', function(body){
|
|
// check that we are requesting the right things, () to convert to boolean
|
|
// 92 because 100 requested and 8 already in inventory
|
|
if(body.name == "iron-plate") assert(body.count == "92");
|
|
// nock wants us to return true if this is the correct body and we should reply
|
|
// if we return false we won't send a reply.
|
|
return true;
|
|
})
|
|
// nock destroys the endpoints after being hit once, this changes the number of hits required for destruction
|
|
.times(10)
|
|
// respond with JSON object instead of url query parameters
|
|
.reply(200,function(uri, req){
|
|
return req
|
|
},{
|
|
'Content-Type': 'application/json',
|
|
'Accept': 'application/json'
|
|
})
|
|
// nock logging statement .log((data) => console.log(data));
|
|
|
|
functions.handleInventory(inventory, config, callback);
|
|
function callback(x){
|
|
assert(x.includes(92) && x.includes("iron-plate"), "it should have included the items it was going to import");
|
|
assert(!x.includes("steel-plate"), "Inventory is already filled with steel so shouldn't be importing that");
|
|
assert(isFactorioCommand(x), "it should have returned a valid factorio command");
|
|
assert(x.includes('"Danielv123"'), "it should include the name of the player that will recieve the items");
|
|
done();
|
|
}
|
|
});
|
|
it("posts leftovers to master", function(done){
|
|
let inventory2 = {
|
|
"exports":{
|
|
"1":[
|
|
{"name":"iron-ore","count":1200},
|
|
{"name":"steel-plate","count":1337},
|
|
{"name":"copper-plate","count":0},
|
|
]
|
|
}
|
|
}
|
|
let timesRan = 0;
|
|
let callback = function(){
|
|
timesRan++
|
|
assert(timesRan <= 2, "placed more than 2 items, unexpeceted test result");
|
|
if(timesRan == 2){
|
|
done();
|
|
}
|
|
}
|
|
var scope = nock('http://localhost:8080')
|
|
.post('/api/place', function(body){
|
|
// check that we are requesting the right things
|
|
assert(body.name != "copper-plate", "copper plate should not be placed because it is 0");
|
|
assert(body.count > 0, "no need for placing 0 things");
|
|
assert(Number(body.count) != NaN, "count should be a number");
|
|
callback();
|
|
return true;
|
|
})
|
|
// nock destroys the endpoints after being hit once, this changes the number of hits required for destruction
|
|
.times(10)
|
|
.reply(200,"affirmative")
|
|
// if it tries using the nonexisting callback (argv 3) it will throw. It shoudln't.
|
|
assert.doesNotThrow(function(){
|
|
functions.handleInventory(inventory2, config);
|
|
}, "this here threw for some reason, remove assert.doesNotThrow for easier debugging of this issue");
|
|
});
|
|
});
|
|
describe("pollInventories(outputfile)", function(){
|
|
it("Returns a big factorio command as string", function(){
|
|
let x = functions.pollInventories("output.txt");
|
|
assert(typeof x == "string", "pollInventories() should always return a string");
|
|
assert(isFactorioCommand(x), "This is not a command factorio will accept, please prepend /c");
|
|
assert(x.length > 20, "LUA string seems to short, this ain't good");
|
|
});
|
|
it("Returns valid LUA", function(){
|
|
let x = functions.pollInventories("output.txt");
|
|
|
|
// remove string added to make factorio interpret as command
|
|
x = x.replace("/silent-command ","").replace("/c ","");
|
|
|
|
let y = false;
|
|
// luamin throws when it recieves something that is invalid LUA
|
|
assert.doesNotThrow(function(){
|
|
y = luamin.minify(x);
|
|
}, "Invalid LUA supplied");
|
|
assert(typeof y == "string", "luamin does not return string???");
|
|
assert(y.length > 20, "Minified LUA too short, something is up");
|
|
});
|
|
});
|
|
describe("insertItemsFromObject(object)", function(){
|
|
let testObject = {"copper-plate":100, "iron-ore":1337}
|
|
let playerName = "Danielv123"
|
|
it("Returns undefined if any of the parameters are missing", function(){
|
|
let x = functions.insertItemsFromObject();
|
|
assert(x === undefined);
|
|
|
|
let y = functions.insertItemsFromObject(testObject);
|
|
assert(y === undefined);
|
|
|
|
let z = functions.insertItemsFromObject(undefined, playerName);
|
|
assert(z === undefined);
|
|
});
|
|
it("Throws if player name is not a string", function(){
|
|
assert.throws(function(){
|
|
let x = functions.insertItemsFromObject(testObject, testObject);
|
|
}, "playerName is: 'object' instead of string!");
|
|
});
|
|
it("Returns a big factorio command as string", function(){
|
|
let x = functions.insertItemsFromObject(testObject, playerName);
|
|
|
|
assert(typeof x == "string", "LUA returned should be a string");
|
|
assert(x.length > 20, "LUA strings are quite long");
|
|
assert(isFactorioCommand(x), "This is not a command factorio will accept, please prepend /c");
|
|
});
|
|
it("The returned string is a valid factorio command", function(){
|
|
let x = functions.insertItemsFromObject(testObject, playerName);
|
|
|
|
assert(isFactorioCommand(x) == true);
|
|
});
|
|
});
|
|
describe("parseJsString(string) => object", function(){
|
|
it("converts a string with JS object notation to object", function(){
|
|
let x = functions.parseJsString("{hello:'thisAString!', yes:function(){return 'JS string!'}, not:'json'}");
|
|
assert(!!x == true, "Should under no circumstance return a falsey value, even !!{} is truthy");
|
|
assert(typeof x == "object", "parseJsString should return an object in this case");
|
|
assert(typeof x.yes == "function", "parseJsString is not JSON, so it should be able to contain functions");
|
|
});
|
|
it("*Tries* to avoid XSS attempts by throwing on certain symbols", function(){
|
|
assert.throws(function(){
|
|
let x = functions.parseJsString("{};throw 'fail'");
|
|
}, function(err) {
|
|
let error = err+""
|
|
/* istanbul ignore else */
|
|
if(error.includes('parseJsString might have gotten something that could be a xss attempt')){
|
|
return true;
|
|
}
|
|
}, "should throw when ; are passed because those are the simplest form of xss");
|
|
});
|
|
});
|
|
}); |