@friggframework/core 2.0.0--canary.397.1b51778.0 → 2.0.0--canary.397.3862908.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -2,10 +2,10 @@ const _ = require('lodash');
2
2
  const { mongoose } = require('../../database/mongoose');
3
3
  const { expect } = require('chai');
4
4
  const { IntegrationBase } = require("../integration-base");
5
- const {Credential} = require('../../module-plugin/credential');
6
- const {Entity} = require('../../module-plugin/entity');
5
+ const { Credential } = require('../../module-plugin/credential');
6
+ const { Entity } = require('../../module-plugin/entity');
7
7
  const { IntegrationMapping } = require('../integration-mapping')
8
- const {IntegrationModel} = require("../integration-model");
8
+ const { IntegrationModel } = require("../integration-model");
9
9
 
10
10
  describe(`Should fully test the IntegrationBase Class`, () => {
11
11
  let integrationRecord;
@@ -93,15 +93,15 @@ describe(`Should fully test the IntegrationBase Class`, () => {
93
93
  describe('upsertIntegrationMapping()', () => {
94
94
  it('should throw error if sourceId is null', async () => {
95
95
  try {
96
- await integration.upsertMapping( null, {});
96
+ await integration.upsertMapping(null, {});
97
97
  fail('should have thrown error')
98
- } catch(err) {
98
+ } catch (err) {
99
99
  expect(err.message).to.contain('sourceId must be set');
100
100
  }
101
101
  });
102
102
 
103
103
  it('should return for empty mapping', async () => {
104
- const mapping = await integration.upsertMapping( 'validId2', {});
104
+ const mapping = await integration.upsertMapping('validId2', {});
105
105
  expect(_.pick(mapping, ['integration', 'sourceId', 'mapping'])).to.eql({
106
106
  integration: integrationRecord._id,
107
107
  sourceId: 'validId2',
@@ -0,0 +1,11 @@
1
+ const { IntegrationBase } = require('../../integration-base');
2
+
3
+ class DummyIntegration extends IntegrationBase {
4
+ static Definition = {
5
+ name: 'dummy',
6
+ version: '1.0.0',
7
+ modules: {},
8
+ };
9
+ }
10
+
11
+ module.exports = { DummyIntegration };
@@ -0,0 +1,52 @@
1
+ const { v4: uuid } = require('uuid');
2
+
3
+ class TestIntegrationRepository {
4
+ constructor() {
5
+ this.store = new Map();
6
+ }
7
+
8
+ async createIntegration(entities, userId, config) {
9
+ const id = uuid();
10
+ const record = {
11
+ id,
12
+ entitiesIds: entities,
13
+ userId,
14
+ config,
15
+ version: '0.0.0',
16
+ status: 'NEW',
17
+ messages: {},
18
+ };
19
+ this.store.set(id, record);
20
+ return record;
21
+ }
22
+
23
+ async findIntegrationById(id) {
24
+ const rec = this.store.get(id);
25
+ if (!rec) return null;
26
+ return rec;
27
+ }
28
+
29
+ async findIntegrationsByUserId(userId) {
30
+ return Array.from(this.store.values()).filter(r => r.userId === userId);
31
+ }
32
+
33
+ async updateIntegrationMessages(id, type, title, body, timestamp) {
34
+ const rec = this.store.get(id);
35
+ if (!rec) return false;
36
+ if (!rec.messages[type]) rec.messages[type] = [];
37
+ rec.messages[type].push({ title, message: body, timestamp });
38
+ return true;
39
+ }
40
+
41
+ async deleteIntegrationById(id) {
42
+ return this.store.delete(id);
43
+ }
44
+
45
+ async updateIntegrationStatus(id, status) {
46
+ const rec = this.store.get(id);
47
+ if (rec) rec.status = status;
48
+ return true;
49
+ }
50
+ }
51
+
52
+ module.exports = { TestIntegrationRepository };
@@ -0,0 +1,27 @@
1
+ const { CreateIntegration } = require('../../use-cases/create-integration');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
5
+
6
+ describe('CreateIntegration Use-Case', () => {
7
+ it('creates an integration and returns DTO', async () => {
8
+ const integrationRepository = new TestIntegrationRepository();
9
+ const moduleFactory = new TestModuleFactory();
10
+
11
+ const useCase = new CreateIntegration({
12
+ integrationRepository,
13
+ integrationClasses: [DummyIntegration],
14
+ moduleFactory,
15
+ });
16
+
17
+ const entities = ['entity-1'];
18
+ const userId = 'user-1';
19
+ const config = { type: 'dummy', foo: 'bar' };
20
+
21
+ const dto = await useCase.execute(entities, userId, config);
22
+
23
+ expect(dto.id).toBeDefined();
24
+ expect(dto.config).toEqual(config);
25
+ expect(dto.userId).toBe(userId);
26
+ });
27
+ });
@@ -0,0 +1,20 @@
1
+ const { DeleteIntegrationForUser } = require('../../use-cases/delete-integration-for-user');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
4
+
5
+ describe('DeleteIntegrationForUser', () => {
6
+ it('deletes integration', async () => {
7
+ const repo = new TestIntegrationRepository();
8
+ const record = await repo.createIntegration(['e1'], 'user-1', { type: 'dummy' });
9
+
10
+ const useCase = new DeleteIntegrationForUser({
11
+ integrationRepository: repo,
12
+ integrationClasses: [DummyIntegration],
13
+ });
14
+
15
+ await useCase.execute(record.id, 'user-1');
16
+
17
+ const found = await repo.findIntegrationById(record.id);
18
+ expect(found).toBeNull();
19
+ });
20
+ });
@@ -0,0 +1,29 @@
1
+ const { GetIntegrationForUser } = require('../../use-cases/get-integration-for-user');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { TestModuleRepository } = require('../../../modules/tests/doubles/test-module-repository');
5
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
6
+
7
+
8
+ describe('GetIntegrationForUser', () => {
9
+ it('returns integration dto', async () => {
10
+ const iRepo = new TestIntegrationRepository();
11
+ const mRepo = new TestModuleRepository();
12
+ const mFactory = new TestModuleFactory();
13
+
14
+ const entity = { id: 'entity-1' };
15
+ mRepo.addEntity(entity);
16
+
17
+ const record = await iRepo.createIntegration([entity.id], 'user-1', { type: 'dummy' });
18
+
19
+ const useCase = new GetIntegrationForUser({
20
+ integrationRepository: iRepo,
21
+ integrationClasses: [DummyIntegration],
22
+ moduleFactory: mFactory,
23
+ moduleRepository: mRepo,
24
+ });
25
+
26
+ const dto = await useCase.execute(record.id, 'user-1');
27
+ expect(dto.id).toBe(record.id);
28
+ });
29
+ });
@@ -0,0 +1,26 @@
1
+ const { GetIntegrationInstance } = require('../../use-cases/get-integration-instance');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
5
+
6
+ describe('GetIntegrationInstance Use-Case', () => {
7
+ it('returns hydrated integration instance', async () => {
8
+ const integrationRepository = new TestIntegrationRepository();
9
+ const moduleFactory = new TestModuleFactory();
10
+
11
+ // first create record directly via repo
12
+ const record = await integrationRepository.createIntegration(['entity-1'], 'user-1', { type: 'dummy' });
13
+
14
+ const useCase = new GetIntegrationInstance({
15
+ integrationRepository,
16
+ integrationClasses: [DummyIntegration],
17
+ moduleFactory,
18
+ });
19
+
20
+ const instance = await useCase.execute(record.id, 'user-1');
21
+
22
+ expect(instance.id).toBe(record.id);
23
+ expect(instance.getConfig().type).toBe('dummy');
24
+ expect(instance.entities).toEqual(record.entitiesIds);
25
+ });
26
+ });
@@ -0,0 +1,30 @@
1
+ const { GetIntegrationsForUser } = require('../../use-cases/get-integrations-for-user');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { TestModuleRepository } = require('../../../modules/tests/doubles/test-module-repository');
5
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
6
+
7
+ describe('GetIntegrationsForUser', () => {
8
+ it('returns integrations dto list', async () => {
9
+ const integrationRepo = new TestIntegrationRepository();
10
+ const moduleRepo = new TestModuleRepository();
11
+ const moduleFactory = new TestModuleFactory();
12
+
13
+ // setup entity and module repo
14
+ const entity = { id: 'entity-1' };
15
+ moduleRepo.addEntity(entity);
16
+
17
+ await integrationRepo.createIntegration([entity.id], 'user-1', { type: 'dummy' });
18
+
19
+ const useCase = new GetIntegrationsForUser({
20
+ integrationRepository: integrationRepo,
21
+ integrationClasses: [DummyIntegration],
22
+ moduleFactory,
23
+ moduleRepository: moduleRepo,
24
+ });
25
+
26
+ const list = await useCase.execute('user-1');
27
+ expect(list.length).toBe(1);
28
+ expect(list[0].config.type).toBe('dummy');
29
+ });
30
+ });
@@ -0,0 +1,12 @@
1
+ const { GetPossibleIntegrations } = require('../../use-cases/get-possible-integrations');
2
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
3
+
4
+ describe('GetPossibleIntegrations', () => {
5
+ it('returns option details array', async () => {
6
+ const useCase = new GetPossibleIntegrations({ integrationClasses: [DummyIntegration] });
7
+ const res = await useCase.execute();
8
+ expect(Array.isArray(res)).toBe(true);
9
+ expect(res.length).toBe(1);
10
+ expect(res[0].display).toBeDefined();
11
+ });
12
+ });
@@ -0,0 +1,15 @@
1
+ const { UpdateIntegrationMessages } = require('../../use-cases/update-integration-messages');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+
4
+ describe('UpdateIntegrationMessages', () => {
5
+ it('adds message', async () => {
6
+ const repo = new TestIntegrationRepository();
7
+ const rec = await repo.createIntegration(['e1'], 'user-1', { type: 'dummy' });
8
+
9
+ const useCase = new UpdateIntegrationMessages({ integrationRepository: repo });
10
+ await useCase.execute(rec.id, 'errors', 'title', 'body', Date.now());
11
+
12
+ const fetched = await repo.findIntegrationById(rec.id);
13
+ expect(fetched.messages.errors.length).toBe(1);
14
+ });
15
+ });
@@ -0,0 +1,24 @@
1
+ const { UpdateIntegration } = require('../../use-cases/update-integration');
2
+ const { TestIntegrationRepository } = require('../doubles/test-integration-repository');
3
+ const { TestModuleFactory } = require('../../../modules/tests/doubles/test-module-factory');
4
+ const { DummyIntegration } = require('../doubles/dummy-integration-class');
5
+
6
+ describe('UpdateIntegration', () => {
7
+ it('calls on update and returns dto', async () => {
8
+ const repo = new TestIntegrationRepository();
9
+ const mf = new TestModuleFactory();
10
+
11
+ const record = await repo.createIntegration(['e1'], 'user-1', { type: 'dummy', foo: 'bar' });
12
+
13
+ const useCase = new UpdateIntegration({
14
+ integrationRepository: repo,
15
+ integrationClasses: [DummyIntegration],
16
+ moduleFactory: mf,
17
+ });
18
+
19
+ const newConfig = { type: 'dummy', foo: 'baz' };
20
+ const dto = await useCase.execute(record.id, 'user-1', newConfig);
21
+
22
+ expect(dto.config.foo).toBe('baz');
23
+ });
24
+ });
@@ -19,26 +19,6 @@ class ModuleRepository {
19
19
  };
20
20
  }
21
21
 
22
- async findEntitiesByIds(entitiesIds) {
23
- const entitiesRecords = await Entity.find({ _id: { $in: entitiesIds } }, '', { lean: true }).populate('credential');
24
-
25
- // todo: this is a workaround needed while we create an integration with the same entity twice
26
- if (entitiesRecords.length !== entitiesIds.length && entitiesIds[0] !== entitiesIds[1]) {
27
- throw new Error(`Some entities not found`);
28
- }
29
-
30
- return entitiesRecords.map(e => ({
31
- id: e._id,
32
- accountId: e.accountId,
33
- credential: e.credential,
34
- userId: e.user.toString(),
35
- name: e.name,
36
- externalId: e.externalId,
37
- type: e.__t,
38
- moduleName: e.moduleName,
39
- }));
40
- }
41
-
42
22
  async findEntitiesByUserId(userId) {
43
23
  const entitiesRecords = await Entity.find(
44
24
  { user: userId },
@@ -84,7 +64,8 @@ class ModuleRepository {
84
64
  * @returns {Promise<import('mongoose').UpdateWriteOpResult>}
85
65
  */
86
66
  async unsetCredential(entityId) {
87
- return Entity.updateOne({ _id: entityId }, { $unset: { credential: "" } });
67
+ const result = await Entity.updateOne({ _id: entityId }, { $unset: { credential: "" } });
68
+ return result.acknowledged;
88
69
  }
89
70
  }
90
71
 
@@ -0,0 +1,16 @@
1
+ class TestModuleFactory {
2
+ constructor() { }
3
+
4
+ async getModuleInstance(entityId, userId) {
5
+ // return minimal stub module with getName and api property
6
+ return {
7
+ getName() { return 'stubModule'; },
8
+ api: {},
9
+ entityId,
10
+ userId,
11
+ testAuth: async () => true,
12
+ };
13
+ }
14
+ }
15
+
16
+ module.exports = { TestModuleFactory };
@@ -0,0 +1,19 @@
1
+ class TestModuleRepository {
2
+ constructor() {
3
+ this.entities = new Map();
4
+ }
5
+
6
+ addEntity(entity) {
7
+ this.entities.set(entity.id, entity);
8
+ }
9
+
10
+ async findEntityById(id) {
11
+ return this.entities.get(id);
12
+ }
13
+
14
+ async findEntitiesByIds(ids) {
15
+ return ids.map((id) => this.entities.get(id));
16
+ }
17
+ }
18
+
19
+ module.exports = { TestModuleRepository };
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@friggframework/core",
3
3
  "prettier": "@friggframework/prettier-config",
4
- "version": "2.0.0--canary.397.1b51778.0",
4
+ "version": "2.0.0--canary.397.3862908.0",
5
5
  "dependencies": {
6
6
  "@hapi/boom": "^10.0.1",
7
7
  "aws-sdk": "^2.1200.0",
@@ -22,9 +22,9 @@
22
22
  "uuid": "^9.0.1"
23
23
  },
24
24
  "devDependencies": {
25
- "@friggframework/eslint-config": "2.0.0--canary.397.1b51778.0",
26
- "@friggframework/prettier-config": "2.0.0--canary.397.1b51778.0",
27
- "@friggframework/test": "2.0.0--canary.397.1b51778.0",
25
+ "@friggframework/eslint-config": "2.0.0--canary.397.3862908.0",
26
+ "@friggframework/prettier-config": "2.0.0--canary.397.3862908.0",
27
+ "@friggframework/test": "2.0.0--canary.397.3862908.0",
28
28
  "@types/lodash": "4.17.15",
29
29
  "@typescript-eslint/eslint-plugin": "^8.0.0",
30
30
  "chai": "^4.3.6",
@@ -53,5 +53,5 @@
53
53
  },
54
54
  "homepage": "https://github.com/friggframework/frigg#readme",
55
55
  "description": "",
56
- "gitHead": "1b51778697149cbb26c6ba4de50e507461663f48"
56
+ "gitHead": "3862908989603188a6c3a404d456f4349c84e54b"
57
57
  }