{"id":28396200,"url":"https://github.com/ssbc/scuttle-testbot","last_synced_at":"2025-07-08T22:05:51.735Z","repository":{"id":28788852,"uuid":"119327730","full_name":"ssbc/scuttle-testbot","owner":"ssbc","description":null,"archived":false,"fork":false,"pushed_at":"2023-11-07T13:18:57.000Z","size":828,"stargazers_count":10,"open_issues_count":3,"forks_count":4,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-06-09T16:22:56.582Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ssbc.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2018-01-29T03:38:56.000Z","updated_at":"2022-08-05T21:12:41.000Z","dependencies_parsed_at":"2023-01-14T09:35:25.106Z","dependency_job_id":"43d62b44-20f2-460f-87e5-b8b5ca5c181c","html_url":"https://github.com/ssbc/scuttle-testbot","commit_stats":null,"previous_names":[],"tags_count":34,"template":false,"template_full_name":null,"purl":"pkg:github/ssbc/scuttle-testbot","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssbc%2Fscuttle-testbot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssbc%2Fscuttle-testbot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssbc%2Fscuttle-testbot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssbc%2Fscuttle-testbot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ssbc","download_url":"https://codeload.github.com/ssbc/scuttle-testbot/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ssbc%2Fscuttle-testbot/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260959380,"owners_count":23088840,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2025-05-31T21:37:18.650Z","updated_at":"2025-07-08T22:05:51.722Z","avatar_url":"https://github.com/ssbc.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# scuttle-testbot\n\n\u003e Spins up an empty, temporary ssb-server that stores data in your temp folder\n\n\n## Usage\n\n```js\nconst TestBot = require('scuttle-testbot')\n\nconst piet = TestBot()\nconst content = { type: 'test', text: \"a test message\" }\n\npiet.db.create publish({ content }, (err, msg) =\u003e {\n  console.log(msg)\n  piet.close()\n})\n```\n\nOutputs:\n```\n{\n  key: '%FQ2auS8kVY9qPgpTWNY3le/JG5+IlO6JHDjBIQcSPSc=.sha256',\n  value: {\n    previous: null,\n    sequence: 1,\n    author: '@UreG2i/rf4mz7QAVOtg0OML5SRRB42Cwwl3D1ct0mbU=.ed25519',\n    timestamp: 1517190039755,\n    hash: 'sha256',\n    content: { type: 'test', content: 'a test message' },\n    signature: '0AxMJ7cKjHQ6vJDPkVNWcGND4gUwv2Z8barND5eha7ZXH/s5T0trFqcratIqzmhE3YJU2FY61Rf1S/Za2foLCA==.sig.ed25519'\n  },\n  timestamp: 1517190039758\n}\n```\n\n## API\n\n```js\nconst TestBot = require('scuttle-testbot')\n```\n\n### `TestBot(opts = {})`\n\nReturns a ssb-server instance.\n\nBy default, CreateTestSbot deletes an existing database of the same `name` before starting.\n\nValid `opts` keys include:\n- `opts.name` *String* (optional) (default: `ssb-test + Number(new Date)`)\n- `opts.path` *String* (optional) (default: `/tmp/${name}`, where `name` is the above)\n    - `~/.ssb-test`: Sets the database in `~/.ssb-test`\n- `opts.keys` *String* (optional) (default: scuttle-testbot generates a new set of random keys)\n    - you can create your own keys with `ssbKeys.generate()`\n- `opts.rimraf` (default: `true`)\n    - `false`: Don't delete an existing database before starting up.\n    - this is useful if you want to test state after stopping and starting a server. In this case you need to set the `name` and `keys` options to be connecting to the same log\n    - note `opts.startUnclean` is still accepted\n- `opts.db1` (default: `false`)\n    - uses `ssb-db2` by default, but if `true` will use `ssb-db`\n    - your can also switch to db1 by setting the ENV `SSB_DB1=true`\n- `opts.noDefaultUse` (default: `false`)\n    - if true then the testbot uses neither db1 nor db2 by default, leaving that up to you. Useful e.g. in case you want to control what plugins get imported along with db2.\n\n### `TestBot.use(plugin)`\n\n`CreateTestSbot.use` lets you add ssb-server plugins. `use` can be chained the same as the ssb-server api.\n\nExample:\n\n```js\nfunction Server (opts) {\n  const stack = Testbot\n    .use('ssb-master')\n    .use('ssb-tribes')\n\n  return stack(opts)\n}\n```\n\n### `Testbot.replicate({ from, to, feedId?, live?, name?, log? }, done)`\n\nReplicates data from one testbot to another, which is sometimes needed when you have functions\nwhich are only triggered by _another_ feedId, e.g. when I am added to a private group someone else started.\n\nExample:\n\n```js\nfunction Server (opts) {\n  const stack = require('scuttle-testbot')\n    // required for replicate\n    .use(require('ssb-db2/compat/feedstate'))\n    .use(require('ssb-db2/compat/history-stream'))\n\n  return stack(opts)\n}\nconst piet = Server({ name: 'piet' })\nconst katie = Server({ name: 'katie' })\n\nconst content = {\n  type: 'direct-message',\n  text: 'oh hey'\n}\n\npiet.db.create({ content }, (err, msg) =\u003e {\n  TestBot.replicate({ from: piet, to: katie }, (err) =\u003e {\n    katie.db.getMsg(msg.key, private: true }, (err, value) =\u003e {\n\n      console.log(value.content)\n      // should be same as content piet sent, if katie can decrypt\n\n      piet.close()\n      katie.close()\n    })\n  })\n})\n```\n\narguments:\n- `from` *SSB* - an ssb instance to be replicated from. This will replicate only this feeds messages (not everything in log)\n- `to` *SSB* - an ssb instance being replicate to.\n- `feedId` *String* (optional)\n    - the id of the feed you would like to replicate from one peer to another\n    - default: `from.id`\n- `live` *Boolean* (optional)- whether or not to keep replication running (default: `false`).\n    - provide a custom logging function, or disable the logging by setting this `false`\n    - default: `console.log`\n- `name` *Function* (optional) - makes logged output easier to read by allowing you to replace feedIds with human readable names\n    ```js\n    // example\n    const name = (feedId) =\u003e {\n      if (feedId === piet.id) return 'piet'\n      if (feedId === katie.id) return 'katie'\n    }\n    ```\n    - alternatively, if an instance has a \"name\" property, then that will be used, e.g.\n        ```js\n        const piet = TestBot()\n        piet.name = 'piet'\n        ```\n        ```js\n        const piet = TestBot({ name: 'katie ' })\n        ```\n- `log` *Function|false* (optional)\n- `done` *Function* - an optional callback which is triggered when the replication is complete or if there is an error.\n    - If `live === true` this will ony be called on an error. Signature `done (err) { ... }`\n\nAlso supports promise style.\n```js\n  await TestBot.replicate({ from: piet, to: katie })\n```\nThis requires that `live: false`\n\nUnder the hood this function just uses `createHistoryStream` directly from one peer to another\n\n### `Testbot.connect(peers, { names, friends }, done)`\n\nConnects all listed peers.\n\nExample:\n\n```js\nconst crypto = require('crypto')\n\nfunction Server (opts) {\n  const stack = require('scuttle-testbot')\n    .use('ssb-conn')\n    .use('ssb-friends') // only needed if opts.friends\n\n  return stack(opts)\n}\n\nconst caps = { shs: crypto.randomBytes(32).toString('base64') }\nconst piet = Server({ caps, name: 'piet' })\nconst katie = Server({ caps, name: 'katie' })\n// all peers need to have same caps to be able to connect to each other\n\nTestbot.connect([piet, katie], { friends: true }, (err) =\u003e {\n  // as friends: true - piet now follows katie + vice versa\n  // and there is a connection live between these two\n\n  piet.close()\n  katie.close()\n})\n```\n\narguments:\n- `peers` *Array*\n    - a collection of ssb instances which will all be connected to one another\n    - NOTE: by default scuttle-testbot creates random caps for each instance. You need to overide this as in example to form connections\n\n- `opts` *Object*\n    - `opts.friends` *Boolean* (optional)\n        - if true will get each peer to publish a follow for each other peer in the list\n        - NOTE: this requires `ssb-friends` to be installed\n        - default: `false`\n    - `opts.name` *Function* (optional) - makes logged output easier to read by allowing you to replace feedIds with human readable names\n        ```js\n        // example\n        const name = (feedId) =\u003e {\n          if (feedId === piet.id) return 'piet'\n          if (feedId === katie.id) return 'katie'\n        }\n        ```\n    - `opts.log` *Function|false* (optional)\n        - provide a custom logging function, or disable the logging by setting this `false`\n        - default: `console.log`\n\n- `done` *Function* - an optional callback which is triggered when the replication is complete or if there is an error.\n    - If `live === true` this will ony be called on an error. Signature `done (err) { ... }`\n\nUnder the hood this just uses `createHistoryStream` directly from one peer to another\n\nAlso supports promise style.\n```js\n  await Testbot.connect([piet, katie], { friends: true })\n```\n\n### `TestBot.colorLog(obj, ...)`\n\nLike `console.log(JSON.stringify(obj, null, 2))` but also:\n- colorises the cipherlinks based on value - makes it easier to pattern-match across messages\n- removes quotes-marks from keys - easier to read\n- takes multiiple input values\n\n\n## License\n\nMIT\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssbc%2Fscuttle-testbot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fssbc%2Fscuttle-testbot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fssbc%2Fscuttle-testbot/lists"}