Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions .github/workflows/integration-tests.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Integration Tests

on:
workflow_dispatch:
inputs:
rpc_url:
description: 'Steem RPC node URL to test'
required: false
default: 'https://api2.steemyy.com'
pull_request:
branches: [ main ]

jobs:
integration:
name: Run integration tests against Steem RPC node
runs-on: ubuntu-latest

steps:
- name: Checkout repository
uses: actions/checkout@v4

- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

- name: Install project dependencies
run: npm ci

- name: Install Steem SDKs for integration tests
run: npm install --no-save [email protected] [email protected]

- name: Run integration tests
env:
STEEM_RPC_URL: ${{ github.event.inputs.rpc_url || 'https://api2.steemyy.com' }}
run: node tests/integration-tests.js
185 changes: 185 additions & 0 deletions tests/integration-tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,185 @@
#!/usr/bin/env node

const API_URL = process.env.STEEM_RPC_URL || "https://api2.steemyy.com";

Check failure on line 3 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'process' is not defined

Check failure on line 3 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'process' is not defined

if (typeof globalThis.log === "undefined") {
globalThis.log = (...args) => console.log(...args);
}

const steemModule = await import("steem").then((m) => m.default ?? m);
const dsteemModule = await import("dsteem").then((m) => m.default ?? m);
const steem = steemModule;
const dsteem = dsteemModule;

steem.api.setOptions({ url: API_URL });
log(`Using Steem Node ${steem.api.options.url}`);

Check failure on line 15 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 15 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

steem.api.getAccounts(["justyy", "ety001"], function (err, result) {
if (!err) {
for (let i = 0; i < result.length; ++i) {
let reputation = result[i].reputation;
let formatted_rep = steem.formatter.reputation(reputation);
log(result[i].name + "'s Reputation is " + formatted_rep);

Check failure on line 22 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 22 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
}
} else {
log("Steem API Error:", err);

Check failure on line 25 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 25 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
}
});

let username = "test";
let password = "password";
log(dsteem.PrivateKey.fromLogin(username, password, "owner").createPublic());

Check failure on line 31 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 31 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

function steemCall(method, params) {
return new Promise((resolve, reject) => {
steem.api[method](...params, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
}

function steemRpcCall(method, params) {
return new Promise((resolve, reject) => {
steem.api.call(method, params, (err, result) => {
if (err) reject(err);
else resolve(result);
});
});
}

const tests = [];
function addTest(name, fn) {
tests.push({ name, fn });
}

addTest("steem.api.getAccounts", async () => {
const accounts = await steemCall("getAccounts", [["justyy"]]);
if (accounts && accounts[0] && accounts[0].name === "justyy") return;
throw new Error("Account not returned");
});

addTest("steem.formatter.reputation", async () => {
const rep = steem.formatter.reputation("352352352352");
if (typeof rep === "number") return;
throw new Error("Formatter did not return number");
});

addTest("steem.api.getDynamicGlobalProperties", async () => {
const props = await steemCall("getDynamicGlobalProperties", []);
if (props && props.head_block_number) return;
throw new Error("Missing head_block_number");
});

addTest("steem.api.getChainProperties", async () => {
await steemCall("getChainProperties", []);
});

addTest("steem.api.getConfig", async () => {
await steemCall("getConfig", []);
});

addTest("steem.api.getRewardFund", async () => {
const fund = await steemCall("getRewardFund", ["post"]);
if (fund && fund.reward_balance) return;
throw new Error("Reward fund missing");
});

addTest("steem.api.getCurrentMedianHistoryPrice", async () => {
const price = await steemCall("getCurrentMedianHistoryPrice", []);
if (price && price.base) return;
throw new Error("Missing price");
});

addTest("steem.api.getAccountHistory", async () => {
const hist = await steemCall("getAccountHistory", ["justyy", -1, 1]);
if (Array.isArray(hist)) return;
throw new Error("History not an array");
});

addTest("steem.api.getDiscussionsByCreated", async () => {
const posts = await steemCall("getDiscussionsByCreated", [{ tag: "steem", limit: 1 }]);
if (Array.isArray(posts)) return;
throw new Error("Posts not array");
});

addTest("steem.api.getTrendingTags", async () => {
const tags = await steemCall("getTrendingTags", ["steem", 1]);
if (Array.isArray(tags)) return;
throw new Error("Tags not array");
});

addTest("steem.api.getBlock", async () => {
const data = await steemCall("getBlock", [102496700]);
if (data.previous === "061bf9bb3389a026b4e07f3b28aaa24d87c639e1") return;
throw new Error("getBlock return error");
});

const dynamicBlockTest = new Promise((resolve, reject) => {
steem.api.getDynamicGlobalProperties((err, result) => {
if (err) {
console.error(err);
reject(err);
return;
}

const latestBlock = result.head_block_number;
log("Latest block height:", latestBlock);

Check failure on line 127 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 127 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
addTest(`steem.api.getBlock (latest block height ${latestBlock})`, async () => {
const data = await steemCall("getBlock", [latestBlock]);
log(data);

Check failure on line 130 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 130 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
if (data.previous && data.witness && data.timestamp && data.witness_signature) return;
throw new Error(`getBlock (latest block height: ${latestBlock}) return error`);
});

resolve();
});
});

addTest("Negative invalid method name", async () => {
try {
await steemRpcCall("NON_EXISTENT_METHOD", {});
} catch {
return;
}
throw new Error("Invalid method unexpectedly succeeded");
});

addTest("Negative invalid history range", async () => {
try {
await steemCall("getAccountHistory", ["justyy", 999999999, -5]);
} catch {
return;
}
throw new Error("Invalid history range unexpectedly succeeded");
});

async function runTests() {
log("Starting SteemJS test suite...");

Check failure on line 158 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 158 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
let failures = 0;

for (const t of tests) {
try {
await t.fn();
log(`✅Test passed: ${t.name}`);

Check failure on line 164 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 164 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
} catch (err) {
failures += 1;
log(`❌Test failed: ${t.name} (${err.message || err})`);

Check failure on line 167 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined

Check failure on line 167 in tests/integration-tests.js

View workflow job for this annotation

GitHub Actions / lint

'log' is not defined
}
}

log("Finished.");

if (failures > 0) {
throw new Error(`${failures} integration test(s) failed`);
}
}

try {
await dynamicBlockTest;
await runTests();
log(`SteemJs Version: ${steem.version}`);
} catch (err) {
console.error(err);
process.exit(1);
}
Loading