diff --git a/app/models/contribution.js b/app/models/contribution.js index 1b89125..3fde117 100644 --- a/app/models/contribution.js +++ b/app/models/contribution.js @@ -1,6 +1,5 @@ import EmberObject, { computed } from '@ember/object'; import { isEmpty, isPresent } from '@ember/utils'; -import bignumber from 'kredits-web/utils/cps/bignumber'; import moment from 'moment'; export default EmberObject.extend({ @@ -9,11 +8,15 @@ export default EmberObject.extend({ id: null, contributorId: null, amount: null, - confirmedAt: bignumber('confirmedAtBlock', 'toNumber'), + confirmedAt: null, vetoed: null, ipfsHash: null, - creatorAccount: null, + // contributor model instance + contributor: null, + + // TODO contributor who submitted the contribution + // submittedBy: null, // IPFS kind: null, @@ -22,7 +25,6 @@ export default EmberObject.extend({ url: null, date: null, time: null, - ipfsData: '', pendingTx: null, @@ -41,6 +43,10 @@ export default EmberObject.extend({ hasPendingChanges: computed('pendingTx', function() { return isPresent(this.pendingTx); - }) + }), + + serialize () { + return JSON.stringify(this); + } }); diff --git a/app/models/contributor.js b/app/models/contributor.js index 76baf08..9485d0f 100644 --- a/app/models/contributor.js +++ b/app/models/contributor.js @@ -1,14 +1,12 @@ import EmberObject from '@ember/object'; -import bignumber from 'kredits-web/utils/cps/bignumber'; -import kreditsValue from 'kredits-web/utils/cps/kredits'; export default EmberObject.extend({ // Contract - id: bignumber('idRaw', 'toString'), + id: null, account: null, - balance: kreditsValue('balanceRaw'), - totalKreditsEarned: bignumber('totalKreditsEarnedRaw', 'toNumber'), - contributionsCount: bignumber('contributionsCountRaw', 'toNumber'), + balance: 0, + totalKreditsEarned: 0, + contributionsCount: 0, isCore: false, ipfsHash: null, @@ -20,6 +18,9 @@ export default EmberObject.extend({ github_uid: null, wiki_username: null, zoom_display_name: null, - ipfsData: '' + + serialize () { + return JSON.stringify(this); + } }); diff --git a/app/routes/application.js b/app/routes/application.js index 85eabe9..b5fdfc9 100644 --- a/app/routes/application.js +++ b/app/routes/application.js @@ -1,5 +1,6 @@ import { inject as service } from '@ember/service'; import Route from '@ember/routing/route'; +import { schedule } from '@ember/runloop'; export default Route.extend({ kredits: service(), @@ -21,6 +22,12 @@ export default Route.extend({ return this.kredits.loadInitialData() .then(() => { this.kredits.addContractEventHandlers(); + }) + .then(() => { + if (this.kredits.contributorsNeedFetch) { + schedule('afterRender', this.kredits, this.kredits.fetchContributors); + } + schedule('afterRender', this.kredits, this.kredits.fetchContributions); }); } }); diff --git a/app/services/browser-cache.js b/app/services/browser-cache.js new file mode 100644 index 0000000..29232dd --- /dev/null +++ b/app/services/browser-cache.js @@ -0,0 +1,27 @@ +import Service from '@ember/service'; +import * as localforage from 'localforage'; +import config from 'kredits-web/config/environment'; + +function createStore(name) { + const networkName = config.web3RequiredNetwork || 'custom'; + return localforage.createInstance({ name: `kredits:${networkName}:${name}` }); +} + +export default class BrowserCacheService extends Service { + + constructor() { + super(...arguments); + this.stores = { + contributors: createStore('contributors'), + contributions: createStore('contributions') + } + } + + get contributors() { + return this.stores.contributors; + } + + get contributions() { + return this.stores.contributions; + } +} diff --git a/app/services/kredits.js b/app/services/kredits.js index bd1b0f5..c33b347 100644 --- a/app/services/kredits.js +++ b/app/services/kredits.js @@ -7,8 +7,11 @@ import EmberObject from '@ember/object'; import { computed } from '@ember/object'; import { alias, notEmpty } from '@ember/object/computed'; import { isEmpty, isPresent } from '@ember/utils'; +import { inject as service } from '@ember/service'; import groupBy from 'kredits-web/utils/group-by'; +import processContributorData from 'kredits-web/utils/process-contributor-data'; +import processContributionData from 'kredits-web/utils/process-contribution-data'; import formatKredits from 'kredits-web/utils/format-kredits'; import config from 'kredits-web/config/environment'; @@ -17,6 +20,9 @@ import Contribution from 'kredits-web/models/contribution' export default Service.extend({ + browserCache: service(), + contributorsNeedFetch: false, + currentBlock: null, currentUserAccounts: null, // default to not having an account. this is the wen web3 is loaded. currentUser: null, @@ -169,12 +175,23 @@ export default Service.extend({ .then(total => total.toNumber()); }), + async loadInitialData () { + const numCachedContributors = await this.browserCache.contributors.length(); + if (numCachedContributors > 0) { + await this.loadContributorsFromCache(); + this.set('contributorsNeedFetch', true); + } else { + await this.fetchContributors(); + } - loadInitialData () { - return this.getContributors() - .then(contributors => this.contributors.pushObjects(contributors)) - .then(() => this.getContributions()) - .then(contributions => this.contributions.pushObjects(contributions)) + const numCachedContributions = await this.browserCache.contributions.length(); + if (numCachedContributions > 0) { + await this.loadContributionsFromCache(); + } else { + await this.fetchContributions({ page: { size: 30 } }); + } + + return Promise.resolve(); }, addContributor (attributes) { @@ -205,15 +222,39 @@ export default Service.extend({ }); }, - getContributors () { + fetchContributors () { + console.debug(`[kredits] Fetching all contributors from the network`); return this.kredits.Contributor.all() .then(contributors => { - return contributors.map(contributor => { - return Contributor.create(contributor); + return contributors.map(data => { + const contributor = Contributor.create(processContributorData(data)); + const loadedContributor = this.contributors.findBy('id', contributor.id); + if (loadedContributor) { this.contributors.removeObject(loadedContributor); } + this.contributors.pushObject(contributor); + return contributor; }); + }) + .then(() => { + return this.cacheLoadedContributors(); }); }, + async cacheLoadedContributors () { + for (const c of this.contributors) { + await this.browserCache.contributors.setItem(c.id, c.serialize()); + } + console.debug(`[kredits] Cached ${this.contributors.length} contributors in browser storage`); + return Promise.resolve(); + }, + + async loadContributorsFromCache () { + return this.browserCache.contributors.iterate((value/*, key , iterationNumber */) => { + this.contributors.pushObject(Contributor.create(JSON.parse(value))); + }).then((/* result */) => { + console.debug(`[kredits] Loaded ${this.contributors.length} contributors from cache`); + }); + }, + addContribution (attributes) { console.debug('[kredits] add contribution', attributes); @@ -229,16 +270,45 @@ export default Service.extend({ }); }, - getContributions () { - return this.kredits.Contribution.all({page: {size: 200}}) + fetchContributions (options = { page: { size: 200 } }) { + console.debug(`[kredits] Fetching contributions from the network`); + return this.kredits.Contribution.all(options) .then(contributions => { - return contributions.map(contribution => { - contribution.contributor = this.contributors.findBy('id', contribution.contributorId.toString()); - return Contribution.create(contribution); + return contributions.map(data => { + const contribution = Contribution.create(processContributionData(data)); + contribution.set('contributor', this.contributors.findBy('id', data.contributorId.toString())); + const loadedContribution = this.contributions.findBy('id', contribution.id); + if (loadedContribution) { this.contributions.removeObject(loadedContribution); } + this.contributions.pushObject(contribution); + return contribution; + }); + }) + .then(contributions => { + const cacheWrites = contributions.map(c => { + return this.browserCache.contributions.setItem(c.id.toString(), c.serialize()); + }); + return Promise.all(cacheWrites).then(() => { + console.debug(`[kredits] Cached ${contributions.length} contributions in browser storage`); }); }); }, + async cacheLoadedContributions () { + for (const c of this.contributions) { + await this.browserCache.contributions.setItem(c.id, c.serialize()); + } + console.debug(`[kredits] Cached ${this.contributions.length} contributions in browser storage`); + return Promise.resolve(); + }, + + async loadContributionsFromCache () { + return this.browserCache.contributions.iterate((value/*, key , iterationNumber */) => { + this.contributions.pushObject(Contribution.create(JSON.parse(value))); + }).then((/* result */) => { + console.debug(`[kredits] Loaded ${this.contributions.length} contributions from cache`); + }); + }, + veto (contributionId) { console.debug('[kredits] veto against', contributionId); const contribution = this.contributions.findBy('id', contributionId); diff --git a/app/utils/cps/bignumber.js b/app/utils/cps/bignumber.js deleted file mode 100644 index 5646820..0000000 --- a/app/utils/cps/bignumber.js +++ /dev/null @@ -1,20 +0,0 @@ -import { computed } from '@ember/object'; -import ethers from 'ethers'; - -export default function(dependentKey, converterMethod) { - return computed(dependentKey, { - get () { - let value = this.get(dependentKey); - if (value && ethers.utils.BigNumber.isBigNumber(value)) { - return value[converterMethod](); - } else { - return value; - } - }, - set (key, value) { - const bnValue = ethers.utils.bigNumberify(value); - this.set(dependentKey, bnValue); - return bnValue[converterMethod](); - } - }); -} diff --git a/app/utils/cps/kredits.js b/app/utils/cps/kredits.js deleted file mode 100644 index 8f6eb3e..0000000 --- a/app/utils/cps/kredits.js +++ /dev/null @@ -1,17 +0,0 @@ -import { computed } from '@ember/object'; -import ethers from 'ethers'; -import formatKredits from 'kredits-web/utils/format-kredits'; - -export default function(dependentKey, options = {}) { - return computed(dependentKey, { - get () { - const value = this.get(dependentKey); - return formatKredits(value, options); - }, - set (key, value) { - const bnValue = ethers.utils.bigNumberify(value); - this.set(dependentKey, bnValue); - return formatKredits(bnValue, options); - } - }); -} diff --git a/app/utils/process-contribution-data.js b/app/utils/process-contribution-data.js new file mode 100644 index 0000000..0a3f18d --- /dev/null +++ b/app/utils/process-contribution-data.js @@ -0,0 +1,21 @@ +export default function processContributionData(data) { + const processed = {} + + if (data.confirmedAtBlock && (typeof data.confirmedAtBlock.toNumber === 'function')) { + processed.confirmedAt = data.confirmedAtBlock.toNumber(); + } else if (data.confirmedAt !== 'undefined') { + processed.confirmedAt = data.confirmedAt; + } + + const otherProperties = [ + 'id', 'contributorId', 'amount', 'vetoed', + 'ipfsHash', 'kind', 'description', 'details', + 'url', 'date', 'time', 'pendingTx' + ]; + + otherProperties.forEach(prop => { + processed[prop] = data[prop]; + }); + + return processed; +} diff --git a/app/utils/process-contributor-data.js b/app/utils/process-contributor-data.js new file mode 100644 index 0000000..48074fb --- /dev/null +++ b/app/utils/process-contributor-data.js @@ -0,0 +1,19 @@ +export default function processContributorData(data) { + const processed = { + id: data.id.toString(), + balance: data.balanceInt, + totalKreditsEarned: data.totalKreditsEarned, + contributionsCount: data.contributionsCount?.toNumber() + } + + const otherProperties = [ + 'account', 'accounts', 'ipfsHash', 'isCore', 'kind', 'name', 'url', + 'github_username', 'github_uid', 'wiki_username', 'zoom_display_name' + ]; + + otherProperties.forEach(prop => { + processed[prop] = data[prop]; + }); + + return processed; +} diff --git a/package-lock.json b/package-lock.json index 8c36079..aaac05a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -15545,6 +15545,12 @@ "integrity": "sha512-MzbUSahkTW1u7JpKKjY7LCARd1fU5W2rLdxlM4kdkayuCwZImjkpluF9CM1aLewYJguPDqewLam18Y6AU69A8A==", "dev": true }, + "immediate": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", + "dev": true + }, "import-fresh": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.2.1.tgz", @@ -16768,6 +16774,15 @@ } } }, + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "dev": true, + "requires": { + "immediate": "~3.0.5" + } + }, "linkify-it": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/linkify-it/-/linkify-it-2.2.0.tgz", @@ -16849,6 +16864,15 @@ "integrity": "sha512-9M2KvGT6duzGMgkOcTkWb+PR/Q2Oe54df/tLgHGVmFpAmtqJ553xJh6N63iFYI2yjo2PeJXbS5skHi/QpJq4vA==", "dev": true }, + "localforage": { + "version": "1.7.3", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.3.tgz", + "integrity": "sha512-1TulyYfc4udS7ECSBT2vwJksWbkwwTX8BzeUIiq8Y07Riy7bDAAnxDaPU/tWyOVmQAcWJIEIFP9lPfBGqVoPgQ==", + "dev": true, + "requires": { + "lie": "3.1.1" + } + }, "locate-character": { "version": "2.0.5", "resolved": "https://registry.npmjs.org/locate-character/-/locate-character-2.0.5.tgz", diff --git a/package.json b/package.json index e87aa72..3ec4ec6 100644 --- a/package.json +++ b/package.json @@ -67,6 +67,7 @@ "kosmos-schemas": "^2.1.0", "kredits-contracts": "^5.5.0", "loader.js": "^4.7.0", + "localforage": "^1.7.3", "ndjson": "github:hugomrdias/ndjson#feat/readable-stream3", "npm-run-all": "^4.1.5", "qunit-dom": "^1.2.0", diff --git a/tests/fixtures/contribution-data.js b/tests/fixtures/contribution-data.js new file mode 100644 index 0000000..38aa602 --- /dev/null +++ b/tests/fixtures/contribution-data.js @@ -0,0 +1,391 @@ +export default { + "0": 511, + "1": 1, + "2": 500, + "3": false, + "4": "0x4e918f5b0199311fffa2c930cd6ec8e82de65d4caa5a84e6e850c9c956a92ed7", + "5": 18, + "6": 32, + "7": { + "_hex": "0x64bf54" + }, + "8": true, + "9": false, + "id": 511, + "contributorId": 1, + "amount": 500, + "claimed": false, + "hashDigest": "0x4e918f5b0199311fffa2c930cd6ec8e82de65d4caa5a84e6e850c9c956a92ed7", + "hashFunction": 18, + "hashSize": 32, + "confirmedAtBlock": { + "_hex": "0x64bf54", + "toNumber": function() { return 6602580; } + }, + "exists": true, + "vetoed": false, + "ipfsHash": "QmTdMF6u8TBNp2riP43m8p49VxMasS73Qbdj3fSo2V8SJ2", + "date": "2020-05-27", + "time": "14:22:41Z", + "kind": "dev", + "description": "67P/kredits-contracts: Chore/dependency updates", + "details": { + "url": "https://api.github.com/repos/67P/kredits-contracts/pulls/196", + "id": 423708597, + "node_id": "MDExOlB1bGxSZXF1ZXN0NDIzNzA4NTk3", + "html_url": "https://github.com/67P/kredits-contracts/pull/196", + "diff_url": "https://github.com/67P/kredits-contracts/pull/196.diff", + "patch_url": "https://github.com/67P/kredits-contracts/pull/196.patch", + "issue_url": "https://api.github.com/repos/67P/kredits-contracts/issues/196", + "number": 196, + "state": "closed", + "locked": false, + "title": "Chore/dependency updates", + "user": { + "login": "bumi", + "id": 318, + "node_id": "MDQ6VXNlcjMxOA==", + "avatar_url": "https://avatars1.githubusercontent.com/u/318?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bumi", + "html_url": "https://github.com/bumi", + "followers_url": "https://api.github.com/users/bumi/followers", + "following_url": "https://api.github.com/users/bumi/following{/other_user}", + "gists_url": "https://api.github.com/users/bumi/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bumi/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bumi/subscriptions", + "organizations_url": "https://api.github.com/users/bumi/orgs", + "repos_url": "https://api.github.com/users/bumi/repos", + "events_url": "https://api.github.com/users/bumi/events{/privacy}", + "received_events_url": "https://api.github.com/users/bumi/received_events", + "type": "User", + "site_admin": false + }, + "body": "Updated the npm dependencies to the latest versions\r\n\r\nmissing: \r\n- [ ] ipfs-http-client - which has some breaking changes. I think it is not a problem for us but needs to be tested\r\n- [ ] solhint - wich also has a breaking change and now needs pretier for codestyle linting. I did not want that additional dependency now. Also we probably needs to improve the linting of the solidity files\r\n", + "created_at": "2020-05-27T08:57:43Z", + "updated_at": "2020-05-27T14:22:41Z", + "closed_at": "2020-05-27T14:22:41Z", + "merged_at": "2020-05-27T14:22:41Z", + "merge_commit_sha": "2b99593699999756f0f49549873f2cfb679d3f4c", + "assignee": null, + "assignees": [], + "requested_reviewers": [], + "requested_teams": [], + "labels": [ + { + "id": 923540870, + "node_id": "MDU6TGFiZWw5MjM1NDA4NzA=", + "url": "https://api.github.com/repos/67P/kredits-contracts/labels/kredits-1", + "name": "kredits-1", + "color": "008080", + "default": false, + "description": "" + } + ], + "milestone": null, + "draft": false, + "commits_url": "https://api.github.com/repos/67P/kredits-contracts/pulls/196/commits", + "review_comments_url": "https://api.github.com/repos/67P/kredits-contracts/pulls/196/comments", + "review_comment_url": "https://api.github.com/repos/67P/kredits-contracts/pulls/comments{/number}", + "comments_url": "https://api.github.com/repos/67P/kredits-contracts/issues/196/comments", + "statuses_url": "https://api.github.com/repos/67P/kredits-contracts/statuses/606350eb5e173a38a8c5f1b3faf30aa03224065c", + "head": { + "label": "67P:chore/dependency-updates", + "ref": "chore/dependency-updates", + "sha": "606350eb5e173a38a8c5f1b3faf30aa03224065c", + "user": { + "login": "67P", + "id": 9769503, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=", + "avatar_url": "https://avatars1.githubusercontent.com/u/9769503?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/67P", + "html_url": "https://github.com/67P", + "followers_url": "https://api.github.com/users/67P/followers", + "following_url": "https://api.github.com/users/67P/following{/other_user}", + "gists_url": "https://api.github.com/users/67P/gists{/gist_id}", + "starred_url": "https://api.github.com/users/67P/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/67P/subscriptions", + "organizations_url": "https://api.github.com/users/67P/orgs", + "repos_url": "https://api.github.com/users/67P/repos", + "events_url": "https://api.github.com/users/67P/events{/privacy}", + "received_events_url": "https://api.github.com/users/67P/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 124804465, + "node_id": "MDEwOlJlcG9zaXRvcnkxMjQ4MDQ0NjU=", + "name": "kredits-contracts", + "full_name": "67P/kredits-contracts", + "private": false, + "owner": { + "login": "67P", + "id": 9769503, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=", + "avatar_url": "https://avatars1.githubusercontent.com/u/9769503?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/67P", + "html_url": "https://github.com/67P", + "followers_url": "https://api.github.com/users/67P/followers", + "following_url": "https://api.github.com/users/67P/following{/other_user}", + "gists_url": "https://api.github.com/users/67P/gists{/gist_id}", + "starred_url": "https://api.github.com/users/67P/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/67P/subscriptions", + "organizations_url": "https://api.github.com/users/67P/orgs", + "repos_url": "https://api.github.com/users/67P/repos", + "events_url": "https://api.github.com/users/67P/events{/privacy}", + "received_events_url": "https://api.github.com/users/67P/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/67P/kredits-contracts", + "description": "Smart contracts and JS API for Kosmos Kredits", + "fork": false, + "url": "https://api.github.com/repos/67P/kredits-contracts", + "forks_url": "https://api.github.com/repos/67P/kredits-contracts/forks", + "keys_url": "https://api.github.com/repos/67P/kredits-contracts/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/67P/kredits-contracts/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/67P/kredits-contracts/teams", + "hooks_url": "https://api.github.com/repos/67P/kredits-contracts/hooks", + "issue_events_url": "https://api.github.com/repos/67P/kredits-contracts/issues/events{/number}", + "events_url": "https://api.github.com/repos/67P/kredits-contracts/events", + "assignees_url": "https://api.github.com/repos/67P/kredits-contracts/assignees{/user}", + "branches_url": "https://api.github.com/repos/67P/kredits-contracts/branches{/branch}", + "tags_url": "https://api.github.com/repos/67P/kredits-contracts/tags", + "blobs_url": "https://api.github.com/repos/67P/kredits-contracts/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/67P/kredits-contracts/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/67P/kredits-contracts/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/67P/kredits-contracts/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/67P/kredits-contracts/statuses/{sha}", + "languages_url": "https://api.github.com/repos/67P/kredits-contracts/languages", + "stargazers_url": "https://api.github.com/repos/67P/kredits-contracts/stargazers", + "contributors_url": "https://api.github.com/repos/67P/kredits-contracts/contributors", + "subscribers_url": "https://api.github.com/repos/67P/kredits-contracts/subscribers", + "subscription_url": "https://api.github.com/repos/67P/kredits-contracts/subscription", + "commits_url": "https://api.github.com/repos/67P/kredits-contracts/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/67P/kredits-contracts/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/67P/kredits-contracts/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/67P/kredits-contracts/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/67P/kredits-contracts/contents/{+path}", + "compare_url": "https://api.github.com/repos/67P/kredits-contracts/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/67P/kredits-contracts/merges", + "archive_url": "https://api.github.com/repos/67P/kredits-contracts/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/67P/kredits-contracts/downloads", + "issues_url": "https://api.github.com/repos/67P/kredits-contracts/issues{/number}", + "pulls_url": "https://api.github.com/repos/67P/kredits-contracts/pulls{/number}", + "milestones_url": "https://api.github.com/repos/67P/kredits-contracts/milestones{/number}", + "notifications_url": "https://api.github.com/repos/67P/kredits-contracts/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/67P/kredits-contracts/labels{/name}", + "releases_url": "https://api.github.com/repos/67P/kredits-contracts/releases{/id}", + "deployments_url": "https://api.github.com/repos/67P/kredits-contracts/deployments", + "created_at": "2018-03-11T22:11:45Z", + "updated_at": "2020-05-07T08:08:30Z", + "pushed_at": "2020-05-27T14:22:41Z", + "git_url": "git://github.com/67P/kredits-contracts.git", + "ssh_url": "git@github.com:67P/kredits-contracts.git", + "clone_url": "https://github.com/67P/kredits-contracts.git", + "svn_url": "https://github.com/67P/kredits-contracts", + "homepage": "https://wiki.kosmos.org/Kredits", + "size": 2289, + "stargazers_count": 3, + "watchers_count": 3, + "language": "JavaScript", + "has_issues": true, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 3, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 35, + "license": null, + "forks": 3, + "open_issues": 35, + "watchers": 3, + "default_branch": "master" + } + }, + "base": { + "label": "67P:master", + "ref": "master", + "sha": "31c29ab6d0bf0d4fc4c27dbc1ecbb3d27659cf7e", + "user": { + "login": "67P", + "id": 9769503, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=", + "avatar_url": "https://avatars1.githubusercontent.com/u/9769503?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/67P", + "html_url": "https://github.com/67P", + "followers_url": "https://api.github.com/users/67P/followers", + "following_url": "https://api.github.com/users/67P/following{/other_user}", + "gists_url": "https://api.github.com/users/67P/gists{/gist_id}", + "starred_url": "https://api.github.com/users/67P/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/67P/subscriptions", + "organizations_url": "https://api.github.com/users/67P/orgs", + "repos_url": "https://api.github.com/users/67P/repos", + "events_url": "https://api.github.com/users/67P/events{/privacy}", + "received_events_url": "https://api.github.com/users/67P/received_events", + "type": "Organization", + "site_admin": false + }, + "repo": { + "id": 124804465, + "node_id": "MDEwOlJlcG9zaXRvcnkxMjQ4MDQ0NjU=", + "name": "kredits-contracts", + "full_name": "67P/kredits-contracts", + "private": false, + "owner": { + "login": "67P", + "id": 9769503, + "node_id": "MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=", + "avatar_url": "https://avatars1.githubusercontent.com/u/9769503?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/67P", + "html_url": "https://github.com/67P", + "followers_url": "https://api.github.com/users/67P/followers", + "following_url": "https://api.github.com/users/67P/following{/other_user}", + "gists_url": "https://api.github.com/users/67P/gists{/gist_id}", + "starred_url": "https://api.github.com/users/67P/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/67P/subscriptions", + "organizations_url": "https://api.github.com/users/67P/orgs", + "repos_url": "https://api.github.com/users/67P/repos", + "events_url": "https://api.github.com/users/67P/events{/privacy}", + "received_events_url": "https://api.github.com/users/67P/received_events", + "type": "Organization", + "site_admin": false + }, + "html_url": "https://github.com/67P/kredits-contracts", + "description": "Smart contracts and JS API for Kosmos Kredits", + "fork": false, + "url": "https://api.github.com/repos/67P/kredits-contracts", + "forks_url": "https://api.github.com/repos/67P/kredits-contracts/forks", + "keys_url": "https://api.github.com/repos/67P/kredits-contracts/keys{/key_id}", + "collaborators_url": "https://api.github.com/repos/67P/kredits-contracts/collaborators{/collaborator}", + "teams_url": "https://api.github.com/repos/67P/kredits-contracts/teams", + "hooks_url": "https://api.github.com/repos/67P/kredits-contracts/hooks", + "issue_events_url": "https://api.github.com/repos/67P/kredits-contracts/issues/events{/number}", + "events_url": "https://api.github.com/repos/67P/kredits-contracts/events", + "assignees_url": "https://api.github.com/repos/67P/kredits-contracts/assignees{/user}", + "branches_url": "https://api.github.com/repos/67P/kredits-contracts/branches{/branch}", + "tags_url": "https://api.github.com/repos/67P/kredits-contracts/tags", + "blobs_url": "https://api.github.com/repos/67P/kredits-contracts/git/blobs{/sha}", + "git_tags_url": "https://api.github.com/repos/67P/kredits-contracts/git/tags{/sha}", + "git_refs_url": "https://api.github.com/repos/67P/kredits-contracts/git/refs{/sha}", + "trees_url": "https://api.github.com/repos/67P/kredits-contracts/git/trees{/sha}", + "statuses_url": "https://api.github.com/repos/67P/kredits-contracts/statuses/{sha}", + "languages_url": "https://api.github.com/repos/67P/kredits-contracts/languages", + "stargazers_url": "https://api.github.com/repos/67P/kredits-contracts/stargazers", + "contributors_url": "https://api.github.com/repos/67P/kredits-contracts/contributors", + "subscribers_url": "https://api.github.com/repos/67P/kredits-contracts/subscribers", + "subscription_url": "https://api.github.com/repos/67P/kredits-contracts/subscription", + "commits_url": "https://api.github.com/repos/67P/kredits-contracts/commits{/sha}", + "git_commits_url": "https://api.github.com/repos/67P/kredits-contracts/git/commits{/sha}", + "comments_url": "https://api.github.com/repos/67P/kredits-contracts/comments{/number}", + "issue_comment_url": "https://api.github.com/repos/67P/kredits-contracts/issues/comments{/number}", + "contents_url": "https://api.github.com/repos/67P/kredits-contracts/contents/{+path}", + "compare_url": "https://api.github.com/repos/67P/kredits-contracts/compare/{base}...{head}", + "merges_url": "https://api.github.com/repos/67P/kredits-contracts/merges", + "archive_url": "https://api.github.com/repos/67P/kredits-contracts/{archive_format}{/ref}", + "downloads_url": "https://api.github.com/repos/67P/kredits-contracts/downloads", + "issues_url": "https://api.github.com/repos/67P/kredits-contracts/issues{/number}", + "pulls_url": "https://api.github.com/repos/67P/kredits-contracts/pulls{/number}", + "milestones_url": "https://api.github.com/repos/67P/kredits-contracts/milestones{/number}", + "notifications_url": "https://api.github.com/repos/67P/kredits-contracts/notifications{?since,all,participating}", + "labels_url": "https://api.github.com/repos/67P/kredits-contracts/labels{/name}", + "releases_url": "https://api.github.com/repos/67P/kredits-contracts/releases{/id}", + "deployments_url": "https://api.github.com/repos/67P/kredits-contracts/deployments", + "created_at": "2018-03-11T22:11:45Z", + "updated_at": "2020-05-07T08:08:30Z", + "pushed_at": "2020-05-27T14:22:41Z", + "git_url": "git://github.com/67P/kredits-contracts.git", + "ssh_url": "git@github.com:67P/kredits-contracts.git", + "clone_url": "https://github.com/67P/kredits-contracts.git", + "svn_url": "https://github.com/67P/kredits-contracts", + "homepage": "https://wiki.kosmos.org/Kredits", + "size": 2289, + "stargazers_count": 3, + "watchers_count": 3, + "language": "JavaScript", + "has_issues": true, + "has_projects": false, + "has_downloads": true, + "has_wiki": false, + "has_pages": false, + "forks_count": 3, + "mirror_url": null, + "archived": false, + "disabled": false, + "open_issues_count": 35, + "license": null, + "forks": 3, + "open_issues": 35, + "watchers": 3, + "default_branch": "master" + } + }, + "_links": { + "self": { + "href": "https://api.github.com/repos/67P/kredits-contracts/pulls/196" + }, + "html": { + "href": "https://github.com/67P/kredits-contracts/pull/196" + }, + "issue": { + "href": "https://api.github.com/repos/67P/kredits-contracts/issues/196" + }, + "comments": { + "href": "https://api.github.com/repos/67P/kredits-contracts/issues/196/comments" + }, + "review_comments": { + "href": "https://api.github.com/repos/67P/kredits-contracts/pulls/196/comments" + }, + "review_comment": { + "href": "https://api.github.com/repos/67P/kredits-contracts/pulls/comments{/number}" + }, + "commits": { + "href": "https://api.github.com/repos/67P/kredits-contracts/pulls/196/commits" + }, + "statuses": { + "href": "https://api.github.com/repos/67P/kredits-contracts/statuses/606350eb5e173a38a8c5f1b3faf30aa03224065c" + } + }, + "author_association": "CONTRIBUTOR", + "merged": true, + "mergeable": null, + "rebaseable": null, + "mergeable_state": "unknown", + "merged_by": { + "login": "bumi", + "id": 318, + "node_id": "MDQ6VXNlcjMxOA==", + "avatar_url": "https://avatars1.githubusercontent.com/u/318?v=4", + "gravatar_id": "", + "url": "https://api.github.com/users/bumi", + "html_url": "https://github.com/bumi", + "followers_url": "https://api.github.com/users/bumi/followers", + "following_url": "https://api.github.com/users/bumi/following{/other_user}", + "gists_url": "https://api.github.com/users/bumi/gists{/gist_id}", + "starred_url": "https://api.github.com/users/bumi/starred{/owner}{/repo}", + "subscriptions_url": "https://api.github.com/users/bumi/subscriptions", + "organizations_url": "https://api.github.com/users/bumi/orgs", + "repos_url": "https://api.github.com/users/bumi/repos", + "events_url": "https://api.github.com/users/bumi/events{/privacy}", + "received_events_url": "https://api.github.com/users/bumi/received_events", + "type": "User", + "site_admin": false + }, + "comments": 3, + "review_comments": 0, + "maintainer_can_modify": false, + "commits": 4, + "additions": 16649, + "deletions": 4256, + "changed_files": 10 + }, + "url": "https://github.com/67P/kredits-contracts/pull/196", + "ipfsData": "{\n \"@context\": \"https://schema.kosmos.org\",\n \"@type\": \"Contribution\",\n \"contributor\": {\n \"ipfs\": \"QmYgiRd1FZ7JjDGBwkmLQNF6XQuyF8AWoFDRvUWhhmxiEj\"\n },\n \"date\": \"2020-05-27\",\n \"time\": \"14:22:41Z\",\n \"kind\": \"dev\",\n \"description\": \"67P/kredits-contracts: Chore/dependency updates\",\n \"details\": {\n \"url\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/196\",\n \"id\": 423708597,\n \"node_id\": \"MDExOlB1bGxSZXF1ZXN0NDIzNzA4NTk3\",\n \"html_url\": \"https://github.com/67P/kredits-contracts/pull/196\",\n \"diff_url\": \"https://github.com/67P/kredits-contracts/pull/196.diff\",\n \"patch_url\": \"https://github.com/67P/kredits-contracts/pull/196.patch\",\n \"issue_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues/196\",\n \"number\": 196,\n \"state\": \"closed\",\n \"locked\": false,\n \"title\": \"Chore/dependency updates\",\n \"user\": {\n \"login\": \"bumi\",\n \"id\": 318,\n \"node_id\": \"MDQ6VXNlcjMxOA==\",\n \"avatar_url\": \"https://avatars1.githubusercontent.com/u/318?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/bumi\",\n \"html_url\": \"https://github.com/bumi\",\n \"followers_url\": \"https://api.github.com/users/bumi/followers\",\n \"following_url\": \"https://api.github.com/users/bumi/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/bumi/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/bumi/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/bumi/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/bumi/orgs\",\n \"repos_url\": \"https://api.github.com/users/bumi/repos\",\n \"events_url\": \"https://api.github.com/users/bumi/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/bumi/received_events\",\n \"type\": \"User\",\n \"site_admin\": false\n },\n \"body\": \"Updated the npm dependencies to the latest versions\\r\\n\\r\\nmissing: \\r\\n- [ ] ipfs-http-client - which has some breaking changes. I think it is not a problem for us but needs to be tested\\r\\n- [ ] solhint - wich also has a breaking change and now needs pretier for codestyle linting. I did not want that additional dependency now. Also we probably needs to improve the linting of the solidity files\\r\\n\",\n \"created_at\": \"2020-05-27T08:57:43Z\",\n \"updated_at\": \"2020-05-27T14:22:41Z\",\n \"closed_at\": \"2020-05-27T14:22:41Z\",\n \"merged_at\": \"2020-05-27T14:22:41Z\",\n \"merge_commit_sha\": \"2b99593699999756f0f49549873f2cfb679d3f4c\",\n \"assignee\": null,\n \"assignees\": [],\n \"requested_reviewers\": [],\n \"requested_teams\": [],\n \"labels\": [\n {\n \"id\": 923540870,\n \"node_id\": \"MDU6TGFiZWw5MjM1NDA4NzA=\",\n \"url\": \"https://api.github.com/repos/67P/kredits-contracts/labels/kredits-1\",\n \"name\": \"kredits-1\",\n \"color\": \"008080\",\n \"default\": false,\n \"description\": \"\"\n }\n ],\n \"milestone\": null,\n \"draft\": false,\n \"commits_url\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/196/commits\",\n \"review_comments_url\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/196/comments\",\n \"review_comment_url\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/comments{/number}\",\n \"comments_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues/196/comments\",\n \"statuses_url\": \"https://api.github.com/repos/67P/kredits-contracts/statuses/606350eb5e173a38a8c5f1b3faf30aa03224065c\",\n \"head\": {\n \"label\": \"67P:chore/dependency-updates\",\n \"ref\": \"chore/dependency-updates\",\n \"sha\": \"606350eb5e173a38a8c5f1b3faf30aa03224065c\",\n \"user\": {\n \"login\": \"67P\",\n \"id\": 9769503,\n \"node_id\": \"MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=\",\n \"avatar_url\": \"https://avatars1.githubusercontent.com/u/9769503?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/67P\",\n \"html_url\": \"https://github.com/67P\",\n \"followers_url\": \"https://api.github.com/users/67P/followers\",\n \"following_url\": \"https://api.github.com/users/67P/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/67P/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/67P/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/67P/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/67P/orgs\",\n \"repos_url\": \"https://api.github.com/users/67P/repos\",\n \"events_url\": \"https://api.github.com/users/67P/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/67P/received_events\",\n \"type\": \"Organization\",\n \"site_admin\": false\n },\n \"repo\": {\n \"id\": 124804465,\n \"node_id\": \"MDEwOlJlcG9zaXRvcnkxMjQ4MDQ0NjU=\",\n \"name\": \"kredits-contracts\",\n \"full_name\": \"67P/kredits-contracts\",\n \"private\": false,\n \"owner\": {\n \"login\": \"67P\",\n \"id\": 9769503,\n \"node_id\": \"MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=\",\n \"avatar_url\": \"https://avatars1.githubusercontent.com/u/9769503?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/67P\",\n \"html_url\": \"https://github.com/67P\",\n \"followers_url\": \"https://api.github.com/users/67P/followers\",\n \"following_url\": \"https://api.github.com/users/67P/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/67P/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/67P/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/67P/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/67P/orgs\",\n \"repos_url\": \"https://api.github.com/users/67P/repos\",\n \"events_url\": \"https://api.github.com/users/67P/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/67P/received_events\",\n \"type\": \"Organization\",\n \"site_admin\": false\n },\n \"html_url\": \"https://github.com/67P/kredits-contracts\",\n \"description\": \"Smart contracts and JS API for Kosmos Kredits\",\n \"fork\": false,\n \"url\": \"https://api.github.com/repos/67P/kredits-contracts\",\n \"forks_url\": \"https://api.github.com/repos/67P/kredits-contracts/forks\",\n \"keys_url\": \"https://api.github.com/repos/67P/kredits-contracts/keys{/key_id}\",\n \"collaborators_url\": \"https://api.github.com/repos/67P/kredits-contracts/collaborators{/collaborator}\",\n \"teams_url\": \"https://api.github.com/repos/67P/kredits-contracts/teams\",\n \"hooks_url\": \"https://api.github.com/repos/67P/kredits-contracts/hooks\",\n \"issue_events_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues/events{/number}\",\n \"events_url\": \"https://api.github.com/repos/67P/kredits-contracts/events\",\n \"assignees_url\": \"https://api.github.com/repos/67P/kredits-contracts/assignees{/user}\",\n \"branches_url\": \"https://api.github.com/repos/67P/kredits-contracts/branches{/branch}\",\n \"tags_url\": \"https://api.github.com/repos/67P/kredits-contracts/tags\",\n \"blobs_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/blobs{/sha}\",\n \"git_tags_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/tags{/sha}\",\n \"git_refs_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/refs{/sha}\",\n \"trees_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/trees{/sha}\",\n \"statuses_url\": \"https://api.github.com/repos/67P/kredits-contracts/statuses/{sha}\",\n \"languages_url\": \"https://api.github.com/repos/67P/kredits-contracts/languages\",\n \"stargazers_url\": \"https://api.github.com/repos/67P/kredits-contracts/stargazers\",\n \"contributors_url\": \"https://api.github.com/repos/67P/kredits-contracts/contributors\",\n \"subscribers_url\": \"https://api.github.com/repos/67P/kredits-contracts/subscribers\",\n \"subscription_url\": \"https://api.github.com/repos/67P/kredits-contracts/subscription\",\n \"commits_url\": \"https://api.github.com/repos/67P/kredits-contracts/commits{/sha}\",\n \"git_commits_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/commits{/sha}\",\n \"comments_url\": \"https://api.github.com/repos/67P/kredits-contracts/comments{/number}\",\n \"issue_comment_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues/comments{/number}\",\n \"contents_url\": \"https://api.github.com/repos/67P/kredits-contracts/contents/{+path}\",\n \"compare_url\": \"https://api.github.com/repos/67P/kredits-contracts/compare/{base}...{head}\",\n \"merges_url\": \"https://api.github.com/repos/67P/kredits-contracts/merges\",\n \"archive_url\": \"https://api.github.com/repos/67P/kredits-contracts/{archive_format}{/ref}\",\n \"downloads_url\": \"https://api.github.com/repos/67P/kredits-contracts/downloads\",\n \"issues_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues{/number}\",\n \"pulls_url\": \"https://api.github.com/repos/67P/kredits-contracts/pulls{/number}\",\n \"milestones_url\": \"https://api.github.com/repos/67P/kredits-contracts/milestones{/number}\",\n \"notifications_url\": \"https://api.github.com/repos/67P/kredits-contracts/notifications{?since,all,participating}\",\n \"labels_url\": \"https://api.github.com/repos/67P/kredits-contracts/labels{/name}\",\n \"releases_url\": \"https://api.github.com/repos/67P/kredits-contracts/releases{/id}\",\n \"deployments_url\": \"https://api.github.com/repos/67P/kredits-contracts/deployments\",\n \"created_at\": \"2018-03-11T22:11:45Z\",\n \"updated_at\": \"2020-05-07T08:08:30Z\",\n \"pushed_at\": \"2020-05-27T14:22:41Z\",\n \"git_url\": \"git://github.com/67P/kredits-contracts.git\",\n \"ssh_url\": \"git@github.com:67P/kredits-contracts.git\",\n \"clone_url\": \"https://github.com/67P/kredits-contracts.git\",\n \"svn_url\": \"https://github.com/67P/kredits-contracts\",\n \"homepage\": \"https://wiki.kosmos.org/Kredits\",\n \"size\": 2289,\n \"stargazers_count\": 3,\n \"watchers_count\": 3,\n \"language\": \"JavaScript\",\n \"has_issues\": true,\n \"has_projects\": false,\n \"has_downloads\": true,\n \"has_wiki\": false,\n \"has_pages\": false,\n \"forks_count\": 3,\n \"mirror_url\": null,\n \"archived\": false,\n \"disabled\": false,\n \"open_issues_count\": 35,\n \"license\": null,\n \"forks\": 3,\n \"open_issues\": 35,\n \"watchers\": 3,\n \"default_branch\": \"master\"\n }\n },\n \"base\": {\n \"label\": \"67P:master\",\n \"ref\": \"master\",\n \"sha\": \"31c29ab6d0bf0d4fc4c27dbc1ecbb3d27659cf7e\",\n \"user\": {\n \"login\": \"67P\",\n \"id\": 9769503,\n \"node_id\": \"MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=\",\n \"avatar_url\": \"https://avatars1.githubusercontent.com/u/9769503?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/67P\",\n \"html_url\": \"https://github.com/67P\",\n \"followers_url\": \"https://api.github.com/users/67P/followers\",\n \"following_url\": \"https://api.github.com/users/67P/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/67P/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/67P/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/67P/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/67P/orgs\",\n \"repos_url\": \"https://api.github.com/users/67P/repos\",\n \"events_url\": \"https://api.github.com/users/67P/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/67P/received_events\",\n \"type\": \"Organization\",\n \"site_admin\": false\n },\n \"repo\": {\n \"id\": 124804465,\n \"node_id\": \"MDEwOlJlcG9zaXRvcnkxMjQ4MDQ0NjU=\",\n \"name\": \"kredits-contracts\",\n \"full_name\": \"67P/kredits-contracts\",\n \"private\": false,\n \"owner\": {\n \"login\": \"67P\",\n \"id\": 9769503,\n \"node_id\": \"MDEyOk9yZ2FuaXphdGlvbjk3Njk1MDM=\",\n \"avatar_url\": \"https://avatars1.githubusercontent.com/u/9769503?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/67P\",\n \"html_url\": \"https://github.com/67P\",\n \"followers_url\": \"https://api.github.com/users/67P/followers\",\n \"following_url\": \"https://api.github.com/users/67P/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/67P/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/67P/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/67P/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/67P/orgs\",\n \"repos_url\": \"https://api.github.com/users/67P/repos\",\n \"events_url\": \"https://api.github.com/users/67P/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/67P/received_events\",\n \"type\": \"Organization\",\n \"site_admin\": false\n },\n \"html_url\": \"https://github.com/67P/kredits-contracts\",\n \"description\": \"Smart contracts and JS API for Kosmos Kredits\",\n \"fork\": false,\n \"url\": \"https://api.github.com/repos/67P/kredits-contracts\",\n \"forks_url\": \"https://api.github.com/repos/67P/kredits-contracts/forks\",\n \"keys_url\": \"https://api.github.com/repos/67P/kredits-contracts/keys{/key_id}\",\n \"collaborators_url\": \"https://api.github.com/repos/67P/kredits-contracts/collaborators{/collaborator}\",\n \"teams_url\": \"https://api.github.com/repos/67P/kredits-contracts/teams\",\n \"hooks_url\": \"https://api.github.com/repos/67P/kredits-contracts/hooks\",\n \"issue_events_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues/events{/number}\",\n \"events_url\": \"https://api.github.com/repos/67P/kredits-contracts/events\",\n \"assignees_url\": \"https://api.github.com/repos/67P/kredits-contracts/assignees{/user}\",\n \"branches_url\": \"https://api.github.com/repos/67P/kredits-contracts/branches{/branch}\",\n \"tags_url\": \"https://api.github.com/repos/67P/kredits-contracts/tags\",\n \"blobs_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/blobs{/sha}\",\n \"git_tags_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/tags{/sha}\",\n \"git_refs_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/refs{/sha}\",\n \"trees_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/trees{/sha}\",\n \"statuses_url\": \"https://api.github.com/repos/67P/kredits-contracts/statuses/{sha}\",\n \"languages_url\": \"https://api.github.com/repos/67P/kredits-contracts/languages\",\n \"stargazers_url\": \"https://api.github.com/repos/67P/kredits-contracts/stargazers\",\n \"contributors_url\": \"https://api.github.com/repos/67P/kredits-contracts/contributors\",\n \"subscribers_url\": \"https://api.github.com/repos/67P/kredits-contracts/subscribers\",\n \"subscription_url\": \"https://api.github.com/repos/67P/kredits-contracts/subscription\",\n \"commits_url\": \"https://api.github.com/repos/67P/kredits-contracts/commits{/sha}\",\n \"git_commits_url\": \"https://api.github.com/repos/67P/kredits-contracts/git/commits{/sha}\",\n \"comments_url\": \"https://api.github.com/repos/67P/kredits-contracts/comments{/number}\",\n \"issue_comment_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues/comments{/number}\",\n \"contents_url\": \"https://api.github.com/repos/67P/kredits-contracts/contents/{+path}\",\n \"compare_url\": \"https://api.github.com/repos/67P/kredits-contracts/compare/{base}...{head}\",\n \"merges_url\": \"https://api.github.com/repos/67P/kredits-contracts/merges\",\n \"archive_url\": \"https://api.github.com/repos/67P/kredits-contracts/{archive_format}{/ref}\",\n \"downloads_url\": \"https://api.github.com/repos/67P/kredits-contracts/downloads\",\n \"issues_url\": \"https://api.github.com/repos/67P/kredits-contracts/issues{/number}\",\n \"pulls_url\": \"https://api.github.com/repos/67P/kredits-contracts/pulls{/number}\",\n \"milestones_url\": \"https://api.github.com/repos/67P/kredits-contracts/milestones{/number}\",\n \"notifications_url\": \"https://api.github.com/repos/67P/kredits-contracts/notifications{?since,all,participating}\",\n \"labels_url\": \"https://api.github.com/repos/67P/kredits-contracts/labels{/name}\",\n \"releases_url\": \"https://api.github.com/repos/67P/kredits-contracts/releases{/id}\",\n \"deployments_url\": \"https://api.github.com/repos/67P/kredits-contracts/deployments\",\n \"created_at\": \"2018-03-11T22:11:45Z\",\n \"updated_at\": \"2020-05-07T08:08:30Z\",\n \"pushed_at\": \"2020-05-27T14:22:41Z\",\n \"git_url\": \"git://github.com/67P/kredits-contracts.git\",\n \"ssh_url\": \"git@github.com:67P/kredits-contracts.git\",\n \"clone_url\": \"https://github.com/67P/kredits-contracts.git\",\n \"svn_url\": \"https://github.com/67P/kredits-contracts\",\n \"homepage\": \"https://wiki.kosmos.org/Kredits\",\n \"size\": 2289,\n \"stargazers_count\": 3,\n \"watchers_count\": 3,\n \"language\": \"JavaScript\",\n \"has_issues\": true,\n \"has_projects\": false,\n \"has_downloads\": true,\n \"has_wiki\": false,\n \"has_pages\": false,\n \"forks_count\": 3,\n \"mirror_url\": null,\n \"archived\": false,\n \"disabled\": false,\n \"open_issues_count\": 35,\n \"license\": null,\n \"forks\": 3,\n \"open_issues\": 35,\n \"watchers\": 3,\n \"default_branch\": \"master\"\n }\n },\n \"_links\": {\n \"self\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/196\"\n },\n \"html\": {\n \"href\": \"https://github.com/67P/kredits-contracts/pull/196\"\n },\n \"issue\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/issues/196\"\n },\n \"comments\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/issues/196/comments\"\n },\n \"review_comments\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/196/comments\"\n },\n \"review_comment\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/comments{/number}\"\n },\n \"commits\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/pulls/196/commits\"\n },\n \"statuses\": {\n \"href\": \"https://api.github.com/repos/67P/kredits-contracts/statuses/606350eb5e173a38a8c5f1b3faf30aa03224065c\"\n }\n },\n \"author_association\": \"CONTRIBUTOR\",\n \"merged\": true,\n \"mergeable\": null,\n \"rebaseable\": null,\n \"mergeable_state\": \"unknown\",\n \"merged_by\": {\n \"login\": \"bumi\",\n \"id\": 318,\n \"node_id\": \"MDQ6VXNlcjMxOA==\",\n \"avatar_url\": \"https://avatars1.githubusercontent.com/u/318?v=4\",\n \"gravatar_id\": \"\",\n \"url\": \"https://api.github.com/users/bumi\",\n \"html_url\": \"https://github.com/bumi\",\n \"followers_url\": \"https://api.github.com/users/bumi/followers\",\n \"following_url\": \"https://api.github.com/users/bumi/following{/other_user}\",\n \"gists_url\": \"https://api.github.com/users/bumi/gists{/gist_id}\",\n \"starred_url\": \"https://api.github.com/users/bumi/starred{/owner}{/repo}\",\n \"subscriptions_url\": \"https://api.github.com/users/bumi/subscriptions\",\n \"organizations_url\": \"https://api.github.com/users/bumi/orgs\",\n \"repos_url\": \"https://api.github.com/users/bumi/repos\",\n \"events_url\": \"https://api.github.com/users/bumi/events{/privacy}\",\n \"received_events_url\": \"https://api.github.com/users/bumi/received_events\",\n \"type\": \"User\",\n \"site_admin\": false\n },\n \"comments\": 3,\n \"review_comments\": 0,\n \"maintainer_can_modify\": false,\n \"commits\": 4,\n \"additions\": 16649,\n \"deletions\": 4256,\n \"changed_files\": 10\n },\n \"url\": \"https://github.com/67P/kredits-contracts/pull/196\"\n}" +} diff --git a/tests/fixtures/contributions.js b/tests/fixtures/contributions.js index f675937..75a1270 100644 --- a/tests/fixtures/contributions.js +++ b/tests/fixtures/contributions.js @@ -1,23 +1,25 @@ import Model from 'kredits-web/models/contribution'; import contributors from '../../tests/fixtures/contributors'; +import processContributionData from 'kredits-web/utils/process-contribution-data'; const items = []; const data = [ - { id: 1, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'dev' }, - { id: 2, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000, kind: 'ops' }, - { id: 3, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'ops' }, - { id: 4, contributorId: 2, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'docs' }, - { id: 5, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: false, amount: 5000, kind: 'design' }, - { id: 6, contributorId: 1, confirmedAtBlock: 1000, claimed: false, vetoed: true, amount: 500, kind: 'dev' }, - { id: 7, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 5000, kind: 'dev' }, - { id: 8, contributorId: 1, confirmedAtBlock: 2000, claimed: false, vetoed: false, amount: 1500, kind: 'community' }, - { id: 9, contributorId: 3, confirmedAtBlock: 2000, claimed: false, vetoed: true, amount: 1500, kind: 'docs' }, + { id: 1, contributorId: 1, confirmedAt: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'dev' }, + { id: 2, contributorId: 1, confirmedAt: 1000, claimed: false, vetoed: false, amount: 5000, kind: 'ops' }, + { id: 3, contributorId: 2, confirmedAt: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'ops' }, + { id: 4, contributorId: 2, confirmedAt: 1000, claimed: false, vetoed: false, amount: 1500, kind: 'docs' }, + { id: 5, contributorId: 1, confirmedAt: 1000, claimed: false, vetoed: false, amount: 5000, kind: 'design' }, + { id: 6, contributorId: 1, confirmedAt: 1000, claimed: false, vetoed: true, amount: 500, kind: 'dev' }, + { id: 7, contributorId: 3, confirmedAt: 2000, claimed: false, vetoed: false, amount: 5000, kind: 'dev' }, + { id: 8, contributorId: 1, confirmedAt: 2000, claimed: false, vetoed: false, amount: 1500, kind: 'community' }, + { id: 9, contributorId: 3, confirmedAt: 2000, claimed: false, vetoed: true, amount: 1500, kind: 'docs' }, ]; data.forEach(attrs => { - attrs.contributor = contributors.findBy('id', attrs.contributorId.toString()); - items.push(Model.create(attrs)) + const c = Model.create(processContributionData(attrs)); + c.set('contributor', contributors.findBy('id', attrs.contributorId.toString())); + items.push(c); }); export default items; diff --git a/tests/fixtures/contributor-data.js b/tests/fixtures/contributor-data.js new file mode 100644 index 0000000..5d7477c --- /dev/null +++ b/tests/fixtures/contributor-data.js @@ -0,0 +1,64 @@ +export default { + "0": 1, + "1": "0x7E8f313C56F809188313aa274Fa67EE58c31515d", + "2": "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", + "3": 18, + "4": 32, + "5": true, + "6": { + "_hex": "0x09979c0838e8fc880000" + }, + "7": 53500, + "8": { + "_hex": "0x49" + }, + "9": true, + "id": 1, + "account": "0x7E8f313C56F809188313aa274Fa67EE58c31515d", + "hashDigest": "0x99b8afd7b266e19990924a8be9099e81054b70c36b20937228a77a5cf75723b8", + "hashFunction": 18, + "hashSize": 32, + "isCore": true, + "balance": { + "_hex": "0x09979c0838e8fc880000" + }, + "totalKreditsEarned": 53500, + "contributionsCount": { + "_hex": "0x49", + "toNumber": function() { return 73; } + }, + "exists": true, + "balanceInt": 45298, + "ipfsHash": "QmYgiRd1FZ7JjDGBwkmLQNF6XQuyF8AWoFDRvUWhhmxiEj", + "name": "Bumi", + "kind": "person", + "url": "https://michaelbumann.com", + "accounts": [ + { + "site": "github.com", + "uid": 318, + "username": "bumi", + "url": "https://github.com/bumi" + }, + { + "site": "gitea.kosmos.org", + "username": "bumi", + "url": "https://gitea.kosmos.org/bumi" + }, + { + "site": "wiki.kosmos.org", + "username": "Bumi", + "url": "https://wiki.kosmos.org/User:Bumi" + }, + { + "site": "zoom.us", + "username": "bumi" + } + ], + "github_uid": 318, + "github_username": "bumi", + "gitea_username": "bumi", + "wiki_username": "Bumi", + "zoom_display_name": "bumi", + "ipfsData": "{\n \"@context\": \"https://schema.kosmos.org\",\n \"@type\": \"Contributor\",\n \"kind\": \"person\",\n \"name\": \"Bumi\",\n \"accounts\": [\n {\n \"site\": \"github.com\",\n \"uid\": 318,\n \"username\": \"bumi\",\n \"url\": \"https://github.com/bumi\"\n },\n {\n \"site\": \"gitea.kosmos.org\",\n \"username\": \"bumi\",\n \"url\": \"https://gitea.kosmos.org/bumi\"\n },\n {\n \"site\": \"wiki.kosmos.org\",\n \"username\": \"Bumi\",\n \"url\": \"https://wiki.kosmos.org/User:Bumi\"\n },\n {\n \"site\": \"zoom.us\",\n \"username\": \"bumi\"\n }\n ],\n \"url\": \"https://michaelbumann.com\"\n}" +} diff --git a/tests/fixtures/contributors.js b/tests/fixtures/contributors.js index 97c0fac..ebe261e 100644 --- a/tests/fixtures/contributors.js +++ b/tests/fixtures/contributors.js @@ -1,13 +1,17 @@ import Contributor from 'kredits-web/models/contributor'; +import processContributorData from 'kredits-web/utils/process-contributor-data'; const contributors = []; const data = [ - { id: 1, name: 'Bumi', totalKreditsEarned: 11500, github_uid: 318 }, - { id: 2, name: 'Râu Cao', totalKreditsEarned: 3000, github_uid: 842 }, - { id: 3, name: 'Manuel', totalKreditsEarned: 0, github_uid: 54812 } + { id: '1', name: 'Bumi', totalKreditsEarned: 11500, github_uid: 318 }, + { id: '2', name: 'Râu Cao', totalKreditsEarned: 3000, github_uid: 842 }, + { id: '3', name: 'Manuel', totalKreditsEarned: 0, github_uid: 54812 } ]; -data.forEach(attrs => contributors.push(Contributor.create(attrs))); +data.forEach(attrs => { + const c = Contributor.create(processContributorData(attrs)); + contributors.push(c); +}); export default contributors; diff --git a/tests/unit/services/browser-cache-test.js b/tests/unit/services/browser-cache-test.js new file mode 100644 index 0000000..a7d6459 --- /dev/null +++ b/tests/unit/services/browser-cache-test.js @@ -0,0 +1,17 @@ +import { module, test } from 'qunit'; +import { setupTest } from 'ember-qunit'; + +module('Unit | Service | browser-cache', function(hooks) { + setupTest(hooks); + + test('it exists', function(assert) { + let service = this.owner.lookup('service:browser-cache'); + assert.ok(service); + }); + + test('creates kredits data stores', function(assert) { + let cache = this.owner.lookup('service:browser-cache'); + assert.equal(cache.contributors._config.name, "kredits:rinkeby:contributors"); + assert.equal(cache.contributions._config.name, "kredits:rinkeby:contributions"); + }); +}); diff --git a/tests/unit/utils/process-contribution-data-test.js b/tests/unit/utils/process-contribution-data-test.js new file mode 100644 index 0000000..9c93c02 --- /dev/null +++ b/tests/unit/utils/process-contribution-data-test.js @@ -0,0 +1,28 @@ +import { module, test } from 'qunit'; +import processContributionData from 'kredits-web/utils/process-contribution-data'; +import testData from '../../fixtures/contribution-data'; + +module('Unit | Utility | process-contribution-data', function() { + + let result = processContributionData(testData); + + test('formats the data correctly', function(assert) { + assert.ok(typeof result.confirmedAt === 'number'); + }); + + test('copies other properties', function(assert) { + [ + 'id', 'contributorId', 'amount', 'vetoed', + 'ipfsHash', 'kind', 'description', 'details', + 'url', 'date', 'time', 'pendingTx' + ].forEach(p => { + assert.ok(Object.prototype.hasOwnProperty.call(result, p), `copies property ${p}`); + }) + }); + + test('does not copy unnecessary properties', function(assert) { + ['exists', '5'].forEach(p => { + assert.notOk(Object.prototype.hasOwnProperty.call(result, p)); + }) + }); +}); diff --git a/tests/unit/utils/process-contributor-data-test.js b/tests/unit/utils/process-contributor-data-test.js new file mode 100644 index 0000000..f81a58d --- /dev/null +++ b/tests/unit/utils/process-contributor-data-test.js @@ -0,0 +1,31 @@ +import { module, test } from 'qunit'; +import processContributorData from 'kredits-web/utils/process-contributor-data'; +import testData from '../../fixtures/contributor-data'; + +module('Unit | Utility | process-contributor-data', function() { + + let result = processContributorData(testData); + + test('formats the data correctly', function(assert) { + // TODO use integers everywhere for IDs + assert.ok(typeof result.id === 'string'); + assert.ok(typeof result.balance === 'number'); + assert.ok(typeof result.totalKreditsEarned === 'number'); + assert.ok(typeof result.contributionsCount === 'number'); + }); + + test('copies other properties', function(assert) { + [ + 'account', 'accounts', 'ipfsHash', 'isCore', 'kind', 'name', 'url', + 'github_username', 'github_uid', 'wiki_username', 'zoom_display_name' + ].forEach(p => { + assert.ok(Object.prototype.hasOwnProperty.call(result, p), `copies property ${p}`); + }) + }); + + test('does not copy unnecessary properties', function(assert) { + ['exists', '5'].forEach(p => { + assert.notOk(Object.prototype.hasOwnProperty.call(result, p)); + }) + }); +});