Skip to content

Commit

Permalink
feat: data model for organizations
Browse files Browse the repository at this point in the history
  • Loading branch information
alinarublea committed Jan 17, 2024
1 parent 8a413fd commit 261a9d7
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ const Organization = (data = {}) => {
*/
self.updateName = (name) => {
if (!hasText(name)) {
throw new Error('Name must be provided');
throw new Error('Org name must be provided');
}

self.state.name = name;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
/* eslint-env mocha */
import { expect } from 'chai';
import { createOrganization } from '../../../src/models/organization.js';
import { sleep } from '../util.js';

const validData = {
id: '1111111',
Expand Down Expand Up @@ -60,29 +61,90 @@ describe('Organization Model Tests', () => {
expect(config.alerts).to.be.an('array');
expect(config.slack.workspace).to.equal('workspace');
expect(config.slack.channel).to.equal('channel');
expect(config.alerts[0].mentions[0].slack[0]).to.equal('slackId');
});
});

describe('Organization Object Functionality', () => {
let organization;

beforeEach(() => {
organization = createOrganization(validData);
});

it('updates name correctly', () => {
const name = 'newOrgName123';
organization.updateName(name);
expect(organization.getName()).to.equal(name);
});

it('updates imsOrgId correctly', () => {
const imsOrgId = 'newImsOrg123';
organization.updateImsOrgId(imsOrgId);
expect(organization.getImsOrgId()).to.equal(imsOrgId);
});

it('updates config correctly', () => {
const conf = {
slack: {
workspace: 'workspace',
channel: 'channel',
},
alerts: [{
type: '404',
byOrg: false,
mentions: [{ slack: ['slackId'] }],
}],
};
organization.updateConfig(conf);
const updatedConf = organization.getConfig();
expect(updatedConf.slack).to.be.an('object');
expect(updatedConf.alerts).to.be.an('array');
expect(updatedConf.slack.workspace).to.equal('workspace');
expect(updatedConf.slack.channel).to.equal('channel');
expect(updatedConf.alerts[0].mentions[0].slack[0]).to.equal('slackId');
});

it('throws an error when updating with an empty name', () => {
expect(() => organization.updateName('')).to.throw('Org name must be provided');
});

it('throws an error when updating with an invalid name', () => {
it('throws an error when updating with an empty imsOrgId', () => {
expect(() => organization.updateImsOrgId('')).to.throw('IMS Org ID must be provided');
});

it('throws an error when updating with an invalid config', () => {
expect(() => organization.updateConfig('abcd')).to.throw('Config must be provided');
});

it('updates updatedAt when imsOrgId is updated', async () => {
const initialUpdatedAt = organization.getUpdatedAt();

await sleep(20);

organization.updateName('Name123');

expect(organization.getUpdatedAt()).to.not.equal(initialUpdatedAt);
});

it('updates updatedAt when name is updated', async () => {
const initialUpdatedAt = organization.getUpdatedAt();

await sleep(20);

organization.updateImsOrgId('imsOrg123');

expect(organization.getUpdatedAt()).to.not.equal(initialUpdatedAt);
});

it('updates updatedAt when config is updated', async () => {
const initialUpdatedAt = organization.getUpdatedAt();

await sleep(20);

organization.updateName('Name123');

expect(organization.getUpdatedAt()).to.not.equal(initialUpdatedAt);
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,178 @@
/*
* Copyright 2023 Adobe. All rights reserved.
* This file is licensed to you under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License. You may obtain a copy
* of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under
* the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS
* OF ANY KIND, either express or implied. See the License for the specific language
* governing permissions and limitations under the License.
*/

/* eslint-env mocha */

import chai from 'chai';
import chaiAsPromised from 'chai-as-promised';
import sinon from 'sinon';

import { organizationFunctions } from '../../../../src/service/organizations/index.js';
import { createOrganization } from '../../../../src/models/organization.js';

chai.use(chaiAsPromised);

const { expect } = chai;

const TEST_DA_CONFIG = {
tableNameOrganizations: 'spacecat-services-organizations',
indexNameAllOrganizations: 'spacecat-services-all-organizations',
pkAllOrganizations: 'ALL_ORGANIZATIONS',
};

describe('Organization Access Pattern Tests', () => {
describe('Organization Functions Export Tests', () => {
const mockDynamoClient = {};
const mockLog = {};

const exportedFunctions = organizationFunctions(mockDynamoClient, TEST_DA_CONFIG, mockLog);

it('exports getOrganizations function', () => {
expect(exportedFunctions).to.have.property('getOrganizations');
expect(exportedFunctions.getOrganizations).to.be.a('function');
});

it('exports getOrganizationByID function', () => {
expect(exportedFunctions).to.have.property('getOrganizationByID');
expect(exportedFunctions.getOrganizationByID).to.be.a('function');
});
});

describe('Organization Functions Tests', () => {
let mockDynamoClient;
let mockLog;
let exportedFunctions;

beforeEach(() => {
mockDynamoClient = {
query: sinon.stub().returns(Promise.resolve([])),
getItem: sinon.stub().returns(Promise.resolve(null)),
};
mockLog = { log: sinon.stub() };

exportedFunctions = organizationFunctions(mockDynamoClient, TEST_DA_CONFIG, mockLog);
});

it('calls getOrganizations and returns an array', async () => {
const result = await exportedFunctions.getOrganizations();
expect(result).to.be.an('array');
expect(mockDynamoClient.query.called).to.be.true;
});

it('calls getOrganizationByID and returns null', async () => {
const result = await exportedFunctions.getOrganizationByID();
expect(result).to.be.null;
expect(mockDynamoClient.getItem.called).to.be.true;
});

it('calls getOrganizationByID and returns site', async () => {
const mockOrgData = {
id: 'organization1',
name: 'Organization1',
};

mockDynamoClient.getItem.onFirstCall().resolves(mockOrgData);

const result = await exportedFunctions.getOrganizationByID();

expect(result).to.be.an('object');
expect(result.getId()).to.equal(mockOrgData.id);
expect(result.getName()).to.equal(mockOrgData.name);
expect(mockDynamoClient.getItem.called).to.be.true;
});

describe('addOrganization Tests', () => {
beforeEach(() => {
mockDynamoClient = {
query: sinon.stub().returns(Promise.resolve([])),
putItem: sinon.stub().returns(Promise.resolve()),
};
mockLog = { log: sinon.stub() };
exportedFunctions = organizationFunctions(mockDynamoClient, TEST_DA_CONFIG, mockLog);
});

it('adds a new organization successfully', async () => {
const orgData = { name: 'Org1' };
const result = await exportedFunctions.addOrganization(orgData);
expect(mockDynamoClient.putItem.calledOnce).to.be.true;
expect(result.getName()).to.equal(orgData.name);
expect(result.getId()).to.be.a('string');
});
});
});

describe('updateOrganization Tests', () => {
let mockDynamoClient;
let mockLog;
let exportedFunctions;

beforeEach(() => {
mockDynamoClient = {
getItem: sinon.stub().returns(Promise.resolve()),
putItem: sinon.stub().returns(Promise.resolve()),
};
mockLog = { log: sinon.stub() };
exportedFunctions = organizationFunctions(mockDynamoClient, TEST_DA_CONFIG, mockLog);
});

it('updates an existing organization successfully', async () => {
const orgData = { name: 'Org1' };
mockDynamoClient.getItem.resolves(Promise.resolve(orgData));

const org = await exportedFunctions.getOrganizationByID('id1');
// site.updateBaseURL('https://newsite.com');
org.updateImsOrgId('newOrg123');

const result = await exportedFunctions.updateOrganization(org);
expect(mockDynamoClient.putItem.calledOnce).to.be.true;
expect(result.getName()).to.equal(org.getName());
expect(result.getImsOrgId()).to.equal(org.getImsOrgId());
});

it('throws an error if organization does not exist', async () => {
const org = createOrganization({ name: 'Org1' });
await expect(exportedFunctions.updateOrganization(org)).to.be.rejectedWith('Organization not found');
});
});

describe('removeOrganization Tests', () => {
let mockDynamoClient;
let mockLog;
let exportedFunctions;

beforeEach(() => {
mockDynamoClient = {
query: sinon.stub().returns(Promise.resolve([])),
removeItem: sinon.stub().returns(Promise.resolve()),
};
mockLog = {
log: sinon.stub(),
error: sinon.stub(),
};
exportedFunctions = organizationFunctions(mockDynamoClient, TEST_DA_CONFIG, mockLog);
});

it('removes the organization', async () => {
await exportedFunctions.removeOrganization('some-id');

expect(mockDynamoClient.removeItem.calledOnce).to.be.true;
});

it('logs an error and reject if the organization removal fails', async () => {
const errorMessage = 'Failed to delete org';
mockDynamoClient.removeItem.rejects(new Error(errorMessage));

await expect(exportedFunctions.removeOrganization('some-id')).to.be.rejectedWith(errorMessage);
expect(mockLog.error.calledOnce).to.be.true;
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ const TEST_DA_CONFIG = {
tableNameSites: 'test-sites',
indexNameAllSites: 'test-index-all-sites',
indexNameAllSitesByDeliveryType: 'test-index-all-sites-by-delivery-type',
indexNameAllSitesOrganizations: 'test-index-all-sites-organizations',
indexNameAllLatestAuditScores: 'test-index-all-latest-audit-scores',
pkAllSites: 'test-pk-all-sites',
pkAllLatestAudits: 'test-pk-all-latest-audits',
Expand All @@ -51,6 +52,11 @@ describe('Site Access Pattern Tests', () => {
expect(exportedFunctions.getSitesByDeliveryType).to.be.a('function');
});

it('exports getSitesByOrganizationId function', () => {
expect(exportedFunctions).to.have.property('getSitesByOrganizationId');
expect(exportedFunctions.getSitesByOrganizationId).to.be.a('function');
});

it('exports getSitesToAudit function', () => {
expect(exportedFunctions).to.have.property('getSitesToAudit');
expect(exportedFunctions.getSitesToAudit).to.be.a('function');
Expand Down

0 comments on commit 261a9d7

Please sign in to comment.