diff --git a/README.md b/README.md index a4b1fb0..a8f9768 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,9 @@ this.get('store').query('github-release', { repo: 'jimmay5469/old-hash' }); // g this.get('store').queryRecord('github-pull', { repo: 'jimmay5469/old-hash', pullId: 1 }); // get a specific pull request this.get('store').query('github-pull', { repo: 'jimmay5469/old-hash' }); // get a repo's pull requests this.get('store').queryRecord('github-blob', { repo: 'jimmay5469/old-hash', sha: '47c5438403ca875f170db2aa07d1bfa3689406e3' }); // get a file's contents + +this.get('store').findRecord('github-organization', { org: 'my-org' }); +this.get('store').query('github-members', { org: 'my-org' }) ``` ## Contributing diff --git a/addon/adapters/github-member.js b/addon/adapters/github-member.js new file mode 100644 index 0000000..88be2e0 --- /dev/null +++ b/addon/adapters/github-member.js @@ -0,0 +1,10 @@ +import GithubAdapter from 'ember-data-github/adapters/github'; + +export default GithubAdapter.extend({ + urlForQuery(query) { + const org = query.org; + delete query.org; + + return `${this.get('host')}/orgs/${org}/members`; + }, +}); diff --git a/addon/models/github-member.js b/addon/models/github-member.js new file mode 100644 index 0000000..95142e3 --- /dev/null +++ b/addon/models/github-member.js @@ -0,0 +1,11 @@ +import Model from 'ember-data/model'; +import attr from 'ember-data/attr'; + +export default Model.extend({ + login: attr('string'), + avatarUrl: attr('string'), + gravatarId: attr('string'), + type: attr('string'), + siteAdmin: attr('boolean'), + url: attr('string') +}); diff --git a/addon/models/github-organization.js b/addon/models/github-organization.js index 84b8e6b..56525e1 100644 --- a/addon/models/github-organization.js +++ b/addon/models/github-organization.js @@ -7,6 +7,6 @@ export default Model.extend({ name: attr('string'), avatarUrl: attr('string'), - users: hasMany('github-user'), + members: hasMany('github-member', { inverse: null }), repositories: hasMany('github-repository') }); diff --git a/addon/serializers/github-member.js b/addon/serializers/github-member.js new file mode 100644 index 0000000..65d0e53 --- /dev/null +++ b/addon/serializers/github-member.js @@ -0,0 +1,3 @@ +import GithubSerializer from './github'; + +export default GithubSerializer.extend({}); diff --git a/addon/serializers/github-organization.js b/addon/serializers/github-organization.js index 97d1f22..e5c34c9 100644 --- a/addon/serializers/github-organization.js +++ b/addon/serializers/github-organization.js @@ -4,7 +4,7 @@ export default GithubSerializer.extend({ normalize(modelClass, resourceHash, prop) { resourceHash.id = resourceHash.recordId || resourceHash.login; resourceHash.links = { - users: resourceHash.members_url.replace(/\{\/member\}/, ''), + members: resourceHash.members_url.replace(/\{\/member\}/, ''), repositories: resourceHash.repos_url }; return this._super(modelClass, resourceHash, prop); diff --git a/app/adapters/github-member.js b/app/adapters/github-member.js new file mode 100644 index 0000000..c1cff29 --- /dev/null +++ b/app/adapters/github-member.js @@ -0,0 +1 @@ +export { default } from 'ember-data-github/adapters/github-member'; diff --git a/app/mirage-factories/github-member.js b/app/mirage-factories/github-member.js new file mode 100644 index 0000000..c37e06d --- /dev/null +++ b/app/mirage-factories/github-member.js @@ -0,0 +1 @@ +export { default } from 'ember-data-github/mirage-factories/github-member'; diff --git a/app/mirage-models/github-member.js b/app/mirage-models/github-member.js new file mode 100644 index 0000000..e62db26 --- /dev/null +++ b/app/mirage-models/github-member.js @@ -0,0 +1 @@ +export { default } from 'ember-data-github/mirage-models/github-member'; diff --git a/app/models/github-member.js b/app/models/github-member.js new file mode 100644 index 0000000..8eb1278 --- /dev/null +++ b/app/models/github-member.js @@ -0,0 +1 @@ +export { default } from 'ember-data-github/models/github-member'; diff --git a/app/serializers/github-member.js b/app/serializers/github-member.js new file mode 100644 index 0000000..0982e32 --- /dev/null +++ b/app/serializers/github-member.js @@ -0,0 +1 @@ +export { default } from 'ember-data-github/serializers/github-member'; diff --git a/tests/acceptance/github-organization-test.js b/tests/acceptance/github-organization-test.js index dc30c6c..f125ae7 100644 --- a/tests/acceptance/github-organization-test.js +++ b/tests/acceptance/github-organization-test.js @@ -58,3 +58,20 @@ test(`finding an organization's repositories`, function (assert) { }); }); }); + +test(`finding an organization's members`, function (assert) { + assert.expect(4); + server.create('github-organization', 'withMembers'); + container.lookup('service:github-session').set('githubAccessToken', 'abc123'); + + return run(() => { + return store.findRecord('githubOrganization', 'organization0').then((organization) => { + return organization.get('members').then(function (members) { + assert.equal(members.get('length'), 2); + assert.githubMemberOk(members.toArray()[0]); + assert.equal(server.pretender.handledRequests.length, 2); + assert.equal(server.pretender.handledRequests[1].requestHeaders.Authorization, 'token abc123'); + }); + }); + }); +}); diff --git a/tests/dummy/mirage/config.js b/tests/dummy/mirage/config.js index b98d809..85f614c 100644 --- a/tests/dummy/mirage/config.js +++ b/tests/dummy/mirage/config.js @@ -80,4 +80,8 @@ export default function() { this.get('orgs/:org/repos', (schema, { params }) => { return schema.githubOrganizations.findBy({ login: params.org }).repositories; }); + + this.get('orgs/:org/members', (schema, { params }) => { + return schema.githubOrganizations.findBy({ login: params.org }).members; + }); } diff --git a/tests/dummy/mirage/factories/github-member.js b/tests/dummy/mirage/factories/github-member.js new file mode 100644 index 0000000..711d0e5 --- /dev/null +++ b/tests/dummy/mirage/factories/github-member.js @@ -0,0 +1,16 @@ +import { Factory } from 'ember-cli-mirage'; + +export default Factory.extend({ + login: function(i) { + return `member${i}`; + }, + type: 'github-member', + avatar_url: function(i) { + return `member${i}-avatar.gif`; + }, + gravatar_id: '', + site_admin: false, + url: function(i) { + return `https://api.github.com/users/member${i}`; + } +}); diff --git a/tests/dummy/mirage/factories/github-organization.js b/tests/dummy/mirage/factories/github-organization.js index 66bb0b3..4bdbb20 100644 --- a/tests/dummy/mirage/factories/github-organization.js +++ b/tests/dummy/mirage/factories/github-organization.js @@ -22,4 +22,9 @@ export default Factory.extend({ server.createList('githubRepository', 2, { owner: organization }); } }), + withMembers: trait({ + afterCreate(organization) { + server.createList('githubMember', 2, { organization }); + } + }) }); diff --git a/tests/dummy/mirage/models/github-member.js b/tests/dummy/mirage/models/github-member.js new file mode 100644 index 0000000..df54a72 --- /dev/null +++ b/tests/dummy/mirage/models/github-member.js @@ -0,0 +1,5 @@ +import { Model, belongsTo } from 'ember-cli-mirage'; + +export default Model.extend({ + organization: belongsTo('github-organization') +}); diff --git a/tests/dummy/mirage/models/github-organization.js b/tests/dummy/mirage/models/github-organization.js index a32af38..e266c72 100644 --- a/tests/dummy/mirage/models/github-organization.js +++ b/tests/dummy/mirage/models/github-organization.js @@ -1,6 +1,6 @@ import { Model, hasMany } from 'ember-cli-mirage'; export default Model.extend({ - users: hasMany('github-user'), + members: hasMany('github-member'), repositories: hasMany('github-repository') }); diff --git a/tests/helpers/custom-helpers/assert-github-member-ok.js b/tests/helpers/custom-helpers/assert-github-member-ok.js new file mode 100644 index 0000000..70e3ee3 --- /dev/null +++ b/tests/helpers/custom-helpers/assert-github-member-ok.js @@ -0,0 +1,20 @@ +import { registerHelper } from '@ember/test'; +import QUnit from 'qunit'; +import assertionBuilder from '../utils/defined-attribute-assertion-builder'; + +QUnit.assert.githubMemberOk = assertionBuilder([ + 'id', + 'login', + 'avatarUrl', + 'gravatarId', + 'url', + 'type', + 'siteAdmin' +]); + +export default registerHelper( + 'assertGithubMemberOk', + function (app, assert, member) { + assert.githubMemberOk(member); + } +); diff --git a/tests/helpers/start-app.js b/tests/helpers/start-app.js index b2af9db..3b16687 100644 --- a/tests/helpers/start-app.js +++ b/tests/helpers/start-app.js @@ -11,6 +11,7 @@ import './custom-helpers/assert-github-release-ok'; import './custom-helpers/assert-github-blob-ok'; import './custom-helpers/assert-github-tree-ok'; import './custom-helpers/assert-github-pull-ok'; +import './custom-helpers/assert-github-member-ok'; export default function startApp(attrs) { let attributes = merge({}, config.APP); diff --git a/tests/unit/adapters/github-member-test.js b/tests/unit/adapters/github-member-test.js new file mode 100644 index 0000000..1926913 --- /dev/null +++ b/tests/unit/adapters/github-member-test.js @@ -0,0 +1,16 @@ +import { moduleFor, test } from 'ember-qunit'; + +moduleFor('adapter:github-member', 'Unit | Adapter | github member', { + needs: ['service:github-session'] +}); + +test('it builds the organization\'s members URL correctly', function(assert) { + let adapter = this.subject(); + const host = adapter.get('host'); + const org = 'ember'; + const query = { + org, + }; + + assert.equal(adapter.buildURL('github-member', null, null, 'query', query), `${host}/orgs/${org}/members`); +}); diff --git a/tests/unit/adapters/github-organization-test.js b/tests/unit/adapters/github-organization-test.js index 31e3106..6029057 100644 --- a/tests/unit/adapters/github-organization-test.js +++ b/tests/unit/adapters/github-organization-test.js @@ -16,7 +16,7 @@ test('it builds the index URL correctly', function(assert) { assert.equal(adapter.buildURL('organizations', null, null), `${host}/orgs`); }); -test('it build the specified org URL correctly', function(assert) { +test('it builds the specified org URL correctly', function(assert) { let adapter = this.subject(); const host = adapter.get('host'); const org = 'ember'; diff --git a/tests/unit/models/github-member-test.js b/tests/unit/models/github-member-test.js new file mode 100644 index 0000000..9c88217 --- /dev/null +++ b/tests/unit/models/github-member-test.js @@ -0,0 +1,12 @@ +import { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('github-member', 'Unit | Model | github member', { + // Specify the other units that are required for this test. + needs: [] +}); + +test('it exists', function(assert) { + let model = this.subject(); + // let store = this.store(); + assert.ok(!!model); +}); diff --git a/tests/unit/serializers/github-member-test.js b/tests/unit/serializers/github-member-test.js new file mode 100644 index 0000000..e37ea3c --- /dev/null +++ b/tests/unit/serializers/github-member-test.js @@ -0,0 +1,15 @@ +import { moduleForModel, test } from 'ember-qunit'; + +moduleForModel('github-member', 'Unit | Serializer | github member', { + // Specify the other units that are required for this test. + needs: ['serializer:github-member'] +}); + +// Replace this with your real tests. +test('it serializes records', function(assert) { + let record = this.subject(); + + let serializedRecord = record.serialize(); + + assert.ok(serializedRecord); +}); diff --git a/tests/unit/serializers/github-organization-test.js b/tests/unit/serializers/github-organization-test.js index 00d8ffb..34a64df 100644 --- a/tests/unit/serializers/github-organization-test.js +++ b/tests/unit/serializers/github-organization-test.js @@ -6,7 +6,7 @@ moduleForModel('github-organization', 'Unit | Serializer | github organization', 'serializer:github-organization', 'model:githubRepository', 'model:githubBranch', - 'model:githubUser' + 'model:githubMember' ] });