diff --git a/app/components/add-contributor/component.js b/app/components/add-contributor/component.js index 77483fa..13c83da 100644 --- a/app/components/add-contributor/component.js +++ b/app/components/add-contributor/component.js @@ -1,81 +1,67 @@ -import Ember from 'ember'; -import Contributor from 'kredits-web/models/contributor'; +import Component from 'ember-component'; +import computed, { and } from 'ember-computed'; +import injectService from 'ember-service/inject'; +import isPresent from 'kredits-web/utils/cps/is-present'; -const { - Component, - isPresent, - inject: { - service - }, - computed -} = Ember; export default Component.extend({ + kredits: injectService(), - kredits: service(), + // Default attributes used by reset + attributes: { + address: null, + name: null, + kind: 'person', + url: null, + github_username: null, + github_uid: null, + wiki_username: null, + isCore: false, + }, - newContributor: null, - inProgress: false, + didInsertElement() { + this._super(...arguments); + this.reset(); + }, - isValidAddress: function() { + isValidAddress: computed('kredits.ethProvider', 'address', function() { // TODO: add proper address validation - return this.get('newContributor.address') !== ''; - }.property('kredits.ethProvider', 'newContributor.address'), - - isValidName: function() { - return isPresent(this.get('newContributor.name')); - }.property('newContributor.name'), - - isValidURL: function() { - return isPresent(this.get('newContributor.url')); - }.property('newContributor.url'), - - isValidGithubUID: function() { - return isPresent(this.get('newContributor.github_uid')); - }.property('newContributor.github_uid'), - - isValidGithubUsername: function() { - return isPresent(this.get('newContributor.github_username')); - }.property('newContributor.github_username'), - - isValidWikiUsername: function() { - return isPresent(this.get('newContributor.wiki_username')); - }.property('newContributor.wiki_username'), - - isValid: computed.and( + return this.get('address') !== ''; + }), + isValidName: isPresent('name'), + isValidURL: isPresent('url'), + isValidGithubUID: isPresent('github_uid'), + isValidGithubUsername: isPresent('github_username'), + isValidWikiUsername: isPresent('wiki_username'), + isValid: and( 'isValidAddress', 'isValidName', 'isValidGithubUID' ), reset: function() { - this.setProperties({ - newContributor: Contributor.create({ kind: 'person' }), - inProgress: false - }); + this.setProperties(this.get('attributes')); }, actions: { - - save() { - if (!this.get('contractInteractionEnabled')) { - alert('Only core team members can add new contributors. Please ask someone to set you up.'); + submit() { + if (!this.get('isValid')) { + alert('Invalid data. Please review and try again.'); return; } - if (this.get('isValid')) { - this.set('inProgress', true); + let attributes = Object.keys(this.get('attributes')); + let contributor = this.getProperties(attributes); + let saved = this.save(contributor); - this.get('kredits').addContributor(this.get('newContributor')).then(contributor => { - this.reset(); - this.get('contributors').pushObject(contributor); - window.scroll(0,0); - }); - } else { - alert('Invalid data. Please review and try again.'); - } + // The promise handles inProgress + this.set('inProgress', saved); + + saved.then(() => { + this.reset(); + window.scroll(0,0); + window.alert('Contributor added.'); + }); } - } - }); diff --git a/app/components/add-contributor/template.hbs b/app/components/add-contributor/template.hbs index eaa5818..ded7d47 100644 --- a/app/components/add-contributor/template.hbs +++ b/app/components/add-contributor/template.hbs @@ -1,6 +1,9 @@ -
+

- {{input type="checkbox" name="is-core" id="is-core" checked=newContributor.isCore}} + {{input name="is-core" + type="checkbox" + id="is-core" + checked=isCore}} @@ -9,51 +12,53 @@ {{input name="address" type="text" placeholder="0xF18E631Ea191aE4ebE70046Fcb01a436554421BA4" - value=newContributor.address + value=address class=(if isValidAddress 'valid' '')}}

- + +

{{input name="name" type="text" placeholder="Name" - value=newContributor.name + value=name class=(if isValidName 'valid' '')}}

{{input name="url" type="text" placeholder="URL" - value=newContributor.url + value=url class=(if isValidURL 'valid' '')}}

{{input name="github_uid" type="text" placeholder="GitHub UID (123)" - value=newContributor.github_uid + value=github_uid class=(if isValidGithubUID 'valid' '')}}

{{input name="github_username" type="text" placeholder="GitHub username" - value=newContributor.github_username + value=github_username class=(if isValidGithubUsername 'valid' '')}}

{{input name="wiki_username" type="text" placeholder="Wiki Username" - value=newContributor.wiki_username + value=wiki_username class=(if isValidWikiUsername 'valid' '')}}

- {{input type="submit" value=(if inProgress 'Processing' 'Save') disabled=inProgress}} + {{input type="submit" + disabled=(is-pending inProgress) + value=(if (is-pending inProgress) 'Processing' 'Save')}}

diff --git a/app/controllers/index.js b/app/controllers/index.js index 1f2ecda..e502daf 100644 --- a/app/controllers/index.js +++ b/app/controllers/index.js @@ -116,13 +116,18 @@ export default Ember.Controller.extend({ actions: { - confirmProposal(proposalId) { this.get('kredits').vote(proposalId).then(transaction => { window.confirm('Vote submitted to Ethereum blockhain: '+transaction.hash); }); + }, + + save(contributor) { + return this.get('kredits').addContributor(contributor) + .then((contributor) => { + this.get('model.contributors').pushObject(contributor); + return contributor; + }); } - } - }); diff --git a/app/lib/kredits/index.js b/app/lib/kredits/index.js new file mode 100644 index 0000000..0960559 --- /dev/null +++ b/app/lib/kredits/index.js @@ -0,0 +1,5 @@ +import ContributorSerializer from './serializers/contributor'; + +export { + ContributorSerializer +}; diff --git a/app/lib/kredits/serializers/contributor.js b/app/lib/kredits/serializers/contributor.js new file mode 100644 index 0000000..80df182 --- /dev/null +++ b/app/lib/kredits/serializers/contributor.js @@ -0,0 +1,93 @@ +/** + * Handle serialization for JSON-LD object of the contributor, according to + * https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json + * + * @class + * @public + */ +export default class Contributor { + /** + * Deserialize JSON to object + * + * @method + * @public + */ + static deserialize(serialized) { + let { + name, + kind, + url, + accounts, + } = JSON.parse(serialized); + + let github_username, github_uid, wiki_username; + let github = accounts.find((a) => a.site === 'github.com'); + let wiki = accounts.find((a) => a.site === 'wiki.kosmos.org'); + + if (github) { + ({ username: github_username, uid: github_uid} = github); + } + if (wiki) { + ({ username: wiki_username } = wiki); + } + + return { + name, + kind, + url, + github_uid, + github_username, + wiki_username, + ipfsData: serialized, + }; + } + + /** + * Serialize object to JSON + * + * @method + * @public + */ + static serialize(deserialized) { + let { + name, + kind, + url, + github_uid, + github_username, + wiki_username, + } = deserialized; + + let data = { + "@context": "https://schema.kosmos.org", + "@type": "Contributor", + kind, + name, + "accounts": [] + }; + + if (url) { + data["url"] = url; + } + + if (github_uid) { + data.accounts.push({ + "site": "github.com", + "uid": github_uid, + "username": github_username, + "url": `https://github.com/${github_username}` + }); + } + + if (wiki_username) { + data.accounts.push({ + "site": "wiki.kosmos.org", + "username": wiki_username, + "url": `https://wiki.kosmos.org/User:${wiki_username}` + }); + } + + // Write it pretty to ipfs + return JSON.stringify(data, null, 2); + } +} diff --git a/app/models/contributor.js b/app/models/contributor.js index de16bfb..cd793d3 100644 --- a/app/models/contributor.js +++ b/app/models/contributor.js @@ -1,14 +1,7 @@ -import Ember from 'ember'; import computed from 'ember-computed'; -import injectService from 'ember-service/inject'; - -const { - isPresent, -} = Ember; - -export default Ember.Object.extend({ - ipfs: injectService(), +import EmberObject from 'ember-object'; +export default EmberObject.extend({ id: null, address: null, name: null, @@ -18,7 +11,7 @@ export default Ember.Object.extend({ github_uid: null, wiki_username: null, profileHash: null, - balance: null, + balance: 0, isCore: false, isCurrentUser: false, @@ -28,99 +21,4 @@ export default Ember.Object.extend({ return `https://avatars2.githubusercontent.com/u/${github_uid}?v=3&s=128`; } }), - - /** - * Loads the contributor's profile data from IPFS and sets local instance - * properties from it - * - * @method - * @public - */ - loadProfile() { - let profileHash = this.get('profileHash'); - if (!profileHash) { - return; - } - - return this.get('ipfs') - .getFile(profileHash) - .then((content) => { - let profile = Ember.Object.create(JSON.parse(content)); - this.set('ipfsData', JSON.stringify(profile, null, 2)); - - Ember.Logger.debug('[contributor] loaded contributor profile', profile); - - this.setProperties({ - name: profile.get('name'), - kind: profile.get('kind') - }); - - let accounts = profile.get('accounts'); - let github = accounts.findBy('site', 'github.com'); - let wiki = accounts.findBy('site', 'wiki.kosmos.org'); - - if (isPresent(github)) { - this.setProperties({ - github_username: github.username, - github_uid: github.uid, - }); - } - if (isPresent(wiki)) { - this.setProperties({ - wiki_username: wiki.username - }); - } - }).catch((err) => { - Ember.Logger.error('[contributor] error trying to load contributor profile', profileHash, err); - }); - }, - - /** - * Creates a JSON-LD object of the contributor, according to - * https://github.com/67P/kosmos-schemas/blob/master/schemas/contributor.json - * - * @method - * @public - */ - toJSON() { - let contributor = { - "@context": "https://schema.kosmos.org", - "@type": "Contributor", - "kind": this.get('kind'), - "name": this.get('name'), - "accounts": [] - }; - - if (Ember.isPresent(this.get('url'))) { - contributor["url"] = this.get('url'); - } - if (Ember.isPresent(this.get('github_uid'))) { - contributor.accounts.push({ - "site": "github.com", - "uid": this.get('github_uid'), - "username": this.get('github_username'), - "url": `https://github.com/${this.get('github_username')}` - }); - } - if (Ember.isPresent(this.get('wiki_username'))) { - contributor.accounts.push({ - "site": "wiki.kosmos.org", - "username": this.get('wiki_username'), - "url": `https://wiki.kosmos.org/User:${this.get('wiki_username')}` - }); - } - - return contributor; - }, - - /** - * Returns the JSON-LD representation of the model as a string - * - * @method - * @public - */ - serialize() { - return JSON.stringify(this.toJSON()); - } - }); diff --git a/app/services/kredits.js b/app/services/kredits.js index 3af0ecd..868e5d2 100644 --- a/app/services/kredits.js +++ b/app/services/kredits.js @@ -14,12 +14,14 @@ import Proposal from 'kredits-web/models/proposal'; import abis from 'contracts/abis'; import addresses from 'contracts/addresses'; +import { ContributorSerializer } from 'kredits-web/lib/kredits'; const { getOwner, Logger: { debug, - warn + warn, + error } } = Ember; @@ -103,37 +105,55 @@ export default Service.extend({ }); }, - getContributorData(id) { + // TODO: Should be part of the service + buildContributor(attributes) { + debug('[kredits] buildContributor', attributes); + + let contributor = getOwner(this).lookup('model:contributor'); + contributor.setProperties(attributes); + return contributor; + }, + + getContributorById(id) { return this.get('contributorsContract') .then((contract) => contract.contributors(id)) - .then((data) => { - debug('[kredits] contributor', data); + // Set basic data + .then(({ + account: address, + hashFunction, + hashSize, + isCore, + profileHash: digest, + }) => { - let [ address, digest, hashFunction, size, isCore ] = data; let isCurrentUser = this.get('currentUserAccounts').includes(address); let profileHash = this.getMultihashFromBytes32({ digest, - hashFunction: hashFunction, - size: size + hashFunction, + size: hashSize }); - return this.get('tokenContract') - .then((contract) => contract.balanceOf(address)) - .then((balance) => { - balance = balance.toNumber(); - let contributor = getOwner(this).lookup('model:contributor'); - contributor.setProperties({ - id, - address, - profileHash, - isCore, - isCurrentUser, - balance - }); - // Load data from IPFS - contributor.loadProfile(); - return contributor; + return { + id, + address, + isCore, + isCurrentUser, + profileHash, + }; + }) + // Add the balance + .then((data) => { + return this.get('tokenContract') + .then((contract) => contract.balanceOf(data.address)) + .then((balance) => { + data.balance = balance.toNumber(); + return data; }); + }) + // Fetch IPFS data if available + .then(this.loadContributorProfile.bind(this)) + .then((attributes) => { + return this.buildContributor(attributes); }); }, @@ -145,13 +165,43 @@ export default Service.extend({ let contributors = []; for(var id = 1; id <= contributorsCount.toNumber(); id++) { - contributors.push(this.getContributorData(id)); + contributors.push(this.getContributorById(id)); } return RSVP.all(contributors); }); }, + + /** + * Loads the contributor's profile data from IPFS and returns the attributes + * + * @method + * @public + */ + loadContributorProfile(data) { + let profileHash = data.profileHash; + + if (!profileHash) { + return data; + } + + return this.get('ipfs') + .getFile(profileHash) + .then(ContributorSerializer.deserialize) + .then((attributes) => { + debug('[kredits] loaded contributor profile', attributes); + return Object.assign({}, data, attributes); + }) + .catch((err) => { + error( + '[kredits] error trying to load contributor profile', + profileHash, + err + ); + }); + }, + getProposalData(i) { return this.get('kreditsContract') .then((contract) => contract.proposals(i)) @@ -234,36 +284,42 @@ export default Service.extend({ }; }, - addContributor(contributor) { - debug('[kredits] add contributor', contributor); + + // TODO: extract common logic to module + addContributor(attributes) { + debug('[kredits] add contributor', attributes); + + let json = ContributorSerializer.serialize(attributes); return this.get('ipfs') - .storeFile(contributor.serialize()) - .then(profileHash => { - contributor.setProperties({ - profileHash: profileHash, - balance: 0, - isCurrentUser: this.get('currentUserAccounts').includes(contributor.address) - }); - - let { - digest, hashFunction, size - } = this.getBytes32FromMultihash(profileHash); - + .storeFile(json) + // Set profileHash + .then((profileHash) => { + attributes.profileHash = profileHash; + return attributes; + }) + .then((attributes) => { return this.get('kreditsContract') .then((contract) => { - return contract.addContributor( - contributor.address, + let { address, isCore, profileHash } = attributes; + let { + digest, hashFunction, size + } = this.getBytes32FromMultihash(profileHash); + + let contributor = [ + address, digest, hashFunction, size, - contributor.isCore - ); - }) - .then((data) => { - debug('[kredits] add contributor response', data); - return contributor; + isCore, + ]; + debug('[kredits] addContributor', ...contributor); + return contract.addContributor(...contributor); }); + }) + .then((data) => { + debug('[kredits] add contributor response', data); + return this.buildContributor(attributes); }); }, @@ -301,11 +357,12 @@ export default Service.extend({ .then((contract) => { return contract.getContributorIdByAddress(this.get('currentUserAccounts.firstObject')) .then((id) => { + id = id.toNumber(); // check if the user is a contributor or not - if( id.toNumber() === 0) { + if (id === 0) { return RSVP.resolve(); } else { - return this.getContributorData(id.toNumber()); + return this.getContributorById(id); } }); }); diff --git a/app/templates/index.hbs b/app/templates/index.hbs index 49817d1..5dfcad5 100644 --- a/app/templates/index.hbs +++ b/app/templates/index.hbs @@ -65,8 +65,11 @@
- {{add-contributor contributors=model.contributors - newContributor=model.newContributor - contractInteractionEnabled=contractInteractionEnabled}} + {{!-- + TODO: + only show the form if currentUser.isCore else show: + Only core team members can add new contributors. Please ask someone to set you up. + --}} + {{add-contributor contributors=model.contributors save=(action 'save')}}
diff --git a/app/utils/cps/is-present.js b/app/utils/cps/is-present.js new file mode 100644 index 0000000..c11e1ea --- /dev/null +++ b/app/utils/cps/is-present.js @@ -0,0 +1,8 @@ +import computed from 'ember-computed'; +import { isPresent } from 'ember-utils'; + +export default function(key) { + return computed(key, function() { + return isPresent(this.get(key)); + }); +} diff --git a/package-lock.json b/package-lock.json index fabcead..c8b812b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -3144,6 +3144,11 @@ "safe-buffer": "5.1.1" }, "dependencies": { + "core-util-is": { + "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", + "dev": true + }, "process-nextick-args": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", @@ -3163,13 +3168,6 @@ "safe-buffer": "5.1.1", "string_decoder": "1.0.3", "util-deprecate": "1.0.2" - }, - "dependencies": { - "core-util-is": { - "version": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==", - "dev": true - } } }, "string_decoder": { @@ -3462,6 +3460,11 @@ "source-map": "https://registry.npmjs.org/source-map/-/source-map-0.5.6.tgz" }, "dependencies": { + "convert-source-map": { + "version": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.3.0.tgz", + "integrity": "sha512-8iaBspZWViJD+h8epOgGyXGWH2wSDLzQ8w9qDs/L7W67IfnEeXKu/Q1cPeWpIrRJc9Mvzbn6hKxnL3goD5ncwQ==", + "dev": true + }, "minimatch": { "version": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.3.tgz", "integrity": "sha512-NyXjqu1IwcqH6nv5vmMtaG3iw7kdV3g6MwlUBZkc3Vn5b5AMIWYKfptvzipoyFfhlfOgBQ9zoTxQMravF1QTnw==", @@ -5668,11 +5671,6 @@ "integrity": "sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4=", "dev": true }, - "convert-source-map": { - "version": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.3.0.tgz", - "integrity": "sha512-8iaBspZWViJD+h8epOgGyXGWH2wSDLzQ8w9qDs/L7W67IfnEeXKu/Q1cPeWpIrRJc9Mvzbn6hKxnL3goD5ncwQ==", - "dev": true - }, "copy-dereference": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/copy-dereference/-/copy-dereference-1.0.0.tgz", @@ -22277,7 +22275,7 @@ "ember-cli-babel": { "version": "6.12.0", "resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.12.0.tgz", - "integrity": "sha512-LMwZ3Xf3Q3jQUXaJtLLJsbbhRZRNv/iea64lZ8OgqZp1fh66CSXfmqV3L9QSuYQKPDNqFiu2v6IpOT08C6GU6w==", + "integrity": "sha1-Otzb4SeNofzQuQOPE2DLSsXUQUw=", "dev": true, "requires": { "amd-name-resolver": "0.0.7", @@ -23378,7 +23376,7 @@ "ember-weakmap": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/ember-weakmap/-/ember-weakmap-3.1.1.tgz", - "integrity": "sha512-rfW3A1m3NFsHd/NuHyBkssU0Qf0zGcJmASGfhjZc7fIQeBZvSLIFYZTej+W+YBLPtED9h/SVW63DHTRY5PUR4Q==", + "integrity": "sha1-KubgCAtbgM8NEI93Utxp6pYD29c=", "dev": true, "requires": { "browserslist": "2.11.3", @@ -23389,7 +23387,7 @@ "debug": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz", - "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", "dev": true, "requires": { "ms": "2.0.0" @@ -23398,7 +23396,7 @@ "ember-cli-babel": { "version": "6.12.0", "resolved": "https://registry.npmjs.org/ember-cli-babel/-/ember-cli-babel-6.12.0.tgz", - "integrity": "sha512-LMwZ3Xf3Q3jQUXaJtLLJsbbhRZRNv/iea64lZ8OgqZp1fh66CSXfmqV3L9QSuYQKPDNqFiu2v6IpOT08C6GU6w==", + "integrity": "sha1-Otzb4SeNofzQuQOPE2DLSsXUQUw=", "dev": true, "requires": { "amd-name-resolver": "0.0.7", @@ -25695,7 +25693,7 @@ } }, "kredits-contracts": { - "version": "github:67P/truffle-kredits#4d2ba2a4bf1bb3ceb1ae9c768abfc73a9cf5ab00", + "version": "github:67P/truffle-kredits#bdd99d58cf601d9fadd81c7f0cbd61e57cf552b5", "dev": true }, "lcid": { @@ -28245,7 +28243,7 @@ }, "slash": { "version": "https://registry.npmjs.org/slash/-/slash-1.0.0.tgz", - "integrity": "sha512-3TYDR7xWt4dIqV2JauJr+EJeW356RXijHeUlO+8djJ+uBXPn8/2dpzBc8yQhh583sVvc9CvFAeQVgijsH+PNNg==", + "integrity": "sha1-xB8vbDn8FtHNF61LXYlhFK5HDVU=", "dev": true }, "snapdragon": { @@ -29020,7 +29018,7 @@ }, "trim-right": { "version": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", - "integrity": "sha512-WZGXGstmCWgeevgTL54hrCuw1dyMQIzWy7ZfqRJfSmJZBwklI15egmQytFP6bPidmw3M8d5yEowl1niq4vmqZw==", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", "dev": true }, "true-case-path": { diff --git a/package.json b/package.json index f798f8f..524671d 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "ember-load-initializers": "^0.5.1", "ember-macro-helpers": "0.17.0", "ember-parachute": "0.1.0", + "ember-promise-helpers": "1.0.6", "ember-resolver": "^2.0.3", "ember-truth-helpers": "1.3.0", "ethers": "^3.0.8", diff --git a/tests/unit/lib/kredits/serializers/contributor-test.js b/tests/unit/lib/kredits/serializers/contributor-test.js new file mode 100644 index 0000000..9c08650 --- /dev/null +++ b/tests/unit/lib/kredits/serializers/contributor-test.js @@ -0,0 +1,53 @@ +import { module, test } from 'ember-qunit'; +import schemas from 'npm:kosmos-schemas'; +import tv4 from 'npm:tv4'; +import { ContributorSerializer } from 'kredits-web/lib/kredits'; + +module('Serializers contributor'); + +test('#serialize returns a valid JSON-LD representation', function(assert) { + let serialized = ContributorSerializer.serialize({ + name: 'Satoshi Nakamoto', + kind: 'person', + github_uid: 123, + github_username: 'therealsatoshi', + wiki_username: 'Satoshi', + }); + + let valid = tv4.validate(JSON.parse(serialized), schemas['contributor']); + assert.ok(valid); +}); + +test('#deserialize returns a valid object representation', function(assert) { + let json = JSON.stringify({ + "@context": "https://schema.kosmos.org", + "@type": "Contributor", + "kind": "person", + "name": "Satoshi Nakamoto", + "accounts": [ + { + "site": "github.com", + "uid": 123, + "username": "therealsatoshi", + "url": "https://github.com/therealsatoshi" + }, + { + "site": "wiki.kosmos.org", + "username": "Satoshi", + "url": "https://wiki.kosmos.org/User:Satoshi" + } + ] + }); + let deserialized = ContributorSerializer.deserialize(json); + + let expected = { + name: 'Satoshi Nakamoto', + kind: 'person', + github_uid: 123, + github_username: 'therealsatoshi', + wiki_username: 'Satoshi', + url: undefined, + ipfsData: json, + }; + assert.deepEqual(expected, deserialized); +}); diff --git a/tests/unit/models/contributor-test.js b/tests/unit/models/contributor-test.js index 39651f1..4261724 100644 --- a/tests/unit/models/contributor-test.js +++ b/tests/unit/models/contributor-test.js @@ -1,6 +1,4 @@ import { moduleFor, test } from 'ember-qunit'; -import schemas from 'npm:kosmos-schemas'; -import tv4 from 'npm:tv4'; moduleFor('model:contributor', 'Unit | Model | contributor'); @@ -10,17 +8,3 @@ test('#avatarURL() returns correct URL', function(assert) { assert.equal(model.get('avatarURL'), 'https://avatars2.githubusercontent.com/u/318?v=3&s=128'); }); - -test('#toJSON() returns a valid JSON-LD representation of the model', function(assert) { - let model = this.subject(); - - model.setProperties({ - name: 'Satoshi Nakamoto', - kind: 'person', - github_uid: 123, - github_username: 'therealsatoshi', - wiki_username: 'Satoshi', - }); - - assert.ok(tv4.validate(model.toJSON(), schemas['contributor'])); -});