UNPKG

google-admin-sdk

Version:

node.js library that wraps the Directory and Groups APIs in the Google Admin SDK

983 lines (890 loc) 36.4 kB
assert = require 'assert' async = require 'async' _ = require 'underscore' google_apis = require "#{__dirname}/../" nock = require 'nock' util = require 'util' # There are 3 large test suites in this file: # describe 'UserProvisioning' # describe 'OrgUnitProvisioning' # describe 'GroupProvisioning' before -> nock.disableNetConnect() beforeEach -> nock.cleanAll() describe 'Retry', -> before -> @retry_count = 5 @up = new google_apis.UserProvisioning token: access: 'fake access token' @up.retry_options = {minTimeout: 100, maxTimeout: 200, retries: @retry_count, randomize: true} # The following 2 test verifies that @up.get is indeed retrying for @retry_count times. # Including the initial request, there are retry_count + 1 total requests. it "retries for `retry_count` times but nocked for `(retry_count + 1)` times", (done) -> # Nock out all requests with failure nock('https://www.googleapis.com:443').get('/admin/directory/v1/users/1234567890') .times(@retry_count + 1).reply(500, 'FAIL') @up.get '1234567890', (err, data) -> assert.equal err, 'FAIL' done() it 'retries for retry_count times and nocked for retry_count times', (done) -> # Nock out all but last request with failure, so that on the (retry_count + 1)th request, # it attempts to make a real http request. nock('https://www.googleapis.com:443').get('/admin/directory/v1/users/1234567890') .times(@retry_count).reply(500, 'FAIL') @up.get '1234567890', (err, data) -> assert.equal err.name, 'NetConnectNotAllowedError' assert.equal err.message, 'Nock: Not allow net connect for "www.googleapis.com:443"' done() describe 'oauth2_request', -> it 'does not deadlock with request_refresh_token if no refresh token', (done) -> gsdk = new google_apis.AdminSDK token: refresh: 'sometoken' access: 'someaccess' client: id: 'someid' secret: 'somesecret' refresh_nock = nock('https://accounts.google.com:443') .filteringRequestBody(() -> return '*') .post('/o/oauth2/token', '*') .reply(400, 'no refresh from google') request_nock = nock('https://www.googleapis.com:443').get('/admin/directory/v1/users/1234') .reply(401, 'go request token refresh') opts = json: true uri: "https://www.googleapis.com/admin/directory/v1/users/1234" gsdk.oauth2_request opts, (err, dontcare) -> refresh_nock.done() request_nock.done() assert.equal err, 'no refresh from google' done() it 'does not deadlock with request_refresh_token if genuinely invalid credentials', (done) -> gsdk = new google_apis.AdminSDK token: refresh: 'sometoken' access: 'someaccess' client: id: 'someid' secret: 'somesecret' refresh_nock = nock('https://accounts.google.com:443') .filteringRequestBody(() -> return '*') .post('/o/oauth2/token', '*') .reply(200, 'okay, here you go') request_nock = nock('https://www.googleapis.com:443') .get('/admin/directory/v1/users/1234').reply(401, 'go request token refresh') .get('/admin/directory/v1/users/1234').reply(401, 'nope, genuinely invalid credentials') opts = json: true uri: "https://www.googleapis.com/admin/directory/v1/users/1234" gsdk.oauth2_request opts, (err, resp, body) -> refresh_nock.done() request_nock.done() assert.equal resp.statusCode, 401 assert.equal body, 'nope, genuinely invalid credentials' done() describe 'UserProvisioning', ()-> before -> @up = new google_apis.UserProvisioning token: access: 'fake access token' @up.retry_options = {minTimeout: 100, maxTimeout: 200, retries: 2, randomize: true} it 'requires domain, client_id, client_secret upon construction', (done) -> assert.throws () -> new google_apis.UserProvisioning() , Error done() it 'returns an error when an argument of wrong type is given', (done) -> async.waterfall [ (cb_wf) => @up.get 12345, (err, data) -> assert.equal err.toString(), 'Error: UserProvisioning::get requires (String userkey, [callback])' cb_wf() (cb_wf) => @up.insert 12345, (err, data) -> assert.equal err.toString(), "Error: UserProvisioning::insert expected (Object body, [callback])" cb_wf() (cb_wf) => @up.list 12345, (err, data) -> assert.equal err.toString(), "Error: UserProvisioning::list requires (Object params, [callback])" cb_wf() (cb_wf) => @up.patch 12345, (err, data) -> assert.equal err.toString(), "Error: UserProvisioning::patch expected (String userkey, [Object body, String fields, callback])" cb_wf() (cb_wf) => @up.delete 12345, (err, data) -> assert.equal err.toString(), "Error: UserProvisioning::delete expected (String userkey, [callback])" cb_wf() ], done ## GET ## it 'can get user by id', (done) -> body = kind: 'admin#directory#user' id: '1234567890' primaryEmail: 'george@domain.org' name: { givenName: 'George', familyName: 'Washington', fullName: 'George Washington' } isAdmin: false isDelegatedAdmin: false lastLoginTime: '1970-01-01T00:00:00.000Z' creationTime: '2013-02-20T21:29:18.000Z' agreedToTerms: true suspended: false changePasswordAtNextLogin: false ipWhitelisted: false emails: [{address: "george@domain.org", primary: true}] customerId: 'fake_customer_id' orgUnitPath: '/' isMailboxSetup: true includeInGlobalAddressList: true nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/users/1234567890') .reply(200, body) @up.get '1234567890', (err, data) -> assert.ifError err assert.deepEqual data, body done() it '404s when making get with bad userkey', (done) -> body = error: errors: [{ domain: "global", reason: "notFound", message: "Resource Not Found: userKey" }] code: 404 message: "Resource Not Found: userKey" nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/users/12345') .reply(404, body) @up.get '12345', (err, data) -> assert.deepEqual err, body done() ## LIST ## it 'gets partial response for field argument', (done) -> body = users: [ { name: { givenName: "George", familyName: "Washington", fullName: "George Washington" } } { name: { givenName: "Lhamo", familyName: "Dondrub", fullName: "Lhamo Dondrub" } } ] nextPageToken: "next_page" nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/users?domain=domain.org&maxResults=2&fields=users%2Fname%2C%20nextPageToken') .reply(200, body) @up.list {domain: 'domain.org', maxResults: 2, fields: 'users/name, nextPageToken'}, (err, data) -> assert.deepEqual data, body done() it 'gets users that match a query', (done) -> user = kind: 'admin#directory#user' id: '987654321' primaryEmail: 'betsyross@domain.org' name: { givenName: 'Betsy', familyName: 'Ross', fullName: 'Betsy Ross' } isAdmin: false isDelegatedAdmin: false lastLoginTime: '1970-01-01T00:00:00.000Z' creationTime: '2013-06-25T17:01:23.000Z' agreedToTerms: true suspended: false changePasswordAtNextLogin: false ipWhitelisted: false emails: [ { address: 'betsyross@domain.org', primary: true } ] customerId: 'fake_customer_id' orgUnitPath: '/' isMailboxSetup: true includeInGlobalAddressList: true body = kind: 'admin#directory#users' users: [user] nextPageToken: 'next_page' nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/users?domain=domain.org&maxResults=1&query=email%3Abetsy*') .reply(200, body) @up.list {domain: 'domain.org', maxResults: 1, query: 'email:betsy*'}, (err, data) -> assert.deepEqual data, body done() it 'gets paging info even when not explicitly requested', (done) -> body = users: [ { name: { givenName: "George", familyName: "Washington", fullName: "George Washington" } } { name: { givenName: "Lhamo", familyName: "Dondrub", fullName: "Lhamo Dondrub" } } ] nextPageToken: "next_page" nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/users?domain=domain.org&maxResults=2&fields=nextPageToken%2Cusers%2Fname') .reply(200, body) @up.list {domain: 'domain.org', maxResults: 2, fields: 'users/name'}, (err, data) -> assert.deepEqual data, body done() ## INSERT ## it 'creates a user', (done) -> post_body = name: {familyName: "Gandhi", givenName: "Mahatma"} password: "supersecurepassword12345" primaryEmail: "mgandhi@domain.org" resp_body = kind: "admin#directory#user" id: "1234567890" primaryEmail: "mgandhi@domain.org" name: { givenName: "Mahatma", familyName: "Gandhi" } isAdmin: false isDelegatedAdmin: false customerId: "fake_customer_id" orgUnitPath: "/" isMailboxSetup: false nock('https://www.googleapis.com:443').persist().post('/admin/directory/v1/users', post_body) .reply(200, resp_body) @up.insert post_body, (err, data) -> assert.deepEqual data, resp_body done() ## INSERT, and FAIL ## it 'sends a "Domain User Limit" when their domain has its max number of users', (done) -> # Lets pretend the domain is already at its user limit when we try to create this user post_body = name: {familyName: "Gandhi", givenName: "Mahatma"} password: "supersecurepassword12345" primaryEmail: "mgandhi@domain.org" error = error: errors: [ { domain: 'global', reason: 'DomainUserLimitExceeded', message: 'Domain user limit exceeded.' } ] code: 412 message: 'Domain user limit exceeded.' nock('https://www.googleapis.com:443').persist().post('/admin/directory/v1/users', post_body) .reply(412, error) @up.insert post_body, (err, data) -> assert.deepEqual error, err done() it 'creates a user and returns a partial response', (done) -> post_body = name: {familyName: "Gandhi", givenName: "Mahatma"} password: "supersecurepassword12345" primaryEmail: "mgandhi@domain.org" resp_body = id: "1234567890" primaryEmail: "mgandhi@domain.org" name: { givenName: "Mahatma", familyName: "Gandhi" } nock('https://www.googleapis.com:443').persist().post('/admin/directory/v1/users', post_body) .reply(200, resp_body) @up.insert post_body, 'name,primaryEmail,id', (err, data) -> assert.deepEqual data, resp_body done() it 'returns an error when trying to create a user without a required field', (done) -> post_body = name: {familyName: "Gandhi", givenName: "Mahatma"} password: "supersecurepassword12345" @up.insert post_body, (err, data) -> assert.equal(err.toString(), "Error: UserProvisioning::insert requires 'primaryEmail'") done() ## PATCH ## it 'updates a user', (done) -> req_body = {name: {familyName: 'Thatcher', givenName: 'Margaret'}} resp_body = kind: "admin#directory#user" id: "1234567890" primaryEmail: "mthatcher@domain.org" name: { givenName: "Margaret", familyName: "Thatcher" } isAdmin: false isDelegatedAdmin: false lastLoginTime: "1970-01-01T00:00:00.000Z" creationTime: "2013-06-25T19:41:26.000Z" agreedToTerms: true suspended: false changePasswordAtNextLogin: false ipWhitelisted: false emails: [{ address: "mthatcher@domain.org", primary: true }] customerId: "fake_customer_id" orgUnitPath: "/" isMailboxSetup: true includeInGlobalAddressList: true nock('https://www.googleapis.com:443').persist().patch('/admin/directory/v1/users/1234567890', req_body) .reply(200, resp_body) @up.patch '1234567890', req_body, (err, data) -> assert.deepEqual resp_body, data done() it '404s when updating with a bad userkey', (done) -> req_body = {} body = error: errors: [{ domain: "global", reason: "notFound", message: "Resource Not Found: userKey" }] code: 404 message: "Resource Not Found: userKey" nock('https://www.googleapis.com:443').persist().patch('/admin/directory/v1/users/12345', req_body) .reply(404, body) @up.patch '12345', req_body, (err, data) -> assert.deepEqual err, body done() it 'can correctly call patch with userkey, body, cb', (done) -> body = kind: 'admin#directory#user' id: '1234567890' primaryEmail: 'newemail@domain.org' name: {givenName: 'Benjamin', familyName: 'Newlastname', fullName: 'Benjamin Newlastname' } isAdmin: false isDelegatedAdmin: false lastLoginTime: '1970-01-01T00:00:00.000Z' creationTime: '2013-06-26T03:39:52.000Z' agreedToTerms: true suspended: false changePasswordAtNextLogin: false ipWhitelisted: false emails: [ { address: 'newemail@domain.org', type: 'custom', primary: true } ] customerId: 'fake_customer_id' orgUnitPath: '/' isMailboxSetup: true includeInGlobalAddressList: true patch_body = name: familyName: 'Newlastname' primaryEmail: 'newemail@domain.org' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/users/1234567890', patch_body) .reply(200, body) @up.patch '1234567890', patch_body, (err, data) -> assert.deepEqual data, body done() it 'can correctly call patch with userkey, fields, cb', (done) -> body = primaryEmail: 'newemail@domain.org' name: givenName: 'George' familyName: 'Newlastname' fullName: 'George Newlastname' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/users/1234567890?fields=name%2CprimaryEmail') .reply(200, body) @up.patch '1234567890', 'name,primaryEmail', (err, data) -> assert.deepEqual data, body done() ## DELETE ## it 'deletes a user', (done) -> body = {204: "Operation success"} nock('https://www.googleapis.com:443').persist().delete('/admin/directory/v1/users/1234567890') .reply(204, body) @up.delete '1234567890', (err, data) -> assert.deepEqual data, body done() it '404s when deleting a user with a bad userkey', (done) -> body = error: errors: [{ domain: "global", reason: "notFound", message: "Resource Not Found: userKey" }] code: 404 message: "Resource Not Found: userKey" nock('https://www.googleapis.com:443').persist().delete('/admin/directory/v1/users/12345') .reply(404, body) @up.delete '12345', (err, data) -> assert.deepEqual err, body done() describe 'OrgUnitProvisioning', ()-> ou_not_found = error: errors: [] code: 404, message: "Org unit not found" beforeEach -> @ou = new google_apis.OrgUnitProvisioning token: access: 'access_token' @ou.retry_options = {minTimeout: 100, maxTimeout: 200, retries: 2, randomize: true} it 'returns an error when an argument of wrong type is given', (done) -> async.waterfall [ (cb_wf) => @ou.get 12345, (err, data) -> assert.equal err.toString(), "Error: OrgUnit::get expected (String customer_id, String org_unit_path, [, String fields, callback])" cb_wf() (cb_wf) => @ou.insert 12345, (err, data) -> assert.equal err.toString(), "Error: OrgUnit::insert expected (String customer_id, Object properties[, String fields, callback])" cb_wf() (cb_wf) => @ou.list 12345, (err, data) -> assert.equal err.toString(), "Error: OrgUnit::list expected (String customer_id[, Object params, callback])" cb_wf() (cb_wf) => @ou.patch 12345, (err, data) -> assert.equal err.toString(), "Error: OrgUnit::patch expected (String customer_id, String org_unit_path, [Object patch_body, String fields, callback])" cb_wf() (cb_wf) => @ou.delete 12345, (err, data) -> assert.equal err.toString(), "Error: OrgUnit::delete expected (String customer_id, String org_unit_path[, callback])" cb_wf() ], done it 'can get an OrgUnit', (done) -> body = kind: 'admin#directory#orgUnit' name: 'RockyRoad' description: 'For people who like Rocky Road ice cream' orgUnitPath: '/RockyRoad' parentOrgUnitPath: '/' blockInheritance: false nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/customer/fake_customer_id/orgunits/RockyRoad') .reply(200, body) @ou.get 'fake_customer_id', 'RockyRoad', (err, data) -> assert.deepEqual data, body done() ## get_children it 'get_children makes a request to the right endpoint', (done) -> ou_path = "OrgUnitName" customer_id = "customer_123" mock_endpoint = nock('https://www.googleapis.com') .get("/admin/directory/v1/customer/#{customer_id}/orgunits?orgUnitPath=#{ou_path}&type=children") .reply(200, {body: "OK"}) @ou.get_children customer_id, ou_path, (err, data) -> assert.ifError err assert.deepEqual data, {body: "OK"} assert mock_endpoint.isDone() done() it 'can get an OrgUnit filtered by fields', (done) -> body = name: 'RockyRoad' description: 'For people who like Rocky Road ice cream' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/customer/fake_customer_id/orgunits/RockyRoad?fields=name%2Cdescription') .reply(200, body) @ou.get 'fake_customer_id', 'RockyRoad', 'name,description', (err, data) -> assert.deepEqual data, body done() it 'can list all org units for a customer', (done) -> body = kind: 'admin#directory#orgUnits', organizationUnits: [ kind: 'admin#directory#orgUnit' name: 'RockyRoad' description: '' orgUnitPath: '/RockyRoad' parentOrgUnitPath: '/' blockInheritance: false , kind: 'admin#directory#orgUnit' name: 'Vanilla' description: '' orgUnitPath: '/Vanilla' parentOrgUnitPath: '/' blockInheritance: false , kind: 'admin#directory#orgUnit' name: 'ChocolateChipCookieDough' description: '' orgUnitPath: '/ChocolateChipCookieDough' parentOrgUnitPath: '/' blockInheritance: false ] nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/customer/fake_customer_id/orgunits') .reply(200, body) @ou.list 'fake_customer_id', (err, data) -> assert.deepEqual data, body done() it 'can list an org unit by params', (done) -> body = kind: 'admin#directory#orgUnits', organizationUnits: [ { kind: 'admin#directory#orgUnit', name: 'OrgUnit1', description: '', orgUnitPath: '/ParentOU/OrgUnit1', parentOrgUnitPath: '/ParentOU', blockInheritance: false }, { kind: 'admin#directory#orgUnit', name: 'OrgUnit2', description: '', orgUnitPath: '/ParentOU/OrgUnit2', parentOrgUnitPath: '/ParentOU', blockInheritance: false } ] nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/customer/fake_customer_id/orgunits?orgUnitPath=ParentOU') .reply(200, body) @ou.list 'fake_customer_id', {orgUnitPath: 'ParentOU'}, (err, data) -> assert.deepEqual data, body done() it 'returns 400 with bad customer_id', (done) -> error = error: errors: [{ domain: "global", reason: "badRequest", message: "Bad Request" }] code: 400 message: "Bad Request" nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/customer/asdfasdf/orgunits') .reply(400, error) @ou.list 'asdfasdf', (err, data) -> assert.deepEqual err, error done() it 'uses cache for OU lookup', (done) -> org_unit = ['Students'] first_ou = kind: 'admin#directory#orgUnit' name: 'Students' orgUnitPath: '/Students' orgUnitId: 'ou_id1' parentOrgUnitPath: '/' second_ou = kind: 'admin#directory#orgUnit' name: 'Schoolname' orgUnitPath: '/Students/SchoolName' orgUnitId: 'ou_id2' parentOrgUnitPath: '/Students' cache = {} cache[first_ou.orgUnitPath] = first_ou cache[second_ou.orgUnitPath] = second_ou @ou.findOrCreate 'abcdef', org_unit, cache, (err, parent, returned_cache) -> # this test is successful if it hits the cache and doesn't trigger nock.disableNetConnect() assert.ifError err assert.deepEqual returned_cache, cache assert.equal parent, '/Students' done() it 'findOrCreate properly memoizes calls to get and insert', (done) -> org_unit = ['TestOU'] properties = name: 'TestOU' parentOrgUnitPath: '/' body = kind: 'admin#directory#orgUnit' name: org_unit[0] orgUnitPath: "/#{org_unit[0]}" orgUnitId: 'ou_id' parentOrgUnitPath: '/' customer_id = "fake_customer_id" nock('https://www.googleapis.com') .get("/admin/directory/v1/customer/#{customer_id}/orgunits/#{org_unit[0]}") .times(3) .reply(404, ou_not_found) insert_nock = nock('https://www.googleapis.com:443') .post("/admin/directory/v1/customer/#{customer_id}/orgunits", properties) .reply(200, body) expected_cache = {} expected_cache[body.orgUnitPath] = body # this test is successful if the nock is hit only once, and doesn't trigger nock.disableNetConnect() # on subsequent requests async.each [0..100], (i, cb_e) => @ou.findOrCreate customer_id, org_unit, {}, (err, parent, returned_cache) -> assert.ifError err assert.deepEqual returned_cache, expected_cache assert.equal parent, '/TestOU' cb_e() , done ## INSERT ## it 'creates an orgunit', (done) -> properties = name: 'TestOU' parentOrgUnitPath: '/' body = kind: 'admin#directory#orgUnit' name: 'TestOU' orgUnitPath: '/TestOU' orgUnitId: 'ou_id' parentOrgUnitPath: '/' nock('https://www.googleapis.com:443').persist().post('/admin/directory/v1/customer/fake_customer_id/orgunits', properties) .reply(200, body) @ou.insert 'fake_customer_id', properties, (err, data) -> assert.deepEqual data, body done() it 'returns an orgunit if it already exists', (done) -> properties = name: 'TestOUAlreadyExists' parentOrgUnitPath: '/' body = kind: 'admin#directory#orgUnit' name: 'TestOUAlreadyExists' orgUnitPath: '/TestOUAlreadyExists' orgUnitId: 'ou_id_already_exists' parentOrgUnitPath: '/' nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/customer/fake_customer_id/orgunits/TestOUAlreadyExists') .reply(200, body) @ou.findOrCreate 'fake_customer_id', ['TestOUAlreadyExists'], (err, parent, cache) -> assert.ifError err assert.deepEqual cache, {'/TestOUAlreadyExists': body} assert.equal parent, '/TestOUAlreadyExists' done() it 'creates an orgunit if not found', (done) -> properties = name: 'TestOUCreate' parentOrgUnitPath: '/' body = kind: 'admin#directory#orgUnit' name: 'TestOUCreate' orgUnitPath: '/TestOUCreate' orgUnitId: 'ou_id' parentOrgUnitPath: '/' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/customer/fake_customer_id/orgunits/TestOUCreate') .reply(404, ou_not_found) insert_nock = nock('https://www.googleapis.com:443') .post('/admin/directory/v1/customer/fake_customer_id/orgunits', properties) .reply(200, body) @ou.findOrCreate 'fake_customer_id', ['TestOUCreate'], (err, parent, cache) -> assert.ifError err assert.deepEqual cache, {'/TestOUCreate': body} assert.equal parent, '/TestOUCreate' insert_nock.done() done() it 'creates an orgunit with fields args for partial response', (done) -> properties = name: 'TestOU' parentOrgUnitPath: '/' fields = 'name, orgUnitPath' body = name: 'TestOU' orgUnitPath: '/TestOU' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/customer/fake_customer_id/orgunits/TestOU') .reply(404, ou_not_found) nock('https://www.googleapis.com:443').persist() .post('/admin/directory/v1/customer/fake_customer_id/orgunits?fields=name%2C%20orgUnitPath', properties) .reply(200, body) @ou.insert 'fake_customer_id', properties, fields, (err, data) -> assert.deepEqual data, body done() it 'fails to create an orgunit when invalid customer_id is given', (done) -> properties = name: 'TestOU' parentOrgUnitPath: '/' error = error: errors: [{ domain: "global", reason: "badRequest", message: "Bad Request" }] code: 400 message: "Bad Request" nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/customer/fake_customer_id/orgunits/TestOU') .reply(404, ou_not_found) nock('https://www.googleapis.com:443').persist() .post('/admin/directory/v1/customer/badId/orgunits', properties) .reply(400, error) @ou.insert 'badId', properties, (err, data) -> assert.deepEqual err, error done() it 'fails to create an orgunit when required properties are not given', (done) -> properties = name: 'TestOU4' error = error: errors: [ { domain: 'global', reason: 'invalid', message: 'Invalid Parent Orgunit Id' } ] code: 400 message: 'Invalid Parent Orgunit Id' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/customer/fake_customer_id/orgunits/TestOU') .reply(404, ou_not_found) nock('https://www.googleapis.com:443').persist() .post('/admin/directory/v1/customer/fake_customer_id/orgunits', properties) .reply(400, error) @ou.insert 'fake_customer_id', properties, (err, data) -> assert.deepEqual err, error done() ## DELETE ## it 'deletes an orgunit', (done) -> body = { 204: 'Operation success' } nock('https://www.googleapis.com:443').persist().delete('/admin/directory/v1/customer/fake_customer_id/orgunits/DeleteThis') .reply(204, body) @ou.delete 'fake_customer_id', 'DeleteThis', (err, data) -> assert.deepEqual data, body done() it '404s when trying to delete a nonexistant an orgunit', (done) -> error = error: errors: [ { domain: 'global', reason: 'notFound', message: 'Org unit not found' } ] code: 404 message: 'Org unit not found' nock('https://www.googleapis.com:443').persist().delete('/admin/directory/v1/customer/fake_customer_id/orgunits/doesnotexist') .reply(404, error) @ou.delete 'fake_customer_id', 'doesnotexist', (err, data) -> assert.deepEqual err, error done() ## PATCH ## it 'updates an OrgUnit', (done) -> patch_body = {name: 'UpdatedName'} body = kind: 'admin#directory#orgUnit' name: 'UpdatedName' orgUnitPath: '/UpdatedName' parentOrgUnitPath: '/' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/customer/fake_customer_id/orgunits/UpdateThisName', patch_body) .reply(200, body) @ou.patch 'fake_customer_id', 'UpdateThisName', patch_body, (err, data) -> assert.deepEqual data, body done() it 'updates an OrgUnit and returns a partial response', (done) -> patch_body = {name: 'UpdatedName'} body = name: 'UpdatedName' orgUnitPath: '/UpdatedName' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/customer/fake_customer_id/orgunits/UpdateThisName?fields=name%2CorgUnitPath', patch_body) .reply(200, body) @ou.patch 'fake_customer_id', 'UpdateThisName', patch_body, 'name,orgUnitPath', (err, data) -> assert.deepEqual data, body done() it 'can call update with no patch_body', (done) -> body = { name: 'UpdateThisName' } nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/customer/fake_customer_id/orgunits/UpdateThisName?fields=name') .reply(200, body) @ou.patch 'fake_customer_id', 'UpdateThisName', 'name', (err, data) -> assert.deepEqual data, body done() it 'update returns an error when called with an invalid customer_id', (done) -> error = errors: [ { domain: 'global', reason: 'authError', message: 'Invalid Credentials', locationType: 'header', location: 'Authorization' } ] code: 401 message: 'Invalid Credentials' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/customer/bad_id/orgunits/UpdateThisName?fields=name') .reply(401, error) @ou.patch 'bad_id', 'UpdateThisName', 'name', (err, data) -> assert.deepEqual err, error done() describe 'GroupProvisioning', ()-> before -> @gp = new google_apis.GroupProvisioning token: access: 'fake_access_token' @gp.retry_options = {minTimeout: 100, maxTimeout: 200, retries: 2, randomize: true} it 'returns an error when an argument of wrong type is given', (done) -> async.waterfall [ (cb_wf) => @gp.get 12345, (err, data) -> assert.equal err.toString(), "Error: GroupProvisioning::get expected (String group_key[, callback])" cb_wf() (cb_wf) => @gp.insert 12345, (err, data) -> assert.equal err.toString(), "Error: GroupProvisioning::insert expected (Object properties[, String fields, callback])" cb_wf() (cb_wf) => @gp.list 12345, (err, data) -> assert.equal err.toString(), "Error: GroupProvisioning::list expected (Object params[, callback])" cb_wf() (cb_wf) => @gp.patch 12345, (err, data) -> assert.equal err.toString(), "Error: GroupProvisioning::delete expected (String group_key[, Object body, String fields, callback])" cb_wf() (cb_wf) => @gp.delete 12345, (err, data) -> assert.equal err.toString(), "Error: GroupProvisioning::delete expected (String group_key[, callback])" cb_wf() ], done ## LIST ## it 'lists groups for a domain', (done) -> body = kind: 'admin#directory#groups' groups: [{ id: 'abcd1234' email: 'group1@domain.org', name: 'Group1', description: 'the first group' }] nextPageToken: 'next_page' params = domain: 'domain.org' maxResults: 1 fields: 'groups(description,email,id,name),kind,nextPageToken' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/groups?domain=domain.org&maxResults=1&fields=groups(description%2Cemail%2Cid%2Cname)%2Ckind%2CnextPageToken') .reply(200, body) @gp.list params, (err, data) -> assert.deepEqual data, body done() it 'returns an error when an invalid param is given', (done) -> params = domain: 'domain.org' maxResults: 1 unknown_field: true @gp.list params, (err, data) -> assert.equal err.toString(), "Error: GroupProvisioning::list invalid param 'unknown_field'" done() it 'returns 404 for a valid parameter that doesn not exist', (done) -> params = domain: 'badexample.com' maxResults: 1 error = errors: [ { domain: 'global', reason: 'notFound', message: 'Resource Not Found: badexample.com' } ] code: 404 message: 'Resource Not Found: badexample.com' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/groups?domain=badexample.com&maxResults=1') .reply(404, error) @gp.list params, (err, data) -> assert.deepEqual err, error done() ## GET ## it 'can get group by group_key', (done) -> body = kind: 'admin#directory#group' id: 'abcd1234' email: 'group1@domain.org' name: 'Group1' description: 'the first group' adminCreated: true nock('https://www.googleapis.com:443').persist().get('/admin/directory/v1/groups/abcd1234') .reply(200, body) @gp.get 'abcd1234', (err, data) -> assert.deepEqual data, body done() it '404s when trying to get a group by invalid group_key', (done) -> error = error: errors: [ { domain: 'global', reason: 'notFound', message: 'Resource Not Found: groupKey' } ] code: 404 message: 'Resource Not Found: groupKey' nock('https://www.googleapis.com:443').persist() .get('/admin/directory/v1/groups/badkey') .reply(404, error) @gp.get 'badkey', (err, data) -> assert.deepEqual err, error done() ## INSERT ## it 'can insert a group', (done) -> fields = 'description,email,id' body = id: 'abcd1234' email: 'newgroup@domain.org' description: 'new test group' properties = email: 'newgroup@domain.org' description: 'new test group' nock('https://www.googleapis.com:443').persist().post('/admin/directory/v1/groups?fields=description%2Cemail%2Cid', properties) .reply(200, body) @gp.insert properties, fields, (err, data) -> assert.deepEqual data, body done() it 'returns an error when trying to insert a group without required properties', (done) -> error = error: errors: [ { domain: 'global', reason: 'required', message: 'Missing required field: email' } ] code: 400 message: 'Missing required field: email' properties = description: 'no email for this group' nock('https://www.googleapis.com:443').persist().post('/admin/directory/v1/groups', properties) .reply(400, error) @gp.insert properties, (err, data) -> assert.deepEqual err, error done() ## DELETE ## it 'can delete a group', (done) -> nock('https://www.googleapis.com:443').persist() .delete('/admin/directory/v1/groups/abcd1234') .reply(204, "") @gp.delete 'abcd1234', (err, data) -> assert.deepEqual data, { 204: 'Operation success'} done() it 'delete returns an error when a nonstring group_key is given', (done) -> @gp.delete 12345, (err, data) -> assert.equal err.toString(), 'Error: GroupProvisioning::delete expected (String group_key[, callback])' done() it 'returns an error when a nonexistant group_key is given', (done) -> error = error: errors: [ { domain: 'global', reason: 'notFound', message: 'Resource Not Found: groupKey' } ] code: 404 message: 'Resource Not Found: groupKey' nock('https://www.googleapis.com:443').persist() .delete('/admin/directory/v1/groups/asdf1234asdf') .reply(404, error) @gp.delete 'asdf1234asdf', (err, data) -> assert.deepEqual err, error done() it 'updates a group', (done) -> req_body = name: 'Updated group' description: 'new description' resp_body = id: 'abcd1234' email: 'group1@domain.org' name: 'Updated group' description: 'new description' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/groups/abcd1234?fields=id%2Cname%2Cdescription%2Cemail', req_body) .reply(200, resp_body) @gp.patch 'abcd1234', req_body, 'id,name,description,email', (err, data) -> assert.deepEqual data, resp_body done() it '404s when updating with a bad group_key', (done) -> req_body = {name: 'Updated group'} error = error: errors: [ { domain: 'global', reason: 'notFound', message: 'Resource Not Found: groupKey' } ] code: 404, message: 'Resource Not Found: groupKey' nock('https://www.googleapis.com:443').persist() .patch('/admin/directory/v1/groups/12345', req_body) .reply(404, error) @gp.patch '12345', req_body, (err, data) -> assert.deepEqual err, error done()